Skip to content

Commit

Permalink
allow remapping cheat keys (closes #85)
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Mar 19, 2021
1 parent 273db2d commit 2a31a98
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 53 deletions.
3 changes: 3 additions & 0 deletions build/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ void T1MInit()
GF.strings[GS_KEYMAP_LOOK] = "Look";
GF.strings[GS_KEYMAP_ROLL] = "Roll";
GF.strings[GS_KEYMAP_INVENTORY] = "Inventory";
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_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";
Expand Down
2 changes: 1 addition & 1 deletion cfg/Tomb1Main.json5
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"enable_tr3_sidesteps": true,

// Enables various cheats:
// - F10: immediately end the level.
// - X: immediately end the level.
// - F11: heal Lara. Hold WALK key to hurt instead.
// - I: gives Lara all the guns, ammo, medpacks and plot items for the
// current level.
Expand Down
3 changes: 3 additions & 0 deletions cfg/Tomb1Main_gameflow.json5
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,9 @@
"KEYMAP_LOOK": "Look",
"KEYMAP_ROLL": "Roll",
"KEYMAP_INVENTORY": "Inventory",
"KEYMAP_FLY_CHEAT": "Fly cheat",
"KEYMAP_ITEM_CHEAT": "Item cheat",
"KEYMAP_LEVEL_SKIP_CHEAT": "Level skip",
"STATS_TIME_TAKEN_FMT": "TIME TAKEN %s",
"STATS_SECRETS_FMT": "SECRETS %d OF %d",
"STATS_PICKUPS_FMT": "PICKUPS %d",
Expand Down
2 changes: 1 addition & 1 deletion src/game/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ int32_t ControlPhase(int32_t nframes, int32_t demo_mode)
}

