Decompile ST0 func_801BD8F0 (#1563)

In addition to decompiling the function, two big changes were needed:

- Decompiling this function uncovered a maspsx bug with generating `nop`
padding instructions; that is now fixed and this PR includes a maspsx
update.
- We also discovered (thanks @mkst !) that g_Tilemap.bg was not actually
a member of g_Tilemap. I renamed it to g_BgLayers, and did a
find-and-replace across the repo to change all references. This appears
to have no impact on any existing function, but leads to the correct
register loading on this function.

It's a weird one, and was tricky to get matching (actually, this was a
super old decomp.me browser tab I discovered was still open, which is
why I came back to it), but these tricky ones are great for discovering
where we have mistakes in our structure of the game's data.
This commit is contained in:
bismurphy 2024-08-22 13:19:49 -04:00 committed by GitHub
parent 5ce562a3ed
commit a11c22adef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 381 additions and 74 deletions

View File

@ -82,7 +82,7 @@ segments:
- [0x27CAC, .rodata, e_collect] # EntityEquipItemDrop
- [0x27CC4, rodata]
- [0x27D3C, .rodata, prim_helpers]
- [0x27D44, rodata]
- [0x27D44, .rodata, 3D8F0]
- [0x27D64, c]
- [0x28984, c, draculacutscene]
- [0x2A218, c]

View File

@ -931,16 +931,16 @@ g_Tilemap_x = 0x800730C0;
g_Tilemap_y = 0x800730C4;
g_Tilemap_width = 0x800730C8;
g_Tilemap_height = 0x800730CC;
g_Tilemap_bg = 0x800730D8;
g_Tilemap_bg_0_tiledef = 0x800730DC;
g_Tilemap_bg_0_scrollX_i_hi = 0x800730E2;
g_Tilemap_bg_0_scrollY_i_hi = 0x800730E6;
g_Tilemap_bg_0_zPriority = 0x800730F0;
g_Tilemap_bg_0_flags = 0x800730F4;
g_Tilemap_bg_0_w = 0x800730F8;
g_Tilemap_bg_0_h = 0x800730FC;
g_Tilemap_bg_0_D_80073100 = 0x80073100;
g_Tilemap_bg_0_scrollKind = 0x80073104;
g_BgLayers = 0x800730D8;
g_BgLayers_0_tiledef = 0x800730DC;
g_BgLayers_0_scrollX_i_hi = 0x800730E2;
g_BgLayers_0_scrollY_i_hi = 0x800730E6;
g_BgLayers_0_zPriority = 0x800730F0;
g_BgLayers_0_flags = 0x800730F4;
g_BgLayers_0_w = 0x800730F8;
g_BgLayers_0_h = 0x800730FC;
g_BgLayers_0_D_80073100 = 0x80073100;
g_BgLayers_0_scrollKind = 0x80073104;
g_Entities = 0x800733D8;
PLAYER_posX_i_hi = 0x800733DA;
PLAYER_posY_val = 0x800733DC;

View File

@ -47,7 +47,6 @@ EntityDraculaFinalForm = 0x801ADD60;
EntityDraculaMegaFireball = 0x801AEFD8;
EntityDraculaRainAttack = 0x801AF154;
PrologueScroll = 0x801B0464;
Random = 0x801B186C;
EntityDamageDisplay = 0x801B2A3C;
CreateEntityFromCurrentEntity = 0x801B3B68;
EntityRedDoor = 0x801B3CD0;

View File

