Identify unk_020232E0 -> font_manager

This commit is contained in:
Rachel 2024-10-12 18:23:26 -07:00
parent 540c749aa4
commit 059f8d8e0a
10 changed files with 399 additions and 398 deletions

View File

@ -17,7 +17,7 @@ typedef struct FontAttributes {
u8 shadowColor;
} FontAttributes;
void sub_02002B7C(void);
void Fonts_Init(void);
void sub_02002BB8(int param0, u32 param1);
void sub_02002BEC(int param0, u32 param1);
void sub_02002C28(int param0);

56
include/font_manager.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef POKEPLATINUM_FONT_MANAGER_H
#define POKEPLATINUM_FONT_MANAGER_H
#include "charcode.h"
#include "narc.h"
#include "render_text.h"
enum GlyphShape {
GLYPH_SHAPE_8x8 = 0,
GLYPH_SHAPE_8x16,
GLYPH_SHAPE_16x8,
GLYPH_SHAPE_16x16,
GLYPH_SHAPE_MAX,
};
typedef struct FontManager FontManager;
typedef void (*GlyphBitmapFunc)(const FontManager *fontManager, charcode_t c, TextGlyph *outGlyph);
typedef u8 (*GlyphWidthFunc)(const FontManager *fontManager, u32 glyph);
typedef struct FontHeader {
u32 size;
u32 widthTableOffset;
u32 numGlyphs;
u8 maxWidth;
u8 maxHeight;
u8 glyphWidth;
u8 glyphHeight;
} FontHeader;
struct FontManager {
int glyphAccessMode;
GlyphBitmapFunc glyphBitmapFunc;
enum GlyphShape glyphShape;
u32 glyphSize;
u8 *narcBuf;
u8 glyphBuf[64];
NARC *narc;
u32 arcFileIdx;
FontHeader header;
BOOL isMonospace;
GlyphWidthFunc glyphWidthFunc;
u8 *glyphWidths;
};
FontManager *FontManager_New(u32 param0, u32 param1, int param2, BOOL param3, u32 param4);
void FontManager_Delete(FontManager *param0);
void FontManager_SwitchGlyphAccessMode(FontManager *param0, int param1, u32 param2);
void FontManager_TryLoadGlyph(const FontManager *param0, u16 param1, TextGlyph *param2);
u32 FontManager_CalcStringWidth(const FontManager *param0, const u16 *param1, u32 param2);
BOOL FontManager_AreAllCharsValid(const FontManager *param0, const u16 *param1);
u32 FontManager_CalcMaxLineWidth(const FontManager *param0, const u16 *param1, u32 param2);
u32 FontManager_CalcStringWidthWithCursorControl(const FontManager *param0, const u16 *param1);
#endif // POKEPLATINUM_FONT_MANAGER_H

View File

@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_02023350_DECL_H
#define POKEPLATINUM_STRUCT_02023350_DECL_H
typedef struct UnkStruct_02023350_t UnkStruct_02023350;
#endif // POKEPLATINUM_STRUCT_02023350_DECL_H

View File

@ -1,17 +0,0 @@
#ifndef POKEPLATINUM_UNK_020232E0_H
#define POKEPLATINUM_UNK_020232E0_H
#include "struct_decls/struct_02023350_decl.h"
#include "render_text.h"
UnkStruct_02023350 *sub_020232E0(u32 param0, u32 param1, int param2, BOOL param3, u32 param4);
void sub_02023318(UnkStruct_02023350 *param0);
void sub_02023330(UnkStruct_02023350 *param0, int param1, u32 param2);
void sub_020234A0(const UnkStruct_02023350 *param0, u16 param1, TextGlyph *param2);
u32 sub_02023620(const UnkStruct_02023350 *param0, const u16 *param1, u32 param2);
BOOL sub_0202366C(const UnkStruct_02023350 *param0, const u16 *param1);
u32 sub_020236D0(const UnkStruct_02023350 *param0, const u16 *param1, u32 param2);
u32 sub_02023738(const UnkStruct_02023350 *param0, const u16 *param1);
#endif // POKEPLATINUM_UNK_020232E0_H

View File

