From d55ca283637c348c1671de62ba53da50c541057e Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sun, 20 Oct 2024 23:51:31 +0200 Subject: [PATCH 01/22] tr2: port Skidoo_CheckGetOn --- docs/tr2/progress.svg | 80 ++++++++++++++-------------- docs/tr2/progress.txt | 34 ++++++------ src/tr2/decomp/skidoo.c | 50 +++++++++++++++++ src/tr2/decomp/skidoo.h | 5 ++ src/tr2/game/lara/control.c | 2 +- src/tr2/game/objects/vehicles/boat.c | 44 +++++++-------- src/tr2/game/objects/vehicles/boat.h | 2 +- src/tr2/global/funcs.h | 31 ++++++----- src/tr2/inject_exec.c | 10 +++- src/tr2/meson.build | 1 + 10 files changed, 161 insertions(+), 98 deletions(-) create mode 100644 src/tr2/decomp/skidoo.c create mode 100644 src/tr2/decomp/skidoo.h diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index f1e9c4602..bb7677d48 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -65.84% (819) · 31.75% (395) · 0% (0) · 2.41% (30) +65.92% (820) · 31.67% (394) · 0% (0) · 2.41% (30) - - + + @@ -163,7 +163,7 @@ void __cdecl Bird_Initialise(int16_t item_num); void __cdecl Bird_Control(int16_t item_num); void __cdecl Boat_Initialise(int16_t item_num); -int32_t __cdecl Boat_CheckGeton(int16_t item_num, COLL_INFO *coll); +int32_t __cdecl Boat_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Boat_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Boat_TestWaterHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); void __cdecl Boat_DoShift(int32_t boat_num); @@ -777,27 +777,27 @@ void __cdecl Jelly_Control(int16_t item_num); void __cdecl Baracudda_Control(int16_t item_num); void __cdecl Shark_Control(int16_t item_num); -void __cdecl InitialiseSkidoo(int16_t item_num); -int32_t __cdecl SkidooCheckGeton(int16_t item_num, COLL_INFO *coll); -void __cdecl SkidooCollision(int16_t item_num, ITEM *litem, COLL_INFO *coll); -void __cdecl SkidooBaddieCollision(ITEM *skidoo); -int32_t __cdecl TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +void __cdecl Skidoo_Initialise(int16_t item_num); +int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); +void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); +void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); +int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); -void __cdecl DoSnowEffect(ITEM *skidoo); -int32_t __cdecl SkidooDynamics(ITEM *skidoo); -int32_t __cdecl SkidooUserControl(ITEM *skidoo, int32_t height, int32_t *pitch); -int32_t __cdecl SkidooCheckGetOffOK(int32_t direction); -void __cdecl SkidooAnimation(ITEM *skidoo, int32_t collide, int32_t dead); -void __cdecl SkidooExplode(ITEM *skidoo); -int32_t __cdecl SkidooCheckGetOff(void); -void __cdecl SkidooGuns(void); -int32_t __cdecl SkidooControl(void); -void __cdecl SkidooArmed_Draw(const ITEM *item); +void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); +int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); +int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); +int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); +void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); +void __cdecl Skidoo_Explode(ITEM *skidoo); +int32_t __cdecl Skidoo_CheckGetOff(void); +void __cdecl Skidoo_Guns(void); +int32_t __cdecl Skidoo_Control(void); +void __cdecl Skidoo_Armed_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); -void __cdecl SkidmanPush(ITEM *item, ITEM *lara_item, int32_t radius); +void __cdecl SkidooDriver_Push(ITEM *item, ITEM *lara_item, int32_t radius); void __cdecl SkidooDriver_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Music_GetRealTrack(int32_t track); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -70.23% · 29.45% · 0% · 0.33% +70.29% · 29.38% · 0% · 0.33% - - + + @@ -1375,14 +1375,14 @@ void __cdecl Output_InsertTrans8(const PHD_VBUF *vbuf, int16_t shade); void __cdecl Monk_Control(int16_t item_num); LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -int32_t __cdecl SkidooDynamics(ITEM *skidoo); +int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); void __cdecl Option_Sound(INVENTORY_ITEM *item); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); void __cdecl Pickup_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl GF_InterpretSequence(int16_t *ptr, GAMEFLOW_LEVEL_TYPE type, int32_t seq_type); TARGET_TYPE __cdecl Box_CalculateTarget(XYZ_32 *target, ITEM *item, LOT_INFO *lot); void __cdecl Output_InsertGT4_ZBuffered(const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2, const PHD_VBUF *vtx3, const PHD_TEXTURE *texture); -int32_t __cdecl SkidooControl(void); +int32_t __cdecl Skidoo_Control(void); void __cdecl Creature_Mood(ITEM *item, AI_INFO *info, int32_t violent); const int16_t *__cdecl Output_InsertObjectG4_Sorted(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); void __cdecl Worker2_Control(int16_t item_num); @@ -1446,7 +1446,7 @@ bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); void __cdecl Option_Detail(INVENTORY_ITEM *item); int32_t __cdecl Collide_GetSpheres(const ITEM *item, SPHERE *spheres, bool world_space); -void __cdecl SkidooArmed_Draw(const ITEM *item); +void __cdecl Skidoo_Armed_Draw(const ITEM *item); const int16_t *__cdecl Output_InsertObjectG3_ZBuffered(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); int32_t __cdecl Output_XYClipper(int32_t vtx_count, VERTEX_INFO *vtx); void __cdecl ControlMissile(int16_t fx_num); @@ -1455,7 +1455,7 @@ void __cdecl GiantYeti_Control(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); void __cdecl Lara_Initialise(int32_t type); -void __cdecl SkidooAnimation(ITEM *skidoo, int32_t collide, int32_t dead); +void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Room_DrawAllRooms(int16_t current_room); void __cdecl PuzzleHole_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl Zipline_Control(int16_t item_num); @@ -1485,7 +1485,7 @@ void __cdecl MovableBlock_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Lara_TestClimbUpPos(ITEM *item, int32_t front, int32_t right, int32_t *shift, int32_t *ledge); void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); -int32_t __cdecl SkidooCheckGetOff(void); +int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl DisplayCredits(void); void __cdecl Gun_Pistols_Undraw(LARA_GUN_TYPE weapon_type); int32_t __cdecl MovableBlock_TestPull(ITEM *item, int32_t block_height, uint16_t quadrant); @@ -1509,7 +1509,7 @@ void __cdecl CreateStartInfo(int32_t level_num); void __cdecl Bird_Control(int16_t item_num); void __cdecl BodyPart_Control(int16_t fx_num); -void __cdecl SkidooBaddieCollision(ITEM *skidoo); +void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); void __cdecl S_DrawAirBar(int32_t percent); void __cdecl Screenshot(LPDDS screen); void __cdecl MineControl(int16_t mine_num); @@ -1541,7 +1541,7 @@ BOOL __stdcall EnumDisplayAdaptersCallback(GUID *lpGUID, LPTSTR lpDriverDescription, LPTSTR lpDriverName, LPVOID lpContext); void __cdecl BGND_Make640x480(uint8_t *bitmap, RGB_888 *palette); void __cdecl D3DDeviceCreate(LPDDS lpBackBuffer); -int32_t __cdecl SkidooUserControl(ITEM *skidoo, int32_t height, int32_t *pitch); +int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); void __cdecl Item_Initialise(int16_t item_num); int32_t __cdecl Demo_Start(int32_t level_num); bool __cdecl LOT_EnableBaddieAI(int16_t item_num, bool always); @@ -1584,7 +1584,7 @@ void __cdecl Boat_DoWakeEffect(ITEM *boat); bool __cdecl TexturePageInit(TEXPAGE_DESC *page); void __cdecl Winston_Control(int16_t item_num); -int32_t __cdecl Boat_CheckGeton(int16_t item_num, COLL_INFO *coll); +int32_t __cdecl Boat_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Creature_Kill(ITEM *item, int32_t kill_anim, int32_t kill_state, int32_t lara_kill_state); int32_t __cdecl Game_Cutscene_Control(int32_t nframes); int32_t __cdecl Misc_Move3DPosTo3DPos(PHD_3DPOS *src_pos, const PHD_3DPOS *dest_pos, int32_t velocity, PHD_ANGLE ang_add); @@ -1621,7 +1621,7 @@ void __cdecl Lara_State_Run(ITEM *item, COLL_INFO *coll); int32_t __cdecl Output_ZedClipper(int32_t vtx_count, POINT_INFO *pts, VERTEX_INFO *vtx); void __cdecl Output_DrawClippedPoly_Textured(int32_t vtx_count); -void __cdecl DoSnowEffect(ITEM *skidoo); +void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); void __cdecl Lara_UseItem(GAME_OBJECT_ID object_id); void __cdecl Inv_Ring_DoMotions(RING_INFO *ring); void __cdecl DartEmitterControl(int16_t item_num); @@ -1656,10 +1656,10 @@ void __cdecl Item_Kill(int16_t item_num); void __cdecl Gun_InitialiseNewWeapon(void); void __cdecl Lara_Col_UpJump(ITEM *item, COLL_INFO *coll); -void __cdecl SkidooGuns(void); +void __cdecl Skidoo_Guns(void); void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC lpDdsd, LPVOID lpContext); -void __cdecl SkidmanPush(ITEM *item, ITEM *lara_item, int32_t radius); +void __cdecl SkidooDriver_Push(ITEM *item, ITEM *lara_item, int32_t radius); void __cdecl Jelly_Control(int16_t item_num); void __cdecl S_DrawScreenBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE color_idx, const GOURAUD_OUTLINE *gour, uint16_t flags); void __cdecl ControlCeilingSpikes(int16_t item_num); @@ -1682,7 +1682,7 @@ int32_t __cdecl Text_GetWidth(TEXTSTRING *string); int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl LOT_InitialiseSlot(int16_t item_num, int32_t slot); -int32_t __cdecl SkidooCheckGetOffOK(int32_t direction); +int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); TEXTSTRING *__cdecl Text_Create(int32_t x, int32_t y, int32_t z, const char *text); void __cdecl FallingBlock(int16_t item_num); @@ -1700,7 +1700,7 @@ int32_t __cdecl Boat_TestWaterHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl Creature_CheckBaddieOverlap(int16_t item_num); void __cdecl Flare_DrawInAir(ITEM *item); -void __cdecl SkidooCollision(int16_t item_num, ITEM *litem, COLL_INFO *coll); +void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); void __cdecl Output_DrawPoly_Gouraud(int32_t vtx_count, int32_t red, int32_t green, int32_t blue); int32_t __cdecl Lara_TestHangOnClimbWall(ITEM *item, COLL_INFO *coll); void __cdecl Gun_Rifle_Control(LARA_GUN_TYPE weapon_type); @@ -1733,7 +1733,7 @@ bool __cdecl WinVidSpinMessageLoop(bool needWait); BOOL __stdcall S_Audio_Sample_DSoundEnumCallback(LPGUID guid, LPCTSTR description, LPCTSTR module, LPVOID context); int32_t __cdecl Lara_TestWall(ITEM *item, int32_t front, int32_t right, int32_t down); -int32_t __cdecl SkidooCheckGeton(int16_t item_num, COLL_INFO *coll); +int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl FallingCeiling(int16_t item_num); BOOL __cdecl SelectDrive(void); void __cdecl ControlHotLiquid(int16_t fx_num); @@ -1819,7 +1819,7 @@ void __cdecl Lara_Col_FastBack(ITEM *item, COLL_INFO *coll); void __cdecl Lara_Col_Roll2(ITEM *item, COLL_INFO *coll); void __cdecl AssaultFinished(ITEM *item); -int32_t __cdecl TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl Lara_TestHangSwingIn(ITEM *item, PHD_ANGLE angle); int32_t __cdecl OnDrawBridge(ITEM *item, int32_t x, int32_t y); void __cdecl S_AnimateTextures(int32_t ticks); @@ -1974,7 +1974,7 @@ void __cdecl Lara_State_StepLeft(ITEM *item, COLL_INFO *coll); void __cdecl Gun_Pistols_Draw(LARA_GUN_TYPE weapon_type); void __cdecl InitialiseDyingMonk(int16_t item_num); -void __cdecl SkidooExplode(ITEM *skidoo); +void __cdecl Skidoo_Explode(ITEM *skidoo); int32_t __cdecl WinGameStart(void); void __cdecl Gun_Rifle_FireM16(bool running); void __cdecl Matrix_TranslateAbs(int32_t x, int32_t y, int32_t z); @@ -2191,7 +2191,7 @@ void __cdecl lara_normal_effect(ITEM *item); void __cdecl Inv_Ring_Light(RING_INFO *ring); void __cdecl Lara_State_FastFall(ITEM *item, COLL_INFO *coll); -void __cdecl InitialiseSkidoo(int16_t item_num); +void __cdecl Skidoo_Initialise(int16_t item_num); bool __cdecl WinVidInit(void); void __cdecl Option_Controls_DefaultConflict(void); void __cdecl UpdateTicks(void); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index f3a1a6e5a..6d231d286 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -2940,7 +2940,7 @@ typedef enum { # game/boat.c 0x0040CB30 0x003C + void __cdecl Boat_Initialise(int16_t item_num); -0x0040CB70 0x0170 + int32_t __cdecl Boat_CheckGeton(int16_t item_num, COLL_INFO *coll); +0x0040CB70 0x0170 + int32_t __cdecl Boat_CheckGetOn(int16_t item_num, COLL_INFO *coll); 0x0040CCE0 0x015E + void __cdecl Boat_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); 0x0040CE40 0x00F8 + int32_t __cdecl Boat_TestWaterHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); 0x0040CF40 0x01C1 + void __cdecl Boat_DoShift(int32_t boat_num); @@ -3634,27 +3634,27 @@ typedef enum { 0x0043CBA0 0x027C -R void __cdecl Shark_Control(int16_t item_num); # game/skidoo.c -0x0043CE30 0x0040 -R void __cdecl InitialiseSkidoo(int16_t item_num); -0x0043CE70 0x00E1 -R int32_t __cdecl SkidooCheckGeton(int16_t item_num, COLL_INFO *coll); -0x0043CF60 0x00F8 -R void __cdecl SkidooCollision(int16_t item_num, ITEM *litem, COLL_INFO *coll); -0x0043D060 0x01F9 -R void __cdecl SkidooBaddieCollision(ITEM *skidoo); -0x0043D260 0x00B2 -R int32_t __cdecl TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +0x0043CE30 0x0040 -R void __cdecl Skidoo_Initialise(int16_t item_num); +0x0043CE70 0x00E1 +R int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); +0x0043CF60 0x00F8 -R void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); +0x0043D060 0x01F9 -R void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); +0x0043D260 0x00B2 -R int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); 0x0043D320 0x027C -R int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); 0x0043D5A0 0x0054 -R int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); 0x0043D600 0x0090 -R int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); -0x0043D690 0x0140 -R void __cdecl DoSnowEffect(ITEM *skidoo); -0x0043D7D0 0x049E -R int32_t __cdecl SkidooDynamics(ITEM *skidoo); -0x0043DC70 0x01B6 -R int32_t __cdecl SkidooUserControl(ITEM *skidoo, int32_t height, int32_t *pitch); -0x0043DE30 0x0106 -R int32_t __cdecl SkidooCheckGetOffOK(int32_t direction); -0x0043DF40 0x02B9 -R void __cdecl SkidooAnimation(ITEM *skidoo, int32_t collide, int32_t dead); -0x0043E220 0x007C -R void __cdecl SkidooExplode(ITEM *skidoo); -0x0043E2A0 0x0233 -R int32_t __cdecl SkidooCheckGetOff(void); -0x0043E4E0 0x011B -R void __cdecl SkidooGuns(void); -0x0043E600 0x0440 -R int32_t __cdecl SkidooControl(void); -0x0043EA60 0x02D5 -R void __cdecl SkidooArmed_Draw(const ITEM *item); +0x0043D690 0x0140 -R void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); +0x0043D7D0 0x049E -R int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); +0x0043DC70 0x01B6 -R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); +0x0043DE30 0x0106 -R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); +0x0043DF40 0x02B9 -R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); +0x0043E220 0x007C -R void __cdecl Skidoo_Explode(ITEM *skidoo); +0x0043E2A0 0x0233 -R int32_t __cdecl Skidoo_CheckGetOff(void); +0x0043E4E0 0x011B -R void __cdecl Skidoo_Guns(void); +0x0043E600 0x0440 -R int32_t __cdecl Skidoo_Control(void); +0x0043EA60 0x02D5 -R void __cdecl Skidoo_Armed_Draw(const ITEM *item); 0x0043ED40 0x007F -R void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 - void __cdecl SkidooDriver_Control(int16_t rider_num); -0x0043F1D0 0x0119 -R void __cdecl SkidmanPush(ITEM *item, ITEM *lara_item, int32_t radius); +0x0043F1D0 0x0119 -R void __cdecl SkidooDriver_Push(ITEM *item, ITEM *lara_item, int32_t radius); 0x0043F2F0 0x0081 - void __cdecl SkidooDriver_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); # game/sound.c diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c new file mode 100644 index 000000000..662a9727a --- /dev/null +++ b/src/tr2/decomp/skidoo.c @@ -0,0 +1,50 @@ +#include "decomp/skidoo.h" + +#include "game/input.h" +#include "game/items.h" +#include "game/room.h" +#include "global/funcs.h" +#include "global/vars.h" + +typedef enum { + SKIDOO_GET_ON_NONE = 0, + SKIDOO_GET_ON_LEFT = 1, + SKIDOO_GET_ON_RIGHT = 2, +} SKIDOO_GET_ON_SIDE; + +int32_t __cdecl Skidoo_CheckGetOn(const int16_t item_num, COLL_INFO *const coll) +{ + if (!(g_Input & IN_ACTION) || g_Lara.gun_status != LGS_ARMLESS + || g_LaraItem->gravity) { + return SKIDOO_GET_ON_NONE; + } + + ITEM *const item = &g_Items[item_num]; + const int16_t angle = item->rot.y - g_LaraItem->rot.y; + + SKIDOO_GET_ON_SIDE get_on = SKIDOO_GET_ON_NONE; + if (angle > PHD_45 && angle < PHD_135) { + get_on = SKIDOO_GET_ON_LEFT; + } else if (angle > -PHD_135 && angle < -PHD_45) { + get_on = SKIDOO_GET_ON_RIGHT; + } + + if (!Item_TestBoundsCollide(item, g_LaraItem, coll->radius)) { + return SKIDOO_GET_ON_NONE; + } + + if (!Collide_TestCollision(item, g_LaraItem)) { + return SKIDOO_GET_ON_NONE; + } + + int16_t room_num = item->room_num; + const SECTOR *const sector = + Room_GetSector(item->pos.x, item->pos.y, item->pos.z, &room_num); + const int32_t height = + Room_GetHeight(sector, item->pos.x, item->pos.y, item->pos.z); + if (height < -32000) { + return SKIDOO_GET_ON_NONE; + } + + return get_on; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h new file mode 100644 index 000000000..2bb188736 --- /dev/null +++ b/src/tr2/decomp/skidoo.h @@ -0,0 +1,5 @@ +#pragma once + +#include "global/types.h" + +int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); diff --git a/src/tr2/game/lara/control.c b/src/tr2/game/lara/control.c index 5c5e80b28..ba0a20dbf 100644 --- a/src/tr2/game/lara/control.c +++ b/src/tr2/game/lara/control.c @@ -46,7 +46,7 @@ void __cdecl Lara_HandleAboveWater(ITEM *const item, COLL_INFO *const coll) if (g_Lara.skidoo != NO_ITEM) { if (g_Items[g_Lara.skidoo].object_id == O_SKIDOO_FAST) { - if (SkidooControl()) { + if (Skidoo_Control()) { return; } } else { diff --git a/src/tr2/game/objects/vehicles/boat.c b/src/tr2/game/objects/vehicles/boat.c index 7f280af3c..d80acbbef 100644 --- a/src/tr2/game/objects/vehicles/boat.c +++ b/src/tr2/game/objects/vehicles/boat.c @@ -17,10 +17,10 @@ #define BOAT_FALL_ANIM 15 #define BOAT_DEATH_ANIM 18 -#define BOAT_GETON_LW_ANIM 0 -#define BOAT_GETON_RW_ANIM 8 -#define BOAT_GETON_J_ANIM 6 -#define BOAT_GETON_START 1 +#define BOAT_GET_ON_LW_ANIM 0 +#define BOAT_GET_ON_RW_ANIM 8 +#define BOAT_GET_ON_J_ANIM 6 +#define BOAT_GET_ON_START 1 #define BOAT_RADIUS 500 #define BOAT_SIDE 300 @@ -44,7 +44,7 @@ #define GONDOLA_SINK_SPEED 50 typedef enum { - BOAT_GETON = 0, + BOAT_GET_ON = 0, BOAT_STILL = 1, BOAT_MOVING = 2, BOAT_JUMP_R = 3, @@ -77,7 +77,7 @@ void __cdecl Boat_Initialise(const int16_t item_num) boat->data = boat_data; } -int32_t __cdecl Boat_CheckGeton( +int32_t __cdecl Boat_CheckGetOn( const int16_t item_num, const COLL_INFO *const coll) { if (g_Lara.gun_status != LGS_ARMLESS) { @@ -95,7 +95,7 @@ int32_t __cdecl Boat_CheckGeton( return 0; } - int32_t geton = 0; + int32_t get_on = 0; const int16_t rot = boat->rot.y - lara->rot.y; if (g_Lara.water_status == LWS_SURFACE || g_Lara.water_status == LWS_WADE) { @@ -104,27 +104,27 @@ int32_t __cdecl Boat_CheckGeton( } if (rot > PHD_45 && rot < PHD_135) { - geton = 1; + get_on = 1; } else if (rot > -PHD_135 && rot < -PHD_45) { - geton = 2; + get_on = 2; } } else if (g_Lara.water_status == LWS_ABOVE_WATER) { int16_t fall_speed = lara->fall_speed; if (fall_speed > 0) { if (rot > -PHD_135 && rot < PHD_135 && lara->pos.y > boat->pos.y) { - geton = 3; + get_on = 3; } } else if (!fall_speed && rot > -PHD_135 && rot < PHD_135) { if (lara->pos.x == boat->pos.x && lara->pos.y == boat->pos.y && lara->pos.z == boat->pos.z) { - geton = 4; + get_on = 4; } else { - geton = 3; + get_on = 3; } } } - if (!geton) { + if (!get_on) { return 0; } @@ -136,7 +136,7 @@ int32_t __cdecl Boat_CheckGeton( return 0; } - return geton; + return get_on; } void __cdecl Boat_Collision( @@ -146,8 +146,8 @@ void __cdecl Boat_Collision( return; } - const int32_t geton = Boat_CheckGeton(item_num, coll); - if (!geton) { + const int32_t get_on = Boat_CheckGetOn(item_num, coll); + if (!get_on) { coll->enable_baddie_push = 1; Object_Collision(item_num, lara, coll); return; @@ -155,18 +155,18 @@ void __cdecl Boat_Collision( g_Lara.skidoo = item_num; - switch (geton) { + switch (get_on) { case 1: - lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GETON_RW_ANIM; + lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GET_ON_RW_ANIM; break; case 2: - lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GETON_LW_ANIM; + lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GET_ON_LW_ANIM; break; case 3: - lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GETON_J_ANIM; + lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GET_ON_J_ANIM; break; default: - lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GETON_START; + lara->anim_num = g_Objects[O_LARA_BOAT].anim_idx + BOAT_GET_ON_START; break; } @@ -652,7 +652,7 @@ void __cdecl Boat_Control(const int16_t item_num) if (g_Lara.skidoo == item_num && lara->hit_points > 0) { switch (lara->current_anim_state) { - case BOAT_GETON: + case BOAT_GET_ON: case BOAT_JUMP_R: case BOAT_JUMP_L: break; diff --git a/src/tr2/game/objects/vehicles/boat.h b/src/tr2/game/objects/vehicles/boat.h index 855e63774..e2221e1f8 100644 --- a/src/tr2/game/objects/vehicles/boat.h +++ b/src/tr2/game/objects/vehicles/boat.h @@ -5,7 +5,7 @@ #include void __cdecl Boat_Initialise(int16_t item_num); -int32_t __cdecl Boat_CheckGeton(int16_t item_num, const COLL_INFO *coll); +int32_t __cdecl Boat_CheckGetOn(int16_t item_num, const COLL_INFO *coll); void __cdecl Boat_Collision(int16_t item_num, ITEM *lara, COLL_INFO *coll); int32_t __cdecl Boat_TestWaterHeight( const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 4d961452d..c1ebea8f9 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -168,27 +168,26 @@ #define Jelly_Control ((void __cdecl (*)(int16_t item_num))0x0043C850) #define Baracudda_Control ((void __cdecl (*)(int16_t item_num))0x0043C970) #define Shark_Control ((void __cdecl (*)(int16_t item_num))0x0043CBA0) -#define InitialiseSkidoo ((void __cdecl (*)(int16_t item_num))0x0043CE30) -#define SkidooCheckGeton ((int32_t __cdecl (*)(int16_t item_num, COLL_INFO *coll))0x0043CE70) -#define SkidooCollision ((void __cdecl (*)(int16_t item_num, ITEM *litem, COLL_INFO *coll))0x0043CF60) -#define SkidooBaddieCollision ((void __cdecl (*)(ITEM *skidoo))0x0043D060) -#define TestHeight ((int32_t __cdecl (*)(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos))0x0043D260) +#define Skidoo_Initialise ((void __cdecl (*)(int16_t item_num))0x0043CE30) +#define Skidoo_Collision ((void __cdecl (*)(int16_t item_num, ITEM *litem, COLL_INFO *coll))0x0043CF60) +#define Skidoo_BaddieCollision ((void __cdecl (*)(ITEM *skidoo))0x0043D060) +#define Skidoo_TestHeight ((int32_t __cdecl (*)(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos))0x0043D260) #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define DoSnowEffect ((void __cdecl (*)(ITEM *skidoo))0x0043D690) -#define SkidooDynamics ((int32_t __cdecl (*)(ITEM *skidoo))0x0043D7D0) -#define SkidooUserControl ((int32_t __cdecl (*)(ITEM *skidoo, int32_t height, int32_t *pitch))0x0043DC70) -#define SkidooCheckGetOffOK ((int32_t __cdecl (*)(int32_t direction))0x0043DE30) -#define SkidooAnimation ((void __cdecl (*)(ITEM *skidoo, int32_t collide, int32_t dead))0x0043DF40) -#define SkidooExplode ((void __cdecl (*)(ITEM *skidoo))0x0043E220) -#define SkidooCheckGetOff ((int32_t __cdecl (*)(void))0x0043E2A0) -#define SkidooGuns ((void __cdecl (*)(void))0x0043E4E0) -#define SkidooControl ((int32_t __cdecl (*)(void))0x0043E600) -#define SkidooArmed_Draw ((void __cdecl (*)(const ITEM *item))0x0043EA60) +#define Skidoo_DoSnowEffect ((void __cdecl (*)(ITEM *skidoo))0x0043D690) +#define Skidoo_Dynamics ((int32_t __cdecl (*)(ITEM *skidoo))0x0043D7D0) +#define Skidoo_UserControl ((int32_t __cdecl (*)(ITEM *skidoo, int32_t height, int32_t *pitch))0x0043DC70) +#define Skidoo_CheckGetOffOK ((int32_t __cdecl (*)(int32_t direction))0x0043DE30) +#define Skidoo_Animation ((void __cdecl (*)(ITEM *skidoo, int32_t collide, int32_t dead))0x0043DF40) +#define Skidoo_Explode ((void __cdecl (*)(ITEM *skidoo))0x0043E220) +#define Skidoo_CheckGetOff ((int32_t __cdecl (*)(void))0x0043E2A0) +#define Skidoo_Guns ((void __cdecl (*)(void))0x0043E4E0) +#define Skidoo_Control ((int32_t __cdecl (*)(void))0x0043E600) +#define Skidoo_Armed_Draw ((void __cdecl (*)(const ITEM *item))0x0043EA60) #define SkidooDriver_Initialise ((void __cdecl (*)(int16_t item_num))0x0043ED40) #define SkidooDriver_Control ((void __cdecl (*)(int16_t rider_num))0x0043EDD0) -#define SkidmanPush ((void __cdecl (*)(ITEM *item, ITEM *lara_item, int32_t radius))0x0043F1D0) +#define SkidooDriver_Push ((void __cdecl (*)(ITEM *item, ITEM *lara_item, int32_t radius))0x0043F1D0) #define SkidooDriver_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) #define Music_GetRealTrack ((int32_t __cdecl (*)(int32_t track))0x0043F380) #define Collide_TestCollision ((int32_t __cdecl (*)(ITEM *item, const ITEM *lara_item))0x0043F9B0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 1058ee5d8..6f83d6c54 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -3,6 +3,7 @@ #include "decomp/decomp.h" #include "decomp/effects.h" #include "decomp/fmv.h" +#include "decomp/skidoo.h" #include "decomp/stats.h" #include "game/background.h" #include "game/box.h" @@ -77,6 +78,7 @@ static void M_DecompGeneral(const bool enable); static void M_DecompFMV(const bool enable); +static void M_DecompSkidoo(const bool enable); static void M_DecompStats(const bool enable); static void M_DecompEffects(const bool enable); static void M_HWR(bool enable); @@ -240,6 +242,11 @@ static void M_DecompFMV(const bool enable) INJECT(enable, 0x0044C460, S_IntroFMV); } +static void M_DecompSkidoo(const bool enable) +{ + INJECT(enable, 0x0043CE70, Skidoo_CheckGetOn); +} + static void M_DecompStats(const bool enable) { INJECT(enable, 0x004262B0, AddAssaultTime); @@ -960,7 +967,7 @@ static void M_Objects(const bool enable) INJECT(enable, 0x0040C880, Bird_Initialise); INJECT(enable, 0x0040C910, Bird_Control); INJECT(enable, 0x0040CB30, Boat_Initialise); - INJECT(enable, 0x0040CB70, Boat_CheckGeton); + INJECT(enable, 0x0040CB70, Boat_CheckGetOn); INJECT(enable, 0x0040CCE0, Boat_Collision); INJECT(enable, 0x0040CE40, Boat_TestWaterHeight); INJECT(enable, 0x0040CF40, Boat_DoShift); @@ -1058,6 +1065,7 @@ void Inject_Exec(void) { M_DecompGeneral(true); M_DecompFMV(true); + M_DecompSkidoo(true); M_DecompStats(true); M_DecompEffects(true); M_HWR(true); diff --git a/src/tr2/meson.build b/src/tr2/meson.build index 3ba9a8f35..860cea956 100644 --- a/src/tr2/meson.build +++ b/src/tr2/meson.build @@ -87,6 +87,7 @@ dll_sources = [ 'decomp/decomp.c', 'decomp/fmv.c', 'decomp/effects.c', + 'decomp/skidoo.c', 'decomp/stats.c', 'game/background.c', 'game/backpack.c', From b46d431e7e87336876c9138c83a39f4d2374b0b1 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 00:19:31 +0200 Subject: [PATCH 02/22] tr2: port Skidoo_Initialise --- docs/tr2/progress.svg | 16 ++++++++-------- docs/tr2/progress.txt | 12 +++++++++++- src/tr2/decomp/skidoo.c | 17 +++++++++++++++++ src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/global/types.h | 10 ++++++++++ src/tr2/inject_exec.c | 1 + 7 files changed, 48 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index bb7677d48..f15b13ee0 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -65.92% (820) · 31.67% (394) · 0% (0) · 2.41% (30) +66% (821) · 31.59% (393) · 0% (0) · 2.41% (30) - - + + @@ -777,7 +777,7 @@ void __cdecl Jelly_Control(int16_t item_num); void __cdecl Baracudda_Control(int16_t item_num); void __cdecl Shark_Control(int16_t item_num); -void __cdecl Skidoo_Initialise(int16_t item_num); +void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -70.29% · 29.38% · 0% · 0.33% +70.31% · 29.36% · 0% · 0.33% - - + + @@ -2191,7 +2191,7 @@ void __cdecl lara_normal_effect(ITEM *item); void __cdecl Inv_Ring_Light(RING_INFO *ring); void __cdecl Lara_State_FastFall(ITEM *item, COLL_INFO *coll); -void __cdecl Skidoo_Initialise(int16_t item_num); +void __cdecl Skidoo_Initialise(int16_t item_num); bool __cdecl WinVidInit(void); void __cdecl Option_Controls_DefaultConflict(void); void __cdecl UpdateTicks(void); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 6d231d286..f4379d197 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -2631,6 +2631,16 @@ typedef struct __unaligned { int32_t pitch; } BOAT_INFO; +typedef struct __unaligned { + int16_t track_mesh; + int32_t skidoo_turn; + int32_t left_fallspeed; + int32_t right_fallspeed; + int16_t momentum_angle; + int16_t extra_rotation; + int32_t pitch; +} SKIDOO_INFO; + typedef struct __unaligned { struct { XYZ_16 min; @@ -3634,7 +3644,7 @@ typedef enum { 0x0043CBA0 0x027C -R void __cdecl Shark_Control(int16_t item_num); # game/skidoo.c -0x0043CE30 0x0040 -R void __cdecl Skidoo_Initialise(int16_t item_num); +0x0043CE30 0x0040 +R void __cdecl Skidoo_Initialise(int16_t item_num); 0x0043CE70 0x00E1 +R int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); 0x0043CF60 0x00F8 -R void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); 0x0043D060 0x01F9 -R void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 662a9727a..33bf6a2c5 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -12,6 +12,23 @@ typedef enum { SKIDOO_GET_ON_RIGHT = 2, } SKIDOO_GET_ON_SIDE; +void __cdecl Skidoo_Initialise(const int16_t item_num) +{ + ITEM *const item = &g_Items[item_num]; + + SKIDOO_INFO *const skidoo_data = + game_malloc(sizeof(SKIDOO_INFO), GBUF_SKIDOO_STUFF); + skidoo_data->skidoo_turn = 0; + skidoo_data->right_fallspeed = 0; + skidoo_data->left_fallspeed = 0; + skidoo_data->extra_rotation = 0; + skidoo_data->momentum_angle = item->rot.y; + skidoo_data->track_mesh = 0; + skidoo_data->pitch = 0; + + item->data = skidoo_data; +} + int32_t __cdecl Skidoo_CheckGetOn(const int16_t item_num, COLL_INFO *const coll) { if (!(g_Input & IN_ACTION) || g_Lara.gun_status != LGS_ARMLESS diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 2bb188736..8f0c69838 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -2,4 +2,5 @@ #include "global/types.h" +void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index c1ebea8f9..418952576 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -168,7 +168,6 @@ #define Jelly_Control ((void __cdecl (*)(int16_t item_num))0x0043C850) #define Baracudda_Control ((void __cdecl (*)(int16_t item_num))0x0043C970) #define Shark_Control ((void __cdecl (*)(int16_t item_num))0x0043CBA0) -#define Skidoo_Initialise ((void __cdecl (*)(int16_t item_num))0x0043CE30) #define Skidoo_Collision ((void __cdecl (*)(int16_t item_num, ITEM *litem, COLL_INFO *coll))0x0043CF60) #define Skidoo_BaddieCollision ((void __cdecl (*)(ITEM *skidoo))0x0043D060) #define Skidoo_TestHeight ((int32_t __cdecl (*)(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos))0x0043D260) diff --git a/src/tr2/global/types.h b/src/tr2/global/types.h index a33faac4e..aa2ccc4aa 100644 --- a/src/tr2/global/types.h +++ b/src/tr2/global/types.h @@ -1574,6 +1574,16 @@ typedef struct __unaligned { int32_t pitch; } BOAT_INFO; +typedef struct __unaligned { + int16_t track_mesh; + int32_t skidoo_turn; + int32_t left_fallspeed; + int32_t right_fallspeed; + int16_t momentum_angle; + int16_t extra_rotation; + int32_t pitch; +} SKIDOO_INFO; + typedef struct __unaligned { struct { XYZ_16 min; diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 6f83d6c54..aa5662bbd 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -244,6 +244,7 @@ static void M_DecompFMV(const bool enable) static void M_DecompSkidoo(const bool enable) { + INJECT(enable, 0x0043CE30, Skidoo_Initialise); INJECT(enable, 0x0043CE70, Skidoo_CheckGetOn); } From f518a40ed6996b4ba4c719495a9725360de9f430 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 16:00:55 +0200 Subject: [PATCH 03/22] tr2: port Skidoo_Collision --- docs/tr2/progress.svg | 16 ++--- docs/tr2/progress.txt | 4 +- src/libtrx/game/rooms/common.c | 23 +++++++ src/libtrx/include/libtrx/game/rooms/common.h | 4 ++ src/libtrx/meson.build | 1 + src/tr2/decomp/skidoo.c | 66 +++++++++++++++++++ src/tr2/decomp/skidoo.h | 2 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 9 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 src/libtrx/game/rooms/common.c diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index f15b13ee0..823fe3d09 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66% (821) · 31.59% (393) · 0% (0) · 2.41% (30) +66.08% (822) · 31.51% (392) · 0% (0) · 2.41% (30) - - + + @@ -779,7 +779,7 @@ void __cdecl Shark_Control(int16_t item_num); void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); -void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); +void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -70.31% · 29.36% · 0% · 0.33% +70.38% · 29.29% · 0% · 0.33% - - + + @@ -1700,7 +1700,7 @@ int32_t __cdecl Boat_TestWaterHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl Creature_CheckBaddieOverlap(int16_t item_num); void __cdecl Flare_DrawInAir(ITEM *item); -void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); +void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); void __cdecl Output_DrawPoly_Gouraud(int32_t vtx_count, int32_t red, int32_t green, int32_t blue); int32_t __cdecl Lara_TestHangOnClimbWall(ITEM *item, COLL_INFO *coll); void __cdecl Gun_Rifle_Control(LARA_GUN_TYPE weapon_type); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index f4379d197..cd1dd57b4 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -2017,7 +2017,7 @@ typedef enum { // decompiled LGT_M16 = 5, LGT_GRENADE = 6, LGT_HARPOON = 7, - LGT_FLARE = 8 , + LGT_FLARE = 8, LGT_SKIDOO = 9, NUM_WEAPONS = 10, } LARA_GUN_TYPE; @@ -3646,7 +3646,7 @@ typedef enum { # game/skidoo.c 0x0043CE30 0x0040 +R void __cdecl Skidoo_Initialise(int16_t item_num); 0x0043CE70 0x00E1 +R int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); -0x0043CF60 0x00F8 -R void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); +0x0043CF60 0x00F8 +R void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); 0x0043D060 0x01F9 -R void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); 0x0043D260 0x00B2 -R int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); 0x0043D320 0x027C -R int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); diff --git a/src/libtrx/game/rooms/common.c b/src/libtrx/game/rooms/common.c new file mode 100644 index 000000000..d2a532651 --- /dev/null +++ b/src/libtrx/game/rooms/common.c @@ -0,0 +1,23 @@ +#include "game/rooms/common.h" + +#include + +int32_t Room_GetAdjoiningRooms( + int16_t init_room_num, int16_t out_room_nums[], + const int32_t max_room_num_count) +{ + int32_t count = 0; + if (max_room_num_count >= 1) { + out_room_nums[count++] = init_room_num; + } + + const PORTALS *const portals = Room_Get(init_room_num)->portals; + if (portals != NULL) { + for (int32_t i = 0; i < portals->count; i++) { + const int16_t room_num = portals->portal[i].room_num; + out_room_nums[count++] = room_num; + } + } + + return count; +} diff --git a/src/libtrx/include/libtrx/game/rooms/common.h b/src/libtrx/include/libtrx/game/rooms/common.h index c86e855a0..1a91b0adb 100644 --- a/src/libtrx/include/libtrx/game/rooms/common.h +++ b/src/libtrx/include/libtrx/game/rooms/common.h @@ -7,3 +7,7 @@ extern ROOM *Room_Get(int32_t room_num); extern void Room_FlipMap(void); extern bool Room_GetFlipStatus(void); + +int32_t Room_GetAdjoiningRooms( + int16_t init_room_num, int16_t out_room_nums[], + const int32_t max_room_num_count); diff --git a/src/libtrx/meson.build b/src/libtrx/meson.build index c0bf994fd..a341f262d 100644 --- a/src/libtrx/meson.build +++ b/src/libtrx/meson.build @@ -95,6 +95,7 @@ sources = [ 'game/objects/common.c', 'game/objects/names.c', 'game/objects/vars.c', + 'game/rooms/common.c', 'game/ui/common.c', 'game/ui/events.c', 'game/ui/widgets/console.c', diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 33bf6a2c5..75f57c261 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -2,6 +2,7 @@ #include "game/input.h" #include "game/items.h" +#include "game/objects/common.h" #include "game/room.h" #include "global/funcs.h" #include "global/vars.h" @@ -12,6 +13,31 @@ typedef enum { SKIDOO_GET_ON_RIGHT = 2, } SKIDOO_GET_ON_SIDE; +typedef enum { + // clang-format off + LARA_STATE_SKIDOO_SIT = 0, + LARA_STATE_SKIDOO_GET_ON = 1, + LARA_STATE_SKIDOO_LEFT = 2, + LARA_STATE_SKIDOO_RIGHT = 3, + LARA_STATE_SKIDOO_FALL = 4, + LARA_STATE_SKIDOO_HIT = 5, + LARA_STATE_SKIDOO_GET_ON_L = 6, + LARA_STATE_SKIDOO_GET_OFF_L = 7, + LARA_STATE_SKIDOO_STILL = 8, + LARA_STATE_SKIDOO_GET_OFF = 9, + LARA_STATE_SKIDOO_LETGO = 10, + LARA_STATE_SKIDOO_DEATH = 11, + LARA_STATE_SKIDOO_FALLOFF = 12, + // clang-format on +} LARA_SKIDOO_STATE; + +typedef enum { + // clang-format off + LA_SKIDOO_GET_ON_L = 1, + LA_SKIDOO_GET_ON_R = 18, + // clang-format on +} LARA_ANIM_SKIDOO; + void __cdecl Skidoo_Initialise(const int16_t item_num) { ITEM *const item = &g_Items[item_num]; @@ -65,3 +91,43 @@ int32_t __cdecl Skidoo_CheckGetOn(const int16_t item_num, COLL_INFO *const coll) return get_on; } + +void __cdecl Skidoo_Collision( + const int16_t item_num, ITEM *const lara_item, COLL_INFO *const coll) +{ + if (lara_item->hit_points < 0 || g_Lara.skidoo != NO_ITEM) { + return; + } + + const SKIDOO_GET_ON_SIDE get_on = Skidoo_CheckGetOn(item_num, coll); + if (get_on == SKIDOO_GET_ON_NONE) { + Object_Collision(item_num, lara_item, coll); + return; + } + + g_Lara.skidoo = item_num; + if (g_Lara.gun_type == LGT_FLARE) { + Flare_Create(false); + Flare_UndrawMeshes(); + g_Lara.flare_control_left = 0; + g_Lara.gun_type = LGT_UNARMED; + g_Lara.request_gun_type = LGT_UNARMED; + } + if (get_on == SKIDOO_GET_ON_LEFT) { + lara_item->anim_num = + g_Objects[O_LARA_SKIDOO].anim_idx + LA_SKIDOO_GET_ON_L; + } else if (get_on == SKIDOO_GET_ON_RIGHT) { + lara_item->anim_num = + g_Objects[O_LARA_SKIDOO].anim_idx + LA_SKIDOO_GET_ON_R; + } + lara_item->current_anim_state = LARA_STATE_SKIDOO_GET_ON; + lara_item->frame_num = g_Anims[lara_item->anim_num].frame_base; + g_Lara.gun_status = LGS_ARMLESS; + + ITEM *const item = &g_Items[item_num]; + lara_item->pos.x = item->pos.x; + lara_item->pos.y = item->pos.y; + lara_item->pos.z = item->pos.z; + lara_item->rot.y = item->rot.y; + item->hit_points = 1; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 8f0c69838..7bcdcd8af 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -4,3 +4,5 @@ void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); +void __cdecl Skidoo_Collision( + int16_t item_num, ITEM *lara_item, COLL_INFO *coll); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 418952576..74d044f32 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -168,7 +168,6 @@ #define Jelly_Control ((void __cdecl (*)(int16_t item_num))0x0043C850) #define Baracudda_Control ((void __cdecl (*)(int16_t item_num))0x0043C970) #define Shark_Control ((void __cdecl (*)(int16_t item_num))0x0043CBA0) -#define Skidoo_Collision ((void __cdecl (*)(int16_t item_num, ITEM *litem, COLL_INFO *coll))0x0043CF60) #define Skidoo_BaddieCollision ((void __cdecl (*)(ITEM *skidoo))0x0043D060) #define Skidoo_TestHeight ((int32_t __cdecl (*)(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos))0x0043D260) #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index aa5662bbd..4891a759c 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -246,6 +246,7 @@ static void M_DecompSkidoo(const bool enable) { INJECT(enable, 0x0043CE30, Skidoo_Initialise); INJECT(enable, 0x0043CE70, Skidoo_CheckGetOn); + INJECT(enable, 0x0043CF60, Skidoo_Collision); } static void M_DecompStats(const bool enable) From 44d3305a5c17ae7be7600f978b98c0530c250b80 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 11:45:22 +0200 Subject: [PATCH 04/22] tr1/lara: use new Room_GetAdjoiningRooms --- src/tr1/game/lara/control.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/tr1/game/lara/control.c b/src/tr1/game/lara/control.c index 7247a9bf2..af1a9eb6b 100644 --- a/src/tr1/game/lara/control.c +++ b/src/tr1/game/lara/control.c @@ -22,8 +22,6 @@ #include #include -#define MAX_BADDIE_COLLISION 12 - static int32_t m_OpenDoorsCheatCooldown = 0; static void M_WaterCurrent(COLL_INFO *coll); @@ -117,22 +115,11 @@ static void M_BaddieCollision(ITEM *lara_item, COLL_INFO *coll) return; } - int16_t numroom = 0; - int16_t roomies[MAX_BADDIE_COLLISION]; - - roomies[numroom++] = lara_item->room_num; - - PORTALS *portals = g_RoomInfo[lara_item->room_num].portals; - if (portals != NULL) { - for (int i = 0; i < portals->count; i++) { - if (numroom >= MAX_BADDIE_COLLISION) { - break; - } - roomies[numroom++] = portals->portal[i].room_num; - } - } + int16_t roomies[12]; + const int32_t roomies_count = + Room_GetAdjoiningRooms(lara_item->room_num, roomies, 12); - for (int i = 0; i < numroom; i++) { + for (int32_t i = 0; i < roomies_count; i++) { int16_t item_num = g_RoomInfo[roomies[i]].item_num; while (item_num != NO_ITEM) { ITEM *item = &g_Items[item_num]; From 32b0c49817f3dfdc8c5194a5039fd36a0a740059 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 16:02:30 +0200 Subject: [PATCH 05/22] tr2: port Skidoo_BaddieCollision --- docs/tr2/progress.svg | 20 ++++++------ docs/tr2/progress.txt | 16 ++++++++-- src/tr2/decomp/skidoo.c | 69 +++++++++++++++++++++++++++++++++++++++++ src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 3 +- src/tr2/global/types.h | 12 +++++++ src/tr2/inject_exec.c | 1 + 7 files changed, 108 insertions(+), 14 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 823fe3d09..203465c00 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.08% (822) · 31.51% (392) · 0% (0) · 2.41% (30) +66.16% (823) · 31.43% (391) · 0% (0) · 2.41% (30) - - + + @@ -780,7 +780,7 @@ void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); -void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); +void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); @@ -797,7 +797,7 @@ void __cdecl Skidoo_Armed_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); -void __cdecl SkidooDriver_Push(ITEM *item, ITEM *lara_item, int32_t radius); +void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); void __cdecl SkidooDriver_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Music_GetRealTrack(int32_t track); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -70.38% · 29.29% · 0% · 0.33% +70.53% · 29.14% · 0% · 0.33% - - + + @@ -1509,7 +1509,7 @@ void __cdecl CreateStartInfo(int32_t level_num); void __cdecl Bird_Control(int16_t item_num); void __cdecl BodyPart_Control(int16_t fx_num); -void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); +void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); void __cdecl S_DrawAirBar(int32_t percent); void __cdecl Screenshot(LPDDS screen); void __cdecl MineControl(int16_t mine_num); @@ -1659,7 +1659,7 @@ void __cdecl Skidoo_Guns(void); void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC lpDdsd, LPVOID lpContext); -void __cdecl SkidooDriver_Push(ITEM *item, ITEM *lara_item, int32_t radius); +void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); void __cdecl Jelly_Control(int16_t item_num); void __cdecl S_DrawScreenBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE color_idx, const GOURAUD_OUTLINE *gour, uint16_t flags); void __cdecl ControlCeilingSpikes(int16_t item_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index cd1dd57b4..c80ee1ccf 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -1053,6 +1053,18 @@ typedef enum { GAMEMODE_IN_CUTSCENE } GAMEMODE; +typedef enum { + TRAP_SET = 0, + TRAP_ACTIVATE = 1, + TRAP_WORKING = 2, + TRAP_FINISHED = 3, +} TRAP_ANIM; + +typedef enum { + DOOR_CLOSED = 0, + DOOR_OPEN = 1, +} DOOR_ANIM; + typedef enum { GFD_START_GAME = 0x0000, GFD_START_SAVED_GAME = 0x0100, @@ -3647,7 +3659,7 @@ typedef enum { 0x0043CE30 0x0040 +R void __cdecl Skidoo_Initialise(int16_t item_num); 0x0043CE70 0x00E1 +R int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); 0x0043CF60 0x00F8 +R void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); -0x0043D060 0x01F9 -R void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); +0x0043D060 0x01F9 +R void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); 0x0043D260 0x00B2 -R int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); 0x0043D320 0x027C -R int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); 0x0043D5A0 0x0054 -R int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); @@ -3664,7 +3676,7 @@ typedef enum { 0x0043EA60 0x02D5 -R void __cdecl Skidoo_Armed_Draw(const ITEM *item); 0x0043ED40 0x007F -R void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 - void __cdecl SkidooDriver_Control(int16_t rider_num); -0x0043F1D0 0x0119 -R void __cdecl SkidooDriver_Push(ITEM *item, ITEM *lara_item, int32_t radius); +0x0043F1D0 0x0119 -R void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); 0x0043F2F0 0x0081 - void __cdecl SkidooDriver_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); # game/sound.c diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 75f57c261..6413be893 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -2,6 +2,7 @@ #include "game/input.h" #include "game/items.h" +#include "game/lara/control.h" #include "game/objects/common.h" #include "game/room.h" #include "global/funcs.h" @@ -38,6 +39,57 @@ typedef enum { // clang-format on } LARA_ANIM_SKIDOO; +#define SKIDOO_RADIUS 500 +#define M_TARGET_DIST (WALL_L * 2) // = 2048 + +static bool M_IsNearby(const ITEM *item_1, const ITEM *item_2); +static bool M_CheckBaddieCollision(ITEM *item, const ITEM *skidoo); + +static bool M_IsNearby(const ITEM *const item_1, const ITEM *const item_2) +{ + const int32_t dx = item_1->pos.x - item_2->pos.x; + const int32_t dy = item_1->pos.y - item_2->pos.y; + const int32_t dz = item_1->pos.z - item_2->pos.z; + return dx > -M_TARGET_DIST && dx < M_TARGET_DIST && dy > -M_TARGET_DIST + && dy < M_TARGET_DIST && dz > -M_TARGET_DIST && dz < M_TARGET_DIST; +} + +static bool M_CheckBaddieCollision(ITEM *const item, const ITEM *const skidoo) +{ + if (!item->collidable || item->status == IS_INVISIBLE || item == g_LaraItem + || item == skidoo) { + return false; + } + + const OBJECT *const object = Object_GetObject(item->object_id); + const bool is_availanche = item->object_id == O_ROLLING_BALL_2; + if (object->collision == NULL || (!object->intelligent && !is_availanche)) { + return false; + } + + if (!M_IsNearby(item, skidoo)) { + return false; + } + + if (!Item_TestBoundsCollide(item, skidoo, SKIDOO_RADIUS)) { + return false; + } + + if (item->object_id == O_SKIDOO_ARMED) { + SkidooDriver_Push(item, skidoo, SKIDOO_RADIUS); + } else if (is_availanche) { + if (item->current_anim_state == TRAP_ACTIVATE) { + Lara_TakeDamage(100, true); + } + } else { + DoLotsOfBlood( + item->pos.x, skidoo->pos.y - STEP_L, item->pos.z, skidoo->speed, + skidoo->rot.y, item->room_num, 3); + item->hit_points = 0; + } + return true; +} + void __cdecl Skidoo_Initialise(const int16_t item_num) { ITEM *const item = &g_Items[item_num]; @@ -131,3 +183,20 @@ void __cdecl Skidoo_Collision( lara_item->rot.y = item->rot.y; item->hit_points = 1; } + +void __cdecl Skidoo_BaddieCollision(const ITEM *const skidoo) +{ + int16_t roomies[12]; + const int32_t roomies_count = + Room_GetAdjoiningRooms(skidoo->room_num, roomies, 12); + + for (int32_t i = 0; i < roomies_count; i++) { + const ROOM *const room = Room_Get(roomies[i]); + int16_t item_num = room->item_num; + while (item_num != NO_ITEM) { + ITEM *item = Item_Get(item_num); + M_CheckBaddieCollision(item, skidoo); + item_num = item->next_item; + } + } +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 7bcdcd8af..441329887 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -6,3 +6,4 @@ void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision( int16_t item_num, ITEM *lara_item, COLL_INFO *coll); +void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 74d044f32..dcf296fd4 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -168,7 +168,6 @@ #define Jelly_Control ((void __cdecl (*)(int16_t item_num))0x0043C850) #define Baracudda_Control ((void __cdecl (*)(int16_t item_num))0x0043C970) #define Shark_Control ((void __cdecl (*)(int16_t item_num))0x0043CBA0) -#define Skidoo_BaddieCollision ((void __cdecl (*)(ITEM *skidoo))0x0043D060) #define Skidoo_TestHeight ((int32_t __cdecl (*)(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos))0x0043D260) #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) @@ -185,7 +184,7 @@ #define Skidoo_Armed_Draw ((void __cdecl (*)(const ITEM *item))0x0043EA60) #define SkidooDriver_Initialise ((void __cdecl (*)(int16_t item_num))0x0043ED40) #define SkidooDriver_Control ((void __cdecl (*)(int16_t rider_num))0x0043EDD0) -#define SkidooDriver_Push ((void __cdecl (*)(ITEM *item, ITEM *lara_item, int32_t radius))0x0043F1D0) +#define SkidooDriver_Push ((void __cdecl (*)(ITEM *item, const ITEM *lara_item, int32_t radius))0x0043F1D0) #define SkidooDriver_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) #define Music_GetRealTrack ((int32_t __cdecl (*)(int32_t track))0x0043F380) #define Collide_TestCollision ((int32_t __cdecl (*)(ITEM *item, const ITEM *lara_item))0x0043F9B0) diff --git a/src/tr2/global/types.h b/src/tr2/global/types.h index aa2ccc4aa..98dd9a702 100644 --- a/src/tr2/global/types.h +++ b/src/tr2/global/types.h @@ -794,6 +794,18 @@ typedef enum { GAMEMODE_IN_CUTSCENE } GAMEMODE; +typedef enum { + TRAP_SET = 0, + TRAP_ACTIVATE = 1, + TRAP_WORKING = 2, + TRAP_FINISHED = 3, +} TRAP_ANIM; + +typedef enum { + DOOR_CLOSED = 0, + DOOR_OPEN = 1, +} DOOR_ANIM; + typedef enum { GFD_START_GAME = 0x0000, GFD_START_SAVED_GAME = 0x0100, diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 4891a759c..ff9290779 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -247,6 +247,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043CE30, Skidoo_Initialise); INJECT(enable, 0x0043CE70, Skidoo_CheckGetOn); INJECT(enable, 0x0043CF60, Skidoo_Collision); + INJECT(enable, 0x0043D060, Skidoo_BaddieCollision); } static void M_DecompStats(const bool enable) From ec8c5900b60961880f8d5b9e5c2771d0f2fde723 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 16:08:19 +0200 Subject: [PATCH 06/22] tr2: port Skidoo_TestHeight --- docs/tr2/progress.svg | 16 ++++++++-------- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 18 ++++++++++++++++++ src/tr2/decomp/skidoo.h | 2 ++ src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 203465c00..91f19fd96 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.16% (823) · 31.43% (391) · 0% (0) · 2.41% (30) +66.24% (824) · 31.35% (390) · 0% (0) · 2.41% (30) - - + + @@ -781,7 +781,7 @@ int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); -int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -70.53% · 29.14% · 0% · 0.33% +70.58% · 29.09% · 0% · 0.33% - - + + @@ -1819,7 +1819,7 @@ void __cdecl Lara_Col_FastBack(ITEM *item, COLL_INFO *coll); void __cdecl Lara_Col_Roll2(ITEM *item, COLL_INFO *coll); void __cdecl AssaultFinished(ITEM *item); -int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl Lara_TestHangSwingIn(ITEM *item, PHD_ANGLE angle); int32_t __cdecl OnDrawBridge(ITEM *item, int32_t x, int32_t y); void __cdecl S_AnimateTextures(int32_t ticks); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index c80ee1ccf..b088761d8 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3660,7 +3660,7 @@ typedef enum { 0x0043CE70 0x00E1 +R int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); 0x0043CF60 0x00F8 +R void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); 0x0043D060 0x01F9 +R void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); -0x0043D260 0x00B2 -R int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +0x0043D260 0x00B2 +R int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); 0x0043D320 0x027C -R int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); 0x0043D5A0 0x0054 -R int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); 0x0043D600 0x0090 -R int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 6413be893..8d8278a60 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -3,6 +3,7 @@ #include "game/input.h" #include "game/items.h" #include "game/lara/control.h" +#include "game/math.h" #include "game/objects/common.h" #include "game/room.h" #include "global/funcs.h" @@ -200,3 +201,20 @@ void __cdecl Skidoo_BaddieCollision(const ITEM *const skidoo) } } } + +int32_t __cdecl Skidoo_TestHeight( + const ITEM *const item, const int32_t z_off, const int32_t x_off, + XYZ_32 *const out_pos) +{ + const int32_t sx = Math_Sin(item->rot.x); + const int32_t sz = Math_Sin(item->rot.z); + const int32_t cy = Math_Cos(item->rot.y); + const int32_t sy = Math_Sin(item->rot.y); + out_pos->x = item->pos.x + ((x_off * cy + z_off * sy) >> W2V_SHIFT); + out_pos->y = item->pos.y + ((x_off * sz - z_off * sx) >> W2V_SHIFT); + out_pos->z = item->pos.z + ((z_off * cy - x_off * sy) >> W2V_SHIFT); + int16_t room_num = item->room_num; + const SECTOR *const sector = + Room_GetSector(out_pos->x, out_pos->y, out_pos->z, &room_num); + return Room_GetHeight(sector, out_pos->x, out_pos->y, out_pos->z); +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 441329887..6149343db 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -7,3 +7,5 @@ int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision( int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); +int32_t __cdecl Skidoo_TestHeight( + const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *out_pos); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index dcf296fd4..17d758a77 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -168,7 +168,6 @@ #define Jelly_Control ((void __cdecl (*)(int16_t item_num))0x0043C850) #define Baracudda_Control ((void __cdecl (*)(int16_t item_num))0x0043C970) #define Shark_Control ((void __cdecl (*)(int16_t item_num))0x0043CBA0) -#define Skidoo_TestHeight ((int32_t __cdecl (*)(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos))0x0043D260) #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index ff9290779..ee81080e5 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -248,6 +248,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043CE70, Skidoo_CheckGetOn); INJECT(enable, 0x0043CF60, Skidoo_Collision); INJECT(enable, 0x0043D060, Skidoo_BaddieCollision); + INJECT(enable, 0x0043D260, Skidoo_TestHeight); } static void M_DecompStats(const bool enable) From 8463fa15ac8d0661df58b389de94f3aa1326cdbc Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 16:17:59 +0200 Subject: [PATCH 07/22] tr2: port Skidoo_DoSnowEffect --- docs/tr2/progress.svg | 16 ++++++++-------- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 38 ++++++++++++++++++++++++++++++++++++++ src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 49 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 91f19fd96..dcb7fd396 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.24% (824) · 31.35% (390) · 0% (0) · 2.41% (30) +66.32% (825) · 31.27% (389) · 0% (0) · 2.41% (30) - - + + @@ -785,7 +785,7 @@ int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); -void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); +void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -70.58% · 29.09% · 0% · 0.33% +70.68% · 29% · 0% · 0.33% - - + + @@ -1621,7 +1621,7 @@ void __cdecl Lara_State_Run(ITEM *item, COLL_INFO *coll); int32_t __cdecl Output_ZedClipper(int32_t vtx_count, POINT_INFO *pts, VERTEX_INFO *vtx); void __cdecl Output_DrawClippedPoly_Textured(int32_t vtx_count); -void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); +void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); void __cdecl Lara_UseItem(GAME_OBJECT_ID object_id); void __cdecl Inv_Ring_DoMotions(RING_INFO *ring); void __cdecl DartEmitterControl(int16_t item_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index b088761d8..b972ccede 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3664,7 +3664,7 @@ typedef enum { 0x0043D320 0x027C -R int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); 0x0043D5A0 0x0054 -R int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); 0x0043D600 0x0090 -R int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); -0x0043D690 0x0140 -R void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); +0x0043D690 0x0140 +R void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); 0x0043D7D0 0x049E -R int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); 0x0043DC70 0x01B6 -R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); 0x0043DE30 0x0106 -R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 8d8278a60..54e8fbc4e 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -1,14 +1,18 @@ #include "decomp/skidoo.h" +#include "game/effects.h" #include "game/input.h" #include "game/items.h" #include "game/lara/control.h" #include "game/math.h" #include "game/objects/common.h" +#include "game/random.h" #include "game/room.h" #include "global/funcs.h" #include "global/vars.h" +#include + typedef enum { SKIDOO_GET_ON_NONE = 0, SKIDOO_GET_ON_LEFT = 1, @@ -41,6 +45,8 @@ typedef enum { } LARA_ANIM_SKIDOO; #define SKIDOO_RADIUS 500 +#define SKIDOO_SIDE 260 +#define SKIDOO_SNOW 500 #define M_TARGET_DIST (WALL_L * 2) // = 2048 static bool M_IsNearby(const ITEM *item_1, const ITEM *item_2); @@ -218,3 +224,35 @@ int32_t __cdecl Skidoo_TestHeight( Room_GetSector(out_pos->x, out_pos->y, out_pos->z, &room_num); return Room_GetHeight(sector, out_pos->x, out_pos->y, out_pos->z); } + +void __cdecl Skidoo_DoSnowEffect(ITEM *const skidoo) +{ + const int16_t fx_num = Effect_Create(skidoo->room_num); + if (fx_num == NO_ITEM) { + return; + } + + const int32_t sx = Math_Sin(skidoo->rot.x); + const int32_t sy = Math_Sin(skidoo->rot.y); + const int32_t cy = Math_Cos(skidoo->rot.y); + const int32_t x = (SKIDOO_SIDE * (Random_GetDraw() - 0x4000)) >> 14; + FX *const fx = &g_Effects[fx_num]; + fx->pos.x = skidoo->pos.x - ((sy * SKIDOO_SNOW + cy * x) >> W2V_SHIFT); + fx->pos.y = skidoo->pos.y + ((sx * SKIDOO_SNOW) >> W2V_SHIFT); + fx->pos.z = skidoo->pos.z - ((cy * SKIDOO_SNOW - sy * x) >> W2V_SHIFT); + fx->room_num = skidoo->room_num; + fx->object_id = O_SNOW_SPRITE; + fx->frame_num = 0; + fx->speed = 0; + if (skidoo->speed < 64) { + fx->fall_speed = (Random_GetDraw() * ABS(skidoo->speed)) >> 15; + } else { + fx->fall_speed = 0; + } + + g_MatrixPtr->_23 = 0; + + S_CalculateLight(fx->pos.x, fx->pos.y, fx->pos.z, fx->room_num); + fx->shade = g_LsAdder - 512; + CLAMPL(fx->shade, 0); +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 6149343db..500de92ca 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -9,3 +9,4 @@ void __cdecl Skidoo_Collision( void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); int32_t __cdecl Skidoo_TestHeight( const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *out_pos); +void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 17d758a77..81bf5be94 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_DoSnowEffect ((void __cdecl (*)(ITEM *skidoo))0x0043D690) #define Skidoo_Dynamics ((int32_t __cdecl (*)(ITEM *skidoo))0x0043D7D0) #define Skidoo_UserControl ((int32_t __cdecl (*)(ITEM *skidoo, int32_t height, int32_t *pitch))0x0043DC70) #define Skidoo_CheckGetOffOK ((int32_t __cdecl (*)(int32_t direction))0x0043DE30) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index ee81080e5..2684e3ca6 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -249,6 +249,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043CF60, Skidoo_Collision); INJECT(enable, 0x0043D060, Skidoo_BaddieCollision); INJECT(enable, 0x0043D260, Skidoo_TestHeight); + INJECT(enable, 0x0043D690, Skidoo_DoSnowEffect); } static void M_DecompStats(const bool enable) From 6321828bde78e05fec041a17210e24a2ed39179d Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 17:18:06 +0200 Subject: [PATCH 08/22] tr2: port Skidoo_Dynamics --- docs/tr2/progress.svg | 16 ++-- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 171 +++++++++++++++++++++++++++++++++++++++- src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 179 insertions(+), 13 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index dcb7fd396..e48fc676c 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.32% (825) · 31.27% (389) · 0% (0) · 2.41% (30) +66.40% (826) · 31.19% (388) · 0% (0) · 2.41% (30) - - + + @@ -786,7 +786,7 @@ int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); -int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); +int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -70.68% · 29% · 0% · 0.33% +71.02% · 28.65% · 0% · 0.33% - - + + @@ -1375,7 +1375,7 @@ void __cdecl Output_InsertTrans8(const PHD_VBUF *vbuf, int16_t shade); void __cdecl Monk_Control(int16_t item_num); LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); +int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); void __cdecl Option_Sound(INVENTORY_ITEM *item); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); void __cdecl Pickup_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index b972ccede..a3856bdf8 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3665,7 +3665,7 @@ typedef enum { 0x0043D5A0 0x0054 -R int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); 0x0043D600 0x0090 -R int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); 0x0043D690 0x0140 +R void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); -0x0043D7D0 0x049E -R int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); +0x0043D7D0 0x049E +R int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); 0x0043DC70 0x01B6 -R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); 0x0043DE30 0x0106 -R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); 0x0043DF40 0x02B9 -R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 54e8fbc4e..1aca358a7 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -46,8 +46,20 @@ typedef enum { #define SKIDOO_RADIUS 500 #define SKIDOO_SIDE 260 +#define SKIDOO_FRONT 550 #define SKIDOO_SNOW 500 -#define M_TARGET_DIST (WALL_L * 2) // = 2048 + +#define SKIDOO_MAX_SPEED 100 +#define SKIDOO_ACCELERATION 10 +#define SKIDOO_SLIP 100 +#define SKIDOO_SLIP_SIDE 50 + +#define SKIDOO_MAX_BACK -30 +#define SKIDOO_UNDO_TURN (PHD_DEGREE * 2) // = 364 +#define SKIDOO_MOMENTUM_TURN (PHD_DEGREE * 3) // = 546 +#define SKIDOO_MAX_MOMENTUM_TURN (PHD_DEGREE * 150) // = 27300 + +#define SKIDOO_TARGET_DIST (WALL_L * 2) // = 2048 static bool M_IsNearby(const ITEM *item_1, const ITEM *item_2); static bool M_CheckBaddieCollision(ITEM *item, const ITEM *skidoo); @@ -57,8 +69,9 @@ static bool M_IsNearby(const ITEM *const item_1, const ITEM *const item_2) const int32_t dx = item_1->pos.x - item_2->pos.x; const int32_t dy = item_1->pos.y - item_2->pos.y; const int32_t dz = item_1->pos.z - item_2->pos.z; - return dx > -M_TARGET_DIST && dx < M_TARGET_DIST && dy > -M_TARGET_DIST - && dy < M_TARGET_DIST && dz > -M_TARGET_DIST && dz < M_TARGET_DIST; + return dx > -SKIDOO_TARGET_DIST && dx < SKIDOO_TARGET_DIST + && dy > -SKIDOO_TARGET_DIST && dy < SKIDOO_TARGET_DIST + && dz > -SKIDOO_TARGET_DIST && dz < SKIDOO_TARGET_DIST; } static bool M_CheckBaddieCollision(ITEM *const item, const ITEM *const skidoo) @@ -256,3 +269,155 @@ void __cdecl Skidoo_DoSnowEffect(ITEM *const skidoo) fx->shade = g_LsAdder - 512; CLAMPL(fx->shade, 0); } + +int32_t __cdecl Skidoo_Dynamics(ITEM *const skidoo) +{ + SKIDOO_INFO *const skidoo_data = skidoo->data; + + XYZ_32 fl_old; + XYZ_32 bl_old; + XYZ_32 br_old; + XYZ_32 fr_old; + int32_t hfl_old = + Skidoo_TestHeight(skidoo, SKIDOO_FRONT, -SKIDOO_SIDE, &fl_old); + int32_t hfr_old = + Skidoo_TestHeight(skidoo, SKIDOO_FRONT, SKIDOO_SIDE, &fr_old); + int32_t hbl_old = + Skidoo_TestHeight(skidoo, -SKIDOO_FRONT, -SKIDOO_SIDE, &bl_old); + int32_t hbr_old = + Skidoo_TestHeight(skidoo, -SKIDOO_FRONT, SKIDOO_SIDE, &br_old); + + XYZ_32 old = { + .z = skidoo->pos.z, + .x = skidoo->pos.x, + .y = skidoo->pos.y, + }; + + CLAMPG(bl_old.y, hbl_old); + CLAMPG(br_old.y, hbr_old); + CLAMPG(fl_old.y, hfl_old); + CLAMPG(fr_old.y, hfr_old); + + if (skidoo->pos.y <= skidoo->floor - STEP_L) { + skidoo->rot.y += skidoo_data->extra_rotation + skidoo_data->skidoo_turn; + } else { + if (skidoo_data->skidoo_turn < -SKIDOO_UNDO_TURN) { + skidoo_data->skidoo_turn += SKIDOO_UNDO_TURN; + } else if (skidoo_data->skidoo_turn > SKIDOO_UNDO_TURN) { + skidoo_data->skidoo_turn -= SKIDOO_UNDO_TURN; + } else { + skidoo_data->skidoo_turn = 0; + } + skidoo->rot.y += skidoo_data->skidoo_turn + skidoo_data->extra_rotation; + + int16_t rot = skidoo->rot.y - skidoo_data->momentum_angle; + if (rot < -SKIDOO_MOMENTUM_TURN) { + if (rot < -SKIDOO_MAX_MOMENTUM_TURN) { + rot = -SKIDOO_MAX_MOMENTUM_TURN; + skidoo_data->momentum_angle = skidoo->rot.y - rot; + } else { + skidoo_data->momentum_angle -= SKIDOO_MOMENTUM_TURN; + } + } else if (rot > SKIDOO_MOMENTUM_TURN) { + if (rot > SKIDOO_MAX_MOMENTUM_TURN) { + rot = SKIDOO_MAX_MOMENTUM_TURN; + skidoo_data->momentum_angle = skidoo->rot.y - rot; + } else { + skidoo_data->momentum_angle += SKIDOO_MOMENTUM_TURN; + } + } else { + skidoo_data->momentum_angle = skidoo->rot.y; + } + } + + skidoo->pos.z += + (skidoo->speed * Math_Cos(skidoo_data->momentum_angle)) >> W2V_SHIFT; + skidoo->pos.x += + (skidoo->speed * Math_Sin(skidoo_data->momentum_angle)) >> W2V_SHIFT; + + int32_t slip; + slip = (SKIDOO_SLIP * Math_Sin(skidoo->rot.x)) >> W2V_SHIFT; + if (ABS(slip) > SKIDOO_SLIP / 2) { + skidoo->pos.z -= (slip * Math_Cos(skidoo->rot.y)) >> W2V_SHIFT; + skidoo->pos.x -= (slip * Math_Sin(skidoo->rot.y)) >> W2V_SHIFT; + } + + slip = (SKIDOO_SLIP_SIDE * Math_Sin(skidoo->rot.z)) >> W2V_SHIFT; + if (ABS(slip) > SKIDOO_SLIP_SIDE / 2) { + skidoo->pos.z -= (slip * Math_Sin(skidoo->rot.y)) >> W2V_SHIFT; + skidoo->pos.x += (slip * Math_Cos(skidoo->rot.y)) >> W2V_SHIFT; + } + + XYZ_32 moved = { + .x = skidoo->pos.x, + .z = skidoo->pos.z, + }; + if (!(skidoo->flags & IF_ONE_SHOT)) { + Skidoo_BaddieCollision(skidoo); + } + + int32_t rot = 0; + + XYZ_32 br; + XYZ_32 fl; + XYZ_32 bl; + XYZ_32 fr; + const int32_t hbl = + Skidoo_TestHeight(skidoo, -SKIDOO_FRONT, -SKIDOO_SIDE, &bl); + if (hbl < bl_old.y - STEP_L) { + rot = DoShift(skidoo, &bl, &bl_old); + } + const int32_t hbr = + Skidoo_TestHeight(skidoo, -SKIDOO_FRONT, SKIDOO_SIDE, &br); + if (hbr < br_old.y - STEP_L) { + rot += DoShift(skidoo, &br, &br_old); + } + const int32_t hfl = + Skidoo_TestHeight(skidoo, SKIDOO_FRONT, -SKIDOO_SIDE, &fl); + if (hfl < fl_old.y - STEP_L) { + rot += DoShift(skidoo, &fl, &fl_old); + } + const int32_t hfr = + Skidoo_TestHeight(skidoo, SKIDOO_FRONT, SKIDOO_SIDE, &fr); + if (hfr < fr_old.y - STEP_L) { + rot += DoShift(skidoo, &fr, &fr_old); + } + + int16_t room_num = skidoo->room_num; + const SECTOR *const sector = + Room_GetSector(skidoo->pos.x, skidoo->pos.y, skidoo->pos.z, &room_num); + const int32_t height = + Room_GetHeight(sector, skidoo->pos.x, skidoo->pos.y, skidoo->pos.z); + if (height < skidoo->pos.y - STEP_L) { + DoShift(skidoo, &skidoo->pos, &old); + } + + skidoo_data->extra_rotation = rot; + + int32_t collide = GetCollisionAnim(skidoo, &moved); + if (collide != 0) { + const int32_t c = Math_Cos(skidoo_data->momentum_angle); + const int32_t s = Math_Sin(skidoo_data->momentum_angle); + const int32_t dx = skidoo->pos.x - old.x; + const int32_t dz = skidoo->pos.z - old.z; + const int32_t new_speed = (s * dx + c * dz) >> W2V_SHIFT; + + if (skidoo == Item_Get(g_Lara.skidoo) + && skidoo->speed > SKIDOO_MAX_SPEED + SKIDOO_ACCELERATION + && new_speed < skidoo->speed - SKIDOO_ACCELERATION) { + Lara_TakeDamage((skidoo->speed - new_speed) / 2, true); + } + + if (skidoo->speed > 0 && new_speed < skidoo->speed) { + skidoo->speed = new_speed < 0 ? 0 : new_speed; + } else if (skidoo->speed < 0 && new_speed > skidoo->speed) { + skidoo->speed = new_speed > 0 ? 0 : new_speed; + } + + if (skidoo->speed < SKIDOO_MAX_BACK) { + skidoo->speed = SKIDOO_MAX_BACK; + } + } + + return collide; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 500de92ca..b9fbcf374 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -10,3 +10,4 @@ void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); int32_t __cdecl Skidoo_TestHeight( const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *out_pos); void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); +int32_t __cdecl Skidoo_Dynamics(ITEM *const skidoo); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 81bf5be94..1d245f62f 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_Dynamics ((int32_t __cdecl (*)(ITEM *skidoo))0x0043D7D0) #define Skidoo_UserControl ((int32_t __cdecl (*)(ITEM *skidoo, int32_t height, int32_t *pitch))0x0043DC70) #define Skidoo_CheckGetOffOK ((int32_t __cdecl (*)(int32_t direction))0x0043DE30) #define Skidoo_Animation ((void __cdecl (*)(ITEM *skidoo, int32_t collide, int32_t dead))0x0043DF40) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 2684e3ca6..af373ea29 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -250,6 +250,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043D060, Skidoo_BaddieCollision); INJECT(enable, 0x0043D260, Skidoo_TestHeight); INJECT(enable, 0x0043D690, Skidoo_DoSnowEffect); + INJECT(enable, 0x0043D7D0, Skidoo_Dynamics); } static void M_DecompStats(const bool enable) From f3114f19b26bb29e2e693243ecc5b1bc78f6a0ad Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 18:08:48 +0200 Subject: [PATCH 09/22] tr2: port Skidoo_UserControl --- docs/tr2/progress.svg | 16 ++++---- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 85 +++++++++++++++++++++++++++++++++++++++++ src/tr2/decomp/skidoo.h | 2 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 97 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index e48fc676c..0b3423671 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.40% (826) · 31.19% (388) · 0% (0) · 2.41% (30) +66.48% (827) · 31.11% (387) · 0% (0) · 2.41% (30) - - + + @@ -787,7 +787,7 @@ int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); -int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); +int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Skidoo_Explode(ITEM *skidoo); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -71.02% · 28.65% · 0% · 0.33% +71.15% · 28.52% · 0% · 0.33% - - + + @@ -1541,7 +1541,7 @@ BOOL __stdcall EnumDisplayAdaptersCallback(GUID *lpGUID, LPTSTR lpDriverDescription, LPTSTR lpDriverName, LPVOID lpContext); void __cdecl BGND_Make640x480(uint8_t *bitmap, RGB_888 *palette); void __cdecl D3DDeviceCreate(LPDDS lpBackBuffer); -int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); +int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); void __cdecl Item_Initialise(int16_t item_num); int32_t __cdecl Demo_Start(int32_t level_num); bool __cdecl LOT_EnableBaddieAI(int16_t item_num, bool always); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index a3856bdf8..28041cfe2 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3666,7 +3666,7 @@ typedef enum { 0x0043D600 0x0090 -R int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); 0x0043D690 0x0140 +R void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); 0x0043D7D0 0x049E +R int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); -0x0043DC70 0x01B6 -R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); +0x0043DC70 0x01B6 +R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); 0x0043DE30 0x0106 -R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); 0x0043DF40 0x02B9 -R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); 0x0043E220 0x007C -R void __cdecl Skidoo_Explode(ITEM *skidoo); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 1aca358a7..d5b02d495 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -4,6 +4,7 @@ #include "game/input.h" #include "game/items.h" #include "game/lara/control.h" +#include "game/lara/look.h" #include "game/math.h" #include "game/objects/common.h" #include "game/random.h" @@ -49,13 +50,22 @@ typedef enum { #define SKIDOO_FRONT 550 #define SKIDOO_SNOW 500 +#define SKIDOO_MIN_SPEED 15 #define SKIDOO_MAX_SPEED 100 +#define SKIDOO_SLOW_SPEED 50 +#define SKIDOO_FAST_SPEED 150 #define SKIDOO_ACCELERATION 10 +#define SKIDOO_SLOWDOWN 2 + #define SKIDOO_SLIP 100 #define SKIDOO_SLIP_SIDE 50 #define SKIDOO_MAX_BACK -30 +#define SKIDOO_BRAKE 5 +#define SKIDOO_REVERSE (-5) #define SKIDOO_UNDO_TURN (PHD_DEGREE * 2) // = 364 +#define SKIDOO_TURN (PHD_DEGREE / 2 + SKIDOO_UNDO_TURN) // = 455 +#define SKIDOO_MAX_TURN (PHD_DEGREE * 6) // = 1092 #define SKIDOO_MOMENTUM_TURN (PHD_DEGREE * 3) // = 546 #define SKIDOO_MAX_MOMENTUM_TURN (PHD_DEGREE * 150) // = 27300 @@ -421,3 +431,78 @@ int32_t __cdecl Skidoo_Dynamics(ITEM *const skidoo) return collide; } + +int32_t __cdecl Skidoo_UserControl( + ITEM *const skidoo, const int32_t height, int32_t *const out_pitch) +{ + SKIDOO_INFO *const skidoo_data = skidoo->data; + + bool drive = false; + + if (skidoo->pos.y >= height - STEP_L) { + *out_pitch = skidoo->speed + (height - skidoo->pos.y); + + if (skidoo->speed == 0 && (g_Input & IN_LOOK)) { + Lara_LookUpDown(); + } + + if (((g_Input & IN_LEFT) && !(g_Input & IN_BACK)) + || ((g_Input & IN_RIGHT) && (g_Input & IN_BACK))) { + skidoo_data->skidoo_turn -= SKIDOO_TURN; + CLAMPL(skidoo_data->skidoo_turn, -SKIDOO_MAX_TURN); + } + + if (((g_Input & IN_RIGHT) && !(g_Input & IN_BACK)) + || ((g_Input & IN_LEFT) && (g_Input & IN_BACK))) { + skidoo_data->skidoo_turn += SKIDOO_TURN; + CLAMPG(skidoo_data->skidoo_turn, SKIDOO_MAX_TURN); + } + + if (g_Input & IN_BACK) { + if (skidoo->speed > 0) { + skidoo->speed -= SKIDOO_BRAKE; + } else { + if (skidoo->speed > SKIDOO_MAX_BACK) { + skidoo->speed += SKIDOO_REVERSE; + } + drive = true; + } + } else if (g_Input & IN_FORWARD) { + int32_t max_speed; + if ((g_Input & IN_ACTION) && !(skidoo_data->track_mesh & 4)) { + max_speed = SKIDOO_FAST_SPEED; + } else if (g_Input & IN_SLOW) { + max_speed = SKIDOO_SLOW_SPEED; + } else { + max_speed = SKIDOO_MAX_SPEED; + } + + if (skidoo->speed < max_speed) { + skidoo->speed += + SKIDOO_ACCELERATION * skidoo->speed / (2 * max_speed) + + SKIDOO_ACCELERATION / 2; + } else if (skidoo->speed > max_speed + SKIDOO_SLOWDOWN) { + skidoo->speed -= SKIDOO_SLOWDOWN; + } + + drive = true; + } else if ( + skidoo->speed >= 0 && skidoo->speed < SKIDOO_MIN_SPEED + && (g_Input & (IN_LEFT | IN_RIGHT))) { + skidoo->speed = SKIDOO_MIN_SPEED; + drive = true; + } else if (skidoo->speed > SKIDOO_SLOWDOWN) { + skidoo->speed -= SKIDOO_SLOWDOWN; + if ((Random_GetDraw() & 0x7F) < skidoo->speed) { + drive = true; + } + } else { + skidoo->speed = 0; + } + } else if (g_Input & (IN_FORWARD | IN_BACK)) { + drive = true; + *out_pitch = skidoo_data->pitch + 50; + } + + return drive; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index b9fbcf374..f8e957d72 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -11,3 +11,5 @@ int32_t __cdecl Skidoo_TestHeight( const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *out_pos); void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); int32_t __cdecl Skidoo_Dynamics(ITEM *const skidoo); +int32_t __cdecl Skidoo_UserControl( + ITEM *skidoo, int32_t height, int32_t *out_pitch); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 1d245f62f..a28f687d1 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_UserControl ((int32_t __cdecl (*)(ITEM *skidoo, int32_t height, int32_t *pitch))0x0043DC70) #define Skidoo_CheckGetOffOK ((int32_t __cdecl (*)(int32_t direction))0x0043DE30) #define Skidoo_Animation ((void __cdecl (*)(ITEM *skidoo, int32_t collide, int32_t dead))0x0043DF40) #define Skidoo_Explode ((void __cdecl (*)(ITEM *skidoo))0x0043E220) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index af373ea29..d776e70a8 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -251,6 +251,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043D260, Skidoo_TestHeight); INJECT(enable, 0x0043D690, Skidoo_DoSnowEffect); INJECT(enable, 0x0043D7D0, Skidoo_Dynamics); + INJECT(enable, 0x0043DC70, Skidoo_UserControl); } static void M_DecompStats(const bool enable) From 7b6e1f86abd7859b44d6dd3bf3b732952660ebc8 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 23:01:22 +0200 Subject: [PATCH 10/22] tr2: port Skidoo_CheckGetOffOK --- docs/tr2/progress.svg | 16 ++++++++-------- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 52 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 0b3423671..b3d666355 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.48% (827) · 31.11% (387) · 0% (0) · 2.41% (30) +66.56% (828) · 31.03% (386) · 0% (0) · 2.41% (30) - - + + @@ -788,7 +788,7 @@ void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); -int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); +int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Skidoo_Explode(ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -71.15% · 28.52% · 0% · 0.33% +71.23% · 28.45% · 0% · 0.33% - - + + @@ -1682,7 +1682,7 @@ int32_t __cdecl Text_GetWidth(TEXTSTRING *string); int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl LOT_InitialiseSlot(int16_t item_num, int32_t slot); -int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); +int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); TEXTSTRING *__cdecl Text_Create(int32_t x, int32_t y, int32_t z, const char *text); void __cdecl FallingBlock(int16_t item_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 28041cfe2..cb3630f7a 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3667,7 +3667,7 @@ typedef enum { 0x0043D690 0x0140 +R void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); 0x0043D7D0 0x049E +R int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); 0x0043DC70 0x01B6 +R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); -0x0043DE30 0x0106 -R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); +0x0043DE30 0x0106 +R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); 0x0043DF40 0x02B9 -R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); 0x0043E220 0x007C -R void __cdecl Skidoo_Explode(ITEM *skidoo); 0x0043E2A0 0x0233 -R int32_t __cdecl Skidoo_CheckGetOff(void); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index d5b02d495..6ba71a6ce 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -49,6 +49,7 @@ typedef enum { #define SKIDOO_SIDE 260 #define SKIDOO_FRONT 550 #define SKIDOO_SNOW 500 +#define SKIDOO_GET_OFF_DIST 330 #define SKIDOO_MIN_SPEED 15 #define SKIDOO_MAX_SPEED 100 @@ -506,3 +507,43 @@ int32_t __cdecl Skidoo_UserControl( return drive; } + +int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction) +{ + ITEM *const skidoo = Item_Get(g_Lara.skidoo); + + int16_t rot; + if (direction == LARA_STATE_SKIDOO_GET_OFF_L) { + rot = skidoo->rot.y + PHD_90; + } else { + rot = skidoo->rot.y - PHD_90; + } + + const int32_t c = Math_Cos(rot); + const int32_t s = Math_Sin(rot); + const int32_t x = skidoo->pos.x - ((SKIDOO_GET_OFF_DIST * s) >> W2V_SHIFT); + const int32_t z = skidoo->pos.z - ((SKIDOO_GET_OFF_DIST * c) >> W2V_SHIFT); + const int32_t y = skidoo->pos.y; + + int16_t room_num = skidoo->room_num; + const SECTOR *const sector = Room_GetSector(x, y, z, &room_num); + const int32_t height = Room_GetHeight(sector, x, y, z); + + if (g_HeightType == HT_BIG_SLOPE || height == NO_HEIGHT) { + return false; + } + + if (ABS(height - skidoo->pos.y) > WALL_L / 2) { + return false; + } + + const int32_t ceiling = Room_GetCeiling(sector, x, y, z); + if (ceiling - skidoo->pos.y > -LARA_HEIGHT) { + return false; + } + if (height - ceiling < LARA_HEIGHT) { + return false; + } + + return true; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index f8e957d72..1f082c006 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -13,3 +13,4 @@ void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); int32_t __cdecl Skidoo_Dynamics(ITEM *const skidoo); int32_t __cdecl Skidoo_UserControl( ITEM *skidoo, int32_t height, int32_t *out_pitch); +int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index a28f687d1..07c434dfc 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_CheckGetOffOK ((int32_t __cdecl (*)(int32_t direction))0x0043DE30) #define Skidoo_Animation ((void __cdecl (*)(ITEM *skidoo, int32_t collide, int32_t dead))0x0043DF40) #define Skidoo_Explode ((void __cdecl (*)(ITEM *skidoo))0x0043E220) #define Skidoo_CheckGetOff ((int32_t __cdecl (*)(void))0x0043E2A0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index d776e70a8..5d683f019 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -252,6 +252,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043D690, Skidoo_DoSnowEffect); INJECT(enable, 0x0043D7D0, Skidoo_Dynamics); INJECT(enable, 0x0043DC70, Skidoo_UserControl); + INJECT(enable, 0x0043DE30, Skidoo_CheckGetOffOK); } static void M_DecompStats(const bool enable) From 7bb51a210a7dcfed6371a81f6f64584ab067dd5e Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 23:20:47 +0200 Subject: [PATCH 11/22] tr2: port Skidoo_Animation --- docs/tr2/progress.svg | 16 +++--- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 121 +++++++++++++++++++++++++++++++++++++++- src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 130 insertions(+), 12 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index b3d666355..4cf900f96 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.56% (828) · 31.03% (386) · 0% (0) · 2.41% (30) +66.64% (829) · 30.95% (385) · 0% (0) · 2.41% (30) - - + + @@ -789,7 +789,7 @@ int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); -void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); +void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Skidoo_Explode(ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl Skidoo_Guns(void); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -71.23% · 28.45% · 0% · 0.33% +71.43% · 28.24% · 0% · 0.33% - - + + @@ -1455,7 +1455,7 @@ void __cdecl GiantYeti_Control(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); void __cdecl Lara_Initialise(int32_t type); -void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); +void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Room_DrawAllRooms(int16_t current_room); void __cdecl PuzzleHole_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); void __cdecl Zipline_Control(int16_t item_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index cb3630f7a..53dbc28ee 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3668,7 +3668,7 @@ typedef enum { 0x0043D7D0 0x049E +R int32_t __cdecl Skidoo_Dynamics(ITEM *skidoo); 0x0043DC70 0x01B6 +R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); 0x0043DE30 0x0106 +R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); -0x0043DF40 0x02B9 -R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); +0x0043DF40 0x02B9 +R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); 0x0043E220 0x007C -R void __cdecl Skidoo_Explode(ITEM *skidoo); 0x0043E2A0 0x0233 -R int32_t __cdecl Skidoo_CheckGetOff(void); 0x0043E4E0 0x011B -R void __cdecl Skidoo_Guns(void); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 6ba71a6ce..2bdfc6076 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -6,9 +6,11 @@ #include "game/lara/control.h" #include "game/lara/look.h" #include "game/math.h" +#include "game/music.h" #include "game/objects/common.h" #include "game/random.h" #include "game/room.h" +#include "game/sound.h" #include "global/funcs.h" #include "global/vars.h" @@ -31,8 +33,8 @@ typedef enum { LARA_STATE_SKIDOO_GET_ON_L = 6, LARA_STATE_SKIDOO_GET_OFF_L = 7, LARA_STATE_SKIDOO_STILL = 8, - LARA_STATE_SKIDOO_GET_OFF = 9, - LARA_STATE_SKIDOO_LETGO = 10, + LARA_STATE_SKIDOO_GET_OFF_R = 9, + LARA_STATE_SKIDOO_LET_GO = 10, LARA_STATE_SKIDOO_DEATH = 11, LARA_STATE_SKIDOO_FALLOFF = 12, // clang-format on @@ -41,6 +43,12 @@ typedef enum { typedef enum { // clang-format off LA_SKIDOO_GET_ON_L = 1, + LA_SKIDOO_FALL = 8, + LA_SKIDOO_HIT_LEFT = 11, + LA_SKIDOO_HIT_RIGHT = 12, + LA_SKIDOO_HIT_FRONT = 13, + LA_SKIDOO_HIT_BACK = 14, + LA_SKIDOO_DEAD = 15, LA_SKIDOO_GET_ON_R = 18, // clang-format on } LARA_ANIM_SKIDOO; @@ -547,3 +555,112 @@ int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction) return true; } + +void __cdecl Skidoo_Animation( + ITEM *const skidoo, const int32_t collide, const int32_t dead) +{ + const SKIDOO_INFO *const skidoo_data = skidoo->data; + + if (skidoo->pos.y != skidoo->floor && skidoo->fall_speed > 0 + && g_LaraItem->current_anim_state != 4 && !dead) { + g_LaraItem->anim_num = + g_Objects[O_LARA_SKIDOO].anim_idx + LA_SKIDOO_FALL; + g_LaraItem->frame_num = g_Anims[g_LaraItem->anim_num].frame_base; + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_FALL; + g_LaraItem->current_anim_state = LARA_STATE_SKIDOO_FALL; + return; + } + + if (collide != 0 && !dead + && g_LaraItem->current_anim_state != LARA_STATE_SKIDOO_FALL) { + if (g_LaraItem->current_anim_state != LARA_STATE_SKIDOO_HIT) { + if (collide == LA_SKIDOO_HIT_FRONT) { + Sound_Effect(SFX_CLATTER_2, &skidoo->pos, SPM_NORMAL); + } else { + Sound_Effect(SFX_CLATTER_1, &skidoo->pos, SPM_NORMAL); + } + g_LaraItem->anim_num = g_Objects[O_LARA_SKIDOO].anim_idx + collide; + g_LaraItem->frame_num = g_Anims[g_LaraItem->anim_num].frame_base; + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_HIT; + g_LaraItem->current_anim_state = LARA_STATE_SKIDOO_HIT; + } + return; + } + + switch (g_LaraItem->current_anim_state) { + case LARA_STATE_SKIDOO_SIT: + if (skidoo->speed == 0) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_STILL; + } + if (dead) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_FALLOFF; + } else if (g_Input & IN_LEFT) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_LEFT; + } else if (g_Input & IN_RIGHT) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_RIGHT; + } + break; + + case LARA_STATE_SKIDOO_LEFT: + if (!(g_Input & IN_LEFT)) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_SIT; + } + break; + + case LARA_STATE_SKIDOO_RIGHT: + if (!(g_Input & IN_RIGHT)) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_SIT; + } + break; + + case LARA_STATE_SKIDOO_FALL: + if (skidoo->fall_speed <= 0 || skidoo_data->left_fallspeed <= 0 + || skidoo_data->right_fallspeed <= 0) { + Sound_Effect(SFX_CLATTER_3, &skidoo->pos, SPM_NORMAL); + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_SIT; + } else if (skidoo->fall_speed > DAMAGE_START + DAMAGE_LENGTH) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_LET_GO; + } + break; + + case LARA_STATE_SKIDOO_STILL: { + const int32_t music_track = + (skidoo_data->track_mesh & 4) ? MX_BATTLE_THEME : MX_SKIDOO_THEME; + if (!(g_MusicTrackFlags[music_track] & IF_ONE_SHOT)) { + Music_Play(music_track, false); + g_LaraItem = g_LaraItem; + g_MusicTrackFlags[music_track] |= IF_ONE_SHOT; + } + + if (dead) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_DEATH; + return; + } + + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_STILL; + + if (g_Input & IN_JUMP) { + if ((g_Input & IN_RIGHT) + && Skidoo_CheckGetOffOK(LARA_STATE_SKIDOO_GET_OFF_R)) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_GET_OFF_R; + skidoo->speed = 0; + } else if ( + (g_Input & IN_LEFT) + && Skidoo_CheckGetOffOK(LARA_STATE_SKIDOO_GET_OFF_L)) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_GET_OFF_L; + skidoo->speed = 0; + } + } else if (g_Input & IN_LEFT) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_LEFT; + } else if (g_Input & IN_RIGHT) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_RIGHT; + } else if (g_Input & (IN_BACK | IN_FORWARD)) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_SIT; + } + break; + } + + default: + break; + } +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 1f082c006..e5a4de64d 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -14,3 +14,4 @@ int32_t __cdecl Skidoo_Dynamics(ITEM *const skidoo); int32_t __cdecl Skidoo_UserControl( ITEM *skidoo, int32_t height, int32_t *out_pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); +void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 07c434dfc..69a7bf54c 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_Animation ((void __cdecl (*)(ITEM *skidoo, int32_t collide, int32_t dead))0x0043DF40) #define Skidoo_Explode ((void __cdecl (*)(ITEM *skidoo))0x0043E220) #define Skidoo_CheckGetOff ((int32_t __cdecl (*)(void))0x0043E2A0) #define Skidoo_Guns ((void __cdecl (*)(void))0x0043E4E0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 5d683f019..875bcd383 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -253,6 +253,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043D7D0, Skidoo_Dynamics); INJECT(enable, 0x0043DC70, Skidoo_UserControl); INJECT(enable, 0x0043DE30, Skidoo_CheckGetOffOK); + INJECT(enable, 0x0043DF40, Skidoo_Animation); } static void M_DecompStats(const bool enable) From f19f3b96419ef1d0bbce2b0f4994bc5574b3eb05 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 23:22:11 +0200 Subject: [PATCH 12/22] tr2: port Skidoo_Explode --- docs/tr2/progress.svg | 16 ++++++++-------- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 19 +++++++++++++++++++ src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 4cf900f96..b91e86fbf 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.64% (829) · 30.95% (385) · 0% (0) · 2.41% (30) +66.72% (830) · 30.87% (384) · 0% (0) · 2.41% (30) - - + + @@ -790,7 +790,7 @@ int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); -void __cdecl Skidoo_Explode(ITEM *skidoo); +void __cdecl Skidoo_Explode(ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl Skidoo_Guns(void); int32_t __cdecl Skidoo_Control(void); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -71.43% · 28.24% · 0% · 0.33% +71.47% · 28.21% · 0% · 0.33% - - + + @@ -1974,7 +1974,7 @@ void __cdecl Lara_State_StepLeft(ITEM *item, COLL_INFO *coll); void __cdecl Gun_Pistols_Draw(LARA_GUN_TYPE weapon_type); void __cdecl InitialiseDyingMonk(int16_t item_num); -void __cdecl Skidoo_Explode(ITEM *skidoo); +void __cdecl Skidoo_Explode(ITEM *skidoo); int32_t __cdecl WinGameStart(void); void __cdecl Gun_Rifle_FireM16(bool running); void __cdecl Matrix_TranslateAbs(int32_t x, int32_t y, int32_t z); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 53dbc28ee..12be40588 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3669,7 +3669,7 @@ typedef enum { 0x0043DC70 0x01B6 +R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); 0x0043DE30 0x0106 +R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); 0x0043DF40 0x02B9 +R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); -0x0043E220 0x007C -R void __cdecl Skidoo_Explode(ITEM *skidoo); +0x0043E220 0x007C +R void __cdecl Skidoo_Explode(ITEM *skidoo); 0x0043E2A0 0x0233 -R int32_t __cdecl Skidoo_CheckGetOff(void); 0x0043E4E0 0x011B -R void __cdecl Skidoo_Guns(void); 0x0043E600 0x0440 -R int32_t __cdecl Skidoo_Control(void); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 2bdfc6076..e3e621d41 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -664,3 +664,22 @@ void __cdecl Skidoo_Animation( break; } } + +void __cdecl Skidoo_Explode(ITEM *const skidoo) +{ + const int16_t fx_num = Effect_Create(skidoo->room_num); + if (fx_num != NO_ITEM) { + FX *const fx = &g_Effects[fx_num]; + fx->pos.x = skidoo->pos.x; + fx->pos.y = skidoo->pos.y; + fx->pos.z = skidoo->pos.z; + fx->speed = 0; + fx->frame_num = 0; + fx->counter = 0; + fx->object_id = O_EXPLOSION; + } + + Effect_ExplodingDeath(g_Lara.skidoo, -4, 0); + Sound_Effect(SFX_EXPLOSION1, NULL, SPM_NORMAL); + g_Lara.skidoo = NO_ITEM; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index e5a4de64d..98f36c887 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -15,3 +15,4 @@ int32_t __cdecl Skidoo_UserControl( ITEM *skidoo, int32_t height, int32_t *out_pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); +void __cdecl Skidoo_Explode(ITEM *skidoo); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 69a7bf54c..f3d1c6777 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_Explode ((void __cdecl (*)(ITEM *skidoo))0x0043E220) #define Skidoo_CheckGetOff ((int32_t __cdecl (*)(void))0x0043E2A0) #define Skidoo_Guns ((void __cdecl (*)(void))0x0043E4E0) #define Skidoo_Control ((int32_t __cdecl (*)(void))0x0043E600) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 875bcd383..8742452cb 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -254,6 +254,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043DC70, Skidoo_UserControl); INJECT(enable, 0x0043DE30, Skidoo_CheckGetOffOK); INJECT(enable, 0x0043DF40, Skidoo_Animation); + INJECT(enable, 0x0043E220, Skidoo_Explode); } static void M_DecompStats(const bool enable) From 1cf7a3af73c8afd6129277181d2a7123e15f2dd1 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 23:29:26 +0200 Subject: [PATCH 13/22] tr2: port Skidoo_CheckGetOff --- docs/tr2/progress.svg | 28 +++++++++---------- docs/tr2/progress.txt | 8 +++--- src/tr2/decomp/skidoo.c | 61 ++++++++++++++++++++++++++++++++++++++++- src/tr2/decomp/skidoo.h | 3 +- src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 81 insertions(+), 21 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index b91e86fbf..6e5612fc7 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.72% (830) · 30.87% (384) · 0% (0) · 2.41% (30) +66.80% (831) · 30.79% (383) · 0% (0) · 2.41% (30) - - + + @@ -780,8 +780,8 @@ void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); -void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); -int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); +int32_t __cdecl Skidoo_TestHeight(const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); @@ -790,8 +790,8 @@ int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); -void __cdecl Skidoo_Explode(ITEM *skidoo); -int32_t __cdecl Skidoo_CheckGetOff(void); +void __cdecl Skidoo_Explode(const ITEM *skidoo); +int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl Skidoo_Guns(void); int32_t __cdecl Skidoo_Control(void); void __cdecl Skidoo_Armed_Draw(const ITEM *item); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -71.47% · 28.21% · 0% · 0.33% +71.63% · 28.04% · 0% · 0.33% - - + + @@ -1485,7 +1485,7 @@ void __cdecl MovableBlock_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Lara_TestClimbUpPos(ITEM *item, int32_t front, int32_t right, int32_t *shift, int32_t *ledge); void __cdecl SE_OptionsDlgUpdate(HWND hwndDlg); -int32_t __cdecl Skidoo_CheckGetOff(void); +int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl DisplayCredits(void); void __cdecl Gun_Pistols_Undraw(LARA_GUN_TYPE weapon_type); int32_t __cdecl MovableBlock_TestPull(ITEM *item, int32_t block_height, uint16_t quadrant); @@ -1509,7 +1509,7 @@ void __cdecl CreateStartInfo(int32_t level_num); void __cdecl Bird_Control(int16_t item_num); void __cdecl BodyPart_Control(int16_t fx_num); -void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); +void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); void __cdecl S_DrawAirBar(int32_t percent); void __cdecl Screenshot(LPDDS screen); void __cdecl MineControl(int16_t mine_num); @@ -1819,7 +1819,7 @@ void __cdecl Lara_Col_FastBack(ITEM *item, COLL_INFO *coll); void __cdecl Lara_Col_Roll2(ITEM *item, COLL_INFO *coll); void __cdecl AssaultFinished(ITEM *item); -int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +int32_t __cdecl Skidoo_TestHeight(const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); int32_t __cdecl Lara_TestHangSwingIn(ITEM *item, PHD_ANGLE angle); int32_t __cdecl OnDrawBridge(ITEM *item, int32_t x, int32_t y); void __cdecl S_AnimateTextures(int32_t ticks); @@ -1974,7 +1974,7 @@ void __cdecl Lara_State_StepLeft(ITEM *item, COLL_INFO *coll); void __cdecl Gun_Pistols_Draw(LARA_GUN_TYPE weapon_type); void __cdecl InitialiseDyingMonk(int16_t item_num); -void __cdecl Skidoo_Explode(ITEM *skidoo); +void __cdecl Skidoo_Explode(const ITEM *skidoo); int32_t __cdecl WinGameStart(void); void __cdecl Gun_Rifle_FireM16(bool running); void __cdecl Matrix_TranslateAbs(int32_t x, int32_t y, int32_t z); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 12be40588..80b8b847c 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3659,8 +3659,8 @@ typedef enum { 0x0043CE30 0x0040 +R void __cdecl Skidoo_Initialise(int16_t item_num); 0x0043CE70 0x00E1 +R int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); 0x0043CF60 0x00F8 +R void __cdecl Skidoo_Collision(int16_t item_num, ITEM *litem, COLL_INFO *coll); -0x0043D060 0x01F9 +R void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); -0x0043D260 0x00B2 +R int32_t __cdecl Skidoo_TestHeight(ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); +0x0043D060 0x01F9 +R void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); +0x0043D260 0x00B2 +R int32_t __cdecl Skidoo_TestHeight(const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *pos); 0x0043D320 0x027C -R int32_t __cdecl DoShift(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old); 0x0043D5A0 0x0054 -R int32_t __cdecl DoDynamics(int32_t height, int32_t fall_speed, int32_t *y); 0x0043D600 0x0090 -R int32_t __cdecl GetCollisionAnim(ITEM *skidoo, XYZ_32 *moved); @@ -3669,8 +3669,8 @@ typedef enum { 0x0043DC70 0x01B6 +R int32_t __cdecl Skidoo_UserControl(ITEM *skidoo, int32_t height, int32_t *pitch); 0x0043DE30 0x0106 +R int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); 0x0043DF40 0x02B9 +R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); -0x0043E220 0x007C +R void __cdecl Skidoo_Explode(ITEM *skidoo); -0x0043E2A0 0x0233 -R int32_t __cdecl Skidoo_CheckGetOff(void); +0x0043E220 0x007C +R void __cdecl Skidoo_Explode(const ITEM *skidoo); +0x0043E2A0 0x0233 +R int32_t __cdecl Skidoo_CheckGetOff(void); 0x0043E4E0 0x011B -R void __cdecl Skidoo_Guns(void); 0x0043E600 0x0440 -R int32_t __cdecl Skidoo_Control(void); 0x0043EA60 0x02D5 -R void __cdecl Skidoo_Armed_Draw(const ITEM *item); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index e3e621d41..cebc1cf5f 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -665,7 +665,7 @@ void __cdecl Skidoo_Animation( } } -void __cdecl Skidoo_Explode(ITEM *const skidoo) +void __cdecl Skidoo_Explode(const ITEM *const skidoo) { const int16_t fx_num = Effect_Create(skidoo->room_num); if (fx_num != NO_ITEM) { @@ -683,3 +683,62 @@ void __cdecl Skidoo_Explode(ITEM *const skidoo) Sound_Effect(SFX_EXPLOSION1, NULL, SPM_NORMAL); g_Lara.skidoo = NO_ITEM; } + +int32_t __cdecl Skidoo_CheckGetOff(void) +{ + ITEM *const skidoo = &g_Items[g_Lara.skidoo]; + + if ((g_LaraItem->current_anim_state == LARA_STATE_SKIDOO_GET_OFF_R + || g_LaraItem->current_anim_state == LARA_STATE_SKIDOO_GET_OFF_L) + && g_LaraItem->frame_num == g_Anims[g_LaraItem->anim_num].frame_end) { + if (g_LaraItem->current_anim_state == LARA_STATE_SKIDOO_GET_OFF_L) { + g_LaraItem->rot.y += PHD_90; + } else { + g_LaraItem->rot.y -= PHD_90; + } + g_LaraItem->anim_num = LA_STAND_STILL; + g_LaraItem->frame_num = g_Anims[LA_STAND_STILL].frame_base; + g_LaraItem->goal_anim_state = LS_STOP; + g_LaraItem->current_anim_state = LS_STOP; + g_LaraItem->pos.x -= + (SKIDOO_GET_OFF_DIST * Math_Sin(g_LaraItem->rot.y)) >> W2V_SHIFT; + g_LaraItem->pos.z -= + (SKIDOO_GET_OFF_DIST * Math_Cos(g_LaraItem->rot.y)) >> W2V_SHIFT; + g_LaraItem->rot.x = 0; + g_LaraItem->rot.z = 0; + g_Lara.skidoo = NO_ITEM; + g_Lara.gun_status = LGS_ARMLESS; + return true; + } + + if (g_LaraItem->current_anim_state == LARA_STATE_SKIDOO_LET_GO + && (skidoo->pos.y == skidoo->floor + || g_LaraItem->frame_num + == g_Anims[g_LaraItem->anim_num].frame_end)) { + g_LaraItem->anim_num = LA_FREEFALL; + g_LaraItem->frame_num = g_Anims[g_LaraItem->anim_num].frame_base; + g_LaraItem->current_anim_state = LARA_STATE_SKIDOO_GET_OFF_R; + if (skidoo->pos.y == skidoo->floor) { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_STILL; + g_LaraItem->fall_speed = DAMAGE_START + DAMAGE_LENGTH; + g_LaraItem->speed = 0; + Skidoo_Explode(skidoo); + } else { + g_LaraItem->goal_anim_state = LARA_STATE_SKIDOO_GET_OFF_R; + g_LaraItem->pos.y -= 200; + g_LaraItem->fall_speed = skidoo->fall_speed; + g_LaraItem->speed = skidoo->speed; + Sound_Effect(SFX_LARA_FALL, &g_LaraItem->pos, SPM_NORMAL); + } + g_LaraItem->rot.x = 0; + g_LaraItem->rot.z = 0; + g_LaraItem->gravity = 1; + g_Lara.gun_status = LGS_ARMLESS; + g_Lara.move_angle = skidoo->rot.y; + skidoo->flags |= IF_ONE_SHOT; + skidoo->collidable = 0; + return false; + } + + return true; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 98f36c887..1e12efa95 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -15,4 +15,5 @@ int32_t __cdecl Skidoo_UserControl( ITEM *skidoo, int32_t height, int32_t *out_pitch); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); -void __cdecl Skidoo_Explode(ITEM *skidoo); +void __cdecl Skidoo_Explode(const ITEM *skidoo); +int32_t __cdecl Skidoo_CheckGetOff(void); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index f3d1c6777..f9637b84b 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_CheckGetOff ((int32_t __cdecl (*)(void))0x0043E2A0) #define Skidoo_Guns ((void __cdecl (*)(void))0x0043E4E0) #define Skidoo_Control ((int32_t __cdecl (*)(void))0x0043E600) #define Skidoo_Armed_Draw ((void __cdecl (*)(const ITEM *item))0x0043EA60) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 8742452cb..af59b2f2d 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -255,6 +255,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043DE30, Skidoo_CheckGetOffOK); INJECT(enable, 0x0043DF40, Skidoo_Animation); INJECT(enable, 0x0043E220, Skidoo_Explode); + INJECT(enable, 0x0043E2A0, Skidoo_CheckGetOff); } static void M_DecompStats(const bool enable) From 4404a86e12c26cfc8135cbaa4e215da9d46ca11a Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 21 Oct 2024 23:38:14 +0200 Subject: [PATCH 14/22] tr2: port Skidoo_Guns --- docs/tr2/progress.svg | 16 +++++++-------- docs/tr2/progress.txt | 4 +++- src/tr2/decomp/skidoo.c | 44 +++++++++++++++++++++++++++++++++++++++++ src/tr2/decomp/skidoo.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 57 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 6e5612fc7..a7607e01f 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.80% (831) · 30.79% (383) · 0% (0) · 2.41% (30) +66.88% (832) · 30.71% (382) · 0% (0) · 2.41% (30) - - + + @@ -792,7 +792,7 @@ void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Skidoo_Explode(const ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); -void __cdecl Skidoo_Guns(void); +void __cdecl Skidoo_Guns(void); int32_t __cdecl Skidoo_Control(void); void __cdecl Skidoo_Armed_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -71.63% · 28.04% · 0% · 0.33% +71.72% · 27.96% · 0% · 0.33% - - + + @@ -1656,7 +1656,7 @@ void __cdecl Item_Kill(int16_t item_num); void __cdecl Gun_InitialiseNewWeapon(void); void __cdecl Lara_Col_UpJump(ITEM *item, COLL_INFO *coll); -void __cdecl Skidoo_Guns(void); +void __cdecl Skidoo_Guns(void); void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC lpDdsd, LPVOID lpContext); void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 80b8b847c..ca2eb96ac 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3671,7 +3671,7 @@ typedef enum { 0x0043DF40 0x02B9 +R void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); 0x0043E220 0x007C +R void __cdecl Skidoo_Explode(const ITEM *skidoo); 0x0043E2A0 0x0233 +R int32_t __cdecl Skidoo_CheckGetOff(void); -0x0043E4E0 0x011B -R void __cdecl Skidoo_Guns(void); +0x0043E4E0 0x011B +R void __cdecl Skidoo_Guns(void); 0x0043E600 0x0440 -R int32_t __cdecl Skidoo_Control(void); 0x0043EA60 0x02D5 -R void __cdecl Skidoo_Armed_Draw(const ITEM *item); 0x0043ED40 0x007F -R void __cdecl SkidooDriver_Initialise(int16_t item_num); @@ -4742,6 +4742,8 @@ typedef enum { 0x004645A8 - const uint16_t g_Requester_UnselectionGour1[]; 0x005216E0 - uint16_t g_InvColors[17]; // INV_COLOR_NUMBER_OF 0x00464150 + BITE g_DragonMouth; +0x00466230 + BITE g_SkidooLeftGun; +0x00466240 + BITE g_SkidooRightGun; 0x00465F40 - int16_t g_MovableBlockBounds[]; 0x00465F58 - int16_t g_ZiplineHandleBounds[]; 0x00465FF0 - int16_t g_PickupBounds[]; diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index cebc1cf5f..785827cc1 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -1,6 +1,8 @@ #include "decomp/skidoo.h" +#include "game/creature.h" #include "game/effects.h" +#include "game/gun/gun_misc.h" #include "game/input.h" #include "game/items.h" #include "game/lara/control.h" @@ -80,6 +82,15 @@ typedef enum { #define SKIDOO_TARGET_DIST (WALL_L * 2) // = 2048 +static BITE m_LeftGun = { + .pos = { .x = 219, .y = -71, .z = SKIDOO_FRONT }, + .mesh_num = 0, +}; +static BITE m_RightGun = { + .pos = { .x = -235, .y = -71, .z = SKIDOO_FRONT }, + .mesh_num = 0, +}; + static bool M_IsNearby(const ITEM *item_1, const ITEM *item_2); static bool M_CheckBaddieCollision(ITEM *item, const ITEM *skidoo); @@ -742,3 +753,36 @@ int32_t __cdecl Skidoo_CheckGetOff(void) return true; } + +void __cdecl Skidoo_Guns(void) +{ + WEAPON_INFO *const winfo = &g_Weapons[LGT_SKIDOO]; + Gun_GetNewTarget(winfo); + Gun_AimWeapon(winfo, &g_Lara.right_arm); + + if (!(g_Input & IN_ACTION)) { + return; + } + + int16_t angles[2]; + angles[0] = g_Lara.right_arm.rot.y + g_LaraItem->rot.y; + angles[1] = g_Lara.right_arm.rot.x; + + if (!Gun_FireWeapon(LGT_SKIDOO, g_Lara.target, g_LaraItem, angles)) { + return; + } + + g_Lara.right_arm.flash_gun = winfo->flash_time; + Sound_Effect(winfo->sample_num, &g_LaraItem->pos, SPM_NORMAL); + + const int32_t cy = Math_Cos(g_LaraItem->rot.y); + const int32_t sy = Math_Sin(g_LaraItem->rot.y); + const int32_t x = g_LaraItem->pos.x + (sy >> 4); + const int32_t z = g_LaraItem->pos.z + (cy >> 4); + const int32_t y = g_LaraItem->pos.y - 512; + AddDynamicLight(x, y, z, 12, 11); + + ITEM *const skidoo = Item_Get(g_Lara.skidoo); + Creature_Effect(skidoo, &m_LeftGun, GunShot); + Creature_Effect(skidoo, &m_RightGun, GunShot); +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 1e12efa95..70ef2ad8f 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -17,3 +17,4 @@ int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Skidoo_Explode(const ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); +void __cdecl Skidoo_Guns(void); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index f9637b84b..6759ffe7c 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_Guns ((void __cdecl (*)(void))0x0043E4E0) #define Skidoo_Control ((int32_t __cdecl (*)(void))0x0043E600) #define Skidoo_Armed_Draw ((void __cdecl (*)(const ITEM *item))0x0043EA60) #define SkidooDriver_Initialise ((void __cdecl (*)(int16_t item_num))0x0043ED40) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index af59b2f2d..70efb2162 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -256,6 +256,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043DF40, Skidoo_Animation); INJECT(enable, 0x0043E220, Skidoo_Explode); INJECT(enable, 0x0043E2A0, Skidoo_CheckGetOff); + INJECT(enable, 0x0043E4E0, Skidoo_Guns); } static void M_DecompStats(const bool enable) From 8104747ea0bfb44d16863776843f7925d6f651c8 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 14:01:50 +0200 Subject: [PATCH 15/22] tr2: port Skidoo_Control --- docs/tr2/progress.svg | 16 ++-- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 162 ++++++++++++++++++++++++++++++++++-- src/tr2/decomp/skidoo.h | 1 + src/tr2/game/lara/control.c | 2 + src/tr2/game/sound.c | 2 - src/tr2/game/sound.h | 2 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 9 files changed, 172 insertions(+), 17 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index a7607e01f..4f45bf487 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.88% (832) · 30.71% (382) · 0% (0) · 2.41% (30) +66.96% (833) · 30.63% (381) · 0% (0) · 2.41% (30) - - + + @@ -793,7 +793,7 @@ void __cdecl Skidoo_Explode(const ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl Skidoo_Guns(void); -int32_t __cdecl Skidoo_Control(void); +int32_t __cdecl Skidoo_Control(void); void __cdecl Skidoo_Armed_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -71.72% · 27.96% · 0% · 0.33% +72.03% · 27.64% · 0% · 0.33% - - + + @@ -1382,7 +1382,7 @@ int32_t __cdecl GF_InterpretSequence(int16_t *ptr, GAMEFLOW_LEVEL_TYPE type, int32_t seq_type); TARGET_TYPE __cdecl Box_CalculateTarget(XYZ_32 *target, ITEM *item, LOT_INFO *lot); void __cdecl Output_InsertGT4_ZBuffered(const PHD_VBUF *vtx0, const PHD_VBUF *vtx1, const PHD_VBUF *vtx2, const PHD_VBUF *vtx3, const PHD_TEXTURE *texture); -int32_t __cdecl Skidoo_Control(void); +int32_t __cdecl Skidoo_Control(void); void __cdecl Creature_Mood(ITEM *item, AI_INFO *info, int32_t violent); const int16_t *__cdecl Output_InsertObjectG4_Sorted(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); void __cdecl Worker2_Control(int16_t item_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index ca2eb96ac..756bbad31 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3672,7 +3672,7 @@ typedef enum { 0x0043E220 0x007C +R void __cdecl Skidoo_Explode(const ITEM *skidoo); 0x0043E2A0 0x0233 +R int32_t __cdecl Skidoo_CheckGetOff(void); 0x0043E4E0 0x011B +R void __cdecl Skidoo_Guns(void); -0x0043E600 0x0440 -R int32_t __cdecl Skidoo_Control(void); +0x0043E600 0x0440 +R int32_t __cdecl Skidoo_Control(void); 0x0043EA60 0x02D5 -R void __cdecl Skidoo_Armed_Draw(const ITEM *item); 0x0043ED40 0x007F -R void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 - void __cdecl SkidooDriver_Control(int16_t rider_num); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 785827cc1..5edf3e825 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -60,6 +60,7 @@ typedef enum { #define SKIDOO_FRONT 550 #define SKIDOO_SNOW 500 #define SKIDOO_GET_OFF_DIST 330 +#define SKIDOO_TARGET_DIST (WALL_L * 2) // = 2048 #define SKIDOO_MIN_SPEED 15 #define SKIDOO_MAX_SPEED 100 @@ -80,7 +81,7 @@ typedef enum { #define SKIDOO_MOMENTUM_TURN (PHD_DEGREE * 3) // = 546 #define SKIDOO_MAX_MOMENTUM_TURN (PHD_DEGREE * 150) // = 27300 -#define SKIDOO_TARGET_DIST (WALL_L * 2) // = 2048 +#define SKIDOO_GUN_MESH 4 static BITE m_LeftGun = { .pos = { .x = 219, .y = -71, .z = SKIDOO_FRONT }, @@ -92,6 +93,7 @@ static BITE m_RightGun = { }; static bool M_IsNearby(const ITEM *item_1, const ITEM *item_2); +static bool M_IsArmed(const SKIDOO_INFO *const skidoo_data); static bool M_CheckBaddieCollision(ITEM *item, const ITEM *skidoo); static bool M_IsNearby(const ITEM *const item_1, const ITEM *const item_2) @@ -104,6 +106,11 @@ static bool M_IsNearby(const ITEM *const item_1, const ITEM *const item_2) && dz > -SKIDOO_TARGET_DIST && dz < SKIDOO_TARGET_DIST; } +static bool M_IsArmed(const SKIDOO_INFO *const skidoo_data) +{ + return skidoo_data->track_mesh & SKIDOO_GUN_MESH; +} + static bool M_CheckBaddieCollision(ITEM *const item, const ITEM *const skidoo) { if (!item->collidable || item->status == IS_INVISIBLE || item == g_LaraItem @@ -489,7 +496,7 @@ int32_t __cdecl Skidoo_UserControl( } } else if (g_Input & IN_FORWARD) { int32_t max_speed; - if ((g_Input & IN_ACTION) && !(skidoo_data->track_mesh & 4)) { + if ((g_Input & IN_ACTION) && !M_IsArmed(skidoo_data)) { max_speed = SKIDOO_FAST_SPEED; } else if (g_Input & IN_SLOW) { max_speed = SKIDOO_SLOW_SPEED; @@ -573,7 +580,7 @@ void __cdecl Skidoo_Animation( const SKIDOO_INFO *const skidoo_data = skidoo->data; if (skidoo->pos.y != skidoo->floor && skidoo->fall_speed > 0 - && g_LaraItem->current_anim_state != 4 && !dead) { + && g_LaraItem->current_anim_state != LARA_STATE_SKIDOO_FALL && !dead) { g_LaraItem->anim_num = g_Objects[O_LARA_SKIDOO].anim_idx + LA_SKIDOO_FALL; g_LaraItem->frame_num = g_Anims[g_LaraItem->anim_num].frame_base; @@ -636,7 +643,7 @@ void __cdecl Skidoo_Animation( case LARA_STATE_SKIDOO_STILL: { const int32_t music_track = - (skidoo_data->track_mesh & 4) ? MX_BATTLE_THEME : MX_SKIDOO_THEME; + M_IsArmed(skidoo_data) ? MX_BATTLE_THEME : MX_SKIDOO_THEME; if (!(g_MusicTrackFlags[music_track] & IF_ONE_SHOT)) { Music_Play(music_track, false); g_LaraItem = g_LaraItem; @@ -690,7 +697,7 @@ void __cdecl Skidoo_Explode(const ITEM *const skidoo) fx->object_id = O_EXPLOSION; } - Effect_ExplodingDeath(g_Lara.skidoo, -4, 0); + Effect_ExplodingDeath(g_Lara.skidoo, ~(SKIDOO_GUN_MESH - 1), 0); Sound_Effect(SFX_EXPLOSION1, NULL, SPM_NORMAL); g_Lara.skidoo = NO_ITEM; } @@ -786,3 +793,148 @@ void __cdecl Skidoo_Guns(void) Creature_Effect(skidoo, &m_LeftGun, GunShot); Creature_Effect(skidoo, &m_RightGun, GunShot); } + +int32_t __cdecl Skidoo_Control(void) +{ + ITEM *const skidoo = Item_Get(g_Lara.skidoo); + SKIDOO_INFO *const skidoo_data = skidoo->data; + int32_t collide = Skidoo_Dynamics(skidoo); + + XYZ_32 fl; + XYZ_32 fr; + const int32_t hfl = + Skidoo_TestHeight(skidoo, SKIDOO_FRONT, -SKIDOO_SIDE, &fl); + const int32_t hfr = + Skidoo_TestHeight(skidoo, SKIDOO_FRONT, SKIDOO_SIDE, &fr); + + int16_t room_num = skidoo->room_num; + const SECTOR *const sector = + Room_GetSector(skidoo->pos.x, skidoo->pos.y, skidoo->pos.z, &room_num); + int32_t height = + Room_GetHeight(sector, skidoo->pos.x, skidoo->pos.y, skidoo->pos.z); + Room_TestTriggers(g_TriggerIndex, false); + + bool dead = false; + if (g_LaraItem->hit_points <= 0) { + dead = true; + g_Input &= ~IN_BACK; + g_Input &= ~IN_FORWARD; + g_Input &= ~IN_LEFT; + g_Input &= ~IN_RIGHT; + } else if (g_LaraItem->current_anim_state == LARA_STATE_SKIDOO_LET_GO) { + dead = true; + collide = 0; + } + + int32_t drive; + int32_t pitch; + if (skidoo->flags & IF_ONE_SHOT) { + drive = 0; + collide = 0; + } else { + switch (g_LaraItem->current_anim_state) { + case LARA_STATE_SKIDOO_GET_ON: + case LARA_STATE_SKIDOO_GET_OFF_L: + case LARA_STATE_SKIDOO_GET_OFF_R: + case LARA_STATE_SKIDOO_LET_GO: + drive = -1; + collide = 0; + break; + + default: + drive = Skidoo_UserControl(skidoo, height, &pitch); + break; + } + } + + const int32_t old_track_mesh = skidoo_data->track_mesh; + if (drive > 0) { + skidoo_data->track_mesh = (skidoo_data->track_mesh & 3) == 1 ? 2 : 1; + skidoo_data->pitch += (pitch - skidoo_data->pitch) >> 2; + + const int32_t pitch_delta = + (SKIDOO_MAX_SPEED - skidoo_data->pitch) * 100; + const int32_t pitch = (SOUND_DEFAULT_PITCH - pitch_delta) << 8; + + Sound_Effect(SFX_SKIDOO_MOVING, &skidoo->pos, SPM_PITCH | pitch); + } else { + skidoo_data->track_mesh = 0; + if (!drive) { + Sound_Effect(SFX_SKIDOO_IDLE, &skidoo->pos, SPM_NORMAL); + } + skidoo_data->pitch = 0; + } + skidoo_data->track_mesh |= old_track_mesh & SKIDOO_GUN_MESH; + + skidoo->floor = height; + + skidoo_data->left_fallspeed = + DoDynamics(hfl, skidoo_data->left_fallspeed, &fl.y); + skidoo_data->right_fallspeed = + DoDynamics(hfr, skidoo_data->right_fallspeed, &fr.y); + skidoo->fall_speed = DoDynamics(height, skidoo->fall_speed, &skidoo->pos.y); + + height = (fr.y + fl.y) / 2; + const int16_t x_rot = Math_Atan(SKIDOO_FRONT, skidoo->pos.y - height); + const int16_t z_rot = Math_Atan(SKIDOO_SIDE, height - fl.y); + skidoo->rot.x += (x_rot - skidoo->rot.x) >> 1; + skidoo->rot.z += (z_rot - skidoo->rot.z) >> 1; + + if (skidoo->flags & IF_ONE_SHOT) { + if (room_num != skidoo->room_num) { + Item_NewRoom(g_Lara.skidoo, room_num); + } + if (skidoo->pos.y == skidoo->floor) { + Skidoo_Explode(skidoo); + } + return 0; + } + + Skidoo_Animation(skidoo, collide, dead); + if (room_num != skidoo->room_num) { + Item_NewRoom(g_Lara.skidoo, room_num); + Item_NewRoom(g_Lara.item_num, room_num); + } + + if (g_LaraItem->current_anim_state == LARA_STATE_SKIDOO_FALLOFF) { + g_LaraItem->rot.x = 0; + g_LaraItem->rot.z = 0; + } else { + g_LaraItem->pos.x = skidoo->pos.x; + g_LaraItem->pos.y = skidoo->pos.y; + g_LaraItem->pos.z = skidoo->pos.z; + g_LaraItem->rot.y = skidoo->rot.y; + if (drive >= 0) { + g_LaraItem->rot.x = skidoo->rot.x; + g_LaraItem->rot.z = skidoo->rot.z; + } else { + g_LaraItem->rot.x = 0; + g_LaraItem->rot.z = 0; + } + } + + Item_Animate(g_LaraItem); + if (!dead && drive >= 0 && M_IsArmed(skidoo_data)) { + Skidoo_Guns(); + } + + if (dead) { + skidoo->anim_num = g_Objects[O_SKIDOO_FAST].anim_idx + LA_SKIDOO_DEAD; + skidoo->frame_num = g_Anims[skidoo->anim_num].frame_base; + } else { + skidoo->anim_num = g_Objects[O_SKIDOO_FAST].anim_idx + + g_LaraItem->anim_num - g_Objects[O_LARA_SKIDOO].anim_idx; + skidoo->frame_num = g_LaraItem->frame_num + + g_Anims[skidoo->anim_num].frame_base + - g_Anims[g_LaraItem->anim_num].frame_base; + } + + if (skidoo->speed != 0 && skidoo->floor == skidoo->pos.y) { + Skidoo_DoSnowEffect(skidoo); + if (skidoo->speed < SKIDOO_SLOW_SPEED) { + Skidoo_DoSnowEffect(skidoo); + } + } + + return Skidoo_CheckGetOff(); +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 70ef2ad8f..ec0a01d14 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -18,3 +18,4 @@ void __cdecl Skidoo_Animation(ITEM *skidoo, int32_t collide, int32_t dead); void __cdecl Skidoo_Explode(const ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl Skidoo_Guns(void); +int32_t __cdecl Skidoo_Control(void); diff --git a/src/tr2/game/lara/control.c b/src/tr2/game/lara/control.c index ba0a20dbf..057b9ecdd 100644 --- a/src/tr2/game/lara/control.c +++ b/src/tr2/game/lara/control.c @@ -1,5 +1,6 @@ #include "game/lara/control.h" +#include "decomp/skidoo.h" #include "game/creature.h" #include "game/gun/gun.h" #include "game/input.h" @@ -46,6 +47,7 @@ void __cdecl Lara_HandleAboveWater(ITEM *const item, COLL_INFO *const coll) if (g_Lara.skidoo != NO_ITEM) { if (g_Items[g_Lara.skidoo].object_id == O_SKIDOO_FAST) { + // TODO: make this g_Objects[O_SKIDOO_FAST].control if (Skidoo_Control()) { return; } diff --git a/src/tr2/game/sound.c b/src/tr2/game/sound.c index 98b10eb8b..23e6e0a31 100644 --- a/src/tr2/game/sound.c +++ b/src/tr2/game/sound.c @@ -36,8 +36,6 @@ typedef enum { // clang-format on } SAMPLE_FLAG; -#define SOUND_DEFAULT_PITCH 0x10000 - #define SOUND_RANGE 10 #define SOUND_RADIUS (SOUND_RANGE * WALL_L) // = 0x2800 = 10240 #define SOUND_RADIUS_SQRD SQUARE(SOUND_RADIUS) // = 0x6400000 diff --git a/src/tr2/game/sound.h b/src/tr2/game/sound.h index 689cf228a..9ca04ee92 100644 --- a/src/tr2/game/sound.h +++ b/src/tr2/game/sound.h @@ -2,6 +2,8 @@ #include "global/types.h" +#define SOUND_DEFAULT_PITCH 0x10000 + void __cdecl Sound_Init(void); void __cdecl Sound_Shutdown(void); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 6759ffe7c..14f9226a3 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_Control ((int32_t __cdecl (*)(void))0x0043E600) #define Skidoo_Armed_Draw ((void __cdecl (*)(const ITEM *item))0x0043EA60) #define SkidooDriver_Initialise ((void __cdecl (*)(int16_t item_num))0x0043ED40) #define SkidooDriver_Control ((void __cdecl (*)(int16_t rider_num))0x0043EDD0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 70efb2162..ffae38b04 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -257,6 +257,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043E220, Skidoo_Explode); INJECT(enable, 0x0043E2A0, Skidoo_CheckGetOff); INJECT(enable, 0x0043E4E0, Skidoo_Guns); + INJECT(enable, 0x0043E600, Skidoo_Control); } static void M_DecompStats(const bool enable) From 22664192057120408b5d7ea5746d4ccbd0ae3fd9 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 00:04:25 +0200 Subject: [PATCH 16/22] tr2: port Skidoo_Draw --- data/tr2/ship/cfg/TR2X_gameflow.json5 | 2 +- docs/tr2/progress.svg | 16 +-- docs/tr2/progress.txt | 4 +- .../include/libtrx/game/objects/ids_tr2.def | 2 +- .../include/libtrx/game/objects/names_tr2.def | 2 +- src/tr2/decomp/skidoo.c | 102 ++++++++++++++++++ src/tr2/decomp/skidoo.h | 1 + src/tr2/game/lara/draw.c | 3 +- src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 10 files changed, 119 insertions(+), 15 deletions(-) diff --git a/data/tr2/ship/cfg/TR2X_gameflow.json5 b/data/tr2/ship/cfg/TR2X_gameflow.json5 index 352714261..8d78ef2c2 100644 --- a/data/tr2/ship/cfg/TR2X_gameflow.json5 +++ b/data/tr2/ship/cfg/TR2X_gameflow.json5 @@ -174,7 +174,7 @@ "O_BELL": "Bell", "O_WATER_SPRITE": "Boat Wake", "O_SNOW_SPRITE": "Snowmobile Wale", - "O_SKIDOO_LARA": "Snowmobile Animation", + "O_SKIDOO_TRACK": "Snowmobile Track", "O_SWITCH_TYPE_AIRLOCK": "Airlock Switch", "O_SWITCH_TYPE_SMALL": "Small Switch", "O_PROPELLER_2": "Underwater Propeller", diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 4f45bf487..7aac4e55a 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -66.96% (833) · 30.63% (381) · 0% (0) · 2.41% (30) +67.04% (834) · 30.55% (380) · 0% (0) · 2.41% (30) - - + + @@ -794,7 +794,7 @@ int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl Skidoo_Guns(void); int32_t __cdecl Skidoo_Control(void); -void __cdecl Skidoo_Armed_Draw(const ITEM *item); +void __cdecl Skidoo_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -72.03% · 27.64% · 0% · 0.33% +72.25% · 27.43% · 0% · 0.33% - - + + @@ -1446,7 +1446,7 @@ bool __cdecl SE_ShowSetupDialog(HWND hParent, bool isDefault); void __cdecl Option_Detail(INVENTORY_ITEM *item); int32_t __cdecl Collide_GetSpheres(const ITEM *item, SPHERE *spheres, bool world_space); -void __cdecl Skidoo_Armed_Draw(const ITEM *item); +void __cdecl Skidoo_Draw(const ITEM *item); const int16_t *__cdecl Output_InsertObjectG3_ZBuffered(const int16_t *obj_ptr, int32_t num, SORT_TYPE sort_type); int32_t __cdecl Output_XYClipper(int32_t vtx_count, VERTEX_INFO *vtx); void __cdecl ControlMissile(int16_t fx_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 756bbad31..e12591abb 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -2146,7 +2146,7 @@ typedef enum { // decompiled O_BELL = 88, O_WATER_SPRITE = 89, O_SNOW_SPRITE = 90, - O_SKIDOO_LARA = 91, + O_SKIDOO_TRACK = 91, O_SWITCH_TYPE_AIRLOCK = 92, O_SWITCH_TYPE_SMALL = 93, O_PROPELLER_2 = 94, @@ -3673,7 +3673,7 @@ typedef enum { 0x0043E2A0 0x0233 +R int32_t __cdecl Skidoo_CheckGetOff(void); 0x0043E4E0 0x011B +R void __cdecl Skidoo_Guns(void); 0x0043E600 0x0440 +R int32_t __cdecl Skidoo_Control(void); -0x0043EA60 0x02D5 -R void __cdecl Skidoo_Armed_Draw(const ITEM *item); +0x0043EA60 0x02D5 +R void __cdecl Skidoo_Draw(const ITEM *item); 0x0043ED40 0x007F -R void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 - void __cdecl SkidooDriver_Control(int16_t rider_num); 0x0043F1D0 0x0119 -R void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); diff --git a/src/libtrx/include/libtrx/game/objects/ids_tr2.def b/src/libtrx/include/libtrx/game/objects/ids_tr2.def index b8fa8e92c..74b83003b 100644 --- a/src/libtrx/include/libtrx/game/objects/ids_tr2.def +++ b/src/libtrx/include/libtrx/game/objects/ids_tr2.def @@ -89,7 +89,7 @@ OBJ_ID_DEFINE(O_CEILING_SPIKES, 87) OBJ_ID_DEFINE(O_BELL, 88) OBJ_ID_DEFINE(O_WATER_SPRITE, 89) OBJ_ID_DEFINE(O_SNOW_SPRITE, 90) -OBJ_ID_DEFINE(O_SKIDOO_LARA, 91) +OBJ_ID_DEFINE(O_SKIDOO_TRACK, 91) OBJ_ID_DEFINE(O_SWITCH_TYPE_AIRLOCK, 92) OBJ_ID_DEFINE(O_SWITCH_TYPE_SMALL, 93) OBJ_ID_DEFINE(O_PROPELLER_2, 94) diff --git a/src/libtrx/include/libtrx/game/objects/names_tr2.def b/src/libtrx/include/libtrx/game/objects/names_tr2.def index a6f1e5a5d..39098e167 100644 --- a/src/libtrx/include/libtrx/game/objects/names_tr2.def +++ b/src/libtrx/include/libtrx/game/objects/names_tr2.def @@ -89,7 +89,7 @@ OBJ_NAME_DEFINE(O_CEILING_SPIKES, "Spiky Ceiling") OBJ_NAME_DEFINE(O_BELL, "Bell") OBJ_NAME_DEFINE(O_WATER_SPRITE, "Boat Wake") OBJ_NAME_DEFINE(O_SNOW_SPRITE, "Snowmobile Wale") -OBJ_NAME_DEFINE(O_SKIDOO_LARA, "Snowmobile Animation") +OBJ_NAME_DEFINE(O_SKIDOO_TRACK, "Snowmobile Track") OBJ_NAME_DEFINE(O_SWITCH_TYPE_AIRLOCK, "Airlock Switch") OBJ_NAME_DEFINE(O_SWITCH_TYPE_SMALL, "Small Switch") OBJ_NAME_DEFINE(O_PROPELLER_2, "Underwater Propeller") diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 5edf3e825..51ac22fbc 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -8,8 +8,10 @@ #include "game/lara/control.h" #include "game/lara/look.h" #include "game/math.h" +#include "game/matrix.h" #include "game/music.h" #include "game/objects/common.h" +#include "game/output.h" #include "game/random.h" #include "game/room.h" #include "game/sound.h" @@ -938,3 +940,103 @@ int32_t __cdecl Skidoo_Control(void) return Skidoo_CheckGetOff(); } + +void __cdecl Skidoo_Draw(const ITEM *const item) +{ + int32_t track_mesh = 0; + const SKIDOO_INFO *const skidoo_data = item->data; + if (skidoo_data != NULL) { + track_mesh = skidoo_data->track_mesh; + } + + OBJECT *obj = &g_Objects[item->object_id]; + if ((track_mesh & SKIDOO_GUN_MESH) != 0) { + obj = &g_Objects[O_SKIDOO_ARMED]; + } + + int16_t *track_mesh_ptr = NULL; + if ((track_mesh & 3) == 1) { + track_mesh_ptr = g_Meshes[g_Objects[O_SKIDOO_TRACK].mesh_idx + 1]; + } else if ((track_mesh & 3) == 2) { + track_mesh_ptr = g_Meshes[g_Objects[O_SKIDOO_TRACK].mesh_idx + 7]; + } + int16_t **mesh_ptrs = &g_Meshes[obj->mesh_idx]; + + int16_t *old_track_mesh_ptr = mesh_ptrs[1]; + if (track_mesh_ptr != NULL) { + mesh_ptrs[1] = track_mesh_ptr; + } + + // TODO: merge common code parts down below with Object_DrawAnimatingItem. + + FRAME_INFO *frames[2]; + int32_t rate; + const int32_t frac = Item_GetFrames(item, frames, &rate); + + Matrix_Push(); + Matrix_TranslateAbs(item->pos.x, item->pos.y, item->pos.z); + Matrix_RotYXZ(item->rot.y, item->rot.x, item->rot.z); + + const int32_t clip = S_GetObjectBounds(&frames[0]->bounds); + if (!clip) { + Matrix_Pop(); + return; + } + + Output_CalculateObjectLighting(item, frames[0]); + + int32_t *bone = &g_AnimBones[obj->bone_idx]; + if (frac) { + const int16_t *mesh_rots_1 = frames[0]->mesh_rots; + const int16_t *mesh_rots_2 = frames[1]->mesh_rots; + + Matrix_InitInterpolate(frac, rate); + Matrix_TranslateRel_ID( + frames[0]->offset.x, frames[0]->offset.y, frames[0]->offset.z, + frames[1]->offset.x, frames[1]->offset.y, frames[1]->offset.z); + Matrix_RotYXZsuperpack_I(&mesh_rots_1, &mesh_rots_2, 0); + + Output_InsertPolygons_I(mesh_ptrs[0], clip); + for (int32_t mesh_idx = 1; mesh_idx < obj->mesh_count; mesh_idx++) { + const int32_t bone_flags = bone[0]; + if (bone_flags & BF_MATRIX_POP) { + Matrix_Pop_I(); + } + if (bone_flags & BF_MATRIX_PUSH) { + Matrix_Push_I(); + } + + Matrix_TranslateRel_I(bone[1], bone[2], bone[3]); + Matrix_RotYXZsuperpack_I(&mesh_rots_1, &mesh_rots_2, 0); + bone += 4; + + Output_InsertPolygons_I(mesh_ptrs[mesh_idx], clip); + } + } else { + const int16_t *mesh_rots = frames[0]->mesh_rots; + Matrix_TranslateRel( + frames[0]->offset.x, frames[0]->offset.y, frames[0]->offset.z); + Matrix_RotYXZsuperpack(&mesh_rots, 0); + + Output_InsertPolygons(mesh_ptrs[0], clip); + for (int32_t mesh_idx = 1; mesh_idx < obj->mesh_count; mesh_idx++) { + const int32_t bone_flags = bone[0]; + if (bone_flags & BF_MATRIX_POP) { + Matrix_Pop(); + } + if (bone_flags & BF_MATRIX_PUSH) { + Matrix_Push(); + } + + Matrix_TranslateRel(bone[1], bone[2], bone[3]); + Matrix_RotYXZsuperpack(&mesh_rots, 0); + bone += 4; + + Output_InsertPolygons(mesh_ptrs[mesh_idx], clip); + } + } + + Matrix_Pop(); + + mesh_ptrs[1] = old_track_mesh_ptr; +} diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index ec0a01d14..b93f8e29e 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -19,3 +19,4 @@ void __cdecl Skidoo_Explode(const ITEM *skidoo); int32_t __cdecl Skidoo_CheckGetOff(void); void __cdecl Skidoo_Guns(void); int32_t __cdecl Skidoo_Control(void); +void __cdecl Skidoo_Draw(const ITEM *item); diff --git a/src/tr2/game/lara/draw.c b/src/tr2/game/lara/draw.c index 9bef0d73c..5911164d4 100644 --- a/src/tr2/game/lara/draw.c +++ b/src/tr2/game/lara/draw.c @@ -512,7 +512,8 @@ void __cdecl Lara_Draw_I( Matrix_RotX_I(-16380); Matrix_RotY_I(2 * Random_GetDraw()); S_CalculateStaticLight(2048); - Output_InsertPolygons_I(g_Meshes[g_Objects[235].mesh_idx], clip); + Output_InsertPolygons_I( + g_Meshes[g_Objects[O_FLARE_FIRE].mesh_idx], clip); } Matrix_Pop(); break; diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 14f9226a3..516f56cef 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define Skidoo_Armed_Draw ((void __cdecl (*)(const ITEM *item))0x0043EA60) #define SkidooDriver_Initialise ((void __cdecl (*)(int16_t item_num))0x0043ED40) #define SkidooDriver_Control ((void __cdecl (*)(int16_t rider_num))0x0043EDD0) #define SkidooDriver_Push ((void __cdecl (*)(ITEM *item, const ITEM *lara_item, int32_t radius))0x0043F1D0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index ffae38b04..198fc398d 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -258,6 +258,7 @@ static void M_DecompSkidoo(const bool enable) INJECT(enable, 0x0043E2A0, Skidoo_CheckGetOff); INJECT(enable, 0x0043E4E0, Skidoo_Guns); INJECT(enable, 0x0043E600, Skidoo_Control); + INJECT(enable, 0x0043EA60, Skidoo_Draw); } static void M_DecompStats(const bool enable) From 682978c8f3375624c7fa02885251a0268c0fb398 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 10:11:21 +0200 Subject: [PATCH 17/22] objects: move SkidooArmed_Setup to its own file --- data/tr2/ship/cfg/TR2X_gameflow.json5 | 2 +- docs/tr2/progress.svg | 8 ++--- docs/tr2/progress.txt | 6 ++-- .../include/libtrx/game/objects/ids_tr2.def | 2 +- .../include/libtrx/game/objects/names_tr2.def | 2 +- src/tr2/decomp/skidoo.c | 2 +- src/tr2/game/creature.c | 2 +- .../game/objects/creatures/skidoo_driver.c | 29 +------------------ .../game/objects/creatures/skidoo_driver.h | 3 +- src/tr2/game/objects/setup.c | 5 +++- src/tr2/game/objects/vars.c | 2 +- src/tr2/game/objects/vehicles/skidoo_armed.c | 28 ++++++++++++++++++ src/tr2/game/objects/vehicles/skidoo_armed.h | 3 ++ src/tr2/global/funcs.h | 4 +-- src/tr2/meson.build | 1 + 15 files changed, 54 insertions(+), 45 deletions(-) create mode 100644 src/tr2/game/objects/vehicles/skidoo_armed.c create mode 100644 src/tr2/game/objects/vehicles/skidoo_armed.h diff --git a/data/tr2/ship/cfg/TR2X_gameflow.json5 b/data/tr2/ship/cfg/TR2X_gameflow.json5 index 8d78ef2c2..e7488071d 100644 --- a/data/tr2/ship/cfg/TR2X_gameflow.json5 +++ b/data/tr2/ship/cfg/TR2X_gameflow.json5 @@ -135,7 +135,7 @@ "O_BANDIT_2": "Mercenary 2", "O_BANDIT_2B": "Mercenary 3", "O_SKIDOO_ARMED": "Black Snowmobile", - "O_SKIDMAN": "Black Snowmobile Driver", + "O_SKIDOO_DRIVER": "Black Snowmobile Driver", "O_MONK_1": "Monk 1", "O_MONK_2": "Monk 2", "O_FALLING_BLOCK_1": "Falling Block 1", diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 7aac4e55a..12b215f42 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -797,8 +797,8 @@ void __cdecl Skidoo_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); -void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); -void __cdecl SkidooDriver_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); +void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); +void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Music_GetRealTrack(int32_t track); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); void __cdecl Sound_StopEffect(int32_t sample_id); @@ -1659,7 +1659,7 @@ void __cdecl Skidoo_Guns(void); void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC lpDdsd, LPVOID lpContext); -void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); +void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); void __cdecl Jelly_Control(int16_t item_num); void __cdecl S_DrawScreenBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE color_idx, const GOURAUD_OUTLINE *gour, uint16_t flags); void __cdecl ControlCeilingSpikes(int16_t item_num); @@ -1956,7 +1956,7 @@ int32_t __cdecl AddAssaultTime(uint32_t time); void __cdecl Lara_Col_Stop(ITEM *item, COLL_INFO *coll); void __cdecl Lara_Col_Roll(ITEM *item, COLL_INFO *coll); -void __cdecl SkidooDriver_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); +void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Room_FindByPos(int32_t x, int32_t y, int32_t z); void __cdecl ControlExplosion1(int16_t fx_num); int32_t __cdecl Lara_DeflectEdge(ITEM *item, COLL_INFO *coll); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index e12591abb..fb3c96230 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -2107,7 +2107,7 @@ typedef enum { // decompiled O_BANDIT_2 = 49, O_BANDIT_2B = 50, O_SKIDOO_ARMED = 51, - O_SKIDMAN = 52, + O_SKIDOO_DRIVER = 52, O_MONK_1 = 53, O_MONK_2 = 54, O_FALLING_BLOCK_1 = 55, @@ -3676,8 +3676,8 @@ typedef enum { 0x0043EA60 0x02D5 +R void __cdecl Skidoo_Draw(const ITEM *item); 0x0043ED40 0x007F -R void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 - void __cdecl SkidooDriver_Control(int16_t rider_num); -0x0043F1D0 0x0119 -R void __cdecl SkidooDriver_Push(ITEM *item, const ITEM *lara_item, int32_t radius); -0x0043F2F0 0x0081 - void __cdecl SkidooDriver_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); +0x0043F1D0 0x0119 -R void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); +0x0043F2F0 0x0081 - void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); # game/sound.c 0x0043F380 0x0031 * int32_t __cdecl Music_GetRealTrack(int32_t track); diff --git a/src/libtrx/include/libtrx/game/objects/ids_tr2.def b/src/libtrx/include/libtrx/game/objects/ids_tr2.def index 74b83003b..dc9d8653c 100644 --- a/src/libtrx/include/libtrx/game/objects/ids_tr2.def +++ b/src/libtrx/include/libtrx/game/objects/ids_tr2.def @@ -50,7 +50,7 @@ OBJ_ID_DEFINE(O_BANDIT_1, 48) OBJ_ID_DEFINE(O_BANDIT_2, 49) OBJ_ID_DEFINE(O_BANDIT_2B, 50) OBJ_ID_DEFINE(O_SKIDOO_ARMED, 51) -OBJ_ID_DEFINE(O_SKIDMAN, 52) +OBJ_ID_DEFINE(O_SKIDOO_DRIVER, 52) OBJ_ID_DEFINE(O_MONK_1, 53) OBJ_ID_DEFINE(O_MONK_2, 54) OBJ_ID_DEFINE(O_FALLING_BLOCK_1, 55) diff --git a/src/libtrx/include/libtrx/game/objects/names_tr2.def b/src/libtrx/include/libtrx/game/objects/names_tr2.def index 39098e167..4ee74fb1f 100644 --- a/src/libtrx/include/libtrx/game/objects/names_tr2.def +++ b/src/libtrx/include/libtrx/game/objects/names_tr2.def @@ -50,7 +50,7 @@ OBJ_NAME_DEFINE(O_BANDIT_1, "Mercenary 1") OBJ_NAME_DEFINE(O_BANDIT_2, "Mercenary 2") OBJ_NAME_DEFINE(O_BANDIT_2B, "Mercenary 3") OBJ_NAME_DEFINE(O_SKIDOO_ARMED, "Black Snowmobile") -OBJ_NAME_DEFINE(O_SKIDMAN, "Black Snowmobile Driver") +OBJ_NAME_DEFINE(O_SKIDOO_DRIVER, "Black Snowmobile Driver") OBJ_NAME_DEFINE(O_MONK_1, "Monk 1") OBJ_NAME_DEFINE(O_MONK_2, "Monk 2") OBJ_NAME_DEFINE(O_FALLING_BLOCK_1, "Falling Block 1") diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index 51ac22fbc..d60dc512d 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -135,7 +135,7 @@ static bool M_CheckBaddieCollision(ITEM *const item, const ITEM *const skidoo) } if (item->object_id == O_SKIDOO_ARMED) { - SkidooDriver_Push(item, skidoo, SKIDOO_RADIUS); + SkidooArmed_Push(item, skidoo, SKIDOO_RADIUS); } else if (is_availanche) { if (item->current_anim_state == TRAP_ACTIVATE) { Lara_TakeDamage(100, true); diff --git a/src/tr2/game/creature.c b/src/tr2/game/creature.c index 9898ef7d9..e358e88ed 100644 --- a/src/tr2/game/creature.c +++ b/src/tr2/game/creature.c @@ -336,7 +336,7 @@ void __cdecl Creature_Die(const int16_t item_num, const bool explode) return; } - if (item->object_id == O_SKIDMAN) { + if (item->object_id == O_SKIDOO_DRIVER) { if (explode) { Effect_ExplodingDeath(item_num, -1, 0); } diff --git a/src/tr2/game/objects/creatures/skidoo_driver.c b/src/tr2/game/objects/creatures/skidoo_driver.c index 1d27b9d7c..b1e601694 100644 --- a/src/tr2/game/objects/creatures/skidoo_driver.c +++ b/src/tr2/game/objects/creatures/skidoo_driver.c @@ -1,38 +1,11 @@ #include "game/objects/creatures/skidoo_driver.h" -#include "game/creature.h" -#include "game/objects/common.h" -#include "global/const.h" #include "global/funcs.h" #include "global/vars.h" -#define SKIDOO_DRIVER_HITPOINTS 100 -#define SKIDOO_ARMED_RADIUS (WALL_L / 3) // = 341 - -void SkidooArmed_Setup(void) -{ - OBJECT *const obj = &g_Objects[O_SKIDOO_ARMED]; - if (!obj->loaded) { - return; - } - - obj->collision = SkidooDriver_Collision; - - obj->hit_points = SKIDOO_DRIVER_HITPOINTS; - obj->radius = SKIDOO_ARMED_RADIUS; - obj->shadow_size = UNIT_SHADOW / 2; - obj->pivot_length = 0; - - obj->intelligent = 1; - obj->save_anim = 1; - obj->save_position = 1; - obj->save_hitpoints = 1; - obj->save_flags = 1; -} - void SkidooDriver_Setup(void) { - OBJECT *const obj = &g_Objects[O_SKIDMAN]; + OBJECT *const obj = &g_Objects[O_SKIDOO_DRIVER]; if (!obj->loaded) { return; } diff --git a/src/tr2/game/objects/creatures/skidoo_driver.h b/src/tr2/game/objects/creatures/skidoo_driver.h index ba6fa835a..bc55bbcf8 100644 --- a/src/tr2/game/objects/creatures/skidoo_driver.h +++ b/src/tr2/game/objects/creatures/skidoo_driver.h @@ -1,4 +1,5 @@ #pragma once -void SkidooArmed_Setup(void); +#define SKIDOO_DRIVER_HITPOINTS 100 + void SkidooDriver_Setup(void); diff --git a/src/tr2/game/objects/setup.c b/src/tr2/game/objects/setup.c index 16cda60ea..e293ca6ac 100644 --- a/src/tr2/game/objects/setup.c +++ b/src/tr2/game/objects/setup.c @@ -27,6 +27,7 @@ #include "game/objects/creatures/xian_knight.h" #include "game/objects/creatures/xian_spearman.h" #include "game/objects/creatures/yeti.h" +#include "game/objects/vehicles/skidoo_armed.h" #include "global/funcs.h" #include "global/types.h" #include "global/vars.h" @@ -86,7 +87,6 @@ void __cdecl Object_SetupBaddyObjects(void) Monk2_Setup(); Bird_SetupEagle(); Bird_SetupCrow(); - SkidooArmed_Setup(); SkidooDriver_Setup(); Bartoli_Setup(); Dragon_SetupFront(); @@ -101,6 +101,9 @@ void __cdecl Object_SetupBaddyObjects(void) GiantYeti_Setup(); TRex_Setup(); Winston_Setup(); + + // TODO: move this to Object_SetupGeneralObjects + SkidooArmed_Setup(); } void __cdecl Object_SetupAllObjects(void) diff --git a/src/tr2/game/objects/vars.c b/src/tr2/game/objects/vars.c index 64a55eb4b..3c5f8298e 100644 --- a/src/tr2/game/objects/vars.c +++ b/src/tr2/game/objects/vars.c @@ -38,7 +38,7 @@ const GAME_OBJECT_ID g_EnemyObjects[] = { O_BANDIT_1, O_BANDIT_2, O_BANDIT_2B, - O_SKIDMAN, + O_SKIDOO_DRIVER, O_DINO, NO_OBJECT, // clang-format on diff --git a/src/tr2/game/objects/vehicles/skidoo_armed.c b/src/tr2/game/objects/vehicles/skidoo_armed.c new file mode 100644 index 000000000..3421baa4f --- /dev/null +++ b/src/tr2/game/objects/vehicles/skidoo_armed.c @@ -0,0 +1,28 @@ +#include "game/objects/vehicles/skidoo_armed.h" + +#include "game/objects/creatures/skidoo_driver.h" +#include "global/funcs.h" +#include "global/vars.h" + +#define SKIDOO_ARMED_RADIUS (WALL_L / 3) // = 341 + +void SkidooArmed_Setup(void) +{ + OBJECT *const obj = &g_Objects[O_SKIDOO_ARMED]; + if (!obj->loaded) { + return; + } + + obj->collision = SkidooArmed_Collision; + + obj->hit_points = SKIDOO_DRIVER_HITPOINTS; + obj->radius = SKIDOO_ARMED_RADIUS; + obj->shadow_size = UNIT_SHADOW / 2; + obj->pivot_length = 0; + + obj->intelligent = 1; + obj->save_anim = 1; + obj->save_position = 1; + obj->save_hitpoints = 1; + obj->save_flags = 1; +} diff --git a/src/tr2/game/objects/vehicles/skidoo_armed.h b/src/tr2/game/objects/vehicles/skidoo_armed.h new file mode 100644 index 000000000..b6006f443 --- /dev/null +++ b/src/tr2/game/objects/vehicles/skidoo_armed.h @@ -0,0 +1,3 @@ +#pragma once + +void SkidooArmed_Setup(void); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 516f56cef..273523c19 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -173,8 +173,8 @@ #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) #define SkidooDriver_Initialise ((void __cdecl (*)(int16_t item_num))0x0043ED40) #define SkidooDriver_Control ((void __cdecl (*)(int16_t rider_num))0x0043EDD0) -#define SkidooDriver_Push ((void __cdecl (*)(ITEM *item, const ITEM *lara_item, int32_t radius))0x0043F1D0) -#define SkidooDriver_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) +#define SkidooArmed_Push ((void __cdecl (*)(ITEM *item, const ITEM *lara_item, int32_t radius))0x0043F1D0) +#define SkidooArmed_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) #define Music_GetRealTrack ((int32_t __cdecl (*)(int32_t track))0x0043F380) #define Collide_TestCollision ((int32_t __cdecl (*)(ITEM *item, const ITEM *lara_item))0x0043F9B0) #define Collide_GetSpheres ((int32_t __cdecl (*)(const ITEM *item, SPHERE *spheres, bool world_space))0x0043FAE0) diff --git a/src/tr2/meson.build b/src/tr2/meson.build index 860cea956..0b93084d6 100644 --- a/src/tr2/meson.build +++ b/src/tr2/meson.build @@ -178,6 +178,7 @@ dll_sources = [ 'game/objects/traps/flame_emitter.c', 'game/objects/vars.c', 'game/objects/vehicles/boat.c', + 'game/objects/vehicles/skidoo_armed.c', 'game/option/option.c', 'game/option/option_compass.c', 'game/option/option_controls.c', From 22d7a406fd0ab0758c92b5827ae50e4ea0678133 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 10:18:52 +0200 Subject: [PATCH 18/22] tr2: port SkidooDriver_Initialise --- docs/tr2/progress.svg | 16 ++++++------ docs/tr2/progress.txt | 2 +- .../game/objects/creatures/skidoo_driver.c | 25 +++++++++++++++++++ .../game/objects/creatures/skidoo_driver.h | 3 +++ src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 2 ++ 6 files changed, 39 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 12b215f42..0c53e6909 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -67.04% (834) · 30.55% (380) · 0% (0) · 2.41% (30) +67.12% (835) · 30.47% (379) · 0% (0) · 2.41% (30) - - + + @@ -795,7 +795,7 @@ void __cdecl Skidoo_Guns(void); int32_t __cdecl Skidoo_Control(void); void __cdecl Skidoo_Draw(const ITEM *item); -void __cdecl SkidooDriver_Initialise(int16_t item_num); +void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -72.25% · 27.43% · 0% · 0.33% +72.28% · 27.39% · 0% · 0.33% - - + + @@ -1960,7 +1960,7 @@ int32_t __cdecl Room_FindByPos(int32_t x, int32_t y, int32_t z); void __cdecl ControlExplosion1(int16_t fx_num); int32_t __cdecl Lara_DeflectEdge(ITEM *item, COLL_INFO *coll); -void __cdecl SkidooDriver_Initialise(int16_t item_num); +void __cdecl SkidooDriver_Initialise(int16_t item_num); bool __cdecl WinInputInit(void); void __cdecl Random_Seed(void); void __cdecl Option_DoInventory(INVENTORY_ITEM *item); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index fb3c96230..38008a6ea 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3674,7 +3674,7 @@ typedef enum { 0x0043E4E0 0x011B +R void __cdecl Skidoo_Guns(void); 0x0043E600 0x0440 +R int32_t __cdecl Skidoo_Control(void); 0x0043EA60 0x02D5 +R void __cdecl Skidoo_Draw(const ITEM *item); -0x0043ED40 0x007F -R void __cdecl SkidooDriver_Initialise(int16_t item_num); +0x0043ED40 0x007F + void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 - void __cdecl SkidooDriver_Control(int16_t rider_num); 0x0043F1D0 0x0119 -R void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); 0x0043F2F0 0x0081 - void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); diff --git a/src/tr2/game/objects/creatures/skidoo_driver.c b/src/tr2/game/objects/creatures/skidoo_driver.c index b1e601694..7487b87bd 100644 --- a/src/tr2/game/objects/creatures/skidoo_driver.c +++ b/src/tr2/game/objects/creatures/skidoo_driver.c @@ -1,8 +1,11 @@ #include "game/objects/creatures/skidoo_driver.h" +#include "game/items.h" #include "global/funcs.h" #include "global/vars.h" +#include + void SkidooDriver_Setup(void) { OBJECT *const obj = &g_Objects[O_SKIDOO_DRIVER]; @@ -19,3 +22,25 @@ void SkidooDriver_Setup(void) obj->save_anim = 1; obj->save_flags = 1; } + +void __cdecl SkidooDriver_Initialise(const int16_t item_num) +{ + ITEM *const skidoo_driver = Item_Get(item_num); + + const int16_t skidoo_item_num = Item_Create(); + assert(skidoo_item_num != NO_ITEM); + + ITEM *const skidoo = Item_Get(skidoo_item_num); + skidoo->object_id = O_SKIDOO_ARMED; + skidoo->pos.x = skidoo_driver->pos.x; + skidoo->pos.y = skidoo_driver->pos.y; + skidoo->pos.z = skidoo_driver->pos.z; + skidoo->rot.y = skidoo_driver->rot.y; + skidoo->room_num = skidoo_driver->room_num; + skidoo->flags = IF_ONE_SHOT; + skidoo->shade_1 = -1; + Item_Initialise(skidoo_item_num); + + skidoo_driver->data = (void *)(intptr_t)skidoo_item_num; + g_LevelItemCount++; +} diff --git a/src/tr2/game/objects/creatures/skidoo_driver.h b/src/tr2/game/objects/creatures/skidoo_driver.h index bc55bbcf8..781dbaaaa 100644 --- a/src/tr2/game/objects/creatures/skidoo_driver.h +++ b/src/tr2/game/objects/creatures/skidoo_driver.h @@ -1,5 +1,8 @@ #pragma once +#include + #define SKIDOO_DRIVER_HITPOINTS 100 void SkidooDriver_Setup(void); +void __cdecl SkidooDriver_Initialise(int16_t item_num); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 273523c19..7fe7a36ae 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define SkidooDriver_Initialise ((void __cdecl (*)(int16_t item_num))0x0043ED40) #define SkidooDriver_Control ((void __cdecl (*)(int16_t rider_num))0x0043EDD0) #define SkidooArmed_Push ((void __cdecl (*)(ITEM *item, const ITEM *lara_item, int32_t radius))0x0043F1D0) #define SkidooArmed_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 198fc398d..a8fb124be 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -43,6 +43,7 @@ #include "game/objects/creatures/bird.h" #include "game/objects/creatures/diver.h" #include "game/objects/creatures/dragon.h" +#include "game/objects/creatures/skidoo_driver.h" #include "game/objects/effects/ember.h" #include "game/objects/effects/flame.h" #include "game/objects/effects/twinkle.h" @@ -1027,6 +1028,7 @@ static void M_Objects(const bool enable) INJECT(enable, 0x00438E80, Pickup_Trigger); INJECT(enable, 0x0043A480, Object_SetupBaddyObjects); INJECT(enable, 0x0043C710, Object_SetupAllObjects); + INJECT(enable, 0x0043ED40, SkidooDriver_Initialise); INJECT(enable, 0x00442B30, FlameEmitter_Control); INJECT(enable, 0x00442BC0, Flame_Control); INJECT(enable, 0x00442E70, EmberEmitter_Control); From 8618d9bd2c6efd7d5d451f8d7e9273580d6fb80f Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 11:01:55 +0200 Subject: [PATCH 19/22] tr2: port SkidooDriver_Control --- docs/tr2/progress.svg | 16 +- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 58 +++-- src/tr2/decomp/skidoo.h | 12 + .../game/objects/creatures/skidoo_driver.c | 220 ++++++++++++++++++ .../game/objects/creatures/skidoo_driver.h | 1 + src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 8 files changed, 269 insertions(+), 42 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 0c53e6909..a6009df2c 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -67.12% (835) · 30.47% (379) · 0% (0) · 2.41% (30) +67.20% (836) · 30.39% (378) · 0% (0) · 2.41% (30) - - + + @@ -796,7 +796,7 @@ int32_t __cdecl Skidoo_Control(void); void __cdecl Skidoo_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); -void __cdecl SkidooDriver_Control(int16_t rider_num); +void __cdecl SkidooDriver_Control(int16_t rider_num); void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Music_GetRealTrack(int32_t track); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -72.28% · 27.39% · 0% · 0.33% +72.57% · 27.10% · 0% · 0.33% - - + + @@ -1394,7 +1394,7 @@ void __cdecl Cultist1_Control(int16_t item_num); void __cdecl Rocket_Control(int16_t item_num); void __cdecl XianKnight_Draw(const ITEM *item); -void __cdecl SkidooDriver_Control(int16_t rider_num); +void __cdecl SkidooDriver_Control(int16_t rider_num); void __cdecl InitialiseDoor(int16_t item_num); int32_t __cdecl Collide_CollideStaticObjects(COLL_INFO *coll, int32_t x, int32_t y, int32_t z, int16_t room_num, int32_t height); void __cdecl Room_Clip(ROOM *r); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 38008a6ea..f005946cc 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3675,7 +3675,7 @@ typedef enum { 0x0043E600 0x0440 +R int32_t __cdecl Skidoo_Control(void); 0x0043EA60 0x02D5 +R void __cdecl Skidoo_Draw(const ITEM *item); 0x0043ED40 0x007F + void __cdecl SkidooDriver_Initialise(int16_t item_num); -0x0043EDD0 0x03E2 - void __cdecl SkidooDriver_Control(int16_t rider_num); +0x0043EDD0 0x03E2 + void __cdecl SkidooDriver_Control(int16_t rider_num); 0x0043F1D0 0x0119 -R void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); 0x0043F2F0 0x0081 - void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index d60dc512d..f326e8b93 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -20,6 +20,27 @@ #include +#define SKIDOO_RADIUS 500 +#define SKIDOO_SIDE 260 +#define SKIDOO_FRONT 550 +#define SKIDOO_SNOW 500 +#define SKIDOO_GET_OFF_DIST 330 +#define SKIDOO_TARGET_DIST (WALL_L * 2) // = 2048 + +#define SKIDOO_ACCELERATION 10 +#define SKIDOO_SLOWDOWN 2 + +#define SKIDOO_SLIP 100 +#define SKIDOO_SLIP_SIDE 50 + +#define SKIDOO_MAX_BACK -30 +#define SKIDOO_BRAKE 5 +#define SKIDOO_REVERSE (-5) +#define SKIDOO_UNDO_TURN (PHD_DEGREE * 2) // = 364 +#define SKIDOO_TURN (PHD_DEGREE / 2 + SKIDOO_UNDO_TURN) // = 455 +#define SKIDOO_MOMENTUM_TURN (PHD_DEGREE * 3) // = 546 +#define SKIDOO_MAX_MOMENTUM_TURN (PHD_DEGREE * 150) // = 27300 + typedef enum { SKIDOO_GET_ON_NONE = 0, SKIDOO_GET_ON_LEFT = 1, @@ -57,39 +78,12 @@ typedef enum { // clang-format on } LARA_ANIM_SKIDOO; -#define SKIDOO_RADIUS 500 -#define SKIDOO_SIDE 260 -#define SKIDOO_FRONT 550 -#define SKIDOO_SNOW 500 -#define SKIDOO_GET_OFF_DIST 330 -#define SKIDOO_TARGET_DIST (WALL_L * 2) // = 2048 - -#define SKIDOO_MIN_SPEED 15 -#define SKIDOO_MAX_SPEED 100 -#define SKIDOO_SLOW_SPEED 50 -#define SKIDOO_FAST_SPEED 150 -#define SKIDOO_ACCELERATION 10 -#define SKIDOO_SLOWDOWN 2 - -#define SKIDOO_SLIP 100 -#define SKIDOO_SLIP_SIDE 50 - -#define SKIDOO_MAX_BACK -30 -#define SKIDOO_BRAKE 5 -#define SKIDOO_REVERSE (-5) -#define SKIDOO_UNDO_TURN (PHD_DEGREE * 2) // = 364 -#define SKIDOO_TURN (PHD_DEGREE / 2 + SKIDOO_UNDO_TURN) // = 455 -#define SKIDOO_MAX_TURN (PHD_DEGREE * 6) // = 1092 -#define SKIDOO_MOMENTUM_TURN (PHD_DEGREE * 3) // = 546 -#define SKIDOO_MAX_MOMENTUM_TURN (PHD_DEGREE * 150) // = 27300 - -#define SKIDOO_GUN_MESH 4 - -static BITE m_LeftGun = { +BITE g_Skidoo_LeftGun = { .pos = { .x = 219, .y = -71, .z = SKIDOO_FRONT }, .mesh_num = 0, }; -static BITE m_RightGun = { + +BITE g_Skidoo_RightGun = { .pos = { .x = -235, .y = -71, .z = SKIDOO_FRONT }, .mesh_num = 0, }; @@ -792,8 +786,8 @@ void __cdecl Skidoo_Guns(void) AddDynamicLight(x, y, z, 12, 11); ITEM *const skidoo = Item_Get(g_Lara.skidoo); - Creature_Effect(skidoo, &m_LeftGun, GunShot); - Creature_Effect(skidoo, &m_RightGun, GunShot); + Creature_Effect(skidoo, &g_Skidoo_LeftGun, GunShot); + Creature_Effect(skidoo, &g_Skidoo_RightGun, GunShot); } int32_t __cdecl Skidoo_Control(void) diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index b93f8e29e..94b95e43f 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -1,7 +1,19 @@ #pragma once +#include "global/const.h" #include "global/types.h" +#define SKIDOO_MIN_SPEED 15 +#define SKIDOO_MAX_SPEED 100 +#define SKIDOO_SLOW_SPEED 50 +#define SKIDOO_FAST_SPEED 150 + +#define SKIDOO_MAX_TURN (PHD_DEGREE * 6) // = 1092 +#define SKIDOO_GUN_MESH 4 + +extern BITE g_Skidoo_LeftGun; +extern BITE g_Skidoo_RightGun; + void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision( diff --git a/src/tr2/game/objects/creatures/skidoo_driver.c b/src/tr2/game/objects/creatures/skidoo_driver.c index 7487b87bd..9a2c246c0 100644 --- a/src/tr2/game/objects/creatures/skidoo_driver.c +++ b/src/tr2/game/objects/creatures/skidoo_driver.c @@ -1,11 +1,171 @@ #include "game/objects/creatures/skidoo_driver.h" +#include "decomp/skidoo.h" +#include "game/creature.h" #include "game/items.h" +#include "game/lot.h" +#include "game/sound.h" #include "global/funcs.h" #include "global/vars.h" +#include + #include +#define SKIDOO_DRIVER_MIN_TURN (SKIDOO_MAX_TURN / 3) // = 364 +#define SKIDOO_DRIVER_TARGET_ANGLE (PHD_DEGREE * 15) // = 2730 +#define SKIDOO_DRIVER_WAIT_RANGE SQUARE(WALL_L * 4) // = 0x1000000 +#define SKIDOO_DRIVER_SHOT_DAMAGE 10 +#define SKIDOO_DRIVER_LARA_DAMAGE 50 + +typedef enum { + // clang-format off + SKIDOO_DRIVER_STATE_EMPTY = 0, + SKIDOO_DRIVER_STATE_WAIT = 1, + SKIDOO_DRIVER_STATE_MOVING = 2, + SKIDOO_DRIVER_STATE_START_LEFT = 3, + SKIDOO_DRIVER_STATE_START_RIGHT = 4, + SKIDOO_DRIVER_STATE_LEFT = 5, + SKIDOO_DRIVER_STATE_RIGHT = 6, + SKIDOO_DRIVER_STATE_DEATH = 7, + // clang-format on +} SKIDOO_DRIVER_STATE; + +typedef enum { + SKIDOO_DRIVER_ANIM_DEATH = 10, +} SKIDOO_DRIVER_ANIM; + +static void M_KillDriver(ITEM *driver_item); +static void M_MakeMountable(ITEM *skidoo_item); +static void M_ControlDead(ITEM *driver_item, ITEM *skidoo_item); +static int16_t M_ControlAlive(ITEM *driver_item, ITEM *skidoo_item); + +static void M_KillDriver(ITEM *const driver_item) +{ + const int32_t driver_item_num = driver_item - g_Items; + Item_RemoveActive(driver_item_num); + driver_item->collidable = 0; + driver_item->flags |= IF_ONE_SHOT; + driver_item->hit_points = DONT_TARGET; +} + +static void M_MakeMountable(ITEM *const skidoo_item) +{ + const int32_t skidoo_item_num = skidoo_item - g_Items; + LOT_DisableBaddieAI(skidoo_item_num); + skidoo_item->object_id = O_SKIDOO_FAST; + skidoo_item->status = IS_DEACTIVATED; + Skidoo_Initialise(skidoo_item_num); + + SKIDOO_INFO *const skidoo_data = skidoo_item->data; + skidoo_data->track_mesh = SKIDOO_GUN_MESH; +} + +static void M_ControlDead(ITEM *const driver_item, ITEM *const skidoo_item) +{ + if (driver_item->current_anim_state == SKIDOO_DRIVER_STATE_DEATH) { + Item_Animate(driver_item); + } else { + driver_item->pos.x = skidoo_item->pos.x; + driver_item->pos.y = skidoo_item->pos.y; + driver_item->pos.z = skidoo_item->pos.z; + driver_item->rot.y = skidoo_item->rot.y; + driver_item->room_num = skidoo_item->room_num; + driver_item->anim_num = + g_Objects[O_SKIDOO_DRIVER].anim_idx + SKIDOO_DRIVER_ANIM_DEATH; + driver_item->frame_num = g_Anims[driver_item->anim_num].frame_base; + driver_item->current_anim_state = SKIDOO_DRIVER_STATE_DEATH; + + if (g_Lara.target == skidoo_item) { + g_Lara.target = NULL; + } + } + + switch (skidoo_item->current_anim_state) { + case SKIDOO_DRIVER_STATE_MOVING: + case SKIDOO_DRIVER_STATE_WAIT: + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_WAIT; + break; + default: + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_MOVING; + break; + } +} + +static int16_t M_ControlAlive(ITEM *const driver_item, ITEM *const skidoo_item) +{ + CREATURE *const driver_data = skidoo_item->data; + + AI_INFO info; + Creature_AIInfo(skidoo_item, &info); + Creature_Mood(skidoo_item, &info, MOOD_ATTACK); + int16_t angle = Creature_Turn(skidoo_item, SKIDOO_MAX_TURN / 2); + + switch (skidoo_item->current_anim_state) { + case SKIDOO_DRIVER_STATE_WAIT: + if (driver_data->mood != MOOD_BORED + && (ABS(info.angle) >= SKIDOO_DRIVER_TARGET_ANGLE + || info.distance >= SKIDOO_DRIVER_WAIT_RANGE)) { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_MOVING; + } + break; + + case SKIDOO_DRIVER_STATE_MOVING: + if (driver_data->mood == MOOD_BORED) { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_WAIT; + } else if ( + ABS(info.angle) < SKIDOO_DRIVER_TARGET_ANGLE + && info.distance < SKIDOO_DRIVER_WAIT_RANGE) { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_WAIT; + } else if (angle < -SKIDOO_DRIVER_MIN_TURN) { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_START_LEFT; + } else if (angle > SKIDOO_DRIVER_MIN_TURN) { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_START_RIGHT; + } + break; + + case SKIDOO_DRIVER_STATE_START_LEFT: + case SKIDOO_DRIVER_STATE_LEFT: + if (angle >= -SKIDOO_DRIVER_MIN_TURN) { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_MOVING; + } else { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_LEFT; + } + break; + + case SKIDOO_DRIVER_STATE_START_RIGHT: + case SKIDOO_DRIVER_STATE_RIGHT: + if (angle >= -SKIDOO_DRIVER_MIN_TURN) { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_MOVING; + } else { + skidoo_item->goal_anim_state = SKIDOO_DRIVER_STATE_LEFT; + } + break; + } + + if (driver_item->current_anim_state != SKIDOO_DRIVER_STATE_DEATH) { + if (driver_data->flags == 0 + && ABS(info.angle) < SKIDOO_DRIVER_TARGET_ANGLE + && g_LaraItem->hit_points > 0) { + const int32_t damage = g_Lara.skidoo != NO_ITEM + ? SKIDOO_DRIVER_SHOT_DAMAGE + : SKIDOO_DRIVER_LARA_DAMAGE; + + if (ShotLara(skidoo_item, &info, &g_Skidoo_RightGun, 0, damage) + + ShotLara(skidoo_item, &info, &g_Skidoo_LeftGun, 0, damage)) { + driver_data->flags = 5; + } + } + + if (driver_data->flags != 0) { + Sound_Effect(SFX_LARA_UZI_FIRE, &skidoo_item->pos, SPM_NORMAL); + driver_data->flags--; + } + } + + return angle; +} + void SkidooDriver_Setup(void) { OBJECT *const obj = &g_Objects[O_SKIDOO_DRIVER]; @@ -44,3 +204,63 @@ void __cdecl SkidooDriver_Initialise(const int16_t item_num) skidoo_driver->data = (void *)(intptr_t)skidoo_item_num; g_LevelItemCount++; } + +void __cdecl SkidooDriver_Control(const int16_t driver_item_num) +{ + ITEM *const driver_item = Item_Get(driver_item_num); + + const int16_t skidoo_item_num = (int16_t)(intptr_t)driver_item->data; + ITEM *const skidoo_item = Item_Get(skidoo_item_num); + + if (skidoo_item->data == NULL) { + LOT_EnableBaddieAI(skidoo_item_num, true); + skidoo_item->status = IS_ACTIVE; + } + + CREATURE *const driver_data = skidoo_item->data; + int16_t angle = 0; + + if (skidoo_item->hit_points <= 0) { + M_ControlDead(driver_item, skidoo_item); + } else { + angle = M_ControlAlive(driver_item, skidoo_item); + } + + if (skidoo_item->current_anim_state == SKIDOO_DRIVER_STATE_WAIT) { + driver_data->head_rotation = 0; + Sound_Effect(SFX_SKIDOO_IDLE, &skidoo_item->pos, SPM_NORMAL); + } else { + driver_data->head_rotation = driver_data->head_rotation == 1 ? 2 : 1; + Skidoo_DoSnowEffect(skidoo_item); + + const int32_t pitch_delta = + (SKIDOO_MAX_SPEED - skidoo_item->speed) * 100; + const int32_t pitch = (SOUND_DEFAULT_PITCH - pitch_delta) << 8; + Sound_Effect(SFX_SKIDOO_MOVING, &skidoo_item->pos, SPM_PITCH | pitch); + } + + Creature_Animate(skidoo_item_num, angle, 0); + + if (driver_item->current_anim_state == SKIDOO_DRIVER_STATE_DEATH) { + if (driver_item->status == IS_DEACTIVATED && skidoo_item->speed == 0 + && skidoo_item->fall_speed == 0) { + M_KillDriver(driver_item); + M_MakeMountable(skidoo_item); + } + } else { + driver_item->pos.x = skidoo_item->pos.x; + driver_item->pos.y = skidoo_item->pos.y; + driver_item->pos.z = skidoo_item->pos.z; + driver_item->rot.y = skidoo_item->rot.y; + const int16_t room_num = skidoo_item->room_num; + if (room_num != driver_item->room_num) { + Item_NewRoom(driver_item_num, room_num); + } + driver_item->anim_num = skidoo_item->anim_num + + g_Objects[O_SKIDOO_DRIVER].anim_idx + - g_Objects[O_SKIDOO_ARMED].anim_idx; + driver_item->frame_num = skidoo_item->frame_num + + g_Anims[driver_item->anim_num].frame_base + - g_Anims[skidoo_item->anim_num].frame_base; + } +} diff --git a/src/tr2/game/objects/creatures/skidoo_driver.h b/src/tr2/game/objects/creatures/skidoo_driver.h index 781dbaaaa..363ea4ae9 100644 --- a/src/tr2/game/objects/creatures/skidoo_driver.h +++ b/src/tr2/game/objects/creatures/skidoo_driver.h @@ -6,3 +6,4 @@ void SkidooDriver_Setup(void); void __cdecl SkidooDriver_Initialise(int16_t item_num); +void __cdecl SkidooDriver_Control(int16_t item_num); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 7fe7a36ae..c5490c42a 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define SkidooDriver_Control ((void __cdecl (*)(int16_t rider_num))0x0043EDD0) #define SkidooArmed_Push ((void __cdecl (*)(ITEM *item, const ITEM *lara_item, int32_t radius))0x0043F1D0) #define SkidooArmed_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) #define Music_GetRealTrack ((int32_t __cdecl (*)(int32_t track))0x0043F380) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index a8fb124be..944980f10 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -1029,6 +1029,7 @@ static void M_Objects(const bool enable) INJECT(enable, 0x0043A480, Object_SetupBaddyObjects); INJECT(enable, 0x0043C710, Object_SetupAllObjects); INJECT(enable, 0x0043ED40, SkidooDriver_Initialise); + INJECT(enable, 0x0043EDD0, SkidooDriver_Control); INJECT(enable, 0x00442B30, FlameEmitter_Control); INJECT(enable, 0x00442BC0, Flame_Control); INJECT(enable, 0x00442E70, EmberEmitter_Control); From 1b453a77535ab1e4030e0dc54ad5be22356b5a81 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 11:14:39 +0200 Subject: [PATCH 20/22] tr2: port SkidooArmed_Push --- docs/tr2/progress.svg | 16 +++---- docs/tr2/progress.txt | 2 +- src/tr2/decomp/skidoo.c | 7 ++-- src/tr2/decomp/skidoo.h | 2 +- src/tr2/game/objects/vehicles/skidoo_armed.c | 44 ++++++++++++++++++++ src/tr2/game/objects/vehicles/skidoo_armed.h | 5 +++ src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 2 + 8 files changed, 65 insertions(+), 14 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index a6009df2c..f05afafff 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -67.20% (836) · 30.39% (378) · 0% (0) · 2.41% (30) +67.28% (837) · 30.31% (377) · 0% (0) · 2.41% (30) - - + + @@ -797,7 +797,7 @@ void __cdecl Skidoo_Draw(const ITEM *item); void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); -void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); +void __cdecl SkidooArmed_Push(const ITEM *item, ITEM *lara_item, int32_t radius); void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Music_GetRealTrack(int32_t track); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -72.57% · 27.10% · 0% · 0.33% +72.66% · 27.02% · 0% · 0.33% - - + + @@ -1659,7 +1659,7 @@ void __cdecl Skidoo_Guns(void); void __cdecl SE_SoundDlgUpdate(HWND hwndDlg); HRESULT __stdcall EnumTextureFormatsCallback(LPDDSDESC lpDdsd, LPVOID lpContext); -void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); +void __cdecl SkidooArmed_Push(const ITEM *item, ITEM *lara_item, int32_t radius); void __cdecl Jelly_Control(int16_t item_num); void __cdecl S_DrawScreenBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE color_idx, const GOURAUD_OUTLINE *gour, uint16_t flags); void __cdecl ControlCeilingSpikes(int16_t item_num); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index f005946cc..c27b40588 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3676,7 +3676,7 @@ typedef enum { 0x0043EA60 0x02D5 +R void __cdecl Skidoo_Draw(const ITEM *item); 0x0043ED40 0x007F + void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 + void __cdecl SkidooDriver_Control(int16_t rider_num); -0x0043F1D0 0x0119 -R void __cdecl SkidooArmed_Push(ITEM *item, const ITEM *lara_item, int32_t radius); +0x0043F1D0 0x0119 + void __cdecl SkidooArmed_Push(const ITEM *item, ITEM *lara_item, int32_t radius); 0x0043F2F0 0x0081 - void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); # game/sound.c diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c index f326e8b93..648f79c7a 100644 --- a/src/tr2/decomp/skidoo.c +++ b/src/tr2/decomp/skidoo.c @@ -11,6 +11,7 @@ #include "game/matrix.h" #include "game/music.h" #include "game/objects/common.h" +#include "game/objects/vehicles/skidoo_armed.h" #include "game/output.h" #include "game/random.h" #include "game/room.h" @@ -90,7 +91,7 @@ BITE g_Skidoo_RightGun = { static bool M_IsNearby(const ITEM *item_1, const ITEM *item_2); static bool M_IsArmed(const SKIDOO_INFO *const skidoo_data); -static bool M_CheckBaddieCollision(ITEM *item, const ITEM *skidoo); +static bool M_CheckBaddieCollision(ITEM *item, ITEM *skidoo); static bool M_IsNearby(const ITEM *const item_1, const ITEM *const item_2) { @@ -107,7 +108,7 @@ static bool M_IsArmed(const SKIDOO_INFO *const skidoo_data) return skidoo_data->track_mesh & SKIDOO_GUN_MESH; } -static bool M_CheckBaddieCollision(ITEM *const item, const ITEM *const skidoo) +static bool M_CheckBaddieCollision(ITEM *const item, ITEM *const skidoo) { if (!item->collidable || item->status == IS_INVISIBLE || item == g_LaraItem || item == skidoo) { @@ -237,7 +238,7 @@ void __cdecl Skidoo_Collision( item->hit_points = 1; } -void __cdecl Skidoo_BaddieCollision(const ITEM *const skidoo) +void __cdecl Skidoo_BaddieCollision(ITEM *const skidoo) { int16_t roomies[12]; const int32_t roomies_count = diff --git a/src/tr2/decomp/skidoo.h b/src/tr2/decomp/skidoo.h index 94b95e43f..077745448 100644 --- a/src/tr2/decomp/skidoo.h +++ b/src/tr2/decomp/skidoo.h @@ -18,7 +18,7 @@ void __cdecl Skidoo_Initialise(int16_t item_num); int32_t __cdecl Skidoo_CheckGetOn(int16_t item_num, COLL_INFO *coll); void __cdecl Skidoo_Collision( int16_t item_num, ITEM *lara_item, COLL_INFO *coll); -void __cdecl Skidoo_BaddieCollision(const ITEM *skidoo); +void __cdecl Skidoo_BaddieCollision(ITEM *skidoo); int32_t __cdecl Skidoo_TestHeight( const ITEM *item, int32_t z_off, int32_t x_off, XYZ_32 *out_pos); void __cdecl Skidoo_DoSnowEffect(ITEM *skidoo); diff --git a/src/tr2/game/objects/vehicles/skidoo_armed.c b/src/tr2/game/objects/vehicles/skidoo_armed.c index 3421baa4f..f1aab9aec 100644 --- a/src/tr2/game/objects/vehicles/skidoo_armed.c +++ b/src/tr2/game/objects/vehicles/skidoo_armed.c @@ -1,5 +1,7 @@ #include "game/objects/vehicles/skidoo_armed.h" +#include "game/items.h" +#include "game/math.h" #include "game/objects/creatures/skidoo_driver.h" #include "global/funcs.h" #include "global/vars.h" @@ -26,3 +28,45 @@ void SkidooArmed_Setup(void) obj->save_hitpoints = 1; obj->save_flags = 1; } + +void __cdecl SkidooArmed_Push( + const ITEM *const item, ITEM *const lara_item, const int32_t radius) +{ + const int32_t dx = lara_item->pos.x - item->pos.x; + const int32_t dz = lara_item->pos.z - item->pos.z; + const int32_t cy = Math_Cos(item->rot.y); + const int32_t sy = Math_Sin(item->rot.y); + + int32_t rx = (cy * dx - sy * dz) >> W2V_SHIFT; + int32_t rz = (sy * dx + cy * dz) >> W2V_SHIFT; + + const FRAME_INFO *const best_frame = Item_GetBestFrame(item); + BOUNDS_16 bounds = { + .min_x = best_frame->bounds.min_x - radius, + .max_x = best_frame->bounds.max_x + radius, + .min_z = best_frame->bounds.min_z - radius, + .max_z = best_frame->bounds.max_z + radius, + }; + + if (rx < bounds.min_x || rx > bounds.max_x || rz < bounds.min_z + || rz > bounds.max_z) { + return; + } + + const int32_t r = bounds.max_x - rx; + const int32_t l = rx - bounds.min_x; + const int32_t t = bounds.max_z - rz; + const int32_t b = rz - bounds.min_z; + if (l <= r && l <= t && l <= b) { + rx -= l; + } else if (r <= l && r <= t && r <= b) { + rx += r; + } else if (t <= l && t <= r && t <= b) { + rz += t; + } else { + rz -= b; + } + + lara_item->pos.x = item->pos.x + ((rz * sy + rx * cy) >> W2V_SHIFT); + lara_item->pos.z = item->pos.z + ((rz * cy - rx * sy) >> W2V_SHIFT); +} diff --git a/src/tr2/game/objects/vehicles/skidoo_armed.h b/src/tr2/game/objects/vehicles/skidoo_armed.h index b6006f443..07e480276 100644 --- a/src/tr2/game/objects/vehicles/skidoo_armed.h +++ b/src/tr2/game/objects/vehicles/skidoo_armed.h @@ -1,3 +1,8 @@ #pragma once +#include "global/types.h" + void SkidooArmed_Setup(void); + +void __cdecl SkidooArmed_Push( + const ITEM *item, ITEM *lara_item, int32_t radius); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index c5490c42a..331e98bda 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define SkidooArmed_Push ((void __cdecl (*)(ITEM *item, const ITEM *lara_item, int32_t radius))0x0043F1D0) #define SkidooArmed_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) #define Music_GetRealTrack ((int32_t __cdecl (*)(int32_t track))0x0043F380) #define Collide_TestCollision ((int32_t __cdecl (*)(ITEM *item, const ITEM *lara_item))0x0043F9B0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 944980f10..128446e66 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -62,6 +62,7 @@ #include "game/objects/traps/ember_emitter.h" #include "game/objects/traps/flame_emitter.h" #include "game/objects/vehicles/boat.h" +#include "game/objects/vehicles/skidoo_armed.h" #include "game/option/option.h" #include "game/output.h" #include "game/overlay.h" @@ -1030,6 +1031,7 @@ static void M_Objects(const bool enable) INJECT(enable, 0x0043C710, Object_SetupAllObjects); INJECT(enable, 0x0043ED40, SkidooDriver_Initialise); INJECT(enable, 0x0043EDD0, SkidooDriver_Control); + INJECT(enable, 0x0043F1D0, SkidooArmed_Push); INJECT(enable, 0x00442B30, FlameEmitter_Control); INJECT(enable, 0x00442BC0, Flame_Control); INJECT(enable, 0x00442E70, EmberEmitter_Control); From 8463d1e1693dce9797382f90143d518fa47efa53 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 11:19:24 +0200 Subject: [PATCH 21/22] tr2: port SkidooArmed_Collision --- docs/tr2/progress.svg | 16 ++++++------- docs/tr2/progress.txt | 2 +- src/tr2/game/objects/vehicles/skidoo_armed.c | 25 ++++++++++++++++++++ src/tr2/game/objects/vehicles/skidoo_armed.h | 3 +++ src/tr2/global/funcs.h | 1 - src/tr2/inject_exec.c | 1 + 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index f05afafff..90aa91d38 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -67.28% (837) · 30.31% (377) · 0% (0) · 2.41% (30) +67.36% (838) · 30.23% (376) · 0% (0) · 2.41% (30) - - + + @@ -798,7 +798,7 @@ void __cdecl SkidooDriver_Initialise(int16_t item_num); void __cdecl SkidooDriver_Control(int16_t rider_num); void __cdecl SkidooArmed_Push(const ITEM *item, ITEM *lara_item, int32_t radius); -void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); +void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Music_GetRealTrack(int32_t track); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); void __cdecl Sound_StopEffect(int32_t sample_id); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -72.66% · 27.02% · 0% · 0.33% +72.69% · 26.98% · 0% · 0.33% - - + + @@ -1956,7 +1956,7 @@ int32_t __cdecl AddAssaultTime(uint32_t time); void __cdecl Lara_Col_Stop(ITEM *item, COLL_INFO *coll); void __cdecl Lara_Col_Roll(ITEM *item, COLL_INFO *coll); -void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); +void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); int32_t __cdecl Room_FindByPos(int32_t x, int32_t y, int32_t z); void __cdecl ControlExplosion1(int16_t fx_num); int32_t __cdecl Lara_DeflectEdge(ITEM *item, COLL_INFO *coll); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index c27b40588..40b263fe5 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3677,7 +3677,7 @@ typedef enum { 0x0043ED40 0x007F + void __cdecl SkidooDriver_Initialise(int16_t item_num); 0x0043EDD0 0x03E2 + void __cdecl SkidooDriver_Control(int16_t rider_num); 0x0043F1D0 0x0119 + void __cdecl SkidooArmed_Push(const ITEM *item, ITEM *lara_item, int32_t radius); -0x0043F2F0 0x0081 - void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); +0x0043F2F0 0x0081 + void __cdecl SkidooArmed_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); # game/sound.c 0x0043F380 0x0031 * int32_t __cdecl Music_GetRealTrack(int32_t track); diff --git a/src/tr2/game/objects/vehicles/skidoo_armed.c b/src/tr2/game/objects/vehicles/skidoo_armed.c index f1aab9aec..c0486ea04 100644 --- a/src/tr2/game/objects/vehicles/skidoo_armed.c +++ b/src/tr2/game/objects/vehicles/skidoo_armed.c @@ -1,6 +1,8 @@ #include "game/objects/vehicles/skidoo_armed.h" #include "game/items.h" +#include "game/lara/control.h" +#include "game/lara/misc.h" #include "game/math.h" #include "game/objects/creatures/skidoo_driver.h" #include "global/funcs.h" @@ -70,3 +72,26 @@ void __cdecl SkidooArmed_Push( lara_item->pos.x = item->pos.x + ((rz * sy + rx * cy) >> W2V_SHIFT); lara_item->pos.z = item->pos.z + ((rz * cy - rx * sy) >> W2V_SHIFT); } + +void __cdecl SkidooArmed_Collision( + const int16_t item_num, ITEM *const lara_item, COLL_INFO *const coll) +{ + ITEM *const item = Item_Get(item_num); + if (!Item_TestBoundsCollide(item, lara_item, coll->radius)) { + return; + } + + if (!Collide_TestCollision(item, lara_item)) { + return; + } + + if (coll->enable_baddie_push) { + Lara_Push( + item, lara_item, coll, item->speed > 0 ? coll->enable_spaz : false, + false); + } + + if (g_Lara.skidoo == NO_ITEM && item->speed > 0) { + Lara_TakeDamage(100, true); + } +} diff --git a/src/tr2/game/objects/vehicles/skidoo_armed.h b/src/tr2/game/objects/vehicles/skidoo_armed.h index 07e480276..5a55efcdb 100644 --- a/src/tr2/game/objects/vehicles/skidoo_armed.h +++ b/src/tr2/game/objects/vehicles/skidoo_armed.h @@ -6,3 +6,6 @@ void SkidooArmed_Setup(void); void __cdecl SkidooArmed_Push( const ITEM *item, ITEM *lara_item, int32_t radius); + +void __cdecl SkidooArmed_Collision( + int16_t item_num, ITEM *lara_item, COLL_INFO *coll); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 331e98bda..b199212d7 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -171,7 +171,6 @@ #define DoShift ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *pos, XYZ_32 *old))0x0043D320) #define DoDynamics ((int32_t __cdecl (*)(int32_t height, int32_t fall_speed, int32_t *y))0x0043D5A0) #define GetCollisionAnim ((int32_t __cdecl (*)(ITEM *skidoo, XYZ_32 *moved))0x0043D600) -#define SkidooArmed_Collision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x0043F2F0) #define Music_GetRealTrack ((int32_t __cdecl (*)(int32_t track))0x0043F380) #define Collide_TestCollision ((int32_t __cdecl (*)(ITEM *item, const ITEM *lara_item))0x0043F9B0) #define Collide_GetSpheres ((int32_t __cdecl (*)(const ITEM *item, SPHERE *spheres, bool world_space))0x0043FAE0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 128446e66..a56577060 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -1032,6 +1032,7 @@ static void M_Objects(const bool enable) INJECT(enable, 0x0043ED40, SkidooDriver_Initialise); INJECT(enable, 0x0043EDD0, SkidooDriver_Control); INJECT(enable, 0x0043F1D0, SkidooArmed_Push); + INJECT(enable, 0x0043F2F0, SkidooArmed_Collision); INJECT(enable, 0x00442B30, FlameEmitter_Control); INJECT(enable, 0x00442BC0, Flame_Control); INJECT(enable, 0x00442E70, EmberEmitter_Control); From 229c17cb9e89b810ba123528c3f0c78003a9e89f Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Tue, 22 Oct 2024 11:56:48 +0200 Subject: [PATCH 22/22] tools: fix ida c signature parser It failed to recognize function pointer arguments. --- tools/shared/ida_progress.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/shared/ida_progress.py b/tools/shared/ida_progress.py index a3abf244a..ef397ceb3 100644 --- a/tools/shared/ida_progress.py +++ b/tools/shared/ida_progress.py @@ -21,7 +21,7 @@ function_name = identifier parameters = ("(" _ "void" _ ")") / ("(" _ (parameter_list?) _ ")") parameter_list = parameter _ ("," _ parameter _)* - parameter = function_decl / var_decl + parameter = decl / type qualifier = ~"const|__cdecl|__stdcall|__thiscall|__fastcall" array_subscript = (_ "[" number? "]")*