Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
msg.c
Go to the documentation of this file.
1#include "common.h"
2#include "ld_addrs.h"
3#include "message_ids.h"
4#include "sprite.h"
5
6#include "charset/charset.h"
7#include "charset/postcard.png.h"
8#include "charset/letter_content_1.png.h"
9
17
18#ifdef SHIFT
19#define MSG_ROM_START (s32)msg_ROM_START
20#elif VERSION_JP
21#define MSG_ROM_START 0x1D40000
22#else
23#define MSG_ROM_START 0x1B83000
24#endif
25
26#if VERSION_PAL
27#define CHOICE_POINTER_MOVE_RATE 5.0
28#else
29#define CHOICE_POINTER_MOVE_RATE 6.0
30#endif
31
33
35 .vp = {
36 .vscale = {640, 480, 511, 0},
37 .vtrans = {640, 480, 511, 0},
38 }
39};
40
41#if !VERSION_JP
43
44#if VERSION_PAL
45u8 MessagePlural_de[] = { MSG_CHAR_LOWER_N, MSG_CHAR_READ_END };
46#endif
47
49#endif
50
51#if VERSION_PAL
52s32 gCurrentLanguage = 0;
53
54void* D_PAL_8014AE50[] = {
55 [LANGUAGE_EN] = msg_pal_en_ROM_START,
56 [LANGUAGE_DE] = msg_pal_de_ROM_START,
57 [LANGUAGE_FR] = msg_pal_fr_ROM_START,
58 [LANGUAGE_ES] = msg_pal_es_ROM_START,
59};
60#endif
61
63
65 {{{ -16, 9, 0 }, 0, { 0x000, 0x000 }, { 255, 255, 255, 255 }}},
66 {{{ 16, 9, 0 }, 0, { 0x400, 0x000 }, { 255, 255, 255, 255 }}},
67 {{{ -16, -9, 0 }, 0, { 0x000, 0x240 }, { 255, 255, 255, 255 }}},
68 {{{ 16, -9, 0 }, 0, { 0x400, 0x240 }, { 255, 255, 255, 255 }}},
69};
70
71Gfx D_8014C2D8[] = {
72 gsDPSetCycleType(G_CYC_2CYCLE),
73 gsSPClearGeometryMode(G_CULL_BOTH | G_LIGHTING),
74 gsSPSetGeometryMode(G_SHADE | G_SHADING_SMOOTH),
75 gsDPSetColorDither(G_CD_DISABLE),
76 gsDPSetAlphaDither(G_AD_DISABLE),
77 gsDPSetAlphaCompare(G_AC_NONE),
78 gsSPTexture(-1, -1, 0, G_TX_RENDERTILE, G_ON),
79 gsDPSetTexturePersp(G_TP_PERSP),
80 gsDPSetTextureLUT(G_TT_NONE),
81 gsDPSetTextureFilter(G_TF_AVERAGE),
82 gsDPSetRenderMode(IM_RD | CVG_DST_SAVE | ZMODE_XLU | FORCE_BL | G_RM_PASS, IM_RD | CVG_DST_SAVE | ZMODE_XLU |
83 FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
84 gsDPSetCombineMode(PM_CC_MSG_UP_ARROW, G_CC_PASS2),
85 gsSPEndDisplayList(),
86};
87
94
95static char gMessageBuffers[2][1024];
96static MessagePrintState gMessagePrinters[3];
97#if VERSION_JP
98static s32 D_80155C38;
99#endif
100static u8 gMessageMsgVars[3][32];
101static s16 D_80155C98;
102static Mtx gMessageWindowProjMatrix[2];
103
106
107extern s16 MsgStyleVerticalLineOffsets[];
108
111extern IMG_BIN ui_msg_star_png[];
113
114extern IMG_BIN MsgCharImgTitle[];
116extern MessageCharset* MsgCharsets[5];
118extern PAL_BIN D_802F4560[80][8];
119#if VERSION_JP
120extern IMG_BIN MsgCharImgKana[];
121extern IMG_BIN MsgCharImgLatin[];
124#endif
125
128
130#if VERSION_JP
131 {
132 .rasters = &MsgCharImgKana[0x4910],
133 .texSize = 112,
134 .texWidth = 16,
135 .texHeight = 14,
136 .digitWidth = {11, 8, 11, 11, 11, 11, 11, 11, 11, 11},
137 .fixedWidth = 11
138 }, {
139 .rasters = &MsgCharImgMenuKana[0x2EF8],
140 .texSize = 72,
141 .texWidth = 12,
142 .texHeight = 12,
143 .digitWidth = {9, 8, 9, 9, 9, 9, 9, 9, 9, 9},
144 .fixedWidth = 9
145 }
146#else
147 {
148 .rasters = &MsgCharImgNormal[0x800],
149 .texSize = 128,
150 .texWidth = 16,
151 .texHeight = 16,
152 .digitWidth = {11, 8, 11, 11, 11, 11, 11, 11, 11, 11},
153 .fixedWidth = 11
154 }, {
155 .rasters = &MsgCharImgNormal[0x800],
156 .texSize = 128,
157 .texWidth = 16,
158 .texHeight = 16,
159 .digitWidth = {9, 8, 9, 9, 9, 9, 9, 9, 9, 9},
160 .fixedWidth = 9
161 }
162#endif
163};
164
166 gsDPPipeSync(),
167 gsDPSetCycleType(G_CYC_1CYCLE),
168 gsDPSetTextureFilter(G_TF_POINT),
169 gsDPSetTexturePersp(G_TP_NONE),
170 gsDPSetColorDither(G_CD_DISABLE),
171 gsDPSetAlphaDither(G_AD_DISABLE),
172 gsDPSetCombineKey(G_CK_NONE),
173 gsDPSetAlphaCompare(G_AC_NONE),
174 gsDPSetTextureLUT(G_TT_RGBA16),
175 gsSPTexture(-1, -1, 0, G_TX_RENDERTILE, G_ON),
176 gsSPEndDisplayList(),
177};
178
179s32 draw_image_with_clipping(IMG_PTR raster, s32 width, s32 height, s32 fmt, s32 bitDepth, s16 posX, s16 posY, u16 clipULx,
180 u16 clipULy, u16 clipLRx, u16 clipRLy);
181
183void msg_copy_to_print_buffer(MessagePrintState* printer, s32 arg1, s32 arg2);
184void initialize_printer(MessagePrintState* printer, s32 arg1, s32 arg2);
185MessagePrintState* _msg_get_printer_for_msg(s32 msgID, s32* donePrintingWriteback, s32 arg2);
187void msg_draw_rewind_arrow(s32);
190void appendGfx_message(MessagePrintState*, s16, s16, u16, u16, u16, u8);
191
193 D_80155C98 = -1;
194}
195
196void clear_printers(void) {
197 s32 i;
198
199 for (i = 0; i < ARRAY_COUNT(gMessagePrinters); i++) {
200 initialize_printer(&gMessagePrinters[i], 0, 0);
201 }
202
205
206 for (i = 0; i < ARRAY_COUNT(gMessageMsgVars); i++) {
207 gMessageMsgVars[i][0] = 0;
208 }
209
210 D_80151338 = nullptr;
212 load_font(0);
213}
214
215#if VERSION_IQUE
216void load_font_data(Addr offset, u32 size, void* dest) {
217#else
218void load_font_data(Addr offset, u16 size, void* dest) {
219#endif
220 u8* base = charset_ROM_START + (s32) offset;
221
222 dma_copy(base, base + size, dest);
223}
224
225void load_font(s32 font) {
226 if (font != D_80155C98) {
227 if (font == 0) {
228#if VERSION_JP
229 load_font_data(charset_kana_OFFSET, 0x5710, MsgCharImgKana);
230 load_font_data(charset_latin_OFFSET, 0xBD0, MsgCharImgLatin);
231 load_font_data(charset_kanji_OFFSET, 0x34F0, MsgCharImgTitle); // huh
232 load_font_data(charset_buttons_OFFSET, 0x460, MsgCharImgSubtitle); // what
233 load_font_data(charset_menu_kana_OFFSET, 0x37F8, MsgCharImgMenuKana);
234 load_font_data(charset_menu_latin_OFFSET, 0x798, MsgCharImgMenuLatin);
235#else
237#endif
239
240 // fix outline color after loading
241 for (s32 i = 0; i < 80; i++) {
242 // set the transparent color to the outline color but with alpha = 0
243 D_802F4560[i][0] = D_802F4560[i][6] & ~1;
244 }
245 } else if (font == 1) {
249 }
250 }
251}
252
253void update_messages(void) {
254 s32 i;
255
257 if (gMsgGlobalWaveCounter >= 360) {
259 }
260
261 for (i = 0; i < ARRAY_COUNT(gMessagePrinters); i++) {
262 if (gMessagePrinters[i].stateFlags & MSG_STATE_FLAG_2) {
263 _update_message(&gMessagePrinters[i]);
264 }
265 }
266
267 gMsgBGScrollAmtX += 12;
268 gMsgBGScrollAmtY -= 12;
269 if (gMsgBGScrollAmtX >= 2048) {
270 gMsgBGScrollAmtX -= 2048;
271 }
272 if (gMsgBGScrollAmtY < 0) {
273 gMsgBGScrollAmtY += 2048;
274 }
275}
276
278 f32 speechPan;
279 u8 cond;
280 s16 endPosDist;
281 s16 lineIncAmt;
282 s32 charsToPrint;
283 s32 i;
284
285 printer->effectFrameCounter++;
286 if (printer->effectFrameCounter >= 3600) {
287 printer->effectFrameCounter = 0;
288 }
289
290 speechPan = (((f32)printer->initOpenPos.x - (SCREEN_WIDTH / 2.0)) / 3.8) + 64.0;
291 if (speechPan < 5.0) {
292 speechPan = 5.0f;
293 } else if (speechPan > 122.0) {
294 speechPan = 122.0f;
295 }
296 printer->speechPan = speechPan;
297
298 cond = false;
299 if (!(printer->stateFlags & MSG_STATE_FLAG_40)) {
300 if (!(printer->stateFlags & (MSG_STATE_FLAG_20 | MSG_STATE_FLAG_10))) {
301 s32 buttons = BUTTON_A;
302
303 switch (printer->windowState) {
305 if (printer->stateFlags & MSG_STATE_FLAG_80000) {
306 buttons = BUTTON_A | BUTTON_C_DOWN;
307 }
308 if ((buttons & gGameStatusPtr->pressedButtons[0]) || (gGameStatusPtr->curButtons[0] & BUTTON_B)) {
310 printer->curPrintDelay = 0;
311 printer->stateFlags |= MSG_STATE_FLAG_4;
313 cond = true;
315 } else if (printer->srcBuffer[printer->srcBufferPos] != MSG_CHAR_READ_END) {
317 if (printer->fontVariant != 0 || printer->srcBuffer[printer->srcBufferPos] != MSG_CHAR_UNK_C3) {
319 }
321 } else if (printer->style == MSG_STYLE_RIGHT ||
322 printer->style == MSG_STYLE_LEFT ||
323 printer->style == MSG_STYLE_CENTER ||
324 printer->style == MSG_STYLE_TATTLE)
325 {
327 }
328 } else if ((gGameStatusPtr->pressedButtons[0] & BUTTON_Z) &&
329 !(printer->stateFlags & MSG_STATE_FLAG_40000) &&
330 (printer->curLine != 0))
331 {
333 printer->unk_4CC = 0;
334 printer->unkArraySize = printer->curLine - 1;
335 printer->unk_4C8 = abs(printer->curLinePos - printer->lineEndPos[printer->unkArraySize]);
337 }
338 break;
342 printer->unk_4CC = 0;
343 printer->unkArraySize = printer->curLine;
344 printer->unk_4C8 = abs(printer->curLinePos - printer->lineEndPos[printer->unkArraySize]);
346 } else if (gGameStatusPtr->pressedButtons[0] & BUTTON_Z) {
347 if (printer->unkArraySize > 0) {
349 printer->unk_4CC = 0;
350 printer->unkArraySize--;
351 printer->unk_4C8 = abs(printer->curLinePos - printer->lineEndPos[printer->unkArraySize]);
353 }
354 } else {
357 printer->unk_4CC = 0;
358 printer->unkArraySize++;
359 printer->unk_4C8 = abs(printer->curLinePos - printer->lineEndPos[printer->unkArraySize]);
361 }
362 }
363 break;
366 printer->madeChoice = 1;
368 printer->scrollingTime = 0;
371 } else if (printer->cancelOption != 0xFF && (gGameStatusPtr->pressedButtons[0] & BUTTON_B)) {
372 if (printer->cancelOption >= printer->maxOption) {
373 printer->selectedOption = printer->curOption;
374 } else {
375 printer->selectedOption = printer->cancelOption;
376 }
377 printer->madeChoice = 1;
379 printer->scrollingTime = 0;
380 printer->curOption = printer->cancelOption;
384 if (printer->curOption != printer->maxOption - 1) {
385 printer->targetOption = printer->curOption + 1;
387 printer->scrollingTime = 1;
389 }
390 } else if (gGameStatusPtr->heldButtons[0] & BUTTON_STICK_UP) {
391 if (printer->curOption != 0) {
392 printer->targetOption = printer->curOption - 1;
394 printer->scrollingTime = 1;
396 }
397 }
398
400 break;
401 }
403 printer->scrollingTime++;
404 if (printer->scrollingTime >= (s32)(5 * DT)) {
406 printer->curOption = printer->targetOption;
407 printer->selectedOption = printer->curOption;
408 }
409 break;
410 }
411 } else if (!(printer->stateFlags & MSG_STATE_FLAG_20) &&
414 {
416 printer->curPrintDelay = 0;
417 printer->stateFlags |= MSG_STATE_FLAG_4;
418 }
419
420 if (printer->stateFlags & MSG_STATE_FLAG_4 && !(gGameStatusPtr->curButtons[0] & BUTTON_A)) {
421 printer->stateFlags &= ~MSG_STATE_FLAG_4;
422 }
423
424 for (i = 0; i < ARRAY_COUNT(printer->animTimers); i++) {
425 if (printer->animTimers[i] > 0) {
426 printer->animTimers[i]--;
427 }
428 }
429
430 switch (printer->windowState) {
433 if (!(printer->stateFlags & (MSG_STATE_FLAG_20 | MSG_STATE_FLAG_10)) && !cond) {
435
436 }
437 }
438 // fallthrough
440 charsToPrint = printer->charsPerChunk;
441 if (printer->windowState == MSG_WINDOW_STATE_INIT) {
443 printer->curPrintDelay = 0;
444 } else if (printer->stateFlags & MSG_STATE_FLAG_PRINT_QUICKLY) {
445 charsToPrint = 12;
446 printer->curPrintDelay = 0;
447 } else if (!(printer->stateFlags & MSG_STATE_FLAG_4)) {
448 if (!(printer->stateFlags & (MSG_STATE_FLAG_20 | MSG_STATE_FLAG_10)) &&
450 {
451 charsToPrint = 6;
452 printer->curPrintDelay = 0;
453 }
454 }
455 if ((printer->curPrintDelay == 0) || --printer->curPrintDelay == 0) {
456 msg_copy_to_print_buffer(printer, charsToPrint, 0);
457 }
458 break;
461 if (!(printer->stateFlags & (MSG_STATE_FLAG_20 | MSG_STATE_FLAG_10))) {
463 }
464 }
465 printer->curLinePos += printer->windowScrollRate;
466 if ((printer->stateFlags & MSG_STATE_FLAG_PRINT_QUICKLY) ||
467 (!(printer->stateFlags & (MSG_STATE_FLAG_10 | MSG_STATE_FLAG_4)) &&
469 {
470 printer->curLinePos += (s32)(6 / DT);
471 }
472
473 if (printer->curLinePos >= printer->nextLinePos) {
475 printer->curLinePos = printer->nextLinePos;
476 printer->stateFlags |= MSG_STATE_FLAG_4;
477
478 if (printer->style == MSG_STYLE_SIGN ||
479 printer->style == MSG_STYLE_LAMPPOST ||
480 printer->srcBuffer[printer->srcBufferPos] == MSG_CHAR_READ_WAIT)
481 {
482 printer->curPrintDelay = 0;
483 } else {
484 printer->curPrintDelay = 5;
485 }
486 printer->lineEndPos[printer->curLine] = printer->curLinePos;
487 }
488 break;
490 printer->unk_4CC++;
491 endPosDist = abs(printer->curLinePos - printer->lineEndPos[printer->unkArraySize]);
492 lineIncAmt = 2;
493
494 if (printer->unk_4C8 <= 16) {
495 if (endPosDist >= 15) {
496 lineIncAmt = 4;
497 } else if (endPosDist >= 9) {
498 lineIncAmt = 3;
499 }
500 } else if (endPosDist > 96) {
501 lineIncAmt = 10;
502 } else if (endPosDist > 48) {
503 lineIncAmt = 9;
504 } else if (endPosDist >= 24) {
505 lineIncAmt = 7;
506 } else if (endPosDist >= 16) {
507 lineIncAmt = 5;
508 } else if (endPosDist >= 8) {
509 lineIncAmt = 4;
510 } else if (endPosDist > 4) {
511 lineIncAmt = 3;
512 }
513
514 printer->unk_4CA = lineIncAmt;
515
516 if (printer->lineEndPos[printer->unkArraySize] < printer->curLinePos) {
517 printer->curLinePos -= printer->unk_4CA;
518 if (printer->lineEndPos[printer->unkArraySize] >= printer->curLinePos) {
519 printer->curLinePos = printer->lineEndPos[printer->unkArraySize];
521 }
522 } else {
523 printer->curLinePos += printer->unk_4CA;
524 if (printer->curLinePos >= printer->lineEndPos[printer->unkArraySize]) {
525 printer->curLinePos = printer->lineEndPos[printer->unkArraySize];
527 if (printer->unkArraySize == printer->curLine) {
530 printer->rewindArrowCounter = 0;
531 }
532 }
533 }
534 break;
545 break;
546 }
547 }
548
549 if (printer->stateFlags & MSG_STATE_FLAG_1) {
551 printer->stateFlags = 0;
552 if (printer->letterBackgroundImg != nullptr) {
554 }
555 if (printer->letterBackgroundPal != nullptr) {
557 }
558 if (printer->letterContentImg != nullptr) {
560 }
561 if (printer->letterContentPal != nullptr) {
563 }
564 if (printer->closedWritebackBool != nullptr) {
565 *printer->closedWritebackBool = true;
566 printer->closedWritebackBool = nullptr;
567 }
568 }
569
570 return printer->windowState;
571}
572
573void render_messages(void) {
574 Mtx* matrix = &gMessageWindowProjMatrix[gCurrentDisplayContextIndex];
575 s32 i;
576
577 for (i = 0; i < ARRAY_COUNT(gMessagePrinters); i++) {
578 if (gMessagePrinters[i].stateFlags & MSG_STATE_FLAG_2) {
579 gSPViewport(gMainGfxPos++, &D_8014C280);
580 guOrtho(matrix, 0.0f, 319.0f, -240.0f, 0.0f, -500.0f, 500.0f, 1.0f);
581 gSPMatrix(gMainGfxPos++, OS_K0_TO_PHYSICAL(matrix), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
582 gDPPipeSync(gMainGfxPos++);
583 gDPSetCycleType(gMainGfxPos++, G_CYC_1CYCLE);
584 gSPClearGeometryMode(gMainGfxPos++, G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
585 G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH);
586 gSPSetGeometryMode(gMainGfxPos++, G_SHADE | G_SHADING_SMOOTH);
587 break;
588 }
589 }
590
591 for (i = 0; i < ARRAY_COUNT(gMessagePrinters); i++) {
592 if (gMessagePrinters[i].stateFlags & MSG_STATE_FLAG_2) {
593 draw_message_window(&gMessagePrinters[i]);
594
595 if (gMessagePrinters[i].windowState == MSG_WINDOW_STATE_WAITING) {
596 if (!(gMessagePrinters[i].stateFlags & MSG_STATE_FLAG_8000) &&
597 !(gMessagePrinters[i].stateFlags & MSG_STATE_FLAG_40))
598 {
600 }
601 } else if (gMessagePrinters[i].windowState == MSG_WINDOW_STATE_C) {
603 } else if (gMessagePrinters[i].windowState == MSG_WINDOW_STATE_WAITING_FOR_CHOICE ||
604 gMessagePrinters[i].windowState == MSG_WINDOW_STATE_SCROLLING_BACK ||
605 gMessagePrinters[i].stateFlags & MSG_STATE_FLAG_10000 ||
606 gMessagePrinters[i].stateFlags & MSG_STATE_FLAG_20000)
607 {
608 msg_draw_choice_pointer(&gMessagePrinters[i]);
609 }
610 }
611 }
612}
613
614void msg_play_speech_sound(MessagePrintState* printer, u8 character) {
615 f32 volTemp;
616 s16 volume;
617 s32 pitchShift;
618 s32 flag = 1;
619 s32 baseShift = 100;
620
621 if (printer->stateFlags & MSG_STATE_FLAG_800000 && !(printer->delayFlags & (MSG_DELAY_FLAG_2 | MSG_DELAY_FLAG_4)) && printer->volume != 0) {
622 volTemp = (f32)printer->volume / 100.0;
623 pitchShift = ((character % 20) * 10) + (printer->speechPitchShift - baseShift);
624 volume = ((rand_int(15) + 78) * volTemp);
625
626 if (volume > 255) {
627 volume = 255;
628 }
629
630 if (character & flag) {
631 sfx_play_sound_with_params(printer->speechSoundIDA, volume, printer->speechPan, pitchShift);
632 } else {
633 sfx_play_sound_with_params(printer->speechSoundIDB, volume, printer->speechPan, pitchShift);
634 }
635 }
636}
637
638extern s32 gItemIconRasterOffsets[];
639extern s32 gItemIconPaletteOffsets[];
642extern MsgVoice MsgVoices[];
643
644#if VERSION_PAL
645INCLUDE_ASM(s32, "msg", msg_copy_to_print_buffer);
646#else
647void msg_copy_to_print_buffer(MessagePrintState* printer, s32 arg1, s32 arg2) {
648 u8 arg;
649 u8 argQ;
650 u8 argW;
651 u8 argE;
652 u8 sp10[4];
653 s16 offset;
654 s32 i;
655 u8* romAddr;
656 u8* romEnd;
657 void* a2;
658 s8 s8 = arg2 & 1;
659 u8* printBuf = &printer->printBuffer[printer->printBufferPos];
660 u8* srcBuf = &printer->srcBuffer[printer->srcBufferPos];
661
662 do {
663 u8 c = *srcBuf++; // a1
664 u8 nextArg = *srcBuf; // a2
665 switch (c) {
667 *printBuf++ = MSG_CHAR_PRINT_ENDL;
668 printer->lineCount += (u8)printer->sizeScale;
669 break;
672 printer->delayFlags |= MSG_DELAY_FLAG_1;
673 printer->delayFlags &= ~MSG_DELAY_FLAG_2;
675 printer->rewindArrowCounter = 0;
676 printer->stateFlags &= ~MSG_STATE_FLAG_SPEAKING;
677 printer->stateFlags &= ~MSG_STATE_FLAG_PRINT_QUICKLY;
678 if (printer->style != MSG_STYLE_F) {
680 }
681 break;
683 printer->curPrintDelay = *srcBuf++;
684 printer->delayFlags |= MSG_DELAY_FLAG_1;
685 printer->stateFlags &= ~MSG_STATE_FLAG_SPEAKING;
686 break;
692 printer->fontVariant = c + 13;
693 break;
695 *printBuf++ = MSG_CHAR_PRINT_SPACE;
696 break;
698 *printBuf++ = MSG_CHAR_PRINT_FULL_SPACE;
699 break;
701 *printBuf++ = MSG_CHAR_PRINT_HALF_SPACE;
702 break;
704 *printBuf++ = MSG_CHAR_PRINT_UNK_CHAR_FA;
705 arg1--;
706 break;
708 if (printer->lineCount != 0) {
709 printer->lineEndPos[printer->curLine] = printer->curLinePos;
710 printer->curLine++;
711 *printBuf++ = MSG_CHAR_PRINT_NEXT;
712 printer->nextLinePos = printer->curLinePos + (MsgCharsets[printer->font]->newLineY
713#if !VERSION_JP
715#endif
716 ) * printer->lineCount;
718 printer->delayFlags |= MSG_DELAY_FLAG_1;
719 }
720 printer->lineCount = 0;
721 break;
723 *printBuf++ = MSG_CHAR_PRINT_STYLE;
724 arg = *srcBuf++;
725 printer->style = arg;
726 *printBuf++ = arg;
727 printer->fadeInCounter = 0;
728 switch (arg) {
729 case MSG_STYLE_RIGHT:
730 case MSG_STYLE_LEFT:
731 case MSG_STYLE_CENTER:
732 case MSG_STYLE_TATTLE:
733 if (arg == MSG_STYLE_RIGHT || arg == MSG_STYLE_LEFT || arg == MSG_STYLE_CENTER) {
734 printer->maxLinesPerPage = 3;
735 }
736 printer->delayFlags |= MSG_DELAY_FLAG_1;
738 if (nextArg != MSG_CHAR_UNK_C3) {
740 }
744 break;
745 case MSG_STYLE_CHOICE:
746 printer->windowBasePos.x = *srcBuf++;
747 printer->windowBasePos.y = *srcBuf++;
748 printer->windowSize.x = *srcBuf++;
749 printer->windowSize.y = *srcBuf++;
751 printer->stateFlags |= MSG_STATE_FLAG_800;
752 break;
755 case MSG_STYLE_F:
756 if (!s8) {
757#if VERSION_JP
758 printer->windowBasePos.x = 40;
759#else
760 printer->windowBasePos.x = 20;
761#endif
762 printer->windowBasePos.y = 28;
763 printer->windowSize.y = 58;
764#if VERSION_JP
765 printer->windowSize.x = 240;
766#else
767 printer->windowSize.x = 280;
768#endif
770 printer->stateFlags |= MSG_STATE_FLAG_800;
771 printer->delayFlags |= MSG_DELAY_FLAG_1;
772 if (arg == MSG_STYLE_INSPECT) {
774 }
775 }
776 break;
778 printer->windowBasePos.x = *srcBuf++;
779 printer->windowBasePos.y = *srcBuf++;
780 printer->windowSize.x = *srcBuf++;
781 printer->windowSize.y = *srcBuf++;
784 printer->delayFlags |= MSG_DELAY_FLAG_1;
785 printer->stateFlags |= MSG_STATE_FLAG_800;
786 break;
788 printer->windowSize.y = *srcBuf++;
789 // fallthrough
790 case MSG_STYLE_SIGN:
791 if (!s8) {
793 printer->stateFlags |= MSG_STATE_FLAG_800;
794 printer->delayFlags |= MSG_DELAY_FLAG_1;
795 }
796 break;
798 arg = *srcBuf++;
800 printer->stateFlags |= MSG_STATE_FLAG_800;
801 printer->delayFlags |= MSG_DELAY_FLAG_1;
802 printer->letterBackgroundImg = heap_malloc(((charset_postcard_png_width * charset_postcard_png_height) / 2));
803 romAddr = charset_ROM_START + (s32)charset_postcard_OFFSET;
804 dma_copy(romAddr, romAddr + ((charset_postcard_png_width * charset_postcard_png_height) / 2), printer->letterBackgroundImg);
805 printer->letterBackgroundPal = heap_malloc(0x20);
806 romAddr = charset_ROM_START + (s32)charset_postcard_pal_OFFSET;
807 dma_copy(romAddr, romAddr + 0x20, printer->letterBackgroundPal);
808 printer->letterContentImg = heap_malloc(charset_letter_content_1_png_width * charset_letter_content_1_png_height);
809 romAddr = charset_ROM_START + (s32) MsgLetterRasterOffsets[arg];
810 dma_copy(romAddr, romAddr + (charset_letter_content_1_png_width * charset_letter_content_1_png_height), printer->letterContentImg);
811 printer->letterContentPal = heap_malloc(0x200);
812 romAddr = charset_ROM_START + (s32) MsgLetterPaletteOffsets[arg];
813 dma_copy(romAddr, romAddr + 0x200, printer->letterContentPal);
814 break;
815 case MSG_STYLE_POPUP:
816 case MSG_STYLE_B:
817 printer->windowSize.x = printer->msgWidth + 32;
818#if VERSION_JP
819 printer->windowSize.y = 32;
820#else
821 printer->windowSize.y = 40;
822#endif
824 if (!s8) {
827 printer->delayFlags |= MSG_DELAY_FLAG_1;
828 }
829 break;
832 break;
833 }
834 if ((printer->delayFlags & MSG_DELAY_FLAG_1) && (printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2))) {
835 printer->delayFlags &= ~MSG_DELAY_FLAG_1;
836 }
837 break;
839 *printBuf++ = MSG_CHAR_PRINT_END;
840 if (printer->stateFlags & MSG_STATE_FLAG_800) {
841 if (printer->stateFlags & MSG_STATE_FLAG_1000) {
842 if (printer->closedWritebackBool != nullptr) {
843 *printer->closedWritebackBool = true;
844 }
845 }
846 if (printer->style != MSG_STYLE_POPUP && printer->style != MSG_STYLE_B) {
848 } else {
850 }
851 printer->fadeOutCounter = 0;
852 } else {
853 printer->stateFlags |= MSG_STATE_FLAG_1;
854 }
855 printer->delayFlags |= MSG_DELAY_FLAG_1;
856 printer->delayFlags &= ~MSG_DELAY_FLAG_2;
857 break;
859 switch (*srcBuf++) {
861 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
862 *printBuf++ = MSG_PRINT_FUNC_FONT;
863 *printBuf++ = printer->font = *srcBuf++;
864 break;
866 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
867 *printBuf++ = MSG_PRINT_FUNC_VARIANT;
868 *printBuf++ = printer->fontVariant = *srcBuf++;
869 break;
871 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
872 *printBuf++ = MSG_PRINT_FUNC_COLOR;
873 *printBuf++ = *srcBuf++;
874 break;
876 printer->stateFlags |= MSG_STATE_FLAG_10;
877 break;
879 printer->stateFlags |= MSG_STATE_FLAG_20;
880 printer->stateFlags &= ~MSG_STATE_FLAG_PRINT_QUICKLY;
881 break;
883 printer->stateFlags &= ~MSG_STATE_FLAG_20;
884 break;
886 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
887 *printBuf++ = MSG_PRINT_FUNC_SPACING;
888 *printBuf++ = *srcBuf++;
889 break;
891 printer->delayFlags |= MSG_DELAY_FLAG_2;
892 break;
894 printer->delayFlags &= ~MSG_DELAY_FLAG_2;
895 printer->delayFlags |= MSG_DELAY_FLAG_1;
896 break;
898 printer->lineEndPos[printer->curLine] = printer->curLinePos;
899 printer->curLine++;
900 *printBuf++ = MSG_CHAR_PRINT_NEXT;
901 arg = *srcBuf++;
902 printer->nextLinePos = printer->curLinePos + (MsgCharsets[printer->font]->newLineY
903#if !VERSION_JP
905#endif
906 ) * arg;
908 printer->delayFlags |= MSG_DELAY_FLAG_1;
909 printer->lineCount = 0;
910 break;
911#if !VERSION_IQUE
913 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
914 *printBuf++ = MSG_PRINT_FUNC_SIZE;
915 *printBuf++ = *srcBuf++;
916 *printBuf++ = arg = *srcBuf++;
917 printer->sizeScale = (arg >> 4) + (arg & 0xF) * 0.0625f;
918 break;
920 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
921 *printBuf++ = MSG_PRINT_FUNC_SIZE_RESET;
922 printer->sizeScale = 1.0f;
923 break;
924#endif
926 printer->printDelayTime = *srcBuf++;
927 printer->charsPerChunk = *srcBuf++;
928 break;
930 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
931 *printBuf++ = MSG_PRINT_FUNC_SET_X;
932 *printBuf++ = *srcBuf++;
933 *printBuf++ = *srcBuf++;
934 break;
936 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
937 *printBuf++ = MSG_PRINT_FUNC_SET_Y;
938 *printBuf++ = *srcBuf++;
939 break;
941 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
942 *printBuf++ = MSG_PRINT_FUNC_RIGHT;
943 *printBuf++ = *srcBuf++;
944 break;
946 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
947 *printBuf++ = MSG_PRINT_FUNC_DOWN;
948 *printBuf++ = *srcBuf++;
949 break;
950 case MSG_READ_FUNC_UP:
951 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
952 *printBuf++ = MSG_PRINT_FUNC_UP;
953 *printBuf++ = *srcBuf++;
954 break;
956 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
957 *printBuf++ = MSG_PRINT_FUNC_INLINE_IMAGE;
958 *printBuf++ = *srcBuf++;
959 arg1--;
960 printer->curPrintDelay = printer->printDelayTime;
961 if (arg1 <= 0) {
962 printer->delayFlags |= MSG_DELAY_FLAG_1;
963 }
964 if (printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2)) {
965 printer->delayFlags &= ~MSG_DELAY_FLAG_1;
966 }
967 break;
969 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
970 *printBuf++ = MSG_PRINT_FUNC_ANIM_SPRITE;
971 *printBuf++ = *srcBuf++;
972 *printBuf++ = *srcBuf++;
973 *printBuf++ = *srcBuf++;
974 printer->curPrintDelay = printer->printDelayTime;
975 if (--arg1 <= 0) {
976 printer->delayFlags |= MSG_DELAY_FLAG_1;
977 }
978 if (printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2)) {
979 printer->delayFlags &= ~MSG_DELAY_FLAG_1;
980 }
981 break;
983 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
984 *printBuf++ = MSG_PRINT_FUNC_ITEM_ICON;
985
986 arg = *srcBuf++;
987 argQ = *srcBuf++;
988
989 a2 = D_80159B50;
990 offset = arg << 8 | argQ;
991
993 dma_copy(icon_ROM_START + gItemIconRasterOffsets[offset],
994 icon_ROM_START + gItemIconRasterOffsets[offset] + 0x200, a2);
995 romEnd = icon_ROM_START + gItemIconPaletteOffsets[offset] + 0x20;
996 dma_copy(icon_ROM_START + gItemIconPaletteOffsets[offset],
997 romEnd, D_8015C7E0);
998 printer->curPrintDelay = printer->printDelayTime;
999 if (--arg1 <= 0) {
1000 printer->delayFlags |= MSG_DELAY_FLAG_1;
1001 }
1002 if (printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2)) {
1003 printer->delayFlags &= ~MSG_DELAY_FLAG_1;
1004 }
1005 break;
1007 printer->curImageIndex = *srcBuf++;
1008 arg = *srcBuf++;
1009 argQ = *srcBuf++;
1010 printer->varImageScreenPos.x = arg << 8 | argQ;
1011 printer->varImageScreenPos.y = *srcBuf++;
1012 printer->varImgHasBorder = *srcBuf++;
1013 printer->varImgFinalAlpha = *srcBuf++;
1014 printer->varImgAlphaFadeStep = *srcBuf++;
1015 printer->varImageDisplayState = 0;
1016 printer->varImageFadeTimer = 0;
1017 if (--arg1 <= 0) {
1018 printer->delayFlags |= MSG_DELAY_FLAG_1;
1019 }
1020 if (printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2)) {
1021 printer->delayFlags &= ~MSG_DELAY_FLAG_1;
1022 }
1023 break;
1025 arg = *srcBuf++;
1026 if (arg != 0) {
1027 printer->varImageDisplayState = 2;
1028 printer->varImgAlphaFadeStep = arg;
1029 printer->varImageFadeTimer = 0;
1030 } else {
1031 printer->varImageScreenPos.x = 0;
1032 }
1033 break;
1035 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1036 *printBuf++ = MSG_PRINT_FUNC_ANIM_DELAY;
1037 *printBuf++ = *srcBuf++;
1038 *printBuf++ = *srcBuf++;
1039 *printBuf++ = *srcBuf++;
1040 printer->delayFlags |= MSG_DELAY_FLAG_4;
1041 break;
1043 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1044 *printBuf++ = MSG_PRINT_FUNC_ANIM_LOOP;
1045 *printBuf++ = *srcBuf++;
1046 *printBuf++ = *srcBuf++;
1047 break;
1049 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1050 *printBuf++ = MSG_PRINT_FUNC_ANIM_DONE;
1051 *printBuf++ = *srcBuf++;
1052 printer->delayFlags &= ~MSG_DELAY_FLAG_4;
1053 if (--arg1 <= 0) {
1054 printer->delayFlags |= MSG_DELAY_FLAG_1;
1055 }
1056 break;
1058 arg = *srcBuf++;
1059 argQ = *srcBuf++;
1060 argW = *srcBuf++;
1061 argE = *srcBuf++;
1062 printer->cursorPosX[arg] = argQ << 8 | argW;
1063 printer->cursorPosY[arg] = argE;
1064 break;
1066 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1067 *printBuf++ = MSG_PRINT_FUNC_CURSOR;
1068 *printBuf++ = *srcBuf++;
1069 break;
1072 printer->maxOption = *srcBuf++;
1073 printer->madeChoice = 0;
1074 printer->curOption = 0;
1075 printer->selectedOption = 0;
1077 printer->delayFlags |= MSG_DELAY_FLAG_1;
1078 break;
1080 printer->cancelOption = *srcBuf++;
1081 break;
1083 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1084 *printBuf++ = MSG_PRINT_FUNC_OPTION;
1085 *printBuf++ = *srcBuf++;
1086 break;
1088 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1089 *printBuf++ = MSG_PRINT_RESET_GFX;
1090 break;
1093 printer->delayFlags |= MSG_DELAY_FLAG_1;
1094 printer->stateFlags &= ~MSG_STATE_FLAG_SPEAKING;
1095 printer->stateFlags &= ~MSG_STATE_FLAG_PRINT_QUICKLY;
1096 break;
1098 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1099 *printBuf++ = MSG_PRINT_FUNC_SAVE_POS;
1100 break;
1102 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1103 *printBuf++ = MSG_PRINT_FUNC_RESTORE_POS;
1104 break;
1106 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1107 *printBuf++ = MSG_PRINT_FUNC_SAVE_COLOR;
1108 break;
1110 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1111 *printBuf++ = MSG_PRINT_FUNC_RESTORE_COLOR;
1112 break;
1114 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1115 *printBuf++ = MSG_PRINT_FUNC_START_FX;
1116 arg = *srcBuf++;
1117 switch (arg) {
1118 case MSG_FX_SHAKE:
1119 case MSG_FX_WAVE:
1121 case MSG_FX_RAINBOW:
1122 case MSG_FX_GLOBAL_WAVE:
1124 case MSG_FX_RISE_PRINT:
1125 case MSG_FX_GROW_PRINT:
1126 case MSG_FX_SIZE_JITTER:
1127 case MSG_FX_SIZE_WAVE:
1128 case MSG_FX_DROP_SHADOW:
1129 *printBuf++ = arg;
1130 break;
1131 case MSG_FX_STATIC:
1132 case MSG_FX_BLUR:
1133 case MSG_FX_DITHER_FADE:
1134 *printBuf++ = arg;
1135 *printBuf++ = *srcBuf++;
1136 break;
1137 }
1138 break;
1140 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1141 *printBuf++ = MSG_PRINT_FUNC_END_FX;
1142 *printBuf++ = *srcBuf++;
1143 break;
1144 case MSG_READ_FUNC_VAR:
1145 arg = *srcBuf++;
1146 srcBuf -= 3;
1147 if (printer->varBufferReadPos == 0) {
1148 printer->unk_52A = printer->fontVariant;
1149 *printBuf++ = MSG_CHAR_PRINT_VARIANT0;
1150 }
1151
1152 do {
1153 s32 a0 = 1;
1154 argQ = gMessageMsgVars[arg][printer->varBufferReadPos++];
1155 if (argQ >= MSG_CONTROL_CHAR) {
1156
1157 switch (argQ) {
1158 case MSG_CHAR_READ_ENDL:
1159 if (gMessageMsgVars[arg][printer->varBufferReadPos] != MSG_CHAR_READ_END) {
1160 sp10[0] = MSG_CHAR_PRINT_ENDL;
1161 } else {
1162 a0 = 0;
1163 }
1164 break;
1170 printer->fontVariant = sp10[0] + 0x10F;
1171 break;
1172#if !VERSION_JP
1174 sp10[0] = MSG_CHAR_PRINT_SPACE;
1175 break;
1176#endif
1178 sp10[0] = MSG_CHAR_PRINT_FUNCTION;
1179 switch (gMessageMsgVars[arg][printer->varBufferReadPos++]) {
1181 sp10[1] = MSG_PRINT_FUNC_COLOR;
1182 sp10[2] = gMessageMsgVars[arg][printer->varBufferReadPos++];
1183 a0 = 3;
1184 break;
1186 sp10[1] = MSG_PRINT_FUNC_SAVE_COLOR;
1187 a0 = 2;
1188 break;
1191 a0 = 2;
1192 break;
1193 }
1194 break;
1195 }
1196 } else {
1197 sp10[0] = argQ;
1198 }
1199 for (i = 0; i < a0; i++) {
1200 arg1--;
1201 *printBuf++ = sp10[i];
1202 }
1203
1204 if (gMessageMsgVars[arg][printer->varBufferReadPos] == MSG_CHAR_READ_END) {
1205 srcBuf += 3;
1206 printer->varBufferReadPos = 0;
1207 printer->fontVariant = printer->unk_52A;
1208 *printBuf++ = MSG_CHAR_PRINT_VARIANT0 + printer->fontVariant;
1209 break;
1210 }
1211 } while ((printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2)) || arg1 > 0);
1212
1213 if (!(printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2)) && arg1 <= 0) {
1214 printer->delayFlags |= MSG_DELAY_FLAG_1;
1215 printer->curPrintDelay = printer->printDelayTime;
1216 }
1217 msg_play_speech_sound(printer, argQ);
1218 if (printer->stateFlags & MSG_STATE_FLAG_800000) {
1220 }
1221 break;
1223 arg = *srcBuf++;
1224 printer->speechSoundType = arg;
1225 printer->speechSoundIDA = MsgVoices[arg].voiceA;
1226 printer->speechSoundIDB = MsgVoices[arg].voiceB;
1227 printer->speechPitchShift = MsgVoices[arg].pitchShift;
1228 break;
1230 printer->volume = *srcBuf++;
1231 break;
1233 arg = *srcBuf++;
1234 argQ = *srcBuf++;
1235 argW = *srcBuf++;
1236 argE = *srcBuf++;
1237 printer->speechSoundIDA = (arg << 0x18) + (argQ << 0x10) + (argW << 0x8) + (argE);
1238 arg = *srcBuf++;
1239 argQ = *srcBuf++;
1240 argW = *srcBuf++;
1241 argE = *srcBuf++;
1242 printer->speechSoundIDB = (arg << 0x18) + (argQ << 0x10) + (argW << 0x8) + (argE);
1243 break;
1245 *printBuf++ = MSG_CHAR_PRINT_FUNCTION;
1246 *printBuf++ = MSG_PRINT_FUNC_CENTER_X;
1247 *printBuf++ = *srcBuf++;
1248 break;
1250 if (*srcBuf++) {
1251 printer->stateFlags |= MSG_STATE_FLAG_40000;
1252 } else {
1253 printer->stateFlags &= ~MSG_STATE_FLAG_40000;
1254 }
1255 break;
1257 printer->stateFlags |= MSG_STATE_FLAG_80000;
1258 break;
1259 }
1260 break;
1261 default:
1262 *printBuf++ = c;
1263 arg1--;
1264#if VERSION_IQUE
1265 if (c >= MSG_CHAR_MULTIBYTE_FIRST && c <= MSG_CHAR_MULTIBYTE_LAST) {
1266 *printBuf++ = nextArg;
1267 srcBuf++;
1268 arg1--;
1269 }
1270#endif
1271 if (printer->fontVariant == 0 && c == MSG_CHAR_UNK_C3) {
1272 printer->stateFlags &= ~MSG_STATE_FLAG_SPEAKING;
1273 } else {
1274 msg_play_speech_sound(printer, c);
1275 if (printer->stateFlags & MSG_STATE_FLAG_800000) {
1277 }
1278 }
1279 break;
1280 }
1281
1282 if (!(printer->delayFlags & (MSG_DELAY_FLAG_4 | MSG_DELAY_FLAG_2)) && arg1 <= 0) {
1283 printer->delayFlags |= MSG_DELAY_FLAG_1;
1284 printer->curPrintDelay = printer->printDelayTime;
1285 }
1286 if (!(printer->delayFlags & MSG_DELAY_FLAG_1)) {
1287 continue;
1288 }
1289 if (!s8) {
1290 break;
1291 }
1292 if (srcBuf[-1] == MSG_CHAR_READ_END) {
1293 break;
1294 }
1295 arg1 = 10000;
1296 } while (true);
1297
1298 printer->printBufferPos = printBuf - printer->printBuffer;
1299 printer->delayFlags = 0;
1300 printer->srcBufferPos = (u16)(s32)(srcBuf - (s32)printer->srcBuffer);
1301 *printBuf = MSG_CHAR_PRINT_END;
1302}
1303#endif
1304
1305void initialize_printer(MessagePrintState* printer, s32 arg1, s32 arg2) {
1306 s32 i;
1307
1308 printer->printBufferSize = ARRAY_COUNT(printer->printBuffer);
1309 printer->printBuffer[0] = MSG_CHAR_PRINT_END;
1310 printer->printDelayTime = 1;
1311 printer->charsPerChunk = 1;
1312 printer->windowScrollRate = (s32)(6 / DT);
1313 printer->srcBuffer = nullptr;
1314 printer->msgID = 0;
1315 printer->curPrintDelay = 0;
1316 printer->windowOffsetPos.x = 0;
1317 printer->windowOffsetPos.y = 0;
1318 printer->windowBasePos.x = 0;
1319 printer->windowBasePos.y = 0;
1321 printer->rewindArrowCounter = 0;
1322 printer->rewindArrowPos.x = 0;
1323 printer->rewindArrowPos.y = 0;
1324 printer->curLine = 0;
1325 printer->unkArraySize = 0;
1326 printer->maxOption = 0;
1327 printer->madeChoice = 0;
1328 printer->curOption = 0;
1329 printer->selectedOption = 0;
1330 printer->cancelOption = -1;
1332 printer->stateFlags = 0;
1333 printer->delayFlags = 0;
1334 printer->closedWritebackBool = nullptr;
1335 printer->printBufferPos = 0;
1336 printer->srcBufferPos = 0;
1337 printer->font = 0;
1338 printer->fontVariant = 0;
1339 printer->effectFrameCounter = 0;
1340 printer->curLinePos = 0;
1341 printer->unk_46C = 0;
1342 printer->lineCount = 0;
1343
1344 for (i = 0; i < ARRAY_COUNT(printer->animTimers); i++) {
1345 printer->curAnimFrame[i] = 0;
1346 printer->animTimers[i] = -1;
1347 }
1348
1349 printer->initOpenPos.x = 160;
1350 printer->initOpenPos.y = 40;
1351 printer->speechSoundType = -1;
1352 printer->speechPan = 64;
1353 printer->volume = 75;
1354 printer->rewindArrowCounter = 0;
1355 printer->style = 0;
1356 printer->fadeInCounter = 0;
1357 printer->openStartPos.x = 0;
1358 printer->openStartPos.y = 0;
1359 printer->fadeOutCounter = 0;
1360 printer->windowSize.y = 0;
1361 printer->windowSize.x = 0;
1362 printer->speechPitchShift = 0;
1363 printer->speechSoundIDA = 0;
1364 printer->speechSoundIDB = 0;
1365 printer->varBufferReadPos = 0;
1366 printer->curImageIndex = 0;
1367 printer->varImageScreenPos.x = 0;
1368 printer->varImageScreenPos.y = 0;
1369 printer->varImgHasBorder = 0;
1370 printer->varImgFinalAlpha = 255;
1371 printer->varImageDisplayState = 0;
1372 printer->varImageFadeTimer = 0;
1373 printer->letterBackgroundImg = nullptr;
1374 printer->letterBackgroundPal = nullptr;
1375 printer->letterContentImg = nullptr;
1376 printer->letterContentPal = nullptr;
1377 printer->sizeScale = 1.0f;
1378}
1379
1380#if VERSION_PAL
1381void dma_load_msg(u32 msgID, void* dest) {
1382 u8* langPtr = D_PAL_8014AE50[gCurrentLanguage];
1383 u8* new_langPtr;
1384 u8* addr = (u8*) langPtr + (msgID >> 14); // (msgID >> 16) * 4
1385 u8* offset[2]; // start, end
1386
1387 dma_copy(addr, addr + 4, &offset[0]); // Load section offset
1388
1389 new_langPtr = langPtr;
1390 new_langPtr = offset[0] + ((u32) new_langPtr);
1391 addr = new_langPtr + ((msgID & 0xFFFF) * 4);
1392 dma_copy(addr, addr + 8, &offset); // Load message start and end offsets
1393
1394 // Load the msg data
1395 dma_copy(&langPtr[(u32)offset[0]], &langPtr[(u32)offset[1]], dest);
1396}
1397#else
1398void dma_load_msg(u32 msgID, void* dest) {
1399 u8* addr = (u8*) MSG_ROM_START + (msgID >> 14); // (msgID >> 16) * 4
1400 u8* offset[2]; // start, end
1401
1402 dma_copy(addr, addr + 4, &offset[0]); // Load section offset
1403
1404 addr = MSG_ROM_START + offset[0] + (msgID & 0xFFFF) * 4;
1405 dma_copy(addr, addr + 8, &offset); // Load message start and end offsets
1406
1407 // Load the msg data
1408 dma_copy(MSG_ROM_START + offset[0], MSG_ROM_START + offset[1], dest);
1409}
1410#endif
1411
1413 s8* prevBufferPos;
1414
1415 dma_load_msg(msgID, &gMessageBuffers[gNextMessageBuffer]);
1416 prevBufferPos = gMessageBuffers[gNextMessageBuffer];
1417
1419 if (gNextMessageBuffer >= ARRAY_COUNT(gMessageBuffers)) {
1421 }
1422
1423 return prevBufferPos;
1424}
1425
1426MessagePrintState* msg_get_printer_for_msg(s32 msgID, s32* donePrintingWriteback) {
1427 return _msg_get_printer_for_msg(msgID, donePrintingWriteback, 0);
1428}
1429
1430MessagePrintState* _msg_get_printer_for_msg(s32 msgID, s32* donePrintingWriteback, s32 arg2) {
1431 MessagePrintState* printer;
1432 s8* srcBuffer;
1433 s32 height;
1434 s32 width;
1435 s32 maxLineChars;
1436 s32 numLines;
1437 s32 maxLinesPerPage;
1438 s32 i;
1439
1440 if (msgID == MSG_NONE) {
1441 return nullptr;
1442 }
1443
1444 srcBuffer = (s8*) msgID;
1445 if (msgID >= 0) {
1446 srcBuffer = load_message_to_buffer((s32)srcBuffer);
1447 }
1448
1449 for (i = 0; i < ARRAY_COUNT(gMessagePrinters); i++) {
1450 printer = &gMessagePrinters[i];
1451
1452 if (!(printer->stateFlags & MSG_STATE_FLAG_2)) {
1453 initialize_printer(printer, 1, arg2);
1455 printer->srcBuffer = srcBuffer;
1456 printer->msgID = msgID;
1457 printer->stateFlags |= MSG_STATE_FLAG_2;
1458 get_msg_properties(msgID, &height, &width, &maxLineChars, &numLines, &maxLinesPerPage, nullptr, 0);
1459 printer->msgHeight = height;
1460 printer->msgWidth = width;
1461 printer->maxLineChars = maxLineChars;
1462 printer->numLines = numLines;
1463 printer->maxLinesPerPage = maxLinesPerPage;
1464 printer->closedWritebackBool = donePrintingWriteback;
1465
1466 if (donePrintingWriteback != nullptr) {
1467 *donePrintingWriteback = false;
1468 }
1469 return printer;
1470 }
1471 }
1472
1473 return nullptr;
1474}
1475
1476s32 msg_printer_load_msg(s32 msgID, MessagePrintState* printer) {
1477 s8* buffer;
1478
1479 if (msgID >= 0) {
1480 buffer = load_message_to_buffer(msgID);
1481 } else {
1482 buffer = (s8*) msgID;
1483 }
1484
1485 printer->srcBuffer = buffer;
1486 printer->srcBufferPos = 0;
1487 printer->stateFlags &= ~MSG_STATE_FLAG_40;
1488 return 1;
1489}
1490
1491void msg_printer_set_origin_pos(MessagePrintState* msgPrintState, s32 x, s32 y) {
1492 msgPrintState->initOpenPos.x = x;
1493 msgPrintState->initOpenPos.y = y;
1494
1495 if (msgPrintState->initOpenPos.x < 0) {
1496 msgPrintState->initOpenPos.x = 0;
1497 }
1498 if (msgPrintState->initOpenPos.x > SCREEN_WIDTH) {
1499 msgPrintState->initOpenPos.x = SCREEN_WIDTH;
1500 }
1501 if (msgPrintState->initOpenPos.y < 0) {
1502 msgPrintState->initOpenPos.y = 0;
1503 }
1504 if (msgPrintState->initOpenPos.y > 220) {
1505 msgPrintState->initOpenPos.y = 220;
1506 }
1507}
1508
1510 if (!(msgPrintState->stateFlags & MSG_STATE_FLAG_2)) {
1511 return false;
1512 }
1513
1514 msgPrintState->stateFlags |= MSG_STATE_FLAG_1;
1515 return true;
1516}
1517
1519 *gMsgVarImages = images;
1520}
1521
1522void set_message_text_var(s32 msgID, s32 index) {
1523 u8* mallocSpace = nullptr;
1524 s32 i;
1525 u8* msgVars;
1526
1527 if (msgID >= 0) {
1528 mallocSpace = general_heap_malloc(0x400);
1529 dma_load_msg(msgID, mallocSpace);
1530 msgID = (s32)mallocSpace;
1531 }
1532
1533 i = 0;
1534 msgVars = gMessageMsgVars[index];
1535 while (true) {
1536 msgVars[i] = ((u8*)msgID)[i];
1537 if (((u8*)msgID)[i] == MSG_CHAR_READ_END) {
1538 break;
1539 }
1540
1541 if (++i >= 32) {
1542 msgVars[i - 1] = MSG_CHAR_READ_END;
1543 break;
1544 }
1545 }
1546
1547 if (mallocSpace != nullptr) {
1548 general_heap_free(mallocSpace);
1549 }
1550}
1551
1552void set_message_int_var(s32 value, s32 index) {
1553 s8 strBuffer[ARRAY_COUNT(gMessageMsgVars[index])];
1554 s8* bufferIt;
1555 s32 i;
1556
1557 int_to_string(value, strBuffer, 10);
1558
1559 for (i = 0, bufferIt = strBuffer; i < ARRAY_COUNT(gMessageMsgVars[index]) - 1; i++) {
1560 s8 thisChar = bufferIt[i];
1561
1562 if (thisChar == 0) {
1563 break;
1564 }
1565 gMessageMsgVars[index][i] = thisChar - '0' + MSG_CHAR_DIGIT_0;
1566 }
1567 gMessageMsgVars[index][i] = MSG_CHAR_READ_END;
1568}
1569
1570void close_message(MessagePrintState* msgPrintState) {
1571 msgPrintState->stateFlags &= ~MSG_STATE_FLAG_40;
1572}
1573
1574#if VERSION_JP
1575#define CHAR_SPACE_MULTIPLIER 0.7
1576#else
1577#define CHAR_SPACE_MULTIPLIER 0.6
1578#endif
1579
1580s32 msg_get_print_char_width(s32 character, s32 charset, s32 variation, f32 msgScale, s32 overrideCharWidth, u8 flags) {
1581 f32 charWidth;
1582
1583 if (character >= MSG_CONTROL_CHAR
1584 && (character != MSG_CHAR_READ_SPACE
1585 && character != MSG_CHAR_READ_FULL_SPACE
1586 && character != MSG_CHAR_READ_HALF_SPACE)) {
1587 return 0;
1588 }
1589
1590#if VERSION_IQUE
1591 if (character >= MSG_CHAR_MULTIBYTE_FIRST && character <= MSG_CHAR_MULTIBYTE_LAST) {
1592 charWidth = 16.0;
1593 return charWidth * msgScale;
1594 }
1595#endif
1596
1597 if (overrideCharWidth != 0) {
1598 charWidth = overrideCharWidth;
1599 } else if (flags != 0) {
1600 u8* charWidthTable = MsgCharsets[charset]->rasters[variation].charWidthTable;
1601
1602 if (charWidthTable != nullptr
1603 && character != MSG_CHAR_READ_SPACE
1604 && character != MSG_CHAR_READ_FULL_SPACE
1605 && character != MSG_CHAR_READ_HALF_SPACE) {
1606 charWidth = charWidthTable[character];
1607 } else {
1608 charWidth = MsgCharsets[charset]->rasters[variation].monospaceWidth;
1609 }
1610 } else {
1611 charWidth = MsgCharsets[charset]->rasters[variation].monospaceWidth;
1612 }
1613
1614 if (character == MSG_CHAR_READ_SPACE) {
1615 return charWidth * msgScale * CHAR_SPACE_MULTIPLIER;
1616 }
1617 if (character == MSG_CHAR_READ_FULL_SPACE) {
1618 f64 retWidth = charWidth * msgScale;
1619 return retWidth;
1620 }
1621 if (character == MSG_CHAR_READ_HALF_SPACE) {
1622 return charWidth * msgScale * 0.5;
1623 }
1624 if (character >= MSG_CONTROL_CHAR) {
1625 return 0;
1626 }
1627 return charWidth * msgScale;
1628}
1629
1630s32 msg_get_draw_char_width(s32 character, s32 charset, s32 variation, f32 msgScale, s32 overrideCharWidth, u16 flags) {
1631 f32 baseWidth;
1632
1633 if (character >= MSG_CONTROL_CHAR
1634 && (character != MSG_CHAR_PRINT_SPACE
1635 && character != MSG_CHAR_PRINT_FULL_SPACE
1636 && character != MSG_CHAR_PRINT_HALF_SPACE)) {
1637 return 0;
1638 }
1639
1640 if (overrideCharWidth != 0) {
1641 baseWidth = overrideCharWidth;
1642 } else if (flags & MSG_PRINT_FLAG_100) {
1643 u8* charWidthTable = MsgCharsets[charset]->rasters[variation].charWidthTable;
1644
1645 if (charWidthTable != nullptr
1646 && character != MSG_CHAR_PRINT_SPACE
1647 && character != MSG_CHAR_PRINT_FULL_SPACE
1648 && character != MSG_CHAR_PRINT_HALF_SPACE) {
1649 baseWidth = charWidthTable[character];
1650 } else {
1651 baseWidth = MsgCharsets[charset]->rasters[variation].monospaceWidth;
1652 }
1653 } else {
1654 baseWidth = MsgCharsets[charset]->rasters[variation].monospaceWidth;
1655 }
1656
1657 if (character == MSG_CHAR_PRINT_SPACE) {
1658 return baseWidth * msgScale * CHAR_SPACE_MULTIPLIER;
1659 }
1660 if (character == MSG_CHAR_PRINT_FULL_SPACE) {
1661 f64 charWidth = baseWidth * msgScale;
1662 return charWidth;
1663 }
1664 if (character == MSG_CHAR_PRINT_HALF_SPACE) {
1665 return baseWidth * msgScale * 0.5;
1666 }
1667 if (character >= MSG_CONTROL_CHAR) {
1668 return 0;
1669 }
1670 return baseWidth * msgScale;
1671}
1672
1673void get_msg_properties(s32 msgID, s32* height, s32* width, s32* maxLineChars, s32* numLines, s32* maxLinesPerPage, s32* numSpaces, u16 charset) {
1674 u8* message;
1675 s32 i;
1676 u16 pageCount;
1677 s32 linesOnPage;
1678 u8 stop;
1679 s32 lineWidth;
1680 s32 charCount;
1681 u16 lineIndex;
1682 s32 msgStyle;
1683 s32 functionCode;
1684 u8 packedScaleY;
1685 f32 scale;
1686 s32 temp;
1687
1688 u16 lineWidths[32];
1689 u16 lineCharNumbers[32];
1690 u16 linesPerPage[32];
1691 s32 lineCount;
1692 u16 varIndex;
1693 u16 font;
1694 u8* buffer;
1695 u16 maxLineWidth;
1696 u16 maxCharsPerLine;
1697 u16 maxLinesOnPage;
1698 u16 spaceCount;
1699 u16 endl;
1700
1701 u8 c;
1702 u8 prevChar;
1703
1704 scale = 1.0f;
1705 c = 0;
1706 lineIndex = 0;
1707 pageCount = 0;
1708 varIndex = 0;
1709 font = 0;
1710 buffer = nullptr;
1711 maxLineWidth = 0;
1712 maxCharsPerLine = 0;
1713 maxLinesOnPage = 0;
1714 spaceCount = 0;
1715
1716 if (msgID == MSG_NONE) {
1717 return;
1718 }
1719
1720 if (msgID >= 0) {
1721 buffer = general_heap_malloc(0x400);
1722 dma_load_msg(msgID, buffer);
1723 message = buffer;
1724 } else {
1725 message = (u8*)msgID;
1726 }
1727
1728 if (charset & 1) {
1729 font = 1;
1730 }
1731
1732 i = 0;
1733 stop = false;
1734 lineWidth = 0;
1735 linesOnPage = 0;
1736 charCount = 0;
1737 endl = true;
1738 lineCount = 0;
1739
1740 do {
1741 prevChar = c;
1742 c = message[i++];
1743 switch (c) {
1748 varIndex = c - MSG_CHAR_READ_VARIANT0;
1749 break;
1751 i++;
1752 break;
1753 case MSG_CHAR_READ_WAIT:
1754 case MSG_CHAR_READ_NEXT:
1755 if (linesOnPage != 0) {
1756 linesPerPage[pageCount] = linesOnPage;
1757 pageCount++;
1758 if (pageCount >= 32) {
1759 stop = 1;
1760 }
1761 linesOnPage = 0;
1762 }
1763 break;
1764 case MSG_CHAR_READ_ENDL:
1765 lineWidths[lineIndex] = lineWidth;
1766 lineCharNumbers[lineIndex] = charCount;
1767 lineIndex++;
1768 if (lineIndex >= 32) {
1769 stop = 1;
1770 }
1771 lineWidth = 0;
1772 charCount = 0;
1773 endl = true;
1774 break;
1776 msgStyle = message[i++];
1777 switch (msgStyle) {
1778 case MSG_STYLE_CHOICE:
1779 i += 4;
1780 break;
1781 case MSG_STYLE_POSTCARD:
1782 i++;
1783 break;
1784 case MSG_STYLE_RIGHT:
1785 case MSG_STYLE_LEFT:
1786 case MSG_STYLE_CENTER:
1787 case MSG_STYLE_TATTLE:
1788 case MSG_STYLE_INSPECT:
1789 case MSG_STYLE_SIGN:
1790 case MSG_STYLE_LAMPPOST:
1791 case MSG_STYLE_POPUP:
1792 case MSG_STYLE_B:
1793 break;
1794 }
1795 break;
1796 case MSG_CHAR_READ_END:
1797 lineWidths[lineIndex] = lineWidth;
1798 lineCharNumbers[lineIndex] = charCount;
1799 lineIndex++;
1800 stop = true;
1801 break;
1803 functionCode = message[i++];
1804 switch (functionCode) {
1805 case MSG_READ_FUNC_FONT:
1806 font = message[i++];
1807 break;
1819 break;
1820 default:
1821 stop = true;
1822 break;
1824 i++;
1825 // fallthrough
1826 temp = 4;
1828 i += temp;
1829 // fallthrough
1832 i++;
1833 // fallthrough
1837 i++;
1838 // fallthrough
1844 case MSG_READ_FUNC_DOWN:
1845 case MSG_READ_FUNC_UP:
1857 i++;
1858 break;
1860 if (message[i] == 0) {
1861 stop = true;
1862 }
1863 i++;
1864 break;
1866 if (message[i] == MSG_CHAR_READ_END) {
1867 stop = true;
1868 }
1869 break;
1870 case MSG_READ_FUNC_SIZE:
1871 packedScaleY = message[i + 1];
1872 i += 2;
1873 scale = (f32)(packedScaleY >> 4) + ((packedScaleY & 0xF) * 0.0625f);
1874 break;
1876 scale = 1.0f;
1877 break;
1879 switch (message[i++]) {
1880 case MSG_FX_STATIC:
1881 case MSG_FX_BLUR:
1882 case MSG_FX_DITHER_FADE:
1883 i++;
1884 break;
1885 case MSG_FX_SHAKE:
1886 case MSG_FX_WAVE:
1888 case MSG_FX_RAINBOW:
1889 case MSG_FX_GLOBAL_WAVE:
1891 case MSG_FX_RISE_PRINT:
1892 case MSG_FX_GROW_PRINT:
1893 case MSG_FX_SIZE_JITTER:
1894 case MSG_FX_SIZE_WAVE:
1895 case MSG_FX_DROP_SHADOW:
1896 break;
1897 }
1898 break;
1899 case MSG_READ_FUNC_VAR:
1900 lineWidth += get_msg_width((s32)gMessageMsgVars[message[i++]], 0);
1901 break;
1902 }
1903 break;
1905 break;
1909 spaceCount++;
1910 // fallthrough
1911 default:
1912 if (endl) {
1913 lineCount++;
1914 linesOnPage++;
1915 endl = false;
1916 }
1917
1918#if VERSION_IQUE
1919 if (prevChar >= MSG_CHAR_MULTIBYTE_FIRST && prevChar <= MSG_CHAR_MULTIBYTE_LAST) {
1920 break;
1921 }
1922#endif
1923
1924 lineWidth += msg_get_print_char_width(c, font, varIndex, scale, 0, 1);
1925 charCount++;
1926 break;
1927 }
1928 } while (!stop);
1929
1930 if (buffer != nullptr) {
1931 general_heap_free(buffer);
1932 }
1933
1934 for (i = 0; i < lineIndex; i++) {
1935 if (maxLineWidth < lineWidths[i]) {
1936 maxLineWidth = lineWidths[i];
1937 }
1938 if (maxCharsPerLine < lineCharNumbers[i]) {
1939 maxCharsPerLine = lineCharNumbers[i];
1940 }
1941 }
1942
1943 if (pageCount == 0) {
1944 maxLinesOnPage = linesOnPage;
1945 } else {
1946 for (i = 0; i < pageCount; i++) {
1947 if (maxLinesOnPage < linesPerPage[i]) {
1948 maxLinesOnPage = linesPerPage[i];
1949 }
1950 }
1951 }
1952
1953 if (width != nullptr) {
1954 *width = maxLineWidth;
1955 }
1956 if (height != nullptr) {
1957 *height = lineCount * MsgCharsets[font]->newLineY;
1958 }
1959 if (maxLineChars != nullptr) {
1960 *maxLineChars = maxCharsPerLine;
1961 }
1962 if (numLines != nullptr) {
1963 *numLines = lineCount;
1964 }
1965 if (maxLinesPerPage != nullptr) {
1966 *maxLinesPerPage = maxLinesOnPage;
1967 }
1968 if (numSpaces != nullptr) {
1969 *numSpaces = spaceCount;
1970 }
1971}
1972
1973s32 get_msg_width(s32 msgID, u16 charset) {
1974 s32 width;
1975
1976 get_msg_properties(msgID, nullptr, &width, nullptr, nullptr, nullptr, nullptr, charset);
1977 return width;
1978}
1979
1980#if !VERSION_JP
1981s32 get_msg_lines(s32 msgID) {
1982 s32 numLines;
1983
1984 get_msg_properties(msgID, nullptr, nullptr, nullptr, &numLines, nullptr, nullptr, 0);
1985 return numLines;
1986}
1987#endif
1988
1989void draw_msg(s32 msgID, s32 posX, s32 posY, s32 opacity, s32 palette, u8 style) {
1990 MessagePrintState stackPrinter;
1991 MessagePrintState* printer;
1992 u16 bufferPos;
1993 s8* mallocSpace;
1994 s32 charset;
1995 u16 flags;
1996 s32 width;
1997
1998 flags = 0;
1999 bufferPos = 0;
2000 mallocSpace = nullptr;
2001 charset = 0;
2002
2003 if (msgID != 0) {
2004 if (style & DRAW_MSG_STYLE_MENU) {
2005 flags = 2;
2006 charset = 1;
2007 }
2008
2009 if (opacity < 0xFF) {
2010 flags |= 1;
2011 }
2012
2013 printer = &stackPrinter;
2014 initialize_printer(printer, 1, 0);
2015
2016 if (msgID < 0) {
2017 printer->srcBuffer = (u8*)msgID;
2018 } else {
2019 mallocSpace = general_heap_malloc(0x400);
2020 dma_load_msg(msgID, mallocSpace);
2021 printer->srcBuffer = mallocSpace;
2022 get_msg_properties((s32) printer->srcBuffer, 0, &width, 0, 0, 0, 0, charset);
2023 printer->msgWidth = width;
2024 }
2025
2026 if (palette >= 0) {
2027 printer->printBuffer[bufferPos++] = MSG_CHAR_PRINT_FUNCTION;
2028 printer->printBuffer[bufferPos++] = MSG_PRINT_FUNC_COLOR;
2029 printer->printBuffer[bufferPos++] = palette;
2030 printer->printBufferPos += 3;
2031 }
2032
2033 if (style & DRAW_MSG_STYLE_WAVY) {
2034 printer->printBuffer[bufferPos++] = MSG_CHAR_PRINT_FUNCTION;
2035 printer->printBuffer[bufferPos++] = MSG_PRINT_FUNC_START_FX;
2036 printer->printBuffer[bufferPos++] = MSG_FX_GLOBAL_WAVE;
2037 printer->printBufferPos += 3;
2038 }
2039
2040 if (style & DRAW_MSG_STYLE_RAINBOW) {
2041 printer->printBuffer[bufferPos++] = MSG_CHAR_PRINT_FUNCTION;
2042 printer->printBuffer[bufferPos++] = MSG_PRINT_FUNC_START_FX;
2043 printer->printBuffer[bufferPos++] = MSG_FX_GLOBAL_RAINBOW;
2044 printer->printBufferPos += 3;
2045 }
2046
2047 if (style & DRAW_MSG_STYLE_DROP_SHADOW) {
2048 printer->printBuffer[bufferPos++] = MSG_CHAR_PRINT_FUNCTION;
2049 printer->printBuffer[bufferPos++] = MSG_PRINT_FUNC_START_FX;
2050 printer->printBuffer[bufferPos++] = MSG_FX_DROP_SHADOW;
2051 printer->printBufferPos += 3;
2052 }
2053
2054 msg_copy_to_print_buffer(printer, 10000, 1);
2055 appendGfx_message(printer, (s16)posX, (s16)posY, 0, 0, flags, opacity & 0xFF);
2056
2057 if (mallocSpace != nullptr) {
2058 general_heap_free(mallocSpace);
2059 }
2060 }
2061}
2062
2063void msg_update_rewind_arrow(s32 printerIndex) {
2064 MessagePrintState* printer = &gMessagePrinters[printerIndex];
2065 f32 angle = 0.0f;
2066 f32 scale = 1.0f;
2067 f32 colorG = 255.0f;
2068 f32 colorR = 255.0f;
2069 f32 colorB = 255.0f;
2070 Matrix4f sp18;
2071 Matrix4f sp58;
2072 f32 temp;
2073
2074 gDPPipeSync(gMainGfxPos++);
2075 gSPDisplayList(gMainGfxPos++, D_8014C2D8);
2076
2077 switch (printer->rewindArrowAnimState) {
2079 printer->rewindArrowCounter = 0;
2080 printer->rewindArrowSwingPhase = 0;
2082 // fallthrough
2084 temp = printer->rewindArrowCounter;
2085 scale = temp * 0.2 + 0.5;
2086 if (++printer->rewindArrowCounter >= 4) {
2087 printer->rewindArrowCounter = 0;
2089 }
2090 break;
2092 if (++printer->rewindArrowCounter >= 25) {
2093 printer->rewindArrowCounter = 0;
2095 }
2096 break;
2098 colorR = update_lerp(EASING_LINEAR, 255.0f, 224.0f, printer->rewindArrowCounter, 15);
2099 colorG = update_lerp(EASING_LINEAR, 255.0f, 224.0f, printer->rewindArrowCounter, 15);
2100 colorB = update_lerp(EASING_LINEAR, 255.0f, 208.0f, printer->rewindArrowCounter, 15);
2101 if (++printer->rewindArrowCounter >= 15) {
2102 printer->rewindArrowCounter = 0;
2104 }
2105 break;
2107 colorR = update_lerp(EASING_LINEAR, 224.0f, 255.0f, printer->rewindArrowCounter, 15);
2108 colorG = update_lerp(EASING_LINEAR, 224.0f, 255.0f, printer->rewindArrowCounter, 15);
2109 colorB = update_lerp(EASING_LINEAR, 208.0f, 255.0f, printer->rewindArrowCounter, 15);
2110 if (++printer->rewindArrowCounter >= 15) {
2111 printer->rewindArrowCounter = 0;
2113 }
2114 break;
2115 }
2116
2117 gDPSetPrimColor(gMainGfxPos++, 0, 0, colorR, colorG, colorB, 255);
2118
2122 angle = cosine(printer->rewindArrowSwingPhase) * 30.0f;
2123 printer->rewindArrowSwingPhase += 15;
2124 if (printer->rewindArrowSwingPhase >= 360) {
2125 printer->rewindArrowSwingPhase -= 360;
2126 }
2127 }
2128
2129 guTranslateF(sp18, printer->rewindArrowPos.x + 12, -(printer->rewindArrowPos.y + 12), 0);
2130 if (angle != 0.0) {
2131 guRotateF(sp58, angle, 0, 0, 1.0f);
2132 guMtxCatF(sp58, sp18, sp18);
2133 }
2134 if (scale != 1.0) {
2135 guScaleF(sp58, scale, scale, 1.0f);
2136 guMtxCatF(sp58, sp18, sp18);
2137 }
2138
2140 gSPMatrix(gMainGfxPos++, VIRTUAL_TO_PHYSICAL(&gDisplayContext->matrixStack[gMatrixListPos++]), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
2141 gDPLoadTextureTile(gMainGfxPos++, ui_msg_star_png, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 0, 0, 0, 15, 17, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD);
2142 gDPLoadMultiTile_4b(gMainGfxPos++, ui_msg_star_silhouette_png, 0x0100, 1, G_IM_FMT_I, 16, 0, 0, 0, 15, 18, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 5, G_TX_NOLOD, G_TX_NOLOD);
2143 gSPVertex(gMainGfxPos++, gRewindArrowQuad, 4, 0);
2144 gSP2Triangles(gMainGfxPos++, 0, 2, 1, 0, 1, 2, 3, 0);
2145}
2146
2147void msg_draw_rewind_arrow(s32 printerIndex) {
2148 MessagePrintState* printer = &gMessagePrinters[printerIndex];
2149
2150 if (printer->rewindArrowCounter < 6) {
2152 printer->rewindArrowPos.y, 10, 10, SCREEN_WIDTH - 20, SCREEN_HEIGHT - 20, 255);
2153 }
2154
2155 printer->rewindArrowCounter++;
2156 if (printer->rewindArrowCounter >= 12) {
2157 printer->rewindArrowCounter = 0;
2158 }
2159}
2160
2162 s32 pointerAlpha = 255;
2163 s32 shadowAlpha = 72;
2164 s32 posInterpPhase = gGameStatusPtr->frameCounter % 360;
2165 s32 posX, posY;
2166
2168 posX = printer->windowOffsetPos.x + printer->windowBasePos.x + printer->cursorPosX[printer->selectedOption];
2169 posY = printer->windowOffsetPos.y + printer->windowBasePos.y + printer->cursorPosY[printer->selectedOption];
2170 } else {
2171 s32 baseX, baseY, targetX, targetY;
2172 f32 moveToTargetAlpha = (f32)(printer->scrollingTime + 1.0) / CHOICE_POINTER_MOVE_RATE;
2173
2174 baseX = printer->windowOffsetPos.x + printer->windowBasePos.x + printer->cursorPosX[printer->selectedOption];
2175 targetX = printer->windowOffsetPos.x + printer->windowBasePos.x + printer->cursorPosX[printer->targetOption];
2176 posX = baseX + (targetX - baseX) * moveToTargetAlpha;
2177
2178 baseY = printer->windowOffsetPos.y + printer->windowBasePos.y + printer->cursorPosY[printer->selectedOption];
2179 targetY = printer->windowOffsetPos.y + printer->windowBasePos.y + printer->cursorPosY[printer->targetOption];
2180 posY = baseY + (targetY - baseY) * moveToTargetAlpha;
2181 }
2182
2183 posY++;
2184 posX += (cosine(posInterpPhase * 38 + 270) + 1.0) * 0.5 * 3.2;
2185 posX -= 2;
2186
2187 if (printer->stateFlags & MSG_STATE_FLAG_20000) {
2188 u32 opacity;
2189 opacity = 255.0 - printer->fadeOutCounter * 46.0;
2190 pointerAlpha = opacity;
2191 opacity = 72.0 - printer->fadeOutCounter * 14.4;
2192 shadowAlpha = opacity;
2193 }
2194
2195 gDPPipeSync(gMainGfxPos++);
2196 gDPSetTextureLUT(gMainGfxPos++, G_TT_RGBA16);
2197 gDPLoadTLUT_pal16(gMainGfxPos++, 0, ui_point_right_pal);
2198 gDPSetRenderMode(gMainGfxPos++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
2199 gDPSetCombineMode(gMainGfxPos++, PM_CC_07, PM_CC_07);
2200 gDPSetPrimColor(gMainGfxPos++, 0, 0, 40, 40, 40, shadowAlpha);
2201 draw_image_with_clipping(ui_point_right_png, 16, 16, G_IM_FMT_CI, G_IM_SIZ_4b, posX + 2, posY + 2, 10, 10, 300, 220);
2202 draw_ci_image_with_clipping(ui_point_right_png, 16, 16, G_IM_FMT_CI, G_IM_SIZ_4b, ui_point_right_pal, posX, posY, 20, 20, 300, 200, pointerAlpha);
2203}
2204
2205void draw_digit(IMG_PTR img, s32 charset, s32 posX, s32 posY) {
2206 MessageNumber* num = &gMsgNumbers[charset];
2207
2208 gDPLoadTextureTile_4b(gMainGfxPos++,
2209 img, G_IM_FMT_CI,
2210 num->texWidth , num->texHeight,
2211 0, 0,
2212 num->texWidth - 1, num->texHeight - 1,
2213 0,
2214 G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
2215 G_TX_NOMASK, G_TX_NOMASK,
2216 G_TX_NOLOD, G_TX_NOLOD);
2217 gSPTextureRectangle(gMainGfxPos++,
2218 4 * posX, 4 * posY,
2219 4 * (posX + num->texWidth), 4 * (posY + num->texHeight),
2220 G_TX_RENDERTILE,
2221 0, 0,
2222 1 << 10, 1 << 10);
2223}
2224
2225void draw_number(s32 value, s32 x, s32 y, s32 charset, s32 palette, s32 opacity, u16 style) {
2226 u8 valueStr[24];
2227 s8 digits[24];
2228 s32 digitPosX[24];
2229 s32 i;
2230 s32 count;
2231 s32 posX;
2232 IMG_PTR raster = gMsgNumbers[charset].rasters;
2233 s32 texSize = gMsgNumbers[charset].texSize;
2234
2235#if !VERSION_JP
2236 y -= 2;
2237#endif
2238 if (y < 0 || y > 240) {
2239 return;
2240 }
2241
2242 int_to_string(value, valueStr, 10);
2243
2244 for (i = 0; i < 10; i++) {
2245 u8 digit;
2246 if (valueStr[i] == '\0') {
2247 break;
2248 }
2249
2250 // handle negative numbers
2251 if (valueStr[i] == '-') {
2252 digits[i] = MSG_CHAR_MINUS - MSG_CHAR_DIGIT_0;
2253 continue;
2254 }
2255
2256 digit = valueStr[i] - '0';
2257 if (digit < 10){
2258 digits[i] = digit;
2259 }
2260 }
2261 posX = x;
2262 count = i;
2263
2264 gSPDisplayList(gMainGfxPos++, gMsgDlistInitDrawNumber);
2265
2266 if (style & DRAW_NUMBER_STYLE_ALIGN_RIGHT) {
2267 for (i = count - 1; i >= 0; i--) {
2268 if ((style & DRAW_NUMBER_STYLE_MONOSPACE) || digits[i] < 0) {
2269 posX -= gMsgNumbers[charset].fixedWidth;
2270 } else {
2271 posX -= gMsgNumbers[charset].digitWidth[digits[i]];
2272 }
2273 digitPosX[i] = posX;
2274 }
2275 } else {
2276 for (i = 0; i < count; i++) {
2277 digitPosX[i] = posX;
2278 if ((style & DRAW_NUMBER_STYLE_MONOSPACE) || digits[i] < 0) {
2279 posX += gMsgNumbers[charset].fixedWidth;
2280 } else {
2281 posX += gMsgNumbers[charset].digitWidth[digits[i]];
2282 }
2283 }
2284 }
2285
2286 if (style & DRAW_NUMBER_STYLE_DROP_SHADOW) {
2287 for (i = 0; i < count; i++) {
2288 gDPPipeSync(gMainGfxPos++);
2289 gDPSetRenderMode(gMainGfxPos++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
2290 gDPSetCombineMode(gMainGfxPos++, PM_CC_07, PM_CC_07);
2291 gDPSetPrimColor(gMainGfxPos++, 0, 0, 40, 40, 40, 72);
2292 draw_digit(raster + digits[i] * texSize, charset, digitPosX[i] + 2, y + 2);
2293 gDPPipeSync(gMainGfxPos++);
2294 }
2295 }
2296
2297 if (opacity == 255) {
2298 gDPSetRenderMode(gMainGfxPos++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
2299 gDPSetCombineMode(gMainGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
2300 } else {
2301 gDPSetRenderMode(gMainGfxPos++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
2302 gDPSetCombineMode(gMainGfxPos++, PM_CC_01, PM_CC_01);
2303 gDPSetPrimColor(gMainGfxPos++, 0, 0, 255, 255, 255, opacity);
2304 }
2305
2306 gDPLoadTLUT_pal16(gMainGfxPos++, 0, D_802F4560[palette]);
2307 for (i = 0; i < count; i++) {
2308 posX = digitPosX[i];
2309 if (posX > 0 && posX < 320) {
2310 draw_digit(raster + digits[i] * texSize, charset, posX, y);
2311 }
2312 }
2313 gDPPipeSync(gMainGfxPos++);
2314}
unsigned char charset_standard_pal_OFFSET[]
unsigned char charset_postcard_OFFSET[]
unsigned short charset_postcard_pal_OFFSET[]
unsigned char charset_standard_OFFSET[]
unsigned char charset_subtitle_pal_OFFSET[]
unsigned char charset_subtitle_OFFSET[]
unsigned char charset_title_OFFSET[]
u32 pressedButtons[4]
MessageCharData * rasters
#define IMG_BIN
Mtx matrixStack[0x200]
#define PAL_PTR
#define IMG_PTR
f32 Matrix4f[4][4]
#define PAL_BIN
s8 flags
Definition demo_api.c:15
#define general_heap_malloc
#define guRotateF
#define get_msg_width
#define guMtxF2L
#define guTranslateF
#define guMtxCatF
#define rand_int
#define draw_msg
#define guScaleF
@ DRAW_MSG_STYLE_DROP_SHADOW
Definition enums.h:4973
@ DRAW_MSG_STYLE_MENU
Definition enums.h:4970
@ DRAW_MSG_STYLE_RAINBOW
Definition enums.h:4972
@ DRAW_MSG_STYLE_WAVY
Definition enums.h:4971
@ DRAW_NUMBER_STYLE_ALIGN_RIGHT
drawn to the left of posX
Definition enums.h:4978
@ DRAW_NUMBER_STYLE_DROP_SHADOW
Definition enums.h:4981
@ DRAW_NUMBER_STYLE_MONOSPACE
Definition enums.h:4979
@ MSG_STATE_FLAG_10000
Definition enums.h:5837
@ MSG_STATE_FLAG_4
Definition enums.h:5826
@ MSG_STATE_FLAG_40
Definition enums.h:5829
@ MSG_STATE_FLAG_PRINT_QUICKLY
Definition enums.h:5831
@ MSG_STATE_FLAG_1
Definition enums.h:5824
@ MSG_STATE_FLAG_80000
Definition enums.h:5840
@ MSG_STATE_FLAG_10
Definition enums.h:5827
@ MSG_STATE_FLAG_20
Definition enums.h:5828
@ MSG_STATE_FLAG_100000
Definition enums.h:5841
@ MSG_STATE_FLAG_800
Definition enums.h:5833
@ MSG_STATE_FLAG_800000
Definition enums.h:5842
@ MSG_STATE_FLAG_20000
Definition enums.h:5838
@ MSG_STATE_FLAG_40000
Definition enums.h:5839
@ MSG_STATE_FLAG_8000
Definition enums.h:5836
@ MSG_STATE_FLAG_1000
Definition enums.h:5834
@ MSG_STATE_FLAG_SPEAKING
Definition enums.h:5830
@ MSG_STATE_FLAG_2
Definition enums.h:5825
@ BUTTON_A
Definition enums.h:2776
@ BUTTON_C_DOWN
Definition enums.h:2765
@ BUTTON_STICK_UP
Definition enums.h:2777
@ BUTTON_STICK_DOWN
Definition enums.h:2778
@ BUTTON_B
Definition enums.h:2775
@ BUTTON_Z
Definition enums.h:2774
@ MSG_PRINT_FUNC_RIGHT
Definition enums.h:5726
@ MSG_READ_FUNC_COLOR
Definition enums.h:5672
@ MSG_READ_FUNC_CURSOR
Definition enums.h:5697
@ MSG_READ_FUNC_RESTORE_COLOR
Definition enums.h:5704
@ MSG_READ_FUNC_VOLUME
Definition enums.h:5712
@ MSG_READ_FUNC_RESET_GFX
Definition enums.h:5670
@ MSG_PRINT_FUNC_UP
Definition enums.h:5728
@ MSG_READ_FUNC_START_FX
Definition enums.h:5705
@ MSG_READ_FUNC_INPUT_OFF
Definition enums.h:5674
@ MSG_PRINT_FUNC_COLOR
Definition enums.h:5719
@ MSG_PRINT_FUNC_OPTION
Definition enums.h:5736
@ MSG_READ_FUNC_VAR
Definition enums.h:5707
@ MSG_READ_FUNC_VARIANT
Definition enums.h:5668
@ MSG_READ_FUNC_SET_CURSOR
Definition enums.h:5696
@ MSG_READ_FUNC_SET_CANCEL
Definition enums.h:5699
@ MSG_READ_FUNC_DELAY_OFF
Definition enums.h:5676
@ MSG_PRINT_FUNC_FONT
Definition enums.h:5715
@ MSG_PRINT_FUNC_ITEM_ICON
Definition enums.h:5731
@ MSG_PRINT_FUNC_SPACING
Definition enums.h:5720
@ MSG_READ_FUNC_SAVE_COLOR
Definition enums.h:5703
@ MSG_READ_FUNC_VOICE
Definition enums.h:5713
@ MSG_READ_FUNC_SAVE_POS
Definition enums.h:5701
@ MSG_READ_FUNC_CUSTOM_VOICE
Definition enums.h:5711
@ MSG_PRINT_FUNC_ANIM_DELAY
Definition enums.h:5732
@ MSG_READ_FUNC_INLINE_IMAGE
Definition enums.h:5688
@ MSG_READ_FUNC_SET_X
Definition enums.h:5683
@ MSG_PRINT_FUNC_SET_Y
Definition enums.h:5725
@ MSG_PRINT_FUNC_ANIM_LOOP
Definition enums.h:5733
@ MSG_PRINT_FUNC_ANIM_SPRITE
Definition enums.h:5730
@ MSG_READ_FUNC_END_FX
Definition enums.h:5706
@ MSG_READ_FUNC_SET_Y
Definition enums.h:5684
@ MSG_PRINT_FUNC_INLINE_IMAGE
Definition enums.h:5729
@ MSG_PRINT_FUNC_SET_X
Definition enums.h:5724
@ MSG_PRINT_FUNC_SIZE_RESET
Definition enums.h:5723
@ MSG_READ_FUNC_SCROLL
Definition enums.h:5679
@ MSG_PRINT_FUNC_DOWN
Definition enums.h:5727
@ MSG_READ_FUNC_DOWN
Definition enums.h:5686
@ MSG_READ_FUNC_YIELD
Definition enums.h:5671
@ MSG_READ_FUNC_NO_SKIP
Definition enums.h:5673
@ MSG_PRINT_FUNC_SAVE_COLOR
Definition enums.h:5739
@ MSG_READ_FUNC_SPACING
Definition enums.h:5678
@ MSG_READ_FUNC_RESTORE_POS
Definition enums.h:5702
@ MSG_PRINT_FUNC_VARIANT
Definition enums.h:5716
@ MSG_READ_FUNC_SPEED
Definition enums.h:5682
@ MSG_READ_FUNC_OPTION
Definition enums.h:5700
@ MSG_READ_FUNC_SIZE
Definition enums.h:5680
@ MSG_READ_FUNC_ENABLE_CDOWN_NEXT
Definition enums.h:5710
@ MSG_READ_FUNC_HIDE_IMAGE
Definition enums.h:5692
@ MSG_READ_FUNC_DELAY_ON
Definition enums.h:5677
@ MSG_PRINT_FUNC_RESTORE_COLOR
Definition enums.h:5740
@ MSG_PRINT_FUNC_END_FX
Definition enums.h:5742
@ MSG_PRINT_FUNC_START_FX
Definition enums.h:5741
@ MSG_READ_FUNC_END_CHOICE
Definition enums.h:5698
@ MSG_READ_FUNC_IMAGE
Definition enums.h:5691
@ MSG_READ_FUNC_RIGHT
Definition enums.h:5685
@ MSG_PRINT_FUNC_RESTORE_POS
Definition enums.h:5738
@ MSG_READ_FUNC_ANIM_LOOP
Definition enums.h:5694
@ MSG_PRINT_FUNC_CURSOR
Definition enums.h:5735
@ MSG_READ_FUNC_CENTER_X
Definition enums.h:5708
@ MSG_READ_FUNC_ANIM_DELAY
Definition enums.h:5693
@ MSG_READ_FUNC_ITEM_ICON
Definition enums.h:5690
@ MSG_READ_FUNC_SET_REWIND
Definition enums.h:5709
@ MSG_PRINT_FUNC_SIZE
Definition enums.h:5722
@ MSG_READ_FUNC_UP
Definition enums.h:5687
@ MSG_PRINT_FUNC_ANIM_DONE
Definition enums.h:5734
@ MSG_READ_FUNC_INPUT_ON
Definition enums.h:5675
@ MSG_READ_FUNC_FONT
Definition enums.h:5667
@ MSG_READ_FUNC_SIZE_RESET
Definition enums.h:5681
@ MSG_PRINT_FUNC_CENTER_X
Definition enums.h:5743
@ MSG_PRINT_FUNC_SAVE_POS
Definition enums.h:5737
@ MSG_READ_FUNC_ANIM_SPRITE
Definition enums.h:5689
@ MSG_PRINT_RESET_GFX
Definition enums.h:5718
@ MSG_READ_FUNC_ANIM_DONE
Definition enums.h:5695
@ LANGUAGE_DE
Definition enums.h:5992
@ LANGUAGE_ES
Definition enums.h:5994
@ LANGUAGE_EN
Definition enums.h:5991
@ LANGUAGE_FR
Definition enums.h:5993
MsgVoices
Definition enums.h:5807
@ MSG_DELAY_FLAG_4
Definition enums.h:5848
@ MSG_DELAY_FLAG_2
Definition enums.h:5847
@ MSG_DELAY_FLAG_1
Definition enums.h:5846
@ EASING_LINEAR
Definition enums.h:510
@ MSG_STYLE_POSTCARD
Definition enums.h:5790
@ MSG_STYLE_CENTER
Definition enums.h:5784
@ MSG_STYLE_LEFT
Definition enums.h:5783
@ MSG_STYLE_UPGRADE
Definition enums.h:5793
@ MSG_STYLE_SIGN
Definition enums.h:5788
@ MSG_STYLE_F
Definition enums.h:5796
@ MSG_STYLE_B
Definition enums.h:5792
@ MSG_STYLE_NARRATE
Definition enums.h:5794
@ MSG_STYLE_INSPECT
Definition enums.h:5787
@ MSG_STYLE_LAMPPOST
Definition enums.h:5789
@ MSG_STYLE_POPUP
Definition enums.h:5791
@ MSG_STYLE_RIGHT
Definition enums.h:5782
@ MSG_STYLE_EPILOGUE
Definition enums.h:5795
@ MSG_STYLE_TATTLE
Definition enums.h:5785
@ MSG_STYLE_CHOICE
Definition enums.h:5786
@ MSG_PRINT_FLAG_100
Definition enums.h:5820
@ SOUND_MSG_VOICE_1A
Definition enums.h:565
@ SOUND_MSG_REWIND
Definition enums.h:707
@ SOUND_MENU_SHOW_CHOICE
Definition enums.h:557
@ SOUND_MSG_WAIT
Definition enums.h:705
@ SOUND_MENU_BACK
Definition enums.h:704
@ SOUND_MSG_UNREWIND
Definition enums.h:708
@ SOUND_APPROVE
Definition enums.h:935
@ SOUND_MSG_VOICE_1B
Definition enums.h:566
@ SOUND_MENU_CHANGE_SELECTION
Definition enums.h:701
@ SOUND_MSG_SKIP
Definition enums.h:706
@ SOUND_MENU_NEXT
Definition enums.h:703
@ MSG_FX_NOISE_OUTLINE
Definition enums.h:5749
@ MSG_FX_RISE_PRINT
Definition enums.h:5756
@ MSG_FX_SIZE_JITTER
Definition enums.h:5758
@ MSG_FX_SHAKE
Definition enums.h:5747
@ MSG_FX_GLOBAL_WAVE
Definition enums.h:5754
@ MSG_FX_GLOBAL_RAINBOW
Definition enums.h:5755
@ MSG_FX_DROP_SHADOW
Definition enums.h:5760
@ MSG_FX_SIZE_WAVE
Definition enums.h:5759
@ MSG_FX_STATIC
Definition enums.h:5750
@ MSG_FX_BLUR
Definition enums.h:5751
@ MSG_FX_DITHER_FADE
Definition enums.h:5753
@ MSG_FX_WAVE
Definition enums.h:5748
@ MSG_FX_RAINBOW
Definition enums.h:5752
@ MSG_FX_GROW_PRINT
Definition enums.h:5757
@ MSG_CHAR_LOWER_S
Definition enums.h:5524
@ MSG_CHAR_READ_VARIANT2
Definition enums.h:5633
@ MSG_CHAR_DIGIT_0
Definition enums.h:5457
@ MSG_CHAR_READ_PAUSE
Definition enums.h:5630
@ MSG_CHAR_PRINT_SPACE
Definition enums.h:5652
@ MSG_CHAR_READ_WAIT
Definition enums.h:5629
@ MSG_CHAR_MINUS
Definition enums.h:5454
@ MSG_CHAR_READ_HALF_SPACE
Definition enums.h:5637
@ MSG_CHAR_READ_SPACE
Definition enums.h:5635
@ MSG_CHAR_PRINT_NEXT
Definition enums.h:5657
@ MSG_CHAR_READ_VARIANT3
Definition enums.h:5634
@ MSG_CHAR_READ_STYLE
Definition enums.h:5640
@ MSG_CHAR_PRINT_END
Definition enums.h:5658
@ MSG_CHAR_PRINT_ENDL
Definition enums.h:5647
@ MSG_CHAR_READ_FULL_SPACE
Definition enums.h:5636
@ MSG_CHAR_READ_UNK_CHAR_FA
Definition enums.h:5638
@ MSG_CHAR_READ_NEXT
Definition enums.h:5639
@ MSG_CHAR_PRINT_FULL_SPACE
Definition enums.h:5653
@ MSG_CHAR_READ_VARIANT0
Definition enums.h:5631
@ MSG_CHAR_PRINT_VARIANT0
Definition enums.h:5648
@ MSG_CHAR_PRINT_FUNCTION
Definition enums.h:5662
@ MSG_CHAR_PRINT_STYLE
Definition enums.h:5655
@ MSG_CHAR_PRINT_UNK_CHAR_FA
Definition enums.h:5656
@ MSG_CHAR_READ_ENDL
Definition enums.h:5628
@ MSG_CHAR_PRINT_HALF_SPACE
Definition enums.h:5654
@ MSG_CHAR_UNK_C3
Definition enums.h:5619
@ MSG_CHAR_READ_END
Definition enums.h:5641
@ MSG_CHAR_READ_VARIANT1
Definition enums.h:5632
@ MSG_CHAR_LOWER_N
Definition enums.h:5519
@ MSG_CONTROL_CHAR
Definition enums.h:5646
@ MSG_CHAR_READ_FUNCTION
Definition enums.h:5643
@ MSG_WINDOW_STATE_DONE
Definition enums.h:5852
@ MSG_WINDOW_STATE_B
Definition enums.h:5863
@ MSG_WINDOW_STATE_WAITING
Definition enums.h:5857
@ MSG_WINDOW_STATE_WAITING_FOR_CHOICE
Definition enums.h:5859
@ MSG_WINDOW_STATE_INIT
Definition enums.h:5853
@ MSG_WINDOW_STATE_OPENING
Definition enums.h:5854
@ MSG_WINDOW_STATE_SCROLLING
Definition enums.h:5858
@ MSG_WINDOW_STATE_PRINTING
Definition enums.h:5856
@ MSG_WINDOW_STATE_C
Definition enums.h:5864
@ MSG_WINDOW_STATE_E
Definition enums.h:5866
@ MSG_WINDOW_STATE_SCROLLING_BACK
Definition enums.h:5860
@ MSG_WINDOW_STATE_D
Definition enums.h:5865
@ MSG_WINDOW_STATE_CLOSING
Definition enums.h:5855
@ MSG_WINDOW_STATE_VIEWING_PREV
Definition enums.h:5861
@ MSG_WINDOW_STATE_A
Definition enums.h:5862
f32 update_lerp(s32 easing, f32 start, f32 end, s32 elapsed, s32 duration)
Definition 43F0.c:735
s32 draw_ci_image_with_clipping(u8 *raster, s32 width, s32 height, s32 fmt, s32 bitDepth, u16 *palette, s16 posX, s16 posY, u16 clipULx, u16 clipULy, u16 clipLRx, u16 clipRLy, u8 opacity)
f32 cosine(s16 arg0)
Definition 43F0.c:352
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:442
s32 general_heap_free(void *data)
Definition heap.c:18
char * int_to_string(s32, char *, s32)
Definition 43F0.c:384
void * heap_malloc(s32 size)
Definition heap.c:34
s32 gItemIconPaletteOffsets[]
void msg_draw_rewind_arrow(s32)
Definition msg.c:2147
void get_msg_properties(s32 msgID, s32 *height, s32 *width, s32 *maxLineChars, s32 *numLines, s32 *maxLinesPerPage, s32 *numSpaces, u16 charset)
Definition msg.c:1673
IMG_BIN ui_msg_rewind_arrow_png[]
void msg_printer_set_origin_pos(MessagePrintState *msgPrintState, s32 x, s32 y)
Definition msg.c:1491
MessagePrintState * _msg_get_printer_for_msg(s32 msgID, s32 *donePrintingWriteback, s32 arg2)
Definition msg.c:1430
s16 gNextMessageBuffer
Definition msg.c:62
s32 cancel_message(MessagePrintState *msgPrintState)
Definition msg.c:1509
s8 * load_message_to_buffer(s32 msgID)
Definition msg.c:1412
IMG_BIN MsgCharImgSubtitle[]
Definition msg_img.c:92
PAL_BIN D_8015C7E0[0x10]
Definition msg.c:105
void render_messages(void)
Definition msg.c:573
u8 MessageSingular[]
Definition msg.c:48
Vtx gRewindArrowQuad[]
Definition msg.c:64
s32 draw_image_with_clipping(IMG_PTR raster, s32 width, s32 height, s32 fmt, s32 bitDepth, s16 posX, s16 posY, u16 clipULx, u16 clipULy, u16 clipLRx, u16 clipRLy)
IMG_BIN D_80159B50[0x200]
Definition msg.c:104
void clear_character_set(void)
Definition msg.c:192
s16 MsgStyleVerticalLineOffsets[]
Definition msg_data.c:927
PAL_PTR MsgLetterPaletteOffsets[]
Definition msg_data.c:893
s32 msg_get_print_char_width(s32 character, s32 charset, s32 variation, f32 msgScale, s32 overrideCharWidth, u8 flags)
Definition msg.c:1580
PAL_BIN ui_msg_rewind_arrow_pal[]
void close_message(MessagePrintState *msgPrintState)
Definition msg.c:1570
Vp D_8014C280
Definition msg.c:34
void appendGfx_message(MessagePrintState *, s16, s16, u16, u16, u16, u8)
Definition msg_draw.c:213
Gfx * D_80151338
Definition msg.c:93
void draw_digit(IMG_PTR img, s32 charset, s32 posX, s32 posY)
Definition msg.c:2205
IMG_BIN MsgCharImgTitle[]
Definition msg_img.c:90
#define MSG_ROM_START
Definition msg.c:23
void clear_printers(void)
Definition msg.c:196
MessageImageData * MessageImageDataList[1]
Definition msg.c:32
s32 gItemIconRasterOffsets[]
#define CHOICE_POINTER_MOVE_RATE
Definition msg.c:29
u16 gMsgGlobalWaveCounter
Definition msg.c:89
Gfx gMsgDlistInitDrawNumber[]
Definition msg.c:165
u8 MessagePlural[]
Definition msg.c:42
void dma_load_msg(u32 msgID, void *dest)
Definition msg.c:1398
s32 msg_get_draw_char_width(s32 character, s32 charset, s32 variation, f32 msgScale, s32 overrideCharWidth, u16 flags)
Definition msg.c:1630
void msg_play_speech_sound(MessagePrintState *printer, u8 character)
Definition msg.c:614
s32 gMsgBGScrollAmtY
Definition msg.c:91
void initialize_printer(MessagePrintState *printer, s32 arg1, s32 arg2)
Definition msg.c:1305
void load_font_data(Addr offset, u16 size, void *dest)
Definition msg.c:218
IMG_BIN ui_msg_star_png[]
IMG_BIN MsgCharImgNormal[]
Definition msg_img.c:91
s32 get_msg_lines(s32 msgID)
Definition msg.c:1981
MessageNumber gMsgNumbers[]
Definition msg.c:129
PAL_BIN D_802F4560[80][8]
void set_message_int_var(s32 value, s32 index)
Definition msg.c:1552
void set_message_text_var(s32 msgID, s32 index)
Definition msg.c:1522
Gfx D_8014C2D8[]
Definition msg.c:71
IMG_BIN ui_msg_star_silhouette_png[]
void msg_update_rewind_arrow(s32)
Definition msg.c:2063
MessagePrintState * msg_get_printer_for_msg(s32 msgID, s32 *donePrintingWriteback)
Definition msg.c:1426
void draw_message_window(MessagePrintState *printer)
Definition msg_draw.c:137
void msg_copy_to_print_buffer(MessagePrintState *printer, s32 arg1, s32 arg2)
Definition msg.c:647
void load_font(s32 font)
Definition msg.c:225
void draw_number(s32 value, s32 x, s32 y, s32 charset, s32 palette, s32 opacity, u16 style)
Definition msg.c:2225
void set_message_images(MessageImageData *images)
Definition msg.c:1518
MessageImageDataList gMsgVarImages
Definition msg.c:90
IMG_BIN ui_point_right_png[]
s32 msg_printer_load_msg(s32 msgID, MessagePrintState *printer)
Definition msg.c:1476
s32 _update_message(MessagePrintState *printer)
Definition msg.c:277
MessageCharset * MsgCharsets[5]
Definition msg_data.c:865
void msg_draw_choice_pointer(MessagePrintState *printer)
Definition msg.c:2161
#define CHAR_SPACE_MULTIPLIER
Definition msg.c:1577
IMG_PTR MsgLetterRasterOffsets[]
Definition msg_data.c:878
void update_messages(void)
Definition msg.c:253
u8 * D_8015131C
Definition msg.c:92
PAL_BIN ui_point_right_pal[]
RewindArrowStates
Definition msg.c:10
@ REWIND_ARROW_STATE_NEUTRAL
Definition msg.c:13
@ REWIND_ARROW_STATE_INIT
Definition msg.c:11
@ REWIND_ARROW_STATE_CHANGE_COLOR_BACK
Definition msg.c:15
@ REWIND_ARROW_STATE_GROW
Definition msg.c:12
@ REWIND_ARROW_STATE_CHANGE_COLOR
Definition msg.c:14
s32 gMsgBGScrollAmtX
Definition msg.c:88
IMG_BIN MsgCharImgLatin[]
IMG_BIN MsgCharImgMenuKana[]
IMG_BIN MsgCharImgMenuLatin[]
IMG_BIN MsgCharImgKana[]
void sfx_play_sound_with_params(s32 soundID, u8 volume, u8 pan, s16 pitchShift)
#define PM_CC_MSG_UP_ARROW
Definition macros.h:309
#define PM_CC_07
Definition macros.h:294
#define SCREEN_WIDTH
Definition macros.h:108
#define ARRAY_COUNT(arr)
Definition macros.h:39
#define PM_CC_01
Definition macros.h:287
#define SCREEN_HEIGHT
Definition macros.h:109
#define DT
Definition macros.h:534
#define VIRTUAL_TO_PHYSICAL(addr)
Definition macros.h:46
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
Definition types.h:16
#define gCurrentLanguage
Definition variables.h:119
GameStatus * gGameStatusPtr
Definition main_loop.c:31
Gfx * gMainGfxPos
Definition cam_main.c:14
u16 gMatrixListPos
Definition main_loop.c:44
s32 gCurrentDisplayContextIndex
Definition main_loop.c:46
DisplayContext * gDisplayContext
Definition cam_main.c:15