@ -93,7 +93,7 @@ Static main
Object main.nef.p/src_error_handling.c.o
Object main.nef.p/src_resource_collection.c.o
Object main.nef.p/src_unk_0202309C.c.o
Object main.nef.p/src_unk_020232E0.c.o
Object main.nef.p/src_font_manager.c.o
Object main.nef.p/src_strbuf.c.o
Object main.nef.p/src_unk_02023FCC.c.o
Object main.nef.p/src_unk_0202414C.c.o

View File

@ -3,19 +3,17 @@
#include <nitro.h>
#include <string.h>
#include "struct_decls/struct_02023350_decl.h"
#include "font_manager.h"
#include "heap.h"
#include "render_text.h"
#include "strbuf.h"
#include "unk_02006E3C.h"
#include "unk_0201D670.h"
#include "unk_020232E0.h"
typedef struct {
TextGlyph curGlyph;
void *data[4];
UnkStruct_02023350 *unk_94[4];
FontManager *unk_94[4];
} FontWork;
static const struct {
@ -77,7 +75,7 @@ static const FontAttributes sFontAttributes[FONT_MAX + 1] = {
static FontWork *sFontWork = NULL;
void sub_02002B7C(void)
void Fonts_Init(void)
{
u32 v0;
static FontWork work;
@ -94,7 +92,7 @@ void sub_02002B7C(void)
void sub_02002BB8(int param0, u32 param1)
{
sFontWork->unk_94[param0] = sub_020232E0(14, sFontArchiveData[param0].arcFileIdx, 1, sFontArchiveData[param0].unk_02, param1);
sFontWork->unk_94[param0] = FontManager_New(14, sFontArchiveData[param0].arcFileIdx, 1, sFontArchiveData[param0].unk_02, param1);
}
void sub_02002BEC(int param0, u32 param1)
@ -102,7 +100,7 @@ void sub_02002BEC(int param0, u32 param1)
GF_ASSERT(param0 < 4);
GF_ASSERT(sFontWork->unk_94[param0]);
sub_02023330(sFontWork->unk_94[param0], 0, param1);
FontManager_SwitchGlyphAccessMode(sFontWork->unk_94[param0], 0, param1);
}
void sub_02002C28(int param0)
@ -110,7 +108,7 @@ void sub_02002C28(int param0)
GF_ASSERT(param0 < 4);
GF_ASSERT(sFontWork->unk_94[param0]);
sub_02023330(sFontWork->unk_94[param0], 1, 0);
FontManager_SwitchGlyphAccessMode(sFontWork->unk_94[param0], 1, 0);
}
void sub_02002C60(int param0)
@ -138,14 +136,14 @@ void sub_02002C60(int param0)
}
if (sFontWork->unk_94[param0] != NULL) {
sub_02023318(sFontWork->unk_94[param0]);
FontManager_Delete(sFontWork->unk_94[param0]);
sFontWork->unk_94[param0] = NULL;
}
}
const TextGlyph *sub_02002CFC(int param0, u16 param1)
{
sub_020234A0(sFontWork->unk_94[param0], param1, &sFontWork->curGlyph);
FontManager_TryLoadGlyph(sFontWork->unk_94[param0], param1, &sFontWork->curGlyph);
return &(sFontWork->curGlyph);
}
@ -166,13 +164,13 @@ int sub_02002D18(int param0, TextPrinter *param1)
u32 sub_02002D48(int param0, const u16 *param1, u32 param2)
{
GF_ASSERT(sFontWork->unk_94[param0] != NULL);
return sub_02023620(sFontWork->unk_94[param0], param1, param2);
return FontManager_CalcStringWidth(sFontWork->unk_94[param0], param1, param2);
}
u32 sub_02002D7C(int param0, const Strbuf *param1, u32 param2)
{
GF_ASSERT(sFontWork->unk_94[param0] != NULL);
return sub_02023620(sFontWork->unk_94[param0], Strbuf_GetData(param1), param2);
return FontManager_CalcStringWidth(sFontWork->unk_94[param0], Strbuf_GetData(param1), param2);
}
u32 sub_02002DB4(int param0, Strbuf *param1, Strbuf *param2)
@ -182,7 +180,7 @@ u32 sub_02002DB4(int param0, Strbuf *param1, Strbuf *param2)
Strbuf_Clear(param2);
Strbuf_ConcatTrainerName(param2, param1);
return sub_0202366C(sFontWork->unk_94[param0], Strbuf_GetData(param2));
return FontManager_AreAllCharsValid(sFontWork->unk_94[param0], Strbuf_GetData(param2));
}
u8 Font_GetAttribute(u8 param0, u8 param1)
@ -232,7 +230,7 @@ void sub_02002E98(u32 param0, u32 param1, u32 param2)
u32 sub_02002EB4(int param0, const Strbuf *param1, u32 param2)
{
GF_ASSERT(sFontWork->unk_94[param0] != NULL);
return sub_020236D0(sFontWork->unk_94[param0], Strbuf_GetData(param1), param2);
return FontManager_CalcMaxLineWidth(sFontWork->unk_94[param0], Strbuf_GetData(param1), param2);
}
u32 sub_02002EEC(int param0, const Strbuf *param1, u32 param2, u32 param3)
@ -245,5 +243,5 @@ u32 sub_02002EEC(int param0, const Strbuf *param1, u32 param2, u32 param3)
u32 sub_02002F04(int param0, const Strbuf *param1)
{
GF_ASSERT(sFontWork->unk_94[param0] != NULL);
return sub_02023738(sFontWork->unk_94[param0], Strbuf_GetData(param1));
return FontManager_CalcStringWidthWithCursorControl(sFontWork->unk_94[param0], Strbuf_GetData(param1));
}

