mirror of
https://github.com/Xeeynamo/sotn-decomp.git
synced 2024-11-26 22:40:33 +00:00
Decompile ST0 func_801ABBBC (#1041)
First function of my new effort to make progress in ST0. There's a fun bug in case 5 where they forgot to increment their prim. This required the creation of a new variety of Primitive, since there's strong evidence of an `f32` at offset 0x20. For now it's draculaPrimitive, but maybe we'll find more uses of it in the future. I think those are the main highlights. No pressure to merge this one quickly, I'm expecting progress on ST0 to be slow.
This commit is contained in:
parent
6011e02320
commit
fc78c026e5
@ -49,7 +49,7 @@ segments:
|
||||
- [0x27ACC, .rodata, 2A8DC] # EntitySecretStairs
|
||||
- [0x27AE0, .rodata, 2B0C8] # EntityStageTitleFadeout
|
||||
- [0x27B00, .rodata, 2B0C8] # EntityStageTitleCard
|
||||
- [0x27B18, rodata]
|
||||
- [0x27B18, .rodata, 2B0C8] # func_801ABBBC
|
||||
- [0x27B40, .rodata, 2C564] # EntityDracula
|
||||
- [0x27B7C, rodata]
|
||||
- [0x27BFC, rodata]
|
||||
|
@ -278,10 +278,16 @@ typedef struct {
|
||||
} ET_GurkhaSword;
|
||||
|
||||
typedef struct ET_Dracula {
|
||||
/* 0x7C */ char pad_7C[0x10];
|
||||
/* 0x7C */ char pad_7C[4];
|
||||
/* 0x80 */ struct draculaPrimitive* unk80;
|
||||
/* 0x84 */ struct draculaPrimitive* unk84;
|
||||
/* 0x88 */ char pad_88[4];
|
||||
/* 0x8C */ s16 unk8C;
|
||||
/* 0x8E */ char pad_8E[0x2];
|
||||
/* 0x90 */ char pad_90[0x4];
|
||||
/* 0x90 */ u8 unk90;
|
||||
/* 0x91 */ char pad91;
|
||||
/* 0x92 */ u8 unk92;
|
||||
/* 0x93 */ char pad93;
|
||||
/* 0x94 */ u8 unk94;
|
||||
/* 0x95 */ char pad_95[0x3];
|
||||
/* 0x98 */ s16 unk98;
|
||||
|
@ -33,6 +33,7 @@ typedef enum {
|
||||
PRIM_SPRT,
|
||||
PRIM_ENV,
|
||||
PRIM_TILE_ALT = PRIM_TILE | 0x10,
|
||||
PRIM_LINE_G2_ALT = PRIM_LINE_G2 | 0x10,
|
||||
PRIM_G4_ALT = PRIM_G4 | 0x10
|
||||
} PrimitiveType;
|
||||
|
||||
|
@ -103,4 +103,40 @@ typedef struct {
|
||||
/* 0x2C */ f32 preciseY;
|
||||
/* 0x30 */ s16 timer;
|
||||
/* 0x32 */ u16 drawMode;
|
||||
} PrimLineG2;
|
||||
} PrimLineG2;
|
||||
|
||||
typedef struct {
|
||||
struct primitive* next;
|
||||
/* 0x04 */ u8 r0;
|
||||
/* 0x05 */ u8 g0;
|
||||
/* 0x06 */ u8 b0;
|
||||
/* 0x07 */ u8 type;
|
||||
/* 0x08 */ s16 x0;
|
||||
/* 0x0A */ s16 y0;
|
||||
/* 0x0C */ u8 u0;
|
||||
/* 0x0D */ u8 v0;
|
||||
/* 0x0E */ u16 clut;
|
||||
/* 0x10 */ u8 r1;
|
||||
/* 0x11 */ u8 g1;
|
||||
/* 0x12 */ u8 b1;
|
||||
/* 0x13 */ u8 p1;
|
||||
/* 0x14 */ s16 x1;
|
||||
/* 0x16 */ s16 y1;
|
||||
/* 0x18 */ u8 u1;
|
||||
/* 0x19 */ u8 v1;
|
||||
/* 0x1A */ u16 tpage;
|
||||
/* 0x1C */ u8 r2;
|
||||
/* 0x1D */ u8 g2;
|
||||
/* 0x1E */ u8 b2;
|
||||
/* 0x1F */ u8 p2;
|
||||
/* 0x20 */ f32 y1_f32;
|
||||
/* 0x24 */ s16 unk24;
|
||||
/* 0x26 */ u16 priority;
|
||||
/* 0x28 */ u8 r3;
|
||||
/* 0x29 */ u8 g3;
|
||||
/* 0x2A */ u8 b3;
|
||||
/* 0x2B */ u8 p3;
|
||||
/* 0x2C */ f32 y1_f32_velocity;
|
||||
/* 0x30 */ s16 unk30;
|
||||
/* 0x32 */ u16 drawMode;
|
||||
} draculaPrimitive;
|
@ -381,7 +381,324 @@ void EntityStageTitleCard(Entity* self) {
|
||||
}
|
||||
}
|
||||
|
||||
INCLUDE_ASM("st/st0/nonmatchings/2B0C8", func_801ABBBC);
|
||||
// Helper function for EntityDracula
|
||||
u32 func_801ABBBC(s32 step, Entity* dracula) {
|
||||
draculaPrimitive* prim;
|
||||
s32 randVar;
|
||||
s32 randVar2;
|
||||
s32 colorLimit;
|
||||
s32 var_a1;
|
||||
s32 var_a2;
|
||||
s32 var_a3;
|
||||
s32 i;
|
||||
s32 var_t0;
|
||||
s32 fake_a2;
|
||||
s32 color;
|
||||
u8* redPtr;
|
||||
u8* greenPtr;
|
||||
u8 constFF;
|
||||
|
||||
switch (step) {
|
||||
case 0:
|
||||
prim = dracula->ext.dracula.prim;
|
||||
dracula->ext.dracula.unk80 = prim;
|
||||
for (i = 0; i < 16; i++) {
|
||||
prim->type = PRIM_LINE_G2_ALT;
|
||||
if (i == 15) {
|
||||
prim->type = PRIM_LINE_G2;
|
||||
}
|
||||
if (i & 1) {
|
||||
prim->x0 = prim->x1 = dracula->posX.i.hi + i / 2;
|
||||
} else {
|
||||
prim->x0 = prim->x1 = dracula->posX.i.hi - i / 2;
|
||||
}
|
||||
|
||||
prim->y0 = prim->y1 = 0;
|
||||
prim->r0 = prim->g0 = prim->b0 = 0x70;
|
||||
prim->r1 = prim->g1 = prim->b1 = 0;
|
||||
randVar = Random();
|
||||
prim->r2 = (((randVar & 1) * 0x10) + 0x10);
|
||||
prim->g2 = (((randVar * 8) & 0x10) + 0x10);
|
||||
prim->b2 = (((randVar * 4) & 0x10) + 0x10);
|
||||
prim->priority = dracula->zPriority + 2;
|
||||
prim->drawMode = 0x33;
|
||||
if (i == 0) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
}
|
||||
prim = prim->next;
|
||||
}
|
||||
step++;
|
||||
dracula->ext.dracula.unk90 = 1;
|
||||
dracula->ext.dracula.unk92 = 0;
|
||||
dracula->ext.dracula.unk8C = 0;
|
||||
break;
|
||||
case 1:
|
||||
if (dracula->ext.dracula.unk8C++ >= 3) {
|
||||
dracula->ext.dracula.unk90 += 2;
|
||||
if (dracula->ext.dracula.unk90 >= 16) {
|
||||
dracula->ext.dracula.unk90 = 16;
|
||||
}
|
||||
dracula->ext.dracula.unk8C = 0;
|
||||
}
|
||||
prim = dracula->ext.dracula.unk80;
|
||||
i = 0;
|
||||
for (i = 0; i < dracula->ext.dracula.unk90; i++) {
|
||||
prim->y1 += 0x30;
|
||||
if (dracula->ext.dracula.unkA1 != 0) {
|
||||
if (prim->y1 >= 171) {
|
||||
prim->y1 = 171;
|
||||
}
|
||||
} else if (prim->y1 >= 203) {
|
||||
prim->y1 = 203;
|
||||
}
|
||||
// Iterate through r1, g1, and b1.
|
||||
for (redPtr = &prim->r1, var_a1 = 0; var_a1 < 3; redPtr++,
|
||||
var_a1++) {
|
||||
color = *redPtr;
|
||||
if (color < 0xFF) {
|
||||
// This ends up offsetting to r2, g2, and b2
|
||||
color += redPtr[0xC];
|
||||
if (color > 0xFF) {
|
||||
color = 0xFF;
|
||||
}
|
||||
}
|
||||
*redPtr = color;
|
||||
}
|
||||
prim = prim->next;
|
||||
}
|
||||
if (dracula->ext.dracula.unk92++ >= 25) {
|
||||
dracula->ext.dracula.unk92 = 0;
|
||||
step++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
prim = dracula->ext.dracula.unk80;
|
||||
for (i = 0; i < 16; i++) {
|
||||
prim = prim->next;
|
||||
}
|
||||
dracula->ext.dracula.unk84 = prim;
|
||||
for (i = 0; i < 48; i++) {
|
||||
prim->type = PRIM_LINE_G2_ALT;
|
||||
if (i == 47) {
|
||||
prim->type = PRIM_LINE_G2;
|
||||
}
|
||||
prim->r0 = prim->g0 = prim->b0 = 0x70;
|
||||
prim->r1 = prim->g1 = prim->b1 = 0x20;
|
||||
randVar2 = Random();
|
||||
prim->r2 = (((randVar2 & 1) * 4) + 4);
|
||||
prim->g2 = (((randVar2 * 2) & 4) + 4);
|
||||
prim->b2 = ((randVar2 & 4) + 4);
|
||||
if (i & 1) {
|
||||
prim->x0 = prim->x1 = dracula->posX.i.hi + i / 2;
|
||||
} else {
|
||||
prim->x0 = prim->x1 = dracula->posX.i.hi - i / 2;
|
||||
}
|
||||
if (dracula->ext.dracula.unkA1 != 0) {
|
||||
prim->y0 = prim->y1 = 171;
|
||||
if (i >= 0x22) {
|
||||
prim->y0 = prim->y1 = -0x20;
|
||||
}
|
||||
} else {
|
||||
prim->y0 = prim->y1 = 203;
|
||||
}
|
||||
prim->y1_f32.i.lo = 0;
|
||||
prim->y1_f32.i.hi = prim->y1;
|
||||
// FAKE variable reuse
|
||||
color = (i >> 1);
|
||||
prim->y1_f32_velocity.val =
|
||||
((color * color * color) << 8) + 0x80000;
|
||||
prim->priority = dracula->zPriority + 2;
|
||||
prim->drawMode = 0x33;
|
||||
if (i == 0) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
}
|
||||
prim = prim->next;
|
||||
}
|
||||
step++;
|
||||
dracula->ext.dracula.unk8C = 0;
|
||||
g_api.PlaySfx(0x636);
|
||||
break;
|
||||
case 3:
|
||||
prim = dracula->ext.dracula.unk84;
|
||||
if (dracula->ext.dracula.unkA1 != 0) {
|
||||
var_a1 = 0x22;
|
||||
} else {
|
||||
var_a1 = 0x30;
|
||||
}
|
||||
for (i = 0; i < var_a1; prim = prim->next) {
|
||||
prim->y1_f32.i.hi = prim->y1;
|
||||
prim->y1_f32.val -= prim->y1_f32_velocity.val;
|
||||
prim->y1 = prim->y1_f32.i.hi;
|
||||
i++;
|
||||
if (prim->y1 < 0) {
|
||||
prim->y1 = 0U;
|
||||
}
|
||||
}
|
||||
if (++dracula->ext.dracula.unk8C < 9) {
|
||||
prim = dracula->ext.dracula.unk80;
|
||||
for (i = 0; i < 16 - (dracula->ext.dracula.unk8C * 2); i++) {
|
||||
prim = prim->next;
|
||||
}
|
||||
for (; i < 16; i++) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = prim->next;
|
||||
}
|
||||
}
|
||||
prim = dracula->ext.dracula.unk84;
|
||||
for (i = 0, constFF = 0xFF, colorLimit = 0xFF; i < 48; i++) {
|
||||
color = prim->r0;
|
||||
color += 4;
|
||||
prim->r0 = (color > colorLimit ? colorLimit : color);
|
||||
colorLimit -= 2;
|
||||
if (prim->r0 >= 0xFF) {
|
||||
prim->r0 = constFF;
|
||||
step = 4;
|
||||
}
|
||||
prim->b0 = prim->g0 = prim->r0;
|
||||
prim = prim->next;
|
||||
}
|
||||
var_a2 = 0xFF;
|
||||
prim = dracula->ext.dracula.unk84;
|
||||
for (i = 0; i < 48; i++) {
|
||||
redPtr = &prim->r1;
|
||||
for (var_a1 = 0; var_a1 < 3; var_a1 += 1) {
|
||||
color = *redPtr;
|
||||
color += redPtr[0xC];
|
||||
if (var_a2 < color) {
|
||||
color = var_a2;
|
||||
}
|
||||
*redPtr = color;
|
||||
redPtr++;
|
||||
}
|
||||
prim = prim->next;
|
||||
var_a2 -= 2;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
var_t0 = 1;
|
||||
prim = dracula->ext.dracula.unk84;
|
||||
for (i = 0, var_a3 = 0xFF; i < 48; i++) {
|
||||
|
||||
for (redPtr = &prim->r1, var_a1 = 0, var_a2 = var_a3; var_a1 < 3;
|
||||
redPtr++, var_a1++) {
|
||||
color = *redPtr;
|
||||
color += 0x18;
|
||||
if (var_a2 < color) {
|
||||
color = var_a2;
|
||||
} else {
|
||||
var_t0 = 0;
|
||||
}
|
||||
*redPtr = color;
|
||||
}
|
||||
prim = prim->next;
|
||||
var_a3 -= 2;
|
||||
}
|
||||
if (var_t0 != 0) {
|
||||
step = 5;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
prim = dracula->ext.dracula.unk80;
|
||||
// @bug: They forgot to do prim = prim->next in this loop!
|
||||
for (i = 0; i < 16; i++) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
}
|
||||
prim = dracula->ext.dracula.unk80;
|
||||
prim->type = PRIM_TILE;
|
||||
prim->r0 = prim->g0 = prim->b0 = 0;
|
||||
prim->y0 = 0;
|
||||
if (dracula->ext.dracula.unkA1 != 0) {
|
||||
prim->x0 = dracula->posX.i.hi - 17;
|
||||
prim->u0 = 0x22;
|
||||
prim->v0 = 0xAC;
|
||||
} else {
|
||||
prim->x0 = dracula->posX.i.hi - 24;
|
||||
prim->u0 = 0x30;
|
||||
prim->v0 = 0xCC;
|
||||
}
|
||||
step++;
|
||||
prim->priority = dracula->zPriority + 1;
|
||||
prim->drawMode = 0x53;
|
||||
dracula->ext.dracula.unk8C = 0;
|
||||
break;
|
||||
case 6:
|
||||
var_t0 = 1;
|
||||
prim = dracula->ext.dracula.unk84;
|
||||
for (i = 0; i < 48; i++) {
|
||||
redPtr = &prim->r0;
|
||||
var_a1 = 0;
|
||||
greenPtr = &prim->g0;
|
||||
for (; var_a1 < 2;) {
|
||||
color = *redPtr;
|
||||
color -= 10;
|
||||
if (color < 0) {
|
||||
color = 0;
|
||||
} else {
|
||||
var_t0 = 0;
|
||||
}
|
||||
var_a1++;
|
||||
greenPtr[0] = greenPtr[1] = color;
|
||||
greenPtr += 0xC;
|
||||
*redPtr = color;
|
||||
redPtr += 0xC;
|
||||
}
|
||||
prim = prim->next;
|
||||
}
|
||||
prim = dracula->ext.dracula.unk80;
|
||||
prim->r0 += 7;
|
||||
if (prim->r0 > 0xE0) {
|
||||
prim->r0 = 0xE0;
|
||||
} else {
|
||||
var_t0 = 0;
|
||||
}
|
||||
prim->g0 = prim->b0 = prim->r0;
|
||||
if (var_t0 != 0) {
|
||||
prim = dracula->ext.dracula.unk84;
|
||||
for (i = 0; i < 48; i++) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = prim->next;
|
||||
}
|
||||
step++;
|
||||
dracula->drawFlags = DRAW_HIDE;
|
||||
dracula->unk6C = 0;
|
||||
dracula->ext.dracula.unkA0 = 1;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
prim = dracula->ext.dracula.unk80;
|
||||
color = prim->r0;
|
||||
color -= 16;
|
||||
if (color < 0) {
|
||||
color = 0;
|
||||
}
|
||||
prim->g0 = prim->b0 = prim->r0 = color;
|
||||
if (prim->r0 < 16) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
step++;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
dracula->unk6C += 10;
|
||||
if (dracula->unk6C >= 0x80U) {
|
||||
step++;
|
||||
dracula->unk6C = 0x80U;
|
||||
dracula->drawFlags = 0;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
prim = dracula->ext.dracula.prim;
|
||||
while (prim != NULL) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = prim->next;
|
||||
}
|
||||
step = 0xFF;
|
||||
if (dracula->ext.dracula.unkA1 != 0) {
|
||||
dracula->ext.dracula.unkA1 = 0U;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return step;
|
||||
}
|
||||
|
||||
s32 func_801AC458(s16 arg0) {
|
||||
s32 ret = arg0;
|
||||
|
Loading…
Reference in New Issue
Block a user