Alchemy
Loading...
Searching...
No Matches

options.c

Go to the documentation of this file.
1/// @file
2/// Window colours, the option screen and the system menu.
3/// Part of window.c, the window object, compiled only through it.
4
6
7/// Nothing calls them.
11
12/// One of the seven entries of the option screen's work from offset 0x400;
13/// only its state is known.
15 u8 unk00[10];
17 u8 unk0c[40];
18};
19
20/// Clears the option screen's seven entry states, its row, its tint and its
21/// cursor animation.
22/// Nothing calls it.
24 struct MenuWorkspaceEntry *entry =
25 (struct MenuWorkspaceEntry *)((u8 *)work + 0x400);
26 u16 zero = 0;
27
28 entry->state = zero;
29 entry++;
30 entry->state = zero;
31 entry++;
32 entry->state = zero;
33 entry++;
34 entry->state = zero;
35 entry++;
36 entry->state = zero;
37 entry++;
38 entry->state = zero;
39 entry++;
40 entry->state = zero;
41 work->page = zero;
42 work->tint[0] = zero;
43 work->tint[1] = zero;
44 work->tint[2] = zero;
45 work->cursorFrame = zero;
46}
47
48/// Works out the window tint (red, green and blue, 0 to 31) from the window
49/// colour settings: the hue picks a point on the colour wheel and the
50/// brightness shifts all three channels.
51/// The three wave samples are one third of the 96-step colour cycle apart.
52/// Nothing calls it.
54 s16 phase;
55 s32 bias;
56 s32 blue;
57 s32 red;
58 s32 green;
59
60 phase = (gGameState.paletteGlow[0] + 12) % 24 * 4;
61 bias = gGameState.paletteGlow[1] - 7;
62 red = gPaletteGlow_WaveTable[(phase % 96)];
63 green = gPaletteGlow_WaveTable[(phase + 32) % 96];
64 blue = gPaletteGlow_WaveTable[(phase + 64) % 96];
65 red += bias;
66 green += bias;
67 blue += bias;
68 if (red < 0)
69 red = 0;
70 if (green < 0)
71 green = 0;
72 if (blue < 0)
73 blue = 0;
74 if (red > 31)
75 red = 31;
76 if (green > 31)
77 green = 31;
78 if (blue > 31)
79 blue = 31;
80 work->tint[0] = red;
81 work->tint[1] = green;
82 work->tint[2] = blue;
83}
84
85/// Writes window colours 4 to 10 of BG palette 15, each a fixed scale of the
86/// window tint.
87/// Nothing calls it.
89 *(s16 *)&BG_PLTT_COLOR(15, 4) =
90 WindowColor_ScaleTint(work, 0xEEEE, 0xCCCC, 0x11110);
91 *(s16 *)&BG_PLTT_COLOR(15, 5) =
92 WindowColor_ScaleTint(work, 0xD555, 0xBBBB, 0xEEEE);
93 *(s16 *)&BG_PLTT_COLOR(15, 6) =
94 WindowColor_ScaleTint(work, 0xBBBB, 0xAAAA, 0xCCCC);
95 *(s16 *)&BG_PLTT_COLOR(15, 7) =
96 WindowColor_ScaleTint(work, 0xA221, 0x9999, 0xAAAA);
97 *(s16 *)&BG_PLTT_COLOR(15, 8) =
98 WindowColor_ScaleTint(work, 0x10888, 0xDDDD, 0x13333);
99 *(s16 *)&BG_PLTT_COLOR(15, 9) =
100 WindowColor_ScaleTint(work, 0x12221, 0xEEEE, 0x15555);
101 *(s16 *)&BG_PLTT_COLOR(15, 10) =
102 WindowColor_ScaleTint(work, 0x13BBB, 0x10000, 0x17777);
103}
104
105/// Returns the window tint with each channel scaled (16.16 fixed point) and
106/// clamped to 0 to 31, as a BGR555 colour.
108 s32 greenScale, s32 blueScale) {
109 s32 red;
110 s32 green;
111 s32 blue;
112
113 red = Iwram_MulQ16(work->tint[0] << 16, redScale) >> 16;
114 green = Iwram_MulQ16(work->tint[1] << 16, greenScale) >> 16;
115 blue = Iwram_MulQ16(work->tint[2] << 16, blueScale) >> 16;
116 if (red < 0)
117 red = 0;
118 if (green < 0)
119 green = 0;
120 if (blue < 0)
121 blue = 0;
122 if (red > 31)
123 red = 31;
124 if (green > 31)
125 green = 31;
126 if (blue > 31)
127 blue = 31;
128 return red + ((blue << 10) + (green << 5));
129}
130
131/// Returns rgb with each channel scaled (16.16 fixed point) and clamped to 0 to
132/// 31, as a BGR555 colour.
133/// rgb holds three components, not an already packed palette word.
134u16 Color_ScaleComponents(s16 *rgb, s32 redScale, s32 greenScale,
135 s32 blueScale) {
136 s32 red;
137 s32 green;
138 s32 blue;
139
140 red = Iwram_MulQ16(rgb[0] << 16, redScale) >> 16;
141 green = Iwram_MulQ16(rgb[1] << 16, greenScale) >> 16;
142 blue = Iwram_MulQ16(rgb[2] << 16, blueScale) >> 16;
143 CLAMP(red, 0, 31);
144 CLAMP(green, 0, 31);
145 CLAMP(blue, 0, 31);
146 return red + ((blue << 10) + (green << 5));
147}
148
149/// Sets the window colours (BG palette 15, colours 4 to 10) for a window hue
150/// (0 to 23) and brightness (0 to 14, 7 neutral).
151/// The live palette path leaves the saved colour settings untouched.
152void PaletteGlow_Update(s32 phase, s32 brightness) {
153 s16 rgb[3];
154 s16 step;
155 s16 red;
156 s16 green;
157 s16 blue;
158 s16 offset;
159
160 step = ((phase + 12) % 24) * 4;
161 offset = brightness - 7;
162 red = gPaletteGlow_WaveTable[(step % 96)] + offset;
163 green = gPaletteGlow_WaveTable[(step + 32) % 96] + offset;
164 blue = gPaletteGlow_WaveTable[(step + 64) % 96] + offset;
165 CLAMP(red, 0, 31);
166 CLAMP(green, 0, 31);
167 CLAMP(blue, 0, 31);
168 rgb[0] = red;
169 rgb[1] = green;
170 rgb[2] = blue;
171 BG_PLTT_COLOR(15, 4) = Color_ScaleComponents(rgb, 0xeeee, 0xcccc, 0x11110);
172 BG_PLTT_COLOR(15, 5) = Color_ScaleComponents(rgb, 0xd555, 0xbbbb, 0xeeee);
173 BG_PLTT_COLOR(15, 6) = Color_ScaleComponents(rgb, 0xbbbb, 0xaaaa, 0xcccc);
174 BG_PLTT_COLOR(15, 7) = Color_ScaleComponents(rgb, 0xa221, 0x9999, 0xaaaa);
175 BG_PLTT_COLOR(15, 8) = Color_ScaleComponents(rgb, 0x10888, 0xdddd, 0x13333);
176 BG_PLTT_COLOR(15, 9) = Color_ScaleComponents(rgb, 0x12221, 0xeeee, 0x15555);
177 BG_PLTT_COLOR(15, 10) = Color_ScaleComponents(rgb, 0x13bbb, 0x10000, 0x17777);
178}
179
180/// Moves the three-row settings cursor up, wrapping to the bottom.
181/// Nothing calls it.
183 if (work->page == 0)
184 work->page = 2;
185 else
186 work->page--;
187}
188
189/// Moves the three-row settings cursor down, wrapping to the top.
190/// Nothing calls it.
192 if (++work->page > 2)
193 work->page = 0;
194}
195
196/// Lowers the setting on the three-row cursor's row: message speed, window hue
197/// or window brightness.
198/// Nothing calls it.
200 switch (work->page) {
201 case 0:
202 if (gGameState.messageSpeed != 0)
204 break;
205 case 1:
206 if (gGameState.paletteGlow[0] != 0)
208 break;
209 case 2:
210 if (gGameState.paletteGlow[1] != 0)
212 break;
213 }
214}
215
216/// Raises the setting on the three-row cursor's row: message speed, window hue
217/// or window brightness.
218/// Nothing calls it.
220 switch (work->page) {
221 case 0:
222 if (gGameState.messageSpeed <= 1)
224 break;
225 case 1:
226 if (gGameState.paletteGlow[0] <= 23)
228 break;
229 case 2:
230 if (gGameState.paletteGlow[1] <= 14)
232 break;
233 }
234}
235
237
238/// The option screen's per-frame callback: moves the cursor and the two slider
239/// markers, animates the marker of the slider in use, and pulses the chosen
240/// setting's icon.
242 s32 cursorResource;
243 s32 markerResource;
244 s32 selectedOption;
245 struct WorkspaceWork *work;
246
247 work = gSelectionWork;
248 selectedOption = work->page;
252
253 if (selectedOption == 0) {
254 cursorResource =
256 } else {
257 cursorResource = (s32)&ResourceId_ShopCursorFrames;
258 }
259 VramCache_Load((u8)work->marker[0].output->index, 0x100,
260 Resource_GetTableEntry(cursorResource));
261
262 if (selectedOption == 1) {
263 markerResource =
265 } else {
266 markerResource = (s32)&ResourceId_ShopCursorFrames;
267 }
268 VramCache_Load((u8)work->marker[1].output->index, 0x100,
269 Resource_GetTableEntry(markerResource));
270
271 if (selectedOption > 1)
273 work->frame[selectedOption - 2][work->option[selectedOption]]);
274 work->cursorFrame++;
275}
276
277/// Allocates the option screen's work block, copies the settings into it with
278/// how many values each takes, and starts its per-frame callback.
279/// The copy lets cancelling discard the edits.
281 struct WorkspaceWork *work;
282
283 work = Runtime_AllocateBlock(20, 0x628);
284 Dma_Fill32(0, work, 0x628);
285 work->option[0] = gGameState.paletteGlow[0];
286 work->optionCount[0] = 24;
287 work->option[1] = gGameState.paletteGlow[1];
288 work->optionCount[1] = 15;
289 work->option[2] = gGameState.messageSpeed;
290 work->optionCount[2] = 3;
291 work->option[3] = gGameState.speech;
292 work->optionCount[3] = 2;
294 work->optionCount[4] = 2;
296}
297
298/// Stops the option screen's per-frame callback and frees its work block.
299/// The callback goes first, since it reads the work block.
303}
304
305#define SLIDER_PALETTE 14
306#define RESOURCE_SLOTS 96
307
308/// Opens the option screen's window: the labels, the hue and brightness
309/// sliders with their markers, the cursor and the setting icons. Returns the
310/// window.
312 /* FAKEMATCH: the shared cursor union keeps pointer stores before window
313 * reads; an equal-size struct reorders these moves in all six editions. */
314 struct WorkspaceWork *work;
315 struct UiWindow *window;
316 struct RenderOutput *marker;
317 s32 x;
318 s32 y;
319 s32 labelMessage;
320
321 work = gSelectionWork;
323 UiWindow_DrawDividerLine(window, 0, 2, OPTION_WINDOW_WIDTH - 1, 2);
324 UiWindow_DrawDividerLine(window, 0, 4, OPTION_WINDOW_WIDTH - 1, 4);
325 UiWindow_DrawDividerLine(window, 0, 7, OPTION_WINDOW_WIDTH - 1, 7);
326 UiWindow_DrawDividerLine(window, 0, 10, OPTION_WINDOW_WIDTH - 1, 10);
327 labelMessage = MsgWindowColorLabel;
328 UiText_DrawCharacterAtOffset(labelMessage, window, 8, 0);
329 labelMessage++;
330 UiText_DrawCharacterAtOffset(labelMessage, window, 8, 16);
331#if (LANGUAGE != LANGUAGE_JAPANESE)
332 labelMessage = MsgMessageSpeedLabel;
333 UiText_DrawCharacterAtOffset(labelMessage, window, 8, 32);
334 labelMessage++;
335 UiText_DrawCharacterAtOffset(labelMessage, window, 32, 40);
336#else
337 UiText_DrawCharacterAtOffset(MsgMessageSpeedLabel, window, 8, 40);
338#endif
339 UiText_DrawCharacterAtOffset(MsgSpeechLabel, window, 8, 64);
340 UiText_DrawCharacterAtOffset(MsgAutoSleepLabel, window, 8, 88);
341
343 if (x < RESOURCE_SLOTS) {
345 marker = RenderOutput_Create(x, 0x40000000, window, 0, 0);
346 work->cursor.output = marker;
347 x = window->x * 8;
348 y = window->y * 8 + 12;
350 }
351
353 if (x < RESOURCE_SLOTS) {
355 (void *)&OBJ_PLTT_COLOR(SLIDER_PALETTE, 0), DMA_COPY16(32),
356 REG_DMA3);
358 y = 0;
359 marker = RenderOutput_Create(x, 0x40004000, window, OPTION_SLIDER_X - 6, y);
360 marker->oam.palette = SLIDER_PALETTE;
361 marker =
362 RenderOutput_Create(x, 0x40004000, window, OPTION_SLIDER_X + 26, y);
363 marker->oam.index += 4;
364 marker->oam.palette = SLIDER_PALETTE;
365 y = 16;
366 marker = RenderOutput_Create(x, 0x40004000, window, OPTION_SLIDER_X - 6, y);
367 marker->oam.palette = 15;
368 marker =
369 RenderOutput_Create(x, 0x40004000, window, OPTION_SLIDER_X + 26, y);
370 marker->oam.index += 4;
371 marker->oam.palette = 15;
372 }
373
375 if (x < RESOURCE_SLOTS) {
376 VramCache_Load(x, 256, 0);
377 marker = RenderOutput_Create(x, 0x40000000, window, 0, 0);
378 marker->oam.palette256 = 1;
379 work->marker[0].output = marker;
380 x = window->x * 8 + OPTION_SLIDER_X;
381 x += work->option[0] * 60 / work->optionCount[0];
382 y = window->y * 8 + 4;
384 }
385
387 if (x < RESOURCE_SLOTS) {
388 VramCache_Load(x, 256, 0);
389 marker = RenderOutput_Create(x, 0x40000000, window, 0, 0);
390 marker->oam.palette256 = 1;
391 work->marker[1].output = marker;
392 x = window->x * 8 + OPTION_SLIDER_X;
393 x += work->option[1] * 60 / work->optionCount[1];
394 y = window->y * 8 + 20;
396 }
397
398 y = 28;
400 window, OPTION_FRAME_X, y);
401 work->frame[0][1] = RenderResource_CreateFrame(
402 gOptionMenu_SpeedFrames[1], 0, window, OPTION_FRAME_X + 24, y);
403 work->frame[0][2] = RenderResource_CreateFrame(
404 gOptionMenu_SpeedFrames[2], 0, window, OPTION_FRAME_X + 48, y);
405 y = 52;
407 window, 100, y);
409 window, 124, y);
410 y = 76;
411 work->frame[2][0] =
413 work->frame[2][1] =
415 return window;
416}
417
418/// Runs the option screen (window colour and brightness, message speed,
419/// speech, auto-sleep) until A or START keeps the settings (returns 0) or B
420/// drops them (returns -1). SELECT cycles through the colour presets.
421/// Preview edits affect the live palette; only confirmation saves the settings.
423 struct WorkspaceWork *work;
424 struct UiWindow *settingsWindow;
425 struct UiWindow *helpWindow;
426 struct RenderOutput *pair;
427 s8 *hue;
428 s8 *brightness;
429 s32 redraw;
430 s32 selectedOption;
431 s32 i;
432 s32 dimmed;
433 s32 resourceIndex;
434 s32 x;
435 s32 y;
436 s32 result;
437 struct RenderOutput *frame;
438
439 redraw = 1;
440 selectedOption = 0;
442 work = gSelectionWork;
444 settingsWindow = OptionMenu_Open();
445 pair = RenderResource_CreatePair(7, settingsWindow, 64, -48);
446 WaitFrames(1);
447 hue = &work->option[0];
448 brightness = &work->option[1];
449
450 for (;;) {
451 if (redraw != 0) {
452 redraw = 0;
453 selectedOption = (selectedOption + 5) % 5;
454 work->option[selectedOption] =
455 (work->option[selectedOption] + work->optionCount[selectedOption]) %
456 work->optionCount[selectedOption];
457 work->page = selectedOption;
458 if (gSleepDisabled != 0)
459 work->option[4] = 0;
460
461 for (i = 0; i <= 2; i++) {
462 frame = work->frame[0][i];
463 frame->sentinel = 0xfb;
465 resourceIndex = (u8)work->frame[0][i]->index;
466 dimmed = 0;
467 if (i != work->option[2])
468 dimmed = 1;
470 dimmed);
471 }
472 for (i = 0; i <= 1; i++) {
473 frame = work->frame[1][i];
474 frame->sentinel = 0xfb;
476 resourceIndex = (u8)work->frame[1][i]->index;
477 dimmed = 0;
478 if (i != work->option[3])
479 dimmed = 1;
481 dimmed);
482 }
483 for (i = 0; i <= 1; i++) {
484 frame = work->frame[2][i];
485 frame->sentinel = 0xfb;
487 resourceIndex = (u8)work->frame[2][i]->index;
488 dimmed = 0;
489 if (i != work->option[4])
490 dimmed = 1;
492 dimmed);
493 }
494
495 x = settingsWindow->x * 8 + OPTION_SLIDER_X;
496 x += (*hue * 60) / work->optionCount[0];
497 y = settingsWindow->y * 8 + 4;
498 Shop_SetCursorFar(&work->marker[0].cursor, x, y, 1);
499 x = settingsWindow->x * 8 + OPTION_SLIDER_X;
500 x += (*brightness * 60) / work->optionCount[1];
501 y = settingsWindow->y * 8 + 20;
502 Shop_SetCursorFar(&work->marker[1].cursor, x, y, 1);
503
504 x = work->option[2] + MsgMessageSpeedSetting;
506 OPTION_SPEED_END, 48);
507 UiText_DrawCharacterAtOffset(x, settingsWindow, OPTION_SETTING_X, 40);
508 x = work->option[3] + MsgSpeechSetting;
511 UiText_DrawCharacterAtOffset(x, settingsWindow, OPTION_SETTING_X, 64);
512 x = work->option[4] + MsgAutoSleepSetting;
515 UiText_DrawCharacterAtOffset(x, settingsWindow, OPTION_SETTING_X, 88);
516 PaletteGlow_Update(*hue, *brightness);
517
518 x = settingsWindow->x * 8;
519 y = (selectedOption * 3 + settingsWindow->y) * 8 + 4;
520 if (selectedOption == 0)
521 y += 8;
522 Shop_SetCursorFar(&work->cursor.cursor, x, y, 3);
523 RenderOutput_ClearList(helpWindow);
524 UiText_DrawResource(selectedOption + MsgOptionHelp, helpWindow, 0, 0);
525 }
527 WaitFrames(1);
528
529 if (gKeysPressed & KEY_SELECT) {
531 work->preset++;
532 redraw = 1;
533 if (work->preset > 5)
534 work->preset = 0;
535 *hue = gOptionMenu_HuePresets[work->preset];
536 *brightness = gOptionMenu_BrightnessPresets[work->preset];
537 continue;
538 }
539 if (gKeysPressed & (KEY_A | KEY_START)) {
540 result = 0;
542 break;
543 }
544 if (gKeysPressed & KEY_B) {
545 result = -1;
547 break;
548 }
549 if (gKeysRepeat & KEY_UP) {
551 selectedOption--;
552 redraw = 1;
553 } else if (gKeysRepeat & KEY_DOWN) {
555 selectedOption++;
556 redraw = 1;
557 } else {
558 if (gKeysRepeat & KEY_LEFT) {
560 work->option[selectedOption]--;
561 redraw = 1;
562 }
563 if (gKeysRepeat & KEY_RIGHT) {
565 work->option[selectedOption]++;
566 redraw = 1;
567 }
568 }
569 }
570
571 UiWork_Finalize(helpWindow, 2);
572 UiWork_Finalize(settingsWindow, 2);
573 if (result == 0) {
574 gGameState.paletteGlow[0] = work->option[0];
575 gGameState.paletteGlow[1] = work->option[1];
576 gGameState.messageSpeed = work->option[2];
577 gGameState.speech = work->option[3];
580 } else {
582 }
584 WaitFrames(1);
585 return result;
586}
587
588#define WORKSPACE_ROWS 3
589#define WORKSPACE_DEBUG_ROWS 3
590#define WORKSPACE_ROW_HEIGHT 24
591#define WORKSPACE_TEXT_X 48
592
593/// The system menu's per-frame callback: moves the cursor and pulses the
594/// chosen entry's icon.
596 struct WorkspaceWork *work = gSelectionWork;
597 u32 index;
598
600 index = work->page;
601 Ui_ApplyTableScaleToObject(work->icon[index]);
602}
603
604/// Allocates the system menu's work block and starts its per-frame callback.
605/// The system menu shares the option workspace slot and cannot run
606/// concurrently.
608 void *work;
609 work = Runtime_AllocateBlock(20, 0x628);
610 Dma_Fill32(0, work, 0x628);
612}
613
614/// Stops the system menu's per-frame callback and frees its work block.
615/// The callback goes first, since it reads the work block.
619}
620
621/// Opens the system menu's window with its entries (Save your quest, Sleep,
622/// Change settings, and the debug entries in debug mode; only Change settings
623/// while FLAG_IN_LINK_LOBBY is set), their icons and the cursor. Returns the
624/// window.
626 struct WorkspaceWork *work;
627 s32 rows;
628 s32 first;
629 s32 settingsOnly;
630 s32 top;
631 s32 height;
632 struct UiWindow *window;
633 s32 y;
634 s32 cacheSlot;
635 s32 labelMessage;
636 s32 i;
637 s32 x;
638
639 rows = WORKSPACE_ROWS;
640 work = gSelectionWork;
641 settingsOnly = GameFlag_TestFar(FLAG_IN_LINK_LOBBY);
642 first = 0;
643 if (settingsOnly != 0) {
644 rows = 1;
645 first = 2;
646 }
647 if (gDebugMode != 0)
648 rows += WORKSPACE_DEBUG_ROWS;
649 top = 8 - rows;
650 height = rows * 3 + 1;
651 if (top + height > 19) {
652 top = 1;
653 height = 19;
654 }
655 window = UiWindow_Create(5, top, 20, height, 2);
656 for (i = 1; i < rows; i++)
657 UiWindow_DrawDividerLine(window, 0, i * 3, 19, i * 3);
658 y = 4;
659 if (settingsOnly == 0) {
660 labelMessage = MsgWorkspaceSaveQuest;
661 UiText_DrawResource(labelMessage, window, WORKSPACE_TEXT_X, 4);
662 labelMessage++;
663 UiText_DrawResource(labelMessage, window, WORKSPACE_TEXT_X,
665 y = 4 + 2 * WORKSPACE_ROW_HEIGHT;
666 }
667 UiText_DrawResource(MsgWorkspaceChangeSettings, window, WORKSPACE_TEXT_X, y);
669 if (gDebugMode != 0) {
670 labelMessage = MsgWorkspaceRoughMenu;
671 UiText_DrawResource(labelMessage, window, WORKSPACE_TEXT_X, y);
673 UiText_DrawResource(labelMessage + 1, window, WORKSPACE_TEXT_X, y);
675 labelMessage += 2;
676 UiText_DrawResource(labelMessage, window, WORKSPACE_TEXT_X, y);
677 }
678 cacheSlot = Resource_FindFreeEntry();
679 if (cacheSlot < RESOURCE_SLOTS) {
681 work->cursor.output =
682 RenderOutput_Create(cacheSlot, 0x40000000, window, 0, 0);
683 x = window->x * 8;
684 y = window->y * 8 + 16;
686 }
687 y = -4;
688 for (i = 0; i < rows; i++) {
690 gMenu_WorkspaceIconFrames[first + i], 0, window, 12, y);
692 }
693 return window;
694}
695
696/// Runs the system menu until the player picks an entry (its number, counting
697/// Save your quest as 0) or cancels with B or START (-1).
698/// The result counts in the full entry table even when only Change settings is
699/// shown.
701 struct UiWindow *window;
702 s32 redraw;
703 struct RenderOutput *pair;
704 s32 first;
705 s32 i;
706 s32 j;
707 s32 rows;
708 s32 settingsOnly;
709 s32 dimmed;
710 s32 y;
711 s32 result;
712 s32 selectedEntry;
713 s32 resourceIndex;
714 s32 x;
715 s32 top;
716 const s8 *iconFrames;
717 struct RenderOutput *icon;
718 struct WorkspaceWork *work;
719
720 redraw = 1;
721 rows = 3;
722 settingsOnly = GameFlag_TestFar(FLAG_IN_LINK_LOBBY);
723 first = 0;
725 work = gSelectionWork;
726 window = SystemMenu_Open();
727#if TBS_PATCH_1
728 y = -0x18;
729 if (gDebugMode != 0) {
730 y = -0x10;
731 }
732 pair = RenderResource_CreatePair(6, window, 0x28, y);
733#else
734 pair = RenderResource_CreatePair(6, window, 0x28, -0x18);
735#endif
736 WaitFrames(1);
737 selectedEntry = work->page;
738 if (settingsOnly != 0) {
739 rows = 1;
740 first = 2;
741 }
742 if (gDebugMode != 0) {
743 rows += 3;
744 }
745 for (;;) {
746 if (redraw != 0) {
747 redraw = 0;
748 selectedEntry = (selectedEntry + rows) % rows;
749 work->page = selectedEntry;
750 i = 0;
751 if (i < rows) {
752 j = first;
753 iconFrames = gMenu_WorkspaceIconFrames;
754 do {
755 icon = work->icon[i];
756 icon->sentinel = 0xFB;
758 resourceIndex = (u8)icon->index;
759 dimmed = 0;
760 if (i != work->page) {
761 dimmed = 1;
762 }
763 RenderResource_LoadFrame(*(s8 *)(j + (s32)iconFrames), resourceIndex,
764 dimmed);
765 i++;
766 j++;
767 } while (i < rows);
768 }
769 top = window->y;
770 x = window->x * 8;
771 y = (((selectedEntry * 3) + top) * 8) + 0x10;
772 Shop_SetCursorFar(&work->cursor.cursor, x, y, 3);
773 }
775 WaitFrames(1);
776 if (gKeysPressed & KEY_A) {
777 result = selectedEntry;
779 } else if (gKeysPressed & (KEY_B | KEY_START)) {
780 result = -1;
782 } else {
783 if (gKeysRepeat & KEY_UP) {
785 selectedEntry -= 1;
786 redraw = 1;
787 } else if (gKeysRepeat & KEY_DOWN) {
789 selectedEntry += 1;
790 redraw = 1;
791 }
792 continue;
793 }
794 break;
795 }
796 UiWork_Finalize(window, 2);
798 WaitFrames(1);
799 if (result >= 0) {
800 result += first;
801 }
802 return result;
803}
static __inline__ void Dma_Set(const volatile void *source, volatile void *destination, u32 control, volatile u32 *channel)
Starts a DMA transfer: stores the source, destination and control words into channel's registers with...
Definition dma.h:62
#define Dma_Fill32(value, destination, size)
Fills size bytes at destination with the word value by DMA3.
Definition dma.h:30
s32 GameFlag_TestFar(s32 flag)
void UiIcon_PrepareObjectFar(struct RenderOutput *object)
void Shop_SetCursorFar(struct ShopCursor *cursor, s32 targetX, s32 targetY, s32 kind)
void ShopCursor_SetPositionImmediateFar(struct ShopCursor *cursor, s32 x, s32 y)
void ShopCursor_AdvanceFar(struct ShopCursor *cursor)
void ShopCursor_MoveTowardTargetFar(struct ShopCursor *cursor)
void AudioCommand_PlayFar(s32 id)
#define FLAG_IN_LINK_LOBBY
Set when the cleared game's menu goes to the link lobby: there Psynergy has no effect and the system ...
Definition flags.h:80
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
volatile u8 gSleepDisabled
Nonzero: WaitFrames counts no idle time and ignores sleep requests.
u8 gDebugMode
Debug builds: Start+Select pauses the frame loop.
volatile u8 gIdleSleepEnabled
Sleep after three idle minutes.
struct GameState gGameState
u8 gResource_FixedBlockBTiles[]
void * Runtime_AllocateBlock(s32 kind, s32 size)
As Runtime_AllocateHeapBlock, but tries EWRAM first, for blocks that need room more than speed: the b...
Definition heap.c:80
@ KEY_UP
Definition io_reg.h:249
@ KEY_B
Definition io_reg.h:244
@ KEY_SELECT
Definition io_reg.h:245
@ KEY_LEFT
Definition io_reg.h:248
@ KEY_START
Definition io_reg.h:246
@ KEY_RIGHT
Definition io_reg.h:247
@ KEY_A
Definition io_reg.h:243
@ KEY_DOWN
Definition io_reg.h:250
#define OBJ_PLTT_COLOR(palette, color)
Definition io_reg.h:160
#define REG_DMA3
Definition io_reg.h:153
#define BG_PLTT_COLOR(palette, color)
Definition io_reg.h:158
#define Iwram_MulQ16(left, right)
Definition iwram_call.h:127
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
#define CLAMP(v, low, high)
Keeps v within low to high, the low bound tested first.
Definition macros.h:23
void Runtime_ReleaseHeapBlock(s32 slot)
const u8 gWorkspaceOptions_SliderTiles[]
const u16 gWorkspaceOptions_SliderPalette[]
void SystemMenu_Initialize(void)
Allocates the system menu's work block and starts its per-frame callback.
Definition options.c:607
UNUSED void GraphicsPalette_ReservedNoOpC9C4(void)
Definition options.c:10
struct UiWindow * SystemMenu_Open(void)
Opens the system menu's window with its entries (Save your quest, Sleep, Change settings,...
Definition options.c:625
UNUSED void OptionMenu_LowerSetting(struct WorkspaceWork *work)
Lowers the setting on the three-row cursor's row: message speed, window hue or window brightness.
Definition options.c:199
#define SLIDER_PALETTE
Definition options.c:305
#define WORKSPACE_ROW_HEIGHT
Definition options.c:590
UNUSED void WindowColor_ComputeTint(struct WorkspaceWork *work)
Works out the window tint (red, green and blue, 0 to 31) from the window colour settings: the hue pic...
Definition options.c:53
UNUSED void OptionMenu_ResetEntries(struct WorkspaceWork *work)
Clears the option screen's seven entry states, its row, its tint and its cursor animation.
Definition options.c:23
#define RESOURCE_SLOTS
Definition options.c:306
#define WORKSPACE_ROWS
Definition options.c:588
void OptionMenu_AnimateCursors(void)
The option screen's per-frame callback: moves the cursor and the two slider markers,...
Definition options.c:241
s32 Menu_RunWorkspaceSelectionLoop(void)
Runs the system menu until the player picks an entry (its number, counting Save your quest as 0) or c...
Definition options.c:700
void OptionMenu_InitializeWork(void)
Allocates the option screen's work block, copies the settings into it with how many values each takes...
Definition options.c:280
void SystemMenu_Release(void)
Stops the system menu's per-frame callback and frees its work block.
Definition options.c:616
struct UiWindow * OptionMenu_Open(void)
Opens the option screen's window: the labels, the hue and brightness sliders with their markers,...
Definition options.c:311
void GraphicsPalette_SelectionNoOp(void)
Definition options.c:236
UNUSED void GraphicsPalette_ReservedNoOpC9C0(void)
Definition options.c:9
void SystemMenu_AnimateCursor(void)
The system menu's per-frame callback: moves the cursor and pulses the chosen entry's icon.
Definition options.c:595
#define WORKSPACE_DEBUG_ROWS
Definition options.c:589
u16 Color_ScaleComponents(s16 *rgb, s32 redScale, s32 greenScale, s32 blueScale)
Returns rgb with each channel scaled (16.16 fixed point) and clamped to 0 to 31, as a BGR555 colour.
Definition options.c:134
u16 WindowColor_ScaleTint(struct WorkspaceWork *work, s32 redScale, s32 greenScale, s32 blueScale)
Returns the window tint with each channel scaled (16.16 fixed point) and clamped to 0 to 31,...
Definition options.c:107
void OptionMenu_Release(void)
Stops the option screen's per-frame callback and frees its work block.
Definition options.c:300
UNUSED void OptionMenu_RaiseSetting(struct WorkspaceWork *work)
Raises the setting on the three-row cursor's row: message speed, window hue or window brightness.
Definition options.c:219
void PaletteGlow_Update(s32 phase, s32 brightness)
Sets the window colours (BG palette 15, colours 4 to 10) for a window hue (0 to 23) and brightness (0...
Definition options.c:152
UNUSED void WindowColor_WritePalette(struct WorkspaceWork *work)
Writes window colours 4 to 10 of BG palette 15, each a fixed scale of the window tint.
Definition options.c:88
UNUSED void OptionMenu_NextRow(struct WorkspaceWork *work)
Moves the three-row settings cursor down, wrapping to the top.
Definition options.c:191
s32 Menu_RunWorkspaceOptions(void)
Runs the option screen (window colour and brightness, message speed, speech, auto-sleep) until A or S...
Definition options.c:422
#define WORKSPACE_TEXT_X
Definition options.c:591
UNUSED void GraphicsPalette_ReservedNoOpC9BC(void)
Nothing calls them.
Definition options.c:8
UNUSED void OptionMenu_PreviousRow(struct WorkspaceWork *work)
Moves the three-row settings cursor up, wrapping to the bottom.
Definition options.c:182
struct RenderOutput * RenderOutput_Create(s32 slot, s32 oamFlags, struct UiWindow *window, s32 offsetX, s32 offsetY)
Creates a sprite output for the VRAM cache slot slot and attaches it to window, placed at (offsetX,...
Definition outputs.c:13
struct RenderOutput * RenderResource_CreateFrame(s32 icon, s32 remap, struct UiWindow *window, s32 x, s32 y)
Shows command icon icon (see RenderResource_LoadFrame) as a 32x32 256-colour sprite at (x,...
Definition pictures.c:85
struct RenderOutput * RenderResource_CreatePair(s32 picture, struct UiWindow *window, s32 x, s32 y)
Shows picture picture of gRenderResource_PairSourceTable as two 32x32 sprites side by side at (x,...
Definition pictures.c:28
void RenderResource_LoadFrame(s32 icon, s32 slot, s32 remap)
Decompresses command icon icon (a 32x32 picture of 256 colours, 1 KB) into VRAM slot slot,...
Definition pictures.c:67
void Ui_ApplyTableScaleToObject(struct RenderOutput *obj)
Makes the sprite obj pulse: scales it about its centre by gUi_ObjectPulseScales (in 1/65536,...
Definition pictures.c:105
void RenderOutput_BobPair(struct RenderOutput *obj)
Bobs the two sprites of a pair (see RenderResource_CreatePair) up and down by gUi_PairBobOffsets,...
Definition pictures.c:50
char ResourceId_ShopCursorFrames
const u8 gPaletteGlow_WaveTable[121]
The window colour wheel: one colour channel's level (0 to 31) over 96 hue steps.
Definition scales.c:30
const u8 gOptionMenu_HuePresets[6]
The window colour presets SELECT cycles through on the option screen: the colour (hue) and the bright...
Definition scales.c:57
const s8 gOptionMenu_SleepFrames[2]
Definition scales.c:51
const u8 gOptionMenu_BrightnessPresets[6]
Definition scales.c:61
const s8 gMenu_WorkspaceIconFrames[8]
The sprite frame of each entry's icon in the system menu (Save your quest, Sleep, Change settings,...
Definition scales.c:67
const s8 gOptionMenu_SpeechFrames[2]
Definition scales.c:47
const s8 gOptionMenu_SpeedFrames[3]
The option screen's sprite frames for each setting's choices: message speed Slow, Normal and Fast; Sp...
Definition scales.c:43
s32 Scheduler_AddOrUpdateCallback(SchedulerCallback callback, s32 order)
Schedules callback with order, or gives a task already running it the new order, and re-sorts the tab...
Definition scheduler.c:102
s32 Scheduler_RemoveCallback(SchedulerCallback callback)
Unschedules the task running callback: clears its routine and gives it order 0x7fff,...
Definition scheduler.c:146
#define SE_MENU_CANCEL
Definition songs.h:106
#define SE_MENU_CURSOR_MOVE
Definition songs.h:104
#define SE_MENU_CONFIRM
Definition songs.h:105
u8 paletteGlow[2]
window hue (0 to 24), brightness
Definition game_state.h:62
u8 idleSleepEnabled
the option, saved from gIdleSleepEnabled
Definition game_state.h:91
u8 messageSpeed
0 to 2; 1 on a new game
Definition game_state.h:66
u8 speech
1 shows speakers' portraits beside their messages
Definition game_state.h:64
One of the seven entries of the option screen's work from offset 0x400; only its state is known.
Definition options.c:14
A render output: a sprite in a window's output list (a character, an icon or a portrait),...
struct RenderOam oam
u16 y
screen pixels
u8 sentinel
depth slot it is drawn at (254 for glyphs)
u16 x
screen pixels
s8 index
VRAM cache slot, or a glyph's tile after glyphTiles.
A window: a framed rectangle of the tilemap with its sprite outputs, its opening or closing animation...
Definition uiwindow.h:11
u16 y
tiles
Definition uiwindow.h:16
u16 x
tiles
Definition uiwindow.h:15
u16 height
tiles
Definition uiwindow.h:14
The option screen's work (heap block 20): the settings being edited and how many values each takes,...
struct RenderOutput * icon[6]
struct RenderOutput * frame[3][3]
union MenuCursor cursor
union MenuCursor marker[2]
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
#define OPTION_WINDOW_X
#define OPTION_SLIDER_X
#define OPTION_FRAME_X
#define OPTION_SETTING_X
#define OPTION_SETTING_END
#define OPTION_SPEED_END
#define OPTION_WINDOW_WIDTH
void UiText_DrawResource(s32 message, struct UiWindow *window, s32 x, s32 y)
Decodes a message and draws it into a text canvas window at pixel (x, y).
Definition text_tiles.c:538
void UiWindow_DrawDividerLine(struct UiWindow *win, u32 x1, u32 y1, u32 x2, u32 y2)
Draws a straight divider line inside a window from tile (x1, y1) to (x2, y2), horizontal or vertical:...
Definition text_tiles.c:365
void UiText_DrawCharacterAtOffset(s32 message, const struct UiWindow *window, u32 offsetX, u32 offsetY)
Decodes a message and draws it as tiles in a window at pixel (offsetX, offsetY) of its interior.
Definition text_tiles.c:552
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
struct ShopCursor cursor
Definition cursor.h:32
struct RenderOutput * output
the image alone; cursor.anchor
Definition cursor.h:31
#define DMA_COPY16(count)
The DMA control word that copies count halfwords.
Definition window.h:114
s32 Resource_FindFreeEntry(void)
Returns the number of the first free cache entry, or VRAM_CACHE_ENTRY_COUNT when all are taken.
Definition vram_cache.c:211
s32 VramCache_Load(u32 no, u32 size, const void *src)
Gives cache entry no size bytes of sprite VRAM and copies src there.
Definition vram_cache.c:143
What every part of the window object shares: its includes, edition values, macros and the codes of de...
void UiWork_Finalize(struct UiWindow *window, s32 instant)
Closes a window: clears its contents and remembers its last rectangle.
Definition windows.c:349
void RenderOutput_ClearList(void *outputs)
Releases every render output in a list and empties it.
Definition windows.c:406
void UiWindow_ClearInteriorTiles(const struct UiWindow *window, u32 left, u32 top, u32 right, u32 bottom)
Clears an area of a window's interior to the window fill.
Definition windows.c:428
struct UiWindow * UiWindow_Create(s32 x, s32 y, s32 width, s32 height, s32 attrs)
Opens a window at tile (x, y) of width by height tiles in the first free window slot,...
Definition windows.c:279
struct WorkspaceWork * gSelectionWork