diff --git a/config/symbol_addrs.txt b/config/symbol_addrs.txt index 95cd8d0f3..eb72f9672 100644 --- a/config/symbol_addrs.txt +++ b/config/symbol_addrs.txt @@ -334,8 +334,8 @@ PvFromPsplot__FP5SPLOT = 0x11C3B8; // type:func PsplotFromPv__FPv = 0x11C3C0; // type:func FIsPvGarbage__FPv = 0x11C3C8; // type:func MarkPvAlive__FPv = 0x11C3F0; // type:func -FUN_0011C418 = 0x11C418; // type:func -FUN_0011C498 = 0x11C498; // type:func +FUN_0011C418__FPvT0P6CFrame = 0x11C418; // type:func +FUN_0011C498__Fv = 0x11C498; // type:func FUN_0011C4E8 = 0x11C4E8; // type:func g_splotheapPair = 0x25C250; // size:0x1C @@ -778,13 +778,13 @@ SetAloRotationSmoothDetail__FP3ALOP4SMPA = 0x12A320; // type:f SetAloDefaultAckPos__FP3ALO3ACK = 0x12A390; // type:func SetAloDefaultAckRot__FP3ALO3ACK = 0x12A398; // type:func SetAloRestorePosition__FP3ALOi = 0x12A3A0; // type:func -FUN_0012a3c8 = 0x12A3C8; // type:func -FUN_0012a3e8 = 0x12A3E8; // type:func -FUN_0012a418 = 0x12A418; // type:func +FUN_0012a3c8__FP3ALOi = 0x12A3C8; // type:func +FUN_0012a3e8__FP3ALOi = 0x12A3E8; // type:func +FUN_0012a418__FP3ALOPi = 0x12A418; // type:func SetAloRestorePositionAck__FP3ALO3ACK = 0x12A430; // type:func SetAloRestoreRotation__FP3ALOi = 0x12A478; // type:func SetAloRestoreRotationAck__FP3ALO3ACK = 0x12A4A0; // type:func -FUN_0012a4e8 = 0x12A4E8; // type:func +FUN_0012a4e8__FP3ALOi = 0x12A4E8; // type:func SetAloLookAt__FP3ALO3ACK = 0x12A528; // type:func SetAloLookAtIgnore__FP3ALOf = 0x12A580; // type:func GetAloLookAtIgnore__FP3ALOPf = 0x12A5B8; // type:func @@ -800,12 +800,12 @@ SetAloLookAtEnabledPriority__FP3ALOi = 0x12A770; // type:f GetAloLookAtEnabledPriority__FP3ALOPi = 0x12A7A8; // type:func SetAloLookAtDisabledPriority__FP3ALOi = 0x12A7C0; // type:func GetAloLookAtDisabledPriority__FP3ALOPi = 0x12A7F8; // type:func -FUN_0012a810 = 0x12A810; // type:func -FUN_0012a848 = 0x12A848; // type:func -FUN_0012a860 = 0x12A860; // type:func -FUN_0012a888 = 0x12A888; // type:func -FUN_0012a8b8__FP3ALO = 0x12A8B8; // type:func -FUN_0012a8c8 = 0x12A8C8; // type:func +FUN_0012a810__FP3ALOi = 0x12A810; // type:func +FUN_0012a848__FP3ALOPi = 0x12A848; // type:func +FUN_0012a860__FP3ALOT0 = 0x12A860; // type:func +FUN_0012a888__FP3ALOPP3ALO = 0x12A888; // type:func +FUN_0012a8b8__FP3ALO = 0x12A8B8; // type:func +FUN_0012a8c8__FP3ALO = 0x12A8C8; // type:func SetAloRotationMatchesVelocity__FP3ALOff3ACK = 0x12A8D8; // type:func PtargetEnsureAlo__FP3ALO = 0x12A970; // type:func SetAloTargetAttacks__FP3ALOi = 0x12A9C8; // type:func @@ -1000,19 +1000,19 @@ FUN_00134b48 = 0x134B48; // type:func DrawBinocFilter = 0x135228; // type:func FUN_00135550 = 0x135550; // type:func open_close_binoc = 0x1356C0; // type:func -FUN_001357f0 = 0x1357F0; // type:func +FUN_001357f0__FPvT0 = 0x1357F0; // type:func FUN_00135858 = 0x135858; // type:func FUN_001358d0 = 0x1358D0; // type:func junk_00135E20 = 0x135E20; // type:func -FUN_00135E30 = 0x135E30; // type:func +FUN_00135E30__FPvN20 = 0x135E30; // type:func junk_00135E40 = 0x135E40; // type:func -FUN_00135E48 = 0x135E48; // type:func +FUN_00135E48__FPviP6VECTOR = 0x135E48; // type:func junk_00135E70 = 0x135E70; // type:func SetBinocBfk = 0x135E78; // type:func FUN_00135f48 = 0x135F48; // type:func FUN_00136040 = 0x136040; // type:func FUN_00136238 = 0x136238; // type:func -FUN_001363d0 = 0x1363D0; // type:func +FUN_001363d0__FP5BINOC = 0x1363D0; // type:func SetBinocAchzDraw = 0x136408; // type:func FDoneBinocAchz__FP5BINOC = 0x136530; // type:func SetBinocLookat__FP5BINOCP3ALO = 0x1365A0; // type:func @@ -1022,7 +1022,7 @@ FUN_00136648 = 0x136648; // type:func DrawBinoc = 0x1366A0; // type:func GetBinocReticleFocus__FP5BINOCPfT1 = 0x136EC8; // type:func FUN_00136ef8 = 0x136EF8; // type:func -FUN_00136fa8 = 0x136FA8; // type:func +FUN_00136fa8__FP5BINOC = 0x136FA8; // type:func binoc__static_initialization_and_destruction_0 = 0x136FE8; // type:func SetPos__8CTextBoxff = 0x137228; // type:func SetSize__8CTextBoxff = 0x137238; // type:func @@ -1308,10 +1308,10 @@ BindChkpnt__FP6CHKPNT = 0x141338; // type:func PostChkpntLoad__FP6CHKPNT = 0x141438; // type:func CloneChkpnt__FP6CHKPNTT0 = 0x1415D0; // type:func UpdateChkpnt__FP6CHKPNTf = 0x141690; // type:func -FUN_001417f0 = 0x1417F0; // type:func +FUN_001417f0__FP6CHKPNTP3WKR = 0x1417F0; // type:func TriggerChkpnt__FP6CHKPNT = 0x141870; // type:func -FUN_001419A0 = 0x1419A0; // type:func -FUN_001419C0 = 0x1419C0; // type:func +FUN_001419A0__FP6CHKPNTi = 0x1419A0; // type:func +FUN_001419C0__FP6CHKPNTi = 0x1419C0; // type:func FUN_001419E0__FPii = 0x1419E0; // type:func g_chkmgr = 0x261420; // size:0x430 @@ -1392,7 +1392,7 @@ RemoveCmFadeObject = 0x143B20; // type:func FUN_00143BA8 = 0x143BA8; // type:func UpdateCmFade = 0x143BE0; // type:func UpdateCmLast = 0x143E40; // type:func -SetupCmRotateToCam = 0x144008; // type:func +SetupCmRotateToCam__FP2CM = 0x144008; // type:func ConvertCmScreenToWorld = 0x144128; // type:func ConvertCmWorldToScreen = 0x1441C0; // type:func SetupCm__FP2CM = 0x144270; // type:func @@ -1401,11 +1401,11 @@ BuildFrustrum = 0x1443C8; // type:func UpdateCmMat4 = 0x144540; // type:func DrawCm__FP2CM = 0x144848; // type:func SetCmPosMat__FP2CMP6VECTORP7MATRIX3 = 0x1448C8; // type:func -SetCmLookAt = 0x144938; // type:func -ConvertWorldToCylindVelocity = 0x144978; // type:func -ConvertCylindToWorldVelocity = 0x144AA0; // type:func -ResetCmLookAtSmooth = 0x144B70; // type:func -SetCmLookAtSmooth = 0x144BE8; // type:func +SetCmLookAt__FP2CMP6VECTORT1 = 0x144938; // type:func +ConvertWorldToCylindVelocity__FPvN50 = 0x144978; // type:func +ConvertCylindToWorldVelocity__FPvN20fff = 0x144AA0; // type:func +ResetCmLookAtSmooth__FP2CMPv = 0x144B70; // type:func +SetCmLookAtSmooth__FP2CMiP6VECTORT2iffffff = 0x144BE8; // type:func AdjustCmJoy__FP2CMP3JOY5JOYIDPf = 0x144FF8; // type:func junk_00145080 = 0x145080; // type:func SetCmPolicy__FP2CM3CPPP5CPLCYP2SOPv = 0x145088; // type:func @@ -1421,7 +1421,7 @@ SetCm = 0x145718; // type:func PsoEnemyStepguard = 0x145810; // type:func FUN_00145950 = 0x145950; // type:func FUN_00145b68 = 0x145B68; // type:func -FUN_00145DD8 = 0x145DD8; // type:func +FUN_00145DD8__FUiP2CM = 0x145DD8; // type:func FUN_00145de8 = 0x145DE8; // type:func FUN_00145e68 = 0x145E68; // type:func PushLookkCm__FP2CM5LOOKK = 0x145FB8; // type:func @@ -1495,7 +1495,7 @@ UpdateDprize__FP6DPRIZEf = 0x147428; // type:func RenderDprizeAll__FP6DPRIZEP2CMP2RO = 0x1478F0; // type:func SetDprizeDprizes__FP6DPRIZE7DPRIZES = 0x147AB0; // type:func InitCoin__FP4COIN = 0x147E40; // type:func -FUN_00147ed0 = 0x147ED0; // type:func +FUN_00147ed0__FP6DPRIZE = 0x147ED0; // type:func FUN_00147ef8 = 0x147EF8; // type:func UpdateCoin__FP4COINf = 0x147FB0; // type:func CreateSwCharm__FP2SW = 0x148038; // type:func @@ -1507,22 +1507,22 @@ SetCharmDprizes__FP5CHARM7DPRIZES = 0x148470; // type:func InitKey__FP3KEY = 0x148510; // type:func SetKeyDprizes__FP3KEY7DPRIZES = 0x148598; // type:func FUN_00148698 = 0x148698; // type:func -FUN_00148718 = 0x148718; // type:func -FUN_00148748 = 0x148748; // type:func +FUN_00148718__FP6DPRIZE = 0x148718; // type:func +FUN_00148748__FPv = 0x148748; // type:func FUN_00148770 = 0x148770; // type:func -FUN_00148828 = 0x148828; // type:func +FUN_00148828__FP6DPRIZEf = 0x148828; // type:func FUN_00148888 = 0x148888; // type:func FUN_00148910__FPfT0 = 0x148910; // type:func FUN_00148938 = 0x148938; // type:func CpdprizeAttractSwDprizes__FP2SW3CIDP6VECTORiPP6DPRIZE = 0x148AC0; // type:func RemoveSwExtraneousCharms__FP2SW = 0x148CE0; // type:func FUN_00148d90 = 0x148D90; // type:func -FUN_00148e18 = 0x148E18; // type:func +FUN_00148e18__FPv = 0x148E18; // type:func FUN_00148e40 = 0x148E40; // type:func -FUN_00148ef8 = 0x148EF8; // type:func +FUN_00148ef8__FP4COINf = 0x148EF8; // type:func increment_and_show_life_count = 0x148F80; // type:func CollectLifetkn__FP7LIFETKN = 0x148FF0; // type:func -FUN_00149168 = 0x149168; // type:func +FUN_00149168__FP6DPRIZE = 0x149168; // type:func break_bottle = 0x149190; // type:func s_asnipDprize = 0x2619A0; // size:0x3c @@ -1531,9 +1531,9 @@ s_asnipDprize = 0x2619A0; // size:0x3c //////////////////////////////////////////////////////////////// // P2/cplcy.c //////////////////////////////////////////////////////////////// -InitCplcy = 0x149398; // type:func -FActiveCplcy = 0x1493A0; // type:func -SetCpmanCpmt = 0x1493B8; // type:func +InitCplcy__FP5CPLCYP2CM = 0x149398; // type:func +FActiveCplcy__FP5CPLCY = 0x1493A0; // type:func +SetCpmanCpmt__FP5CPMAN4CPMT = 0x1493B8; // type:func FUN_001493c0__Fv = 0x1493C0; // type:func PosCplookAnchor = 0x1493C8; // type:func FUN_00149458 = 0x149458; // type:func @@ -1541,12 +1541,12 @@ plays_binoc_sfx = 0x149508; // type:func PushCplookLookk__FP6CPLOOK5LOOKK = 0x1495E8; // type:func LookkPopCplook__FP6CPLOOK = 0x149610; // type:func LookkCurCplook__FP6CPLOOK = 0x149638; // type:func -InitCplook = 0x149660; // type:func +InitCplook__FP6CPLOOKP2CM = 0x149660; // type:func FUN_001496c0 = 0x1496C0; // type:func UpdateCplook = 0x149760; // type:func FUN_0014a7b8 = 0x14A7B8; // type:func InitCpalign = 0x14A888; // type:func -FUN_0014a8d0 = 0x14A8D0; // type:func +FUN_0014a8d0__FP7CPALIGN = 0x14A8D0; // type:func UpdateCpalign = 0x14A8F8; // type:func FUN_0014aa90__FPii = 0x14AA90; // type:func FUN_0014aa98__FPv = 0x14AA98; // type:func @@ -1596,14 +1596,14 @@ InitCrbrain__FP7CRBRAIN = 0x14C018; // type:func post_load_crbrain = 0x14C138; // type:func FUN_0014c2f0 = 0x14C2F0; // type:func FUN_0014c5e8 = 0x14C5E8; // type:func -FUN_0014c668 = 0x14C668; // type:func +FUN_0014c668__FPvi = 0x14C668; // type:func update_crbrain = 0x14C6E0; // type:func -FUN_0014c788 = 0x14C788; // type:func -FUN_0014c820 = 0x14C820; // type:func -FUN_0014c838 = 0x14C838; // type:func +FUN_0014c788__FPv = 0x14C788; // type:func +FUN_0014c820__FPv = 0x14C820; // type:func +FUN_0014c838__FPvi = 0x14C838; // type:func FUN_0014c858 = 0x14C858; // type:func FUN_0014cba8 = 0x14CBA8; // type:func -FUN_0014cd70 = 0x14CD70; // type:func +FUN_0014cd70__FPv = 0x14CD70; // type:func FUN_0014cdc8 = 0x14CDC8; // type:func handle_crbrain_message = 0x14CF30; // type:func @@ -1683,7 +1683,7 @@ s_asnipDart = 0x261CC8; InitDartgun__FP7DARTGUN = 0x14F740; // type:func HandleDartgunMessage__FP7DARTGUN5MSGIDPv = 0x14F770; // type:func BindDartgun__FP7DARTGUN = 0x14F850; // type:func -FUN_0014f900 = 0x14F900; // type:func +FUN_0014f900__FP7DARTGUN = 0x14F900; // type:func PostDartgunLoad__FP7DARTGUN = 0x14F920; // type:func UpdateDartgun__FP7DARTGUNf = 0x14FA88; // type:func FIgnoreDartgunIntersection__FP7DARTGUNP2SO = 0x14FBE0; // type:func @@ -1842,7 +1842,7 @@ PemitterEnsureEmitter__FP7EMITTER4ENSK = 0x1557B8; // AddEmitterSkeleton__FP7EMITTER3OIDT1ffff = 0x1557D0; // type:func ModifyEmitterParticles__FP7EMITTER = 0x155868; // type:func UpdateEmitter__FP7EMITTERf = 0x155AB0; // type:func -FUN_00155f28 = 0x155F28; // type:func +FUN_00155f28__FP2SO = 0x155F28; // type:func PauseEmitter__FP7EMITTERf = 0x155F78; // type:func PauseEmitterIndefinite__FP7EMITTER = 0x155F90; // type:func UnpauseEmitter__FP7EMITTER = 0x155FA0; // type:func @@ -1983,8 +1983,8 @@ FCheckFlyOpenSpaceBelow__FP3FLY = 0x15C0A0; // type:func // P2/font.c //////////////////////////////////////////////////////////////// StartupFont__Fv = 0x15C178; // type:func -FUN_0015c188 = 0x15C188; // type:func -FUN_0015c1c0 = 0x15C1C0; // type:func +FUN_0015c188__Fi = 0x15C188; // type:func +FUN_0015c1c0__Fi = 0x15C1C0; // type:func FUN_0015c200 = 0x15C200; // type:func CopyTo__5CFontP5CFont = 0x15C260; // type:func SetupDraw__5CFontP8CTextBoxP4GIFS = 0x15C2E8; // type:func @@ -2091,9 +2091,9 @@ StartupGame__Fv = 0x160070; // type:func junk_00160090 = 0x160090; // type:func search_level_by_load_data = 0x1600A0; // type:func search_level_by_id = 0x160110; // type:func -PchzFriendlyFromWid = 0x160148; // type:func +PchzFriendlyFromWid__Fi = 0x160148; // type:func junk_00160178 = 0x160178; // type:func -call_search_level_by_id = 0x160180; // type:func +call_search_level_by_id__Fi = 0x160180; // type:func FFindLevel = 0x1601A0; // type:func junk_001601D0 = 0x1601D0; // type:func get_level_completion_by_id = 0x1601D8; // type:func @@ -2101,7 +2101,7 @@ tally_world_completion = 0x160208; // type:func get_game_completion__Fv = 0x1602A0; // type:func UnlockIntroCutsceneFromWid__Fi = 0x160340; // type:func DefeatBossFromWid = 0x1603E8; // type:func -UnlockEndgameCutscenesFromFgs = 0x1604B8; // type:func +UnlockEndgameCutscenesFromFgs__F3FGS = 0x1604B8; // type:func PlayEndingFromCompletionFlags = 0x160578; // type:func InitGameState__FP2GS = 0x1605E8; // type:func @@ -2111,7 +2111,7 @@ FUN_00160650 = 0x160650; // type:func SetupGame__FPci = 0x160690; // type:func UpdateGameState__Ff = 0x1607D0; // type:func -LsFromWid = 0x160810; // type:func +LsFromWid__F3WID = 0x160810; // type:func GrflsFromWid__F3WID = 0x160850; // type:func UnloadGame__Fv = 0x160880; // type:func @@ -2199,7 +2199,7 @@ DrawThreeWay__4GLBS = 0x161F70; // type:func EndStrip__4GLBS = 0x162508; // type:func SetNormal__4GLBSP6VECTOR = 0x162680; // type:func junk_001626A0 = 0x1626A0; // type:func -SetRgba__4GLBSG4RGBA = 0x1626A8; // type:func +SetRgba__4GLBSP4RGBA = 0x1626A8; // type:func SetUv__4GLBSP3UVF = 0x1626C0; // type:func AddVtx__4GLBSi = 0x1626D8; // type:func @@ -2337,7 +2337,7 @@ SolveAloIK__FP3ALO = 0x16C528; // type:func InitJlo__FP3JLO = 0x16CE00; // type:func LoadJloFromBrx__FP3JLOP18CBinaryInputStream = 0x16CE80; // type:func PostJloLoad__FP3JLO = 0x16CF70; // type:func -FUN_0016d040 = 0x16D040; // type:func +FUN_0016d040__FP3JLO3OID = 0x16D040; // type:func PresetJloAccel__FP3JLOf = 0x16D0C0; // type:func UpdateJlo__FP3JLOf = 0x16D128; // type:func JlosNextJlo__FP3JLO = 0x16D1E0; // type:func @@ -2345,7 +2345,7 @@ SetJloJlovol__FP3JLOP6JLOVOL = 0x16D3F0; // type:func FireJlo__FP3JLO = 0x16D490; // type:func LandJlo__FP3JLO = 0x16D788; // type:func JumpJlo__FP3JLO = 0x16D828; // type:func -FUN_0016d928 = 0x16D928; // type:func +FUN_0016d928__FP3JLO = 0x16D928; // type:func FUN_0016d9a8 = 0x16D9A8; // type:func HandleJloMessage__FP3JLO5MSGIDPv = 0x16DA00; // type:func SetJloJlos__FP3JLO4JLOS = 0x16DAC0; // type:func @@ -2414,7 +2414,7 @@ PresetJtAccelBase = 0x16FD70; // type:func PresetJtAccel__FP2JTf = 0x1701B0; // type:func AdjustJtNewXp__FP2JTP2XPi = 0x170410; // type:func AdjustJtDz__FP2JTiP2DZif = 0x170528; // type:func -HandleJtGrfjtsc = 0x1705C8; // type:func +HandleJtGrfjtsc__FP2JT = 0x1705C8; // type:func UpdateJtInternalXps__FP2JT = 0x170660; // type:func FCheckJtXpBase__FP2JTP2XPi = 0x170790; // type:func AdjustJtXpVelocity__FP2JTP2XPi = 0x170820; // type:func @@ -2450,7 +2450,7 @@ EnableJtActadj__FP2JTi = 0x175078; // type:func SetJtJts__FP2JT3JTS4JTBS = 0x175170; // type:func ProfileJt__FP2JTi = 0x1777F8; // type:func SetJtPuppet__FP2JTP5ASEGA = 0x177800; // type:func -FUN_00177828 = 0x177828; // type:func +FUN_00177828__FP2JTi = 0x177828; // type:func PaloAbsorbWkr__FP3WKRiPP3ALO = 0x177838; // type:func NCmpWkr__FP3WKRT0 = 0x177968; // type:func UpdateJtEffect__FP2JT = 0x177990; // type:func @@ -2560,7 +2560,7 @@ UseLgnCharm__FP3LGN = 0x181AF0; // type:func ApplyLgnThrow__FP3LGNP2PO = 0x181B20; // type:func FTakeLgnDamage__FP3LGNP3ZPR = 0x181BC8; // type:func HandleLgnMessage__FP3LGN5MSGIDPv = 0x181D28; // type:func -FUN_00181d88 = 0x181D88; // type:func +FUN_00181d88__FPUc = 0x181D88; // type:func SetLgnLgns__FP3LGN4LGNS = 0x181DA8; // type:func UpdateLgnrAim__FP4LGNRP3JOY = 0x181ED0; // type:func DrawLgnr__FP4LGNR = 0x1821B0; // type:func @@ -2893,8 +2893,8 @@ ProjectMissileTransform__FP7MISSILEfi = 0x18D9B8; // type:func FireMissile__FP7MISSILEP3ALOP6VECTOR = 0x18DA40; // type:func RenderMissileAll__FP7MISSILEP2CMP2RO = 0x18DB20; // type:func FUN_0018dc88 = 0x18DC88; // type:func -FUN_0018dd50 = 0x18DD50; // type:func -FUN_0018dd78 = 0x18DD78; // type:func +FUN_0018dd50__FPvi = 0x18DD50; // type:func +FUN_0018dd78__FPvi = 0x18DD78; // type:func InitAccmiss__FP7ACCMISS = 0x18DDA0; // type:func FireAccmiss__FP7ACCMISSP3ALOP6VECTOR = 0x18DDD8; // type:func PresetAccmissAccel__FP7ACCMISSf = 0x18DE70; // type:func @@ -2907,10 +2907,10 @@ s_asnipMissile = 0x2699b0; //////////////////////////////////////////////////////////////// // P2/mpeg.c //////////////////////////////////////////////////////////////// -FUN_0018e410 = 0x18E410; // type:func -FUN_0018e480 = 0x18E480; // type:func -FUN_0018e4c0 = 0x18E4C0; // type:func -FUN_0018e4f0 = 0x18E4F0; // type:func +FUN_0018e410__FPv = 0x18E410; // type:func +FUN_0018e480__Fi = 0x18E480; // type:func +FUN_0018e4c0__Fi = 0x18E4C0; // type:func +FUN_0018e4f0__Fii = 0x18E4F0; // type:func FUN_0018e558 = 0x18E558; // type:func StartupMpeg__Fv = 0x18E5E8; // type:func Init__15CQueueOutputIopii = 0x18E678; // type:func @@ -2935,7 +2935,7 @@ BuildMpegGifs__FP2QWP11sceIpuRGB32iiiii = 0x18EDA8; // type:func FUN_0018ef78 = 0x18EF78; // type:func FUN_0018f0e8 = 0x18F0E8; // type:func ExecuteOids__5CMpeg = 0x18F148; // type:func -Execute__5CMpeg = 0x18F198; // type:func +Execute__5CMpegP3OID = 0x18F198; // type:func Start__5CMpegP18CBinaryAsyncStream = 0x18F448; // type:func FUN_0018f610__5CMpeg = 0x18F610; // type:func Update__5CMpeg = 0x18F6E8; // type:func @@ -2981,7 +2981,7 @@ CollectMurrayPrize__FP6MURRAY3PCKP3ALO = 0x1906F8; // type:func CheckMurrayStunOrDying__FP6MURRAY = 0x190740; // type:func HandleMurrayMessage__FP6MURRAY5MSGIDPv = 0x190770; // type:func -D_00269B60 = 0x269B60; +D_00269B60 = 0x269B60; //////////////////////////////////////////////////////////////// @@ -3003,7 +3003,7 @@ LoadPathzoneFromBrx__FP8PATHZONEP18CBinaryInputStream = 0x1916D0; // type:func HookupCg__FP2CG = 0x1919F8; // type:func CposFindPathzonePath__FP8PATHZONEP6VECTORT1iT1 = 0x191A68; // type:func FindPathzoneClosestPoint__FP8PATHZONEP6VECTORT1 = 0x191A88; // type:func -FUN_00191aa8 = 0x191AA8; // type:func +FUN_00191aa8__FPvP6VECTORT1iP3LSG = 0x191AA8; // type:func FUN_00191ac8 = 0x191AC8; // type:func ChoosePathzoneRandomPoint__FP8PATHZONEP6VECTOR = 0x191C78; // type:func @@ -3055,7 +3055,7 @@ MakePoActive__FP2PO = 0x192418; // type:func FInvulnerablePo__FP2PO3ZPK = 0x192450; // type:func FTakePoDamage__FP2POP3ZPR = 0x192488; // type:func JthsCurrentPo__FP2PO = 0x192490; // type:func -FUN_00192498 = 0x192498; // type:func +FUN_00192498__FP2POPi = 0x192498; // type:func CollectPoPrize__FP2PO3PCKP3ALO = 0x1924C8; // type:func FUN_001925C0 = 0x1925C0; // type:func PpoCur__Fv = 0x1925F0; // type:func @@ -3106,7 +3106,7 @@ FUN_00193ee8 = 0x193ee8; // type:func FUN_00193f88__Fv = 0x193f88; // type:func FUN_00193fb8 = 0x193fb8; // type:func OnPromptActive__FP6PROMPTi = 0x1940e8; // type:func -FUN_00194278 = 0x194278; // type:func +FUN_00194278__FP6PROMPTi5WIPEK = 0x194278; // type:func FUN_00194398__Fv = 0x194398; // type:func UpdatePromptActive__FP6PROMPTP3JOY = 0x1943e8; // type:func SetPrompt__FP6PROMPT3PRP3PRK = 0x194d30; // type:func @@ -3144,13 +3144,13 @@ FFilterPuffer__FP6PUFFERP2SO = 0x196E48; // type:func UpdatePuffer__FP6PUFFERf = 0x196EB0; // type:func PpufftChoosePuffer__FP6PUFFER = 0x1971B8; // type:func FUN_001973d8 = 0x1973D8; // type:func -FUN_00197458 = 0x197458; // type:func +FUN_00197458__FPvi = 0x197458; // type:func OnPufferActive__FP6PUFFERiP2PO = 0x1974D8; // type:func UpdatePufferActive__FP6PUFFERP3JOYf = 0x1974F8; // type:func FUN_00197788 = 0x197788; // type:func FUN_00197848 = 0x197848; // type:func -FUN_00197a08 = 0x197A08; // type:func -FUN_00197a68 = 0x197A68; // type:func +FUN_00197a08__FPvT0 = 0x197A08; // type:func +FUN_00197a68__FPvT0 = 0x197A68; // type:func AddPufferWaterAcceleration__FP6PUFFERP5WATERf = 0x197A88; // type:func HandlePufferMessage__FP6PUFFER5MSGIDPv = 0x197F10; // type:func PostPuffcLoad__FP5PUFFC = 0x198090; // type:func @@ -3440,7 +3440,7 @@ RobkCur__Fv = 0x1A4898; // type:func BindRob__FP3ROB = 0x1A48C0; // type:func PostRobLoad__FP3ROB = 0x1A4B30; // type:func UpdateRob__FP3ROBf = 0x1A4C48; // type:func -FUN_001a4d60 = 0x1A4D60; // type:func +FUN_001a4d60__FP3ROB = 0x1A4D60; // type:func RobsNextRob__FP3ROB = 0x1A4DC0; // type:func SetRobRobs__FP3ROB4ROBS = 0x1A4EF0; // type:func AddRobRoc__FP3ROB = 0x1A5120; // type:func @@ -3493,6 +3493,8 @@ UpdateRop__FP3ROPf = 0x1A7800; // type:func SetRopRops__FP3ROP4ROPS = 0x1A7998; // type:func RopsNextRop__FP3ROP = 0x1A7AA0; // type:func +s_asnip = 0x26A918; +s_asnipLoadUbg = 0x275B60; s_asnipLoadRov = 0x26B778; @@ -3507,7 +3509,7 @@ SetRumbleRums__FP6RUMBLE4RUMS = 0x1A7D98; // type:func StopRumbleActuators__FP6RUMBLE = 0x1A7E40; // type:func FUN_001A7E70__Fv = 0x1A7E70; // type:func FUN_001A7E90 = 0x1A7E90; // type:func -FUN_001A7EE8 = 0x1A7EE8; // type:func +FUN_001A7EE8__FP2GS = 0x1A7EE8; // type:func FUN_001A7F50 = 0x1A7F50; // type:func DAT_0026c3dc = 0x26C3DC; @@ -3517,13 +3519,13 @@ DAT_0026c3dc = 0x26C3DC; // P2/rwm.c //////////////////////////////////////////////////////////////// InitRwm__FP3RWM = 0x1A7FE8; // type:func -OnRwmRemove = 0x1A80E0; // type:func -FUN_001a8110 = 0x1A8110; // type:func +OnRwmRemove__FP3RWM = 0x1A80E0; // type:func +FUN_001a8110__FP3RWM = 0x1A8110; // type:func FUN_001a8150 = 0x1A8150; // type:func InitRwmCallback__FP3RWM5MSGIDPv = 0x1A8208; // type:func -FUN_001a84c8 = 0x1A84C8; // type:func +FUN_001a84c8__FP3RWMT0 = 0x1A84C8; // type:func PostRwmLoad__FP3RWM = 0x1A8590; // type:func -FUN_001a86f8 = 0x1A86F8; // type:func +FUN_001a86f8__FP3RWMi = 0x1A86F8; // type:func PrwcFindRwm__FP3RWM3OID = 0x1A8718; // type:func EnableRwmRwc__FP3RWM3OID = 0x1A8778; // type:func DisableRwmRwc__FP3RWM3OID = 0x1A87A8; // type:func @@ -3610,17 +3612,17 @@ DtVisibleTrunkctr__FP8TRUNKCTR = 0x1ABE40; // type:func DtVisibleCrusherctr__FP10CRUSHERCTR = 0x1ABE50; // type:func FUN_001ABE60__Fv = 0x1ABE60; // type:func FUN_001abe70 = 0x1ABE70; // type:func -FUN_001ac060 = 0x1AC060; // type:func +FUN_001ac060__FP5TIMER = 0x1AC060; // type:func FUN_001ac0e8 = 0x1AC0E8; // type:func PostNoteLoad__FP4NOTE = 0x1AC5C0; // type:func SetNoteAchzDraw__FP4NOTEPc = 0x1AC638; // type:func DrawNote__FP4NOTE = 0x1AC700; // type:func -FUN_001ac888 = 0x1AC888; // type:func +FUN_001ac888__FP4BLOT = 0x1AC888; // type:func FUN_001ac910 = 0x1AC910; // type:func FUN_001ac990 = 0x1AC990; // type:func FUN_001ac9e0 = 0x1AC9E0; // type:func -FUN_001aca30 = 0x1ACA30; // type:func -FUN_001aca68 = 0x1ACA68; // type:func +FUN_001aca30__FP4BLOT = 0x1ACA30; // type:func +FUN_001aca68__FP4BLOT = 0x1ACA68; // type:func DrawTitle__FP5TITLE = 0x1ACAA8; // type:func PostTotalsLoad__FP6TOTALS = 0x1ACDA0; // type:func FUN_001ace38 = 0x1ACE38; // type:func @@ -3632,13 +3634,13 @@ SetTotalsBlots__FP6TOTALS5BLOTS = 0x1AD320; // type:func ShowTotalsQMARK = 0x1AD378; // type:func HideTotalsQMARK = 0x1AD3B0; // type:func DrawTotals__FP6TOTALS = 0x1AD3F0; // type:func -FUN_001ad6a8 = 0x1AD6A8; // type:func +FUN_001ad6a8__FP4BLOT = 0x1AD6A8; // type:func FUN_001ad718 = 0x1AD718; // type:func FUN_001ad7b0 = 0x1AD7B0; // type:func -FUN_001ad940 = 0x1AD940; // type:func +FUN_001ad940__FP4BLOT = 0x1AD940; // type:func FUN_001ad970 = 0x1AD970; // type:func DrawLetterbox__FP9LETTERBOX = 0x1ADB00; // type:func -FUN_001adc60 = 0x1ADC60; // type:func +FUN_001adc60__FP4BLOT = 0x1ADC60; // type:func DrawLogo__FP4LOGO = 0x1ADD28; // type:func FUN_001adf28 = 0x1ADF28; // type:func FUN_001adff0 = 0x1ADFF0; // type:func @@ -3648,13 +3650,13 @@ DrawAttract__FP7ATTRACT = 0x1AE220; // type:func DrawLineScreen__FUiUiUiUiUiUiG4RGBAi = 0x1AE3B8; // type:func FUN_001ae510 = 0x1AE510; // type:func FUN_001ae5e0 = 0x1AE5E0; // type:func -FUN_001ae758 = 0x1AE758; // type:func -FUN_001ae7f8 = 0x1AE7F8; // type:func +FUN_001ae758__FP4BLOT = 0x1AE758; // type:func +FUN_001ae7f8__FP3CTR5BLOTS = 0x1AE7F8; // type:func FUN_001ae820 = 0x1AE820; // type:func FUN_001aea08 = 0x1AEA08; // type:func FUN_001aea70 = 0x1AEA70; // type:func junk_001aec80 = 0x1AEC80; // type:func -FUN_001aec90 = 0x1AEC90; // type:func +FUN_001aec90__Fv = 0x1AEC90; // type:func // Global blots g_lifectr = 0x26c6c8; // size:0x280 @@ -3949,7 +3951,7 @@ RenderSoSelf__FP2SOP2CMP2RO = 0x1B93D8; // type:func UpdateSo__FP2SOf = 0x1B93F8; // type:func SetSoMass__FP2SOf = 0x1B9418; // type:func AdjustSoMomint__FP2SOf = 0x1B9448; // type:func -DiscardSoXps__FP2SO = 0x1B94F0; // type:func +DiscardSoXps__FP2SOi = 0x1B94F0; // type:func UpdateSoPosWorldPrev__FP2SO = 0x1B9680; // type:func TranslateSoToPos__FP2SOP6VECTOR = 0x1B9690; // type:func RotateSoToMat__FP2SOP7MATRIX3 = 0x1B97E0; // type:func @@ -4009,10 +4011,10 @@ ApplySoImpulse__FP2SOP6VECTORT1f = 0x1BC0E0; // type:func CalculateSoTrajectoryApex__FP2SOP6VECTORfT1 = 0x1BC260; // type:func FAbsorbSoWkr__FP2SOP3WKR = 0x1BC320; // type:func CloneSoPhys__FP2SOT0i = 0x1BC368; // type:func -FUN_001bc4d8 = 0x1BC4D8; // type:func +FUN_001bc4d8__FPUcT0 = 0x1BC4D8; // type:func FUN_001bc670 = 0x1BC670; // type:func -FUN_001bc710 = 0x1BC710; // type:func -FUN_001bc748 = 0x1BC748; // type:func +FUN_001bc710__FP2SOi = 0x1BC710; // type:func +FUN_001bc748__FP2SOPi = 0x1BC748; // type:func //////////////////////////////////////////////////////////////// @@ -4046,17 +4048,17 @@ SbpEnsureBank__Fi = 0x1BE268; // type:func SbpEnsureBank__F5SFXID = 0x1BE4A8; // type:func NewSfx__FPP3SFX = 0x1BE4D8; // type:func FContinuousSound__F5SFXID = 0x1BE568; // type:func -FUN_001BE5D8 = 0x1BE5D8; // type:func +FUN_001BE5D8__Fv = 0x1BE5D8; // type:func SetVagUnpaused__Fv = 0x1BE5E8; // type:func PreloadVag__FPc2FK = 0x1BE5F8; // type:func -FUN_001be708 = 0x1BE708; // type:func +FUN_001be708__Fv = 0x1BE708; // type:func PreloadVag1 = 0x1BE728; // type:func FPauseForVag__Fv = 0x1BE810; // type:func RefreshPambVolPan__FP3AMB = 0x1BE860; // type:func -FUN_001be8f8 = 0x1BE8F8; // type:func +FUN_001be8f8__FP3ALOPP3AMBff = 0x1BE8F8; // type:func FVagPlaying__Fv = 0x1BE980; // type:func junk_001BE990 = 0x1BE990; // type:func @@ -4070,8 +4072,8 @@ StartMusidSong__F5MUSID = 0x1BEC58; // type:func PauseMusic__Fv = 0x1BECF8; // type:func ContinueMusic__Fv = 0x1BED20; // type:func -SfxhMusicUnknown1 = 0x1BED48; // type:func -SfxhMusicUnknown2 = 0x1BED70; // type:func +SfxhMusicUnknown1__Fv = 0x1BED48; // type:func +SfxhMusicUnknown2__Fv = 0x1BED70; // type:func PexcAlloc__Fv = 0x1BED98; // type:func RemoveExc__FP3EXC = 0x1BEDF8; // type:func @@ -4101,25 +4103,25 @@ FillPamb__FP3AMBPP3AMBiP3ALOP6VECTORfffffP2LMT10_ = 0x1BF920; // type:func ActivatePamb__FP3AMB5SFXID = 0x1BFAF8; // type:func ScheduleNextIntermittentSound__FP3AMB = 0x1BFBF8; // type:func StartSound__F5SFXIDPP3AMBP3ALOP6VECTORfffffP2LMT9 = 0x1BFCD8; // type:func -FUN_001BFFC8 = 0x1BFFC8; // type:func +FUN_001BFFC8__FiUl = 0x1BFFC8; // type:func HandleWipeHandleWipeVolumes__FifVolumes = 0x1C0000; // type:func UpdateSounds__Fv = 0x1C0070; // type:func SetMvgkUvol__Ff = 0x1c05d0; // type:func MvgkUnknown1__F4MVGK = 0x1C0600; // type:func SetMvgkRvol__Fi4MVGKf = 0x1C06A0; // type:func MvgkUnknown2__Fv = 0x1C06D8; // type:func -MvgkUnknown3 = 0x1C0760; // type:func -MvgkUnknown4 = 0x1C0790; // type:func +MvgkUnknown3__Fi = 0x1C0760; // type:func +MvgkUnknown4__Fi = 0x1C0790; // type:func KillSoundSystem__Fv = 0x1C07B0; // type:func KillSounds__Fi = 0x1C0808; // type:func PushSwReverb__FP2SW7REVERBKi = 0x1C08B0; // type:func PopSwReverb__FP2SW = 0x1C0950; // type:func SetSwDefaultReverb__FP2SW7REVERBKi = 0x1C09D8; // type:func FUN_001C0A50 = 0x1C0A50; // type:func -FUN_001C0AB8 = 0x1C0AB8; // type:func -FUN_001C0B08 = 0x1C0B08; // type:func +FUN_001C0AB8__FP2SWPf = 0x1C0AB8; // type:func +FUN_001C0B08__FP2SWP2LM = 0x1C0B08; // type:func StartSwIntermittentSounds__FP2SW = 0x1C0B38; // type:func -SetAMRegister__FiUc = 0x1C0C08; // type:func +SetAMRegister__Fii = 0x1C0C08; // type:func GetAMRegister__Fi = 0x1C0C50; // type:func UpdateAMRegister__Fii = 0x1C0C68; // type:func FUN_001c0cb0__Fv = 0x1C0CB0; // type:func @@ -4189,7 +4191,7 @@ _GLOBAL_$I$g_asprbuf = 0x1C29C8; // type:func //////////////////////////////////////////////////////////////// // P2/sqtr.c //////////////////////////////////////////////////////////////// -FUN_001c29e8 = 0x1C29E8; // type:func +FUN_001c29e8__FP5SQTRM = 0x1C29E8; // type:func UpdateSqtrm__FP5SQTRMP6VECTORP7MATRIX3ff = 0x1C29F8; // type:func RenderSqtrm__FP5SQTRMP2CM = 0x1C3028; // type:func DrawSqtrm__FP3RPL = 0x1C30E8; // type:func @@ -4202,7 +4204,7 @@ InitStep__FP4STEP = 0x1C4458; // type:func PostStepLoad__FP4STEP = 0x1C44F0; // type:func LimitStepHands__FP4STEPi = 0x1C4578; // type:func FUN_001c4618 = 0x1C4618; // type:func -FUN_001c4790 = 0x1C4790; // type:func +FUN_001c4790__FPvP2SOP3BSPT0 = 0x1C4790; // type:func FUN_001c4848 = 0x1C4848; // type:func RenderStepSelf__FP4STEPP2CMP2RO = 0x1C49C8; // type:func ReadStepJoystick__FP4STEPP3JOY = 0x1C49E8; // type:func @@ -4311,17 +4313,17 @@ LoadStepguardPhys__FP9STEPGUARD = 0x1CA8E8; // type:func AddStepguardEffect__FP9STEPGUARD3OID3ZPK = 0x1CA960; // type:func SetStepguardPathzone__FP9STEPGUARD3OID = 0x1CA998; // type:func PsoEnemyStepguard__FP9STEPGUARD = 0x1CAA08; // type:func -FUN_001caad0 = 0x1CAAD0; // type:func +FUN_001caad0__FP2SOPP2SO = 0x1CAAD0; // type:func SetStepguardEnemyObject__FP9STEPGUARDP2SO = 0x1CAB00; // type:func RebindStepguardEnemy__FP9STEPGUARD = 0x1CAB10; // type:func -FUN_001cac28__FP9STEPGUARD = 0x1CAC28; // type:func +FUN_001cac28__FP9STEPGUARDi = 0x1CAC28; // type:func FUN_001cac30 = 0x1CAC30; // type:func AdjustStepguardDz__FP9STEPGUARDiP2DZif = 0x1CACB0; // type:func SetStepguardAttackAngleMax__FP9STEPGUARDf = 0x1CAD28; // type:func AddStepguardAlarm__FP9STEPGUARDP5ALARM = 0x1CAD40; // type:func MatchStepguardAnimationPhase__FP9STEPGUARD3OIDN31 = 0x1CAD60; // type:func AddStepguardCustomXps__FP9STEPGUARDP2SOiP3BSPT3PP2XP = 0x1CAD98; // type:func -FUN_001caee0 = 0x1CAEE0; // type:func +FUN_001caee0__FP9STEPGUARDP2SO = 0x1CAEE0; // type:func UpdateStepguardEffect__FP9STEPGUARD = 0x1CAF38; // type:func SetStepguardPatrolAnimation__FP9STEPGUARDP4ASEG = 0x1CB328; // type:func FInflictStepguardZap__FP9STEPGUARDP2XPP3ZPR = 0x1CB3C0; // type:func @@ -4376,13 +4378,13 @@ JtbsChooseJtHide__FP2JTP2LOP4JTHK = 0x1CDFB8; // type:func MeasureJtJumpToTarget__FP2JTP6VECTORP3ALOT1T1PfT5T1T1 = 0x1CE590; // type:func GetJtRailLanding__FP2JTP4RAILfP6VECTORT3 = 0x1CE800; // type:func GMeasureJumpRail__FP3MJRf = 0x1CE9E8; // type:func -FUN_001cea58 = 0x1CEA58; // type:func +FUN_001cea58__FP3MJH = 0x1CEA58; // type:func GMeasureJumpHshape__FP3MJHf = 0x1CEAB8; // type:func FUN_001ceb18 = 0x1CEB18; // type:func FUN_001cedf8 = 0x1CEDF8; // type:func FUN_001cee30 = 0x1CEE30; // type:func FUN_001ceec8 = 0x1CEEC8; // type:func -FUN_001cf138 = 0x1CF138; // type:func +FUN_001cf138__FP2JTiff = 0x1CF138; // type:func FUN_001cf158 = 0x1CF158; // type:func UpdateJtActiveHide__FP2JTP3JOY = 0x1CFFD0; // type:func MatchJtXmgRail__FP2JTP3XMGP6ACTADJ = 0x1D0B20; // type:func @@ -4427,12 +4429,12 @@ s_mpfspgrfvault = 0x274F38; // size:0x1c // TODO: Mangle the function names. //////////////////////////////////////////////////////////////// func_001D31D0__FP2LOi = 0x1D31D0; // type:func -post_load_steprail = 0x1D3290; // type:func +post_load_steprail__FP3ALO = 0x1D3290; // type:func func_001D32D8__FiP2JTl = 0x1D32D8; // type:func update_steprail = 0x1D3398; // type:func -preset_steprail_accel = 0x1D3470; // type:func -FUN_001d34e0 = 0x1D34E0; // type:func -FUN_001d3500 = 0x1D3500; // type:func +preset_steprail_accel__FP2SOf = 0x1D3470; // type:func +FUN_001d34e0__FPUc = 0x1D34E0; // type:func +FUN_001d3500__FP2SOP3WKR = 0x1D3500; // type:func FUN_001d35a8 = 0x1D35A8; // type:func update_steprail_message = 0x1D3678; // type:func @@ -4554,9 +4556,9 @@ DeleteSw__FP2SW = 0x1DB838; // SetupBulkDataFromBrx__FiP18CBinaryInputStream = 0x1DB928; // type:func LoadBulkDataFromBrx__FP18CBinaryInputStream = 0x1DBA38; // type:func SetSwGravity__FP2SWf = 0x1DBA90; // type:func -FUN_001dbac0 = 0x1DBAC0; // type:func -FUN_001dbae0__FP2SWi = 0x1DBAE0; // type:func -FUN_001dbb00__FP2SWii = 0x1DBB00; // type:func +FUN_001dbac0__FP2SWii = 0x1DBAC0; // type:func +FUN_001dbae0__FP2SWi = 0x1DBAE0; // type:func +FUN_001dbb00__FP2SWii = 0x1DBB00; // type:func FOverflowSwLo__FP2SWP2LOi = 0x1DBB20; // type:func PxaAllocSw__FP2SW = 0x1DBB50; // type:func FreeSwXaList__FP2SWP2XA = 0x1DBB90; // type:func @@ -4593,16 +4595,16 @@ FLevelSwPrimary__FP2SW3WID = 0x1DD6B0; // FLevelSwSecondary__FP2SW3WID = 0x1DD6D0; // type:func FLevelSwTertiary__FP2SW3WID = 0x1DD6F0; // type:func FUN_001dd710 = 0x1DD710; // type:func -FUN_001dd758 = 0x1DD758; // type:func -FUN_001dd7a0 = 0x1DD7A0; // type:func +FUN_001dd758__FP2SWi = 0x1DD758; // type:func +FUN_001dd7a0__FP2SWi = 0x1DD7A0; // type:func FUN_001dd7e8 = 0x1DD7E8; // type:func -FUN_001dd888 = 0x1DD888; // type:func -FUN_001dd8e8__FP2SW9GAMEWORLD = 0x1DD8E8; // type:func -FUN_001dd908__FP2SW9GAMEWORLD = 0x1DD908; // type:func -FUN_001dd928 = 0x1DD928; // type:func -FUN_001dd950 = 0x1DD950; // type:func -FUN_001dd9a0__Ff = 0x1DD9A0; // type:func -FUN_001dd9c0__FPvPf = 0x1DD9C0; // type:func +FUN_001dd888__FP2SW3WIDi = 0x1DD888; // type:func +FUN_001dd8e8__FP2SW9GAMEWORLD = 0x1DD8E8; // type:func +FUN_001dd908__FP2SW9GAMEWORLD = 0x1DD908; // type:func +FUN_001dd928__FP2SW = 0x1DD928; // type:func +FUN_001dd950__FP2SWiiP6VECTOR = 0x1DD950; // type:func +FUN_001dd9a0__Ff = 0x1DD9A0; // type:func +FUN_001dd9c0__FPvPf = 0x1DD9C0; // type:func SetSwPlayerSuck__FP2SWf = 0x1DD9D8; // type:func GetSwPlayerSuck__FP2SWPf = 0x1DDA08; // type:func IncrementSwHandsOff__FP2SW = 0x1DDA20; // type:func @@ -4612,17 +4614,17 @@ IsSwVagPlaying__FP2SWPi = 0x1DDA90; // SetSwDarken__FP2SWf = 0x1DDAB8; // type:func SetSwDarkenSmooth__FP2SWf = 0x1DDAC8; // type:func CancelSwDialogPlaying__FP2SW = 0x1DDAD0; // type:func -FUN_001ddb20 = 0x1DDB20; // type:func -FUN_001ddb58 = 0x1DDB58; // type:func -FUN_001ddbb8 = 0x1DDBB8; // type:func -FUN_001ddbf8 = 0x1DDBF8; // type:func -FUN_001ddc18 = 0x1DDC18; // type:func -FUN_001ddc38 = 0x1DDC38; // type:func -FUN_001ddc40 = 0x1DDC40; // type:func -FUN_001ddc78__FPvi = 0x1DDC78; // type:func -FUN_001ddc90 = 0x1DDC90; // type:func -FUN_001ddcb0 = 0x1DDCB0; // type:func -FUN_001ddcc8 = 0x1DDCC8; // type:func +FUN_001ddb20__FP2SW3PRKi = 0x1DDB20; // type:func +FUN_001ddb58__FP2SW = 0x1DDB58; // type:func +FUN_001ddbb8__FP2SW = 0x1DDBB8; // type:func +FUN_001ddbf8__FP2SWi = 0x1DDBF8; // type:func +FUN_001ddc18__FP2SWP3EXC = 0x1DDC18; // type:func +FUN_001ddc38__FPvT0 = 0x1DDC38; // type:func +FUN_001ddc40__FPv = 0x1DDC40; // type:func +FUN_001ddc78__FPvi = 0x1DDC78; // type:func +FUN_001ddc90__FPvi = 0x1DDC90; // type:func +FUN_001ddcb0__FPvPi = 0x1DDCB0; // type:func +FUN_001ddcc8__FPvPi = 0x1DDCC8; // type:func g_grfdfl = 0x275630; // size:0x10 g_vecHighlight = 0x275640; // size:0x10 @@ -4656,7 +4658,7 @@ MatchTailOtherObject__FP4TAILP3ALO = 0x1DE768; // type:func InitTank__FP4TANK = 0x1DE798; // type:func PostTankLoad__FP4TANK = 0x1DE808; // type:func UpdateTank__FP4TANKf = 0x1DE910; // type:func -FUN_001deb30 = 0x1DEB30; // type:func +FUN_001deb30__FP4TANK = 0x1DEB30; // type:func UseTankCharm__FP4TANK = 0x1DEBB8; // type:func UpdateTankActive__FP4TANKP3JOYf = 0x1DEBE8; // type:func OnTankActive__FP4TANKiP2PO = 0x1DF290; // type:func @@ -4751,7 +4753,7 @@ UpdateTnCallback__FP2TN5MSGIDPv = 0x1E2870; // type:f UpdateTn__FP2TNf = 0x1E2940; // type:func RenderTnSelf__FP2TNP2CMP2RO = 0x1E2988; // type:func FreezeTn__FP2TNi = 0x1E29A8; // type:func -FUN_001e29e8 = 0x1E29E8; // type:func +FUN_001e29e8__FP2TNf = 0x1E29E8; // type:func CalculateTnCrv__FP2TNP6VECTORN21 = 0x1E2A00; // type:func CalculateTnPos__FP2TNP6VECTORffP3CLQP2LM4FTNDT1 = 0x1E2BF0; // type:func ActivateCptn__FP4CPTNPv = 0x1E2E68; // type:func @@ -4761,7 +4763,7 @@ RevokeCptn__FP4CPTNPv = 0x1E30E0; // type:f FUN_001e30e8 = 0x1E30E8; // type:func UpdateCptn__FP4CPTNP6CPDEFIP3JOYf = 0x1E31F0; // type:func FUN_001e4578 = 0x1E4578; // type:func -FUN_001e4880 = 0x1E4880; // type:func +FUN_001e4880__FiiiPv = 0x1E4880; // type:func FUN_001e4888 = 0x1E4888; // type:func LoadTbspFromBrx__FP18CBinaryInputStreamPiPP5TSURFT1PP4TBSP = 0x1E4C48; // type:func FCheckTbspPoint__FP4TBSPP6VECTOR = 0x1E4DC0; // type:func @@ -4796,7 +4798,7 @@ HandleTurretMessage__FP6TURRET5MSGIDPv = 0x1E5CE8; // type:func FIgnoreTurretIntersection__FP6TURRETP2SO = 0x1E5DA8; // type:func CollectTurretPrize__FP6TURRET3PCKP3ALO = 0x1E5E08; // type:func GetTurretDiapi__FP6TURRETP6DIALOGP5DIAPI = 0x1E5E50; // type:func -FUN_001e5e60 = 0x1E5E60; // type:func +FUN_001e5e60__Fi = 0x1E5E60; // type:func //////////////////////////////////////////////////////////////// @@ -5024,7 +5026,7 @@ g_pwipe = 0x275f84; //////////////////////////////////////////////////////////////// // P2/wm.c //////////////////////////////////////////////////////////////// -FUN_001f0468 = 0x1F0468; // type:func +FUN_001f0468__Fv = 0x1F0468; // type:func FUN_001f0490 = 0x1F0490; // type:func FUN_001f0580 = 0x1F0580; // type:func PostWmLoad__FP2WM = 0x1F0660; // type:func diff --git a/include/alo.h b/include/alo.h index 1e39bcaf4..202492977 100644 --- a/include/alo.h +++ b/include/alo.h @@ -281,7 +281,7 @@ void UpdateAlo(ALO *palo, float dt); void InvalidateAloLighting(ALO *palo); -void UpdateAloXfWorld__FP3ALO(ALO * palo); +void UpdateAloXfWorld(ALO *palo); void UpdateAloXfWorldHierarchy(ALO *palo); diff --git a/include/binoc.h b/include/binoc.h index b4a448008..d88ba8a9a 100644 --- a/include/binoc.h +++ b/include/binoc.h @@ -157,4 +157,6 @@ class CTextBox enum JV m_jv; // Vertical text justification; }; +extern "C" void open_close_binoc(BINOC *pbinoc, int state); + #endif /* BINOC_H */ diff --git a/include/blip.h b/include/blip.h index 875991e4f..f244879d2 100644 --- a/include/blip.h +++ b/include/blip.h @@ -20,11 +20,13 @@ struct RPL; typedef int GRFZON; /** + * @brief 128-bit VU scalar (the value lives in the x lane), 16-byte aligned. + * Passed by value in a single 128-bit GP register and stored with sq. * @todo Move elsewhere? */ struct VU_FLOAT { - uint16_t data; + qword data; }; /** diff --git a/include/bsp.h b/include/bsp.h index 212213965..a4167bbf5 100644 --- a/include/bsp.h +++ b/include/bsp.h @@ -75,8 +75,8 @@ struct VBSP */ struct LSG { - VECTOR apos[2]; - VECTOR anormal[2]; + VECTOR4 apos[2]; + VECTOR4 anormal[2]; float au[2]; LSGK lsgk; undefined4 unk1; @@ -84,7 +84,7 @@ struct LSG EDGE *pedge; int iiposSwap; LSG *plsgNext; -}; +} __attribute__((aligned(16))); /** * @brief Unknown. diff --git a/include/cm.h b/include/cm.h index b1248574e..80d235984 100644 --- a/include/cm.h +++ b/include/cm.h @@ -553,4 +553,11 @@ extern int g_rgbaFog; //Just to get the code matching -Kestin // extern float D_0026198c; // extern CM* g_pcm; +void ResetCmLookAtSmooth(CM *pcm, void *pv); + +void SetupCmRotateToCam(CM *pcm); +void SetCmLookAtSmooth(CM *pcm, int a1, VECTOR *pposEye, VECTOR *pposCenter, int a4, float u0, float u1, float u2, float u3, float u4, float u5); +void ConvertCylindToWorldVelocity(void *a, void *b, void *c, float f0, float f1, float f2); +void ConvertWorldToCylindVelocity(void *a, void *b, void *c, void *d, void *e, void *f); + #endif // CM_H diff --git a/include/cplcy.h b/include/cplcy.h index e2683e1ec..4cd455e4a 100644 --- a/include/cplcy.h +++ b/include/cplcy.h @@ -17,4 +17,6 @@ LOOKK LookkPopCplook(CPLOOK *pcplook); LOOKK LookkCurCplook(CPLOOK *pcplook); +int FActiveCplcy(CPLCY *pcplcy); + #endif // CPLCY_H diff --git a/include/crusher.h b/include/crusher.h index 874c9e5f2..d84fd1d4b 100644 --- a/include/crusher.h +++ b/include/crusher.h @@ -73,4 +73,10 @@ void InitCrbrain(CRBRAIN *pcrbrain); // TODO: Add unknown functions here. +extern "C" void FUN_0014c5e8(void *p); + +extern "C" void FUN_0014c858(void *p); + +extern "C" void FUN_0014cba8(void *p); + #endif // CRUSHER_H diff --git a/include/font.h b/include/font.h index ecdd854e7..c3fcc9aa6 100644 --- a/include/font.h +++ b/include/font.h @@ -124,6 +124,10 @@ extern CFont *g_pfont; void StartupFont(); +CFont *FUN_0015c1c0(int i); + +int FUN_0015c188(int i); + void PostFontsLoad(); #endif // FONT_H diff --git a/include/frm.h b/include/frm.h index bde0c20bc..9da8fb0e2 100644 --- a/include/frm.h +++ b/include/frm.h @@ -63,4 +63,6 @@ extern FRM *g_pfrmOpen; extern uchar g_abRenderLoopStack[0x20000]; // TODO: Move elsewhere? +extern "C" void func_0015F618(int, int); + #endif // FRM_H diff --git a/include/game.h b/include/game.h index ac75bf859..579b7e97b 100644 --- a/include/game.h +++ b/include/game.h @@ -251,7 +251,7 @@ void StartupGame(); // LevelLoadData * search_level_by_load_data(LevelLoadData *search_level); -// LevelLoadData * search_level_by_id(int search_id); +extern "C" LevelLoadData *search_level_by_id(int search_id); /** * @brief Gets the friendly name of a level from its world ID. @@ -401,7 +401,7 @@ bool FCharmAvailable(); * @param pls Pointer to level state. * @param param_2 OID of the dialog. */ -//int PfLookupDialog(LS *pls, OID oidDialog); +int *PfLookupDialog(LS *pls, OID oidDialog); /** * @brief Clears 8 bytes of memory. diff --git a/include/glbs.h b/include/glbs.h index 2b000f785..0d9cb568a 100644 --- a/include/glbs.h +++ b/include/glbs.h @@ -13,6 +13,7 @@ // Forward. struct UV; +struct UVF; /** * @brief (?) kind. @@ -92,9 +93,9 @@ struct GLBS void SetNormal(VECTOR *ppos); // Might be SetPos? - void SetRgba(RGBA &rgba); // Might not be correct. + void SetRgba(RGBA *prgba); - void SetUv(UV *puv); + void SetUv(UVF *puv); void SetVtx(int fAdc); }; diff --git a/include/gomer.h b/include/gomer.h index cf78e7102..029d72096 100644 --- a/include/gomer.h +++ b/include/gomer.h @@ -29,4 +29,6 @@ struct GOMER : public STEPGUARD /* 0xc40 */ int fAbandonExternal; }; +void PostGomerLoad(GOMER *pgomer); + #endif // GOMER_H diff --git a/include/gs.h b/include/gs.h index dd3f975a3..908f48dda 100644 --- a/include/gs.h +++ b/include/gs.h @@ -55,4 +55,10 @@ void ClearFrameBuffers(); void UploadBitmaps(GRFZON grfzon, GSB *pgsb); +struct GIFS; + +int FBuildUploadBitmapGifs(GRFZON grfzon, GSB *pgsb, GIFS *pgifs); + +void PropagateSurs(); + #endif // GS_H diff --git a/include/hide.h b/include/hide.h index 9f32c925d..3b33b77a0 100644 --- a/include/hide.h +++ b/include/hide.h @@ -6,8 +6,19 @@ #include "common.h" +/** + * @todo Implement the HPNT and HSHAPE structs. + */ +struct HPNT; +struct HSHAPE; +struct VECTOR; + // ... void StartupHide(); +void GetHshapeHidePos(HSHAPE *phshape, float s, VECTOR *ppos, float *pf); + +void GetHpntClosestHidePos(HPNT *phpnt, VECTOR *ppos, float *pf); + #endif // HIDE_H diff --git a/include/jp.h b/include/jp.h new file mode 100644 index 000000000..f5587359b --- /dev/null +++ b/include/jp.h @@ -0,0 +1,14 @@ +/** + * @file jp.h + */ +#ifndef JP_H +#define JP_H + +#include "common.h" + +struct JT; +struct LOCKG; + +extern "C" void func_001781E0(JT *pjt, LOCKG *plockg); + +#endif // JP_H diff --git a/include/jt.h b/include/jt.h index 054703160..5f644a51c 100644 --- a/include/jt.h +++ b/include/jt.h @@ -78,7 +78,6 @@ enum JTBS JTBS_Zap_Electric = 34, JTBS_Zap_Fire = 35, JTBS_Zap_Water = 36, - // ... JTBS_Unk_54 = 54, JTBS_Unk_55 = 55 @@ -103,7 +102,6 @@ enum JTHS */ enum JTCS { - // ... }; /** @@ -145,14 +143,14 @@ struct JT : public STEP STRUCT_PADDING(930); undefined2 padding0_extra; - ALO *paloMine_0x1518; // 0x1518 + ALO *paloMine_0x1518; STRUCT_PADDING(832); undefined2 padding1_extra; - JTS jts; // 0x2220 + JTS jts; int unk_0x2224; - JTBS jtbs; // 0x2228 + JTBS jtbs; STRUCT_PADDING(328); undefined1 padding2_extra; @@ -179,6 +177,11 @@ void SetJtJts(JT *pjt, JTS jts, JTBS jtbs); */ void ProfileJt(JT *pjt, int fProfile); +struct XMG; +struct ACTADJ; + +int FMatchJtXmg(JT *pjt, XMG *pxmg, ACTADJ *pactadj); + extern JT *g_pjt; #endif // JT_H diff --git a/include/mat.h b/include/mat.h index d81d1b476..fda92f316 100644 --- a/include/mat.h +++ b/include/mat.h @@ -14,6 +14,8 @@ struct MATRIX4 { float mat[4][4]; + + void PostCopyMatrix3(); }; /** @@ -25,7 +27,6 @@ struct MATRIX3 float mat[3][3]; }; -void PostCopyMatrix3(MATRIX4 *pmat); MATRIX3 *MatMulMatTransMat(MATRIX3 *matLeft, MATRIX3 *matRight); diff --git a/include/mpeg.h b/include/mpeg.h index 8435d3db0..cdd3e1a94 100644 --- a/include/mpeg.h +++ b/include/mpeg.h @@ -22,10 +22,16 @@ class CMpeg void Start(CBinaryAsyncStream *pbas); void Update(); void Finish(); + void CbDemuxed(int nParam); }; void StartupMpeg(); extern CMpeg g_mpeg; +extern "C" void FUN_0018f0e8(CMpeg *pmpeg, void *pv); + +extern "C" int FAccept__10CMpegAudioiPUc(void *pmpega, int cb, uchar *pb); + + #endif // MPEG_H diff --git a/include/path.h b/include/path.h index e3366aa0b..f19dba355 100644 --- a/include/path.h +++ b/include/path.h @@ -6,6 +6,11 @@ #include "common.h" -// ... +struct CG; +struct VECTOR; + +int CposFindPath(CG *pcg, VECTOR *pvec0, VECTOR *pvec1, int n, VECTOR *pvec2); + +void FindClosestPointInCg(CG *pcg, VECTOR *pvec0, VECTOR *pvec1); #endif // PATH_H diff --git a/include/pipe.h b/include/pipe.h index 691192827..fcffc3ed6 100644 --- a/include/pipe.h +++ b/include/pipe.h @@ -6,6 +6,7 @@ #include "common.h" #include +#include /** * @class PIPE @@ -16,7 +17,12 @@ struct PIPE : public LO { /* 0x34 */ undefined4 unk; /* 0x38 */ DLE dlePipe; - /* 0x40 */ STRUCT_PADDING(9); + /* 0x40 */ VU_VECTOR normal; // TODO: Verify name. + /* 0x50 */ int unk_0x50; + /* 0x54 */ int unk_0x54; + /* 0x58 */ int unk_0x58; + /* 0x5C */ float unk_0x5c; + /* 0x60 */ STRUCT_PADDING(1); /* 0x64 */ OID oid; // TODO: Verify name. /* 0x68 */ LO *plo; // TODO: Verify type and name. }; diff --git a/include/puffer.h b/include/puffer.h index 23e6b4c27..0b23ef9fa 100644 --- a/include/puffer.h +++ b/include/puffer.h @@ -96,4 +96,6 @@ int FCanPuffcAttack(PUFFC *ppuffc); void PostPuffbLoad(PUFFB *ppuffb); +extern "C" void FUN_001973d8(void *p); + #endif // PUFFER_H diff --git a/include/rumble.h b/include/rumble.h index f9a8bffa7..4906fa5ef 100644 --- a/include/rumble.h +++ b/include/rumble.h @@ -88,6 +88,8 @@ void TriggerRumbleRumk(RUMBLE *prumble, RUMK rumk, float dt); void SetRumbleRums(RUMBLE *prumble, RUMS rums); +void TriggerRumbleRumpat(RUMBLE *prumble, RUMPAT *prumpat, float dt); + void StopRumbleActuators(RUMBLE *prumble); #endif // RUMBLE_H diff --git a/include/rwm.h b/include/rwm.h index 63f7fa0a1..af03d5ac1 100644 --- a/include/rwm.h +++ b/include/rwm.h @@ -94,4 +94,6 @@ void GetRwacPan(RWAC *prwac, float *pradPan); void GetRwacTilt(RWAC *prwac, float *pradTilt); +extern "C" void FUN_001a93c8(RWM *prwm); + #endif // RWM_H diff --git a/include/sce/libs.h b/include/sce/libs.h new file mode 100644 index 000000000..66a236fdd --- /dev/null +++ b/include/sce/libs.h @@ -0,0 +1,13 @@ +/** + * @file sce/libs.h + * + * @brief Declarations for SDK library functions (asm/sce/libs.s). + */ +#ifndef SCE_LIBS_H +#define SCE_LIBS_H + +extern "C" int func_00202120(); +extern "C" void func_00202058(int); +extern "C" void *memmove(void *dst, const void *src, int cb); + +#endif // SCE_LIBS_H diff --git a/include/screen.h b/include/screen.h index 91bd34a19..f29ef76a0 100644 --- a/include/screen.h +++ b/include/screen.h @@ -387,4 +387,8 @@ void UpdateAttract(ATTRACT *pattract); void DrawLineScreen(uint x1, uint y1, uint z1, uint x2, uint y2, uint z2, RGBA *rgba, int fDepthTest); +extern "C" char FUN_001aea08(void); + +extern "C" void FUN_001aea70(int, int); + #endif // SCREEN_H diff --git a/include/sensor.h b/include/sensor.h index 72113037a..953be25ce 100644 --- a/include/sensor.h +++ b/include/sensor.h @@ -65,13 +65,10 @@ struct SENSOR : public SO STRUCT_PADDING(2); /* 0x564 */ uint ctriggerObjects; // Current count of trigger object IDs. /* 0x568 */ OID atriggerObjects[4]; // Array of trigger object IDs. - STRUCT_PADDING(4); /* 0x578 */ uint cnoTriggerObjects; // Current count of no-trigger object IDs. /* 0x57C */ OID anoTriggerObjects[4]; // Array of no-trigger object IDs. - STRUCT_PADDING(4); /* 0x58c */ uint ctriggerClasses; // Current count of trigger class IDs. /* 0x590 */ CID atriggerClasses[4]; // Array of trigger class IDs. - STRUCT_PADDING(4); /* 0x5a0 */ uint cnoTriggerClasses; // Current count of no-trigger class IDs. /* 0x5a4 */ CID anoTriggerClasses[4]; // Array of no-trigger class IDs. }; diff --git a/include/so.h b/include/so.h index af990d88a..9df8b7d4f 100644 --- a/include/so.h +++ b/include/so.h @@ -17,7 +17,6 @@ #include #include -// Forward. class CBinaryInputStream; struct XA; struct XP; @@ -25,7 +24,13 @@ struct RO; struct WKR; struct ZPR; struct WATER; -struct CNSTR; +/** + * @brief Constraint kind, an index into the s_acnstre table (see + * ConstrFromCnstr); each entry resolves to a CT and a normal vector. + */ +enum CNSTR +{ +}; struct CONSTR; struct SURFX; @@ -37,7 +42,6 @@ typedef int GRFFSO; */ enum EGK { - // ... }; /** @@ -162,7 +166,7 @@ void SetSoMass(SO *pso, float m); void AdjustSoMomint(SO *pso, float r); -void DiscardSoXps(SO *pso); +void DiscardSoXps(SO *pso, int mode); void UpdateSoPosWorldPrev(SO *pso); @@ -286,4 +290,6 @@ int FAbsorbSoWkr(SO *pso, WKR *pwkr); void CloneSoPhys(SO *pso, SO *psoPhys, int cposExtra); +void FUN_001bc4d8(uint8_t *param_1, uint8_t *param_2); + #endif // SO_H diff --git a/include/sound.h b/include/sound.h index 53988ff92..30a47ad3f 100644 --- a/include/sound.h +++ b/include/sound.h @@ -209,11 +209,26 @@ int FVagPlaying(); */ int SetVagUnpaused(); +/** + * @brief Stop the currently playing VAG. + */ +void StopVag(); + /** * @brief Unknown. */ void UnsetExcitement(EXC *pexc); +/** + * @brief Unknown. + */ +void UnsetExcitementHyst(EXC *pexc); + +/** + * @brief Unknown. + */ +EXC *PexcSetExcitement(int gexc); + /** * @brief Unknown. */ @@ -256,6 +271,11 @@ void StartSound(SFXID sfxid, AMB **ppamb, ALO *palo, VECTOR *ppos, float sStart, */ void StopSound(AMB *pamb, int msRampdown); +// The symbol's GCC2 mangling says (int, unsigned char), but the ROM call +// sites pass the second argument as a plain word with no narrowing, so the +// in-game declaration must have taken ints; bind by literal symbol name. +void SetAMRegister(int n, int bReg); + /** * @brief TODO */ @@ -314,4 +334,6 @@ int GetAMRegister(int reg); */ void UpdateAMRegister(int reg, int value); +extern "C" void PreloadVag1(void *pv); + #endif // SOUND_H diff --git a/include/splice/bif.h b/include/splice/bif.h index b0b1bf065..92f370de3 100644 --- a/include/splice/bif.h +++ b/include/splice/bif.h @@ -17,6 +17,12 @@ class CFrame; */ enum BIFK { + // ... + BIFK_SetCar = 35, + BIFK_SetCdr = 36, + // ... + BIFK_HitTestObjects = 113, + BIFK_HitTestObjectsFirst = 114, // ... BIFK_AddO = 99, BIFK_EnsureO = 100, diff --git a/include/splice/eval.h b/include/splice/eval.h index 12f128066..881679549 100644 --- a/include/splice/eval.h +++ b/include/splice/eval.h @@ -6,6 +6,13 @@ #include "common.h" +// Forward. +class CRef; +class CPair; +class CFrame; + +CRef RefEvalSymbol(CPair *ppair, CFrame *pframe); + // ... #endif // SPLICE_EVAL_H diff --git a/include/splice/frame.h b/include/splice/frame.h index 249b2b5ff..24c7c4d15 100644 --- a/include/splice/frame.h +++ b/include/splice/frame.h @@ -19,10 +19,10 @@ class CFrame public: void SetSingleParent(CFrame *pframeParent); void AddParent(CFrame *pframeParent); - CFrame *RefAddBinding(int symid, CRef * pref); - CFrame *RefSetBinding(int symid, CRef *pref); - int FFindBinding(int symid, int fRecursive, CRef *pref); - CRef *PrefFindBinding(int symid, int fRecursive); + CRef RefAddBinding(uint symid, CRef *pref); + CRef RefSetBinding(uint symid, CRef *pref); + int FFindBinding(uint symid, int fRecursive, CRef *pref); + CRef *PrefFindBinding(uint symid, int fRecursive); void CloneTo(CFrame *pframeClone); }; diff --git a/include/splice/ref.h b/include/splice/ref.h index f13bfa4a8..4c0fde8bc 100644 --- a/include/splice/ref.h +++ b/include/splice/ref.h @@ -102,8 +102,8 @@ class CRef void SetSmp(SMP *psmp); void SetBasic(BASIC *pbasic); void SetMethod(CMethod *pmethod); - int RefCoerceS32() const; - float RefCoerceF32() const; + CRef RefCoerceS32(); + CRef RefCoerceF32(); }; #endif // SPLICE_REF_H diff --git a/include/splice/sidebag.h b/include/splice/sidebag.h index 858d3469d..a806c91b5 100644 --- a/include/splice/sidebag.h +++ b/include/splice/sidebag.h @@ -30,9 +30,9 @@ class CSidebag SBB m_asbb[16]; public: - CSidebag& RefAddBinding(int n, CRef *pref); + CRef RefAddBinding(int n, CRef *pref); - CSidebag& RefSetBinding(int n, CRef *pref); + CRef RefSetBinding(int n, CRef *pref); bool FFindBinding(int n, CRef *pref); diff --git a/include/splice/splotheap.h b/include/splice/splotheap.h index 886232611..92f7314ff 100644 --- a/include/splice/splotheap.h +++ b/include/splice/splotheap.h @@ -43,6 +43,12 @@ extern CSplotheap g_splotheapUnk1; extern CSplotheap g_splotheapProc; extern CSplotheap g_splotheapMethod; +// Sidebag binding-node helpers: allocate a node {int n; CRef ref; pNext} +// from g_splotheapUnk1, and recursively clone a node list. +class CFrame; +void *FUN_0011C498(); +void FUN_0011C418(void *psbbFrom, void *psbbTo, CFrame *pframe); + static void *PvFromPsplot(SPLOT *psplot); static SPLOT *PsplotFromPv(void *pv); bool FIsPvGarbage(void *pv); diff --git a/include/splice/vecmat.h b/include/splice/vecmat.h index 4b473f367..06fc13e85 100644 --- a/include/splice/vecmat.h +++ b/include/splice/vecmat.h @@ -11,6 +11,8 @@ VECTOR *PvectorNew(); +MATRIX4 *PmatrixNew(); + void IncrefVector(VECTOR *pvector); void DecrefVector(VECTOR *pvector); diff --git a/include/stepguard.h b/include/stepguard.h index 971c996e5..34c591c4f 100644 --- a/include/stepguard.h +++ b/include/stepguard.h @@ -260,6 +260,8 @@ void SetSggSggs(SGG *psgg, SGGS sggs); void AssignSggSearchPoints(SGG *psgg); +struct PUFFC; +extern "C" void FUN_001c8920(PUFFC *ppuffc); /** * @brief Checks the struct has a 0 on an address, no idea what it means. * @todo Figure out what this actually does and give it a better name. diff --git a/include/stepzap.h b/include/stepzap.h index 45c4afa86..0c4486f4b 100644 --- a/include/stepzap.h +++ b/include/stepzap.h @@ -8,4 +8,6 @@ // ... +extern "C" void FUN_001d4c98(JT *pjt); + #endif // STEPZAP_H diff --git a/include/sw.h b/include/sw.h index 20f1900d5..f97510f68 100644 --- a/include/sw.h +++ b/include/sw.h @@ -111,6 +111,12 @@ extern SW *g_psw; void InitSwDlHash(SW *psw); +void FUN_001ddb58(SW *psw); + +void FUN_001ddbb8(SW *psw); + +void FUN_001ddc38(void *pv, void *pvBlot); + void InitSw(SW *psw); void DeleteSw(SW *psw); diff --git a/include/text.h b/include/text.h index 4180ebd58..6132bd667 100644 --- a/include/text.h +++ b/include/text.h @@ -156,4 +156,6 @@ extern "C" void UpperizePchz(char *pchz); +extern "C" char *strcpy1(char *pchzDst, char *pchzSrc); + #endif // TEXT_H diff --git a/include/vec.h b/include/vec.h index cd50c93fb..7d00aa9a3 100644 --- a/include/vec.h +++ b/include/vec.h @@ -9,6 +9,7 @@ #include "common.h" struct SO; +struct VU_VECTOR; /** * @brief Vector3 with X, Y, and Z @@ -17,6 +18,8 @@ struct SO; struct VECTOR { float x, y, z; + + VECTOR &operator=(VU_VECTOR vuvec); }; struct VECTOR4 @@ -25,13 +28,27 @@ struct VECTOR4 }; /** - * @todo Should be 16-byte aligned. + * @brief 128-bit VU quadword vector (x, y, z, w), 16-byte aligned. Passed by + * value in a single 128-bit GP register and loaded/stored with lq/sq. */ struct VU_VECTOR { - ushort data; + qword data; + + VU_VECTOR() {} + VU_VECTOR(const VECTOR &vec); }; +/** + * @brief Unit Z-axis normal (0, 0, 1). + */ +extern VECTOR g_normalZ; + +/** + * @brief Zero vector constant (16 zero bytes; also read as a VU_VECTOR qword). + */ +extern VECTOR D_00248D30; + /** * @brief Sets the coordinates of a vector using cylindrical coordinates. * diff --git a/include/water.h b/include/water.h index 01602d746..abcc361f4 100644 --- a/include/water.h +++ b/include/water.h @@ -25,7 +25,9 @@ struct WATER : public SO { /* 0x550 */ XA *pxaFirst; /* 0x554 */ MRG mrg; - STRUCT_PADDING(8); // 0x564 .. 0x584 + STRUCT_PADDING(3); // 0x564 .. 0x570 + /* 0x570 */ VU_VECTOR vecCurrent; + STRUCT_PADDING(1); // 0x580 .. 0x584 /* 0x584 */ int unk_0x584; /* 0x588 */ int unk_0x588; STRUCT_PADDING(1); // 0x58c .. 0x590 diff --git a/src/P2/ac.c b/src/P2/ac.c index b32b5d765..84f59d554 100644 --- a/src/P2/ac.c +++ b/src/P2/ac.c @@ -1,4 +1,6 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/ac", FindKey__FfiiiPcPfT5PPv); @@ -67,19 +69,58 @@ INCLUDE_ASM("asm/nonmatchings/P2/ac", LoadAcgbFromBrx__FP4ACGBP18CBinaryInputStr INCLUDE_ASM("asm/nonmatchings/P2/ac", EvaluateAcgb__FP4ACGBP3ALOffiPfT5); -INCLUDE_ASM("asm/nonmatchings/P2/ac", GetAcgbTimes__FP4ACGBPiPPf); +void GetAcgbTimes(ACGB *pacgb, int *pct, float **pat) +{ + int cct = STRUCT_OFFSET(pacgb, 0x8, int); + *pct = cct; + if (pat) + { + int i; + *pat = (float *)PvAllocStackImpl(cct << 2); + for (i = 0; i < *pct; i++) + { + (*pat)[i] = *(float *)((char *)STRUCT_OFFSET(pacgb, 0xC, void *) + i * 0x18); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/ac", LoadAcgbwFromBrx__FP5ACGBWP18CBinaryInputStream); INCLUDE_ASM("asm/nonmatchings/P2/ac", EvaluateAcgbw__FP5ACGBWP3ALOffiPfT5); -INCLUDE_ASM("asm/nonmatchings/P2/ac", GetAcgbwTimes__FP5ACGBWPiPPf); +void GetAcgbwTimes(ACGBW *pacgbw, int *pct, float **pat) +{ + int cct = STRUCT_OFFSET(pacgbw, 0x8, int); + *pct = cct; + if (pat) + { + int i; + *pat = (float *)PvAllocStackImpl(cct << 2); + for (i = 0; i < *pct; i++) + { + (*pat)[i] = *(float *)((char *)STRUCT_OFFSET(pacgbw, 0xC, void *) + i * 0x20); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/ac", EvaluateAcgl__FP4ACGLP3ALOffiPfT5); INCLUDE_ASM("asm/nonmatchings/P2/ac", LoadAcglFromBrx__FP4ACGLP18CBinaryInputStream); -INCLUDE_ASM("asm/nonmatchings/P2/ac", GetAcglTimes__FP4ACGLPiPPf); +void GetAcglTimes(ACGL *pacgl, int *pct, float **pat) +{ + int i; + + *pct = STRUCT_OFFSET(pacgl, 0x8, int); + if (pat) + { + *pat = (float *)PvAllocStackImpl(*pct * 4); + for (i = 0; i < *pct; i++) + { + (*pat)[i] = *(float *)((char *)STRUCT_OFFSET(pacgl, 0xc, char *) + i * 8); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/ac", EvaluateApacg__FPP3ACGP3ALOffiP6VECTORN25); @@ -87,13 +128,39 @@ INCLUDE_ASM("asm/nonmatchings/P2/ac", LoadApacgFromBrx__FPP3ACGP6VECTORP18CBinar INCLUDE_ASM("asm/nonmatchings/P2/ac", GetApacgTimes__FPP3ACGPiPPf); -INCLUDE_ASM("asm/nonmatchings/P2/ac", EvaluateAkvb__FiP3KVBffiP6VECTORT5); +void EvaluateAkvb(int ckvb, KVB *akvb, float t, float svt, GRFEVAL grfeval, VECTOR *pvec, VECTOR *pdvec) +{ + float dt; + float dtSeg; + void *pkey; + + FindKey(t, grfeval, 0x40, ckvb, (char *)akvb, &dt, &dtSeg, &pkey); + EvaluateBezierPos(dtSeg, dt, svt, + (VECTOR *)((char *)pkey + 0x10), + (VECTOR *)((char *)pkey + 0x30), + (VECTOR *)((char *)pkey + 0x50), + (VECTOR *)((char *)pkey + 0x60), + pvec, pdvec, NULL); +} INCLUDE_ASM("asm/nonmatchings/P2/ac", LoadAkvbFromBrx__FPiPP3KVBP18CBinaryInputStream); INCLUDE_ASM("asm/nonmatchings/P2/ac", GetAkvbTimes__FiP3KVBPiPPf); -INCLUDE_ASM("asm/nonmatchings/P2/ac", EvaluateAcpc__FP4ACPCP3ALOffiP6VECTORT5); +void EvaluateAcpc(ACPC *pacpc, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *ppos, VECTOR *pv) +{ + EvaluateApacg(&STRUCT_OFFSET(pacpc, 0x20, ACG *), palo, t, svt, grfeval, &STRUCT_OFFSET(pacpc, 0x10, VECTOR), ppos, pv); + + if (palo) + { + void (*pfn)(ALO *, VECTOR *, VECTOR *) = + *(void (**)(ALO *, VECTOR *, VECTOR *))((char *)palo->pvtlo + 0xB0); + if (pfn) + { + pfn(palo, ppos, pv); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/ac", LoadAcpcFromBrx__FP4ACPCP18CBinaryInputStream); @@ -102,7 +169,21 @@ void GetAcpcTimes(ACPC *pacpc, int *pct, float **pat) GetApacgTimes(&STRUCT_OFFSET(pacpc, 0x20, ACG *), pct, pat); // pacpc->apacg } -INCLUDE_ASM("asm/nonmatchings/P2/ac", EvaluateAcpb__FP4ACPBP3ALOffiP6VECTORT5); +void EvaluateAcpb(ACPB *pacpb, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *ppos, VECTOR *pv) +{ + // pacpb->ckvb, pacpb->akvb + EvaluateAkvb(STRUCT_OFFSET(pacpb, 0xc, int), STRUCT_OFFSET(pacpb, 0x10, KVB *), t, svt, grfeval, ppos, pv); + + if (palo) + { + void (*pfn)(ALO *, VECTOR *, VECTOR *) = + *(void (**)(ALO *, VECTOR *, VECTOR *))((char *)palo->pvtlo + 0xB0); + if (pfn) + { + pfn(palo, ppos, pv); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/ac", LoadAcpbFromBrx__FP4ACPBP18CBinaryInputStream); @@ -184,6 +265,34 @@ INCLUDE_ASM("asm/nonmatchings/P2/ac", PacpNew__F4ACVK); INCLUDE_ASM("asm/nonmatchings/P2/ac", PacrNew__F4ACVK); -INCLUDE_ASM("asm/nonmatchings/P2/ac", PacsNew__F4ACVK); +extern void *D_00219718; +extern void *D_00219728; + +ACS *PacsNew(ACVK acvk) +{ + void *pacs; + + switch (acvk) + { + case ACVK_Component: + pacs = PvAllocSwClearImpl(0x30); + STRUCT_OFFSET(pacs, 0x0, void *) = &D_00219718; + break; + case ACVK_Bezier: + pacs = PvAllocSwClearImpl(0x10); + STRUCT_OFFSET(pacs, 0x0, void *) = &D_00219728; + break; + default: + pacs = NULL; + break; + } + + if (pacs) + { + STRUCT_OFFSET(pacs, 0x4, ACVK) = acvk; + } + + return (ACS *)pacs; +} INCLUDE_ASM("asm/nonmatchings/P2/ac", PacgNew__F4ACGK); diff --git a/src/P2/act.c b/src/P2/act.c index c5a0b97ff..7a4893cb6 100644 --- a/src/P2/act.c +++ b/src/P2/act.c @@ -1,14 +1,89 @@ #include +#include +#include +#include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/act", PactNew__FP2SWP3ALOP5VTACT); +ACT *PactNew(SW *psw, ALO *palo, VTACT *pvtact) +{ + ACT *pact = (ACT *)PvAllocSlotheapClearImpl((SLOTHEAP *)((uint8_t *)psw + 0x1B20)); + pact->pvtact = pvtact; + (*(void (**)(ACT *, ALO *))pvtact)(pact, palo); + return pact; +} -INCLUDE_ASM("asm/nonmatchings/P2/act", PactNewClone__FP3ACTP2SWP3ALO); +extern VTACT g_vtact; + +ACT *PactNewClone(ACT *pactBase, SW *psw, ALO *palo) +{ + ACT *pact = PactNew(psw, palo, &g_vtact); + (*(void (**)(ACT *, ACT *))((uint8_t *)pact->pvtact + 4))(pact, pactBase); + return pact; +} -INCLUDE_ASM("asm/nonmatchings/P2/act", CloneAct__FP3ACTT0); +void CloneAct(ACT *pact, ACT *pactBase) +{ + DLE dleSav = pact->dleAlo; + ALO *paloSav = pact->palo; + CopyAb(pact, pactBase, STRUCT_OFFSET(g_psw, 0x1B20, int)); + pact->dleAlo = dleSav; + pact->palo = paloSav; +} -INCLUDE_ASM("asm/nonmatchings/P2/act", InitAct__FP3ACTP3ALO); +void InitAct(ACT *pact, ALO *palo) +{ + int du = -1; + STRUCT_OFFSET(pact, 0x12, char) = du; + pact->palo = palo; + STRUCT_OFFSET(pact, 0x13, char) = -1; + STRUCT_OFFSET(pact, 0x11, char) = du; + STRUCT_OFFSET(pact, 0x10, char) = du; +} -INCLUDE_ASM("asm/nonmatchings/P2/act", RetractAct__FP3ACTi); +void RetractAct(ACT *pact, GRFRA grfra) +{ + VECTOR v; + ALO *palo = pact->palo; + ACT *pactPos; + ACT *pactRot; + + RemoveDlEntry((DL *)((uint8_t *)palo + 0x1E0), pact); + + pactPos = STRUCT_OFFSET(palo, 0x1EC, ACT *); + pactRot = STRUCT_OFFSET(palo, 0x1F0, ACT *); + (*(void (**)(ALO *))((char *)palo->pvtlo + 0xBC))(palo); + + if (pact == pactPos && STRUCT_OFFSET(palo, 0x1EC, int) == 0 && (grfra & 1)) + { + if (palo->pvtlo->grfcid & 2) + { + ApplySoConstraintLocal((SO *)palo, (CONSTR *)((uint8_t *)palo + 0x440), + (VECTOR *)((uint8_t *)palo + 0x150), &v, NULL); + (*(void (**)(ALO *, VECTOR *))((char *)palo->pvtlo + 0x90))(palo, &v); + } + else + { + SetAloVelocityVec(palo, &D_00248D30); + } + } + + if (pact == pactRot && STRUCT_OFFSET(palo, 0x1F0, int) == 0 && (grfra & 2)) + { + if (palo->pvtlo->grfcid & 2) + { + ApplySoConstraintLocal((SO *)palo, (CONSTR *)((uint8_t *)palo + 0x460), + (VECTOR *)((uint8_t *)palo + 0x160), &v, NULL); + (*(void (**)(ALO *, VECTOR *))((char *)palo->pvtlo + 0x94))(palo, &v); + } + else + { + SetAloAngularVelocityVec(palo, &D_00248D30); + } + } + + FreeSlotheapPv((SLOTHEAP *)((uint8_t *)palo->psw + 0x1B20), pact); +} INCLUDE_ASM("asm/nonmatchings/P2/act", GetActPositionGoal__FP3ACTfP6VECTORT2); @@ -20,7 +95,14 @@ void GetActTwistGoal(ACT *pact, float *pradTwist, float *pdradTwist) *(int *)pdradTwist = 0; } -INCLUDE_ASM("asm/nonmatchings/P2/act", GetActScale__FP3ACTP7MATRIX3); +extern char D_002483D0[]; + +void GetActScale(ACT *pact, MATRIX3 *pmat) +{ + *(qword *)((char *)pmat + 0x0) = *(qword *)(D_002483D0 + 0x0); + *(qword *)((char *)pmat + 0x10) = *(qword *)(D_002483D0 + 0x10); + *(qword *)((char *)pmat + 0x20) = *(qword *)(D_002483D0 + 0x20); +} float GGetActPoseGoal(ACT *pact, int ipose) { @@ -29,7 +111,28 @@ float GGetActPoseGoal(ACT *pact, int ipose) INCLUDE_ASM("asm/nonmatchings/P2/act", CalculateActDefaultAck__FP3ACT); -INCLUDE_ASM("asm/nonmatchings/P2/act", SnapAct__FP3ACTi); +void SnapAct(ACT *pact, int fForce) +{ + VECTOR pos; + VECTOR v; + MATRIX3 mat; + ALO *palo = pact->palo; + + if (pact == STRUCT_OFFSET(palo, 0x1ec, ACT *) && + (fForce != 0 || STRUCT_OFFSET(pact, 0x10, char) == 2)) + { + (*(void (**)(ACT *, float, VECTOR *, VECTOR *))((char *)pact->pvtact + 0x10))(pact, 0.0f, &pos, &v); + (*(void (**)(ALO *, VECTOR *))((char *)palo->pvtlo + 0x84))(palo, &pos); + (*(void (**)(ALO *, VECTOR *))((char *)palo->pvtlo + 0x90))(palo, &v); + } + if (pact == STRUCT_OFFSET(palo, 0x1f0, ACT *) && + (fForce != 0 || STRUCT_OFFSET(pact, 0x11, char) == 2)) + { + (*(void (**)(ACT *, float, MATRIX3 *, VECTOR *))((char *)pact->pvtact + 0x14))(pact, 0.0f, &mat, &pos); + (*(void (**)(ALO *, MATRIX3 *))((char *)palo->pvtlo + 0x88))(palo, &mat); + (*(void (**)(ALO *, VECTOR *))((char *)palo->pvtlo + 0x94))(palo, &pos); + } +} INCLUDE_ASM("asm/nonmatchings/P2/act", CalculateAloPositionSpring__FP3ALOfP6VECTORN22); @@ -39,15 +142,65 @@ INCLUDE_ASM("asm/nonmatchings/P2/act", CalculateAloRotationSpring__FP3ALOfP7MATR INCLUDE_ASM("asm/nonmatchings/P2/act", ProjectActRotation__FP3ACT); +extern SMP D_00260E60; + INCLUDE_ASM("asm/nonmatchings/P2/act", ProjectActPose__FP3ACTi); +#ifdef SKIP_ASM +void ProjectActPose(ACT *pact, int ipose) +{ + float g = (*(float (**)(ACT *))((char *)pact->pvtact + 0x20))(pact); + signed char actk = STRUCT_OFFSET(pact, 0x13, signed char); + + if (actk == 2) + { + float *ag = STRUCT_OFFSET(pact->palo, 0x270, float *); + ag[ipose] = g; + } + else if (actk == 3) + { + ALO *palo = pact->palo; + int off = ipose << 2; + float *ag = STRUCT_OFFSET(palo, 0x270, float *); + float dt; + dt = STRUCT_OFFSET(palo, 0x294, int) ? g_clock.dtReal : g_clock.dt; + *(float *)((char *)ag + off) = + GSmooth(*(float *)((char *)ag + off), g, dt, &D_00260E60, NULL); + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/act", PredictAloPosition__FP3ALOfP6VECTORT2); INCLUDE_ASM("asm/nonmatchings/P2/act", PredictAloRotation__FP3ALOfP7MATRIX3P6VECTOR); -INCLUDE_ASM("asm/nonmatchings/P2/act", AdaptAct__FP3ACT); +void AdaptAct(ACT *pact) +{ + if (STRUCT_OFFSET(pact, 0x10, char) == 7) + STRUCT_OFFSET(pact, 0x10, char) = 3; + if (STRUCT_OFFSET(pact, 0x11, char) == 7) + STRUCT_OFFSET(pact, 0x11, char) = 3; +} -INCLUDE_ASM("asm/nonmatchings/P2/act", InitActval__FP6ACTVALP3ALO); +void InitActval(ACTVAL *pactval, ALO *palo) +{ + uint8_t *psen; + + InitAct(pactval, palo); + *(qword *)((uint8_t *)pactval + 0x20) = *(qword *)((uint8_t *)palo + 0x190); + *(qword *)((uint8_t *)pactval + 0x40) = *(qword *)((uint8_t *)palo + 0x1a0); + *(qword *)((uint8_t *)pactval + 0x50) = *(qword *)((uint8_t *)palo + 0x1b0); + *(qword *)((uint8_t *)pactval + 0x60) = *(qword *)((uint8_t *)palo + 0x1c0); + psen = STRUCT_OFFSET(palo, 0x224, uint8_t *); + if (psen != 0 && (STRUCT_OFFSET(psen, 0xb0, int) & 0x20)) + { + pactval->radTwistGoal = STRUCT_OFFSET(psen, 0x8c, float); + } + *(qword *)((uint8_t *)pactval + 0x90) = *(qword *)(D_002483D0 + 0x0); + *(qword *)((uint8_t *)pactval + 0xa0) = *(qword *)(D_002483D0 + 0x10); + *(qword *)((uint8_t *)pactval + 0xb0) = *(qword *)(D_002483D0 + 0x20); + STRUCT_OFFSET(pactval, 0xc0, int) = STRUCT_OFFSET(palo, 0x26c, int); + STRUCT_OFFSET(pactval, 0xc4, int) = STRUCT_OFFSET(palo, 0x274, int); +} INCLUDE_ASM("asm/nonmatchings/P2/act", GetActvalPositionGoal__FP6ACTVALfP6VECTORT2); @@ -59,16 +212,45 @@ void GetActvalTwistGoal(ACTVAL *pactval, float *pradTwist, float *pdradTwist) *pdradTwist = pactval->dradTwistGoal; } -INCLUDE_ASM("asm/nonmatchings/P2/act", GetActvalScale__FP6ACTVALP7MATRIX3); +void GetActvalScale(ACTVAL *pactval, MATRIX3 *pmat) +{ + *(qword *)((uint8_t *)pmat + 0x0) = *(qword *)((uint8_t *)pactval + 0x90); + *(qword *)((uint8_t *)pmat + 0x10) = *(qword *)((uint8_t *)pactval + 0xA0); + *(qword *)((uint8_t *)pmat + 0x20) = *(qword *)((uint8_t *)pactval + 0xB0); +} float GGetActvalPoseGoal(ACTVAL *pactval, int ipose) { return pactval->agPoses[ipose]; } -INCLUDE_ASM("asm/nonmatchings/P2/act", InitActref__FP6ACTREFP3ALO); +void InitActref(ACTREF *pactref, ALO *palo) +{ + InitAct(pactref, palo); + STRUCT_OFFSET(pactref, 0x1c, uint8_t *) = (uint8_t *)palo + 0x190; + STRUCT_OFFSET(pactref, 0x24, uint8_t *) = (uint8_t *)palo + 0x1a0; + STRUCT_OFFSET(pactref, 0x38, uint8_t *) = (uint8_t *)palo + 0x26c; + STRUCT_OFFSET(pactref, 0x20, VECTOR *) = &D_00248D30; + STRUCT_OFFSET(pactref, 0x28, VECTOR *) = &D_00248D30; + STRUCT_OFFSET(pactref, 0x3c, float *) = STRUCT_OFFSET(palo, 0x274, float *); + uint8_t *psen = STRUCT_OFFSET(palo, 0x224, uint8_t *); + if (psen != NULL && (STRUCT_OFFSET(psen, 0xb0, int) & 0x20)) + { + STRUCT_OFFSET(pactref, 0x30, VECTOR *) = &D_00248D30; + STRUCT_OFFSET(pactref, 0x2c, uint8_t *) = psen + 0x8c; + } + STRUCT_OFFSET(pactref, 0x34, char *) = D_002483D0; +} -INCLUDE_ASM("asm/nonmatchings/P2/act", GetActrefPositionGoal__FP6ACTREFfP6VECTORT2); +void GetActrefPositionGoal(ACTREF *pactref, float dtOffset, VECTOR *ppos, VECTOR *pv) +{ + *(qword *)ppos = *(qword *)STRUCT_OFFSET(pactref, 0x1c, uint8_t *); + *(qword *)pv = *(qword *)STRUCT_OFFSET(pactref, 0x20, uint8_t *); + ALO *palo = pactref->palo; + void (*pfn)(ALO *) = (void (*)(ALO *))STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x0, void *), 0xB0, void *); + if (pfn) + pfn(palo); +} INCLUDE_ASM("asm/nonmatchings/P2/act", GetActrefRotationGoal__FP6ACTREFfP7MATRIX3P6VECTOR); @@ -78,7 +260,13 @@ void GetActrefTwistGoal(ACTREF *pactref, float *pradTwist, float *pdradTwist) *pdradTwist = *pactref->pdradTwistGoal; } -INCLUDE_ASM("asm/nonmatchings/P2/act", GetActrefScale__FP6ACTREFP7MATRIX3); +void GetActrefScale(ACTREF *pactref, MATRIX3 *pmat) +{ + uint8_t *psrc = STRUCT_OFFSET(pactref, 0x34, uint8_t *); + *(qword *)((uint8_t *)pmat + 0x0) = *(qword *)(psrc + 0x0); + *(qword *)((uint8_t *)pmat + 0x10) = *(qword *)(psrc + 0x10); + *(qword *)((uint8_t *)pmat + 0x20) = *(qword *)(psrc + 0x20); +} float GGetActrefPoseGoal(ACTREF *pactref, int ipose) { diff --git a/src/P2/actseg.c b/src/P2/actseg.c index b15e0e0b2..7b3427d97 100644 --- a/src/P2/actseg.c +++ b/src/P2/actseg.c @@ -33,4 +33,20 @@ INCLUDE_ASM("asm/nonmatchings/P2/actseg", GetActsegTwistGoal__FP6ACTSEGPfT1); INCLUDE_ASM("asm/nonmatchings/P2/actseg", GetActsegScale__FP6ACTSEGP7MATRIX3); -INCLUDE_ASM("asm/nonmatchings/P2/actseg", GGetActsegPoseGoal__FP6ACTSEGi); +float GGetActsegPoseGoal(ACTSEG *pactseg, int ipose) +{ + float gGoal; + ASEGA *pasega = pactseg->pasega; + int iapose = STRUCT_OFFSET(pactseg, 0x28, int); + void *p8 = STRUCT_OFFSET(pasega, 0x8, void *); + uint8_t *pbase = STRUCT_OFFSET(p8, 0x3C, uint8_t *) + iapose * 0x1C; + void **parr = STRUCT_OFFSET(pbase, 0x18, void **); + void *papx = parr[ipose]; + + (*(void (**)(void *, ALO *, int, float *, int, float, float))(*(void ***)papx))( + papx, pactseg->palo, 0, &gGoal, 0, + STRUCT_OFFSET(pasega, 0x14, float), + STRUCT_OFFSET(pasega, 0x18, float)); + + return gGoal; +} diff --git a/src/P2/alarm.c b/src/P2/alarm.c index b5c25dda8..852c26568 100644 --- a/src/P2/alarm.c +++ b/src/P2/alarm.c @@ -1,6 +1,7 @@ #include #include #include +#include void BreakAlbrk(ALBRK *palbrk) { @@ -66,11 +67,53 @@ void DisableAlarmAlbrk(ALARM *palarm) STRUCT_OFFSET(palarm, 0x61c, int)++; // palarm->calbrksDisabled } -INCLUDE_ASM("asm/nonmatchings/P2/alarm", EnableAlarmSensors__FP5ALARM); +void EnableAlarmSensors(ALARM *palarm) +{ + int i; -INCLUDE_ASM("asm/nonmatchings/P2/alarm", DisableAlarmSensors__FP5ALARM); + for (i = 0; i < STRUCT_OFFSET(palarm, 0x5bc, int); i++) + { + SENSOR *psensor = ((SENSOR **)((uint8_t *)palarm + 0x5c0))[i]; + if (STRUCT_OFFSET(psensor, 0x560, int) == -1) + { + void (*pfn)(SENSOR *, int) = (void (*)(SENSOR *, int))STRUCT_OFFSET(psensor->pvtlo, 0x134, void *); + if (pfn != 0) + { + pfn(psensor, 0); + } + } + } +} -INCLUDE_ASM("asm/nonmatchings/P2/alarm", NotifyAlarmSensorsOnTrigger__FP5ALARM); +void DisableAlarmSensors(ALARM *palarm) +{ + int ipsensor; + + for (ipsensor = 0; ipsensor < STRUCT_OFFSET(palarm, 0x5bc, int); ipsensor++) // palarm->cpsensors + { + SENSOR *psensor = STRUCT_OFFSET_INDEX(palarm, 0x5c0, SENSOR *, ipsensor); // palarm->apsensors[ipsensor] + void **ppvtable = (void **)STRUCT_OFFSET(psensor, 0x0, void *); + void (*pfn)(SENSOR *) = (void (*)(SENSOR *))STRUCT_OFFSET(ppvtable, 0x138, void *); + + if (pfn != NULL) + pfn(psensor); + } +} + +void NotifyAlarmSensorsOnTrigger(ALARM *palarm) +{ + int ipsensor; + + for (ipsensor = 0; ipsensor < STRUCT_OFFSET(palarm, 0x5bc, int); ipsensor++) // palarm->cpsensors + { + SENSOR *psensor = STRUCT_OFFSET_INDEX(palarm, 0x5c0, SENSOR *, ipsensor); // palarm->apsensors[ipsensor] + void **ppvtable = (void **)STRUCT_OFFSET(psensor, 0x0, void *); + void (*pfn)(SENSOR *) = (void (*)(SENSOR *))STRUCT_OFFSET(ppvtable, 0x13c, void *); + + if (pfn != NULL) + pfn(psensor); + } +} void AddAlarmAlbrk(ALARM *palarm, OID oid) { diff --git a/src/P2/alo.c b/src/P2/alo.c index db8c50cbb..183b5bec5 100644 --- a/src/P2/alo.c +++ b/src/P2/alo.c @@ -7,13 +7,14 @@ #include #include #include +#include +#include +#include +#include +#include -extern VTACT g_vtact; -extern VTACT g_vtactadj; // TODO: ACTADJ has it's own vtable. -extern VTACT g_vtactseg; // TODO: ACTSEG has it's own vtable. -extern VTACT g_vtactla; // TODO: ACTLA has it's own vtable. +extern VTACT g_vtactseg; extern SHADOW s_shadow; -extern CLQ D_00275C40; INCLUDE_ASM("asm/nonmatchings/P2/alo", FIsZeroV__FP6VECTOR); @@ -51,9 +52,24 @@ INCLUDE_ASM("asm/nonmatchings/P2/alo", UpdateAloHierarchy__FP3ALOf); INCLUDE_ASM("asm/nonmatchings/P2/alo", UpdateAlo__FP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/alo", InvalidateAloLighting__FP3ALO); +void InvalidateAloLighting(ALO *palo) +{ + for (int iglobi = 0; iglobi < STRUCT_OFFSET(palo, 0x238, int); iglobi++) + { + char *pb = STRUCT_OFFSET(palo, 0x240, char *) + iglobi * 0x28; + *(int *)(pb + 8) = -1; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", UpdateAloXfWorld__FP3ALO); +void UpdateAloXfWorld(ALO *palo) +{ + void (*pfn)(ALO *) = (void (*)(ALO *))palo->pvtlo->pfnUpdateLoXfWorldHierarchy; + + if (pfn != NULL) + { + pfn(palo); + } +} INCLUDE_ASM("asm/nonmatchings/P2/alo", UpdateAloXfWorldHierarchy__FP3ALO); @@ -111,11 +127,40 @@ INCLUDE_ASM("asm/nonmatchings/P2/alo", RotateAloToMat__FP3ALOP7MATRIX3); INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloVelocityVec__FP3ALOP6VECTOR); -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloVelocityXYZ__FP3ALOfff); +void SetAloVelocityXYZ(ALO *palo, float x, float y, float z) +{ + VECTOR vec; + + vec.x = x; + vec.y = y; + vec.z = z; + ((void (*)(ALO *, VECTOR *))STRUCT_OFFSET(palo->pvtlo, 0x90, void *))(palo, &vec); +} + +void SetAloAngularVelocityVec(ALO *palo, VECTOR *pw) +{ + STRUCT_OFFSET(palo, 0x160, VU_VECTOR) = *(VU_VECTOR *)pw; // palo->wWorld (angular velocity) + ACT *pactRot = STRUCT_OFFSET(palo, 0x1f0, ACT *); // palo->pactRot + if (pactRot != NULL) + { + AdaptAct(pactRot); + } + + if (!FIsZeroW(pw)) + { + ResolveAlo(palo); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloAngularVelocityVec__FP3ALOP6VECTOR); +void SetAloAngularVelocityXYZ(ALO *palo, float x, float y, float z) +{ + VECTOR w; -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloAngularVelocityXYZ__FP3ALOfff); + w.x = x; + w.y = y; + w.z = z; + (*(void (**)(ALO *, VECTOR *))((char *)palo->pvtlo + 0x94))(palo, &w); +} INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloVelocityLocal__FP3ALOP6VECTOR); @@ -135,7 +180,22 @@ INCLUDE_ASM("asm/nonmatchings/P2/alo", ConvertAloVec__FP3ALOT0P6VECTORT2); INCLUDE_ASM("asm/nonmatchings/P2/alo", ConvertAloMat__FP3ALOT0P7MATRIX3T2); -INCLUDE_ASM("asm/nonmatchings/P2/alo", FDrivenAlo__FP3ALO); +int FDrivenAlo(ALO *palo) +{ + ACT *pact = STRUCT_OFFSET(palo, 0x1ec, ACT *); // palo->pactPos + if (pact != NULL && STRUCT_OFFSET(pact, 0x10, char) == ACK_Drive) + { + return 1; + } + + pact = STRUCT_OFFSET(palo, 0x1f0, ACT *); // palo->pactRot + if (pact != NULL && STRUCT_OFFSET(pact, 0x11, char) == ACK_Drive) + { + return 1; + } + + return 0; +} INCLUDE_ASM("asm/nonmatchings/P2/alo", RetractAloDrive__FP3ALO); @@ -205,9 +265,36 @@ void GetAloFastShadowDepth(ALO *palo, float *psDepth) *psDepth = STRUCT_OFFSET(palo, 0x290, float) * 100.0f; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", PshadowAloEnsure__FP3ALO); +SHADOW *PshadowAloEnsure(ALO *palo) +{ + if (!STRUCT_OFFSET(palo, 0x284, SHADOW *)) + { + SHADOW *pshadow = (SHADOW *)PvAllocSlotheapClearImpl(&STRUCT_OFFSET(palo->psw, 0x1bf4, SLOTHEAP)); + STRUCT_OFFSET(palo, 0x284, SHADOW *) = pshadow; + InitShadow(pshadow); + AppendDlEntry(&STRUCT_OFFSET(palo->psw, 0x1c00, DL), STRUCT_OFFSET(palo, 0x284, SHADOW *)); + } + return STRUCT_OFFSET(palo, 0x284, SHADOW *); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloCastShadow__FP3ALOi); +extern DL D_00262300; + +void SetAloCastShadow(ALO *palo, int fCastShadow) +{ + if (fCastShadow) + { + PshadowAloEnsure(palo); + return; + } + + SHADOW *pshadow = STRUCT_OFFSET(palo, 0x284, SHADOW *); // palo->pshadow + if (pshadow != NULL) + { + RemoveDlEntry(&STRUCT_OFFSET(palo->psw, 0x1c00, DL), pshadow); + AppendDlEntry(&D_00262300, STRUCT_OFFSET(palo, 0x284, SHADOW *)); + STRUCT_OFFSET(palo, 0x284, SHADOW *) = NULL; + } +} void SetAloShadowShader(ALO *palo, OID oidShdShadow) { @@ -321,29 +408,37 @@ void GetAloShadowConeAngle(ALO *palo, float *pdegConeAngle) *pdegConeAngle = atan2f(pshadow->sNearRadius / pshadow->sNearCast, 1.0f) * RAD_TO_DEG * 2.0f; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloShadowFrustrumUp__FP3ALOP6VECTOR); +void GetAloShadowFrustrumUp(ALO *palo, VECTOR *pvecUp) +{ + SHADOW *pshadow = PshadowInferAlo(palo); + *(VU_VECTOR *)pvecUp = STRUCT_OFFSET(pshadow, 0x30, VU_VECTOR); // pshadow->vecFrustrumUp +} INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloEuler__FP3ALOP6VECTOR); INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloEuler__FP3ALOP6VECTOR); +extern VTACT g_vtact; + void EnsureAloActRestore(ALO *palo) { - if (!STRUCT_OFFSET(palo, 0x1fc, ACT *)) // palo->pactRestore + if (STRUCT_OFFSET(palo, 0x1fc, ACT *) == NULL) // palo->pactRestore { ACT *pact = PactNew(palo->psw, palo, &g_vtact); - STRUCT_OFFSET(palo, 0x1fc, ACT *) = pact; // palo->pactRestore + STRUCT_OFFSET(palo, 0x1fc, ACT *) = pact; InsertAloAct(palo, pact); } } +extern VTACT g_vtactla; + void EnsureAloActla(ALO *palo) { - if (!STRUCT_OFFSET(palo, 0x200, ACT *)) // palo->pactla + if (STRUCT_OFFSET(palo, 0x200, ACT *) == NULL) // palo->pactla { - ACTLA *pactla = (ACTLA *)PactNew(palo->psw, palo, &g_vtactla); - STRUCT_OFFSET(palo, 0x200, ACT *) = pactla; // palo->pactla - InsertAloAct(palo, pactla); + ACT *pact = PactNew(palo->psw, palo, &g_vtactla); + STRUCT_OFFSET(palo, 0x200, ACT *) = pact; + InsertAloAct(palo, pact); } } @@ -357,20 +452,60 @@ INCLUDE_ASM("asm/nonmatchings/P2/alo", PasegaFindAlo__FP3ALO3OID); INCLUDE_ASM("asm/nonmatchings/P2/alo", PsmaFindAlo__FP3ALO3OID); -INCLUDE_ASM("asm/nonmatchings/P2/alo", PasegaFindAloNearest__FP3ALO); +ASEGA *PasegaFindAloNearest(ALO *paloLeaf) +{ + while (paloLeaf != NULL) + { + ACT *pact = STRUCT_OFFSET(paloLeaf, 0x1ec, ACT *); + if (pact != NULL && pact->pvtact == &g_vtactseg) + return STRUCT_OFFSET(pact, 0x1c, ASEGA *); + + pact = STRUCT_OFFSET(paloLeaf, 0x1f0, ACT *); + if (pact != NULL && pact->pvtact == &g_vtactseg) + return STRUCT_OFFSET(pact, 0x1c, ASEGA *); + + paloLeaf = paloLeaf->paloParent; + } + return NULL; +} + +extern VTACT g_vtactadj; void CreateAloActadj(ALO *palo, int nPriority, ACTADJ **ppactadj) { if (palo) { - ACTADJ *pactadj = (ACTADJ *)PactNew(palo->psw, palo, &g_vtactadj); - pactadj->nPriority = nPriority; - InsertAloAct(palo, pactadj); - *ppactadj = pactadj; + ACT *pact = PactNew(palo->psw, palo, &g_vtactadj); + pact->nPriority = nPriority; + InsertAloAct(palo, pact); + *ppactadj = (ACTADJ *)pact; } } -INCLUDE_ASM("asm/nonmatchings/P2/alo", FIsAloStatic__FP3ALO); +int FIsAloStatic(ALO *palo) +{ + if (!FIsZeroV(&STRUCT_OFFSET(palo, 0x150, VECTOR))) + { + return 0; + } + + if (!FIsZeroW(&STRUCT_OFFSET(palo, 0x160, VECTOR))) + { + return 0; + } + + ALO *paloChild = (ALO *)palo->dlChild.head; + while (paloChild != NULL) + { + if (paloChild->pvtlo->grfcid & 1 && !FIsAloStatic(paloChild)) + { + return 0; + } + paloChild = (ALO *)paloChild->dleChild.next; + } + + return 1; +} void ResolveAlo(ALO *palo) { @@ -382,31 +517,108 @@ void ResolveAlo(ALO *palo) INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloPositionSpring__FP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloPositionSpringDetail__FP3ALOP3CLQ); +extern CLQ D_00260E70; +void SetAloPositionSpringDetail(ALO *palo, CLQ *pclq) +{ + CLQ *&pclqDst = STRUCT_OFFSET(palo, 0x20c, CLQ *); // palo->pclqPositionSpring (default &D_00260E70) + + if (pclqDst == &D_00260E70) + { + pclqDst = (CLQ *)PvAllocSwImpl(0x10); + } + + *(VU_VECTOR *)pclqDst = *(VU_VECTOR *)pclq; +} INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloPositionDamping__FP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloPositionDampingDetail__FP3ALOP3CLQ); +extern CLQ D_00260E80; +void SetAloPositionDampingDetail(ALO *palo, CLQ *pclq) +{ + CLQ *&pclqDst = STRUCT_OFFSET(palo, 0x210, CLQ *); // palo->pclwPosDamping (real offset 0x210) + + if (pclqDst == &D_00260E80) + { + pclqDst = (CLQ *)PvAllocSwImpl(0x10); + } + + *(VU_VECTOR *)pclqDst = *(VU_VECTOR *)pclq; +} INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationSpring__FP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationSpringDetail__FP3ALOP3CLQ); +extern CLQ D_00260E90; +void SetAloRotationSpringDetail(ALO *palo, CLQ *pclq) +{ + CLQ *&pclqDst = STRUCT_OFFSET(palo, 0x214, CLQ *); // palo->pclqRotationSpring (default &D_00260E90) + + if (pclqDst == &D_00260E90) + { + pclqDst = (CLQ *)PvAllocSwImpl(0x10); + } + + *(VU_VECTOR *)pclqDst = *(VU_VECTOR *)pclq; +} INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationDamping__FP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationDampingDetail__FP3ALOP3CLQ); +extern CLQ D_00260EA0; +void SetAloRotationDampingDetail(ALO *palo, CLQ *pclq) +{ + CLQ *&pclqDst = STRUCT_OFFSET(palo, 0x218, CLQ *); // palo->pclqRotationDamping (default &D_00260EA0) + + if (pclqDst == &D_00260EA0) + { + pclqDst = (CLQ *)PvAllocSwImpl(0x10); + } + + *(VU_VECTOR *)pclqDst = *(VU_VECTOR *)pclq; +} INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloPositionSmooth__FP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloPositionSmoothMaxAccel__FP3ALOf); +struct SMPA { float ag[4]; }; +void SetAloPositionSmoothMaxAccel(ALO *palo, float r) +{ + SMPA smpa = *STRUCT_OFFSET(palo, 0x21c, SMPA *); // copy palo->psmpaPos + smpa.ag[3] = r * (smpa.ag[0] - smpa.ag[1]) / smpa.ag[2]; + SetAloPositionSmoothDetail(palo, &smpa); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloPositionSmoothDetail__FP3ALOP4SMPA); +extern SMPA D_00260EB0; +void SetAloPositionSmoothDetail(ALO *palo, SMPA *psmpa) +{ + SMPA *&psmpaDst = STRUCT_OFFSET(palo, 0x21c, SMPA *); // palo->psmpaPos (default &D_00260EB0) + + if (psmpaDst == &D_00260EB0) + { + psmpaDst = (SMPA *)PvAllocSwImpl(0x10); + } + + *psmpaDst = *psmpa; +} INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationSmooth__FP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationSmoothMaxAccel__FP3ALOf); +void SetAloRotationSmoothMaxAccel(ALO *palo, float r) +{ + SMPA smpa = *STRUCT_OFFSET(palo, 0x220, SMPA *); // copy palo->psmapaRot + smpa.ag[3] = r * (smpa.ag[0] - smpa.ag[1]) / smpa.ag[2]; + SetAloRotationSmoothDetail(palo, &smpa); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationSmoothDetail__FP3ALOP4SMPA); +extern SMPA D_00260EC0; +void SetAloRotationSmoothDetail(ALO *palo, SMPA *psmpa) +{ + SMPA *&psmpaDst = STRUCT_OFFSET(palo, 0x220, SMPA *); // palo->psmapaRot (default &D_00260EC0) + + if (psmpaDst == &D_00260EC0) + { + psmpaDst = (SMPA *)PvAllocSwImpl(0x10); + } + + *psmpaDst = *psmpa; +} void SetAloDefaultAckPos(ALO *palo, ACK ack) { @@ -418,28 +630,77 @@ void SetAloDefaultAckRot(ALO *palo, ACK ack) STRUCT_OFFSET(palo, 0x2ca, char) = ack; } -void SetAloRestorePosition(ALO *palo, int fRestore) -{ - SetAloRestorePositionAck(palo, (ACK)(fRestore ? 1 : -1)); +void SetAloRestorePosition(ALO *palo, int fRestore) +{ + SetAloRestorePositionAck(palo, fRestore ? ACK_Spring : ACK_Nil); } -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a3c8); +void FUN_0012a3e8(ALO *palo, int unk); -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a3e8); +void FUN_0012a3c8(ALO *palo, int unk) +{ + FUN_0012a3e8(palo, unk != 0); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a418); +void FUN_0012a3e8(ALO *palo, int n) +{ + STRUCT_OFFSET(palo, 0x2c8, uint64_t) = + (STRUCT_OFFSET(palo, 0x2c8, uint64_t) & ~((uint64_t)3 << 40)) | ((uint64_t)(n & 3) << 40); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRestorePositionAck__FP3ALO3ACK); +void FUN_0012a418(ALO *palo, int *pn) +{ + *pn = (int)(STRUCT_OFFSET(palo, 0x2c8, uint64_t) >> 40) & 3; +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRestoreRotation__FP3ALOi); +void SetAloRestorePositionAck(ALO *palo, ACK ack) +{ + EnsureAloActRestore(palo); + // palo->pactRestore (ACT at 0x1FC), ackPos byte at +0x10 + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x1fc, ACT *), 0x10, char) = ack; + (*(void (**)(ALO *))((char *)palo->pvtlo + 0xBC))(palo); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRestoreRotationAck__FP3ALO3ACK); +void SetAloRestoreRotation(ALO *palo, int fRestore) +{ + SetAloRestoreRotationAck(palo, fRestore ? ACK_Spring : ACK_Nil); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a4e8); +void SetAloRestoreRotationAck(ALO *palo, ACK ack) +{ + EnsureAloActRestore(palo); + // palo->pactRestore (ACT at 0x1FC), ackRot byte at +0x11 + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x1fc, ACT *), 0x11, char) = ack; + (*(void (**)(ALO *))((char *)palo->pvtlo + 0xBC))(palo); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAt__FP3ALO3ACK); +void FUN_0012a4e8(ALO *palo, int n) +{ + void *pactrest; -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAtIgnore__FP3ALOf); + EnsureAloActRestore(palo); + pactrest = STRUCT_OFFSET(palo, 0x1fc, void *); + STRUCT_OFFSET(pactrest, 0x14, int) = n; + ResortAloActList(palo); +} + +void SetAloLookAt(ALO *palo, ACK ack) +{ + EnsureAloActla(palo); + + if (ack == ACK_Smooth) + { + ack = ACK_SmoothNoLock; + } + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x11, char) = ack; + ((void (*)(ALO *))STRUCT_OFFSET(palo->pvtlo, 0xbc, void *))(palo); +} + +void SetAloLookAtIgnore(ALO *palo, float sIgnore) +{ + EnsureAloActla(palo); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x40, float) = sIgnore; +} void GetAloLookAtIgnore(ALO *palo, float *psIgnore) { @@ -452,34 +713,84 @@ void GetAloLookAtIgnore(ALO *palo, float *psIgnore) *psIgnore = sIgnore; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAtPanFunction__FP3ALOP3CLQ); +void SetAloLookAtPanFunction(ALO *palo, CLQ *pclq) +{ + EnsureAloActla(palo); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x50, qword) = STRUCT_OFFSET(pclq, 0x0, qword); +} void GetAloLookAtPanFunction(ALO *palo, CLQ *pclq) { - void *temp = STRUCT_OFFSET(palo, 0x200, void *); + extern CLQ D_00275C40; + void *pactla = STRUCT_OFFSET(palo, 0x200, void *); + CLQ *pclqSrc; - if (temp != NULL) { - temp = (char *)temp + 0x50; - } else { - temp = &D_00275C40; - } + if (pactla) + pclqSrc = &STRUCT_OFFSET(pactla, 0x50, CLQ); + else + pclqSrc = &D_00275C40; + + *(VU_VECTOR *)pclq = *(VU_VECTOR *)pclqSrc; +} + +void SetAloLookAtPanLimits(ALO *palo, LM *plm) +{ + EnsureAloActla(palo); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x60, LM) = *plm; +} + +void GetAloLookAtPanLimits(ALO *palo, LM *plm) +{ + void *pactla = STRUCT_OFFSET(palo, 0x200, void *); + LM *plmSrc; + + if (pactla) + plmSrc = &STRUCT_OFFSET(pactla, 0x60, LM); + else + plmSrc = &g_lmZeroOne; - *(qword *)pclq = *(qword *)temp; + *plm = *plmSrc; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAtPanLimits__FP3ALOP2LM); +void SetAloLookAtTiltFunction(ALO *palo, CLQ *pclq) +{ + EnsureAloActla(palo); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x70, qword) = STRUCT_OFFSET(pclq, 0x0, qword); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloLookAtPanLimits__FP3ALOP2LM); +extern qword D_00275C40; +void GetAloLookAtTiltFunction(ALO *palo, CLQ *pclq) +{ + void *pactla = STRUCT_OFFSET(palo, 0x200, void *); + qword *pqSrc; -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAtTiltFunction__FP3ALOP3CLQ); + if (pactla) + pqSrc = &STRUCT_OFFSET(pactla, 0x70, qword); + else + pqSrc = &D_00275C40; -INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloLookAtTiltFunction__FP3ALOP3CLQ); + *(qword *)pclq = *pqSrc; +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAtTiltLimits__FP3ALOP2LM); +void SetAloLookAtTiltLimits(ALO *palo, LM *plm) +{ + EnsureAloActla(palo); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x80, LM) = *plm; +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloLookAtTiltLimits__FP3ALOP2LM); +void GetAloLookAtTiltLimits(ALO *palo, LM *plm) +{ + void *pactla = STRUCT_OFFSET(palo, 0x200, void *); + LM *plmSrc = pactla ? &STRUCT_OFFSET(pactla, 0x80, LM) : &g_lmZeroOne; -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAtEnabledPriority__FP3ALOi); + *plm = *plmSrc; +} + +void SetAloLookAtEnabledPriority(ALO *palo, int nPriority) +{ + EnsureAloActla(palo); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x44, int) = nPriority; +} void GetAloLookAtEnabledPriority(ALO *palo, int *pnPriority) { @@ -492,7 +803,11 @@ void GetAloLookAtEnabledPriority(ALO *palo, int *pnPriority) *pnPriority = nPriority; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloLookAtDisabledPriority__FP3ALOi); +void SetAloLookAtDisabledPriority(ALO *palo, int nPriority) +{ + EnsureAloActla(palo); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x200, void *), 0x48, int) = nPriority; +} void GetAloLookAtDisabledPriority(ALO *palo, int *pnPriority) { @@ -505,13 +820,35 @@ void GetAloLookAtDisabledPriority(ALO *palo, int *pnPriority) *pnPriority = nPriority; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a810); +void FUN_0012a810(ALO *palo, int n) +{ + void *pactla; + + EnsureAloActla(palo); + pactla = STRUCT_OFFSET(palo, 0x200, void *); + STRUCT_OFFSET(pactla, 0x20, int) = n; +} + +void FUN_0012a848(ALO *palo, int *pn) +{ + void *pactla = STRUCT_OFFSET(palo, 0x200, void *); + int n = -1; + + if (pactla) + n = STRUCT_OFFSET(pactla, 0x20, int); -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a848); + *pn = n; +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a860); +void FUN_0012a860(ALO *palo, ALO *paloTarget) +{ + SetActlaTarget(STRUCT_OFFSET(palo, 0x200, ACTLA *), paloTarget, &D_00248D30); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a888); +void FUN_0012a888(ALO *palo, ALO **ppaloTarget) +{ + *ppaloTarget = PaloGetActlaTarget(STRUCT_OFFSET(palo, 0x200, ACTLA *)); +} void FUN_0012a8b8(ALO *palo) { @@ -519,13 +856,48 @@ void FUN_0012a8b8(ALO *palo) STRUCT_OFFSET(pactla, 0x4C, int) = 0; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", FUN_0012a8c8); +void FUN_0012a8c8(ALO *palo) +{ + void *pactla = STRUCT_OFFSET(palo, 0x200, void *); + STRUCT_OFFSET(pactla, 0x4C, int) = 1; +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloRotationMatchesVelocity__FP3ALOff3ACK); +extern VTACT D_00219600; +void SetAloRotationMatchesVelocity(ALO *palo, float uBank, float dtPredict, ACK ackRot) +{ + if (STRUCT_OFFSET(palo, 0x204, ACT *) == 0) + { + ACT *pact = PactNew(palo->psw, palo, &D_00219600); + STRUCT_OFFSET(palo, 0x204, ACT *) = pact; + InsertAloAct(palo, pact); + } -INCLUDE_ASM("asm/nonmatchings/P2/alo", PtargetEnsureAlo__FP3ALO); + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x204, ACT *), 0x11, char) = ackRot; + ((ACTBANK *)STRUCT_OFFSET(palo, 0x204, ACT *))->uBank = uBank; + ((ACTBANK *)STRUCT_OFFSET(palo, 0x204, ACT *))->dtPredict = dtPredict; + (*(void (**)(ALO *))((char *)palo->pvtlo + 0xBC))(palo); +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloTargetAttacks__FP3ALOi); +TARGET *PtargetEnsureAlo(ALO *palo) +{ + TARGET *ptarget = (TARGET *)PloFindSwObject(palo->psw, 0x102, (OID)0x22a, palo); + + if (ptarget == NULL) + { + ptarget = (TARGET *)PloNew((CID)0x75, palo->psw, palo, (OID)0x22a, -1); + } + + return ptarget; +} + +void SetAloTargetAttacks(ALO *palo, GRFTAK grftak) +{ + TARGET *ptarget = PtargetEnsureAlo(palo); + if (grftak != -1) + { + STRUCT_OFFSET(ptarget, 0x88, GRFTAK) = grftak; // ptarget->grftak + } +} void SetAloTargetRadius(ALO *palo, float sRadiusTarget) { @@ -594,7 +966,11 @@ void SetAloSFull(ALO *palo, float sFull) STRUCT_OFFSET(palo, 0x2ac, SFX *)->sFull = sFull; // palo->psfx } -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloSndRepeat__FP3ALOP2LM); +void SetAloSndRepeat(ALO *palo, LM *plm) +{ + EnsureAloSfx(palo); + STRUCT_OFFSET(palo, 0x2ac, SFX *)->lmRepeat = *plm; // palo->psfx +} void GetAloSFull(ALO *palo, float *psFull) { @@ -676,7 +1052,19 @@ void GetAloUPitch(ALO *palo, float *puPitch) *puPitch = uPitch; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloSndRepeat__FP3ALOP2LM); +void GetAloSndRepeat(ALO *palo, LM *plmRepeat) +{ + // palo->psfx + if (STRUCT_OFFSET(palo, 0x2ac, SFX *)) + { + *plmRepeat = STRUCT_OFFSET(palo, 0x2ac, SFX *)->lmRepeat; + } + else + { + plmRepeat->gMin = -1.0f; + plmRepeat->gMax = -1.0f; + } +} INCLUDE_ASM("asm/nonmatchings/P2/alo", StartAloSound__FP3ALO5SFXIDfffP2LM); @@ -689,7 +1077,23 @@ void StopAloSound(ALO *palo) } } -INCLUDE_ASM("asm/nonmatchings/P2/alo", EnsureAloThrob__FP3ALO); +extern qword D_00261000[4]; + +void EnsureAloThrob(ALO *palo) +{ + THROB *&pthrob = STRUCT_OFFSET(palo, 0x288, THROB *); + + if (!pthrob) + { + qword *pdst = (qword *)PvAllocSwImpl(0x40); + pthrob = (THROB *)pdst; + pdst[0] = D_00261000[0]; + pdst[1] = D_00261000[1]; + pdst[2] = D_00261000[2]; + pdst[3] = D_00261000[3]; + pthrob->throbk = (THROBK)-1; + } +} INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloThrobKind__FP3ALO6THROBK); @@ -704,13 +1108,36 @@ void GetAloThrobKind(ALO *palo, THROBK *pthrobk) *pthrobk = throbk; } -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloThrobInColor__FP3ALOP6VECTOR); +void SetAloThrobInColor(ALO *palo, VECTOR *phsvInColor) +{ + EnsureAloThrob(palo); + // palo->pthrob->hsvInColor + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x288, THROB *), 0x10, VU_VECTOR) = *(VU_VECTOR *)phsvInColor; +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloThrobInColor__FP3ALOP6VECTOR); +void GetAloThrobInColor(ALO *palo, VECTOR *phsvInColor) +{ + THROB *pthrob = STRUCT_OFFSET(palo, 0x288, THROB *); // palo->pthrob + VU_VECTOR *pqSrc = pthrob + ? &STRUCT_OFFSET(pthrob, 0x10, VU_VECTOR) // pthrob->hsvInColor + : (VU_VECTOR *)&D_00248D30; -INCLUDE_ASM("asm/nonmatchings/P2/alo", SetAloThrobOutColor__FP3ALOP6VECTOR); + *(VU_VECTOR *)phsvInColor = *pqSrc; +} + +void SetAloThrobOutColor(ALO *palo, VECTOR *phsvOutColor) +{ + EnsureAloThrob(palo); + // palo->pthrob->hsvOutColor + STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x288, THROB *), 0x20, VU_VECTOR) = *(VU_VECTOR *)phsvOutColor; +} -INCLUDE_ASM("asm/nonmatchings/P2/alo", GetAloThrobOutColor__FP3ALOP6VECTOR); +void GetAloThrobOutColor(ALO *palo, VECTOR *phsvOutColor) +{ + THROB *pthrob = STRUCT_OFFSET(palo, 0x288, THROB *); // palo->throb + VU_VECTOR *pvuvec = pthrob ? &STRUCT_OFFSET(pthrob, 0x20, VU_VECTOR) : (VU_VECTOR *)&D_00248D30; + *(VU_VECTOR *)phsvOutColor = *pvuvec; +} void SetAloThrobDtInOut(ALO *palo, float dtInOut) { @@ -729,14 +1156,13 @@ void GetAloThrobDtInOut(ALO *palo, float *pdtInOut) *pdtInOut = dtInOut; } -void SetAloInteractCane(ALO *palo, GRFIC grfic) +void SetAloInteractCane(ALO *palo, GRFIC grfic) { - STRUCT_OFFSET(palo, 0x2B2, uchar) = grfic; - STRUCT_OFFSET(palo, 0x2B1, uchar) = grfic; - STRUCT_OFFSET(palo, 0x2B0, uchar) = grfic; + STRUCT_OFFSET(palo, 0x2b2, char) = grfic; + STRUCT_OFFSET(palo, 0x2b1, char) = grfic; + STRUCT_OFFSET(palo, 0x2b0, char) = grfic; } - void GetAloInteractCane(ALO *palo, GRFIC *pgrfic) { *pgrfic = STRUCT_OFFSET(palo, 0x2B0, uchar); diff --git a/src/P2/aseg.c b/src/P2/aseg.c index 9910533e0..c7488ed62 100644 --- a/src/P2/aseg.c +++ b/src/P2/aseg.c @@ -1,5 +1,6 @@ #include #include +#include void StartupAseg() { @@ -19,7 +20,26 @@ void CloneAseg(ASEG *paseg, LO *ploBase) INCLUDE_ASM("asm/nonmatchings/P2/aseg", PostAsegLoad__FP4ASEG); -INCLUDE_ASM("asm/nonmatchings/P2/aseg", PostAsegLoadCallback__FP4ASEG5MSGIDPv); +void PostAsegLoadCallback(ASEG *paseg, MSGID msgid, void *pvData) +{ + ASEGA *pasega; + LO *plo; + + if (STRUCT_OFFSET(paseg, 0x40, OID) != OID_Nil) + { + plo = PloFindSwObject(paseg->psw, 4, STRUCT_OFFSET(paseg, 0x40, OID), paseg); + if (!plo) + { + plo = PloFindSwObject(paseg->psw, 0x104, STRUCT_OFFSET(paseg, 0x40, OID), paseg); + } + } + else + { + plo = NULL; + } + + ApplyAseg(paseg, (ALO *)plo, 0.0f, 1.0f, 0, &pasega); +} INCLUDE_ASM("asm/nonmatchings/P2/aseg", ApplyAsegOvr__FP4ASEGP3ALOiP3OVRffiPP5ASEGA); @@ -37,7 +57,25 @@ ASEGA *PasegaApplyAseg(ASEG *paseg, ALO *paloAsegRoot, float tLocal, float svtLo INCLUDE_ASM("asm/nonmatchings/P2/aseg", PasegaFindAseg__FP4ASEGP3ALO); -INCLUDE_ASM("asm/nonmatchings/P2/aseg", EnsureAseg__FP4ASEGP3ALO4SEEKffiPP5ASEGA); +void SeekAsega(ASEGA *pasega, SEEK seek, float t, float svt); + +void EnsureAseg(ASEG *paseg, ALO *paloRoot, SEEK seek, float t, float svt, GRFAPL grfapl, ASEGA **ppasega) +{ + ASEGA *pasega; + ASEGA **pp = ppasega ? ppasega : &pasega; + + pasega = PasegaFindAseg(paseg, paloRoot); + if (pasega != NULL) + { + *pp = pasega; + } + else + { + ApplyAseg(paseg, paloRoot, 0.0f, 1.0f, grfapl, pp); + } + + SeekAsega(*pp, seek, t, svt); +} ASEGA *PasegaEnsureAseg(ASEG *paseg, ALO *paloRoot, SEEK seek, float t, float svt, GRFAPL grfapl) { diff --git a/src/P2/asega.c b/src/P2/asega.c index 0acfc1f0d..4930a1478 100644 --- a/src/P2/asega.c +++ b/src/P2/asega.c @@ -1,7 +1,17 @@ #include #include +#include -INCLUDE_ASM("asm/nonmatchings/P2/asega", PasegaNew__FP2SW); +extern char D_002197B8[]; + +ASEGA *PasegaNew(SW *psw) +{ + ASEGA *pasega = (ASEGA *)PvAllocSlotheapClearImpl(&psw->slotheapAsega); + STRUCT_OFFSET(pasega, 0x0, void *) = D_002197B8; + InitDl(&pasega->dlActseg, 0x20); + STRUCT_OFFSET(pasega, 0x60, void *) = (char *)pasega + 0x64; + return pasega; +} void SetAsegaHandsOff(ASEGA *pasega, int fHandsOff) { @@ -21,6 +31,57 @@ void SetAsegaHandsOff(ASEGA *pasega, int fHandsOff) } INCLUDE_ASM("asm/nonmatchings/P2/asega", UpdateAsegaIeaCur__FP5ASEGA); +#ifdef SKIP_ASM +void UpdateAsegaIeaCur(ASEGA *pasega) +{ + void *paseg = STRUCT_OFFSET(pasega, 0x8, void *); + int c = STRUCT_OFFSET(paseg, 0x5C, int); + if (c == 0) + return; + + if (0.0f <= STRUCT_OFFSET(pasega, 0x18, float)) + { + int i = 0; + if (c > 0) + { + char *p = STRUCT_OFFSET(paseg, 0x60, char *); + float t = STRUCT_OFFSET(pasega, 0x14, float); + if (!(t <= *(float *)p)) + { + int cmax = c; + i = i + 1; + while (i < cmax) + { + p += 0x10; + if (t <= *(float *)p) + break; + i = i + 1; + } + } + } + STRUCT_OFFSET(pasega, 0x20, int) = i; + } + else + { + int i = c - 1; + if (i >= 0) + { + char *p = STRUCT_OFFSET(paseg, 0x60, char *) + (i << 4); + float t = STRUCT_OFFSET(pasega, 0x14, float); + while (1) + { + if (*(float *)p <= t) + break; + i = i - 1; + if (i < 0) + break; + p -= 0x10; + } + } + STRUCT_OFFSET(pasega, 0x20, int) = i + 1; + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/asega", PactsegFindAsega__FP5ASEGA3OID); @@ -56,14 +117,58 @@ INCLUDE_ASM("asm/nonmatchings/P2/asega", AdaptAsega__FP5ASEGA); INCLUDE_ASM("asm/nonmatchings/P2/asega", FindChnClosestPointLocal__FP3CHNP3ALOP6VECTORfffPfT2T2); -INCLUDE_ASM("asm/nonmatchings/P2/asega", SetAsegaSpeed__FP5ASEGAf); +void SetAsegaSpeed(ASEGA *pasega, float speed) +{ + STRUCT_OFFSET(pasega, 0x18, float) = + speed * STRUCT_OFFSET(pasega, 0x1C, float) * + STRUCT_OFFSET(STRUCT_OFFSET(pasega, 0x8, void *), 0x98, float); +} -INCLUDE_ASM("asm/nonmatchings/P2/asega", SetAsegaMasterSpeed__FP5ASEGAf); +void SetAsegaMasterSpeed(ASEGA *pasega, float gSpeed) +{ + float denom = STRUCT_OFFSET(pasega, 0x1C, float) * + STRUCT_OFFSET(STRUCT_OFFSET(pasega, 0x8, void *), 0x98, float); + float speed = STRUCT_OFFSET(pasega, 0x18, float); + if (denom != 0.0f) + speed = speed / denom; + STRUCT_OFFSET(pasega, 0x1C, float) = gSpeed; + SetAsegaSpeed(pasega, speed); +} INCLUDE_ASM("asm/nonmatchings/P2/asega", SetAsegaPriority__FP5ASEGAi); -INCLUDE_ASM("asm/nonmatchings/P2/asega", SendAsegaMessage__FP5ASEGA5MSGIDPv); +void SendAsegaMessage(ASEGA *pasega, MSGID msgid, void *pv) +{ + LO *plo = STRUCT_OFFSET(pasega, 0xC, LO *); + if (plo) + { + plo->pvtlo->pfnSendLoMessage(plo, msgid, pv); + } + + MQ *pmq = STRUCT_OFFSET(pasega, 0xE4, MQ *); + + while (pmq) + { + PFNMQ pfnmq = pmq->pfnmq; + void *pmqContext = pmq->pvContext; -INCLUDE_ASM("asm/nonmatchings/P2/asega", SubscribeAsegaStruct__FP5ASEGAPFPv5MSGIDPv_vPv); + pmq = pmq->pmqNext; -INCLUDE_ASM("asm/nonmatchings/P2/asega", SubscribeAsegaObject__FP5ASEGAP2LO); + pfnmq(pmqContext, msgid, pv); + } +} + +void SubscribeAsegaStruct(ASEGA *pasega, PFNMQ pfnmq, void *pvContext) +{ + SubscribeSwPpmqStruct(STRUCT_OFFSET(STRUCT_OFFSET(pasega, 0x8, void *), 0x14, SW *), + &STRUCT_OFFSET(pasega, 0xE4, MQ *), + pfnmq, pvContext); +} + +void SubscribeAsegaObject(ASEGA *pasega, LO *plo) +{ + SubscribeSwPpmqStruct(STRUCT_OFFSET(STRUCT_OFFSET(pasega, 0x8, void *), 0x14, SW *), + &STRUCT_OFFSET(pasega, 0xE4, MQ *), + STRUCT_OFFSET(plo->pvtlo, 0x44, PFNMQ), + plo); +} diff --git a/src/P2/barrier.c b/src/P2/barrier.c index c64e85505..550fdd315 100644 --- a/src/P2/barrier.c +++ b/src/P2/barrier.c @@ -19,7 +19,53 @@ void CloneBarrier(BARRIER *pbarrier, BARRIER *pbarrierBase) INCLUDE_ASM("asm/nonmatchings/P2/barrier", PostBarrierLoad__FP7BARRIER); +extern VECTOR D_00248D30; + INCLUDE_ASM("asm/nonmatchings/P2/barrier", UpdateBarrier__FP7BARRIERf); +#ifdef SKIP_ASM +void UpdateBarrier(BARRIER *pbarrier, float dt) +{ + UpdateSo(pbarrier, dt); + + SO *psoWarp = STRUCT_OFFSET(pbarrier, 0x5A0, SO *); + if (psoWarp) + { + VECTOR *pvecZero = &D_00248D30; + + (*(void (**)(SO *, VECTOR *))((char *)psoWarp->pvtlo + 0x90))(psoWarp, pvecZero); + + psoWarp = STRUCT_OFFSET(pbarrier, 0x5A0, SO *); + (*(void (**)(SO *, VECTOR *))((char *)psoWarp->pvtlo + 0x94))(psoWarp, pvecZero); + + int state = STRUCT_OFFSET(pbarrier, 0x580, int); + void *pvResult; + if (state == 1) + { + psoWarp = STRUCT_OFFSET(pbarrier, 0x5A0, SO *); + (*(void (**)(SO *, void *))((char *)psoWarp->pvtlo + 0x84))( + psoWarp, &STRUCT_OFFSET(pbarrier, 0x590, int)); + pvResult = STRUCT_OFFSET(pbarrier, 0x5A0, void *); + } + else if (state == 2) + { + SO *psoWarpSrc = STRUCT_OFFSET(pbarrier, 0x590, SO *); + VECTOR vec; + ConvertAloPos(STRUCT_OFFSET(psoWarpSrc, 0x18, ALO *), NULL, + (VECTOR *)((char *)psoWarpSrc + 0x40), &vec); + psoWarp = STRUCT_OFFSET(pbarrier, 0x5A0, SO *); + (*(void (**)(SO *, VECTOR *))((char *)psoWarp->pvtlo + 0x84))(psoWarp, &vec); + pvResult = STRUCT_OFFSET(pbarrier, 0x5A0, void *); + } + else + { + pvResult = STRUCT_OFFSET(pbarrier, 0x5A0, void *); + } + + STRUCT_OFFSET(pbarrier, 0x5A0, void *) = NULL; + STRUCT_OFFSET(pbarrier, 0x5A4, void *) = pvResult; + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/barrier", FIgnoreBarrierIntersection__FP7BARRIERP2SO); diff --git a/src/P2/bbmark.c b/src/P2/bbmark.c index 518a55151..85c57a9c0 100644 --- a/src/P2/bbmark.c +++ b/src/P2/bbmark.c @@ -14,9 +14,38 @@ OX *PoxAddSw(SW *psw, OXA *poxa, OXA *poxaOther) return pox; } -INCLUDE_ASM("asm/nonmatchings/P2/bbmark", PoxRemoveSw__FP2SWP3OXAT1); +OX *PoxRemoveSw(SW *psw, OXA *poxa, OXA *poxaOther) +{ + OX **ppox = &poxa->pox; + OX *pox = poxa->pox; + SO *psoOther = poxaOther->pso; + + while (pox) + { + if (pox->psoOther == psoOther) + { + *ppox = pox->poxNext; + break; + } + ppox = &pox->poxNext; + pox = pox->poxNext; + } -INCLUDE_ASM("asm/nonmatchings/P2/bbmark", PoxFromSoSo__FP2SOT0); + return pox; +} + +OX *PoxFromSoSo(SO *pso, SO *psoOther) +{ + OX *pox = STRUCT_OFFSET(STRUCT_OFFSET(pso, 0x50, SW *), 0x480, OXA *)->pox; + SO *psoKey = STRUCT_OFFSET(psoOther, 0x50, SO *); + while (pox != NULL) + { + if (pox->psoOther == psoKey) + return pox; + pox = pox->poxNext; + } + return NULL; +} XP *PxpFirstFromSoSo(SO *pso, SO *psoOther) { @@ -35,8 +64,49 @@ void InvalidateSwAaox(SW *psw) INCLUDE_ASM("asm/nonmatchings/P2/bbmark", UpdateSwAaox__FP2SW); -INCLUDE_ASM("asm/nonmatchings/P2/bbmark", InvalidateSwXpForObject__FP2SWP2SOi); +void InvalidateSwXpForObject(SW *psw, SO *pso, GRFPVA grfpvaInvalid) +{ + SW *pswObject = STRUCT_OFFSET(pso, 0x50, SW *); + if (pswObject) + { + STRUCT_OFFSET(pswObject, 0x4B8, int) &= ~grfpvaInvalid; + } +} INCLUDE_ASM("asm/nonmatchings/P2/bbmark", RecalcSwXpAll__FP2SWi); +extern void UpdateSwPox(SW *, OXA *, OXA *, unsigned char, unsigned char); + INCLUDE_ASM("asm/nonmatchings/P2/bbmark", RecalcSwOxfFilterForObject__FP2SWP2SO); +#ifdef SKIP_ASM +void RecalcSwOxfFilterForObject(SW *psw, SO *pso) +{ + OXA *poxa; + + STRUCT_OFFSET(pso, 0x4B8, int) = 0; + poxa = STRUCT_OFFSET(psw, 0x1AE8, OXA *); + while (poxa != NULL) + { + if (poxa->pso != pso) + { + int fHit = 0; + void **pvtbl = STRUCT_OFFSET(pso, 0x0, void **); + if (((int (*)(SO *))pvtbl[0xF0 / 4])(pso) != 0) + { + fHit = 1; + } + else + { + void **pvtblOther = STRUCT_OFFSET(poxa->pso, 0x0, void **); + if (((int (*)(SO *, SO *))pvtblOther[0xF0 / 4])(poxa->pso, pso) != 0) + { + fHit = 1; + } + } + UpdateSwPox(psw, STRUCT_OFFSET(pso, 0x480, OXA *), poxa, + fHit ? 0 : 8, fHit ? 8 : 0); + } + poxa = poxa->poxaNext; + } +} +#endif // SKIP_ASM diff --git a/src/P2/binoc.c b/src/P2/binoc.c index 68293fa9c..1e3a6d5fc 100644 --- a/src/P2/binoc.c +++ b/src/P2/binoc.c @@ -2,6 +2,9 @@ #include #include #include +#include +#include +#include void InitBei(BEI *pbei, CLQ *pclq, float duWidth, float dgHeight, int cseg) { @@ -105,7 +108,19 @@ INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00135550); INCLUDE_ASM("asm/nonmatchings/P2/binoc", open_close_binoc); -INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_001357f0); +int FUN_001357f0(void *a, void *b) +{ + if (!FIsLoInWorld(STRUCT_OFFSET(a, 0x0, LO *))) + return 1; + + if (!FIsLoInWorld(STRUCT_OFFSET(b, 0x0, LO *))) + return -1; + + if (STRUCT_OFFSET(a, 0x4, float) < STRUCT_OFFSET(b, 0x4, float)) + return -1; + + return 1; +} INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00135858); @@ -114,11 +129,19 @@ INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_001358d0); JUNK_ADDIU(30); JUNK_WORD(0xE4C00000); -INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00135E30); +void FUN_00135E30(void *a0, void *a1, void *a2) +{ + STRUCT_OFFSET(a1, 0x0, qword) = STRUCT_OFFSET(a0, 0x140, qword); + STRUCT_OFFSET(a2, 0x0, int) = 0; +} JUNK_ADDIU(A0); -INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00135E48); +int FUN_00135E48(void *param_1, int param_2, VECTOR *param_3) +{ + *(qword *)param_3 = *(qword *)((uint8_t *)param_1 + 0x140); + return ChpBuildConvexHullScreen(param_3, 1, (HP *)param_3); +} JUNK_ADDIU(10); @@ -130,7 +153,13 @@ INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00136040); INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00136238); -INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_001363d0); +void FUN_001363d0(BINOC *pbinoc) +{ + OnBlotReset(pbinoc); + DIALOG *pdialog = STRUCT_OFFSET(pbinoc, 0x324, DIALOG *); + if (pdialog) + SetDialogDialogs(pdialog, DIALOGS_Disabled); +} INCLUDE_ASM("asm/nonmatchings/P2/binoc", SetBinocAchzDraw); @@ -185,7 +214,14 @@ void GetBinocReticleFocus(BINOC *binoc, float *dxReticle, float *dyReticle) INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00136ef8); -INCLUDE_ASM("asm/nonmatchings/P2/binoc", FUN_00136fa8); +void FUN_00136fa8(BINOC *pbinoc) +{ + DIALOG *pdialog = STRUCT_OFFSET(pbinoc, 0x324, DIALOG *); + if (pdialog) + SetDialogDialogs(pdialog, DIALOGS_Calling); + else + open_close_binoc(pbinoc, 0); +} INCLUDE_ASM("asm/nonmatchings/P2/binoc", binoc__static_initialization_and_destruction_0); diff --git a/src/P2/blip.c b/src/P2/blip.c index 2f236ae9d..e1a72a18c 100644 --- a/src/P2/blip.c +++ b/src/P2/blip.c @@ -1,4 +1,5 @@ #include +#include extern QW *g_aqwBlipeGifsNormal; extern QW *g_aqwBlipeGifsClampedAdd; @@ -11,15 +12,69 @@ void StartupBlips() BuildBlipAqwGifs(2, &g_aqwBlipeGifsClampedAdd); } -INCLUDE_ASM("asm/nonmatchings/P2/blip", PblipNew__FP5BLIPG); +BLIP *PblipNew(BLIPG *pblipg) +{ + BLIP *pblip; + void *pv; + + pblip = (BLIP *)PvAllocSlotheapUnsafe( + (SLOTHEAP *)((uint8_t *)STRUCT_OFFSET(pblipg, 0x14, void *) + 0x1B40)); + if (pblip == NULL) + return NULL; + + memset(pblip, 0, 0x10C0); + + if (STRUCT_OFFSET(pblipg, 0x320, int) == 2) + { + pv = PvAllocSlotheapUnsafe( + (SLOTHEAP *)((uint8_t *)STRUCT_OFFSET(pblipg, 0x14, void *) + 0x1B4C)); + STRUCT_OFFSET(pblip, 0x1088, void *) = pv; + if (pv == NULL) + { + FreeSlotheapPv( + (SLOTHEAP *)((uint8_t *)STRUCT_OFFSET(pblipg, 0x14, void *) + 0x1B40), + pblip); + return NULL; + } + memset(pv, 0, 0x580); + STRUCT_OFFSET(pblip, 0x108C, BLIPG *) = pblipg; + } + else + { + STRUCT_OFFSET(pblip, 0x108C, BLIPG *) = pblipg; + } + + AppendDlEntry((DL *)((uint8_t *)pblipg + 0x624), pblip); + return pblip; +} INCLUDE_ASM("asm/nonmatchings/P2/blip", RemoveBlip__FP4BLIP); INCLUDE_ASM("asm/nonmatchings/P2/blip", PblipgNew__FP2SW); -INCLUDE_ASM("asm/nonmatchings/P2/blip", InitBlipg__FP5BLIPG); +void InitBlipg(BLIPG *pblipg) +{ + uint64_t flags; + + AppendDlEntry((DL *)((uint8_t *)STRUCT_OFFSET(pblipg, 0x14, void *) + 0x1CC0), pblipg); + InitAlo((ALO *)pblipg); + InitDl((DL *)((uint8_t *)pblipg + 0x624), 0x1090); + + flags = STRUCT_OFFSET(pblipg, 0x2C8, uint64_t); + flags &= 0xFFFFFFFFCFFFFFFFULL; + flags |= 0x20000000; + STRUCT_OFFSET(pblipg, 0x80, float) = 10000000000.0f; + flags &= 0xFFFFFCFFFFFFFFFFULL; + flags |= 0x10000000000ULL; + STRUCT_OFFSET(pblipg, 0x2C8, uint64_t) = flags; +} -INCLUDE_ASM("asm/nonmatchings/P2/blip", OnBlipgAdd__FP5BLIPG); +void OnBlipgAdd(BLIPG *pblipg) +{ + RemoveDlEntry((DL *)((uint8_t *)STRUCT_OFFSET(pblipg, 0x14, void *) + 0x1CC0), pblipg); + AppendDlEntry((DL *)((uint8_t *)STRUCT_OFFSET(pblipg, 0x14, void *) + 0x1CB4), pblipg); + OnAloAdd((ALO *)pblipg); +} INCLUDE_ASM("asm/nonmatchings/P2/blip", OnBlipgRemove__FP5BLIPG); diff --git a/src/P2/bomb.c b/src/P2/bomb.c index e9799cf70..5bf4140ac 100644 --- a/src/P2/bomb.c +++ b/src/P2/bomb.c @@ -25,7 +25,17 @@ void CloneBomb(BOMB *pbomb, BOMB *pbombBase) INCLUDE_ASM("asm/nonmatchings/P2/bomb", PostBombLoad__FP4BOMB); -INCLUDE_ASM("asm/nonmatchings/P2/bomb", HandleBombMessage__FP4BOMB5MSGIDPv); +void HandleBombMessage(BOMB *pbomb, MSGID msgid, void *pv) +{ + HandleAloMessage((ALO *)pbomb, msgid, pv); + if (msgid == MSGID_water_entered) { + if (*(int *)((uint8_t *)pv + 0x4) == (int)pbomb) { + if (!STRUCT_OFFSET(pbomb, 0x550, int)) { + PrimeBomb(pbomb, 0.0f); + } + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/bomb", UpdateBomb__FP4BOMBf); @@ -49,4 +59,13 @@ INCLUDE_ASM("asm/nonmatchings/P2/bomb", ApplyBombThrow__FP4BOMBP2PO); INCLUDE_ASM("asm/nonmatchings/P2/bomb", DetonateBomb__FP4BOMB); -INCLUDE_ASM("asm/nonmatchings/P2/bomb", PsfxEnsureBomb__FP4BOMB4ENSK); +SFX *PsfxEnsureBomb(BOMB *pbomb, ENSK ensk) +{ + // pbomb->psfxDet + if (!STRUCT_OFFSET(pbomb, 0x680, SFX *)) + { + NewSfx(&STRUCT_OFFSET(pbomb, 0x680, SFX *)); + } + + return STRUCT_OFFSET(pbomb, 0x680, SFX *); +} diff --git a/src/P2/bq.c b/src/P2/bq.c index 5f1763f90..1a7e05804 100644 --- a/src/P2/bq.c +++ b/src/P2/bq.c @@ -21,7 +21,39 @@ INCLUDE_ASM("asm/nonmatchings/P2/bq", CbFill__10CByteQueueiP11CQueueInput); INCLUDE_ASM("asm/nonmatchings/P2/bq", CbDrain__10CByteQueueiP12CQueueOutput); -INCLUDE_ASM("asm/nonmatchings/P2/bq", CbFill__10CByteQueueiPUc); +extern int D_00249D98[]; + +int CByteQueue::CbFill(int cb, byte *pb) +{ + int cbRead; + + if (cb == 0) + { + cbRead = 0; + } + else + { + // Stack CQueueInputMemory: vtable ptr (D_00249D98 = __vt_17CQueueInputMemory in + // rodata), pb @0x4, cb @0x8, ib (read cursor) @0xC, cb remaining @0x10 + struct + { + void *pvt; + byte *pb; + int cb; + int ib; + int cbTotal; + } qim; + + qim.pb = pb; + qim.pvt = D_00249D98; + qim.cbTotal = cb; + qim.cb = cb; + qim.ib = 0; + cbRead = CbFill(cb, (CQueueInput *)&qim); + } + + return cbRead; +} void CByteQueue::FreeDrain(int cb) { diff --git a/src/P2/break.c b/src/P2/break.c index df8acc090..050722548 100644 --- a/src/P2/break.c +++ b/src/P2/break.c @@ -1,12 +1,43 @@ #include #include #include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/break", InitBrk__FP3BRK); -INCLUDE_ASM("asm/nonmatchings/P2/break", LoadBrkFromBrx__FP3BRKP18CBinaryInputStream); +void LoadBrkFromBrx(BRK *pbrk, CBinaryInputStream *pbis) +{ + LoadSoFromBrx(pbrk, pbis); + + if (STRUCT_OFFSET(pbrk, 0x614, OID) == (OID)-1) + { + InferExpl((EXPL **)((uint8_t *)pbrk + 0x618), (ALO *)pbrk); + } + else + { + LO *plo = PloFindSwObject(pbrk->psw, 0x101, STRUCT_OFFSET(pbrk, 0x614, OID), (LO *)pbrk); + STRUCT_OFFSET(pbrk, 0x618, LO *) = plo; + + if (plo != NULL) + { + SnipLo(plo); + } + } +} + +void CloneBrk(BRK *pbrk, BRK *pbrkBase) +{ + int ichkBroken = STRUCT_OFFSET(pbrk, 0x688, int); + CloneSo(pbrk, pbrkBase); + STRUCT_OFFSET(pbrk, 0x688, int) = ichkBroken; -INCLUDE_ASM("asm/nonmatchings/P2/break", CloneBrk__FP3BRKT0); + if (STRUCT_OFFSET(pbrkBase, 0x6b4, SFX *) != NULL) + { + STRUCT_OFFSET(pbrk, 0x6b4, SFX *) = (SFX *)PvAllocSwCopyImpl(0x24, STRUCT_OFFSET(pbrkBase, 0x6b4, SFX *)); + } +} void PostBrkLoad(BRK *pbrk) { @@ -16,7 +47,16 @@ void PostBrkLoad(BRK *pbrk) INCLUDE_ASM("asm/nonmatchings/P2/break", PostBrkLoadCallbackHookup__FP3BRK5MSGIDPv); -INCLUDE_ASM("asm/nonmatchings/P2/break", UpdateBrk__FP3BRKf); +void UpdateBrk(BRK *pbrk, float dt) +{ + UpdateSo(pbrk, dt); + + if (STRUCT_OFFSET(pbrk, 0x678, int)) + { + STRUCT_OFFSET(pbrk, 0x678, int) = 0; + (*(void (**)(BRK *))((char *)pbrk->pvtlo + 0x130))(pbrk); + } +} INCLUDE_ASM("asm/nonmatchings/P2/break", FAbsorbBrkWkr__FP3BRKP3WKR); @@ -175,7 +215,33 @@ void InitFragile(FRAGILE *pfragile) STRUCT_OFFSET(pfragile, 0x6c8, int) = -1; } -INCLUDE_ASM("asm/nonmatchings/P2/break", AdjustFragileNewXp__FP7FRAGILEP2XPi); +void AdjustFragileNewXp(FRAGILE *pfragile, XP *pxp, int ixpd) +{ + if (STRUCT_OFFSET(pfragile, 0x680, int)) + return; + + SO *psoRoot = pxp->axpd[1 - ixpd].psoRoot; + + if (STRUCT_OFFSET(pfragile, 0x678, int)) + return; + + if (!FCheckBrkTouchObject((BRK *)pfragile, psoRoot)) + return; + + CNSTR cnstrForce = STRUCT_OFFSET(pfragile, 0x6c4, CNSTR); + if (cnstrForce != (CNSTR)-1) + SetSoCnstrForce((SO *)pfragile, cnstrForce); + + CNSTR cnstrTorque = STRUCT_OFFSET(pfragile, 0x6c8, CNSTR); + if (cnstrTorque != (CNSTR)-1) + SetSoCnstrTorque((SO *)pfragile, cnstrTorque); + + float t = STRUCT_OFFSET(pfragile, 0x368, float); + float scale = STRUCT_OFFSET(pfragile, 0x6c0, float); + STRUCT_OFFSET(pfragile, 0x678, int) = 1; + STRUCT_OFFSET(pfragile, 0x6cc, SO *) = psoRoot; + STRUCT_OFFSET(pfragile, 0x368, float) = t * scale; +} void AdjustZapbreakNewXp(ZAPBREAK *pzapbreak, XP *pxp, int ixpd) { diff --git a/src/P2/brx.c b/src/P2/brx.c index a5b9e4eca..d27b3fee3 100644 --- a/src/P2/brx.c +++ b/src/P2/brx.c @@ -53,4 +53,41 @@ uint IploFromStockOid(int oid) INCLUDE_ASM("asm/nonmatchings/P2/brx", LoadSwObjectsFromBrx__FP2SWP3ALOP18CBinaryInputStream); +struct EOPIDENTRY +{ + void *unk; + EOPID *peopid; +}; + +struct LODEFTAB +{ + int ceopid; + EOPIDENTRY *prgeopidentry; +}; + +extern LODEFTAB D_00244950[]; + INCLUDE_ASM("asm/nonmatchings/P2/brx", SetLoDefaults__FP2LO); +#ifdef SKIP_ASM +void SetLoDefaults(LO *plo) +{ + CID cid = plo->pvtlo->cid; + int ceopid = D_00244950[cid].ceopid; + if (ceopid > 0) + { + EOPIDENTRY *peopidentry = D_00244950[cid].prgeopidentry; + do + { + EOPID *peopid = peopidentry->peopid; + if (peopid->grfeopid & 0x800) + { + CBinaryInputStream bis(NULL, 0, 0); + bis.OpenMemory(4, &peopid->optdat); + LoadOptionFromBrx(plo, peopid, &bis); + } + ceopid--; + peopidentry++; + } while (ceopid != 0); + } +} +#endif // SKIP_ASM diff --git a/src/P2/bsp.c b/src/P2/bsp.c index 056056dcd..a00cd71f1 100644 --- a/src/P2/bsp.c +++ b/src/P2/bsp.c @@ -1,4 +1,5 @@ #include +#include INCLUDE_ASM("asm/nonmatchings/P2/bsp", ClsgClipEdgeToBsp__FP3BSPP6VECTORT1PiiP3LSG); @@ -6,4 +7,25 @@ INCLUDE_ASM("asm/nonmatchings/P2/bsp", PruneBsp__FP3BSPP6VECTORfPP3BSP); INCLUDE_ASM("asm/nonmatchings/P2/bsp", PbspPointInBspQuick__FP6VECTORP3BSP); -INCLUDE_ASM("asm/nonmatchings/P2/bsp", CloneBspc__FP4GEOMP4BSPCT0T1); +void CloneBspc(GEOM *pgeomSrc, BSPC *pbspcSrc, GEOM *pgeomDst, BSPC *pbspcDst) +{ + int ibsp; + + pbspcDst->cbsp = pbspcSrc->cbsp; + pbspcDst->cbspFull = pbspcSrc->cbspFull; + pbspcDst->absp = (BSP *)PvAllocSwImpl(pbspcSrc->cbsp * sizeof(BSP)); + + for (ibsp = 0; ibsp < pbspcDst->cbsp; ibsp++) + { + BSP *pbspSrc = &pbspcSrc->absp[ibsp]; + BSP *pbspDst = &pbspcDst->absp[ibsp]; + + pbspDst->psurf = (SURF *)((int)pgeomDst->asurf + ((int)pbspSrc->psurf - (int)pgeomSrc->asurf)); + pbspDst->pbspNeg = pbspSrc->pbspNeg + ? (BSP *)((int)pbspcDst->absp + ((int)pbspSrc->pbspNeg - (int)pbspcSrc->absp)) + : NULL; + pbspDst->pbspPos = pbspSrc->pbspPos + ? (BSP *)((int)pbspcDst->absp + ((int)pbspSrc->pbspPos - (int)pbspcSrc->absp)) + : NULL; + } +} diff --git a/src/P2/button.c b/src/P2/button.c index 6a569ee8e..be7e66153 100644 --- a/src/P2/button.c +++ b/src/P2/button.c @@ -5,9 +5,25 @@ INCLUDE_ASM("asm/nonmatchings/P2/button", PostAshLoad__FP2SWP3ASHP3ALO); INCLUDE_ASM("asm/nonmatchings/P2/button", FFoundAshAseg__FP3ASHP4ASEG); -INCLUDE_ASM("asm/nonmatchings/P2/button", FAddAshAseg__FP3ASHP4ASEG); +int FAddAshAseg(ASH *pash, ASEG * paseg) +{ + int c = STRUCT_OFFSET(pash, 0x44, int); + ASEG * *a = &STRUCT_OFFSET(pash, 0x48, ASEG *); + a[c] = paseg; + c = c + 1; + STRUCT_OFFSET(pash, 0x44, int) = c; + return c < 16; +} -INCLUDE_ASM("asm/nonmatchings/P2/button", FAddAshOid__FP3ASH3OID); +int FAddAshOid(ASH *pash, OID oid) +{ + int c = STRUCT_OFFSET(pash, 0x0, int); + OID *a = &STRUCT_OFFSET(pash, 0x4, OID); + a[c] = oid; + c = c + 1; + STRUCT_OFFSET(pash, 0x0, int) = c; + return c < 16; +} void InitBtn(BTN *pbtn) { @@ -17,11 +33,42 @@ void InitBtn(BTN *pbtn) INCLUDE_ASM("asm/nonmatchings/P2/button", LoadBtn__FP3BTNP3ALO); -INCLUDE_ASM("asm/nonmatchings/P2/button", PostBtnLoad__FP3BTN); +void PostBtnLoad(BTN *pbtn) +{ + int iash; + SW *psw; + + pbtn->buttons = (BUTTONS)-1; + psw = pbtn->paloOwner->psw; + + for (iash = 0; iash < IASH_Max; iash++) + { + PostAshLoad(psw, &pbtn->aash[iash], pbtn->paloOwner); + } -INCLUDE_ASM("asm/nonmatchings/P2/button", RestoreBtnFromCheckpointCallback__FP3BTN5MSGIDPv); + if (pbtn->fCheckpointed && FGetChkmgrIchk(&g_chkmgr, pbtn->ichkPushed)) + { + PostSwCallback(psw, (PFNMQ)RestoreBtnFromCheckpointCallback, pbtn, MSGID_callback, NULL); + } +} + +void RestoreBtnFromCheckpointCallback(BTN *pbtn, MSGID msgid, void *pv) +{ + if (msgid == MSGID_callback) + { + PostSwCallback(pbtn->paloOwner->psw, (PFNMQ)RestoreBtnFromCheckpointCallback, pbtn, + MSGID_button_trigger, NULL); + } + else + { + TriggerBtn(pbtn, 1, 1); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/button", SetBtnRsmg__FP3BTNi3OIDN22); +void SetBtnRsmg(BTN *pbtn, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal) +{ + FAddRsmg(pbtn->arsmg, 8, &pbtn->crsmg, fOnTrigger, oidRoot, oidSM, oidGoal); +} INCLUDE_ASM("asm/nonmatchings/P2/button", SetBtnButtons__FP3BTN7BUTTONS); @@ -108,7 +155,20 @@ INCLUDE_ASM("asm/nonmatchings/P2/button", UpdateButtonInternalXps__FP6BUTTON); INCLUDE_ASM("asm/nonmatchings/P2/button", UpdateButton__FP6BUTTONf); -INCLUDE_ASM("asm/nonmatchings/P2/button", FAbsorbButtonWkr__FP6BUTTONP3WKR); +int FAbsorbButtonWkr(BUTTON* pbutton, WKR* pwkr) +{ + int fAbsorbed = FAbsorbSoWkr(pbutton, pwkr); + + if (fAbsorbed && + !(pwkr->grfic & 0x4) && + STRUCT_OFFSET(pbutton, 0x550, int) == BUTTONS_Disabled && + !STRUCT_OFFSET(pbutton, 0x680, int)) + { + SetButtonButtons(pbutton, BUTTONS_Contact); + } + + return fAbsorbed; +} void InitVolbtn(VOLBTN *pvolbtn) { diff --git a/src/P2/cd.c b/src/P2/cd.c index 4f99949c2..0df446cc3 100644 --- a/src/P2/cd.c +++ b/src/P2/cd.c @@ -1,4 +1,5 @@ #include +#include #include <989snd.h> #include @@ -41,7 +42,32 @@ void StartupCd() INCLUDE_ASM("asm/nonmatchings/P2/cd", UpdateCd__Fv); +extern short D_00249E20; +extern char D_00249E28[]; +extern char D_00249E30[]; +extern char D_00249E38[]; + INCLUDE_ASM("asm/nonmatchings/P2/cd", CdPath__FPcT0i); +#ifdef SKIP_ASM +void CdPath(char *pchzDest, char *pchzPath, int fIncludeDevice) +{ + char achz[0x100] = D_00249E20; + strcpy1(achz, pchzPath); + int ctoken = ((int (*)(char *))CpchzTokenizePath)(achz); + if (1 < ctoken) + { + int itoken = ctoken - 1; + do + { + achz[strlen(achz)] = '\\'; + itoken--; + } while (itoken != 0); + } + + char *pchzDevice = fIncludeDevice ? D_00249E30 : D_00249E38; + sprintf(pchzDest, D_00249E28, pchzDevice, achz); +} +#endif // SKIP_ASM void ReadCd(uint isector, uint csector, void *pv) { diff --git a/src/P2/chkpnt.c b/src/P2/chkpnt.c index b94b0b02d..e3b926d90 100644 --- a/src/P2/chkpnt.c +++ b/src/P2/chkpnt.c @@ -1,5 +1,12 @@ #include #include +#include +#include +#include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", ResetChkmgrCheckpoints__FP6CHKMGR); #ifdef SKIP_ASM @@ -33,10 +40,43 @@ void ResetChkmgrCheckpoints(CHKMGR *pchkmgr) #endif INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", SaveChkmgrCheckpoint__FP6CHKMGR3OIDT1); +#ifdef SKIP_ASM +void SaveChkmgrCheckpoint(CHKMGR *pchkmgr, OID oidWarp, OID oidWarpContext) +{ + STRUCT_OFFSET(pchkmgr, 0x20C, int) = 0; + memcpy((char *)pchkmgr + 0x220, &pchkmgr->abitChk, 0x204); + STRUCT_OFFSET(pchkmgr, 0x42c, int) = 1; + STRUCT_OFFSET(pchkmgr, 0x424, int) = oidWarp; + STRUCT_OFFSET(pchkmgr, 0x428, int) = oidWarpContext; +} +#endif // SKIP_ASM -INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", ReturnChkmgrToCheckpoint__FP6CHKMGR); +void ReturnChkmgrToCheckpoint(CHKMGR *pchkmgr) +{ + TRANS trans; + trans.fSet = 1; + trans.pchzWorld = (LevelTableStruct *)g_transition.m_achzWorldCur; + if (STRUCT_OFFSET(pchkmgr, 0x42c, int)) + { + trans.oidWarp = (OID)STRUCT_OFFSET(pchkmgr, 0x424, int); + trans.oidWarpContet = (OID)STRUCT_OFFSET(pchkmgr, 0x428, int); + trans.grftrans = 0x11; + } + else + { + trans.oidWarp = OID_Nil; + trans.oidWarpContet = OID_Nil; + trans.grftrans = 0x10; + } + ActivateWipe(&g_wipe, &trans, (WIPEK)1); +} -INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", RestoreChkmgrFromCheckpoint__FP6CHKMGR); +void RestoreChkmgrFromCheckpoint(CHKMGR *pchkmgr) +{ + pchkmgr->cbitChk = 0; + memcpy(&pchkmgr->abitChk, (char *)pchkmgr + 0x220, 0x204); + pchkmgr->fChkDirty = 0; +} int IchkAllocChkmgr(CHKMGR *pchkmgr) { @@ -49,9 +89,27 @@ INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", SetChkmgrIchk__FP6CHKMGRi); INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", ClearChkmgrIchk__FP6CHKMGRi); -INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", LoadVolFromBrx__FP3VOLP18CBinaryInputStream); +void LoadVolFromBrx(VOL *pvol, CBinaryInputStream *pbis) +{ + pbis->ReadMatrix((MATRIX3 *)((uint8_t *)pvol + 0x50)); + pbis->ReadVector((VECTOR *)((uint8_t *)pvol + 0x40)); + LoadTbspFromBrx(pbis, + &STRUCT_OFFSET(pvol, 0x80, int), + &STRUCT_OFFSET(pvol, 0x84, TSURF *), + &STRUCT_OFFSET(pvol, 0x88, int), + &STRUCT_OFFSET(pvol, 0x8c, TBSP *)); + LoadOptionsFromBrx(pvol, pbis); +} + +extern int ConvertXfmLocalToWorld(XFM *pxfm, VECTOR *pposWorld, VECTOR *pposLocal); -INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", FCheckVolPoint__FP3VOLP6VECTOR); +int FCheckVolPoint(VOL *pvol, VECTOR *ppos) +{ + VECTOR posLocal; + + ConvertXfmLocalToWorld(pvol, ppos, &posLocal); + return FCheckTbspPoint(STRUCT_OFFSET(pvol, 0x8c, TBSP *), &posLocal); +} INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", InitChkpnt__FP6CHKPNT); @@ -62,16 +120,77 @@ INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", BindChkpnt__FP6CHKPNT); INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", PostChkpntLoad__FP6CHKPNT); INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", CloneChkpnt__FP6CHKPNTT0); +#ifdef SKIP_ASM +void CloneChkpnt(CHKPNT *pchkpnt, CHKPNT *pchkpntBase) +{ + int i = 0; + LO *plo0 = STRUCT_OFFSET(pchkpnt, 0x5B4, LO *); + LO *plo1 = STRUCT_OFFSET(pchkpnt, 0x5B0, LO *); + + CloneSo((SO *)pchkpnt, (SO *)pchkpntBase); + + STRUCT_OFFSET(pchkpnt, 0x5B0, LO *) = plo1; + STRUCT_OFFSET(pchkpnt, 0x5B4, LO *) = plo0; + + if (STRUCT_OFFSET(pchkpnt, 0x564, int) > 0) + { + LO **a = &STRUCT_OFFSET(pchkpnt, 0x568, LO *); + do + { + *a = PloCloneLo(*a, STRUCT_OFFSET(pchkpnt, 0x14, SW *), (ALO *)pchkpnt); + i++; + a++; + } while (i < STRUCT_OFFSET(pchkpnt, 0x564, int)); + } + + if (STRUCT_OFFSET(pchkpnt, 0x58C, int) > 0) + { + int j = 0; + LO **a = &STRUCT_OFFSET(pchkpnt, 0x590, LO *); + do + { + *a = PloCloneLo(*a, STRUCT_OFFSET(pchkpnt, 0x14, SW *), (ALO *)pchkpnt); + j++; + a++; + } while (j < STRUCT_OFFSET(pchkpnt, 0x58C, int)); + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", UpdateChkpnt__FP6CHKPNTf); -INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", FUN_001417f0); +extern void TriggerJoyRumbleRumk(JOY *pjoy, RUMK rumk, float dt); + +int FUN_001417f0(CHKPNT *pchkpnt, WKR *pwkr) +{ + if ((PO *)pwkr->ploSource == PpoCur()) + { + if (!(pwkr->grftak & 0x10)) + TriggerJoyRumbleRumk(&g_joy, RUMK_MediumThrob, 0.2f); + TriggerChkpnt(pchkpnt); + return 1; + } + + return FAbsorbSoWkr((SO *)pchkpnt, pwkr); +} INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", TriggerChkpnt__FP6CHKPNT); -INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", FUN_001419A0); +void FUN_001419A0(CHKPNT *pchkpnt, int n) +{ + int c = STRUCT_OFFSET(pchkpnt, 0x578, int); + int *a = &STRUCT_OFFSET(pchkpnt, 0x57c, int); + a[c] = n; + STRUCT_OFFSET(pchkpnt, 0x578, int) = c + 1; +} -INCLUDE_ASM("asm/nonmatchings/P2/chkpnt", FUN_001419C0); +void FUN_001419C0(CHKPNT *pchkpnt, int n) +{ + int c = STRUCT_OFFSET(pchkpnt, 0x550, int); + int *a = &STRUCT_OFFSET(pchkpnt, 0x554, int); + a[c] = n; + STRUCT_OFFSET(pchkpnt, 0x550, int) = c + 1; +} void FUN_001419E0(int *param_1, int param_2) { diff --git a/src/P2/clip.c b/src/P2/clip.c index b63fc4e13..17bbad895 100644 --- a/src/P2/clip.c +++ b/src/P2/clip.c @@ -20,7 +20,15 @@ INCLUDE_ASM("asm/nonmatchings/P2/clip", ClsgClipEdgeToCylinder__FP6VECTORT0fT0T0 JUNK_WORD(0x27BD01C0); -INCLUDE_ASM("asm/nonmatchings/P2/clip", SgnCompareMaa__FP3MAAT0); +int SgnCompareMaa(MAA *pmaa1, MAA *pmaa2) +{ + float d = pmaa1->u - pmaa2->u; + if (d < -1e-4f) + return -1; + if (1e-4f < d) + return 1; + return pmaa1->iu - pmaa2->iu; +} INCLUDE_ASM("asm/nonmatchings/P2/clip", ClsgMergeAlsg__FiP3LSG); diff --git a/src/P2/cm.c b/src/P2/cm.c index eed973555..557adac8b 100644 --- a/src/P2/cm.c +++ b/src/P2/cm.c @@ -5,6 +5,11 @@ #include #include #include +#include +#include +#include +#include +#include // todo fix data and rodata // VECTOR4 g_posEyeDefault = { 0.0f, -2000.0f, 500.0f, 0.0f }; @@ -197,13 +202,27 @@ INCLUDE_ASM("asm/nonmatchings/P2/cm", UpdateCmFade); INCLUDE_ASM("asm/nonmatchings/P2/cm", UpdateCmLast); -INCLUDE_ASM("asm/nonmatchings/P2/cm", SetupCmRotateToCam); +INCLUDE_ASM("asm/nonmatchings/P2/cm", SetupCmRotateToCam__FP2CM); INCLUDE_ASM("asm/nonmatchings/P2/cm", ConvertCmScreenToWorld); INCLUDE_ASM("asm/nonmatchings/P2/cm", ConvertCmWorldToScreen); -INCLUDE_ASM("asm/nonmatchings/P2/cm", SetupCm__FP2CM); +void SetupCm(CM *pcm) +{ + VECTOR4 vTmp; + GRFZON grfzon; + + SetupCmRotateToCam(pcm); + + if (g_psw != NULL) + { + STRUCT_OFFSET(&vTmp, 0, qword) = STRUCT_OFFSET(pcm, 0x40, qword); + ClipVismapPointNoHop(g_psw->pvismap, (VECTOR *)&vTmp, &grfzon); + if (grfzon != 0) + pcm->field39_0x21c = grfzon; + } +} INCLUDE_ASM("asm/nonmatchings/P2/cm", CombineEyeLookAtProj); @@ -211,21 +230,58 @@ INCLUDE_ASM("asm/nonmatchings/P2/cm", BuildFrustrum); INCLUDE_ASM("asm/nonmatchings/P2/cm", UpdateCmMat4); -INCLUDE_ASM("asm/nonmatchings/P2/cm", DrawCm__FP2CM); +void DrawCm(CM *pcm) +{ + g_vifs.AddDmaCnt(); + g_vifs.AddVifBaseOffset(0, 0); + g_vifs.AddVifUnpack(UPK_V4_32, 4, (uint8_t *)pcm + 0x100, 4); + g_vifs.AddVifUnpack(UPK_V4_32, 4, (uint8_t *)pcm + 0x140, 8); + g_vifs.EndDmaCnt(); +} INCLUDE_ASM("asm/nonmatchings/P2/cm", SetCmPosMat__FP2CMP6VECTORP7MATRIX3); -INCLUDE_ASM("asm/nonmatchings/P2/cm", SetCmLookAt); +void SetCmLookAt(CM *pcm, VECTOR *pposEye, VECTOR *pposCenter) +{ + SetCmLookAtSmooth(pcm, 0, pposEye, pposCenter, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); +} + +INCLUDE_ASM("asm/nonmatchings/P2/cm", ConvertWorldToCylindVelocity__FPvN50); + +INCLUDE_ASM("asm/nonmatchings/P2/cm", ConvertCylindToWorldVelocity__FPvN20fff); -INCLUDE_ASM("asm/nonmatchings/P2/cm", ConvertWorldToCylindVelocity); +void ResetCmLookAtSmooth(CM *pcm, void *pv) +{ + VECTOR4 vTmp; + + ConvertCylindToWorldVelocity(&STRUCT_OFFSET(pcm, 0x2d0, int), &STRUCT_OFFSET(pcm, 0x40, int), &vTmp, + STRUCT_OFFSET(pcm, 0x2b0, float), STRUCT_OFFSET(pcm, 0x2b4, float), STRUCT_OFFSET(pcm, 0x2b8, float)); + ConvertWorldToCylindVelocity(pv, &STRUCT_OFFSET(pcm, 0x40, int), &vTmp, + &STRUCT_OFFSET(pcm, 0x2b0, int), &STRUCT_OFFSET(pcm, 0x2b4, int), &STRUCT_OFFSET(pcm, 0x2b8, int)); + STRUCT_OFFSET(pcm, 0x2d0, qword) = *(qword *)pv; +} -INCLUDE_ASM("asm/nonmatchings/P2/cm", ConvertCylindToWorldVelocity); +INCLUDE_ASM("asm/nonmatchings/P2/cm", SetCmLookAtSmooth__FP2CMiP6VECTORT2iffffff); -INCLUDE_ASM("asm/nonmatchings/P2/cm", ResetCmLookAtSmooth); +void AdjustCmJoy(CM *pcm, JOY *pjoy, JOYID joyid, float *prad) +{ + float rad; -INCLUDE_ASM("asm/nonmatchings/P2/cm", SetCmLookAtSmooth); + switch (joyid) + { + case JOYID_Left: + rad = atan2f(-pjoy->x, pjoy->y); + break; + case JOYID_Right: + rad = atan2f(-pjoy->x2, pjoy->y2); + break; + default: + rad = 0.0f; + break; + } -INCLUDE_ASM("asm/nonmatchings/P2/cm", AdjustCmJoy__FP2CMP3JOY5JOYIDPf); + *prad = RadNormalize(rad + atan2f(STRUCT_OFFSET(pcm, 0x84, float), STRUCT_OFFSET(pcm, 0x80, float))); +} JUNK_WORD(0x0000102D); @@ -269,14 +325,10 @@ INCLUDE_ASM("asm/nonmatchings/P2/cm", FUN_00145950); INCLUDE_ASM("asm/nonmatchings/P2/cm", FUN_00145b68); -INCLUDE_ASM("asm/nonmatchings/P2/cm", FUN_00145DD8); -#ifdef SKIP_ASM -bool FUN_00145DD8(CM *pcm) +bool FUN_00145DD8(undefined4 unused, CM *pcm) { - return pcm->cptn.tMoveLast != 0; //If tMoveLast is a int/undefined4 it matches only it uses a0 instead of a1 :/ + return STRUCT_OFFSET(pcm, 0x538, int) != 0; } -#endif - INCLUDE_ASM("asm/nonmatchings/P2/cm", FUN_00145de8); INCLUDE_ASM("asm/nonmatchings/P2/cm", FUN_00145e68); diff --git a/src/P2/cnvo.c b/src/P2/cnvo.c index b1ff47bcd..1147fd188 100644 --- a/src/P2/cnvo.c +++ b/src/P2/cnvo.c @@ -34,3 +34,27 @@ void SetCnvoBeltSpeed(CNVO *pcnvo, float svBelt) } INCLUDE_ASM("asm/nonmatchings/P2/cnvo", MatchCnvoScrollerToBeltSpeed__FP4CNVO); +#ifdef SKIP_ASM +void MatchCnvoScrollerToBeltSpeed(CNVO *pcnvo) +{ + int c = STRUCT_OFFSET(pcnvo, 0x27c, int); + if (c <= 0) + return; + + void **arr = &STRUCT_OFFSET(pcnvo, 0x280, void *); + int i = 0; + do + { + void *pelem = arr[i]; + if (STRUCT_OFFSET(pelem, 0x8, int) == 6) + { + STRUCT_OFFSET(pelem, 0x2c, float) = + -(STRUCT_OFFSET(pcnvo, 0x550, float) * STRUCT_OFFSET(pcnvo, 0x554, float)); + STRUCT_OFFSET(pelem, 0x30, float) = + -(STRUCT_OFFSET(pcnvo, 0x550, float) * STRUCT_OFFSET(pcnvo, 0x558, float)); + return; + } + i = i + 1; + } while (i < STRUCT_OFFSET(pcnvo, 0x27c, int)); +} +#endif // SKIP_ASM diff --git a/src/P2/coin.c b/src/P2/coin.c index 1055822ec..e72336bd3 100644 --- a/src/P2/coin.c +++ b/src/P2/coin.c @@ -2,6 +2,9 @@ #include #include #include +#include +#include +#include void InitDprize(DPRIZE *pdprize) { @@ -35,7 +38,21 @@ void CloneDprize(DPRIZE *pdprize, DPRIZE *pdprizeBase) pdprize->ichkCollected = ichkCollected; } -INCLUDE_ASM("asm/nonmatchings/P2/coin", PostDprizeLoad__FP6DPRIZE); +void PostDprizeLoad(DPRIZE *pdprize) +{ + PostAloLoad(pdprize); + LO *plo = PloFindSwObjectByClass(pdprize->psw, 1, (CID)0x75, (LO *)pdprize); + pdprize->ptarget = (TARGET *)plo; + if (plo != NULL) + { + (*(void (**)(LO *))((char *)plo->pvtlo + 0x1C))(plo); + } + if (((STRUCT_OFFSET(g_pgsCur, 0x19D8, int) << 8) | STRUCT_OFFSET(g_pgsCur, 0x19DC, int)) != 0x308 && FGetChkmgrIchk(&g_chkmgr, pdprize->ichkCollected)) + { + pdprize->dprizesInit = DPRIZES_Removed; + } + (*(void (**)(DPRIZE *, DPRIZES))((char *)pdprize->pvtlo + 0xCC))(pdprize, pdprize->dprizesInit); +} INCLUDE_ASM("asm/nonmatchings/P2/coin", ProjectDprizeTransform__FP6DPRIZEfi); @@ -67,11 +84,30 @@ void InitCoin(COIN *pcoin) pcoin->lmDtMaxLifetime.gMax = 10.0f; } -INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00147ed0); +void FUN_00147ed0(DPRIZE *pdprize) +{ + // @todo: fix this vtable call + (*(void (**)(DPRIZE *, DPRIZES))((char *)pdprize->pvtlo + 0xCC))(pdprize, DPRIZES_Removed); +} INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00147ef8); -INCLUDE_ASM("asm/nonmatchings/P2/coin", UpdateCoin__FP4COINf); +extern int D_00270458; + +void UpdateDprize(DPRIZE *pdprize, float dt); + +void UpdateCoin(COIN *pcoin, float dt) +{ + UpdateDprize(pcoin, dt); + if (pcoin->oidInitialState != OID_Unknown) + return; + if (pcoin->fNeverReuse == 0) + return; + if (D_00270458 != 2) + pcoin->tLose -= g_clock.dt; + if (pcoin->tLose <= 0.0f) + (*(void (**)(COIN *, DPRIZES))((char *)pcoin->pvtlo + 0xCC))(pcoin, DPRIZES_Lose); +} INCLUDE_ASM("asm/nonmatchings/P2/coin", CreateSwCharm__FP2SW); @@ -178,13 +214,30 @@ INCLUDE_ASM("asm/nonmatchings/P2/coin", SetKeyDprizes__FP3KEY7DPRIZES); INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148698); -INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148718); +void PostDprizeLoad(DPRIZE *pdprize); + +void FUN_00148718(DPRIZE *pdprize) +{ + PostDprizeLoad(pdprize); + STRUCT_OFFSET(&g_note, 0x270, DPRIZE *) = pdprize; +} -INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148748); +void FUN_00148748(void *param_1) +{ + (*(void (**)(void *, int))(*(int *)param_1 + 0xCC))(param_1, 2); +} INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148770); -INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148828); +void FUN_00148828(DPRIZE *pdprize, float dt) +{ + UpdateDprize(pdprize, dt); + if (pdprize->oidInitialState != OID_Unknown) + return; + // @todo clean up this vtable call + if (STRUCT_OFFSET(pdprize->psw, 0x2308, float) <= g_clock.t) + (*(void (**)(DPRIZE *, DPRIZES))((char *)pdprize->pvtlo + 0xCC))(pdprize, DPRIZES_Lose); +} INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148888); @@ -201,16 +254,35 @@ INCLUDE_ASM("asm/nonmatchings/P2/coin", RemoveSwExtraneousCharms__FP2SW); INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148d90); -INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148e18); +void FUN_00148e18(void *param_1) +{ + // @todo clean up this vtable call + (*(void (**)(void *, int))(*(int *)param_1 + 0xCC))(param_1, 2); +} INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148e40); -INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00148ef8); +void FUN_00148ef8(COIN *pcoin, float dt) +{ + UpdateDprize(pcoin, dt); + if (pcoin->oidInitialState != OID_Unknown) + return; + if (pcoin->fNeverReuse == 0) + return; + if (D_00270458 != 2) + pcoin->tLose -= g_clock.dt; + if (pcoin->tLose <= 0.0f) // @todo clean up this vtable call + (*(void (**)(COIN *, DPRIZES))((char *)pcoin->pvtlo + 0xCC))(pcoin, DPRIZES_Lose); +} INCLUDE_ASM("asm/nonmatchings/P2/coin", increment_and_show_life_count); INCLUDE_ASM("asm/nonmatchings/P2/coin", CollectLifetkn__FP7LIFETKN); -INCLUDE_ASM("asm/nonmatchings/P2/coin", FUN_00149168); +void FUN_00149168(DPRIZE *pdprize) +{ + InitDprize(pdprize); + STRUCT_OFFSET(pdprize, 0x340, int) = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/coin", break_bottle); diff --git a/src/P2/cplcy.c b/src/P2/cplcy.c index 93b29f9c0..1a912a914 100644 --- a/src/P2/cplcy.c +++ b/src/P2/cplcy.c @@ -3,11 +3,20 @@ */ #include -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", InitCplcy); +void InitCplcy(CPLCY *pcplcy, CM *pcm) +{ + pcplcy->pcm = pcm; +} -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", FActiveCplcy); +int FActiveCplcy(CPLCY *pcplcy) +{ + return STRUCT_OFFSET(pcplcy->pcm, 0x3D8, CPLCY *) == pcplcy; +} -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", SetCpmanCpmt); +void SetCpmanCpmt(CPMAN *pcpman, CPMT cpmt) +{ + pcpman->cpmt = cpmt; +} void FUN_001493c0(void) { @@ -19,13 +28,47 @@ INCLUDE_ASM("asm/nonmatchings/P2/cplcy", FUN_00149458); INCLUDE_ASM("asm/nonmatchings/P2/cplcy", plays_binoc_sfx); -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", PushCplookLookk__FP6CPLOOK5LOOKK); +void PushCplookLookk(CPLOOK *pcplook, LOOKK lookk) +{ + int clookk = STRUCT_OFFSET(pcplook, 0x40, int); + if ((unsigned int)clookk < 4) + { + STRUCT_OFFSET_INDEX(pcplook, 0x30, LOOKK, clookk) = lookk; + STRUCT_OFFSET(pcplook, 0x40, int) = clookk + 1; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", LookkPopCplook__FP6CPLOOK); +LOOKK LookkPopCplook(CPLOOK *pcplook) +{ + int n = STRUCT_OFFSET(pcplook, 0x40, int); + if (n <= 0) + return (LOOKK)-1; + n = n - 1; + STRUCT_OFFSET(pcplook, 0x40, int) = n; + LOOKK *a = &STRUCT_OFFSET(pcplook, 0x30, LOOKK); + return a[n]; +} -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", LookkCurCplook__FP6CPLOOK); +LOOKK LookkCurCplook(CPLOOK *pcplook) +{ + int n = STRUCT_OFFSET(pcplook, 0x40, int); + if (n <= 0) + return (LOOKK)-1; + int i = n - 1; + LOOKK *a = &STRUCT_OFFSET(pcplook, 0x30, LOOKK); + return a[i]; +} -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", InitCplook); +void InitCplook(CPLOOK *pcplook, CM *pcm) +{ + InitCplcy(pcplook, pcm); + pcplook->fSoundPaused = 0; + pcplook->rZoomMax = 10.0f; + PushCplookLookk(pcplook, LOOKK_User); + pcplook->sRadiusSniper = 0.5f; + pcplook->rScreenSniper = -1.0f; + pcplook->ppntAnchor = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/cplcy", FUN_001496c0); @@ -35,7 +78,11 @@ INCLUDE_ASM("asm/nonmatchings/P2/cplcy", FUN_0014a7b8); INCLUDE_ASM("asm/nonmatchings/P2/cplcy", InitCpalign); -INCLUDE_ASM("asm/nonmatchings/P2/cplcy", FUN_0014a8d0); +void FUN_0014a8d0(CPALIGN *pcpalign) +{ + CM *pcm = pcpalign->pcm; + ResetCmLookAtSmooth(pcm, (void *)((uint8_t *)STRUCT_OFFSET(pcm, 0x3DC, void *) + 0x370)); +} INCLUDE_ASM("asm/nonmatchings/P2/cplcy", UpdateCpalign); diff --git a/src/P2/credit.c b/src/P2/credit.c index fdb8deabb..bca7f865a 100644 --- a/src/P2/credit.c +++ b/src/P2/credit.c @@ -1,17 +1,80 @@ #include +#include +#include + +struct CREDIT; INCLUDE_ASM("asm/nonmatchings/P2/credit", InitCredit__FP6CREDIT5BLOTK); INCLUDE_ASM("asm/nonmatchings/P2/credit", PostCreditLoad__FP6CREDIT); +#ifdef SKIP_ASM +void PostCreditLoad(CREDIT *pcredit) +{ + int i; + BLOT *pblot; + + PostBlotLoad((BLOT *)pcredit); + + pblot = (BLOT *)((char *)pcredit + 0x264); + for (i = 0; i < 4; i++) + { + pblot->pvtblot->pfnPostBlotLoad(pblot); + pblot->pte = 0; + STRUCT_OFFSET(pblot->pfont, 0x44, float) = 0.8f; + STRUCT_OFFSET(pblot->pfont, 0x48, float) = 0.8f; + SetBlotDtAppear(pblot, 1.0f); + SetBlotDtDisappear(pblot, 1.0f); + SetBlotDtVisible(pblot, 0.0f); + pblot = (BLOT *)((char *)pblot + 0x260); + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/credit", SetCreditClock__FP6CREDITPf); INCLUDE_ASM("asm/nonmatchings/P2/credit", UpdateCredit__FP6CREDIT); INCLUDE_ASM("asm/nonmatchings/P2/credit", DrawCredit__FP6CREDIT); +#ifdef SKIP_ASM +void DrawCredit(CREDIT *pcredit) +{ + extern int D_00275BEC; + + if (D_00275BEC == 1) + { + int i = 0; + float s = STRUCT_OFFSET(pcredit, 0x220, float); + + if (STRUCT_OFFSET(pcredit, 0x260, int) > 0) + { + char *pe = (char *)pcredit + 0x264; + do + { + float sSave = STRUCT_OFFSET(pe, 0x23C, float); + + STRUCT_OFFSET(pe, 0x220, float) = s; + STRUCT_OFFSET(pe, 0x21C, float) = STRUCT_OFFSET(pcredit, 0x21C, float); + STRUCT_OFFSET(pe, 0x23C, float) = sSave * g_rtClock; + + (*(void (**)(void *))(STRUCT_OFFSET(pe, 0x0, char *) + 0x24))(pe); + i++; + + STRUCT_OFFSET(pe, 0x23C, float) = sSave; + s = s + STRUCT_OFFSET(pe, 0x238, float); + pe += 0x260; + } while (i < STRUCT_OFFSET(pcredit, 0x260, int)); + } + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/credit", PlaceCredit__FP6CREDITffi); -INCLUDE_ASM("asm/nonmatchings/P2/credit", VacateCredit__FP6CREDIT); +struct CREDIT; + +void VacateCredit(CREDIT *pcredit) +{ + (*(void (**)(CREDIT *, int))((char *)*(void **)pcredit + 0x40))(pcredit, 0); +} INCLUDE_ASM("asm/nonmatchings/P2/credit", SetCreditLine__FP6CREDITiPcf); diff --git a/src/P2/crusher.c b/src/P2/crusher.c index a7766bbbf..c50be68ce 100644 --- a/src/P2/crusher.c +++ b/src/P2/crusher.c @@ -1,4 +1,7 @@ #include +#include +#include +#include /** * @todo Rename. @@ -67,21 +70,108 @@ INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014c2f0); INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014c5e8); -INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014c668); +extern void *D_0027C00C; +void FUN_0014c668(void *pv, int tnt) +{ + if (tnt != 1) + return; + + OID oidGoal; + OID oidCur; + + GetSmaGoal(STRUCT_OFFSET(D_0027C00C, 0x42c, SMA *), &oidGoal); + GetSmaCur(STRUCT_OFFSET(D_0027C00C, 0x42c, SMA *), &oidCur); + + if (oidGoal != (OID)0x3fe && oidCur != (OID)0x3fe) + { + SetSmaGoal(STRUCT_OFFSET(D_0027C00C, 0x42c, SMA *), (OID)0x3ff); + FUN_0014c5e8(D_0027C00C); + } +} INCLUDE_ASM("asm/nonmatchings/P2/crusher", update_crbrain); +#ifdef SKIP_ASM +void update_crbrain(CRBRAIN *p, float dt) +{ + OID oid; -INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014c788); + UpdateAlo(p, dt); + GetSmaCur(STRUCT_OFFSET(p, 0x42c, SMA *), &oid); -INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014c820); + if (oid == (OID)0x3fd) + { + CLOCK *pclock = &g_clock; -INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014c838); + if (STRUCT_OFFSET(p, 0x45c, float) < pclock->t) + FUN_0014c858(p); + + if (STRUCT_OFFSET(p, 0x460, float) < pclock->t) + FUN_0014cba8(p); + + PO *ppo = PpoCur(); + void *pvt = STRUCT_OFFSET(ppo, 0x0, void *); + void (*pfn)(PO *) = (void (*)(PO *))STRUCT_OFFSET(pvt, 0x144, void *); + pfn(ppo); + } +} +#endif // SKIP_ASM + +extern int FUN_001e9970(); +extern BLOT g_unkblot1; +extern BLOT g_unkblot9; + +void FUN_0014c788(void *pv) +{ + OID oid; + + GetSmaCur(STRUCT_OFFSET(pv, 0x42c, SMA *), &oid); + + int fShow = 0; + if (oid == (OID)0x3fd) + { + fShow = FUN_001e9970(); + } + + if (fShow) + { + g_unkblot1.pvtblot->pfnShowBlot(&g_unkblot1); + g_unkblot9.pvtblot->pfnShowBlot(&g_unkblot9); + } + else + { + g_unkblot1.pvtblot->pfnHideBlot(&g_unkblot1); + g_unkblot9.pvtblot->pfnHideBlot(&g_unkblot9); + } +} + +void *FUN_0014c820(void *p) +{ + int idx = STRUCT_OFFSET(p, 0x690, int); + return (uint8_t *)p + (idx * 0xB0 + 0x480); +} + +void FUN_0014c838(void *p, int value) +{ + int n = STRUCT_OFFSET(p, 0x2dc, int); + STRUCT_OFFSET(p, 0x2dc, int) = n + 1; + STRUCT_OFFSET((uint8_t *)p + n * 0x14, 0x2e0, int) = value; +} INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014c858); INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014cba8); -INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014cd70); +void FUN_0014cd70(void *p) +{ + if (STRUCT_OFFSET(p, 0x458, int) == STRUCT_OFFSET(p, 0x450, int)) + { + float g = GRandInRange(STRUCT_OFFSET(p, 0x43c, float), STRUCT_OFFSET(p, 0x440, float)); + STRUCT_OFFSET(p, 0x45c, float) = g_clock.t + g; + } + + int n = STRUCT_OFFSET(p, 0x458, int); + STRUCT_OFFSET(p, 0x458, int) = n - 1; +} INCLUDE_ASM("asm/nonmatchings/P2/crusher", FUN_0014cdc8); diff --git a/src/P2/crv.c b/src/P2/crv.c index 2acc79845..9cddebdae 100644 --- a/src/P2/crv.c +++ b/src/P2/crv.c @@ -1,8 +1,34 @@ #include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/crv", SMeasureApos__FiP6VECTORPf); -INCLUDE_ASM("asm/nonmatchings/P2/crv", GWrapApos__FfiPfi); +float GWrapApos(float g, int cpos, float *mpiposg, int fClosed) +{ + float f0 = g; + if (!fClosed) + { + return f0; + } + + float f1 = mpiposg[0]; + float f3 = mpiposg[cpos - 1]; + float f2 = f3 - f1; + + while (f0 < f1) + { + f0 = f0 + f2; + } + + while (f3 < f0) + { + f0 = f0 - f2; + } + + return f0; +} INCLUDE_ASM("asm/nonmatchings/P2/crv", IposFindAposG__FfiPfiT2T2); @@ -14,47 +40,153 @@ INCLUDE_ASM("asm/nonmatchings/P2/crv", FindAposClosestPointSegment__FP6VECTORP6C INCLUDE_ASM("asm/nonmatchings/P2/crv", ConvertApos__FiP6VECTORP7MATRIX4T2); -INCLUDE_ASM("asm/nonmatchings/P2/crv", PcrvNew__F4CRVK); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", SFromCrvU__FP3CRVf); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", UFromCrvS__FP3CRVf); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", IcvFindCrvU__FP3CRVfPfT2); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", IcvFindCrvS__FP3CRVfPfT2); +extern char D_002176D0[]; +extern char D_00217708[]; + +CRV *PcrvNew(CRVK crvk) +{ + CRV *pcrv; + + switch (crvk) + { + case CRVK_Linear: + pcrv = (CRV *)PvAllocSwClearImpl(0x1C); + pcrv->unknown = (undefined4)&D_002176D0; + break; + case CRVK_Cubic: + pcrv = (CRV *)PvAllocSwClearImpl(0x1D0); + pcrv->unknown = (undefined4)&D_00217708; + break; + default: + pcrv = NULL; + break; + } + + if (pcrv != NULL) + pcrv->crvk = crvk; + + return pcrv; +} + +float SFromCrvU(CRV *pcrv, float u) +{ + return 0.0f; +} + +float UFromCrvS(CRV *pcrv, float s) +{ + return 0.0f; +} + +int IcvFindCrvU(CRV *pcrv, float u, float *du, float *duSeg) +{ + return IposFindAposG(u, pcrv->ccv, pcrv->mpicvu, pcrv->fClosed, du, duSeg); +} + +int IcvFindCrvS(CRV *pcrv, float s, float *ds, float *dsSeg) +{ + return IposFindAposG(s, pcrv->ccv, pcrv->mpicvs, pcrv->fClosed, ds, dsSeg); +} INCLUDE_ASM("asm/nonmatchings/P2/crv", GMeasureCrvU__FP5CRVMCf); -INCLUDE_ASM("asm/nonmatchings/P2/crv", UMaxCrv__FP3CRV); +float UMaxCrv(CRV *pcrv) +{ + return pcrv->mpicvu[pcrv->ccv - 1]; +} -INCLUDE_ASM("asm/nonmatchings/P2/crv", SMaxCrv__FP3CRV); +float SMaxCrv(CRV *pcrv) +{ + return pcrv->mpicvs[pcrv->ccv - 1]; +} JUNK_ADDIU(A0); -INCLUDE_ASM("asm/nonmatchings/P2/crv", SMeasureCrvSegmentU__FP5CRVMSf); +float SMeasureCrvSegmentU(CRVMS *pcrvms, float u) +{ + void *pcrv = STRUCT_OFFSET(pcrvms, 0x0, void *); + void **pvtbl = STRUCT_OFFSET(pcrv, 0x0, void **); + void (*pfn)(void *, VECTOR *, int) = (void (*)(void *, VECTOR *, int))pvtbl[1]; + VECTOR pos; + + if (pfn != NULL) + { + pfn(pcrv, &pos, 0); + } + + float du, ps; + FindClosestPointOnLineSegment(&pos, STRUCT_OFFSET(pcrvms, 0x4, VECTOR *), STRUCT_OFFSET(pcrvms, 0x8, VECTOR *), &du, &ps); + return ps; +} INCLUDE_ASM("asm/nonmatchings/P2/crv", FindCrvClosestPointOnLineSegmentFromU__FP3CRVP6VECTORT1fT1T1PfT6); JUNK_ADDIU(A0); -INCLUDE_ASM("asm/nonmatchings/P2/crv", DuGetCrvSearchIncrement__FP3CRV); +float DuGetCrvSearchIncrement(CRV *pcrv) +{ + return (pcrv->mpicvu[1] - pcrv->mpicvu[0]) * 0.1f; +} INCLUDE_ASM("asm/nonmatchings/P2/crv", LoadCrvlFromBrx__FP4CRVLP18CBinaryInputStream); -INCLUDE_ASM("asm/nonmatchings/P2/crv", EvaluateCrvlFromU__FP4CRVLfP6VECTORT2); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", EvaluateCrvlFromS__FP4CRVLfP6VECTORT2); +void EvaluateCrvlFromU(CRVL *pcrvl, float u, VECTOR *ppos, VECTOR *pnormTangent) +{ + EvaluateAposG( + u, + STRUCT_OFFSET(pcrvl, 0xC, int), + STRUCT_OFFSET(pcrvl, 0x18, VECTOR *), + STRUCT_OFFSET(pcrvl, 0x10, float *), + STRUCT_OFFSET(pcrvl, 0x8, int), + ppos, + pnormTangent); +} + +void EvaluateCrvlFromS(CRVL *pcrvl, float s, VECTOR *ppos, VECTOR *pnormTangent) +{ + EvaluateAposG( + s, + STRUCT_OFFSET(pcrvl, 0xC, int), + STRUCT_OFFSET(pcrvl, 0x18, VECTOR *), + STRUCT_OFFSET(pcrvl, 0x14, float *), + STRUCT_OFFSET(pcrvl, 0x8, int), + ppos, + pnormTangent); +} INCLUDE_ASM("asm/nonmatchings/P2/crv", RenderCrvlSegment__FP4CRVLiP7MATRIX4P2CMG4RGBAi); -INCLUDE_ASM("asm/nonmatchings/P2/crv", ConvertCrvl__FP4CRVLP7MATRIX4T1); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", SFromCrvlU__FP4CRVLf); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", UFromCrvlS__FP4CRVLf); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", MeasureCrvl__FP4CRVL); +void ConvertCrvl(CRVL *pcrvl, MATRIX4 *pmatSrc, MATRIX4 *pmatDst) +{ + ConvertApos(STRUCT_OFFSET(pcrvl, 0xC, int), STRUCT_OFFSET(pcrvl, 0x18, VECTOR *), pmatSrc, pmatDst); +} + +float SFromCrvlU(CRVL *pcrvl, float u) +{ + float du; + float duSeg; + + int icv = IcvFindCrvU((CRV *)pcrvl, u, &du, &duSeg); + float frac = du / duSeg; + float *mpicvs = ((CRV *)pcrvl)->mpicvs; + return (1.0f - frac) * mpicvs[icv] + frac * mpicvs[icv + 1]; +} + +float UFromCrvlS(CRVL *pcrvl, float s) +{ + float ds, dsSeg; + int icv = IcvFindCrvS((CRV *)pcrvl, s, &ds, &dsSeg); + float *mpicvu = STRUCT_OFFSET(pcrvl, 0x10, float *); + float u0 = mpicvu[icv]; + float u1 = mpicvu[icv + 1]; + float result = (1.0f - (ds / dsSeg)) * u0 + (ds / dsSeg) * u1; + return result; +} + +void MeasureCrvl(CRVL *pcrvl) +{ + SMeasureApos(STRUCT_OFFSET(pcrvl, 0xC, int), STRUCT_OFFSET(pcrvl, 0x18, VECTOR *), STRUCT_OFFSET(pcrvl, 0x14, float *)); +} INCLUDE_ASM("asm/nonmatchings/P2/crv", FindCrvlClosestPointAll__FP4CRVLP6VECTORP6CONSTRT1T1PfT5); @@ -62,23 +194,84 @@ INCLUDE_ASM("asm/nonmatchings/P2/crv", FindCrvlClosestPointFromU__FP4CRVLP6VECTO INCLUDE_ASM("asm/nonmatchings/P2/crv", FindCrvlClosestPointFromS__FP4CRVLP6VECTORfP6CONSTRT1T1PfT6); -INCLUDE_ASM("asm/nonmatchings/P2/crv", LoadCrvcFromBrx__FP4CRVCP18CBinaryInputStream); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", InvalidateCrvcCache__FP4CRVC); +void LoadCrvcFromBrx(CRVC *pcrvc, CBinaryInputStream *pbis) +{ + STRUCT_OFFSET(pcrvc, 0x8, int) = pbis->U8Read(); + int ccv = pbis->U8Read(); + STRUCT_OFFSET(pcrvc, 0xC, int) = ccv; + STRUCT_OFFSET(pcrvc, 0x10, void *) = PvAllocSwImpl(ccv * 4); + STRUCT_OFFSET(pcrvc, 0x14, void *) = PvAllocSwImpl(STRUCT_OFFSET(pcrvc, 0xC, int) * 4); + STRUCT_OFFSET(pcrvc, 0x18, void *) = PvAllocSwImpl(STRUCT_OFFSET(pcrvc, 0xC, int) * 16); + STRUCT_OFFSET(pcrvc, 0x1C, void *) = PvAllocSwImpl(STRUCT_OFFSET(pcrvc, 0xC, int) * 16); + STRUCT_OFFSET(pcrvc, 0x20, void *) = PvAllocSwImpl(STRUCT_OFFSET(pcrvc, 0xC, int) * 16); + + for (int icv = 0; icv < STRUCT_OFFSET(pcrvc, 0xC, int); icv++) + { + STRUCT_OFFSET(pcrvc, 0x10, float *) + [icv] = pbis->F32Read(); + pbis->ReadVector((VECTOR *)((char *)STRUCT_OFFSET(pcrvc, 0x18, void *) + icv * 16)); + pbis->ReadVector((VECTOR *)((char *)STRUCT_OFFSET(pcrvc, 0x1C, void *) + icv * 16)); + pbis->ReadVector((VECTOR *)((char *)STRUCT_OFFSET(pcrvc, 0x20, void *) + icv * 16)); + } + + if (STRUCT_OFFSET(*(void **)pcrvc, 0x24, void *) != NULL) + { + ((void (*)(CRVC *))STRUCT_OFFSET(*(void **)pcrvc, 0x24, void *))(pcrvc); + } + + InvalidateCrvcCache(pcrvc); +} + +void InvalidateCrvcCache(CRVC *pcrvc) +{ + STRUCT_OFFSET(pcrvc, 0x1c0, int) = -1; +} INCLUDE_ASM("asm/nonmatchings/P2/crv", FillCrvcCache__FP4CRVCi); INCLUDE_ASM("asm/nonmatchings/P2/crv", EvaluateCrvcFromU__FP4CRVCfP6VECTORT2); -INCLUDE_ASM("asm/nonmatchings/P2/crv", EvaluateCrvcFromS__FP4CRVCfP6VECTORT2); +void EvaluateCrvcFromS(CRVC *pcrvc, float s, VECTOR *ppos, VECTOR *pnormTangent) +{ + float u = ((float (*)(CRVC *, float))STRUCT_OFFSET(*(void **)pcrvc, 0x18, void *))(pcrvc, s); + if (STRUCT_OFFSET(*(void **)pcrvc, 0x4, void *)) + { + ((void (*)(CRVC *, float, VECTOR *, VECTOR *))STRUCT_OFFSET(*(void **)pcrvc, 0x4, void *))(pcrvc, u, ppos, pnormTangent); + } +} INCLUDE_ASM("asm/nonmatchings/P2/crv", RenderCrvcSegment__FP4CRVCiP7MATRIX4P2CMG4RGBAi); INCLUDE_ASM("asm/nonmatchings/P2/crv", ConvertCrvc__FP4CRVCP7MATRIX4T1); -INCLUDE_ASM("asm/nonmatchings/P2/crv", SFromCrvcU__FP4CRVCf); - -INCLUDE_ASM("asm/nonmatchings/P2/crv", UFromCrvcS__FP4CRVCf); +float SFromCrvcU(CRVC *pcrvc, float u) +{ + float du; + float duSeg; + + int icv = IcvFindCrvU((CRV *)pcrvc, u, &du, &duSeg); + + return SBezierPosLength( + duSeg, + du, + (VECTOR *)((char *)STRUCT_OFFSET(pcrvc, 0x18, void *) + icv * 16), + (VECTOR *)((char *)STRUCT_OFFSET(pcrvc, 0x20, void *) + icv * 16), + (VECTOR *)((char *)STRUCT_OFFSET(pcrvc, 0x18, void *) + (icv * 16 + 16)), + (VECTOR *)((char *)STRUCT_OFFSET(pcrvc, 0x1C, void *) + (icv * 16 + 16))) + + STRUCT_OFFSET(pcrvc, 0x14, float *)[icv]; +} + +float UFromCrvcS(CRVC *pcrvc, float s) +{ + float g, dg, dgSeg; + + int icv = IcvFindCrvS((CRV *)pcrvc, s, &g, NULL); + FillCrvcCache(pcrvc, icv); + int ipos = IposFindAposG(g, 0x14, &STRUCT_OFFSET(pcrvc, 0x170, float), 0, &dg, &dgSeg); + float *pmp = STRUCT_OFFSET(pcrvc, 0x10, float *); + float u = ((float)ipos + dg / dgSeg) * (1.0f / 19.0f); + return (1.0f - u) * pmp[icv] + u * pmp[icv + 1]; +} INCLUDE_ASM("asm/nonmatchings/P2/crv", MeasureCrvc__FP4CRVC); diff --git a/src/P2/dart.c b/src/P2/dart.c index 085e0d216..630b25be0 100644 --- a/src/P2/dart.c +++ b/src/P2/dart.c @@ -10,7 +10,24 @@ void InitDart(DART *pdart) SetDartDarts(pdart, DARTS_Nil); } -INCLUDE_ASM("asm/nonmatchings/P2/dart", OnDartAdd__FP4DART); +void OnDartAdd(DART *pdart) +{ + OnSoAdd(pdart); + + if (FFindDlEntry(&pdart->psw->dlDartFree, pdart)) + { + RemoveDlEntry(&pdart->psw->dlDartFree, pdart); + } + + if (STRUCT_OFFSET(pdart, 0x18, ALO *) && FIsBasicDerivedFrom((BASIC *)STRUCT_OFFSET(pdart, 0x18, ALO *), CID_IKH)) + { + STRUCT_OFFSET(pdart, 0x538, unsigned long long) |= ((unsigned long long)0x8000 << 28); + } + else + { + STRUCT_OFFSET(pdart, 0x538, unsigned long long) &= ~((unsigned long long)0x8000 << 28); + } +} void RemoveDart(DART *pdart) { diff --git a/src/P2/dartgun.c b/src/P2/dartgun.c index 7d24d65ea..61ebf60fd 100644 --- a/src/P2/dartgun.c +++ b/src/P2/dartgun.c @@ -1,4 +1,10 @@ #include +#include +#include +#include +#include +#include +#include void InitDartgun(DARTGUN *pdartgun) { @@ -6,23 +12,159 @@ void InitDartgun(DARTGUN *pdartgun) STRUCT_OFFSET(pdartgun, 0x6c0, OID) = OID_Nil; // pdartgun->oidDart } -INCLUDE_ASM("asm/nonmatchings/P2/dartgun", HandleDartgunMessage__FP7DARTGUN5MSGIDPv); +void HandleDartgunMessage(DARTGUN *pdartgun, MSGID msgid, void *pv) +{ + OID oid; + ALO *palo; + + HandleAloMessage((ALO *)pdartgun, msgid, pv); + + if (msgid != (MSGID)0x14) + return; + + if (pv != STRUCT_OFFSET(pdartgun, 0x740, void *)) + return; + + GetSmaGoal((SMA *)pv, &oid); + if (oid != (OID)0x2B7) + return; + + if (STRUCT_OFFSET(pdartgun, 0x680, int) != 0) + { + RetractSma(STRUCT_OFFSET(pdartgun, 0x740, SMA *)); + STRUCT_OFFSET(pdartgun, 0x740, int) = 0; + } + else + { + STRUCT_OFFSET(STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x734, char *), 0x200, char *), 0x4C, int) = 1; + STRUCT_OFFSET(STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x734, char *), 0x200, char *), 0x1C, int) = 0; + + // @todo check these vtable call + palo = STRUCT_OFFSET(pdartgun, 0x734, ALO *); + (*(void (**)(ALO *, void *))((char *)palo->pvtlo + 0x84))(palo, (char *)palo + 0x190); + palo = STRUCT_OFFSET(pdartgun, 0x734, ALO *); + (*(void (**)(ALO *, void *))((char *)palo->pvtlo + 0x88))(palo, (char *)palo + 0x1A0); + palo = STRUCT_OFFSET(pdartgun, 0x738, ALO *); + (*(void (**)(ALO *, void *))((char *)palo->pvtlo + 0x88))(palo, (char *)palo + 0x1A0); + } +} INCLUDE_ASM("asm/nonmatchings/P2/dartgun", BindDartgun__FP7DARTGUN); -INCLUDE_ASM("asm/nonmatchings/P2/dartgun", FUN_0014f900); +void FUN_0014f900(DARTGUN* pdartgun) +{ + if (g_pjt == NULL) + return; + + STRUCT_OFFSET(pdartgun, 0x6dc, int) = STRUCT_OFFSET(g_pjt, 0x24f8, int); +} INCLUDE_ASM("asm/nonmatchings/P2/dartgun", PostDartgunLoad__FP7DARTGUN); INCLUDE_ASM("asm/nonmatchings/P2/dartgun", UpdateDartgun__FP7DARTGUNf); -INCLUDE_ASM("asm/nonmatchings/P2/dartgun", FIgnoreDartgunIntersection__FP7DARTGUNP2SO); +int FIgnoreDartgunIntersection(DARTGUN *pdartgun, SO *psoOther) +{ + if (FIsBasicDerivedFrom(psoOther, CID_RAT) + && STRUCT_OFFSET(psoOther, 0x588, SO *) == (SO *)pdartgun) + { + return 1; + } + + return FIgnoreSoIntersection((SO *)pdartgun, psoOther); +} + +void BreakDartgun(DARTGUN *pdartgun) +{ + ALO *palo = STRUCT_OFFSET(pdartgun, 0x6c8, ALO *); + if (palo != NULL) + { + (*(void (**)(ALO *, int))((char *)palo->pvtlo + 0x64))(palo, 0); + palo = STRUCT_OFFSET(pdartgun, 0x6c8, ALO *); + (*(void (**)(ALO *))((char *)palo->pvtlo + 0x1c))(palo); + } + + SMA *psma = STRUCT_OFFSET(pdartgun, 0x740, SMA *); + OID oidCur; + if (psma != NULL) + { + SeekSma(psma, (OID)0x2B7); + GetSmaCur(STRUCT_OFFSET(pdartgun, 0x740, SMA *), &oidCur); + if (oidCur == (OID)0x2B7) + { + RetractSma(STRUCT_OFFSET(pdartgun, 0x740, SMA *)); + STRUCT_OFFSET(pdartgun, 0x740, int) = 0; + } + } -INCLUDE_ASM("asm/nonmatchings/P2/dartgun", BreakDartgun__FP7DARTGUN); + palo = STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x734, char *), 0x200, ALO *); + // @todo clean up this vtable call + (*(void (**)(ALO *, int))((char *)palo->pvtlo + 0x8))(palo, 7); -INCLUDE_ASM("asm/nonmatchings/P2/dartgun", SetDartgunGoalState__FP7DARTGUN3OID); + BreakBrk((BRK *)pdartgun); +} -INCLUDE_ASM("asm/nonmatchings/P2/dartgun", TrackDartgun__FP7DARTGUNP3OID); +void SetDartgunGoalState(DARTGUN *pdartgun, OID oidStateGoal) +{ + OID oidCur; + + GetSmaGoal(STRUCT_OFFSET(pdartgun, 0x740, SMA *), &oidCur); + if (oidCur == OID_Nil) + GetSmaCur(STRUCT_OFFSET(pdartgun, 0x740, SMA *), &oidCur); + + if (oidStateGoal == oidCur) + return; + + if (oidCur == (OID)0x2B7) + { + STRUCT_OFFSET(STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x734, char *), 0x200, char *), 0x4C, int) = 0; + } + + if (oidStateGoal < (OID)0x2BA) + { + if (oidStateGoal >= (OID)0x2B8) + { + STRUCT_OFFSET(STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x734, char *), 0x200, char *), 0x1C, int) = (oidStateGoal == (OID)0x2B9); + if ((unsigned int)(oidCur - 0x2BA) >= 2) + STRUCT_OFFSET(pdartgun, 0x6D8, int) = 0; + } + } + + SetSmaGoal(STRUCT_OFFSET(pdartgun, 0x740, SMA *), oidStateGoal); +} + +void TrackDartgun(DARTGUN *pdartgun, OID *poidStateGoal) +{ + if (*poidStateGoal == (OID)0x2B8) + { + STRUCT_OFFSET(STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x734, char *), 0x200, char *), 0x1C, int) = 0; + if (STRUCT_OFFSET(pdartgun, 0x6D0, float) < g_clock.t - STRUCT_OFFSET(pdartgun, 0x6D8, float)) + { + if (FPrepareDartgunToFire(pdartgun)) + *poidStateGoal = (OID)0x2BA; + } + } + else + { + LO *plo = STRUCT_OFFSET(pdartgun, 0x6E0, LO *); + if (plo == NULL || !FIsLoInWorld(plo) || + STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x6E0, SO *), 0x550, int) == 3 || + STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x6E0, SO *), 0x550, int) == 4) + { + STRUCT_OFFSET(pdartgun, 0x6E0, RAT *) = PratGetDartgunRatTarget(pdartgun); + } + + if (STRUCT_OFFSET(pdartgun, 0x6E0, RAT *) != NULL) + { + SetActlaTarget((ACTLA *)STRUCT_OFFSET(STRUCT_OFFSET(pdartgun, 0x734, char *), 0x200, char *), + (ALO *)STRUCT_OFFSET(pdartgun, 0x6E0, ALO *), &D_00248D30); + if (STRUCT_OFFSET(pdartgun, 0x6D0, float) < g_clock.t - STRUCT_OFFSET(pdartgun, 0x6D8, float) && FPrepareDartgunToFire(pdartgun)) + { + *poidStateGoal = (OID)0x2BB; + } + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/dartgun", FPrepareDartgunToFire__FP7DARTGUN); diff --git a/src/P2/dialog.c b/src/P2/dialog.c index 03b31ec89..684231616 100644 --- a/src/P2/dialog.c +++ b/src/P2/dialog.c @@ -24,7 +24,21 @@ void LoadDialogFromBrx(DIALOG *pdialog, CBinaryInputStream *pbis) INCLUDE_ASM("asm/nonmatchings/P2/dialog", LoadDialogEventsFromBrx__FP6DIALOGP18CBinaryInputStreamPiPP2DE); -INCLUDE_ASM("asm/nonmatchings/P2/dialog", PostDialogLoad__FP6DIALOG); +void PostDialogLoad(DIALOG *pdialog) +{ + PostAloLoad(pdialog); + + if (STRUCT_OFFSET(pdialog, 0x30c, OID) == OID_Nil) + { + STRUCT_OFFSET(pdialog, 0x30c, OID) = STRUCT_OFFSET(pdialog, 0x8, OID); + } + + STRUCT_OFFSET(pdialog, 0x304, int *) = PfLookupDialog(g_plsCur, STRUCT_OFFSET(pdialog, 0x30c, OID)); + if (STRUCT_OFFSET(pdialog, 0x304, int *) == NULL) + { + STRUCT_OFFSET(pdialog, 0x304, int *) = &STRUCT_OFFSET(pdialog, 0x308, int); + } +} void SetDialogInstruct(DIALOG *pdialog) { diff --git a/src/P2/difficulty.c b/src/P2/difficulty.c index 4fe892f3d..af3db692e 100644 --- a/src/P2/difficulty.c +++ b/src/P2/difficulty.c @@ -112,40 +112,28 @@ void OnDifficultyInitialTeleport(DIFFICULTY *pdifficulty) INCLUDE_ASM("asm/nonmatchings/P2/difficulty", OnDifficultyPlayerDeath); #ifdef SKIP_ASM -/** - * @todo 88.43% matched. - */ -void OnDifficultyPlayerDeath(float scalar, DIFFICULTY* pdifficulty) +void OnDifficultyPlayerDeath(float scalar, DIFFICULTY *pdifficulty) { - DIFFICULTYLEVEL* pdifflevel = pdifficulty->pDifficultyLevel; + DIFFICULTYLEVEL *pdifflevel = pdifficulty->pDifficultyLevel; - // Get suck values for current level - float uSuckCur = g_plsCur->uSuck; - float duSuckDeath = pdifflevel->duSuckDeath; + ChangeSuck(g_plsCur->uSuck + scalar * STRUCT_OFFSET(pdifflevel, 0x10, float), pdifficulty); - // Increase suck value - ChangeSuck(uSuckCur + scalar * duSuckDeath, pdifficulty); - - // Update suckunknown_0x10 + int clife = g_pgsCur->clife; float result; - if (g_pgsCur->clife < 0) + if (clife < 0) { - // itgame over - result = pdifficulty->pDifficultyLevel->field18_0x40; + result = STRUCT_OFFSET(pdifficulty->pDifficultyLevel, 0x40, float); } else { - // not game over - result = pdifflevel->field17_0x3c; - if (g_pgsCur->clife <= pdifflevel->field21_0x4c) - { - result = result + pdifflevel->field22_0x50; - } + result = STRUCT_OFFSET(pdifflevel, 0x3c, float); + if (clife <= STRUCT_OFFSET(pdifflevel, 0x4c, int)) + result = result + STRUCT_OFFSET(pdifflevel, 0x50, float); } - result = GLimitLm(&g_lmZeroOne, g_plsCur->unk_suck_0x10 + scalar * result); - g_plsCur->unk_suck_0x10 = result; + + g_plsCur->unk_suck_0x10 = GLimitLm(&g_lmZeroOne, g_plsCur->unk_suck_0x10 + scalar * result); } -#endif +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/difficulty", OnDifficultyTriggerCheckpoint__FP10DIFFICULTYP6CHKPNT); #ifdef SKIP_ASM diff --git a/src/P2/dmas.c b/src/P2/dmas.c index 7cf903c53..ebe9b5cb1 100644 --- a/src/P2/dmas.c +++ b/src/P2/dmas.c @@ -2,6 +2,7 @@ #include #include #include +#include extern sceDmaChan *g_pdcVif0; extern sceDmaChan *g_pdcVif1; @@ -120,83 +121,81 @@ void DMAS::AddDmaCnt() EndDmaCnt(); QW *pqw = (QW *)m_pb; m_pqwCnt = pqw; - m_pb = (uchar *)(pqw + 1); - m_pqwCnt->aul[0] = 0x10000000; + m_pb += sizeof(QW); + pqw->aul[0] = 0x10000000; m_pqwCnt->aul[1] = 0; } -/** - * @todo 86.42% match. - */ -INCLUDE_ASM("asm/nonmatchings/P2/dmas", AddDmaRefs__4DMASiP2QW); -#ifdef SKIP_ASM void DMAS::AddDmaRefs(int cqw, QW *aqw) { + int fCnt = 0; + if (m_pqwCnt) { EndDmaCnt(); + fCnt = 1; } - QW *pqw = ((QW *)m_pb)++; - pqw->aul[0] = cqw | 0x40000000 | ((ulong)aqw << 0x20); - pqw->aul[1] = 0; + uchar *pb = m_pb; + m_pb = pb + 0x10; + *(ulong *)pb = (cqw | 0x40000000) | ((ulong)(uint)aqw << 32); + *(ulong *)(pb + 8) = 0; - if (m_pqwCnt) + if (fCnt) { - QW *pqw = (QW *)m_pb; - m_pqwCnt = pqw; - m_pb = (uchar *)(pqw + 1); - m_pqwCnt->aul[0] = 0x10000000; + QW *pqwCnt = (QW *)m_pb; + m_pqwCnt = pqwCnt; + m_pb += sizeof(QW); + pqwCnt->aul[0] = 0x10000000; m_pqwCnt->aul[1] = 0; } } -#endif // SKIP_ASM -/** - * @todo 85.12% match. - */ -INCLUDE_ASM("asm/nonmatchings/P2/dmas", AddDmaCall__4DMASP2QW); -#ifdef SKIP_ASM -void DMAS::AddDmaCall(QW *aqw) +void DMAS::AddDmaCall(QW *pqw) { + int fCnt = 0; + if (m_pqwCnt) { EndDmaCnt(); + fCnt = 1; } - QW *pqw = ((QW *)m_pb)++; - pqw->aul[0] = ((ulong)aqw << 0x20) | 0x50000000; - pqw->aul[1] = 0; + uchar *pb = m_pb; + m_pb = pb + 0x10; + *(ulong *)pb = ((ulong)(uint)pqw << 32) | 0x50000000; + *(ulong *)(pb + 8) = 0; - if (m_pqwCnt) + if (fCnt) { - QW *pqw = (QW *)m_pb; - m_pqwCnt = pqw; - m_pb = (uchar *)(pqw + 1); - m_pqwCnt->aul[0] = 0x10000000; + QW *pqwCnt = (QW *)m_pb; + m_pqwCnt = pqwCnt; + m_pb += sizeof(QW); + pqwCnt->aul[0] = 0x10000000; m_pqwCnt->aul[1] = 0; } } -#endif // SKIP_ASM void DMAS::AddDmaRet() { EndDmaCnt(); - QW *pqw = ((QW *)m_pb)++; - pqw->aul[0] = 0x60000000; - pqw->aul[1] = 0; + uchar *pb = m_pb; + m_pb = pb + 0x10; + *(ulong *)pb = 0x60000000; + *(ulong *)(pb + 8) = 0; } -void DMAS::AddDmaBulk(int cqw, QW *aqw) +void DMAS::AddDmaBulk(int c, QW *aqw) { - CopyAqw(m_pb, aqw, cqw); - m_pb += (cqw * sizeof(QW)); + CopyAqw(m_pb, aqw, c); + m_pb += c * sizeof(QW); } void DMAS::AddDmaEnd() { EndDmaCnt(); - QW *pqw = ((QW *)m_pb)++; + QW *pqw = (QW *)m_pb; + m_pb += sizeof(QW); pqw->aul[0] = 0x70000000; pqw->aul[1] = 0; } diff --git a/src/P2/dysh.c b/src/P2/dysh.c index 7b15c3f71..1772968ee 100644 --- a/src/P2/dysh.c +++ b/src/P2/dysh.c @@ -1,9 +1,31 @@ #include +#include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/dysh", InitDysh__FP4DYSH); +void InitDysh(DYSH* pdysh) +{ + InitAlo((ALO*)pdysh); +} INCLUDE_ASM("asm/nonmatchings/P2/dysh", SetDyshShadow__FP4DYSHP6SHADOW); -INCLUDE_ASM("asm/nonmatchings/P2/dysh", RenderDyshSelf__FP4DYSHP2CMP2RO); +void RenderDyshSelf(DYSH* pdysh, CM* pcm, RO* pro) +{ + RPL rpl; + + if (STRUCT_OFFSET(pdysh, 0x2D0, int)) + { + void** pvtbl = STRUCT_OFFSET(pdysh, 0x0, void**); + ((void (*)(DYSH*, RO*))pvtbl[0xAC / 4])(pdysh, pro); + + memset(&rpl, 0, 0x80); + rpl.pfnDraw = DrawDysh; + rpl.rp = RP_DynamicTexture; + DupAloRo((ALO*)pdysh, pro, (RO*)((char*)&rpl + 0x10)); + STRUCT_OFFSET(&rpl, 0x60, DYSH*) = pdysh; + SubmitRpl(&rpl); + } +} INCLUDE_ASM("asm/nonmatchings/P2/dysh", DrawDysh__FP3RPL); diff --git a/src/P2/dzg.c b/src/P2/dzg.c index 3e8654e1d..f6bb0bf7e 100644 --- a/src/P2/dzg.c +++ b/src/P2/dzg.c @@ -1,6 +1,25 @@ #include - -INCLUDE_ASM("asm/nonmatchings/P2/dzg", InitDzg__FP3DZGi); +#include +#include + +void InitDzg(DZG *pdzg, int cpxp) +{ + int c; + + memset(pdzg, 0, sizeof(DZG)); + c = cpxp * 2; + pdzg->cdzMax = c; + pdzg->adz = (DZ *)PvAllocStackImpl(c * 0x60); + memset(pdzg->adz, 0, c * 0x60); + InitDl(&pdzg->dlPos, 0x4C); + InitDl(&pdzg->dlZero, 0x4C); + InitDl(&pdzg->dlMax, 0x4C); + InitDl(&pdzg->dlUncat, 0x4C); + pdzg->aagPos = (float *)PvAllocStackImpl(c * c * 4); + pdzg->aagPosCrout = (float *)PvAllocStackImpl(c * c * 4); + pdzg->asdv = (float *)PvAllocStackImpl(cpxp * 8); + pdzg->adsfPos = (float *)PvAllocStackImpl(cpxp * 8); +} INCLUDE_ASM("asm/nonmatchings/P2/dzg", ClearDzgSolution__FP3DZG); diff --git a/src/P2/emitter.c b/src/P2/emitter.c index 54381ccaa..2d32dfacb 100644 --- a/src/P2/emitter.c +++ b/src/P2/emitter.c @@ -1,4 +1,14 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include extern float DAT_0024a124; @@ -9,6 +19,23 @@ INCLUDE_ASM("asm/nonmatchings/P2/emitter", InitEmitter__FP7EMITTER); INCLUDE_ASM("asm/nonmatchings/P2/emitter", LoadEmitmeshFromBrx__FP8EMITMESHP18CBinaryInputStream); INCLUDE_ASM("asm/nonmatchings/P2/emitter", LoadEmitblipColorsFromBrx__FP8EMITBLIPiP2LOP18CBinaryInputStream); +#ifdef SKIP_ASM +void LoadEmitblipColorsFromBrx(EMITBLIP *pemitblip, int crgba, LO *ploEmit, CBinaryInputStream *pbis) +{ + int cColor = (crgba > 0x1f) ? 0x20 : crgba; + + STRUCT_OFFSET(pemitblip, 0x4c, int) = cColor; + STRUCT_OFFSET(pemitblip, 0x50, RGBA *) = (RGBA *)PvAllocSwImpl(cColor * 4); + STRUCT_OFFSET(pemitblip, 0x54, int) = pbis->U8Read(); + + for (int i = 0; i < crgba; i++) + { + uint rgba = pbis->U32Read(); + if (i < STRUCT_OFFSET(pemitblip, 0x4c, int)) + STRUCT_OFFSET(pemitblip, 0x50, RGBA *)[i] = (RGBA &)rgba; + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/emitter", LoadEmitterFromBrx__FP7EMITTERP18CBinaryInputStream); @@ -24,9 +51,48 @@ INCLUDE_ASM("asm/nonmatchings/P2/emitter", BindEmitter__FP7EMITTER); INCLUDE_ASM("asm/nonmatchings/P2/emitter", PostEmitterLoad__FP7EMITTER); -INCLUDE_ASM("asm/nonmatchings/P2/emitter", HandleEmitterMessage__FP7EMITTER5MSGIDPv); +void HandleEmitterMessage(EMITTER *pemitter, MSGID msgid, void *pv) +{ + if (msgid == MSGID_removed) + { + if (pv == STRUCT_OFFSET(pemitter, 0x344, void *)) + { + (*(void (**)(void *, EMITTER *))((char *)*(void **)pv + 0x70))(pv, pemitter); + STRUCT_OFFSET(pemitter, 0x344, void *) = 0; + } + else if (pv == STRUCT_OFFSET(pemitter, 0x348, void *)) + { + (*(void (**)(void *, EMITTER *))((char *)*(void **)pv + 0x70))(pv, pemitter); + STRUCT_OFFSET(pemitter, 0x348, void *) = 0; + } + } +} + +EMITB *PemitbCopyOnWrite(EMITB *pemitb) +{ + EMITB *pemitbNew; + + if (pemitb->cref < 2) + { + return pemitb; + } -INCLUDE_ASM("asm/nonmatchings/P2/emitter", PemitbCopyOnWrite__FP5EMITB); + pemitbNew = (EMITB *)PvAllocSwCopyImpl(0x200, pemitb); + + if (STRUCT_OFFSET(pemitb, 0x10, int) == 3) + { + if (STRUCT_OFFSET(pemitb, 0x24, void *) != 0) + { + STRUCT_OFFSET(pemitbNew, 0x24, void *) = + PvAllocSwCopyImpl(0x28 * STRUCT_OFFSET(pemitb, 0x20, int), STRUCT_OFFSET(pemitb, 0x24, void *)); + } + } + + pemitbNew->cref = 1; + pemitb->cref--; + + return pemitbNew; +} EMITB *PemitbEnsureEmitter(EMITTER *pemitter, ENSK ensk) { @@ -59,7 +125,32 @@ INCLUDE_ASM("asm/nonmatchings/P2/emitter", ModifyEmitterParticles__FP7EMITTER); INCLUDE_ASM("asm/nonmatchings/P2/emitter", UpdateEmitter__FP7EMITTERf); -INCLUDE_ASM("asm/nonmatchings/P2/emitter", FUN_00155f28); +void FUN_00155f28(SO *pso) +{ + SO *psoParent; + + if ((STRUCT_OFFSET(pso, 0x2c8, unsigned long long) & 0xC000000) == 0x8000000) + { + return; + } + + psoParent = STRUCT_OFFSET(pso, 0x18, SO *); + while (psoParent != 0) + { + if ((STRUCT_OFFSET(psoParent, 0x2c8, unsigned long long) & 0xC000000) == 0x8000000) + { + break; + } + psoParent = STRUCT_OFFSET(psoParent, 0x18, SO *); + } + + if (psoParent == 0) + { + return; + } + + STRUCT_OFFSET(pso, 0x88, int) = STRUCT_OFFSET(psoParent, 0x88, int); +} void PauseEmitter(EMITTER *pemitter, float dtPause) { @@ -99,7 +190,29 @@ void GetEmitterPaused(EMITTER *pemitter, int *pfPaused) *pfPaused = FPausedEmitter(pemitter); } -INCLUDE_ASM("asm/nonmatchings/P2/emitter", OnEmitterValuesChanged__FP7EMITTER); +void OnEmitterValuesChanged(EMITTER *pemitter) +{ + STRUCT_OFFSET(pemitter, 0x34c, int) = 0; // pemitter->fValuesChanged + + if (STRUCT_OFFSET(pemitter, 0x348, BLIPG *) != 0) + { + SetBlipgEmitb(STRUCT_OFFSET(pemitter, 0x348, BLIPG *), STRUCT_OFFSET(pemitter, 0x2d0, EMITB *)); + } + + if (STRUCT_OFFSET(pemitter, 0x344, RIPG *) != 0) + { + SetRipgEmitb(STRUCT_OFFSET(pemitter, 0x344, RIPG *), STRUCT_OFFSET(pemitter, 0x2d0, EMITB *)); + } + + if (STRUCT_OFFSET(pemitter, 0x2d4, int) == 3) + { + STRUCT_OFFSET(pemitter, 0x328, float) = GRandInRange(STRUCT_OFFSET(pemitter, 0x2dc, float), STRUCT_OFFSET(pemitter, 0x2e0, float)) * 60.0f; + } + else + { + STRUCT_OFFSET(pemitter, 0x328, float) = GRandInRange(STRUCT_OFFSET(pemitter, 0x2dc, float), STRUCT_OFFSET(pemitter, 0x2e0, float)); + } +} INCLUDE_ASM("asm/nonmatchings/P2/emitter", SetEmitterParticleCount__FP7EMITTERi); @@ -132,6 +245,30 @@ INCLUDE_ASM("asm/nonmatchings/P2/emitter", ChooseEmitoPos__FP5EMITOiiP6VECTORT3) INCLUDE_ASM("asm/nonmatchings/P2/emitter", ConvertEmitoPosVec__FP5EMITOP6VECTORT1); INCLUDE_ASM("asm/nonmatchings/P2/emitter", CalculateEmitvx__FiP2LMiP6EMITVX); +#ifdef SKIP_ASM +void CalculateEmitvx(int cParticlePerRing, LM *plmTilt, int cParticle, EMITVX *pemitvx) +{ + if (cParticlePerRing > 0) + { + STRUCT_OFFSET(pemitvx, 0x0, int) = + (cParticlePerRing < cParticle) ? cParticlePerRing : cParticle; + } + else + { + STRUCT_OFFSET(pemitvx, 0x0, int) = cParticle; + } + + int count = STRUCT_OFFSET(pemitvx, 0x0, int); + int cBatch = (cParticle - 1 + count) / count; + float gNorm = RadNormalize(plmTilt->gMax - plmTilt->gMin); + + STRUCT_OFFSET(pemitvx, 0x8, float) = 6.2831855f / (float)STRUCT_OFFSET(pemitvx, 0x0, int); + STRUCT_OFFSET(pemitvx, 0x4, float) = gNorm / (float)cBatch; + STRUCT_OFFSET(pemitvx, 0xc, float) = + plmTilt->gMin + STRUCT_OFFSET(pemitvx, 0x4, float) * 0.5f; + STRUCT_OFFSET(pemitvx, 0x10, float) = GRandInRange(0.0f, 6.2831855f); +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/emitter", ChooseEmitVelocity__FP6EMITVXffP2LMP6VECTORiT4); @@ -153,9 +290,52 @@ JUNK_WORD(0x27bd0290); // junk_00157FF0 INCLUDE_ASM("asm/nonmatchings/P2/emitter", StockSplashBig__FP6VECTORfP2SO); -INCLUDE_ASM("asm/nonmatchings/P2/emitter", StockSplashSmall__FP6VECTORfP2SO); +void StockSplashSmall(VECTOR *ppos, float gScale, SO *psoTouch) +{ + RIP *prip = PripNewRipg(RIPT_Ripple, 0); + + if (prip) + { + (*(void (**)(RIP *, VECTOR *, float, SO *))(*(void **)prip))(prip, ppos, gScale, 0); + STRUCT_OFFSET(prip, 0x1c, float) = 0.75f; + + if (STRUCT_OFFSET(psoTouch, 0x278, SO *) != 0) + { + STRUCT_OFFSET(prip, 0x114, int) = STRUCT_OFFSET(STRUCT_OFFSET(psoTouch, 0x278, SO *), 0xc, int); + } + } +} -INCLUDE_ASM("asm/nonmatchings/P2/emitter", AddEmitoSkeleton__FP5EMITO3OIDT1ffffP2LO); +void AddEmitoSkeleton(EMITO *pemito, OID oid, OID oidOther, float sRadius, float gDensity, float sRadiusOther, float gDensityOther, LO *ploContext) +{ + STRUCT_OFFSET(pemito, 0x0, int) = 3; + + if (STRUCT_OFFSET(pemito, 0x14, void *) == 0) + STRUCT_OFFSET(pemito, 0x14, void *) = PvAllocSwClearImpl(0x500); + + if (STRUCT_OFFSET(pemito, 0x10, int) < 0x20) + { + int c = STRUCT_OFFSET(pemito, 0x10, int); + char *pentry = (char *)STRUCT_OFFSET(pemito, 0x14, void *) + c * 0x28; + + STRUCT_OFFSET(pemito, 0x10, int) = c + 1; + + STRUCT_OFFSET(pentry, 0x0, int) = oid; + STRUCT_OFFSET(pentry, 0x4, int) = oidOther; + + STRUCT_OFFSET(pentry, 0x8, float) = gDensity; + if (0.0f <= gDensityOther) + STRUCT_OFFSET(pentry, 0xc, float) = gDensityOther; + else + STRUCT_OFFSET(pentry, 0xc, float) = gDensity; + + STRUCT_OFFSET(pentry, 0x10, float) = sRadius; + if (0.0f <= sRadiusOther) + STRUCT_OFFSET(pentry, 0x14, float) = sRadiusOther; + else + STRUCT_OFFSET(pentry, 0x14, float) = sRadius; + } +} INCLUDE_ASM("asm/nonmatchings/P2/emitter", BindEmitb__FP5EMITBP2LO); @@ -163,7 +343,11 @@ INCLUDE_ASM("asm/nonmatchings/P2/emitter", SetEmitdvEmitb__FP6EMITDVP5EMITB); INCLUDE_ASM("asm/nonmatchings/P2/emitter", CalculateEmitdvMatrix__FP6EMITDVfP7MATRIX4); -INCLUDE_ASM("asm/nonmatchings/P2/emitter", PostExplLoad__FP4EXPL); +void PostExplLoad(EXPL *pexpl) +{ + PostLoLoad(pexpl); + pexpl->pvtlo->pfnRemoveLo(pexpl); +} INCLUDE_ASM("asm/nonmatchings/P2/emitter", CalculateExplTransform__FP4EXPLP6VECTORP7MATRIX3); @@ -178,7 +362,25 @@ void ExplodeExplExplso(EXPL *pexpl, EXPLSO *pexplso) INCLUDE_ASM("asm/nonmatchings/P2/emitter", LoadExplgFromBrx__FP5EXPLGP18CBinaryInputStream); -INCLUDE_ASM("asm/nonmatchings/P2/emitter", CloneExplg__FP5EXPLGT0); +void CloneExplg(EXPLG *pexplg, EXPLG *pexplgBase) +{ + CloneLo((LO *)pexplg, (LO *)pexplgBase); + + int i = 0; + if (STRUCT_OFFSET(pexplg, 0x90, int) > 0) + { + LO **p = &STRUCT_OFFSET(pexplg, 0x94, LO *); + do + { + LO *plo = PloCloneLo(*p, STRUCT_OFFSET(pexplg, 0x14, SW *), STRUCT_OFFSET(pexplg, 0x18, ALO *)); + i++; + plo->pvtlo->pfnRemoveLo(plo); + *p = plo; + STRUCT_OFFSET(plo, 0x80, EXPLG *) = pexplg; + p++; + } while (i < STRUCT_OFFSET(pexplg, 0x90, int)); + } +} INCLUDE_ASM("asm/nonmatchings/P2/emitter", BindExplg__FP5EXPLG); @@ -188,28 +390,161 @@ INCLUDE_ASM("asm/nonmatchings/P2/emitter", InitExplo__FP5EXPLO); INCLUDE_ASM("asm/nonmatchings/P2/emitter", LoadExploFromBrx__FP5EXPLOP18CBinaryInputStream); -INCLUDE_ASM("asm/nonmatchings/P2/emitter", CloneExplo__FP5EXPLOT0); +void CloneExplo(EXPLO *pexplo, EXPLO *pexploBase) +{ + CloneLo(pexplo, pexploBase); + STRUCT_OFFSET(pexplo, 0x90, EMITB *)->cref++; +} -INCLUDE_ASM("asm/nonmatchings/P2/emitter", BindExplo__FP5EXPLO); +void BindExplo(EXPLO *pexplo) +{ + EMITB *pemitb; + EMITB *pemitbNew; + + if (STRUCT_OFFSET(pexplo, 0x94, int) == -1 && + STRUCT_OFFSET(pexplo, 0x98, int) == -1 && + STRUCT_OFFSET(STRUCT_OFFSET(pexplo, 0x90, EMITB *), 0x10, int) != 3) + { + EMITB *pemitbCur = STRUCT_OFFSET(pexplo, 0x90, EMITB *); + + if (STRUCT_OFFSET(pemitbCur, 0x120, int) != 0) + goto done; + + if (STRUCT_OFFSET(pemitbCur, 0x188, int) == -1) + goto done; + } + + pemitbNew = PemitbEnsureExplo(pexplo, ENSK_Set); + + if (STRUCT_OFFSET(pexplo, 0x94, int) != -1) + { + STRUCT_OFFSET(pemitbNew, 0x7C, void *) = + PloFindSwObject(STRUCT_OFFSET(pexplo, 0x14, SW *), 0x104, + (OID)STRUCT_OFFSET(pexplo, 0x94, int), (LO *)pexplo); + } + + if (STRUCT_OFFSET(pexplo, 0x98, int) != -1) + { + LO *plo = PloFindSwObject(STRUCT_OFFSET(pexplo, 0x14, SW *), 0x104, + (OID)STRUCT_OFFSET(pexplo, 0x98, int), (LO *)pexplo); + STRUCT_OFFSET(pemitbNew, 0x20, int) = STRUCT_OFFSET(plo, 0x34, int); + STRUCT_OFFSET(pemitbNew, 0x7C, int) = STRUCT_OFFSET(plo, 0x18, int); + } + // @todo try to do this without goto +done: + BindEmitb(STRUCT_OFFSET(pexplo, 0x90, EMITB *), (LO *)pexplo); +} void ExplodeExploExplso(EXPLO *pexplo, EXPLSO *pexplso) { return; } -INCLUDE_ASM("asm/nonmatchings/P2/emitter", AddExploSkeleton__FP5EXPLO3OIDT1ffff); +void AddExploSkeleton(EXPLO *pexplo, OID oid, OID oidOther, float sRadius, float gDensity, float sRadiusOther, float gDensityOther) +{ + EMITB *pemitb = PemitbEnsureExplo(pexplo, ENSK_Set); + AddEmitoSkeleton(&pemitb->emito, oid, oidOther, sRadius, gDensity, sRadiusOther, gDensityOther, pexplo); +} -INCLUDE_ASM("asm/nonmatchings/P2/emitter", PemitbEnsureExplo__FP5EXPLO4ENSK); +EMITB *PemitbEnsureExplo(EXPLO *pexplo, ENSK ensk) +{ + if (ensk == ENSK_Set) + { + STRUCT_OFFSET(pexplo, 0x90, EMITB *) = PemitbCopyOnWrite(STRUCT_OFFSET(pexplo, 0x90, EMITB *)); + } + + return STRUCT_OFFSET(pexplo, 0x90, EMITB *); +} INCLUDE_ASM("asm/nonmatchings/P2/emitter", InitExpls__FP5EXPLS); -INCLUDE_ASM("asm/nonmatchings/P2/emitter", BindExpls__FP5EXPLS); +void BindExpls(EXPLS *pexpls) +{ + EMITB *pemitb; + LO *plo; + + BindExplo(pexpls); + + if (STRUCT_OFFSET(pexpls, 0xAC, int) == -1 && + STRUCT_OFFSET(pexpls, 0xB0, long long) == -1) + return; + + pemitb = PemitbEnsureExplo(pexpls, ENSK_Set); + + if (STRUCT_OFFSET(pexpls, 0xAC, int) != -1) + STRUCT_OFFSET(pemitb, 0x1D8, LO *) = + PloFindSwObject(STRUCT_OFFSET(pexpls, 0x14, SW *), 0x104, + STRUCT_OFFSET(pexpls, 0xAC, OID), (LO *)pexpls); + + if (STRUCT_OFFSET(pexpls, 0xB0, int) != -1) + STRUCT_OFFSET(pemitb, 0x1DC, LO *) = + PloFindSwObject(STRUCT_OFFSET(pexpls, 0x14, SW *), 0x104, + STRUCT_OFFSET(pexpls, 0xB0, OID), (LO *)pexpls); + + if (STRUCT_OFFSET(pexpls, 0xB4, int) != -1) + { + plo = PloFindSwObject(STRUCT_OFFSET(pexpls, 0x14, SW *), 0x104, + STRUCT_OFFSET(pexpls, 0xB4, OID), (LO *)pexpls); + if (FIsBasicDerivedFrom((BASIC *)plo, CID_SO)) + STRUCT_OFFSET(pemitb, 0x1E0, LO *) = plo; + } +} + +void HandleExplsMessage(EXPLS *pexpls, MSGID msgid, void *pv) +{ + if (msgid == MSGID_removed) + { + if (pv == STRUCT_OFFSET(pexpls, 0xc0, void *)) + { + (*(void (**)(void *, EXPLS *))((char *)*(void **)pv + 0x70))(pv, pexpls); + STRUCT_OFFSET(pexpls, 0xc0, void *) = 0; + } + else if (pv == STRUCT_OFFSET(pexpls, 0xc4, void *)) + { + (*(void (**)(void *, EXPLS *))((char *)*(void **)pv + 0x70))(pv, pexpls); + STRUCT_OFFSET(pexpls, 0xc4, void *) = 0; + } + } +} + +struct EXPLSOBLOB +{ + qword aqw[5]; +}; + +void ExplodeExplsExplso(EXPLS *pexpls, EXPLSO *pexplso) +{ + int fFired = 0; -INCLUDE_ASM("asm/nonmatchings/P2/emitter", HandleExplsMessage__FP5EXPLS5MSGIDPv); + if (0.0f < STRUCT_OFFSET(pexpls, 0xB8, float)) + { + void *pv = PvAllocSlotheapUnsafe( + (SLOTHEAP *)((char *)STRUCT_OFFSET(pexpls, 0x14, SW *) + 0x1BD0)); + + if (pv != 0) + { + STRUCT_OFFSET(pv, 0x0, EXPLS *) = pexpls; + *(EXPLSOBLOB *)((char *)pv + 0x10) = *(EXPLSOBLOB *)pexplso; + fFired = 1; + STRUCT_OFFSET(pv, 0x60, float) = g_clock.t + STRUCT_OFFSET(pexpls, 0xB8, float); + ClearDle((DLE *)((char *)pv + 0x64)); + AppendDlEntry((DL *)((char *)STRUCT_OFFSET(pexpls, 0x14, SW *) + 0x1BDC), pv); + } + } + + if (!fFired) + FireExplsExplso(pexpls, pexplso); +} -INCLUDE_ASM("asm/nonmatchings/P2/emitter", ExplodeExplsExplso__FP5EXPLSP6EXPLSO); +SFX *PsfxEnsureExpls(EXPLS *pexpls, ENSK ensk) +{ + if (STRUCT_OFFSET(pexpls, 0xa0, SFX *) == 0) + { + NewSfx(&STRUCT_OFFSET(pexpls, 0xa0, SFX *)); + } -INCLUDE_ASM("asm/nonmatchings/P2/emitter", PsfxEnsureExpls__FP5EXPLS4ENSK); + return STRUCT_OFFSET(pexpls, 0xa0, SFX *); +} INCLUDE_ASM("asm/nonmatchings/P2/emitter", FireExplsExplso__FP5EXPLSP6EXPLSO); diff --git a/src/P2/eyes.c b/src/P2/eyes.c index daded505f..8cb23c9fc 100644 --- a/src/P2/eyes.c +++ b/src/P2/eyes.c @@ -1,13 +1,112 @@ #include +#include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/eyes", InitEyes__FP4EYESP4SAAF); +void InitEyes(EYES *peyes, SAAF *psaaf) +{ + InitSaa(peyes, psaaf); + peyes->unk2 = STRUCT_OFFSET(peyes, 0x10, int); + peyes->oid = (OID)*(short *)&psaaf->dframe; + *(float *)&peyes->unk[0] = psaaf->dtLoopMin; + *(float *)&peyes->unk[1] = psaaf->dtLoopMax; + *(float *)&peyes->unk[2] = psaaf->dtPauseMin; + *(float *)&peyes->unk[3] = psaaf->dtPauseMax; +} -INCLUDE_ASM("asm/nonmatchings/P2/eyes", PostEyesLoad__FP4EYES); +void PostEyesLoad(EYES *peyes) +{ + SHD *pshd; + int sCur; + int sShd; -INCLUDE_ASM("asm/nonmatchings/P2/eyes", SetEyesEyess__FP4EYES5EYESS); + PostSaaLoad((SAA *)peyes); + + pshd = PshdFindShader(peyes->oid); + peyes->pshd = pshd; + if (pshd != NULL) + { + if (STRUCT_OFFSET(pshd, 0x24, SAA *) == NULL) + { + if (STRUCT_OFFSET(peyes->sai.pshd, 0x24, SAA *) == (SAA *)peyes) + { + STRUCT_OFFSET(pshd, 0x24, SAA *) = (SAA *)peyes; + } + } + } + + sCur = 0; + if (peyes->sai.pshd != NULL) + { + sCur = STRUCT_OFFSET(peyes->sai.pshd, 0x20, int); + } + sShd = 0; + if (peyes->pshd != NULL) + { + sShd = STRUCT_OFFSET(peyes->pshd, 0x20, int); + } + + peyes->eyess = EYESS_Nil; + STRUCT_OFFSET(peyes, 0x5C, int) = (sShd < sCur) ? sCur : sShd; + SetEyesEyess(peyes, EYESS_Open); +} + +void SetEyesEyess(EYES *peyes, EYESS eyess) +{ + if (peyes->eyess == eyess) + return; + + switch (eyess) + { + case EYESS_Open: + { + int c = STRUCT_OFFSET(peyes, 0x5C, int); + STRUCT_OFFSET(peyes, 0x70, float) = (float)(c - 1) * STRUCT_OFFSET(peyes, 0x74, float); + STRUCT_OFFSET(peyes, 0x6C, float) = + (float)(c * 2) * (1.0f - STRUCT_OFFSET(peyes, 0x74, float)) / + STRUCT_OFFSET(peyes, 0x2C, float); + if (GRandInRange(0.0f, 1.0f) < STRUCT_OFFSET(peyes, 0x38, float)) + STRUCT_OFFSET(peyes, 0x68, float) = 0.0f; + else + STRUCT_OFFSET(peyes, 0x68, float) = + GRandInRange(STRUCT_OFFSET(peyes, 0x30, float), STRUCT_OFFSET(peyes, 0x34, float)); + break; + } + case EYESS_Closing: + break; + case EYESS_Closed: + { + int c = STRUCT_OFFSET(peyes, 0x5C, int); + if ((int)STRUCT_OFFSET(peyes, 0x70, float) != c - 1) + STRUCT_OFFSET(peyes, 0x70, float) = (float)(c - 1); + break; + } + case EYESS_Opening: + break; + } + + peyes->eyess = eyess; + STRUCT_OFFSET(peyes, 0x64, float) = g_clock.t; +} INCLUDE_ASM("asm/nonmatchings/P2/eyes", UpdateEyes__FP4EYESf); -INCLUDE_ASM("asm/nonmatchings/P2/eyes", SetEyesClosed__FP4EYESf); +void SetEyesClosed(EYES *peyes, float uClosed) +{ + STRUCT_OFFSET(peyes, 0x74, float) = uClosed; + + if (1.0f <= uClosed) + { + SetEyesEyess(peyes, EYESS_Closed); + } + else + { + peyes->eyess = EYESS_Nil; + SetEyesEyess(peyes, EYESS_Open); + } + + SetSaiIframe((SAI *)((uint8_t *)peyes + 0x10), (int)STRUCT_OFFSET(peyes, 0x70, float)); + SetSaiIframe((SAI *)((uint8_t *)peyes + 0x40), (int)STRUCT_OFFSET(peyes, 0x70, float)); +} INCLUDE_ASM("asm/nonmatchings/P2/eyes", PsaiFromEyesShd__FP4EYESP3SHD); diff --git a/src/P2/fader.c b/src/P2/fader.c index d066a4161..20dd4556e 100644 --- a/src/P2/fader.c +++ b/src/P2/fader.c @@ -1,7 +1,28 @@ #include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/fader", UpdateFader__FP5FADERf); -INCLUDE_ASM("asm/nonmatchings/P2/fader", PfaderNew__FP3ALO); +FADER *PfaderNew(ALO *palo) +{ + FADER *pfader; + + pfader = (FADER *)PvAllocSlotheapClearImpl(&STRUCT_OFFSET(g_psw, 0x1C18, SLOTHEAP)); + STRUCT_OFFSET(pfader, 0x0, ALO *) = palo; + + if (STRUCT_OFFSET(palo, 0x294, int) != 0) + { + AppendDlEntry(&STRUCT_OFFSET(g_psw, 0x1C30, DL), pfader); + } + else + { + AppendDlEntry(&STRUCT_OFFSET(g_psw, 0x1C24, DL), pfader); + } + + return pfader; +} INCLUDE_ASM("asm/nonmatchings/P2/fader", RemoveFader__FP5FADER); diff --git a/src/P2/fly.c b/src/P2/fly.c index f9ce9f6d7..3dbb3354d 100644 --- a/src/P2/fly.c +++ b/src/P2/fly.c @@ -1,14 +1,53 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/fly", InitFly__FP3FLY); INCLUDE_ASM("asm/nonmatchings/P2/fly", LoadFlyFromBrx__FP3FLYP18CBinaryInputStream); INCLUDE_ASM("asm/nonmatchings/P2/fly", CloneFly__FP3FLYT0); +#ifdef SKIP_ASM +void CloneFly(FLY *pfly, FLY *pflyBase) +{ + uint64_t tmp = STRUCT_OFFSET(pfly, 0x5dc, uint64_t); + CloneSo((SO *)pfly, (SO *)pflyBase); + STRUCT_OFFSET(pfly, 0x5dc, uint64_t) = tmp; + + if (STRUCT_OFFSET(pfly, 0x550, int) == 0) + { + StartSound((SFXID)0x41, (AMB **)((char *)pfly + 0x5e4), (ALO *)pfly, 0, + 700.0f, 10.0f, 1.0f, 0.0f, 0.0f, 0, 0); + } + else + { + if (FFindDlEntry((DL *)((char *)pfly->psw + 0x1c48), pfly)) + RemoveDlEntry((DL *)((char *)pfly->psw + 0x1c48), pfly); + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/fly", FreezeFly__FP3FLYi); -INCLUDE_ASM("asm/nonmatchings/P2/fly", PostFlyLoad__FP3FLY); +void PostFlyLoad(FLY *pfly) +{ + extern SNIP D_002621E0; + + SnipAloObjects((ALO *)pfly, 2, &D_002621E0); + + if (STRUCT_OFFSET(pfly, 0x550, int) == 1) + { + STRUCT_OFFSET(pfly, 0x688, float) = g_clock.t + + GRandInRange(STRUCT_OFFSET(pfly, 0x63c, float), STRUCT_OFFSET(pfly, 0x640, float)); + STRUCT_OFFSET(pfly, 0x680, float) = g_clock.t + + GRandInRange(STRUCT_OFFSET(pfly, 0x670, float), STRUCT_OFFSET(pfly, 0x674, float)); + } + + SetFlyFlys(pfly, (FLYS)STRUCT_OFFSET(pfly, 0x560, int)); + PostAloLoad((ALO *)pfly); + STRUCT_OFFSET(pfly, 0x64c, float) = + STRUCT_OFFSET(pfly, 0x3cc, float) + STRUCT_OFFSET(pfly, 0x3cc, float); +} INCLUDE_ASM("asm/nonmatchings/P2/fly", PresetFlyAccel__FP3FLYf); @@ -31,3 +70,28 @@ INCLUDE_ASM("asm/nonmatchings/P2/fly", FShouldFlyFlee__FP3FLY); INCLUDE_ASM("asm/nonmatchings/P2/fly", FFilterFly__FPvP2SO); INCLUDE_ASM("asm/nonmatchings/P2/fly", FCheckFlyOpenSpaceBelow__FP3FLY); +#ifdef SKIP_ASM +int FCheckFlyOpenSpaceBelow(FLY *pfly) +{ + if (g_clock.t - STRUCT_OFFSET(pfly, 0x66c, float) < 0.05f) + return 0; + + int cpso; + SO **apso; + VECTOR *ppos = &STRUCT_OFFSET(pfly, 0x140, VECTOR); + + InitStackImpl(); + IntersectSwBoundingSphere(STRUCT_OFFSET(pfly, 0x14, SW *), NULL, ppos, + STRUCT_OFFSET(pfly, 0x64c, float), (PFNFILTER)FFilterFly, pfly, &cpso, &apso); + + qword qwBelow = STRUCT_OFFSET(pfly, 0x140, qword); + VECTOR *pposBelow = (VECTOR *)&qwBelow; + float zBelow = pposBelow->z - STRUCT_OFFSET(pfly, 0x64c, float); + pposBelow->z = zBelow; + SO *pso = PsoHitTestLineObjects(0, ppos, pposBelow, cpso, apso, NULL); + FreeStackImpl(); + + STRUCT_OFFSET(pfly, 0x66c, float) = g_clock.t; + return pso == NULL; +} +#endif // SKIP_ASM diff --git a/src/P2/font.c b/src/P2/font.c index f088ac343..25f2874a8 100644 --- a/src/P2/font.c +++ b/src/P2/font.c @@ -10,9 +10,9 @@ void StartupFont() g_pfont = NULL; } -INCLUDE_ASM("asm/nonmatchings/P2/font", FUN_0015c188); +INCLUDE_ASM("asm/nonmatchings/P2/font", FUN_0015c188__Fi); -INCLUDE_ASM("asm/nonmatchings/P2/font", FUN_0015c1c0); +INCLUDE_ASM("asm/nonmatchings/P2/font", FUN_0015c1c0__Fi); INCLUDE_ASM("asm/nonmatchings/P2/font", FUN_0015c200); diff --git a/src/P2/freeze.c b/src/P2/freeze.c index 6648556c3..93a0c86db 100644 --- a/src/P2/freeze.c +++ b/src/P2/freeze.c @@ -1,14 +1,62 @@ #include -INCLUDE_ASM("asm/nonmatchings/P2/freeze", RemergeSwObject__FP2SWP3ALO); +void RemergeSwObject(SW *psw, ALO *palo) +{ + unsigned long long grfalo = STRUCT_OFFSET(palo, 0x2c8, unsigned long long); + + if ((grfalo & (0x8000ULL << 24)) == 0) + { + STRUCT_OFFSET(palo, 0x2c8, unsigned long long) = grfalo | (0x8000ULL << 24); + int cpalo = STRUCT_OFFSET(psw, 0x1ed0, int); + ALO **apalo = STRUCT_OFFSET(psw, 0x1ed4, ALO **); + apalo[cpalo] = palo; + STRUCT_OFFSET(psw, 0x1ed0, int) = cpalo + 1; + } +} INCLUDE_ASM("asm/nonmatchings/P2/freeze", MergeSwFreezeGroups__FP2SWP3ALOT1); INCLUDE_ASM("asm/nonmatchings/P2/freeze", SplinterSwFreezeGroup__FP2SWP3ALO); -INCLUDE_ASM("asm/nonmatchings/P2/freeze", MergeSwGroup__FP2SWP3MRG); +void MergeSwGroup(SW *psw, MRG *pmrg) +{ + int i = 0; + while (i < pmrg->cpalo) + { + if (FIsLoInWorld((LO *)pmrg->apalo[i])) + break; + i++; + } + + for (int iFirst = i; i < pmrg->cpalo; i++) + { + if (FIsLoInWorld((LO *)pmrg->apalo[i])) + { + MergeSwFreezeGroups(psw, pmrg->apalo[iFirst]->paloFreezeRoot, pmrg->apalo[i]->paloFreezeRoot); + } + } +} + +void AddSwMergeGroup(SW *psw, MRG *pmrg) +{ + if (pmrg->cpalo < 2) + return; -INCLUDE_ASM("asm/nonmatchings/P2/freeze", AddSwMergeGroup__FP2SWP3MRG); + for (int i = 0; i < pmrg->cpalo; i++) + { + ALO *palo = pmrg->apalo[i]; + int cpmrg = STRUCT_OFFSET(palo, 0x6c, int); + + if ((unsigned int)cpmrg < 4) + { + MRG **apmrg = &STRUCT_OFFSET(palo, 0x70, MRG *); + apmrg[cpmrg] = pmrg; + STRUCT_OFFSET(palo, 0x6c, int) = cpmrg + 1; + } + } + + MergeSwGroup(psw, pmrg); +} INCLUDE_ASM("asm/nonmatchings/P2/freeze", RemoveFromArray__FPiPPvPv); @@ -18,12 +66,39 @@ INCLUDE_ASM("asm/nonmatchings/P2/freeze", RemergeSwObjects__FP2SW); INCLUDE_ASM("asm/nonmatchings/P2/freeze", FreezeAloHierarchy__FP3ALOi); -void GetAloFrozen(ALO *palo, int *pfFrozen) +void GetAloFrozen(ALO *palo, int *pf) { - *pfFrozen = (int)((unsigned long long) STRUCT_OFFSET(palo, 0x2C8, unsigned long long) >> 0x26) & 1; + *pf = (int)(STRUCT_OFFSET(palo, 0x2c8, unsigned long long) >> 0x26) & 1; } -INCLUDE_ASM("asm/nonmatchings/P2/freeze", FreezeAlo__FP3ALOi); +void FreezeAlo(ALO *palo, int fFreeze) +{ + if (fFreeze) + { + SFX *psfx; + + STRUCT_OFFSET(palo, 0xa0, VU_VECTOR) = STRUCT_OFFSET(palo, 0x150, VU_VECTOR); + STRUCT_OFFSET(palo, 0xb0, VU_VECTOR) = STRUCT_OFFSET(palo, 0x160, VU_VECTOR); + psfx = STRUCT_OFFSET(palo, 0x2ac, SFX *); + STRUCT_OFFSET(palo, 0x29c, int) = 0; + if (psfx) + StopSound(psfx->pamb, 0); + (*(void (**)(ALO *, VECTOR *))(*(uint8_t **)palo + 0x90))(palo, &D_00248D30); + (*(void (**)(ALO *, VECTOR *))(*(uint8_t **)palo + 0x94))(palo, &D_00248D30); + STRUCT_OFFSET(palo, 0x2c8, unsigned long long) |= (0x8000ULL << 23); + } + else + { + SFX *psfx; + + STRUCT_OFFSET(palo, 0x2c8, unsigned long long) &= ~(0x8000ULL << 23); + (*(void (**)(ALO *, VECTOR *))(*(uint8_t **)palo + 0x90))(palo, (VECTOR *)((uint8_t *)palo + 0xa0)); + (*(void (**)(ALO *, VECTOR *))(*(uint8_t **)palo + 0x94))(palo, (VECTOR *)((uint8_t *)palo + 0xb0)); + psfx = STRUCT_OFFSET(palo, 0x2ac, SFX *); + if (psfx) + StartSound(psfx->sfxid, &psfx->pamb, palo, NULL, psfx->sStart, psfx->sFull, psfx->uVol, psfx->uPitch, psfx->uDoppler, &psfx->lmRepeat, NULL); + } +} INCLUDE_ASM("asm/nonmatchings/P2/freeze", FreezeSo__FP2SOi); diff --git a/src/P2/frm.c b/src/P2/frm.c index c5e5e69b2..9234670ca 100644 --- a/src/P2/frm.c +++ b/src/P2/frm.c @@ -6,6 +6,7 @@ #include #include #include +#include extern void *g_pvVu1Code; @@ -49,7 +50,27 @@ void EnsureVu1Code(VIFS *pvifs, void *pvStart, void *pvEnd) } } +extern void *VU1_GlobMpg; +extern void *VU1_GlobMpgEnd; + INCLUDE_ASM("asm/nonmatchings/P2/frm", FinalizeFrameVifs__FP4VIFSPiPP2QW); +#ifdef SKIP_ASM +void FinalizeFrameVifs(VIFS *pvifs, int *pcqwVifs, QW **ppqwVifs) +{ + QW aqw[8]; + GIFS gifs = GIFS(); + + gifs.AllocStatic(8, aqw); + gifs.AddPrimPack(0, 1, 0x0e); + gifs.PackAD(0x61, 0); + gifs.AddPrimEnd(); + pvifs->AddVifFlush(); + pvifs->AddVifGifs(&gifs); + EnsureVu1Code(pvifs, &VU1_GlobMpg, &VU1_GlobMpgEnd); + pvifs->AddDmaEnd(); + pvifs->Detach(pcqwVifs, ppqwVifs); +} +#endif // SKIP_ASM void FinalizeFrameGifs(GIFS *pgifs, int *pcqwGifs, QW **ppqwGifs) { @@ -60,7 +81,30 @@ void FinalizeFrameGifs(GIFS *pgifs, int *pcqwGifs, QW **ppqwGifs) pgifs->Detach(pcqwGifs, ppqwGifs); } -INCLUDE_ASM("asm/nonmatchings/P2/frm", CloseFrame__Fv); +extern DL D_002622E0; +extern DL D_002622F0; +extern DL D_00262300; +extern int D_002622D0; +extern int D_002623B0; + +void CloseFrame() +{ + FinalizeFrameVifs(&g_vifs, &g_pfrmOpen->cqwVifs, 0); + FinalizeFrameGifs(&g_gifs, &g_pfrmOpen->cqwGifs, 0); + + STRUCT_OFFSET(g_pfrmOpen, 0x20, DL) = D_002622E0; + ClearDl(&D_002622E0); + + STRUCT_OFFSET(g_pfrmOpen, 0x2C, DL) = D_002622F0; + ClearDl(&D_002622F0); + + STRUCT_OFFSET(g_pfrmOpen, 0x38, DL) = D_00262300; + ClearDl(&D_00262300); + + D_002622D0 = 0; + g_pfrmOpen = 0; + SignalSema(D_002623B0); +} void PrepareGsForFrameRender(FRM *pfrm) { @@ -74,7 +118,35 @@ void PrepareGsForFrameRender(FRM *pfrm) } } +extern unsigned int D_002C3B00[]; +extern unsigned int func_00100000[]; +extern char D_00148D74[]; +extern int D_00262310; + INCLUDE_ASM("asm/nonmatchings/P2/frm", check_anticrack_antigrab__Fv); +#ifdef SKIP_ASM +void check_anticrack_antigrab() +{ + unsigned int *pwTable = D_002C3B00; + int cb = (int)D_00148D74; + unsigned int crc = 0xFFFFFFFF; + unsigned int *pw = func_00100000; + + while (cb > 0) + { + unsigned int w = *pw; + cb -= 4; + pw += 1; + crc = pwTable[(crc ^ w) & 0xFF] ^ (crc >> 8); + crc = pwTable[(crc ^ (w >> 8)) & 0xFF] ^ (crc >> 8); + crc = pwTable[(crc ^ (w >> 16)) & 0xFF] ^ (crc >> 8); + crc = pwTable[(crc ^ (w >> 24)) & 0xFF] ^ (crc >> 8); + } + + if (crc != 0) + D_00262310 = 1; +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/frm", FrameRenderLoop__FPv); @@ -100,4 +172,7 @@ INCLUDE_ASM("asm/nonmatchings/P2/frm", BlendPrevFrame__Fv); * Once the appropriate functions are matched these can be removed. */ INCLUDE_ASM("asm/nonmatchings/P2/frm", func_0015F618); -INCLUDE_ASM("asm/nonmatchings/P2/frm", func_0015F658); +void func_0015F658(void) +{ + func_0015F618(1, 0xFFFF); +} diff --git a/src/P2/frzg.c b/src/P2/frzg.c index 0373fd11f..1944b4a31 100644 --- a/src/P2/frzg.c +++ b/src/P2/frzg.c @@ -1,5 +1,32 @@ #include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/frzg", PostFrzgLoad__FP4FRZG); +void PostFrzgLoad(FRZG *pfrzg) +{ + int i; + MRG *pmrg = &pfrzg->mrg; + SW *psw; -INCLUDE_ASM("asm/nonmatchings/P2/frzg", AddFrzgObject__FP4FRZG3OID); + PostLoLoad(pfrzg); + psw = pfrzg->psw; + pmrg->apalo = (ALO **)PvAllocSwImpl(pfrzg->coid * 4); + for (i = 0; i < pfrzg->coid; i++) + { + LO *plo = PloFindSwChild(psw, pfrzg->aoid[i], pfrzg->paloParent); + if (plo != 0) + { + int cpalo = pmrg->cpalo; + pmrg->apalo[cpalo] = (ALO *)plo; + pmrg->cpalo = cpalo + 1; + } + } + AddSwMergeGroup(psw, &pfrzg->mrg); +} + +void AddFrzgObject(FRZG *pfrzg, OID oid) +{ + int coid = pfrzg->coid; + pfrzg->aoid[coid] = oid; + pfrzg->coid = coid + 1; +} diff --git a/src/P2/game.c b/src/P2/game.c index e9e2040f0..a44988c91 100644 --- a/src/P2/game.c +++ b/src/P2/game.c @@ -38,11 +38,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/game", search_level_by_load_data); INCLUDE_ASM("asm/nonmatchings/P2/game", search_level_by_id); -INCLUDE_ASM("asm/nonmatchings/P2/game", PchzFriendlyFromWid); +INCLUDE_ASM("asm/nonmatchings/P2/game", PchzFriendlyFromWid__Fi); JUNK_WORD(0x24420010); -INCLUDE_ASM("asm/nonmatchings/P2/game", call_search_level_by_id); +LevelLoadData *call_search_level_by_id(int level_id) +{ + return search_level_by_id(level_id); +} INCLUDE_ASM("asm/nonmatchings/P2/game", FFindLevel); @@ -90,7 +93,27 @@ void UnlockIntroCutsceneFromWid(int wid) INCLUDE_ASM("asm/nonmatchings/P2/game", DefeatBossFromWid); -INCLUDE_ASM("asm/nonmatchings/P2/game", UnlockEndgameCutscenesFromFgs); +void UnlockEndgameCutscenesFromFgs(FGS fgs) +{ + switch (fgs) + { + case FGS_HalfClues: + g_pgsCur->unlocked_cutscenes |= 0xA002; + g_pgsCur->fgs |= 0x2; + break; + case FGS_AllClues: + if (get_game_completion() & FGS_AllClues) + g_pgsCur->unlocked_cutscenes |= 0xC000; + break; + case FGS_FirstVault: + if (get_game_completion() & FGS_FirstVault) + { + g_pgsCur->unlocked_cutscenes |= 0xC; + g_pgsCur->fgs |= 0xC; + } + break; + } +} INCLUDE_ASM("asm/nonmatchings/P2/game", PlayEndingFromCompletionFlags); @@ -125,26 +148,25 @@ void UpdateGameState(float dt) g_plsCur->dt += dt; } -INCLUDE_ASM("asm/nonmatchings/P2/game", LsFromWid); +INCLUDE_ASM("asm/nonmatchings/P2/game", LsFromWid__F3WID); INCLUDE_ASM("asm/nonmatchings/P2/game", GrflsFromWid__F3WID); -INCLUDE_ASM("asm/nonmatchings/P2/game", UnloadGame__Fv); -#ifdef SKIP_ASM -/** - * @todo 60.42% matched. - */ +extern char D_00269984; +extern char D_002623D8; + void UnloadGame() { + struct PACK { int v; } __attribute__((packed)); + InitGameState(g_pgsCur); - // unk_gs? = NULL; - // clr_8_bytes_1(&DAT_002623d8); + ((PACK *)&D_00269984)->v = 0; + clr_8_bytes_1(&D_002623D8); OnDifficultyGameLoad(&g_difficulty); g_grfcht = (GRFCHT)FCHT_None; g_worldlevelPrev = WORLDLEVEL_Nil; RetryGame(); -} -#endif // SKIP_ASM +} // SKIP_ASM void RetryGame() { @@ -289,14 +311,14 @@ bool FCharmAvailable() INCLUDE_ASM("asm/nonmatchings/P2/game", FUN_00160C90); -int PfLookupDialog(LS *pls, OID oidDialog) +int *PfLookupDialog(LS *pls, OID oidDialog) { // todo figure out what these magic numbers represent if (oidDialog - 0x33bU >= 0xc) { - return 0; + return NULL; } - return -0xcd8 + (int)pls + (oidDialog * 4); + return (int *)(-0xcd8 + (int)pls + (oidDialog * 4)); } // TODO: Come up with a name and mangle it. diff --git a/src/P2/gifs.c b/src/P2/gifs.c index cb41a4069..725d905b2 100644 --- a/src/P2/gifs.c +++ b/src/P2/gifs.c @@ -102,22 +102,14 @@ JUNK_ADDIU(30); void GIFS::ListUV(int u, int v) { CheckReg(0, 3); - uint64_t *pui = ((uint64_t *)m_pb)++; - *pui = u | (v << 16); + *((long *)m_pb)++ = u | (v << 16); } -/** - * @todo 83.83% match. - */ -INCLUDE_ASM("asm/nonmatchings/P2/gifs", ListXYZF__4GIFSiiii); -#ifdef SKIP_ASM void GIFS::ListXYZF(int x, int y, int z, int fog) { CheckReg(0, 4); - uint64_t *pqw = ((uint64_t *)m_pb)++; - *pqw = (uint16_t)x | ((uint16_t)y << 16) | (((uint64_t)z & 0xffffff) << 32) | ((uint64_t)fog << 56); + *((long *)m_pb)++ = x | (y << 16) | ((long)(z & 0xffffff) << 32) | ((long)fog << 56); } -#endif // SKIP_ASM JUNK_ADDIU(80); diff --git a/src/P2/glbs.c b/src/P2/glbs.c index e0ed3cada..490a07f1b 100644 --- a/src/P2/glbs.c +++ b/src/P2/glbs.c @@ -45,12 +45,26 @@ INCLUDE_ASM("asm/nonmatchings/P2/glbs", DrawThreeWay__4GLBS); INCLUDE_ASM("asm/nonmatchings/P2/glbs", EndStrip__4GLBS); -INCLUDE_ASM("asm/nonmatchings/P2/glbs", SetNormal__4GLBSP6VECTOR); +void GLBS::SetNormal(VECTOR *ppos) +{ + STRUCT_OFFSET(this, 0xFC, float) = ppos->x; + STRUCT_OFFSET(this, 0x100, float) = ppos->y; + STRUCT_OFFSET(this, 0x104, float) = ppos->z; +} +JUNK_NOP(); JUNK_WORD(0xE4800110); -INCLUDE_ASM("asm/nonmatchings/P2/glbs", SetRgba__4GLBSG4RGBA); +void GLBS::SetRgba(RGBA *prgba) +{ + struct PACK { int v; } __attribute__((packed)); + *(PACK *)((char *)this + 0x114) = *(PACK *)prgba; +} -INCLUDE_ASM("asm/nonmatchings/P2/glbs", SetUv__4GLBSP3UVF); +void GLBS::SetUv(UVF *puv) +{ + struct PACK { long long v; } __attribute__((packed)); + *(PACK *)((char *)this + 0x118) = *(PACK *)puv; +} INCLUDE_ASM("asm/nonmatchings/P2/glbs", AddVtx__4GLBSi); diff --git a/src/P2/glob.c b/src/P2/glob.c index 1762474ae..b7d6865b0 100644 --- a/src/P2/glob.c +++ b/src/P2/glob.c @@ -1,10 +1,40 @@ #include +#include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/glob", BuildGlobsetSaaArray__FP7GLOBSET); +void BuildGlobsetSaaArray(GLOBSET *pglobset) +{ + + void **psaa = (void **)PvAllocSwImpl(STRUCT_OFFSET(pglobset, 0x50, int) * 4); + STRUCT_OFFSET(pglobset, 0x54, void **) = psaa; + + int iDst = 0; + for (int i = 0; i < STRUCT_OFFSET(pglobset, 0xc, int); i++) + { + void *p = STRUCT_OFFSET((uint8_t *)STRUCT_OFFSET(pglobset, 0x10, uint8_t *) + i * 0x70, 0x38, void *); + if (p != 0) + STRUCT_OFFSET(pglobset, 0x54, void **)[iDst++] = p; + } +} INCLUDE_ASM("asm/nonmatchings/P2/glob", LoadGlobsetFromBrx__FP7GLOBSETP18CBinaryInputStreamP3ALO); -INCLUDE_ASM("asm/nonmatchings/P2/glob", EnsureBuffer__FiP4VIFS); +extern char D_18C0; +extern char D_18F8; + +void EnsureBuffer(int iBuffer, VIFS *pvifs) +{ + switch (iBuffer) + { + case 0: + pvifs->AddVifMscal(&D_18C0); + break; + case 1: + pvifs->AddVifMscal(&D_18F8); + break; + } +} INCLUDE_ASM("asm/nonmatchings/P2/glob", EnsureBufferCel__FiP4VIFS); @@ -26,7 +56,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/glob", CloneGlob__FP7GLOBSETP4GLOBP5GLOBI); INCLUDE_ASM("asm/nonmatchings/P2/glob", UpdateGlobset__FP7GLOBSETP3ALOf); -INCLUDE_ASM("asm/nonmatchings/P2/glob", UpdateAloConstraints__FP3ALO); +void UpdateAloConstraints(ALO *palo) +{ + void *p = STRUCT_OFFSET(palo, 0x224, void *); + if (p == NULL || !(STRUCT_OFFSET(p, 0xb0, int) & 0x10) || STRUCT_OFFSET(p, 0x64, int) == 0) + return; + + SolveAloIK(STRUCT_OFFSET(p, 0x60, ALO *)); +} INCLUDE_ASM("asm/nonmatchings/P2/glob", UpdateAloInfluences__FP3ALOP2RO); diff --git a/src/P2/gs.c b/src/P2/gs.c index fd57ed200..c63c2a9a5 100644 --- a/src/P2/gs.c +++ b/src/P2/gs.c @@ -1,10 +1,21 @@ #include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/gs", BlendDisplayOnBufferMismatch__Fv); INCLUDE_ASM("asm/nonmatchings/P2/gs", VBlankS_Interrupt__Fi); -INCLUDE_ASM("asm/nonmatchings/P2/gs", SyncVBlank__Fv); +extern int D_002BE460; +extern int D_002BE46C; + +void SyncVBlank() +{ + D_002BE46C = 1; + WaitSema(D_002BE460); +} INCLUDE_ASM("asm/nonmatchings/P2/gs", SwapGsBuffers__Fv); @@ -14,7 +25,18 @@ INCLUDE_ASM("asm/nonmatchings/P2/gs", GS_Interrupt__Fi); INCLUDE_ASM("asm/nonmatchings/P2/gs", ResetGs__Fv); -INCLUDE_ASM("asm/nonmatchings/P2/gs", SendDmaSyncGsFinish__FP10sceDmaChanP2QW); +extern int D_002BE464; +extern int D_002BE468; + +void SendDmaSyncGsFinish(sceDmaChan *pdc, QW *pqw) +{ + D_002BE468 = 1; + *(volatile uint64_t *)0x12001000 |= 2; + func_00202058(func_00202120() & ~0x200); + FlushCache(0); + sceDmaSend(pdc, pqw); + WaitSema(D_002BE464); +} INCLUDE_ASM("asm/nonmatchings/P2/gs", BuildClearGifs__FP2QWG4RGBAi); @@ -22,11 +44,30 @@ INCLUDE_ASM("asm/nonmatchings/P2/gs", StartupGs__Fv); INCLUDE_ASM("asm/nonmatchings/P2/gs", BlastAqwGifsBothFrames__FP2QW); -INCLUDE_ASM("asm/nonmatchings/P2/gs", ClearFrameBuffers__Fv); +extern QW D_002BE1A0[]; + +void ClearFrameBuffers() +{ + DMAS dmas; + QW aqw[2]; + + dmas.AllocStatic(2, aqw); + dmas.AddDmaRefs(0x2C, D_002BE1A0); + dmas.AddDmaEnd(); + dmas.Detach(NULL, NULL); + BlastAqwGifsBothFrames(aqw); +} INCLUDE_ASM("asm/nonmatchings/P2/gs", FadeFramesToBlack__Ff); -INCLUDE_ASM("asm/nonmatchings/P2/gs", ResetGsMemory__Fv); +extern GSB D_002626D8; +extern int D_002626D0; + +void ResetGsMemory() +{ + InitGsb(&D_002626D8, 0x1E00, 0x4000); + D_002626D0 = 0; +} uint NLog2(uint value) { @@ -61,7 +102,15 @@ int IgsAllocGsb(GSB *pgsb, int iCount) return igsOld; } -INCLUDE_ASM("asm/nonmatchings/P2/gs", BuildImageGifs__FiiiiiiP4GIFS); +void BuildImageGifs(int dbp, int dbw, int psm, int dsax, int dsay, int cqw, GIFS *pgifs) +{ + pgifs->AddPrimPack(0, 1, 0xE); + pgifs->PackAD(0x50, ((long)dbp << 32) | ((long)dbw << 48) | ((long)psm << 56)); + pgifs->PackAD(0x51, 0); + pgifs->PackAD(0x52, (long)dsax | ((long)dsay << 32)); + pgifs->PackAD(0x53, 0); + pgifs->AddImage(cqw); +} INCLUDE_ASM("asm/nonmatchings/P2/gs", BuildClutTex2__FP4CLUTi); @@ -73,11 +122,53 @@ INCLUDE_ASM("asm/nonmatchings/P2/gs", BuildBmpGifs__FP3BMPiP4GIFS); INCLUDE_ASM("asm/nonmatchings/P2/gs", FBuildUploadBitmapGifs__FiP3GSBP4GIFS); -INCLUDE_ASM("asm/nonmatchings/P2/gs", UploadBitmaps__FiP3GSB); +extern int g_cclutUpload; +extern int g_cbmpUpload; + +void UploadBitmaps(GRFZON grfzon, GSB *pgsb) +{ + if (grfzon == 0) + return; + + GIFS gifs; + QW *pqw; + + InitStackImpl(); + gifs.AllocStack(((g_cclutUpload * 3 + g_cbmpUpload) << 3) | 4); + gifs.AddDmaCnt(); + if (FBuildUploadBitmapGifs(grfzon, pgsb, &gifs)) + { + gifs.AddPrimPack(0, 1, 0xE); + gifs.PackAD(0x3F, 0); + gifs.PackAD(0x61, 0); + gifs.AddPrimEnd(); + gifs.AddDmaEnd(); + gifs.Detach(NULL, &pqw); + SendDmaSyncGsFinish(g_pdcGif, pqw); + } + FreeStackImpl(); +} INCLUDE_ASM("asm/nonmatchings/P2/gs", PqwGifsBitmapUpload__Fi); -INCLUDE_ASM("asm/nonmatchings/P2/gs", PropagateSur__FP3SUR); +void PropagateSur(SUR *psur) +{ + CopyAb(psur->pvDst, psur->pvSrc, psur->cb); + + if (psur->cvtx) + { + int *p = (int *)psur->pvDst; + int v0 = p[0]; + int v1 = p[0x10 / 4]; + + v0 |= 0x8000; + v0 |= (int)psur->cvtx; + v1 |= 0x8000; + + p[0] = v0; + p[0x10 / 4] = v1; + } +} INCLUDE_ASM("asm/nonmatchings/P2/gs", ReferenceShaderAqwRegs__FP3SHDP4SHDPP2QWiiP3SAI); @@ -85,7 +176,15 @@ INCLUDE_ASM("asm/nonmatchings/P2/gs", ReferenceUVAnimation__FP2QWiP3SAI); INCLUDE_ASM("asm/nonmatchings/P2/gs", RebaseSurs__FiiPvT2); -INCLUDE_ASM("asm/nonmatchings/P2/gs", PropagateSurs__Fv); +extern SUR D_0027DC20[]; + +void PropagateSurs() +{ + for (int isur = 0; isur < D_002626D0; isur++) + { + PropagateSur(&D_0027DC20[isur]); + } +} INCLUDE_ASM("asm/nonmatchings/P2/gs", PqwVifsBitmapUpload__Fi); diff --git a/src/P2/hide.c b/src/P2/hide.c index d7596a24e..197768967 100644 --- a/src/P2/hide.c +++ b/src/P2/hide.c @@ -1,5 +1,7 @@ #include #include +#include +#include extern DL g_dlHshape; extern DL g_dlHpnt; @@ -12,7 +14,12 @@ void StartupHide() InitDl(&g_dlHbsk, 0x558); } -INCLUDE_ASM("asm/nonmatchings/P2/hide", ResetHideList__Fv); +void ResetHideList() +{ + ClearDl(&g_dlHshape); + ClearDl(&g_dlHpnt); + ClearDl(&g_dlHbsk); +} INCLUDE_ASM("asm/nonmatchings/P2/hide", InitHshape__FP6HSHAPE); @@ -22,7 +29,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/hide", OnHshapeRemove__FP6HSHAPE); INCLUDE_ASM("asm/nonmatchings/P2/hide", BindHshape__FP6HSHAPE); -INCLUDE_ASM("asm/nonmatchings/P2/hide", CloneHshape__FP6HSHAPET0); +struct HSHAPE; + +void CloneHshape(HSHAPE *phshape, HSHAPE *phshapeBase) +{ + DLE dle = STRUCT_OFFSET(phshape, 0x38, DLE); + CloneLo((LO *)phshape, (LO *)phshapeBase); + STRUCT_OFFSET(phshape, 0x38, DLE) = dle; +} INCLUDE_ASM("asm/nonmatchings/P2/hide", GetHshapeHidePos__FP6HSHAPEfP6VECTORPf); @@ -42,19 +56,62 @@ INCLUDE_ASM("asm/nonmatchings/P2/hide", GetHpntClosestHidePos__FP4HPNTP6VECTORPf INCLUDE_ASM("asm/nonmatchings/P2/hide", FUN_0016a320); -INCLUDE_ASM("asm/nonmatchings/P2/hide", InitHbsk__FP4HBSK); +void InitHbsk(HBSK *phbsk) +{ + InitSo((SO *)phbsk); + SetAloRotationSpring((ALO *)phbsk, 3.0f); + SetAloRotationDamping((ALO *)phbsk, 3.0f); + SetAloPositionSmooth((ALO *)phbsk, 3.0f); + SetAloRotationSmooth((ALO *)phbsk, 2.0f); + STRUCT_OFFSET(phbsk, 0x568, float) = 300.0f; +} -INCLUDE_ASM("asm/nonmatchings/P2/hide", LoadHbskFromBrx__FP4HBSKP18CBinaryInputStream); +extern qword D_002483D0[3]; -INCLUDE_ASM("asm/nonmatchings/P2/hide", OnHbskAdd__FP4HBSK); +void LoadHbskFromBrx(HBSK *phbsk, CBinaryInputStream *pbis) +{ + LoadSoFromBrx((SO *)phbsk, pbis); -INCLUDE_ASM("asm/nonmatchings/P2/hide", OnHbskRemove__FP4HBSK); + if (STRUCT_OFFSET(phbsk, 0x224, void *) == 0) + STRUCT_OFFSET(phbsk, 0x224, void *) = PvAllocSwClearImpl(0xC0); + + STRUCT_OFFSET(STRUCT_OFFSET(phbsk, 0x224, void *), 0xB0, int) |= 1; + + void *pv = STRUCT_OFFSET(phbsk, 0x224, void *); + STRUCT_OFFSET(pv, 0x0, qword) = D_002483D0[0]; + STRUCT_OFFSET(pv, 0x10, qword) = D_002483D0[1]; + STRUCT_OFFSET(pv, 0x20, qword) = D_002483D0[2]; +} + +void OnHbskAdd(HBSK *phbsk) +{ + OnSoAdd((SO *)phbsk); + AppendDlEntry(&g_dlHbsk, phbsk); +} + +void OnHbskRemove(HBSK *phbsk) +{ + OnSoRemove((SO *)phbsk); + RemoveDlEntry(&g_dlHbsk, phbsk); +} INCLUDE_ASM("asm/nonmatchings/P2/hide", CloneHbsk__FP4HBSKT0); INCLUDE_ASM("asm/nonmatchings/P2/hide", FIgnoreHbskIntersection__FP4HBSKP2SO); -INCLUDE_ASM("asm/nonmatchings/P2/hide", PresetHbskAccel__FP4HBSKf); +void PresetHbskAccel(HBSK *phbsk, float dt) +{ + MATRIX3 matUpright; + + PresetSoAccel((SO *)phbsk, dt); + if (STRUCT_OFFSET(phbsk, 0x550, int) == 0) + { + TiltMatUpright((MATRIX3 *)((uint8_t *)phbsk + 0xD0), 0, &matUpright); + AccelSoTowardMatSpring((SO *)phbsk, &matUpright, + STRUCT_OFFSET(phbsk, 0x214, CLQ *), &D_00248D30, + STRUCT_OFFSET(phbsk, 0x218, CLQ *), dt); + } +} INCLUDE_ASM("asm/nonmatchings/P2/hide", SetHbskHbsks__FP4HBSK5HBSKS); diff --git a/src/P2/jlo.c b/src/P2/jlo.c index dd51f2ad3..a20fc4af1 100644 --- a/src/P2/jlo.c +++ b/src/P2/jlo.c @@ -1,8 +1,12 @@ #include +#include #include +#include +#include +#include +#include extern JLO *g_pjloCur; -extern VECTOR g_normalZ; // TODO: This should be elsewhere. void InitJlo(JLO *pjlo) { @@ -26,7 +30,20 @@ INCLUDE_ASM("asm/nonmatchings/P2/jlo", LoadJloFromBrx__FP3JLOP18CBinaryInputStre INCLUDE_ASM("asm/nonmatchings/P2/jlo", PostJloLoad__FP3JLO); -INCLUDE_ASM("asm/nonmatchings/P2/jlo", FUN_0016d040); +void FUN_0016d040(JLO *pjlo, OID oid) +{ + STRUCT_OFFSET(pjlo, 0x578, OID) = oid; + JLOVOL *pjlovol = (JLOVOL *)PloFindSwNearest(pjlo->psw, oid, pjlo); + if (pjlovol != NULL) + { + SetJloJlovol(pjlo, pjlovol); + LandJlo(pjlo); + if (STRUCT_OFFSET(pjlovol, 0x7AC, int) != 0) + SetJloJlos(pjlo, JLOS_Idle); + else + SetJloJlos(pjlo, JLOS_Taunt); + } +} void PresetJloAccel(JLO *pjlo, float dt) { @@ -43,15 +60,67 @@ INCLUDE_ASM("asm/nonmatchings/P2/jlo", UpdateJlo__FP3JLOf); INCLUDE_ASM("asm/nonmatchings/P2/jlo", JlosNextJlo__FP3JLO); -INCLUDE_ASM("asm/nonmatchings/P2/jlo", SetJloJlovol__FP3JLOP6JLOVOL); +EXC *PexcSetExcitement(int gexc); + +void SetJloJlovol(JLO *pjlo, JLOVOL *pjlovol) +{ + if (pjlovol == STRUCT_OFFSET(pjlo, 0x558, JLOVOL *)) + return; + + void *p3 = NULL; + if (pjlovol != NULL) + p3 = STRUCT_OFFSET(pjlovol, 0x7AC, void *); + + if (p3 != STRUCT_OFFSET(pjlo, 0x5D0, void *)) + { + STRUCT_OFFSET(pjlo, 0x5D0, void *) = p3; + STRUCT_OFFSET(pjlo, 0x5D4, int) = 3; + } + + STRUCT_OFFSET(pjlo, 0x558, JLOVOL *) = pjlovol; + + if (p3 != NULL) + { + RWM *prwm = STRUCT_OFFSET(pjlo, 0x570, RWM *); + STRUCT_OFFSET(prwm, 0x44, int) = STRUCT_OFFSET(STRUCT_OFFSET(pjlovol, 0x7AC, void *), 0x318, int); + ReloadRwm(STRUCT_OFFSET(pjlo, 0x570, RWM *)); + if (STRUCT_OFFSET(pjlo, 0x5BC, EXC *) == NULL) + STRUCT_OFFSET(pjlo, 0x5BC, EXC *) = PexcSetExcitement(0x6B); + } + else if (STRUCT_OFFSET(pjlo, 0x5BC, EXC *) != NULL) + { + UnsetExcitementHyst(STRUCT_OFFSET(pjlo, 0x5BC, EXC *)); + STRUCT_OFFSET(pjlo, 0x5BC, EXC *) = NULL; + } +} INCLUDE_ASM("asm/nonmatchings/P2/jlo", FireJlo__FP3JLO); -INCLUDE_ASM("asm/nonmatchings/P2/jlo", LandJlo__FP3JLO); +void LandJlo(JLO *pjlo) +{ + VECTOR pos; + + SetSoConstraints(pjlo, CT_Locked, NULL, CT_Locked, NULL); + (*(void (**)(ALO *, VECTOR *))(*(uint8_t **)pjlo + 0x90))(pjlo, &D_00248D30); + (*(void (**)(ALO *, VECTOR *))(*(uint8_t **)pjlo + 0x94))(pjlo, &D_00248D30); + GetPntPos(STRUCT_OFFSET(STRUCT_OFFSET(pjlo, 0x558, void *), 0x7A4, PNT *), &pos); + pos.z += STRUCT_OFFSET(pjlo, 0x56C, float); + (*(void (**)(ALO *, VECTOR *))(*(uint8_t **)pjlo + 0x84))(pjlo, &pos); +} INCLUDE_ASM("asm/nonmatchings/P2/jlo", JumpJlo__FP3JLO); -INCLUDE_ASM("asm/nonmatchings/P2/jlo", FUN_0016d928); +extern char D_002482D8[]; + +void FUN_0016d928(JLO *pjlo) +{ + if (STRUCT_OFFSET(pjlo, 0x5c0, int) == 0 || FVagPlaying() || NRandInRange(0, 100) >= 20) + return; + + int n = NRandInRange(0, 6); + PreloadVag1(&D_002482D8[n << 5]); + STRUCT_OFFSET(pjlo, 0x5cc, int) = 1; +} INCLUDE_ASM("asm/nonmatchings/P2/jlo", FUN_0016d9a8); @@ -69,11 +138,33 @@ void DeactivateJlo(JLO *pjlo) g_pjloCur = NULL; } -INCLUDE_ASM("asm/nonmatchings/P2/jlo", InitJloc__FP4JLOC); +void InitJloc(JLOC *pjloc) +{ + InitAlo(pjloc); + STRUCT_OFFSET(pjloc, 0x31C, float) = 2.25f; + STRUCT_OFFSET(pjloc, 0x320, float) = 2.0f; + STRUCT_OFFSET(pjloc, 0x324, float) = 0.8f; + STRUCT_OFFSET(pjloc, 0x328, float) = 4.0f; + STRUCT_OFFSET(pjloc, 0x32C, float) = 0.5f; + STRUCT_OFFSET(pjloc, 0x330, float) = 1000.0f; + STRUCT_OFFSET(pjloc, 0x334, float) = 2000.0f; +} -INCLUDE_ASM("asm/nonmatchings/P2/jlo", LoadJlocFromBrx__FP4JLOCP18CBinaryInputStream); +void LoadJlocFromBrx(JLOC *pjloc, CBinaryInputStream *pbis) +{ + LoadAloFromBrx(pjloc, pbis); -INCLUDE_ASM("asm/nonmatchings/P2/jlo", PostJlocLoad__FP4JLOC); + uint cplo = CploFindSwObjectsByClass(pjloc->psw, FSO_FindChild | FSO_ReturnActualCount, (CID)0x73, pjloc, 0x10, &STRUCT_OFFSET(pjloc, 0x2D0, LO *)); + STRUCT_OFFSET(pjloc, 0x310, uint) = cplo; + if (cplo > 0x10) + STRUCT_OFFSET(pjloc, 0x310, uint) = 0x10; +} + +void PostJlocLoad(JLOC *pjloc) +{ + PostAloLoad(pjloc); + pjloc->pvtlo->pfnRemoveLo(pjloc); +} INCLUDE_ASM("asm/nonmatchings/P2/jlo", PxfmChooseJloc__FP4JLOC); diff --git a/src/P2/joy.c b/src/P2/joy.c index cc7db82d2..da9a8d644 100644 --- a/src/P2/joy.c +++ b/src/P2/joy.c @@ -439,21 +439,25 @@ void Chetkido() ((NOTE *)&g_note.unk278)->pvtnote->pfnShowBlot((NOTE *)&g_note.unk278); } -INCLUDE_ASM("asm/nonmatchings/P2/joy", StartupCodes__Fv); -#ifdef SKIP_ASM -/** - * @todo 4.38% matched. - */ +extern CODE D_00262A80; +extern CODE D_00262AB8; +extern CODE D_00262AF0; +extern CODE D_00262B28; +extern CODE D_00262B60; +extern CODE D_00262B98; +extern CODE D_00262BD0; +extern CODE D_00262C08; +extern CODE D_00262C48; + void StartupCodes() { - ////AddCode(&cheat_reload_level.pCodeSeq); - ////AddCode(&cheat_reload_no_cheats.pCodeSeq); - ////AddCode(&cheat_reload_slippery_movement.pCodeSeq); - ////AddCode(&cheat_slippery_objects.pCodeSeq); - ////AddCode(&cheat_infinite_charms.pCodeSeq); - ////AddCode(&cheat_collect_bottles.pCodeSeq); - ////AddCode(&cheat_unlock_pages.pCodeSeq); - ////AddCode(&cheat_unlock_all_worlds.pCodeSeq); - ////AddCode(&cheat_chetkido_password.pCodeSeq); -} -#endif // SKIP_ASM + AddCode(&D_00262A80); + AddCode(&D_00262AB8); + AddCode(&D_00262AF0); + AddCode(&D_00262B28); + AddCode(&D_00262B60); + AddCode(&D_00262B98); + AddCode(&D_00262BD0); + AddCode(&D_00262C08); + AddCode(&D_00262C48); +} // SKIP_ASM diff --git a/src/P2/jsg.c b/src/P2/jsg.c index 4c2259fcd..2000b3d3e 100644 --- a/src/P2/jsg.c +++ b/src/P2/jsg.c @@ -17,13 +17,67 @@ INCLUDE_ASM("asm/nonmatchings/P2/jsg", GetJsgLocation__FP3JSGP2LOP6VECTORPf); INCLUDE_ASM("asm/nonmatchings/P2/jsg", SetJsgFocus__FP3JSGP2LO); -INCLUDE_ASM("asm/nonmatchings/P2/jsg", SetJsgTn__FP3JSGP2TN); +extern void FUN_001e2840(TN *ptn, TNS tns); + +void SetJsgTn(JSG *pjsg, TN *ptn) +{ + if (pjsg->ptnCur != NULL) + { + FUN_001e2840(pjsg->ptnCur, TNS_Nil); + STRUCT_OFFSET(pjsg->ptnCur, 0x2d0, int) = 0; + if (pjsg->fHideTn != 0) + { + (*(void (**)(LO *))((char *)pjsg->ptnCur->pvtlo + 0x1c))((LO *)pjsg->ptnCur); + } + pjsg->ptnCur = NULL; + } + + if (ptn != NULL) + { + pjsg->ptnCur = ptn; + pjsg->fHideTn = (FIsLoInWorld(ptn) == 0); + if (pjsg->fHideTn != 0) + { + (*(void (**)(LO *))((char *)ptn->pvtlo + 0x18))((LO *)ptn); + } + STRUCT_OFFSET(ptn, 0x2d0, JT *) = pjsg->pjt; + FUN_001e2840(ptn, TNS_In); + } +} INCLUDE_ASM("asm/nonmatchings/P2/jsg", NextJsgJsge__FP3JSG); INCLUDE_ASM("asm/nonmatchings/P2/jsg", FIsJsgJsgeComplete__FP3JSGP4JSGE); INCLUDE_ASM("asm/nonmatchings/P2/jsg", UpdateJsgJsge__FP3JSG); +#ifdef SKIP_ASM +void UpdateJsgJsge(JSG *pjsg) +{ + JSGE *pjsgeJoy; + + if (pjsg->ijsgeCur < 0) + { + if (pjsg->cjsge > 0) + NextJsgJsge(pjsg); + } + + while (pjsg->ijsgeCur < pjsg->cjsge) + { + JSGE *pjsge = &pjsg->ajsge[pjsg->ijsgeCur]; + if (pjsge->fAsync || FIsJsgJsgeComplete(pjsg, pjsge)) + NextJsgJsge(pjsg); + else + break; + } + + pjsgeJoy = pjsg->pjsgeJoy; + if (pjsgeJoy != NULL) + { + if (!FIsJsgJsgeComplete(pjsg, pjsgeJoy)) + pjsg->pjsgeJoy = NULL; + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/jsg", ReadJsgJoystick__FP3JSGP3JOY); diff --git a/src/P2/jt.c b/src/P2/jt.c index 054118a4f..d5a51e601 100644 --- a/src/P2/jt.c +++ b/src/P2/jt.c @@ -1,4 +1,11 @@ #include +#include +#include +#include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/jt", InitJt__FP2JT); @@ -14,11 +21,53 @@ INCLUDE_ASM("asm/nonmatchings/P2/jt", AdjustJtNewXp__FP2JTP2XPi); INCLUDE_ASM("asm/nonmatchings/P2/jt", AdjustJtDz__FP2JTiP2DZif); -INCLUDE_ASM("asm/nonmatchings/P2/jt", HandleJtGrfjtsc); +void HandleJtGrfjtsc(JT *pjt) +{ + int grfjtsc = STRUCT_OFFSET(pjt, 0x2254, int); + if (grfjtsc == 0) + return; + + if (grfjtsc & 0x8) + { + STRUCT_OFFSET(pjt, 0x2254, int) = grfjtsc & ~0x8; + STRUCT_OFFSET(pjt, 0x224C, int) = STRUCT_OFFSET(pjt, 0x2264, int); + } + + if (STRUCT_OFFSET(pjt, 0x2254, int) & 0x1) + SetJtJts(pjt, STRUCT_OFFSET(pjt, 0x2258, JTS), STRUCT_OFFSET(pjt, 0x225C, JTBS)); + + if (STRUCT_OFFSET(pjt, 0x2254, int) & 0x2) + SetJtJtcs(pjt, STRUCT_OFFSET(pjt, 0x2260, JTCS)); + + if (STRUCT_OFFSET(pjt, 0x2254, int) & 0x10) + FUN_001d4c98(pjt); +} INCLUDE_ASM("asm/nonmatchings/P2/jt", UpdateJtInternalXps__FP2JT); -INCLUDE_ASM("asm/nonmatchings/P2/jt", FCheckJtXpBase__FP2JTP2XPi); +extern float D_00274AD0[]; + +int FCheckJtXpBase(JT *pjt, XP *pxp, int ixpd) +{ + if (pjt->jts != JTS_Max) + { + return FCheckStepXpBase(pjt, pxp, ixpd); + } + + if (STRUCT_OFFSET(pxp, 0x88, float) * D_00274AD0[ixpd] < 0.7f) + { + return 0; + } + + { + int n = STRUCT_OFFSET(pxp, 0x9C, int); + if (n >= 7) + return 0; + if (n < 4) + return 0; + return ixpd == 0; + } +} INCLUDE_ASM("asm/nonmatchings/P2/jt", AdjustJtXpVelocity__FP2JTP2XPi); @@ -32,7 +81,52 @@ INCLUDE_ASM("asm/nonmatchings/P2/jt", RebuildJtXmg__FP2JTP3ALOfT1P6ACTADJP3XMG); INCLUDE_ASM("asm/nonmatchings/P2/jt", FMatchJtXmg__FP2JTP3XMGP6ACTADJ); -INCLUDE_ASM("asm/nonmatchings/P2/jt", UpdateJtStand__FP2JT); +struct XMG; + +int FTurnJtToTarget(JT *pjt); +void RebuildJtXmg(JT *pjt, ALO *palo, float s, ALO *palo2, ACTADJ *pactadj, XMG *pxmg); + +void UpdateJtStand(JT *pjt) +{ + if (FTurnJtToTarget(pjt) == 0) + { + if (STRUCT_OFFSET(pjt, 0x690, int) != 0) + { + VECTOR w; + float g; + + CalculateAloMovement(STRUCT_OFFSET(pjt, 0x6C0, ALO *), NULL, + (VECTOR *)((char *)pjt + 0x6A0), NULL, &w, NULL, NULL); + g = GLimitAbs(w.z, 10.0f); + w.z = g; + STRUCT_OFFSET(pjt, 0x638, float) += g * g_clock.dt; + } + } + + if (STRUCT_OFFSET(pjt, 0x250C, ACTADJ *) != NULL) + { + RebuildJtXmg(pjt, STRUCT_OFFSET(pjt, 0x628, ALO *), 5.0f, STRUCT_OFFSET(pjt, 0x620, ALO *), + STRUCT_OFFSET(pjt, 0x250C, ACTADJ *), (XMG *)((char *)pjt + 0x1190)); + RebuildJtXmg(pjt, STRUCT_OFFSET(pjt, 0x62C, ALO *), 5.0f, STRUCT_OFFSET(pjt, 0x624, ALO *), + STRUCT_OFFSET(pjt, 0x2510, ACTADJ *), (XMG *)((char *)pjt + 0x1290)); + + if (FMatchJtXmg(pjt, (XMG *)((char *)pjt + 0x1190), STRUCT_OFFSET(pjt, 0x250C, ACTADJ *))) + { + if (FMatchJtXmg(pjt, (XMG *)((char *)pjt + 0x1290), STRUCT_OFFSET(pjt, 0x2510, ACTADJ *))) + return; + } + + if (STRUCT_OFFSET(pjt, 0x118C, int) != 0) + return; + + if (STRUCT_OFFSET(pjt, 0x1188, SM *) != NULL) + { + if (IsmsFindSmOptional(STRUCT_OFFSET(pjt, 0x1188, SM *), (OID)0x148) >= 0) + SeekSma(STRUCT_OFFSET(pjt, 0x2234, SMA *), (OID)0x148); + STRUCT_OFFSET(pjt, 0x118C, int) = 1; + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/jt", ThrowJt__FP2JTP6VECTORff); @@ -50,17 +144,81 @@ INCLUDE_ASM("asm/nonmatchings/P2/jt", UpdateJtTool__FP2JT); INCLUDE_ASM("asm/nonmatchings/P2/jt", FUN_00172898); -INCLUDE_ASM("asm/nonmatchings/P2/jt", UpdateJtPosWorldPrev__FP2JT); +void UpdateJtPosWorldPrev(JT *pjt) +{ + UpdateSoPosWorldPrev(pjt); + STRUCT_OFFSET(pjt, 0x21CC, int) = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/jt", FUN_00172b08); -INCLUDE_ASM("asm/nonmatchings/P2/jt", UpdateJtBounds__FP2JT); +void UpdateJtBounds(JT *pjt) +{ + UpdateSoBounds(pjt); + + int i = 0; + if (STRUCT_OFFSET(pjt, 0x21CC, int) > 0) + { + VECTOR *ppos = (VECTOR *)((char *)pjt + 0x21D0); + do + { + ExtendSoBounds(pjt, ppos, STRUCT_OFFSET(pjt, 0x2420, float)); + i++; + ppos = (VECTOR *)((char *)ppos + 0x10); + } while (i < STRUCT_OFFSET(pjt, 0x21CC, int)); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/jt", PsoGetJtEffect__FP2JTPi); +SO *PsoGetJtEffect(JT *pjt, int *pn) +{ + SO *pso; + + pso = STRUCT_OFFSET(pjt, 0x25D8, SO *); + if (pso != NULL && FIsLoInWorld(pso)) + { + *pn = 0; + return STRUCT_OFFSET(pjt, 0x25D8, SO *); + } + + pso = STRUCT_OFFSET(pjt, 0x25E0, SO *); + if (pso != NULL && FIsLoInWorld(pso)) + { + *pn = 1; + return STRUCT_OFFSET(pjt, 0x25E0, SO *); + } + + pso = STRUCT_OFFSET(pjt, 0x25DC, SO *); + if (pso != NULL && FIsLoInWorld(pso)) + { + *pn = 2; + return STRUCT_OFFSET(pjt, 0x25DC, SO *); + } + + pso = STRUCT_OFFSET(pjt, 0x25E4, SO *); + if (pso != NULL && FIsLoInWorld(pso)) + { + *pn = 2; + return STRUCT_OFFSET(pjt, 0x25E4, SO *); + } + + pso = STRUCT_OFFSET(pjt, 0x25E8, SO *); + if (pso != NULL && FIsLoInWorld(pso)) + { + *pn = 1; + return STRUCT_OFFSET(pjt, 0x25E8, SO *); + } + + return NULL; +} INCLUDE_ASM("asm/nonmatchings/P2/jt", AddJtCustomXps__FP2JTP2SOiP3BSPT3PP2XP); -INCLUDE_ASM("asm/nonmatchings/P2/jt", CtTorqueJt__FP2JT); +int CtTorqueJt(JT *pjt) +{ + if (pjt->jts == JTS_Zap || pjt->jts == JTS_Max) + return 0; + return 3; +} INCLUDE_ASM("asm/nonmatchings/P2/jt", FUN_00172ee0); @@ -78,7 +236,25 @@ INCLUDE_ASM("asm/nonmatchings/P2/jt", UpdateJtDrive__FP2JT); INCLUDE_ASM("asm/nonmatchings/P2/jt", ChooseJtPhys__FP2JT); -INCLUDE_ASM("asm/nonmatchings/P2/jt", EnableJtActadj__FP2JTi); +void EnableJtActadj(JT *pjt, int grf) +{ + if (STRUCT_OFFSET(pjt, 0x2500, void *) == NULL) + return; + + int a0 = grf & 0x1; + STRUCT_OFFSET(STRUCT_OFFSET(pjt, 0x2500, char *), 0x10, char) = a0 ? 9 : -1; + STRUCT_OFFSET(STRUCT_OFFSET(pjt, 0x2504, char *), 0x10, char) = a0 ? 9 : -1; + STRUCT_OFFSET(STRUCT_OFFSET(pjt, 0x2508, char *), 0x10, char) = a0 ? 9 : -1; + int a2 = grf & 0x2; + STRUCT_OFFSET(STRUCT_OFFSET(pjt, 0x250C, char *), 0x10, char) = a2 ? 9 : -1; + STRUCT_OFFSET(STRUCT_OFFSET(pjt, 0x2510, char *), 0x10, char) = a2 ? 9 : -1; + + (*(*(void (***)(void *))STRUCT_OFFSET(pjt, 0x24F8, void *))[0x2F])(STRUCT_OFFSET(pjt, 0x24F8, void *)); + (*(*(void (***)(void *))STRUCT_OFFSET(pjt, 0x618, void *))[0x2F])(STRUCT_OFFSET(pjt, 0x618, void *)); + (*(*(void (***)(void *))STRUCT_OFFSET(pjt, 0x61C, void *))[0x2F])(STRUCT_OFFSET(pjt, 0x61C, void *)); + (*(*(void (***)(void *))STRUCT_OFFSET(pjt, 0x610, void *))[0x2F])(STRUCT_OFFSET(pjt, 0x610, void *)); + (*(*(void (***)(void *))STRUCT_OFFSET(pjt, 0x614, void *))[0x2F])(STRUCT_OFFSET(pjt, 0x614, void *)); +} INCLUDE_ASM("asm/nonmatchings/P2/jt", SetJtJts__FP2JT3JTS4JTBS); @@ -87,19 +263,49 @@ void ProfileJt(JT *pjt, int fProfile) return; } -INCLUDE_ASM("asm/nonmatchings/P2/jt", SetJtPuppet__FP2JTP5ASEGA); +void SetJtPuppet(JT *pjt, ASEGA *paseg) +{ + SetJtJts(pjt, paseg ? JTS_Peek : JTS_Stand, JTBS_Nil); +} -INCLUDE_ASM("asm/nonmatchings/P2/jt", FUN_00177828); +void FUN_00177828(JT *pjt, int n) +{ + STRUCT_OFFSET(pjt, 0x2bd8, int) = n; + STRUCT_OFFSET(pjt, 0x4b8, int) = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/jt", PaloAbsorbWkr__FP3WKRiPP3ALO); -INCLUDE_ASM("asm/nonmatchings/P2/jt", NCmpWkr__FP3WKRT0); +int NCmpWkr(WKR *pwkr1, WKR *pwkr2) +{ + return STRUCT_OFFSET(pwkr1, 0x14, float) > STRUCT_OFFSET(pwkr2, 0x14, float) ? 1 : -1; +} INCLUDE_ASM("asm/nonmatchings/P2/jt", UpdateJtEffect__FP2JT); -INCLUDE_ASM("asm/nonmatchings/P2/jt", FIsJtSoundBase__FP2JT); +int FIsJtSoundBase(JT *pjt) +{ + if (pjt->jts == JTS_Ball && pjt->jtbs == JTBS_Zap_Electric) + return 0; + + return !FActiveCplcy(&STRUCT_OFFSET(g_pcm, 0x454, CPLCY)); +} -INCLUDE_ASM("asm/nonmatchings/P2/jt", CollectJtPrize__FP2JT3PCKP3ALO); +void CollectJtPrize(JT *pjt, PCK pck, ALO *paloOther) +{ + CollectPoPrize(pjt, pck, paloOther); + + switch (pck) + { + case PCK_Key: + SetJtJts(pjt, JTS_Rush, JTBS_Rush_Attack); + break; + + case PCK_Gold: + SetJtJts(pjt, JTS_Rush, JTBS_Rush_Bounce); + break; + } +} INCLUDE_ASM("asm/nonmatchings/P2/jt", GetJtDiapi__FP2JTP6DIALOGP5DIAPI); diff --git a/src/P2/lgn.c b/src/P2/lgn.c index 68acb7eb1..9720fd974 100644 --- a/src/P2/lgn.c +++ b/src/P2/lgn.c @@ -1,5 +1,9 @@ #include #include +#include +#include +#include +#include void InitLgn(LGN *plgn) { @@ -34,13 +38,30 @@ void UseLgnCharm(LGN *plgn) SetLgnLgns(plgn, LGNS_Active); } -INCLUDE_ASM("asm/nonmatchings/P2/lgn", ApplyLgnThrow__FP3LGNP2PO); +extern VECTOR D_00264180; +extern float D_00264190; + +void ApplyLgnThrow(LGN *plgn, PO *ppo) +{ + VECTOR posTarget; + VECTOR v; + + ConvertAloPos((ALO *)plgn, NULL, &D_00264180, &posTarget); + CalculateSoTrajectoryApex((SO *)ppo, &posTarget, D_00264190, &v); + (*(void (**)(SO *, VECTOR *))(*(uint8_t **)ppo + 0x90))((SO *)ppo, &v); + STRUCT_OFFSET(ppo, 0x638, float) = RadNormalize(atan2f(v.y, v.x) + 3.1415927f); + FixStepAngularVelocity((STEP *)ppo); + SetJtJts((JT *)ppo, JTS_Sidestep, (JTBS)0x2B); +} INCLUDE_ASM("asm/nonmatchings/P2/lgn", FTakeLgnDamage__FP3LGNP3ZPR); INCLUDE_ASM("asm/nonmatchings/P2/lgn", HandleLgnMessage__FP3LGN5MSGIDPv); -INCLUDE_ASM("asm/nonmatchings/P2/lgn", FUN_00181d88); +void FUN_00181d88(uint8_t *param_1) +{ + FUN_001bc4d8(param_1, param_1 + 0xC04); +} INCLUDE_ASM("asm/nonmatchings/P2/lgn", SetLgnLgns__FP3LGN4LGNS); @@ -50,7 +71,19 @@ INCLUDE_ASM("asm/nonmatchings/P2/lgn", DrawLgnr__FP4LGNR); INCLUDE_ASM("asm/nonmatchings/P2/lgn", InitSwp__FP3SWP); -INCLUDE_ASM("asm/nonmatchings/P2/lgn", PostSwpLoad__FP3SWP); +extern SNIP D_00264230; + +void PostSwpLoad(SWP *pswp) +{ + PostBrkLoad((BRK *)pswp); + SnipAloObjects((ALO *)pswp, 2, &D_00264230); + STRUCT_OFFSET(pswp, 0x6c8, SMA *) = + PsmaApplySm(STRUCT_OFFSET(pswp, 0x6c4, SM *), (ALO *)pswp, (OID)0x36e, 0); + ACG *pacg = PacgNew((ACGK) 0); + STRUCT_OFFSET(pswp, 0x6e8, ACG *) = pacg; + STRUCT_OFFSET(pacg, 0x8, int) = 0; + STRUCT_OFFSET(STRUCT_OFFSET(pswp, 0x6e8, ACG *), 0xc, void *) = PvAllocSwImpl(0xc00); +} INCLUDE_ASM("asm/nonmatchings/P2/lgn", UpdateSwp__FP3SWPf); diff --git a/src/P2/light.c b/src/P2/light.c index ef552ad14..658c5975b 100644 --- a/src/P2/light.c +++ b/src/P2/light.c @@ -4,7 +4,30 @@ #include #include +extern VU_VECTOR g_normalY; + INCLUDE_ASM("asm/nonmatchings/P2/light", InitLight__FP5LIGHT); +#ifdef SKIP_ASM +void InitLight(LIGHT *plight) +{ + uint64_t grfalo = STRUCT_OFFSET(plight, 0x2c8, uint64_t); + STRUCT_OFFSET(plight, 0x2d0, int) = 0; + STRUCT_OFFSET(plight, 0x2c8, uint64_t) = (grfalo & ~0x30000000000ULL) | (0x8000ULL << 0x19); + + STRUCT_OFFSET(plight, 0x320, VU_VECTOR) = *(VU_VECTOR *)&g_normalZ; + STRUCT_OFFSET(plight, 0x340, VU_VECTOR) = g_normalY; + + STRUCT_OFFSET(plight, 0x330, float) = 200.0f; + STRUCT_OFFSET(plight, 0x334, float) = 2000.0f; + STRUCT_OFFSET(plight, 0x2fc, float) = 240.0f; + STRUCT_OFFSET(plight, 0x300, float) = 180.0f; + STRUCT_OFFSET(plight, 0x338, float) = 60.0f; + STRUCT_OFFSET(plight, 0x2f8, float) = 180.0f; + + RebuildLightFrustrum(plight); + InitAlo(plight); +} +#endif // SKIP_ASM void UpdateLightXfWorldHierarchy(LIGHT *plight) { @@ -43,7 +66,7 @@ void OnLightRemove(LIGHT *plight) /** * @todo 98.75% match. */ -INCLUDE_ASM("asm/nonmatchings/P2/light", CloneLight__FP5LIGHTT0); +INCLUDE_ASM("asm/nonmatchings/P2/light", CloneLight__FP5LIGHTT0); // SKIP_ASM #ifdef SKIP_ASM void CloneLight(LIGHT *plight, LIGHT *plightBase) { @@ -131,7 +154,11 @@ INCLUDE_ASM("asm/nonmatchings/P2/light", RebuildLightVifs__FP5LIGHT); INCLUDE_ASM("asm/nonmatchings/P2/light", SetLightKind__FP5LIGHT6LIGHTK); -INCLUDE_ASM("asm/nonmatchings/P2/light", SetLightHighlightColor__FP5LIGHTP6VECTOR); +void SetLightHighlightColor(LIGHT *plight, VECTOR *pvecHighlight) +{ + STRUCT_OFFSET(plight, 0x2E0, VU_VECTOR) = *(VU_VECTOR *)pvecHighlight; + RebuildLightVifs(plight); +} void SetLightMidtoneStrength(LIGHT *plight, float gMidtone) { @@ -191,7 +218,12 @@ void SetLightHotSpotAngle(LIGHT *plight, float degHotSpot) RebuildLightVifs(plight); } -INCLUDE_ASM("asm/nonmatchings/P2/light", SetLightFrustrumUp__FP5LIGHTP6VECTOR); +void SetLightFrustrumUp(LIGHT *plight, VECTOR *pvecUpLocal) +{ + STRUCT_OFFSET(plight, 0x340, VU_VECTOR) = *(VU_VECTOR *)pvecUpLocal; + RebuildLightVifs(plight); + UpdateLightBeamGrfzon(plight); +} INCLUDE_ASM("asm/nonmatchings/P2/light", RebuildLightFrustrum__FP5LIGHT); diff --git a/src/P2/mark.c b/src/P2/mark.c index e300caf44..fba6ef24b 100644 --- a/src/P2/mark.c +++ b/src/P2/mark.c @@ -1,6 +1,22 @@ #include - -INCLUDE_ASM("asm/nonmatchings/P2/mark", MuFromAmtlk__FP4MTLK); +#include + +extern float D_00264840[][2]; + +float MuFromAmtlk(MTLK *amtlk) +{ + float mu = (D_00264840[amtlk[0]][1] + D_00264840[amtlk[1]][1]) / + (D_00264840[amtlk[0]][0] + D_00264840[amtlk[1]][0]); + if (mu < 0.0f) + { + mu = 0.0f; + } + if (g_grfcht & FCHT_LowFriction) + { + mu *= 0.2f; + } + return mu; +} INCLUDE_ASM("asm/nonmatchings/P2/mark", ElasFromAmtlk__FP4MTLK); diff --git a/src/P2/mat.c b/src/P2/mat.c index 2b5c228a9..6269cde75 100644 --- a/src/P2/mat.c +++ b/src/P2/mat.c @@ -1,9 +1,20 @@ #include #include +#include +#include +#include extern VECTOR g_normalZ; -INCLUDE_ASM("asm/nonmatchings/P2/mat", PostCopyMatrix3__7MATRIX4); +extern qword D_0024B260; + +void MATRIX4::PostCopyMatrix3() +{ + STRUCT_OFFSET(this, 0xc, int) = 0; + STRUCT_OFFSET(this, 0x1c, int) = 0; + STRUCT_OFFSET(this, 0x2c, int) = 0; + *(qword *)((char *)this + 0x30) = D_0024B260; +} INCLUDE_ASM("asm/nonmatchings/P2/mat", __as__7MATRIX4RC7MATRIX3); @@ -51,7 +62,16 @@ JUNK_NOP(); JUNK_NOP(); JUNK_ADDIU(60); -INCLUDE_ASM("asm/nonmatchings/P2/mat", CosRotateMatrixMagnitude__FP7MATRIX3); +float CosRotateMatrixMagnitude(MATRIX3 *pmat) +{ + float gTrace; + + gTrace = STRUCT_OFFSET(pmat, 0x0, float) + STRUCT_OFFSET(pmat, 0x14, float); + gTrace = gTrace + STRUCT_OFFSET(pmat, 0x28, float); + gTrace = gTrace - 1.0f; + + return GLimitAbs(gTrace * 0.5f, 1.0f); +} INCLUDE_ASM("asm/nonmatchings/P2/mat", DecomposeRotateMatrixRad__FP7MATRIX3PfP6VECTOR); @@ -65,7 +85,12 @@ INCLUDE_ASM("asm/nonmatchings/P2/mat", CalculateDmat__FP7MATRIX3N20); INCLUDE_ASM("asm/nonmatchings/P2/mat", CalculateDmat4__FP7MATRIX4N20); -INCLUDE_ASM("asm/nonmatchings/P2/mat", DecomposeRotateMatrixPanTilt__FP7MATRIX3PfT1); +void DecomposeRotateMatrixPanTilt(MATRIX3 *pmat, float *pradPan, float *pradTilt) +{ + *pradPan = atan2f(pmat->mat[0][1], pmat->mat[0][0]); + *pradTilt = atan2f(pmat->mat[0][2], + SQRTF(pmat->mat[0][0] * pmat->mat[0][0] + pmat->mat[0][1] * pmat->mat[0][1])); +} INCLUDE_ASM("asm/nonmatchings/P2/mat", LoadRotateMatrixPanTilt__FffP7MATRIX3); diff --git a/src/P2/mb.c b/src/P2/mb.c index 7f447754a..65d374d36 100644 --- a/src/P2/mb.c +++ b/src/P2/mb.c @@ -1,4 +1,9 @@ #include +#include +#include +#include +#include +#include extern SNIP s_asnipLoadMbg[2]; @@ -32,7 +37,22 @@ INCLUDE_ASM("asm/nonmatchings/P2/mb", FDetectMbg__FP3MBG); INCLUDE_ASM("asm/nonmatchings/P2/mb", FUN_0018ab88__Fi); -INCLUDE_ASM("asm/nonmatchings/P2/mb", FUN_0018abf0__Fi); +SGS FUN_0018abf0(int param) +{ + STEPGUARD *pstepguard = (STEPGUARD *)param; + OID oid; + + if (STRUCT_OFFSET(pstepguard, 0x724, int) == 4) + { + GetSmaCur((SMA *)STRUCT_OFFSET(pstepguard, 0xE10, int), &oid); + if (oid == (OID)0x438 && SggsGetStepguard(pstepguard) == 0) + { + return (SGS)2; + } + } + + return SgsNextStepguardAI(pstepguard); +} INCLUDE_ASM("asm/nonmatchings/P2/mb", FUN_0018ac58__Fi); @@ -47,7 +67,22 @@ INCLUDE_ASM("asm/nonmatchings/P2/mb", UpdateMbgGoal__FP3MBGi); INCLUDE_ASM("asm/nonmatchings/P2/mb", UpdateMbgSgs__FP3MBG); -INCLUDE_ASM("asm/nonmatchings/P2/mb", OnMgExitingSgs__FP3MBG3SGS); +void OnMgExitingSgs(MBG *pmbg, SGS sgs) +{ + OnStepguardExitingSgs(pmbg, sgs); + + int field_0x724 = STRUCT_OFFSET(pmbg, 0x724, int); + if (field_0x724 == 0x10) + { + int field_0xE3C = STRUCT_OFFSET(pmbg, 0xE3C, int); + if (field_0xE3C != -1) + { + int field_0xE10 = STRUCT_OFFSET(pmbg, 0xE10, int); + SetSmaGoal((SMA *)field_0xE10, (OID)field_0xE3C); + STRUCT_OFFSET(pmbg, 0xE3C, int) = -1; + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/mb", HandleMbgMessage__FP3MBG5MSGIDPv); diff --git a/src/P2/missile.c b/src/P2/missile.c index 5d65e43ca..1e282c960 100644 --- a/src/P2/missile.c +++ b/src/P2/missile.c @@ -1,5 +1,6 @@ #include #include +#include void InitMissile(MISSILE *pmissile) { @@ -7,7 +8,15 @@ void InitMissile(MISSILE *pmissile) STRUCT_OFFSET(pmissile, 0x6b8, int) = 1; // pmissile->fFollowTrajectory } -INCLUDE_ASM("asm/nonmatchings/P2/missile", LoadMissileFromBrx__FP7MISSILEP18CBinaryInputStream); +extern SNIP s_asnipMissile; + +void LoadMissileFromBrx(MISSILE *pmissile, CBinaryInputStream *pbis) +{ + LoadBombFromBrx(pmissile, pbis); + SnipAloObjects(pmissile, 1, &s_asnipMissile); + uint64_t grfalo = STRUCT_OFFSET(pmissile, 0x2c8, uint64_t); + STRUCT_OFFSET(pmissile, 0x2c8, uint64_t) = (grfalo & ~0x30000000000ULL) | (0x8000ULL << 0x19); +} void OnMissileRemove(MISSILE *pmissile) { @@ -26,12 +35,69 @@ INCLUDE_ASM("asm/nonmatchings/P2/missile", FireMissile__FP7MISSILEP3ALOP6VECTOR) INCLUDE_ASM("asm/nonmatchings/P2/missile", RenderMissileAll__FP7MISSILEP2CMP2RO); INCLUDE_ASM("asm/nonmatchings/P2/missile", FUN_0018dc88); +#ifdef SKIP_ASM +int FUN_0018dc88(SO *pso, SO *psoOther) +{ + int i; + + if (psoOther == STRUCT_OFFSET(pso, 0x6e4, SO *)) + return 1; + + if (STRUCT_OFFSET(pso, 0x6bc, int) > 0) + { + OID *aoid = &STRUCT_OFFSET(pso, 0x6c0, OID); + i = 0; + do + { + if (FMatchesLoName((LO *)psoOther, aoid[i])) + return 1; + i++; + } while (i < STRUCT_OFFSET(pso, 0x6bc, int)); + } -INCLUDE_ASM("asm/nonmatchings/P2/missile", FUN_0018dd50); + if (STRUCT_OFFSET(pso, 0x6d0, int) > 0) + { + CID *acid = &STRUCT_OFFSET(pso, 0x6d4, CID); + i = 0; + do + { + if (FIsBasicDerivedFrom((BASIC *)psoOther, acid[i])) + return 1; + i++; + } while (i < STRUCT_OFFSET(pso, 0x6d0, int)); + } -INCLUDE_ASM("asm/nonmatchings/P2/missile", FUN_0018dd78); + return FIgnoreSoIntersection(pso, psoOther); +} +#endif // SKIP_ASM -INCLUDE_ASM("asm/nonmatchings/P2/missile", InitAccmiss__FP7ACCMISS); +void FUN_0018dd50(void * p, int val) +{ + int c = STRUCT_OFFSET(p, 0x6bc, int); + if ((unsigned int)c < 4) + { + int *a = &STRUCT_OFFSET(p, 0x6c0, int); + a[c] = val; + STRUCT_OFFSET(p, 0x6bc, int) = c + 1; + } +} + +void FUN_0018dd78(void * p, int val) +{ + int c = STRUCT_OFFSET(p, 0x6d0, int); + if ((unsigned int)c < 4) + { + int *a = &STRUCT_OFFSET(p, 0x6d4, int); + a[c] = val; + STRUCT_OFFSET(p, 0x6d0, int) = c + 1; + } +} + +void InitAccmiss(ACCMISS *paccmiss) +{ + InitMissile(paccmiss); + *(qword *)((char *)paccmiss + 0x350) = *(qword *)&D_00248D30; +} INCLUDE_ASM("asm/nonmatchings/P2/missile", FireAccmiss__FP7ACCMISSP3ALOP6VECTOR); diff --git a/src/P2/mpeg.c b/src/P2/mpeg.c index 16a9e044e..0a465c70a 100644 --- a/src/P2/mpeg.c +++ b/src/P2/mpeg.c @@ -1,20 +1,116 @@ #include - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FUN_0018e410); - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FUN_0018e480); - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FUN_0018e4c0); - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FUN_0018e4f0); +#include +#include <989snd.h> +#include + +extern uchar D_002484B0[16][32]; + +int FUN_0018e410(void *pv) +{ + uchar (*pb)[32] = D_002484B0; + int i = 0; +loop: + { + int match; + if (pb == (uchar (*)[32])pv) + match = 1; + else if (pb == 0) + match = 0; + else if (pv == 0) + match = 0; + else + { + int *e = (int *)pb; + int *a = (int *)pv; + match = ((e[2] ^ e[6]) ^ (a[2] ^ a[6])) == 0; + } + if (match != 0) + return i; + } + i++; + if (i < 16) + { + pb++; + goto loop; + } + // @todo try to do this without goto + return -1; +} + +extern char *D_002699C0[16]; +extern char D_0024B580[]; +extern char D_0024B588[]; + +char *FUN_0018e480(int x) +{ + if ((uint)x < 16) + return D_002699C0[x]; + if (x == -1) + return D_0024B580; + return D_0024B588; +} + +extern uchar D_002484B0[16][32]; + +void FUN_0018e4c0(int i) +{ + FUN_0018f0e8(&g_mpeg, D_002484B0[i]); +} + +extern uchar *D_00269A08; + +void FUN_0018e4f0(int param1, int i) +{ + FUN_0018e4c0(param1); + D_00269A08 = D_002484B0[i]; + int bits; + if ((uint)i >= 16) + bits = 0; + else + bits = 1 << i; + STRUCT_OFFSET(g_pgsCur, 0x19F4, int) |= bits; +} INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FUN_0018e558); INCLUDE_ASM("asm/nonmatchings/P2/mpeg", StartupMpeg__Fv); -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Init__15CQueueOutputIopii); - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Reset__15CQueueOutputIop); +#ifndef CQUEUEOUTPUTIOP_DEFINED +#define CQUEUEOUTPUTIOP_DEFINED +class CQueueOutputIop +{ +public: + int unk_0x0; + int unk_0x4; + int unk_0x8; + int unk_0xc; + int unk_0x10; + int unk_0x14; + int unk_0x18; + int unk_0x1c; + + void Init(int nParam1, int nParam2); + void Reset(); + void Update(); + int FAsyncDrain(); +}; +#endif // CQUEUEOUTPUTIOP_DEFINED + +void CQueueOutputIop::Init(int nParam1, int nParam2) +{ + unk_0x4 = nParam2; + unk_0x8 = nParam1; + Reset(); +} + +void CQueueOutputIop::Reset() +{ + unk_0x14 = unk_0x8; + unk_0x18 = 0; + unk_0x10 = 0; + unk_0xc = 0; + unk_0x1c = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/mpeg", CbWrite__15CQueueOutputIopiPv); @@ -22,31 +118,131 @@ INCLUDE_ASM("asm/nonmatchings/P2/mpeg", CbSend__15CQueueOutputIopiPv); INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Update__15CQueueOutputIop); -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FAsyncDrain__15CQueueOutputIop); +int CQueueOutputIop::FAsyncDrain() +{ + return 0; +} + +class CQueueOutputIpu +{ +public: + int FAsyncDrain(); +}; INCLUDE_ASM("asm/nonmatchings/P2/mpeg", CbWrite__15CQueueOutputIpuiPv); -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FAsyncDrain__15CQueueOutputIpu); +int CQueueOutputIpu::FAsyncDrain() +{ + return 1; +} INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Init__10CMpegAudio); -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Reset__10CMpegAudio); - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Close__10CMpegAudio); +#ifndef CMPEGAUDIO_DEFINED +#define CMPEGAUDIO_DEFINED +class CMpegAudio +{ +public: + int unk_0x0; + char pad_0x4[0x2C - 0x4]; + CByteQueue bqDemux; + char pad_0x40[0x4C - 0x2C - (int)sizeof(CByteQueue)]; + CByteQueue bqOut; + char pad_0x60[0x6C - 0x4C - (int)sizeof(CByteQueue)]; + CQueueOutputIop qoi; + + void Reset(); + void Update(); + void Close(); +}; +#endif // CMPEGAUDIO_DEFINED + +void CMpegAudio::Reset() +{ + if (unk_0x0 != 0) + { + snd_ResetMovieSound(); + unk_0x0 = 1; + bqDemux.Reset(); + bqOut.Reset(); + qoi.Reset(); + } +} + +struct SW; +extern SW *g_psw; +void PopSwReverb(SW *psw); + +void CMpegAudio::Close() +{ + unk_0x0 = 0; + snd_CloseMovieSound(); + snd_SetMasterVolume(2, STRUCT_OFFSET(this, 0x8C, int)); + snd_SetMasterVolume(8, STRUCT_OFFSET(this, 0x90, int)); + PopSwReverb(g_psw); + snd_ContinueAllSoundsInGroup(0xFFFFFFFF); +} INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FAccept__10CMpegAudioiPUc); INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Update__10CMpegAudio); - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FMpegAcceptVideo__FP7sceMpegP16sceMpegCbDataStrP5CMpeg); - -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FMpegAcceptAudio__FP7sceMpegP16sceMpegCbDataStrP5CMpeg); +#ifdef SKIP_ASM +void CMpegAudio::Update() +{ + if (unk_0x0 == 2) + { + bqOut.CbDrain(qoi.unk_0x14, (CQueueOutput *)&qoi); + if (qoi.unk_0x14 == 0) + { + snd_StartMovieSound(qoi.unk_0x4, qoi.unk_0x8, qoi.unk_0x4, 0, 0); + unk_0x0 = 3; + } + } + else if (unk_0x0 == 3) + { + qoi.Update(); + bqOut.CbDrain(qoi.unk_0x14, (CQueueOutput *)&qoi); + } +} +#endif // SKIP_ASM + +// @todo Move these to a header +struct sceMpeg; +struct sceMpegCbDataStr; + +int FMpegAcceptVideo(sceMpeg *pmp, sceMpegCbDataStr *pcbdata, CMpeg *pmpeg) +{ + int cb = STRUCT_OFFSET(pcbdata, 0xC, int); // pcbdata->len + + // pmpeg+0x60 is the video CByteQueue; +0x70 is its m_cbFree + if ((uint)STRUCT_OFFSET(pmpeg, 0x70, int) < (uint)cb) + { + return 0; + } + + STRUCT_OFFSET(pmpeg, 0x60, CByteQueue).CbFill(cb, STRUCT_OFFSET(pcbdata, 0x8, byte *)); // pcbdata->data + return 1; +} + +int FMpegAcceptAudio(sceMpeg *pmp, sceMpegCbDataStr *pcbdata, CMpeg *pmpeg) +{ + return FAccept__10CMpegAudioiPUc((uint8_t *)pmpeg + 0x80, STRUCT_OFFSET(pcbdata, 0xC, int), STRUCT_OFFSET(pcbdata, 0x8, uchar *)); +} INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FMpegDecodeVideo__FP7sceMpegP13sceMpegCbDataP5CMpeg); -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FMpegDecoderIdle__FP7sceMpegP13sceMpegCbDataP5CMpeg); +struct sceMpegCbData; +int FMpegDecoderIdle(sceMpeg *pmp, sceMpegCbData *pcbdata, CMpeg *pmpeg) +{ + pmpeg->CbDemuxed((OID)0); + return 1; +} -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FMpegDecoderError__FP7sceMpegP13sceMpegCbDataP5CMpeg); + +int FMpegDecoderError(sceMpeg *pmp, sceMpegCbData *pcbdata, CMpeg *pmpeg) +{ + return 1; +} INCLUDE_ASM("asm/nonmatchings/P2/mpeg", BuildMpegGifs__FP2QWP11sceIpuRGB32iiiii); @@ -54,9 +250,22 @@ INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FUN_0018ef78); INCLUDE_ASM("asm/nonmatchings/P2/mpeg", FUN_0018f0e8); -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", ExecuteOids__5CMpeg); +void CMpeg::ExecuteOids() +{ + OID *poidNext = STRUCT_OFFSET(this, 0x8, OID *); // queued second mpeg oid ptr + OID *poid = STRUCT_OFFSET(this, 0x4, OID *); // queued first mpeg oid ptr + + STRUCT_OFFSET(this, 0x4, OID *) = 0; + STRUCT_OFFSET(this, 0x8, OID *) = 0; + Execute(poid); + + if (poidNext != 0) + { + Execute(poidNext); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Execute__5CMpeg); +INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Execute__5CMpegP3OID); INCLUDE_ASM("asm/nonmatchings/P2/mpeg", Start__5CMpegP18CBinaryAsyncStream); diff --git a/src/P2/path.c b/src/P2/path.c index b06e0c4bb..719b56a48 100644 --- a/src/P2/path.c +++ b/src/P2/path.c @@ -1,19 +1,33 @@ #include struct CBSP; +struct CGT; +struct LSG; CBSP* PcbspExtract(CBSP* pcbsp) { return ((int)pcbsp & 1) ? (CBSP*)0 : pcbsp; } -INCLUDE_ASM("asm/nonmatchings/P2/path", PcgtExtract__FP3CGT); +CGT* PcgtExtract(CGT* pcgt) +{ + if ((int)pcgt & 1) + return (CGT*)((int)pcgt & ~1); + return (CGT*)0; +} INCLUDE_ASM("asm/nonmatchings/P2/path", PcgtPointInCbspQuick__FP4CBSPP6VECTOR); INCLUDE_ASM("asm/nonmatchings/P2/path", PcgtPointInCbspSafe__FP4CBSPP6VECTOR); -INCLUDE_ASM("asm/nonmatchings/P2/path", CbskFromG__Ff); +int CbskFromG(float g) +{ + if (g > 1.0f) + return 0; + if (g < -1.0f) + return 1; + return 2; +} INCLUDE_ASM("asm/nonmatchings/P2/path", ClsgClipEdgeToCbsp__FP4CBSPP6VECTORT1iP3LSG); @@ -39,11 +53,26 @@ INCLUDE_ASM("asm/nonmatchings/P2/path", LoadPathzoneFromBrx__FP8PATHZONEP18CBina INCLUDE_ASM("asm/nonmatchings/P2/path", HookupCg__FP2CG); -INCLUDE_ASM("asm/nonmatchings/P2/path", CposFindPathzonePath__FP8PATHZONEP6VECTORT1iT1); +struct PATHZONE; +struct VECTOR; + +int CposFindPathzonePath(PATHZONE *ppathzone, VECTOR *pvec0, VECTOR *pvec1, int n, VECTOR *pvec2) +{ + return CposFindPath((CG *)((char *)ppathzone + 0x34), pvec0, pvec1, n, pvec2); +} -INCLUDE_ASM("asm/nonmatchings/P2/path", FindPathzoneClosestPoint__FP8PATHZONEP6VECTORT1); -INCLUDE_ASM("asm/nonmatchings/P2/path", FUN_00191aa8); +void FindPathzoneClosestPoint(PATHZONE *ppathzone, VECTOR *pvec0, VECTOR *pvec1) +{ + FindClosestPointInCg((CG *)((char *)ppathzone + 0x34), pvec0, pvec1); +} + +int ClsgClipEdgeToCbsp(CBSP *pcbsp, VECTOR *pvec0, VECTOR *pvec1, int i, LSG *plsg); + +int FUN_00191aa8(void *p, VECTOR *pvec0, VECTOR *pvec1, int i, LSG *plsg) +{ + return ClsgClipEdgeToCbsp(STRUCT_OFFSET(p, 0x54, CBSP *), pvec0, pvec1, i, plsg); +} INCLUDE_ASM("asm/nonmatchings/P2/path", FUN_00191ac8); diff --git a/src/P2/pipe.c b/src/P2/pipe.c index 8472accff..ae123646f 100644 --- a/src/P2/pipe.c +++ b/src/P2/pipe.c @@ -14,7 +14,19 @@ void ResetPipeList() ClearDl(&g_dlPipe); } -INCLUDE_ASM("asm/nonmatchings/P2/pipe", InitPipe__FP4PIPE); +extern VU_VECTOR g_normalX; +extern float D_0024B650; // FLT_MAX + +void InitPipe(PIPE *ppipe) +{ + InitLo(ppipe); + ppipe->normal = g_normalX; + ppipe->unk_0x58 = -1; + ppipe->unk_0x54 = 9; + ppipe->unk_0x50 = 8; + ppipe->unk_0x5c = D_0024B650; + ppipe->oid = OID_Nil; +} void OnPipeAdd(PIPE *ppipe) { diff --git a/src/P2/po.c b/src/P2/po.c index 41a6aa951..f453aa40b 100644 --- a/src/P2/po.c +++ b/src/P2/po.c @@ -1,6 +1,10 @@ #include +#include #include #include +#include +#include +#include extern int g_ippoCur; extern PO *g_appo[]; @@ -26,10 +30,78 @@ void ClonePo(PO *ppo, PO *ppoBase) } INCLUDE_ASM("asm/nonmatchings/P2/po", HandlePoMessage__FP2PO5MSGIDPv); +#ifdef SKIP_ASM +void HandlePoMessage(PO *ppo, MSGID msgid, void *pv) +{ + HandleAloMessage((ALO *)ppo, msgid, pv); + + switch (msgid) + { + case MSGID_water_left: + StopSound(STRUCT_OFFSET(ppo, 0x574, AMB *), 0); + break; + case MSGID_rip_removed: + { + int i; + int c = STRUCT_OFFSET(ppo, 0x5D0, int); + void **a = &STRUCT_OFFSET(ppo, 0x5AC, void *); + + if (c > 0) + { + for (i = 0; i < c; i++) + { + if (a[i] == pv) + { + a[i] = 0; + break; + } + } + } + } + break; + } +} +#endif // SKIP_ASM + +void OnPoActive(PO *ppo, int fActive, PO *ppoOther) +{ + if (fActive) + { + STRUCT_OFFSET(ppo, 0x560, VU_VECTOR) = STRUCT_OFFSET(ppo, 0x140, VU_VECTOR); + SetCmPolicy(g_pcm, CPP_Default, &STRUCT_OFFSET(g_pcm, 0x520, CPLCY), (SO *)ppo, 0); + } + else + { + int i; + + for (i = 1; i < 7; i++) + { + RevokeCmPolicy(g_pcm, 5, (CPP)i, 0, (SO *)ppo, 0); + } + } +} + +extern SMP D_00269BC0; -INCLUDE_ASM("asm/nonmatchings/P2/po", OnPoActive__FP2POiT0); +void GetPoCpdefi(PO *ppo, float dt, CPDEFI *pcpdefi) +{ + GetSoCpdefi((SO *)ppo, dt, pcpdefi); -INCLUDE_ASM("asm/nonmatchings/P2/po", GetPoCpdefi__FP2POfP6CPDEFI); + if (STRUCT_OFFSET(ppo, 0x554, int) != 0) + { + STRUCT_OFFSET(pcpdefi, 0x10, VU_VECTOR) = STRUCT_OFFSET(ppo, 0x560, VU_VECTOR); + } + else + { + if (g_pcm->field41_0x224 == 0) + { + pcpdefi->posBase.z = GSmooth(STRUCT_OFFSET(ppo, 0x568, float), + STRUCT_OFFSET(ppo, 0x148, float), + dt, &D_00269BC0, NULL); + } + STRUCT_OFFSET(ppo, 0x560, VU_VECTOR) = STRUCT_OFFSET(pcpdefi, 0x10, VU_VECTOR); + } +} int FIsPoSoundBase(PO *ppo) { @@ -56,9 +128,50 @@ JTHS JthsCurrentPo(PO *ppo) return JTHS_Normal; } -INCLUDE_ASM("asm/nonmatchings/P2/po", FUN_00192498); +void FUN_00192498(PO *ppo, int *pi) +{ + void *pvt = STRUCT_OFFSET(ppo, 0x0, void *); + int (*pfn)(PO *) = (int (*)(PO *))STRUCT_OFFSET(pvt, 0x144, void *); + *pi = pfn(ppo); +} -INCLUDE_ASM("asm/nonmatchings/P2/po", CollectPoPrize__FP2PO3PCKP3ALO); +void CollectPoPrize(PO *ppo, PCK pck, ALO *palo) +{ + switch (pck) + { + case PCK_Key: + if (STRUCT_OFFSET(ppo, 0x5F0, ASEG *) != 0) + { + RIP *prip = PripNewRipg(RIPT_Match, NULL); + STRUCT_OFFSET(ppo, 0x5AC, RIP *) = prip; + STRUCT_OFFSET(ppo, 0x5D0, int) = 1; + if (prip != NULL) + { + void (*pfnInit)(RIP *, float, VECTOR *, int) = + (void (*)(RIP *, float, VECTOR *, int))STRUCT_OFFSET(STRUCT_OFFSET(prip, 0x0, void *), 0x0, void *); + pfnInit(prip, 1.0f, (VECTOR *)((uint8_t *)palo + 0x140), 0); + SubscribeRipObject(prip, (LO *)ppo); + STRUCT_OFFSET(prip, 0x1C, float) = TFindAsegLabel(STRUCT_OFFSET(ppo, 0x5F0, ASEG *), (OID)0x13F); + STRUCT_OFFSET(prip, 0x20, int) = STRUCT_OFFSET(ppo, 0x59C, int); + STRUCT_OFFSET(prip, 0xC0, qword) = STRUCT_OFFSET(STRUCT_OFFSET(palo, 0x14, uint8_t *), 0x1EE0, qword); + STRUCT_OFFSET(prip, 0x134, ALO *) = palo; + } + { + void (*pfnPrize)(PO *, int) = + (void (*)(PO *, int))STRUCT_OFFSET(STRUCT_OFFSET(ppo, 0x0, void *), 0x14C, void *); + pfnPrize(ppo, 1); + } + } + break; + case PCK_Gold: + { + void (*pfnPrize)(PO *, int) = + (void (*)(PO *, int))STRUCT_OFFSET(STRUCT_OFFSET(ppo, 0x0, void *), 0x14C, void *); + pfnPrize(ppo, 2); + } + break; + } +} INCLUDE_ASM("asm/nonmatchings/P2/po", FUN_001925C0); @@ -72,13 +185,74 @@ PO *PpoCur() return g_appo[g_ippoCur]; } -INCLUDE_ASM("asm/nonmatchings/P2/po", PpoStart__Fv); +extern int D_00269C90; + +PO *PpoStart(void) +{ + PO *ppo = PpoCur(); + + if (ppo == NULL) + { + if (g_pjt != NULL && STRUCT_OFFSET(g_pjt, 0x550, int) != 0) + ppo = (PO *)g_pjt; + + if (ppo == NULL && D_00269C90 != 0) + ppo = g_appo[0]; + } + + return ppo; +} INCLUDE_ASM("asm/nonmatchings/P2/po", _IppoFindPo__FP2PO); -INCLUDE_ASM("asm/nonmatchings/P2/po", AddPoToList__FP2PO); +extern int D_00269C90; + +void AddPoToList(PO *ppo) +{ + if (STRUCT_OFFSET(ppo, 0x550, int) == 0) + return; + + if (STRUCT_OFFSET(ppo, 0x18, ALO *) != 0) + return; + + if (!FIsLoInWorld(ppo)) + return; + + if (_IppoFindPo(ppo) >= 0) + return; + + if ((unsigned)D_00269C90 < 0x10) + { + int c = D_00269C90; + D_00269C90 = c + 1; + g_appo[c] = ppo; + } + else if (STRUCT_OFFSET(ppo, 0x8, int) == 5) + { + if (g_pjt == 0) + { + g_appo[0] = ppo; + } + } +} -INCLUDE_ASM("asm/nonmatchings/P2/po", RemovePoFromList__FP2PO); +void RemovePoFromList(PO *ppo) +{ + int i = _IppoFindPo(ppo); + + if (i < 0) + return; + + if (i == g_ippoCur) + SwitchToIppo(-1); + + memmove(&g_appo[i], &g_appo[i + 1], (D_00269C90 - i) * sizeof(PO *) - sizeof(PO *)); + + if (i < g_ippoCur) + g_ippoCur = g_ippoCur - 1; + + D_00269C90 = D_00269C90 - 1; +} void OnPoAdd(PO *ppo) { diff --git a/src/P2/prompt.c b/src/P2/prompt.c index 45b6148d4..8234810e7 100644 --- a/src/P2/prompt.c +++ b/src/P2/prompt.c @@ -2,6 +2,9 @@ #include #include #include +#include +#include +#include // TODO: Change to static when possible. extern char *s_mprespkachz[13]; @@ -49,7 +52,48 @@ INCLUDE_ASM("asm/nonmatchings/P2/prompt", FUN_00193fb8); INCLUDE_ASM("asm/nonmatchings/P2/prompt", OnPromptActive__FP6PROMPTi); -INCLUDE_ASM("asm/nonmatchings/P2/prompt", FUN_00194278); +void FUN_00194278(PROMPT *pprompt, int fButton, WIPEK wipek) +{ + SetPrompt(pprompt, (PRP)0, (PRK)-1); + + int idLevel = (STRUCT_OFFSET(g_pgsCur, 0x19d8, int) << 8) | STRUCT_OFFSET(g_pgsCur, 0x19dc, int); + + if (idLevel == 0x106) + { + if (fButton) + { + TRANS trans; + trans.fSet = 1; + trans.pchzWorld = (LevelTableStruct *)((char *)&g_transition + 0x14); + trans.oidWarp = (OID)-1; + trans.oidWarpContet = (OID)-1; + trans.grftrans = 0; + ActivateWipe(&g_wipe, &trans, wipek); + } + else + { + LO *plo = PloFindSwObjectByClass(g_psw, 5, (CID)0x5F, NULL); + SetRobRobs((ROB *)plo, (ROBS)6); + } + } + else + { + if (fButton) + { + TRANS trans; + trans.fSet = 1; + trans.pchzWorld = (LevelTableStruct *)((char *)&g_transition + 0x14); + trans.oidWarp = (OID)-1; + trans.oidWarpContet = (OID)-1; + trans.grftrans = 0x10; + ActivateWipe(&g_wipe, &trans, wipek); + } + else + { + TriggerDefaultExit(0, wipek); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/prompt", FUN_00194398__Fv); diff --git a/src/P2/puffer.c b/src/P2/puffer.c index 88074559e..69f5b9dce 100644 --- a/src/P2/puffer.c +++ b/src/P2/puffer.c @@ -1,14 +1,34 @@ #include +#include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/puffer", InitPuffer__FP6PUFFER); -INCLUDE_ASM("asm/nonmatchings/P2/puffer", LoadPufferFromBrx__FP6PUFFERP18CBinaryInputStream); +extern SNIP D_0026A728; + +void LoadPufferFromBrx(PUFFER *ppuffer, CBinaryInputStream *pbis) +{ + LoadSoFromBrx(ppuffer, pbis); + SnipAloObjects(ppuffer, 1, &D_0026A728); +} INCLUDE_ASM("asm/nonmatchings/P2/puffer", PostPufferLoad__FP6PUFFER); INCLUDE_ASM("asm/nonmatchings/P2/puffer", PresetPufferAccel__FP6PUFFERf); -INCLUDE_ASM("asm/nonmatchings/P2/puffer", FFilterPuffer__FP6PUFFERP2SO); +int FFilterPuffer(PUFFER *ppuffer, SO *pso) +{ + if ((STRUCT_OFFSET(pso, 0x538, unsigned long long) & ((unsigned long long)0x8000 << 28)) != 0) + { + if (!FIsBasicDerivedFrom(pso, (CID)0x1F)) + return 0; + } + + return STRUCT_OFFSET(pso, 0x50, SO *) != ppuffer; +} INCLUDE_ASM("asm/nonmatchings/P2/puffer", UpdatePuffer__FP6PUFFERf); @@ -16,9 +36,33 @@ INCLUDE_ASM("asm/nonmatchings/P2/puffer", PpufftChoosePuffer__FP6PUFFER); INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_001973d8); -INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_00197458); +extern void *D_0026A904; + +void FUN_00197458(void *p, int n) +{ + OID oidGoal; + OID oidCur; + + if (n == 1) + { + if (STRUCT_OFFSET(D_0026A904, 0x6B8, SMA *) != NULL) + { + GetSmaGoal(STRUCT_OFFSET(D_0026A904, 0x6B8, SMA *), &oidGoal); + GetSmaCur(STRUCT_OFFSET(D_0026A904, 0x6B8, SMA *), &oidCur); + + if (oidGoal != (OID)0x3F4 && oidCur != (OID)0x3F4) + { + SetSmaGoal(STRUCT_OFFSET(D_0026A904, 0x6B8, SMA *), (OID)0x3F5); + FUN_001973d8(D_0026A904); + } + } + } +} -INCLUDE_ASM("asm/nonmatchings/P2/puffer", OnPufferActive__FP6PUFFERiP2PO); +void OnPufferActive(PUFFER *ppuffer, int fActive, PO *ppoOther) +{ + OnPoActive(ppuffer, fActive, ppoOther); +} INCLUDE_ASM("asm/nonmatchings/P2/puffer", UpdatePufferActive__FP6PUFFERP3JOYf); @@ -26,15 +70,34 @@ INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_00197788); INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_00197848); -INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_00197a08); +void FUN_00197a08(void *pv1, void *pv2) +{ + ROST *prost = STRUCT_OFFSET(pv2, 0xC14, ROST *); + SetRostRosts(prost, ROSTS_Close); + RemoveDlEntry((DL *)((char *)pv1 + 0x6A8), prost); + AppendDlEntry((DL *)((char *)pv1 + 0x69C), prost); + STRUCT_OFFSET(pv2, 0xC14, ROST *) = 0; +} + +extern float D_0026A83C; +extern float D_0026A840; -INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_00197a68); +void FUN_00197a68(void *pv, void *p) +{ + float dx = D_0026A83C; + float dy = D_0026A840; + STRUCT_OFFSET(p, 0x98, float) = dx; + STRUCT_OFFSET(p, 0x94, float) = dy; +} INCLUDE_ASM("asm/nonmatchings/P2/puffer", AddPufferWaterAcceleration__FP6PUFFERP5WATERf); INCLUDE_ASM("asm/nonmatchings/P2/puffer", HandlePufferMessage__FP6PUFFER5MSGIDPv); -INCLUDE_ASM("asm/nonmatchings/P2/puffer", PostPuffcLoad__FP5PUFFC); +void PostPuffcLoad(PUFFC *ppuffc) +{ + PostStepguardLoad((STEPGUARD *)ppuffc); +} INCLUDE_ASM("asm/nonmatchings/P2/puffer", PresetPuffcAccel__FP5PUFFCf); @@ -42,9 +105,29 @@ INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_001982a0); INCLUDE_ASM("asm/nonmatchings/P2/puffer", UpdatePuffcGoal__FP5PUFFCi); -INCLUDE_ASM("asm/nonmatchings/P2/puffer", OnPuffcExitingSgs__FP5PUFFC3SGS); +void OnPuffcExitingSgs(PUFFC *ppuffc, SGS sgsNext) +{ + if (STRUCT_OFFSET(ppuffc, 0x724, int) == SGS_Stun) + { + + FUN_00197a08(PpoCur(), ppuffc); + + VU_VECTOR vec = STRUCT_OFFSET(ppuffc, 0x150, VU_VECTOR); + STRUCT_OFFSET((&vec), 0x8, int) = 0; + (*(void (**)(PUFFC *, VU_VECTOR *))((uint8_t *)STRUCT_OFFSET(ppuffc, 0x0, void *) + 0x90))(ppuffc, &vec); + } -INCLUDE_ASM("asm/nonmatchings/P2/puffer", OnPuffcEnteringSgs__FP5PUFFC3SGSP4ASEG); + OnStepguardExitingSgs((STEPGUARD *)ppuffc, sgsNext); +} + +void OnPuffcEnteringSgs(PUFFC *ppuffc, SGS sgsPrev, ASEG *pasegOverride) +{ + OnStepguardEnteringSgs((STEPGUARD *)ppuffc, sgsPrev, pasegOverride); + if (STRUCT_OFFSET(ppuffc, 0x724, int) == SGS_Stun) + { + FUN_001c8920(ppuffc); + } +} INCLUDE_ASM("asm/nonmatchings/P2/puffer", UpdatePuffcSgs__FP5PUFFC); @@ -59,4 +142,15 @@ int FCanPuffcAttack(PUFFC *ppuffc) INCLUDE_ASM("asm/nonmatchings/P2/puffer", FUN_00198860); -INCLUDE_ASM("asm/nonmatchings/P2/puffer", PostPuffbLoad__FP5PUFFB); +extern SNIP D_0026A8E0; + +void PostPuffbLoad(PUFFB *ppuffb) +{ + SnipAloObjects(ppuffb, 3, &D_0026A8E0); + PostAloLoad(ppuffb); + LO *plo = PloFindSwObjectByClass(ppuffb->psw, FSO_FindAll, CID_TURRET, NULL); + if (plo != NULL) + { + STRUCT_OFFSET(plo, 0x684, int)++; + } +} diff --git a/src/P2/pzo.c b/src/P2/pzo.c index 8f869656b..ca8a0e68c 100644 --- a/src/P2/pzo.c +++ b/src/P2/pzo.c @@ -1,8 +1,20 @@ #include +#include #include #include - -INCLUDE_ASM("asm/nonmatchings/P2/pzo", InitSprize__FP6SPRIZE); +#include +#include +#include +#include +#include +#include +#include + +void InitSprize(SPRIZE *psprize) +{ + InitSo(psprize); + STRUCT_OFFSET(psprize, 0x554, int) = 1; +} INCLUDE_ASM("asm/nonmatchings/P2/pzo", LoadSprizeFromBrx__FP6SPRIZEP18CBinaryInputStream); @@ -18,7 +30,13 @@ INCLUDE_ASM("asm/nonmatchings/P2/pzo", EmitSprizeExplosion__FP6SPRIZE); INCLUDE_ASM("asm/nonmatchings/P2/pzo", PcsFromSprize__FP6SPRIZE); -INCLUDE_ASM("asm/nonmatchings/P2/pzo", AddSprizeAseg__FP6SPRIZE3OID); +void AddSprizeAseg(SPRIZE * p, OID oidAseg) +{ + int c = STRUCT_OFFSET(p, 0x55c, int); + OID *a = &STRUCT_OFFSET(p, 0x560, OID); + a[c] = oidAseg; + STRUCT_OFFSET(p, 0x55c, int) = c + 1; +} INCLUDE_ASM("asm/nonmatchings/P2/pzo", HandleSprizeMessage__FP6SPRIZE5MSGIDPv); @@ -26,52 +44,60 @@ INCLUDE_ASM("asm/nonmatchings/P2/pzo", FIgnoreSprizeIntersection__FP6SPRIZEP2SO) INCLUDE_ASM("asm/nonmatchings/P2/pzo", FUN_00199000); -INCLUDE_ASM("asm/nonmatchings/P2/pzo", InitScprize__FP7SCPRIZE); +void InitScprize(SCPRIZE *pscprize) +{ + InitSprize(pscprize); + STRUCT_OFFSET(pscprize, 0x5a0, int) = IchkAllocChkmgr(&g_chkmgr); +} + +void CloneScprize(SCPRIZE *pscprize, SCPRIZE *pscprizeBase) +{ + int ichk = STRUCT_OFFSET(pscprize, 0x5a0, int); + CloneSo(pscprize, pscprizeBase); + STRUCT_OFFSET(pscprize, 0x5a0, int) = ichk; +} -INCLUDE_ASM("asm/nonmatchings/P2/pzo", CloneScprize__FP7SCPRIZET0); +PCS PcsFromScprize(SCPRIZE *pscprize) +{ + PCS pcs = PcsFromSprize((SPRIZE *)pscprize); + + if (pcs == PCS_Collectible) { + int ichk = STRUCT_OFFSET(pscprize, 0x5a0, int); + if (FGetChkmgrIchk(&g_chkmgr, ichk) != 0) { + pcs = PCS_Collected; + } + } + + return pcs; +} -INCLUDE_ASM("asm/nonmatchings/P2/pzo", PcsFromScprize__FP7SCPRIZE); +void CollectScprize(SCPRIZE *pscprize) +{ + SetChkmgrIchk(&g_chkmgr, STRUCT_OFFSET(pscprize, 0x5a0, int)); + CollectSprize(pscprize); +} -INCLUDE_ASM("asm/nonmatchings/P2/pzo", CollectScprize__FP7SCPRIZE); +extern SNIP s_asnip; -INCLUDE_ASM("asm/nonmatchings/P2/pzo", LoadLockFromBrx__FP4LOCKP18CBinaryInputStream); -#ifdef SKIP_ASM -/** - * @todo 95.80% matched. s_asnip may not be defined correctly. - */ void LoadLockFromBrx(LOCK *plock, CBinaryInputStream *pbis) { - static SNIP *s_asnip; LoadAloFromBrx(plock, pbis); - SnipAloObjects(plock, 1, s_asnip); + SnipAloObjects(plock, 1, &s_asnip); } -#endif +extern SNIP D_0026A928; -INCLUDE_ASM("asm/nonmatchings/P2/pzo", PostLockLoad__FP4LOCK); -#ifdef SKIP_ASM -/** - * @todo 95.00% matched. s_asnip may not be defined correctly. - */ void PostLockLoad(LOCK *plock) { - static SNIP *s_asnip; PostAloLoad(plock); - SnipAloObjects(plock, 1, s_asnip); + SnipAloObjects(plock, 1, &D_0026A928); } -#endif +extern SNIP D_0026A938; -INCLUDE_ASM("asm/nonmatchings/P2/pzo", LoadLockgFromBrx__FP5LOCKGP18CBinaryInputStream); -#ifdef SKIP_ASM -/** - * @todo 95.00% matched. s_asnip may not be defined correctly. - */ void LoadLockgFromBrx(LOCKG *plockg, CBinaryInputStream *pbis) { LoadAloFromBrx(plockg, pbis); - // SnipAloObjects(plockg, 1, PostLockgLoad); + SnipAloObjects(plockg, 1, &D_0026A938); } -#endif - INCLUDE_ASM("asm/nonmatchings/P2/pzo", PostLockgLoad__FP5LOCKG); #ifdef SKIP_ASM /** @@ -146,13 +172,51 @@ void AddLockgLock(LOCKG *plockg, OID oidLock) plockg->coidLock = ++ccur; } -INCLUDE_ASM("asm/nonmatchings/P2/pzo", TriggerLockg__FP5LOCKG); +void TriggerLockg(LOCKG *plockg) +{ + if (g_pjt) + func_001781E0(g_pjt, plockg); +} -INCLUDE_ASM("asm/nonmatchings/P2/pzo", InitClue__FP4CLUE); +void InitClue(CLUE *pclue) +{ + InitSprize(pclue); + SW *psw = pclue->psw; + int n = STRUCT_OFFSET(psw, 0x2300, int); + STRUCT_OFFSET(pclue, 0x5a0, int) = n; + STRUCT_OFFSET(psw, 0x2300, int) = n + 1; +} + +extern SNIP D_0026A948; -INCLUDE_ASM("asm/nonmatchings/P2/pzo", LoadClueFromBrx__FP4CLUEP18CBinaryInputStream); +void LoadClueFromBrx(CLUE *pclue, CBinaryInputStream *pbis) +{ + LoadSprizeFromBrx(pclue, pbis); + SnipAloObjects(pclue, 1, &D_0026A948); + STRUCT_OFFSET(pclue, 0x5b0, void *) = PvAllocSwImpl(0x80); + + int oid = 0x318; + while (oid < 0x338) + { + LO *plo = PloFindSwObject(STRUCT_OFFSET(pclue, 0x14, SW *), 1, (OID)oid, (LO *)pclue); + if (plo == NULL) + break; + + int c = STRUCT_OFFSET(pclue, 0x5ac, int); + LO **aplo = STRUCT_OFFSET(pclue, 0x5b0, LO **); + oid++; + aplo[c] = plo; + STRUCT_OFFSET(pclue, 0x5ac, int) = c + 1; + SnipLo(plo); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/pzo", CloneClue__FP4CLUET0); +void CloneClue(CLUE *pclue, CLUE *pclueBase) +{ + int n = STRUCT_OFFSET(pclue, 0x5a0, int); + CloneSo(pclue, pclueBase); + STRUCT_OFFSET(pclue, 0x5a0, int) = n; +} INCLUDE_ASM("asm/nonmatchings/P2/pzo", PostClueLoad__FP4CLUE); @@ -160,17 +224,64 @@ INCLUDE_ASM("asm/nonmatchings/P2/pzo", UpdateClue); INCLUDE_ASM("asm/nonmatchings/P2/pzo", OnClueSmack__FP4CLUE); -INCLUDE_ASM("asm/nonmatchings/P2/pzo", CollectClue__FP4CLUE); +extern char D_0026A970; + +void CollectClue(CLUE *pclue) +{ + RIP *pripg; + VECTOR vec; + + (*(void (**)(CLUECTR *))(*(int *)&g_cluectr + 0x38))(&g_cluectr); + pripg = PripNewRipg(RIPT_Smack, NULL); + if (pripg) + { + if (STRUCT_OFFSET(g_plsCur, 0x64, int) + 1 >= STRUCT_OFFSET(g_psw, 0x2300, int)) + { + StartSound((SFXID)0x21, NULL, NULL, NULL, 3000.0f, 300.0f, 1.0f, 0.0f, 0.0f, NULL, NULL); + } + STRUCT_OFFSET(pripg, 0x134, CLUE *) = pclue; + STRUCT_OFFSET(pripg, 0x130, void *) = &D_0026A970; + ConvertAloPos(pclue, NULL, (VECTOR *)(STRUCT_OFFSET(pclue, 0x5bc, uint8_t *) + 0x100), &vec); + ((void (*)(RIP *, float, VECTOR *, int))STRUCT_OFFSET(STRUCT_OFFSET(pripg, 0x0, void *), 0x0, void *))(pripg, 1.0f, &vec, 0); + STRUCT_OFFSET(pripg, 0x20, int) = STRUCT_OFFSET(pclue, 0x5bc, int); + } + else + { + OnClueSmack(pclue); + } + CollectSprize(pclue); +} -INCLUDE_ASM("asm/nonmatchings/P2/pzo", BreakClue__FP4CLUE); +void BreakClue(CLUE *pclue) +{ + // @todo clean up this vtable call + ((void (*)(CLUE *))STRUCT_OFFSET(pclue->pvtlo, 0x134, void *))(pclue); +} INCLUDE_ASM("asm/nonmatchings/P2/pzo", CollectClueSilent__FP4CLUE); INCLUDE_ASM("asm/nonmatchings/P2/pzo", FUN_00199c10); -INCLUDE_ASM("asm/nonmatchings/P2/pzo", ImpactClue__FP4CLUEi); +void ImpactClue(CLUE *pclue, int fParentDirty) +{ + ImpactSo(pclue, fParentDirty); +} -INCLUDE_ASM("asm/nonmatchings/P2/pzo", FAbsorbClueWkr__FP4CLUEP3WKR); +int FAbsorbClueWkr(CLUE *pclue, WKR *pwkr) +{ + // @todo clean up these vtable calls + if (pwkr->grfic & 0x8) + { + ((void (*)(CLUE *, int))STRUCT_OFFSET(pclue->pvtlo, 0x64, void *))(pclue, 0); + SetSoConstraints(pclue, CT_Free, 0, CT_Locked, 0); + } + FAbsorbSoWkr(pclue, pwkr); + if (pwkr->grfic & 0x10) + { + ((void (*)(CLUE *))STRUCT_OFFSET(pclue->pvtlo, 0x134, void *))(pclue); + } + return 1; +} INCLUDE_ASM("asm/nonmatchings/P2/pzo", RenderClueAll__FP4CLUEP2CMP2RO); @@ -189,7 +300,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/pzo", FUN_0019a0f0); INCLUDE_ASM("asm/nonmatchings/P2/pzo", InitVault__FP5VAULT); -INCLUDE_ASM("asm/nonmatchings/P2/pzo", PostTmblLoad__FP4TMBL3OID); +void PostTmblLoad(TMBL *ptmbl, OID oidInitialState) +{ + LO *plo = PloFindSwObject(g_psw, 0x101, (OID)0x37A, ptmbl->palo); + ptmbl->psmDial = (SM *)plo; + SnipLo(plo); + + ptmbl->psmaDial = PsmaApplySm((SM *)ptmbl->psmDial, ptmbl->palo, oidInitialState, 0); +} INCLUDE_ASM("asm/nonmatchings/P2/pzo", PostVaultLoad__FP5VAULT); diff --git a/src/P2/rat.c b/src/P2/rat.c index 50f0430d6..3018ac41b 100644 --- a/src/P2/rat.c +++ b/src/P2/rat.c @@ -13,7 +13,16 @@ void InitRat(RAT *prat) INCLUDE_ASM("asm/nonmatchings/P2/rat", LoadRatFromBrx__FP3RATP18CBinaryInputStream); -INCLUDE_ASM("asm/nonmatchings/P2/rat", PostRatLoad__FP3RAT); +extern SNIP D_0026ABA0; + +void PostRatLoad(RAT *prat) +{ + SnipAloObjects(prat, 1, &D_0026ABA0); + PostAloLoad(prat); + STRUCT_OFFSET(prat, 0x550, int) = -1; + SetRatRats(prat, RATS_Scurry); + STRUCT_OFFSET(prat, 0x650, qword) = STRUCT_OFFSET(prat, 0x140, qword); +} void OnRatAdd(RAT *prat) { diff --git a/src/P2/rchm.c b/src/P2/rchm.c index 96505c62a..b7500afc4 100644 --- a/src/P2/rchm.c +++ b/src/P2/rchm.c @@ -1,4 +1,5 @@ #include +#include void InitRchm(RCHM *prchm) { @@ -40,6 +41,44 @@ INCLUDE_ASM("asm/nonmatchings/P2/rchm", PtwrMapRchmSafe__FP4RCHMP3BSPP6VECTOR); INCLUDE_ASM("asm/nonmatchings/P2/rchm", FindRchmClosestPoint__FP4RCHMP6VECTORT1PP3TWRPf); -INCLUDE_ASM("asm/nonmatchings/P2/rchm", TrackJtTarget__FP2JTP4RCHMP6TARGET); +void TrackJtTarget(JT *pjt, RCHM *prchm, TARGET *ptarget) +{ + VECTOR posLocal; + VECTOR posClosest; + TWR *ptwr; + float s; + + if (ptarget == NULL) + return; + + float dt = STRUCT_OFFSET(pjt, 0x2424, float) - g_clock.t; + if (dt < g_clock.dt) + dt = g_clock.dt; + + PredictRchmTargetLocalPos(prchm, ptarget, dt, &posLocal); + FindRchmClosestPoint(prchm, &posLocal, &posClosest, &ptwr, &s); + ReblendRchm(prchm, ptwr, &posClosest); +} -INCLUDE_ASM("asm/nonmatchings/P2/rchm", TrackJtPipe__FP2JTP4RCHMP4PIPEPf); +void TrackJtPipe(JT *pjt, RCHM *prchm, PIPE *ppipe, float *psPipe) +{ + VECTOR posPipeLocal; + VECTOR posOnPipe; + VECTOR posWorld; + VECTOR posLocal; + TWR *ptwr; + float s; + + ConvertAloPos(NULL, ppipe->paloParent, (VECTOR *)((uint8_t *)pjt + 0x140), &posPipeLocal); + + if (STRUCT_OFFSET(STRUCT_OFFSET(ppipe, 0x34, void *), 0x0, void **)[0xc] != NULL) + { + (*(void (**)(void *, float, VECTOR *, int, VECTOR *, int, int, float *)) + (STRUCT_OFFSET(STRUCT_OFFSET(ppipe, 0x34, void **), 0x0, void **) + 0xc))( + STRUCT_OFFSET(ppipe, 0x34, void *), *psPipe, &posPipeLocal, 0, &posOnPipe, 0, 0, psPipe); + } + + ConvertAloPos(ppipe->paloParent, (ALO *)pjt, &posOnPipe, &posWorld); + FindRchmClosestPoint(prchm, &posWorld, &posLocal, &ptwr, &s); + ReblendRchm(prchm, ptwr, &posLocal); +} diff --git a/src/P2/render.c b/src/P2/render.c index 3b6e84a39..f61339c74 100644 --- a/src/P2/render.c +++ b/src/P2/render.c @@ -84,6 +84,7 @@ void EnsureScreenCleared() g_vifs.AddDmaCnt(); g_vifs.AddVifDirect(0x2c, g_aqwGifsClearAll, 0); g_vifs.EndDmaCnt(); + s_fZBCleared = 1; s_fFBCleared = 1; } else if (!s_fZBCleared) diff --git a/src/P2/rip.c b/src/P2/rip.c index 50a43b414..c6c883e75 100644 --- a/src/P2/rip.c +++ b/src/P2/rip.c @@ -1,6 +1,31 @@ #include +#include +#include +#include +#include +#include +#include + +RIPG *PripgNew(SW *psw, RIPGT ripgt) +{ + if (ripgt == RIPGT_Default && STRUCT_OFFSET(psw, 0x1B3C, RIPG *) != NULL) + { + return STRUCT_OFFSET(psw, 0x1B3C, RIPG *); + } -INCLUDE_ASM("asm/nonmatchings/P2/rip", PripgNew__FP2SW5RIPGT); + RIPG *pripg = STRUCT_OFFSET(psw, 0x1B38, RIPG *); + if (pripg != NULL) + { + STRUCT_OFFSET(psw, 0x1B38, RIPG *) = STRUCT_OFFSET(pripg, 0x564, RIPG *); + STRUCT_OFFSET(pripg, 0x550, RIPGT) = ripgt; + (*(void (**)(RIPG *))((uint8_t *)STRUCT_OFFSET(pripg, 0x0, void *) + 0x18))(pripg); + if (ripgt == RIPGT_Default) + { + STRUCT_OFFSET(psw, 0x1B3C, RIPG *) = pripg; + } + } + return pripg; +} INCLUDE_ASM("asm/nonmatchings/P2/rip", InitRipg__FP4RIPG); @@ -52,33 +77,143 @@ void TouchRip(RIP *prip, int fTouching) } } -INCLUDE_ASM("asm/nonmatchings/P2/rip", ForceRipFade__FP3RIPf); +void ForceRipFade(RIP *prip, float dtFade) +{ + float dtRemain = STRUCT_OFFSET(prip, 0x1c, float) - (g_clock.t - STRUCT_OFFSET(prip, 0x18, float)); + if (dtFade < dtRemain) + { + float ratio = dtRemain / STRUCT_OFFSET(prip, 0x1c, float); + float v = dtFade / ratio; + STRUCT_OFFSET(prip, 0x1c, float) = v; + STRUCT_OFFSET(prip, 0x18, float) = g_clock.t - (1.0f - ratio) * v; + } +} INCLUDE_ASM("asm/nonmatchings/P2/rip", FBounceRip__FP3RIPP2SOP6VECTORT2); INCLUDE_ASM("asm/nonmatchings/P2/rip", ProjectRipTransform__FP3RIPf); -INCLUDE_ASM("asm/nonmatchings/P2/rip", UpdateRip__FP3RIPf); +void UpdateRip(RIP *prip, float dt) +{ + if (STRUCT_OFFSET(prip, 0x1c, float) < g_clock.t - STRUCT_OFFSET(prip, 0x18, float)) + { + RemoveRip(prip); + return; + } + + RIPG *pripg = prip->pripg; + if (STRUCT_OFFSET(pripg, 0x550, int) == 1) + return; + + if (STRUCT_OFFSET(prip, 0x24, ALO *) == NULL) + return; + if (STRUCT_OFFSET(STRUCT_OFFSET(prip, 0x24, ALO *), 0x3f8, BSP *) == NULL) + return; + + int fInBsp = 0; + if (FIsLoInWorld((LO *)STRUCT_OFFSET(prip, 0x24, ALO *))) + { + if (PbspPointInBspQuick(&STRUCT_OFFSET(prip, 0x80, VECTOR), STRUCT_OFFSET(STRUCT_OFFSET(prip, 0x24, ALO *), 0x3f8, BSP *))) + fInBsp = 1; + } + + (*(void (**)(RIP *, int))((uint8_t *)STRUCT_OFFSET(prip, 0x0, void *) + 0x18))(prip, fInBsp); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", FRenderRipPosMat__FP3RIPP2CMP6VECTORP7MATRIX3); -INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderRip__FP3RIPP2CM); +void RenderRip(RIP *prip, CM *pcm) +{ + VECTOR pos; + MATRIX3 mat; + VECTOR *ppos; + MATRIX3 *pmat; + WR *pwr; + + pwr = STRUCT_OFFSET(prip, 0x114, WR *); + if (pwr != NULL) + { + WarpWrTransform(pwr, 50.0f, + &STRUCT_OFFSET(prip, 0x80, VECTOR), + &STRUCT_OFFSET(prip, 0x50, MATRIX3), + &pos, &mat, NULL); + ppos = &pos; + pmat = &mat; + } + else + { + ppos = &STRUCT_OFFSET(prip, 0x80, VECTOR); + pmat = &STRUCT_OFFSET(prip, 0x50, MATRIX3); + } -INCLUDE_ASM("asm/nonmatchings/P2/rip", SubscribeRipObject__FP3RIPP2LO); + if (!FRenderRipPosMat(prip, pcm, ppos, pmat)) + { + RemoveRip(prip); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/rip", SubscribeRipStruct__FP3RIPPFPv5MSGIDPv_vPv); +void SubscribeRipObject(RIP *prip, LO *ploTarget) +{ + SubscribeSwPpmqStruct(g_psw, &STRUCT_OFFSET(prip, 0x118, MQ *), ploTarget->pvtlo->pfnHandleLoMessage, ploTarget); +} -INCLUDE_ASM("asm/nonmatchings/P2/rip", UnsubscribeRipStruct__FP3RIPPFPv5MSGIDPv_vPv); +void SubscribeRipStruct(RIP *prip, PFNMQ pfnmq, void *pvContext) +{ + SubscribeSwPpmqStruct(g_psw, &STRUCT_OFFSET(prip, 0x118, MQ *), pfnmq, pvContext); +} + +void UnsubscribeRipStruct(RIP *prip, PFNMQ pfnmq, void *pvContext) +{ + UnsubscribeSwPpmqStruct(g_psw, &STRUCT_OFFSET(prip, 0x118, MQ *), pfnmq, pvContext); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", InitDroplet__FP7DROPLETP6VECTORfP2SO); -INCLUDE_ASM("asm/nonmatchings/P2/rip", TouchDroplet__FP7DROPLETi); +void TouchDroplet(DROPLET *pdroplet, int fTouching) +{ + LSG alsg[16]; + + if (fTouching) + { + *(VU_VECTOR *)alsg = STRUCT_OFFSET(pdroplet, 0x80, VU_VECTOR); + + BSP *pbsp = STRUCT_OFFSET(STRUCT_OFFSET(pdroplet, 0x24, ALO *), 0x3f8, BSP *); + if (pbsp) + { + ClsgClipEdgeToBsp( + pbsp, + (VECTOR *)((uint8_t *)pdroplet + 0x90), + (VECTOR *)((uint8_t *)pdroplet + 0x80), + NULL, 0x10, alsg); + } + + RIP *prip = PripNewRipg(RIPT_Ripple, NULL); + if (prip != NULL) + { + (*(void (**)(RIP *, VECTOR *, float, SO *))(STRUCT_OFFSET(prip, 0x0, void *)))( + prip, (VECTOR *)alsg, 40.0f, NULL); + STRUCT_OFFSET(prip, 0x1c, float) = 0.75f; + STRUCT_OFFSET(prip, 0x34, float) = 30.0f; + + void *p278 = STRUCT_OFFSET(STRUCT_OFFSET(pdroplet, 0x24, ALO *), 0x278, void *); + if (p278 != NULL) + { + STRUCT_OFFSET(prip, 0x114, int) = STRUCT_OFFSET(p278, 0xc, int); + } + } + + RemoveRip((RIP *)pdroplet); + } +} INCLUDE_ASM("asm/nonmatchings/P2/rip", InitBublet__FP6BUBLETP6VECTORfP2SO); INCLUDE_ASM("asm/nonmatchings/P2/rip", ProjectBubletTransform__FP6BUBLETf); -INCLUDE_ASM("asm/nonmatchings/P2/rip", TouchBublet__FP6BUBLETi); +void TouchBublet(BUBLET *pbublet, int fTouching) +{ + TouchDroplet((DROPLET *)pbublet, fTouching == 0); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", InitRipple__FP6RIPPLEP6VECTORfP2SO); @@ -92,7 +227,13 @@ INCLUDE_ASM("asm/nonmatchings/P2/rip", UpdateFlake__FP5FLAKEf); INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderFlake__FP5FLAKEP2CM); -INCLUDE_ASM("asm/nonmatchings/P2/rip", TouchFlake__FP5FLAKEi); +void TouchFlake(FLAKE *pflake, int fTouching) +{ + if (fTouching) + { + RemoveRip(pflake); + } +} INCLUDE_ASM("asm/nonmatchings/P2/rip", InitSpark__FP5SPARKP6VECTORfP2SO); @@ -102,7 +243,10 @@ INCLUDE_ASM("asm/nonmatchings/P2/rip", InitBurst__FP5BURSTP6VECTORfP2SO); INCLUDE_ASM("asm/nonmatchings/P2/rip", InitTrail__FP5TRAILP6VECTORfP2SO); -INCLUDE_ASM("asm/nonmatchings/P2/rip", OnTrailRemove__FP5TRAIL); +void OnTrailRemove(TRAIL *ptrail) +{ + SetTrailTrls(ptrail, (TRLS)0, 0); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", SetTrailTrls__FP5TRAIL4TRLSPv); @@ -130,7 +274,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/rip", ProjectSmackTransform__FP5SMACKf); INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderSmack__FP5SMACKP2CM); -INCLUDE_ASM("asm/nonmatchings/P2/rip", UpdateSmack__FP5SMACKf); +void UpdateSmack(SMACK *psmack, float dt) +{ + if (STRUCT_OFFSET(psmack, 0x1c, float) < g_clock.t - STRUCT_OFFSET(psmack, 0x18, float)) + { + RemoveRip(psmack); + (*(void (**)(int))((uint8_t *)STRUCT_OFFSET(psmack, 0x130, void *) + 0x60))(STRUCT_OFFSET(psmack, 0x134, int)); + } +} INCLUDE_ASM("asm/nonmatchings/P2/rip", InitOrbit__FP5ORBITP6VECTORfP2SO); @@ -157,13 +308,22 @@ INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderRose__FP4ROSEP2CM); INCLUDE_ASM("asm/nonmatchings/P2/rip", SetRoseRoses__FP4ROSE5ROSES); -INCLUDE_ASM("asm/nonmatchings/P2/rip", SgnCmpHp__FPCvT0); +int SgnCmpHp(const void *pv0, const void *pv1) +{ + if (STRUCT_OFFSET(pv0, 0x20, float) < STRUCT_OFFSET(pv1, 0x20, float)) + return -1; + return 1; +} INCLUDE_ASM("asm/nonmatchings/P2/rip", ChpBuildConvexHullScreen__FP6VECTORiP2HP); INCLUDE_ASM("asm/nonmatchings/P2/rip", ChpBuildConvexHullXY__FP7MATRIX4iP2HP); -INCLUDE_ASM("asm/nonmatchings/P2/rip", PostFlyingEmit__FP6FLYINGP5EMITB); +void PostFlyingEmit(FLYING *pflying, EMITB *pemitb) +{ + STRUCT_OFFSET(pflying, 0x120, int) = STRUCT_OFFSET(pemitb, 0x1DC, int); + STRUCT_OFFSET(pflying, 0x124, int) = STRUCT_OFFSET(pemitb, 0x1F0, int); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderFlying__FP6FLYINGP2CM); @@ -173,19 +333,57 @@ INCLUDE_ASM("asm/nonmatchings/P2/rip", FBounceFlying__FP6FLYINGP2SOP6VECTORT2); INCLUDE_ASM("asm/nonmatchings/P2/rip", UpdateStuck__FP5STUCKf); -INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderStuck__FP5STUCKP2CM); +void RenderStuck(STUCK *pstuck, CM *pcm) +{ + VECTOR pos; + MATRIX3 mat; + + ConvertAloPos(STRUCT_OFFSET(pstuck, 0x120, ALO *), NULL, &STRUCT_OFFSET(pstuck, 0x80, VECTOR), &pos); + ConvertAloMat(STRUCT_OFFSET(pstuck, 0x120, ALO *), NULL, &STRUCT_OFFSET(pstuck, 0x50, MATRIX3), &mat); + FRenderRipPosMat((RIP *)pstuck, pcm, &pos, &mat); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", PostLeafEmit__FP4LEAFP5EMITB); INCLUDE_ASM("asm/nonmatchings/P2/rip", ProjectLeafTransform__FP4LEAFf); -INCLUDE_ASM("asm/nonmatchings/P2/rip", FBounceLeaf__FP4LEAFP2SOP6VECTORT2); +int FBounceLeaf(LEAF *pleaf, SO *psoOther, VECTOR *ppos, VECTOR *pnormal) +{ + + if (FIsBasicDerivedFrom(STRUCT_OFFSET(psoOther, 0x50, BASIC *), CID_MISSILE)) + return 0; + if (FIsBasicDerivedFrom(STRUCT_OFFSET(psoOther, 0x50, BASIC *), CID_STEP)) + return 0; -INCLUDE_ASM("asm/nonmatchings/P2/rip", FFilterFlameObjects__FPvP2SO); + STUCK *pstuck; + CreateStuck((RIP *)pleaf, STRUCT_OFFSET(pleaf, 0x20, ALO *), psoOther, ppos, pnormal, &pstuck); + if (pstuck != NULL) + { + ConvertAloMat(NULL, psoOther, &STRUCT_OFFSET(pstuck, 0x50, MATRIX3), &STRUCT_OFFSET(pstuck, 0x50, MATRIX3)); + } + RemoveRip((RIP *)pleaf); + return 1; +} + +int FFilterFlameObjects(void *pv, SO *pso) +{ + if (STRUCT_OFFSET(pso, 0x538, unsigned long long) & ((unsigned long long)0x8000 << 28)) + { + return 0; + } + return pso != STRUCT_OFFSET(pv, 0x7C, SO *); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", PostFlameEmit__FP5FLAMEP5EMITB); -INCLUDE_ASM("asm/nonmatchings/P2/rip", PostBulletEmit__FP6BULLETP5EMITB); +void PostBulletEmit(BULLET *pbullet, EMITB *pemitb) +{ + ConvertAloPos(STRUCT_OFFSET(pemitb, 0x7c, ALO *), NULL, &STRUCT_OFFSET(pemitb, 0x20, VECTOR), &STRUCT_OFFSET(pbullet, 0x80, VECTOR)); + STRUCT_OFFSET(pbullet, 0xb0, int) = 0; + STRUCT_OFFSET(pbullet, 0x110, int) = 0; + STRUCT_OFFSET(pbullet, 0x120, int) = STRUCT_OFFSET(pemitb, 0x1f4, int); + STRUCT_OFFSET(pbullet, 0x124, int) = STRUCT_OFFSET(pemitb, 0x1f0, int); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderBullet__FP6BULLETP2CM); @@ -193,7 +391,12 @@ INCLUDE_ASM("asm/nonmatchings/P2/rip", FBounceBullet__FP6BULLETP2SOP6VECTORT2); INCLUDE_ASM("asm/nonmatchings/P2/rip", PostShrapnelEmit__FP8SHRAPNELP5EMITB); -INCLUDE_ASM("asm/nonmatchings/P2/rip", FBounceShrapnel__FP8SHRAPNELP2SOP6VECTORT2); +int FBounceShrapnel(SHRAPNEL *pshrapnel, SO *psoOther, VECTOR *ppos, VECTOR *pnormal) +{ + if (FIsBasicDerivedFrom(STRUCT_OFFSET(psoOther, 0x50, BASIC *), CID_STEP)) + return 0; + return FBounceRip((RIP *)pshrapnel, psoOther, ppos, pnormal); +} INCLUDE_ASM("asm/nonmatchings/P2/rip", RenderShrapnel__FP8SHRAPNELP2CM); diff --git a/src/P2/rog.c b/src/P2/rog.c index 467e9993c..acebafcc0 100644 --- a/src/P2/rog.c +++ b/src/P2/rog.c @@ -1,5 +1,12 @@ #include #include +#include +#include +#include +#include +#include +#include +#include extern SNIP s_asnipLoadRov[2]; @@ -44,7 +51,30 @@ INCLUDE_ASM("asm/nonmatchings/P2/rog", RovsNextRov__FP3ROV); INCLUDE_ASM("asm/nonmatchings/P2/rog", SetRovRovs__FP3ROV4ROVS); -INCLUDE_ASM("asm/nonmatchings/P2/rog", RovtsNextRov__FP3ROV); +ROVTS RovtsNextRov(ROV *prov) +{ + ROVTS rovts = STRUCT_OFFSET(prov, 0x614, ROVTS); + + switch (rovts) + { + case ROVTS_Calm: + if (STRUCT_OFFSET(prov, 0x624, float) >= 0.8f) + { + rovts = ROVTS_Firing; + } + break; + case ROVTS_Firing: + if (STRUCT_OFFSET(prov, 0x624, float) < 0.8f) + { + rovts = ROVTS_Calm; + } + break; + default: + break; + } + + return rovts; +} INCLUDE_ASM("asm/nonmatchings/P2/rog", SetRovRovts__FP3ROV5ROVTS); @@ -54,7 +84,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/rog", PresetRovAccel__FP3ROVf); INCLUDE_ASM("asm/nonmatchings/P2/rog", AdjustRovXpVelocity__FP3ROVP2XPi); -INCLUDE_ASM("asm/nonmatchings/P2/rog", AdjustRovNewXp__FP3ROVP2XPi); +void AdjustRovNewXp(ROV *prov, XP *pxp, int ixpd) +{ + if (FDrivenAlo(prov)) + return; + + if (0.7f < STRUCT_OFFSET(pxp, 0x88, float)) + STRUCT_OFFSET(pxp, 0x94, float) = 20.0f; +} INCLUDE_ASM("asm/nonmatchings/P2/rog", PropagateRovForce__FP3ROViP2XPiP2DZP2FX); @@ -93,22 +130,13 @@ void AddRobSpawnTunnel(ROB *prob, OID oidSpawnTunnel) STRUCT_OFFSET(prob, 0x2e0, int) = coidRost + 1; // prob->coidRost } -/** - * @brief 80% match. - * https://decomp.me/scratch/s3oRy - */ -INCLUDE_ASM("asm/nonmatchings/P2/rog", RobkCur__Fv); -#ifdef SKIP_ASM ROBK RobkCur() { - if ((uint)g_plsCur->fls & FLS_Secondary) - { - return ROBK_Tertiary; - } - - return (ROBK)((uint)g_plsCur->fls & FLS_KeyCollected); + int grfrob = *(int *)g_plsCur; + if ((grfrob & 0x4) == 0) + return (ROBK)((grfrob & 0x2) > 0); + return ROBK_Tertiary; } -#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/rog", BindRob__FP3ROB); @@ -116,7 +144,26 @@ INCLUDE_ASM("asm/nonmatchings/P2/rog", PostRobLoad__FP3ROB); INCLUDE_ASM("asm/nonmatchings/P2/rog", UpdateRob__FP3ROBf); -INCLUDE_ASM("asm/nonmatchings/P2/rog", FUN_001a4d60); +extern int FUN_001e9970(); +extern BLOT g_unkblot0; + +void FUN_001a4d60(ROB *prob) +{ + int fShow = 0; + if (STRUCT_OFFSET(prob, 0x650, int) == 2) + { + fShow = FUN_001e9970(); + } + + if (fShow) + { + g_unkblot0.pvtblot->pfnShowBlot(&g_unkblot0); + } + else + { + g_unkblot0.pvtblot->pfnHideBlot(&g_unkblot0); + } +} INCLUDE_ASM("asm/nonmatchings/P2/rog", RobsNextRob__FP3ROB); @@ -128,39 +175,198 @@ INCLUDE_ASM("asm/nonmatchings/P2/rog", AddRobRoh__FP3ROB); INCLUDE_ASM("asm/nonmatchings/P2/rog", AdjustRobDifficulty__FP3ROBf); -INCLUDE_ASM("asm/nonmatchings/P2/rog", DestroyedRobRoc__FP3ROBP3ROC); +void DestroyedRobRoc(ROB *prob, ROC *proc) +{ + int cRoc = STRUCT_OFFSET(prob, 0x3c4, int) + 1; + STRUCT_OFFSET(prob, 0x3c4, int) = cRoc; + AdjustRobDifficulty(prob, (float)cRoc / (float)STRUCT_OFFSET(prob, 0x3b8, int)); + + if (STRUCT_OFFSET(proc, 0x55c, ROH *) != NULL) + RemoveDlEntry(&STRUCT_OFFSET(prob, 0x35c, DL), proc); + else + RemoveDlEntry(&STRUCT_OFFSET(prob, 0x368, DL), proc); + + AppendDlEntry(&STRUCT_OFFSET(prob, 0x374, DL), proc); + + if (STRUCT_OFFSET(proc, 0x55c, ROH *) != NULL) + { + if (FChooseRobRoc(prob, STRUCT_OFFSET(proc, 0x55c, ROH *))) + { + SetRohRohs(STRUCT_OFFSET(proc, 0x55c, ROH *), ROHS_Collect); + } + else + { + STRUCT_OFFSET(STRUCT_OFFSET(proc, 0x55c, ROH *), 0x55c, ROC *) = NULL; + SetRohRohs(STRUCT_OFFSET(proc, 0x55c, ROH *), ROHS_Wander); + } + } + + STRUCT_OFFSET(proc, 0x55c, ROH *) = NULL; + // @todo clean up this vtable call + (*(void (**)(ROC *))((char *)((LO *)proc)->pvtlo + 0x1c))(proc); + + if (STRUCT_OFFSET(prob, 0x380, int) == STRUCT_OFFSET(prob, 0x624, int)) + { + STRUCT_OFFSET(prob, 0x634, float) = + g_clock.t + GRandInRange(STRUCT_OFFSET(prob, 0x62c, float), STRUCT_OFFSET(prob, 0x630, float)); + } + STRUCT_OFFSET(prob, 0x380, int) -= 1; +} -INCLUDE_ASM("asm/nonmatchings/P2/rog", SpawnedRobRoh__FP3ROBP3ROH); +void SpawnedRobRoh(ROB *prob, ROH *proh) +{ + RemoveDlEntry((DL *)&STRUCT_OFFSET(prob, 0x3AC, int), STRUCT_OFFSET(proh, 0x560, ROST *)); + AppendDlEntry((DL *)&STRUCT_OFFSET(prob, 0x3A0, int), STRUCT_OFFSET(proh, 0x560, ROST *)); + SetRostRosts(STRUCT_OFFSET(proh, 0x560, ROST *), ROSTS_Close); + STRUCT_OFFSET(proh, 0x560, ROST *) = NULL; +} -INCLUDE_ASM("asm/nonmatchings/P2/rog", GrabbedRobRoh__FP3ROBP3ROH); +void GrabbedRobRoh(ROB *prob, ROH *proh) +{ + (*(void (**)(SO *))(*(uint8_t **)STRUCT_OFFSET(proh, 0x55c, SO *) + 0x64))(STRUCT_OFFSET(proh, 0x55c, SO *)); + (*(void (**)(SO *, VECTOR *))(*(uint8_t **)STRUCT_OFFSET(proh, 0x55c, SO *) + 0x90))(STRUCT_OFFSET(proh, 0x55c, SO *), &D_00248D30); + (*(void (**)(SO *, VECTOR *))(*(uint8_t **)STRUCT_OFFSET(proh, 0x55c, SO *) + 0x94))(STRUCT_OFFSET(proh, 0x55c, SO *), &D_00248D30); + SetSoConstraints(STRUCT_OFFSET(proh, 0x55c, SO *), CT_Locked, NULL, CT_Locked, NULL); + StartSound((SFXID)0x151, NULL, NULL, NULL, 3000.0f, 300.0f, 1.0f, 0.0f, 0.0f, NULL, NULL); +} -INCLUDE_ASM("asm/nonmatchings/P2/rog", DroppedRobRoh__FP3ROBP3ROH); +void DroppedRobRoh(ROB *prob, ROH *proh) +{ -INCLUDE_ASM("asm/nonmatchings/P2/rog", ReturnedRobRoh__FP3ROBP3ROH); + SO *pso = STRUCT_OFFSET(proh, 0x55c, SO *); + + (*(void (**)(SO *, int))(*(uint8_t **)pso + 0x64))(pso, 0); + (*(void (**)(SO *, VECTOR *))(*(uint8_t **)pso + 0x90))(pso, &D_00248D30); + (*(void (**)(SO *, VECTOR *))(*(uint8_t **)pso + 0x94))(pso, &D_00248D30); + SetSoConstraints(pso, CT_Project, &g_normalZ, CT_Locked, NULL); +} + +void ReturnedRobRoh(ROB *prob, ROH *proh) +{ + SetRostRosts(STRUCT_OFFSET(proh, 0x560, ROST*), ROSTS_Open); +} INCLUDE_ASM("asm/nonmatchings/P2/rog", ExitedRobRoh__FP3ROBP3ROH); -INCLUDE_ASM("asm/nonmatchings/P2/rog", KilledRobRoh__FP3ROBP3ROH); +void KilledRobRoh(ROB *prob, ROH *proh) +{ + RemoveDlEntry(&STRUCT_OFFSET(prob, 0x384, DL), proh); + AppendDlEntry(&STRUCT_OFFSET(prob, 0x390, DL), proh); + + if (STRUCT_OFFSET(proh, 0x560, ROST *) != NULL) + { + RemoveDlEntry(&STRUCT_OFFSET(prob, 0x3ac, DL), STRUCT_OFFSET(proh, 0x560, void *)); + AppendDlEntry(&STRUCT_OFFSET(prob, 0x3a0, DL), STRUCT_OFFSET(proh, 0x560, void *)); + SetRostRosts(STRUCT_OFFSET(proh, 0x560, ROST *), ROSTS_Close); + } + + ROC *proc = STRUCT_OFFSET(proh, 0x55c, ROC *); + if (proc != NULL) + { + if (STRUCT_OFFSET(proc, 0x18, ROH *) == proh) + { + DroppedRobRoh(prob, proh); + } + RemoveDlEntry(&STRUCT_OFFSET(prob, 0x35c, DL), proc); + AppendDlEntry(&STRUCT_OFFSET(prob, 0x368, DL), proc); + if (!FChooseRobRoh(prob, proc)) + STRUCT_OFFSET(proc, 0x55c, ROH *) = NULL; + } + + STRUCT_OFFSET(proh, 0x560, ROST *) = NULL; + STRUCT_OFFSET(proh, 0x55c, ROC *) = NULL; + (*(void (**)(ROH *))(STRUCT_OFFSET(proh, 0x0, uint8_t *) + 0x1c))(proh); + + if (STRUCT_OFFSET(prob, 0x39c, int) == STRUCT_OFFSET(prob, 0x628, int)) + { + STRUCT_OFFSET(prob, 0x640, float) = + g_clock.t + GRandInRange(STRUCT_OFFSET(prob, 0x638, float), STRUCT_OFFSET(prob, 0x63c, float)); + } + STRUCT_OFFSET(prob, 0x39c, int) -= 1; +} INCLUDE_ASM("asm/nonmatchings/P2/rog", FChooseRobRoc__FP3ROBP3ROH); -INCLUDE_ASM("asm/nonmatchings/P2/rog", TakeRobRoc__FP3ROBP3ROHP3ROC); +void TakeRobRoc(ROB *prob, ROH *proh, ROC *proc) +{ + ROC *procPrev = STRUCT_OFFSET(proh, 0x55c, ROC *); + if (procPrev != NULL) + { + if (procPrev == proc) + return; + } + + ROH *prohPrev = STRUCT_OFFSET(proc, 0x55c, ROH *); + STRUCT_OFFSET(proh, 0x55c, ROC *) = proc; + STRUCT_OFFSET(proc, 0x55c, ROH *) = proh; + + if (prohPrev == NULL) + { + RemoveDlEntry(&STRUCT_OFFSET(prob, 0x368, DL), proc); + AppendDlEntry(&STRUCT_OFFSET(prob, 0x35c, DL), proc); + } + + if (procPrev != NULL) + { + RemoveDlEntry(&STRUCT_OFFSET(prob, 0x35c, DL), procPrev); + AppendDlEntry(&STRUCT_OFFSET(prob, 0x368, DL), procPrev); + STRUCT_OFFSET(procPrev, 0x55c, ROH *) = NULL; + FChooseRobRoh(prob, procPrev); + } + + if (prohPrev != NULL) + { + STRUCT_OFFSET(prohPrev, 0x55c, ROC *) = NULL; + SetRohRohs(prohPrev, ROHS_Wander); + if (FChooseRobRoc(prob, prohPrev)) + SetRohRohs(prohPrev, ROHS_Collect); + } +} INCLUDE_ASM("asm/nonmatchings/P2/rog", FChooseRobRoh__FP3ROBP3ROC); INCLUDE_ASM("asm/nonmatchings/P2/rog", FChooseRobReturnPoint__FP3ROBP3ROH); -INCLUDE_ASM("asm/nonmatchings/P2/rog", ChooseRobWanderLocation__FP3ROBP3ROH); +void ChooseRobWanderLocation(ROB *prob, ROH *proh) +{ + float rad = GRandInRange(0.0f, 6.2831855f); + float sXY = GRandInRange(0.0f, STRUCT_OFFSET(prob, 0x348, float)); + SetVectorCylind((VECTOR *)((uint8_t *)proh + 0x570), rad, sXY, 0.0f); + STRUCT_OFFSET(proh, 0x574, float) = STRUCT_OFFSET(proh, 0x574, float) * STRUCT_OFFSET(prob, 0x34c, float); +} -INCLUDE_ASM("asm/nonmatchings/P2/rog", ProddCurRob__FP3ROB4ENSK); +RODD *ProddCurRob(ROB *prob, ENSK ensk) +{ + int irodd = STRUCT_OFFSET(prob, 0x620, int); + return (RODD *)((uint8_t *)prob + (irodd * 0xC0 + 0x3E0)); +} + +void InitRoh(ROH *proh) +{ + InitSo(proh); + STRUCT_OFFSET(proh, 0x550, int) = -1; + STRUCT_OFFSET(proh, 0x584, float) = 1.0f; + STRUCT_OFFSET(proh, 0x588, float) = 2.5f; + SetSoConstraints(proh, CT_Tangent, &g_normalZ, CT_Project, &g_normalZ); +} -INCLUDE_ASM("asm/nonmatchings/P2/rog", InitRoh__FP3ROH); +extern SNIP D_0026B7E8; -INCLUDE_ASM("asm/nonmatchings/P2/rog", LoadRohFromBrx__FP3ROHP18CBinaryInputStream); +void LoadRohFromBrx(ROH *proh, CBinaryInputStream *pbis) +{ + LoadSoFromBrx(proh, pbis); + SnipAloObjects(proh, 6, &D_0026B7E8); + InferExpl(&STRUCT_OFFSET(proh, 0x5ac, EXPL *), proh); +} INCLUDE_ASM("asm/nonmatchings/P2/rog", CloneRoh__FP3ROHT0); -INCLUDE_ASM("asm/nonmatchings/P2/rog", PostRohLoad__FP3ROH); +void PostRohLoad(ROH *proh) +{ + PostAloLoad(proh); + SetRohRohs(proh, ROHS_Inactive); + proh->pvtlo->pfnRemoveLo(proh); +} INCLUDE_ASM("asm/nonmatchings/P2/rog", UpdateRoh__FP3ROHf); @@ -172,11 +378,33 @@ INCLUDE_ASM("asm/nonmatchings/P2/rog", SetRohRohs__FP3ROH4ROHS); INCLUDE_ASM("asm/nonmatchings/P2/rog", FAbsorbRohWkr__FP3ROHP3WKR); -INCLUDE_ASM("asm/nonmatchings/P2/rog", ProcContactRoh__FP3ROH); +ROC *ProcContactRoh(ROH *proh) +{ + void *pv = STRUCT_OFFSET(STRUCT_OFFSET(proh, 0x480, DL *), 0x0, void *); + + while (pv != NULL) + { + if (STRUCT_OFFSET(pv, 0x0, int) != 0) + { + if (FIsBasicDerivedFrom(STRUCT_OFFSET(pv, 0xc, BASIC *), (CID)0x43)) + return STRUCT_OFFSET(pv, 0xc, ROC *); + } + pv = STRUCT_OFFSET(pv, 0x4, void *); + } + + return NULL; +} INCLUDE_ASM("asm/nonmatchings/P2/rog", InitRoc__FP3ROC); -INCLUDE_ASM("asm/nonmatchings/P2/rog", LoadRocFromBrx__FP3ROCP18CBinaryInputStream); +extern SNIP D_0026B830; + +void LoadRocFromBrx(ROC *proc, CBinaryInputStream *pbis) +{ + LoadSoFromBrx(proc, pbis); + SnipAloObjects(proc, 1, &D_0026B830); + InferExpl(&STRUCT_OFFSET(proc, 0x574, EXPL *), proc); +} INCLUDE_ASM("asm/nonmatchings/P2/rog", CloneRoc__FP3ROCT0); @@ -184,9 +412,24 @@ INCLUDE_ASM("asm/nonmatchings/P2/rog", PostRocLoad__FP3ROC); INCLUDE_ASM("asm/nonmatchings/P2/rog", UpdateRoc__FP3ROCf); -INCLUDE_ASM("asm/nonmatchings/P2/rog", PresetRocAccel__FP3ROCf); +void PresetRocAccel(ROC *proc, float dt) +{ + MATRIX3 mat; + extern SMP D_0026B850; -INCLUDE_ASM("asm/nonmatchings/P2/rog", AdjustRocNewXp__FP3ROCP2XPi); + PresetSoAccel(proc, dt); + + if (STRUCT_OFFSET(proc, 0x18, int) == 0) + { + TiltMatUpright((MATRIX3 *)((uint8_t *)proc + 0x110), NULL, &mat); + AccelSoTowardMatSmooth(proc, g_clock.dt, &mat, &D_0026B850); + } +} + +void AdjustRocNewXp(ROC *proc, XP *pxp, int ixpd) +{ + STRUCT_OFFSET(pxp, 0x98, float) *= 0.6f; +} INCLUDE_ASM("asm/nonmatchings/P2/rog", FAbsorbRocWkr__FP3ROCP3WKR); @@ -194,15 +437,34 @@ INCLUDE_ASM("asm/nonmatchings/P2/rog", RocsNextRoc__FP3ROC); INCLUDE_ASM("asm/nonmatchings/P2/rog", SetRocRocs__FP3ROC4ROCS); -INCLUDE_ASM("asm/nonmatchings/P2/rog", InitRost__FP4ROST); +void InitRost(ROST *prost) +{ + InitSo(prost); + STRUCT_OFFSET(prost, 0x550, ROSTS) = ROSTS_Nil; // prost->rosts +} + +extern SNIP D_0026B888; -INCLUDE_ASM("asm/nonmatchings/P2/rog", LoadRostFromBrx__FP4ROSTP18CBinaryInputStream); +void LoadRostFromBrx(ROST *prost, CBinaryInputStream *pbis) +{ + LoadSoFromBrx(prost, pbis); + SnipAloObjects(prost, 1, &D_0026B888); +} INCLUDE_ASM("asm/nonmatchings/P2/rog", CloneRost__FP4ROSTT0); INCLUDE_ASM("asm/nonmatchings/P2/rog", PostRostLoad__FP4ROST); -INCLUDE_ASM("asm/nonmatchings/P2/rog", UpdateRost__FP4ROSTf); +void UpdateRost(ROST *prost, float dt) +{ + ROSTS rosts; + + UpdateSo(prost, dt); + while ((rosts = RostsNextRost(prost)) != STRUCT_OFFSET(prost, 0x550, ROSTS)) + { + SetRostRosts(prost, rosts); + } +} ROSTS RostsNextRost(ROST *prost) { @@ -211,11 +473,37 @@ ROSTS RostsNextRost(ROST *prost) INCLUDE_ASM("asm/nonmatchings/P2/rog", SetRostRosts__FP4ROST5ROSTS); -INCLUDE_ASM("asm/nonmatchings/P2/rog", InitRop__FP3ROP); +void InitRop(ROP *prop) +{ + InitSo(prop); + STRUCT_OFFSET(prop, 0x550, int) = -1; // prop->rops + SetSoConstraints(prop, CT_Locked, NULL, CT_Locked, NULL); +} + +extern SNIP D_0026B8A0; + +void LoadRopFromBrx(ROP *prop, CBinaryInputStream *pbis) +{ + LoadSoFromBrx(prop, pbis); + SnipAloObjects(prop, 1, &D_0026B8A0); + InferExpl(&STRUCT_OFFSET(prop, 0x568, EXPL *), prop); +} -INCLUDE_ASM("asm/nonmatchings/P2/rog", LoadRopFromBrx__FP3ROPP18CBinaryInputStream); +void PostRopLoad(ROP *prop) +{ + PostAloLoad(prop); -INCLUDE_ASM("asm/nonmatchings/P2/rog", PostRopLoad__FP3ROP); + if (STRUCT_OFFSET(prop, 0x558, int) == 0) + { + prop->pvtlo->pfnRemoveLo(prop); + } + else + { + STRUCT_OFFSET(prop, 0x55C, LO *) = + PloFindSwObjectByClass(prop->psw, 0x101, (CID)0x59, STRUCT_OFFSET(prop, 0x34, LO *)); + SetRopRops(prop, ROPS_StayPut); + } +} INCLUDE_ASM("asm/nonmatchings/P2/rog", UpdateRop__FP3ROPf); diff --git a/src/P2/rumble.c b/src/P2/rumble.c index 49c697e18..2f64085a1 100644 --- a/src/P2/rumble.c +++ b/src/P2/rumble.c @@ -1,6 +1,7 @@ #include #include #include +#include /** * @brief Rename. @@ -24,7 +25,12 @@ void InitRumble(RUMBLE *prumble, int nPort, int nSlot) INCLUDE_ASM("asm/nonmatchings/P2/rumble", UpdateRumble__FP6RUMBLE); -INCLUDE_ASM("asm/nonmatchings/P2/rumble", TriggerRumbleRumk__FP6RUMBLE4RUMKf); +extern RUMPAT D_0026B8B0[]; + +void TriggerRumbleRumk(RUMBLE *prumble, RUMK rumk, float dt) +{ + TriggerRumbleRumpat(prumble, &D_0026B8B0[rumk], dt); +} INCLUDE_ASM("asm/nonmatchings/P2/rumble", TriggerRumbleRumpat__FP6RUMBLEP6RUMPATf); @@ -91,6 +97,22 @@ void FUN_001A7E70() INCLUDE_ASM("asm/nonmatchings/P2/rumble", FUN_001A7E90); -INCLUDE_ASM("asm/nonmatchings/P2/rumble", FUN_001A7EE8); +int FUN_001A7EE8(GS *pgs) +{ + switch (DAT_0026c3dc) + { + case 1: + break; + case 2: + return 1; + case 3: + return 0; + case 0: + return 0; + default: + break; + } + return ((STRUCT_OFFSET(pgs, 0x19EC, int) >> 5) ^ 1) & 1; +} INCLUDE_ASM("asm/nonmatchings/P2/rumble", FUN_001A7F50); diff --git a/src/P2/rwm.c b/src/P2/rwm.c index ffc7adf62..4b148bd3f 100644 --- a/src/P2/rwm.c +++ b/src/P2/rwm.c @@ -1,28 +1,152 @@ #include +#include +#include +#include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/rwm", InitRwm__FP3RWM); -INCLUDE_ASM("asm/nonmatchings/P2/rwm", OnRwmRemove); - -INCLUDE_ASM("asm/nonmatchings/P2/rwm", FUN_001a8110); +void OnRwmRemove(RWM *prwm) +{ + OnLoRemove(prwm); + FUN_001a93c8(prwm); +} + +void *FUN_001a8110(RWM *prwm) +{ + if (STRUCT_OFFSET(prwm, 0x3c, void *) == 0) + { + void *pv = PvAllocSwClearImpl(0x20); + STRUCT_OFFSET(prwm, 0x3c, void *) = pv; + STRUCT_OFFSET(pv, 0x0, RWM *) = prwm; + } + return STRUCT_OFFSET(prwm, 0x3c, void *); +} INCLUDE_ASM("asm/nonmatchings/P2/rwm", FUN_001a8150); INCLUDE_ASM("asm/nonmatchings/P2/rwm", InitRwmCallback__FP3RWM5MSGIDPv); -INCLUDE_ASM("asm/nonmatchings/P2/rwm", FUN_001a84c8); - -INCLUDE_ASM("asm/nonmatchings/P2/rwm", PostRwmLoad__FP3RWM); - -INCLUDE_ASM("asm/nonmatchings/P2/rwm", FUN_001a86f8); +void FUN_001a84c8(RWM *prwmDst, RWM *prwmSrc) +{ + CloneLo((LO *)prwmDst, (LO *)prwmSrc); + if (STRUCT_OFFSET(prwmDst, 0x3c, void *) != 0 && + STRUCT_OFFSET(STRUCT_OFFSET(prwmDst, 0x3c, void *), 0x4, int) != 0) + { + if (STRUCT_OFFSET(STRUCT_OFFSET(prwmSrc, 0x3c, void *), 0x8, int) == 0) + { + STRUCT_OFFSET(STRUCT_OFFSET(prwmSrc, 0x3c, void *), 0x8, int) = 1; + InitDl((DL *)((uint8_t *)STRUCT_OFFSET(prwmSrc, 0x3c, void *) + 0x14), 0x18); + } + STRUCT_OFFSET(prwmDst, 0x3c, void *) = 0; + FUN_001a8110(prwmDst); + STRUCT_OFFSET(STRUCT_OFFSET(prwmDst, 0x3c, void *), 0x4, int) = 1; + STRUCT_OFFSET(STRUCT_OFFSET(prwmDst, 0x3c, void *), 0x8, int) = 2; + STRUCT_OFFSET(STRUCT_OFFSET(prwmDst, 0x3c, void *), 0x14, RWM *) = prwmSrc; + AppendDlEntry((DL *)((uint8_t *)STRUCT_OFFSET(prwmSrc, 0x3c, void *) + 0x14), + STRUCT_OFFSET(prwmDst, 0x3c, void *)); + } + else + { + STRUCT_OFFSET(prwmDst, 0x38, void *) = + PvAllocSwCopyImpl(STRUCT_OFFSET(prwmSrc, 0x34, int) * 0x14, + STRUCT_OFFSET(prwmSrc, 0x38, void *)); + } +} + +void PostRwmLoad(RWM *prwm) +{ + LO *plo; + OID oid; + + PostLoLoad((LO *)prwm); + if (STRUCT_OFFSET(prwm, 0x168, int) != 0) + return; + STRUCT_OFFSET(prwm, 0x168, int) = 1; + + oid = STRUCT_OFFSET(prwm, 0x4c, OID); + if (oid != OID_Nil) + { + plo = PloFindSwNearest(STRUCT_OFFSET(prwm, 0x14, SW *), oid, (LO *)prwm); + if (plo != 0) + { + if (FIsBasicDerivedFrom((BASIC *)plo, CID_WARP)) + STRUCT_OFFSET(prwm, 0x60, LO *) = plo; + else if (FIsBasicDerivedFrom((BASIC *)plo, (CID)0x73)) + STRUCT_OFFSET(prwm, 0x64, LO *) = plo; + else if (FIsBasicDerivedFrom((BASIC *)plo, CID_ALO)) + STRUCT_OFFSET(prwm, 0x68, LO *) = plo; + } + } + + oid = STRUCT_OFFSET(prwm, 0x50, OID); + if (oid != OID_Nil) + { + plo = PloFindSwNearest(STRUCT_OFFSET(prwm, 0x14, SW *), oid, (LO *)prwm); + if (plo != 0) + { + if (FIsBasicDerivedFrom((BASIC *)plo, CID_ALO)) + STRUCT_OFFSET(prwm, 0xe0, LO *) = plo; + else if (FIsBasicDerivedFrom((BASIC *)plo, (CID)0x75)) + STRUCT_OFFSET(prwm, 0xe4, LO *) = plo; + } + } + + oid = STRUCT_OFFSET(prwm, 0x54, OID); + if (oid != OID_Nil) + { + plo = PloFindSwNearest(STRUCT_OFFSET(prwm, 0x14, SW *), oid, (LO *)prwm); + if (plo != 0) + { + if (FIsBasicDerivedFrom((BASIC *)plo, (CID)0x73)) + STRUCT_OFFSET(prwm, 0x160, LO *) = plo; + else if (FIsBasicDerivedFrom((BASIC *)plo, CID_ALO)) + STRUCT_OFFSET(prwm, 0x164, LO *) = plo; + } + } + + oid = STRUCT_OFFSET(prwm, 0x58, OID); + if (oid != OID_Nil) + { + STRUCT_OFFSET(prwm, 0x5c, LO *) = + PloFindSwNearest(STRUCT_OFFSET(prwm, 0x14, SW *), oid, (LO *)prwm); + } +} + +void FUN_001a86f8(RWM *prwm, int f) +{ + if (f != 0) + FUN_001a93c8(prwm); +} INCLUDE_ASM("asm/nonmatchings/P2/rwm", PrwcFindRwm__FP3RWM3OID); -INCLUDE_ASM("asm/nonmatchings/P2/rwm", EnableRwmRwc__FP3RWM3OID); - -INCLUDE_ASM("asm/nonmatchings/P2/rwm", DisableRwmRwc__FP3RWM3OID); - -INCLUDE_ASM("asm/nonmatchings/P2/rwm", ResizeRwmRwc__FP3RWM3OIDi); +void EnableRwmRwc(RWM *prwm, OID oidCache) +{ + RWC *prwc = PrwcFindRwm(prwm, oidCache); + if (prwc != NULL) + STRUCT_OFFSET(prwc, 0x10, int) |= 0x2; +} + +void DisableRwmRwc(RWM *prwm, OID oidCache) +{ + RWC *prwc = PrwcFindRwm(prwm, oidCache); + if (prwc != NULL) + STRUCT_OFFSET(prwc, 0x10, int) &= ~0x2; +} + +void ResizeRwmRwc(RWM *prwm, OID oidCache, int cpso) +{ + RWC *prwc = PrwcFindRwm(prwm, oidCache); + if (prwc != NULL) + { + int cMax = STRUCT_OFFSET(prwc, 0xc, int); + STRUCT_OFFSET(prwc, 0x4, int) = (cpso < cMax) ? cpso : cMax; + } +} INCLUDE_ASM("asm/nonmatchings/P2/rwm", FIsRwmAmmo__FP3RWMP2SO); @@ -36,18 +160,65 @@ INCLUDE_ASM("asm/nonmatchings/P2/rwm", FEnsureRwmLoaded__FP3RWM); INCLUDE_ASM("asm/nonmatchings/P2/rwm", FFireRwm__FP3RWMi); -INCLUDE_ASM("asm/nonmatchings/P2/rwm", FUN_001a93c8); - -INCLUDE_ASM("asm/nonmatchings/P2/rwm", ClearRwmFireInfo__FP3RWM); +void FUN_001a93c8(RWM *prwm) +{ + int *p = STRUCT_OFFSET(prwm, 0x3c, int *); + STRUCT_OFFSET(prwm, 0x48, int) = 0; + if (p != 0) + { + if (p[1] != 0) + p[4] = 0; + } +} + +extern qword D_002483D0[3]; + +void ClearRwmFireInfo(RWM *prwm) +{ + uint8_t *p = (uint8_t *)prwm + 0x60; + memset(p, 0, 0x80); + STRUCT_OFFSET(p, 0x20, qword) = D_002483D0[0]; + STRUCT_OFFSET(p, 0x30, qword) = D_002483D0[1]; + STRUCT_OFFSET(p, 0x40, qword) = D_002483D0[2]; +} INCLUDE_ASM("asm/nonmatchings/P2/rwm", ClearRwmTargetInfo__FP3RWM); -INCLUDE_ASM("asm/nonmatchings/P2/rwm", ClearRwmAimConstraints__FP3RWM); +void ClearRwmAimConstraints(RWM *prwm) +{ + memset((uint8_t *)prwm + 0x150, 0, 0x18); +} INCLUDE_ASM("asm/nonmatchings/P2/rwm", GetRwfiPosMat__FP4RWFIP6VECTORP7MATRIX3); INCLUDE_ASM("asm/nonmatchings/P2/rwm", GetRwtiPos__FP4RWTIP6VECTORT1); -INCLUDE_ASM("asm/nonmatchings/P2/rwm", GetRwacPan__FP4RWACPf); +void GetRwacPanImpl(RWAC *prwac, float *pradPan, ALO *palo) asm("GetRwacPan__FP4RWACPf"); + +void GetRwacPanImpl(RWAC *prwac, float *pradPan, ALO *palo) +{ + MATRIX3 mat; + + XFM *pxfm = STRUCT_OFFSET(prwac, 0x10, XFM *); + if (pxfm != 0) + { + GetXfmMat(pxfm, &mat); + ConvertAloMat(0, palo, &mat, &mat); + *pradPan = atan2f(mat.mat[0][1], mat.mat[0][0]); + } + else + { + MATRIX3 *pmat = STRUCT_OFFSET(prwac, 0x14, MATRIX3 *); + if (pmat != 0) + { + ConvertAloMat(0, palo, (MATRIX3 *)((uint8_t *)pmat + 0x110), &mat); + *pradPan = atan2f(mat.mat[0][1], mat.mat[0][0]); + } + else + { + *pradPan = STRUCT_OFFSET(prwac, 0x8, float); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/rwm", GetRwacTilt__FP4RWACPf); diff --git a/src/P2/sb.c b/src/P2/sb.c index 05e26cc1f..9ba54c688 100644 --- a/src/P2/sb.c +++ b/src/P2/sb.c @@ -1,10 +1,31 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/sb", PostSbgLoad__FP3SBG); -INCLUDE_ASM("asm/nonmatchings/P2/sb", FUN_001a9928__FP3SBG); +undefined4 FUN_001a9928(SBG *psbg) +{ + if (IsSwHandsOff(STRUCT_OFFSET(psbg, 0x14, SW *))) + return 0; + return STRUCT_OFFSET(psbg, 0xc24, int); +} -INCLUDE_ASM("asm/nonmatchings/P2/sb", UpdateSbgGoal__FP3SBGi); +void UpdateSbgGoal(SBG *psbg, int fEnter) +{ + UpdateStepguardGoal(psbg, fEnter); + + if (STRUCT_OFFSET(psbg, 0x724, int) == 0x10) + { + void *pvt = STRUCT_OFFSET(psbg, 0x0, void *); + SO *(*fn)(SO *) = (SO *(*)(SO *))STRUCT_OFFSET(pvt, 0x198, void *); + SO *pso = fn((SO *)psbg); + if (pso != NULL) + { + SetStepguardGoal(psbg, (VECTOR *)((char *)pso + 0x140)); + } + } +} void UpdateSbgSgs(SBG *psbg) { @@ -19,7 +40,20 @@ void UpdateSbgSgs(SBG *psbg) INCLUDE_ASM("asm/nonmatchings/P2/sb", OnSbgEnteringSgs__FP3SBG3SGSP4ASEG); -INCLUDE_ASM("asm/nonmatchings/P2/sb", UpdateSbg__FP3SBGf); +void UpdateSbg(SBG *psbg, float dt) +{ + UpdateStepguard(psbg, dt); + + ASEGA *pasega = STRUCT_OFFSET(psbg, 0xC20, ASEGA *); + if (pasega != NULL) + { + if (STRUCT_OFFSET(pasega, 0x18, float) == 0.0f) + { + RetractAsega(pasega); + STRUCT_OFFSET(psbg, 0xC20, ASEGA *) = NULL; + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/sb", FUN_001a9a98); diff --git a/src/P2/screen.c b/src/P2/screen.c index a66201c6b..a2b2a3446 100644 --- a/src/P2/screen.c +++ b/src/P2/screen.c @@ -1,18 +1,61 @@ #include #include #include +#include +#include +#include +#include +#include + +extern BLOT *D_002486B0[]; INCLUDE_ASM("asm/nonmatchings/P2/screen", StartupScreen__Fv); -INCLUDE_ASM("asm/nonmatchings/P2/screen", PostBlotsLoad__Fv); +void PostBlotsLoad() +{ + for (int i = 0x24; i >= 0; i--) + { + BLOT *pblot = D_002486B0[i]; + ((VTBLOT *)pblot->pvtblot)->pfnPostBlotLoad(pblot); + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", UpdateBlots__Fv); -INCLUDE_ASM("asm/nonmatchings/P2/screen", ForceHideBlots__Fv); +void ForceHideBlots() +{ + for (int i = 0x24; i >= 0; i--) + { + BLOT *pblot = D_002486B0[i]; + ((void (*)(BLOT *, BLOTS))pblot->pvtblot->pfnSetBlotBlots)(pblot, BLOTS_Hidden); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/screen", ResetBlots__Fv); +void ResetBlots(void) +{ + for (int i = 0; i < 0x25; i++) + { + BLOT *pblot = D_002486B0[i]; + ((VTBLOT *)pblot->pvtblot)->pfnOnBlotReset(pblot); + } +} + +void RenderBlots() +{ + BLOT **ppblot = D_002486B0; -INCLUDE_ASM("asm/nonmatchings/P2/screen", RenderBlots__Fv); + for (int i = 0x24; i >= 0; i--) + { + BLOT *pblot = *ppblot; + ppblot++; + + if (pblot->blots != BLOTS_Hidden) + { + if (((VTBLOT *)pblot->pvtblot)->pfnRenderBlot != NULL) + ((VTBLOT *)pblot->pvtblot)->pfnRenderBlot(pblot); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", DrawBlots__Fv); @@ -71,9 +114,24 @@ void SetBlotDtDisappear(BLOT *pblot, float dtDisappear) pblot->dtDisappear = dtDisappear; } -INCLUDE_ASM("asm/nonmatchings/P2/screen", OnBlotReset__FP4BLOT); +void OnBlotReset(BLOT *pblot) +{ + ((void (*)(BLOT *, BLOTS))pblot->pvtblot->pfnSetBlotBlots)(pblot, BLOTS_Hidden); +} -INCLUDE_ASM("asm/nonmatchings/P2/screen", ShowBlot__FP4BLOT); +void ShowBlot(BLOT *pblot) +{ + switch (pblot->blots) + { + case BLOTS_Hidden: + case BLOTS_Disappearing: + ((void (*)(BLOT *, BLOTS))pblot->pvtblot->pfnSetBlotBlots)(pblot, BLOTS_Appearing); + break; + case BLOTS_Visible: + pblot->tBlots = *pblot->ptNow; + break; + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", HideBlot__FP4BLOT); @@ -81,7 +139,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/screen", SetBlotBlots__FP4BLOT5BLOTS); INCLUDE_ASM("asm/nonmatchings/P2/screen", FIncludeBlotForPeg__FP4BLOTT0); -INCLUDE_ASM("asm/nonmatchings/P2/screen", ResizeBlot__FP4BLOTff); +void ResizeBlot(BLOT *pblot, float dx, float dy) +{ + if (dx >= 0.0f) + pblot->width = dx; + if (dy >= 0.0f) + pblot->height = dy; + RepositionBlot(pblot); +} INCLUDE_ASM("asm/nonmatchings/P2/screen", RepositionBlot__FP4BLOT); @@ -97,7 +162,10 @@ INCLUDE_ASM("asm/nonmatchings/P2/screen", DrawCtr__FP3CTR); INCLUDE_ASM("asm/nonmatchings/P2/screen", RebuildCtrAchzDraw__FP3CTR); -INCLUDE_ASM("asm/nonmatchings/P2/screen", DtVisibleCtr__FP3CTR); +float DtVisibleCtr(CTR *pctr) +{ + return g_clock.fEnabled ? 2.5f : 0.0f; +} INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ab600); @@ -180,17 +248,79 @@ float FUN_001ABE60() INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001abe70); -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ac060); +void FUN_001ac060(TIMER *ptimer) +{ + int n = STRUCT_OFFSET(ptimer, 0x270, int) - 1; + STRUCT_OFFSET(ptimer, 0x270, int) = n; + if (n <= 0) + { + int s = STRUCT_OFFSET(ptimer, 0x26c, int) - 1; + STRUCT_OFFSET(ptimer, 0x26c, int) = s; + if (s <= 0) + { + STRUCT_OFFSET(ptimer, 0x270, int) = 0; + STRUCT_OFFSET(ptimer, 0x26c, int) = 0; + } + else + { + STRUCT_OFFSET(ptimer, 0x270, int) = STRUCT_OFFSET(ptimer, 0x264, int); + } + } + + { + int tmp = STRUCT_OFFSET(ptimer, 0x26c, int) - 1; + int num = (tmp > -1 ? tmp : 0) * STRUCT_OFFSET(ptimer, 0x264, int) + STRUCT_OFFSET(ptimer, 0x270, int); + STRUCT_OFFSET(ptimer, 0x278, float) = (float)num / (float)STRUCT_OFFSET(ptimer, 0x268, int); + STRUCT_OFFSET(ptimer, 0x27c, float) = g_clock.t; + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ac0e8); -INCLUDE_ASM("asm/nonmatchings/P2/screen", PostNoteLoad__FP4NOTE); +extern CFont *D_002743D0; + +void PostNoteLoad(NOTE *pnote) +{ + CFont *pfont; + void *pv; + + PostBlotLoad(pnote); + pfont = STRUCT_OFFSET(pnote, 0x4, CFont *); + pv = STRUCT_OFFSET(pfont, 0x4c, void *); + STRUCT_OFFSET(pnote, 0x4, int) = + (*(int (**)(void *, float, float))((uint8_t *)pv + 0xc))( + (uint8_t *)pfont + STRUCT_OFFSET(pv, 0x8, short), 1.25f, 1.25f); + if (FUN_0015c188(2)) + { + STRUCT_OFFSET(pnote, 0x210, CFont **) = &D_002743D0; + *STRUCT_OFFSET(pnote, 0x210, CFont **) = FUN_0015c1c0(2); + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", SetNoteAchzDraw__FP4NOTEPc); INCLUDE_ASM("asm/nonmatchings/P2/screen", DrawNote__FP4NOTE); -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ac888); +extern CFont *D_002743F0; + +void FUN_001ac888(BLOT *pblot) +{ + CFont *pfont; + void *pv; + + PostBlotLoad(pblot); + pfont = STRUCT_OFFSET(pblot, 0x4, CFont *); + pv = STRUCT_OFFSET(pfont, 0x4c, void *); + STRUCT_OFFSET(pblot, 0x4, int) = + (*(int (**)(void *, float, float))((uint8_t *)pv + 0xc))( + (uint8_t *)pfont + STRUCT_OFFSET(pv, 0x8, short), 0.9f, 0.9f); + STRUCT_OFFSET(pblot, 0x208, unsigned int) = 0xDF7F7F7F; + if (FUN_0015c188(2)) + { + STRUCT_OFFSET(pblot, 0x210, CFont **) = &D_002743F0; + *STRUCT_OFFSET(pblot, 0x210, CFont **) = FUN_0015c1c0(2); + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ac910); @@ -198,13 +328,43 @@ INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ac990); INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ac9e0); -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001aca30); +void FUN_001aca30(BLOT *pblot) +{ + if (STRUCT_OFFSET(pblot, 0x250, int) == 3 && STRUCT_OFFSET(pblot, 0x260, int) != 0) + return; + ShowBlot(pblot); +} -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001aca68); +void FUN_001aca68(BLOT *pblot) +{ + if (STRUCT_OFFSET(pblot, 0x250, int) == 3 && STRUCT_OFFSET(pblot, 0x260, int) != 0) + { + STRUCT_OFFSET(pblot, 0x260, int) = 0; + return; + } + HideBlot(pblot); +} INCLUDE_ASM("asm/nonmatchings/P2/screen", DrawTitle__FP5TITLE); -INCLUDE_ASM("asm/nonmatchings/P2/screen", PostTotalsLoad__FP6TOTALS); +extern CFont *D_00274410; + +void PostTotalsLoad(TOTALS *ptotals) +{ + PostBlotLoad((BLOT *)ptotals); + CFont *pfont = FUN_0015c1c0(0); + void *pv = STRUCT_OFFSET(pfont, 0x4c, void *); + STRUCT_OFFSET(ptotals, 0x4, int) = + (*(int (**)(void *, float, float))((uint8_t *)pv + 0xc))( + (uint8_t *)pfont + STRUCT_OFFSET(pv, 0x8, short), 1.0f, 1.0f); + STRUCT_OFFSET(ptotals, 0x20c, float) = 0.8f; + STRUCT_OFFSET(ptotals, 0x248, float) = 0.5f; + if (FUN_0015c188(2)) + { + STRUCT_OFFSET(ptotals, 0x210, CFont **) = &D_00274410; + *STRUCT_OFFSET(ptotals, 0x210, CFont **) = FUN_0015c1c0(2); + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ace38); @@ -216,7 +376,20 @@ INCLUDE_ASM("asm/nonmatchings/P2/screen", render_level_info); INCLUDE_ASM("asm/nonmatchings/P2/screen", render_hideout_world_info); -INCLUDE_ASM("asm/nonmatchings/P2/screen", SetTotalsBlots__FP6TOTALS5BLOTS); +void SetTotalsBlots(TOTALS *ptotals, BLOTS blots) +{ + if (ptotals->fReshow && blots == BLOTS_Hidden) + { + ptotals->fReshow = 0; + SetBlotAchzDraw(ptotals, (char *)&ptotals->grflsReshow); + blots = BLOTS_Appearing; + } + + if (blots == BLOTS_Hidden) + STRUCT_OFFSET(ptotals, 0x464, int) = 0; + + SetBlotBlots(ptotals, blots); +} INCLUDE_ASM("asm/nonmatchings/P2/screen", ShowTotalsQMARK); @@ -224,22 +397,85 @@ INCLUDE_ASM("asm/nonmatchings/P2/screen", HideTotalsQMARK); INCLUDE_ASM("asm/nonmatchings/P2/screen", DrawTotals__FP6TOTALS); -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ad6a8); +extern char D_0024CEE0[]; + +void FUN_001ad6a8(BLOT *pblot) +{ + PostBlotLoad(pblot); + CFont *pfont = FUN_0015c1c0(2); + void *pv = STRUCT_OFFSET(pfont, 0x4c, void *); + STRUCT_OFFSET(pblot, 0x4, int) = + (*(int (**)(void *, float, float))((uint8_t *)pv + 0xc))( + (uint8_t *)pfont + STRUCT_OFFSET(pv, 0x8, short), 1.0f, 1.0f); + ((VTBLOT *)pblot->pvtblot)->pfnSetBlotAchzDraw(pblot, D_0024CEE0); + STRUCT_OFFSET(pblot, 0x260, int) = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ad718); INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ad7b0); -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ad940); +void FUN_001ad940(BLOT *pblot) +{ + PostBlotLoad(pblot); + pblot->dtDisappear = 0.5f; +} INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ad970); -INCLUDE_ASM("asm/nonmatchings/P2/screen", DrawLetterbox__FP9LETTERBOX); +void DrawLetterbox(LETTERBOX *pletterbox) +{ + float u = pletterbox->uOn * 66.400009f; + float v = 492.80002f - u; + + g_gifs.AddPrimPack(6, 7, 0x44441EE); + g_gifs.PackAD(0x47, 0x30000); + g_gifs.PackAD(0x42, 0x44); + g_gifs.PackRGBA(0x80000000); + g_gifs.PackXYZF(0x6C00, 0x7900, 0xFFFFFF0, 0); + g_gifs.PackXYZF(0x9400, (int)((u * 0.45454547f + 1936.0f) * 16.0f), 0xFFFFFF0, 0); + g_gifs.PackXYZF(0x6C00, (int)((v * 0.45454547f + 1936.0f) * 16.0f), 0xFFFFFF0, 0); + g_gifs.PackXYZF(0x9400, 0x8700, 0xFFFFFF0, 0); +} + +extern float D_00274448; +extern float D_0027444C; +extern CFont *D_00274450; +extern char D_0024CEF0[]; -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001adc60); +void FUN_001adc60(BLOT *pblot) +{ + PostBlotLoad(pblot); + CFont *pfont = STRUCT_OFFSET(pblot, 0x4, CFont *); + void *pv = STRUCT_OFFSET(pfont, 0x4c, void *); + STRUCT_OFFSET(pblot, 0x4, int) = + (*(int (**)(void *, float, float))((uint8_t *)pv + 0xc))( + (uint8_t *)pfont + STRUCT_OFFSET(pv, 0x8, short), D_00274448, D_0027444C); + if (FUN_0015c1c0(2)) + { + STRUCT_OFFSET(pblot, 0x210, CFont **) = &D_00274450; + *STRUCT_OFFSET(pblot, 0x210, CFont **) = FUN_0015c1c0(2); + } + + SHD *pshd = PshdFindShader((OID)0x493); + STRUCT_OFFSET(pblot, 0x260, SHD *) = pshd; + if (pshd != NULL) + { + ResizeBlot(pblot, 366.75f, 165.75f); + } + else + { + ((void (*)(BLOT *, char *))((VTBLOT *)pblot->pvtblot)->pfnSetBlotAchzDraw)(pblot, D_0024CEF0); + } +} INCLUDE_ASM("asm/nonmatchings/P2/screen", DrawLogo__FP4LOGO); +extern float D_0027446C; +extern float D_00274470; +extern CFont *D_00274488; +extern void *D_00269988; + INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001adf28); INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001adff0); @@ -256,9 +492,32 @@ INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ae510); INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ae5e0); -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ae758); +extern float D_002744AC; -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ae7f8); +void FUN_001ae758(BLOT *pblot) +{ + char achz[2]; + + PostBlotLoad(pblot); + SetBlotDtAppear(pblot, 0.25f); + SetBlotDtDisappear(pblot, 0.25f); + SetBlotDtVisible(pblot, 0.0f); + pblot->pfont = FUN_0015c1c0(1); + SetBlotFontScale(pblot, D_002744AC); + + achz[0] = FUN_001aea08(); + achz[1] = 0; + ((void (*)(BLOT *, char *))((VTBLOT *)pblot->pvtblot)->pfnSetBlotAchzDraw)(pblot, achz); + pblot->achzDraw[0] = 0; +} + +void FUN_001ae7f8(CTR *pctr, BLOTS blots) +{ + if (blots == BLOTS_Hidden) + pctr->nDisplay = 0; + + SetBlotBlots(pctr, blots); +} INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001ae820); @@ -269,4 +528,7 @@ INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001aea70); JUNK_WORD(0xE48C0000); JUNK_WORD(0xE48C0008); -INCLUDE_ASM("asm/nonmatchings/P2/screen", FUN_001aec90); +void FUN_001aec90(void) +{ + FUN_001aea70(1, 0xFFFF); +} diff --git a/src/P2/sensor.c b/src/P2/sensor.c index f385fb4ec..c3cd5a9c6 100644 --- a/src/P2/sensor.c +++ b/src/P2/sensor.c @@ -3,6 +3,7 @@ #include #include #include +#include void InitSensor(SENSOR *psensor) { @@ -59,77 +60,68 @@ INCLUDE_ASM("asm/nonmatchings/P2/sensor", FIgnoreSensorObject__FP6SENSORP2SO); INCLUDE_ASM("asm/nonmatchings/P2/sensor", FOnlySensorTriggerObject__FP6SENSORP2SO); -INCLUDE_ASM("asm/nonmatchings/P2/sensor", PauseSensor__FP6SENSOR); +void PauseSensor(SENSOR *psensor) +{ + ASEGA *pasega = PasegaFindAloNearest((ALO *)psensor); + if (pasega) + { + STRUCT_OFFSET(psensor, 0x5CC, float) = STRUCT_OFFSET(pasega, 0x18, float); + STRUCT_OFFSET(pasega, 0x18, int) = 0; + STRUCT_OFFSET(psensor, 0x5C8, ASEGA *) = pasega; + } +} INCLUDE_ASM("asm/nonmatchings/P2/sensor", UpdateSensor__FP6SENSORf); -INCLUDE_ASM("asm/nonmatchings/P2/sensor", AddSensorTriggerObject__FP6SENSOR3OID); - #ifdef SKIP_ASM -/** - * @todo 100% matched but sensor struct offsets are wrong. - */ void AddSensorTriggerObject(SENSOR *psensor, OID oid) { - uint ccur = psensor->ctriggerObjects; - if (ccur >= 4) - return; + uint ccur = psensor->ctriggerObjects; + if (ccur >= 4) + return; - psensor->atriggerObjects[ccur] = oid; - psensor->ctriggerObjects = ccur + 1; + psensor->atriggerObjects[ccur] = oid; + psensor->ctriggerObjects = ccur + 1; } -#endif - -INCLUDE_ASM("asm/nonmatchings/P2/sensor", AddSensorNoTriggerObject__FP6SENSOR3OID); - #ifdef SKIP_ASM -/** - * @todo 100% matched but sensor struct offsets are wrong. - */ void AddSensorNoTriggerObject(SENSOR *psensor, OID oid) { - uint ccur = psensor->cnoTriggerObjects; - if (ccur >= 4) - return; + uint ccur = psensor->cnoTriggerObjects; + if (ccur >= 4) + return; - psensor->anoTriggerObjects[ccur] = oid; - psensor->cnoTriggerObjects = ccur + 1; + psensor->anoTriggerObjects[ccur] = oid; + psensor->cnoTriggerObjects = ccur + 1; } -#endif - -INCLUDE_ASM("asm/nonmatchings/P2/sensor", AddSensorTriggerClass__FP6SENSOR3CID); - #ifdef SKIP_ASM -/** - * @todo 100% matched but sensor struct offsets are wrong. - */ void AddSensorTriggerClass(SENSOR *psensor, CID cid) { - uint ccur = psensor->ctriggerClasses; - if (ccur >= 4) - return; + uint ccur = psensor->ctriggerClasses; + if (ccur >= 4) + return; - psensor->atriggerClasses[ccur] = cid; - psensor->ctriggerClasses = ccur + 1; + psensor->atriggerClasses[ccur] = cid; + psensor->ctriggerClasses = ccur + 1; } -#endif - -INCLUDE_ASM("asm/nonmatchings/P2/sensor", AddSensorNoTriggerClass__FP6SENSOR3CID); - #ifdef SKIP_ASM -/** - * @todo 100% matched but sensor struct offsets are wrong. - */ void AddSensorNoTriggerClass(SENSOR *psensor, CID cid) { - uint ccur = psensor->cnoTriggerClasses; - if (ccur >= 4) - return; + uint ccur = psensor->cnoTriggerClasses; + if (ccur >= 4) + return; - psensor->anoTriggerClasses[ccur] = cid; - psensor->cnoTriggerClasses = ccur + 1; + psensor->anoTriggerClasses[ccur] = cid; + psensor->cnoTriggerClasses = ccur + 1; +} +void InitLasen(LASEN *plasen) +{ + InitSensor(plasen); + STRUCT_OFFSET(plasen, 0xB04, float) = 1.0f; } -#endif -INCLUDE_ASM("asm/nonmatchings/P2/sensor", InitLasen__FP5LASEN); +void LoadLasenFromBrx(LASEN *plasen, CBinaryInputStream *pbis) +{ + extern SNIP D_002744B8[2]; -INCLUDE_ASM("asm/nonmatchings/P2/sensor", LoadLasenFromBrx__FP5LASENP18CBinaryInputStream); + LoadSoFromBrx(plasen, pbis); + SnipAloObjects(plasen, 2, D_002744B8); +} INCLUDE_ASM("asm/nonmatchings/P2/sensor", BindLasen__FP5LASEN); @@ -139,7 +131,28 @@ INCLUDE_ASM("asm/nonmatchings/P2/sensor", UpdateBusyLasenSenseTimes__Fv); INCLUDE_ASM("asm/nonmatchings/P2/sensor", UpdateLasen__FP5LASENf); -INCLUDE_ASM("asm/nonmatchings/P2/sensor", FreezeLasen__FP5LASENi); +extern int D_002744D0; + +void FreezeLasen(LASEN *plasen, int fFreeze) +{ + FreezeSo(plasen, fFreeze); + + if (fFreeze) + { + if (STRUCT_OFFSET(plasen, 0xAF8, int)) + { + RemoveDlEntry((DL *)((char *)plasen->psw + 0x1ca8), plasen); + STRUCT_OFFSET(plasen, 0xAF8, int) = 0; + } + } + else + { + AppendDlEntry((DL *)((char *)plasen->psw + 0x1ca8), plasen); + STRUCT_OFFSET(plasen, 0xAF8, int) = 1; + } + + D_002744D0 = 1; +} INCLUDE_ASM("asm/nonmatchings/P2/sensor", RenderLasenSelf__FP5LASENP2CMP2RO); @@ -193,13 +206,49 @@ INCLUDE_ASM("asm/nonmatchings/P2/sensor", SetLasenSensors__FP5LASEN7SENSORS); INCLUDE_ASM("asm/nonmatchings/P2/sensor", SCalcLasenShapeExtent__FP5LASENP5LBEAM); -INCLUDE_ASM("asm/nonmatchings/P2/sensor", RetractLasen__FP5LASENf); +void RetractLasen(LASEN *plasen, float dtRetract) +{ + STRUCT_OFFSET(plasen, 0xB08, float) = -1.0f / dtRetract; +} -INCLUDE_ASM("asm/nonmatchings/P2/sensor", ExtendLasen__FP5LASENf); +void ExtendLasen(LASEN *plasen, float dtExpand) +{ + STRUCT_OFFSET(plasen, 0xB08, float) = 1.0f / dtExpand; +} -INCLUDE_ASM("asm/nonmatchings/P2/sensor", InitCamsen__FP6CAMSEN); +void InitCamsen(CAMSEN *pcamsen) +{ + InitSensor(pcamsen); + STRUCT_OFFSET(pcamsen, 0x5D8, int) = -1; +} + +extern SNIP D_002744D8[2]; + +void PostCamsenLoad(CAMSEN *pcamsen) +{ + void *pvt; + void (*pfn)(CAMSEN *, int); + + PostAloLoad(pcamsen); + SnipAloObjects(pcamsen, 2, D_002744D8); + + if (STRUCT_OFFSET(pcamsen, 0x5d0, int) == 0) + STRUCT_OFFSET(pcamsen, 0x5d0, int) = (int)pcamsen; -INCLUDE_ASM("asm/nonmatchings/P2/sensor", PostCamsenLoad__FP6CAMSEN); + if (STRUCT_OFFSET(pcamsen, 0x5d4, int) == 0) + STRUCT_OFFSET(pcamsen, 0x5d4, int) = STRUCT_OFFSET(pcamsen->psw, 0x1d14, int); + + if (STRUCT_OFFSET(pcamsen, 0x200, void *) != NULL) + STRUCT_OFFSET(STRUCT_OFFSET(pcamsen, 0x200, void *), 0x44, int) = 0; + + STRUCT_OFFSET(pcamsen, 0x538, ulong) |= ((ulong)0x8000) << 28; + + SetSoConstraints(pcamsen, CT_Locked, NULL, CT_Locked, NULL); + + pvt = STRUCT_OFFSET(pcamsen, 0x0, void *); + pfn = (void (*)(CAMSEN *, int))STRUCT_OFFSET(pvt, 0x144, void *); + pfn(pcamsen, STRUCT_OFFSET(pcamsen, 0x560, int)); +} INCLUDE_ASM("asm/nonmatchings/P2/sensor", UpdateCamsen__FP6CAMSENf); diff --git a/src/P2/shadow.c b/src/P2/shadow.c index 34cff6a8a..e55dec474 100644 --- a/src/P2/shadow.c +++ b/src/P2/shadow.c @@ -1,10 +1,40 @@ #include #include +#include #include INCLUDE_ASM("asm/nonmatchings/P2/shadow", InitShadow__FP6SHADOW); +extern int D_002626D0; +extern SUR D_0027DC20[]; + INCLUDE_ASM("asm/nonmatchings/P2/shadow", PostShadowLoad__FP6SHADOW); +#ifdef SKIP_ASM +void PostShadowLoad(SHADOW *pshadow) +{ + if (pshadow->pshd == NULL) + { + SetShadowShader(pshadow, OID_shd_stock_shadow); + } + + if (!FShadowRadiusSet(pshadow)) + { + SetShadowNearRadius(pshadow, 100.0f); + SetShadowFarRadius(pshadow, 400.0f); + } + + if (!(pshadow->pshd->grfzon & 0x10000000)) + { + if (D_002626D0 < 0x4000) + { + SUR *psur = &D_0027DC20[D_002626D0]; + D_002626D0 += 1; + STRUCT_OFFSET(pshadow, 0x2D0, SUR *) = psur; + memset(psur, 0, sizeof(SUR)); + } + } +} +#endif // SKIP_ASM void InvalidateShadowVifs(SHADOW *pshadow) { @@ -76,11 +106,21 @@ void SetShadowConeAngle(SHADOW *pshadow, float degConeAngle) InvalidateShadowVifs(pshadow); } -INCLUDE_ASM("asm/nonmatchings/P2/shadow", SetShadowFrustrumUp__FP6SHADOWP6VECTOR); +void SetShadowFrustrumUp(SHADOW *pshadow, VECTOR *pvecUp) +{ + STRUCT_OFFSET(pshadow, 0x30, VU_VECTOR) = *(VU_VECTOR *)pvecUp; + InvalidateShadowVifs(pshadow); +} INCLUDE_ASM("asm/nonmatchings/P2/shadow", FShadowValid__FP6SHADOWi); -INCLUDE_ASM("asm/nonmatchings/P2/shadow", FFilterFastShadows__FPvP2SO); +int FFilterFastShadows(void *pv, SO *pso) +{ + int fFast = 0; + if (!(STRUCT_OFFSET(pso, 0x538, unsigned long long) & ((unsigned long long)0x8000 << 28))) + fFast = STRUCT_OFFSET(pso, 0x410, int) != 0; + return fFast; +} INCLUDE_ASM("asm/nonmatchings/P2/shadow", UpdateShadow__FP6SHADOWf); diff --git a/src/P2/shd.c b/src/P2/shd.c index 0220c56e4..fc6c14892 100644 --- a/src/P2/shd.c +++ b/src/P2/shd.c @@ -1,8 +1,11 @@ #include #include +#include extern GRFZON g_grfzonShaders; extern byte *g_pbBulkData; +extern GSB D_002626D8; +extern int D_002626CC; INCLUDE_ASM("asm/nonmatchings/P2/shd", Tex0FromTexIframeCtk__FP3TEXi3CTK); @@ -40,7 +43,20 @@ void UploadPermShaders() g_grfzonShaders = 0; } -INCLUDE_ASM("asm/nonmatchings/P2/shd", PropagateShaders__Fi); +void PropagateShaders(GRFZON grfzonCamera) +{ + PropagateSais(); + if (grfzonCamera == g_grfzonShaders) + return; + + ResetGsb(&D_002626D8); + UploadBitmaps(grfzonCamera, &D_002626D8); + FillShaders(grfzonCamera); + PropagateSurs(); + PropagateBlipgShaders(grfzonCamera); + D_002626CC = 2; + g_grfzonShaders = grfzonCamera; +} INCLUDE_ASM("asm/nonmatchings/P2/shd", FillShaders__Fi); @@ -65,7 +81,34 @@ INCLUDE_ASM("asm/nonmatchings/P2/shd", PshdFindShader__F3OID); INCLUDE_ASM("asm/nonmatchings/P2/shd", SetSaiIframe__FP3SAIi); -INCLUDE_ASM("asm/nonmatchings/P2/shd", SetSaiDuDv__FP3SAIff); +extern SAI *g_psaiUpdate; +extern SAI *g_psaiUpdateTail; + +void SetSaiDuDv(SAI *psai, float du, float dv) +{ + if (!STRUCT_OFFSET(psai, 0x4, int)) + return; + + if (STRUCT_OFFSET(psai, 0xc, float) == du && + STRUCT_OFFSET(psai, 0x10, float) == dv) + return; + + SAI *psaiNext = STRUCT_OFFSET(psai, 0x18, SAI *); + STRUCT_OFFSET(psai, 0xc, float) = du; + STRUCT_OFFSET(psai, 0x10, float) = dv; + + if (psaiNext != 0) + return; + + if (psai == g_psaiUpdateTail) + return; + + if (g_psaiUpdateTail == 0) + g_psaiUpdateTail = psai; + + STRUCT_OFFSET(psai, 0x18, SAI *) = g_psaiUpdate; + g_psaiUpdate = psai; +} INCLUDE_ASM("asm/nonmatchings/P2/shd", PropagateSais__Fv); diff --git a/src/P2/shdanim.c b/src/P2/shdanim.c index c31d0a112..07a6d15f8 100644 --- a/src/P2/shdanim.c +++ b/src/P2/shdanim.c @@ -6,6 +6,7 @@ #include #include #include +#include #define TWO_PI 6.2831855f #define INV_TWO_PI 0.15915494f @@ -420,7 +421,12 @@ void InitLooker(LOOKER *plooker, SAAF *psaaf) plooker->sai.grfsai = (plooker->sai.grfsai & ~1) | 2; } -INCLUDE_ASM("asm/nonmatchings/P2/shdanim", SetLookerSgvr__FP6LOOKERP4SGVRP7GLOBSETP4GLOBP7SUBGLOB); +void SetLookerSgvr(LOOKER *plooker, SGVR *psgvr, GLOBSET *pglobset, GLOB *pglob, SUBGLOB *psubglob) +{ + STRUCT_OFFSET(psgvr, 0x0, float *) = &STRUCT_OFFSET(plooker, 0x44, float); + STRUCT_OFFSET(psgvr, 0x4, float *) = &STRUCT_OFFSET(plooker, 0x4C, float); + STRUCT_OFFSET(psgvr, 0x8, float *) = &STRUCT_OFFSET(plooker, 0x48, float); +} void SetVecPosad(VECTOR *pvec, POSAD *pposad) { diff --git a/src/P2/sky.c b/src/P2/sky.c index 0956156fb..76c19dd7a 100644 --- a/src/P2/sky.c +++ b/src/P2/sky.c @@ -1,5 +1,22 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/sky", PostSkyLoad__FP3SKY); -INCLUDE_ASM("asm/nonmatchings/P2/sky", UpdateSky__FP3SKYf); +void UpdateSky(SKY *psky, float dt) +{ + VU_VECTOR vec; + void (*pfn)(SKY *, VU_VECTOR *); + + UpdateAlo((ALO *)psky, dt); + + vec = STRUCT_OFFSET(g_pcm, 0x40, VU_VECTOR); + if (STRUCT_OFFSET(psky, 0x2D0, int) == 0) + { + STRUCT_OFFSET(&vec, 0x8, float) = STRUCT_OFFSET(psky, 0x148, float); + } + + pfn = (void (*)(SKY *, VU_VECTOR *))STRUCT_OFFSET(STRUCT_OFFSET(psky, 0x0, char *), 0x84, void *); + pfn(psky, &vec); +} diff --git a/src/P2/sm.c b/src/P2/sm.c index 84a3b3b8e..d88c094fb 100644 --- a/src/P2/sm.c +++ b/src/P2/sm.c @@ -1,5 +1,7 @@ #include #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/sm", LoadSmFromBrx__FP2SMP18CBinaryInputStream); @@ -20,11 +22,32 @@ INCLUDE_ASM("asm/nonmatchings/P2/sm", PsmaFindSm__FP2SMP3ALO); INCLUDE_ASM("asm/nonmatchings/P2/sm", IsmsFindSmOptional__FP2SM3OID); -INCLUDE_ASM("asm/nonmatchings/P2/sm", IsmsFindSmRequired__FP2SM3OID); +int IsmsFindSmRequired(SM *psm, OID oid) +{ + int isms = IsmsFindSmOptional(psm, oid); + return isms >= 0 ? isms : 0; +} -INCLUDE_ASM("asm/nonmatchings/P2/sm", OidFromSmIsms__FP2SMi); +OID OidFromSmIsms(SM *psm, int isms) +{ + return psm->asms[isms].oid; +} -INCLUDE_ASM("asm/nonmatchings/P2/sm", RetractSma__FP3SMA); +void RetractSma(SMA *psma) +{ + SM *psm = psma->psm; + if (psma->pasegaCur) + { + RetractAsega(psma->pasegaCur); + psma->pasegaCur = 0; + } + FreeSwMqList(psma->psm->psw, psma->pmqFirst); + psma->pmqFirst = 0; + RemoveDlEntry(&psma->psm->dlSma, psma); + RemoveDlEntry(&STRUCT_OFFSET(psma->psm->psw, 0x1B94, DL), psma); + FreeSlotheapPv(&STRUCT_OFFSET(psma->psm->psw, 0x1B88, SLOTHEAP), psma); + HandleLoSpliceEvent(psm, 0x12, 0, 0); +} INCLUDE_ASM("asm/nonmatchings/P2/sm", SetSmaGoal__FP3SMA3OID); @@ -40,14 +63,85 @@ INCLUDE_ASM("asm/nonmatchings/P2/sm", SeekSma__FP3SMA3OID); INCLUDE_ASM("asm/nonmatchings/P2/sm", ChooseSmaTransition__FP3SMA); -INCLUDE_ASM("asm/nonmatchings/P2/sm", EndSmaTransition__FP3SMA); +void EndSmaTransition(SMA *psma) +{ + int cur = STRUCT_OFFSET(psma, 0x28, int); + int next = STRUCT_OFFSET(psma, 0x2C, int); + NotifySmaSpliceOnEnterState(psma, cur, next); + int nextCopy = STRUCT_OFFSET(psma, 0x2C, int); + STRUCT_OFFSET(psma, 0x2C, int) = -1; + STRUCT_OFFSET(psma, 0x28, int) = nextCopy; +} + +void HandleSmaMessage(SMA *psma, MSGID msgid, void *pv) +{ + if (msgid == MSGID_asega_limit && (ASEGA*)pv == psma->pasegaCur) { + EndSmaTransition(psma); + ChooseSmaTransition(psma); + } +} + +void SkipSma(SMA *psma, float dtSkip) +{ + ASEGA *pasega; + + extern void SeekAsega(ASEGA *pasega, SEEK seek, float t, float svt); -INCLUDE_ASM("asm/nonmatchings/P2/sm", HandleSmaMessage__FP3SMA5MSGIDPv); + while ((pasega = psma->pasegaCur) != NULL) + { + float diff = STRUCT_OFFSET(STRUCT_OFFSET(pasega, 0x8, uint8_t *), 0x34, float) - STRUCT_OFFSET(pasega, 0x14, float); + if (dtSkip < diff) + { + SeekAsega(pasega, SEEK_Current, dtSkip, 1.0f); + break; + } + dtSkip -= diff; + EndSmaTransition(psma); + ChooseSmaTransition(psma); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sm", SkipSma__FP3SMAf); +void SendSmaMessage(SMA *psma, MSGID msgid, void *pv) +{ + ALO *paloRoot = psma->paloRoot; + if (paloRoot) + { + paloRoot->pvtlo->pfnSendLoMessage(paloRoot, msgid, pv); + } + + MQ *pmq = psma->pmqFirst; + while (pmq) + { + PFNMQ pfnmq = pmq->pfnmq; + void *pmqContext = pmq->pvContext; -INCLUDE_ASM("asm/nonmatchings/P2/sm", SendSmaMessage__FP3SMA5MSGIDPv); + pmq = pmq->pmqNext; + + pfnmq(pmqContext, msgid, pv); + } +} INCLUDE_ASM("asm/nonmatchings/P2/sm", FUN_001b6df8); -INCLUDE_ASM("asm/nonmatchings/P2/sm", NotifySmaSpliceOnEnterState__FP3SMAii); +void NotifySmaSpliceOnEnterState(SMA *psma, int ismsFrom, int ismsTo) +{ + int oidFrom; + int oidTo; + void *apv[3]; + + if (ismsFrom >= 0) + oidFrom = psma->psm->asms[ismsFrom].oid; + else + oidFrom = -1; + + if (ismsTo >= 0) + oidTo = psma->psm->asms[ismsTo].oid; + else + oidTo = -1; + + apv[0] = &psma; + apv[1] = &oidFrom; + apv[2] = &oidTo; + + HandleLoSpliceEvent(psma->psm, 0xE, 3, apv); +} diff --git a/src/P2/smartguard.c b/src/P2/smartguard.c index fcaa9aba5..5a36a3705 100644 --- a/src/P2/smartguard.c +++ b/src/P2/smartguard.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/smartguard", InitSmartguard__FP10SMARTGUARD); @@ -13,11 +15,83 @@ void UseSmartguardFlashlightTarget(SMARTGUARD *psmartguard, SGS sgs, OID oidTarg mpsgssgft[sgs].oidTarget = oidTarget; } -INCLUDE_ASM("asm/nonmatchings/P2/smartguard", FUN_001B7100__FP10SMARTGUARDi); +void FUN_001B7100(SMARTGUARD *p, int val) +{ + int c = STRUCT_OFFSET(p, 0xcd4, int); + if ((unsigned int)c < 4) + { + long long *a = &STRUCT_OFFSET(p, 0xcd8, long long); + *(int *)&a[c] = val; + STRUCT_OFFSET(p, 0xcd4, int) = c + 1; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/smartguard", PostSmartguardLoad__FP10SMARTGUARD); +void PostSmartguardLoad(SMARTGUARD *psmartguard) +{ + int i; + int *poid; + int oidNearest; + int coid; -INCLUDE_ASM("asm/nonmatchings/P2/smartguard", FFilterSmartguardDetect__FP10SMARTGUARDP2SO); + PostStepguardLoad(psmartguard); + PostSmartguardLoadFlashlight(psmartguard); + + oidNearest = STRUCT_OFFSET(psmartguard, 0xc28, int); + if (oidNearest != -1) + { + STRUCT_OFFSET(psmartguard, 0xc2c, LO *) = + PloFindSwNearest(psmartguard->psw, (OID)oidNearest, (LO *)psmartguard); + } + + coid = STRUCT_OFFSET(psmartguard, 0xcd4, int); + if (coid > 0) + { + i = 0; + poid = &STRUCT_OFFSET(psmartguard, 0xcd8, int); + do + { + poid[1] = (int)PloFindSwObject(psmartguard->psw, 0x104, (OID)*poid, (LO *)psmartguard); + i++; + poid += 2; + } while (i < STRUCT_OFFSET(psmartguard, 0xcd4, int)); + } +} + +int FFilterSmartguardDetect(SMARTGUARD *psmartguard, SO *pso) +{ + int i, c; + + if (STRUCT_OFFSET(pso, 0x538, long long) & 0x80000000000LL) + { + return 0; + } + + if (FIsBasicDerivedFrom(pso->paloRoot, CID_PO)) + { + return 0; + } + + if (FIsBasicDerivedFrom(pso->paloRoot, CID_UBV)) + { + return 0; + } + + c = STRUCT_OFFSET(psmartguard, 0xcd4, int); + if (c > 0) + { + i = 0; + do + { + if (FFindLoParent(pso, STRUCT_OFFSET(psmartguard, 0xcdc + i * 8, ALO *))) + { + return 0; + } + i++; + } while (i < STRUCT_OFFSET(psmartguard, 0xcd4, int)); + } + + return 1; +} INCLUDE_ASM("asm/nonmatchings/P2/smartguard", FDetectSmartguard__FP10SMARTGUARD); @@ -31,9 +105,41 @@ INCLUDE_ASM("asm/nonmatchings/P2/smartguard", UpdateSmartguardFlashlight__FP10SM INCLUDE_ASM("asm/nonmatchings/P2/smartguard", OnSmartguardEnteringSgs__FP10SMARTGUARD3SGSP4ASEG); -INCLUDE_ASM("asm/nonmatchings/P2/smartguard", FCanSmartguardAttack__FP10SMARTGUARD); +int FCanSmartguardAttack(SMARTGUARD *psmartguard) +{ + if (!FCanStepguardAttack((STEPGUARD *)psmartguard)) + { + return 0; + } + + void *pvt = STRUCT_OFFSET(psmartguard, 0x0, void *); + int (*fn)(SMARTGUARD *) = (int (*)(SMARTGUARD *))STRUCT_OFFSET(pvt, 0x16C, void *); + return fn(psmartguard); +} + +SGAS SgasGetSmartguard(SMARTGUARD *psmartguard) +{ + SGS sgs = STRUCT_OFFSET(psmartguard, 0x724, SGS); + + if (sgs == SGS_Dying) + { + return SGAS_Yes; + } + + if (sgs == SGS_SearchIdle) + { + if (STRUCT_OFFSET(psmartguard, 0xCC4, int) > 0) + { + if (5.0f < g_clock.t - STRUCT_OFFSET(psmartguard, 0x728, float)) + { + return SGAS_Force; + } + return SGAS_Yes; + } + } -INCLUDE_ASM("asm/nonmatchings/P2/smartguard", SgasGetSmartguard__FP10SMARTGUARD); + return SGAS_No; +} void HandleSmartguardMessage(SMARTGUARD *psmartguard, MSGID msgid, void *pv) { diff --git a/src/P2/so.c b/src/P2/so.c index 5f82b8745..263be8101 100644 --- a/src/P2/so.c +++ b/src/P2/so.c @@ -1,93 +1,71 @@ #include #include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/so", InitSo__FP2SO); void OnSoAdd(SO *pso) { SW *psw = pso->psw; - psw->cpsoAll++; + void (*pfn)(SO *); - if (!pso->paloParent) + psw->cpsoAll = psw->cpsoAll + 1; + if (pso->paloParent == NULL) { AddSwAaobrObject(psw, pso); - STRUCT_OFFSET(pso, 0x480, OXA *) = PoxaAllocSw(psw, pso); // pso->poxa + STRUCT_OFFSET(pso, 0x480, OXA *) = PoxaAllocSw(psw, pso); RecalcSwOxfFilterForObject(psw, pso); - psw->cpsoRoot++; + psw->cpsoRoot = psw->cpsoRoot + 1; AppendDlEntry(&psw->dlRoot, pso); } - OnAloAdd(pso); EnableSoPhys(pso, 1); - - pso->pvtso->pfnUpdateSoPosWorldPrev(pso); - - // pso->bspcCamera.absp - if ((STRUCT_OFFSET(pso, 0x538, ulong) & 0x40000000000000) == 0) + pfn = (void (*)(SO *))STRUCT_OFFSET(STRUCT_OFFSET(pso, 0x0, void *), 0x120, void *); + pfn(pso); + if ((STRUCT_OFFSET(pso, 0x538, uint64_t) & ((uint64_t)0x8000 << 39)) == 0) // locked, bit 54 { - RecalcSoLocked((SO *)pso->paloRoot); + RecalcSoLocked(STRUCT_OFFSET(pso, 0x50, SO *)); // pso->paloRoot } else { RecalcSoLocked(pso); } - RebuildSoPhysHook(pso); } -void OnSoRemove(SO *pso) -{ - SW *psw = pso->psw; - ALO *paloRoot = pso->paloRoot; +// Kept wrapped: unwrapping mis-sizes the still-asm TranslateSoToPosSafe and fails the checksum. +INCLUDE_ASM("asm/nonmatchings/P2/so", OnSoRemove__FP2SO); - EnableSoPhys(pso, 0); - OnAloRemove(pso); - psw->cpsoAll--; +void EnableSoPhys(SO *pso, int fPhys) +{ + uint64_t grfso; + SO *psoRoot; + void (*pfn)(SO *); - if (!pso->paloParent) + if (fPhys == ((STRUCT_OFFSET(pso, 0x538, uint64_t) >> 50) & 1)) { - RemoveSwAaobrObject(psw, pso); - FreeSwPoxa(psw, STRUCT_OFFSET(pso, 0x480, OXA *)); // pso->poxa - psw->cpsoRoot--; - RemoveDlEntry(&psw->dlRoot, pso); + return; } - - STSO *pstso = STRUCT_OFFSET(pso, 0x540, STSO *); // pso->pstso - FreeSwStsoList(psw, pstso); - STRUCT_OFFSET(pso, 0x540, STSO *) = NULL; // pso->pstso - - if ((STRUCT_OFFSET(pso, 0x538, ulong) & 0x40000000000000) == 0 && paloRoot != pso) + if (fPhys) { - RecalcSoLocked((SO *)paloRoot); + // append to the hierarchy root's dlPhys (root SO* at 0x50, DL at 0x2D8) + AppendDlEntry(&STRUCT_OFFSET(STRUCT_OFFSET(pso, 0x50, SO *), 0x2D8, DL), pso); } -} - -/** - * @todo 92.19% match. - */ -INCLUDE_ASM("asm/nonmatchings/P2/so", EnableSoPhys__FP2SOi); -#ifdef SKIP_ASM -void EnableSoPhys(SO *pso, int fPhys) -{ - if (fPhys != ((STRUCT_OFFSET(pso, 0x538, ulong)) >> 0x32 & 0x01)) + else { - if (fPhys) - { - AppendDlEntry(STRUCT_OFFSET(&pso->paloRoot[1], 0x08, DL *), pso); - } - else - { - RemoveDlEntry(STRUCT_OFFSET(&pso->paloRoot[1], 0x08, DL *), pso); - } - - ulong absp = STRUCT_OFFSET(pso, 0x538, ulong); - SW *psw = pso->psw; - STRUCT_OFFSET(pso, 0x538, ulong) = (absp & 0xfffbffffffffffff) | ((fPhys & 1) << 0x10); - InvalidateSwXpForObject(psw, pso, 7); - pso->pvtso->pfnUpdateSoBounds(pso); + RemoveDlEntry(&STRUCT_OFFSET(STRUCT_OFFSET(pso, 0x50, SO *), 0x2D8, DL), pso); } + grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)1 << 50); // fPhys, grfso bit 50 + grfso |= (uint64_t)(fPhys & 1) << 50; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; + InvalidateSwXpForObject(pso->psw, pso, 7); + psoRoot = STRUCT_OFFSET(pso, 0x50, SO *); + pfn = (void (*)(SO *))STRUCT_OFFSET(STRUCT_OFFSET(psoRoot, 0x0, void *), 0xD8, void *); + pfn(psoRoot); } -#endif INCLUDE_ASM("asm/nonmatchings/P2/so", DisplaceSo__FP2SOi); @@ -101,9 +79,33 @@ INCLUDE_ASM("asm/nonmatchings/P2/so", UpdateSoBounds__FP2SO); INCLUDE_ASM("asm/nonmatchings/P2/so", UpdateGeomWorld__FP4GEOMT0G9VU_VECTORP7MATRIX3); -INCLUDE_ASM("asm/nonmatchings/P2/so", UpdateSoXfWorldHierarchy__FP2SO); +void UpdateSoXfWorldHierarchy(SO *pso) +{ + UpdateAloXfWorldHierarchy(pso); + UpdateGeomWorld( + &STRUCT_OFFSET(pso, 0x380, GEOM), + &STRUCT_OFFSET(pso, 0x3A4, GEOM), + STRUCT_OFFSET(pso, 0x140, VU_VECTOR), + &STRUCT_OFFSET(pso, 0x110, MATRIX3)); + UpdateGeomWorld( + &STRUCT_OFFSET(pso, 0x4E8, GEOM), + &STRUCT_OFFSET(pso, 0x50C, GEOM), + STRUCT_OFFSET(pso, 0x140, VU_VECTOR), + &STRUCT_OFFSET(pso, 0x110, MATRIX3)); +} -INCLUDE_ASM("asm/nonmatchings/P2/so", UpdateSoXfWorld__FP2SO); +void UpdateSoXfWorld(SO *pso) +{ + SO *psoRoot; + void (*pfn)(SO *); + + UpdateAloXfWorld(pso); + psoRoot = STRUCT_OFFSET(pso, 0x50, SO *); // paloRoot + pfn = (void (*)(SO *))STRUCT_OFFSET(STRUCT_OFFSET(psoRoot, 0x0, void *), 0xD8, void *); + pfn(psoRoot); + InvalidateSwXpForObject(pso->psw, pso, 7); + InvalidateSwAaox(pso->psw); +} INCLUDE_ASM("asm/nonmatchings/P2/so", FIgnoreSoIntersection__FP2SOT0); @@ -121,7 +123,30 @@ INCLUDE_ASM("asm/nonmatchings/P2/so", AccelSoTowardPosSpring__FP2SOP6VECTORP3CLQ INCLUDE_ASM("asm/nonmatchings/P2/so", AccelSoTowardMatSpring__FP2SOP7MATRIX3P3CLQP6VECTORT2f); -INCLUDE_ASM("asm/nonmatchings/P2/so", PresetSoAccel__FP2SOf); +void PresetSoAccel(SO *pso, float dt) +{ + VECTOR v; + XA *pxa; + + if (pso->paloParent == NULL) + { + if ((STRUCT_OFFSET(pso, 0x538, uint64_t) & ((uint64_t)0x8000 << 36)) == 0) // fNoGravity, grfso bit 51 + { + ApplySoConstraintLocal(pso, (CONSTR *)((uint8_t *)pso + 0x440), + (VECTOR *)((uint8_t *)pso + 0x350), &v, NULL); + AddSoAcceleration(pso, &v); + } + } + pxa = STRUCT_OFFSET(pso, 0x4B0, XA *); // pxaFirst + while (pxa != NULL) + { + SO *psoXa = STRUCT_OFFSET(pxa, 0x0, SO *); + void (*pfn)(SO *, XA *, float) = + (void (*)(SO *, XA *, float))STRUCT_OFFSET(psoXa->pvtlo, 0xDC, void *); + pfn(psoXa, pxa, dt); + pxa = STRUCT_OFFSET(pxa, 0x8, XA *); + } +} INCLUDE_ASM("asm/nonmatchings/P2/so", RenderSoSelf__FP2SOP2CMP2RO); @@ -146,9 +171,13 @@ void SetSoMass(SO *pso, float mass) INCLUDE_ASM("asm/nonmatchings/P2/so", AdjustSoMomint__FP2SOf); -INCLUDE_ASM("asm/nonmatchings/P2/so", DiscardSoXps__FP2SO); +INCLUDE_ASM("asm/nonmatchings/P2/so", DiscardSoXps__FP2SOi); -INCLUDE_ASM("asm/nonmatchings/P2/so", UpdateSoPosWorldPrev__FP2SO); +void UpdateSoPosWorldPrev(SO *pso) +{ + // posWorldPrev (0x370) = xf.posWorld (0x140) + STRUCT_OFFSET(pso, 0x370, qword) = STRUCT_OFFSET(pso, 0x140, qword); +} INCLUDE_ASM("asm/nonmatchings/P2/so", TranslateSoToPos__FP2SOP6VECTOR); @@ -168,9 +197,76 @@ INCLUDE_ASM("asm/nonmatchings/P2/so", AddSoAcceleration__FP2SOP6VECTOR); INCLUDE_ASM("asm/nonmatchings/P2/so", AddSoAngularAcceleration__FP2SOP6VECTOR); -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoConstraints__FP2SO2CTP6VECTORT1T2); +void SetSoConstraints(SO *pso, CT ctForce, VECTOR *pnormalForce, CT ctTorque, VECTOR *pnormalTorque) +{ + SO *psoRoot; + uint64_t fWasLocked; -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoParent__FP2SOP3ALO); + STRUCT_OFFSET(pso, 0x450, CT) = ctForce; // constrForce.ct + fWasLocked = (STRUCT_OFFSET(pso, 0x538, uint64_t) >> 54) & 1; + if (pnormalForce != NULL) + { + STRUCT_OFFSET(pso, 0x440, VU_VECTOR) = *(VU_VECTOR *)pnormalForce; + } + STRUCT_OFFSET(pso, 0x470, CT) = ctTorque; // constrTorque.ct + if (pnormalTorque != NULL) + { + STRUCT_OFFSET(pso, 0x460, VU_VECTOR) = *(VU_VECTOR *)pnormalTorque; + } + psoRoot = STRUCT_OFFSET(pso, 0x50, SO *); + if (psoRoot != NULL) + { + int fLocked = 0; + if (ctForce == CT_Locked) + { + fLocked = ctTorque == CT_Locked; + } + if (fWasLocked != fLocked) + { + RecalcSoLocked(psoRoot); + } + } +} + +void SetSoParent(SO *pso, ALO *paloParent) +{ + VECTOR vecForce; + VECTOR vecTorque; + SO *psoRootOld; + SO *psoRoot; + + if (pso->paloParent == paloParent) + { + return; + } + psoRootOld = STRUCT_OFFSET(pso, 0x50, SO *); + // carry the constraint normals (world space) across the reparent + ConvertAloVec(pso->paloParent, NULL, (VECTOR *)&STRUCT_OFFSET(pso, 0x440, VU_VECTOR), &vecForce); + ConvertAloVec(pso->paloParent, NULL, (VECTOR *)&STRUCT_OFFSET(pso, 0x460, VU_VECTOR), &vecTorque); + SetAloParent(pso, paloParent); + ConvertAloVec(NULL, paloParent, &vecForce, (VECTOR *)&STRUCT_OFFSET(pso, 0x440, VU_VECTOR)); + ConvertAloVec(NULL, paloParent, &vecTorque, (VECTOR *)&STRUCT_OFFSET(pso, 0x460, VU_VECTOR)); + if (STRUCT_OFFSET(pso, 0x50, SO *) != NULL) + { + if (STRUCT_OFFSET(pso, 0x538, uint64_t) & ((uint64_t)0x8000 << 39)) // locked, bit 54 + { + if (psoRootOld != NULL) + { + RecalcSoLocked(psoRootOld); + } + } + psoRoot = STRUCT_OFFSET(pso, 0x50, SO *); + if (STRUCT_OFFSET(psoRoot, 0x538, uint64_t) & ((uint64_t)0x8000 << 40)) // hierarchy locked, bit 55 + { + RecalcSoLocked(psoRoot); + } + else + { + RecalcSoLocked(pso); + } + } + RebuildSoPhysHook(pso); +} INCLUDE_ASM("asm/nonmatchings/P2/so", ApplySoProxy__FP2SOP5PROXY); @@ -199,12 +295,44 @@ void ApplySoConstraintLocal(SO *pso, CONSTR *pconstr, VECTOR *pvecLocal, VECTOR void AddSoXa(SO *pso, XA *pxaAdd) { - STRUCT_OFFSET(pxaAdd, 0x08, XA *) = STRUCT_OFFSET(pso, 0x4b0, XA *); // pxaAdd->pxaNextSource = pso->pxa; - STRUCT_OFFSET(pso, 0x4b0, XA *) = pxaAdd; // pso->pxa = pxaAdd; + STRUCT_OFFSET(pxaAdd, 0x8, XA *) = STRUCT_OFFSET(pso, 0x4B0, XA *); // pxaNext + STRUCT_OFFSET(pso, 0x4B0, XA *) = pxaAdd; // pxaFirst ResolveAlo(pso); } -INCLUDE_ASM("asm/nonmatchings/P2/so", RemoveSoXa__FP2SOP2XA); +void RemoveSoXa(SO *pso, XA *pxaRemove) +{ + XA **ppxa = &STRUCT_OFFSET(pso, 0x4B0, XA *); // &pxaFirst + XA *pxa = STRUCT_OFFSET(pso, 0x4B0, XA *); + if (pxa != NULL) + { + if (pxa == pxaRemove) + { + STRUCT_OFFSET(pso, 0x4B0, XA *) = STRUCT_OFFSET(pxaRemove, 0x8, XA *); + } + else + { + for (;;) + { + XA *pxaCur = *ppxa; + XA *pxaNext = STRUCT_OFFSET(pxaCur, 0x8, XA *); + ppxa = &STRUCT_OFFSET(pxaCur, 0x8, XA *); + if (pxaNext == NULL) + { + goto LDone; + } + if (pxaNext == pxaRemove) + { + STRUCT_OFFSET(pxaCur, 0x8, XA *) = STRUCT_OFFSET(pxaRemove, 0x8, XA *); + break; + } + } + } + STRUCT_OFFSET(pxaRemove, 0x8, XA *) = NULL; + } +LDone: + ResolveAlo(pso); +} INCLUDE_ASM("asm/nonmatchings/P2/so", AddSoWaterAcceleration__FP2SOP5WATERf); @@ -227,40 +355,180 @@ void SetSoNoInteract(SO *pso, int fNoInteract) SetSoConstraints(pso, CT_Locked, NULL, CT_Locked, NULL); } -INCLUDE_ASM("asm/nonmatchings/P2/so", ConstrFromCnstr__F5CNSTRP2CTP6VECTOR); +struct CNSTRE +{ + VECTOR *pnormal; + CT ct; +}; +extern CNSTRE D_002746E0[]; // s_acnstre: CNSTR -> (ct, normal) table + +void ConstrFromCnstr(CNSTR cnstr, CT *pct, VECTOR *pnormal) +{ + *pct = D_002746E0[cnstr].ct; + *(qword *)pnormal = *(qword *)D_002746E0[cnstr].pnormal; +} INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoCnstrForce__FP2SO5CNSTR); INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoCnstrTorque__FP2SO5CNSTR); -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoCameraStyle__FP2SO3CMK); +void SetSoCameraStyle(SO *pso, CMK cmk) +{ + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)0xF << 32); // cmk field, grfso bits 32..35 + grfso |= (uint64_t)(cmk & 0xF) << 32; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; +} -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoIgnoreLocked__FP2SOi); +void SetSoIgnoreLocked(SO *pso, int fIgnoreLocked) +{ + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)1 << 47); // fIgnoreLocked, grfso bit 47 + grfso |= (uint64_t)(fIgnoreLocked & 1) << 47; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; +} -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoIceable__FP2SOi); +void SetSoIceable(SO *pso, int fIceable) +{ + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)1 << 48); // fIceable, grfso bit 48 + grfso |= (uint64_t)(fIceable & 1) << 48; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; +} void SetSoMtlk(SO *pso, MTLK mtlk) { STRUCT_OFFSET(pso, 0x2c8, char) = mtlk; } -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoEdgeGrab__FP2SO3EGK); +void SetSoEdgeGrab(SO *pso, EGK egk) +{ + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)0xF0 << 32); // egk field, grfso bits 36..39 + grfso |= (uint64_t)(egk & 0xF) << 36; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; +} -INCLUDE_ASM("asm/nonmatchings/P2/so", SendSoMessage__FP2SO5MSGIDPv); +void SendSoMessage(SO *pso, MSGID msgid, void *pv) +{ + XA *pxa; + + SendLoMessage(pso, msgid, pv); + pxa = STRUCT_OFFSET(pso, 0x4B0, XA *); // pxaFirst + while (pxa != NULL) + { + SO *psoTarget = STRUCT_OFFSET(pxa, 0x0, SO *); + XA *pxaNext = STRUCT_OFFSET(pxa, 0x8, XA *); + if (psoTarget != pso) + { + // virtual HandleMessage at vtable +0x44 + void (*pfn)(SO *, MSGID, void *) = + (void (*)(SO *, MSGID, void *))STRUCT_OFFSET(STRUCT_OFFSET(psoTarget, 0x0, void *), 0x44, void *); + if (pfn != NULL) + { + pfn(psoTarget, msgid, pv); + } + } + pxa = pxaNext; + } +} INCLUDE_ASM("asm/nonmatchings/P2/so", PxpFindSoGround__FP2SOT0Pi); -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoNoGravity__FP2SOi); +void SetSoNoGravity(SO *pso, int fNoGravity) +{ + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)1 << 51); // fNoGravity, grfso bit 51 + grfso |= (uint64_t)(fNoGravity & 1) << 51; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; +} -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoNoXpsAll__FP2SOi); +void SetSoNoXpsAll(SO *pso, int fNoXps) +{ + uint64_t bit = (uint64_t)(fNoXps & 1) << 42; // fNoXpsAll, grfso bit 42 + uint64_t mask = ~((uint64_t)1 << 42); + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= mask; + grfso |= bit; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; + DiscardSoXps(pso, fNoXps != 0); +} -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoNoXpsSelf__FP2SOi); +void SetSoNoXpsSelf(SO *pso, int fNoXps) +{ + uint64_t bit = (uint64_t)(fNoXps & 1) << 43; // fNoXpsSelf, grfso bit 43 + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)1 << 43); + grfso |= bit; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; + DiscardSoXps(pso, fNoXps ? 2 : 0); +} -INCLUDE_ASM("asm/nonmatchings/P2/so", SetSoNoXpsCenter__FP2SOi); +void SetSoNoXpsCenter(SO *pso, int fNoXps) +{ + uint64_t bit = (uint64_t)(fNoXps & 1) << 44; // fNoXpsCenter, grfso bit 44 + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)1 << 44); + grfso |= bit; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; + DiscardSoXps(pso, fNoXps ? 3 : 0); +} -INCLUDE_ASM("asm/nonmatchings/P2/so", RebuildSoPhysHook__FP2SO); +void RebuildSoPhysHook(SO *pso) +{ + SO *psoChild; + VECTOR vecUnused; // dead local; needed for the original's 0x30 frame + void *pvt = STRUCT_OFFSET(pso, 0x0, void *); + + // The object is its own phys hook if it overrides any of the phys + // handler virtuals (vtable slots 0x114 / 0x100 / 0x104 / 0x108). + if (STRUCT_OFFSET(pvt, 0x114, void *) != NULL || STRUCT_OFFSET(pvt, 0x100, void *) != NULL || + STRUCT_OFFSET(pvt, 0x104, void *) != NULL || STRUCT_OFFSET(pvt, 0x108, void *) != NULL) + { + STRUCT_OFFSET(pso, 0x4E4, SO *) = pso; // psoPhysHook + } + else + { + ALO *paloParent = STRUCT_OFFSET(pso, 0x18, ALO *); + if (paloParent != NULL) + { + STRUCT_OFFSET(pso, 0x4E4, SO *) = STRUCT_OFFSET(paloParent, 0x4E4, SO *); + } + else + { + STRUCT_OFFSET(pso, 0x4E4, SO *) = NULL; + } + } + for (psoChild = STRUCT_OFFSET(pso, 0x34, SO *); psoChild != NULL; + psoChild = STRUCT_OFFSET(psoChild, 0x1C, SO *)) + { + // class-flags word at vtable +0x8, bit 1 = derives from SO + if (STRUCT_OFFSET(STRUCT_OFFSET(psoChild, 0x0, void *), 0x8, int) & 2) + { + RebuildSoPhysHook(psoChild); + } + } +} -INCLUDE_ASM("asm/nonmatchings/P2/so", PsoFindSoPhysHook__FP2SOi); +SO *PsoFindSoPhysHook(SO *psoLeaf, int ib) +{ + SO *pso = psoLeaf; + while (pso != NULL) + { + pso = STRUCT_OFFSET(pso, 0x4E4, SO *); // psoPhysHook + if (pso == NULL) + { + break; + } + // hook handles phys if its virtual at vtable offset ib is non-null + if (STRUCT_OFFSET(STRUCT_OFFSET(pso, 0x0, void *), ib, void *) != NULL) + { + return pso; + } + pso = STRUCT_OFFSET(pso, 0x18, SO *); // paloParent + } + return NULL; +} INCLUDE_ASM("asm/nonmatchings/P2/so", RecalcSoLocked__FP2SO); @@ -270,28 +538,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/so", GetSoContacts__FP2SOPiPPP2SO); int FSoInStsoList(STSO *pstsoFirst, SO *pso) { - // NOTE: Compiler doesn't seem to emit matching code if the check is inverted. - if (pstsoFirst) + while (pstsoFirst != NULL) { - SO *psoTouch = pstsoFirst->psoTouch; - - while (true) + if (STRUCT_OFFSET(pstsoFirst, 0x0, SO *) == pso) // pso held by this STSO { - if (psoTouch == pso) - { - return 1; - } - - pstsoFirst = pstsoFirst->pstsoNext; - if (!pstsoFirst) - { - break; - } - - psoTouch = pstsoFirst->psoTouch; + return 1; } + pstsoFirst = pstsoFirst->pstsoNext; } - return 0; } @@ -308,11 +562,10 @@ INCLUDE_ASM("asm/nonmatchings/P2/so", ProjectSoLvo__FP2SOf); void ProjectSoTransform(SO *pso, float dt, int fForce) { - if (STRUCT_OFFSET(pso, 0x3c8, LVO *)) // pso->plvo + if (STRUCT_OFFSET(pso, 0x3C8, void *) != NULL) { ProjectSoLvo(pso, dt); } - ProjectAloTransform(pso, dt, fForce); } @@ -322,20 +575,28 @@ INCLUDE_ASM("asm/nonmatchings/P2/so", CalculateSoTrajectoryApex__FP2SOP6VECTORfT int FAbsorbSoWkr(SO *pso, WKR *pwkr) { - if ((pwkr->grfic & 8) != 0) + if (pwkr->grfic & 0x8) { - ApplySoImpulse(pso, &pwkr->pos, &pwkr->v, pwkr->sftMax); + ApplySoImpulse(pso, &STRUCT_OFFSET(pwkr, 0x20, VECTOR), &STRUCT_OFFSET(pwkr, 0x30, VECTOR), pwkr->sftMax); } - - return (int)(pwkr->grfic != 0); + return pwkr->grfic != 0; } INCLUDE_ASM("asm/nonmatchings/P2/so", CloneSoPhys__FP2SOT0i); -INCLUDE_ASM("asm/nonmatchings/P2/so", FUN_001bc4d8); +INCLUDE_ASM("asm/nonmatchings/P2/so", FUN_001bc4d8__FPUcT0); INCLUDE_ASM("asm/nonmatchings/P2/so", FUN_001bc670); -INCLUDE_ASM("asm/nonmatchings/P2/so", FUN_001bc710); +void FUN_001bc710(SO *pso, int f) +{ + uint64_t grfso = STRUCT_OFFSET(pso, 0x538, uint64_t); + grfso &= ~((uint64_t)1 << 52); + grfso |= (uint64_t)(f & 1) << 52; + STRUCT_OFFSET(pso, 0x538, uint64_t) = grfso; +} -INCLUDE_ASM("asm/nonmatchings/P2/so", FUN_001bc748); +void FUN_001bc748(SO *pso, int *pn) +{ + *pn = (int)(STRUCT_OFFSET(pso, 0x538, uint64_t) >> 52) & 1; // grfso bit 52 (qword view) +} diff --git a/src/P2/sort.c b/src/P2/sort.c index 359f8cdda..959f7f9a7 100644 --- a/src/P2/sort.c +++ b/src/P2/sort.c @@ -17,4 +17,53 @@ void SwapEntries(void *afoo, int cb, int i1, int i2) } } -INCLUDE_ASM("asm/nonmatchings/P2/sort", HeapSort__FPviiPFPvPv_i); +void HeapSort(void *afoo, int iMac, int cb, PFNCMP pfncmp) +{ + int iLast, cHalf, iRoot, iChild; + + if (iMac < 2) + { + return; + } + iLast = iMac - 1; + cHalf = iMac / 2; + for (;;) + { + if (cHalf > 0) + { + // build phase: sift the next non-leaf down + cHalf--; + } + else + { + // extract phase: move the max to the end, shrink the heap + SwapEntries(afoo, cb, iLast, 0); + if (iLast-- < 2) + { + return; + } + } + iRoot = cHalf; + iChild = iRoot * 2 + 1; + while (iChild <= iLast) + { + if (iChild < iLast) + { + if (pfncmp((void *)(iChild * cb + (int)afoo), (void *)((iChild + 1) * cb + (int)afoo)) < 0) + { + iChild = iChild + 1; + } + } + if (pfncmp((void *)(iRoot * cb + (int)afoo), (void *)(iChild * cb + (int)afoo)) < 0) + { + SwapEntries(afoo, cb, iRoot, iChild); + iRoot = iChild; + iChild += iChild + 1; + } + else + { + break; + } + } + } +} diff --git a/src/P2/sound.c b/src/P2/sound.c index 1b5abe8db..fd105eeda 100644 --- a/src/P2/sound.c +++ b/src/P2/sound.c @@ -1,6 +1,12 @@ #include #include <989snd.h> #include +#include +#include +#include +#include +#include +#include extern uchar D_00604790[]; // temp extern int D_006053E0[]; @@ -18,50 +24,245 @@ struct MVG }; extern float D_00274838[10][4]; // temp +extern int D_00274720; -INCLUDE_ASM("asm/nonmatchings/P2/sound", UnloadMusic__Fv); +void UnloadMusic() +{ + extern u_int D_0027473C; + extern u_int D_00274728; + + if (D_0027473C != 0) + { + if (D_00274728 != 0) + snd_StopSound(D_00274728); + snd_UnloadBank((SoundBankPtr)D_0027473C); + while (snd_FlushSoundCommands()) {} + D_0027473C = 0; + } + D_00274720 = 0; + D_00274728 = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/sound", SbpEnsureBank__Fi); -INCLUDE_ASM("asm/nonmatchings/P2/sound", SbpEnsureBank__F5SFXID); +extern int D_00245020[][2]; +void SbpEnsureBank(SFXID sfxid) +{ + SbpEnsureBank(D_00245020[sfxid][0]); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", NewSfx__FPP3SFX); +void NewSfx(SFX **ppsfx) +{ + *ppsfx = (SFX *)PvAllocSwClearImpl(sizeof(SFX)); + (*ppsfx)->sfxid = (SFXID)-1; + (*ppsfx)->sStart = 3000.0f; + (*ppsfx)->sFull = 300.0f; + (*ppsfx)->uVol = 1.0f; + (*ppsfx)->uPitch = 0.0f; + (*ppsfx)->pamb = NULL; + (*ppsfx)->lmRepeat.gMin = -1.0f; + (*ppsfx)->uDoppler = 0.0f; +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", FContinuousSound__F5SFXID); +extern int D_006047B0[]; +extern int D_006047D0[]; -INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001BE5D8); +int FContinuousSound(SFXID sfxid) +{ + if (D_006047B0[D_00245020[sfxid][0]] == 0) + { + SbpEnsureBank(sfxid); + } + return D_006047D0[sfxid]; +} + +extern int D_00274730; +void FUN_001BE5D8(void) +{ + D_00274730 = 0; +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", SetVagUnpaused__Fv); +extern u_int D_00274744; +int SetVagUnpaused() +{ + return D_00274744; +} INCLUDE_ASM("asm/nonmatchings/P2/sound", PreloadVag__FPc2FK); -INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001be708); +extern u_int D_00274744; +void FUN_001be708(void) +{ + D_00274744 = 0; + StopVag(); +} INCLUDE_ASM("asm/nonmatchings/P2/sound", PreloadVag1); -INCLUDE_ASM("asm/nonmatchings/P2/sound", FPauseForVag__Fv); +extern u_int D_00274744; +extern u_int D_0027472C; +extern int D_00274730; +int FPauseForVag() +{ + if (D_00274744 != 0) + { + return 0; + } + u_int handle = D_0027472C; + if (handle != 0) + { + if (D_00274730 != 0) + { + return 1; + } + snd_ContinueVAGStream(handle); + } + return 0; +} + +void RefreshPambVolPan(AMB *pamb) +{ + int vol = (int)(STRUCT_OFFSET(pamb, 0x50, float) * 1024.0f); + float pan = STRUCT_OFFSET(pamb, 0x54, float); + int panOut; + if (0.0f < pan) + panOut = (int)((pan + 2.0f) * 179.5f) - 359; + else + panOut = (int)((pan + 2.0f) * 179.5f); + snd_SetSoundVolPan(pamb->sfxh, vol, panOut); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", RefreshPambVolPan__FP3AMB); +void RefreshPambVolPan(AMB *pamb); +void DropPamb(AMB **ppamb); -INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001be8f8); +void FUN_001be8f8(ALO *palo, AMB **ppamb, float sStart, float sFull) +{ + AMB *pambLocal; + int fLocal = 0; -INCLUDE_ASM("asm/nonmatchings/P2/sound", FVagPlaying__Fv); + if (ppamb == NULL) + { + fLocal = 1; + ppamb = &pambLocal; + } + + StartSound((SFXID)-2, ppamb, palo, NULL, sStart, sFull, 1.0f, 0.0f, 0.0f, NULL, NULL); + + if (*ppamb != NULL) + { + RefreshPambVolPan(*ppamb); + if (fLocal) + { + DropPamb(ppamb); + } + } +} + +extern u_int D_0027472C; +int FVagPlaying() +{ + return D_0027472C != 0; +} JUNK_WORD(0x0080102D); -INCLUDE_ASM("asm/nonmatchings/P2/sound", StopVag__Fv); +void StopVag() +{ + if (D_00274744 == 0 && D_0027472C != 0) + { + snd_StopSound(D_0027472C); + while (snd_SoundIsStillPlaying(D_0027472C)) + { + int i = 0x4E1F; + do + { + i--; + } while (i >= 0); + } + D_0027472C = 0; + D_00274730 = 0; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", PauseVag__Fv); +extern u_int D_0027472C; +void PauseVag() +{ + u_int handle = D_0027472C; + if (handle != 0) + { + snd_PauseSound(handle); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", ContinueVag__Fv); +extern u_int D_0027472C; +void ContinueVag() +{ + u_int handle = D_0027472C; + if (handle != 0) + { + snd_ContinueSound(handle); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", KillMusic__Fv); +extern int D_00274720; +extern u_int D_00274728; +void KillMusic() +{ + if (D_00274720 == 3) + { + snd_StopSound(D_00274728); + D_00274728 = 0; + D_00274720 = 2; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", PreloadMusidSongComplete__FUiUl); +extern int D_00274720; +extern int D_00274724; +extern u_int D_0027473C; +void PreloadMusidSongComplete(u_int handle, u_long unused) +{ + D_0027473C = handle; + if (handle != 0) + { + snd_ResolveBankXREFS(); + D_00274720 = 2; + } + else + { + D_00274724 = 0; + D_00274720 = 0; + } +} INCLUDE_ASM("asm/nonmatchings/P2/sound", PreloadMusidSong__F5MUSID); -INCLUDE_ASM("asm/nonmatchings/P2/sound", StartMusidSong__F5MUSID); +enum MUSID {}; +void PreloadMusidSong(MUSID musid); + +void StartMusidSong(MUSID musid) +{ + extern int D_00274720; + extern u_int D_00274728; + extern u_int D_0027473C; + + PreloadMusidSong(musid); + if (musid != 0) + { + while (snd_FlushSoundCommands() != 0) + { + if (D_00274720 != 1) + break; + FlushCache(0); + } + if (D_00274720 == 2) + { + u_int handle = snd_PlaySoundVolPanPMPB((SoundBankPtr)D_0027473C, 0, 0x400, -1, 0, 0); + D_00274728 = handle; + if (handle != 0) + D_00274720 = 3; + } + } +} void PauseMusic() { @@ -73,13 +274,34 @@ void ContinueMusic() SetMvgkRvol(2, MVGK_Music, 1.0f); } -INCLUDE_ASM("asm/nonmatchings/P2/sound", SfxhMusicUnknown1); +extern u_int D_00274728; +void SfxhMusicUnknown1() +{ + snd_PauseSound(D_00274728); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", SfxhMusicUnknown2); +extern u_int D_00274728; +void SfxhMusicUnknown2() +{ + snd_ContinueSound(D_00274728); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", PexcAlloc__Fv); +EXC *PexcAlloc() +{ + EXC *pexc = (EXC *)PvAllocSlotheapUnsafe(&STRUCT_OFFSET(g_psw, 0x1bb8, SLOTHEAP)); + if (pexc != 0) + { + memset(pexc, 0, sizeof(EXC)); + AppendDlEntry(&STRUCT_OFFSET(g_psw, 0x1bc4, DL), pexc); + } + return pexc; +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", RemoveExc__FP3EXC); +void RemoveExc(EXC *pexc) +{ + RemoveDlEntry(&STRUCT_OFFSET(g_psw, 0x1bc4, DL), pexc); + FreeSlotheapPv(&STRUCT_OFFSET(g_psw, 0x1bb8, SLOTHEAP), pexc); +} INCLUDE_ASM("asm/nonmatchings/P2/sound", KillExcitement__Fv); @@ -87,9 +309,46 @@ INCLUDE_ASM("asm/nonmatchings/P2/sound", PexcSetExcitement__Fi); INCLUDE_ASM("asm/nonmatchings/P2/sound", SetIexcCurHigh__FP3EXC); -INCLUDE_ASM("asm/nonmatchings/P2/sound", UnsetExcitement__FP3EXC); +extern int D_00274734; +extern int D_002748EC; +void SetIexcCurHigh(EXC *pexc); + +void UnsetExcitement(EXC *pexc) +{ + if (pexc != 0) + { + int iexc = pexc->iexc; + RemoveExc(pexc); + if (iexc == D_00274734) + { + SetIexcCurHigh(pexc); + int iexcCur = D_00274734; + if (iexcCur >= 0) + D_002748EC = 0; + g_iexcHyst = iexcCur; + snd_SetGlobalExcite(iexcCur + 0x14); + SetMvgkRvol(7, MVGK_Music, 1.0f); + g_iexcHyst = -0x64; + } + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", UnsetExcitementHyst__FP3EXC); +extern int D_00274734; +void SetIexcCurHigh(EXC *pexc); + +void UnsetExcitementHyst(EXC *pexc) +{ + if (pexc != 0) + { + int iexc = pexc->iexc; + RemoveExc(pexc); + if (iexc == D_00274734) + { + g_iexcHyst = iexc; + SetIexcCurHigh(pexc); + } + } +} void StartupSound() { @@ -110,7 +369,11 @@ void StartupSound() JUNK_NOP(); JUNK_ADDIU(10); -INCLUDE_ASM("asm/nonmatchings/P2/sound", FAmbientsPaused__Fv); +extern int D_00274748; +int FAmbientsPaused() +{ + return D_00274748; +} INCLUDE_ASM("asm/nonmatchings/P2/sound", CalculateVolPan__FfP6VECTORPfT2fff); @@ -124,21 +387,86 @@ INCLUDE_ASM("asm/nonmatchings/P2/sound", SetDoppler__FP3AMB); INCLUDE_ASM("asm/nonmatchings/P2/sound", PfneardistGet__Fv); -INCLUDE_ASM("asm/nonmatchings/P2/sound", SDistEar__FP6VECTOR); +VECTOR *PposEar(); +typedef float (*PFNSDIST)(VECTOR *, VECTOR *); +PFNSDIST PfneardistGet(); +float SDistEar(VECTOR *pvec) +{ + VECTOR *pposEar = PposEar(); + return PfneardistGet()(pposEar, pvec); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", CalculateDistVolPan__FP6VECTORPfT1fff); +void CalculateVolPan(float dist, VECTOR *pvec, float *pa, float *pb, float a, float b, float c); -INCLUDE_ASM("asm/nonmatchings/P2/sound", PambAlloc__Fv); +void CalculateDistVolPan(VECTOR *pvec, float *pa, float *pb, float a, float b, float c) +{ + if (pvec) + { + CalculateVolPan(SDistEar(pvec), pvec, pa, pb, a, b, c); + } + else + { + *pa = a; + *pb = 0; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", DropPamb__FPP3AMB); +AMB *PambAlloc() +{ + AMB *pamb = (AMB *)PvAllocSlotheapUnsafe(&STRUCT_OFFSET(g_psw, 0x1ba0, SLOTHEAP)); + if (pamb != 0) + { + memset(pamb, 0, 0x90); + AppendDlEntry(&STRUCT_OFFSET(g_psw, 0x1bac, DL), pamb); + } + return pamb; +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", RemoveAmb__FP3AMB); +void DropPamb(AMB **ppamb) +{ + (*ppamb)->ppamb = NULL; + *ppamb = NULL; +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", StopSound__FP3AMBi); +void RemoveAmb(AMB *pamb) +{ + if (pamb->ppamb != NULL) + { + *pamb->ppamb = NULL; + } + pamb->iSerial = -1; + RemoveDlEntry(&STRUCT_OFFSET(g_psw, 0x1bac, DL), pamb); + FreeSlotheapPv(&STRUCT_OFFSET(g_psw, 0x1ba0, SLOTHEAP), pamb); +} + +void RemoveAmb(AMB *pamb); + +void StopSound(AMB *pamb, int msRampdown) +{ + if (pamb != 0) + { + if (msRampdown == 0) + snd_StopSound(pamb->sfxh); + else + snd_AutoVol(pamb->sfxh, -4, (int)((float)msRampdown * 0.24000001f), 2); + RemoveAmb(pamb); + } +} INCLUDE_ASM("asm/nonmatchings/P2/sound", SetPambFrq__FP3AMBf); -INCLUDE_ASM("asm/nonmatchings/P2/sound", SetPambVol__FP3AMBf); +void RefreshPambVolPan(AMB *pamb); + +void SetPambVol(AMB *pamb, float uVolAtSource) +{ + if (pamb != 0) + { + float ratio = uVolAtSource / pamb->uVolAtSource; + pamb->uVolAtSource = uVolAtSource; + STRUCT_OFFSET(pamb, 0x50, float) *= ratio; // real volAttenuated (compiled AMB layout is shifted -8 here; named field at 0x50 is frq) + RefreshPambVolPan(pamb); + } +} INCLUDE_ASM("asm/nonmatchings/P2/sound", FillPamb__FP3AMBPP3AMBiP3ALOP6VECTORfffffP2LMT10_); @@ -148,7 +476,18 @@ INCLUDE_ASM("asm/nonmatchings/P2/sound", ScheduleNextIntermittentSound__FP3AMB); INCLUDE_ASM("asm/nonmatchings/P2/sound", StartSound__F5SFXIDPP3AMBP3ALOP6VECTORfffffP2LMT9); -INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001BFFC8); +void FUN_001BFFC8(int err, u_long user_data) +{ + if (err == 0) + { + int iSerial = (int)(user_data >> 32); + AMB *pamb = (AMB *)(user_data & 0xFFFFFFFF); + if (pamb->iSerial == iSerial) + { + STRUCT_OFFSET(pamb, 0x48, int) = 1; // fStopped (real offset; compiled AMB::fStopped lands at 0x44) + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/sound", HandleWipeHandleWipeVolumes__FifVolumes); @@ -187,11 +526,35 @@ void SetMvgkRvol(int channel, MVGK mvgk, float rvol) MvgkUnknown1(mvgk); } -INCLUDE_ASM("asm/nonmatchings/P2/sound", MvgkUnknown2__Fv); +extern float D_00274758[10][4]; +void MvgkUnknown3(int fMute); +void MvgkUnknown4(int mode); +void MvgkUnknown2() +{ + CopyAb(D_00274838, D_00274758, 0xB0); + SetMvgkUvol(1.0f); + for (int i = 0; i < 4; ++i) + { + MvgkUnknown1((MVGK)i); + } + MvgkUnknown3(STRUCT_OFFSET(g_pgsCur, 0x19EC, int) & 0x80); + MvgkUnknown4(STRUCT_OFFSET(g_pgsCur, 0x19EC, int) & 0x40); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", MvgkUnknown3); +void MvgkUnknown3(int fMute) +{ + float rvol = 1.0f; + if (fMute != 0) + { + rvol = 0.0f; + } + SetMvgkRvol(3, MVGK_Music, rvol); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", MvgkUnknown4); +void MvgkUnknown4(int mode) +{ + snd_SetPlaybackMode(mode != 0); +} /** * @todo Figure out func_001c0cb0, and use enum values for params where applicable. @@ -209,32 +572,101 @@ void KillSoundSystem() INCLUDE_ASM("asm/nonmatchings/P2/sound", KillSounds__Fi); -INCLUDE_ASM("asm/nonmatchings/P2/sound", PushSwReverb__FP2SW7REVERBKi); +enum REVERBK {}; +extern int D_00274808[]; + +void PushSwReverb(SW *psw, REVERBK reverb, int depth) +{ + if ((unsigned)STRUCT_OFFSET(psw, 0x2348, int) < 4) + { + snd_SetReverbType(2, D_00274808[reverb]); + snd_SetReverbDepth(2, depth, depth); + STRUCT_OFFSET((char *)psw + (STRUCT_OFFSET(psw, 0x2348, int) << 3), 0x2328, int) = reverb; + STRUCT_OFFSET((char *)psw + (STRUCT_OFFSET(psw, 0x2348, int) << 3), 0x232c, int) = depth; + STRUCT_OFFSET(psw, 0x2348, int) = STRUCT_OFFSET(psw, 0x2348, int) + 1; + } +} INCLUDE_ASM("asm/nonmatchings/P2/sound", PopSwReverb__FP2SW); -INCLUDE_ASM("asm/nonmatchings/P2/sound", SetSwDefaultReverb__FP2SW7REVERBKi); +void SetSwDefaultReverb(SW *psw, REVERBK reverb, const int depth) +{ + snd_SetReverbType(2, D_00274808[reverb]); + snd_SetReverbDepth(2, depth, depth); + STRUCT_OFFSET(psw, 0x2328, int) = reverb; + STRUCT_OFFSET(psw, 0x232c, int) = depth; + STRUCT_OFFSET(psw, 0x2348, int) = 1; +} INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001C0A50); -INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001C0AB8); +struct SW; + +void FUN_001C0AB8(SW *psw, float *pg) +{ + int c = STRUCT_OFFSET(psw, 0x1D80, int); // count of intermittent-sound entries (array of 0x14-byte entries at 0x1D84) + if (c != 0) + { + char *pisnd = (char *)psw + (c * 0x14 + 0x1D70); // last entry: 0x1D84 + (c-1)*0x14 + STRUCT_OFFSET(pisnd, 0xC, float) = 8000.0f - pg[1] * 50.0f; // lmRepDist.gMin + STRUCT_OFFSET(pisnd, 0x10, float) = 8000.0f - pg[0] * 50.0f; // lmRepDist.gMax + } +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001C0B08); +struct SW; + +void FUN_001C0B08(SW *psw, LM *plm) +{ + int c = STRUCT_OFFSET(psw, 0x1D80, int); // count of intermittent-sound entries (array of 0x14-byte entries at 0x1D84) + if (c != 0) + { + char *pisnd = (char *)psw + (c * 0x14 + 0x1D70); // last entry: 0x1D84 + (c-1)*0x14 + STRUCT_OFFSET(pisnd, 0x4, LM) = *plm; // lmRepeat (unaligned 8-byte struct copy: ldl/ldr + sdl/sdr) + } +} INCLUDE_ASM("asm/nonmatchings/P2/sound", StartSwIntermittentSounds__FP2SW); // TODO: Verify signature. -INCLUDE_ASM("asm/nonmatchings/P2/sound", SetAMRegister__FiUc); +extern u_int D_00274728; +void SetAMRegister(int n, int bReg) +{ + if (bReg != D_006053E0[n]) + { + D_006053E0[n] = bReg; + snd_SetMIDIRegister(D_00274728, n, bReg); + } +} -int GetAMRegister(int reg) +int GetAMRegister(int reg) { return D_006053E0[reg]; } -INCLUDE_ASM("asm/nonmatchings/P2/sound", UpdateAMRegister__Fii); +extern u_int D_00274728; +void UpdateAMRegister(int reg, int value) +{ + D_006053E0[reg] = snd_GetMIDIRegister(D_00274728, reg); +} -INCLUDE_ASM("asm/nonmatchings/P2/sound", FUN_001c0cb0__Fv); +void FUN_001c0cb0() +{ + for (int i = 0; i < 8; i++) + { + SetAMRegister(i, 0); + } +} INCLUDE_ASM("asm/nonmatchings/P2/sound", HsNextFootFall__Fv); -INCLUDE_ASM("asm/nonmatchings/P2/sound", NextSneakyFootstep__Fv); +extern int D_002748EC; +int HsNextFootFall(); + +void NextSneakyFootstep() +{ + if (D_002748EC != 0) + { + int hs = HsNextFootFall(); + StartSound((SFXID)0x77, NULL, NULL, NULL, 0.0f, 0.0f, 0.5f, hs * 0.083333336f, 0.0f, NULL, NULL); + } +} diff --git a/src/P2/speaker.c b/src/P2/speaker.c index 0e329e499..04f271f68 100644 --- a/src/P2/speaker.c +++ b/src/P2/speaker.c @@ -1,7 +1,26 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/speaker", InitSpeaker__FP7SPEAKER); INCLUDE_ASM("asm/nonmatchings/P2/speaker", PostSpeakerLoad__FP7SPEAKER); -INCLUDE_ASM("asm/nonmatchings/P2/speaker", SetSpeakerSmIdle__FP7SPEAKER3OID); +void SetSpeakerSmIdle(SPEAKER *pspeaker, OID oid) +{ + if (STRUCT_OFFSET(pspeaker, 0x334, SMA *) != NULL) + { + RetractSma(STRUCT_OFFSET(pspeaker, 0x334, SMA *)); + STRUCT_OFFSET(pspeaker, 0x334, SMA *) = NULL; + } + + SM *psm = (SM *) PloFindSwObject(pspeaker->psw, 0x101, oid, pspeaker); + STRUCT_OFFSET(pspeaker, 0x330, SM *) = psm; + + if (psm != NULL) + { + STRUCT_OFFSET(pspeaker, 0x334, SMA *) = PsmaApplySm(psm, pspeaker, (OID)-1, 1); + } + + STRUCT_OFFSET(pspeaker, 0x32c, OID) = oid; +} diff --git a/src/P2/splice/bif.cpp b/src/P2/splice/bif.cpp index 31c00231b..c65bdd7a8 100644 --- a/src/P2/splice/bif.cpp +++ b/src/P2/splice/bif.cpp @@ -1,7 +1,15 @@ #include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpAdd__FiP4CRefP6CFrame); @@ -193,17 +201,59 @@ CRef RefOpNot(int carg, CRef *aref, CFrame *pframe) INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpCons__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpCar__FiP4CRefP6CFrame); +CRef RefOpCar(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref = aref->m_tag.m_ppair->m_ref; + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpCdr__FiP4CRefP6CFrame); +CRef RefOpCdr(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + CPair *ppairNext = STRUCT_OFFSET(aref->m_tag.m_ppair, 0x8, CPair *); // m_ppairNext (private) + if (ppairNext != NULL) + { + ref.SetPair(ppairNext); + } + else + { + ref.SetTag(TAGK_None); + } + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpSetCadr__FiP4CRefP6CFrame4BIFK); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpSetCar__FiP4CRefP6CFrame); +CRef RefOpSetCar(int carg, CRef *aref, CFrame *pframe) +{ + return RefOpSetCadr(carg, aref, pframe, BIFK_SetCar); +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpSetCdr__FiP4CRefP6CFrame); +CRef RefOpSetCdr(int carg, CRef *aref, CFrame *pframe) +{ + return RefOpSetCadr(carg, aref, pframe, BIFK_SetCdr); +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpLength__FiP4CRefP6CFrame); +CRef RefOpLength(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + int c = 0; + if (aref->m_tagk == TAGK_Pair) + { + CPair *ppair = aref->m_tag.m_ppair; + if (ppair != NULL) + { + do + { + ppair = STRUCT_OFFSET(ppair, 0x8, CPair *); // m_ppairNext + c = c + 1; + } while (ppair != NULL); + } + } + ref.SetS32(c); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpNth__FiP4CRefP6CFrame); @@ -228,7 +278,13 @@ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpVector__FiP4CRefP6CFrame); INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMatrix__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpSetMusicRegister__FiP4CRefP6CFrame); +CRef RefOpSetMusicRegister(int carg, CRef *aref, CFrame *pframe) +{ + SetAMRegister(aref[0].m_tag.m_n, aref[1].m_tag.m_n); + CRef ref; + ref.SetTag(TAGK_Void); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpClq__FiP4CRefP6CFrame); @@ -238,9 +294,44 @@ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpSmp__FiP4CRefP6CFrame); INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpGetElement__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpRandomSeed__FiP4CRefP6CFrame); - -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpRandom__FiP4CRefP6CFrame); +CRef RefOpRandomSeed(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + if (aref->m_tagk == TAGK_S32) + { + srand(aref->m_tag.m_n); + } + else + { + srand((int)aref->m_tag.m_g); + } + ref.m_tagk = TAGK_Void; + return ref; +} + +CRef RefOpRandom(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + float g0, g1; + if (aref[0].m_tagk == TAGK_S32) + { + g0 = (float)aref[0].m_tag.m_n; + } + else + { + g0 = aref[0].m_tag.m_g; + } + if (aref[1].m_tagk == TAGK_S32) + { + g1 = (float)aref[1].m_tag.m_n; + } + else + { + g1 = aref[1].m_tag.m_g; + } + ref.SetF32(GRandInRange(g0, g1)); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefUfo__FP4CRef4UFOK); @@ -306,15 +397,43 @@ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpVectorBallisticVelocity__FiP4 INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpVectorRadianNormal__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMatrixTranspose__FiP4CRefP6CFrame); +CRef RefOpMatrixTranspose(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + MATRIX4 *pmatrix = PmatrixNew(); + TransposeMatrix4(aref->m_tag.m_pmatrix, pmatrix); + ref.SetMatrix(pmatrix); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMatrixInvert__FiP4CRefP6CFrame); +CRef RefOpMatrixInvert(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + MATRIX4 *pmatrix = PmatrixNew(); + FInvertMatrix4(aref->m_tag.m_pmatrix, pmatrix); + ref.SetMatrix(pmatrix); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMatrixCalculateDmat__FiP4CRefP6CFrame); +CRef RefOpMatrixCalculateDmat(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + MATRIX4 *pmatrix = PmatrixNew(); + CalculateDmat4(aref[0].m_tag.m_pmatrix, aref[1].m_tag.m_pmatrix, pmatrix); + ref.SetMatrix(pmatrix); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMatrixInterpolateRotate__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMatrixDecomposeToTranslate__FiP4CRefP6CFrame); +CRef RefOpMatrixDecomposeToTranslate(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + VECTOR *pvector = PvectorNew(); + *(qword *)pvector = STRUCT_OFFSET(aref->m_tag.m_pmatrix, 0x30, qword); // matrix.pos row + ref.SetVector(pvector); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMatrixDecomposeToRotate__FiP4CRefP6CFrame); @@ -336,27 +455,89 @@ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpLmLimit__FiP4CRefP6CFrame); INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpLmCheck__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpFloor__FiP4CRefP6CFrame); +CRef RefOpFloor(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref.SetS32((int)aref->m_tag.m_g); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpCeiling__FiP4CRefP6CFrame); +CRef RefOpCeiling(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref.SetS32((int)(aref->m_tag.m_g + 1.0f)); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpRound__FiP4CRefP6CFrame); +CRef RefOpRound(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref.SetS32((int)(aref->m_tag.m_g + 0.5f)); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpTruncate__FiP4CRefP6CFrame); +CRef RefOpTruncate(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref.SetS32((int)aref->m_tag.m_g); + return ref; +} +// Kept wrapped: unwrapping inflates the still-asm RefOpPredictAnimationEffect and fails the checksum. INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpAbs__FiP4CRefP6CFrame); +#ifdef SKIP_ASM +CRef RefOpAbs(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + if (aref->m_tagk == TAGK_S32) + { + ref.SetS32(__builtin_abs(aref->m_tag.m_n)); + } + else + { + float g = aref->m_tag.m_g; + if (g < 0.0f) + { + g = -g; + } + ref.SetF32(g); + } + return ref; +} +#endif INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMaximum__FiP4CRefP6CFrame); INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpMinimum__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpModulo__FiP4CRefP6CFrame); +CRef RefOpModulo(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref.SetS32(aref[0].m_tag.m_n % aref[1].m_tag.m_n); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpCurrentTime__FiP4CRefP6CFrame); +CRef RefOpCurrentTime(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref.SetF32(g_clock.t); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpScheduleCallback__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpDeferObjectUpdate__FiP4CRefP6CFrame); +CRef RefOpDeferObjectUpdate(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + BASIC *pbasic = aref->m_tag.m_pbasic; + float g; + { + CRef refCoerced = aref[1].RefCoerceF32(); + g = refCoerced.m_tag.m_g; + } + STRUCT_OFFSET(pbasic, 0x29C, float) = g; + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpObjectOption__FiP4CRefP6CFrame4BIFK); @@ -382,11 +563,22 @@ CRef RefOpGetO(int carg, CRef *aref, CFrame *pframe) INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefPairFromAplo__FiPP2LO); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpFindObject__FiP4CRefP6CFrame); +CRef RefOpFindObject(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + LO *plo = (LO *)aref[1].m_tag.m_pbasic; + ref.SetBasic((BASIC *)PloFindSwObject(g_psw, plo ? 0x101 : 0x105, (OID)aref[0].m_tag.m_n, plo)); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpFindObjects__FiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpFindNearestObject__FiP4CRefP6CFrame); +CRef RefOpFindNearestObject(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref.SetBasic((BASIC *)PloFindSwObject(g_psw, 0x104, (OID)aref[0].m_tag.m_n, (LO *)aref[1].m_tag.m_pbasic)); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpFindNearestObjects__FiP4CRefP6CFrame); @@ -419,13 +611,37 @@ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpFindObjectsInBoundingSphere__ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpHitTestObjectsImpl__F4BIFKiP4CRefP6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpHitTestObjects__FiP4CRefP6CFrame); +CRef RefOpHitTestObjects(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref = RefOpHitTestObjectsImpl(BIFK_HitTestObjects, carg, aref, pframe); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpHitTestObjectsFirst__FiP4CRefP6CFrame); +CRef RefOpHitTestObjectsFirst(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + ref = RefOpHitTestObjectsImpl(BIFK_HitTestObjectsFirst, carg, aref, pframe); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpConvertObjectPosition__FiP4CRefP6CFrame); +CRef RefOpConvertObjectPosition(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + VECTOR *pvector = PvectorNew(); + ConvertAloPos((ALO *)aref[0].m_tag.m_pbasic, (ALO *)aref[1].m_tag.m_pbasic, aref[2].m_tag.m_pvector, pvector); + ref.SetVector(pvector); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpConvertObjectVector__FiP4CRefP6CFrame); +CRef RefOpConvertObjectVector(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + VECTOR *pvector = PvectorNew(); + ConvertAloVec((ALO *)aref[0].m_tag.m_pbasic, (ALO *)aref[1].m_tag.m_pbasic, aref[2].m_tag.m_pvector, pvector); + ref.SetVector(pvector); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpConvertObjectMatrix__FiP4CRefP6CFrame); @@ -433,7 +649,17 @@ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpNearClipCenter__FiP4CRefP6CFr INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpStartSound__FiP4CRefP6CFrame); +// Kept wrapped: unwrapping inflates the still-asm RefOpPredictAnimationEffect and fails the checksum. INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpStopSound__FiP4CRefP6CFrame); +#ifdef SKIP_ASM +CRef RefOpStopSound(int carg, CRef *aref, CFrame *pframe) +{ + CRef ref; + StopSound((AMB *)aref->m_tag.m_pbasic, 0); + ref.m_tagk = TAGK_Void; + return ref; +} +#endif INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpStartRumble__FiP4CRefP6CFrame); @@ -443,8 +669,25 @@ INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", RefOpPredictAnimationEffect__FiP4C INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", __8VU_FLOATf); -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", __9VU_VECTORRC6VECTOR); +VU_VECTOR::VU_VECTOR(const VECTOR &vec) +{ + data = *(qword *)&vec; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", __as__6VECTORG9VU_VECTOR); +VECTOR &VECTOR::operator=(VU_VECTOR vuvec) +{ + *(qword *)this = vuvec.data; + return *this; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/bif", __ml__FG8VU_FLOATG9VU_VECTOR); +VU_VECTOR operator*(VU_FLOAT f, VU_VECTOR v) +{ + VU_VECTOR r; + asm("qmtc2.ni %1, $vf1\n\t" + "qmtc2.ni %2, $vf2\n\t" + "vmulx.xyzw $vf1, $vf2, $vf1\n\t" + "qmfc2.ni %0, $vf1" + : "=r"(r.data) + : "r"(f.data), "r"(v.data)); + return r; +} diff --git a/src/P2/splice/eval.cpp b/src/P2/splice/eval.cpp index 10d744122..80e11eb75 100644 --- a/src/P2/splice/eval.cpp +++ b/src/P2/splice/eval.cpp @@ -1,6 +1,14 @@ #include - -INCLUDE_ASM("asm/nonmatchings/P2/splice/eval", RefEvalSymbol__FP5CPairP6CFrame); +#include +#include +#include + +CRef RefEvalSymbol(CPair *ppair, CFrame *pframe) +{ + CRef ref; + pframe->FFindBinding(ppair->m_ref.m_tag.m_symid, 1, &ref); + return ref; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/eval", RefEvalSet__FP5CPairP6CFrame); diff --git a/src/P2/splice/frame.cpp b/src/P2/splice/frame.cpp index 9a88b10cd..e0d4d8a17 100644 --- a/src/P2/splice/frame.cpp +++ b/src/P2/splice/frame.cpp @@ -1,6 +1,8 @@ #include +#include #include #include +#include void CFrame::SetSingleParent(CFrame *pframeParent) { @@ -13,15 +15,58 @@ void CFrame::AddParent(CFrame *pframeParent) m_apframeParent[m_cpframeParent++] = pframeParent; } -INCLUDE_ASM("asm/nonmatchings/P2/splice/frame", RefAddBinding__6CFrameUiP4CRef); +CRef CFrame::RefAddBinding(uint symid, CRef *pref) +{ + CRef ref; + void *psbb = FUN_0011C498(); + STRUCT_OFFSET(psbb, 0x0, uint) = symid; + STRUCT_OFFSET(psbb, 0x4, CRef) = *pref; + STRUCT_OFFSET(psbb, 0xC, void *) = STRUCT_OFFSET(this, 0x14, void *); + STRUCT_OFFSET(this, 0x14, void *) = psbb; + ref.SetTag(TAGK_Void); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/frame", RefSetBinding__6CFrameUiP4CRef); +CRef CFrame::RefSetBinding(uint symid, CRef *pref) +{ + CRef ref; + CRef *prefFound = PrefFindBinding(symid, 1); + if (prefFound != NULL) + { + *prefFound = *pref; + } + ref.SetTag(TAGK_Void); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/frame", FFindBinding__6CFrameUiiP4CRef); +int CFrame::FFindBinding(uint symid, int fRecursive, CRef *pref) +{ + CRef *prefFound = PrefFindBinding(symid, fRecursive); + if (prefFound != NULL) + { + if (pref != NULL) + { + *pref = *prefFound; + } + return 1; + } + return 0; +} INCLUDE_ASM("asm/nonmatchings/P2/splice/frame", PrefFindBinding__6CFrameUii); -INCLUDE_ASM("asm/nonmatchings/P2/splice/frame", CloneTo__6CFrameP6CFrame); +void CFrame::CloneTo(CFrame *pframeClone) +{ + pframeClone->m_cpframeParent = m_cpframeParent; + CopyAb(pframeClone->m_apframeParent, m_apframeParent, m_cpframeParent * 4); + // binding-node list head at +0x14 (same node type as CSidebag) + if (STRUCT_OFFSET(this, 0x14, void *) != NULL) + { + void *psbb = FUN_0011C498(); + FUN_0011C418(STRUCT_OFFSET(this, 0x14, void *), psbb, pframeClone); + STRUCT_OFFSET(pframeClone, 0x14, void *) = psbb; + } +} CFrame *PframeNew() { diff --git a/src/P2/splice/ref.cpp b/src/P2/splice/ref.cpp index 8e91db9fb..2721f95e0 100644 --- a/src/P2/splice/ref.cpp +++ b/src/P2/splice/ref.cpp @@ -253,6 +253,26 @@ void CRef::SetMethod(CMethod *pmethod) m_tagk = TAGK_Method; } -INCLUDE_ASM("asm/nonmatchings/P2/splice/ref", RefCoerceS32__4CRef); +CRef CRef::RefCoerceS32() +{ + if (m_tagk == TAGK_S32) + { + return *this; + } + CRef ref; + ref.SetS32((int)m_tag.m_g); + return ref; +} + +CRef CRef::RefCoerceF32() +{ + if (m_tagk == TAGK_F32) + { + return *this; + } + CRef ref; + ref.SetF32((float)m_tag.m_n); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/ref", RefCoerceF32__4CRef); +JUNK_NOP(); diff --git a/src/P2/splice/sidebag.cpp b/src/P2/splice/sidebag.cpp index 889b4be17..f244e4d45 100644 --- a/src/P2/splice/sidebag.cpp +++ b/src/P2/splice/sidebag.cpp @@ -1,14 +1,66 @@ #include +#include +#include #include #include -INCLUDE_ASM("asm/nonmatchings/P2/splice/sidebag", RefAddBinding__8CSidebagiP4CRef); +CRef CSidebag::RefAddBinding(int n, CRef *pref) +{ + CRef ref; + void *psbb = FUN_0011C498(); + STRUCT_OFFSET(psbb, 0x0, int) = n; + STRUCT_OFFSET(psbb, 0x4, CRef) = *pref; + STRUCT_OFFSET(psbb, 0xC, void *) = STRUCT_OFFSET(this, 0x0, void *); + STRUCT_OFFSET(this, 0x0, void *) = psbb; + ref.SetTag(TAGK_Void); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/sidebag", RefSetBinding__8CSidebagiP4CRef); +CRef CSidebag::RefSetBinding(int n, CRef *pref) +{ + void *psbb = STRUCT_OFFSET(this, 0x0, void *); + if (psbb != NULL) + { + do + { + if (STRUCT_OFFSET(psbb, 0x0, int) == n) + { + CRef ref; + STRUCT_OFFSET(psbb, 0x4, CRef) = *pref; + ref.SetTag(TAGK_Void); + return ref; + } + psbb = STRUCT_OFFSET(psbb, 0xC, void *); + } while (psbb != NULL); + } + CRef ref; + ref.SetTag(TAGK_Void); + return ref; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/sidebag", FFindBinding__8CSidebagiP4CRef); +bool CSidebag::FFindBinding(int n, CRef *pref) +{ + void *psbb; + for (psbb = STRUCT_OFFSET(this, 0x0, void *); psbb != NULL; psbb = STRUCT_OFFSET(psbb, 0xC, void *)) + { + if (STRUCT_OFFSET(psbb, 0x0, int) == n) + { + if (pref != NULL) + { + *pref = STRUCT_OFFSET(psbb, 0x4, CRef); + } + return true; + } + } + return false; +} -INCLUDE_ASM("asm/nonmatchings/P2/splice/sidebag", CloneTo__8CSidebagP8CSidebag); +void CSidebag::CloneTo(CSidebag *psidebagClone) +{ + void *psbb = FUN_0011C498(); + FUN_0011C418(STRUCT_OFFSET(this, 0x0, void *), psbb, NULL); + STRUCT_OFFSET(psidebagClone, 0x0, void *) = psbb; +} CSidebag *PsidebagNew() { diff --git a/src/P2/splice/splotheap.cpp b/src/P2/splice/splotheap.cpp index 48be3c2a3..107ef20a0 100644 --- a/src/P2/splice/splotheap.cpp +++ b/src/P2/splice/splotheap.cpp @@ -105,8 +105,8 @@ void MarkPvAlive(void *pv) psplot->fAlive = 1; } -INCLUDE_ASM("asm/nonmatchings/P2/splice/splotheap", FUN_0011C418); +INCLUDE_ASM("asm/nonmatchings/P2/splice/splotheap", FUN_0011C418__FPvT0P6CFrame); -INCLUDE_ASM("asm/nonmatchings/P2/splice/splotheap", FUN_0011C498); +INCLUDE_ASM("asm/nonmatchings/P2/splice/splotheap", FUN_0011C498__Fv); INCLUDE_ASM("asm/nonmatchings/P2/splice/splotheap", FUN_0011C4E8); diff --git a/src/P2/splicemap.c b/src/P2/splicemap.c index 9bcad5522..15e21e45a 100644 --- a/src/P2/splicemap.c +++ b/src/P2/splicemap.c @@ -1,7 +1,18 @@ #include +#include INCLUDE_ASM("asm/nonmatchings/P2/splicemap", LoadSwSpliceFromBrx__FP2SWP18CBinaryInputStream); -INCLUDE_ASM("asm/nonmatchings/P2/splicemap", PframeFromIsplice__FiP2SW); +CFrame *PframeFromIsplice(int isplice, SW *psw) +{ + if (isplice == -1) + return NULL; + + CFrame *pframe = *(CFrame **)((uint8_t *)STRUCT_OFFSET(psw, 0x1EF4, void *) + isplice * 8 + 4); + if (pframe != NULL) + g_gc.AddRootFrame(pframe); + + return pframe; +} INCLUDE_ASM("asm/nonmatchings/P2/splicemap", RefEvalModule__FiP2SW); diff --git a/src/P2/spliceobj.c b/src/P2/spliceobj.c index 6e1c5c9ca..55cf4570e 100644 --- a/src/P2/spliceobj.c +++ b/src/P2/spliceobj.c @@ -1,4 +1,6 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", PeopidFind__FP5BASICi); @@ -16,12 +18,32 @@ INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", RefSetArgListFromPvs__FiP4OTYPPPv); INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", RefSetPeopid__FP5BASICP5EOPIDP4CRef); -INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", RefGetOption__FP5BASICi); +CRef RefGetOption(BASIC *pbasic, int optid) +{ + if (optid < 0x495) + { + EOPID *peopid = PeopidFind(pbasic, optid); + return RefGetPeopid(pbasic, peopid); + } + else + { + CRef ref; + pbasic->psidebag->FFindBinding(optid, &ref); + return ref; + } +} INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", RefSetOption__FP5BASICiP4CRef); INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", RefAddOption__FP5BASICiP4CRef); -INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", RefEnsureOption__FP5BASICiP4CRef); +CRef RefEnsureOption(BASIC *pbasic, int optid, CRef *prefValue) +{ + EnsureBasicSidebag(pbasic); + if (pbasic->psidebag->FFindBinding(optid, NULL)) + return pbasic->psidebag->RefSetBinding(optid, prefValue); + else + return pbasic->psidebag->RefAddBinding(optid, prefValue); +} INCLUDE_ASM("asm/nonmatchings/P2/spliceobj", RefSetArgsFromSplice__FiP4CRefP4OTYPe); diff --git a/src/P2/sqtr.c b/src/P2/sqtr.c index 6e57e4f1f..a733c87b9 100644 --- a/src/P2/sqtr.c +++ b/src/P2/sqtr.c @@ -1,6 +1,10 @@ #include -INCLUDE_ASM("asm/nonmatchings/P2/sqtr", FUN_001c29e8); +void FUN_001c29e8(SQTRM *psqtrm) +{ + STRUCT_OFFSET(psqtrm, 0xc, int) = 0; + STRUCT_OFFSET(psqtrm, 0x8, int) = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/sqtr", UpdateSqtrm__FP5SQTRMP6VECTORP7MATRIX3ff); diff --git a/src/P2/step.c b/src/P2/step.c index 0c5b1a2c8..a6aeeca90 100644 --- a/src/P2/step.c +++ b/src/P2/step.c @@ -1,4 +1,7 @@ #include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/step", InitStep__FP4STEP); @@ -9,7 +12,31 @@ INCLUDE_ASM("asm/nonmatchings/P2/step", LimitStepHands__FP4STEPi); // TODO: This might be "RetractStepExtremity". Further research needed. INCLUDE_ASM("asm/nonmatchings/P2/step", FUN_001c4618); -INCLUDE_ASM("asm/nonmatchings/P2/step", FUN_001c4790); +void FUN_001c4790(void *p1, SO *pso, BSP *pbsp, void *p4) +{ + + if (STRUCT_OFFSET(p4, 0x50, int) == 0) + return; + + LSG alsg[2]; + int clsg = ClsgClipEdgeToObjectPruned(pso, pbsp, (VECTOR *)((uint8_t *)p4 + 0x70), + (VECTOR *)((uint8_t *)p4 + 0x60), 2, alsg); + + int i = 0; + if (clsg > 0) + { + if (alsg[0].au[0] == 0.0f) + i = 1; + } + + if (i < clsg) + { + if (alsg[i].au[0] < STRUCT_OFFSET(p4, 0xD0, float)) + { + *(LSG *)((uint8_t *)p4 + 0x90) = alsg[i]; + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/step", FUN_001c4848); @@ -37,7 +64,16 @@ CT CtTorqueStep(STEP *pstep) return CT_Locked; } -INCLUDE_ASM("asm/nonmatchings/P2/step", PropagateStepForce__FP4STEPiP2XPiP2DZP2FX); +void PropagateSoForce(SO *psoRoot, GRFSG grfsg, XP *pxp, int ixpd, DZ *pdz, FX *afx); + +void PropagateStepForce(STEP *pstep, GRFSG grfsg, XP *pxp, int ixpd, DZ *pdz, FX *afx) +{ + CT ctSav = STRUCT_OFFSET(pstep, 0x470, CT); + STRUCT_OFFSET(pstep, 0x470, CT) = + (*(CT (**)(STEP *))((uint8_t *)pstep->pvtlo + 0x164))(pstep); + PropagateSoForce(pstep, grfsg, pxp, ixpd, pdz, afx); + STRUCT_OFFSET(pstep, 0x470, CT) = ctSav; +} INCLUDE_ASM("asm/nonmatchings/P2/step", RotateStepToMat__FP4STEPP7MATRIX3); @@ -65,9 +101,16 @@ void AdjustStepDzBase(STEP *pstep, GRFADJ grfadj, DZ *pdz, int ixpd) return; } -INCLUDE_ASM("asm/nonmatchings/P2/step", UpdateStepMatTarget__FP4STEP); +void UpdateStepMatTarget(STEP *pstep) +{ + LoadRotateMatrixRad(*(float *)((uint8_t *)(pstep) + 0x638), &g_normalZ, (MATRIX3 *)((uint8_t *)(pstep) + 0x660)); +} -INCLUDE_ASM("asm/nonmatchings/P2/step", AdjustStepXpVelocity__FP4STEPP2XPi); +void AdjustStepXpVelocity(STEP *pstep, XP *pxp, int ixpd) +{ + if ((*(int (**)(STEP *))((char *)pstep->pvtlo + 0x168))(pstep)) + AdjustStepXpVelocityBase(pstep, pxp, ixpd); +} INCLUDE_ASM("asm/nonmatchings/P2/step", UpdateStepXfWorld__FP4STEP); @@ -75,11 +118,21 @@ INCLUDE_ASM("asm/nonmatchings/P2/step", AdjustStepXpVelocityBase__FP4STEPP2XPi); INCLUDE_ASM("asm/nonmatchings/P2/step", AdjustStepXps__FP4STEP); -INCLUDE_ASM("asm/nonmatchings/P2/step", AddStepCustomXps__FP4STEPP2SOiP3BSPT3PP2XP); +void AddStepCustomXps(STEP *pstep, SO *psoOther, int cbspPruned, BSP *abspPruned, BSP *pbspPruned, XP **ppxpFirst) +{ + AddStepCustomXpsBase(pstep, psoOther, pbspPruned, ppxpFirst); +} INCLUDE_ASM("asm/nonmatchings/P2/step", AddStepCustomXpsBase__FP4STEPP2SOP3BSPPP2XP); -INCLUDE_ASM("asm/nonmatchings/P2/step", FixStepAngularVelocity__FP4STEP); +void FixStepAngularVelocity(STEP *pstep) +{ + qword local = STRUCT_OFFSET(pstep, 0x160, qword); + float radTarget = atan2f(STRUCT_OFFSET(pstep, 0xd4, float), STRUCT_OFFSET(pstep, 0xd0, float)); + RadSmooth(radTarget, STRUCT_OFFSET(pstep, 0x638, float), 0.0f, + (SMP *)((uint8_t *)pstep + 0x6e0), (float *)((uint8_t *)&local + 8)); + (*(void (**)(STEP *, qword *))((uint8_t *)pstep->pvtlo + 0x94))(pstep, &local); +} INCLUDE_ASM("asm/nonmatchings/P2/step", PredictStepRotation__FP4STEPfP7MATRIX3P6VECTOR); diff --git a/src/P2/stepcane.c b/src/P2/stepcane.c index ff77abe9e..055b0ae7f 100644 --- a/src/P2/stepcane.c +++ b/src/P2/stepcane.c @@ -1,4 +1,6 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/stepcane", SetJtJtcs__FP2JT4JTCS); @@ -10,6 +12,37 @@ INCLUDE_ASM("asm/nonmatchings/P2/stepcane", ChooseJtAttackTarget__FP2JTiP6VECTOR INCLUDE_ASM("asm/nonmatchings/P2/stepcane", ChooseJtSweepTarget__FP2JTP2BLP6ASEGBL); -INCLUDE_ASM("asm/nonmatchings/P2/stepcane", ChooseJtRushTarget__FP2JT); +extern VECTOR D_00274BF0; +extern VECTOR D_00274C00; -INCLUDE_ASM("asm/nonmatchings/P2/stepcane", ChooseJtSmashTarget__FP2JT); +void ChooseJtRushTarget(JT *pjt) +{ + VECTOR dposProj; + TARGET *ptarget; + + ChooseJtAttackTarget(pjt, 8, &D_00274BF0, 0.25f, 1.0f, &ptarget, &dposProj); + STRUCT_OFFSET(pjt, 0x2204, int) = 0; + STRUCT_OFFSET(pjt, 0x2200, TARGET *) = ptarget; + STRUCT_OFFSET(pjt, 0x2208, int) = 0; + if (ptarget != NULL) + { + STRUCT_OFFSET(pjt, 0x638, float) = atan2f(dposProj.y, dposProj.x); + FixStepAngularVelocity((STEP *)pjt); + } +} + +void ChooseJtSmashTarget(JT *pjt) +{ + VECTOR dposProj; + TARGET *ptarget; + + ChooseJtAttackTarget(pjt, 4, &D_00274C00, 0.25f, 3.15f, &ptarget, &dposProj); + STRUCT_OFFSET(pjt, 0x2204, int) = 0; + STRUCT_OFFSET(pjt, 0x2200, TARGET *) = ptarget; + STRUCT_OFFSET(pjt, 0x2208, int) = 0; + if (ptarget != NULL) + { + STRUCT_OFFSET(pjt, 0x638, float) = atan2f(dposProj.y, dposProj.x); + FixStepAngularVelocity((STEP *)pjt); + } +} diff --git a/src/P2/stepguard.c b/src/P2/stepguard.c index 945118aa4..5c458bed1 100644 --- a/src/P2/stepguard.c +++ b/src/P2/stepguard.c @@ -1,5 +1,9 @@ #include #include +#include +#include +#include +#include extern SNIP s_asnipStepguardLoad; @@ -25,7 +29,10 @@ void CloneStepguard(STEPGUARD *pstepguard, STEPGUARD *pstepguardBase) INCLUDE_ASM("asm/nonmatchings/P2/stepguard", BindStepguard__FP9STEPGUARD); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", PostStepguardLoadCallback__FP9STEPGUARD5MSGIDPv); +void PostStepguardLoadCallback(STEPGUARD *pstepguard, MSGID msgid, void *pv) +{ + pstepguard->pvtlo->pfnRemoveLo(pstepguard); +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", PostStepguardLoad__FP9STEPGUARD); @@ -103,7 +110,13 @@ INCLUDE_ASM("asm/nonmatchings/P2/stepguard", SgsNextStepguardAI__FP9STEPGUARD); INCLUDE_ASM("asm/nonmatchings/P2/stepguard", SetStepguardGoal__FP9STEPGUARDP6VECTOR); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FReachedStepguardGoal__FP9STEPGUARD); +int FReachedStepguardGoal(STEPGUARD *pstepguard) +{ + int fReached = 0; + if (STRUCT_OFFSET(pstepguard, 0xa60, int)) + fReached = STRUCT_OFFSET(pstepguard, 0x930, int) == STRUCT_OFFSET(pstepguard, 0x92c, int); + return fReached; +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FFilterStepguardJump__FP9STEPGUARDP2SO); @@ -129,7 +142,13 @@ INCLUDE_ASM("asm/nonmatchings/P2/stepguard", OnStepguardExitingSgs__FP9STEPGUARD INCLUDE_ASM("asm/nonmatchings/P2/stepguard", OnStepguardEnteringSgs__FP9STEPGUARD3SGSP4ASEG); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", SggsGetStepguard__FP9STEPGUARD); +SGGS SggsGetStepguard(STEPGUARD *pstepguard) +{ + SGG *psgg = STRUCT_OFFSET(pstepguard, 0x720, SGG*); + if (psgg == NULL) + return SGGS_Dead; + return STRUCT_OFFSET(psgg, 0x50, SGGS); +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FAbsorbStepguardWkr__FP9STEPGUARDP3WKR); @@ -144,7 +163,17 @@ INCLUDE_ASM("asm/nonmatchings/P2/stepguard", HandleStepguardGrfsgsc__FP9STEPGUAR INCLUDE_ASM("asm/nonmatchings/P2/stepguard", DoStepguardFreefallJump__FP9STEPGUARD); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", DoStepguardFreefallLanding__FP9STEPGUARD); +void SeekAsega(ASEGA *pasega, SEEK seek, float t, float svt); + +void DoStepguardFreefallLanding(STEPGUARD *pstepguard) +{ + ASEGA *pasegaSgs = STRUCT_OFFSET(pstepguard, 0x7e0, ASEGA *); + STRUCT_OFFSET(pstepguard, 0xb8c, int) = 0; + STRUCT_OFFSET(pstepguard, 0xa60, int) = 0; + float t = TFindAsegLabel(STRUCT_OFFSET(pasegaSgs, 0x8, ASEG *), (OID)0x1B1); + SeekAsega(STRUCT_OFFSET(pstepguard, 0x7e0, ASEGA *), SEEK_Start, t, 1.0f); + STRUCT_OFFSET(pstepguard, 0xba4, int) = 0; +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FUN_001c9d50); @@ -157,14 +186,24 @@ SGAS SgasGetStepguard(STEPGUARD *pstepguard) INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FCanStepguardAttack__FP9STEPGUARD); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", RenderStepguardSelf__FP9STEPGUARDP2CMP2RO); +void RenderStepguardSelf(STEPGUARD *pstepguard, CM *pcm, RO *pro) +{ + RenderStepSelf(pstepguard, pcm, pro); +} int FValidSgs(SGS sgs) { return ((uint)sgs < 0x11); } -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", UseStepguardAnimation__FP9STEPGUARD3SGS3OID); +void UseStepguardAnimation(STEPGUARD *pstepguard, SGS sgs, OID oidAnim) +{ + if (FValidSgs(sgs)) + { + long long *a = &STRUCT_OFFSET(pstepguard, 0x758, long long); + *(OID *)&a[sgs] = oidAnim; + } +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", UseStepguardAnimationImmediate__FP9STEPGUARD3SGS3OID); @@ -172,7 +211,19 @@ INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FUN_001ca6d0); INCLUDE_ASM("asm/nonmatchings/P2/stepguard", UseStepguardDeathAnimation__FP9STEPGUARDi3OID); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", PasegFindStepguard__FP9STEPGUARD3OID); +ASEG *PasegFindStepguard(STEPGUARD *pstepguard, OID oidAseg) +{ + ASEG *paseg = (ASEG *)PloFindSwObject(pstepguard->psw, 0x101, oidAseg, STRUCT_OFFSET(pstepguard, 0xb74, LO *)); + + if (paseg != NULL) + { + STRUCT_OFFSET(paseg, 0x48, int) = 0; + StripAsegAlo(paseg, (ALO *)pstepguard); + SnipLo(paseg); + } + + return paseg; +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", LoadStepguardAnimations__FP9STEPGUARD); @@ -188,7 +239,14 @@ void UseStepguardRwm(STEPGUARD *pstepguard, OID oidRwm) STRUCT_OFFSET(pstepguard, 0xb04, int) = 1; } -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", UseStepguardPhys__FP9STEPGUARD3SGS3OID); +void UseStepguardPhys(STEPGUARD *pstepguard, SGS sgs, OID oidPhys) +{ + if (FValidSgs(sgs)) + { + long long *a = &STRUCT_OFFSET(pstepguard, 0x870, long long); + *(OID *)&a[sgs] = oidPhys; + } +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", LoadStepguardPhys__FP9STEPGUARD); @@ -198,7 +256,12 @@ INCLUDE_ASM("asm/nonmatchings/P2/stepguard", SetStepguardPathzone__FP9STEPGUARD3 INCLUDE_ASM("asm/nonmatchings/P2/stepguard", PsoEnemyStepguard__FP9STEPGUARD); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FUN_001caad0); +void FUN_001caad0(SO *pso, SO **ppso) +{ + void *pvt = STRUCT_OFFSET(pso, 0x0, void *); + SO *(*fn)(SO *) = (SO *(*)(SO *))STRUCT_OFFSET(pvt, 0x198, void *); + *ppso = fn(pso); +} void SetStepguardEnemyObject(STEPGUARD *pstepguard, SO *psoEnemy) { @@ -208,7 +271,10 @@ void SetStepguardEnemyObject(STEPGUARD *pstepguard, SO *psoEnemy) INCLUDE_ASM("asm/nonmatchings/P2/stepguard", RebindStepguardEnemy__FP9STEPGUARD); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FUN_001cac28__FP9STEPGUARD); +void FUN_001cac28(STEPGUARD *pstepguard, int n) +{ + STRUCT_OFFSET(pstepguard, 0xB50, int) = n; +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FUN_001cac30); @@ -219,13 +285,24 @@ void SetStepguardAttackAngleMax(STEPGUARD *pstepguard, float degAttackMax) STRUCT_OFFSET(pstepguard, 0x74c, float) = degAttackMax * 0.017453294f; } -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", AddStepguardAlarm__FP9STEPGUARDP5ALARM); +void AddStepguardAlarm(STEPGUARD *pstepguard, ALARM *palarm) +{ + EnsureSggAlarm(STRUCT_OFFSET(pstepguard, 0x720, SGG *), palarm); +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", MatchStepguardAnimationPhase__FP9STEPGUARD3OIDN31); INCLUDE_ASM("asm/nonmatchings/P2/stepguard", AddStepguardCustomXps__FP9STEPGUARDP2SOiP3BSPT3PP2XP); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", FUN_001caee0); +void FUN_001caee0(STEPGUARD *pstepguard, SO *pso) +{ + (*(void (**)(SO *, void *))((char *)pso->pvtlo + 0x90))(pso, (char *)pstepguard + 0xAB0); + + if (FIsBasicDerivedFrom(pso, CID_JT)) + { + SetJtJts((JT *)pso, JTS_Sidestep, (JTBS)0x2b); + } +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", UpdateStepguardEffect__FP9STEPGUARD); @@ -253,11 +330,40 @@ void InitSgg(SGG *psgg) STRUCT_OFFSET(psgg, 0x180, OID) = OID_Nil; // psgg->oidSync } -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", AddSggGuard__FP3SGGP9STEPGUARD); +void AddSggGuard(SGG *psgg, STEPGUARD *pstepguard) +{ + if (STRUCT_OFFSET(psgg, 0x58, int) == 0) + SetSggSggs(psgg, (SGGS)0); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", AddSggGuardName__FP3SGG3OID); + int c = STRUCT_OFFSET(psgg, 0x58, int); + if ((unsigned int)c < 0x10) + { + STRUCT_OFFSET_INDEX(psgg, 0x5c, STEPGUARD *, c) = pstepguard; + STRUCT_OFFSET(psgg, 0x58, int) = c + 1; + } +} + +void AddSggGuardName(SGG * p, OID oid) +{ + int c = STRUCT_OFFSET(p, 0x9c, int); + if ((unsigned int)c < 16) + { + OID *a = &STRUCT_OFFSET(p, 0xa0, OID); + a[c] = oid; + STRUCT_OFFSET(p, 0x9c, int) = c + 1; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", AddSggSearchXfmName__FP3SGG3OID); +void AddSggSearchXfmName(SGG * p, OID oid) +{ + int c = STRUCT_OFFSET(p, 0x124, int); + if ((unsigned int)c < 16) + { + OID *a = &STRUCT_OFFSET(p, 0x128, OID); + a[c] = oid; + STRUCT_OFFSET(p, 0x124, int) = c + 1; + } +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", RemoveSggGuard__FP3SGGP9STEPGUARD); @@ -267,9 +373,30 @@ INCLUDE_ASM("asm/nonmatchings/P2/stepguard", PostSggLoadCallback__FP3SGG5MSGIDPv INCLUDE_ASM("asm/nonmatchings/P2/stepguard", EnsureSggCallback__FP3SGG); -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", PsoEnemySgg__FP3SGG); +SO *PsoEnemySgg(SGG *psgg) +{ + SO *pso = STRUCT_OFFSET(psgg, 0x5c, SO *); + void *pvt = STRUCT_OFFSET(pso, 0x0, void *); + SO *(*fn)(SO *) = (SO *(*)(SO *))STRUCT_OFFSET(pvt, 0x198, void *); + return fn(pso); +} -INCLUDE_ASM("asm/nonmatchings/P2/stepguard", UpdateSggCallback__FP3SGG5MSGIDPv); +void UpdateSggCallback(SGG *psgg, MSGID msgid, void *pv) +{ + SGGS sggs; + + STRUCT_OFFSET(psgg, 0x17c, int) = 0; + + if (STRUCT_OFFSET(psgg, 0x50, SGGS) != SGGS_Dead) + { + STRUCT_OFFSET(psgg, 0x188, int) = FDetectSgg(psgg); + + while ((sggs = SggsNextSgg(psgg)) != STRUCT_OFFSET(psgg, 0x50, SGGS)) + { + SetSggSggs(psgg, sggs); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/stepguard", SggsNextSgg__FP3SGG); diff --git a/src/P2/stephang.c b/src/P2/stephang.c index 1ca1f8530..691f9b9ce 100644 --- a/src/P2/stephang.c +++ b/src/P2/stephang.c @@ -1,6 +1,21 @@ #include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/stephang", PostJtLoadSwing__FP2JTP2BLPP6ASEGBL); +void PostJtLoadSwing(JT *pjt, BL *ablSwing, ASEGBL **ppasegbl) +{ + ASEGBL *pasegbl; + + STRUCT_OFFSET(ablSwing, 0x0, int) = 0; + STRUCT_OFFSET(ablSwing, 0xC, int) = 0; + STRUCT_OFFSET(ablSwing, 0x18, float) = 1.0f; + + EnsureAsegBlendDynamic((ALO *)pjt, 0xC, 3, ablSwing, 0, NULL, NULL, &pasegbl); + ReblendAsegbl(pasegbl, 0xC, 3, ablSwing); + + if (ppasegbl != NULL) + *ppasegbl = pasegbl; +} INCLUDE_ASM("asm/nonmatchings/P2/stephang", AnticipateJtForce__FP2JTP2SOP6VECTORT2P2FX); @@ -8,7 +23,15 @@ INCLUDE_ASM("asm/nonmatchings/P2/stephang", CalculateJtHangAccel__FP2JT); INCLUDE_ASM("asm/nonmatchings/P2/stephang", PresetJtAccelHang__FP2JT); -INCLUDE_ASM("asm/nonmatchings/P2/stephang", AddJtExternalAccelerations__FP2JTP2XAf); +void AddJtExternalAccelerations(JT *pjt, XA *pxa, float dt) +{ + SO *pso = STRUCT_OFFSET(pjt, 0x22AC, SO *); + SO *psoBody = STRUCT_OFFSET(pso, 0x4, SO *); + AddSoAcceleration(psoBody, (VECTOR *)((uint8_t *)pjt + 0x22D0)); + pso = STRUCT_OFFSET(pjt, 0x22AC, SO *); + psoBody = STRUCT_OFFSET(pso, 0x4, SO *); + AddSoAngularAcceleration(psoBody, (VECTOR *)((uint8_t *)pjt + 0x22E0)); +} INCLUDE_ASM("asm/nonmatchings/P2/stephang", UpdateJtActiveHang__FP2JTP3JOY); @@ -18,7 +41,14 @@ INCLUDE_ASM("asm/nonmatchings/P2/stephang", UpdateJtHookOx__FP2JTP2LOi); INCLUDE_ASM("asm/nonmatchings/P2/stephang", AddJtHookXps__FP2JTiP2LOP6VECTORN23); -INCLUDE_ASM("asm/nonmatchings/P2/stephang", GetJtHangHeading__FP2JTPf); +void GetJtHangHeading(JT *pjt, float *pradForward) +{ + ALO *paloHook = STRUCT_OFFSET(pjt, 0x2204, ALO *); + ALO *paloParent = STRUCT_OFFSET(paloHook, 0x18, ALO *); + VECTOR vec; + ConvertAloVec(paloParent, NULL, (VECTOR *)((uint8_t *)paloHook + 0x50), &vec); + *pradForward = atan2f(vec.y, vec.x); +} INCLUDE_ASM("asm/nonmatchings/P2/stephang", UpdateJtIkHang__FP2JT); diff --git a/src/P2/stephide.c b/src/P2/stephide.c index 866492ab0..127222f3d 100644 --- a/src/P2/stephide.c +++ b/src/P2/stephide.c @@ -1,4 +1,6 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/stephide", JtbsChooseJtHide__FP2JTP2LOP4JTHK); @@ -6,11 +8,53 @@ INCLUDE_ASM("asm/nonmatchings/P2/stephide", MeasureJtJumpToTarget__FP2JTP6VECTOR INCLUDE_ASM("asm/nonmatchings/P2/stephide", GetJtRailLanding__FP2JTP4RAILfP6VECTORT3); -INCLUDE_ASM("asm/nonmatchings/P2/stephide", GMeasureJumpRail__FP3MJRf); +float GMeasureJumpRail(MJR *pmjr, float u) +{ + VECTOR posLanding; + VECTOR vLanding; + float gInteg; -INCLUDE_ASM("asm/nonmatchings/P2/stephide", FUN_001cea58); + GetJtRailLanding(STRUCT_OFFSET(pmjr, 0x0, JT *), + STRUCT_OFFSET(pmjr, 0x4, RAIL *), + u, &posLanding, &vLanding); -INCLUDE_ASM("asm/nonmatchings/P2/stephide", GMeasureJumpHshape__FP3MJHf); + MeasureJtJumpToTarget(STRUCT_OFFSET(pmjr, 0x0, JT *), + (VECTOR *)((uint8_t *)pmjr + 0x10), + STRUCT_OFFSET(STRUCT_OFFSET(pmjr, 0x4, RAIL *), 0x18, ALO *), + &posLanding, &vLanding, 0, &gInteg, 0, 0); + + return gInteg; +} + +float FUN_001cea58(MJH *pmjh) +{ + VECTOR posTarget; + float gInteg; + + GetHpntClosestHidePos(STRUCT_OFFSET(pmjh, 0x4, HPNT *), &posTarget, 0); + + MeasureJtJumpToTarget(STRUCT_OFFSET(pmjh, 0x0, JT *), + (VECTOR *)((uint8_t *)pmjh + 0x10), + STRUCT_OFFSET(STRUCT_OFFSET(pmjh, 0x4, HPNT *), 0x18, ALO *), + &posTarget, 0, 0, &gInteg, 0, 0); + + return gInteg; +} + +float GMeasureJumpHshape(MJH *pmjh, float s) +{ + VECTOR posTarget; + float gInteg; + + GetHshapeHidePos(STRUCT_OFFSET(pmjh, 0x4, HSHAPE *), s, &posTarget, 0); + + MeasureJtJumpToTarget(STRUCT_OFFSET(pmjh, 0x0, JT *), + (VECTOR *)((uint8_t *)pmjh + 0x10), + STRUCT_OFFSET(STRUCT_OFFSET(pmjh, 0x4, HSHAPE *), 0x18, ALO *), + &posTarget, 0, 0, &gInteg, 0, 0); + + return gInteg; +} INCLUDE_ASM("asm/nonmatchings/P2/stephide", FUN_001ceb18); @@ -20,7 +64,15 @@ INCLUDE_ASM("asm/nonmatchings/P2/stephide", FUN_001cee30); INCLUDE_ASM("asm/nonmatchings/P2/stephide", FUN_001ceec8); -INCLUDE_ASM("asm/nonmatchings/P2/stephide", FUN_001cf138); +extern float D_00274E3C; + +float FUN_001cf138(JT *pjt, int n, float a, float b) +{ + a = a + b; + if (n == STRUCT_OFFSET(pjt, 0x2bdc, int)) + a = a + D_00274E3C; + return a; +} INCLUDE_ASM("asm/nonmatchings/P2/stephide", FUN_001cf158); diff --git a/src/P2/steppipe.c b/src/P2/steppipe.c index e3402430b..c55e84cd7 100644 --- a/src/P2/steppipe.c +++ b/src/P2/steppipe.c @@ -10,6 +10,23 @@ INCLUDE_ASM("asm/nonmatchings/P2/steppipe", UpdateJtActivePipe__FP2JTP3JOY); INCLUDE_ASM("asm/nonmatchings/P2/steppipe", UpdateJtInternalXpsPipe__FP2JT); -INCLUDE_ASM("asm/nonmatchings/P2/steppipe", SetJtJtpdk__FP2JT5JTPDK); +void SetJtJtpdk(JT *pjt, JTPDK jtpdk) +{ + JTPDK jtpdkCur = STRUCT_OFFSET(pjt, 0x2718, JTPDK); + if (jtpdkCur != jtpdk) + { + if (jtpdkCur == JTPDK_Nil) + { + IncrementSwHandsOff(pjt->psw); + FUN_001ddb58(pjt->psw); + } + STRUCT_OFFSET(pjt, 0x2718, JTPDK) = jtpdk; + if (jtpdk == JTPDK_Nil) + { + DecrementSwHandsOff(pjt->psw); + FUN_001ddbb8(pjt->psw); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/steppipe", PlaceJtOnPipe__FP2JTP4PIPE); diff --git a/src/P2/steprail.c b/src/P2/steprail.c index a3481caa2..f8a47cca8 100644 --- a/src/P2/steprail.c +++ b/src/P2/steprail.c @@ -1,18 +1,69 @@ #include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/steprail", func_001D31D0__FP2LOi); -INCLUDE_ASM("asm/nonmatchings/P2/steprail", post_load_steprail); +extern SNIP D_00274F90; + +void post_load_steprail(ALO *palo) +{ + PostAloLoad(palo); + SnipAloObjects(palo, 1, &D_00274F90); + void **ppvtable = (void **)STRUCT_OFFSET(palo, 0x0, void*); + void (*pfn)(ALO *) = (void (*)(ALO *))STRUCT_OFFSET(ppvtable, 0x1c, void*); + pfn(palo); +} INCLUDE_ASM("asm/nonmatchings/P2/steprail", func_001D32D8__FiP2JTl); INCLUDE_ASM("asm/nonmatchings/P2/steprail", update_steprail); -INCLUDE_ASM("asm/nonmatchings/P2/steprail", preset_steprail_accel); +void preset_steprail_accel(SO *pso, float dt) +{ + MATRIX3 mat; + + PresetSoAccel(pso, dt); + + if (STRUCT_OFFSET(pso, 0x18, int) == 0) // pso->paloParent + { + TiltMatUpright((MATRIX3 *)((uint8_t *)pso + 0xD0), NULL, &mat); + AccelSoTowardMatSpring( + pso, + &mat, + STRUCT_OFFSET(pso, 0x214, CLQ *), + &D_00248D30, + STRUCT_OFFSET(pso, 0x218, CLQ *), + dt); + } +} -INCLUDE_ASM("asm/nonmatchings/P2/steprail", FUN_001d34e0); +void FUN_001d34e0(uint8_t *param_1) +{ + FUN_001bc4d8(param_1, param_1 + 0x554); +} -INCLUDE_ASM("asm/nonmatchings/P2/steprail", FUN_001d3500); +int FUN_001d3500(SO *pso, WKR *pwkr) +{ + int fAbsorbed = FAbsorbSoWkr(pso, pwkr); + if (fAbsorbed != 0 && (pwkr->grfic & 0x20)) + { + LO *plo = pwkr->ploSource; + int g; + if (STRUCT_OFFSET(STRUCT_OFFSET(plo, 0x0, uint8_t *), 0x8, int) & 1) + { + g = STRUCT_OFFSET(plo, 0x50, int); + } + else + { + g = STRUCT_OFFSET(STRUCT_OFFSET(plo, 0x18, uint8_t *), 0x50, int); + } + func_001D32D8((int)pso, (JT *)pwkr->ploSource, g == (int)(long)g_pjt); + FreeSwXpList(STRUCT_OFFSET(pso, 0x14, SW *), STRUCT_OFFSET(pso, 0x554, XP *)); + STRUCT_OFFSET(pso, 0x554, XP *) = 0; + } + return fAbsorbed; +} INCLUDE_ASM("asm/nonmatchings/P2/steprail", FUN_001d35a8); diff --git a/src/P2/suv.c b/src/P2/suv.c index c6bbc0257..ebbc91852 100644 --- a/src/P2/suv.c +++ b/src/P2/suv.c @@ -1,4 +1,11 @@ #include +#include +#include +#include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/suv", InitSuv__FP3SUV); @@ -10,7 +17,16 @@ INCLUDE_ASM("asm/nonmatchings/P2/suv", GExcludeAlm__FiP2LMf); INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvBalance__FP3SUV); -INCLUDE_ASM("asm/nonmatchings/P2/suv", DsGetTrackRelative__Ffff); +float DsGetTrackRelative(float track, float relative, float range) +{ + relative -= range; + if (track * 0.5f < relative) { + relative -= track; + } else if (relative < track * (-0.5f)) { + relative += track; + } + return relative; +} INCLUDE_ASM("asm/nonmatchings/P2/suv", FIsSuvAheadOf__FP3SUVT0); @@ -19,6 +35,30 @@ INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvLine__FP3SUVPi); INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvHeading__FP3SUV); INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvWheels__FP3SUV); +#ifdef SKIP_ASM +void UpdateSuvWheels(SUV *psuv) +{ + extern float D_002754F8; + extern float D_002754F4; + extern SMP D_002754E8; + float rad = atan2f(STRUCT_OFFSET(psuv, 0xD4, float), STRUCT_OFFSET(psuv, 0xD0, float)); + rad = RadNormalize(STRUCT_OFFSET(psuv, 0x694, float) - rad); + rad = GLimitAbs(D_002754F8 * rad, D_002754F4); + STRUCT_OFFSET(psuv, 0x69C, float) = RadSmooth(STRUCT_OFFSET(psuv, 0x69C, float), rad, g_clock.dt, &D_002754E8, NULL); + + char *p = (char *)psuv + 0x6B0; + for (int i = 0; i < 4; i++) + { + float gDiv; + if (i < 2) + gDiv = STRUCT_OFFSET(psuv, 0x610, float); + else + gDiv = STRUCT_OFFSET(psuv, 0x614, float); + *(float *)(p + 0x50) = STRUCT_OFFSET(psuv, 0x698, float) / gDiv; + p += 0x60; + } +} +#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvExpls__FP3SUV); @@ -38,7 +78,10 @@ INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvActive__FP3SUVP3JOYf); INCLUDE_ASM("asm/nonmatchings/P2/suv", FUN_001da170); -INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvInternalXps__FP3SUV); +void UpdateSuvInternalXps(SUV *psuv) +{ + STRUCT_OFFSET(psuv, 0x6A0, int) += 1; +} INCLUDE_ASM("asm/nonmatchings/P2/suv", AddSuvCustomXps__FP3SUVP2SOiP3BSPT3PP2XP); @@ -50,13 +93,29 @@ INCLUDE_ASM("asm/nonmatchings/P2/suv", RenderSuvSelf__FP3SUVP2CMP2RO); INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvBounds__FP3SUV); -INCLUDE_ASM("asm/nonmatchings/P2/suv", CollectSuvPrize__FP3SUV3PCKP3ALO); +void CollectSuvPrize(SUV *psuv, PCK pck, ALO *paloOther) +{ + STEPGUARD *pstepguard = STRUCT_OFFSET(psuv, 0xb78, STEPGUARD *); + if (pstepguard != NULL) + { + SetStepguardPatrolAnimation(pstepguard, NULL); + pstepguard = STRUCT_OFFSET(psuv, 0xb78, STEPGUARD *); + (*(void (**)(STEPGUARD *, PCK, ALO *))((char *)pstepguard->pvtlo + 0x148))(pstepguard, pck, paloOther); + } + else + { + CollectPoPrize((PO *)psuv, pck, paloOther); + } +} INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvShapes__FP3SUV); INCLUDE_ASM("asm/nonmatchings/P2/suv", UpdateSuvXfWorld__FP3SUV); -INCLUDE_ASM("asm/nonmatchings/P2/suv", GetSuvCpdefi__FP3SUVfP6CPDEFI); +void GetSuvCpdefi(SUV *psuv, float dt, CPDEFI *pcpdefi) +{ + GetSoCpdefi((SO *)psuv, dt, pcpdefi); +} INCLUDE_ASM("asm/nonmatchings/P2/suv", OnSuvActive__FP3SUViP2PO); diff --git a/src/P2/sw.c b/src/P2/sw.c index 768eb2092..3cef699e7 100644 --- a/src/P2/sw.c +++ b/src/P2/sw.c @@ -8,6 +8,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include extern SW *g_psw; extern int g_fLoadDebugInfo; @@ -44,9 +50,32 @@ void LoadBulkDataFromBrx(CBinaryInputStream *pbis) } } -INCLUDE_ASM("asm/nonmatchings/P2/sw", SetSwGravity__FP2SWf); +static inline VU_VECTOR VuVectorXyz(float x, float y, float z) +{ + VU_VECTOR v; + qword tmp; + asm("mfc1 %0, %2\n\tmfc1 %1, %3\n\tpextlw %0, %1, %0\n\tmfc1 %1, %4\n\tpcpyld %0, %1, %0" + : "=r"(v.data), "=r"(tmp) + : "f"(x), "f"(y), "f"(z)); + return v; +} + +void SetSwGravity(SW *psw, float z) +{ + union + { + qword q; + float af[4]; + } u; -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dbac0); + u.q = VuVectorXyz(0.0f, 0.0f, z).data; + STRUCT_OFFSET(psw, 0x1EE0, qword) = u.q; // vecGravity = (0, 0, z, junk) +} + +void FUN_001dbac0(SW *psw, int reg, int value) +{ + SetAMRegister(reg, value); +} int FUN_001dbae0(SW *psw, int reg) { @@ -58,7 +87,18 @@ void FUN_001dbb00(SW *psw, int reg, int value) UpdateAMRegister(reg, value); } -INCLUDE_ASM("asm/nonmatchings/P2/sw", FOverflowSwLo__FP2SWP2LOi); +int FOverflowSwLo(SW *psw, LO *plo, int fHiPri) +{ + int fOverflow = 0; + + if ((plo->pvtlo->grfcid & 2) && psw->cpsoRoot >= 247) + { + int fLow = (fHiPri == 0); + fOverflow = fLow; + } + + return fOverflow; +} XA *PxaAllocSw(SW *psw) { @@ -155,21 +195,98 @@ void FreeSwStsoList(SW *psw, STSO *pstsoFirst) } } +struct PSL +{ + int cplo; + LO **aplo; +} __attribute__((packed)); + INCLUDE_ASM("asm/nonmatchings/P2/sw", AddSwProxySource__FP2SWP2LOi); +#ifdef SKIP_ASM +void AddSwProxySource(SW *psw, LO *ploProxySource, int cploClone) +{ + PSL psl; + + cploClone -= 1; + psl.cplo = cploClone; + + if (cploClone > 0) + { + LO **aplo = (LO **)PvAllocSwImpl(cploClone << 2); + psl.aplo = aplo; + + if (cploClone > 0) + { + int i = 0; + do + { + aplo[i] = PloCloneLo(ploProxySource, psw, NULL); + i++; + } while (i < cploClone); + } + } -INCLUDE_ASM("asm/nonmatchings/P2/sw", PloGetSwProxySource__FP2SWi); + int cpsl = STRUCT_OFFSET(psw, 0x1EFC, int); + STRUCT_OFFSET(psw, cpsl * 8 + 0x1F00, PSL) = psl; + STRUCT_OFFSET(psw, 0x1EFC, int) = cpsl + 1; +} +#endif // SKIP_ASM + +LO *PloGetSwProxySource(SW *psw, int ipsl) +{ + // Proxy-source list at SW+0x1F00: array of 8-byte {int cplo; LO **aplo} pairs + // (count cpsl lives at 0x1EFC; see AddSwProxySource). + int *p = &STRUCT_OFFSET(psw, ipsl * 8 + 0x1F00, int); + int c = p[0] - 1; + LO **aplo = (LO **)p[1]; + int i = c * 4; + asm volatile(""); // scheduling barrier: preserve the original count-store ordering + p[0] = c; + return *(LO **)(i + (int)aplo); +} INCLUDE_ASM("asm/nonmatchings/P2/sw", IntersectSwBoundingBox__FP2SWP2SOP6VECTORT2PFPvP2SO_iPvPiPPP2SO); INCLUDE_ASM("asm/nonmatchings/P2/sw", IntersectSwBoundingSphere__FP2SWP2SOP6VECTORfPFPvP2SO_iPvPiPPP2SO); -INCLUDE_ASM("asm/nonmatchings/P2/sw", RemoveOxa__FP3OXAPP3OXA); +void RemoveOxa(OXA *poxa, OXA **ppoxaFirst) +{ + if (poxa->poxaNext != NULL) + { + poxa->poxaNext->poxaPrev = poxa->poxaPrev; + } + + if (poxa->poxaPrev != NULL) + { + poxa->poxaPrev->poxaNext = poxa->poxaNext; + } + else + { + *ppoxaFirst = poxa->poxaNext; + } +} INCLUDE_ASM("asm/nonmatchings/P2/sw", InitSwAoxa__FP2SW); -INCLUDE_ASM("asm/nonmatchings/P2/sw", AddOxa__FP3OXAPP3OXA); +void AddOxa(OXA *poxa, OXA **ppoxaFirst) +{ + poxa->poxaNext = *ppoxaFirst; + poxa->poxaPrev = NULL; + if (*ppoxaFirst != NULL) + { + (*ppoxaFirst)->poxaPrev = poxa; + } + *ppoxaFirst = poxa; +} -INCLUDE_ASM("asm/nonmatchings/P2/sw", PoxaAllocSw__FP2SWP2SO); +OXA *PoxaAllocSw(SW *psw, SO *pso) +{ + OXA *poxa = STRUCT_OFFSET(psw, 0x1AE4, OXA *); + RemoveOxa(poxa, &STRUCT_OFFSET(psw, 0x1AE4, OXA *)); + AddOxa(poxa, &STRUCT_OFFSET(psw, 0x1AE8, OXA *)); + poxa->pso = pso; + return poxa; +} INCLUDE_ASM("asm/nonmatchings/P2/sw", FreeSwPoxa__FP2SWP3OXA); @@ -199,7 +316,27 @@ INCLUDE_ASM("asm/nonmatchings/P2/sw", FClipLineHomogeneous__FP7VECTOR4); INCLUDE_ASM("asm/nonmatchings/P2/sw", DrawLineWorld__FP6VECTORT0G4RGBAP2CMi); +void DrawLineWorld(VECTOR *ppos1, VECTOR *ppos2, RGBA rgba, CM *pcm, int fDepthTest); + INCLUDE_ASM("asm/nonmatchings/P2/sw", DrawAxesWorld__FP6VECTORP7MATRIX3fP2CMi); +#ifdef SKIP_ASM +void DrawAxesWorld(VECTOR *ppos, MATRIX3 *pmat, float sScale, CM *pcm, int fDepthTest) +{ + VECTOR4 apos[10]; + RGBA rgba; + + TesselateBezier(sScale, 0.0f, sScale, ppos, (VECTOR *)pmat, + (VECTOR *)((char *)0), (VECTOR *)((char *)0), 10, (VECTOR *)apos); + + rgba = *(RGBA *)pcm; + + for (int i = 1; i < 10; i++) + { + DrawLineWorld((VECTOR *)&apos[i - 1], (VECTOR *)&apos[i], rgba, + (CM *)(long)fDepthTest, 1); + } +} +#endif // SKIP_ASM void SetSwIllum(SW *psw, float uMidtone) { @@ -243,13 +380,61 @@ int FLevelSwTertiary(SW *psw, WID wid) INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dd710); -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dd758); +uint GrflsLevelCompletionFromWid(int wid) __asm__("get_level_completion_by_id"); -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dd7a0); +int FUN_001dd758(SW *psw, int wid) +{ + uint grfls = GrflsLevelCompletionFromWid(wid); + uint f = 0; + uint mask = grfls & 3; + + if (grfls & 4) + { + LS *pls = g_plsCur; + f = (mask & pls->fls) ^ mask; + f = f < 1; + } + + return f; +} + +uint GrflsLevelCompletionFromWid(int wid) __asm__("get_level_completion_by_id"); + +int FUN_001dd7a0(SW *psw, int wid) +{ + uint grfls = GrflsLevelCompletionFromWid(wid); + int f = 0; + uint mask = grfls & 7; + + if (grfls & 8) + { + uint t = mask & g_plsCur->fls; + f = (t ^ mask) < 1; + } + + return f; +} INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dd7e8); -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dd888); + +int FUN_001dd888(SW *psw, WID wid, int nKey) +{ + int *pls = LsFromWid(wid); + if (pls != NULL) + { + int *p = pls + 0x11; + int i = 0; + do + { + if (p[0] == nKey) + return p[1]; + i++; + p += 2; + } while ((unsigned)i < 4); + } + return 0; +} int FUN_001dd8e8(SW *psw, GAMEWORLD gameworld) { @@ -261,9 +446,20 @@ int FUN_001dd908(SW *psw, GAMEWORLD gameworld) return g_pgsCur->aws[gameworld].fws & 0x20; } -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dd928); +int FUN_001dd928(SW *psw) +{ + return CalculatePercentCompletion(g_pgsCur); +} + +void FUN_001dd950(SW *psw, int nLow, int nHigh, VECTOR *pposCenter) +{ + int cpdprize = NRandInRange(nLow, nHigh); -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001dd950); + if (cpdprize != 0) + { + CpdprizeAttractSwDprizes(g_psw, (CID)0x58, pposCenter, cpdprize, NULL); + } +} void FUN_001dd9a0(float nParam) { @@ -332,28 +528,89 @@ void CancelSwDialogPlaying(SW *psw) } } -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddb20); +typedef struct +{ + int n; +} __attribute__((packed)) UNALIGNED_INT; + +extern PROMPT D_0026FF68; -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddb58); +void FUN_001ddb20(SW *psw, PRK prk, int oid) +{ + PROMPT *pprompt = &D_0026FF68; -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddbb8); + STRUCT_OFFSET(pprompt, 0x280, UNALIGNED_INT).n = oid; + SetPrompt(pprompt, PRP_Basic, prk); +} + +extern BLOT D_002721D0; + +void FUN_001ddb58(SW *psw) +{ + if (++STRUCT_OFFSET(psw, 0x2320, int) == 1) + { + SetBlotDtVisible(&D_002721D0, 0.0f); + D_002721D0.pvtblot->pfnShowBlot(&D_002721D0); + } +} + +extern BLOT D_002721D0; + +void FUN_001ddbb8(SW *psw) +{ + if (--STRUCT_OFFSET(psw, 0x2320, int) == 0) + { + D_002721D0.pvtblot->pfnHideBlot(&D_002721D0); + } +} JUNK_WORD(0x0002102a); -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddbf8); +EXC *FUN_001ddbf8(SW *psw, int gexc) +{ + return PexcSetExcitement(gexc); +} + +void FUN_001ddc18(SW *psw, EXC *pexc) +{ + UnsetExcitementHyst(pexc); +} -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddc18); +void FUN_001ddc38(void *pv, void *pvBlot) +{ + STRUCT_OFFSET(pv, 0x2324, void *) = pvBlot; +} -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddc38); +void FUN_001ddc40(void *pv) +{ + typedef void (*PFNBLOT)(void *); -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddc40); + void *pvBlot = STRUCT_OFFSET(pv, 0x2324, void *); // blot/vtable'd object set by FUN_001ddc38 + if (pvBlot != NULL) + { + PFNBLOT pfn = STRUCT_OFFSET(STRUCT_OFFSET(pvBlot, 0x0, void *), 0xC8, PFNBLOT); + if (pfn != NULL) + { + pfn(pvBlot); + } + } +} void FUN_001ddc78(void *pv, int n) { STRUCT_OFFSET(pv, 0x235C, int) |= (1 << n); } -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddc90); +void FUN_001ddc90(void *pv, int n) +{ + STRUCT_OFFSET(pv, 0x235C, int) &= ~(1 << n); +} -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddcb0); +void FUN_001ddcb0(void *pv, int *pccharm) +{ + *pccharm = g_pgsCur->ccharm; +} -INCLUDE_ASM("asm/nonmatchings/P2/sw", FUN_001ddcc8); +void FUN_001ddcc8(void *pv, int *pclife) +{ + *pclife = g_pgsCur->clife; +} diff --git a/src/P2/tank.c b/src/P2/tank.c index 622fd9a72..0e7ec8eb7 100644 --- a/src/P2/tank.c +++ b/src/P2/tank.c @@ -1,13 +1,59 @@ #include #include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/tank", InitTank__FP4TANK); +extern qword D_00275740; + +void InitTank(TANK *ptank) +{ + InitStep((STEP *)ptank); + + float rad = atan2f(STRUCT_OFFSET(ptank, 0xD4, float), STRUCT_OFFSET(ptank, 0xD0, float)); + STRUCT_OFFSET(ptank, 0x638, float) = rad; + LoadRotateMatrixRad(rad, &g_normalZ, (MATRIX3 *)((uint8_t *)ptank + 0x660)); + + STRUCT_OFFSET(ptank, 0x720, int) = -1; + STRUCT_OFFSET(ptank, 0x72C, float) = -10.0f; + STRUCT_OFFSET(ptank, 0x6F0, qword) = D_00275740; +} INCLUDE_ASM("asm/nonmatchings/P2/tank", PostTankLoad__FP4TANK); INCLUDE_ASM("asm/nonmatchings/P2/tank", UpdateTank__FP4TANKf); -INCLUDE_ASM("asm/nonmatchings/P2/tank", FUN_001deb30); +static inline VU_VECTOR VuVectorXyz(float x, float y, float z) +{ + VU_VECTOR v; + qword tmp; + asm("mfc1 %0, %2\n\tmfc1 %1, %3\n\tpextlw %0, %1, %0\n\tmfc1 %1, %4\n\tpcpyld %0, %1, %0" + : "=r"(v.data), "=r"(tmp) + : "f"(x), "f"(y), "f"(z)); + return v; +} + +void FUN_001deb30(TANK *ptank) +{ + union + { + qword q; + float af[4]; + } u; + float radPanTarget; + float radTiltTarget; + float svTarget; + + CalculateAloDrive((ALO *)ptank, NULL, NULL, g_clock.dt, + STRUCT_OFFSET(ptank, 0x638, float), + &radPanTarget, &radTiltTarget, &svTarget); + + STRUCT_OFFSET(ptank, 0x638, float) = radPanTarget; + LoadRotateMatrixPanTilt(radPanTarget, radTiltTarget, + (MATRIX3 *)((uint8_t *)ptank + 0x660)); + + u.q = VuVectorXyz(-svTarget, 0.0f, 0.0f).data; + STRUCT_OFFSET(ptank, 0x640, qword) = u.q; +} void UseTankCharm(TANK *ptank) { @@ -40,7 +86,52 @@ INCLUDE_ASM("asm/nonmatchings/P2/tank", FUN_001dfa10); INCLUDE_ASM("asm/nonmatchings/P2/tank", AdjustTankNewXp__FP4TANKP2XPi); +#ifndef SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/tank", HandleTankMessage__FP4TANK5MSGIDPv); +#else +void HandleTankMessage(TANK *ptank, MSGID msgid, void *pv) +{ + OID oidCur; + OID oidGoal; + + switch (msgid) + { + case (MSGID)0x14: + if (pv == STRUCT_OFFSET(ptank, 0x75C, void *)) + { + GetSmaCur((SMA *)pv, &oidCur); + GetSmaGoal(STRUCT_OFFSET(ptank, 0x75C, SMA *), &oidGoal); + } + break; + + case (MSGID)0x13: + { + SMA *psma = STRUCT_OFFSET(ptank, 0x75C, SMA *); + if (psma != NULL) + { + if (STRUCT_OFFSET(pv, 0x0, ASEGA *) == psma->pasegaCur) + { + int label = STRUCT_OFFSET(pv, 0x8, int); + if (label != 0x15E) + { + if (label == 0x15F) + { + STRUCT_OFFSET(ptank, 0x738, int) = 0; + } + } + else + { + STRUCT_OFFSET(ptank, 0x738, int) = 1; + } + } + } + break; + } + } + + HandlePoMessage(ptank, msgid, pv); +} +#endif JTHS JthsCurrentTank(TANK *ptank) { diff --git a/src/P2/tn.c b/src/P2/tn.c index 6b8c395bc..41f5bcea9 100644 --- a/src/P2/tn.c +++ b/src/P2/tn.c @@ -1,12 +1,48 @@ #include #include #include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/tn", PtnfnFromTn__FP2TN); +extern TNFN D_00275980; +extern VECTOR D_00275A10; +extern char D_00275A20[8]; + +TNFN *PtnfnFromTn(TN *ptn) +{ + return ptn == NULL ? &D_00275980 : (TNFN *)((uint8_t *)ptn + 0x2F0); +} INCLUDE_ASM("asm/nonmatchings/P2/tn", GetTnfnNose__FP4TNFNP6CPDEFIP6VECTORP2TN); +struct TNFN_DATA { char rgb[0x90]; }; + INCLUDE_ASM("asm/nonmatchings/P2/tn", InitTn__FP2TN); +#ifdef SKIP_ASM +void InitTn(TN *ptn) +{ + uint64_t flags; + + InitAlo(ptn); + + *(struct TNFN_DATA *)((char *)ptn + 0x2F0) = *(struct TNFN_DATA *)&D_00275980; + + flags = STRUCT_OFFSET(ptn, 0x2C8, uint64_t); + flags &= ~((uint64_t)0x300 << 32); + flags |= ((uint64_t)0x8000 << 25); + + STRUCT_OFFSET(ptn, 0x420, float) = 2.0f; + STRUCT_OFFSET(ptn, 0x424, float) = 1.0f; + STRUCT_OFFSET(ptn, 0x2C8, uint64_t) = flags; + STRUCT_OFFSET(ptn, 0x428, float) = 2.0f; + STRUCT_OFFSET(ptn, 0x42C, float) = 1.0f; + STRUCT_OFFSET(ptn, 0x430, int) = -1; + + *(VECTOR *)((char *)ptn + 0x450) = D_00275A10; + *(uint64_t *)((char *)ptn + 0x460) = *(uint64_t *)D_00275A20; + STRUCT_OFFSET(ptn, 0x398, int) = -1; +} +#endif // SKIP_ASM void OnTnRemove(TN *ptn) { @@ -23,6 +59,34 @@ void PostTnLoad(TN *ptn) } INCLUDE_ASM("asm/nonmatchings/P2/tn", SetTnTns__FP2TN3TNS); +#ifdef SKIP_ASM +void SetTnTns(TN *ptn, TNS tns) +{ + if (STRUCT_OFFSET(ptn, 0x394, TNS) == tns) + return; + + if (tns == TNS_Out) + { + RevokeCmPolicy(g_pcm, 8, CPP_Nil, NULL, NULL, ptn); + HandleLoSpliceEvent(ptn, 3, 0, NULL); + STRUCT_OFFSET(ptn, 0x394, TNS) = tns; + } + else if (tns == TNS_In) + { + SetCmPolicy(g_pcm, (CPP)(STRUCT_OFFSET(ptn, 0x388, int) + 2), + &STRUCT_OFFSET(g_pcm, 0x520, CPLCY), + STRUCT_OFFSET(ptn, 0x2D0, SO *), ptn); + HandleLoSpliceEvent(ptn, 2, 0, NULL); + STRUCT_OFFSET(ptn, 0x394, TNS) = tns; + } + else + { + STRUCT_OFFSET(ptn, 0x394, TNS) = tns; + } + + STRUCT_OFFSET(ptn, 0x39C, float) = g_clock.t; +} +#endif // SKIP_ASM /** * @todo Rename. @@ -40,6 +104,37 @@ void FUN_001e2840(TN *ptn, TNS tns) } INCLUDE_ASM("asm/nonmatchings/P2/tn", UpdateTnCallback__FP2TN5MSGIDPv); +#ifdef SKIP_ASM +void UpdateTnCallback(TN *ptn, MSGID msgid, void *pv) +{ + PO *ppo = PpoCur(); + if (ppo == NULL) + return; + + if (ppo != STRUCT_OFFSET(ptn, 0x2D0, PO *)) + { + SetTnTns(ptn, TNS_Out); + STRUCT_OFFSET(ptn, 0x2D0, PO *) = ppo; + } + + VECTOR posLocal; + TNS tns = STRUCT_OFFSET(ptn, 0x398, TNS); + if (tns == TNS_Nil) + { + ConvertAloPos(NULL, ptn, (VECTOR *)((char *)ppo + 0x140), &posLocal); + tns = (TNS)(FCheckTbspPoint(STRUCT_OFFSET(ptn, 0x2E0, TBSP *), &posLocal) != 0); + } + + if (STRUCT_OFFSET(ptn, 0x384, int) == 0 && ppo == (PO *)g_pjt && + STRUCT_OFFSET(ppo, 0x2220, int) == 2 && g_pcm->field41_0x224 == 0 && + STRUCT_OFFSET(ptn, 0x398, TNS) == TNS_Nil) + { + return; + } + + SetTnTns(ptn, tns); +} +#endif // SKIP_ASM void UpdateTn(TN *ptn, float dt) { @@ -64,7 +159,12 @@ void FreezeTn(TN *ptn, int fFreeze) } } -INCLUDE_ASM("asm/nonmatchings/P2/tn", FUN_001e29e8); +void FUN_001e29e8(TN *ptn, float g) +{ + STRUCT_OFFSET(ptn, 0x364, float) = g; + STRUCT_OFFSET(ptn, 0x368, float) = 1.0f; + STRUCT_OFFSET(ptn, 0x360, float) = g; +} INCLUDE_ASM("asm/nonmatchings/P2/tn", CalculateTnCrv__FP2TNP6VECTORN21); @@ -72,7 +172,18 @@ INCLUDE_ASM("asm/nonmatchings/P2/tn", CalculateTnPos__FP2TNP6VECTORffP3CLQP2LM4F INCLUDE_ASM("asm/nonmatchings/P2/tn", ActivateCptn__FP4CPTNPv); -INCLUDE_ASM("asm/nonmatchings/P2/tn", DeactivateCptn__FP4CPTNPv); +void DeactivateCptn(CPTN *pcptn, void *pv) +{ + TN *ptn = pcptn->ptn; + if (ptn != NULL) + { + if (STRUCT_OFFSET(ptn, 0x438, float) != 0.0f) + { + STRUCT_OFFSET(g_pcm, 0x1c8, float) = STRUCT_OFFSET(ptn, 0x43c, float); + } + } + pcptn->ptn = NULL; +} void SetCptn(CPTN *pcptn, void *pv) { @@ -90,7 +201,10 @@ INCLUDE_ASM("asm/nonmatchings/P2/tn", UpdateCptn__FP4CPTNP6CPDEFIP3JOYf); INCLUDE_ASM("asm/nonmatchings/P2/tn", FUN_001e4578); -INCLUDE_ASM("asm/nonmatchings/P2/tn", FUN_001e4880); +float FUN_001e4880(int a, int b, int c, void *p) +{ + return STRUCT_OFFSET(p, 0x20, float); +} INCLUDE_ASM("asm/nonmatchings/P2/tn", FUN_001e4888); diff --git a/src/P2/turret.c b/src/P2/turret.c index b09fec360..afd4ec163 100644 --- a/src/P2/turret.c +++ b/src/P2/turret.c @@ -1,5 +1,11 @@ #include #include +#include +#include +#include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/turret", InitTurret__FP6TURRET); @@ -9,7 +15,31 @@ INCLUDE_ASM("asm/nonmatchings/P2/turret", PostTurretLoad__FP6TURRET); INCLUDE_ASM("asm/nonmatchings/P2/turret", UpdateTurret__FP6TURRETf); -INCLUDE_ASM("asm/nonmatchings/P2/turret", UpdateTurretActive__FP6TURRETP3JOYf); +void UpdateTurretActive(TURRET *pturret, JOY *pjoy, float dt) +{ + char b[0xC4]; + + UpdateTurretAim(pturret); + + if ((pjoy->grfbtnPressed & 0xC0) != 0) + { + SetJoyBtnHandled(pjoy, 0xC0); + FireTurret(pturret); + } + + if (g_pjt != NULL && STRUCT_OFFSET(g_pjt, 0x2740, int) != 0) + { + if (FIsLoInWorld(g_pjt)) + { + void (*pfn)(JT *, void *, float); + + memset(b, 0, 0xC4); + pfn = (void (*)(JT *, void *, float))STRUCT_OFFSET(g_pjt->pvtlo, 0x134, void *); + if (pfn != 0) + pfn(g_pjt, b, dt); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/turret", OnTurretActive__FP6TURRETiP2PO); @@ -17,7 +47,22 @@ INCLUDE_ASM("asm/nonmatchings/P2/turret", FFilterTurret__FP6TURRETP2SO); INCLUDE_ASM("asm/nonmatchings/P2/turret", UpdateTurretAim__FP6TURRET); -INCLUDE_ASM("asm/nonmatchings/P2/turret", FireTurret__FP6TURRET); +void FireTurret(TURRET *pturret) +{ + OID oidCur; + OID oidGoal; + + GetSmaCur(STRUCT_OFFSET(pturret, 0x614, SMA *), &oidCur); + GetSmaGoal(STRUCT_OFFSET(pturret, 0x614, SMA *), &oidGoal); + + if (oidCur == (OID)0x359 && oidGoal == oidCur) + { + if (FEnsureRwmLoaded(STRUCT_OFFSET(pturret, 0x618, RWM *))) + { + SetSmaGoal(STRUCT_OFFSET(pturret, 0x614, SMA *), (OID)0x35A); + } + } +} INCLUDE_ASM("asm/nonmatchings/P2/turret", HandleTurretMessage__FP6TURRET5MSGIDPv); @@ -31,4 +76,8 @@ void GetTurretDiapi(TURRET *pturret, DIALOG *pdialog, DIAPI *pdiapi) pdiapi->fPlayable = 0; } -INCLUDE_ASM("asm/nonmatchings/P2/turret", FUN_001e5e60); +int FUN_001e5e60(int n) +{ + int v = STRUCT_OFFSET(n, 0x620, int); + return v != 0 ? v : n; +} diff --git a/src/P2/ub.c b/src/P2/ub.c index ca3f7d3a3..e92aaca96 100644 --- a/src/P2/ub.c +++ b/src/P2/ub.c @@ -1,8 +1,37 @@ #include +extern SNIP s_asnipLoadUbg[8]; // @todo migrate from asm/data/P2/ub.data.s and make static + INCLUDE_ASM("asm/nonmatchings/P2/ub", InitUbg__FP3UBG); +#ifndef SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/ub", PostUbgLoad__FP3UBG); +#else +void PostUbgLoad(UBG *pubg) +{ + SnipAloObjects((ALO *)pubg, 8, s_asnipLoadUbg); + FUN_001ddc38(STRUCT_OFFSET(pubg, 0x14, void *), pubg); + + if (STRUCT_OFFSET(pubg, 0xC50, void *) != NULL) + { + STRUCT_OFFSET(pubg, 0xC54, SMA *) = + PsmaApplySm(STRUCT_OFFSET(pubg, 0xC50, SM *), NULL, (OID)0x2D7, 0); + } + + STRUCT_OFFSET(pubg, 0xC90, int) = 4; + + int *pichk = &STRUCT_OFFSET(pubg, 0xC80, int); + int i = 0; + do + { + *pichk = IchkAllocChkmgr(&g_chkmgr); + i++; + pichk++; + } while ((uint)i < 4); + + PostGomerLoad(pubg); +} +#endif INCLUDE_ASM("asm/nonmatchings/P2/ub", PsoPadUbgClosest__FP3UBGP6VECTOR); diff --git a/src/P2/vifs.c b/src/P2/vifs.c index ce2682da1..a69a66e4c 100644 --- a/src/P2/vifs.c +++ b/src/P2/vifs.c @@ -66,11 +66,40 @@ INCLUDE_ASM("asm/nonmatchings/P2/vifs", AddVifStmask__4VIFSUi); INCLUDE_ASM("asm/nonmatchings/P2/vifs", CbUnpackSetup__4VIFS3UPKii); -INCLUDE_ASM("asm/nonmatchings/P2/vifs", UnpackHelper__4VIFS3UPKiiPiPPUi); +void VIFS::UnpackHelper(UPK upk, int c, int iqw, int *pcb, uint **ppun) +{ + if (c == 0) + { + if (ppun != NULL) + *ppun = 0; + if (pcb != NULL) + *pcb = 0; + return; + } + + int cb = CbUnpackSetup(upk, c, iqw); + if (ppun != NULL) + *ppun = (uint *)m_pb; + m_pb = m_pb + ((cb + 3) / 4) * 4; + if (pcb != NULL) + *pcb = cb; +} INCLUDE_ASM("asm/nonmatchings/P2/vifs", AddVifUnpack__4VIFS3UPKiPvi); -INCLUDE_ASM("asm/nonmatchings/P2/vifs", AddVifUnpackRefs__4VIFS3UPKiPviPPPv); +void VIFS::AddVifUnpackRefs(UPK upk, int c, void *pvSrc, int iqw, void ***pppv) +{ + if (c == 0) + return; + + Align(3); + + int cb = CbUnpackSetup(upk, c, iqw); + AddDmaRefs((cb + 15) / 16, (QW *)pvSrc); + + if (pppv != NULL) + *pppv = (void **)((char *)m_pqwCnt - 0xC); +} /** * @todo Figure out why using the inlined function doesn't work here. diff --git a/src/P2/vis.c b/src/P2/vis.c index ce0570169..35db162af 100644 --- a/src/P2/vis.c +++ b/src/P2/vis.c @@ -45,12 +45,6 @@ GRFZON GrfzonOneHop(VISMAP *pvismap, VBSP *pvbsp) INCLUDE_ASM("asm/nonmatchings/P2/vis", ClipVbspSphereOneHop__FP6VISMAPP4VBSPG9VU_VECTORfPi); -/** - * @brief 89.47% match. Single load instruction mismatch. VU_VECTOR implemented wrong? - * https://decomp.me/scratch/5lzfX - */ -INCLUDE_ASM("asm/nonmatchings/P2/vis", ClipVismapSphereOneHop__FP6VISMAPP6VECTORfPi); -#ifdef SKIP_ASM void ClipVismapSphereOneHop(VISMAP *pvismap, VECTOR *ppos, float sRadius, GRFZON *pgrfzon) { if (pvismap && pvismap->avbsp) @@ -63,6 +57,5 @@ void ClipVismapSphereOneHop(VISMAP *pvismap, VECTOR *ppos, float sRadius, GRFZON *pgrfzon = 0xfffffff; } -#endif // SKIP_ASM INCLUDE_ASM("asm/nonmatchings/P2/vis", ClipVismapPointNoHop__FP6VISMAPP6VECTORPi); diff --git a/src/P2/water.c b/src/P2/water.c index b94fae0c5..645e96baf 100644 --- a/src/P2/water.c +++ b/src/P2/water.c @@ -1,6 +1,11 @@ #include #include #include +#include +#include + +struct JT; +extern JT *g_pjt; void InitWater(WATER *pwater) { @@ -20,7 +25,38 @@ void InitWater(WATER *pwater) INCLUDE_ASM("asm/nonmatchings/P2/water", PostWaterLoad__FP5WATER); -INCLUDE_ASM("asm/nonmatchings/P2/water", CalculateWaterCurrent__FP5WATERP6VECTORN21); +void CalculateWaterCurrent(WATER *pwater, VECTOR *ppos, VECTOR *pv, VECTOR *pw) +{ + VU_VECTOR vec0; + VU_VECTOR vecPos; + VU_VECTOR vecCur; + VU_VECTOR vecWarp; + + ConvertAloVec(NULL, pwater, ppos, (VECTOR *)&vec0); + *(int *)((char *)&vec0 + 8) = 0; + vecPos = pwater->vecCurrent; + vecCur = *(VU_VECTOR *)&D_00248D30; + CalculateAloTransformAdjust(pwater, NULL, (VECTOR *)&vec0, NULL, (VECTOR *)&vecPos, (VECTOR *)&vecCur); + + void *p278 = STRUCT_OFFSET(pwater, 0x278, void *); + if (p278 != NULL) + { + WR *pwr = STRUCT_OFFSET(p278, 0xC, WR *); + WarpWrTransform(pwr, 50.0f, ppos, NULL, NULL, NULL, (VECTOR *)&vecWarp); + asm volatile( + "lqc2 $vf1, %1\n\t" + "lqc2 $vf2, %2\n\t" + "vadd.xyzw $vf1, $vf1, $vf2\n\t" + "sqc2 $vf1, %0" + : "=m"(vecPos) + : "m"(vecPos), "m"(vecWarp)); + } + + if (pv != NULL) + *(VU_VECTOR *)pv = vecPos; + if (pw != NULL) + *(VU_VECTOR *)pw = vecCur; +} void UpdateSwXaList(SW *psw, XA **ppxa) { @@ -96,9 +132,139 @@ void UpdateWaterMergeGroup(WATER *pwater) AddSwMergeGroup(pwater->psw, pmrg); } +/** + * @brief ~95% match; kept under SKIP_ASM until the permuter settles the g_pjt height branch. + */ INCLUDE_ASM("asm/nonmatchings/P2/water", UGetWaterSubmerged__FP5WATERP2SOP6VECTORT2); +#ifdef SKIP_ASM +float UGetWaterSubmerged(WATER *pwater, SO *pso, VECTOR *pposSurface, VECTOR *pnormalSurface) +{ + VECTOR4 aedge[2]; + LSG alsg[16]; + VECTOR4 scratch; -INCLUDE_ASM("asm/nonmatchings/P2/water", UpdateWaterBounds__FP5WATER); + void *p278 = STRUCT_OFFSET(pwater, 0x278, void *); + if (p278 != NULL) + { + WR *pwr = STRUCT_OFFSET(p278, 0xC, WR *); + WarpWrTransform(pwr, 50.0f, (VECTOR *)((char *)pso + 0x140), NULL, (VECTOR *)&aedge[0], NULL, NULL); + // %0=aedge[0] %1=aedge[1] %2=scratch %3=pso->pos %4=aedge[0](warp) + asm volatile( + ".set noat\n\t" + "lui $1, 0x4000\n\t" + "mtc1 $1, $f0\n\t" + "lui $1, 0xbf80\n\t" + "mtc1 $1, $f1\n\t" + ".set at\n\t" + "mfc1 $2, $f0\n\t" + "qmtc2.ni $2, $vf3\n\t" + "lqc2 $vf1, %3\n\t" + "mfc1 $2, $f1\n\t" + "qmtc2.ni $2, $vf4\n\t" + "lqc2 $vf2, %4\n\t" + "vmulax.xyzw ACC, $vf1, $vf3x\n\t" + "vmaddx.xyzw $vf1, $vf2, $vf4x\n\t" + "sqc2 $vf3, %2\n\t" + "sqc2 $vf1, %0\n\t" + "sqc2 $vf4, %2\n\t" + "sqc2 $vf1, %1" + : "=m"(aedge[0]), "=m"(aedge[1]), "=m"(scratch) + : "m"(STRUCT_OFFSET(pso, 0x140, VU_VECTOR)), "m"(aedge[0]) + : "$1", "$2", "$f0", "$f1"); + } + else + { + *(VU_VECTOR *)&aedge[0] = STRUCT_OFFSET(pso, 0x140, VU_VECTOR); + *(VU_VECTOR *)&aedge[1] = *(VU_VECTOR *)&aedge[0]; + } + + if ((void *)pso == (void *)g_pjt) + { + float z = aedge[0].z + -75.0f; + if (STRUCT_OFFSET(pso, 0x690, int) == 0) + aedge[0].z = z; + else + { + float m = STRUCT_OFFSET(pso, 0x6A8, float); + aedge[0].z = m > z ? m : z; + } + } + else + { + aedge[0].z += STRUCT_OFFSET(pso, 0x428, float) - STRUCT_OFFSET(pso, 0x148, float); + } + + aedge[1].z += STRUCT_OFFSET(pso, 0x438, float) - STRUCT_OFFSET(pso, 0x148, float); + + if (ClsgClipEdgeToBsp(STRUCT_OFFSET(pwater, 0x3F8, BSP *), (VECTOR *)&aedge[0], (VECTOR *)&aedge[1], NULL, 0x10, alsg) == 0) + { + if (pnormalSurface != NULL) + *(VU_VECTOR *)pnormalSurface = *(VU_VECTOR *)&g_normalZ; + return 0.0f; + } + + if (pposSurface != NULL) + *(VU_VECTOR *)pposSurface = *(VU_VECTOR *)&alsg[0].apos[1]; + + if (pnormalSurface != NULL) + { + void *pn = STRUCT_OFFSET(&alsg[0], 0x54, void *); + if (pn != NULL) + *(VU_VECTOR *)pnormalSurface = *(VU_VECTOR *)pn; + else + *(VU_VECTOR *)pnormalSurface = *(VU_VECTOR *)&g_normalZ; + } + + return alsg[0].au[1] - alsg[0].au[0]; +} +#endif + +void UpdateWaterBounds(WATER *pwater) +{ + UpdateSoBounds(pwater); + + void *p278 = STRUCT_OFFSET(pwater, 0x278, void *); + if (p278 == NULL) + return; + + WR *pwr = STRUCT_OFFSET(p278, 0xC, WR *); + if (pwr == NULL) + return; + + VU_VECTOR dpos; + GetWrBounds(pwr, (VECTOR *)&dpos); + + // %0=vecBoundsMin %1=vecBoundsMax %2=sRadiusBounds %3=unk_0x3d4 %4=dpos + asm volatile( + "lqc2 $vf3, %4\n\t" + "vmul.xyz $vf1, $vf3, $vf3\n\t" + "vaddw.x $vf2, $vf0, $vf0w\n\t" + "vadday.x ACC, $vf1, $vf1y\n\t" + "vmaddz.x $vf1, $vf2, $vf1z\n\t" + "lwc1 $f2, %2\n\t" + ".word 0x4A0103BD\n\t" // vsqrt Q, $vf1x + "vwaitq\n\t" + "vaddq.x $vf1, $vf0, Q\n\t" + "lwc1 $f0, %3\n\t" + "qmfc2.ni $2, $vf1\n\t" + "mtc1 $2, $f1\n\t" + "lqc2 $vf2, %0\n\t" + "lqc2 $vf1, %1\n\t" + "add.s $f0, $f0, $f1\n\t" + "add.s $f2, $f2, $f1\n\t" + "vsub.xyzw $vf2, $vf2, $vf3\n\t" + "vadd.xyzw $vf1, $vf1, $vf3\n\t" + "sqc2 $vf2, %0\n\t" + "sqc2 $vf1, %1\n\t" + "swc1 $f0, %3\n\t" + "swc1 $f2, %2" + : "=m"(STRUCT_OFFSET(pwater, 0x420, VECTOR4)), + "=m"(STRUCT_OFFSET(pwater, 0x430, VECTOR4)), + "=m"(STRUCT_OFFSET(pwater, 0x3d0, float)), + "=m"(STRUCT_OFFSET(pwater, 0x3d4, float)) + : "m"(dpos) + : "$f0", "$f1", "$f2", "$2"); +} int FInflictWaterZap(WATER *pwater, XP *pxp, ZPR *pzpr) { diff --git a/src/P2/wipe.c b/src/P2/wipe.c index e9353e40f..3dc3160d7 100644 --- a/src/P2/wipe.c +++ b/src/P2/wipe.c @@ -22,22 +22,22 @@ INCLUDE_ASM("asm/nonmatchings/P2/wipe", DrawWipe__FP4WIPE); #ifdef SKIP_ASM void DrawWipe(WIPE *pwipe) { - if (!g_psw || !g_pwipe) + if (g_psw == NULL || g_pwipe == NULL) { return; } WIPEK wipek = pwipe->wipek; - if (wipek != WIPEK_Keyhole) + if (wipek == WIPEK_Keyhole) { - if (wipek > WIPEK_Keyhole || wipek == WIPEK_Fade) + if (g_pkeyhole != NULL) { + DrawKeyhole(g_pkeyhole, pwipe->uBlack); return; } } - if (g_pkeyhole) + else if (wipek >= WIPEK_WorldMap || wipek != WIPEK_Fade) { - DrawKeyhole(g_pkeyhole, pwipe->uBlack); return; } @@ -47,7 +47,11 @@ void DrawWipe(WIPE *pwipe) INCLUDE_ASM("asm/nonmatchings/P2/wipe", ActivateWipe__FP4WIPEP5TRANS5WIPEK); -INCLUDE_ASM("asm/nonmatchings/P2/wipe", SetWipeButtonTrans__FP4WIPEP5TRANS5WIPEK); +void SetWipeButtonTrans(WIPE *pwipe, TRANS *ptrans, WIPEK wipek) +{ + STRUCT_OFFSET(pwipe, 0x28, TRANS) = *ptrans; + STRUCT_OFFSET(pwipe, 0x3c, WIPEK) = wipek; +} INCLUDE_ASM("asm/nonmatchings/P2/wipe", FCatchWipeButtonTrans__FP4WIPEP3JOY5WIPES); diff --git a/src/P2/wm.c b/src/P2/wm.c index 2edf1c0d7..622f5740e 100644 --- a/src/P2/wm.c +++ b/src/P2/wm.c @@ -1,6 +1,15 @@ #include +#include +#include -INCLUDE_ASM("asm/nonmatchings/P2/wm", FUN_001f0468); +extern int D_00275BF0; + +int FUN_001f0468(void) +{ + if (D_00275BF0 != 2) + return STRUCT_OFFSET(g_pgsCur, 0x19DC, int); + return 10; +} INCLUDE_ASM("asm/nonmatchings/P2/wm", FUN_001f0490); @@ -12,19 +21,55 @@ INCLUDE_ASM("asm/nonmatchings/P2/wm", BindWm__FP2WM); INCLUDE_ASM("asm/nonmatchings/P2/wm", RefreshWmMoveStats__FP2WM10WORLDLEVEL); -INCLUDE_ASM("asm/nonmatchings/P2/wm", ThrowWmDisplayState__FP2WM10WORLDLEVELi); +extern WORLDLEVEL D_00276250; +extern int D_00276654; + +void ThrowWmDisplayState(WM *pwm, WORLDLEVEL worldlevel, int fReverse) +{ + D_00276250 = worldlevel; + D_00276654 = fReverse; +} INCLUDE_ASM("asm/nonmatchings/P2/wm", CatchWmDisplayState__FP2WM); INCLUDE_ASM("asm/nonmatchings/P2/wm", UpdateWm__FP2WMf); -INCLUDE_ASM("asm/nonmatchings/P2/wm", RenderWmAll__FP2WMP2CMP2RO); +void RenderWmAll(WM *pwm, CM *pcm, RO *pro) +{ + RO ro; + float sNearFog = g_pcm->fgfn.sNearFog; + float duFogPlusClipBias = g_pcm->fgfn.duFogPlusClipBias; + + SetCmFov(g_pcm, 1.0f); + DupAloRo((ALO *)pwm, pro, &ro); + LoadMatrixFromPosRot((VECTOR *)((char *)pcm + 0x40), (MATRIX3 *)((char *)pcm + 0x80), &ro.mat); + RenderAloAll((ALO *)pwm, pcm, &ro); + SetCmFov(g_pcm, sNearFog); + g_pcm->fgfn.duFogPlusClipBias = duFogPlusClipBias; +} INCLUDE_ASM("asm/nonmatchings/P2/wm", HandleWmMessage__FP2WM5MSGIDPv); INCLUDE_ASM("asm/nonmatchings/P2/wm", SetWmWms__FP2WM3WMS); -INCLUDE_ASM("asm/nonmatchings/P2/wm", ShowWm__FP2WM10WORLDLEVEL3WMS); +void ShowWm(WM *pwm, WORLDLEVEL worldlevel, WMS wmsActive) +{ + switch (STRUCT_OFFSET(pwm, 0x2D0, WMS)) + { + case WMS_Hidden: + case WMS_Disappearing: + STRUCT_OFFSET(pwm, 0x2DC, WORLDLEVEL) = worldlevel; + STRUCT_OFFSET(pwm, 0x2E0, WMS) = wmsActive; + SetWmWms(pwm, WMS_Appearing); + break; + + case WMS_Manual: + STRUCT_OFFSET(pwm, 0x2DC, WORLDLEVEL) = worldlevel; + if (wmsActive == WMS_Warping) + SetWmWms(pwm, WMS_Warping); + break; + } +} INCLUDE_ASM("asm/nonmatchings/P2/wm", HideWm__FP2WM); diff --git a/src/P2/wr.c b/src/P2/wr.c index 2cdd9e112..60a23fa64 100644 --- a/src/P2/wr.c +++ b/src/P2/wr.c @@ -32,7 +32,29 @@ float UBias(float u, float v) return u / ((1.0f / v - 2.0f) * (1.0f - u) + 1.0f); } -INCLUDE_ASM("asm/nonmatchings/P2/wr", GFromOnz__FP3ONZ); +float GFromOnz(ONZ *ponz) +{ + float g = 0.0f; + float uAmplSum = 0.0f; + int i = 0; + + if (ponz->conze > 0) + { + ONZE *ponze = ponz->aonze; + do + { + float n = UNoise(ponze->gFreq, ponze->gPhase, ponze->uRandom); + float uAmpl = ponze->uAmpl; + ponze++; + i++; + g += uAmpl * n; + uAmplSum += uAmpl; + } while (i < ponz->conze); + } + + return ponz->lm.gMin + + UBias(g / uAmplSum, ponz->uBias) * (ponz->lm.gMax - ponz->lm.gMin); +} INCLUDE_ASM("asm/nonmatchings/P2/wr", UpdateWrMatrixes__FP2WR); diff --git a/src/P2/xform.c b/src/P2/xform.c index 353243a24..804c4d6d1 100644 --- a/src/P2/xform.c +++ b/src/P2/xform.c @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include INCLUDE_ASM("asm/nonmatchings/P2/xform", InitXfm__FP3XFM); @@ -42,9 +45,35 @@ INCLUDE_ASM("asm/nonmatchings/P2/xform", PwarpFromOid__F3OIDT0); INCLUDE_ASM("asm/nonmatchings/P2/xform", LoadWarpFromBrx__FP4WARPP18CBinaryInputStream); -INCLUDE_ASM("asm/nonmatchings/P2/xform", CloneWarp__FP4WARPT0); +void CloneWarp(WARP *pwarp, WARP *pwarpBase) +{ + int i; + + CloneLo(pwarp, pwarpBase); + + STRUCT_OFFSET(pwarp, 0xa4, LO **) = (LO **)PvAllocSwImpl(STRUCT_OFFSET(pwarp, 0xa0, int) * 4); + + for (i = 0; i < STRUCT_OFFSET(pwarp, 0xa0, int); i++) + { + LO *ploClone = PloCloneLo(STRUCT_OFFSET(pwarpBase, 0xa4, LO **)[i], pwarp->psw, NULL); + STRUCT_OFFSET(pwarp, 0xa4, LO **)[i] = ploClone; + } +} -INCLUDE_ASM("asm/nonmatchings/P2/xform", PostWarpLoad__FP4WARP); +void PostWarpLoad(WARP *pwarp) +{ + int i; + + PostLoLoad(pwarp); + + for (i = 0; i < STRUCT_OFFSET(pwarp, 0xa0, int); i++) + { + LO *plo = STRUCT_OFFSET(pwarp, 0xa4, LO **)[i]; + // @todo clean up this vtable call + (*(void (**)(LO *, ALO *))((char *)plo->pvtlo + 0x64))(plo, pwarp->paloParent); + SnipLo(plo); + } +} INCLUDE_ASM("asm/nonmatchings/P2/xform", TriggerWarp__FP4WARP); @@ -61,7 +90,22 @@ int FUN_001F4308(WARP *pwarp, float g) return 1; } -INCLUDE_ASM("asm/nonmatchings/P2/xform", TeleportSwPlayer__FP2SW3OIDT1); +void TeleportSwPlayer(SW *psw, OID oidWarp, OID oidWarpContext) +{ + WARP *pwarp = PwarpFromOid(oidWarp, oidWarpContext); + if (pwarp != NULL) + { + TriggerWarp(pwarp); + return; + } + + if (PpoCur() != NULL) + return; + + PO *ppo = PpoStart(); + if (ppo != NULL) + SwitchToPo(ppo); +} INCLUDE_ASM("asm/nonmatchings/P2/xform", PexitDefault__Fv); @@ -112,7 +156,26 @@ void InitCamera(CAMERA *pcamera) STRUCT_OFFSET(pcamera, 0x2d0, OID) = OID_Nil; // pcamera->oidTarget } -INCLUDE_ASM("asm/nonmatchings/P2/xform", PostCameraLoad__FP6CAMERA); +void PostCameraLoad(CAMERA *pcamera) +{ + PostAloLoad(pcamera); + + if (pcamera->oidTarget != OID_Nil) + { + LO *plo = PloFindSwObject(pcamera->psw, 0x104, pcamera->oidTarget, pcamera); + if (plo) + { + if (plo->pvtlo->grfcid & 1) + { + pcamera->paloTarget = (ALO *)plo; + } + else if (FIsBasicDerivedFrom(plo, (CID)0x7e)) + { + pcamera->ppntTarget = (PNT *)plo; + } + } + } +} void EnableCamera(CAMERA *pcamera) {