diff --git a/docs/progress.svg b/docs/progress.svg
index e9b9cf74f..45e671f9a 100644
--- a/docs/progress.svg
+++ b/docs/progress.svg
@@ -514,7 +514,7 @@
Scion3Control
EarthQuakeControl
DoInventoryOptions
-DoPassportOption
+DoPassportOption
DoDetailOptionHW
DoDetailOption
DoSoundOption
@@ -772,7 +772,7 @@
DoSoundOption
CalculateTarget
DrawLightning
-DoPassportOption
+DoPassportOption
BaldyControl
SoundEffect
S_ShowControls
@@ -1463,10 +1463,10 @@
sub_440EF0
sub_437BC0
S_CDVolume
-Functions decompiled (count): 67.17%
-Functions decompiled (bytesize): 63.24%
-Functions not decompiled, but with known names (count): 18.88%
-Functions not decompiled, but with known names (bytesize): 21.03%
+Functions decompiled (count): 67.31%
+Functions decompiled (bytesize): 63.73%
+Functions not decompiled, but with known names (count): 18.74%
+Functions not decompiled, but with known names (bytesize): 20.54%
Functions not decompiled, with unknown names (count): 13.95%
Functions not decompiled, with unknown names (bytesize): 15.73%
diff --git a/docs/progress.txt b/docs/progress.txt
index 9767b6fd8..13d17aac2 100644
--- a/docs/progress.txt
+++ b/docs/progress.txt
@@ -724,7 +724,7 @@ EarthQuakeControl 0x0042D700 0x0000006F +
# option.cpp
GetScancodeName ---------- ---------- -
DoInventoryOptions 0x0042D770 0x00000180 +
-DoPassportOption 0x0042D9C0 0x000004D0 *
+DoPassportOption 0x0042D9C0 0x000004D0 +
DoGammaOption ---------- ---------- +
DoDetailOptionHW 0x0042DE90 0x00000435 -
DoDetailOption 0x0042E2D0 0x000002E8 -
@@ -737,7 +737,7 @@ S_ShowControls 0x0042F230 0x000004B1 +
S_ChangeCtrlText ---------- ---------- -
S_RemoveCtrlText ---------- ---------- -
S_RemoveCtrl ---------- ---------- -
-InitRequester ---------- ---------- -
+InitRequester ---------- ---------- +
RemoveRequester ---------- ---------- -
DisplayRequester 0x0042F6F0 0x0000056B *
diff --git a/src/game/game.c b/src/game/game.c
index 87730f0dd..9686a00e0 100644
--- a/src/game/game.c
+++ b/src/game/game.c
@@ -418,9 +418,6 @@ void GetSavedGamesList(REQUEST_INFO* req)
req->y = -100;
req->vis_lines = 12;
break;
-
- default:
- break;
}
if (req->requested >= req->vis_lines) {
diff --git a/src/game/option.c b/src/game/option.c
index 4e93fcf59..73cead7c9 100644
--- a/src/game/option.c
+++ b/src/game/option.c
@@ -10,6 +10,11 @@
#define GAMMA_MODIFIER 8
#define MIN_GAMMA_LEVEL -127
#define MAX_GAMMA_LEVEL 127
+#define PASSPORT_2FRONT IN_LEFT
+#define PASSPORT_2BACK IN_RIGHT
+
+static TEXTSTRING* PassportText1;
+static int32_t PassportMode;
// original name: do_inventory_options
void DoInventoryOptions(INVENTORY_ITEM* inv_item)
@@ -75,6 +80,208 @@ void DoInventoryOptions(INVENTORY_ITEM* inv_item)
}
}
+void DoPassportOption(INVENTORY_ITEM* inv_item)
+{
+ T_RemovePrint(InvItemText[0]);
+ InvItemText[IT_NAME] = NULL;
+
+ int16_t page = (inv_item->goal_frame - inv_item->open_frame) / 5;
+ if ((inv_item->goal_frame - inv_item->open_frame) % 5) {
+ page = -1;
+ }
+
+ if (InventoryMode == INV_LOAD_MODE || InventoryMode == INV_SAVE_MODE) {
+ InputDB &= ~(PASSPORT_2FRONT | PASSPORT_2BACK);
+ }
+
+ switch (page) {
+ case 0:
+ if (PassportMode == 1) {
+ int32_t select = DisplayRequester(&LoadGameRequester);
+ if (select) {
+ if (select > 0) {
+ InventoryExtraData[1] = select - 1;
+ } else if (
+ InventoryMode != INV_SAVE_MODE
+ && InventoryMode != INV_LOAD_MODE) {
+ Input = 0;
+ InputDB = 0;
+ }
+ PassportMode = 0;
+ } else {
+ Input = 0;
+ InputDB = 0;
+ }
+ } else if (PassportMode == 0) {
+ if (!SavedGamesCount || InventoryMode == INV_SAVE_MODE) {
+ InputDB = PASSPORT_2BACK;
+ } else {
+ if (!PassportText1) {
+ PassportText1 = T_Print(0, -16, 0, "Load Game");
+ T_BottomAlign(PassportText1, 1);
+ T_CentreH(PassportText1, 1);
+ }
+ if (CHK_ANY(InputDB, IN_SELECT)
+ || InventoryMode == INV_LOAD_MODE) {
+ T_RemovePrint(InvRingText);
+ InvRingText = NULL;
+ T_RemovePrint(InvItemText[IT_NAME]);
+ InvItemText[IT_NAME] = NULL;
+ GetSavedGamesList(&LoadGameRequester);
+ InitRequester(&LoadGameRequester);
+ PassportMode = 1;
+ Input = 0;
+ InputDB = 0;
+ }
+ }
+ }
+ break;
+
+ case 1:
+ if (PassportMode == 1) {
+ int32_t select = DisplayRequester(&LoadGameRequester);
+ if (select) {
+ if (select > 0) {
+ PassportMode = 0;
+ InventoryExtraData[1] = select - 1;
+ } else {
+ if (InventoryMode != INV_SAVE_MODE
+ && InventoryMode != INV_LOAD_MODE) {
+ Input = 0;
+ InputDB = 0;
+ }
+ PassportMode = 0;
+ }
+ } else {
+ Input = 0;
+ InputDB = 0;
+ }
+ } else if (PassportMode == 0) {
+ if (InventoryMode == INV_DEATH_MODE) {
+ InputDB = inv_item->anim_direction == -1 ? PASSPORT_2FRONT
+ : PASSPORT_2BACK;
+ }
+ if (!PassportText1) {
+ if (InventoryMode == INV_TITLE_MODE || !CurrentLevel) {
+ PassportText1 = T_Print(0, -16, 0, "New Game");
+ } else {
+ PassportText1 = T_Print(0, -16, 0, "Save Game");
+ }
+ T_BottomAlign(PassportText1, 1);
+ T_CentreH(PassportText1, 1);
+ }
+ if (CHK_ANY(InputDB, IN_SELECT) || InventoryMode == INV_SAVE_MODE) {
+ if (InventoryMode == INV_TITLE_MODE || !CurrentLevel) {
+ InventoryExtraData[1] = CurrentLevel;
+ } else {
+ T_RemovePrint(InvRingText);
+ InvRingText = NULL;
+ T_RemovePrint(InvItemText[IT_NAME]);
+ InvItemText[IT_NAME] = NULL;
+ GetSavedGamesList(&LoadGameRequester);
+ InitRequester(&LoadGameRequester);
+ PassportMode = 1;
+ Input = 0;
+ InputDB = 0;
+ }
+ }
+ }
+ break;
+
+ case 2:
+ if (!PassportText1) {
+ if (InventoryMode == INV_TITLE_MODE) {
+ PassportText1 = T_Print(0, -16, 0, "Exit Game");
+ } else {
+ PassportText1 = T_Print(0, -16, 0, "Exit to Title");
+ }
+ T_BottomAlign(PassportText1, 1);
+ T_CentreH(PassportText1, 1);
+ }
+ break;
+ }
+
+ if (CHK_ANY(InputDB, PASSPORT_2FRONT)
+ && (InventoryMode != INV_DEATH_MODE || SavedGamesCount)) {
+ inv_item->anim_direction = -1;
+ inv_item->goal_frame -= 5;
+
+ Input = 0;
+ InputDB = 0;
+
+ if (!SavedGamesCount) {
+ if (inv_item->goal_frame < inv_item->open_frame + 5) {
+ inv_item->goal_frame = inv_item->open_frame + 5;
+ } else if (PassportText1) {
+ T_RemovePrint(PassportText1);
+ PassportText1 = NULL;
+ }
+ } else {
+ if (inv_item->goal_frame < inv_item->open_frame) {
+ inv_item->goal_frame = inv_item->open_frame;
+ } else {
+ SoundEffect(115, NULL, SFX_ALWAYS);
+ if (PassportText1) {
+ T_RemovePrint(PassportText1);
+ PassportText1 = NULL;
+ }
+ }
+ }
+ }
+
+ if (CHK_ANY(InputDB, PASSPORT_2BACK)) {
+ inv_item->goal_frame += 5;
+ inv_item->anim_direction = 1;
+
+ Input = 0;
+ InputDB = 0;
+
+ if (inv_item->goal_frame > inv_item->frames_total - 6) {
+ inv_item->goal_frame = inv_item->frames_total - 6;
+ } else {
+ SoundEffect(115, NULL, SFX_ALWAYS);
+ if (PassportText1) {
+ T_RemovePrint(PassportText1);
+ PassportText1 = NULL;
+ }
+ }
+ }
+
+ if (CHK_ANY(InputDB, IN_DESELECT)) {
+ if (InventoryMode == INV_DEATH_MODE) {
+ Input = 0;
+ InputDB = 0;
+ } else {
+ if (page == 2) {
+ inv_item->anim_direction = 1;
+ inv_item->goal_frame = inv_item->frames_total - 1;
+ } else {
+ inv_item->goal_frame = 0;
+ inv_item->anim_direction = -1;
+ }
+ if (PassportText1) {
+ T_RemovePrint(PassportText1);
+ PassportText1 = 0;
+ }
+ }
+ }
+
+ if (CHK_ANY(InputDB, IN_SELECT)) {
+ InventoryExtraData[0] = page;
+ if (page == 2) {
+ inv_item->anim_direction = 1;
+ inv_item->goal_frame = inv_item->frames_total - 1;
+ } else {
+ inv_item->goal_frame = 0;
+ inv_item->anim_direction = -1;
+ }
+ if (PassportText1) {
+ T_RemovePrint(PassportText1);
+ PassportText1 = 0;
+ }
+ }
+}
+
// original name: do_gamma_option
void DoGammaOption(INVENTORY_ITEM* inv_item)
{
@@ -280,5 +487,6 @@ void InitRequester(REQUEST_INFO* req)
void T1MInjectGameOption()
{
INJECT(0x0042D770, DoInventoryOptions);
+ INJECT(0x0042D9C0, DoPassportOption);
INJECT(0x0042F230, S_ShowControls);
}
diff --git a/src/game/option.h b/src/game/option.h
index 997f25d8c..c1f427da0 100644
--- a/src/game/option.h
+++ b/src/game/option.h
@@ -4,7 +4,6 @@
#include "game/types.h"
// clang-format off
-#define DoPassportOption ((void (*)(INVENTORY_ITEM* inv_item))0x0042D9C0)
#define DoDetailOption ((void (*)(INVENTORY_ITEM* inv_item))0x0042E2D0)
#define DoSoundOption ((void (*)(INVENTORY_ITEM* inv_item))0x0042E5C0)
#define DoControlOption ((void (*)(INVENTORY_ITEM* inv_item))0x0042EAC0)
@@ -12,9 +11,11 @@
// clang-format on
void DoInventoryOptions(INVENTORY_ITEM* inv_item);
+void DoPassportOption(INVENTORY_ITEM* inv_item);
void DoGammaOption(INVENTORY_ITEM* inv_item);
void DoCompassOption(INVENTORY_ITEM* inv_item);
void S_ShowControls();
+void InitRequester(REQUEST_INFO* req);
void T1MInjectGameOption();
diff --git a/src/json-parser/json.c b/src/json-parser/json.c
index 1a7437e57..b4144c59a 100644
--- a/src/json-parser/json.c
+++ b/src/json-parser/json.c
@@ -227,8 +227,6 @@ int json_get_string_size(struct json_parse_state_s* state, size_t is_key)
data_size++;
switch (src[offset]) {
- default:
- break;
case '\0':
case '\t':
state->error = json_parse_error_invalid_string;
@@ -1784,8 +1782,6 @@ json_extract_get_value_size(const struct json_value_s* const value)
struct json_extract_result_s result = { 0, 0 };
switch (value->type) {
- default:
- break;
case json_type_object:
result = json_extract_get_object_size(
(const struct json_object_s*)value->payload);
@@ -2004,8 +2000,6 @@ int json_write_get_number_size(const struct json_number_s* number, size_t* size)
if (number->number_size >= 2) {
switch (number->number[1]) {
- default:
- break;
case 'x':
case 'X':
/* the number is a json_parse_flags_allow_hexadecimal_numbers
@@ -2235,8 +2229,6 @@ char* json_write_number(const struct json_number_s* number, char* data)
if (number->number_size >= 2) {
switch (number->number[1]) {
- default:
- break;
case 'x':
case 'X':
/* The number is a json_parse_flags_allow_hexadecimal_numbers