camera: add manual camera control

This commit is contained in:
oziphantom 2021-10-23 01:41:41 +11:00 committed by GitHub
parent 5f7d908508
commit 36288025a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 164 additions and 11 deletions

View file

@ -75,6 +75,7 @@ Not all options are turned on by default. Refer to `Tomb1Main.json5` for details
- added UI and bar scaling
- added save game crystals game mode (enabled via gameflow)
- added pause screen
- added movable camera on W,A,S,D
- changed internal game memory limit from 3.5 MB to 16 MB
- changed moveable limit from 256 to 10240
- changed input method to DirectInput

View file

@ -488,6 +488,11 @@
"KEYMAP_FLY_CHEAT": "Fly cheat",
"KEYMAP_ITEM_CHEAT": "Item cheat",
"KEYMAP_LEVEL_SKIP_CHEAT": "Level skip",
"KEYMAP_CAMERA_UP": "Camera Up",
"KEYMAP_CAMERA_DOWN": "Camera Down",
"KEYMAP_CAMERA_LEFT": "Camera Left",
"KEYMAP_CAMERA_RIGHT": "Camera Right",
"KEYMAP_CAMERA_RESET": "Reset Camera",
"STATS_TIME_TAKEN_FMT": "TIME TAKEN %s",
"STATS_SECRETS_FMT": "SECRETS %d OF %d",
"STATS_PICKUPS_FMT": "PICKUPS %d",
@ -532,6 +537,6 @@
"INV_ITEM_SOUND": "Sound",
"INV_ITEM_CONTROLS": "Controls",
"INV_ITEM_GAMMA": "Gamma",
"INV_ITEM_LARAS_HOME": "Lara's Home",
"INV_ITEM_LARAS_HOME": "Lara's Home"
},
}

View file

@ -147,6 +147,11 @@
"KEYMAP_FLY_CHEAT": "Fly cheat",
"KEYMAP_ITEM_CHEAT": "Item cheat",
"KEYMAP_LEVEL_SKIP_CHEAT": "Level skip",
"KEYMAP_CAMERA_UP": "Camera Up",
"KEYMAP_CAMERA_DOWN": "Camera Down",
"KEYMAP_CAMERA_LEFT": "Camera Left",
"KEYMAP_CAMERA_RIGHT": "Camera Right",
"KEYMAP_CAMERA_RESET": "Reset Camera",
"STATS_TIME_TAKEN_FMT": "TIME TAKEN %s",
"STATS_SECRETS_FMT": "SECRETS %d OF %d",
"STATS_PICKUPS_FMT": "PICKUPS %d",

View file