@ -960,16 +960,16 @@ g_Tilemap_x = 0x800730C0;
g_Tilemap_y = 0x800730C4;
g_Tilemap_width = 0x800730C8;
g_Tilemap_height = 0x800730CC;
g_Tilemap_bg = 0x800730D8;
g_Tilemap_bg_0_tiledef = 0x800730DC;
g_Tilemap_bg_0_scrollX_i_hi = 0x800730E2;
g_Tilemap_bg_0_scrollY_i_hi = 0x800730E6;
g_Tilemap_bg_0_zPriority = 0x800730F0;
g_Tilemap_bg_0_flags = 0x800730F4;
g_Tilemap_bg_0_w = 0x800730F8;
g_Tilemap_bg_0_h = 0x800730FC;
g_Tilemap_bg_0_D_80073100 = 0x80073100;
g_Tilemap_bg_0_scrollKind = 0x80073104;
g_BgLayers = 0x800730D8;
g_BgLayers_0_tiledef = 0x800730DC;
g_BgLayers_0_scrollX_i_hi = 0x800730E2;
g_BgLayers_0_scrollY_i_hi = 0x800730E6;
g_BgLayers_0_zPriority = 0x800730F0;
g_BgLayers_0_flags = 0x800730F4;
g_BgLayers_0_w = 0x800730F8;
g_BgLayers_0_h = 0x800730FC;
g_BgLayers_0_D_80073100 = 0x80073100;
g_BgLayers_0_scrollKind = 0x80073104;
g_Entities = 0x800733D8;
PLAYER_posX_i_hi = 0x800733DA;
PLAYER_posY_val = 0x800733DC;

View File

@ -13,6 +13,7 @@ D_8006ED4C = 0x8006ED4C;
g_Player = 0x80072BD0;
g_Tilemap = 0x80073084;
g_BgLayers = 0x800730D8;
g_Camera = 0x8007308C;
g_CurrentRoom = 0x800730A0;

View File