if (Lara.death_count > DEATH_WAIT
|| (Lara.death_count > DEATH_WAIT_MIN && (Input & ~IN_DOZYCHEAT))
|| (Lara.death_count > DEATH_WAIT_MIN && (Input & ~IN_FLY_CHEAT))
|| OverlayFlag == 2) {
if (demo_mode) {
return 1;
Expand Down
3 changes: 3 additions & 0 deletions src/game/gameflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ static GAME_STRING_ID StringToGameStringID(const char *str)
{ "KEYMAP_LOOK", GS_KEYMAP_LOOK },
{ "KEYMAP_ROLL", GS_KEYMAP_ROLL },
{ "KEYMAP_INVENTORY", GS_KEYMAP_INVENTORY },
{ "KEYMAP_FLY_CHEAT", GS_KEYMAP_FLY_CHEAT },
{ "KEYMAP_ITEM_CHEAT", GS_KEYMAP_ITEM_CHEAT },
{ "KEYMAP_LEVEL_SKIP_CHEAT", GS_KEYMAP_LEVEL_SKIP_CHEAT },
{ "STATS_TIME_TAKEN_FMT", GS_STATS_TIME_TAKEN_FMT },
{ "STATS_SECRETS_FMT", GS_STATS_SECRETS_FMT },
{ "STATS_PICKUPS_FMT", GS_STATS_PICKUPS_FMT },
Expand Down
6 changes: 3 additions & 3 deletions src/game/laramisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ void LaraControl(int16_t item_num)
ROOM_INFO *r = &RoomInfo[item->room_number];
int32_t room_submerged = r->flags & RF_UNDERWATER;

if (Input & IN_STUFFCHEAT) {
if (Input & IN_ITEM_CHEAT) {
LaraCheatGetStuff();
}

if (Lara.water_status != LWS_CHEAT && (Input & IN_DOZYCHEAT)) {
if (Lara.water_status != LWS_CHEAT && (Input & IN_FLY_CHEAT)) {
if (Lara.water_status != LWS_UNDERWATER || item->hit_points <= 0) {
item->pos.y -= 0x80;
item->current_anim_state = AS_SWIM;
Expand Down Expand Up @@ -185,7 +185,7 @@ void LaraControl(int16_t item_num)
Lara.death_count = 0;
LaraUnderWater(item, &coll);
if (CHK_ANY(Input, IN_SLOW)
&& !CHK_ANY(Input, IN_LOOK | IN_DOZYCHEAT)) {
&& !CHK_ANY(Input, IN_LOOK | IN_FLY_CHEAT)) {
int16_t wh = GetWaterHeight(
item->pos.x, item->pos.y, item->pos.z, item->room_number);
if (room_submerged || (wh != NO_HEIGHT && wh > 0)) {
Expand Down
119 changes: 82 additions & 37 deletions src/game/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,15 +881,15 @@ void DoControlOption(INVENTORY_ITEM *inv_item)
S_WriteUserSettings();
} else {
T_RemoveBackground(CtrlTextA[KeyChange]);
if (KeyChange <= KEY_NUMBER_OF / 2) {
KeyChange += (KEY_NUMBER_OF) / 2 + 1;
if (KeyChange <= 6) {
KeyChange += 7;
if (KeyChange == KEY_NUMBER_OF) {
KeyChange = KEY_NUMBER_OF - 1;
}
} else if (KeyChange == KEY_NUMBER_OF - 1) {
KeyChange = KEY_NUMBER_OF / 2;
KeyChange = 6;
} else {
KeyChange -= (KEY_NUMBER_OF / 2) + 1;
KeyChange -= 7;
}
T_AddBackground(
CtrlTextA[KeyChange], 0, 0, 0, 0, 48, IC_BLACK, NULL, 0);
Expand All @@ -914,7 +914,7 @@ void DoControlOption(INVENTORY_ITEM *inv_item)

KeyChange--;
if (KeyChange < -1) {
KeyChange = 12;
KeyChange = KEY_NUMBER_OF - 1;
}

T_AddBackground(
Expand All @@ -925,7 +925,7 @@ void DoControlOption(INVENTORY_ITEM *inv_item)
KeyChange == -1 ? CtrlText[0] : CtrlTextA[KeyChange]);

KeyChange++;
if (KeyChange > 12) {
if (KeyChange > KEY_NUMBER_OF - 1) {
KeyChange = -1;
}

Expand Down Expand Up @@ -1011,34 +1011,61 @@ void DoControlOption(INVENTORY_ITEM *inv_item)
void S_ShowControls()
{
int16_t centre = GetRenderWidthDownscaled() / 2;
int16_t hpos;
int16_t vpos;

CtrlText[1] = T_Print(0, -60, 0, " ");
T_CentreH(CtrlText[1], 1);
T_CentreV(CtrlText[1], 1);

hpos = 420;
vpos = 150;
int16_t hpos = 420;
int16_t vpos = 150;
if (T1MConfig.enable_cheats) {
vpos += 45;
}
T_AddBackground(CtrlText[1], hpos, vpos, 0, 0, 48, IC_BLACK, NULL, 0);

if (!CtrlTextB[0]) {
int16_t *layout = Layout[IConfig];
hpos = centre - 200;

CtrlTextB[0] = T_Print(hpos, -25, 0, ScanCodeNames[layout[0]]);
CtrlTextB[1] = T_Print(hpos, -10, 0, ScanCodeNames[layout[1]]);
CtrlTextB[2] = T_Print(hpos, 5, 0, ScanCodeNames[layout[2]]);
CtrlTextB[3] = T_Print(hpos, 20, 0, ScanCodeNames[layout[3]]);
CtrlTextB[4] = T_Print(hpos, 35, 0, ScanCodeNames[layout[4]]);
CtrlTextB[5] = T_Print(hpos, 50, 0, ScanCodeNames[layout[5]]);
CtrlTextB[6] = T_Print(hpos, 65, 0, ScanCodeNames[layout[6]]);
CtrlTextB[7] = T_Print(centre + 20, -25, 0, ScanCodeNames[layout[7]]);
CtrlTextB[8] = T_Print(centre + 20, -10, 0, ScanCodeNames[layout[8]]);
CtrlTextB[9] = T_Print(centre + 20, 5, 0, ScanCodeNames[layout[9]]);
CtrlTextB[10] = T_Print(centre + 20, 20, 0, ScanCodeNames[layout[10]]);
CtrlTextB[11] = T_Print(centre + 20, 35, 0, ScanCodeNames[layout[11]]);
CtrlTextB[12] = T_Print(centre + 20, 65, 0, ScanCodeNames[layout[12]]);
CtrlTextB[KEY_UP] =
T_Print(hpos, -25, 0, ScanCodeNames[layout[KEY_UP]]);
CtrlTextB[KEY_DOWN] =
T_Print(hpos, -10, 0, ScanCodeNames[layout[KEY_DOWN]]);
CtrlTextB[KEY_LEFT] =
T_Print(hpos, 5, 0, ScanCodeNames[layout[KEY_LEFT]]);
CtrlTextB[KEY_RIGHT] =
T_Print(hpos, 20, 0, ScanCodeNames[layout[KEY_RIGHT]]);
CtrlTextB[KEY_STEP_L] =
T_Print(hpos, 35, 0, ScanCodeNames[layout[KEY_STEP_L]]);
CtrlTextB[KEY_STEP_R] =
T_Print(hpos, 50, 0, ScanCodeNames[layout[KEY_STEP_R]]);
CtrlTextB[KEY_SLOW] =
T_Print(hpos, 65, 0, ScanCodeNames[layout[KEY_SLOW]]);
CtrlTextB[KEY_JUMP] =
T_Print(centre + 20, -25, 0, ScanCodeNames[layout[KEY_JUMP]]);
CtrlTextB[KEY_ACTION] =
T_Print(centre + 20, -10, 0, ScanCodeNames[layout[KEY_ACTION]]);
CtrlTextB[KEY_DRAW] =
T_Print(centre + 20, 5, 0, ScanCodeNames[layout[KEY_DRAW]]);
CtrlTextB[KEY_LOOK] =
T_Print(centre + 20, 20, 0, ScanCodeNames[layout[KEY_LOOK]]);
CtrlTextB[KEY_ROLL] =
T_Print(centre + 20, 35, 0, ScanCodeNames[layout[KEY_ROLL]]);

if (T1MConfig.enable_cheats) {
CtrlTextB[KEY_OPTION] =
T_Print(centre + 20, 50, 0, ScanCodeNames[layout[KEY_OPTION]]);
CtrlTextB[KEY_FLY_CHEAT] = T_Print(
centre + 20, 80, 0, ScanCodeNames[layout[KEY_FLY_CHEAT]]);
CtrlTextB[KEY_ITEM_CHEAT] = T_Print(
centre + 20, 95, 0, ScanCodeNames[layout[KEY_ITEM_CHEAT]]);
CtrlTextB[KEY_LEVEL_SKIP_CHEAT] = T_Print(
centre + 20, 110, 0,
ScanCodeNames[layout[KEY_LEVEL_SKIP_CHEAT]]);
} else {
CtrlTextB[KEY_OPTION] =
T_Print(centre + 20, 65, 0, ScanCodeNames[layout[KEY_OPTION]]);
}

for (int i = 0; i < KEY_NUMBER_OF; i++) {
T_CentreV(CtrlTextB[i], 1);
Expand All @@ -1049,22 +1076,40 @@ void S_ShowControls()
if (!CtrlTextA[0]) {
hpos = centre - 130;

CtrlTextA[0] = T_Print(hpos, -25, 0, GF.strings[GS_KEYMAP_RUN]);
CtrlTextA[1] = T_Print(hpos, -10, 0, GF.strings[GS_KEYMAP_BACK]);
CtrlTextA[2] = T_Print(hpos, 5, 0, GF.strings[GS_KEYMAP_LEFT]);
CtrlTextA[3] = T_Print(hpos, 20, 0, GF.strings[GS_KEYMAP_RIGHT]);
CtrlTextA[4] = T_Print(hpos, 35, 0, GF.strings[GS_KEYMAP_STEP_LEFT]);
CtrlTextA[5] = T_Print(hpos, 50, 0, GF.strings[GS_KEYMAP_STEP_RIGHT]);
CtrlTextA[6] = T_Print(hpos, 65, 0, GF.strings[GS_KEYMAP_WALK]);
CtrlTextA[7] = T_Print(centre + 90, -25, 0, GF.strings[GS_KEYMAP_JUMP]);
CtrlTextA[8] =
CtrlTextA[KEY_UP] = T_Print(hpos, -25, 0, GF.strings[GS_KEYMAP_RUN]);
CtrlTextA[KEY_DOWN] = T_Print(hpos, -10, 0, GF.strings[GS_KEYMAP_BACK]);
CtrlTextA[KEY_LEFT] = T_Print(hpos, 5, 0, GF.strings[GS_KEYMAP_LEFT]);
CtrlTextA[KEY_RIGHT] =
T_Print(hpos, 20, 0, GF.strings[GS_KEYMAP_RIGHT]);
CtrlTextA[KEY_STEP_L] =
T_Print(hpos, 35, 0, GF.strings[GS_KEYMAP_STEP_LEFT]);
CtrlTextA[KEY_STEP_R] =
T_Print(hpos, 50, 0, GF.strings[GS_KEYMAP_STEP_RIGHT]);
CtrlTextA[KEY_SLOW] = T_Print(hpos, 65, 0, GF.strings[GS_KEYMAP_WALK]);
CtrlTextA[KEY_JUMP] =
T_Print(centre + 90, -25, 0, GF.strings[GS_KEYMAP_JUMP]);
CtrlTextA[KEY_ACTION] =
T_Print(centre + 90, -10, 0, GF.strings[GS_KEYMAP_ACTION]);
CtrlTextA[9] =
CtrlTextA[KEY_DRAW] =
T_Print(centre + 90, 5, 0, GF.strings[GS_KEYMAP_DRAW_WEAPON]);
CtrlTextA[10] = T_Print(centre + 90, 20, 0, GF.strings[GS_KEYMAP_LOOK]);
CtrlTextA[11] = T_Print(centre + 90, 35, 0, GF.strings[GS_KEYMAP_ROLL]);
CtrlTextA[12] =
T_Print(centre + 90, 65, 0, GF.strings[GS_KEYMAP_INVENTORY]);
CtrlTextA[KEY_LOOK] =
T_Print(centre + 90, 20, 0, GF.strings[GS_KEYMAP_LOOK]);
CtrlTextA[KEY_ROLL] =
T_Print(centre + 90, 35, 0, GF.strings[GS_KEYMAP_ROLL]);

if (T1MConfig.enable_cheats) {
CtrlTextA[KEY_OPTION] =
T_Print(centre + 90, 50, 0, GF.strings[GS_KEYMAP_INVENTORY]);
CtrlTextA[KEY_FLY_CHEAT] =
T_Print(centre + 90, 80, 0, GF.strings[GS_KEYMAP_FLY_CHEAT]);
CtrlTextA[KEY_ITEM_CHEAT] =
T_Print(centre + 90, 95, 0, GF.strings[GS_KEYMAP_ITEM_CHEAT]);
CtrlTextA[KEY_LEVEL_SKIP_CHEAT] = T_Print(
centre + 90, 110, 0, GF.strings[GS_KEYMAP_LEVEL_SKIP_CHEAT]);
} else {
CtrlTextA[KEY_OPTION] =
T_Print(centre + 90, 65, 0, GF.strings[GS_KEYMAP_INVENTORY]);
}

for (int i = 0; i < KEY_NUMBER_OF; i++) {
T_CentreV(CtrlTextA[i], 1);
Expand Down
4 changes: 2 additions & 2 deletions src/game/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static int32_t S_ReadUserSettingsT1M()
CLAMP(IConfig, 0, 1);

struct json_array_s *layout_arr = json_object_get_array(root_obj, "layout");
for (int i = 0; i < 13; i++) {
for (int i = 0; i < KEY_NUMBER_OF; i++) {
Layout[1][i] = json_array_get_number_int(layout_arr, i, Layout[1][i]);
}

Expand Down Expand Up @@ -155,7 +155,7 @@ static int32_t S_WriteUserSettingsT1M()
json_object_append_number_int(root_obj, "layout_num", IConfig);

struct json_array_s *layout_arr = json_array_new();
for (int i = 0; i < 13; i++) {
for (int i = 0; i < KEY_NUMBER_OF; i++) {
json_array_append_number_int(layout_arr, Layout[1][i]);
}
json_object_append_array(root_obj, "layout", layout_arr);
Expand Down
12 changes: 9 additions & 3 deletions src/game/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,10 @@ typedef enum KEY_NUMBER {
KEY_LOOK = 10,
KEY_ROLL = 11,
KEY_OPTION = 12,
KEY_NUMBER_OF = 13,
KEY_FLY_CHEAT = 13,
KEY_ITEM_CHEAT = 14,
KEY_LEVEL_SKIP_CHEAT = 15,
KEY_NUMBER_OF = 16,
} KEY_NUMBER;

typedef enum INPUT_STATE {
Expand Down Expand Up @@ -776,8 +779,8 @@ typedef enum INPUT_STATE {
IN_DESELECT = 1 << 21,
IN_SAVE = 1 << 22,
IN_LOAD = 1 << 23,
IN_DOZYCHEAT = 1 << 24,
IN_STUFFCHEAT = 1 << 25,
IN_FLY_CHEAT = 1 << 24,
IN_ITEM_CHEAT = 1 << 25,
} INPUT_STATE;

typedef enum TEXTSTRING_FLAG {
Expand Down Expand Up @@ -1099,6 +1102,9 @@ typedef enum GAME_STRING_ID {
GS_KEYMAP_LOOK,
GS_KEYMAP_ROLL,
GS_KEYMAP_INVENTORY,
GS_KEYMAP_FLY_CHEAT,
GS_KEYMAP_ITEM_CHEAT,
GS_KEYMAP_LEVEL_SKIP_CHEAT,

GS_STATS_TIME_TAKEN_FMT,
GS_STATS_SECRETS_FMT,
Expand Down
17 changes: 11 additions & 6 deletions src/specific/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ int16_t Layout[2][KEY_NUMBER_OF] = {
DIK_NUMPAD0, // KEY_LOOK
DIK_END, // KEY_ROLL
DIK_ESCAPE, // KEY_OPTION
DIK_O, // KEY_FLY_CHEAT,
DIK_I, // KEY_ITEM_CHEAT,
DIK_X, // KEY_LEVEL_SKIP_CHEAT,
},

// default user controls
Expand All @@ -43,6 +46,9 @@ int16_t Layout[2][KEY_NUMBER_OF] = {
DIK_NUMPAD0, // KEY_LOOK
DIK_NUMPAD5, // KEY_ROLL
DIK_DECIMAL, // KEY_OPTION
DIK_O, // KEY_FLY_CHEAT,
DIK_I, // KEY_ITEM_CHEAT,
DIK_X, // KEY_LEVEL_SKIP_CHEAT,
}
};

Expand Down Expand Up @@ -198,20 +204,19 @@ void S_UpdateInput()

if (T1MConfig.enable_cheats) {
static int8_t is_stuff_cheat_key_pressed = 0;
if (KeyData->keymap[DIK_I]) {
if (Key_(KEY_ITEM_CHEAT)) {
if (!is_stuff_cheat_key_pressed) {
is_stuff_cheat_key_pressed = 1;
TRACE("enabling stuff cheat");
linput |= IN_STUFFCHEAT;
linput |= IN_ITEM_CHEAT;
}
} else {
is_stuff_cheat_key_pressed = 0;
}

if (KeyData->keymap[DIK_O]) {
linput |= IN_DOZYCHEAT;
if (Key_(KEY_FLY_CHEAT)) {
linput |= IN_FLY_CHEAT;
}
if (KeyData->keymap[DIK_F10]) {
if (Key_(KEY_LEVEL_SKIP_CHEAT)) {
LevelComplete = 1;
}
if (KeyData->keymap[DIK_F11] && LaraItem) {
Expand Down

0 comments on commit 2a31a98

Please sign in to comment.