diff --git a/CMakeLists.txt b/CMakeLists.txt index 1abe420b67..5c485a0c6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -363,7 +363,8 @@ set(DUSK_COPYRIGHT "Copyright (C) Twilit Realm contributors") source_group("dolzel" FILES ${DOLZEL_FILES} ${Z2AUDIOLIB_FILES} ${REL_FILES}) source_group("dusklight" FILES ${DUSK_FILES} ${DUSK_HTTP_BACKEND_FILES}) -set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0 MTX_USE_PS=1) +# PARTIAL_DEBUG makes debug and release share one struct/vtable ABI so a mod binary loads into either +set(GAME_COMPILE_DEFS TARGET_PC WIDESCREEN_SUPPORT=1 AVOID_UB=1 VERSION=0 MTX_USE_PS=1 PARTIAL_DEBUG=1) set(GAME_INCLUDE_DIRS include @@ -474,7 +475,7 @@ set(GAME_DEBUG_FILES set_source_files_properties( ${GAME_DEBUG_FILES} PROPERTIES - COMPILE_DEFINITIONS "$<$:DEBUG=1>;$<$:PARTIAL_DEBUG=1>" + COMPILE_DEFINITIONS "$<$:DEBUG=1>;PARTIAL_DEBUG=1" ) # game_base is for all other game code files @@ -488,14 +489,14 @@ set(GAME_BASE_FILES set_source_files_properties( ${GAME_BASE_FILES} PROPERTIES - COMPILE_DEFINITIONS "NDEBUG=1;NDEBUG_DEFINED=1;DEBUG_DEFINED=0;$<$:PARTIAL_DEBUG=1>" + COMPILE_DEFINITIONS "NDEBUG=1;NDEBUG_DEFINED=1;DEBUG_DEFINED=0;PARTIAL_DEBUG=1" ) foreach(jsystem_lib IN LISTS JSYSTEM_LIBRARIES) target_compile_definitions(${jsystem_lib} PRIVATE ${GAME_COMPILE_DEFS} $<$:DEBUG=1> - $<$:PARTIAL_DEBUG=1> + PARTIAL_DEBUG=1 ) target_include_directories(${jsystem_lib} PRIVATE ${GAME_INCLUDE_DIRS}) target_link_libraries(${jsystem_lib} PRIVATE ${GAME_LIBS}) diff --git a/include/SSystem/SComponent/c_bg_s_shdw_draw.h b/include/SSystem/SComponent/c_bg_s_shdw_draw.h index 9ec3023306..55792f8410 100644 --- a/include/SSystem/SComponent/c_bg_s_shdw_draw.h +++ b/include/SSystem/SComponent/c_bg_s_shdw_draw.h @@ -20,7 +20,7 @@ public: /* 0x14 */ cM3dGAab mM3dGAab; /* 0x30 */ cBgS_ShdwDraw_Callback mCallbackFun; - #if DEBUG + #if PARTIAL_DEBUG || DEBUG /* 0x34 */ int field_0x34; #endif }; diff --git a/include/Z2AudioLib/Z2AudioMgr.h b/include/Z2AudioLib/Z2AudioMgr.h index e543bf6061..0f8e5a17ea 100644 --- a/include/Z2AudioLib/Z2AudioMgr.h +++ b/include/Z2AudioLib/Z2AudioMgr.h @@ -48,6 +48,8 @@ public: /* 0x1370 */ Z2FxLineMgr mFxLineMgr; #if DEBUG /* 0x13BC */ Z2DebugSys mDebugSys; + #elif PARTIAL_DEBUG + alignas(Z2DebugSys) u8 mDebugSys[sizeof(Z2DebugSys)]; #endif }; // Size: 0x138C diff --git a/include/Z2AudioLib/Z2SeqMgr.h b/include/Z2AudioLib/Z2SeqMgr.h index 76c2674697..94191a1318 100644 --- a/include/Z2AudioLib/Z2SeqMgr.h +++ b/include/Z2AudioLib/Z2SeqMgr.h @@ -194,7 +194,7 @@ public: JAISoundHandle* getMainBgmHandle() { return &mMainBgmHandle; } JAISoundHandle* getSubBgmHandle() { return &mSubBgmHandle; } - #if DEBUG + #if PARTIAL_DEBUG || DEBUG f32 field_0x00_debug; u8 field_0x04_debug; #endif diff --git a/include/Z2AudioLib/Z2SoundObjMgr.h b/include/Z2AudioLib/Z2SoundObjMgr.h index c0b4ed778c..687f9eaf0a 100644 --- a/include/Z2AudioLib/Z2SoundObjMgr.h +++ b/include/Z2AudioLib/Z2SoundObjMgr.h @@ -100,13 +100,13 @@ public: bool isForceBattle() { return forceBattle_; } JSUList* getEnemyList() { return &field_0x0; } - #if DEBUG + #if PARTIAL_DEBUG || DEBUG JSUList* getAllList() { return &allList_; } #endif private: /* 0x00 */ JSUList field_0x0; - #if DEBUG + #if PARTIAL_DEBUG || DEBUG /* 0x0C */ JSUList allList_; #endif /* 0x0C */ Z2EnemyArea enemyArea_; diff --git a/include/Z2AudioLib/Z2SoundObject.h b/include/Z2AudioLib/Z2SoundObject.h index ca4b69a520..2d85db34c0 100644 --- a/include/Z2AudioLib/Z2SoundObject.h +++ b/include/Z2AudioLib/Z2SoundObject.h @@ -7,7 +7,7 @@ struct Z2SoundStarter; class Z2SoundObjBase : public Z2SoundHandles -#if DEBUG +#if PARTIAL_DEBUG || DEBUG , public JSULink #endif { diff --git a/include/d/d_attention.h b/include/d/d_attention.h index 455516e54f..5b8930b5dd 100644 --- a/include/d/d_attention.h +++ b/include/d/d_attention.h @@ -45,7 +45,7 @@ private: class dAttParam_c : public JORReflexible { public: -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x04 */ s8 mHIOChildNo; #endif @@ -66,7 +66,7 @@ public: /* 0x35 */ u8 mAttnCursorDisappearFrames; /* 0x38 */ f32 field_0x38; /* 0x3C */ f32 field_0x3c; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x44 */ s32 mDebugDispPosX; /* 0x48 */ s32 mDebugDispPosY; #endif diff --git a/include/d/d_bg_s_acch.h b/include/d/d_bg_s_acch.h index 33bca24c0a..04a388c61b 100644 --- a/include/d/d_bg_s_acch.h +++ b/include/d/d_bg_s_acch.h @@ -201,7 +201,7 @@ private: /* 0x02C */ u32 m_flags; /* 0x030 */ cXyz* pm_pos; /* 0x034 */ cXyz* pm_old_pos; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x038 */ cXyz unk_0x38; #endif /* 0x038 */ cXyz* pm_speed; @@ -229,7 +229,7 @@ private: /* 0x0CC */ f32 field_0xcc; /* 0x0D0 */ f32 m_wtr_chk_offset; /* 0x0D4 */ cBgS_PolyInfo* pm_out_poly_info; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x0E4 */ cXyz unk_0xe4; #endif /* 0x0D8 */ f32 field_0xd8; diff --git a/include/d/d_cc_s.h b/include/d/d_cc_s.h index b4d90787ae..d156867cce 100644 --- a/include/d/d_cc_s.h +++ b/include/d/d_cc_s.h @@ -79,7 +79,7 @@ public: // /* 0x0000 */ cCcS mCCcS; /* 0x284C */ dCcMassS_Mng mMass_Mng; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x2AD0 */ u8 m_is_mass_all_timer; #endif }; // Size = 0x2AC4 diff --git a/include/d/d_com_inf_game.h b/include/d/d_com_inf_game.h index fbc9964ca2..d240507f97 100644 --- a/include/d/d_com_inf_game.h +++ b/include/d/d_com_inf_game.h @@ -1037,7 +1037,7 @@ public: /* 0x1DE09 */ u8 field_0x1de09; /* 0x1DE0A */ u8 field_0x1de0a; /* 0x1DE0B */ u8 mIsDebugMode; - #if DEBUG + #if PARTIAL_DEBUG || DEBUG /* 0x1DE0C */ OSStopwatch mStopwatch; #endif diff --git a/include/d/d_event_manager.h b/include/d/d_event_manager.h index 03a8ef7ac3..de046797ff 100644 --- a/include/d/d_event_manager.h +++ b/include/d/d_event_manager.h @@ -41,7 +41,7 @@ public: BASE_ROOM5, BASE_DEMO, - #if DEBUG + #if PARTIAL_DEBUG || DEBUG BASE_DEBUG, #endif diff --git a/include/d/d_kankyo.h b/include/d/d_kankyo.h index 3c81f08d10..06c8f0eb56 100644 --- a/include/d/d_kankyo.h +++ b/include/d/d_kankyo.h @@ -259,7 +259,7 @@ public: /* 0x09B8 */ DUNGEON_LIGHT dungeonlight[8]; /* 0x0C18 */ BOSS_LIGHT field_0x0c18[8]; /* 0x0D58 */ BOSS_LIGHT field_0x0d58[6]; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x0E48 */ NAVYCHAN navy; /* 0x0E58 */ u8 field_0xe58[0xE68 - 0xE58]; // part of NAVYCHAN? #endif diff --git a/include/d/d_particle.h b/include/d/d_particle.h index c9db174fcd..3098dbd521 100644 --- a/include/d/d_particle.h +++ b/include/d/d_particle.h @@ -521,13 +521,13 @@ private: /* 0x019 */ u8 field_0x19; /* 0x01A */ u8 field_0x1a; /* 0x01B */ u8 field_0x1b; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x01C */ dPa_simpleEcallBack field_0x1c[48]; #else /* 0x01C */ dPa_simpleEcallBack field_0x1c[25]; #endif /* 0x210 */ level_c field_0x210; - #if DEBUG + #if PARTIAL_DEBUG || DEBUG u8 mSceneCount; #endif }; diff --git a/include/d/d_resorce.h b/include/d/d_resorce.h index 31d028a082..b70d2d5452 100644 --- a/include/d/d_resorce.h +++ b/include/d/d_resorce.h @@ -59,7 +59,7 @@ private: /* 0x18 */ JKRHeap* heap; /* 0x1C */ JKRSolidHeap* mDataHeap; /* 0x20 */ void** mRes; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x24 */ int mSize; #endif }; // Size: 0x24 diff --git a/include/d/d_save.h b/include/d/d_save.h index 69d4d3174d..fc54e541f4 100644 --- a/include/d/d_save.h +++ b/include/d/d_save.h @@ -1008,7 +1008,7 @@ public: static const int ZONE_MAX = 0x20; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x000 */ u8 unk_0x0; /* 0x001 */ char unk_0x1; /* 0x000 */ u8 unk_0x2[0x48 - 0x2]; @@ -1029,6 +1029,9 @@ public: /* 0xF30 */ s64 mSaveTotalTime; #if DEBUG /* 0xF80 */ flagFile_c mFlagFile; +#elif PARTIAL_DEBUG + // flagFile_c's ctor/virtuals are only defined under #if DEBUG (d_save.cpp) + alignas(flagFile_c) u8 mFlagFile[sizeof(flagFile_c)]; #endif }; // Size: 0xF38 diff --git a/include/d/d_stage.h b/include/d/d_stage.h index 04a6115fd0..83a1c808fd 100644 --- a/include/d/d_stage.h +++ b/include/d/d_stage.h @@ -538,7 +538,7 @@ public: /* vt[86] */ virtual stage_tgsc_class* getDrTg(void) const = 0; /* vt[87] */ virtual void setDoor(stage_tgsc_class*) = 0; /* vt[88] */ virtual stage_tgsc_class* getDoor(void) const = 0; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG virtual void setUnit(void*) = 0; virtual void* getUnit() = 0; #endif @@ -796,7 +796,7 @@ public: virtual stage_tgsc_class* getDrTg(void) const { return mDrTg; } virtual void setDoor(stage_tgsc_class* i_Door) { mDoor = i_Door; } virtual stage_tgsc_class* getDoor(void) const { return mDoor; } -#if DEBUG +#if PARTIAL_DEBUG || DEBUG virtual void setUnit(void* i_Unit) { mUnit = i_Unit; } virtual void* getUnit() { return mUnit; } #endif @@ -845,7 +845,7 @@ public: /* 0x54 */ stage_tgsc_class* mDrTg; /* 0x58 */ stage_tgsc_class* mDoor; /* 0x5C */ dStage_FloorInfo_c* mFloorInfo; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x60 */ void* mUnit; #endif /* 0x60 */ u16 mPlayerNum; @@ -990,7 +990,7 @@ public: /* vt[86] */ virtual stage_tgsc_class* getDrTg(void) const { return mDrTg; } /* vt[87] */ virtual void setDoor(stage_tgsc_class* i_Door) { mDoor = i_Door; } /* vt[88] */ virtual stage_tgsc_class* getDoor(void) const { return mDoor; } -#if DEBUG +#if PARTIAL_DEBUG || DEBUG virtual void setUnit(void* i_Unit) { UNUSED(i_Unit); OSReport("stage non unit list data !!\n"); diff --git a/include/d/d_vibration.h b/include/d/d_vibration.h index 4018acea50..ee87f7dcc4 100644 --- a/include/d/d_vibration.h +++ b/include/d/d_vibration.h @@ -97,6 +97,9 @@ public: private: #if DEBUG /* 0x00 */ dVibTest_c mVibTest; +#elif PARTIAL_DEBUG + // dVibTest_c's ctor/virtuals are only defined under #if DEBUG (d_vibration.cpp) + alignas(dVibTest_c) u8 mVibTest[sizeof(dVibTest_c)]; #endif class { diff --git a/include/f_pc/f_pc_node_req.h b/include/f_pc/f_pc_node_req.h index d710379c89..880e733ac9 100644 --- a/include/f_pc/f_pc_node_req.h +++ b/include/f_pc/f_pc_node_req.h @@ -36,7 +36,7 @@ typedef struct node_create_request { /* 0x58 */ s16 name; /* 0x5C */ void* data; /* 0x60 */ s16 unk_0x60; -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x64 */ int unk_0x64; /* 0x68 */ int unk_0x68; #endif diff --git a/include/m_Do/m_Do_audio.h b/include/m_Do/m_Do_audio.h index 4bc2f20c94..e1e15c1ef1 100644 --- a/include/m_Do/m_Do_audio.h +++ b/include/m_Do/m_Do_audio.h @@ -11,13 +11,13 @@ class mDoAud_zelAudio_c : public Z2AudioMgr { public: void reset(); mDoAud_zelAudio_c() { -#if DEBUG +#if PARTIAL_DEBUG || DEBUG setMode(2); #endif } ~mDoAud_zelAudio_c() {} -#if DEBUG +#if PARTIAL_DEBUG || DEBUG u8 getMode() { return field_0x13bd; } void setMode(u8 mode) { field_0x13bd = mode; } diff --git a/include/m_Do/m_Do_hostIO.h b/include/m_Do/m_Do_hostIO.h index fa4eb8b1af..d88a0a9853 100644 --- a/include/m_Do/m_Do_hostIO.h +++ b/include/m_Do/m_Do_hostIO.h @@ -35,6 +35,11 @@ public: /* 0x4 */ s8 mNo; /* 0x5 */ u8 mCount; #else +#if PARTIAL_DEBUG + // Initialized here since the DEBUG ctor doesn't run. + /* 0x4 */ s8 mNo = -1; + /* 0x5 */ u8 mCount = 0; +#endif virtual ~mDoHIO_entry_c() {} #endif }; diff --git a/libs/JSystem/include/JSystem/JHostIO/JORReflexible.h b/libs/JSystem/include/JSystem/JHostIO/JORReflexible.h index 533a3184ba..84894de275 100644 --- a/libs/JSystem/include/JSystem/JHostIO/JORReflexible.h +++ b/libs/JSystem/include/JSystem/JHostIO/JORReflexible.h @@ -12,12 +12,23 @@ struct JORNodeEvent; class JORMContext; class JORServer; +// NOTE (stable game ABI): these classes stay non-polymorphic outside DEBUG +// on purpose. Making them polymorphic under PARTIAL_DEBUG would give every one of the ~250 +// derived HIO classes a vptr and turn their plain `void genMessage(JORMContext*);` +// declarations into implicit virtual overrides whose definitions are #if DEBUG-gated; every +// instantiated one then fails to link (missing vtable). Closure types shared with DEBUG TUs +// either declare their own unconditional virtuals (vptr in all TUs anyway) or add a +// PARTIAL_DEBUG-only virtual dtor for vptr parity (see dAttParam_c). class JOREventListener { public: #if DEBUG JOREventListener() {} +#if TARGET_PC + virtual void listenPropertyEvent(const JORPropertyEvent*) {} +#else virtual void listenPropertyEvent(const JORPropertyEvent*) = 0; #endif +#endif }; class JORReflexible : public JOREventListener { @@ -30,7 +41,11 @@ public: virtual void listenPropertyEvent(const JORPropertyEvent*); virtual void listen(u32, const JOREvent*); virtual void genObjectInfo(const JORGenEvent*); +#if TARGET_PC + virtual void genMessage(JORMContext*) {} +#else virtual void genMessage(JORMContext*) = 0; +#endif virtual void listenNodeEvent(const JORNodeEvent*); #endif }; diff --git a/libs/JSystem/include/JSystem/JStudio/JStudio/functionvalue.h b/libs/JSystem/include/JSystem/JStudio/JStudio/functionvalue.h index 7b2c935272..8acdbe1623 100644 --- a/libs/JSystem/include/JSystem/JStudio/JStudio/functionvalue.h +++ b/libs/JSystem/include/JSystem/JStudio/JStudio/functionvalue.h @@ -314,7 +314,7 @@ public: > { TIterator_data_(const TFunctionValue_list_parameter& rParent, const f32* value) { -#if DEBUG +#if PARTIAL_DEBUG || DEBUG pOwn_ = &rParent; #endif pf_ = value; @@ -372,7 +372,7 @@ public: return (r1.pf_ - r2.pf_) / suData_size; } -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x00 */ const TFunctionValue_list_parameter* pOwn_; #endif /* 0x00 */ const f32* pf_; @@ -425,7 +425,7 @@ public: > { TIterator_data_(const TFunctionValue_hermite& rParent, const f32* value) { -#if DEBUG +#if PARTIAL_DEBUG || DEBUG pOwn_ = &rParent; #endif pf_ = value; @@ -491,7 +491,7 @@ public: return (r1.pf_ - r2.pf_) / r1.uSize_; } -#if DEBUG +#if PARTIAL_DEBUG || DEBUG /* 0x00 */ const TFunctionValue_hermite* pOwn_; /* 0x04 */ const f32* pf_; /* 0x08 */ u32 uSize_; diff --git a/src/Z2AudioLib/Z2SoundObject.cpp b/src/Z2AudioLib/Z2SoundObject.cpp index 1c81be0f17..23e8171736 100644 --- a/src/Z2AudioLib/Z2SoundObject.cpp +++ b/src/Z2AudioLib/Z2SoundObject.cpp @@ -22,7 +22,7 @@ #include "os_report.h" Z2SoundObjBase::Z2SoundObjBase() -#if DEBUG +#if PARTIAL_DEBUG || DEBUG : JSULink(this) #endif {