326
src/font_manager.c Normal file
View File

@ -0,0 +1,326 @@
#include "font_manager.h"
#include <nitro.h>
#include <string.h>
#include "charcode.h"
#include "heap.h"
#include "narc.h"
#include "render_text.h"
#include "unk_0201D670.h"
static void sub_02023350(FontManager *param0, u32 param1, u32 param2, BOOL param3, u32 param4);
static void sub_02023408(FontManager *param0);
static void sub_02023424(FontManager *param0, int param1, u32 param2);
static void sub_0202343C(FontManager *param0, u32 param1);
static void sub_0202346C(FontManager *param0, u32 param1);
static void sub_02023478(FontManager *param0);
static void sub_0202348C(FontManager *param0);
static void sub_0202349C(FontManager *param0);
static void sub_020234BC(const FontManager *param0, u16 param1, TextGlyph *param2);
static void sub_02023564(const FontManager *param0, u16 param1, TextGlyph *param2);
static u8 sub_020236B0(const FontManager *param0, u32 param1);
static u8 sub_020236C8(const FontManager *param0, u32 param1);
FontManager *FontManager_New(u32 param0, u32 param1, int param2, BOOL param3, u32 param4)
{
FontManager *v0 = Heap_AllocFromHeap(param4, sizeof(FontManager));
if (v0) {
sub_02023350(v0, param0, param1, param3, param4);
sub_02023424(v0, param2, param4);
}
return v0;
}
void FontManager_Delete(FontManager *param0)
{
sub_02023478(param0);
sub_02023408(param0);
Heap_FreeToHeap(param0);
}
void FontManager_SwitchGlyphAccessMode(FontManager *param0, int param1, u32 param2)
{
if (param0->glyphAccessMode != param1) {
sub_02023478(param0);
sub_02023424(param0, param1, param2);
}
}
static void sub_02023350(FontManager *param0, u32 param1, u32 param2, BOOL param3, u32 param4)
{
param0->narc = NARC_ctor(param1, param4);
if (param0->narc) {
NARC_ReadFromMember(param0->narc, param2, 0, sizeof(FontHeader), &(param0->header));
param0->isMonospace = param3;
if (param3) {
param0->glyphWidths = NULL;
param0->glyphWidthFunc = sub_020236C8;
} else {
GF_ASSERT(param0->header.widthTableOffset);
param0->glyphWidths = Heap_AllocFromHeap(param4, param0->header.numGlyphs);
param0->glyphWidthFunc = sub_020236B0;
NARC_ReadFromMember(param0->narc, param2, param0->header.widthTableOffset, param0->header.numGlyphs, (void *)(param0->glyphWidths));
}
{
static const u8 v0[2][2] = {
{ 0x0, 0x1 },
{ 0x2, 0x3 }
};
GF_ASSERT(param0->header.glyphWidth <= 2 && param0->header.glyphHeight <= 2);
param0->glyphShape = v0[param0->header.glyphWidth - 1][param0->header.glyphHeight - 1];
param0->glyphSize = 16 * param0->header.glyphWidth * param0->header.glyphHeight;
}
param0->arcFileIdx = param2;
}
}
static void sub_02023408(FontManager *param0)
{
if (param0->glyphWidths) {
Heap_FreeToHeap(param0->glyphWidths);
}
if (param0->narc) {
NARC_dtor(param0->narc);
}
}
static void sub_02023424(FontManager *param0, int param1, u32 param2)
{
static void (*const v0[])(FontManager *, u32) = {
sub_0202343C,
sub_0202346C,
};
param0->glyphAccessMode = param1;
v0[param1](param0, param2);
}
static void sub_0202343C(FontManager *param0, u32 param1)
{
u32 v0 = param0->glyphSize * param0->header.numGlyphs;
param0->narcBuf = Heap_AllocFromHeap(param1, v0);
param0->glyphBitmapFunc = sub_020234BC;
NARC_ReadFromMember(param0->narc, param0->arcFileIdx, param0->header.size, v0, param0->narcBuf);
}
static void sub_0202346C(FontManager *param0, u32 param1)
{
param0->glyphBitmapFunc = sub_02023564;
}
static void sub_02023478(FontManager *param0)
{
static void (*const v0[])(FontManager *) = {
sub_0202348C,
sub_0202349C
};
v0[param0->glyphAccessMode](param0);
}
static void sub_0202348C(FontManager *param0)
{
Heap_FreeToHeap(param0->narcBuf);
param0->narcBuf = NULL;
}
static void sub_0202349C(FontManager *param0)
{
(void)0;
}
void FontManager_TryLoadGlyph(const FontManager *param0, u16 param1, TextGlyph *param2)
{
if (param1 <= param0->header.numGlyphs) {
param1--;
} else {
param1 = 0x1ac - 1;
}
param0->glyphBitmapFunc(param0, param1, param2);
}
static void sub_020234BC(const FontManager *param0, u16 param1, TextGlyph *param2)
{
u32 v0;
v0 = (u32)(&param0->narcBuf[param1 * param0->glyphSize]);
switch (param0->glyphShape) {
case 0:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
break;
case 1:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0(v0 + 0x10 * 1, ((u32)param2->gfx) + 0x20 * 2);
break;
case 2:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0(v0 + 0x10 * 1, ((u32)param2->gfx) + 0x20 * 1);
break;
case 3:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0(v0 + 0x10 * 1, ((u32)param2->gfx) + 0x20 * 1);
sub_0201DAA0(v0 + 0x10 * 2, ((u32)param2->gfx) + 0x20 * 2);
sub_0201DAA0(v0 + 0x10 * 3, ((u32)param2->gfx) + 0x20 * 3);
break;
}
param2->width = param0->glyphWidthFunc(param0, param1);
param2->height = param0->header.maxHeight;
}
static void sub_02023564(const FontManager *param0, u16 param1, TextGlyph *param2)
{
u32 v0;
NARC_ReadFromMember(param0->narc, param0->arcFileIdx, param0->header.size + param1 * param0->glyphSize, param0->glyphSize, (void *)(param0->glyphBuf));
switch (param0->glyphShape) {
case 0:
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
break;
case 1:
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 1])), ((u32)param2->gfx) + 0x20 * 2);
break;
case 2:
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 1])), ((u32)param2->gfx) + 0x20 * 1);
break;
case 3:
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 1])), ((u32)param2->gfx) + 0x20 * 1);
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 2])), ((u32)param2->gfx) + 0x20 * 2);
sub_0201DAA0((u32)(&(param0->glyphBuf[0x10 * 3])), ((u32)param2->gfx) + 0x20 * 3);
break;
}
param2->width = param0->glyphWidthFunc(param0, param1);
param2->height = param0->header.maxHeight;
}
u32 FontManager_CalcStringWidth(const FontManager *param0, const u16 *param1, u32 param2)
{
u32 v0 = 0;
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
param1 = CharCode_SkipFormatArg(param1);
if (*param1 == 0xffff) {
break;
}
}
v0 += (param0->glyphWidthFunc(param0, (*param1) - 1) + param2);
param1++;
}
return v0 - param2;
}
BOOL FontManager_AreAllCharsValid(const FontManager *param0, const u16 *param1)
{
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
param1 = CharCode_SkipFormatArg(param1);
if (*param1 == 0xffff) {
return 1;
}
}
if (((*param1) - 1) >= param0->header.numGlyphs) {
return 0;
}
param1++;
}
return 1;
}
static u8 sub_020236B0(const FontManager *param0, u32 param1)
{
if (param1 < param0->header.numGlyphs) {
return param0->glyphWidths[param1];
} else {
return param0->glyphWidths[0x1ac - 1];
}
}
static u8 sub_020236C8(const FontManager *param0, u32 param1)
{
return param0->header.maxWidth;
}
u32 FontManager_CalcMaxLineWidth(const FontManager *param0, const u16 *param1, u32 param2)
{
u32 v0 = 0, v1 = 0;
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
param1 = CharCode_SkipFormatArg(param1);
continue;
} else if (*param1 == 0xe000) {
v1 -= param2;
if (v0 < v1) {
v0 = v1;
}
v1 = 0;
param1++;
continue;
}
v1 += (param0->glyphWidthFunc(param0, (*param1) - 1) + param2);
param1++;
}
v1 -= param2;
if (v0 < v1) {
v0 = v1;
}
return v0;
}
u32 FontManager_CalcStringWidthWithCursorControl(const FontManager *param0, const u16 *param1)
{
u32 v0 = 0;
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
if (CharCode_FormatArgType(param1) == 0x203) {
v0 = CharCode_FormatArgParam(param1, 0) - 12;
}
param1 = CharCode_SkipFormatArg(param1);
continue;
}
v0 += param0->glyphWidthFunc(param0, (*param1) - 1);
param1++;
}
return v0;
}

