diff options
| author | theo3 <arisstephenson2@gmail.com> | 2021-12-28 13:53:53 -0800 |
|---|---|---|
| committer | theo3 <arisstephenson2@gmail.com> | 2021-12-28 13:53:53 -0800 |
| commit | 3fd900f1bc81cbaf106de17f5b8d41e26de682a8 (patch) | |
| tree | b6226159f870a5974379851e986261eb8d1ce5fc /src/message.c | |
| parent | 0f65f8fd5008d06defcfae6c9d66270ff45a8e49 (diff) | |
rename files, sort asm into subdirectories
Diffstat (limited to 'src/message.c')
| -rw-r--r-- | src/message.c | 809 |
1 files changed, 809 insertions, 0 deletions
diff --git a/src/message.c b/src/message.c new file mode 100644 index 00000000..3560df71 --- /dev/null +++ b/src/message.c @@ -0,0 +1,809 @@ +#include "global.h" +#include "sound.h" +#include "asm.h" +#include "room.h" +#include "utils.h" +#include "functions.h" +#include "message.h" +#include "save.h" + +#define MESSAGE_ADVANCE_KEYS (A_BUTTON | B_BUTTON | DPAD_ANY | R_BUTTON) +#define MESSAGE_PRESS_ANY_ADVANCE_KEYS ((gInput.newKeys & MESSAGE_ADVANCE_KEYS) != 0) + +#define MESSAGE_WIDTH 0x20 +#define MESSAGE_POSITION_INDEX(window) ((window).yPos * MESSAGE_WIDTH + (window).xPos) + +#define MESSAGE_PALETTE 0xF + +// todo: move this to a shared header for ui tiles +enum { + MSG_BORDER_CORNER = 0x7B, + MSG_BORDER_H_CORNER = 0x7C, + MSG_BORDER_H_STRAIGHT = 0x7D, + MSG_BORDER_V_CORNER = 0x7E, + MSG_BORDER_V_STRAIGHT = 0x7F, + MSG_CURSOR = 0x80, + MSG_BACKGROUND = 0x81, + MSG_TEXT_LINE1TOP = 0x82, + MSG_TEXT_LINE1BOTTOM = 0x83, + MSG_TEXT_LINE2TOP = 0xb6, + MSG_TEXT_LINE2BOTTOM = 0xb7, +}; + +extern void WriteBit(u32*, u32); +extern void sub_0805EF40(Token* tok, const u8*); +extern void RecoverUI(u32 bottomPt, u32 topPt); +extern void RefreshUI(void); +extern void sub_0805F918(u32, u32, u32); +extern u32 sub_0801D51C(u32, u8*, u32); + +u32 sub_08056FEC(u32, u8*); +u32 GetCharacter(Token* tok); +extern void sub_0805EEB4(Token* tok, u32 textIdx); +u16 sub_0805F7DC(u32, u8*); +u32 GetFontStrWith(u8*, u32); + +static void StatusUpdate(u32 status); + +static u16 RunTextCommand(TextRender* this); +static void PaletteChange(TextRender* this, u32 id); +static void SwitchChoice(u32 to, u32 from); + +static void MsgChangeLine(u32 lineNo); +static void SetDoTextBox(u32 doTextbox); + +static void DeleteWindow(void); +static u32 ChangeWindowSize(u32 delta); +static void CreateWindow(void); + +static void DispString(void); +static void DispCursor(void); +static void DrawCanvasLine(void); +static void sub_08056F88(u32, u32); +static void sub_08056FBC(TextRender*); + +typedef u32 (*MessageFunction)(void); +static u32 MsgIdle(void); +static u32 MsgInit(void); +static u32 MsgUpdate(void); +static u32 MsgOpen(void); +static u32 MsgClose(void); +static u32 MsgDie(void); +typedef enum { + MSG_IDLE, + MSG_INIT, + MSG_UPDATE, + MSG_OPEN, + MSG_CLOSE, + MSG_DIE, +} MessageStatus; + +typedef void (*TextRenderFunction)(TextRender*); +static void TextDispInit(TextRender* this); +static void TextDispUpdate(TextRender* this); +static void TextDispDie(TextRender* this); +static void TextDispWait(TextRender* this); +static void TextDispRoll(TextRender* this); +static void TextDispEnquiry(TextRender* this); +typedef enum { + RENDER_INIT, + RENDER_UPDATE, + RENDER_DIE, + RENDER_WAIT, + RENDER_ROLL, + RENDER_ENQUIRY, +} TextRenderStatus; + +typedef struct Window { + u8 unk0; + u8 active; + u8 unk2; + u8 unk3; + u8 xPos; + u8 yPos; + u8 width; + u8 height; +} Window; +extern Window gCurrentWindow; +extern Window gNewWindow; + +extern struct { + u8 unk_00; + u8 unk_01[1]; + s8 choiceCount; + s8 currentChoice; + u8 unk_04[4]; + u16 unk_08[4]; + u16 unk_10[4]; +} gMessageChoices; + +extern u8 gTextGfxBuffer[0xD00]; + +s32 sub_08056338(void) { + s32 result; + + result = -1; + if (((gMessage.doTextBox & 0x7f) == 0) && (gUnk_02000040.unk_00 == 3)) + result = gUnk_02000040.unk_01; + return result; +} + +void MessageClose(void) { + if ((gMessage.doTextBox & 0x7f) != 0) { + gMessage.doTextBox = 0x88; + } +} + +void MessageFromTarget(u32 index) { + if (gRoomControls.cameraTarget != NULL) { + MessageNoOverlap(index, gRoomControls.cameraTarget); + } else { + MessageRequest(index); + } +} + +void MessageNoOverlap(u32 index, Entity* entity) { + s16 y; + s16 height; + + MessageRequest(index); + + y = entity->y.HALF.HI; + height = entity->z.HALF.HI; + + if (((y + height) - gRoomControls.roomScrollY) > 0x58) { + gMessage.textWindowPosY = 1; + } +} + +void MessageAtHeight(u32 index, u32 y) { + MessageAtPos(index, 1, y); +} + +void MessageAtPos(u32 index, u32 x, u32 y) { + MessageRequest(index); + gMessage.textWindowPosX = x; + gMessage.textWindowPosY = y; +} + +void MessageRequest(u32 index) { + MemClear(&gMessage, sizeof(gMessage)); + gMessage.textIndex = index; + gMessage.textSpeed = 99; + gMessage.textWindowWidth = 26; + gMessage.textWindowHeight = 4; + gMessage.textWindowPosX = 1; + gMessage.textWindowPosY = 12; + gMessage.doTextBox = 1; +} + +void MessageInitialize(void) { + MemClear(&gMessage, sizeof(gMessage)); + MemClear(&gTextRender, sizeof(gTextRender)); + MemClear(&gNewWindow, sizeof(gNewWindow)); + MemClear(&gCurrentWindow, sizeof(gCurrentWindow)); + MemClear(&gUnk_02000040, 4); +} + +void MessageMain(void) { + static const MessageFunction gMessageFunctions[] = { + [MSG_IDLE] = MsgIdle, [MSG_INIT] = MsgInit, [MSG_UPDATE] = MsgUpdate, + [MSG_OPEN] = MsgOpen, [MSG_CLOSE] = MsgClose, [MSG_DIE] = MsgDie, + }; + + if (gMessage.doTextBox == 1) { + MemClear((u32*)&gTextRender, sizeof(gTextRender)); + StatusUpdate(MSG_INIT); + } + + if (gTextRender.newlineDelay != 0) { + gTextRender.newlineDelay--; + } else { + int result; + do { + result = gMessageFunctions[gTextRender.msgStatus](); + } while (result != 0); + } + if (gTextRender.updateDraw) { + gTextRender.updateDraw = 0; + DrawCanvasLine(); + } + DeleteWindow(); + CreateWindow(); +} + +static void StatusUpdate(MessageStatus status) { + gTextRender.msgStatus = status; + gTextRender.renderStatus = RENDER_INIT; +} + +static u32 MsgIdle(void) { + gTextRender._98.bytes.b1 = 0; + return 0; +} + +extern u8 gUnk_020227DC, gUnk_020227E8, gUnk_020227F0, gUnk_020227F8, gUnk_02022800; +u8* const gUnk_08107BE0[] = { + &gUnk_020227DC, &gUnk_020227E8, &gUnk_020227F0, &gUnk_020227F8, &gUnk_02022800, +}; + +// regalloc in loop +NONMATCH("asm/non_matching/textbox/TextBoxFunction1.inc", static u32 MsgInit(void)) { + char* dest; + u32 i; + + MemClear((void*)&gNewWindow, sizeof(gNewWindow)); + MemClear((void*)&gMessageChoices, sizeof(gMessageChoices)); + MemClear((void*)&gTextRender, sizeof(gTextRender)); + MemCopy(&gMessage, &gTextRender, sizeof(gMessage)); + if (gTextRender.message.textSpeed == 99) { + gTextRender.message.textSpeed = gSaveHeader->messageSpeed; + } + gTextRender._9c = 0xff; + sub_0805EEB4(&gTextRender.curToken, gTextRender.message.textIndex); + gTextRender.playerName[0] = 2; + gTextRender.playerName[1] = 0xe; // Green text color + dest = &gTextRender.playerName[2]; + + for (i = 0; i < FILENAME_LENGTH; ++i) { + char c = gSave.playerName[i]; + if (c == '\0') + break; + *dest++ = c; + } + + dest[0] = 2; + dest[1] = 0xf; // White text color + dest[2] = '\0'; + sub_08056FBC(&gTextRender); + gTextRender.curToken._c = &gUnk_08107BE0; + gTextRender._50.unk8 = gTextGfxBuffer; + gTextRender._50.unk4 = 0xd0; + SetDoTextBox(2); + MsgChangeLine(0); + StatusUpdate(MSG_UPDATE); + return 1; +} +END_NONMATCH + +static u32 MsgOpen(void) { + if (gTextRender.renderStatus == RENDER_INIT) { + gTextRender.renderStatus = RENDER_UPDATE; + gTextRender._98.bytes.b1 = 1; + sub_08056F88(gTextRender.message.unk3, gTextRender._50.unk3); + SoundReq(SFX_TEXTBOX_OPEN); + } + + if (ChangeWindowSize(1)) { + gTextRender._98.bytes.b1 = 2; + StatusUpdate(MSG_UPDATE); + } + return 0; +} + +static u32 MsgClose(void) { + if (gTextRender.renderStatus == RENDER_INIT) { + gTextRender.renderStatus = RENDER_UPDATE; + gTextRender._98.bytes.b1 = 3; + MsgChangeLine(0); + SoundReq(SFX_TEXTBOX_CLOSE); + } + + if (ChangeWindowSize(-1)) { + gTextRender._98.bytes.b1 = 0; + StatusUpdate(MSG_UPDATE); + } + return 0; +} + +static u32 MsgDie(void) { + SetDoTextBox(0); + StatusUpdate(MSG_IDLE); + return 0; +} + +static u32 MsgUpdate(void) { + static const TextRenderFunction gTextDispFunctions[] = { + [RENDER_INIT] = TextDispInit, [RENDER_UPDATE] = TextDispUpdate, [RENDER_DIE] = TextDispDie, + [RENDER_WAIT] = TextDispWait, [RENDER_ROLL] = TextDispRoll, [RENDER_ENQUIRY] = TextDispEnquiry, + }; + + SetDoTextBox(4); + gTextDispFunctions[gTextRender.renderStatus](&gTextRender); + ChangeWindowSize(0); + return 0; +} + +static void TextDispInit(TextRender* this) { + if ((gTextRender.curToken.flags & 1) == 0) { + if (gTextRender._98.bytes.b1 == 0) { + StatusUpdate(MSG_DIE); + } + } else { + this->renderStatus = RENDER_UPDATE; + } +} + +static void TextDispUpdate(TextRender* this) { + static const u8 speeds[] = { 5, 3, 1 }; + u32 speedModifier; + s32 numCharsToRead, pxDrawn; + + if (this->delay != 0) { + this->delay--; + return; + } + + if ((gInput.heldKeys & B_BUTTON) != 0) { + speedModifier = 8; + } else { + speedModifier = 1; + } + this->typeSpeed -= speedModifier; + + if (this->typeSpeed > 0) { + return; + } + + numCharsToRead = 0; + do { + numCharsToRead++; + this->typeSpeed += speeds[this->message.textSpeed]; + } while (this->typeSpeed <= 0); + + pxDrawn = 0; + do { + u32 pxCnt = RunTextCommand(this); + if (pxCnt == 0 || this->delay != 0 || this->newlineDelay != 0) + break; + pxDrawn += pxCnt; + numCharsToRead--; + } while (0 < numCharsToRead); + + if (pxDrawn != 0) { + gTextRender.updateDraw = 1; + } else { + this->typeSpeed = 0; + } +} + +NONMATCH("asm/non_matching/textbox/sub_08056750.inc", static u16 RunTextCommand(TextRender* this)) { + s32 palette; + u32 chr = this->curToken.extended; + + if (chr == 0) { + s32 r1; + chr = GetCharacter(&this->curToken); + switch (chr) { + case 0: + if (gUnk_02000040.unk_00 == 1) { + this->renderStatus = RENDER_ENQUIRY; + SwitchChoice(0, 0); + } else { + this->renderStatus = RENDER_DIE; + } + break; + case 1: + this->newlineDelay = 2; + if (this->_98.bytes.lineNo == 0) { + MsgChangeLine(1); + } else { + this->renderStatus = RENDER_WAIT; + } + break; + case 2: + StatusUpdate(MSG_OPEN); + break; + case 3: + StatusUpdate(MSG_CLOSE); + break; + case 4: + this->_50.unk6 += (this->_50.unk4 - this->_50.unk6 - GetFontStrWith(&this->curToken.flags, 0)) / 2; + break; + case 5: + gMessage.unk = this->curToken.param; + break; + case 6: + WriteBit(&gMessage.field_0xc, this->curToken.param & 0x1f); + break; + case 7: + switch (this->curToken.param) { + case 0xe: + this->_91 = this->_8f; + palette = 2; + break; + case 0xf: + palette = this->_91; + break; + default: + palette = this->curToken.param; + break; + } + this->_90 = 0; + PaletteChange(this, palette); + break; + case 8: + SoundReq(this->curToken.param); + break; + case 9: + gTextRender.message.unk3 = this->curToken.param; + sub_08056F88(this->curToken.param, this->_50.unk3); + break; + case 10: + this->message.textWindowPosY = this->curToken.param; + break; + case 12: + if (gUnk_02000040.unk_00 != 1) { + MemClear(&gUnk_02000040, 4); + MemClear(&gMessageChoices, sizeof(gMessageChoices)); + gMessageChoices.unk_00 = 1; + gUnk_02000040.unk_00 = 1; + } + if (gMessageChoices.choiceCount > 3) + break; + + gMessageChoices.unk_10[gMessageChoices.choiceCount] = this->curToken._6; + gMessageChoices.unk_08[gMessageChoices.choiceCount] = this->_50.unk6; + gMessageChoices.choiceCount++; + this->_50.unk6 += 8; + break; + case 13: + switch (this->curToken.param) { + case 0xff: + this->_8e = 1; + break; + case 0xfe: + this->_8e = 2; + break; + default: + this->delay = this->curToken.param; + break; + } + break; + case 14: + r1 = this->curToken.param; + this->_94 = r1; + break; + default: + break; + } + if (chr >> 8 == 0) + return 0; + } + if (gTextRender._98.bytes.b1 != 2) { + StatusUpdate(MSG_OPEN); + return 0; + } + if (gMessage.unk == 0) { + gMessage.unk = 0x80; + } + this->curToken.extended = '\0'; + if (chr >> 8 == 7) { + this->_90 = this->_8f | 0x80; + PaletteChange(this, 0); + } else { + if ((this->_90 & 0x80) != 0) { + palette = this->_90; + this->_90 = 0; + PaletteChange(this, palette); + } + } + return sub_0805F7DC(chr, &this->_50.unk0); +} +END_NONMATCH + +static void PaletteChange(TextRender* this, u32 id) { + u32 temp = id % 8; + this->_8f = temp; + this->_50.unk2 = temp; +} + +const u8 gUnk_08107C0F[] = { 0x8, 0x1e, 0x4, 0x12, 0x0 }; +const u8 gUnk_08107C14[] = { 0x8, 0x1e, 0x8, 0xFE, 0x0 }; + +#ifdef EU +ASM_FUNC("asm/non_matching/eu/TextBoxHandlerQuestion.inc", static void TextDispEnquiry(TextRender* ctb)) +#else + +static void TextDispEnquiry(TextRender* this) { + s32 nextTextIdx, choiceIdx, lastChoice; + u32 doSwitch; + const u8* src; + + choiceIdx = gMessageChoices.currentChoice; + switch (gInput.newKeys) { + case START_BUTTON: + case A_BUTTON: + nextTextIdx = gMessageChoices.unk_10[choiceIdx]; + if (nextTextIdx == 0) { + src = gUnk_08107C14; + } else { + this->message.textIndex = nextTextIdx; + sub_0805EEB4(&this->curToken, nextTextIdx); + src = gUnk_08107C0F; + } + sub_0805EF40(&this->curToken, src); + gUnk_02000040.unk_01 = gMessageChoices.currentChoice; + gUnk_02000040.unk_00 = 3; + MemClear(&gMessageChoices, sizeof(gMessageChoices)); + SoundReq(SFX_TEXTBOX_SELECT); + this->renderStatus = RENDER_UPDATE; + break; + case DPAD_LEFT: + choiceIdx--; + break; + case DPAD_RIGHT: + choiceIdx++; + break; + default: + break; + } + choiceIdx = (choiceIdx + gMessageChoices.choiceCount) % gMessageChoices.choiceCount; + lastChoice = gMessageChoices.currentChoice; + if (choiceIdx != lastChoice) { + gMessageChoices.currentChoice = choiceIdx; + SoundReq(SFX_TEXTBOX_CHOICE); + doSwitch = 1; + } else { + doSwitch = 0; + } + if (gUnk_02000040.unk_00 == 1) { + gMessageChoices.unk_00 = gUnk_02000040.unk_00 = 2; + doSwitch = 1; + } + if (doSwitch) { + SwitchChoice(choiceIdx, lastChoice); + } +} + +static void SwitchChoice(u32 to, u32 from) { + u16 t; + t = gTextRender._50.unk6; + gTextRender._50.unk6 = gMessageChoices.unk_08[from]; + sub_0805F8E4(0, &gTextRender._50); + gTextRender._50.unk6 = gMessageChoices.unk_08[to]; + sub_0805F8E4(1, &gTextRender._50); + gTextRender._50.unk6 = t; + gTextRender.updateDraw = 1; +} + +#endif + +static void TextDispWait(TextRender* this) { + gMessage.unk = 0; + if (this->_94 != 0) { + if (--this->_94 == 0) { + this->renderStatus = RENDER_ROLL; + } + } else if (MESSAGE_PRESS_ANY_ADVANCE_KEYS) { + SoundReq(SFX_TEXTBOX_SWAP); + this->_98.bytes.b2 = 0; + this->renderStatus = RENDER_ROLL; + } else { + this->_98.bytes.b2++; + } +} + +static void TextDispRoll(TextRender* this) { + MsgChangeLine(0); + PaletteChange(this, this->_8f | 0x40); + this->renderStatus = RENDER_UPDATE; +} + +static void TextDispDie(TextRender* this) { + gMessage.unk = 0; + SetDoTextBox(7); + if ((this->_8e != 1) && (this->_8e == 2 || MESSAGE_PRESS_ANY_ADVANCE_KEYS)) { + StatusUpdate(MSG_CLOSE); + } +} + +static void MsgChangeLine(u32 lineNo) { + gTextRender._98.bytes.lineNo = lineNo; + if (lineNo == 0) { + MemFill32(0xFFFFFFFF, gTextGfxBuffer, sizeof(gTextGfxBuffer)); + DrawCanvasLine(); + gTextRender.beginTiles[0] = (MESSAGE_PALETTE << 12) | MSG_TEXT_LINE1TOP; + gTextRender.beginTiles[1] = (MESSAGE_PALETTE << 12) | MSG_TEXT_LINE1BOTTOM; + gTextRender.beginTiles[2] = (MESSAGE_PALETTE << 12) | MSG_TEXT_LINE2TOP; + gTextRender.beginTiles[3] = (MESSAGE_PALETTE << 12) | MSG_TEXT_LINE2BOTTOM; + gTextRender._50.unk6 = 0; + gTextRender._50.unk4 = 0xd0; + } else { + gTextRender._50.unk6 = 0xd0; + gTextRender._50.unk4 = 0x1a0; + } + PaletteChange(&gTextRender, gTextRender._8f | 0x40); +} + +static void SetDoTextBox(u32 doTextbox) { + gMessage.doTextBox = gTextRender.message.doTextBox = doTextbox; +} + +static void DeleteWindow(void) { + Window* window = &gCurrentWindow; + if (window->active) { + u16* ptr; + int i; + window->active = 0; + ptr = &gBG0Buffer[MESSAGE_POSITION_INDEX(*window)]; + i = window->height + 2; + do { + int j = 0; + do { + ptr[j] = 0; + } while (j++, j < window->width + 2); + ptr += MESSAGE_WIDTH; + i--; + } while (i > 0); + RecoverUI(window->yPos, window->height); + RefreshUI(); + } +} + +static u32 ChangeWindowSize(u32 delta) { + Window* window; + u32 result = 0; + + gTextRender._98.bytes.sizeScale += delta; + + if (gTextRender._98.bytes.sizeScale < 1) { + gTextRender._98.bytes.sizeScale = 0; + result = 1; + } else if (gTextRender._98.bytes.sizeScale >= 8) { + gTextRender._98.bytes.sizeScale = 8; + result = 1; + } + + window = &gNewWindow; + if (gTextRender._98.bytes.sizeScale != 0) { + u32 scale = gTextRender._98.bytes.sizeScale; + window->width = (scale * (gTextRender.message.textWindowWidth << 1)) / 16; + if ((window->width & 1) != 0) { + window->width++; + } + window->xPos = + ((gTextRender.message.textWindowWidth / 2) + gTextRender.message.textWindowPosX) - (window->width / 2); + + window->height = (scale * (gTextRender.message.textWindowHeight << 1)) / 16; + if ((window->height & 1) != 0) { + window->height++; + } + window->yPos = + ((gTextRender.message.textWindowHeight / 2) + gTextRender.message.textWindowPosY) - (window->height / 2); + } else { + window->yPos = -1; + window->xPos = -1; + window->height = -1; + window->width = -1; + } + window->active = 1; + return result; +} + +static void CreateWindow(void) { + s32 borderBeginTile; + u16* ptr; + + if (gTextRender._98.bytes.sizeScale <= 0) + return; + ptr = &gBG0Buffer[MESSAGE_POSITION_INDEX(gNewWindow)]; + borderBeginTile = (MESSAGE_PALETTE << 12) | MSG_BORDER_CORNER; + DispMessageFrame(ptr, gNewWindow.width, gNewWindow.height, borderBeginTile); + DispString(); + DispCursor(); + gCurrentWindow = gNewWindow; + RefreshUI(); +} + +// Also used by figurine menu +ASM_FUNC("asm/non_matching/textbox/DispMessageFrame.inc", + void DispMessageFrame(u16* buffer, u32 width_, u32 height_, u32 flags_)) + +extern u16 gUnk_02034CB2[]; +extern u16 gUnk_0202281E[]; + +/* + Each character is two tiles tall. + They are stored in VRAM in the following order: + + 82 84 86 --> | | |\| |/ + 83 85 87 --> |_ | | \ |\ + + b6 b8 ba --> | | | + b7 b9 bb --> . . . + + There are 2 lines of text available, and each line is 20 chars long, + So the canvas is 20x4 tiles. +*/ + +static void DispString(void) { + u32 r0, tileAttr; + u16 *buf, *line; + s32 i, w, h; + + Window* window = &gNewWindow; + + if (window->width != 0) { + if (window->height != 0) { + h = window->height; + buf = &gBG0Buffer[MESSAGE_POSITION_INDEX(*window) + 1]; + i = (4 - h) / 2; + do { + //! @bug abnormally big width causes tile idx to overwrite other tile attributes + w = window->width; + tileAttr = gTextRender.beginTiles[i]; + buf += MESSAGE_WIDTH; + r0 = i + 1; + h--; + line = buf; + do { + *line = tileAttr; + line++; + tileAttr += 2; + w--; + } while (w > 0); + i = r0; + } while (h != 0); + } + } +} + +static void DispCursor(void) { + u32 offset; + u16* ptr; + + if ((gTextRender._98.word & 0x10ff00) == 0x100200) { + ptr = &gBG0Buffer[MESSAGE_POSITION_INDEX(gNewWindow)]; + offset = (((gNewWindow.height + 1) * MESSAGE_WIDTH) - 2); + offset += gNewWindow.width; + ptr += offset; + *ptr = 0xf080; + } +} + +static void DrawCanvasLine(void) { + LoadResourceAsync(gTextGfxBuffer, 0x0600D040, sizeof(gTextGfxBuffer)); +} + +void sub_08056F88(u32 unk_1, u32 unk_2) { + u32 uVar1; + + if (0xf < unk_1) { + unk_1 = 0; + } + uVar1 = unk_1 << 4 | unk_2; + if (gTextRender._9c != uVar1) { + gTextRender._9c = uVar1; + sub_0805F918(unk_1, unk_2, 0x0600CF60); + } +} + +static void sub_08056FBC(TextRender* ctb) { + sub_08056FEC(ctb->message.field_0x10, &ctb->_66[0x2]); + sub_08056FEC(ctb->message.field_0x14, &ctb->_66[0xa]); + sub_08056FEC(ctb->message.field_0x18, &ctb->_77[0x1]); + sub_08056FEC(ctb->message.field_0x1c, &ctb->_77[0x9]); +} + +NONMATCH("asm/non_matching/textbox/sub_08056FEC.inc", u32 sub_08056FEC(u32 this, u8* param_2)) { + u32 uVar1; + int iVar2; + int iVar3; + int iVar4; + u8 local_1c[8]; + + uVar1 = sub_0801D51C(this, param_2, this); + uVar1 = uVar1 & 0xfffffff; + iVar4 = 0; + do { + local_1c[iVar4++] = uVar1 & 0xf; + uVar1 = uVar1 / 16; + } while (uVar1 != 0); + for (iVar3 = 0; --iVar4 >= 0; iVar3++) { + param_2[iVar3] = local_1c[iVar4] | 0x30; + } + param_2[iVar3] = 0; + return iVar4; +} +END_NONMATCH |
