From aa40a3b402a890fa43a1df234da061b6b122d7fb Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Thu, 16 Nov 2023 13:35:30 +0100 Subject: [PATCH] port Shell_Main --- docs/progress.svg | 16 +- docs/progress.txt | 107 +++++++++---- src/game/shell.c | 136 +++++++++++++++++ src/game/shell.h | 3 + src/global/funcs.h | 1 - src/global/types.h | 351 ++++++++++++++++++++++++++----------------- src/global/vars.h | 11 +- src/inject_exec.c | 1 + tools/generate_funcs | 9 +- 9 files changed, 455 insertions(+), 180 deletions(-) diff --git a/docs/progress.svg b/docs/progress.svg index 2a0c5db5..3d6c6be1 100644 --- a/docs/progress.svg +++ b/docs/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -28.41% (346) · 69.13% (842) · 0.66% (8) · 1.81% (22) +28.49% (347) · 69.05% (841) · 0.66% (8) · 1.81% (22) - - + + @@ -1200,7 +1200,7 @@ void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); HWND __cdecl SE_FindSetupDialog(void); -BOOL __cdecl GameMain(void); +BOOL __cdecl Shell_Main(void); int16_t __cdecl TitleSequence(void); void __cdecl CheckCheatMode(void); void __cdecl S_SaveSettings(void); @@ -1299,10 +1299,10 @@ Tomb2.exe progress according to the function sizes: -26.61% · 73.06% · 0.02% · 0.31% +26.82% · 72.85% · 0.02% · 0.31% - - + + @@ -1426,7 +1426,7 @@ const int16_t *__cdecl Output_InsertObjectG3_ZBuffered(const int16_t *obj_ptr, int32_t num, enum SORT_TYPE sort_type); int32_t __cdecl Output_XYClipper(int32_t vtx_count, struct VERTEX_INFO *vtx); void __cdecl ControlMissile(int16_t fx_num); -BOOL __cdecl GameMain(void); +BOOL __cdecl Shell_Main(void); void __cdecl Lara_Animate(struct ITEM_INFO *item); void __cdecl GiantYetiControl(int16_t item_num); void __cdecl Output_DrawSprite(uint32_t flags, int32_t x, int32_t y, int32_t z, int16_t sprite_idx, int16_t shade, int16_t scale); diff --git a/docs/progress.txt b/docs/progress.txt index ae30aaca..b86025c9 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -849,6 +849,46 @@ typedef struct __unaligned BOX_INFO { uint16_t overlap_index; } BOX_INFO; +typedef enum GAME_FLOR_DIR { + GFD_START_GAME = 0x0000, + GFD_START_SAVED_GAME = 0x0100, + GFD_START_CINE = 0x0200, + GFD_START_FMV = 0x0300, + GFD_START_DEMO = 0x0400, + GFD_EXIT_TO_TITLE = 0x0500, + GFD_LEVEL_COMPLETE = 0x0600, + GFD_EXIT_GAME = 0x0700, + GFD_EXIT_TO_OPTION = 0x0800, + GFD_TITLE_DESELECT = 0x0900, +} GAME_FLOW_DIR; + +typedef struct GAME_FLOW { + int32_t first_option; + int32_t title_replace; + int32_t on_death_demo_mode; + int32_t on_death_in_game; + int32_t no_input_time; + int32_t on_demo_interrupt; + int32_t on_demo_end; + uint16_t reserved1[18]; + uint16_t num_levels; + uint16_t num_pictures; + uint16_t num_titles; + uint16_t num_fmvs; + uint16_t num_cutscenes; + uint16_t num_demos; + uint16_t title_track; + int16_t single_level; + uint16_t reserved2[16]; + uint16_t flags; + uint16_t reserved3[3]; + uint8_t cypher_code; + uint8_t language; + uint8_t secret_track; + uint8_t level_complete_track; + uint16_t reserved4[2]; +} GAME_FLOW; + typedef struct __unaligned OBJECT_INFO { int16_t mesh_count; int16_t mesh_idx; @@ -1431,7 +1471,7 @@ typedef enum LARA_MESH { # game/cinema.c 00411F50 0000000A - void __cdecl Game_SetCutsceneTrack(int32_t track); -00411F60 00000112 - int32_t __cdecl Game_Cutscene_Start(int32_t level_num); +00411F60 00000112 * int32_t __cdecl Game_Cutscene_Start(int32_t level_num); 00412080 00000093 -R void __cdecl Misc_InitCinematicRooms(void); 00412120 0000016F - int32_t __cdecl Game_Cutscene_Control(int32_t nframes); 00412290 00000138 + void __cdecl Camera_UpdateCutscene(void); @@ -1489,7 +1529,7 @@ typedef enum LARA_MESH { 00416830 000000DA - void __cdecl Control_TriggerMusicNormalTrack(int16_t value, int16_t flags, int16_t type); # game/demo.c -00416910 00000059 - int32_t __cdecl Demo_Control(int32_t level_num); +00416910 00000059 * int32_t __cdecl Demo_Control(int32_t level_num); 00416970 000001B0 - int32_t __cdecl Demo_Start(int32_t level_num); 00416B20 000000CD - void __cdecl Demo_LoadLaraPos(void); 00416BF0 0000002D - void __cdecl Demo_GetInput(void); @@ -1623,9 +1663,9 @@ typedef enum LARA_MESH { 0041F670 000003BA -R void __cdecl WarriorControl(int16_t item_num); # game/gameflow.c -0041FA60 000001E9 -R int32_t __cdecl GF_LoadScriptFile(char *fname); -0041FC50 0000001F -R int32_t __cdecl GF_DoFrontEndSequence(void); -0041FC70 00000066 -R int32_t __cdecl GF_DoLevelSequence(int32_t level, int32_t type); +0041FA60 000001E9 *R int32_t __cdecl GF_LoadScriptFile(char *fname); +0041FC50 0000001F *R int32_t __cdecl GF_DoFrontEndSequence(void); +0041FC70 00000066 *R int32_t __cdecl GF_DoLevelSequence(int32_t level, int32_t type); 0041FCE0 0000047C -R int32_t __cdecl GF_InterpretSequence(int16_t *ptr, int32_t type, int32_t seq_type); 004201C0 00000CD3 -R void __cdecl GF_ModifyInventory(int32_t level, int32_t type); @@ -2045,7 +2085,7 @@ typedef enum LARA_MESH { 00438EF0 000001DC -R void __cdecl MouseControl(int16_t item_num); # game/savegame.c -004390E0 00000062 -R void __cdecl InitialiseStartInfo(void); +004390E0 00000062 *R void __cdecl InitialiseStartInfo(void); 00439150 000000DB -R void __cdecl ModifyStartInfo(int32_t level_num); 00439230 00000201 -R void __cdecl CreateStartInfo(int32_t level_num); 00439440 0000052B -R void __cdecl CreateSaveGameInfo(void); @@ -2099,7 +2139,7 @@ typedef enum LARA_MESH { 0043F860 0000005E - void __cdecl Sound_StopEffect(int32_t sample_id); 0043F8C0 00000086 - void __cdecl Sound_UpdateContinued(void); 0043F950 00000024 - void __cdecl Sound_Shutdown(void); -0043F980 0000002A - void __cdecl Sound_Init(void); +0043F980 0000002A * void __cdecl Sound_Init(void); # game/sphere.c 0043F9B0 00000128 -R int32_t __cdecl TestCollision(struct ITEM_INFO *item, struct ITEM_INFO *lara_item); @@ -2283,7 +2323,7 @@ typedef enum LARA_MESH { 00447810 00000062 -R void __cdecl IncreaseScreenSize(void); 00447880 00000062 -R void __cdecl DecreaseScreenSize(void); 004478F0 0000009F -R void __cdecl setup_screen_size(void); -00447990 00000034 -R void __cdecl TempVideoAdjust(int32_t hires, double sizer); +00447990 00000034 *R void __cdecl TempVideoAdjust(int32_t hires, double sizer); 004479D0 00000039 -R void __cdecl TempVideoRemove(void); 00447A10 00000035 -R void __cdecl S_FadeInInventory(BOOL isFade); 00447A50 00000027 -R void __cdecl S_FadeOutInventory(BOOL isFade); @@ -2370,13 +2410,13 @@ typedef enum LARA_MESH { 0044C240 00000116 -R void __cdecl S_DrawScreenBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE color_idx, const struct GOURAUD_OUTLINE *gour, uint16_t flags); 0044C360 0000002E -R void __cdecl S_DrawScreenFBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE color_idx, const struct GOURAUD_FILL *gour, uint16_t flags); 0044C390 0000000F -R void __cdecl S_FinishInventory(void); -0044C3A0 00000043 -R void __cdecl S_FadeToBlack(void); -0044C3F0 00000057 -R void __cdecl S_Wait(int32_t timeout, BOOL inputCheck); +0044C3A0 00000043 *R void __cdecl S_FadeToBlack(void); +0044C3F0 00000057 *R void __cdecl S_Wait(int32_t timeout, BOOL inputCheck); 0044C450 0000000E -R bool __cdecl S_PlayFMV(LPCTSTR fileName); 0044C460 00000013 -R bool __cdecl S_IntroFMV(LPCTSTR fileName1, LPCTSTR fileName2); 0044C480 00000144 -R int16_t __cdecl StartGame(int32_t levelID, GF_LEVEL_TYPE levelType); 0044C5D0 0000009A -R int32_t __cdecl GameLoop(BOOL demoMode); -0044C670 00000006 -R int32_t __cdecl LevelCompleteSequence(void); +0044C670 00000006 *R int32_t __cdecl LevelCompleteSequence(void); 0044C680 000001C2 -R int32_t __cdecl LevelStats(int32_t levelID); 0044C850 00000113 -R int32_t __cdecl GameStats(int32_t levelID); 0044C970 0000001E * int32_t __cdecl Random_GetControl(void); @@ -2386,7 +2426,7 @@ typedef enum LARA_MESH { 0044C9D0 00000044 -R void __cdecl GetValidLevelsList(REQUEST_INFO *req); 0044CA20 0000004C -R void __cdecl GetSavedGamesList(REQUEST_INFO *req); 0044CA70 00000233 -R void __cdecl DisplayCredits(void); -0044CCB0 00000165 -R BOOL __cdecl S_FrontEndCheck(void); +0044CCB0 00000165 *R BOOL __cdecl S_FrontEndCheck(void); 0044CE20 00000114 -R int32_t __cdecl S_SaveGame(const void *save_data, uint32_t save_size, int32_t slot_num); 0044CF40 00000096 -R int32_t __cdecl S_LoadGame(void *save_data, uint32_t save_size, int32_t slot_num); 0044CFE0 00000128 -R void __cdecl HWR_InitState(void); @@ -2403,7 +2443,7 @@ typedef enum LARA_MESH { 0044D570 00000035 -R void __cdecl HWR_GetPageHandles(void); 0044D5B0 00000019 -R bool __cdecl HWR_VertexBufferFull(void); 0044D5E0 00000022 -R bool __cdecl HWR_Init(void); -0044D610 0000005C -R BOOL __cdecl S_InitialiseSystem(void); +0044D610 0000005C *R BOOL __cdecl S_InitialiseSystem(void); 0044D670 00000011 * void __cdecl GameBuf_Shutdown(void); 0044D690 00000021 -R void __cdecl init_game_malloc(void); 0044D6C0 0000006C -R void *__cdecl game_malloc(DWORD allocSize, DWORD bufIndex); @@ -2411,7 +2451,7 @@ typedef enum LARA_MESH { 0044D780 000000E8 -R void __cdecl CalculateWibbleTable(void); 0044D870 0000007F -R void __cdecl S_SeedRandom(void); 0044D8F0 00000120 -R BOOL __cdecl Key(KEYMAP keyMap); -0044DA10 00000AC4 -R bool __cdecl S_UpdateInput(void); +0044DA10 00000AC4 *R bool __cdecl S_UpdateInput(void); 0044E4E0 0000003C -R int32_t __cdecl RenderErrorBox(int32_t errorCode); 0044E520 000001D6 -R int32_t __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int32_t nShowCmd); 0044E6F0 00000001 x sub_44E6F0 @@ -2440,11 +2480,11 @@ typedef enum LARA_MESH { 00450AA0 0000003B -R void __cdecl S_RemoveCtrlText(void); 00450AE0 00000006 -R int32_t __cdecl GetRenderHeight(void); 00450AF0 00000006 -R int32_t __cdecl GetRenderWidth(void); -00450B00 000000E4 -R void __cdecl S_InitialisePolyList(BOOL clearBackBuffer); -00450BF0 00000036 -R DWORD __cdecl S_DumpScreen(void); +00450B00 000000E4 *R void __cdecl S_InitialisePolyList(BOOL clearBackBuffer); +00450BF0 00000036 *R DWORD __cdecl S_DumpScreen(void); 00450C30 0000000B -R void __cdecl S_ClearScreen(void); 00450C40 00000037 -R void __cdecl S_InitialiseScreen(GF_LEVEL_TYPE levelType); -00450C80 00000089 -R void __cdecl S_OutputPolyList(void); +00450C80 00000089 *R void __cdecl S_OutputPolyList(void); 00450CC0 00000270 -R int32_t __cdecl S_GetObjectBounds(int16_t *bPtr); 00450F30 00000046 -R void __cdecl S_InsertBackPolygon(int32_t x0, int32_t y0, int32_t x1, int32_t y1); 00450F80 000001F1 -R void __cdecl S_PrintShadow(int16_t radius, int16_t *bPtr, ITEM_INFO *item); @@ -2458,15 +2498,15 @@ typedef enum LARA_MESH { 00451C90 00000051 -R void __cdecl S_SetupBelowWater(BOOL underwater); 00451CF0 00000021 -R void __cdecl S_SetupAboveWater(BOOL underwater); 00451D20 000000B1 -R void __cdecl S_AnimateTextures(int32_t nTicks); -00451DE0 00000105 -R void __cdecl S_DisplayPicture(LPCTSTR fileName, BOOL isTitle); +00451DE0 00000105 *R void __cdecl S_DisplayPicture(LPCTSTR fileName, BOOL isTitle); 00451EF0 0000007E -R void __cdecl S_SyncPictureBufferPalette(void); -00451F70 0000001C -R void __cdecl S_DontDisplayPicture(void); +00451F70 0000001C *R void __cdecl S_DontDisplayPicture(void); 00451F80 0000000D -R void __cdecl ScreenDump(void); 00451F90 00000010 -R void __cdecl ScreenPartialDump(void); -00451FA0 000001C9 -R void __cdecl FadeToPal(int32_t fadeValue, RGB888 *palette); +00451FA0 000001C9 *R void __cdecl FadeToPal(int32_t fadeValue, RGB888 *palette); 00452170 00000026 -R void __cdecl ScreenClear(bool isPhdWinSize); 004521A0 000000AB -R void __cdecl S_CopyScreenToBuffer(void); -00452250 00000254 -R void __cdecl S_CopyBufferToScreen(void); +00452250 00000254 *R void __cdecl S_CopyBufferToScreen(void); 004522A0 000000FA -R BOOL __cdecl DecompPCX(LPCBYTE pcx, DWORD pcxSize, LPBYTE pic, RGB888 *pal); 004523A0 00000005 -R sub_4523A0 004523B0 00000001 -R sub_4523B0 @@ -2505,11 +2545,11 @@ typedef enum LARA_MESH { 004548B0 00000093 -R void __cdecl SE_AdvancedDlgUpdate(HWND hwndDlg); 00454950 0000000E -R void __cdecl SE_AdvancedDlgInit(HWND hwndDlg); 00454960 00000011 -R HWND __cdecl SE_FindSetupDialog(void); -00454980 000002D0 -R BOOL __cdecl GameMain(void); -00454C50 00000110 -R int16_t __cdecl TitleSequence(void); +00454980 000002D0 + BOOL __cdecl Shell_Main(void); +00454C50 00000110 *R int16_t __cdecl TitleSequence(void); 00454D60 0000032D -R void __cdecl CheckCheatMode(void); -004550C0 0000007D -R void __cdecl S_SaveSettings(void); -00455140 000000DB -R void __cdecl S_LoadSettings(void); +004550C0 0000007D *R void __cdecl S_SaveSettings(void); +00455140 000000DB *R void __cdecl S_LoadSettings(void); 00455220 00000046 + int32_t __cdecl S_Audio_Sample_OutPlay(int32_t sample_id, uint16_t volume, int32_t pitch, int32_t pan); 00455270 0000002A + int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); 004552A0 00000026 + int32_t __cdecl S_Audio_Sample_CalculateSamplePan(int16_t pan); @@ -2621,6 +2661,8 @@ typedef enum LARA_MESH { 00465E20 - void (*__cdecl g_LaraCollisionRoutines[71])(struct ITEM_INFO *item, struct COLL_INFO *coll); 00466290 - int8_t g_TextSpacing[80]; 004662E0 - int8_t g_TextASCIIMap[]; +00466480 - double g_GameSizer = 1.0; +00466488 - double g_GameSizerCopy = 1.0; 00467DD0 + const int32_t g_AtanBaseTable[8]; 00467DF0 + const int16_t g_AtanAngleTable[0x800]; 00468DF4 + const int16_t g_SinTable[0x402]; @@ -2630,6 +2672,7 @@ typedef enum LARA_MESH { 0046C30C - int32_t g_XGenY2; 0046C310 - struct GOURAUD_ENTRY g_GouraudTable[256]; 0046E310 - int32_t g_PhdWinTop; +0046E318 - struct PHD_SPRITE g_PhdSprites[512]; 00470318 - int32_t g_LsAdder; 0047031C - float g_FltWinBottom; 00470320 - float g_FltResZBuf; @@ -2685,7 +2728,7 @@ typedef enum LARA_MESH { 004BF3D8 - int32_t g_PhdScreenWidth; 004BF3DC - int32_t g_LsDivider; 004BF3E0 - struct PHD_VBUF g_PhdVBuf[1500]; -004CAF60 - void *g_XBuffer; +004CAF60 - void *g_XBuffer; // no-dereferencing 004D6AE0 - uint8_t *g_TexturePageBuffer8[32]; 004D6B60 - float g_FltWinRight; 004D6B68 - struct PHD_VECTOR g_LsVectorView; @@ -2702,13 +2745,16 @@ typedef enum LARA_MESH { 004D7380 - PALETTEENTRY g_GamePalette16[256]; 004D7780 - int32_t g_CineFrameCurrent; 004D778C - int32_t g_IsChunkyCamera; +004D7794 - int32_t g_NoInputCounter; 004D77A0 - int32_t g_LOSNumRooms = 0; 004D77AC - int32_t g_IsDemoLevelType; +004D780C - int8_t g_GF_StartGame; 004D7C38 - int32_t g_LevelItemCount; 004D7C80 - int32_t g_SoundTrackIds[128]; 004D7EBC - LPDIRECT3DDEVICE2 g_D3DDev; 004D7F10 - HWND g_GameWindowHandle; 004D8378 - uint8_t g_IsGameToExit; +004D8568 - int32_t g_ScreenSizer; 004D8570 - DWORD g_SampleFreqs[256]; 004D8970 - struct SOUND_ADAPTER_LIST g_SoundAdapterList; 004D8980 - LPDIRECTSOUNDBUFFER g_SampleBuffers[256]; @@ -2723,12 +2769,17 @@ typedef enum LARA_MESH { 004D92BC - LPDDS g_PictureBufferSurface; 004D92C0 - LPDDS g_ZBufferSurface; 004D92C8 - LPDDS g_PrimaryBufferSurface; +004D934C - int32_t g_UVAdd; +004D9351 - int8_t g_GameVid_IsWindowedVGA; 004D9EC4 - int32_t g_LevelComplete; 004D9ED8 - D3DTLVERTEX g_HWR_VertexBuffer[0x2000]; 00519EE0 - HWR_TEX_HANDLE g_HWR_PageHandles[32]; 00519F60 - D3DTLVERTEX *g_HWR_VertexPtr; +0051A0CC - void *g_GameMemoryPtr; 0051A208 - int32_t g_Input; +0051A20C - int8_t g_IsVidModeLock; 0051B918 - RECT g_PhdWinRect; +0051B928 - int32_t g_HiRes; 0051B930 - RGB888 g_GamePalette8[256]; 0051BCC0 - struct APP_SETTINGS g_SavedAppSettings; 0051BD20 - char g_ErrorMessage[128]; @@ -2748,6 +2799,7 @@ typedef enum LARA_MESH { 005207C8 - int16_t g_NextItemActive; 005207CA - int16_t g_NextEffectActive; 005207CC - int16_t g_PrevItemActive; +00521DE0 - struct GAME_FLOW g_GameFlow; 00521FDC - int32_t g_SoundFxCount; 00522000 - struct OBJECT_INFO g_Objects[265]; 005252B0 - int16_t **g_Meshes; @@ -2769,6 +2821,3 @@ typedef enum LARA_MESH { 00526314 - int16_t g_CineFrameIdx; 00526320 - struct CAMERA_INFO g_Camera; 005263CC - struct BOX_INFO *g_Boxes; -0046E318 - struct PHD_SPRITE g_PhdSprites[512]; -004D934C - int32_t g_UVAdd; -004D9351 - int8_t g_GameVid_IsWindowedVGA; diff --git a/src/game/shell.c b/src/game/shell.c index 674486ac..93768cbe 100644 --- a/src/game/shell.c +++ b/src/game/shell.c @@ -3,6 +3,142 @@ #include "global/funcs.h" #include "global/vars.h" +#include + +// TODO: refactor the hell out of me +BOOL __cdecl Shell_Main(void) +{ + g_HiRes = 0; + g_ScreenSizer = 0; + g_GameSizer = 1.0; + g_GameSizerCopy = 1.0; + + if (!S_InitialiseSystem()) { + return false; + } + + if (!GF_LoadScriptFile("data\\tombPC.dat")) { + Shell_ExitSystem("GameMain: could not load script file"); + return false; + } + + Sound_Init(); + InitialiseStartInfo(); + S_FrontEndCheck(); + S_LoadSettings(); + + g_HiRes = -1; + g_GameMemoryPtr = GlobalAlloc(0, 0x380000u); + + if (!g_GameMemoryPtr) { + strcpy(g_ErrorMessage, "GameMain: could not allocate malloc_buffer"); + return false; + } + + g_HiRes = 0; + TempVideoAdjust(1, 1.0); + S_UpdateInput(); + + g_IsVidModeLock = 1; + S_DisplayPicture("data\\legal.pcx", 0); + S_InitialisePolyList(0); + S_CopyBufferToScreen(); + S_OutputPolyList(); + S_DumpScreen(); + FadeToPal(30, g_GamePalette8); + S_Wait(180, 1); + S_FadeToBlack(); + S_DontDisplayPicture(); + g_IsVidModeLock = 0; + + bool is_frontend_fail = GF_DoFrontEndSequence(); + if (g_IsGameToExit) { + return true; + } + + if (is_frontend_fail == 1) { + strcpy(g_ErrorMessage, "GameMain: failed in GF_DoFrontEndSequence()"); + return false; + } + + S_FadeToBlack(); + int16_t gf_option = g_GameFlow.first_option; + g_NoInputCounter = 0; + + bool is_loop_continued = true; + while (is_loop_continued) { + const int16_t gf_dir = gf_option & 0xFF00; + const int16_t gf_param = gf_option & 0x00FF; + + switch (gf_dir) { + case GFD_START_GAME: + if (g_GameFlow.single_level >= 0) { + gf_option = GF_DoLevelSequence(g_GameFlow.single_level, 1); + } else { + if (gf_param > g_GameFlow.num_levels) { + sprintf( + g_ErrorMessage, + "GameMain: STARTGAME with invalid level number (%d)", + gf_param); + return false; + } + gf_option = GF_DoLevelSequence(gf_param, 1); + } + break; + + case GFD_START_SAVED_GAME: + S_LoadGame(&g_SaveGame, sizeof(SAVEGAME_INFO), gf_param); + if (g_SaveGame.current_level > g_GameFlow.num_levels) { + sprintf( + g_ErrorMessage, + "GameMain: STARTSAVEDGAME with invalid level number (%d)", + g_SaveGame.current_level); + return false; + } + gf_option = GF_DoLevelSequence(g_SaveGame.current_level, 2); + break; + + case GFD_START_CINE: + Game_Cutscene_Start(gf_param); + gf_option = GFD_EXIT_TO_TITLE; + break; + + case GFD_START_DEMO: + gf_option = Demo_Control(-1); + break; + + case GFD_LEVEL_COMPLETE: + gf_option = LevelCompleteSequence(); + break; + + case GFD_EXIT_TO_TITLE: + case GFD_EXIT_TO_OPTION: + if (g_GameFlow.flags & GFF_TITLE_DISABLED) { + if (g_GameFlow.title_replace < 0 + || g_GameFlow.title_replace == GFD_EXIT_TO_TITLE) { + strcpy( + g_ErrorMessage, + "GameMain Failed: Title disabled & no replacement"); + return false; + } + gf_option = g_GameFlow.title_replace; + } else { + gf_option = TitleSequence(); + g_GF_StartGame = 1; + } + break; + + default: + is_loop_continued = false; + break; + } + } + + S_SaveSettings(); + GameBuf_Shutdown(); + return true; +} + void __cdecl Shell_ExitSystem(const char *message) { GameBuf_Shutdown(); diff --git a/src/game/shell.h b/src/game/shell.h index 071b0c1c..703a65b4 100644 --- a/src/game/shell.h +++ b/src/game/shell.h @@ -1,3 +1,6 @@ #pragma once +#include "global/types.h" + +BOOL __cdecl Shell_Main(void); void __cdecl Shell_ExitSystem(const char *message); diff --git a/src/global/funcs.h b/src/global/funcs.h index 9397accc..38ffb6aa 100644 --- a/src/global/funcs.h +++ b/src/global/funcs.h @@ -782,7 +782,6 @@ #define SE_AdvancedDlgUpdate ((void __cdecl (*)(HWND hwndDlg))0x004548B0) #define SE_AdvancedDlgInit ((void __cdecl (*)(HWND hwndDlg))0x00454950) #define SE_FindSetupDialog ((HWND __cdecl (*)(void))0x00454960) -#define GameMain ((BOOL __cdecl (*)(void))0x00454980) #define TitleSequence ((int16_t __cdecl (*)(void))0x00454C50) #define CheckCheatMode ((void __cdecl (*)(void))0x00454D60) #define S_SaveSettings ((void __cdecl (*)(void))0x004550C0) diff --git a/src/global/types.h b/src/global/types.h index acb51f10..d6105aef 100644 --- a/src/global/types.h +++ b/src/global/types.h @@ -536,17 +536,17 @@ typedef struct ITEM_INFO { int16_t carried_item; void *data; struct PHD_3DPOS pos; - // clang-format on - uint16_t active : 1; // 0x0001 - uint16_t status : 2; // 0x0002…0x0004 - uint16_t gravity : 1; // 0x0008 - uint16_t hit_status : 1; // 0x0010 - uint16_t collidable : 1; // 0x0020 - uint16_t looked_at : 1; // 0x0040 - uint16_t dynamic_light : 1; // 0x0080 - uint16_t killed : 1; // 0x0100 - uint16_t pad : 7; // 0x0200…0x8000 // clang-format off + uint16_t active: 1; // 0x0001 + uint16_t status: 2; // 0x0002…0x0004 + uint16_t gravity: 1; // 0x0008 + uint16_t hit_status: 1; // 0x0010 + uint16_t collidable: 1; // 0x0020 + uint16_t looked_at: 1; // 0x0040 + uint16_t dynamic_light: 1; // 0x0080 + uint16_t killed: 1; // 0x0100 + uint16_t pad: 7; // 0x0200…0x8000 + // clang-format on } ITEM_INFO; typedef struct STATISTICS_INFO { @@ -889,6 +889,65 @@ typedef struct BOX_INFO { uint16_t overlap_index; } BOX_INFO; +// clang-format off +typedef enum GAME_FLOW_DIR { + GFD_START_GAME = 0x0000, + GFD_START_SAVED_GAME = 0x0100, + GFD_START_CINE = 0x0200, + GFD_START_FMV = 0x0300, + GFD_START_DEMO = 0x0400, + GFD_EXIT_TO_TITLE = 0x0500, + GFD_LEVEL_COMPLETE = 0x0600, + GFD_EXIT_GAME = 0x0700, + GFD_EXIT_TO_OPTION = 0x0800, + GFD_TITLE_DESELECT = 0x0900, +} GAME_FLOW_DIR; +// clang-format on + +// clang-format off +typedef enum GAME_FLOW_FLAG { + GFF_DEMO_VERSION = 0x0001, + GFF_TITLE_DISABLED = 0x0002, + GFF_CHEAT_MODE_CHECK_DISABLED = 0x0004, + GFF_NO_INPUT_TIMEOUT = 0x0008, + GFF_LOAD_SAVE_DISABLED = 0x0010, + GFF_SCREEN_SIZING_DISABLED = 0x0020, + GFF_LOCKOUT_OPTION_RING = 0x0040, + GFF_DOZY_CHEAT_ENABLED = 0x0080, + GFF_USE_SECURITY_TAG = 0x0100, + GFF_GYM_ENABLED = 0x0200, + GFF_SELECT_ANY_LEVEL = 0x0400, + GFF_ENABLE_CHEAT_CODE = 0x0800, +} GAME_FLOW_FLAG; +// clang-format on + +typedef struct GAME_FLOW { + int32_t first_option; + int32_t title_replace; + int32_t on_death_demo_mode; + int32_t on_death_in_game; + int32_t no_input_time; + int32_t on_demo_interrupt; + int32_t on_demo_end; + uint16_t reserved1[18]; + uint16_t num_levels; + uint16_t num_pictures; + uint16_t num_titles; + uint16_t num_fmvs; + uint16_t num_cutscenes; + uint16_t num_demos; + uint16_t title_track; + int16_t single_level; + uint16_t reserved2[16]; + uint16_t flags; + uint16_t reserved3[3]; + uint8_t cypher_code; + uint8_t language; + uint8_t secret_track; + uint8_t level_complete_track; + uint16_t reserved4[2]; +} GAME_FLOW; + typedef struct OBJECT_INFO { int16_t mesh_count; int16_t mesh_idx; @@ -1072,48 +1131,55 @@ typedef struct CINE_FRAME { int16_t roll; } CINE_FRAME; +// clang-format off typedef enum ITEM_FLAG { - IF_ONESHOT = 0x0100, + IF_ONESHOT = 0x0100, IF_CODE_BITS = 0x3E00, - IF_REVERSE = 0x4000, + IF_REVERSE = 0x4000, IF_INVISIBLE = 0x0100, - IF_KILLED = 0x8000, + IF_KILLED = 0x8000, } ITEM_FLAG; +// clang-format on +// clang-format off typedef enum ITEM_STATUS { - IS_INACTIVE = 0, - IS_ACTIVE = 1, + IS_INACTIVE = 0, + IS_ACTIVE = 1, IS_DEACTIVATED = 2, - IS_INVISIBLE = 3, + IS_INVISIBLE = 3, } ITEM_STATUS; +// clang-format on +// clang-format off typedef enum INPUT_STATE { - IN_FORWARD = 0x00000001, - IN_BACK = 0x00000002, - IN_LEFT = 0x00000004, - IN_RIGHT = 0x00000008, - IN_JUMP = 0x00000010, - IN_DRAW = 0x00000020, - IN_ACTION = 0x00000040, - IN_SLOW = 0x00000080, - IN_OPTION = 0x00000100, - IN_LOOK = 0x00000200, - IN_STEP_LEFT = 0x00000400, - IN_STEP_RIGHT = 0x00000800, - IN_ROLL = 0x00001000, - IN_PAUSE = 0x00002000, - IN_RESERVED1 = 0x00004000, - IN_RESERVED2 = 0x00008000, - IN_DOZY_CHEAT = 0x00010000, + IN_FORWARD = 0x00000001, + IN_BACK = 0x00000002, + IN_LEFT = 0x00000004, + IN_RIGHT = 0x00000008, + IN_JUMP = 0x00000010, + IN_DRAW = 0x00000020, + IN_ACTION = 0x00000040, + IN_SLOW = 0x00000080, + IN_OPTION = 0x00000100, + IN_LOOK = 0x00000200, + IN_STEP_LEFT = 0x00000400, + IN_STEP_RIGHT = 0x00000800, + IN_ROLL = 0x00001000, + IN_PAUSE = 0x00002000, + IN_RESERVED1 = 0x00004000, + IN_RESERVED2 = 0x00008000, + IN_DOZY_CHEAT = 0x00010000, IN_STUFF_CHEAT = 0x00020000, - IN_DEBUG_INFO = 0x00040000, - IN_FLARE = 0x00080000, - IN_SELECT = 0x00100000, - IN_DESELECT = 0x00200000, - IN_SAVE = 0x00400000, - IN_LOAD = 0x00800000, + IN_DEBUG_INFO = 0x00040000, + IN_FLARE = 0x00080000, + IN_SELECT = 0x00100000, + IN_DESELECT = 0x00200000, + IN_SAVE = 0x00400000, + IN_LOAD = 0x00800000, } INPUT_STATE; +// clang-format on +// clang-format off typedef enum LARA_ANIMATION { LA_RUN = 0, LA_WALK_FORWARD = 1, @@ -1196,129 +1262,138 @@ typedef enum LARA_ANIMATION { LA_UW_TWIST = 203, LA_PICKUP_FLARE_UW = 206, } LARA_ANIMATION; +// clang-format on +// clang-format off typedef enum LARA_STATE { - LS_WALK = 0, - LS_RUN = 1, - LS_STOP = 2, + LS_WALK = 0, + LS_RUN = 1, + LS_STOP = 2, LS_FORWARD_JUMP = 3, - LS_POSE = 4, - LS_FAST_BACK = 5, - LS_TURN_RIGHT = 6, - LS_TURN_LEFT = 7, - LS_DEATH = 8, - LS_FAST_FALL = 9, - LS_HANG = 10, - LS_REACH = 11, - LS_SPLAT = 12, - LS_TREAD = 13, - LS_LAND = 14, - LS_COMPRESS = 15, - LS_BACK = 16, - LS_SWIM = 17, - LS_GLIDE = 18, - LS_NULL = 19, - LS_FAST_TURN = 20, - LS_STEP_RIGHT = 21, - LS_STEP_LEFT = 22, - LS_HIT = 23, - LS_SLIDE = 24, - LS_BACK_JUMP = 25, - LS_RIGHT_JUMP = 26, - LS_LEFT_JUMP = 27, - LS_UP_JUMP = 28, - LS_FALL_BACK = 29, - LS_HANG_LEFT = 30, - LS_HANG_RIGHT = 31, - LS_SLIDE_BACK = 32, - LS_SURF_TREAD = 33, - LS_SURF_SWIM = 34, - LS_DIVE = 35, - LS_PUSH_BLOCK = 36, - LS_PULL_BLOCK = 37, - LS_PP_READY = 38, - LS_PICKUP = 39, - LS_SWITCH_ON = 40, - LS_SWITCH_OFF = 41, - LS_USE_KEY = 42, - LS_USE_PUZZLE = 43, - LS_UW_DEATH = 44, - LS_ROLL = 45, - LS_SPECIAL = 46, - LS_SURF_BACK = 47, - LS_SURF_LEFT = 48, - LS_SURF_RIGHT = 49, - LS_USE_MIDAS = 50, - LS_DIE_MIDAS = 51, - LS_SWAN_DIVE = 52, - LS_FAST_DIVE = 53, - LS_GYMNAST = 54, - LS_WATER_OUT = 55, + LS_POSE = 4, + LS_FAST_BACK = 5, + LS_TURN_RIGHT = 6, + LS_TURN_LEFT = 7, + LS_DEATH = 8, + LS_FAST_FALL = 9, + LS_HANG = 10, + LS_REACH = 11, + LS_SPLAT = 12, + LS_TREAD = 13, + LS_LAND = 14, + LS_COMPRESS = 15, + LS_BACK = 16, + LS_SWIM = 17, + LS_GLIDE = 18, + LS_NULL = 19, + LS_FAST_TURN = 20, + LS_STEP_RIGHT = 21, + LS_STEP_LEFT = 22, + LS_HIT = 23, + LS_SLIDE = 24, + LS_BACK_JUMP = 25, + LS_RIGHT_JUMP = 26, + LS_LEFT_JUMP = 27, + LS_UP_JUMP = 28, + LS_FALL_BACK = 29, + LS_HANG_LEFT = 30, + LS_HANG_RIGHT = 31, + LS_SLIDE_BACK = 32, + LS_SURF_TREAD = 33, + LS_SURF_SWIM = 34, + LS_DIVE = 35, + LS_PUSH_BLOCK = 36, + LS_PULL_BLOCK = 37, + LS_PP_READY = 38, + LS_PICKUP = 39, + LS_SWITCH_ON = 40, + LS_SWITCH_OFF = 41, + LS_USE_KEY = 42, + LS_USE_PUZZLE = 43, + LS_UW_DEATH = 44, + LS_ROLL = 45, + LS_SPECIAL = 46, + LS_SURF_BACK = 47, + LS_SURF_LEFT = 48, + LS_SURF_RIGHT = 49, + LS_USE_MIDAS = 50, + LS_DIE_MIDAS = 51, + LS_SWAN_DIVE = 52, + LS_FAST_DIVE = 53, + LS_GYMNAST = 54, + LS_WATER_OUT = 55, LS_CLIMB_STANCE = 56, - LS_CLIMBING = 57, - LS_CLIMB_LEFT = 58, - LS_CLIMB_END = 59, - LS_CLIMB_RIGHT = 60, - LS_CLIMB_DOWN = 61, - LS_LARA_TEST1 = 62, - LS_LARA_TEST2 = 63, - LS_LARA_TEST3 = 64, - LS_WADE = 65, - LS_WATER_ROLL = 66, + LS_CLIMBING = 57, + LS_CLIMB_LEFT = 58, + LS_CLIMB_END = 59, + LS_CLIMB_RIGHT = 60, + LS_CLIMB_DOWN = 61, + LS_LARA_TEST1 = 62, + LS_LARA_TEST2 = 63, + LS_LARA_TEST3 = 64, + LS_WADE = 65, + LS_WATER_ROLL = 66, LS_FLARE_PICKUP = 67, - LS_TWIST = 68, - LS_KICK = 69, - LS_DEATH_SLIDE = 70, - LS_DUCK = 71, - LS_DUCK_ROLL = 72, - LS_DASH = 73, - LS_DASH_DIVE = 74, + LS_TWIST = 68, + LS_KICK = 69, + LS_DEATH_SLIDE = 70, + LS_DUCK = 71, + LS_DUCK_ROLL = 72, + LS_DASH = 73, + LS_DASH_DIVE = 74, LS_MONKEY_SWING = 75, - LS_MONKEYF = 76, - LS_LAST = 77, + LS_MONKEYF = 76, + LS_LAST = 77, } LARA_STATE; +// clang-format on +// clang-format off typedef enum LARA_GUN_STATE { - LGS_ARMLESS = 0, + LGS_ARMLESS = 0, LGS_HANDS_BUSY = 1, - LGS_DRAW = 2, - LGS_UNDRAW = 3, - LGS_READY = 4, - LGS_SPECIAL = 5, + LGS_DRAW = 2, + LGS_UNDRAW = 3, + LGS_READY = 4, + LGS_SPECIAL = 5, } LARA_GUN_STATE; +// clang-format on +// clang-format off typedef enum LARA_GUN_TYPE { LGT_UNARMED = 0, LGT_PISTOLS = 1, LGT_MAGNUMS = 2, - LGT_UZIS = 3, + LGT_UZIS = 3, LGT_SHOTGUN = 4, - LGT_M16 = 5, - LGT_ROCKET = 6, + LGT_M16 = 5, + LGT_ROCKET = 6, LGT_HARPOON = 7, - LGT_FLARE = 8, - LGT_SKIDOO = 9, + LGT_FLARE = 8, + LGT_SKIDOO = 9, NUM_WEAPONS = 10, } LARA_GUN_TYPE; +// clang-format on +// clang-format off typedef enum LARA_MESH { - LM_HIPS = 0, - LM_THIGH_L = 1, - LM_CALF_L = 2, - LM_FOOT_L = 3, - LM_THIGH_R = 4, - LM_CALF_R = 5, - LM_FOOT_R = 6, - LM_TORSO = 7, - LM_UARM_R = 8, - LM_LARM_R = 9, - LM_HAND_R = 10, - LM_UARM_L = 11, - LM_LARM_L = 12, - LM_HAND_L = 13, - LM_HEAD = 14, + LM_HIPS = 0, + LM_THIGH_L = 1, + LM_CALF_L = 2, + LM_FOOT_L = 3, + LM_THIGH_R = 4, + LM_CALF_R = 5, + LM_FOOT_R = 6, + LM_TORSO = 7, + LM_UARM_R = 8, + LM_LARM_R = 9, + LM_HAND_R = 10, + LM_UARM_L = 11, + LM_LARM_L = 12, + LM_HAND_L = 13, + LM_HEAD = 14, LM_NUMBER_OF = 15, } LARA_MESH; +// clang-format on // clang-format off typedef enum { diff --git a/src/global/vars.h b/src/global/vars.h index 953df2b2..81940bb7 100644 --- a/src/global/vars.h +++ b/src/global/vars.h @@ -20,6 +20,8 @@ #define g_LaraCollisionRoutines (*((void(__cdecl *(*)[71])(struct ITEM_INFO *item, struct COLL_INFO *coll))0x00465E20)) #define g_TextSpacing (*(int8_t(*)[80])0x00466290) #define g_TextASCIIMap (*(int8_t(*)[])0x004662E0) +#define g_GameSizer (*(double*)0x00466480) // = 1.0 +#define g_GameSizerCopy (*(double*)0x00466488) // = 1.0 #define g_MidSort (*(int32_t*)0x0046C300) // = 0 #define g_ViewportAspectRatio (*(float*)0x0046C304) // = 0.0f #define g_XGenY1 (*(int32_t*)0x0046C308) @@ -82,7 +84,7 @@ #define g_PhdScreenWidth (*(int32_t*)0x004BF3D8) #define g_LsDivider (*(int32_t*)0x004BF3DC) #define g_PhdVBuf (*(struct PHD_VBUF(*)[1500])0x004BF3E0) -#define g_XBuffer ((void*)0x004CAF60) +#define g_XBuffer ((void *)0x004CAF60) #define g_TexturePageBuffer8 (*(uint8_t *(*)[32])0x004D6AE0) #define g_FltWinRight (*(float*)0x004D6B60) #define g_LsVectorView (*(struct PHD_VECTOR*)0x004D6B68) @@ -99,13 +101,16 @@ #define g_GamePalette16 (*(PALETTEENTRY(*)[256])0x004D7380) #define g_CineFrameCurrent (*(int32_t*)0x004D7780) #define g_IsChunkyCamera (*(int32_t*)0x004D778C) +#define g_NoInputCounter (*(int32_t*)0x004D7794) #define g_LOSNumRooms (*(int32_t*)0x004D77A0) // = 0 #define g_IsDemoLevelType (*(int32_t*)0x004D77AC) +#define g_GF_StartGame (*(int8_t*)0x004D780C) #define g_LevelItemCount (*(int32_t*)0x004D7C38) #define g_SoundTrackIds (*(int32_t(*)[128])0x004D7C80) #define g_D3DDev (*(LPDIRECT3DDEVICE2*)0x004D7EBC) #define g_GameWindowHandle (*(HWND*)0x004D7F10) #define g_IsGameToExit (*(uint8_t*)0x004D8378) +#define g_ScreenSizer (*(int32_t*)0x004D8568) #define g_SampleFreqs (*(DWORD(*)[256])0x004D8570) #define g_SoundAdapterList (*(struct SOUND_ADAPTER_LIST*)0x004D8970) #define g_SampleBuffers (*(LPDIRECTSOUNDBUFFER(*)[256])0x004D8980) @@ -126,8 +131,11 @@ #define g_HWR_VertexBuffer (*(D3DTLVERTEX(*)[0x2000])0x004D9ED8) #define g_HWR_PageHandles (*(HWR_TEX_HANDLE(*)[32])0x00519EE0) #define g_HWR_VertexPtr (*(D3DTLVERTEX **)0x00519F60) +#define g_GameMemoryPtr (*(void **)0x0051A0CC) #define g_Input (*(int32_t*)0x0051A208) +#define g_IsVidModeLock (*(int8_t*)0x0051A20C) #define g_PhdWinRect (*(RECT*)0x0051B918) +#define g_HiRes (*(int32_t*)0x0051B928) #define g_GamePalette8 (*(RGB888(*)[256])0x0051B930) #define g_SavedAppSettings (*(struct APP_SETTINGS*)0x0051BCC0) #define g_ErrorMessage (*(char(*)[128])0x0051BD20) @@ -147,6 +155,7 @@ #define g_NextItemActive (*(int16_t*)0x005207C8) #define g_NextEffectActive (*(int16_t*)0x005207CA) #define g_PrevItemActive (*(int16_t*)0x005207CC) +#define g_GameFlow (*(struct GAME_FLOW*)0x00521DE0) #define g_SoundFxCount (*(int32_t*)0x00521FDC) #define g_Objects (*(struct OBJECT_INFO(*)[265])0x00522000) #define g_Meshes (*(int16_t ***)0x005252B0) diff --git a/src/inject_exec.c b/src/inject_exec.c index 821b0dfe..0b79ed7c 100644 --- a/src/inject_exec.c +++ b/src/inject_exec.c @@ -98,6 +98,7 @@ static void Inject_Math(void) static void Inject_Shell(void) { INJECT(1, 0x0044E890, Shell_ExitSystem); + INJECT(1, 0x00454980, Shell_Main); } static void Inject_Text(void) diff --git a/tools/generate_funcs b/tools/generate_funcs index 2b659c6f..4a6f09c4 100755 --- a/tools/generate_funcs +++ b/tools/generate_funcs @@ -138,15 +138,18 @@ def make_var_pointer_define(variable: Symbol) -> str: r"(?P\b\w+)\s*" r"(?P(?:\[[^\]]*?\])*)" r"(\s*=\s*(?P.*?))?" - r";?$", + r";?" + r"(\s*\/\/\s*(?P.*))?" + r"$", variable.signature, ): ret_type = match.group("ret_type") var_name = match.group("var_name") array_def = match.group("array_def") value_def = match.group("value_def") - if not array_def and not value_def and re.match('void\s*\*', ret_type): - return f"#define {var_name} ((void*){variable.offset_str})" + comment = match.group("comment") + if not array_def and not value_def and comment == 'no-dereferencing': + return f"#define {var_name} (({ret_type}){variable.offset_str})" if array_def: return f"#define {var_name} (*({ret_type}(*){array_def}){variable.offset_str})" elif value_def: