pmd-red/src/credits.c
2023-07-22 23:11:00 -04:00

247 lines
5.9 KiB
C

#include "global.h"
#include "input.h"
#include "memory.h"
#include "text.h"
// size: 0x6C
struct unkCreditsStruct_203B340
{
struct UnkTextStruct2 unk0[4];
s32 unk60; // Unsure if s32/u32/ptr
s32 unk64;
/* 0x68 */ s32 creditsCategoryIndex;
};
// size: 0x8
struct unkCreditsStruct_203B344
{
/* 0x0 */ u32 state; // state variable
u32 unk4; // timer?
};
// size: 0xC
struct CreditsData
{
/* 0x0 */ s16 type;
s16 x;
s16 y;
/* 0x8 */ u8 *text;
};
extern struct unkCreditsStruct_203B340 *gUnknown_203B340;
extern struct unkCreditsStruct_203B344 *gUnknown_203B344;
extern struct UnkTextStruct2 gUnknown_80E4A10;
extern struct UnkTextStruct2 gUnknown_80E4A28;
extern const u32 gUnknown_80E4A40[];
extern struct CreditsData* gCreditsTable[27];
extern u16 gUnknown_80E5990[];
extern void sub_80015C0(u32, u32);
extern s32 sub_8001658(u32, u32);
extern void sub_80073B8(u32);
extern void sub_80073E0(u32);
extern void sub_8099690(u32);
extern void sub_8099A5C(u32, u32, u32);
extern void sub_8099AFC(u32, u32, u32);
extern u8 sub_8099B94();
// Unsure if param_2 is a s32/u32/ptr
s32 DrawCredits(s32 creditsCategoryIndex, s32 param_2)
{
s32 i;
s32 x;
s32 y;
struct CreditsData *cred;
u8 *srcText;
u8 *destText1;
u8 *destText2;
u8 curChar;
u8 buffer[128];
gUnknown_203B340 = (struct unkCreditsStruct_203B340 *)MemoryAlloc(sizeof(struct unkCreditsStruct_203B340), 8);
gUnknown_203B340->unk60 = 0;
gUnknown_203B340->unk64 = param_2;
gUnknown_203B340->creditsCategoryIndex = creditsCategoryIndex;
for (i = 0; i < 4; i++)
gUnknown_203B340->unk0[i] = gUnknown_80E4A10;
gUnknown_203B340->unk0[0] = gUnknown_80E4A28;
ResetUnusedInputStruct();
sub_800641C(&gUnknown_203B340->unk0[0], 1, 1);
sub_8099690(2);
sub_80073B8(0);
cred = creditsCategoryIndex[gCreditsTable]; // WTF
y = 0;
while (cred->text != NULL) {
srcText = cred->text;
if (cred->y >= 0)
y = cred->y;
else
y -= cred->y;
x = cred->x;
switch (cred->type) {
case 1:
destText1 = buffer;
while ((curChar = *srcText) != 0) {
*destText1 = curChar;
srcText++;
destText1++;
}
*destText1 = 0;
srcText = buffer;
break;
case 2:
destText2 = buffer;
while ((curChar = *srcText) != 0) {
*destText2 = curChar;
srcText++;
destText2++;
}
*destText2 = 0;
srcText = buffer;
break;
}
xxx_call_draw_string(x, y, srcText, 0, 0);
cred++;
}
sub_80073E0(0);
SelectCharmap(0);
do {
const u32 *a = gUnknown_80E4A40;
int b = 9;
unsigned long long c = b;
sub_8099AFC(c, 0, a[0]);
} while(0);
return 1;
}
s32 sub_8035574(void)
{
#ifdef NONMATCHING
u32 const *p;
#else
register u32 const *p asm("r2");
#endif
switch (gUnknown_203B340->unk60) {
case 0:
if (sub_8099B94() == 0) {
gUnknown_203B340->unk60 = 1;
p = gUnknown_80E4A40;
sub_8099A5C(9, 30, p[0]); // Probably same/similar macro from the above func - Kermalis
}
break;
case 1:
if (sub_8099B94() == 0)
gUnknown_203B340->unk60 = 2;
break;
case 2:
if (gUnknown_203B340->unk64 < 1) {
gUnknown_203B340->unk60 = 3;
p = gUnknown_80E4A40;
sub_8099AFC(9, 30, p[0]);
}
gUnknown_203B340->unk64--;
break;
case 3:
if (sub_8099B94() == 0) {
ResetUnusedInputStruct();
sub_800641C(NULL, 1, 1);
gUnknown_203B340->unk60 = 4;
}
break;
case 4:
sub_8099690(0);
p = gUnknown_80E4A40;
sub_8099A5C(1, 0, p[0]);
return 3;
}
return 0;
}
// Frees gUnknown_203B340
void sub_803565C(void)
{
if (gUnknown_203B340 != NULL) {
MemoryFree(gUnknown_203B340);
gUnknown_203B340 = NULL;
}
}
u32 sub_8035678(void)
{
gUnknown_203B344 = MemoryAlloc(sizeof(struct unkCreditsStruct_203B344), 8);
gUnknown_203B344->state = 0;
gUnknown_203B344->unk4 = 0;
sub_80015C0(0, 0x39);
return 1;
}
u32 sub_80356A0(void)
{
u16 uVar1;
u16 held_input;
held_input = gRealInputs.held;
uVar1 = gUnknown_80E5990[gUnknown_203B344->unk4];
switch (gUnknown_203B344->state) {
case 0:
gUnknown_203B344->state = 3;
break;
case 1:
if (uVar1 == 0)
gUnknown_203B344->state = 4;
else {
if (held_input == uVar1)
gUnknown_203B344->state = 2;
else {
// NOTE: couldn't match with OR'd condition so split up to match
if ((uVar1 & held_input) != held_input)
gUnknown_203B344->state = 3;
else
{
if (gUnknown_203B344->unk4 == 0)
gUnknown_203B344->state = 3;
}
}
}
break;
case 2:
if (held_input == 0) {
gUnknown_203B344->state = 1;
gUnknown_203B344->unk4++;
}
else {
if ((uVar1 & held_input) != held_input)
gUnknown_203B344->state = 3;
}
break;
case 3:
return 2;
case 4:
return 3; // sub_809C478 clears the flash data when this is returned
}
if (sub_8001658(0, 0x39) != 0) {
gUnknown_203B344->state = 3;
return 2;
}
else
return 0;
}
// Frees gUnknown_203B344
void sub_8035758(void)
{
if (gUnknown_203B344 != NULL) {
MemoryFree(gUnknown_203B344);
gUnknown_203B344 = NULL;
}
}