@ -35,6 +35,8 @@ void InitialiseCamera()
Camera.flags = 0;
Camera.bounce = 0;
Camera.number = NO_CAMERA;
Camera.additional_angle = 0;
Camera.additional_elevation = 0;
CalculateCamera();
}
@ -643,13 +645,24 @@ void CalculateCamera()
Camera.last = Camera.number;
Camera.fixed_camera = fixed_camera;
// should we clear the manual camera
switch (Camera.type) {
case CAM_LOOK:
case CAM_CINEMATIC:
case CAM_COMBAT:
case CAM_FIXED:
Camera.additional_angle = 0;
Camera.additional_elevation = 0;
break;
}
if (Camera.type != CAM_HEAVY || Camera.timer == -1) {
Camera.type = CAM_CHASE;
Camera.number = NO_CAMERA;
Camera.last_item = Camera.item;
Camera.item = NULL;
Camera.target_angle = 0;
Camera.target_elevation = 0;
Camera.target_angle = Camera.additional_angle;
Camera.target_elevation = Camera.additional_elevation;
Camera.target_distance = WALL_L * 3 / 2;
Camera.flags = 0;
}
@ -657,6 +670,35 @@ void CalculateCamera()
ChunkyFlag = 0;
}
void CameraOffsetAdditionalAngle(int16_t delta)
{
Camera.additional_angle += delta;
}
void CameraOffsetAdditionalElevation(int16_t delta)
{
// don't let this value wrap, so clamp it.
if (delta > 0) {
if (Camera.additional_elevation > INT16_MAX - delta) {
Camera.additional_elevation = INT16_MAX;
} else {
Camera.additional_elevation += delta;
}
} else {
if (Camera.additional_elevation < INT16_MIN - delta) {
Camera.additional_elevation = INT16_MIN;
} else {
Camera.additional_elevation += delta;
}
}
}
void CameraOffsetReset()
{
Camera.additional_angle = 0;
Camera.additional_elevation = 0;
}
void T1MInjectGameCamera()
{
INJECT(0x0040F920, InitialiseCamera);

View file

@ -26,6 +26,10 @@ void LookCamera(ITEM_INFO *item);
void FixedCamera();
void CalculateCamera();
void CameraOffsetAdditionalAngle(int16_t delta);
void CameraOffsetAdditionalElevation(int16_t delta);
void CameraOffsetReset();
void T1MInjectGameCamera();
#endif

View file

@ -88,6 +88,11 @@ static GAME_STRING_ID StringToGameStringID(const char *str)
{ "KEYMAP_ITEM_CHEAT", GS_KEYMAP_ITEM_CHEAT },
{ "KEYMAP_LEVEL_SKIP_CHEAT", GS_KEYMAP_LEVEL_SKIP_CHEAT },
{ "KEYMAP_PAUSE", GS_KEYMAP_PAUSE },
{ "KEYMAP_CAMERA_UP", GS_KEYMAP_CAMERA_UP },
{ "KEYMAP_CAMERA_DOWN", GS_KEYMAP_CAMERA_DOWN },
{ "KEYMAP_CAMERA_LEFT", GS_KEYMAP_CAMERA_LEFT },
{ "KEYMAP_CAMERA_RIGHT", GS_KEYMAP_CAMERA_RIGHT },
{ "KEYMAP_CAMERA_RESET", GS_KEYMAP_CAMERA_RESET },
{ "STATS_TIME_TAKEN_FMT", GS_STATS_TIME_TAKEN_FMT },
{ "STATS_SECRETS_FMT", GS_STATS_SECRETS_FMT },
{ "STATS_PICKUPS_FMT", GS_STATS_PICKUPS_FMT },

View file

@ -2,6 +2,7 @@
#include "3dsystem/phd_math.h"
#include "config.h"
#include "game/camera.h"
#include "game/collide.h"
#include "game/control.h"
#include "game/effects/splash.h"
@ -152,6 +153,22 @@ void LaraControl(int16_t item_num)
Lara.target = NULL;
}
int16_t camera_move_delta = PHD_45 / 30;
if (Input & IN_CAMERA_LEFT) {
CameraOffsetAdditionalAngle(camera_move_delta);
} else if (Input & IN_CAMERA_RIGHT) {
CameraOffsetAdditionalAngle(-camera_move_delta);
}
if (Input & IN_CAMERA_UP) {
CameraOffsetAdditionalElevation(-camera_move_delta);
} else if (Input & IN_CAMERA_DOWN) {
CameraOffsetAdditionalElevation(camera_move_delta);
}
if (Input & IN_CAMERA_RESET) {
CameraOffsetReset();
}
switch (Lara.water_status) {
case LWS_ABOVEWATER:
Lara.air = LARA_AIR;

View file

@ -36,7 +36,7 @@
#define CONTROLS_TOP_Y -60
#define CONTROLS_BORDER 4
#define CONTROLS_HEADER_HEIGHT 25
#define CONTROLS_ROW_HEIGHT 15
#define CONTROLS_ROW_HEIGHT 17
typedef enum COMPASS_TEXT {
COMPASS_TITLE = 0,
@ -73,10 +73,29 @@ static TEXTSTRING *CtrlTextA[KEY_NUMBER_OF] = { 0 };
static TEXTSTRING *CtrlTextB[KEY_NUMBER_OF] = { 0 };
static const TEXT_COLUMN_PLACEMENT CtrlTextPlacementNormal[] = {
{ KEY_UP, 0 }, { KEY_DOWN, 0 }, { KEY_LEFT, 0 }, { KEY_RIGHT, 0 },
{ KEY_STEP_L, 0 }, { KEY_STEP_R, 0 }, { KEY_SLOW, 0 }, { KEY_JUMP, 1 },
{ KEY_ACTION, 1 }, { KEY_DRAW, 1 }, { KEY_LOOK, 1 }, { KEY_ROLL, 1 },
{ -1, 1 }, { KEY_OPTION, 1 }, { -1, -1 },
{ KEY_UP, 0 },
{ KEY_DOWN, 0 },
{ KEY_LEFT, 0 },
{ KEY_RIGHT, 0 },
{ KEY_STEP_L, 0 },
{ KEY_STEP_R, 0 },
{ KEY_CAMERA_UP, 0 },
{ KEY_CAMERA_DOWN, 0 },
{ KEY_CAMERA_LEFT, 0 },
{ KEY_CAMERA_RIGHT, 0 },
{ KEY_CAMERA_RESET, 0 },
{ KEY_SLOW, 1 },
{ KEY_JUMP, 1 },
{ KEY_ACTION, 1 },
{ KEY_DRAW, 1 },
{ KEY_LOOK, 1 },
{ KEY_ROLL, 1 },
{ KEY_OPTION, 1 },
{ KEY_PAUSE, 1 },
{ KEY_FLY_CHEAT, 1 },
{ KEY_ITEM_CHEAT, 1 },
{ KEY_LEVEL_SKIP_CHEAT, 1 },
{ -1, -1 },
};
static const TEXT_COLUMN_PLACEMENT CtrlTextPlacementCheats[] = {
{ KEY_UP, 0 },
@ -85,13 +104,19 @@ static const TEXT_COLUMN_PLACEMENT CtrlTextPlacementCheats[] = {
{ KEY_RIGHT, 0 },
{ KEY_STEP_L, 0 },
{ KEY_STEP_R, 0 },
{ KEY_SLOW, 0 },
{ KEY_JUMP, 0 },
{ KEY_CAMERA_UP, 0 },
{ KEY_CAMERA_DOWN, 0 },
{ KEY_CAMERA_LEFT, 0 },
{ KEY_CAMERA_RIGHT, 0 },
{ KEY_CAMERA_RESET, 0 },
{ KEY_SLOW, 1 },
{ KEY_JUMP, 1 },
{ KEY_ACTION, 1 },
{ KEY_DRAW, 1 },
{ KEY_LOOK, 1 },
{ KEY_ROLL, 1 },
{ KEY_OPTION, 1 },
{ KEY_PAUSE, 1 },
{ KEY_FLY_CHEAT, 1 },
{ KEY_ITEM_CHEAT, 1 },
{ KEY_LEVEL_SKIP_CHEAT, 1 },

View file

@ -752,7 +752,12 @@ typedef enum KEY_NUMBER {
KEY_ITEM_CHEAT = 14,
KEY_LEVEL_SKIP_CHEAT = 15,
KEY_PAUSE = 16,
KEY_NUMBER_OF = 17,
KEY_CAMERA_UP = 17,
KEY_CAMERA_DOWN = 18,
KEY_CAMERA_LEFT = 19,
KEY_CAMERA_RIGHT = 20,
KEY_CAMERA_RESET = 21,
KEY_NUMBER_OF = 22,
} KEY_NUMBER;
typedef enum INPUT_STATE {
@ -782,6 +787,11 @@ typedef enum INPUT_STATE {
IN_LOAD = 1 << 23,
IN_FLY_CHEAT = 1 << 24,
IN_ITEM_CHEAT = 1 << 25,
IN_CAMERA_UP = 1 << 26,
IN_CAMERA_DOWN = 1 << 27,
IN_CAMERA_LEFT = 1 << 28,
IN_CAMERA_RIGHT = 1 << 29,
IN_CAMERA_RESET = 1 << 30,
} INPUT_STATE;
typedef enum TEXTSTRING_FLAG {
@ -1111,6 +1121,11 @@ typedef enum GAME_STRING_ID {
GS_KEYMAP_ITEM_CHEAT,
GS_KEYMAP_LEVEL_SKIP_CHEAT,
GS_KEYMAP_PAUSE,
GS_KEYMAP_CAMERA_UP,
GS_KEYMAP_CAMERA_DOWN,
GS_KEYMAP_CAMERA_LEFT,
GS_KEYMAP_CAMERA_RIGHT,
GS_KEYMAP_CAMERA_RESET,
GS_STATS_TIME_TAKEN_FMT,
GS_STATS_SECRETS_FMT,
@ -1741,6 +1756,9 @@ typedef struct CAMERA_INFO {
/* 0058 */ ITEM_INFO *last_item;
/* 005C */ OBJECT_VECTOR *fixed;
/* 0060 end */
// used for the manual camera control
int16_t additional_angle;
int16_t additional_elevation;
} CAMERA_INFO;
typedef struct ANIM_STRUCT {

View file

@ -51,6 +51,11 @@ void T1MInit()
GF.strings[GS_KEYMAP_FLY_CHEAT] = "Fly cheat";
GF.strings[GS_KEYMAP_ITEM_CHEAT] = "Item cheat";
GF.strings[GS_KEYMAP_LEVEL_SKIP_CHEAT] = "Level skip";
GF.strings[GS_KEYMAP_CAMERA_UP] = "Camera Up";
GF.strings[GS_KEYMAP_CAMERA_DOWN] = "Camera Down";
GF.strings[GS_KEYMAP_CAMERA_LEFT] = "Camera Left";
GF.strings[GS_KEYMAP_CAMERA_RIGHT] = "Camera Right";
GF.strings[GS_KEYMAP_CAMERA_RESET] = "Reset Camera";
GF.strings[GS_STATS_TIME_TAKEN_FMT] = "TIME TAKEN %s";
GF.strings[GS_STATS_SECRETS_FMT] = "SECRETS %d OF %d";
GF.strings[GS_STATS_PICKUPS_FMT] = "PICKUPS %d";

View file

@ -34,6 +34,11 @@ int16_t Layout[2][KEY_NUMBER_OF] = {
DIK_I, // KEY_ITEM_CHEAT,
DIK_X, // KEY_LEVEL_SKIP_CHEAT,
DIK_P, // KEY_PAUSE,
DIK_W, // KEY_CAMERA_UP
DIK_S, // KEY_CAMERA_DOWN
DIK_A, // KEY_CAMERA_LEFT
DIK_D, // KEY_CAMERA_RIGHT
DIK_SLASH, // KEY_CAMERA_RESET
},
// default user controls
@ -55,6 +60,11 @@ int16_t Layout[2][KEY_NUMBER_OF] = {
DIK_I, // KEY_ITEM_CHEAT,
DIK_X, // KEY_LEVEL_SKIP_CHEAT,
DIK_P, // KEY_PAUSE,
DIK_W, // KEY_CAMERA_UP
DIK_S, // KEY_CAMERA_DOWN
DIK_A, // KEY_CAMERA_LEFT
DIK_D, // KEY_CAMERA_RIGHT
DIK_SLASH, // KEY_CAMERA_RESET
}
};
@ -255,6 +265,22 @@ void S_UpdateInput()
linput |= IN_ROLL;
}
if (Key_(KEY_CAMERA_UP)) {
linput |= IN_CAMERA_UP;
}
if (Key_(KEY_CAMERA_DOWN)) {
linput |= IN_CAMERA_DOWN;
}
if (Key_(KEY_CAMERA_LEFT)) {
linput |= IN_CAMERA_LEFT;
}
if (Key_(KEY_CAMERA_RIGHT)) {
linput |= IN_CAMERA_RIGHT;
}
if (Key_(KEY_CAMERA_RESET)) {
linput |= IN_CAMERA_RESET;
}
if (T1MConfig.enable_cheats) {
static int8_t is_stuff_cheat_key_pressed = 0;
if (Key_(KEY_ITEM_CHEAT)) {