Alchemy
Loading...
Searching...
No Matches

shortcuts.c

Go to the documentation of this file.
1/// @file
2/// The area name notice, the Psynergy shortcut picker and heap block 19.
3/// Part of window.c, the window object, compiled only through it.
4
6
7/// The area name notice's fields, which live in the event work block.
9 u8 eventWork[0x230]; ///< the event work's other fields
12};
13
14/// Shows the area's name in a window near the top of the screen for 90 frames.
15/// The event work owns the window and countdown until the scheduler closes it.
17 struct TimedNoticeWork *notice;
18 s32 height;
19 s32 width;
20 s32 y;
21 s32 x;
22 s32 areaMessage;
23 struct UiWindow *nameWindow;
24
25 notice = (struct TimedNoticeWork *)gEventWork;
26 x = 8;
27 y = 8;
28 areaMessage =
31 UiText_GetResourceDimensions(areaMessage, &x, &y, &width, &height);
32 x = (30 - width) >> 1;
33 y = (10 - height) >> 1;
34 nameWindow = UiWindow_Create(x, y, width, height, 2);
35 notice->window = nameWindow;
36 UiText_DrawResource(areaMessage, nameWindow, 0, 0);
39}
40
41/// Counts the area name down, and closes it at 0.
43 struct TimedNoticeWork *notice;
44 u16 framesLeft;
45
46 notice = (struct TimedNoticeWork *)gEventWork;
47 notice->countdown = (framesLeft = notice->countdown + 0xffff);
48 if ((framesLeft << 16) == 0) {
49 UiWork_Finalize(notice->window, 2);
51 }
52}
53
54/// Closes the area name at once, if it is shown.
56 struct UiWindow *window;
57
58 window = ((struct TimedNoticeWork *)gEventWork)->window;
59 if (window != NULL && window->flags != 0) {
62 }
63}
64
67 return 0;
68}
69
70s32 Item_ReturnTrue(void) { return 1; }
71
72/// Steps the window hue one step: back when keys contains LEFT, on
73/// otherwise.
74/// Nothing calls it.
76 u8 hue = gGameState.paletteGlow[0];
77 if (keys & KEY_LEFT)
78 hue += 0xff;
79 else
80 hue += 1;
81 gGameState.paletteGlow[0] = hue;
82}
83
84/// A Psynergy the debug shortcut picker lists: its owner and the Psynergy.
88};
89
90/// Lets the player pick two Psynergy shortcuts from all the party's Psynergy,
91/// showing each one's cost and description, and stores them in
92/// gGameState.firstShortcut and secondShortcut (owner << 10 | Psynergy).
93/// This debug path seeds extra Psynergy before enumerating the party's
94/// shortcuts.
96 struct AbilityListEntry *list;
97 struct UiWindow *win;
98 struct UiWindow *title;
99 struct UiWindow *info;
100 struct RenderOutput *cursor;
101 u32 first;
102 u32 second;
103 u32 count;
104 UNUSED s32 done = 0;
105 s32 row = 0;
106 s32 redraw;
107 s32 slot;
108 s32 y;
109 s32 cost;
110 s32 ability;
111
112 cursor = NULL;
113 redraw = 1;
114 // Build the debug shortcut candidates before creating their three windows.
115 list = MemAlloc(0x700);
116 Unit_LearnPsynergyFar(0, 140);
117 Unit_LearnPsynergyFar(1, 140);
118 Unit_LearnPsynergyFar(2, 140);
119 Unit_LearnPsynergyFar(2, 141);
122 Unit_LearnPsynergyFar(5, 140);
123 second = 0;
124 first = 0;
125 count = Party_ListPsynergy(list);
126 if (count != 0) {
127 Menu_FindShortcutEntries(&first, &second, list);
128 win = UiWindow_Create(4, 6, 20, 7, 2);
129 title = UiWindow_Create(4, 3, 20, 3, 2);
130 info = UiWindow_Create(4, 14, 20, 5, 2);
131 slot = Resource_FindFreeEntry();
132 if (slot != 0) {
134 cursor = RenderOutput_Create(slot, 0x40000000, win, 0, 0);
135 }
136 /* FAKEMATCH(temporary): the title message passed through slot; as the
137 * message passed directly, 2 of 362 instructions differ in tbs-en. */
138 slot = MsgPanelHpMaxLabel;
139 UiText_DrawCharacterAtOffset(slot, title, 16, 0);
140 // Redraw both shortcut rows and the selected ability's detail pane.
141 for (;;) {
142 if (redraw != 0) {
143 redraw = 0;
144 first = (first + count) % count;
145 second = (second + count) % count;
146 row = (row + 2) % 2;
147 y = (row << 4) + (win->y << 3) + 28;
148 cursor->y = y;
149 cursor->oam.y = y;
151 UiWindow_DrawDividerLine(win, 1, 2, 17, 2);
152 UiText_DrawCharacterAtOffset(MsgPanelStatusLabel, win, 48, 0);
153 UiText_DrawCharacterAtOffset(list[first].ability + MsgAbilityName, win,
154 56, 16);
155 UiText_DrawCharacterAtOffset(list[second].ability + MsgAbilityName, win,
156 56, 32);
157 UiText_DrawCharacterAtOffset(MsgPanelStatusLabel - 2, win, 16, 16);
158 UiText_DrawCharacterAtOffset(MsgPanelStatusLabel - 1, win, 16, 32);
159 UiText_DrawCharacterAtOffset(list[first].owner + MsgCharacterName, win,
160 104, 16);
161 UiText_DrawCharacterAtOffset(list[second].owner + MsgCharacterName, win,
162 104, 32);
164 UiText_DrawCharacterAtOffset(MsgPsynergyNeedMorePp, info, 0, 16);
165 if (row != 0) {
166 cost = BattleActGet(list[second].ability)->ppCost;
167 ability = list[second].ability;
168 } else {
169 cost = BattleActGet(list[first].ability)->ppCost;
170 ability = list[first].ability;
171 }
172 UiText_DrawNumberAtOffset(cost, 2, info, 64, 16);
173 UiText_DrawCharacterAtOffset(ability + MsgAbilityDescription, info, 0,
174 0);
175 }
176 WaitFrames(1);
177 if (gKeysRepeat & KEY_LEFT) {
179 if (row != 0)
180 second--;
181 else
182 first--;
183 redraw = 1;
184 }
185 if (gKeysRepeat & KEY_RIGHT) {
187 if (row != 0)
188 second++;
189 else
190 first++;
191 redraw = 1;
192 }
193 if (gKeysRepeat & KEY_UP) {
195 row--;
196 redraw = 1;
197 }
198 if (gKeysRepeat & KEY_DOWN) {
200 row++;
201 redraw = 1;
202 }
203 if (gKeysPressed & KEY_A)
205 else if (gKeysPressed & KEY_B)
207 else if (gKeysPressed & KEY_START)
209 else
210 continue;
211 /* FAKEMATCH(dead): an unread flag, which forces fresh zeros for both
212 * entries and the cursor argument instead of reusing the row register;
213 * without the flag, 5 of 362 instructions differ in tbs-en. */
214 done = 1;
215 break;
216 }
217 // Persist both owner/ability pairs before releasing the picker resources.
218 gGameState.firstShortcut = (list[first].owner << 10) | list[first].ability;
220 (list[second].owner << 10) | list[second].ability;
221 UiWork_Finalize(win, 1);
222 UiWork_Finalize(title, 1);
223 UiWork_Finalize(info, 1);
224 WaitFrames(1);
225 }
226 MemFree(list);
227}
228
229/// Lists every Psynergy of the party's active members as (owner, Psynergy)
230/// pairs in output and returns how many.
231/// output must hold every owner's nonzero action slots; there is no capacity
232/// argument.
234 u16 ownerIds[14];
235 s32 outputCount = 0;
236 s32 ownerCount = Party_ListActiveOwnersFar(ownerIds);
237 s32 i;
238
239 for (i = 0; i < ownerCount; i++) {
240 struct BattleUnit *unit;
241 u32 owner;
242 s32 slotIndex;
243 u32 ability;
244
245 owner = ownerIds[i];
246 unit = UnitGetFar(owner);
247 for (slotIndex = 0; slotIndex < (s32)(sizeof(unit->actionSlots) /
248 sizeof(unit->actionSlots[0]));
249 slotIndex++) {
250 ability = unit->actionSlots[slotIndex].encodedAction & ACTION_ID_MASK;
251 if (ability == 0)
252 break;
253 BattleActGet(ability);
254 output[outputCount].owner = owner;
255 output[outputCount].ability = ability;
256 outputCount++;
257 }
258 }
259
260 return outputCount;
261}
262
263/// Finds the two Psynergy shortcuts in a list from Party_ListPsynergy, and
264/// returns their indexes (0 for one not found).
265/// A shortcut absent from the list falls back to entry 0.
266void Menu_FindShortcutEntries(u32 *firstIndex, u32 *secondIndex,
267 const struct AbilityListEntry *entries) {
268 s32 entryIndex;
269
270 *firstIndex = 0;
271 *secondIndex = 0;
272
273 for (entryIndex = 0; entryIndex <= 447; entryIndex++) {
274 if (entries[entryIndex].ability == (gGameState.firstShortcut & 0x3ff) &&
275 entries[entryIndex].owner == (gGameState.firstShortcut >> 10)) {
276 *firstIndex = entryIndex;
277 break;
278 }
279 }
280
281 for (entryIndex = 0; entryIndex <= 447; entryIndex++) {
282 if (entries[entryIndex].ability == (gGameState.secondShortcut & 0x3ff) &&
283 entries[entryIndex].owner == (gGameState.secondShortcut >> 10)) {
284 *secondIndex = entryIndex;
285 break;
286 }
287 }
288}
289
290/// Runs the Psynergy shortcut picker.
292
293/// The work block of heap slot 19: two icon flags and resources and a window,
294/// among fields nothing here uses.
296 u8 unk000[0x46];
299 u8 unk04a[0x352 - 0x4a];
302 u8 unk356[0xff4 - 0x356];
305};
306
307/// Allocates the work block of heap slot 19 and clears its two icon flags.
308/// Nothing calls it.
310 struct SelectionWorkspace *work;
311 u32 zero;
312
313 work = Runtime_AllocateBlock(0x13, 0x1004);
314 zero = 0;
315 work->firstActive = zero;
316 work->secondActive = zero;
317}
318
319/// Closes the window of heap slot 19's work block, frees its two icons and
320/// frees the block.
321/// Nothing calls it.
323 struct SelectionWorkspace *state;
324
325 state = *(struct SelectionWorkspace **)gSelectionWorkspace;
326 UiWork_Finalize(state->window, 0);
327 while (UiWork_IsIdle(state->window) == 0) {
328 WaitFrames(1);
329 }
330 if (state->firstActive != 0) {
332 }
333 if (state->secondActive != 0) {
335 }
337}
struct BattleUnit * UnitGetFar(u32 owner)
s32 Party_ListActiveOwnersFar(s16 *owners)
struct BattleAct * BattleActGet(s32 actionId)
Far call to BattleAction_GetDirect.
s32 Unit_LearnPsynergyFar()
s32 PartyInventory_RemoveFar(s32 item_id)
s32 Scene_GetAreaNameIndexFar(s32 scene, s32 entrance)
void AudioCommand_PlayFar(s32 id)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
s32 UiWork_IsIdle(struct UiWindow *window)
Returns 1 when a window is fully closed (its slot free), and 0 while it is open or closing.
Definition frames.c:224
struct GameState gGameState
u8 gSelectionWorkspace[]
u8 gResource_FixedBlockBTiles[]
void * MemAlloc(s32 size)
Allocates size bytes (rounded up to words) with no slot, from IWRAM when they fit and EWRAM otherwise...
Definition heap.c:115
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_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
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
void Runtime_ReleaseHeapBlock(s32 slot)
void MemFree(void *buffer)
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
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
s32 Party_ListPsynergy(struct AbilityListEntry *output)
Lists every Psynergy of the party's active members as (owner, Psynergy) pairs in output and returns h...
Definition shortcuts.c:233
void Debug_SelectAbilityPair(void)
Lets the player pick two Psynergy shortcuts from all the party's Psynergy, showing each one's cost an...
Definition shortcuts.c:95
UNUSED void Menu_AllocateSelectionWorkspace(void)
Allocates the work block of heap slot 19 and clears its two icon flags.
Definition shortcuts.c:309
UNUSED void OptionMenu_StepWindowHue(s32 keys)
Steps the window hue one step: back when keys contains LEFT, on otherwise.
Definition shortcuts.c:75
void Menu_FindShortcutEntries(u32 *firstIndex, u32 *secondIndex, const struct AbilityListEntry *entries)
Finds the two Psynergy shortcuts in a list from Party_ListPsynergy, and returns their indexes (0 for ...
Definition shortcuts.c:266
void UiTimedNotice_Create(void)
Shows the area's name in a window near the top of the screen for 90 frames.
Definition shortcuts.c:16
void Menu_RunSelectionHook(void)
Runs the Psynergy shortcut picker.
Definition shortcuts.c:291
s32 Item_ReturnTrue(void)
Definition shortcuts.c:70
void UiTimedNotice_CloseIfActive(void)
Closes the area name at once, if it is shown.
Definition shortcuts.c:55
void UiTimedNotice_Tick(void)
Counts the area name down, and closes it at 0.
Definition shortcuts.c:42
s32 Item_RemoveFromInventory(s32 unused, s32 itemId)
Definition shortcuts.c:65
UNUSED void Menu_ReleaseSelectionWorkspace(void)
Closes the window of heap slot 19's work block, frees its two icons and frees the block.
Definition shortcuts.c:322
#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
struct EventWork * gEventWork
#define NULL
Definition bilibin.h:6
A Psynergy the debug shortcut picker lists: its owner and the Psynergy.
Definition shortcuts.c:85
u8 ppCost
PP the ability costs.
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
struct OwnerActionSlot actionSlots[32]
The action list: Psynergy taught for good, then the class's and the equipment's (Unit_RefreshPsynergy...
u16 firstShortcut
The shortcuts' assignments.
Definition game_state.h:86
u8 paletteGlow[2]
window hue (0 to 24), brightness
Definition game_state.h:62
u16 secondShortcut
Definition game_state.h:87
s16 entrance
Definition game_state.h:37
u16 encodedAction
bits: 15 from the class | 14 from an equipped item | 13..0 action id.
Definition battle_unit.h:22
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
The work block of heap slot 19: two icon flags and resources and a window, among fields nothing here ...
Definition shortcuts.c:295
u8 unk356[0xff4 - 0x356]
Definition shortcuts.c:302
struct UiWindow * window
Definition shortcuts.c:303
u8 unk04a[0x352 - 0x4a]
Definition shortcuts.c:299
The area name notice's fields, which live in the event work block.
Definition shortcuts.c:8
struct UiWindow * window
Definition shortcuts.c:10
u8 eventWork[0x230]
the event work's other fields
Definition shortcuts.c:9
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 flags
UI_WINDOW_ flags; 0 once closing or free.
Definition uiwindow.h:25
#define RENDER_RESOURCE_BASE
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_DrawNumberAtOffset(s32 value, s32 width, const struct UiWindow *window, s32 x, s32 y)
Draws a number (width as UiText_FormatNumber) as tiles in a window at pixel (x, y) of its interior.
Definition text_tiles.c:668
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
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11
s32 UiText_GetResourceDimensions(s32 no, s32 *x, s32 *y, u32 *width, u32 *height)
#define ACTION_ID_MASK
Definition window.h:269
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
Definition vram_cache.c:106
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...
#define UI_AREA_NOTICE_FRAMES
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_RedrawSavedRect(struct UiWindow *window)
Redraws a window's empty frame at its current rectangle.
Definition windows.c:400
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