Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
menu.c
Go to the documentation of this file.
1/* The training menu */
2
3#include "menus/gym.h"
4
5/* Creates the training menu's text windows */
7 win[0] = createTextWindow(menu->layerId, 1, 0xAE, 0x49);
8 win[1] = createTextWindow(menu->layerId, 1, 0xA3, 0xA0);
9 win[2] = createTextWindow(menu->layerId, 1, 0x74, 0xC0);
10 win[3] = createTextWindow(menu->layerId, 1, 0x74, 0xCE);
11}
12
13/* Shows the name and description of the selected training (show) or hides them */
15 s32 entry;
16
17 if (show != 0) {
18 entry = menu->trainings[menu->page][menu->col + menu->row * 4];
19 if (entry > 0) {
22 return;
23 }
24 }
25 win[2]->setVisible(win[2], 0);
26 win[3]->setVisible(win[3], 0);
27}
28
29/* Draws the training menu: its panels, the trainings of the page and the cursor */
31 SpriteDrawer sprite;
32 s32 i;
33 s32 entry;
34 s32 x;
35 s32 y;
36
37 initSpriteDrawer(&sprite);
38 sprite.setLayerId(menu->layerId, menu->depth);
39 sprite.setTexture(0x240, 0x100);
40 if (menu->panels[0].level != 0) {
41 if (menu->panels[0].level != ONE) {
42 sprite.setScale(menu->panels[0].level, ONE, ONE);
43 sprite.setPivot(0x140, 0x4E);
44 }
45 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x22, 0x92, 0x43);
46 }
47 if (menu->cursorShown != 0) {
48 if (GFX.funcs.getTime() - menu->cursorTime >= 0xB) {
49 menu->cursorTime = GFX.funcs.getTime();
50 menu->cursorClut++;
51 if (menu->cursorClut >= 4) {
52 menu->cursorClut = 0;
53 }
54 }
55 sprite.setClutRow(menu->cursorClut);
56 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x1E, menu->col * 40 + 0x94, menu->row * 40 + 0x64);
57 sprite.setClutRow(0);
58 }
59 if (menu->panels[2].level != 0) {
60 if (GFX.funcs.getTime() - menu->iconTime >= 0x10) {
61 menu->iconTime = GFX.funcs.getTime();
62 menu->iconFrame++;
63 if (menu->iconFrame >= 4) {
64 menu->iconFrame = 0;
65 }
66 }
67 if (menu->panels[2].level != ONE) {
68 sprite.setScale(menu->panels[2].level, menu->panels[2].level, ONE);
69 }
70 for (i = 0; i < 8; i++) {
71 entry = menu->trainings[menu->page][i];
72 if (entry != 0) {
73 x = (i % 4) * 40;
74 y = (i / 4) * 40;
75 if (menu->panels[2].level != ONE) {
76 sprite.setPivot(x + 0xA8, y + 0x76);
77 }
78 if (entry == -1) {
79 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x5F, x + 0x94, y + 0x64);
80 } else if (i == menu->col + menu->row * 4) {
81 sprite.setClutRow(0);
83 STGTRAIN_state.trainings[entry].icons[menu->iconFrame], x + 0x94, y + 0x64);
84 } else {
85 sprite.setClutRow(1);
87 x + 0x94, y + 0x64);
88 }
89 }
90 }
91 }
92 if (menu->arrowShown != 0) {
93 if (GFX.funcs.getTime() - menu->arrowTime >= 0xB) {
94 menu->arrowTime = GFX.funcs.getTime();
95 menu->arrowClut++;
96 if (menu->arrowClut >= 4) {
97 menu->arrowClut = 0;
98 }
99 }
100 sprite.setClutRow(menu->arrowClut);
101 if (menu->page == 0) {
102 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x2C, 0xE4, 0xA0);
103 } else {
104 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x2B, 0x94, 0xA0);
105 }
106 }
107 sprite.setClutRow(0);
108 if (menu->panels[1].level != 0) {
109 sprite.setScale(menu->panels[1].level, ONE, ONE);
110 if (menu->panels[1].level != ONE) {
111 sprite.setPivot(0x140, 0x8A);
112 }
113 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x24, 0x8F, 0x5F);
114 }
115 if (menu->panels[3].level != 0) {
116 if (menu->panels[3].level != ONE) {
117 sprite.setScale(menu->panels[3].level, ONE, ONE);
118 sprite.setPivot(0x140, 0xCD);
119 }
120 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x23, 0x46, 0xBA);
121 }
122}
123
124/* Shows the hint to the other page: R1 on the first page, L1 on the second */
125static inline void STGTRAIN_showPageHint(TrainMenu *menu, TextWindow **win) {
126 if (menu->page == 0) {
127 win[1]->setString(win[1], FILE_CACHE.load(STGTRAIN_TEXT), 0x45);
128 win[1]->setPos(win[1], 0xE4, 0xA0);
129 } else {
130 win[1]->setString(win[1], FILE_CACHE.load(STGTRAIN_TEXT), 0x44);
131 win[1]->setPos(win[1], 0xA3, 0xA0);
132 }
133}
134
135/* Turns the page with L1 or R1 when the gym has more than five trainings,
136 putting the cursor on the new page's first training; or moves the cursor
137 to the next training in the direction pressed, and closes the menu with
138 the one under it picked (cross) or none (triangle) */
139static inline void STGTRAIN_pickTraining(TrainMenu *menu, TextWindow **win) {
140 s32 col;
141 s32 row;
142
143 col = menu->page;
144 if (STGTRAIN_state.tableCount >= 6) {
145 if (!PAD_HELD(PAD_R1) && PAD_PRESSED(PAD_L1)) {
146 menu->page = 0;
147 } else if (!PAD_HELD(PAD_L1) && PAD_PRESSED(PAD_R1)) {
148 menu->page = 1;
149 }
150 }
151 if (col != menu->page) {
153 STGTRAIN_showPageHint(menu, win);
154 for (col = 0; col < 8; col++) {
155 if (menu->trainings[menu->page][col] > 0) {
156 menu->col = col % 4;
157 menu->row = col / 4;
158 break;
159 }
160 }
161 STGTRAIN_showTrainingInfo(menu, win, 1);
162 menu->iconFrame = 0;
163 return;
164 }
165 col = menu->col;
166 row = menu->row;
168 for (;;) {
169 if (--menu->col < 0) {
170 menu->col = 0;
171 break;
172 }
173 if (menu->trainings[menu->page][menu->col + menu->row * 4] > 0) {
174 break;
175 }
176 }
178 for (;;) {
179 if (++menu->col >= 4) {
180 menu->col = 3;
181 break;
182 }
183 if (menu->trainings[menu->page][menu->col + menu->row * 4] > 0) {
184 break;
185 }
186 }
187 }
189 for (;;) {
190 if (--menu->row < 0) {
191 menu->row = 0;
192 break;
193 }
194 if (menu->trainings[menu->page][menu->col + menu->row * 4] > 0) {
195 break;
196 }
197 }
198 } else if (PAD_PRESSED(PAD_DOWN) || PAD_REPEATED(PAD_DOWN)) {
199 for (;;) {
200 if (++menu->row >= 2) {
201 menu->row = 1;
202 break;
203 }
204 if (menu->trainings[menu->page][menu->col + menu->row * 4] > 0) {
205 break;
206 }
207 }
208 }
209 if (col != menu->col || row != menu->row) {
210 if (menu->trainings[menu->page][menu->col + menu->row * 4] > 0) {
212 STGTRAIN_showTrainingInfo(menu, win, 1);
213 } else {
214 menu->col = col;
215 menu->row = row;
216 }
217 } else if (PAD_PRESSED(PAD_CROSS)) {
219 menu->screen->training = menu->trainings[menu->page][menu->col + menu->row * 4];
220 if (menu->screen->training > 0) {
221 menu->substate = 0x32;
222 }
223 } else if (PAD_PRESSED(PAD_TRIANGLE)) {
225 menu->substate = 0x32;
226 menu->step = 1;
227 }
228}
229
230/*
231 * Runs the training menu: opens its panels, moves the cursor over the
232 * trainings of a page (L1 and R1 turn the pages when the gym has more than
233 * five), and closes with a training picked (cross) or none (triangle).
234 */
236 switch (menu->substate) {
237 case 0:
238 default:
239 STGTRAIN_state.startFade(&menu->panels[0], 1);
240 menu->substate++;
241 break;
242 case 1:
243 if (STGTRAIN_state.updateFade(&menu->panels[0])) {
244 win[0]->setString(win[0], FILE_CACHE.load(STGTRAIN_TEXT), 7);
245 STGTRAIN_state.startFade(&menu->panels[1], 1);
246 menu->substate++;
247 }
248 break;
249 case 2:
250 if (STGTRAIN_state.updateFade(&menu->panels[1])) {
251 STGTRAIN_state.startFade(&menu->panels[2], 1);
252 menu->substate++;
253 }
254 break;
255 case 3:
256 if (STGTRAIN_state.updateFade(&menu->panels[2])) {
257 if (STGTRAIN_state.tableCount >= 6) {
258 menu->arrowShown = 1;
259 STGTRAIN_showPageHint(menu, win);
260 }
261 STGTRAIN_state.startFade(&menu->panels[3], 1);
262 menu->substate++;
263 }
264 break;
265 case 4:
266 if (STGTRAIN_state.updateFade(&menu->panels[3])) {
267 STGTRAIN_showTrainingInfo(menu, win, 1);
268 menu->cursorShown = 1;
269 menu->substate = 10;
270 }
271 break;
272 case 10:
273 STGTRAIN_pickTraining(menu, win);
274 break;
275 case 0x32:
276 menu->cursorShown = 0;
277 menu->arrowShown = 0;
278 win[1]->setVisible(win[1], 0);
279 STGTRAIN_state.startFade(&menu->panels[2], 0);
280 menu->substate++;
281 break;
282 case 0x33:
283 if (STGTRAIN_state.updateFade(&menu->panels[2])) {
284 STGTRAIN_showTrainingInfo(menu, win, 0);
285 win[0]->setVisible(win[0], 0);
286 STGTRAIN_state.startFade(&menu->panels[0], 0);
287 STGTRAIN_state.startFade(&menu->panels[1], 0);
288 STGTRAIN_state.startFade(&menu->panels[3], 0);
289 menu->substate++;
290 }
291 break;
292 case 0x34:
295 if (STGTRAIN_state.updateFade(&menu->panels[3])) {
296 if (menu->step != 0) {
297 menu->setState(menu, TASK_DONE);
298 } else {
299 menu->state = TASK_KILL;
300 }
301 }
302 break;
303 }
304}
305
306/*
307 * The training menu's task: a grid of trainings on two pages, filled from
308 * the gym's table (the trainings it has), with the cursor on the last one.
309 */
311 TrainEntry *table;
312 s32 i;
313 s32 page;
314 s32 row;
315 s32 col;
316
317 switch (menu->state) {
318 case TASK_INIT:
319 default:
320 menu->nextState(menu);
322 menu->panels[0].duration = 10;
323 menu->panels[1].duration = 10;
324 menu->panels[2].duration = 10;
325 menu->panels[3].duration = 10;
327 for (row = 0; row < 2; row++) {
328 for (col = 0; col < 3; col++) {
329 if (row == 1 && col == 2) {
330 break;
331 }
332 menu->trainings[0][col + row * 4] = -1;
333 }
334 }
335 for (row = 0; row < 2; row++) {
336 for (col = 0; col < 4; col++) {
337 if (row != 1 || col != 0) {
338 menu->trainings[1][col + row * 4] = -1;
339 }
340 }
341 }
342 for (i = 0; i < 16; i++) {
343 switch (table[i].id) {
344 case 1:
345 case 13:
346 menu->trainings[0][0] = table[i].id;
347 break;
348 case 2:
349 case 14:
350 menu->trainings[0][1] = table[i].id;
351 break;
352 case 3:
353 case 15:
354 menu->trainings[0][2] = table[i].id;
355 break;
356 case 4:
357 case 16:
358 menu->trainings[0][4] = table[i].id;
359 break;
360 case 5:
361 case 17:
362 menu->trainings[0][5] = table[i].id;
363 break;
364 case 6:
365 case 18:
366 menu->trainings[1][0] = table[i].id;
367 break;
368 case 7:
369 case 19:
370 menu->trainings[1][1] = table[i].id;
371 break;
372 case 8:
373 case 20:
374 menu->trainings[1][2] = table[i].id;
375 break;
376 case 9:
377 case 21:
378 menu->trainings[1][3] = table[i].id;
379 break;
380 case 10:
381 case 22:
382 menu->trainings[1][5] = table[i].id;
383 break;
384 case 11:
385 case 23:
386 menu->trainings[1][6] = table[i].id;
387 break;
388 case 12:
389 case 24:
390 menu->trainings[1][7] = table[i].id;
391 break;
392 }
393 }
394 if (menu->screen->training > 0) {
395 for (page = 0; page < 2; page++) {
396 for (row = 0; row < 2; row++) {
397 for (col = 0; col < 4; col++) {
398 if (menu->trainings[page][col + row * 4] == menu->screen->training) {
399 menu->page = page;
400 menu->col = col;
401 menu->row = row;
402 break;
403 }
404 }
405 }
406 }
407 }
408 break;
409 case TASK_RUN:
410 STGTRAIN_runMenu(menu, win);
411 STGTRAIN_drawMenu(menu);
412 break;
413 case TASK_DONE:
414 case TASK_KILL:
415 break;
416 }
417}
418
419/* Opens the training menu (its substate 0) */
421 menu->state = TASK_RUN;
422 menu->substate = 0;
423}
424
425/* Closes the training menu (its substate 0x32) */
427 menu->state = TASK_RUN;
428 menu->substate = 0x32;
429}
430
431/* Shows the selected training's name and description */
435
436/* Creates the training menu */
438 TrainMenu *menu = createTask(STGTRAIN_updateMenu, sizeof(TrainMenu), 0x10);
439
440 menu->open = STGTRAIN_openMenu;
443 menu->layerId = SCREEN_LAYER;
444 menu->depth = 6;
445 menu->screen = screen;
446 return menu;
447}
signed int s32
Definition common.h:11
GfxState GFX
GFX: the graphics state and its methods.
Definition display.c:209
GameState GAME
The save data, the game mode and the methods.
Definition state.c:64
#define TASK_RUN
Definition task.h:35
#define TASK_KILL
Definition task.h:37
#define TASK_INIT
Tasks: every game object is a task, a heap block that starts with this header and is updated once per...
Definition task.h:34
#define TASK_DONE
Definition task.h:36
FileCache FILE_CACHE
The file cache.
Definition file_cache.c:7
TrainState STGTRAIN_state
Definition files.c:422
#define SCREEN_LAYER
The layer over the whole screen that most modes create first and draw their menus on (FIELDSTG and ST...
Definition gfx.h:45
STGTRAIN.PRO: the gyms, where the partners train their stats.
#define STGTRAIN_FILE_SPRITES
Definition gym.h:20
#define STGTRAIN_SPRITES
its sprite bank
Definition gym.h:23
#define STGTRAIN_TEXT
The overlay's files: the discs number them differently.
Definition gym.h:19
void STGTRAIN_showMenuInfo(TrainMenu *menu)
Shows the selected training's name and description.
Definition menu.c:432
void STGTRAIN_showTrainingInfo(TrainMenu *menu, TextWindow **win, s32 show)
Shows the name and description of the selected training (show) or hides them.
Definition menu.c:14
TrainMenu * STGTRAIN_createMenu(TrainScreen *screen)
Creates the training menu.
Definition menu.c:437
void STGTRAIN_updateMenu(TrainMenu *menu, TextWindow **win)
The training menu's task: a grid of trainings on two pages, filled from the gym's table (the training...
Definition menu.c:310
void STGTRAIN_drawMenu(TrainMenu *menu)
Draws the training menu: its panels, the trainings of the page and the cursor.
Definition menu.c:30
void STGTRAIN_openMenu(TrainMenu *menu)
Opens the training menu (its substate 0)
Definition menu.c:420
static void STGTRAIN_pickTraining(TrainMenu *menu, TextWindow **win)
Turns the page with L1 or R1 when the gym has more than five trainings, putting the cursor on the new...
Definition menu.c:139
void STGTRAIN_closeMenu(TrainMenu *menu)
Closes the training menu (its substate 0x32)
Definition menu.c:426
static void STGTRAIN_showPageHint(TrainMenu *menu, TextWindow **win)
Shows the hint to the other page: R1 on the first page, L1 on the second.
Definition menu.c:125
void STGTRAIN_runMenu(TrainMenu *menu, TextWindow **win)
Runs the training menu: opens its panels, moves the cursor over the trainings of a page (L1 and R1 tu...
Definition menu.c:235
void STGTRAIN_createMenuWindows(TrainMenu *menu, TextWindow **win)
Creates the training menu's text windows.
Definition menu.c:6
#define PAD_CROSS
Definition pad.h:31
#define PAD_DOWN
Definition pad.h:24
#define PAD_RIGHT
Definition pad.h:23
#define PAD_TRIANGLE
Definition pad.h:32
#define PAD_PRESSED(button)
One button of pad 1: newly pressed, auto-repeated while held, or held.
Definition pad.h:140
#define PAD_UP
Definition pad.h:22
#define PAD_L1
Definition pad.h:28
#define PAD_LEFT
Definition pad.h:25
#define PAD_HELD(button)
Definition pad.h:142
#define PAD_R1
Definition pad.h:29
#define PAD_REPEATED(button)
Definition pad.h:141
SoundState SOUND
rsin and rcos (libgte) read rsin_tbl[a - 0x800] and the like: their addresses before the table fall i...
Definition sound.c:180
#define SOUND_MENU_CANCEL
SYSTEM01.
Definition sound.h:39
#define SOUND_MENU_MOVE
SYSTEM06.
Definition sound.h:43
void initSpriteDrawer(SpriteDrawer *obj)
Clears a sprite drawer to neutral (no scale, gray tint, follows the scroll), gives it its methods and...
void *(* load)(u32 file)
Definition file.h:92
void *(* getEntry)(u32 fileAndIndex)
Definition file.h:96
s32(* getModeArg)()
Definition game_state.h:20
GameFuncs funcs
Definition game_state.h:582
s32(* getTime)(void)
Definition gfx.h:31
GfxFuncs funcs
Definition gfx.h:77
s32 level
Definition menu.h:21
s32 duration
Definition menu.h:19
short(* playSound)(s32 id)
returns the voice of a key-on
Definition sound.h:187
Draws sprites from a sprite sheet (such as file 0x277, the menu graphics): a sheet has a table of fra...
Definition gfx.h:223
void(* setPivot)()
(x, y)
Definition gfx.h:250
void(* setScale)()
(x, y, z), ONE = 1.0
Definition gfx.h:248
void(* setLayerId)()
(id, depth)
Definition gfx.h:244
void(* setClutRow)()
(row)
Definition gfx.h:247
void(* draw)()
(sheet, frame, x, y)
Definition gfx.h:246
void(* setTexture)()
(x, y)
Definition gfx.h:242
A text window (createTextWindow): up to six text buffers (0 is shown, 1-5 are "work" buffers that con...
Definition text.h:131
void(* setPos)(struct TextWindow *obj, s16 x, s16 y)
Definition text.h:173
void(* setString)()
Definition text.h:165
void(* setVisible)(struct TextWindow *obj, u8 arg)
Definition text.h:177
An entry of a gym level's trainings (STGTRAIN_gymTrainings)
Definition gym.h:326
s32 id
Definition gym.h:327
s32 icons[4]
frames of STGTRAIN_FILE_SPRITES
Definition gym.h:336
s32 desc
Definition gym.h:335
s32 name
strings of the text file
Definition gym.h:334
The training menu (STGTRAIN_createMenu)
Definition gym.h:149
void(* setState)(struct TrainMenu *task, s32 state)
Definition gym.h:150
TrainScreen * screen
Definition gym.h:151
s32 cursorTime
Definition gym.h:156
s32 trainings[2][8]
[page][row * 4 + col], -1: none
Definition gym.h:165
s32 arrowTime
Definition gym.h:162
void(* close)(struct TrainMenu *menu)
Definition gym.h:168
void(* nextState)(struct TrainMenu *task)
Definition gym.h:150
s32 layerId
Definition gym.h:152
s32 page
Definition gym.h:159
void(* open)(struct TrainMenu *menu)
Definition gym.h:167
void(* showInfo)(struct TrainMenu *menu)
Definition gym.h:169
s32 cursorClut
Definition gym.h:155
PanelAnim panels[4]
Definition gym.h:166
s32 row
Definition gym.h:158
s32 iconTime
Definition gym.h:164
void * children
Definition gym.h:150
s32 cursorShown
Definition gym.h:154
s32 iconFrame
the selected training's icon
Definition gym.h:163
s32 arrowClut
Definition gym.h:161
s32 arrowShown
to the other page
Definition gym.h:160
s32 substate
Definition gym.h:150
s32 col
the cursor's
Definition gym.h:157
s32 depth
Definition gym.h:153
s32 step
Definition gym.h:150
s32 state
Definition gym.h:150
The training screen's main task (STGTRAIN_createScreen)
Definition gym.h:106
s32 training
the one picked in the menu, 0 for none
Definition gym.h:118
s32 tableCount
the entries of the last getTable
Definition gym.h:341
s32(* updateFade)(PanelAnim *fade)
Definition gym.h:348
TrainEntry *(* getTable)(s32 index)
Definition gym.h:363
void(* startFade)(PanelAnim *fade, s32 fadeIn)
Definition gym.h:347
TrainInfo * trainings
STGTRAIN_trainings.
Definition gym.h:345
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105
TextWindow * createTextWindow(s16 layerId, s16 style, s16 x, s16 y)
A text window on a layer, in a font style, at (x, y)