@ -1639,7 +1639,6 @@ typedef struct {
/* 800730CC */ s32 height;
/* 800730D0 */ s32 unk30;
/* 800730D4 */ s32 D_800730D4;
/* 800730D8 */ BgLayer bg[MAX_BG_LAYER_COUNT];
} Tilemap;
typedef struct {
@ -1833,6 +1832,9 @@ extern Event g_EvSwCardNew; // 80073078
extern s32 g_PrevScrollY;
extern s32 D_80073080;
extern Tilemap g_Tilemap;
// this was previously g_Tilemap.bg, but func_801BD8F0 showed that it is a
// separate symbol.
extern BgLayer g_BgLayers[MAX_BG_LAYER_COUNT]; /* 800730D8 */
extern Entity g_Entities[TOTAL_ENTITY_COUNT];
extern s32 g_entityDestroyed[18];
extern Event g_EvHwCardEnd;

View File

@ -158,6 +158,38 @@ extern long ratan2(long y, long x);
#define gte_stsxy(r0) \
__asm__ volatile("swc2 $14, 0( %0 )" : : "r"(r0) : "memory")
#define gte_stsxy3_gt3(r0) \
__asm__ volatile( \
"swc2 $12, 8( %0 );" \
"swc2 $13, 20( %0 );" \
"swc2 $14, 32( %0 )" \
: \
: "r"(r0) \
: "memory")
#define gte_ldv3c(r0) \
__asm__ volatile( \
"lwc2 $0, 0( %0 );" \
"lwc2 $1, 4( %0 );" \
"lwc2 $2, 8( %0 );" \
"lwc2 $3, 12( %0 );" \
"lwc2 $4, 16( %0 );" \
"lwc2 $5, 20( %0 )" \
: \
: "r"(r0))
#define gte_SetTransVector(r0) \
__asm__ volatile( \
"lw $12, 0( %0 );" \
"lw $13, 4( %0 );" \
"lw $14, 8( %0 );" \
"ctc2 $12, $5;" \
"ctc2 $13, $6;" \
"ctc2 $14, $7" \
: \
: "r"(r0) \
: "$12", "$13", "$14")
#define gte_SetGeomScreen(r0) __asm__ volatile("ctc2 %0, $26" : : "r"(r0))
#else

View File

@ -1286,7 +1286,7 @@ void HideAllBackgroundLayers(void) {
g_Tilemap.flags = 0;
for (i = 0; i < MAX_BG_LAYER_COUNT; i++) {
g_Tilemap.bg[i].flags = 0;
g_BgLayers[i].flags = 0;
}
}
@ -1445,7 +1445,7 @@ void RenderTilemap(void) {
}
l = 0;
bg = g_Tilemap.bg;
bg = g_BgLayers;
for (; l < MAX_BG_LAYER_COUNT; l++, bg++) {
if (bg->hideTimer > 0) {
bg->hideTimer--;
@ -1590,16 +1590,16 @@ void SetRoomForegroundLayer(LayerDef* layerDef) {
}
void SetRoomBackgroundLayer(s32 index, LayerDef* layerDef) {
g_Tilemap.bg[index].flags = 0;
g_Tilemap.bg[index].tileDef = layerDef->tileDef;
g_Tilemap.bg[index].layout = layerDef->layout;
if (g_Tilemap.bg[index].tileDef != 0) {
g_Tilemap.bg[index].order = layerDef->zPriority;
g_Tilemap.bg[index].flags = layerDef->flags;
g_Tilemap.bg[index].w = layerDef->rect.right - layerDef->rect.left + 1;
g_Tilemap.bg[index].h = layerDef->rect.bottom - layerDef->rect.top + 1;
g_Tilemap.bg[index].scrollKind = layerDef->rect.params;
g_Tilemap.bg[index].hideTimer = 1;
g_BgLayers[index].flags = 0;
g_BgLayers[index].tileDef = layerDef->tileDef;
g_BgLayers[index].layout = layerDef->layout;
if (g_BgLayers[index].tileDef != 0) {
g_BgLayers[index].order = layerDef->zPriority;
g_BgLayers[index].flags = layerDef->flags;
g_BgLayers[index].w = layerDef->rect.right - layerDef->rect.left + 1;
g_BgLayers[index].h = layerDef->rect.bottom - layerDef->rect.top + 1;
g_BgLayers[index].scrollKind = layerDef->rect.params;
g_BgLayers[index].hideTimer = 1;
}
}
@ -1610,7 +1610,7 @@ void LoadRoomLayer(s32 layerIndex) {
SetRoomBackgroundLayer(0, g_api.o.tileLayers[layerIndex].bg);
for (i = 1; i < MAX_BG_LAYER_COUNT; i++) {
g_Tilemap.bg[i].flags = 0;
g_BgLayers[i].flags = 0;
}
}

View File

@ -263,50 +263,50 @@ s32 func_800F087C(u32 chunkX, u32 chunkY) {
void func_800F0940(void) {
s32 temp;
switch (g_Tilemap.bg[0].scrollKind) {
switch (g_BgLayers[0].scrollKind) {
case 1:
g_Tilemap.bg[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi;
g_Tilemap.bg[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi;
g_BgLayers[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi;
g_BgLayers[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi;
return;
case 2:
g_Tilemap.bg[0].scrollX.i.hi = (g_Tilemap.scrollX.i.hi / 2);
g_Tilemap.bg[0].scrollY.i.hi = (g_Tilemap.scrollY.i.hi / 2) + 0x76;
g_BgLayers[0].scrollX.i.hi = (g_Tilemap.scrollX.i.hi / 2);
g_BgLayers[0].scrollY.i.hi = (g_Tilemap.scrollY.i.hi / 2) + 0x76;
return;
case 3:
g_Tilemap.bg[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
g_Tilemap.bg[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi;
g_BgLayers[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
g_BgLayers[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi;
return;
case 4:
g_Tilemap.bg[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi;
g_Tilemap.bg[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi / 2;
g_BgLayers[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi;
g_BgLayers[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi / 2;
if (g_StageId == STAGE_RCHI) {
g_Tilemap.bg[0].scrollY.i.hi += 0x80;
g_BgLayers[0].scrollY.i.hi += 0x80;
}
return;
case 5:
g_Tilemap.bg[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
g_Tilemap.bg[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi / 2;
g_BgLayers[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
g_BgLayers[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi / 2;
if (g_StageId == STAGE_RDAI) {
g_Tilemap.bg[0].scrollX.i.hi += 0x80;
g_BgLayers[0].scrollX.i.hi += 0x80;
}
return;
case 6:
g_Tilemap.bg[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
g_BgLayers[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
temp = (g_Tilemap.scrollY.i.hi / 2 - ((g_Tilemap.vSize - 1) << 7)) +
(g_Tilemap.bg[0].h << 7);
g_Tilemap.bg[0].scrollY.i.hi = temp;
(g_BgLayers[0].h << 7);
g_BgLayers[0].scrollY.i.hi = temp;
if (g_StageId == STAGE_RDAI) {
g_Tilemap.bg[0].scrollX.i.hi += 0x80;
g_Tilemap.bg[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi / 2;
g_BgLayers[0].scrollX.i.hi += 0x80;
g_BgLayers[0].scrollY.i.hi = g_Tilemap.scrollY.i.hi / 2;
}
return;
case 7:
g_Tilemap.bg[0].scrollY.i.hi = 4;
g_Tilemap.bg[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
g_BgLayers[0].scrollY.i.hi = 4;
g_BgLayers[0].scrollX.i.hi = g_Tilemap.scrollX.i.hi / 2;
return;
default:
g_Tilemap.bg[0].scrollX.i.hi = 0;
g_Tilemap.bg[0].scrollY.i.hi = 4;
g_BgLayers[0].scrollX.i.hi = 0;
g_BgLayers[0].scrollY.i.hi = 4;
return;
}
}
@ -503,8 +503,8 @@ void func_800F1424(void) {
if (g_pads[1].tapped & PAD_L1) {
g_Tilemap.flags ^= 1;
}
if ((g_pads[1].tapped & PAD_L2) && (g_Tilemap.bg[0].tileDef != 0)) {
g_Tilemap.bg[0].flags ^= 1;
if ((g_pads[1].tapped & PAD_L2) && (g_BgLayers[0].tileDef != 0)) {
g_BgLayers[0].flags ^= 1;
}
}

View File

@ -99,6 +99,7 @@ char D_80097902[] = "dummy";
s32 g_EquippedWeaponIds[2] = {0};
u8 g_SaveName[12];
Tilemap g_Tilemap;
BgLayer g_BgLayers[MAX_BG_LAYER_COUNT];
u8 g_CastleMap[0x800];
u8 g_saveIcon0[0x180];
u8 g_saveIcon1[0x180];

View File

@ -1198,8 +1198,8 @@ void EntityMermanRockLeftSide(Entity* self) {
tileLayoutPtr = &D_8018127C;
tilePos = 0x1F1;
for (i = 0; i < 3; i++) {
g_Tilemap.bg[0].layout[tilePos] = *tileLayoutPtr;
g_Tilemap.bg[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
g_BgLayers[0].layout[tilePos] = *tileLayoutPtr;
g_BgLayers[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
tileLayoutPtr++;
tilePos += 0x30;
}
@ -1297,8 +1297,8 @@ void EntityMermanRockRightSide(Entity* self) {
tileLayoutPtr = &D_801812B8;
tilePos = 0x1FD;
for (i = 0; i < 3; i++) {
g_Tilemap.bg[0].layout[tilePos] = *tileLayoutPtr;
g_Tilemap.bg[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
g_BgLayers[0].layout[tilePos] = *tileLayoutPtr;
g_BgLayers[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
tileLayoutPtr++;
tilePos += 0x30;
}
@ -1403,7 +1403,7 @@ void EntityUnkId26(Entity* self) {
for (tileLayoutPtr = &D_8018131E, i = 0; i < 3; i++) {
tileLayoutPos = 0x420 + i;
for (j = 0; j < 5; j++, tileLayoutPtr++) {
g_Tilemap.bg[0].layout[tileLayoutPos] = *tileLayoutPtr;
g_BgLayers[0].layout[tileLayoutPos] = *tileLayoutPtr;
tileLayoutPos += 0x30;
}
}
@ -1688,7 +1688,7 @@ void EntityDeathSkySwirl(Entity* self) {
prim->priority = 0x1F;
prim->drawMode = DRAW_DEFAULT;
}
g_Tilemap.bg[0].flags &= 0xFFFE;
g_BgLayers[0].flags &= 0xFFFE;
self->ext.deathSkySwirl.unk84 -= 32;
SetGeomScreen(256);
SetGeomOffset(128, 192);

View File

@ -86,7 +86,7 @@ void EntityRoomTransition2(Entity* self) {
if (prim->r0 >= 240) {
self->step++;
DestroyEntity(&g_Entities[208]);
g_Tilemap.bg[0].flags |= 1;
g_BgLayers[0].flags |= 1;
g_api.PlaySfx(0xA1);
g_api.PlaySfx(0x30F);
}

View File

@ -1118,8 +1118,8 @@ void EntityMermanRockLeftSide(Entity* self) {
tileLayoutPtr = &D_80181144;
tilePos = 0x1F1;
for (i = 0; i < 3; i++) {
g_Tilemap.bg[0].layout[tilePos] = *tileLayoutPtr;
g_Tilemap.bg[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
g_BgLayers[0].layout[tilePos] = *tileLayoutPtr;
g_BgLayers[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
tileLayoutPtr++;
tilePos += 0x30;
}
@ -1217,8 +1217,8 @@ void EntityMermanRockRightSide(Entity* self) {
tileLayoutPtr = &D_80181180;
tilePos = 0x1FD;
for (i = 0; i < 3; i++) {
g_Tilemap.bg[0].layout[tilePos] = *tileLayoutPtr;
g_Tilemap.bg[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
g_BgLayers[0].layout[tilePos] = *tileLayoutPtr;
g_BgLayers[0].layout[tilePos + 1] = *(tileLayoutPtr + 3);
tileLayoutPtr++;
tilePos += 0x30;
}
@ -1323,7 +1323,7 @@ void func_801B5488(Entity* self) {
for (tileLayoutPtr = &D_801811E6, i = 0; i < 3; i++) {
tileLayoutPos = 0x420 + i;
for (j = 0; j < 5; j++, tileLayoutPtr++) {
g_Tilemap.bg[0].layout[tileLayoutPos] = *tileLayoutPtr;
g_BgLayers[0].layout[tileLayoutPos] = *tileLayoutPtr;
tileLayoutPos += 0x30;
}
}

View File

@ -1,5 +1,277 @@
#include "st0.h"
INCLUDE_ASM("st/st0/nonmatchings/3D8F0", func_801BD8F0);
typedef struct {
Point16 unk0;
s16 unk4;
s16 unk6;
s16 unk8;
s16 unkA;
s16 unkC;
s16 unkE;
s32 unk10;
s16 unk14;
} unkstr_801C06B0;
extern SVECTOR D_80182690;
extern SVECTOR D_80182698;
extern SVECTOR D_801826A0;
extern SVECTOR D_801826A8;
extern unkstr_801C06B0 D_801C06B0;
void func_801BD8F0(Entity* self) {
DRAWENV drawEnv;
RECT cliprect;
DR_ENV* dr_env;
Primitive* prim;
s32 var_s8;
s32 var_s7;
s32 i;
s32 yVar;
s32 var_s5;
s32 j;
s32 xVar;
unkstr_801C06B0* var_s3;
s16 angle;
s32 sp48;
Entity* sp44;
SVECTOR* sp40;
VECTOR* sp3c;
MATRIX* sp38;
SVECTOR* sp34;
switch (self->step) {
case 0:
InitializeEntity(D_801805D4);
g_GpuBuffers[0].draw.r0 = 0;
g_GpuBuffers[0].draw.g0 = 0;
g_GpuBuffers[0].draw.b0 = 0;
g_GpuBuffers[1].draw.r0 = 0;
g_GpuBuffers[1].draw.g0 = 0;
g_GpuBuffers[1].draw.b0 = 0;
/* fallthrough */
case 1:
self->step++;
return;
case 2:
sp48 = g_api.func_800EDB58(4, 15 * 15);
if (sp48 == -1) {
SetStep(7);
return;
}
self->flags |= FLAG_UNK_800000;
self->primIndex = sp48;
prim = &g_PrimBuf[sp48];
self->ext.prim = prim;
for (; prim != NULL; prim = prim->next) {
prim->drawMode = DRAW_HIDE;
}
self->step += 1;
case 3:
prim = self->ext.prim;
drawEnv = g_CurrentBuffer->draw;
if (drawEnv.ofs[0] == 0) {
prim->tpage = 0x100;
} else {
prim->tpage = 0x104;
}
prim->type = PRIM_GT4;
prim->u0 = prim->u2 = 0;
prim->u1 = prim->u3 = 0xFF;
prim->v0 = prim->v1 = 0;
prim->v2 = prim->v3 = 0xEF;
prim->x0 = prim->x2 = 0;
prim->x1 = prim->x3 = 0xFF;
prim->y0 = prim->y1 = 0;
prim->y2 = prim->y3 = 0xEF;
prim->priority = 0x69;
prim->drawMode = DRAW_DEFAULT;
prim = prim->next;
dr_env = g_api.func_800EDB08((POLY_GT4*)prim);
if (dr_env == NULL) {
SetStep(7);
return;
}
prim->type = PRIM_ENV;
drawEnv.isbg = 1;
drawEnv.r0 = 0;
drawEnv.g0 = 0;
drawEnv.b0 = 0;
drawEnv.dtd = 0;
cliprect.x = 0x300;
cliprect.y = 0;
cliprect.w = 0x100;
cliprect.h = 0x100;
drawEnv.clip = cliprect;
drawEnv.ofs[0] = 0x300;
drawEnv.ofs[1] = 0;
SetDrawEnv(dr_env, &drawEnv);
prim->priority = 0x68;
prim->drawMode = DRAW_DEFAULT;
prim = prim->next;
dr_env = g_api.func_800EDB08((POLY_GT4*)prim);
if (dr_env == NULL) {
SetStep(7);
return;
}
prim->type = PRIM_ENV;
prim->priority = 0x6A;
prim->drawMode = DRAW_UNK_800;
self->step++;
return;
case 4:
prim = self->ext.prim;
prim = prim->next;
for (i = 0; i < 2; i++) {
dr_env = LOW(prim->r1);
dr_env->tag = 0;
prim->type = PRIM_GT4;
prim = prim->next;
}
prim = self->ext.prim;
for (i = 0; i < 15; i++) {
for (j = 0; j < 15; j++) {
xVar = j * 17;
yVar = i * 16;
prim->tpage = 0x10C;
prim->u0 = prim->u2 = xVar;
prim->u1 = prim->u3 = xVar + 17;
prim->v0 = prim->v1 = yVar;
prim->v2 = prim->v3 = yVar + 16;
prim->x0 = prim->x2 = xVar;
prim->x1 = prim->x3 = xVar + 17;
prim->y0 = prim->y1 = yVar;
prim->y2 = prim->y3 = yVar + 16;
prim->r0 = 0x40;
prim->g0 = prim->b0 = 0x30;
LOW(prim->r1) = LOW(prim->r0);
LOW(prim->r2) = LOW(prim->r0);
LOW(prim->r3) = LOW(prim->r0);
prim->priority = 0x6C;
prim->drawMode = DRAW_DEFAULT;
prim = prim->next;
}
}
self->step++;
return;
case 5:
var_s3 = &D_801C06B0;
g_Tilemap.flags &= 0xFFFE;
g_BgLayers[0].flags &= 0xFFFE;
prim = self->ext.prim;
for (i = 0; i < 15 * 15; i++, var_s3++) {
xVar = prim->x0 + 8;
yVar = prim->y0 + 8;
xVar -= 0x80;
yVar -= 0x80;
var_s3->unkA = xVar;
var_s3->unkE = yVar;
var_s3->unk10 = 0x80;
angle = ratan2(yVar, xVar);
var_s7 = (xVar * xVar) + (yVar * yVar);
xVar = rsin(angle) * 0x24;
yVar = rcos(angle) * 0x24;
var_s7 = SquareRoot0(var_s7);
var_s8 = 0xC0 - var_s7;
xVar = xVar * var_s8 / 0xC0;
yVar = yVar * var_s8 / 0xC0;
xVar >>= 0xC;
yVar >>= 0xC;
var_s3->unk0.x = xVar;
var_s3->unk0.y = yVar;
var_s3->unk14 = ((var_s7 * 3) / 2) - (Random() & 0x1F);
if (var_s3->unk14 < 0) {
var_s3->unk14 = 0;
}
var_s3->unk4 = 0;
var_s3->unk6 = 0;
prim = prim->next;
}
self->ext.GS_Props.pickupFlag = 1;
self->step++;
return;
case 6:
SetGeomScreen(0x80);
SetGeomOffset(0x80, 0x80);
#ifndef VERSION_PC
sp38 = (MATRIX*)SPAD(0);
sp40 = (SVECTOR*)SPAD(8);
sp3c = (VECTOR*)SPAD(10);
sp34 = (SVECTOR*)SPAD(14);
#else
MATRIX sp38_;
SVECTOR sp40_;
VECTOR sp3c_;
SVECTOR sp34_;
sp38 = &sp38_;
sp40 = &sp40_;
sp3c = &sp3c_;
sp34 = &sp34_;
#endif
sp34[0] = D_80182690;
sp34[1] = D_80182698;
sp34[2] = D_801826A0;
sp34[3] = D_801826A8;
var_s3 = &D_801C06B0;
prim = self->ext.prim;
for (i = 0; i < 15 * 15; i++, var_s3++) {
if ((var_s3->unk14) || (var_s3->unk10 > 0x180)) {
prim = prim->next;
continue;
}
sp40->vx = var_s3->unk4;
sp40->vy = var_s3->unk6;
sp40->vz = 0;
RotMatrixYXZ(sp40, sp38);
gte_SetRotMatrix(sp38);
sp3c->vx = var_s3->unkA;
sp3c->vy = var_s3->unkE;
sp3c->vz = var_s3->unk10;
gte_SetTransVector(sp3c);
gte_ldv3c(sp34);
gte_rtpt();
gte_stsxy3_gt3(prim);
gte_ldv0(&sp34[3]);
gte_rtps();
gte_stsxy(&prim->x3);
prim->drawMode = DRAW_DEFAULT;
prim = prim->next;
}
var_s3 = &D_801C06B0;
prim = self->ext.prim;
var_s8 = 0;
for (i = 0; i < 15 * 15; i++, var_s3++) {
if (var_s3->unk14) {
var_s3->unk14--;
prim = prim->next;
continue;
}
var_s3->unk4 += var_s3->unk0.x;
var_s3->unk6 += var_s3->unk0.y;
var_s3->unk10 += 3;
if (var_s3->unk10 > 0x180) {
var_s8 += 1;
prim->drawMode = DRAW_HIDE;
}
prim = prim->next;
}
if (self->ext.GS_Props.pickupFlag) {
if (var_s8 > 14) {
self->ext.GS_Props.pickupFlag = 0;
sp44 = self + 1;
CreateEntityFromCurrentEntity(0x24, sp44);
}
}
if (var_s8 == 15 * 15) {
DestroyEntity(self);
}
break;
case 7:
sp44 = self + 1;
CreateEntityFromCurrentEntity(0x24, sp44);
DestroyEntity(self);
}
}
INCLUDE_ASM("st/st0/nonmatchings/3D8F0", EntityBackgroundVortex);

@ -1 +1 @@
Subproject commit 1c768238ca3fe4acec473127a3546a23cdde8a3a
Subproject commit 7b7652969f43a461d385e78392cc7cd40e29b0a2