tmc/src/code_0807CC3C.c

543 lines
15 KiB
C

#include "global.h"
#include "structures.h"
#include "functions.h"
#include "script.h"
#include "entity.h"
#include "save.h"
typedef struct Thing {
u16 unk_1;
u16 unk_2;
u32 unk_3;
} Thing;
extern u8 gUnk_0811E514[];
extern u8 gUnk_0811E510[];
extern struct_0807D1C4 gUnk_0811E4BC[];
extern const char gUnk_0811E4B4[8];
extern ScriptExecutionContext gPlayerScriptExecutionContext;
extern ScriptExecutionContext gScriptExecutionContextArray[0x20];
extern void CreateSpeechBubbleExclamationMark(Entity*, u32, u32);
extern void CreateSpeechBubbleQuestionMark(Entity*, u32, u32);
extern void DeleteThisEntity(void);
extern u32 sub_080B180C(u32, const char*);
extern void sub_0801C4A0(u32);
extern s32 __divsi3(s32, s32);
extern void _call_via_r6(Entity*, ScriptExecutionContext*);
extern u16 sub_080B18DC(u16, const char*);
void sub_0807DB88(ScriptExecutionContext* context, u16* unk1);
void sub_0807DAF0(Entity* entity, ScriptExecutionContext* context, u16* unk1);
u32 sub_0807D1D8(u32 unk_1, const char* unk_2, u32 unk_3);
u32 sub_0807D128(const Thing* unk_1);
u16 sub_0807D1A4(u16* unk_1, u32 unk_2);
u32 sub_0807D0A0(u16* unk_1, u16* unk_2, u32 unk_3);
u32 sub_0807D0EC(u32 unk_1, const char* unk_2);
void sub_0807DF38(void);
void sub_0807DE80(Entity* entity);
void sub_0807DB98(Entity*, ScriptExecutionContext*);
u32 sub_0807CF88(u32 arg0, u8* arg1) {
Thing thing;
u32 retval;
struct_0807D1C4* ptr;
u32 e0, e1;
u16 l1prep;
ptr = sub_0807D1C4(arg0);
thing.unk_3 = 'MCZ3';
l1prep = sub_0807D1A4((u16*)&thing.unk_3, 4);
l1prep += sub_0807D1A4((u16*)arg1, ptr->field_0x0);
thing.unk_1 = l1prep;
thing.unk_2 = -(u32)l1prep;
e0 = sub_0807D20C(ptr->field_0x6, (const char*)arg1, ptr->field_0x0);
if (e0) {
e0 = sub_0807D184(ptr->field_0x2, (const char*)&thing.unk_1);
}
e1 = sub_0807D20C(ptr->field_0x8, (const char*)arg1, ptr->field_0x0);
if (e1) {
e1 = sub_0807D184(ptr->field_0x4, (const char*)&thing.unk_1);
}
retval = 0;
if (e0 || e1) {
retval = 1;
}
return retval;
}
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D008.inc", u32 sub_0807D008(u32 param_1, SaveFile* saveFile)) {
u32 set_0;
char auStack32[8];
struct_0807D1C4* unk_s;
u32 t1;
u32 t2;
u32 ret;
u32 temp;
unk_s = sub_0807D1C4(param_1);
t1 = sub_0807D0EC(unk_s->field_0x2, auStack32);
if (t1 == 2) {
if ((sub_0807D1D8(unk_s->field_0x6, (char*)saveFile, unk_s->field_0x0) == 0) ||
(sub_0807D0A0((u16*)auStack32, (u16*)saveFile, (u32)unk_s->field_0x0) == 0)) {
t1 = 0;
} else {
return 1;
}
}
t2 = sub_0807D0EC(unk_s->field_0x4, auStack32);
if (t2 == 2) {
if ((sub_0807D1D8(unk_s->field_0x8, (char*)saveFile, unk_s->field_0x0) != 0) &&
(sub_0807D0A0((u16*)auStack32, (u16*)saveFile, (u32)unk_s->field_0x0) != 0)) {
return 1;
}
t2 = 0;
}
set_0 = 0;
CpuSet(&set_0, saveFile, unk_s->field_0x0 >> 2 | CPU_SET_SRC_FIXED | CPU_SET_32BIT);
temp = t1 | t2;
ret = 0;
if (temp == 0) {
ret = -1;
}
return ret;
}
END_NONMATCH
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D0A0.inc", u32 sub_0807D0A0(u16* unk_1, u16* unk_2, u32 unk_3)) {
u32 r0;
u32* u32_1 = (u32*)unk_1;
u16 u0;
u32 u1;
u0 = sub_0807D1A4(unk_1 + 2, 4);
u0 = u0 + sub_0807D1A4(unk_2, unk_3);
u1 = unk_1[0];
if (u1 != u0) {
r0 = 0;
} else {
if (unk_1[1] == (-(u1 << 0x10) >> 0x10)) {
if (*(u32_1 + 1) != 'MCZ3') {
r0 = 0;
} else {
r0 = 1;
}
} else {
r0 = 0;
}
}
return r0;
}
END_NONMATCH
u32 sub_0807D0EC(u32 unk_1, const char* unk_2) {
u32 ret;
if (!sub_0807D1D8(unk_1, unk_2, 8)) {
ret = 0;
} else {
ret = sub_0807D128((Thing*)unk_2);
}
if (!ret && sub_0807D1D8(unk_1 + 8, unk_2, 8)) {
ret = sub_0807D128((Thing*)unk_2);
}
return ret;
}
u32 sub_0807D128(const Thing* thing) {
u32 ret;
switch (thing->unk_3) {
case 'MCZ3':
if (thing->unk_1 + thing->unk_2 == 0x10000) {
ret = 2;
} else {
ret = 0;
}
break;
case 'FleD':
case 'TINI':
ret = 0;
if ((thing->unk_1 & thing->unk_2) == 0xffff) {
ret = 1;
}
break;
default:
ret = 0;
break;
}
return ret;
}
u32 sub_0807D184(u32 param_1, const char* param_2) {
u32 uVar1;
uVar1 = sub_0807D20C(param_1, param_2, 8);
if (uVar1 == 0) {
uVar1 = sub_0807D20C(param_1 + 8, param_2, 8);
}
return uVar1;
}
u16 sub_0807D1A4(u16* unk_1, u32 unk_2) {
u32 uVar1;
uVar1 = 0;
while (unk_2 != 0) {
uVar1 = uVar1 + (*unk_1 ^ unk_2);
unk_1 = unk_1 + 1;
unk_2 = unk_2 - 2;
}
return uVar1;
}
struct_0807D1C4* sub_0807D1C4(u32 unk_1) {
return &gUnk_0811E4BC[unk_1];
}
// these three are basically the same and wrong by basically one instruction in the wrong place
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D1D8.inc", u32 sub_0807D1D8(u32 unk_1, const char* unk_2, u32 unk_3)) {
}
END_NONMATCH
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D20C.inc", u32 sub_0807D20C(u32 unk_1, const char* unk_2, u32 unk_3)) {
unk_3 >>= 3;
unk_1 >>= 3;
while (unk_3-- > 0) {
if (sub_080B18DC(unk_1, unk_2)) {
sub_080B18DC(unk_1, gUnk_0811E4B4);
return 0;
}
unk_1++;
unk_2 += 8;
}
return 1;
}
END_NONMATCH
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D24C.inc", u32 sub_0807D24C(u32 unk_1, const char* unk_2, u32 unk_3)) {
unk_3 >>= 3;
unk_1 >>= 3;
while (unk_3-- > 0) {
if (sub_080B180C(unk_1, unk_2))
return 0;
unk_1++;
unk_2 += 8;
}
return 1;
}
END_NONMATCH
// these three functions use gRoomControls, maybe once that is understood better, these can be decompiled easier
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D280.inc", void sub_0807D280(u32 unk_1, u32 unk_2)) {
}
END_NONMATCH
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D46C.inc", void sub_0807D46C(u32 unk_1, u32 unk_2)) {
}
END_NONMATCH
NONMATCH("asm/non_matching/code_0807CC3C/sub_0807D6D8.inc", void sub_0807D6D8(u32 unk_1, u32 unk_2)) {
}
END_NONMATCH
void sub_0807DA70(void) {
_DmaZero(&gUnk_02033280, sizeof(gUnk_02033280));
_DmaZero(&gScriptExecutionContextArray, sizeof(gScriptExecutionContextArray));
_DmaZero(&gPlayerScriptExecutionContext, sizeof(gPlayerScriptExecutionContext));
gUnk_02033280.unk_08 = 8;
}
ScriptExecutionContext* CreateScriptExecutionContext(void) {
ScriptExecutionContext* puVar1;
puVar1 = gScriptExecutionContextArray;
do {
if (puVar1->unk_00 == 0) {
return puVar1;
}
puVar1++;
} while (puVar1 < gScriptExecutionContextArray + ARRAY_COUNT(gScriptExecutionContextArray));
return NULL;
}
void DestroyScriptExecutionContext(ScriptExecutionContext* context) {
_DmaZero(context, sizeof(ScriptExecutionContext));
}
ScriptExecutionContext* StartCutscene(Entity* entity, u16* unk_2) {
ScriptExecutionContext* puVar1;
puVar1 = CreateScriptExecutionContext();
if (puVar1) {
sub_0807DAF0(entity, puVar1, unk_2);
}
return puVar1;
}
void sub_0807DAF0(Entity* entity, ScriptExecutionContext* context, u16* unk1) {
entity->flags = entity->flags | 2;
*(ScriptExecutionContext**)&entity->cutsceneBeh = context;
sub_0807DB88(context, unk1);
}
void UnloadCutsceneData(Entity* entity) {
if ((entity->flags & 2)) {
entity->flags = entity->flags & 0xfd;
DestroyScriptExecutionContext(*(ScriptExecutionContext**)&entity->cutsceneBeh);
*(ScriptExecutionContext**)&entity->cutsceneBeh = NULL;
}
}
void StartPlayerScript(u16* unk1) {
Entity* player;
_DmaZero(&gPlayerScriptExecutionContext, sizeof(gPlayerScriptExecutionContext));
gPlayerScriptExecutionContext.unk_00 = unk1;
player = &gPlayerEntity;
*(ScriptExecutionContext**)&player->cutsceneBeh = &gPlayerScriptExecutionContext;
gPlayerState.playerAction = 0x1c;
gPlayerState.field_0x3a = 0;
gPlayerState.field_0x39 = 0;
gPlayerState.field_0x38 = 0;
}
ScriptExecutionContext* sub_0807DB68(Entity* entity, u16* unk1) {
ScriptExecutionContext* context;
context = CreateScriptExecutionContext();
if (context) {
entity->flags |= 2;
*(ScriptExecutionContext**)&entity->field_0x3c = context;
context->unk_00 = unk1;
}
return context;
}
void sub_0807DB88(ScriptExecutionContext* context, u16* unk1) {
_DmaZero(context, sizeof(ScriptExecutionContext));
context->unk_00 = unk1;
}
void sub_0807DB98(Entity* entity, ScriptExecutionContext* context) {
u32 switchVar;
while (context->unk_08) {
switchVar = (~context->unk_08 + 1) & context->unk_08;
context->unk_08 ^= switchVar;
switch (switchVar) {
case 1:
entity->field_0x80.HWORD = 0;
break;
case 2:
entity->field_0x80.HWORD = 4;
break;
case 4:
break;
case 8:
entity->field_0x20 = 0x18000;
break;
case 0x10:
CreateSpeechBubbleExclamationMark(entity, 8, -0x18);
break;
case 0x20:
CreateSpeechBubbleQuestionMark(entity, 8, -0x18);
break;
case 0x40:
DestroyScriptExecutionContext(context);
DeleteThisEntity();
case 0x80:
entity->spriteSettings.b.draw = 1;
break;
case 0x100:
entity->spriteSettings.b.draw = 0;
break;
case 0x200:
entity->spriteOffsetY = 0;
entity->spriteOffsetX = 0;
entity->field_0x82.HWORD = 0;
break;
case 0x400:
entity->field_0x82.HWORD |= 2;
break;
case 0x800:
entity->field_0x82.HWORD &= 0xfffd;
break;
case 0x1000:
entity->field_0x82.HWORD &= 0xfffe;
break;
case 0x2000:
entity->field_0x82.HWORD |= 1;
break;
case 0x4000:
entity->field_0x82.HWORD |= 8;
break;
case 0x8000:
entity->field_0x82.HWORD ^= 4;
break;
case 0x10000:
entity->field_0x82.HWORD ^= 0x10;
break;
case 0x20000:
entity->spriteSettings.b.flipX ^= 1;
break;
case 0x40000:
entity->field_0x82.HWORD |= 0x20;
break;
case 0x80000:
entity->field_0x82.HWORD &= 0xffdf;
break;
default:
break;
}
}
}
void sub_0807DD50(Entity* entity) {
sub_0807DD64(entity);
sub_0807DD94(entity, 0);
}
void sub_0807DD64(Entity* entity) {
entity->field_0xf = entity->animationState;
entity->animIndex = 0xff;
entity->field_0x80.HWORD = 0;
entity->field_0x82.HWORD = 0;
}
void sub_0807DD80(Entity* entity, u16* unk1) {
sub_0807DB88(*(ScriptExecutionContext**)&entity->cutsceneBeh, unk1);
sub_0807DD64(entity);
}
void sub_0807DD94(Entity* entity, void (*function)(Entity*, ScriptExecutionContext*)) {
sub_0807DDAC(entity, function);
sub_0807DDE4(entity);
sub_0807DE80(entity);
}
void sub_0807DDAC(Entity* entity, void (*function)(Entity*, ScriptExecutionContext*)) {
ScriptExecutionContext** piVar1;
piVar1 = (ScriptExecutionContext**)&entity->cutsceneBeh;
if (*piVar1) {
ExecuteScriptCommandSet(entity, *piVar1);
if (function) {
function(entity, *piVar1);
} else {
sub_0807DB98(entity, *piVar1);
}
if (!entity->next) {
DeleteThisEntity();
}
}
}
void sub_0807DDE4(Entity* entity) {
u32 temp;
u32 switchVar;
u32 loopVar;
loopVar = entity->field_0x82.HWORD;
while (loopVar) {
switchVar = (~loopVar + 1) & loopVar;
loopVar = loopVar ^ switchVar;
switch (switchVar) {
case 2:
if (entity->entityType.type == 7) {
sub_0806ED78(entity);
} else {
sub_0800445C(entity);
}
break;
case 8:
if ((gScreenTransition.frameCount & 3) == 0) {
temp = (entity->field_0xf + 2U) & 7;
entity->animationState = temp;
entity->field_0xf = temp;
}
break;
case 0x10:
if ((gScreenTransition.frameCount & 1) == 0) {
entity->spriteOffsetX = gUnk_0811E510[Random() & 3];
}
break;
case 0x20:
sub_08003FC4(entity, 0x2000);
break;
}
}
}
void sub_0807DE80(Entity* entity) {
u32 local1;
u16 local2;
u32 temp;
local2 = entity->field_0x80.HWORD;
if (local2 < 8) {
if (entity->field_0x82.HWORD & 1) {
u32 t1, t2;
t1 = local2 & 0xfc;
t2 = entity->field_0xf >> 1;
local2 = t1 + t2;
} else {
u32 t1, t2;
t1 = local2 & 0xfc;
t2 = entity->animationState >> 1;
local2 = t1 + t2;
entity->field_0xf = entity->animationState;
}
}
if (local2 != entity->animIndex) {
InitAnimationForceUpdate(entity, local2);
}
temp = entity->field_0x82.HWORD & 4;
local1 = 1;
if (temp) {
local1 = 2;
}
sub_080042BA(entity, local1);
}
void sub_0807DEDC(Entity* entity, ScriptExecutionContext* context, u32 arg2, u32 arg3) {
int temp;
s32 t0, t1;
context->unk_19 = 8;
context->unk_08 |= 2;
context->unk_14 = 0;
context->unk_1C.HALF.HI = arg2;
context->unk_20.HALF.HI = arg3;
t0 = context->unk_1C.HALF.HI - entity->x.HALF.HI;
t1 = context->unk_20.HALF.HI - entity->y.HALF.HI;
temp = sub_080045DA(t0, t1);
entity->direction = temp;
entity->animationState = (entity->animationState & 0x80) | gUnk_0811E514[(u32)(temp << 0x18) >> 0x1c];
}
void sub_0807DF28(void) {
sub_0807DF38();
sub_08079184();
sub_08077B20();
}
void sub_0807DF38(void) {
gUnk_0200AF00.filler0[1] = 0xff;
gUnk_02034490[0] = 0xff;
}
void sub_0807DF50(void) {
gUnk_02034490[0] = 0;
gUnk_0200AF00.filler0[1] = 0;
sub_0801C4A0(0);
sub_080791D0();
sub_08079184();
}