View File

@ -73,7 +73,7 @@ void NitroMain(void)
sub_0202419C();
InitRTC();
sub_02000E3C();
sub_02002B7C();
Fonts_Init();
sub_02002BB8(0, 3);
sub_02002BB8(1, 3);

View File

@ -86,7 +86,7 @@ pokeplatinum_c = files(
'unk_02022844.c',
'resource_collection.c',
'unk_0202309C.c',
'unk_020232E0.c',
'font_manager.c',
'unk_02023FCC.c',
'unk_0202414C.c',
'unk_0202419C.c',

View File

@ -1,356 +0,0 @@
#include "unk_020232E0.h"
#include <nitro.h>
#include <string.h>
#include "struct_decls/struct_02006C24_decl.h"
#include "charcode.h"
#include "heap.h"
#include "narc.h"
#include "render_text.h"
#include "unk_0201D670.h"
typedef void (*UnkFuncPtr_02023350)(const UnkStruct_02023350 *, u16, TextGlyph *);
typedef u8 (*UnkFuncPtr_02023350_1)(const UnkStruct_02023350 *, u32);
typedef struct {
u32 unk_00;
u32 unk_04;
u32 unk_08;
u8 unk_0C;
u8 unk_0D;
u8 unk_0E;
u8 unk_0F;
} UnkStruct_02023350_sub1;
typedef struct UnkStruct_02023350_t {
int unk_00;
UnkFuncPtr_02023350 unk_04;
u32 unk_08;
u32 unk_0C;
u8 *unk_10;
u8 unk_14[64];
NARC *unk_54;
u32 unk_58;
UnkStruct_02023350_sub1 unk_5C;
BOOL unk_6C;
UnkFuncPtr_02023350_1 unk_70;
u8 *unk_74;
} UnkStruct_02023350;
static void sub_02023350(UnkStruct_02023350 *param0, u32 param1, u32 param2, BOOL param3, u32 param4);
static void sub_02023408(UnkStruct_02023350 *param0);
static void sub_02023424(UnkStruct_02023350 *param0, int param1, u32 param2);
static void sub_0202343C(UnkStruct_02023350 *param0, u32 param1);
static void sub_0202346C(UnkStruct_02023350 *param0, u32 param1);
static void sub_02023478(UnkStruct_02023350 *param0);
static void sub_0202348C(UnkStruct_02023350 *param0);
static void sub_0202349C(UnkStruct_02023350 *param0);
static void sub_020234BC(const UnkStruct_02023350 *param0, u16 param1, TextGlyph *param2);
static void sub_02023564(const UnkStruct_02023350 *param0, u16 param1, TextGlyph *param2);
static u8 sub_020236B0(const UnkStruct_02023350 *param0, u32 param1);
static u8 sub_020236C8(const UnkStruct_02023350 *param0, u32 param1);
UnkStruct_02023350 *sub_020232E0(u32 param0, u32 param1, int param2, BOOL param3, u32 param4)
{
UnkStruct_02023350 *v0 = Heap_AllocFromHeap(param4, sizeof(UnkStruct_02023350));
if (v0) {
sub_02023350(v0, param0, param1, param3, param4);
sub_02023424(v0, param2, param4);
}
return v0;
}
void sub_02023318(UnkStruct_02023350 *param0)
{
sub_02023478(param0);
sub_02023408(param0);
Heap_FreeToHeap(param0);
}
void sub_02023330(UnkStruct_02023350 *param0, int param1, u32 param2)
{
if (param0->unk_00 != param1) {
sub_02023478(param0);
sub_02023424(param0, param1, param2);
}
}
static void sub_02023350(UnkStruct_02023350 *param0, u32 param1, u32 param2, BOOL param3, u32 param4)
{
param0->unk_54 = NARC_ctor(param1, param4);
if (param0->unk_54) {
NARC_ReadFromMember(param0->unk_54, param2, 0, sizeof(UnkStruct_02023350_sub1), &(param0->unk_5C));
param0->unk_6C = param3;
if (param3) {
param0->unk_74 = NULL;
param0->unk_70 = sub_020236C8;
} else {
GF_ASSERT(param0->unk_5C.unk_04);
param0->unk_74 = Heap_AllocFromHeap(param4, param0->unk_5C.unk_08);
param0->unk_70 = sub_020236B0;
NARC_ReadFromMember(param0->unk_54, param2, param0->unk_5C.unk_04, param0->unk_5C.unk_08, (void *)(param0->unk_74));
}
{
static const u8 v0[2][2] = {
{ 0x0, 0x1 },
{ 0x2, 0x3 }
};
GF_ASSERT(param0->unk_5C.unk_0E <= 2 && param0->unk_5C.unk_0F <= 2);
param0->unk_08 = v0[param0->unk_5C.unk_0E - 1][param0->unk_5C.unk_0F - 1];
param0->unk_0C = 16 * param0->unk_5C.unk_0E * param0->unk_5C.unk_0F;
}
param0->unk_58 = param2;
}
}
static void sub_02023408(UnkStruct_02023350 *param0)
{
if (param0->unk_74) {
Heap_FreeToHeap(param0->unk_74);
}
if (param0->unk_54) {
NARC_dtor(param0->unk_54);
}
}
static void sub_02023424(UnkStruct_02023350 *param0, int param1, u32 param2)
{
static void (*const v0[])(UnkStruct_02023350 *, u32) = {
sub_0202343C,
sub_0202346C,
};
param0->unk_00 = param1;
v0[param1](param0, param2);
}
static void sub_0202343C(UnkStruct_02023350 *param0, u32 param1)
{
u32 v0 = param0->unk_0C * param0->unk_5C.unk_08;
param0->unk_10 = Heap_AllocFromHeap(param1, v0);
param0->unk_04 = sub_020234BC;
NARC_ReadFromMember(param0->unk_54, param0->unk_58, param0->unk_5C.unk_00, v0, param0->unk_10);
}
static void sub_0202346C(UnkStruct_02023350 *param0, u32 param1)
{
param0->unk_04 = sub_02023564;
}
static void sub_02023478(UnkStruct_02023350 *param0)
{
static void (*const v0[])(UnkStruct_02023350 *) = {
sub_0202348C,
sub_0202349C
};
v0[param0->unk_00](param0);
}
static void sub_0202348C(UnkStruct_02023350 *param0)
{
Heap_FreeToHeap(param0->unk_10);
param0->unk_10 = NULL;
}
static void sub_0202349C(UnkStruct_02023350 *param0)
{
(void)0;
}
void sub_020234A0(const UnkStruct_02023350 *param0, u16 param1, TextGlyph *param2)
{
if (param1 <= param0->unk_5C.unk_08) {
param1--;
} else {
param1 = 0x1ac - 1;
}
param0->unk_04(param0, param1, param2);
}
static void sub_020234BC(const UnkStruct_02023350 *param0, u16 param1, TextGlyph *param2)
{
u32 v0;
v0 = (u32)(&param0->unk_10[param1 * param0->unk_0C]);
switch (param0->unk_08) {
case 0:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
break;
case 1:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0(v0 + 0x10 * 1, ((u32)param2->gfx) + 0x20 * 2);
break;
case 2:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0(v0 + 0x10 * 1, ((u32)param2->gfx) + 0x20 * 1);
break;
case 3:
sub_0201DAA0(v0 + 0x10 * 0, ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0(v0 + 0x10 * 1, ((u32)param2->gfx) + 0x20 * 1);
sub_0201DAA0(v0 + 0x10 * 2, ((u32)param2->gfx) + 0x20 * 2);
sub_0201DAA0(v0 + 0x10 * 3, ((u32)param2->gfx) + 0x20 * 3);
break;
}
param2->width = param0->unk_70(param0, param1);
param2->height = param0->unk_5C.unk_0D;
}
static void sub_02023564(const UnkStruct_02023350 *param0, u16 param1, TextGlyph *param2)
{
u32 v0;
NARC_ReadFromMember(param0->unk_54, param0->unk_58, param0->unk_5C.unk_00 + param1 * param0->unk_0C, param0->unk_0C, (void *)(param0->unk_14));
switch (param0->unk_08) {
case 0:
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
break;
case 1:
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 1])), ((u32)param2->gfx) + 0x20 * 2);
break;
case 2:
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 1])), ((u32)param2->gfx) + 0x20 * 1);
break;
case 3:
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 0])), ((u32)param2->gfx) + 0x20 * 0);
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 1])), ((u32)param2->gfx) + 0x20 * 1);
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 2])), ((u32)param2->gfx) + 0x20 * 2);
sub_0201DAA0((u32)(&(param0->unk_14[0x10 * 3])), ((u32)param2->gfx) + 0x20 * 3);
break;
}
param2->width = param0->unk_70(param0, param1);
param2->height = param0->unk_5C.unk_0D;
}
u32 sub_02023620(const UnkStruct_02023350 *param0, const u16 *param1, u32 param2)
{
u32 v0 = 0;
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
param1 = CharCode_SkipFormatArg(param1);
if (*param1 == 0xffff) {
break;
}
}
v0 += (param0->unk_70(param0, (*param1) - 1) + param2);
param1++;
}
return v0 - param2;
}
BOOL sub_0202366C(const UnkStruct_02023350 *param0, const u16 *param1)
{
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
param1 = CharCode_SkipFormatArg(param1);
if (*param1 == 0xffff) {
return 1;
}
}
if (((*param1) - 1) >= param0->unk_5C.unk_08) {
return 0;
}
param1++;
}
return 1;
}
static u8 sub_020236B0(const UnkStruct_02023350 *param0, u32 param1)
{
if (param1 < param0->unk_5C.unk_08) {
return param0->unk_74[param1];
} else {
return param0->unk_74[0x1ac - 1];
}
}
static u8 sub_020236C8(const UnkStruct_02023350 *param0, u32 param1)
{
return param0->unk_5C.unk_0C;
}
u32 sub_020236D0(const UnkStruct_02023350 *param0, const u16 *param1, u32 param2)
{
u32 v0 = 0, v1 = 0;
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
param1 = CharCode_SkipFormatArg(param1);
continue;
} else if (*param1 == 0xe000) {
v1 -= param2;
if (v0 < v1) {
v0 = v1;
}
v1 = 0;
param1++;
continue;
}
v1 += (param0->unk_70(param0, (*param1) - 1) + param2);
param1++;
}
v1 -= param2;
if (v0 < v1) {
v0 = v1;
}
return v0;
}
u32 sub_02023738(const UnkStruct_02023350 *param0, const u16 *param1)
{
u32 v0 = 0;
while (*param1 != 0xffff) {
if (*param1 == 0xfffe) {
if (CharCode_FormatArgType(param1) == 0x203) {
v0 = CharCode_FormatArgParam(param1, 0) - 12;
}
param1 = CharCode_SkipFormatArg(param1);
continue;
}
v0 += param0->unk_70(param0, (*param1) - 1);
param1++;
}
return v0;
}