From 185fb8a2dc7fc2a151d761681f1d1d114c2107fe Mon Sep 17 00:00:00 2001 From: Jeff Harris Date: Thu, 3 Sep 2020 00:35:15 -0700 Subject: [PATCH] Feature/mainmenu (#35) * rendering main menu --- .gitignore | 1 + Makefile | 2 +- src/BRSRC13/CORE/FW/devsetup.c | 2 +- src/BRSRC13/CORE/FW/image.c | 2 +- src/BRSRC13/CORE/FW/sys_conf.c | 2 +- src/BRSRC13/CORE/FW/token.c | 2 +- src/BRSRC13/CORE/FW/tokenval.c | 2 +- src/BRSRC13/CORE/HOST/himage.c | 2 +- src/BRSRC13/CORE/V1DB/dbsetup.c | 2 +- src/BRSRC13/CORE/V1DB/enables.c | 2 +- src/BRSRC13/brender.h | 1 + src/DETHRACE/common/controls.c | 115 +++- src/DETHRACE/common/depth.c | 2 +- src/DETHRACE/common/drmem.c | 10 +- src/DETHRACE/common/flicplay.c | 1066 ++++++++++++++++++++++++++++- src/DETHRACE/common/flicplay.h | 2 + src/DETHRACE/common/globvars.c | 2 +- src/DETHRACE/common/graphics.c | 30 +- src/DETHRACE/common/init.c | 4 +- src/DETHRACE/common/input.c | 52 +- src/DETHRACE/common/intrface.c | 477 ++++++++++++- src/DETHRACE/common/loading.c | 81 ++- src/DETHRACE/common/loadsave.c | 4 +- src/DETHRACE/common/loadsave.h | 3 +- src/DETHRACE/common/main.c | 36 +- src/DETHRACE/common/mainmenu.c | 388 ++++++++++- src/DETHRACE/common/network.c | 19 +- src/DETHRACE/common/newgame.c | 2 +- src/DETHRACE/common/powerup.c | 6 +- src/DETHRACE/common/sound.c | 12 +- src/DETHRACE/common/utility.c | 31 +- src/DETHRACE/constants.h | 246 +++++++ src/DETHRACE/dr_types.h | 1 + src/DETHRACE/pc-dos/dossys.c | 11 +- src/harness/debug.h | 5 + src/harness/harness.c | 8 +- src/harness/harness.h | 1 + src/harness/input/keyboard.c | 4 +- src/harness/stack_trace_handler.h | 20 +- test/DETHRACE/test_flicplay.c | 37 + test/DETHRACE/test_loading.c | 32 + test/DETHRACE/test_utility.c | 8 + test/main.c | 2 + tools/add_enum_values.py | 18 + tools/comment_struct.py | 48 ++ tools/keymap_to_keycode.py | 18 + 46 files changed, 2654 insertions(+), 167 deletions(-) create mode 100644 src/DETHRACE/constants.h create mode 100644 test/DETHRACE/test_flicplay.c create mode 100755 tools/add_enum_values.py create mode 100755 tools/comment_struct.py create mode 100755 tools/keymap_to_keycode.py diff --git a/.gitignore b/.gitignore index d76b74e5..1856c95a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build .DS_Store +.vscode diff --git a/Makefile b/Makefile index 867f555e..b5eee2ce 100644 --- a/Makefile +++ b/Makefile @@ -28,4 +28,4 @@ install-deps: sudo apt-get install libsdl2-dev run: build - @src/DETHRACE/build/c1 -lomem + @src/DETHRACE/build/c1 -nocutscenes diff --git a/src/BRSRC13/CORE/FW/devsetup.c b/src/BRSRC13/CORE/FW/devsetup.c index 0593a960..ff60a969 100644 --- a/src/BRSRC13/CORE/FW/devsetup.c +++ b/src/BRSRC13/CORE/FW/devsetup.c @@ -79,7 +79,7 @@ void BrDevPaletteSetOld(br_pixelmap* pm) { // Offset: 2069 // Size: 61 void BrDevPaletteSetEntryOld(int i, br_colour colour) { - NOT_IMPLEMENTED(); + Harness_Hook_BrDevPaletteSetEntryOld(i, colour); } // Offset: 2153 diff --git a/src/BRSRC13/CORE/FW/image.c b/src/BRSRC13/CORE/FW/image.c index b3f786d2..3c90da4f 100644 --- a/src/BRSRC13/CORE/FW/image.c +++ b/src/BRSRC13/CORE/FW/image.c @@ -6,7 +6,7 @@ char rscid[50]; // Offset: 11 // Size: 58 br_boolean BrImageAdd(br_image* img) { - LOG_WARN("Not implemented"); + STUB(); } // Offset: 83 diff --git a/src/BRSRC13/CORE/FW/sys_conf.c b/src/BRSRC13/CORE/FW/sys_conf.c index ac7cf44b..a413499b 100644 --- a/src/BRSRC13/CORE/FW/sys_conf.c +++ b/src/BRSRC13/CORE/FW/sys_conf.c @@ -74,7 +74,7 @@ br_error BrSetDefaultConfig(br_token t, char* Entry) { br_error BrSystemConfigBegin() { char temp[255]; br_value v; - LOG_WARN("Not implemented"); + STUB(); } // Offset: 1472 diff --git a/src/BRSRC13/CORE/FW/token.c b/src/BRSRC13/CORE/FW/token.c index 2600d099..47999ad5 100644 --- a/src/BRSRC13/CORE/FW/token.c +++ b/src/BRSRC13/CORE/FW/token.c @@ -8,7 +8,7 @@ token_type tokenTypes[37]; // Offset: 13 // Size: 112 void BrTokenBegin() { - LOG_WARN("Not implemented"); + STUB(); } // Offset: 139 diff --git a/src/BRSRC13/CORE/FW/tokenval.c b/src/BRSRC13/CORE/FW/tokenval.c index 7d2ae622..5954672f 100644 --- a/src/BRSRC13/CORE/FW/tokenval.c +++ b/src/BRSRC13/CORE/FW/tokenval.c @@ -184,7 +184,7 @@ br_error BrTokenValueSetMany(void* mem, br_int_32* pcount, br_uint_32* pcombined br_int_32 n; br_error r; br_uint_32 cm; - LOG_WARN("Not implemented"); + STUB(); } // Offset: 6409 diff --git a/src/BRSRC13/CORE/HOST/himage.c b/src/BRSRC13/CORE/HOST/himage.c index ebe48726..10b27bfe 100644 --- a/src/BRSRC13/CORE/HOST/himage.c +++ b/src/BRSRC13/CORE/HOST/himage.c @@ -4,7 +4,7 @@ // Offset: 14 // Size: 40 void* HostImageLoad(char* name) { - LOG_WARN("Not implemented"); + STUB(); } // Offset: 70 diff --git a/src/BRSRC13/CORE/V1DB/dbsetup.c b/src/BRSRC13/CORE/V1DB/dbsetup.c index abb3171e..0023846b 100644 --- a/src/BRSRC13/CORE/V1DB/dbsetup.c +++ b/src/BRSRC13/CORE/V1DB/dbsetup.c @@ -147,7 +147,7 @@ br_error BrV1dbRendererEnd() { // Size: 94 void BrZbBegin(br_uint_8 colour_type, br_uint_8 depth_type) { LOG_TRACE("(%d, %d)", colour_type, depth_type); - LOG_WARN("Not implemented"); + STUB(); } // Offset: 2133 diff --git a/src/BRSRC13/CORE/V1DB/enables.c b/src/BRSRC13/CORE/V1DB/enables.c index c1bbfdb6..5c3e89b9 100644 --- a/src/BRSRC13/CORE/V1DB/enables.c +++ b/src/BRSRC13/CORE/V1DB/enables.c @@ -20,7 +20,7 @@ void actorEnable(br_v1db_enable* e, br_actor* a) { // EDX: a void actorDisable(br_v1db_enable* e, br_actor* a) { int i; - LOG_WARN("Not implemented"); + STUB(); } // Offset: 525 diff --git a/src/BRSRC13/brender.h b/src/BRSRC13/brender.h index 69afa468..ab7b8281 100644 --- a/src/BRSRC13/brender.h +++ b/src/BRSRC13/brender.h @@ -28,6 +28,7 @@ extern struct br_font* BrFontProp7x9; br_pixelmap* BrPixelmapLoad(char* filename); br_uint_32 BrPixelmapLoadMany(char* filename, br_pixelmap** pixelmaps, br_uint_16 num); void BrDevPaletteSetOld(br_pixelmap* pm); +void BrDevPaletteSetEntryOld(int i, br_colour colour); void* BrMemAllocate(br_size_t size, br_uint_8 type); void* BrMemCalloc(int nelems, br_size_t size, br_uint_8 type); br_model* BrModelAllocate(char* name, int nvertices, int nfaces); diff --git a/src/DETHRACE/common/controls.c b/src/DETHRACE/common/controls.c index 7bfb2244..22c5e208 100644 --- a/src/DETHRACE/common/controls.c +++ b/src/DETHRACE/common/controls.c @@ -1,11 +1,20 @@ #include "controls.h" -#include "common/displays.h" -#include "common/globvars.h" -#include "common/graphics.h" +#include "car.h" +#include "displays.h" +#include "flicplay.h" +#include "globvars.h" +#include "graphics.h" #include "input.h" +#include "loadsave.h" +#include "mainloop.h" +#include "netgame.h" #include "pc-dos/dossys.h" +#include "pedestrn.h" +#include "pratcam.h" #include "sound.h" +#include "structur.h" +#include "utility.h" #include tCheat gKev_keys[44] = { @@ -56,7 +65,52 @@ tCheat gKev_keys[44] = { char* gAbuse_text[10]; tEdit_func* gEdit_funcs[10][18][8]; char* gEdit_mode_names[10]; -tToggle_element gToggle_array[43]; +tToggle_element _gToggle_array[] = { + { 34, -2, 1, 1, 0, ConcussMe }, + { 56, -2, 1, 1, 0, ToggleMap }, + { 35, -2, 1, 1, 0, TogglePratcam }, + { 59, -2, 1, 1, 0, SetRecovery }, + { 4, 7, 1, 1, 0, AbortRace }, + { 45, -2, 1, 1, 0, ToggleMirror }, + { 50, -2, 1, 1, 0, LookLeft }, + { 51, -2, 1, 1, 0, LookRight }, + { 52, -2, 1, 1, 0, DamageTest }, + { 36, -2, 0, 1, 0, ToggleSoundEnable }, + { 5, 8, 0, 1, 0, PrintScreen }, + //{ 9, 7, 1, 1, 0, locret_1EF00 }, + { 10, 7, 1, 1, 0, ToggleFlying }, + { 54, -2, 1, 1, 0, TogglePedestrians }, + { 17, -2, 0, 0, 0, F4Key }, + { 18, -2, 1, 0, 0, F5Key }, + { 19, -2, 1, 0, 0, F6Key }, + { 20, -2, 1, 0, 0, F7Key }, + { 21, -2, 1, 0, 0, F8Key }, + { 22, -2, 1, 0, 0, F10Key }, + { 23, -2, 1, 0, 0, F11Key }, + { 24, -2, 1, 0, 0, F12Key }, + { 14, -2, 1, 0, 0, NumberKey0 }, + { 37, -2, 1, 0, 0, NumberKey1 }, + { 38, -2, 1, 0, 0, NumberKey2 }, + { 39, -2, 1, 0, 0, NumberKey3 }, + { 40, -2, 1, 0, 0, NumberKey4 }, + { 41, -2, 1, 0, 0, NumberKey5 }, + { 42, -2, 1, 0, 0, NumberKey6 }, + { 43, -2, 1, 0, 0, NumberKey7 }, + { 15, -2, 1, 0, 0, NumberKey8 }, + { 16, -2, 1, 0, 0, NumberKey9 }, + { 60, -2, 1, 0, 0, ScreenLarger }, + { 61, -2, 1, 0, 0, ScreenSmaller }, + { 62, -2, 1, 0, 0, BuyArmour }, + { 63, -2, 1, 0, 0, BuyPower }, + { 64, -2, 1, 0, 0, BuyOffense }, + { 65, -2, 1, 0, 0, ViewNetPlayer }, + { 66, -2, 1, 0, 0, UserSendMessage }, + //{ 25, -2, 1, 1, 0, locret_2CDB4 }, + { 26, -2, 1, 1, 0, ToggleInfo }, + { 26, 8, 1, 1, 0, ToggleInfo }, + { 26, 7, 1, 1, 0, ToggleInfo } +}; + char gString[84]; int gToo_late; int gAllow_car_flying; @@ -460,8 +514,43 @@ void CheckHelp() { // Offset: 4644 // Size: 313 void CheckLoadSave() { + int save_load_allowed; int switched_res; - NOT_IMPLEMENTED(); + LOG_TRACE8("()"); + + save_load_allowed = !gProgram_state.saving && !gProgram_state.loading && gProgram_state.prog_status == eProg_game_ongoing && !gProgram_state.dont_save_or_load; + + if (CmdKeyDown(KEYMAP_F2, KEYMAP_S)) { + if (save_load_allowed) { + FadePaletteDown(); + ClearEntireScreen(); + if (gProgram_state.racing) { + GoingToInterfaceFromRace(); + } + DoSaveGame(gProgram_state.racing == 0); + if (gProgram_state.racing) { + GoingBackToRaceFromInterface(); + } + } + WaitForNoKeys(); + } + if (CmdKeyDown(KEYMAP_F3, KEYMAP_L)) { + if (save_load_allowed && !gProgram_state.dont_load) { + FadePaletteDown(); + ClearEntireScreen(); + if (gProgram_state.racing) { + GoingToInterfaceFromRace(); + } + if (DoLoadGame() && !gProgram_state.racing) { + gProgram_state.prog_status = eProg_game_starting; + } + if (gProgram_state.racing) { + GoingBackToRaceFromInterface(); + } + PlayFlicsFromMemory(); + } + WaitForNoKeys(); + } } // Offset: 4960 @@ -470,7 +559,7 @@ void CheckLoadSave() { void CheckToggles(int pRacing) { int i; int new_state; - NOT_IMPLEMENTED(); + SILENT_STUB(); } // Offset: 5324 @@ -635,7 +724,7 @@ void FlipUpCar(tCar_spec* car) { // EAX: pNum void GetPowerup(int pNum) { _unittest_controls_lastGetPowerup = pNum; - LOG_WARN("Not implemented"); + STUB(); } // Offset: 12604 @@ -644,7 +733,17 @@ void GetPowerup(int pNum) { void CheckSystemKeys(int pRacing) { tU32 start_menu_time; int i; - NOT_IMPLEMENTED(); + + start_menu_time = PDGetTotalTime(); + CheckQuit(); + if (!gAction_replay_mode) { + CheckLoadSave(); + } + AddLostTime(PDGetTotalTime() - start_menu_time); + CheckToggles(pRacing); + if (pRacing & !gAction_replay_mode) { + CheckOtherRacingKeys(); + } } // Offset: 12716 diff --git a/src/DETHRACE/common/depth.c b/src/DETHRACE/common/depth.c index 8bbbcba4..cd919b53 100644 --- a/src/DETHRACE/common/depth.c +++ b/src/DETHRACE/common/depth.c @@ -175,7 +175,7 @@ void LoadDepthTable(char* pName, br_pixelmap** pTable, int* pPower) { void InitDepthEffects() { int i; int j; - LOG_WARN("skipping"); + STUB(); } // Offset: 4732 diff --git a/src/DETHRACE/common/drmem.c b/src/DETHRACE/common/drmem.c index 9edfca3f..ff615b34 100644 --- a/src/DETHRACE/common/drmem.c +++ b/src/DETHRACE/common/drmem.c @@ -250,11 +250,10 @@ char* gMem_names[247] = { "kMem_DOS_HMI_file_open", "kMem_abuse_text", "kMem_action_replay_buffer", - "kMem_misc", - "Unable to support this screen depth setting" + "kMem_misc" }; -int gNon_fatal_allocation_errors; +int gNon_fatal_allocation_errors = 0; br_allocator gAllocator = { "Death Race", DRStdlibAllocate, DRStdlibFree, DRStdlibInquire, Claim4ByteAlignment }; // Offset: 0 @@ -272,7 +271,7 @@ void ResetNonFatalAllocationErrors() { // Offset: 88 // Size: 68 int AllocationErrorsAreFatal() { - NOT_IMPLEMENTED(); + return gNon_fatal_allocation_errors == 0; } // Offset: 156 @@ -338,7 +337,8 @@ void InstallDRMemCalls() { // Size: 59 // EAX: pPtr void MAMSUnlock(void** pPtr) { - NOT_IMPLEMENTED(); + free(*pPtr); + *pPtr = NULL; } // Offset: 632 diff --git a/src/DETHRACE/common/flicplay.c b/src/DETHRACE/common/flicplay.c index 476b6f44..f1bbe228 100644 --- a/src/DETHRACE/common/flicplay.c +++ b/src/DETHRACE/common/flicplay.c @@ -1,13 +1,365 @@ #include "flicplay.h" #include "brender.h" -#include "common/utility.h" +#include "drmem.h" +#include "errors.h" +#include "globvars.h" +#include "graphics.h" +#include "input.h" +#include "loading.h" +#include "main.h" +#include "pc-dos/dossys.h" +#include "sound.h" +#include "utility.h" #include +#include -tFlic_bunch gFlic_bunch[9]; int gFlic_bunch8[16]; int gFlic_bunch4[22]; int gFlic_bunch2[8]; -tFlic_spec gMain_flic_list[372]; + +tFlic_spec gMain_flic_list[372] = { + { "xxxxxxxx.FLI", 1, 0, 0, 0, 0, 25, NULL, 0u }, + { "DEMSTRT2.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "DEMSTRT1.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "GOTOFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "ENDFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "OVERFLIC.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "DEMO8.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "COMPLETE.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "DEMOEND.FLI", 1, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "MAINCNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINCNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINCNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINABFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINABGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINQTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINQTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINSVFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINSVGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINLDFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINLDGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINRCFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINRCGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINARFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINOPFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINOPGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2COME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2AWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINRCGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAINARGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SVVYSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SVVYAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "BGBUTTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "BGBUTTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SVVYOKIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CANBUTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SAVECOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SAVEAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "SMLBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SMLBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SMLBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SMLBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SAVECAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NRACCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NRACAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCARCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NSUMSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NSUMAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPTAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPTDEIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "LOADSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "LOADCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "LOADAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "LOADHIFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "LOADHIGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "NEWGHLFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGHLGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGDNAV.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGDNGY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGDNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGDNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGDNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWGCAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWNSTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWNSTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWNSTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHCKBXFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHCKBXGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHCKBXON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHCKBXOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NEWNAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "NETTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NETTAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NETOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NETOAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NETNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NETNAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "NOPT04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILL1FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILL1GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILLIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILL2FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILL2GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILL3FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SKILL3GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHOAWAY.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHOOPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "ERRRSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT07GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "QUT1STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "QUT2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "QUT3STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT07FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT08GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "QUITOKIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT08FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT09GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT09FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT10GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OPTNCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OPTNAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "NOPT10FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT11GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OPTNSNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OPTNCNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OPTNGRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OPTNMSIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NOPT11FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SNDOCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SNDOAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "DNEBUTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SNDOOLFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SNDOOLGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPHCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPHAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "NCHO00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "CNTLDNIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLCAIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLDFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLMRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLDNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLDNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTLSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OTHRCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "OTHRAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "NCHO00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NCHO06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "STRTSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "STRTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "STRTAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "CNTL00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CNTL00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "STRTCRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "STRTPSIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "STRTSRIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "STRTCCIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NTSHSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NTSCSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NTSHSTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NTSHENIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NTSCLVIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NTSHSTEN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "NTSXSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "VWSC2IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "VWIN2OPP.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "VWOPP2SC.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "2BUTONFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "2BUTONGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "VWOPUPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "VWOPDWFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "VWOPDWGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "VWOPDWIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHRCCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHRCAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHCRCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "CHCRAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "GRPH00GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH01GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH02GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH03GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH04GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH05GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH06GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH07GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH08GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH09GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH10GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH11GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTARIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTPFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTOFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTEXIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTSPIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTARGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTPFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PARTOFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH00FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH01FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH02FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH03FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH04FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH05FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH06FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH07FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH08FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH09FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH10FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRPH11FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PSRMCOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PSRMAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "PSRMDIIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTOF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "RADBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRIDSTIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRIDAWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { "GRIDLFFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRIDLFGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRIDLFIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRIDRTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRIDRTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "GRIDRTIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "DARECOME.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "DAREACIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "DARECHIN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SUM1STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SUM1AWAY.FLI", 0, 1, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "SUM2STIL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "BGBUT8GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "BGBUT8FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "DNBUT8IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "BKBUT8IN.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "BKBUTOFF.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "BKBUTON.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { NULL, 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2QTFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2QTGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2LDFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2LDGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2N1FL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2N1GL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2NNFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2NNGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2OPFL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u }, + { "MAI2OPGL.FLI", 0, 0, 0, 0, 0, 0, NULL, 0u } +}; + tU32 gPanel_flic_data_length[2]; tU32 gLast_panel_frame_time[2]; tU8* gPanel_flic_data[2]; @@ -19,10 +371,40 @@ int gFlic_bunch6[51]; int gFlic_bunch7[7]; int gFlic_bunch5[5]; int gFlic_bunch3[13]; -int gFlic_bunch0[29]; +int gFlic_bunch0[29] = { + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 35, + 26, + 27, + 36, + 28, + 29, + 130, + 131, + 132, + 42, + 43, + 135, + 45 +}; int gFlic_bunch1[31]; tU32 gSound_time; -int gTrans_enabled; +int gTrans_enabled = 1; int gPanel_flic_disable; int gDark_mode; int gPending_pending_flic; @@ -30,7 +412,7 @@ int gTransparency_on; int gSound_ID; int gPlay_from_disk = 0; int gTranslation_count; -int gPending_flic; +int gPending_flic = -1; tDR_font* gTrans_fonts[15]; int gPalette_fuck_prevention; tTranslation_record* gTranslations; @@ -40,6 +422,18 @@ int gPalette_allocate_count; tFlic_descriptor* gFirst_flic; char gLast_flic_name[14]; +tFlic_bunch gFlic_bunch[9] = { + { 29, gFlic_bunch0 }, + { 31, gFlic_bunch1 }, + { 8, gFlic_bunch2 }, + { 13, gFlic_bunch3 }, + { 22, gFlic_bunch4 }, + { 5, gFlic_bunch5 }, + { 51, gFlic_bunch6 }, + { 7, gFlic_bunch7 }, + { 16, gFlic_bunch8 } +}; + // Offset: 0 // Size: 44 void EnableTranslationText() { @@ -111,7 +505,7 @@ void PlayFlicsFromDisk() { // Offset: 508 // Size: 44 void PlayFlicsFromMemory() { - NOT_IMPLEMENTED(); + gPlay_from_disk = 0; } // Offset: 552 @@ -143,7 +537,7 @@ int GetPanelFlicFrameIndex(int pIndex) { // Size: 91 void FlicPaletteAllocate() { LOG_TRACE("()"); - gPalette_pixels = BrMemAllocate(0x400u, 0x8Fu); + gPalette_pixels = BrMemAllocate(0x400u, kMem_flic_pal); gPalette = DRPixelmapAllocate(BR_PMT_RGBX_888, 1, 256, gPalette_pixels, 0); } @@ -166,7 +560,88 @@ int StartFlic(char* pFile_name, int pIndex, tFlic_descriptor_ptr pFlic_info, tU3 tU16 magic_number; tPath_name the_path; int total_size; - NOT_IMPLEMENTED(); + LOG_TRACE("(\"%s\", %d, %p, %u, %p, %p, %d, %d, %d)", pFile_name, pIndex, pFlic_info, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, pFrame_rate); + + if (gPlay_from_disk) { + PathCat(the_path, gApplication_path, "ANIM"); + PathCat(the_path, the_path, pFile_name); + pFlic_info->f = DRfopen(the_path, "rb"); + + if (!pFlic_info->f) { + FatalError(13, pFile_name); + } + total_size = GetFileLength(pFlic_info->f); + if (total_size >= 75000) { + pFlic_info->bytes_in_buffer = 75000; + } else { + pFlic_info->bytes_in_buffer = total_size; + } + if (!pFlic_info->data_start) { + pFlic_info->data_start = BrMemAllocate(pFlic_info->bytes_in_buffer, kMem_flic_data); + } + + pFlic_info->data = pFlic_info->data_start; + strcpy(gLast_flic_name, pFile_name); + fread(pFlic_info->data_start, 1u, pFlic_info->bytes_in_buffer, pFlic_info->f); + pFlic_info->bytes_still_to_be_read = total_size - pFlic_info->bytes_in_buffer; + } else { + pFlic_info->f = NULL; + pFlic_info->data = (char*)pData_ptr; + //TOOD: remove this - we added this line because of the padding hack in PlayNextFlicFrame2 + pFlic_info->data_start = (char*)pData_ptr; + } + pFlic_info->bytes_remaining = MemReadU32(&pFlic_info->data); + magic_number = MemReadU16(&pFlic_info->data); + if (magic_number == 0xAF11) { + pFlic_info->new_format = 0; + } else if (magic_number == 0xAF12) { + pFlic_info->new_format = 1; + } else { + return -1; + } + + pFlic_info->frames_left = MemReadU16(&pFlic_info->data); + pFlic_info->current_frame = 0; + pFlic_info->width = MemReadU16(&pFlic_info->data); + pFlic_info->height = MemReadU16(&pFlic_info->data); + if (MemReadU16(&pFlic_info->data) != 8) { + FatalError(15, gLast_flic_name); + } + MemSkipBytes(&pFlic_info->data, 2); + claimed_speed = MemReadU16(&pFlic_info->data); + MemSkipBytes(&pFlic_info->data, 0x6e); + pFlic_info->the_pixelmap = pDest_pixelmap; + + if (pX_offset == -1) { + pFlic_info->x_offset = (pDest_pixelmap->width - pFlic_info->width) / 2; + } else { + pFlic_info->x_offset = pX_offset; + } + if (pY_offset == -1) { + pFlic_info->y_offset = (pDest_pixelmap->height - pFlic_info->height) / 2; + } else { + pFlic_info->y_offset = pY_offset; + } + + if (pFrame_rate) { + pFlic_info->frame_period = 1000 / pFrame_rate; + } else { + if (!claimed_speed) { + FatalError(16, gLast_flic_name); + } + if (pFlic_info->new_format) { + pFlic_info->frame_period = claimed_speed; + } else { + pFlic_info->frame_period = 14 * claimed_speed; + } + } + pFlic_info->the_index = pIndex; + if (pDest_pixelmap) { + pFlic_info->first_pixel = pDest_pixelmap->pixels + pDest_pixelmap->row_bytes * pFlic_info->y_offset + pFlic_info->x_offset; + } + //LOG_DEBUG("first pixel %p %p", pFlic_info->first_pixel, pDest_pixelmap->pixels); + pFlic_info->the_pixelmap = pDest_pixelmap; + return 0; } // Offset: 1720 @@ -192,12 +667,38 @@ void DoColourMap(tFlic_descriptor_ptr pFlic_info, tU32 chunk_length) { int packet_count; int skip_count; int change_count; - int current_colour; + int current_colour = 0; tU8* palette_pixels; tU8 red; tU8 green; tU8 blue; - NOT_IMPLEMENTED(); + + palette_pixels = gPalette_pixels; + + packet_count = MemReadU16(&pFlic_info->data); + for (i = 0; i < packet_count; i++) { + skip_count = MemReadU8(&pFlic_info->data); + change_count = MemReadU8(&pFlic_info->data); + if (!change_count) { + change_count = 256; + } + palette_pixels += skip_count * sizeof(br_int_32); + current_colour += skip_count; + for (j = 0; j < change_count; j++) { + red = MemReadU8(&pFlic_info->data); + blue = MemReadU8(&pFlic_info->data); + green = MemReadU8(&pFlic_info->data); + //argb + palette_pixels[0] = green * 4; + palette_pixels[1] = blue * 4; + palette_pixels[2] = red * 4; + palette_pixels[3] = 0; + palette_pixels += 4; + } + if (!gPalette_fuck_prevention) { + DRSetPaletteEntries(gPalette, current_colour, change_count); + } + } } // Offset: 2248 @@ -250,12 +751,39 @@ void DoColour256(tFlic_descriptor* pFlic_info, tU32 chunk_length) { int packet_count; int skip_count; int change_count; - int current_colour; + int current_colour = 0; tU8* palette_pixels; tU8 red; tU8 green; tU8 blue; - NOT_IMPLEMENTED(); + + palette_pixels = gPalette_pixels; + + packet_count = MemReadU16(&pFlic_info->data); + for (i = 0; i < packet_count; i++) { + skip_count = MemReadU8(&pFlic_info->data); + change_count = MemReadU8(&pFlic_info->data); + if (!change_count) { + change_count = 256; + } + palette_pixels += skip_count * sizeof(br_int_32); + current_colour += skip_count; + for (j = 0; j < change_count; j++) { + red = MemReadU8(&pFlic_info->data); + blue = MemReadU8(&pFlic_info->data); + green = MemReadU8(&pFlic_info->data); + //argb + palette_pixels[0] = green; + palette_pixels[1] = blue; + palette_pixels[2] = red; + palette_pixels[3] = 0; + palette_pixels += 4; + //LOG_DEBUG("color %d", current_colour); + } + if (!gPalette_fuck_prevention) { + DRSetPaletteEntries(gPalette, current_colour, change_count); + } + } } // Offset: 3276 @@ -276,7 +804,46 @@ void DoDeltaTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) { tU32 the_row_bytes; tU16* line_pixel_ptr; tU16 the_word; - NOT_IMPLEMENTED(); + LOG_TRACE("(%p, %d)", pFlic_info, chunk_length); + + line_count = MemReadU16(&pFlic_info->data); + the_row_bytes = pFlic_info->the_pixelmap->row_bytes; + pixel_ptr = pFlic_info->first_pixel; + + for (i = 0; i < line_count;) { + number_of_packets = MemReadS16(&pFlic_info->data); + line_pixel_ptr = (tU16*)pixel_ptr; + + if (number_of_packets < 0) { + pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets; + } else { + for (j = 0; j < number_of_packets; j++) { + skip_count = MemReadU8(&pFlic_info->data); + size_count = MemReadS8(&pFlic_info->data); + line_pixel_ptr += skip_count / 2; + if (size_count < 0) { + the_word = *(tU16*)pFlic_info->data; + pFlic_info->data += 2; + the_byte = the_word & 0xff; + the_byte2 = the_word >> 8 & 0xff; + + for (k = 0; k < -size_count; k++) { + *line_pixel_ptr = the_word; + line_pixel_ptr++; + } + } else { + for (k = 0; k < size_count; k++) { + the_word = *(tU16*)pFlic_info->data; + pFlic_info->data += 2; + *line_pixel_ptr = the_word; + line_pixel_ptr++; + } + } + } + pixel_ptr = pixel_ptr + the_row_bytes; + i++; + } + } } // Offset: 3816 @@ -295,7 +862,43 @@ void DoDeltaX(tFlic_descriptor* pFlic_info, tU32 chunk_length) { tU32 the_row_bytes; tU16* line_pixel_ptr; tU16 the_word; - NOT_IMPLEMENTED(); + LOG_TRACE("(%p, %d)", pFlic_info, chunk_length); + + line_count = MemReadU16(&pFlic_info->data); + the_row_bytes = pFlic_info->the_pixelmap->row_bytes; + pixel_ptr = pFlic_info->first_pixel; + + for (i = 0; i < line_count;) { + number_of_packets = MemReadS16(&pFlic_info->data); + line_pixel_ptr = (tU16*)pixel_ptr; + + if (number_of_packets < 0) { + pixel_ptr = pixel_ptr + the_row_bytes * -number_of_packets; + } else { + for (j = 0; j < number_of_packets; j++) { + skip_count = MemReadU8(&pFlic_info->data); + size_count = MemReadS8(&pFlic_info->data); + line_pixel_ptr += skip_count / 2; + if (size_count < 0) { + the_word = *(tU16*)pFlic_info->data; + pFlic_info->data += 2; + for (k = 0; k < -size_count; k++) { + *line_pixel_ptr = the_word; + line_pixel_ptr++; + } + } else { + for (k = 0; k < size_count; k++) { + the_word = *(tU16*)pFlic_info->data; + pFlic_info->data += 2; + *line_pixel_ptr = the_word; + line_pixel_ptr++; + } + } + } + pixel_ptr = pixel_ptr + the_row_bytes; + i++; + } + } } // Offset: 4172 @@ -309,6 +912,7 @@ void DoBlack(tFlic_descriptor* pFlic_info, tU32 chunk_length) { tU8* pixel_ptr; tU32 the_row_bytes; tU32* line_pixel_ptr; + LOG_TRACE("(%p, %d)", pFlic_info, chunk_length); NOT_IMPLEMENTED(); } @@ -326,7 +930,32 @@ void DoRunLengthX(tFlic_descriptor* pFlic_info, tU32 chunk_length) { tU8* line_pixel_ptr; tU8 the_byte; tU32 the_row_bytes; - NOT_IMPLEMENTED(); + LOG_TRACE("(%p, %d)", pFlic_info, chunk_length); + + the_row_bytes = pFlic_info->the_pixelmap->row_bytes; + pixel_ptr = pFlic_info->first_pixel; + + for (i = 0; i < pFlic_info->height; i++) { + line_pixel_ptr = pixel_ptr; + number_of_packets = MemReadU8(&pFlic_info->data); + for (j = 0; j < number_of_packets; j++) { + size_count = MemReadS8(&pFlic_info->data); + if (size_count >= 0) { + the_byte = MemReadU8(&pFlic_info->data); + for (k = 0; k < size_count; k++) { + *line_pixel_ptr = the_byte; + line_pixel_ptr++; + } + } else { + for (k = 0; k < -size_count; k++) { + the_byte = MemReadU8(&pFlic_info->data); + *line_pixel_ptr = the_byte; + line_pixel_ptr++; + } + } + } + pixel_ptr += the_row_bytes; + } } // Offset: 4600 @@ -343,7 +972,36 @@ void DoRunLengthTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) { tU8* line_pixel_ptr; tU8 the_byte; tU32 the_row_bytes; - NOT_IMPLEMENTED(); + LOG_TRACE("(%p, %d)", pFlic_info, chunk_length); + + the_row_bytes = pFlic_info->the_pixelmap->row_bytes; + pixel_ptr = pFlic_info->first_pixel; + + for (i = 0; i < pFlic_info->height; i++) { + line_pixel_ptr = pixel_ptr; + number_of_packets = MemReadU8(&pFlic_info->data); + for (j = 0; j < number_of_packets; j++) { + size_count = MemReadS8(&pFlic_info->data); + if (size_count >= 0) { + the_byte = MemReadU8(&pFlic_info->data); + if (the_byte) { + for (k = 0; k < size_count; k++) { + *line_pixel_ptr = the_byte; + line_pixel_ptr++; + } + } + } else { + for (k = 0; k < -size_count; k++) { + the_byte = MemReadU8(&pFlic_info->data); + if (the_byte) { + *line_pixel_ptr = the_byte; + line_pixel_ptr++; + } + } + } + } + pixel_ptr += the_row_bytes; + } } // Offset: 4912 @@ -357,6 +1015,7 @@ void DoUncompressed(tFlic_descriptor* pFlic_info, tU32 chunk_length) { tU8* pixel_ptr; tU32 the_row_bytes; tU32* line_pixel_ptr; + LOG_TRACE("(%p, %d)", pFlic_info, chunk_length); NOT_IMPLEMENTED(); } @@ -372,6 +1031,7 @@ void DoUncompressedTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) { tU8* line_pixel_ptr; tU8 the_byte; tU32 the_row_bytes; + LOG_TRACE("(%p, %d)", pFlic_info, chunk_length); NOT_IMPLEMENTED(); } @@ -410,7 +1070,96 @@ int PlayNextFlicFrame2(tFlic_descriptor* pFlic_info, int pPanel_flic) { int last_frame; int data_knocked_off; int read_amount; - NOT_IMPLEMENTED(); + + //LOG_DEBUG("%d (%p), frames left: %d offset: %d", pFlic_info->the_index, pFlic_info, pFlic_info->frames_left, (pFlic_info->data - pFlic_info->data_start) + 4); + PossibleService(); + frame_length = MemReadU32(&pFlic_info->data); + magic_bytes = MemReadU16(&pFlic_info->data); + chunk_count = MemReadU16(&pFlic_info->data); + MemSkipBytes(&pFlic_info->data, 8); + if (magic_bytes == 0xF1FA) { + for (chunk_counter = 0; chunk_counter < chunk_count; chunk_counter++) { + chunk_length = MemReadU32(&pFlic_info->data); + chunk_type = MemReadU16(&pFlic_info->data); + switch (chunk_type) { + case 4u: + DoColour256(pFlic_info, chunk_length); + break; + case 7u: + if (gTransparency_on) { + DoDeltaTrans(pFlic_info, chunk_length); + } else { + DoDeltaX(pFlic_info, chunk_length); + } + break; + case 0xBu: + DoColourMap(pFlic_info, chunk_length); + break; + case 0xCu: + if (gTransparency_on) { + DoDifferenceTrans(pFlic_info, chunk_length); + } else { + DoDifferenceX(pFlic_info, chunk_length); + } + break; + case 0xD: + DoBlack(pFlic_info, chunk_length); + break; + case 0xF: + if (gTransparency_on) { + DoRunLengthTrans(pFlic_info, chunk_length); + } else { + DoRunLengthX(pFlic_info, chunk_length); + } + break; + case 0x10u: + if (gTransparency_on) { + DoUncompressedTrans(pFlic_info, chunk_length); + } else { + DoUncompressed(pFlic_info, chunk_length); + } + break; + case 0x12u: + MemSkipBytes(&pFlic_info->data, chunk_length - 6); + break; + default: + LOG_WARN("unrecognized chunk type"); + MemSkipBytes(&pFlic_info->data, chunk_length - 6); + break; + } + //TODO: something like // p &= 0xfffffffffffffffe; + int a = (pFlic_info->data - pFlic_info->data_start); + if (a % 2 == 1) { + pFlic_info->data++; + } + } + } else { + LOG_WARN("not frame header"); + MemSkipBytes(&pFlic_info->data, frame_length - 16); + pFlic_info->frames_left++; + pFlic_info->current_frame--; + } + pFlic_info->current_frame++; + pFlic_info->frames_left--; + if (gTrans_enabled && gTranslation_count && !pPanel_flic) { + DrawTranslations(pFlic_info, pFlic_info->frames_left == 0); + } + if (pFlic_info->f && pFlic_info->bytes_still_to_be_read) { + data_knocked_off = pFlic_info->data - pFlic_info->data_start; + memcpy(pFlic_info->data_start, pFlic_info->data, pFlic_info->bytes_in_buffer - data_knocked_off); + pFlic_info->data = pFlic_info->data_start; + read_amount = pFlic_info->bytes_still_to_be_read; + pFlic_info->bytes_in_buffer -= data_knocked_off; + if (data_knocked_off < read_amount) { + read_amount = data_knocked_off; + } + if (read_amount) { + fread(&pFlic_info->data_start[pFlic_info->bytes_in_buffer], 1u, read_amount, pFlic_info->f); + } + pFlic_info->bytes_still_to_be_read -= read_amount; + pFlic_info->bytes_in_buffer = +read_amount; + } + return pFlic_info->frames_left == 0; } // Offset: 6464 @@ -432,20 +1181,68 @@ int PlayFlic(int pIndex, tU32 pSize, tS8* pData_ptr, br_pixelmap* pDest_pixelmap tU32 last_frame; tU32 new_time; tU32 frame_period; - NOT_IMPLEMENTED(); + LOG_TRACE("(%d, %u, %p, %p, %d, %d, %p, %d, %d)", pIndex, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, DoPerFrame, pInterruptable, pFrame_rate); + + finished_playing = 0; + the_flic.data_start = 0; + if (StartFlic(gMain_flic_list[pIndex].file_name, pIndex, &the_flic, pSize, pData_ptr, pDest_pixelmap, pX_offset, pY_offset, pFrame_rate)) { + LOG_WARN("startflic returned error"); + return -1; + } + while ((!pInterruptable || !AnyKeyDown()) && !finished_playing) { + new_time = PDGetTotalTime(); + frame_period = new_time - last_frame; + + if (gSound_time != 0 && new_time >= gSound_time) { + DRS3StartSound(gIndexed_outlets[0], gSound_ID); + gSound_time = 0; + } + if (frame_period >= the_flic.frame_period) { + finished_playing = PlayNextFlicFrame2(&the_flic, 0); + DoPerFrame(); + if (gDark_mode == 0) { + EnsurePaletteUp(); + } + ServiceGame(); + last_frame = new_time; + } + } + ServiceGame(); + if (the_flic.f) { + BrMemFree(pDest_pixelmap); + pDest_pixelmap = NULL; + fclose(the_flic.f); + the_flic.f = NULL; + } + if (pData_ptr) { + pData_ptr = 0; + } + return 0; } // Offset: 6816 // Size: 41 void SwapScreen() { - NOT_IMPLEMENTED(); + PDScreenBufferSwap(0); } // Offset: 6860 // Size: 154 // EAX: pIndex void ShowFlic(int pIndex) { - NOT_IMPLEMENTED(); + do { + PlayFlic( + pIndex, + gMain_flic_list[pIndex].the_size, + gMain_flic_list[pIndex].data_ptr, + gBack_screen, + gMain_flic_list[pIndex].x_offset, + gMain_flic_list[pIndex].y_offset, + SwapScreen, + gMain_flic_list[pIndex].interruptable, + gMain_flic_list[pIndex].frame_rate); + } while (gMain_flic_list[pIndex].repeat && !AnyKeyDown()); + gLast_flic_name[0] = 0; // byte_10344C; } // Offset: 7016 @@ -465,7 +1262,41 @@ int LoadFlic(int pIndex) { tPath_name the_path; FILE* f; char* the_buffer; - NOT_IMPLEMENTED(); + LOG_TRACE("(%d)", pIndex); + + if (pIndex < 0) { + return 0; + } + if (gMain_flic_list[pIndex].data_ptr) { + return 1; + } + if (gPlay_from_disk) { + gMain_flic_list[pIndex].data_ptr = NULL; + return 1; + } + PossibleService(); + PathCat(the_path, gApplication_path, "ANIM"); + PathCat(the_path, the_path, gMain_flic_list[pIndex].file_name); + f = DRfopen(the_path, "rb"); + + if (!f) { + FatalError(13, gMain_flic_list[pIndex].file_name); + } + + gMain_flic_list[pIndex].the_size = GetFileLength(f); + gMain_flic_list[pIndex].data_ptr = BrMemAllocate(gMain_flic_list[pIndex].the_size, 0x90u); + + if (gMain_flic_list[pIndex].data_ptr) { + fread(gMain_flic_list[pIndex].data_ptr, 1u, gMain_flic_list[pIndex].the_size, f); + strcpy(gLast_flic_name, gMain_flic_list[pIndex].file_name); + fclose(f); + return 1; + } else { + if (AllocationErrorsAreFatal()) { + FatalError(14, gMain_flic_list[pIndex].file_name); + } + return 0; + } } // Offset: 7488 @@ -513,7 +1344,26 @@ void RunFlicAt(int pIndex, int pX, int pY) { // Size: 117 // EAX: pIndex void RunFlic(int pIndex) { - NOT_IMPLEMENTED(); + LOG_TRACE("(%d)", pIndex); + + if (gPending_flic >= 0) { + LoadFlic(gPending_flic); + ShowFlic(gPending_flic); + UnlockFlic(gPending_flic); + gPending_flic = -1; + } + if (LoadFlic(pIndex)) { + if (gMain_flic_list[pIndex].queued) { + gPending_flic = pIndex; + } else { + ShowFlic(pIndex); + if (pIndex >= 0) { + if (gMain_flic_list[pIndex].data_ptr) { + MAMSUnlock((void**)&gMain_flic_list[pIndex].data_ptr); + } + } + } + } } // Offset: 8204 @@ -521,7 +1371,9 @@ void RunFlic(int pIndex) { // EAX: pBunch_index void PreloadBunchOfFlics(int pBunch_index) { int i; - NOT_IMPLEMENTED(); + for (i = 0; i < gFlic_bunch[pBunch_index].count; i++) { + LoadFlic(gFlic_bunch[pBunch_index].indexes[i]); + } } // Offset: 8312 @@ -543,7 +1395,7 @@ void FlushAllFlics(int pBunch_index) { // Offset: 8496 // Size: 44 void InitFlicQueue() { - NOT_IMPLEMENTED(); + gFirst_flic = NULL; } // Offset: 8540 @@ -561,7 +1413,44 @@ void ProcessFlicQueue(tU32 pInterval) { tFlic_descriptor* doomed_flic; tU32 new_time; int finished_playing; - NOT_IMPLEMENTED(); + + the_flic = gFirst_flic; + last_flic = NULL; + gPalette_fuck_prevention = 1; + gTransparency_on = 1; + new_time = PDGetTotalTime(); + while (the_flic) { + if (new_time - the_flic->last_frame < the_flic->frame_period) { + finished_playing = 0; + } else { + the_flic->last_frame = new_time; + finished_playing = PlayNextFlicFrame2(the_flic, 0); + } + if (finished_playing) { + if (the_flic->f) { + BrMemFree(the_flic->data_start); + the_flic->data_start = NULL; + fclose(the_flic->f); + the_flic->f = NULL; + } + if (the_flic->data) { + the_flic->data = NULL; + } + if (last_flic) { + last_flic->next = the_flic->next; + } else { + gFirst_flic = the_flic->next; + } + doomed_flic = the_flic; + the_flic = the_flic->next; + BrMemFree(doomed_flic); + } else { + last_flic = the_flic; + the_flic = the_flic->next; + } + } + gPalette_fuck_prevention = 0; + gTransparency_on = 0; } // Offset: 8860 @@ -578,11 +1467,67 @@ void FlushFlicQueue() { // EBX: pY // ECX: pMust_finish void AddToFlicQueue(int pIndex, int pX, int pY, int pMust_finish) { - tFlic_descriptor* the_flic; - tFlic_descriptor* new_flic; - tFlic_descriptor* last_flic; - tFlic_descriptor* doomed_flic; - NOT_IMPLEMENTED(); + tFlic_descriptor* the_flic = NULL; + tFlic_descriptor* new_flic = NULL; + tFlic_descriptor* last_flic = NULL; + tFlic_descriptor* doomed_flic = NULL; + LOG_TRACE("(%d, %d, %d, %d)", pIndex, pX, pY, pMust_finish); + + the_flic = gFirst_flic; + while (the_flic) { + if (pX == the_flic->x_offset && pY == the_flic->y_offset) { + doomed_flic = the_flic; + break; + } + last_flic = the_flic; + the_flic = the_flic->next; + } + + if (doomed_flic) { + if (doomed_flic->f) { + BrMemFree(doomed_flic->data_start); + doomed_flic->data_start = NULL; + fclose(doomed_flic->f); + doomed_flic->f = NULL; + } + if (doomed_flic->data) { + doomed_flic->data = NULL; + } + if (last_flic) { + last_flic->next = doomed_flic->next; + } else { + gFirst_flic = doomed_flic->next; + } + BrMemFree(doomed_flic); + } + + LoadFlic(pIndex); + new_flic = BrMemAllocate(sizeof(tFlic_descriptor), kMem_queued_flic); + new_flic->next = NULL; + the_flic = gFirst_flic; + if (gFirst_flic) { + while (the_flic->next) { + the_flic = the_flic->next; + } + the_flic->next = new_flic; + } else { + gFirst_flic = new_flic; + } + new_flic->last_frame = 0; + new_flic->data_start = 0; + new_flic->the_index = pIndex; + new_flic->must_finish = pMust_finish; + + StartFlic( + gMain_flic_list[pIndex].file_name, + pIndex, + new_flic, + gMain_flic_list[pIndex].the_size, + gMain_flic_list[pIndex].data_ptr, + gBack_screen, + pX >= 0 ? pX : gMain_flic_list[pIndex].x_offset, + pY >= 0 ? pY : gMain_flic_list[pIndex].y_offset, + 20); } // Offset: 9424 @@ -614,7 +1559,62 @@ void ServicePanelFlics(int pCopy_to_buffer) { int j; int iteration_count; int finished; - NOT_IMPLEMENTED(); + + if (gPanel_flic_disable) { + return; + } + the_time = PDGetTotalTime(); + gPalette_fuck_prevention = 1; + gTransparency_on = 1; + for (i = 0; i < 2; i++) { + old_last_time[i] = gLast_panel_frame_time[i]; + if (gPanel_buffer[i] && gPanel_flic[i].data) { + if (old_last_time[i]) { + time_diff = the_time - old_last_time[i]; + iteration_count = time_diff / gPanel_flic[i].frame_period; + } else { + iteration_count = 1; + } + for (j = 0; j < iteration_count; j++) { + finished = PlayNextFlicFrame2(&gPanel_flic[i], 1); + if (finished) { + if (gPanel_flic[i].f) { + BrMemFree(gPanel_flic[i].data_start); + gPanel_flic[i].data_start = NULL; + fclose(gPanel_flic[i].f); + gPanel_flic[i].f = NULL; + } + if (gPanel_flic[i].data) { + gPanel_flic[i].data = 0; + } + StartFlic( + gPanel_flic[i].file_name, + gPanel_flic[i].the_index, + &gPanel_flic[i], + gPanel_flic_data_length[i], + (tS8*)gPanel_flic_data[i], + gPanel_buffer[i], + 0, + 0, + 0); + } + gLast_panel_frame_time[i] = the_time; + } + if (pCopy_to_buffer) { + BrPixelmapRectangleCopy( + gBack_screen, + gPanel_flic_left[i], + gPanel_flic_top[i], + gPanel_buffer[i], + 0, + 0, + gPanel_buffer[i]->width, + gPanel_buffer[i]->height); + } + } + } + gTransparency_on = 0; + gPalette_fuck_prevention = 0; } // Offset: 10248 @@ -646,7 +1646,7 @@ void LoadInterfaceStrings() { int j; int len; - LOG_WARN("Not implemented"); + STUB(); } // Offset: 11948 diff --git a/src/DETHRACE/common/flicplay.h b/src/DETHRACE/common/flicplay.h index 8cb2a5cd..88b38e8c 100644 --- a/src/DETHRACE/common/flicplay.h +++ b/src/DETHRACE/common/flicplay.h @@ -4,6 +4,8 @@ #include "br_types.h" #include "dr_types.h" +extern tFlic_spec gMain_flic_list[372]; + // Offset: 0 // Size: 44 void EnableTranslationText(); diff --git a/src/DETHRACE/common/globvars.c b/src/DETHRACE/common/globvars.c index b77750ca..9e79a337 100644 --- a/src/DETHRACE/common/globvars.c +++ b/src/DETHRACE/common/globvars.c @@ -83,7 +83,7 @@ int gInitial_net_credits[5]; float gCar_cred_value[3]; int gNo_races_yet; int gDefault_engine_noise_index; -int gGame_to_load; +int gGame_to_load = -1; int gJump_start_fine[3]; int gSausage_override; int gAusterity_mode; diff --git a/src/DETHRACE/common/graphics.c b/src/DETHRACE/common/graphics.c index 3fc625d1..a90e0fa4 100644 --- a/src/DETHRACE/common/graphics.c +++ b/src/DETHRACE/common/graphics.c @@ -360,7 +360,15 @@ void ScreenLarger() { // EDX: pFirst_colour // EBX: pCount void DRSetPaletteEntries(br_pixelmap* pPalette, int pFirst_colour, int pCount) { - NOT_IMPLEMENTED(); + LOG_TRACE("(%p, %d, %d)", pPalette, pFirst_colour, pCount); + if (!pFirst_colour) { + ((br_int_32*)pPalette->pixels)[0] = 0; + } + memcpy(gCurrent_palette_pixels + 4 * pFirst_colour, pPalette->pixels + 4 * pFirst_colour, 4 * pCount); + if (!gFaded_palette) { + PDSetPaletteEntries(pPalette, pFirst_colour, pCount); + } + gPalette_munged = 1; } // Offset: 4144 @@ -402,21 +410,21 @@ void DRSetPalette(br_pixelmap* pThe_palette) { // Size: 415 void InitializePalettes() { int j; - gCurrent_palette_pixels = BrMemAllocate(0x400u, 0x96u); + gCurrent_palette_pixels = BrMemAllocate(0x400u, kMem_cur_pal_pixels); gCurrent_palette = DRPixelmapAllocate(BR_PMT_RGBX_888, 1u, 256, gCurrent_palette_pixels, 0); gRender_palette = BrTableFind("DRRENDER.PAL"); if (!gRender_palette) { FatalError(10); } gOrig_render_palette = BrPixelmapAllocateSub(gRender_palette, 0, 0, gRender_palette->width, gRender_palette->height); - gOrig_render_palette->pixels = BrMemAllocate(0x400u, 0x97u); + gOrig_render_palette->pixels = BrMemAllocate(0x400u, kMem_render_pal_pixels); memcpy(gOrig_render_palette->pixels, gRender_palette->pixels, 0x400u); gFlic_palette = BrTableFind("DRACEFLC.PAL"); if (!gFlic_palette) { FatalError(10); } DRSetPalette2(gFlic_palette, 1); - gScratch_pixels = BrMemAllocate(0x400u, 0x98u); + gScratch_pixels = BrMemAllocate(0x400u, kMem_scratch_pal_pixels); gScratch_palette = DRPixelmapAllocate(BR_PMT_RGBX_888, 1u, 256, gScratch_pixels, 0); gPalette_conversion_table = BrTableFind("FLC2REND.TAB"); gRender_shade_table = BrTableFind("DRRENDER.TAB"); @@ -879,7 +887,13 @@ void FadePaletteUp() { // Offset: 20660 // Size: 91 void KillSplashScreen() { - NOT_IMPLEMENTED(); + if (gCurrent_splash) { + BrMapRemove(gCurrent_splash); + BrPixelmapFree(gCurrent_splash); + gCurrent_splash = 0; + FadePaletteDown(); + ClearEntireScreen(); + } } // Offset: 20752 @@ -1084,7 +1098,7 @@ void DeallocateAllTransientBitmaps() { void RemoveTransientBitmaps(int pGraphically_remove_them) { int i; int order_number; - NOT_IMPLEMENTED(); + SILENT_STUB(); } // Offset: 24400 @@ -1147,7 +1161,7 @@ int DoMouseCursor() { static int required_cursor; static int zero_count; static int button_was_down; - NOT_IMPLEMENTED(); + SILENT_STUB(); } // Offset: 27508 @@ -1161,7 +1175,7 @@ int AllocateCursorTransient() { // Offset: 27696 // Size: 138 void StartMouseCursor() { - NOT_IMPLEMENTED(); + LOG_WARN("stub"); } // Offset: 27836 diff --git a/src/DETHRACE/common/init.c b/src/DETHRACE/common/init.c index a5e37cb6..210138ef 100644 --- a/src/DETHRACE/common/init.c +++ b/src/DETHRACE/common/init.c @@ -124,7 +124,7 @@ void AllocateRearviewPixelmap() { (gProgram_state.current_car.mirror_bottom - gProgram_state.current_car.mirror_top + 1) * (gProgram_state.current_car.mirror_right - gProgram_state.current_car.mirror_left + 4) * gGraf_specs[gGraf_spec_index].depth_bytes, - 0x9Au); + kMem_rear_screen_pixels); if (gScreen->row_bytes < 0) { BrFatal("..\\..\\source\\common\\init.c", 260, "Bruce bug at line %d, file ..\\..\\source\\common\\init.c", 4); } @@ -165,7 +165,7 @@ void InstallFindFailedHooks() { void AllocateStandardLamp() { br_actor* lamp; int i; - LOG_WARN("skipping"); + STUB(); } // Offset: 2152 diff --git a/src/DETHRACE/common/input.c b/src/DETHRACE/common/input.c index cb69c74b..451fd147 100644 --- a/src/DETHRACE/common/input.c +++ b/src/DETHRACE/common/input.c @@ -2,6 +2,7 @@ #include "common/globvars.h" #include "pc-dos/dossys.h" +#include "utility.h" #include tJoy_array gJoy_array; @@ -21,7 +22,7 @@ tU32 gLast_key_down_time; int gThe_length; tU32 gLast_roll; int gLast_key_down; -int gGo_ahead_keys[3]; +int gGo_ahead_keys[3] = { 51, 52, 106 }; // enter, return, space int gKey_mapping[67]; char gCurrent_typing[110]; @@ -128,7 +129,14 @@ tKey_down_result PDKeyDown2(int pKey_index) { // EAX: pKey_index int PDKeyDown(int pKey_index) { tKey_down_result result; - NOT_IMPLEMENTED(); + result = PDKeyDown2(pKey_index); + if (!gEdge_trigger_mode || pKey_index <= 10) { + return result != 0; + } + if (result != tKey_down_yes && result != tKey_down_repeat) { + return 0; + } + return 1; } // Offset: 1832 @@ -262,13 +270,43 @@ int OldKeyIsDown(int pKey_index) { // EAX: pKey_index int KeyIsDown(int pKey_index) { int i; - NOT_IMPLEMENTED(); + + if (PDGetTotalTime() - gLast_poll_keys > 500) { + ResetPollKeys(); + CyclePollKeys(); + PollKeys(); + } + if (pKey_index == -2) { + return 1; + } + if (pKey_index != -1) { + return gKey_array[gKey_mapping[pKey_index]]; + } + + for (i = 0; i < 3; i++) { + if (gKey_array[gGo_ahead_keys[i]]) { + return 1; + } + } + + return 0; } // Offset: 3008 // Size: 64 void WaitForNoKeys() { - NOT_IMPLEMENTED(); + LOG_TRACE("()"); + + int key_result = 0; //JeffH added + + while (1) { + CheckQuit(); + key_result = PDAnyKeyDown(); + if ((key_result == -1 || key_result == 4) && !EitherMouseButtonDown()) { + break; + } + } + CheckQuit(); } // Offset: 3072 @@ -282,7 +320,7 @@ void WaitForAKey() { // EAX: pFKey_ID // EDX: pCmd_key_ID int CmdKeyDown(int pFKey_ID, int pCmd_key_ID) { - NOT_IMPLEMENTED(); + return KeyIsDown(pFKey_ID) || (KeyIsDown(KEYMAP_LCTRL) && KeyIsDown(pCmd_key_ID)); } // Offset: 3244 @@ -531,11 +569,11 @@ void KillCursor(int pSlot_index) { // Offset: 7744 // Size: 44 void EdgeTriggerModeOn() { - NOT_IMPLEMENTED(); + gEdge_trigger_mode = 1; } // Offset: 7788 // Size: 44 void EdgeTriggerModeOff() { - NOT_IMPLEMENTED(); + gEdge_trigger_mode = 0; } diff --git a/src/DETHRACE/common/intrface.c b/src/DETHRACE/common/intrface.c index d1dd346d..15c6b4c6 100644 --- a/src/DETHRACE/common/intrface.c +++ b/src/DETHRACE/common/intrface.c @@ -1,4 +1,14 @@ #include "intrface.h" +#include "brender.h" +#include "flicplay.h" +#include "globvars.h" +#include "grafdata.h" +#include "graphics.h" +#include "input.h" +#include "loading.h" +#include "main.h" +#include "pc-dos/dossys.h" +#include "sound.h" #include int gDisabled_choices[10]; @@ -43,7 +53,60 @@ void ResetInterfaceTimeout() { // ECX: pMode void ChangeSelection(tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled) { int i; - NOT_IMPLEMENTED(); + LOG_TRACE("(%p, %p, %p, %d, %d)", pSpec, *pOld_selection, *pNew_selection, pMode, pSkip_disabled); + LOG_DEBUG("on entry: old: %p, new %p", pOld_selection, pNew_selection); + + for (i = 0; i < gDisabled_count; i++) { + if (*pNew_selection == gDisabled_choices[i]) { + if (pSkip_disabled) { + if (*pNew_selection <= *pOld_selection) { + + do { + (*pNew_selection)--; + if (*pNew_selection < pSpec->move_up_min[pMode]) { + *pNew_selection = pSpec->move_up_max[pMode]; + } + if (*pNew_selection > pSpec->move_up_max[pMode]) { + *pNew_selection = pSpec->move_up_min[pMode]; + } + } while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection)); + } else { + do { + (*pNew_selection)++; + if (*pNew_selection < pSpec->move_up_min[pMode]) { + *pNew_selection = pSpec->move_up_max[pMode]; + } + if (*pNew_selection > pSpec->move_up_max[pMode]) { + *pNew_selection = pSpec->move_up_min[pMode]; + } + } while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection)); + } + } else { + *pNew_selection = *pOld_selection; + } + break; + } + } + + if (*pOld_selection != *pNew_selection) { + if (*pOld_selection >= 0 && *pOld_selection < pSpec->number_of_button_flics) { + if (pSpec->flicker_off_flics[*pOld_selection].flic_index >= 0) { + AddToFlicQueue(pSpec->flicker_off_flics[*pOld_selection].flic_index, + pSpec->flicker_off_flics[*pOld_selection].x[gGraf_data_index], + pSpec->flicker_off_flics[*pOld_selection].y[gGraf_data_index], 0); + } + } + if (*pNew_selection >= 0 && *pNew_selection < pSpec->number_of_button_flics) { + if (pSpec->flicker_on_flics[*pNew_selection].flic_index >= 0) { + AddToFlicQueue(pSpec->flicker_on_flics[*pNew_selection].flic_index, + pSpec->flicker_on_flics[*pNew_selection].x[gGraf_data_index], + pSpec->flicker_on_flics[*pNew_selection].y[gGraf_data_index], 0); + } + } + LOG_DEBUG("new: %p, old %p", pNew_selection, pOld_selection); + *pOld_selection = *pNew_selection; + } + LOG_DEBUG("new: %d, old %d", *pNew_selection, *pOld_selection); } // Offset: 864 @@ -52,7 +115,19 @@ void ChangeSelection(tInterface_spec* pSpec, int* pOld_selection, int* pNew_sele // EDX: pCopy_areas void RecopyAreas(tInterface_spec* pSpec, br_pixelmap** pCopy_areas) { int i; - NOT_IMPLEMENTED(); + LOG_TRACE8("(%p, %p)", pSpec, pCopy_areas); + + for (i = 0; i < pSpec->number_of_recopy_areas; i++) { + BrPixelmapRectangleCopy( + gBack_screen, + pSpec->recopy_areas[i].left[gGraf_data_index], + pSpec->recopy_areas[i].top[gGraf_data_index], + pCopy_areas[i], + 0, + 0, + pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index], + pSpec->recopy_areas[i].bottom[gGraf_data_index] - pSpec->recopy_areas[i].top[gGraf_data_index]); + } } // Offset: 1156 @@ -77,37 +152,399 @@ void EnableChoice(int pChoice) { // EDX: pOptions // EBX: pCurrent_choice int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice) { - tProg_status entry_status; - int x_coord; - int y_coord; + tProg_status entry_status; // + int x_coord; // + int y_coord; // int mouse_in_somewhere; - int i; + int i; // int key2; int mouse_was_started; - int last_choice; - int escaped; - int timed_out; - int go_ahead; + int last_choice; // + int escaped; // + int timed_out; // + int go_ahead; // int last_mode; - int result; - int the_key; + int result; // + int the_key; // int the_max; - int mouse_down; - int new_mouse_down; + int mouse_down; // + int new_mouse_down; // int last_mouse_down; - int defeat_mode_change; - int selection_changed; + int defeat_mode_change; // + int selection_changed; // char the_str[256]; - tU32 last_press; + tU32 last_press; // tU32 last_left_press; tU32 last_right_press; tU32 last_up_press; tU32 last_down_press; - br_pixelmap** copy_areas; - br_pixelmap* old_current_splash; + br_pixelmap** copy_areas; // + br_pixelmap* old_current_splash; // void* pixels_copy; void* palette_copy; - NOT_IMPLEMENTED(); + LOG_TRACE("(%p, %d, %d)", pSpec, pOptions, pCurrent_choice); + + //added + int last_choice_2; + + entry_status = gProgram_state.prog_status; + gTyping_slot = -1; + EdgeTriggerModeOn(); + gSpec = pSpec; + gDisabled_count = 0; + LoadInterfaceStuff(gProgram_state.racing); + gProgram_state.dont_save_or_load = pSpec->dont_save_or_load; + for (i = 0; i < pSpec->number_of_button_flics; i++) { + LoadFlic(pSpec->flicker_on_flics[i].flic_index); + LoadFlic(pSpec->flicker_off_flics[i].flic_index); + LoadFlic(pSpec->pushed_flics[i].flic_index); + } + + InitFlicQueue(); + gStart_time = PDGetTotalTime(); + gCurrent_choice = pCurrent_choice; + gCurrent_mode = pSpec->initial_imode; + StartMouseCursor(); + if (pSpec->font_needed) { + InitRollingLetters(); + LoadFont(0); + } + old_current_splash = gCurrent_splash; + KillSplashScreen(); + if (pSpec->start_proc1) { + pSpec->start_proc1(); + } + if (!gFaded_palette && !old_current_splash && !(pOptions & 2)) { + DRS3StartSound(gIndexed_outlets[0], 3006); + } + if (pOptions & 1) { + if (pSpec->second_opening_flic > 0) { + RunFlic(pSpec->second_opening_flic); + } + } else if (pSpec->first_opening_flic > 0) { + RunFlic(pSpec->first_opening_flic); + } + + if (pSpec->start_proc2) { + pSpec->start_proc2(); + } + + if (pSpec->number_of_recopy_areas) { + copy_areas = BrMemAllocate(sizeof(void*) * pSpec->number_of_recopy_areas, kMem_intf_copy_areas); + for (i = 0; i < pSpec->number_of_recopy_areas; i++) { + copy_areas[i] = BrPixelmapAllocate(BR_MEMORY_PIXELS, + ((pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index]) + 3) & 0xFC, + pSpec->recopy_areas[i].bottom[gGraf_data_index] - pSpec->recopy_areas[i].top[gGraf_data_index], + 0, 0); + } + } + + last_choice = -1; + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 0); + WaitForNoKeys(); + for (i = 0; i < pSpec->number_of_recopy_areas; i++) { + BrPixelmapRectangleCopy(copy_areas[i], 0, 0, gBack_screen, pSpec->recopy_areas[i].left[gGraf_data_index], pSpec->recopy_areas[i].top[gGraf_data_index], + pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index], + pSpec->recopy_areas[i].bottom[gGraf_data_index] - pSpec->recopy_areas[i].top[gGraf_data_index]); + } + + timed_out = -1; + last_choice = gCurrent_choice; + do { + if (last_choice != gCurrent_choice) { + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1); + } + last_choice = gCurrent_choice; + PollKeys(); + EdgeTriggerModeOff(); + the_key = PDAnyKeyDown(); + if (the_key != -1 && the_key != KEY_CAPSLOCK) { + gMouse_in_use = 0; + gStart_time = PDGetTotalTime(); + } + EdgeTriggerModeOn(); + if ((gTyping_slot < 0 || gAlways_typing) && (PDKeyDown(KEY_LEFT) || PDKeyDown(KEY_KP_4) || last_press == KEY_LEFT)) { + last_press = -1; + if (pSpec->move_left_delta[gCurrent_mode]) { + gCurrent_choice += pSpec->move_left_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_left_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_left_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_left_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_left_min[gCurrent_mode]; + } + DRS3StartSound(gIndexed_outlets[0], 3000); + } + if (pSpec->move_left_proc[gCurrent_mode]) { + defeat_mode_change = (pSpec->move_left_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_left_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_left_new_mode[gCurrent_mode]; + } + } + if ((gTyping_slot < 0 || gAlways_typing) && (PDKeyDown(KEY_RIGHT) || PDKeyDown(KEY_KP_6) || last_press == KEY_RIGHT)) { + last_press = -1; + if (pSpec->move_right_delta[gCurrent_mode]) { + gCurrent_choice += pSpec->move_right_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_right_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_right_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_right_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_right_min[gCurrent_mode]; + } + DRS3StartSound(gIndexed_outlets[0], 3000); + } + if (pSpec->move_right_proc[gCurrent_mode]) { + defeat_mode_change = (pSpec->move_right_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_right_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_right_new_mode[gCurrent_mode]; + } + } + if (PDKeyDown(KEY_UP) || PDKeyDown(KEY_KP_8) || last_press == KEY_UP) { + last_press = -1; + if (pSpec->move_up_delta[gCurrent_mode]) { + gCurrent_choice += pSpec->move_up_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_up_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_up_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_up_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_up_min[gCurrent_mode]; + } + DRS3StartSound(gIndexed_outlets[0], 3000); + } + if (pSpec->move_up_proc[gCurrent_mode]) { + defeat_mode_change = (pSpec->move_up_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_up_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_up_new_mode[gCurrent_mode]; + } + } + if (PDKeyDown(KEY_DOWN) || PDKeyDown(KEY_KP_2) || last_press == KEY_DOWN) { + last_press = -1; + if (pSpec->move_down_delta[gCurrent_mode]) { + gCurrent_choice += pSpec->move_down_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_down_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_down_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_down_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_down_min[gCurrent_mode]; + } + DRS3StartSound(gIndexed_outlets[0], 3000); + } + if (pSpec->move_down_proc[gCurrent_mode]) { + defeat_mode_change = (pSpec->move_down_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_down_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_down_new_mode[gCurrent_mode]; + } + } + if (gTyping_slot >= 0 && pSpec->typeable[gCurrent_mode] && gTyping_slot != gCurrent_choice && !gAlways_typing) { + gCurrent_choice = gTyping_slot; + } + if (last_choice == gCurrent_choice) { + selection_changed = 0; + } else { + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1); + selection_changed = 1; + } + timed_out = pSpec->time_out && (PDGetTotalTime() >= pSpec->time_out + gStart_time); + RemoveTransientBitmaps(1); + RecopyAreas(pSpec, copy_areas); + if (pSpec->font_needed) { + RollLettersIn(); + } + ServicePanelFlics(1); + if (pSpec->draw_proc) { + pSpec->draw_proc(gCurrent_choice, gCurrent_mode); + } + ProcessFlicQueue(gFrame_period); + if (DoMouseCursor() || EitherMouseButtonDown()) { + gStart_time = PDGetTotalTime(); + } + PDScreenBufferSwap(0); + if (gMouse_in_use && !selection_changed) { + GetMousePosition(&x_coord, &y_coord); + mouse_down = EitherMouseButtonDown(); + last_choice = 0; + new_mouse_down = mouse_down && !new_mouse_down; + for (i = 0; i < pSpec->number_of_mouse_areas; i++) { + if (x_coord >= pSpec->mouse_areas[i].left[gGraf_data_index] + && y_coord >= pSpec->mouse_areas[i].top[gGraf_data_index] + && x_coord <= pSpec->mouse_areas[i].right[gGraf_data_index] + && y_coord <= pSpec->mouse_areas[i].bottom[gGraf_data_index] + && (gTyping_slot < 0 || gAlways_typing || pSpec->mouse_areas[i].available_when_typing || gTyping_slot == pSpec->mouse_areas[i].new_choice)) { + + if (pSpec->mouse_areas[i].new_choice >= 0 && pSpec->mouse_areas[i].new_choice != gCurrent_choice) { + gCurrent_choice = pSpec->mouse_areas[i].new_choice; + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 0); + } + if (pSpec->mouse_areas[i].new_mode >= 0) { + gCurrent_mode = pSpec->mouse_areas[i].new_mode; + } + + if (pSpec->mouse_areas[i].new_mode >= 0 || pSpec->mouse_areas[i].new_choice >= 0) { + last_choice = 1; + } + if (mouse_down) { + if (pSpec->mouse_areas[i].mouse_click) { + mouse_down = pSpec->mouse_areas[i].mouse_click(&gCurrent_choice, &gCurrent_mode, + x_coord - pSpec->mouse_areas[i].left[gGraf_data_index], + y_coord - pSpec->mouse_areas[i].top[gGraf_data_index]); + } + } + break; + } + } + } + + if (PDKeyDown(KEY_RETURN) || PDKeyDown(KEY_KP_ENTER) || (gTyping_slot < 0 && PDKeyDown(KEY_SPACE)) || (gMouse_in_use && last_choice && new_mouse_down)) { + DRS3StartSound(gIndexed_outlets[0], 3004); + go_ahead = pSpec->go_ahead_allowed[gCurrent_mode]; + if (pSpec->go_ahead_proc[gCurrent_mode]) { + go_ahead = (pSpec->go_ahead_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode); + } + } else { + go_ahead = 0; + } + if (PDKeyDown(KEY_ESCAPE)) { + DRS3StartSound(gIndexed_outlets[0], 3005); + escaped = pSpec->escape_allowed[gCurrent_mode]; + if (pSpec->escape_proc[gCurrent_mode]) { + escaped = (pSpec->escape_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode); + } + } else { + escaped = 0; + } + if (escaped && gTyping_slot >= 0 && !gAlways_typing) { + LOG_PANIC("not implemented"); + //pSpec->get_original_string(&pVisible_length, gTyping_slot); + escaped = 0; + //RevertTyping(gTyping_slot, &v106); + gTyping = 0; + gTyping_slot = -1; + } + if (go_ahead) { + if (gCurrent_choice >= 0 && gCurrent_choice < pSpec->number_of_button_flics) { + //v84 = &pSpec->pushed_flics[gCurrent_choice]; + if (pSpec->pushed_flics[gCurrent_choice].flic_index >= 0) { + AddToFlicQueue(pSpec->pushed_flics[gCurrent_choice].flic_index, pSpec->pushed_flics[gCurrent_choice].x[gGraf_data_index], pSpec->pushed_flics[gCurrent_choice].y[gGraf_data_index], 1); + } + } + if (pSpec->typeable[gCurrent_mode]) { + if (gTyping_slot >= 0 || gAlways_typing) { + KillCursor(gCurrent_choice); + RecopyAreas(pSpec, copy_areas); + RollLettersIn(); + PDScreenBufferSwap(0); + } else { + LOG_PANIC("not implemented"); + gTyping_slot = gCurrent_choice; + //(pSpec->get_original_string)(&pVisible_length, gCurrent_choice); + //StartTyping(gTyping_slot, &v106, pVisible_length); + go_ahead = 0; + gTyping = 1; + } + } + } else if (gTyping_slot >= 0 && !escaped) { + last_press = PDAnyKeyDown(); + if (last_press != -1 && (!gAlways_typing || (last_press != KEY_LEFT && last_press != KEY_RIGHT && last_press != KEY_UP && last_press != KEY_DOWN))) { + if (gCurrent_choice != gTyping_slot && !gAlways_typing) { + ChangeSelection(pSpec, &gCurrent_choice, &gTyping_slot, gCurrent_mode, gAlways_typing); + for (i = 0; i < 2; i++) { + if (pSpec->typeable[i]) { + gCurrent_mode = i; + break; + } + } + } + TypeKey(gAlways_typing ? 0 : gCurrent_choice, last_press); + } + } + ServiceGame(); + if (last_choice != gCurrent_choice) { + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1); + } + if (entry_status != eProg_idling && gProgram_state.prog_status == eProg_idling) { + escaped = 1; + } + } while ((!pSpec->exit_proc || !(pSpec->exit_proc)(&gCurrent_choice, &gCurrent_mode)) && !go_ahead && !timed_out && !escaped); + + LOG_WARN("OUT OF LOOP %d %d %d", go_ahead, timed_out, escaped); + gTyping = 0; + if (pSpec->font_needed) { + EndRollingLetters(); + DisposeFont(0); + } + if (pSpec->number_of_recopy_areas > 0) { + for (i = 0; i < pSpec->number_of_recopy_areas; i++) { + BrPixelmapFree(copy_areas[i]); + } + BrMemFree(copy_areas); + } + + RemoveTransientBitmaps(1); + FlushFlicQueue(); + for (i = 0; i < pSpec->number_of_button_flics; i++) { + UnlockFlic(pSpec->flicker_on_flics[i].flic_index); + UnlockFlic(pSpec->flicker_off_flics[i].flic_index); + UnlockFlic(pSpec->pushed_flics[i].flic_index); + } + + //v100 = gCurrent_choice; + if (gCurrent_choice == pSpec->escape_code) { + escaped = 1; + go_ahead = 0; + } + if (escaped) { + //v100 = pSpec->escape_code; + gCurrent_choice = pSpec->escape_code; + } + if (pSpec->done_proc) { + result = (pSpec->done_proc)(gCurrent_choice, gCurrent_mode, go_ahead, escaped, timed_out); + } else { + result = gCurrent_choice; + } + if (!go_ahead) { + if (!escaped) { + if (pSpec->end_flic_otherwise > 0) { + DRS3StartSound(gIndexed_outlets[0], 3007); + RunFlic(pSpec->end_flic_otherwise); + } else if (pSpec->end_flic_otherwise < 0) { + FadePaletteDown(pSpec->end_flic_otherwise); + } + goto LABEL_230; + } else { + if (pSpec->end_flic_escaped > 0) { + DRS3StartSound(gIndexed_outlets[0], 3007); + RunFlic(pSpec->end_flic_escaped); + } else if (pSpec->end_flic_escaped < 0) { + FadePaletteDown(pSpec->end_flic_escaped); + } + goto LABEL_230; + } + } + if (pSpec->end_flic_go_ahead > 0) { + DRS3StartSound(gIndexed_outlets[0], 3007); + RunFlic(pSpec->end_flic_go_ahead); + } else if (pSpec->end_flic_go_ahead < 0) { + FadePaletteDown(pSpec->end_flic_go_ahead); + } + +LABEL_230: + gProgram_state.dont_save_or_load = 0; + EndMouseCursor(); + UnlockInterfaceStuff(); + EdgeTriggerModeOff(); + return result; } // Offset: 6764 diff --git a/src/DETHRACE/common/loading.c b/src/DETHRACE/common/loading.c index 4dbe3351..6d874904 100644 --- a/src/DETHRACE/common/loading.c +++ b/src/DETHRACE/common/loading.c @@ -175,7 +175,9 @@ void SkipBytes(FILE* pF, int pBytes_to_skip) { // EAX: pPtr tU32 MemReadU32(char** pPtr) { tU32 raw_long; - NOT_IMPLEMENTED(); + memcpy(&raw_long, *pPtr, 4); + *pPtr += 4; + return raw_long; } // Offset: 944 @@ -183,14 +185,16 @@ tU32 MemReadU32(char** pPtr) { // EAX: pPtr tU16 MemReadU16(char** pPtr) { tU16 raw_short; - NOT_IMPLEMENTED(); + memcpy(&raw_short, *pPtr, 2); + *pPtr += 2; + return raw_short; } // Offset: 1016 // Size: 55 // EAX: pPtr tU8 MemReadU8(char** pPtr) { - NOT_IMPLEMENTED(); + return *(*pPtr)++; } // Offset: 1072 @@ -206,7 +210,9 @@ tS32 MemReadS32(char** pPtr) { // EAX: pPtr tS16 MemReadS16(char** pPtr) { tS16 raw_short; - NOT_IMPLEMENTED(); + memcpy(&raw_short, *pPtr, 2); + *pPtr += 2; + return raw_short; } // Offset: 1216 @@ -214,7 +220,9 @@ tS16 MemReadS16(char** pPtr) { // EAX: pPtr tS8 MemReadS8(char** pPtr) { tS8 raw_byte; - NOT_IMPLEMENTED(); + raw_byte = **pPtr; + (*pPtr)++; + return raw_byte; } // Offset: 1272 @@ -222,7 +230,7 @@ tS8 MemReadS8(char** pPtr) { // EAX: pPtr // EDX: pBytes_to_skip void MemSkipBytes(char** pPtr, int pBytes_to_skip) { - NOT_IMPLEMENTED(); + *pPtr += pBytes_to_skip; } // Offset: 1320 @@ -419,7 +427,19 @@ br_pixelmap* LoadPixelmap(char* pName) { br_uint_32 LoadPixelmaps(char* pFile_name, br_pixelmap** pPixelmaps, br_uint_16 pNum) { tPath_name path; int count; - NOT_IMPLEMENTED(); + + PathCat(path, gApplication_path, gGraf_specs[gGraf_spec_index].data_dir_name); + PathCat(path, path, "PIXELMAP"); + + PathCat(path, path, pFile_name); + gAllow_open_to_fail = 1; + count = DRPixelmapLoadMany(path, pPixelmaps, pNum); + if (!count) { + PathCat(path, gApplication_path, "PIXELMAP"); + PathCat(path, path, pFile_name); + count = DRPixelmapLoadMany(path, pPixelmaps, pNum); + } + return count; } // Offset: 4044 @@ -552,7 +572,7 @@ void DRLoadLights(char* pPath_name) { br_actor* light_array[100]; int number_of_lights; int i; - LOG_WARN("skipping"); + STUB(); } // Offset: 5328 @@ -624,7 +644,30 @@ void LoadKeyMapping() { void LoadInterfaceStuff(int pWithin_race) { tPath_name path; int i; - NOT_IMPLEMENTED(); + LOG_TRACE("(%d)", pWithin_race); + + if (gProgram_state.sausage_eater_mode) { + strcpy(path, "GHANDX.PIX"); + } else { + strcpy(path, "HANDX.PIX"); + } + PossibleService(); + if (!gCursors[0] && !LoadPixelmaps(path, gCursors, 4)) { + FatalError(22); + } + if (gProgram_state.sausage_eater_mode) { + strcpy(path, "GHANDPX.PIX"); + } else { + strcpy(path, "HANDPX.PIX"); + } + PossibleService(); + if (!gCursors[4] && !LoadPixelmaps(path, &gCursors[4], 4)) { + FatalError(22); + } + PossibleService(); + if (!gCursor_giblet_images[0] && !LoadPixelmaps("CURSGIBX.PIX", gCursor_giblet_images, 18u)) { + FatalError(23); + } } // Offset: 6108 @@ -1174,7 +1217,7 @@ void LoadOpponents() { GetALineAndDontArgue(f, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &gNumber_of_racers); - gOpponents = BrMemAllocate(sizeof(tOpponent) * gNumber_of_racers, 0xA3u); + gOpponents = BrMemAllocate(sizeof(tOpponent) * gNumber_of_racers, kMem_oppo_array); for (i = 0; i < gNumber_of_racers; i++) { PossibleService(); @@ -1204,7 +1247,7 @@ void LoadOpponents() { strcpy(gOpponents[i].stolen_car_flic_name, str); gOpponents[i].text_chunk_count = GetAnInt(f); - gOpponents[i].text_chunks = BrMemAllocate(sizeof(tText_chunk) * gOpponents[i].text_chunk_count, 0xA4u); + gOpponents[i].text_chunks = BrMemAllocate(sizeof(tText_chunk) * gOpponents[i].text_chunk_count, kMem_oppo_text_chunk); for (j = 0; j < gOpponents[i].text_chunk_count; j++) { the_chunk = &gOpponents[i].text_chunks[j]; @@ -1219,7 +1262,7 @@ void LoadOpponents() { for (k = 0; k < the_chunk->line_count; k++) { GetALineAndDontArgue(f, s); - the_chunk->text[k] = BrMemAllocate(strlen(s) + 1, 0xA5u); + the_chunk->text[k] = BrMemAllocate(strlen(s) + 1, kMem_oppo_text_str); strcpy(the_chunk->text[k], s); } } @@ -1250,7 +1293,7 @@ br_font* LoadBRFont(char* pName) { PathCat(the_path, the_path, pName); f = DRfopen(the_path, "rb"); PossibleService(); - the_font = BrMemAllocate(sizeof(br_font), 0xA6u); + the_font = BrMemAllocate(sizeof(br_font), kMem_br_font); // we read 0x18 bytes as that is the size of the struct in 32 bit code. fread(the_font, 0x18, 1u, f); @@ -1263,10 +1306,10 @@ br_font* LoadBRFont(char* pName) { the_font->spacing_y = the_font->spacing_y >> 8 | the_font->spacing_y << 8; data_size = sizeof(br_int_8) * 256; - the_font->width = BrMemAllocate(data_size, 0xA7u); + the_font->width = BrMemAllocate(data_size, kMem_br_font_wid); fread(the_font->width, data_size, 1, f); data_size = sizeof(br_uint_16) * 256; - the_font->encoding = BrMemAllocate(data_size, 0xA8u); + the_font->encoding = BrMemAllocate(data_size, kMem_br_font_enc); fread(the_font->encoding, data_size, 1u, f); for (i = 0; i < 256; i++) { the_font->encoding[i] = the_font->encoding[i] >> 8 | the_font->encoding[i] << 8; @@ -1275,7 +1318,7 @@ br_font* LoadBRFont(char* pName) { fread(&data_size, sizeof(tU32), 1u, f); data_size = BrSwap32(data_size); PossibleService(); - the_font->glyphs = BrMemAllocate(data_size, 0xA9u); + the_font->glyphs = BrMemAllocate(data_size, kMem_br_font_glyphs); fread(the_font->glyphs, data_size, 1u, f); fclose(f); return the_font; @@ -1620,7 +1663,7 @@ void LoadMiscStrings() { } for (i = 0; i < 250; i++) { GetALineAndDontArgue(f, s); - gMisc_strings[i] = BrMemAllocate(strlen(s) + 1, 0xABu); + gMisc_strings[i] = BrMemAllocate(strlen(s) + 1, kMem_misc_string); strcpy(gMisc_strings[i], s); if (feof(f)) { break; @@ -1773,7 +1816,7 @@ FILE* DRfopen(char* pFilename, char* pMode) { } } if (!result) { - LOG_WARN("DRfopen failed"); + LOG_WARN("failed"); } return result; } @@ -1786,7 +1829,7 @@ int GetCDPathFromPathsTxtFile(char* pPath_name) { static tPath_name cd_pathname; FILE* paths_txt_fp; tPath_name paths_txt; - LOG_TRACE("()"); + LOG_TRACE9("()"); if (!got_it_already) { sprintf(paths_txt, "%s%s%s", gApplication_path, gDir_separator, "PATHS.TXT"); diff --git a/src/DETHRACE/common/loadsave.c b/src/DETHRACE/common/loadsave.c index af5cc337..b67f5d24 100644 --- a/src/DETHRACE/common/loadsave.c +++ b/src/DETHRACE/common/loadsave.c @@ -64,7 +64,7 @@ void LoadStart() { // Offset: 2340 // Size: 415 // EAX: pSave_allowed -int DoLoadGame(int pSave_allowed) { +int DoLoadGame() { static tFlicette flicker_on[9]; static tFlicette flicker_off[9]; static tFlicette push[9]; @@ -173,5 +173,5 @@ int SaveGameInterface(int pDefault_choice) { // Size: 181 // EAX: pSave_allowed void DoSaveGame(int pSave_allowed) { - LOG_WARN("Not implemented"); + STUB(); } diff --git a/src/DETHRACE/common/loadsave.h b/src/DETHRACE/common/loadsave.h index ef9b3b01..ea01f15b 100644 --- a/src/DETHRACE/common/loadsave.h +++ b/src/DETHRACE/common/loadsave.h @@ -37,8 +37,7 @@ void LoadStart(); // Offset: 2340 // Size: 415 -// EAX: pSave_allowed -int DoLoadGame(int pSave_allowed); +int DoLoadGame(); // Offset: 2756 // Size: 647 diff --git a/src/DETHRACE/common/main.c b/src/DETHRACE/common/main.c index 573a8526..d33e7bd7 100644 --- a/src/DETHRACE/common/main.c +++ b/src/DETHRACE/common/main.c @@ -1,15 +1,17 @@ #include "main.h" #include -#include "common/errors.h" -#include "common/globvars.h" -#include "common/init.h" -#include "common/loading.h" -#include "common/loadsave.h" -#include "common/sound.h" -#include "common/structur.h" -#include "common/utility.h" +#include "controls.h" +#include "errors.h" +#include "globvars.h" +#include "init.h" +#include "input.h" +#include "loading.h" +#include "loadsave.h" #include "pc-dos/dossys.h" +#include "sound.h" +#include "structur.h" +#include "utility.h" // Offset: 0 // Size: 161 @@ -37,13 +39,27 @@ void CheckNumberOfTracks() { // Size: 173 // EAX: pRacing void ServiceTheGame(int pRacing) { - NOT_IMPLEMENTED(); + if (!pRacing) { + CyclePollKeys(); + } + PollKeys(); + rand(); + if (PDServiceSystem(gFrame_period)) { + //sub_500B0(v3); + } + if (!pRacing) { + CheckSystemKeys(0); + } + if (!pRacing && gSound_enabled) { + // TODO: sound? + // S3Service(gProgram_state.cockpit_on && gProgram_state.cockpit_image_index >= 0, 2); + } } // Offset: 536 // Size: 41 void ServiceGame() { - NOT_IMPLEMENTED(); + ServiceTheGame(0); } // Offset: 580 diff --git a/src/DETHRACE/common/mainmenu.c b/src/DETHRACE/common/mainmenu.c index 941335cb..fa95aca2 100644 --- a/src/DETHRACE/common/mainmenu.c +++ b/src/DETHRACE/common/mainmenu.c @@ -1,4 +1,15 @@ #include "mainmenu.h" +#include "controls.h" +#include "flicplay.h" +#include "globvars.h" +#include "globvrpb.h" +#include "graphics.h" +#include "intrface.h" +#include "loading.h" +#include "loadsave.h" +#include "network.h" +#include "newgame.h" +#include "options.h" #include char* gPalette_copy; @@ -39,18 +50,244 @@ void StartMainMenu() { // EAX: pTime_out // EDX: pContinue_allowed int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) { - static tFlicette flicker_on1[8]; - static tFlicette flicker_off1[8]; - static tFlicette push1[8]; - static tMouse_area mouse_areas1[8]; - static tInterface_spec interface_spec1; - static tFlicette flicker_on2[5]; - static tFlicette flicker_off2[5]; - static tFlicette push2[5]; - static tMouse_area mouse_areas2[5]; - static tInterface_spec interface_spec2; + static tFlicette flicker_on1[8] = { + { 14, { 64, 128 }, { 37, 89 } }, + { 25, { 59, 118 }, { 54, 130 } }, + { 27, { 55, 110 }, { 71, 170 } }, + { 29, { 52, 104 }, { 88, 211 } }, + { 23, { 53, 106 }, { 105, 252 } }, + { 21, { 54, 108 }, { 122, 293 } }, + { 17, { 58, 116 }, { 139, 334 } }, + { 19, { 64, 128 }, { 155, 372 } } + }; + static tFlicette flicker_off1[8] = { + { 13, { 64, 128 }, { 37, 89 } }, + { 24, { 59, 118 }, { 54, 130 } }, + { 26, { 55, 110 }, { 71, 170 } }, + { 28, { 52, 104 }, { 88, 211 } }, + { 22, { 53, 106 }, { 105, 252 } }, + { 20, { 54, 108 }, { 122, 293 } }, + { 16, { 58, 116 }, { 139, 334 } }, + { 18, { 64, 128 }, { 155, 372 } } + }; + + static tFlicette push1[8] = { + { 15, { 63, 126 }, { 36, 86 } }, + { 15, { 58, 116 }, { 53, 127 } }, + { 15, { 54, 108 }, { 70, 168 } }, + { 15, { 51, 102 }, { 87, 209 } }, + { 15, { 52, 104 }, { 104, 250 } }, + { 15, { 53, 106 }, { 121, 290 } }, + { 15, { 57, 114 }, { 138, 331 } }, + { 15, { 63, 126 }, { 154, 370 } } + }; + + static tMouse_area mouse_areas1[8] = { + { { 64, 128 }, { 37, 89 }, { 265, 530 }, { 47, 113 }, 0, 0, 0, NULL }, + { { 59, 118 }, { 54, 130 }, { 265, 530 }, { 64, 154 }, 1, 0, 0, NULL }, + { { 55, 110 }, { 71, 170 }, { 265, 530 }, { 81, 194 }, 2, 0, 0, NULL }, + { { 52, 104 }, { 88, 211 }, { 265, 530 }, { 98, 235 }, 3, 0, 0, NULL }, + { { 53, 106 }, { 105, 252 }, { 265, 530 }, { 115, 276 }, 4, 0, 0, NULL }, + { { 54, 108 }, { 122, 293 }, { 265, 530 }, { 132, 317 }, 5, 0, 0, NULL }, + { { 58, 116 }, { 139, 334 }, { 265, 530 }, { 149, 358 }, 6, 0, 0, NULL }, + { { 64, 128 }, { 155, 372 }, { 265, 530 }, { 165, 396 }, 7, 0, 0, NULL } + }; + static tInterface_spec interface_spec1 = { + 0, // initial_imode + 0, // first_opening_flic + 0, // second_opening_flic + 0, // end_flic_go_ahead + 0, // end_flic_escaped + 0, // end_flic_otherwise + 0, // flic_bunch_to_load + { 0x0FFFFFFFF, 0 }, // move_left_new_mode + { 0, 0 }, // move_left_delta + { 0, 0 }, // move_left_min + { 0, 0 }, // move_left_max + { NULL, NULL }, // move_left_proc + { 0x0FFFFFFFF, 0 }, // move_right_new_mode + { 0, 0 }, // move_right_delta + { 0, 0 }, // move_right_min + { 0, 0 }, // move_right_max + { NULL, NULL }, // move_right_proc + { 0x0FFFFFFFF, 0 }, // move_up_new_mode + { 0x0FFFFFFFF, 0 }, // move_up_delta + { 0, 0 }, // move_up_min + { 7, 0 }, // move_up_max + { NULL, NULL }, // move_up_proc + { 0x0FFFFFFFF, 0 }, // move_down_new_mode + { 1, 0 }, // move_down_delta + { 0, 0 }, // move_down_min + { 7, 0 }, // move_down_max + { NULL, NULL }, // move_down_proc + { 1, 1 }, // go_ahead_allowed + { NULL, NULL }, // go_ahead_proc + { 1, 1 }, // escape_allowed + { NULL, NULL }, // escape_proc + NULL, // exit_proc + NULL, // draw_proc + 0u, // time_out + StartMainMenu, // start_proc1 + NULL, // start_proc2 + MainMenuDone1, // done_proc + 0, // font_needed + { 0, 0 }, // typeable + NULL, // get_original_string + 0, // escape_code + 0, // dont_save_or_load + 8, // number_of_button_flics + flicker_on1, // flicker_on_flics + flicker_off1, // flicker_off_flics + push1, // pushed_flics + 8, // number_of_mouse_areas + mouse_areas1, // mouse_areas + 0, // number_of_recopy_areas + NULL // recopy_areas + }; + + static tFlicette flicker_on2[5] = { + { 335, { 58, 116 }, { 51, 122 } }, + { 337, { 53, 106 }, { 74, 178 } }, + { 339, { 51, 102 }, { 96, 230 } }, + { 333, { 52, 104 }, { 119, 286 } }, + { 331, { 58, 116 }, { 142, 341 } } + }; + static tFlicette flicker_off2[5] = { + { 334, { 58, 116 }, { 51, 122 } }, + { 336, { 53, 106 }, { 74, 178 } }, + { 338, { 51, 102 }, { 96, 230 } }, + { 332, { 52, 104 }, { 119, 286 } }, + { 330, { 58, 116 }, { 142, 341 } } + }; + static tFlicette push2[5] = { + { 15, { 56, 112 }, { 50, 120 } }, + { 15, { 51, 102 }, { 73, 175 } }, + { 15, { 50, 100 }, { 95, 228 } }, + { 15, { 51, 102 }, { 118, 283 } }, + { 15, { 57, 114 }, { 141, 338 } } + }; + static tMouse_area mouse_areas2[5] = { + { { 57, 114 }, { 51, 122 }, { 265, 530 }, { 61, 146 }, 0, 0, 0, NULL }, + { { 52, 104 }, { 74, 178 }, { 265, 530 }, { 84, 202 }, 1, 0, 0, NULL }, + { { 51, 102 }, { 96, 230 }, { 265, 530 }, { 106, 254 }, 2, 0, 0, NULL }, + { { 52, 104 }, { 119, 286 }, { 265, 530 }, { 129, 310 }, 3, 0, 0, NULL }, + { { 58, 116 }, { 142, 341 }, { 265, 530 }, { 152, 365 }, 4, 0, 0, NULL } + }; + static tInterface_spec interface_spec2 = { + 0, // initial_imode + 31, // first_opening_flic + 30, // second_opening_flic + 0, // end_flic_go_ahead + 0, // end_flic_escaped + 0, // end_flic_otherwise + 0, // flic_bunch_to_load + { 0x0FFFFFFFF, 0 }, // move_left_new_mode + { 0, 0 }, // move_left_delta + { 0, 0 }, // move_left_min + { 0, 0 }, // move_left_max + { NULL, NULL }, // move_left_proc + { 0x0FFFFFFFF, 0 }, // move_right_new_mode + { 0, 0 }, // move_right_delta + { 0, 0 }, // move_right_min + { 0, 0 }, // move_right_max + { NULL, NULL }, // move_right_proc + { 0x0FFFFFFFF, 0 }, // move_up_new_mode + { 0x0FFFFFFFF, 0 }, // move_up_delta + { 0, 0 }, // move_up_min + { 4, 0 }, // move_up_max + { NULL, NULL }, // move_up_proc + { 0x0FFFFFFFF, 0 }, // move_down_new_mode + { 1, 0 }, // move_down_delta + { 0, 0 }, // move_down_min + { 4, 0 }, // move_down_max + { NULL, NULL }, // move_down_proc + { 1, 1 }, // go_ahead_allowed + { NULL, NULL }, // go_ahead_proc + { 1, 1 }, // escape_allowed + { NULL, NULL }, // escape_proc + NULL, // exit_proc + NULL, // draw_proc + 0u, // time_out + NULL, // start_proc1 + NULL, // start_proc2 + &MainMenuDone2, // done_proc + 0, // font_needed + { 0, 0 }, // typeable + NULL, // get_original_string + 4, // escape_code + 0, // dont_save_or_load + 5, // number_of_button_flics + flicker_on2, // flicker_on_flics + flicker_off2, // flicker_off_flics + push2, // pushed_flics + 5, // number_of_mouse_areas + mouse_areas2, // mouse_areas + 0, // number_of_recopy_areas + NULL // recopy_areas + }; + int result; - NOT_IMPLEMENTED(); + LOG_TRACE("(%d, %d)", pTime_out, pContinue_allowed); + + if (pContinue_allowed) { + gMain_menu_spec = &interface_spec1; + result = DoInterfaceScreen(&interface_spec1, gFaded_palette | 2, 0); + if (result != 7 && result && result != 1 && result != 2) { + RunFlic(12); + } else { + FadePaletteDown(result); + } + switch (result) { + case 0: + return 0; + case 1: + return 8; + case 2: + return 9; + case 3: + return 6; + case 4: + return 3; + case 5: + return 2; + case 6: + return 1; + case 7: + return 7; + default: + break; + } + result = -1; + } else { + interface_spec2.time_out = pTime_out; + result = DoInterfaceScreen(&interface_spec2, gFaded_palette, 0); + if (result != 4 && result != -1) { + RunFlic(32); + } else { + FadePaletteDown(result); + } + switch (result) { + case 0: + result = 4; + break; + case 1: + result = 5; + break; + case 2: + result = 6; + break; + case 3: + result = 3; + break; + case 4: + result = 7; + break; + default: + result = -1; + break; + } + } + return result; } // Offset: 1068 @@ -59,7 +296,36 @@ int DoMainMenuInterface(tU32 pTime_out, int pContinue_allowed) { // EDX: pContinue_allowed tMM_result GetMainMenuOption(tU32 pTime_out, int pContinue_allowed) { int result; - NOT_IMPLEMENTED(); + + result = DoMainMenuInterface(pTime_out, pContinue_allowed); + if (result < 0) { + return eMM_timeout; + } + if (gProgram_state.prog_status == eProg_game_starting) { + return eMM_continue; + } + switch (result) { + case 1: + return eMM_end_game; + case 2: + return eMM_save; + case 3: + return eMM_loaded; + case 4: + return eMM_1_start; + case 5: + return eMM_n_start; + case 6: + return eMM_options; + case 7: + return eMM_quit; + case 8: + return eMM_recover; + case 9: + return eMM_abort_race; + default: + return eMM_continue; + } } // Offset: 1324 @@ -100,7 +366,66 @@ int DoVerifyQuit(int pReplace_background) { // EBX: pContinue_allowed tMM_result DoMainMenu(tU32 pTime_out, int pSave_allowed, int pContinue_allowed) { tMM_result the_result; - NOT_IMPLEMENTED(); + if (gProgram_state.racing) { + FadePaletteDown(pTime_out); + } + the_result = GetMainMenuOption(pTime_out, pContinue_allowed); + switch (the_result) { + case eMM_end_game: + if (!gNet_mode) { + break; + } + gProgram_state.prog_status = eProg_idling; + break; + case eMM_1_start: + if (pContinue_allowed || gAusterity_mode) { + PlayFlicsFromMemory(); + } + if (!DoOnePlayerStart()) { + the_result = 0; + } + if (!pContinue_allowed && !gAusterity_mode) { + break; + } + PlayFlicsFromDisk(); + break; + case eMM_n_start: + if (DoMultiPlayerStart()) { + break; + } + LoadRaces(gRace_list, &gNumber_of_races, -1); + the_result = 0; + break; + case eMM_loaded: + if (!DoLoadGame(the_result)) { + the_result = 0; + } + break; + case eMM_save: + DoSaveGame(pSave_allowed); + the_result = 0; + break; + case eMM_options: + LoadSoundOptionsData(); + DoOptions(); + FreeSoundOptionsData(); + break; + case eMM_quit: + if (DoVerifyQuit(0)) { + break; + } + the_result = 0; + break; + case eMM_recover: + SetRecovery(); + break; + case eMM_abort_race: + gAbandon_game = 1; + break; + default: + break; + } + return the_result; } // Offset: 2420 @@ -110,5 +435,40 @@ tMM_result DoMainMenu(tU32 pTime_out, int pSave_allowed, int pContinue_allowed) // EBX: pContinue_allowed void DoMainMenuScreen(tU32 pTime_out, int pSave_allowed, int pContinue_allowed) { tPlayer_status old_status; - NOT_IMPLEMENTED(); + + if (pContinue_allowed || gAusterity_mode) { + PlayFlicsFromDisk(); + } + old_status = gNet_players[gThis_net_player_index].player_status; + NetPlayerStatusChanged(ePlayer_status_main_menu); + PreloadBunchOfFlics(0); + switch (DoMainMenu(pTime_out, pSave_allowed, pContinue_allowed)) { + case eMM_end_game: + gProgram_state.prog_status = eProg_idling; + break; + case eMM_1_start: + case eMM_n_start: + gProgram_state.prog_status = eProg_game_starting; + break; + case eMM_loaded: + if (gGame_to_load < 0) { + gProgram_state.prog_status = eProg_game_starting; + } + break; + case eMM_quit: + gProgram_state.prog_status = eProg_quit; + break; + case eMM_timeout: + gProgram_state.prog_status = eProg_demo; + break; + default: + break; + } + UnlockBunchOfFlics(0); + if (gNet_players[gThis_net_player_index].player_status == ePlayer_status_main_menu) { + NetPlayerStatusChanged(old_status); + } + if (pContinue_allowed || gAusterity_mode) { + PlayFlicsFromMemory(); + } } diff --git a/src/DETHRACE/common/network.c b/src/DETHRACE/common/network.c index 1a9ae842..4eeeb590 100644 --- a/src/DETHRACE/common/network.c +++ b/src/DETHRACE/common/network.c @@ -1,6 +1,8 @@ #include "network.h" #include "common/controls.h" #include "common/netgame.h" +#include "globvars.h" +#include "globvrpb.h" #include "pc-dos/dosnet.h" #include @@ -767,7 +769,7 @@ void CheckForPendingStartRace() { void NetService(int pIn_race) { tU32 time; static tU32 last_status_broadcast; - LOG_WARN("NetService not implemented"); + SILENT_STUB(); } // Offset: 16400 @@ -783,7 +785,20 @@ void NetFinishRace(tNet_game_details* pDetails, tRace_over_reason pReason) { // Size: 157 // EAX: pNew_status void NetPlayerStatusChanged(tPlayer_status pNew_status) { - NOT_IMPLEMENTED(); + LOG_TRACE("(%d)", pNew_status); + tNet_message* the_message; + + if (gNet_mode && pNew_status != gNet_players[gThis_net_player_index].player_status) { + gNet_players[gThis_net_player_index].player_status = pNew_status; + the_message = NetBuildMessage(0xAu, 0); + the_message->contents.data.report.status = gNet_players[gThis_net_player_index].player_status; + NetSendMessageToAllPlayers(gCurrent_net_game, the_message); + if (gProgram_state.current_car.disabled && pNew_status >= ePlayer_status_racing && pNew_status != ePlayer_status_recovering) { + EnableCar(&gProgram_state.current_car); + } else if (!gProgram_state.current_car.disabled && pNew_status < ePlayer_status_racing) { + DisableCar(&gProgram_state.current_car); + } + } } // Offset: 16648 diff --git a/src/DETHRACE/common/newgame.c b/src/DETHRACE/common/newgame.c index 7db19bd3..64790810 100644 --- a/src/DETHRACE/common/newgame.c +++ b/src/DETHRACE/common/newgame.c @@ -396,7 +396,7 @@ void RevertToDefaults() { void DefaultNetSettings() { FILE* f; int i; - LOG_WARN("Not implemented"); + STUB(); } // Offset: 7964 diff --git a/src/DETHRACE/common/powerup.c b/src/DETHRACE/common/powerup.c index e3208f49..8f32ea25 100644 --- a/src/DETHRACE/common/powerup.c +++ b/src/DETHRACE/common/powerup.c @@ -96,7 +96,7 @@ void LoadPowerups() { FatalError(25); } gNumber_of_powerups = GetAnInt(f); - gPowerup_array = BrMemAllocate(sizeof(tPowerup) * gNumber_of_powerups, 0xC5u); + gPowerup_array = BrMemAllocate(sizeof(tPowerup) * gNumber_of_powerups, kMem_powerup_array); for (i = 0; i < gNumber_of_powerups; i++) { the_powerup = &gPowerup_array[i]; @@ -129,12 +129,12 @@ void LoadPowerups() { the_powerup->got_proc = NULL; } the_powerup->number_of_float_params = GetAnInt(f); - the_powerup->float_params = BrMemAllocate(4 * the_powerup->number_of_float_params, 0xC6u); + the_powerup->float_params = BrMemAllocate(4 * the_powerup->number_of_float_params, kMem_powerup_float_parms); for (j = 0; j < the_powerup->number_of_float_params; j++) { the_powerup->float_params[j] = GetAFloat(f); } the_powerup->number_of_integer_params = GetAnInt(f); - the_powerup->integer_params = BrMemAllocate(4 * the_powerup->number_of_integer_params, 0xC7u); + the_powerup->integer_params = BrMemAllocate(4 * the_powerup->number_of_integer_params, kMem_powerup_int_parms); for (j = 0; j < the_powerup->number_of_integer_params; j++) { the_powerup->integer_params[j] = GetAnInt(f); } diff --git a/src/DETHRACE/common/sound.c b/src/DETHRACE/common/sound.c index 1c4f17af..e95fc6e3 100644 --- a/src/DETHRACE/common/sound.c +++ b/src/DETHRACE/common/sound.c @@ -75,7 +75,7 @@ void InitSound() { // EAX: pOutlet // EDX: pSound tS3_sound_tag DRS3StartSound(tS3_outlet_ptr pOutlet, tS3_sound_id pSound) { - NOT_IMPLEMENTED(); + STUB(); } // Offset: 1348 @@ -83,7 +83,7 @@ tS3_sound_tag DRS3StartSound(tS3_outlet_ptr pOutlet, tS3_sound_id pSound) { // EAX: pOutlet // EDX: pSound tS3_sound_tag DRS3StartSoundNoPiping(tS3_outlet_ptr pOutlet, tS3_sound_id pSound) { - NOT_IMPLEMENTED(); + STUB(); } // Offset: 1424 @@ -203,7 +203,7 @@ int DRS3OverallVolume(tS3_volume pVolume) { // Size: 69 // EAX: pOutlet int DRS3StopOutletSound(tS3_outlet_ptr pOutlet) { - NOT_IMPLEMENTED(); + STUB(); } // Offset: 2756 @@ -222,7 +222,7 @@ void ToggleSoundEnable() { // Size: 125 void SoundService() { br_matrix34 mat; - LOG_WARN("SoundService not implemented"); + SILENT_STUB(); } // Offset: 3028 @@ -287,13 +287,13 @@ void MungeEngineNoise() { int stop_all; int type_of_engine_noise; tS3_sound_id engine_noise; - LOG_WARN("skipping"); + STUB(); } // Offset: 5716 // Size: 154 void SetSoundVolumes() { - LOG_WARN("skipping"); + STUB(); } // Offset: 5872 diff --git a/src/DETHRACE/common/utility.c b/src/DETHRACE/common/utility.c index a2c92e17..99ef2aef 100644 --- a/src/DETHRACE/common/utility.c +++ b/src/DETHRACE/common/utility.c @@ -2,10 +2,14 @@ #include #include "brender.h" +#include "constants.h" #include "dossys.h" #include "errors.h" #include "globvars.h" +#include "input.h" #include "loading.h" +#include "loadsave.h" +#include "mainmenu.h" #include "network.h" #include "sound.h" @@ -22,7 +26,7 @@ tU32 gLong_key[] = { 0x5F991B6C, 0x135FCDB9, 0x0E2004CB, 0x0EA11C5E }; tU32 gOther_long_key[] = { 0x26D6A867, 0x1B45DDB6, 0x13227E32, 0x3794C215 }; char* gMisc_strings[250]; -int gIn_check_quit; +int gIn_check_quit = 0; tU32 gLost_time; int gEncryption_method = 0; br_pixelmap* g16bit_palette; @@ -31,8 +35,20 @@ br_pixelmap* gSource_for_16bit_palette; // Offset: 0 // Size: 144 int CheckQuit() { - int got_as_far_as_verify; - NOT_IMPLEMENTED(); + LOG_TRACE8("()"); + + if (!gIn_check_quit && KeyIsDown(KEYMAP_Q) && KeyIsDown(KEYMAP_LCTRL)) { + gIn_check_quit = 1; + while (AnyKeyDown()) { + ; + } + + if (DoVerifyQuit(1)) { + DoSaveGame(1); + } + gIn_check_quit = 0; + } + return 0; } // Offset: 196 @@ -279,7 +295,10 @@ float tandeg(float pAngle) { // EAX: pF tU32 GetFileLength(FILE* pF) { tU32 the_size; - NOT_IMPLEMENTED(); + fseek(pF, 0, SEEK_END); + the_size = ftell(pF); + rewind(pF); + return the_size; } // Offset: 2164 @@ -588,7 +607,7 @@ tU32 GetRaceTime() { // Size: 46 // EAX: pLost_time void AddLostTime(tU32 pLost_time) { - NOT_IMPLEMENTED(); + gLost_time += pLost_time; } // Offset: 7048 @@ -1237,7 +1256,7 @@ void NobbleNonzeroBlacks(br_pixelmap* pPalette) { // Size: 55 // EAX: pThe_path int PDCheckDriveExists(char* pThe_path) { - LOG_TRACE("(\"%s\")", pThe_path); + LOG_TRACE9("(\"%s\")", pThe_path); return PDCheckDriveExists2(pThe_path, NULL, 0); } diff --git a/src/DETHRACE/constants.h b/src/DETHRACE/constants.h new file mode 100644 index 00000000..d669141e --- /dev/null +++ b/src/DETHRACE/constants.h @@ -0,0 +1,246 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H + +// JeffH: Constant names are not part of the symbol dump, so the names in this file are not original, except as noted. + +// Names from `gMem_names`. See also: `CreateStainlessClasses` +typedef enum dr_memory_classes { + kMem_intf_pix_copy = 129, // 0x81 + kMem_intf_pal_copy = 130, // 0x82 + kMem_nodes_array = 131, // 0x83 + kMem_sections_array = 132, // 0x84 + kMem_key_names = 133, // 0x85 + kMem_columns_z = 134, // 0x86 + kMem_columns_x = 135, // 0x87 + kMem_non_car_list = 136, // 0x88 + kMem_simp_level = 137, // 0x89 + kMem_crush_data = 138, // 0x8a + kMem_crush_neighbours = 139, // 0x8b + kMem_temp_fs = 140, // 0x8c + kMem_error_pix_copy = 141, // 0x8d + kMem_error_pal_copy = 142, // 0x8e + kMem_flic_pal = 143, // 0x8f + kMem_flic_data = 144, // 0x90 + kMem_flic_data_2 = 145, // 0x91 + kMem_queued_flic = 146, // 0x92 + kFlic_panel_pixels = 147, // 0x93 + kMem_translations = 148, // 0x94 + kMem_translations_text = 149, // 0x95 + kMem_cur_pal_pixels = 150, // 0x96 + kMem_render_pal_pixels = 151, // 0x97 + kMem_scratch_pal_pixels = 152, // 0x98 + kMem_shade_table_copy = 153, // 0x99 + kMem_rear_screen_pixels = 154, // 0x9a + kMem_rolling_letters = 155, // 0x9b + kMem_intf_copy_areas = 156, // 0x9c + kMem_strip_image = 157, // 0x9d + kMem_strip_image_perm = 158, // 0x9e + kMem_damage_clauses = 159, // 0x9f + kMem_undamaged_vertices = 160, // 0xa0 + kMem_race_text_chunk = 161, // 0xa1 + kMem_race_text_str = 162, // 0xa2 + kMem_oppo_array = 163, // 0xa3 + kMem_oppo_text_chunk = 164, // 0xa4 + kMem_oppo_text_str = 165, // 0xa5 + kMem_br_font = 166, // 0xa6 + kMem_br_font_wid = 167, // 0xa7 + kMem_br_font_enc = 168, // 0xa8 + kMem_br_font_glyphs = 169, // 0xa9 + kMem_oppo_car_spec = 170, // 0xaa + kMem_misc_string = 171, // 0xab + kMem_mac_host_buffer_1 = 172, // 0xac + kMem_mac_host_buffer_2 = 173, // 0xad + kMem_mac_net_details = 174, // 0xae + kMem_back_pixels = 175, // 0xaf + kMem_quit_vfy_pixels = 176, // 0xb0 + kMem_quit_vfy_pal = 177, // 0xb1 + kMem_net_min_messages = 178, // 0xb2 + kMem_net_mid_messages = 179, // 0xb3 + kMem_net_max_messages = 180, // 0xb4 + kMem_net_pid_details = 181, // 0xb5 + kMem_net_car_spec = 182, // 0xb6 + kMem_dynamic_message = 183, // 0xb7 + kMem_player_list_join = 184, // 0xb8 + kMem_player_list_leave = 185, // 0xb9 + kMem_oppo_new_nodes = 186, // 0xba + kMem_oppo_new_sections = 187, // 0xbb + kMem_cop_car_spec = 188, // 0xbc + kMem_oppo_bit_per_node = 189, // 0xbd + kMem_ped_action_list = 190, // 0xbe + kMem_ped_sequences = 191, // 0xbf + kMem_ped_array_stain = 192, // 0xc0 + kMem_ped_array = 193, // 0xc1 + kMem_ped_instructions = 194, // 0xc2 + kMem_ped_new_instruc = 195, // 0xc3 + kMem_pipe_model_geometry = 196, // 0xc4 + kMem_powerup_array = 197, // 0xc5 + kMem_powerup_float_parms = 198, // 0xc6 + kMem_powerup_int_parms = 199, // 0xc7 + kMem_drugs_palette = 200, // 0xc8 + kMem_pratcam_flic_array = 201, // 0xc9 + kMem_pratcam_flic_data = 202, // 0xca + kMem_pratcam_sequence_array = 203, // 0xcb + kMem_pratcam_pixelmap = 204, // 0xcc + kMem_video_pixels = 205, // 0xcd + kMem_funk_prox_array = 206, // 0xce + kMem_new_mat_id = 207, // 0xcf + kMem_new_mat_id_2 = 208, // 0xd0 + kMem_new_mat_id_3 = 209, // 0xd1 + kMem_special_volume = 210, // 0xd2 + kMem_special_screen = 211, // 0xd3 + kMem_new_special_vol = 212, // 0xd4 + kMem_saved_game = 213, // 0xd5 + kMem_new_save_game = 214, // 0xd6 + kMem_stor_space_pix = 215, // 0xd7 + kMem_stor_space_tab = 216, // 0xd8 + kMem_stor_space_mat = 217, // 0xd9 + kMem_stor_space_mod = 218, // 0xda + kMem_stor_space_save = 219, // 0xdb + kMem_funk_spec = 220, // 0xdc + kMem_groove_spec = 221, // 0xdd + kMem_non_car_spec = 222, // 0xde + kMem_S3_scan_name = 223, // 0xdf + kMem_S3_sound_header = 224, // 0xe0 + kMem_S3_sample = 225, // 0xe1 + kMem_S3_mac_channel = 226, // 0xe2 + kMem_S3_mac_path = 227, // 0xe3 + kMem_S3_sentinel = 228, // 0xe4 + kMem_S3_outlet = 229, // 0xe5 + kMem_S3_channel = 230, // 0xe6 + kMem_S3_descriptor = 231, // 0xe7 + kMem_S3_reverse_buffer = 232, // 0xe8 + kMem_S3_source = 233, // 0xe9 + kMem_S3_DOS_SOS_channel = 234, // 0xea + kMem_S3_PC_DOS_path = 235, // 0xeb + kMem_S3_DOS_SOS_patch = 236, // 0xec + kMem_S3_DOS_SOS_song_structure = 237, // 0xed + kMem_S3_DOS_SOS_song_data = 238, // 0xee + kMem_S3_Windows_95_load_WAV_file = 239, // 0xef + kMem_S3_Windows_95_create_temp_buffer_space_to_reverse_sample = 240, // 0xf0 + kMem_S3_Windows_95_path = 241, // 0xf1 + kMem_DOS_HMI_file_open = 242, // 0xf2 + kMem_abuse_text = 243, // 0xf3 + kMem_action_replay_buffer = 244, // 0xf4 + kMem_misc = 245 // 0xf5 +} dr_memory_classes; + +typedef enum keycodes { + KEY_LSHIFT = 0, // 0x0 + KEY_LALT = 1, // 0x1 + KEY_LCTRL = 2, // 0x2 + KEY_LCTRL_DUPE_2 = 3, // 0x3 + KEY_CAPSLOCK = 4, // 0x4 + KEY_RSHIFT = 5, // 0x5 + KEY_RALT = 6, // 0x6 + KEY_RCTRL = 7, // 0x7 + KEY_LSHIFT_DUPE_2 = 8, // 0x8 + KEY_LALT_DUPE_2 = 9, // 0x9 + KEY_LCTRL_DUPE_3 = 10, // 0xa + KEY_0 = 11, // 0xb + KEY_1 = 12, // 0xc + KEY_2 = 13, // 0xd + KEY_3 = 14, // 0xe + KEY_4 = 15, // 0xf + KEY_5 = 16, // 0x10 + KEY_6 = 17, // 0x11 + KEY_7 = 18, // 0x12 + KEY_8 = 19, // 0x13 + KEY_9 = 20, // 0x14 + KEY_A = 21, // 0x15 + KEY_B = 22, // 0x16 + KEY_C = 23, // 0x17 + KEY_D = 24, // 0x18 + KEY_E = 25, // 0x19 + KEY_F = 26, // 0x1a + KEY_G = 27, // 0x1b + KEY_H = 28, // 0x1c + KEY_I = 29, // 0x1d + KEY_J = 30, // 0x1e + KEY_K = 31, // 0x1f + KEY_L = 32, // 0x20 + KEY_M = 33, // 0x21 + KEY_N = 34, // 0x22 + KEY_O = 35, // 0x23 + KEY_P = 36, // 0x24 + KEY_Q = 37, // 0x25 + KEY_R = 38, // 0x26 + KEY_S = 39, // 0x27 + KEY_T = 40, // 0x28 + KEY_U = 41, // 0x29 + KEY_V = 42, // 0x2a + KEY_W = 43, // 0x2b + KEY_X = 44, // 0x2c + KEY_Y = 45, // 0x2d + KEY_Z = 46, // 0x2e + KEY_GRAVE = 47, // 0x2f + KEY_MINUS = 48, // 0x30 + KEY_EQUALS = 49, // 0x31 + KEY_BACKSPACE = 50, // 0x32 + KEY_RETURN = 51, // 0x33 + KEY_KP_ENTER = 52, // 0x34 + KEY_TAB = 53, // 0x35 + KEY_KP_DIVIDE = 54, // 0x36 + KEY_SLASH = 55, // 0x37 + KEY_SEMICOLON = 56, // 0x38 + KEY_APOSTROPHE = 57, // 0x39 + KEY_PERIOD = 58, // 0x3a + KEY_COMMA = 59, // 0x3b + KEY_LEFTBRACKET = 60, // 0x3c + KEY_RIGHTBRACKET = 61, // 0x3d + KEY_UNDEFINED_2 = 62, // 0x3e + KEY_ESCAPE = 63, // 0x3f + KEY_INSERT = 64, // 0x40 + KEY_DELETE = 65, // 0x41 + KEY_HOME = 66, // 0x42 + KEY_END = 67, // 0x43 + KEY_PAGEUP = 68, // 0x44 + KEY_PAGEDOWN = 69, // 0x45 + KEY_LEFT = 70, // 0x46 + KEY_RIGHT = 71, // 0x47 + KEY_UP = 72, // 0x48 + KEY_DOWN = 73, // 0x49 + KEY_UNDEFINED_3 = 74, // 0x4a + KEY_KP_DIVIDE_2 = 75, // 0x4b + KEY_KP_MULTIPLY = 76, // 0x4c + KEY_KP_MINUS = 77, // 0x4d + KEY_KP_PLUS = 78, // 0x4e + KEY_KP_PERIOD = 79, // 0x4f + KEY_KP_EQUALS = 80, // 0x50 + KEY_KP_0 = 81, // 0x51 + KEY_KP_1 = 82, // 0x52 + KEY_KP_2 = 83, // 0x53 + KEY_KP_3 = 84, // 0x54 + KEY_KP_4 = 85, // 0x55 + KEY_KP_5 = 86, // 0x56 + KEY_KP_6 = 87, // 0x57 + KEY_KP_7 = 88, // 0x58 + KEY_KP_8 = 89, // 0x59 + KEY_KP_9 = 90, // 0x5a + KEY_F1 = 91, // 0x5b + KEY_F2 = 92, // 0x5c + KEY_F3 = 93, // 0x5d + KEY_F4 = 94, // 0x5e + KEY_F5 = 95, // 0x5f + KEY_F6 = 96, // 0x60 + KEY_F7 = 97, // 0x61 + KEY_F8 = 98, // 0x62 + KEY_F9 = 99, // 0x63 + KEY_F10 = 100, // 0x64 + KEY_F11 = 101, // 0x65 + KEY_F12 = 102, // 0x66 + KEY_PRINTSCREEN = 103, // 0x67 + KEY_UNDEFINED_4 = 104, // 0x68 + KEY_PAUSE = 105, // 0x69 + KEY_SPACE = 106, // 0x6a +} keycodes; + +typedef enum keymapcodes { + KEYMAP_Q = 1, + KEYMAP_S = 2, + KEYMAP_L = 3, + KEYMAP_LCTRL = 7, + KEYMAP_F2 = 28, + KEYMAP_F3 = 29, +} keymapcodes; + +#endif \ No newline at end of file diff --git a/src/DETHRACE/dr_types.h b/src/DETHRACE/dr_types.h index 1e9bba39..2b4d93b1 100644 --- a/src/DETHRACE/dr_types.h +++ b/src/DETHRACE/dr_types.h @@ -2,6 +2,7 @@ #define DR_TYPES_H #include "br_types.h" +#include "constants.h" #include "harness.h" #include #include diff --git a/src/DETHRACE/pc-dos/dossys.c b/src/DETHRACE/pc-dos/dossys.c index 3cf22eab..a3fc24b9 100644 --- a/src/DETHRACE/pc-dos/dossys.c +++ b/src/DETHRACE/pc-dos/dossys.c @@ -251,6 +251,7 @@ int PDGetASCIIFromKey(int pKey) { // EAX: pThe_str void PDFatalError(char* pThe_str) { static int been_here = 0; + LOG_TRACE("(\"%s\")", pThe_str); if (been_here) { if (!_unittest_do_not_exit) { @@ -544,7 +545,11 @@ void PDSetPalette(br_pixelmap* pThe_palette) { void PDSetPaletteEntries(br_pixelmap* pPalette, int pFirst_colour, int pCount) { int i; tU8* p; - NOT_IMPLEMENTED(); + p = pPalette->pixels + 4 * pFirst_colour; + for (i = pFirst_colour; i < pFirst_colour + pCount; i++) { + BrDevPaletteSetEntryOld(i, (p[2] << 16) | (p[1] << 8) | *p); + p += 4; + } } // Offset: 5716 @@ -597,7 +602,7 @@ int PDGetTotalTime() { // Size: 37 // EAX: pTime_since_last_call int PDServiceSystem(tU32 pTime_since_last_call) { - NOT_IMPLEMENTED(); + return 0; } // Offset: 6352 @@ -895,7 +900,7 @@ int PDCheckDriveExists2(char* pThe_path, char* pFile_name, tU32 pMin_size) { int stat_failed; char slasher[4]; char the_path[256]; - LOG_TRACE("(\"%s\", \"%s\", %d)", pThe_path, pFile_name, pMin_size); + LOG_TRACE9("(\"%s\", \"%s\", %d)", pThe_path, pFile_name, pMin_size); strcpy(slasher, "?:\\"); if (pFile_name) { diff --git a/src/harness/debug.h b/src/harness/debug.h index 44aa3b4a..d8404a77 100644 --- a/src/harness/debug.h +++ b/src/harness/debug.h @@ -33,6 +33,11 @@ debug_printf("\033[0;31m[PANIC] %s ", __FUNCTION__, "%s", "not implemented"); \ exit(1); +#define STUB() \ + debug_printf("\033[0;31m[WARN] %s ", __FUNCTION__, "%s", "stubbed"); + +#define SILENT_STUB() + void debug_printf(const char* fmt, const char* fn, const char* fmt2, ...); #endif \ No newline at end of file diff --git a/src/harness/harness.c b/src/harness/harness.c index 98e22d5e..bc693a29 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -19,7 +19,6 @@ void Harness_Init(char* name, renderer* renderer) { } void Harness_RunWindowLoop(harness_game_func* game_func, void* arg) { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { LOG_PANIC("SDL_Init Error: %s", SDL_GetError()); } @@ -100,6 +99,13 @@ void Harness_Hook_BrDevPaletteSetOld(br_pixelmap* pm) { } } +void Harness_Hook_BrDevPaletteSetEntryOld(int i, br_colour colour) { + if (palette != NULL) { + uint32_t* colors = palette->pixels; + colors[i] = colour; + } +} + void Harness_Hook_KeyBegin() { Keyboard_Init(); } diff --git a/src/harness/harness.h b/src/harness/harness.h index 189fdff2..4713d1b7 100644 --- a/src/harness/harness.h +++ b/src/harness/harness.h @@ -20,6 +20,7 @@ void Harness_RunWindowLoop(harness_game_func* game_func, void* arg); // Hooks are called from original game code. void Harness_Hook_DOSGfxBegin(); void Harness_Hook_BrDevPaletteSetOld(br_pixelmap* pm); +void Harness_Hook_BrDevPaletteSetEntryOld(int i, br_colour colour); void Harness_Hook_BrPixelmapDoubleBuffer(br_pixelmap* dst, br_pixelmap* src); void Harness_Hook_KeyBegin(); diff --git a/src/harness/input/keyboard.c b/src/harness/input/keyboard.c index e3d49c39..acb58e0b 100644 --- a/src/harness/input/keyboard.c +++ b/src/harness/input/keyboard.c @@ -14,14 +14,12 @@ int keymap[123] = { SDL_SCANCODE_LCTRL, -1, SDL_SCANCODE_CAPSLOCK, - SDL_SCANCODE_RSHIFT, SDL_SCANCODE_RALT, SDL_SCANCODE_RCTRL, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_LALT, SDL_SCANCODE_LCTRL, - SDL_SCANCODE_0, SDL_SCANCODE_1, SDL_SCANCODE_2, @@ -58,7 +56,6 @@ int keymap[123] = { SDL_SCANCODE_X, SDL_SCANCODE_Y, SDL_SCANCODE_Z, - SDL_SCANCODE_GRAVE, SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, @@ -140,6 +137,7 @@ void Keyboard_HandleEvent(SDL_KeyboardEvent* key) { } if (key->type == SDL_KEYDOWN) { sdl_key_state[key->keysym.scancode] = 1; + //LOG_DEBUG("key %d", key->keysym.scancode); } else { sdl_key_state[key->keysym.scancode] = 0; } diff --git a/src/harness/stack_trace_handler.h b/src/harness/stack_trace_handler.h index 905bac97..43b98467 100644 --- a/src/harness/stack_trace_handler.h +++ b/src/harness/stack_trace_handler.h @@ -2,12 +2,14 @@ #include #include +#include #include #include #include #include #include #include +#include #ifdef _WIN32 #include @@ -261,9 +263,25 @@ void posix_signal_handler(int sig, siginfo_t* siginfo, void* context) { } static uint8_t alternate_stack[SIGSTKSZ]; + +void resolve_full_path(char* path, const char* argv0) { + char buf[PATH_MAX]; + char* pos; + if (argv0[0] == '/') { // run with absolute path + strcpy(path, argv0); + } else { // run with relative path + if (NULL == getcwd(path, PATH_MAX)) { + perror("getcwd error"); + return NULL; + } + strcat(path, "/"); + strcat(path, argv0); + } +} + void install_signal_handler(char* program_name) { - strcpy(_program_name, program_name); + resolve_full_path(_program_name, program_name); /* setup alternate stack */ { diff --git a/test/DETHRACE/test_flicplay.c b/test/DETHRACE/test_flicplay.c new file mode 100644 index 00000000..edfc0121 --- /dev/null +++ b/test/DETHRACE/test_flicplay.c @@ -0,0 +1,37 @@ +#include "brender.h" +#include "common/flicplay.h" +#include "common/graphics.h" +#include "tests.h" + +int nbr_frames_rendered; + +void frame_render_callback() { + nbr_frames_rendered++; +} +void test_flicplay_playflic() { + REQUIRES_DATA_DIRECTORY(); + int pIndex = 31; // main menu swing in + br_pixelmap* target; + + gCurrent_palette_pixels = malloc(0x400); + FlicPaletteAllocate(); + TEST_ASSERT_EQUAL_INT(1, LoadFlic(pIndex)); + + target = BrPixelmapAllocate(BR_MEMORY_PIXELS, 320, 200, NULL, 0); + PlayFlic( + pIndex, + gMain_flic_list[pIndex].the_size, + gMain_flic_list[pIndex].data_ptr, + target, + gMain_flic_list[pIndex].x_offset, + gMain_flic_list[pIndex].y_offset, + frame_render_callback, + gMain_flic_list[pIndex].interruptable, + gMain_flic_list[pIndex].frame_rate); + + TEST_ASSERT_EQUAL_INT(3, nbr_frames_rendered); +} + +void test_flicplay_suite() { + RUN_TEST(test_flicplay_playflic); +} \ No newline at end of file diff --git a/test/DETHRACE/test_loading.c b/test/DETHRACE/test_loading.c index da19ebe0..97130aea 100644 --- a/test/DETHRACE/test_loading.c +++ b/test/DETHRACE/test_loading.c @@ -80,10 +80,42 @@ void test_loading_opponents() { TEST_ASSERT_EQUAL_STRING("TOP SPEED: 150MPH", o->text_chunks[0].text[0]); } +void test_loading_memread() { + int32_t int_array[] = { 1, 2, 3, 4 }; + char* data = (char*)int_array; + TEST_ASSERT_EQUAL_INT(1, MemReadU32(&data)); + TEST_ASSERT_EQUAL_INT(2, MemReadU32(&data)); + MemSkipBytes(&data, sizeof(int32_t)); + TEST_ASSERT_EQUAL_INT(4, MemReadU32(&data)); + + int16_t short_array[] = { 1, 2, 3, 4, -5, -6 }; + data = (char*)short_array; + TEST_ASSERT_EQUAL_INT(1, MemReadU16(&data)); + TEST_ASSERT_EQUAL_INT(2, MemReadU16(&data)); + MemSkipBytes(&data, sizeof(int16_t)); + TEST_ASSERT_EQUAL_INT(4, MemReadU16(&data)); + TEST_ASSERT_EQUAL_INT(-5, MemReadS16(&data)); + TEST_ASSERT_EQUAL_INT(-6, MemReadS16(&data)); + + int8_t char_array[] = { 1, 2, 3, -4 }; + data = (char*)char_array; + TEST_ASSERT_EQUAL_INT(1, MemReadU8(&data)); + TEST_ASSERT_EQUAL_INT(2, MemReadU8(&data)); + MemSkipBytes(&data, sizeof(int8_t)); + TEST_ASSERT_EQUAL_INT(252, MemReadU8(&data)); // (unsigned) + + data = (char*)char_array; + TEST_ASSERT_EQUAL_INT(1, MemReadS8(&data)); + TEST_ASSERT_EQUAL_INT(2, MemReadS8(&data)); + MemSkipBytes(&data, sizeof(int8_t)); + TEST_ASSERT_EQUAL_INT(-4, MemReadS8(&data)); +} + void test_loading_suite() { RUN_TEST(test_loading_GetCDPathFromPathsTxtFile); RUN_TEST(test_loading_OldDRfopen); RUN_TEST(test_loading_LoadGeneralParameters); RUN_TEST(test_loading_brfont); RUN_TEST(test_loading_opponents); + RUN_TEST(test_loading_memread); } diff --git a/test/DETHRACE/test_utility.c b/test/DETHRACE/test_utility.c index fc9834d0..29f9ef69 100644 --- a/test/DETHRACE/test_utility.c +++ b/test/DETHRACE/test_utility.c @@ -1,5 +1,6 @@ #include "tests.h" +#include "common/loading.h" #include "common/utility.h" #include @@ -81,6 +82,12 @@ void test_utility_PathCat() { TEST_ASSERT_EQUAL_STRING("a", buf); } +void test_utility_getMiscString() { + // LoadMiscStrings(); + // printf("%s\n", GetMiscString(223)); + // printf("%s\n", GetMiscString(75)); +} + void test_utility_suite() { RUN_TEST(test_utility_EncodeLinex); RUN_TEST(test_utility_DecodeLine2); @@ -88,4 +95,5 @@ void test_utility_suite() { RUN_TEST(test_utility_StripCR); RUN_TEST(test_utility_GetALineWithNoPossibleService); RUN_TEST(test_utility_PathCat); + RUN_TEST(test_utility_getMiscString); } diff --git a/test/main.c b/test/main.c index 940440f1..5c62ceee 100644 --- a/test/main.c +++ b/test/main.c @@ -40,6 +40,7 @@ extern void test_pmfile_suite(); extern void test_graphics_suite(); extern void test_regsupt_suite(); extern void test_powerup_suite(); +extern void test_flicplay_suite(); char* root_dir; @@ -109,6 +110,7 @@ int main(int argc, char** argv) { test_dossys_suite(); test_graphics_suite(); test_powerup_suite(); + test_flicplay_suite(); return UNITY_END(); } diff --git a/tools/add_enum_values.py b/tools/add_enum_values.py new file mode 100755 index 00000000..044f134b --- /dev/null +++ b/tools/add_enum_values.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 -u + +# Used to discover the key referenced in `KeyIsDown` calls. +# Input: keymap index +# Output: keycode index + +import sys + +input = sys.argv[1] +values = input.split('\n') +i = 0 +for v in values: + v = v.replace(',', '') + print(v.strip(), '=', i, ',', '// ', hex(i)) + i = i + 1 + + + diff --git a/tools/comment_struct.py b/tools/comment_struct.py new file mode 100755 index 00000000..bfe12431 --- /dev/null +++ b/tools/comment_struct.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 -u + +f = open("struct_decl", 'r') +f2 = open("struct_def", 'r') + +line = f.readline() +line2 = f2.readline() + +print(line, end='') +while True: + line = f.readline() + line2 = f2.readline() + if line == '': + print('error, didnt see end of struct') + break + if line2 == '': + print('error, files should have same number of lines') + break + + if '};' in line: + print(line) + break + + line = line.rstrip() + line2 = line2.strip() + + comment_index = line.find('//') + if comment_index > 0: + line = line[:comment_index] + + parts = line2.split(' ') + name = parts[1] + array_index = name.find('[') + if array_index > 0: + name = name[0: array_index] + + if name.startswith('(*'): + name = name[2:] + paren_index = name.find(')') + if paren_index > 0: + name = name[0:paren_index] + + if ';' in name: + name = name[:-1] + + + + print(line, '\t\t//', name) \ No newline at end of file diff --git a/tools/keymap_to_keycode.py b/tools/keymap_to_keycode.py new file mode 100755 index 00000000..2280c601 --- /dev/null +++ b/tools/keymap_to_keycode.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 -u + +# Used to discover the key referenced in `KeyIsDown` calls. +# Input: keymap index +# Output: keycode index + +import os +import sys + +f = open(os.environ['DETHRACE_ROOT_DIR'] + '/data/KEYMAP_0.TXT') +content = f.readlines() +f.close() + +keymap_code = int(sys.argv[1]) +print(content[keymap_code].strip()) + + +