tmc/src/text.c

767 lines
19 KiB
C

#include "global.h"
#include "common.h"
#include "structures.h"
#include "functions.h"
#include "asm.h"
#include "enemy.h"
#include "message.h"
#include "fileselect.h"
extern u16 gUnk_081092D4;
extern u8 gUnk_081094CE;
extern u8 gUnk_02036AD8;
extern u8 gUnk_02036A58;
extern void* gUnk_081092AC[];
typedef struct {
u8 filler0[12][16];
} VStruct;
extern VStruct gUnk_0810942E[];
extern u32 gUnk_0810926C[];
extern u32* Translations[];
extern u32 gUnk_08109244;
typedef struct {
u8 unk0;
u8 unk1;
} UStruct;
void sub_0805F820(WStruct* r0, u32* r1);
bool32 sub_0805EF40(Token* tok, const u8*);
void sub_0805F440(Token*, u8*);
u32 sub_0805F6A4(Token*, WStruct*);
u32 GetCharacter(Token* tok);
u32 GetFontStrWith(Token*, u32);
s32 sub_0805F67C(short*, s32, s32);
void sub_0805F918(u32, u32, void*);
bool32 sub_0805F5CC(Font*, Token*, WStruct*);
void sub_0805EEB4(Token*, u32);
u32 sub_0805EF8C(Token*);
u32 sub_0805EFB4(Token*);
u32 sub_0805F9A0(u32);
static u32 sub_0805F8F8(u32 idx);
static u32 sub_0805F7A0(u32 param_1);
typedef struct {
u16 unk0;
s8 unk2;
s8 unk3;
u8 filler[0x4];
u16 unk8[4];
u16 unk10[4];
} struct_gUnk_02034330;
extern struct_gUnk_02034330 gUnk_02034330;
extern WStruct gUnk_02036540[4];
extern u32* gUnk_08109248[];
extern u8* gUnk_08109230[];
extern u32* gTranslations[];
extern u32 gUnk_08109244;
void sub_0805EEB4(Token* token, u32 textIndex) {
u32 langIndex;
u32* puVar2;
u8* puVar5;
s32 iVar3;
u32 uVar4;
u32 uVar6;
u32 uVar7;
token->textIndex = (u16)textIndex;
langIndex = gSaveHeader->language;
if (((1 < langIndex) && (textIndex >> 8 == 1)) && (textIndex < 0x119)) {
langIndex = 3;
}
puVar2 = gTranslations[langIndex];
iVar3 = puVar2[(u8)(textIndex >> 8)];
puVar2 = (u32*)((s32)puVar2 + iVar3);
iVar3 = puVar2[(u8)textIndex];
uVar6 = *(gTranslations[langIndex]) >> 2;
uVar7 = *puVar2 >> 2;
uVar4 = 0;
if (((token->textIndex >> 8) >= uVar6) || ((u8)token->textIndex >= uVar7)) {
uVar4 = 1;
} else {
if (*(char*)((s32)puVar2 + iVar3) == 0) {
uVar4 = 2;
}
}
switch (uVar4) {
case 1:
case 2:
puVar2 = &gUnk_08109244;
iVar3 = 0;
break;
}
puVar2 = (u32*)((s32)puVar2 + iVar3);
sub_0805EF40(token, (u8*)puVar2);
}
bool32 sub_0805EF40(Token* token, const u8* param_2) {
if (token->unk00 != 0) {
if (6 < token->unk01) {
return 0;
}
token->unk01++;
}
token->buf[token->unk01] = param_2;
token->unk00 = 1;
return 1;
}
u32 sub_0805EF8C(Token* token) {
if (token->unk00 == 0) {
return 0;
}
return (token->buf[token->unk01]++)[0];
}
u32 sub_0805EFB4(Token* token) {
u32 rv = token->unk01;
if (token->unk01 != 0) {
token->unk01--;
} else {
token->unk00 = 0;
}
return rv;
}
u32 GetCharacter(Token* token) {
u32 uVar3;
u32 code;
u32 uVar6;
u8** ppuVar7;
s32 iVar8;
do {
code = sub_0805EF8C(token);
token->code = (u8)code;
iVar8 = 0;
switch (code) {
case 0:
iVar8 = sub_0805EFB4(token);
code = 0;
break;
case 1:
uVar6 = sub_0805EF8C(token);
token->param = (u16)uVar6;
code = 6;
if (uVar6 < 0xb) {
code = 5;
}
break;
case 2:
uVar3 = sub_0805EF8C(token);
token->param = uVar3;
code = 7;
break;
case 3:
uVar6 = sub_0805EF8C(token) << 8;
uVar6 += sub_0805EF8C(token);
token->param = uVar6;
code = 8;
break;
case 4:
uVar6 = sub_0805EF8C(token);
switch (uVar6) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 0xb:
case 0xc:
case 0xd:
case 0xe:
case 0xf:
code = 9;
break;
case 0x10:
uVar6 = sub_0805EF8C(token);
code = 10;
break;
case 0x11:
code = 2;
break;
case 0x12:
code = 3;
break;
case 0x13:
code = 4;
break;
case 0x14:
case 0x15:
code = 0xb;
if ((uVar6 ^ 0x14) != 0) {
uVar6 = 1;
} else {
uVar6 = 0;
}
}
token->param = (u16)uVar6;
break;
case 5:
uVar6 = sub_0805EF8C(token);
if (uVar6 == 0xff) {
uVar6 = 0;
} else {
uVar6 <<= 8;
uVar6 += sub_0805EF8C(token);
}
token->_6 = uVar6;
code = 0xc;
break;
case 6:
uVar6 = sub_0805EF8C(token);
switch (uVar6) {
case 0 ... 4:
ppuVar7 = (u8**)token->_c;
if (ppuVar7 == NULL) {
ppuVar7 = gUnk_08109230;
}
sub_0805EF40(token, ppuVar7[uVar6]);
break;
case 5:
uVar6 = sub_0805EF8C(token) << 8;
uVar6 += sub_0805EF8C(token);
sub_0805EEB4(token, uVar6);
break;
default:
break;
}
iVar8 = 1;
break;
case 7:
uVar6 = sub_0805EF8C(token) << 8;
uVar6 += sub_0805EF8C(token);
token->unk00 = 0;
token->unk01 = 0;
sub_0805EEB4(token, uVar6);
iVar8 = 1;
break;
case 8:
uVar3 = sub_0805EF8C(token);
token->param = uVar3;
code = 0xd;
break;
case 9:
uVar3 = sub_0805EF8C(token);
token->param = uVar3;
code = 0xe;
break;
case 10:
code = 1;
break;
case 0xb:
code = sub_0805EF8C(token);
code |= 0x400;
break;
case 0xc:
code = sub_0805EF8C(token);
code |= 0x700;
break;
case 0xd:
code = sub_0805EF8C(token);
code |= 0x500;
break;
case 0xe:
code = sub_0805EF8C(token);
code |= 0x600;
break;
case 0xf:
code = sub_0805EF8C(token);
code |= 0x300;
break;
default:
code += 0x100;
break;
}
} while (iVar8);
if (code >> 8 != 0) {
switch (token->unk05) {
case 0:
break;
case 1:
code = sub_0805F9A0(code);
break;
}
token->extended = (u16)code;
}
return code;
}
u32* sub_0805F25C(u32 param_1) {
u32 uVar1;
uVar1 = param_1 >> 8 & 0xf;
param_1 = param_1 & 0xff;
switch (uVar1) {
case 0:
case 1:
if (0x7f < param_1 && gSaveHeader->language != 0) {
param_1 = param_1 - 0x80;
uVar1 = 2;
}
break;
case 2:
case 3:
case 4:
break;
case 5:
case 6:
case 7:
case 8:
param_1 = param_1 << 1;
break;
}
return gUnk_08109248[uVar1] + param_1 * 0x10;
}
WStruct* sub_0805F2C8(void) {
u32 uVar2;
for (uVar2 = 0; uVar2 < ARRAY_COUNT(gUnk_02036540); uVar2++) {
if ((gUnk_02036540[uVar2].unk00) == 0) {
MemClear(&gUnk_02036540[uVar2], sizeof(WStruct));
gUnk_02036540[uVar2].unk00 = 1;
return &gUnk_02036540[uVar2];
}
}
return NULL;
}
void sub_0805F300(WStruct* param_1) {
u32 uVar2;
for (uVar2 = 0; uVar2 < ARRAY_COUNT(gUnk_02036540); uVar2++) {
if (&gUnk_02036540[uVar2] == param_1) {
MemClear(&gUnk_02036540[uVar2], sizeof(WStruct));
return;
}
}
}
u32 GetFontStrWith(Token* param_1, u32 param_2) {
u32 character;
u32* puVar2;
u32 uVar3;
u32 uVar4;
u16 uVar5;
u32 rv;
u32 r9;
Token token;
s32 local_28;
s32 local_24;
MemCopy(param_1, &token, sizeof(Token));
local_24 = 0;
local_28 = 0;
rv = 0;
uVar5 = 0;
do {
uVar4 = 0;
r9 = 1;
while (r9) {
character = GetCharacter(&token);
switch (character) {
case 0xc:
uVar4 += 8;
break;
case 0xb:
uVar5 = token.param;
break;
case 0:
case 1:
r9 = 0;
break;
case 2 ... 10:
case 0xd:
case 0xe:
break;
default:
if (uVar5 == 0) {
puVar2 = (u32*)sub_0805F25C(character);
if (4 < character >> 8) {
uVar3 = sub_0805F7A0(puVar2[0x10]);
uVar4 += (uVar3 >> 8);
}
uVar3 = sub_0805F7A0(*puVar2);
uVar4 += (uVar3 >> 8);
} else if (character >> 8 >= 5) {
uVar4 += 0x10;
} else {
uVar4 += 8;
}
if (token.unk05 == 1 && uVar4 > 1) {
uVar4--;
}
}
}
if (uVar4 > rv) {
rv = uVar4;
}
if (uVar4 != 0) {
local_28++;
} else {
local_24++;
}
} while ((param_2 != 0) && (character != 0));
if (param_2 != 0) {
return local_24 << 0x18 | local_28 << 0x10 | rv;
}
return rv;
}
void sub_0805F440(Token* param_1, u8* param_2) {
MemClear(param_1, sizeof(Token));
if ((u32)param_2 >= 0x10000) {
sub_0805EF40(param_1, param_2);
} else {
sub_0805EEB4(param_1, (u32)param_2);
}
}
u32 sub_0805F46C(u32 param_1, const Font* param_2) {
u32 uVar1;
WStruct* pWVar4;
u32 uVar5;
u16* puVar6;
u32 uVar7;
u32 uVar8;
u16* puVar9;
u32 iVar10;
Token token;
Font font;
u32 fontStr;
u32 temp2;
u32 temp3;
pWVar4 = sub_0805F2C8();
if (pWVar4 != NULL) {
MemCopy(param_2, &font, sizeof(Font));
sub_0805F440(&token, (u8*)param_1);
token.unk05 = font.stylized & 3;
pWVar4->unk04 = font.stylized;
pWVar4->unk4 = font.width;
pWVar4->unk8 = font.buffer_loc;
pWVar4->charColor = font._15;
pWVar4->bgColor = font.fill_type;
if (font.draw_border) {
sub_0805F918(font.border_type, font.fill_type, font.gfx_dest);
font.gfx_dest = (void*)((s32)font.gfx_dest + 0xe0);
fontStr = GetFontStrWith(&token, 1);
iVar10 = (fontStr >> 0x18) * (u32)font._16 + ((u8)((s32)fontStr >> 0x10) << 1);
uVar8 = (u16)fontStr;
temp3 = uVar8;
if (font.width < (s32)temp3) {
temp3 = font.width;
}
uVar8 = (temp3 + 7);
temp2 = ~7;
uVar8 = font.sm_border ? uVar8 & temp2 : font.width;
puVar9 = font.dest;
font.dest += 0x20;
if (font.right_align) {
uVar8 = (uVar8 + 0xf) & ~0xf;
puVar9 -= (uVar8 >> 4) + 1;
} else {
font.dest++;
}
uVar8 = uVar8 >> 3;
param_1 = font.gfx_src;
DispMessageFrame(puVar9, uVar8, iVar10, param_1);
puVar9 = puVar9 + 1;
font.gfx_src = font.gfx_src + 7;
param_1 = font.gfx_src - 1;
while (iVar10-- > 0) {
puVar9 += 0x20;
puVar6 = puVar9;
for (uVar5 = uVar8; (s32)uVar5-- > 0;) {
*puVar6++ = param_1;
}
}
}
MemClear(&gUnk_02034330, sizeof(gUnk_02034330));
while ((s16)sub_0805F5CC(&font, &token, pWVar4) != 0) {}
sub_0805F300(pWVar4);
}
return 0;
}
bool32 sub_0805F5CC(Font* param_1, Token* param_2, WStruct* param_3) {
u16 uVar2;
u32 uVar3;
s32 iVar4;
u16* puVar5;
u32 fontStr;
uVar3 = sub_0805F8F8(param_1->fill_type);
MemFill32(uVar3, param_1->buffer_loc, ((param_1->width + 7) & 0x1f8) << 3);
fontStr = GetFontStrWith(param_2, 0);
param_3->unk6 = param_1->right_align ? ((8 - ((fontStr + 1) >> 1)) & 7) : 0;
puVar5 = (u16*)sub_0805F6A4(param_2, param_3);
if (puVar5) {
iVar4 = (s32)(param_3->unk6 + 7) / 8;
puVar5 = param_1->dest;
if (param_1->right_align) {
puVar5 -= (iVar4 + 1U) >> 1;
}
param_1->gfx_src = sub_0805F67C(puVar5, param_1->gfx_src, iVar4);
param_1->dest += 0x40;
iVar4 *= 0x40;
MemCopy(param_1->buffer_loc, param_1->gfx_dest, iVar4);
param_1->gfx_dest = (void*)((s32)param_1->gfx_dest + iVar4);
} else {
if (param_2->code == 10) {
param_1->dest += param_1->_16 * 0x20;
}
}
return param_2->code > 0;
}
s32 sub_0805F67C(short* param_1, s32 param_2, s32 param_3) {
for (param_3--; param_3 != -1; param_3--) {
param_1[0] = param_2++;
param_1[0x20] = param_2++;
param_1++;
}
return param_2;
}
u32 sub_0805F6A4(Token* param_1, WStruct* param_2) {
u32 uVar1;
u32 uVar3;
s32 iVar4;
u32 r7;
iVar4 = 0;
r7 = 1;
do {
uVar1 = GetCharacter(param_1);
r7 = 1;
switch (uVar1) {
case 7:
if (param_1->param < 0xe) {
param_2->charColor = param_1->param;
}
break;
case 0:
case 1:
r7 = 0;
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 8:
case 9:
case 10:
case 0xd:
case 0xe:
break;
case 0xc:
uVar3 = gUnk_02034330.unk2;
if (uVar3 < 4) {
gUnk_02034330.unk2 = uVar3 + 1;
gUnk_02034330.unk10[uVar3] = param_1->_6;
gUnk_02034330.unk8[uVar3] = param_2->unk6;
}
param_2->unk6 += 8;
iVar4 += 8;
break;
case 0xb:
param_2->unk1 = param_1->param;
break;
default:
iVar4 += sub_0805F7DC(uVar1, param_2);
if ((param_1->unk05 == 1) && (1 < param_2->unk6)) {
iVar4--;
param_2->unk6 = param_2->unk6 - 1;
}
break;
}
} while (r7);
return iVar4;
}
u32 sub_0805F76C(u8* param_1, WStruct* param_2) {
u32 uVar1;
Token local_38;
sub_0805F440(&local_38, param_1);
local_38.unk05 = param_2->unk04 & 3;
uVar1 = sub_0805F6A4(&local_38, param_2);
return uVar1;
}
static u32 sub_0805F7A0(u32 param_1) {
u32 uVar1;
u32 uVar2;
u32 uVar3;
uVar1 = 0xf;
for (uVar2 = 0; uVar2 < 8; uVar2++) {
if (uVar1 != (param_1 & uVar1))
break;
uVar1 <<= 4;
}
for (uVar3 = uVar2; (uVar2 < 8 && (uVar1 != (param_1 & uVar1))); uVar1 <<= 4, uVar2++) {}
uVar2 -= uVar3;
return (uVar2 << 8) | uVar3;
}
u32 sub_0805F7DC(u32 r0, WStruct* r1) {
u32 temp;
u32 temp2;
u32* offset;
if (r1->unk4 <= r1->unk6)
return 0;
offset = sub_0805F25C(r0);
temp = r1->unk6;
if ((r0 >> 8) > 4) {
sub_0805F820(r1, offset);
offset += 0x10;
}
sub_0805F820(r1, offset);
if (r1->unk6 > r1->unk4) {
r1->unk6 = r1->unk4;
}
return r1->unk6 - temp;
}
void sub_0805F820(WStruct* r0, u32* r1) {
u32 bVar1;
u32 bVar2;
s32 uVar3;
s32 uVar4;
void* uVar5;
u32 uVar6;
u32 uVar7;
u8* puVar8;
u8* temp;
void* temp2;
VStruct* temp3;
u32 temp4;
if (r0->unk4 - r0->unk6 > 0) {
sub_08002724(r1, &gUnk_02036A58);
if (r0->unk1 == 0) {
u32 tmp = sub_0805F7A0(*r1);
uVar6 = tmp & 0xf;
uVar3 = tmp >> 8;
} else {
uVar6 = 0;
uVar3 = 8;
}
uVar4 = r0->unk4 - r0->unk6;
if (uVar4 > 8) {
uVar4 = 8;
}
if (uVar4 < uVar3) {
uVar3 = uVar4;
}
puVar8 = &gUnk_02036A58 + uVar6;
temp2 = r0->unk8;
temp = gUnk_0810942E[r0->bgColor].filler0[r0->charColor * 2];
uVar7 = r0->unk6;
r0->unk6 += uVar3;
temp4 = r0->unk04;
if (temp4 != 1) {
while (uVar3-- > 0) {
sub_080026C4(puVar8, temp2, temp, uVar7);
puVar8++;
uVar7++;
}
} else {
while (uVar3-- > 0) {
sub_080026F2(puVar8, temp2, temp, uVar7);
puVar8++;
uVar7++;
}
}
}
}
void sub_0805F8E4(u32 r0, WStruct* r1) {
u32 old = r1->unk1;
r1->unk1 = 1;
sub_0805F7DC(r0, r1);
r1->unk1 = old;
}
static u32 sub_0805F8F8(u32 idx) {
u8* temp = &gUnk_0810942E[idx].filler0[10][10];
return gUnk_0810926C[*temp];
}
void sub_0805F918(u32 idx, u32 idx2, void* dest) {
u32 i;
void* puVar1;
u8* puVar2;
u32 j;
u32 idx3;
u8* temp;
u8* temp2;
MemFill32(sub_0805F8F8(idx2), &gUnk_02036AD8, 0xe0);
puVar1 = gUnk_081092AC[idx];
temp = &gUnk_081094CE + idx2 * 0xc0;
idx3 = 0;
for (i = 0; i < 3; i++) {
puVar2 = &gUnk_02036A58;
sub_08002724(puVar1, &gUnk_02036A58);
puVar1 += 0x40;
for (j = 0; j < 8; j++) {
sub_080026C4(puVar2, &gUnk_02036AD8, temp, idx3);
puVar2++;
idx3++;
}
}
LoadResourceAsync((const void*)&gUnk_02036AD8, (u32)dest, 0xe0);
}
u32 sub_0805F9A0(u32 r0) {
if (gSaveHeader->language == 0) {
u16* val = &gUnk_081092D4;
u32 i = 0;
do {
if (*val == r0) {
return i + 0x800;
}
i++;
val++;
} while (*val != 0);
} else if (r0 == 0x31a) {
r0 = 1;
r0 &= 0xff;
}
return (r0 & 0xff) + 0x800;
}