mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-07 12:03:24 -04:00
process class inheritance vtable fix
This commit is contained in:
@@ -240,8 +240,14 @@ struct cull_box {
|
||||
/* 0xC */ Vec max;
|
||||
};
|
||||
|
||||
#if __MWERKS__
|
||||
class fopAc_ac_c {
|
||||
public:
|
||||
/* 0x000 */ leafdraw_class base;
|
||||
#else
|
||||
class fopAc_ac_c : public leafdraw_class {
|
||||
public:
|
||||
#endif
|
||||
/* 0x0C0 */ int actor_type;
|
||||
/* 0x0C4 */ create_tag_class actor_tag;
|
||||
/* 0x0D8 */ create_tag_class draw_tag;
|
||||
@@ -284,8 +290,16 @@ public:
|
||||
/* 0x566 */ s8 field_0x566;
|
||||
/* 0x567 */ s8 field_0x567;
|
||||
|
||||
#if !__MWERKS__
|
||||
s8 actor_last_base_field;
|
||||
#endif
|
||||
|
||||
fopAc_ac_c();
|
||||
#if !__MWERKS__
|
||||
~fopAc_ac_c() override;
|
||||
#else
|
||||
~fopAc_ac_c();
|
||||
#endif
|
||||
|
||||
static u32 getStopStatus() { return stopStatus; }
|
||||
static void setStopStatus(u32 status) { stopStatus = status; }
|
||||
|
||||
@@ -17,20 +17,25 @@
|
||||
// Modern compilers will zero the parent struct in default constructors.
|
||||
// So instead of adding default constructors to everything,
|
||||
// we'll just save & restore that data.
|
||||
#define fopAcM_ct_placement_copy_length offsetof(fopAc_ac_c, actor_last_base_field) - offsetof(fopAc_ac_c, type)
|
||||
|
||||
#define fopAcM_ct_placement(ptr, ClassName) \
|
||||
fopAc_ac_c copy; \
|
||||
memcpy(©, &(ptr)->base, sizeof(fopAc_ac_c)); \
|
||||
memcpy(©.type, &(ptr)->type, fopAcM_ct_placement_copy_length); \
|
||||
new (ptr) ClassName() ; \
|
||||
memcpy(&(ptr)->base, ©, sizeof(fopAc_ac_c));
|
||||
memcpy(&(ptr)->type, ©.type, fopAcM_ct_placement_copy_length);
|
||||
#else
|
||||
#define fopAcM_ct_placement(ptr, ClassName) new (ptr) ClassName()
|
||||
#endif
|
||||
|
||||
#define fopAcM_ct(ptr, ClassName) \
|
||||
if ((ptr)->layer_tag.layer == NULL) { OSPanic(__FILE__, __LINE__, "UH OH"); } \
|
||||
if (!fopAcM_CheckCondition(ptr, fopAcCnd_INIT_e)) { \
|
||||
fopAcM_ct_placement(ptr, ClassName); \
|
||||
fopAcM_OnCondition(ptr, fopAcCnd_INIT_e); \
|
||||
}
|
||||
} \
|
||||
if ((ptr)->layer_tag.layer == NULL) { OSPanic(__FILE__, __LINE__, "Oh come on"); }
|
||||
|
||||
|
||||
#define fopAcM_RegisterDeleteID(i_this, actor_name_str) \
|
||||
("Delete -> " actor_name_str "(id=%d)\n", fopAcM_GetID(i_this))
|
||||
|
||||
@@ -20,7 +20,7 @@ typedef struct state_class {
|
||||
} state_class;
|
||||
|
||||
typedef struct base_process_class {
|
||||
/* 0x00 */ int type;
|
||||
/* 0x00 */ int type; // DUSK NOTE: fopAcM_ct_placement relies on this being the *very* first field!
|
||||
/* 0x04 */ fpc_ProcID id;
|
||||
/* 0x08 */ s16 name;
|
||||
/* 0x0A */ s8 unk_0xA;
|
||||
@@ -37,6 +37,14 @@ typedef struct base_process_class {
|
||||
/* 0xAC */ void* append;
|
||||
/* 0xB0 */ u32 parameters;
|
||||
/* 0xB4 */ int subtype;
|
||||
#if !__MWERKS__
|
||||
// MSVC places vtables at the start of a class, *even* if that class inherits from something
|
||||
// without vtable. This breaks everything.
|
||||
// TO avoid issues with pointer casting, we make base_process_class also have a vtable and
|
||||
// ensure we're using inheritance on it.
|
||||
|
||||
virtual ~base_process_class();
|
||||
#endif
|
||||
} base_process_class; // Size: 0xB8
|
||||
|
||||
BOOL fpcBs_Is_JustOfType(int i_typeA, int i_typeB);
|
||||
|
||||
@@ -13,8 +13,16 @@ typedef struct leafdraw_method_class {
|
||||
/* 0x10 */ process_method_func draw_method;
|
||||
} leafdraw_method_class;
|
||||
|
||||
#if __MWERKS__
|
||||
#define LEAFDRAW_BASE(val) (val)->base
|
||||
|
||||
typedef struct leafdraw_class {
|
||||
/* 0x00 */ base_process_class base;
|
||||
#else
|
||||
#define LEAFDRAW_BASE(val) (*(base_process_class*)val)
|
||||
|
||||
typedef struct leafdraw_class : base_process_class {
|
||||
#endif
|
||||
/* 0xB8 */ leafdraw_method_class* leaf_methods;
|
||||
/* 0xBC */ s8 unk_0xBC;
|
||||
/* 0xBD */ u8 unk_0xBD;
|
||||
|
||||
@@ -4857,7 +4857,7 @@ int daAlink_c::create() {
|
||||
|
||||
dComIfGp_setPlayer(0, this);
|
||||
dComIfGp_setLinkPlayer(this);
|
||||
fopAcM_setStageLayer(&base);
|
||||
fopAcM_setStageLayer(&LEAFDRAW_BASE(this));
|
||||
|
||||
if (sceneMode == 7) {
|
||||
current.pos = dComIfGs_getTurnRestartPos();
|
||||
|
||||
@@ -350,7 +350,7 @@ int daGrass_c::create() {
|
||||
}
|
||||
|
||||
m_myObj = this;
|
||||
fopAcM_setStageLayer(&base);
|
||||
fopAcM_setStageLayer(&LEAFDRAW_BASE(this));
|
||||
return cPhs_COMPLEATE_e;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ static void* s_hitfish_sub(void* a, void* b) {
|
||||
if (fopAc_IsActor(a)) {
|
||||
mg_fish_class* fish = (mg_fish_class*)a;
|
||||
if (fopAcM_GetName(fish) == PROC_MG_FISH && fish->mCurAction == ACTION_MG_FISH_MF_HIT) {
|
||||
return &fish->actor.base;
|
||||
return &LEAFDRAW_BASE(&fish->actor);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
@@ -278,7 +278,7 @@ void daObj_SMTile_c::touchPrtcls(f32 param_1) {
|
||||
for (int i = 0; i < 21; i++) {
|
||||
if ((field_0xa28[i] == 1) || (field_0xa28[i] == 2)) {
|
||||
mParticleIds[i] =
|
||||
dComIfGp_particle_set(mParticleIds[i], id[field_0xa28[i]], &field_0x788[i], 0, 0);
|
||||
dComIfGp_particle_set(mParticleIds[i], ::id[field_0xa28[i]], &field_0x788[i], 0, 0);
|
||||
JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(mParticleIds[i]);
|
||||
if (emitter != NULL) {
|
||||
f32 dVar6 = mpHIO->m.field_0x4 - mParticleTimers[i];
|
||||
|
||||
@@ -171,3 +171,9 @@ int fpcBs_SubCreate(base_process_class* i_proc) {
|
||||
return cPhs_ERROR_e;
|
||||
}
|
||||
}
|
||||
|
||||
#if !__MWERKS__
|
||||
base_process_class::~base_process_class() {
|
||||
// Nada. Only exists to ensure the base class has a vtable.
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -42,7 +42,7 @@ int fpcLf_Delete(leafdraw_class* i_leaf) {
|
||||
int ret = fpcMtd_Delete(&i_leaf->leaf_methods->base, i_leaf);
|
||||
UNUSED(ret); // possible fakematch? this line fixes debug regalloc
|
||||
if (ret == 1) {
|
||||
i_leaf->base.subtype = 0;
|
||||
LEAFDRAW_BASE(i_leaf).subtype = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -50,10 +50,10 @@ int fpcLf_Delete(leafdraw_class* i_leaf) {
|
||||
int g_fpcLf_type;
|
||||
|
||||
int fpcLf_Create(leafdraw_class* i_leaf) {
|
||||
if (i_leaf->base.state.init_state == 0) {
|
||||
leaf_process_profile_definition* pprofile = (leaf_process_profile_definition*)i_leaf->base.profile;
|
||||
if (LEAFDRAW_BASE(i_leaf).state.init_state == 0) {
|
||||
leaf_process_profile_definition* pprofile = (leaf_process_profile_definition*)LEAFDRAW_BASE(i_leaf).profile;
|
||||
i_leaf->leaf_methods = pprofile->sub_method;
|
||||
i_leaf->base.subtype = fpcBs_MakeOfType(&g_fpcLf_type);
|
||||
LEAFDRAW_BASE(i_leaf).subtype = fpcBs_MakeOfType(&g_fpcLf_type);
|
||||
fpcDwPi_Init(&i_leaf->draw_priority, pprofile->priority);
|
||||
i_leaf->unk_0xBC = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user