mirror of
https://github.com/Xeeynamo/sotn-decomp.git
synced 2024-11-26 22:40:33 +00:00
Decompile NO3 EntityDeathCutscene (#1309)
As far as the duplicate-finder can tell, this is the last of the cutscenes, but who knows - we may find more. Luckily, the pattern is pretty recognizable. Named it due to what we see at the very end in `case 7`, with the TimeAttackController getting triggered.
This commit is contained in:
parent
350559c0b8
commit
4ae980706e
@ -60,9 +60,9 @@ segments:
|
||||
- [0x373E8, .rodata, 377D4] # EntityCastleDoor
|
||||
- [0x37400, .rodata, 377D4] # EntityStairwayPiece
|
||||
- [0x37414, .rodata, 3C4EC]
|
||||
- [0x3742C, .rodata, 3E134]
|
||||
- [0x3742C, .rodata, 3E134] #EntityFlyingOwlAndLeaves
|
||||
- [0x37440, rodata]
|
||||
- [0x37458, rodata]
|
||||
- [0x37458, .rodata, deathcutscene] # EntityDeathCutscene
|
||||
- [0x374DC, .rodata, 3FF00] # EntityRoomTransition2
|
||||
- [0x374F4, .rodata, 3FF00] # EntityDeathStolenItems
|
||||
- [0x37514, .rodata, 3FF00] # EntityDeath
|
||||
@ -82,6 +82,7 @@ segments:
|
||||
- [0x377D4, c]
|
||||
- [0x3C4EC, c]
|
||||
- [0x3E134, c]
|
||||
- [0x3E544, c, deathcutscene]
|
||||
- [0x3FF00, c]
|
||||
- [0x4184C, c, random]
|
||||
- [0x4187C, c, update]
|
||||
|
@ -74,7 +74,7 @@ EntityBackgroundTrees = 0x801BDEB0;
|
||||
EntityBackgroundCastleWall = 0x801BE080;
|
||||
EntityFlyingOwlAndLeaves = 0x801BE134;
|
||||
EntityFallingLeaf = 0x801BE444;
|
||||
EntityRoomTransition1 = 0x801BEEB0;
|
||||
EntityDeathCutscene = 0x801BEEB0;
|
||||
EntityRoomTransition2 = 0x801BFF00;
|
||||
EntityDeathStolenItem = 0x801C033C;
|
||||
EntityDeath = 0x801C083C;
|
||||
|
@ -129,269 +129,3 @@ void EntityFallingLeaf(Entity* entity) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void func_801BE544(void) {
|
||||
D_801D7D30 = 0x182;
|
||||
D_801D7D2E = 0x182;
|
||||
D_801D7D32 = 0;
|
||||
D_801D7D36 = 0;
|
||||
D_801D7D3A = 0;
|
||||
D_801D7D3B = 8;
|
||||
D_801D7D2A = D_801D7D2C + 0x14;
|
||||
}
|
||||
|
||||
s32 func_801BE598(s32 textDialogue) {
|
||||
Primitive* prim;
|
||||
s16 firstPrimIndex;
|
||||
|
||||
firstPrimIndex = g_api.AllocPrimitives(PRIM_SPRT, 7);
|
||||
g_Dialogue.primIndex[2] = firstPrimIndex;
|
||||
if (firstPrimIndex == -1) {
|
||||
g_Dialogue.primIndex[2] = 0;
|
||||
return 0;
|
||||
}
|
||||
g_Dialogue.nextCharDialogue = textDialogue;
|
||||
g_Dialogue.unk3C = 0;
|
||||
g_Dialogue.primIndex[1] = -1;
|
||||
g_Dialogue.primIndex[0] = -1;
|
||||
func_801BE544();
|
||||
|
||||
//! FAKE:
|
||||
if (prim && prim) {
|
||||
}
|
||||
|
||||
prim = g_Dialogue.prim[0] = &g_PrimBuf[g_Dialogue.primIndex[2]];
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[1] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[2] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[3] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[4] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[5] = prim->next;
|
||||
|
||||
prim->type = 4;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
|
||||
prim = prim->next;
|
||||
prim->type = 3;
|
||||
prim->r0 = prim->r1 = prim->r2 = prim->r3 = 0xFF;
|
||||
prim->g0 = prim->g1 = prim->g2 = prim->g3 = 0;
|
||||
prim->b0 = prim->b1 = prim->b2 = prim->b3 = 0;
|
||||
prim->x0 = prim->x2 = 4;
|
||||
prim->x1 = prim->x3 = 0xF8;
|
||||
prim->priority = 0x1FD;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
|
||||
prim = prim->next;
|
||||
prim->type = 1;
|
||||
prim->x0 = 3;
|
||||
prim->y0 = 0x2F;
|
||||
prim->v0 = 0x4A;
|
||||
prim->r0 = prim->g0 = prim->b0 = 0xFF;
|
||||
prim->priority = 0x1FC;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void func_801BE75C(s16 yOffset) {
|
||||
RECT rect;
|
||||
|
||||
rect.x = 384;
|
||||
rect.y = (yOffset * 12) + 256;
|
||||
rect.w = 64;
|
||||
rect.h = 12;
|
||||
ClearImage(&rect, 0, 0, 0);
|
||||
}
|
||||
|
||||
void func_801BE7BC(void) {
|
||||
Primitive* prim;
|
||||
|
||||
func_801BE75C(g_Dialogue.nextCharY);
|
||||
prim = g_Dialogue.prim[g_Dialogue.nextCharY];
|
||||
prim->tpage = 0x16;
|
||||
prim->clut = g_Dialogue.clutIndex;
|
||||
prim->y0 = g_Dialogue.nextLineY;
|
||||
prim->u0 = 0;
|
||||
prim->x0 = g_Dialogue.startX;
|
||||
prim->x0 = prim->x0 + 4;
|
||||
prim->v0 = g_Dialogue.nextCharY * 0xC;
|
||||
prim->u1 = 0xC0;
|
||||
prim->v1 = 0xC;
|
||||
prim->priority = 0x1FF;
|
||||
prim->drawMode = DRAW_DEFAULT;
|
||||
}
|
||||
|
||||
// Creates primitives for the actor name at the head of the dialogue
|
||||
void func_801BE870(u16 actorIndex, Entity* self) {
|
||||
Primitive* prim;
|
||||
s16 primIndex;
|
||||
s32 x;
|
||||
u16 chCount;
|
||||
const char* actorName;
|
||||
char ch;
|
||||
|
||||
actorName = D_80181ACC[actorIndex];
|
||||
chCount = 0;
|
||||
while (true) {
|
||||
ch = *actorName++;
|
||||
if (ch == DIAG_EOL) {
|
||||
ch = *actorName++;
|
||||
if (ch == DIAG_EOS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ch == MENUCHAR(' ')) {
|
||||
continue;
|
||||
}
|
||||
chCount++;
|
||||
}
|
||||
|
||||
// Create chCount amount of sprites based on the actor name's letter count
|
||||
primIndex = g_api.AllocPrimitives(PRIM_SPRT, chCount);
|
||||
if (primIndex == -1) {
|
||||
DestroyEntity(self);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill prims to render the actor name on screen
|
||||
prim = &g_PrimBuf[primIndex];
|
||||
g_Dialogue.primIndex[1] = primIndex;
|
||||
actorName = D_80181ACC[actorIndex];
|
||||
x = 0x38;
|
||||
while (prim != NULL) {
|
||||
ch = *actorName++;
|
||||
if (ch == MENUCHAR(' ')) {
|
||||
x += FONT_SPACE;
|
||||
} else {
|
||||
prim->type = PRIM_SPRT;
|
||||
prim->tpage = 0x1E;
|
||||
prim->clut = 0x196;
|
||||
prim->u0 = (ch & 0x0F) * FONT_W;
|
||||
prim->v0 = (ch & 0xF0) / (FONT_H / 4);
|
||||
prim->v1 = FONT_H;
|
||||
prim->u1 = FONT_W;
|
||||
prim->priority = 0x1FF;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim->x0 = x;
|
||||
prim->y0 = g_Dialogue.startY + 6;
|
||||
prim = prim->next;
|
||||
x += FONT_GAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_801BE9F4(s32 arg0) {
|
||||
g_Dialogue.unk40 = arg0 + 0x100000;
|
||||
g_Dialogue.timer = 0;
|
||||
g_Dialogue.unk3C = 1;
|
||||
}
|
||||
|
||||
void func_801BEA20(void) {
|
||||
Entity* entity;
|
||||
u16 startTimer;
|
||||
u8 entityIndex;
|
||||
|
||||
g_Dialogue.timer++;
|
||||
// protect from overflows
|
||||
if (g_Dialogue.timer > 0xFFFE) {
|
||||
g_Dialogue.unk3C = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
// Start the dialogue script only if the start timer has passed
|
||||
startTimer = (*g_Dialogue.unk40++ << 8) | *g_Dialogue.unk40++;
|
||||
if (g_Dialogue.timer < startTimer) {
|
||||
// Re-evaluate the condition at the next frame
|
||||
g_Dialogue.unk40 -= 2;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (*g_Dialogue.unk40++) {
|
||||
case 0:
|
||||
entityIndex = *g_Dialogue.unk40++;
|
||||
entity = &g_Entities[STAGE_ENTITY_START + entityIndex];
|
||||
DestroyEntity(entity);
|
||||
|
||||
entity->entityId = *g_Dialogue.unk40++;
|
||||
entity->pfnUpdate = PfnEntityUpdates[entity->entityId - 1];
|
||||
entity->posX.i.hi = *g_Dialogue.unk40++ * 0x10;
|
||||
entity->posX.i.hi = *g_Dialogue.unk40++ | entity->posX.i.hi;
|
||||
entity->posY.i.hi = *g_Dialogue.unk40++ * 0x10;
|
||||
entity->posY.i.hi = *g_Dialogue.unk40++ | entity->posY.i.hi;
|
||||
break;
|
||||
case 1:
|
||||
entityIndex = *g_Dialogue.unk40++;
|
||||
entity = &g_Entities[STAGE_ENTITY_START + entityIndex];
|
||||
DestroyEntity(entity);
|
||||
break;
|
||||
case 2:
|
||||
if (!((D_801D7DD0 >> *g_Dialogue.unk40) & 1)) {
|
||||
g_Dialogue.unk40--;
|
||||
return;
|
||||
}
|
||||
D_801D7DD0 &= ~(1 << *g_Dialogue.unk40++);
|
||||
break;
|
||||
case 3:
|
||||
D_801D7DD0 |= 1 << *g_Dialogue.unk40++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_801BECCC(Entity* self) {
|
||||
if (g_pads[0].tapped == PAD_START) {
|
||||
D_801D7D20 = 1;
|
||||
g_api.FreePrimitives(self->primIndex);
|
||||
self->flags ^= FLAG_HAS_PRIMS;
|
||||
if (g_Dialogue.primIndex[1] != -1) {
|
||||
g_api.FreePrimitives(g_Dialogue.primIndex[1]);
|
||||
}
|
||||
if (g_Dialogue.primIndex[0] != -1) {
|
||||
g_api.FreePrimitives(g_Dialogue.primIndex[0]);
|
||||
}
|
||||
g_api.PlaySfx(SET_STOP_MUSIC);
|
||||
self->step = 1;
|
||||
self->step_s = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Animates the portrait size of the actor by enlarging or shrinking it
|
||||
void func_801BEDAC(u8 ySteps) {
|
||||
Primitive* prim;
|
||||
s32 primIndex;
|
||||
s32 i;
|
||||
|
||||
primIndex = g_Dialogue.nextCharY + 1;
|
||||
while (primIndex >= 5) {
|
||||
primIndex -= 5;
|
||||
}
|
||||
if (g_CurrentEntity->step_s == 0) {
|
||||
prim = g_Dialogue.prim[primIndex];
|
||||
prim->v1 -= ySteps;
|
||||
prim->v0 += ySteps;
|
||||
if (prim->v1 == 0) {
|
||||
g_CurrentEntity->step_s++;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (i != primIndex) {
|
||||
prim = g_Dialogue.prim[i];
|
||||
prim->y0 -= ySteps;
|
||||
}
|
||||
}
|
||||
g_Dialogue.portraitAnimTimer++;
|
||||
}
|
||||
|
||||
// seems to cause a room transition
|
||||
INCLUDE_ASM("st/no3/nonmatchings/3E134", EntityRoomTransition1);
|
||||
|
@ -102,7 +102,7 @@ void EntityRoomTransition2(Entity* self) {
|
||||
tilemap->y = 0;
|
||||
D_8003C8B8 = 1;
|
||||
DestroyEntity(gents);
|
||||
CreateEntityFromCurrentEntity(E_ID_17, gents);
|
||||
CreateEntityFromCurrentEntity(E_BG_LIGHTNING, gents);
|
||||
}
|
||||
g_Player.padSim = 0;
|
||||
g_Player.D_80072EFC = 1;
|
||||
|
735
src/st/no3/deathcutscene.c
Normal file
735
src/st/no3/deathcutscene.c
Normal file
@ -0,0 +1,735 @@
|
||||
#include "no3.h"
|
||||
|
||||
void func_801BE544(void) {
|
||||
g_Dialogue.nextLineX = 0x182; // Note that these two lines are "= 2"
|
||||
g_Dialogue.nextCharX = 0x182; // for all other cutscenes (so far)!
|
||||
g_Dialogue.nextCharY = 0;
|
||||
g_Dialogue.unk12 = 0;
|
||||
g_Dialogue.nextCharTimer = 0;
|
||||
g_Dialogue.unk17 = 8;
|
||||
g_Dialogue.nextLineY = g_Dialogue.startY + 0x14;
|
||||
}
|
||||
|
||||
s32 func_801BE598(s32 textDialogue) {
|
||||
Primitive* prim;
|
||||
s16 firstPrimIndex;
|
||||
|
||||
firstPrimIndex = g_api.AllocPrimitives(PRIM_SPRT, 7);
|
||||
g_Dialogue.primIndex[2] = firstPrimIndex;
|
||||
if (firstPrimIndex == -1) {
|
||||
g_Dialogue.primIndex[2] = 0;
|
||||
return 0;
|
||||
}
|
||||
g_Dialogue.nextCharDialogue = textDialogue;
|
||||
g_Dialogue.unk3C = 0;
|
||||
g_Dialogue.primIndex[1] = -1;
|
||||
g_Dialogue.primIndex[0] = -1;
|
||||
func_801BE544();
|
||||
|
||||
//! FAKE:
|
||||
if (prim && prim) {
|
||||
}
|
||||
|
||||
prim = g_Dialogue.prim[0] = &g_PrimBuf[g_Dialogue.primIndex[2]];
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[1] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[2] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[3] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[4] = prim->next;
|
||||
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = g_Dialogue.prim[5] = prim->next;
|
||||
|
||||
prim->type = 4;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
|
||||
prim = prim->next;
|
||||
prim->type = 3;
|
||||
prim->r0 = prim->r1 = prim->r2 = prim->r3 = 0xFF;
|
||||
prim->g0 = prim->g1 = prim->g2 = prim->g3 = 0;
|
||||
prim->b0 = prim->b1 = prim->b2 = prim->b3 = 0;
|
||||
prim->x0 = prim->x2 = 4;
|
||||
prim->x1 = prim->x3 = 0xF8;
|
||||
prim->priority = 0x1FD;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
|
||||
prim = prim->next;
|
||||
prim->type = 1;
|
||||
prim->x0 = 3;
|
||||
prim->y0 = 0x2F;
|
||||
prim->v0 = 0x4A;
|
||||
prim->r0 = prim->g0 = prim->b0 = 0xFF;
|
||||
prim->priority = 0x1FC;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void func_801BE75C(s16 yOffset) {
|
||||
RECT rect;
|
||||
|
||||
rect.x = 384;
|
||||
rect.y = (yOffset * 12) + 256;
|
||||
rect.w = 64;
|
||||
rect.h = 12;
|
||||
ClearImage(&rect, 0, 0, 0);
|
||||
}
|
||||
|
||||
void func_801BE7BC(void) {
|
||||
Primitive* prim;
|
||||
|
||||
func_801BE75C(g_Dialogue.nextCharY);
|
||||
prim = g_Dialogue.prim[g_Dialogue.nextCharY];
|
||||
prim->tpage = 0x16;
|
||||
prim->clut = g_Dialogue.clutIndex;
|
||||
prim->y0 = g_Dialogue.nextLineY;
|
||||
prim->u0 = 0;
|
||||
prim->x0 = g_Dialogue.startX;
|
||||
prim->x0 = prim->x0 + 4;
|
||||
prim->v0 = g_Dialogue.nextCharY * 0xC;
|
||||
prim->u1 = 0xC0;
|
||||
prim->v1 = 0xC;
|
||||
prim->priority = 0x1FF;
|
||||
prim->drawMode = DRAW_DEFAULT;
|
||||
}
|
||||
|
||||
// Creates primitives for the actor name at the head of the dialogue
|
||||
void func_801BE870(u16 actorIndex, Entity* self) {
|
||||
Primitive* prim;
|
||||
s16 primIndex;
|
||||
s32 x;
|
||||
u16 chCount;
|
||||
const char* actorName;
|
||||
char ch;
|
||||
|
||||
actorName = D_80181ACC[actorIndex];
|
||||
chCount = 0;
|
||||
while (true) {
|
||||
ch = *actorName++;
|
||||
if (ch == DIAG_EOL) {
|
||||
ch = *actorName++;
|
||||
if (ch == DIAG_EOS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ch == MENUCHAR(' ')) {
|
||||
continue;
|
||||
}
|
||||
chCount++;
|
||||
}
|
||||
|
||||
// Create chCount amount of sprites based on the actor name's letter count
|
||||
primIndex = g_api.AllocPrimitives(PRIM_SPRT, chCount);
|
||||
if (primIndex == -1) {
|
||||
DestroyEntity(self);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill prims to render the actor name on screen
|
||||
prim = &g_PrimBuf[primIndex];
|
||||
g_Dialogue.primIndex[1] = primIndex;
|
||||
actorName = D_80181ACC[actorIndex];
|
||||
x = 0x38;
|
||||
while (prim != NULL) {
|
||||
ch = *actorName++;
|
||||
if (ch == MENUCHAR(' ')) {
|
||||
x += FONT_SPACE;
|
||||
} else {
|
||||
prim->type = PRIM_SPRT;
|
||||
prim->tpage = 0x1E;
|
||||
prim->clut = 0x196;
|
||||
prim->u0 = (ch & 0x0F) * FONT_W;
|
||||
prim->v0 = (ch & 0xF0) / (FONT_H / 4);
|
||||
prim->v1 = FONT_H;
|
||||
prim->u1 = FONT_W;
|
||||
prim->priority = 0x1FF;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim->x0 = x;
|
||||
prim->y0 = g_Dialogue.startY + 6;
|
||||
prim = prim->next;
|
||||
x += FONT_GAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_801BE9F4(s32 arg0) {
|
||||
g_Dialogue.unk40 = arg0 + 0x100000;
|
||||
g_Dialogue.timer = 0;
|
||||
g_Dialogue.unk3C = 1;
|
||||
}
|
||||
|
||||
void func_801BEA20(void) {
|
||||
Entity* entity;
|
||||
u16 startTimer;
|
||||
u8 entityIndex;
|
||||
|
||||
g_Dialogue.timer++;
|
||||
// protect from overflows
|
||||
if (g_Dialogue.timer > 0xFFFE) {
|
||||
g_Dialogue.unk3C = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
// Start the dialogue script only if the start timer has passed
|
||||
startTimer = (*g_Dialogue.unk40++ << 8) | *g_Dialogue.unk40++;
|
||||
if (g_Dialogue.timer < startTimer) {
|
||||
// Re-evaluate the condition at the next frame
|
||||
g_Dialogue.unk40 -= 2;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (*g_Dialogue.unk40++) {
|
||||
case 0:
|
||||
entityIndex = *g_Dialogue.unk40++;
|
||||
entity = &g_Entities[STAGE_ENTITY_START + entityIndex];
|
||||
DestroyEntity(entity);
|
||||
|
||||
entity->entityId = *g_Dialogue.unk40++;
|
||||
entity->pfnUpdate = PfnEntityUpdates[entity->entityId - 1];
|
||||
entity->posX.i.hi = *g_Dialogue.unk40++ * 0x10;
|
||||
entity->posX.i.hi = *g_Dialogue.unk40++ | entity->posX.i.hi;
|
||||
entity->posY.i.hi = *g_Dialogue.unk40++ * 0x10;
|
||||
entity->posY.i.hi = *g_Dialogue.unk40++ | entity->posY.i.hi;
|
||||
break;
|
||||
case 1:
|
||||
entityIndex = *g_Dialogue.unk40++;
|
||||
entity = &g_Entities[STAGE_ENTITY_START + entityIndex];
|
||||
DestroyEntity(entity);
|
||||
break;
|
||||
case 2:
|
||||
if (!((D_801D7DD0 >> *g_Dialogue.unk40) & 1)) {
|
||||
g_Dialogue.unk40--;
|
||||
return;
|
||||
}
|
||||
D_801D7DD0 &= ~(1 << *g_Dialogue.unk40++);
|
||||
break;
|
||||
case 3:
|
||||
D_801D7DD0 |= 1 << *g_Dialogue.unk40++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_801BECCC(Entity* self) {
|
||||
if (g_pads[0].tapped == PAD_START) {
|
||||
D_801D7D20 = 1;
|
||||
g_api.FreePrimitives(self->primIndex);
|
||||
self->flags ^= FLAG_HAS_PRIMS;
|
||||
if (g_Dialogue.primIndex[1] != -1) {
|
||||
g_api.FreePrimitives(g_Dialogue.primIndex[1]);
|
||||
}
|
||||
if (g_Dialogue.primIndex[0] != -1) {
|
||||
g_api.FreePrimitives(g_Dialogue.primIndex[0]);
|
||||
}
|
||||
g_api.PlaySfx(SET_STOP_MUSIC);
|
||||
self->step = 1;
|
||||
self->step_s = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Animates the portrait size of the actor by enlarging or shrinking it
|
||||
void func_801BEDAC(u8 ySteps) {
|
||||
Primitive* prim;
|
||||
s32 primIndex;
|
||||
s32 i;
|
||||
|
||||
primIndex = g_Dialogue.nextCharY + 1;
|
||||
while (primIndex >= 5) {
|
||||
primIndex -= 5;
|
||||
}
|
||||
if (g_CurrentEntity->step_s == 0) {
|
||||
prim = g_Dialogue.prim[primIndex];
|
||||
prim->v1 -= ySteps;
|
||||
prim->v0 += ySteps;
|
||||
if (prim->v1 == 0) {
|
||||
g_CurrentEntity->step_s++;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (i != primIndex) {
|
||||
prim = g_Dialogue.prim[i];
|
||||
prim->y0 -= ySteps;
|
||||
}
|
||||
}
|
||||
g_Dialogue.portraitAnimTimer++;
|
||||
}
|
||||
|
||||
void EntityDeathCutscene(Entity* self) {
|
||||
RECT rect;
|
||||
Primitive* prim;
|
||||
s32 primIndex;
|
||||
s32 i;
|
||||
s16 j;
|
||||
s16 uCoord;
|
||||
s16 vCoord;
|
||||
u16 nextChar;
|
||||
s32 nextChar2;
|
||||
s32 bit_shifty;
|
||||
|
||||
if (self->step != 0) {
|
||||
if ((D_801D7DD4 != 0) && (D_801D7D20 == 0) &&
|
||||
((g_IsTimeAttackUnlocked) || (g_Settings.D_8003CB04 & 4))) {
|
||||
func_801BECCC(self);
|
||||
}
|
||||
if ((self->step != 0) && (D_801D7D60 != 0)) {
|
||||
func_801BEA20();
|
||||
}
|
||||
}
|
||||
switch (self->step) {
|
||||
case 0:
|
||||
CreateEntityFromCurrentEntity(E_BG_LIGHTNING, &g_Entities[192]);
|
||||
if ((g_CastleFlags[53]) || (g_PlayableCharacter != PLAYER_ALUCARD)) {
|
||||
DestroyEntity(self);
|
||||
g_Entities[192].params = 0;
|
||||
return;
|
||||
}
|
||||
g_Entities[192].params = 0x100;
|
||||
if (func_801BE598(D_80184CE0) & 0xFF) {
|
||||
self->flags |= FLAG_HAS_PRIMS | FLAG_UNK_2000;
|
||||
D_801D7DD0 = 0;
|
||||
D_801D7DD4 = 0;
|
||||
D_801D7D20 = 0;
|
||||
D_8003C704 = 1;
|
||||
self->primIndex = g_Dialogue.primIndex[2];
|
||||
self->step++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// this is a huge While-loop! Don't miss it!
|
||||
while (1) {
|
||||
if ((g_Dialogue.nextCharTimer != 0) && (D_801D7D20 == 0)) {
|
||||
g_Dialogue.nextCharTimer--;
|
||||
return;
|
||||
}
|
||||
nextChar = *g_Dialogue.nextCharDialogue++;
|
||||
switch (nextChar) {
|
||||
case 0:
|
||||
self->step = 7;
|
||||
return;
|
||||
case 1:
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
g_Dialogue.nextCharX = g_Dialogue.nextLineX;
|
||||
if (!(g_Dialogue.unk12 & 1)) {
|
||||
g_Dialogue.nextLineY += 12;
|
||||
}
|
||||
g_Dialogue.nextCharY++;
|
||||
if (g_Dialogue.nextCharY >= 5) {
|
||||
g_Dialogue.nextCharY = 0;
|
||||
}
|
||||
func_801BE7BC();
|
||||
if (!(g_Dialogue.unk12 & 1)) {
|
||||
if (g_Dialogue.nextCharY >= 4) {
|
||||
g_Dialogue.unk12 |= 1;
|
||||
g_Dialogue.portraitAnimTimer = 0;
|
||||
self->step_s = 0;
|
||||
self->step++;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
g_Dialogue.portraitAnimTimer = 0;
|
||||
self->step_s = 0;
|
||||
self->step++;
|
||||
return;
|
||||
case 2:
|
||||
g_Dialogue.unk17 = *g_Dialogue.nextCharDialogue++;
|
||||
continue;
|
||||
case 3:
|
||||
g_Dialogue.nextCharTimer = *g_Dialogue.nextCharDialogue++;
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
case 4:
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
prim = g_Dialogue.prim[0];
|
||||
for (i = 0; i < 5; i++) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = prim->next;
|
||||
}
|
||||
return;
|
||||
case 5:
|
||||
if (D_801D7D20 != 0) {
|
||||
g_Dialogue.nextCharDialogue += 2;
|
||||
continue;
|
||||
}
|
||||
// fake reuse of i?
|
||||
i = *g_Dialogue.nextCharDialogue++;
|
||||
nextChar2 = *g_Dialogue.nextCharDialogue++;
|
||||
prim = g_Dialogue.prim[5];
|
||||
uCoord = D_80181A28[nextChar2 & 1];
|
||||
vCoord = D_80181A2C[nextChar2 & 1];
|
||||
prim->clut = D_80181A30[i];
|
||||
prim->tpage = 0x94; // Weird, this is 0x90 in other cutscenes
|
||||
if (nextChar2 & 0x80) {
|
||||
prim->u0 = prim->u2 = uCoord + 0x2F;
|
||||
prim->u1 = prim->u3 = uCoord;
|
||||
} else {
|
||||
prim->u0 = prim->u2 = uCoord;
|
||||
prim->u1 = prim->u3 = uCoord + 0x2F;
|
||||
}
|
||||
prim->v0 = prim->v1 = vCoord;
|
||||
prim->v2 = prim->v3 = vCoord + 0x48;
|
||||
prim->x0 = prim->x1 = prim->x2 = prim->x3 =
|
||||
g_Dialogue.startX - 0x1E;
|
||||
prim->y0 = prim->y1 = prim->y2 = prim->y3 =
|
||||
g_Dialogue.startY + 0x24;
|
||||
g_Dialogue.clutIndex = D_80181A38[i];
|
||||
func_801BE544();
|
||||
func_801BE7BC();
|
||||
prim->priority = 0x1FE;
|
||||
prim->drawMode = 0;
|
||||
func_801BE870(i, self);
|
||||
g_Dialogue.portraitAnimTimer = 6;
|
||||
self->step = 3;
|
||||
return;
|
||||
case 6:
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
for (prim = g_Dialogue.prim[0], i = 0; i < 5; i++) {
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
prim = prim->next;
|
||||
}
|
||||
g_api.FreePrimitives(g_Dialogue.primIndex[1]);
|
||||
g_Dialogue.primIndex[1] = -1;
|
||||
g_Dialogue.portraitAnimTimer = 6;
|
||||
self->step = 4;
|
||||
return;
|
||||
case 7:
|
||||
if (D_801D7D20 != 0) {
|
||||
g_Dialogue.nextCharDialogue++;
|
||||
g_Dialogue.nextCharDialogue++;
|
||||
continue;
|
||||
}
|
||||
g_Dialogue.startX = *g_Dialogue.nextCharDialogue++;
|
||||
g_Dialogue.startY = *g_Dialogue.nextCharDialogue++;
|
||||
prim = g_Dialogue.prim[5];
|
||||
prim = prim->next;
|
||||
prim->y0 = prim->y1 = g_Dialogue.startY;
|
||||
prim->y2 = prim->y3 = g_Dialogue.startY + 0x48;
|
||||
prim = prim->next;
|
||||
prim->y0 = g_Dialogue.startY - 1;
|
||||
prim->u0 = 0xF6;
|
||||
g_Dialogue.portraitAnimTimer = 0x18;
|
||||
self->step = 5;
|
||||
self->step_s = 0;
|
||||
return;
|
||||
|
||||
case 8:
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
g_Dialogue.portraitAnimTimer = 0x18;
|
||||
self->step = 6;
|
||||
return;
|
||||
case 9:
|
||||
if (D_801D7D20 != 0) {
|
||||
g_Dialogue.nextCharDialogue++;
|
||||
g_Dialogue.nextCharDialogue++;
|
||||
continue;
|
||||
}
|
||||
nextChar = *g_Dialogue.nextCharDialogue++;
|
||||
nextChar <<= 4;
|
||||
nextChar |= *g_Dialogue.nextCharDialogue++;
|
||||
g_api.PlaySfx(nextChar);
|
||||
continue;
|
||||
case 10:
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
if (g_api.func_80131F68() != false) {
|
||||
continue;
|
||||
}
|
||||
*g_Dialogue.nextCharDialogue--;
|
||||
return;
|
||||
case 11:
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
if (g_api.func_80131F68() != true) {
|
||||
continue;
|
||||
}
|
||||
*g_Dialogue.nextCharDialogue--;
|
||||
return;
|
||||
case 12:
|
||||
bit_shifty = (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
func_801BE9F4((u8*)bit_shifty);
|
||||
continue;
|
||||
case 13:
|
||||
continue;
|
||||
case 14:
|
||||
bit_shifty = (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty += (u16)0x100000;
|
||||
g_Dialogue.nextCharDialogue += *(u16*)bit_shifty << 2;
|
||||
|
||||
bit_shifty = (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue;
|
||||
g_Dialogue.nextCharDialogue = (u8*)bit_shifty + 0x100000;
|
||||
continue;
|
||||
|
||||
case 15:
|
||||
bit_shifty = (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue;
|
||||
g_Dialogue.nextCharDialogue = (u8*)bit_shifty + 0x100000;
|
||||
continue;
|
||||
|
||||
case 16:
|
||||
if (!((D_801D7DD0 >> *g_Dialogue.nextCharDialogue) & 1)) {
|
||||
g_Dialogue.nextCharDialogue--;
|
||||
return;
|
||||
}
|
||||
D_801D7DD0 &= ~(1 << *g_Dialogue.nextCharDialogue);
|
||||
*g_Dialogue.nextCharDialogue++;
|
||||
continue;
|
||||
case 17:
|
||||
D_801D7DD0 |= 1 << *g_Dialogue.nextCharDialogue++;
|
||||
continue;
|
||||
case 18:
|
||||
g_Dialogue.unk3C = 0;
|
||||
continue;
|
||||
case 19:
|
||||
if (D_801D7D20 != 0) {
|
||||
g_Dialogue.nextCharDialogue += 5;
|
||||
} else {
|
||||
bit_shifty = (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty <<= 4;
|
||||
bit_shifty |= (s32)*g_Dialogue.nextCharDialogue++;
|
||||
bit_shifty += 0x100000;
|
||||
nextChar2 = g_Dialogue.nextCharDialogue++[0];
|
||||
LoadTPage((u32*)bit_shifty, 1, 0, D_80181A34[nextChar2],
|
||||
0x100, 0x30, 0x48);
|
||||
}
|
||||
continue;
|
||||
case 20:
|
||||
nextChar = *g_Dialogue.nextCharDialogue++;
|
||||
nextChar <<= 4;
|
||||
nextChar |= *g_Dialogue.nextCharDialogue++;
|
||||
g_api.PlaySfx(nextChar);
|
||||
continue;
|
||||
case 21:
|
||||
D_801D7DD0 = 0;
|
||||
D_801D7D20 = 0;
|
||||
D_801D7DD4 = 0;
|
||||
continue;
|
||||
case 22:
|
||||
D_801D7DD0 &= ~(1 << *g_Dialogue.nextCharDialogue++);
|
||||
continue;
|
||||
case 23:
|
||||
return;
|
||||
case 24:
|
||||
if (!((D_801D7DD0 >> *g_Dialogue.nextCharDialogue) & 1)) {
|
||||
*g_Dialogue.nextCharDialogue--;
|
||||
return;
|
||||
}
|
||||
*g_Dialogue.nextCharDialogue++;
|
||||
continue;
|
||||
default:
|
||||
if (D_801D7D20 != 0) {
|
||||
continue;
|
||||
}
|
||||
g_Dialogue.nextCharTimer = g_Dialogue.unk17;
|
||||
}
|
||||
break; // This breaks the big while-loop!
|
||||
}
|
||||
if (nextChar == 0x20) {
|
||||
g_Dialogue.nextCharX += 2;
|
||||
return;
|
||||
}
|
||||
rect.x = ((nextChar & 0xF) * 2) + 0x380;
|
||||
rect.y = ((u32)(nextChar & 0xF0) >> 1) + 0xF0;
|
||||
rect.w = 2;
|
||||
rect.h = 8;
|
||||
// Other cutscenes have + 0x180 here
|
||||
vCoord = (g_Dialogue.nextCharY * 0xC) + 0x100;
|
||||
MoveImage(&rect, g_Dialogue.nextCharX, vCoord);
|
||||
g_Dialogue.nextCharX += 2;
|
||||
break;
|
||||
case 2:
|
||||
func_801BEDAC(2U);
|
||||
if (g_Dialogue.portraitAnimTimer >= 6) {
|
||||
self->step -= 1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
prim = g_Dialogue.prim[5];
|
||||
prim->x0 = prim->x2 -= 4;
|
||||
prim->x1 = prim->x3 += 4;
|
||||
prim->y0 = prim->y1 -= 6;
|
||||
prim->y2 = prim->y3 += 6;
|
||||
g_Dialogue.portraitAnimTimer--;
|
||||
if (!g_Dialogue.portraitAnimTimer) {
|
||||
self->step = 1;
|
||||
for (prim = &g_PrimBuf[g_Dialogue.primIndex[1]]; prim != NULL;
|
||||
prim = prim->next) {
|
||||
prim->drawMode = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
prim = g_Dialogue.prim[5];
|
||||
prim->x0 = prim->x2 += 4;
|
||||
prim->x1 = prim->x3 -= 4;
|
||||
prim->y0 = prim->y1 += 6;
|
||||
prim->y2 = prim->y3 -= 6;
|
||||
if (prim->x1 >= (g_Dialogue.startX - 2)) {
|
||||
prim->x1 = prim->x3 = g_Dialogue.startX - 3;
|
||||
}
|
||||
g_Dialogue.portraitAnimTimer--;
|
||||
if (!g_Dialogue.portraitAnimTimer) {
|
||||
self->step = 1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
switch (self->step_s) {
|
||||
case 0:
|
||||
D_801D7DD4 = 1;
|
||||
primIndex = g_api.AllocPrimitives(PRIM_LINE_G2, 0x48);
|
||||
if (primIndex == -1) {
|
||||
DestroyEntity(self);
|
||||
return;
|
||||
}
|
||||
g_Dialogue.primIndex[0] = primIndex;
|
||||
for (prim = &g_PrimBuf[primIndex], j = 0; prim != NULL;
|
||||
prim = prim->next) {
|
||||
prim->r0 = prim->r1 = 0x7F;
|
||||
prim->b0 = prim->b1 = prim->g0 = prim->g1 = 0;
|
||||
prim->x0 = prim->x1 = 0xF7;
|
||||
prim->y0 = prim->y1 = g_Dialogue.startY + j;
|
||||
prim->priority = 0x1FE;
|
||||
prim->drawMode = 0;
|
||||
prim->x2 = D_80181A3C[j];
|
||||
prim->x3 = 0xF70;
|
||||
|
||||
j++;
|
||||
}
|
||||
self->step_s++;
|
||||
return;
|
||||
case 1:
|
||||
for (j = 0, prim = &g_PrimBuf[g_Dialogue.primIndex[0]];
|
||||
prim != NULL; prim = prim->next) {
|
||||
prim->x3 -= prim->x2;
|
||||
prim->x2 += 2;
|
||||
prim->x0 = prim->x3 / 16;
|
||||
if (prim->x0 < 5) {
|
||||
prim->x0 = 4;
|
||||
} else {
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
if (j == 0) {
|
||||
g_api.FreePrimitives(g_Dialogue.primIndex[0]);
|
||||
g_Dialogue.primIndex[0] = -1;
|
||||
prim = g_Dialogue.prim[5];
|
||||
prim = prim->next;
|
||||
prim->blendMode = 0x11;
|
||||
prim = prim->next;
|
||||
prim->blendMode = 0x51;
|
||||
self->step_s++;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
j = 0;
|
||||
prim = g_Dialogue.prim[5];
|
||||
prim = prim->next;
|
||||
if (prim->r0 < 0x10) {
|
||||
prim->r0 = prim->r1 = prim->r2 = prim->r3 = 0;
|
||||
} else {
|
||||
prim->r0 = prim->r1 = prim->r2 = prim->r3 -= 0x10;
|
||||
j = 1;
|
||||
}
|
||||
if (prim->b0 >= 0x7F) {
|
||||
prim->b0 = prim->b1 = 0x7F;
|
||||
} else {
|
||||
prim->b0 = prim->b1 += 8;
|
||||
j = 1;
|
||||
}
|
||||
|
||||
prim = prim->next;
|
||||
if (prim->r0 < 0x10) {
|
||||
prim->r0 = prim->g0 = prim->b0 = 0x10;
|
||||
} else {
|
||||
prim->r0 = prim->g0 = prim->b0 -= 0xF;
|
||||
j = 1;
|
||||
}
|
||||
if (j == 0) {
|
||||
self->step = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
prim = g_Dialogue.prim[5];
|
||||
prim = prim->next;
|
||||
g_Dialogue.portraitAnimTimer--;
|
||||
if (g_Dialogue.portraitAnimTimer >= 0xC) {
|
||||
prim = prim->next;
|
||||
prim->u0 -= 20;
|
||||
if (g_Dialogue.portraitAnimTimer & 1) {
|
||||
prim->u0--;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!g_Dialogue.portraitAnimTimer) {
|
||||
self->step = 1;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
} else {
|
||||
prim->y2 = (prim->y3 -= 6);
|
||||
}
|
||||
prim = prim->next;
|
||||
prim->drawMode = DRAW_HIDE;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
g_CastleFlags[53] = 1;
|
||||
g_api.TimeAttackController(
|
||||
TIMEATTACK_EVENT_MEET_DEATH, TIMEATTACK_SET_RECORD);
|
||||
D_8003C704 = 0;
|
||||
g_Settings.D_8003CB04 |= 4;
|
||||
DestroyEntity(self);
|
||||
break;
|
||||
}
|
||||
}
|
@ -69,7 +69,7 @@ typedef enum EntityIDs {
|
||||
/* 0x11 */ E_ID_11 = 0x11,
|
||||
/* 0x14 */ E_ID_14 = 0x14,
|
||||
/* 0x15 */ E_ID_15 = 0x15,
|
||||
/* 0x17 */ E_ID_17 = 0x17,
|
||||
/* 0x17 */ E_BG_LIGHTNING = 0x17,
|
||||
/* 0x27 */ E_FALLING_ROCK_2 = 0x27,
|
||||
/* 0x35 */ E_SPLASH_WATER = 0x35,
|
||||
/* 0x36 */ E_SURFACING_WATER,
|
||||
@ -228,14 +228,6 @@ extern u8 D_80183C98[];
|
||||
extern s32 D_80183CAC;
|
||||
extern s32 D_80183CBC;
|
||||
extern s32 D_801D7D20;
|
||||
extern s16 D_801D7D2A;
|
||||
extern u16 D_801D7D2C;
|
||||
extern s16 D_801D7D2E;
|
||||
extern s16 D_801D7D30;
|
||||
extern s16 D_801D7D32;
|
||||
extern s16 D_801D7D36;
|
||||
extern s8 D_801D7D3A;
|
||||
extern s8 D_801D7D3B;
|
||||
extern s32 D_801D7D54;
|
||||
extern s32 D_801D7D58;
|
||||
extern u32 D_801D7DD0;
|
||||
@ -253,4 +245,19 @@ extern u8 g_ESoulStealOrbAnim[];
|
||||
|
||||
extern SVECTOR D_801B73E0;
|
||||
|
||||
// For EntityDeathCutscene
|
||||
extern u8 D_80181A28[];
|
||||
extern u8 D_80181A2C[];
|
||||
extern u16 D_80181A30[];
|
||||
extern u16 D_80181A34[];
|
||||
extern u16 D_80181A38[];
|
||||
extern s16 D_80181A3C[];
|
||||
extern const char D_801813F0[];
|
||||
extern s32 D_801D7D20;
|
||||
extern u32 D_801D7DD0;
|
||||
extern s32 D_801D7DD4;
|
||||
extern u16 D_801D7D60;
|
||||
extern const char D_80184CE0[];
|
||||
extern s32 D_801D7D5C;
|
||||
|
||||
extern Dialogue g_Dialogue;
|
||||
|
Loading…
Reference in New Issue
Block a user