Decompile ST0 func_801B1298 (#1769)
Some checks are pending
Format code / format (push) Waiting to run
Build C code / extract-assets (push) Waiting to run
Build C code / build-linux (push) Blocked by required conditions
Build C code / build-macos (push) Blocked by required conditions
Build C code / build-windows (push) Blocked by required conditions
Build C code / build-linux-lle (push) Blocked by required conditions
Build Saturn version / build-and-test-saturn (push) Waiting to run
Build Saturn version / function-finder-saturn (push) Waiting to run
Build Debug Module tool / build (push) Waiting to run
Build PSX and PSP version / build-and-test (pspeu, hd) (push) Waiting to run
Build PSX and PSP version / build-and-test (pspeu, pspeu) (push) Waiting to run
Build PSX and PSP version / build-and-test (us, us) (push) Waiting to run
Build PSX and PSP version / generate-progress-report (pspeu, hd) (push) Blocked by required conditions
Build PSX and PSP version / generate-progress-report (pspeu, pspeu) (push) Blocked by required conditions
Build PSX and PSP version / generate-progress-report (us, us) (push) Blocked by required conditions
Build PSX and PSP version / generate-duplicates-report (us, us) (push) Blocked by required conditions
Build PSX and PSP version / generate-duplicates-report-psp (pspeu, pspeu) (push) Blocked by required conditions

This one is so dang weird.

It needs to access fields in g_Dialogue which do not match up at all
with the g_Dialogue struct. And it accesses some other elements
normally, but they show up at the wrong offsets. It's like this one
function uses a different g_Dialogue struct. I really don't know what to
make of it. Other files in ST0 use normal g_Dialogue, but this one is
bizarre.

I went ahead and created an ifdef variable to use to handle this, and
that's baked into g_Dialogue, but man. Very weird and yet another thing
I haven't seen before in SOTN. ST0 is such a weird beast. Feels like
it's from a beta build of the game.
This commit is contained in:
bismurphy 2024-10-09 15:46:26 -04:00 committed by GitHub
parent 6f8ec4db8a
commit d84431ba43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 174 additions and 14 deletions

View File

@ -1455,24 +1455,32 @@ typedef struct {
} RelicOrb; /* size=0x10 */
typedef struct {
/* 0x00 */ u8* scriptCur; // ptr to dialogue next character
/* 0x04 */ s16 startX; // starting x coord
/* 0x06 */ s16 nextLineY; // next line y coord
/* 0x08 */ s16 startY; // starting y coord
/* 0x0A */ s16 nextCharX; // next char x coord
/* 0x0C */ s16 nextLineX; // next line x coord
/* 0x00 */ u8* scriptCur; // ptr to dialogue next character
/* 0x04 */ s16 startX; // starting x coord
/* 0x06 */ s16 nextLineY; // next line y coord
/* 0x08 */ s16 startY; // starting y coord
/* 0x0A */ s16 nextCharX; // next char x coord
/* 0x0C */ s16 nextLineX; // next line x coord
#ifdef ST0_WEIRD_DIALOGUE
/* 0x0E */ u16 nextCharY; // next char y coord
/* 0x10 */ u16 portraitAnimTimer; // portrait animation timer
/* 0x12 */ u8 unk12; // unknown
/* 0x13 */ u8 clutIndex;
#else
/* 0x0E */ s16 nextCharY; // next char y coord
/* 0x10 */ s16 portraitAnimTimer; // portrait animation timer
/* 0x12 */ u16 unk12; // unknown
/* 0x14 */ u16 clutIndex; // CLUT index
/* 0x16 */ u8 nextCharTimer; // timer to next character
/* 0x17 */ u8 unk17; // unknown
/* 0x18 */ Primitive* prim[6]; // for dialogue graphics rendering
/* 0x30 */ s32 primIndex[3]; // primIndices: unk, actorName, unk
/* 0x3C */ u16 unk3C; // maybe it is a begin flag?
/* 0x3E */ u16 timer; // global timer
/* 0x40 */ u8* scriptEnd; // pointer to the end of the script
} Dialogue; // size = 0x44
#endif
// Of course, offsets beyond here won't be right in ST0_WEIRD_DIALOGUE.
/* 0x18 */ Primitive* prim[6]; // for dialogue graphics rendering
/* 0x30 */ s32 primIndex[3]; // primIndices: unk, actorName, unk
/* 0x3C */ u16 unk3C; // maybe it is a begin flag?
/* 0x3E */ u16 timer; // global timer
/* 0x40 */ u8* scriptEnd; // pointer to the end of the script
} Dialogue; // size = 0x44
typedef struct {
u32 effects; // Curse, poison, etc; needs an enum.

View File

@ -1,4 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
#define ST0_WEIRD_DIALOGUE
#include "st0.h"
#include "disk.h"
@ -519,7 +522,7 @@ void func_801B1198(s16 arg0) {
ClearImage(&rect, 0, 0, 0);
}
u16* func_801B11E8(char ch) {
u16* func_801B11E8(unsigned char ch) {
u16 jCh;
#ifndef VERSION_PC
@ -548,4 +551,153 @@ u16* func_801B11E8(char ch) {
return g_api.func_80106A28(jCh, 0);
}
INCLUDE_ASM("st/st0/nonmatchings/30030", func_801B1298);
extern u8 D_80182C58[];
extern u16 D_801BEE90[][0x30];
// Resembles SEL func_801B79D4
void func_801B1298(Entity* self) {
s32 i;
Primitive* prim;
u16 y;
u16 glyphIndex;
u16* var_v1;
u16 nextChar;
u16* glyph;
s16 y0;
switch (self->step) {
case 0:
if (func_801B101C(D_80182C58)) {
self->flags |= FLAG_HAS_PRIMS;
self->primIndex = g_Dialogue.prim[1];
++self->step;
func_801B1198(0);
glyphIndex = 0;
while (1) {
nextChar = *g_Dialogue.scriptCur++;
if (nextChar == 1) {
// Gets weirdly relocated in the asm.
g_Dialogue.startY =
g_Dialogue.nextCharX + *g_Dialogue.scriptCur++;
++g_Dialogue.nextLineX;
break;
}
glyph = func_801B11E8(nextChar);
if (glyph) {
var_v1 = &D_801BEE90[glyphIndex][0];
for (i = 0; i < 0x30; ++i) {
var_v1++[0] = glyph++[0];
}
glyph = D_801BEE90[glyphIndex];
y = g_Dialogue.nextLineX * 16;
LoadTPage(
(u_long*)glyph, 0, 0, g_Dialogue.startY, y, 12, 16);
g_Dialogue.startY += 3;
y = g_Dialogue.startY - g_Dialogue.nextCharX;
if (0x38 <= y && y < 0x40) {
g_Dialogue.startY += 8;
}
++glyphIndex;
} else {
g_Dialogue.startY += 2;
y = g_Dialogue.startY - g_Dialogue.nextCharX;
if (0x38 <= y && y < 0x40) {
g_Dialogue.startY += 8;
}
}
}
}
break;
case 1:
if (!g_Dialogue.nextCharY) {
break;
}
nextChar = 0;
glyphIndex = 0;
do {
nextChar = *g_Dialogue.scriptCur++;
switch (nextChar) {
case 0:
self->step = 7;
return;
case 1:
g_Dialogue.startY =
g_Dialogue.nextCharX + *g_Dialogue.scriptCur++;
g_Dialogue.nextLineX++;
if (g_Dialogue.nextLineX > 15) {
g_Dialogue.nextLineX = 0;
}
g_Dialogue.nextCharY = 0;
return;
case 2:
g_Dialogue.startY =
g_Dialogue.nextCharX + *g_Dialogue.scriptCur++;
g_Dialogue.nextLineX++;
if (g_Dialogue.nextLineX > 15) {
g_Dialogue.nextLineX = 0;
}
prim = g_Dialogue.prim[0];
for (i = 0; i < g_Dialogue.nextLineX; ++i) {
prim = prim->next;
prim = prim->next;
}
y0 = prim->y0;
for (prim = g_Dialogue.prim[0]; prim != NULL;
prim = prim->next) {
if (y0 <= prim->y0) {
prim->y0 += 0x16;
prim->p1 += 0x16;
}
}
g_Dialogue.unk12 += 0x58;
g_Dialogue.portraitAnimTimer += 0x16;
g_Dialogue.nextCharY = 0;
return;
}
} while (0);
glyph = func_801B11E8(nextChar);
if (glyph) {
y = g_Dialogue.nextLineX * 16;
LoadTPage((u_long*)glyph, 0, 0, g_Dialogue.startY, y, 0xC, 0x10);
g_Dialogue.startY += 3;
} else {
g_Dialogue.startY += 2;
}
y = g_Dialogue.startY - g_Dialogue.nextCharX;
if (0x38 <= y && y < 0x40) {
g_Dialogue.startY += 8;
}
break;
case 2:
break;
case 7:
if (g_Dialogue.nextCharY) {
g_Dialogue.nextLineX++;
if (g_Dialogue.nextLineX > 15) {
g_Dialogue.nextLineX = 0;
}
g_Dialogue.nextCharY = 0;
}
}
if (!g_Dialogue.unk12) {
func_801B1198(g_Dialogue.nextLineX);
g_Dialogue.nextCharY = 1;
g_Dialogue.unk12 = 88;
}
--g_Dialogue.unk12;
if (!g_Dialogue.clutIndex) {
for (prim = g_Dialogue.prim[0], i = 0; i < 32; ++i) {
prim->y0--;
if (prim->y0 == -22) {
prim->y0 = g_Dialogue.portraitAnimTimer - prim->p1 + 330;
prim->p1 = g_Dialogue.portraitAnimTimer;
}
prim = prim->next;
}
g_Dialogue.clutIndex = 4;
}
--g_Dialogue.clutIndex;
}