Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
screen.c
Go to the documentation of this file.
1/* The training screen: the party, the partner's stats and the training menu;
2 the screen fade; and the first object's data */
3
4#include "menus/gym.h"
5
6/* Creates the screen's text windows */
8 s32 i;
9
10 win->name = createTextWindow(screen->layerId, 1, 0x33, 0x13);
11 win->level[0] = createTextWindow(screen->layerId, 3, 0x33, 0x22);
12 win->level[1] = createTextWindow(screen->layerId, 3, 0x50, 0x22);
13 win->hp[0] = createTextWindow(screen->layerId, 3, 0x33, 0x2C);
14 win->hp[1] = createTextWindow(screen->layerId, 3, 0x5D, 0x2C);
15 win->hp[2] = createTextWindow(screen->layerId, 3, 0x80, 0x2C);
16 win->mp[0] = createTextWindow(screen->layerId, 3, 0x33, 0x35);
17 win->mp[1] = createTextWindow(screen->layerId, 3, 0x5D, 0x35);
18 win->mp[2] = createTextWindow(screen->layerId, 3, 0x80, 0x35);
19 win->slashes[0] = createTextWindow(screen->layerId, 3, 0x5F, 0x2C);
20 win->slashes[1] = createTextWindow(screen->layerId, 3, 0x5F, 0x35);
21 for (i = 0; i < 6; i++) {
22 win->stats[i] = createTextWindow(screen->layerId, 1, 0x33, i * 0xE + 0x4F);
23 }
24 for (i = 0; i < 7; i++) {
25 win->resistances[i] = createTextWindow(screen->layerId, 1, 0x5D, i * 0xE + 0x4F);
26 }
27 win->tp[0] = createTextWindow(screen->layerId, 1, 0x10, 0xBB);
28 win->tp[1] = createTextWindow(screen->layerId, 1, 0x2C, 0xBB);
29 win->help = createTextWindow(screen->layerId, 1, 0xA1, 0x17);
30 win->prompt = createTextWindow(screen->layerId, 1, 0xAE, 0x49);
31}
32
33/* Shows or hides the selected partner's name, level, HP and MP */
35 PartnerTotals totals;
36 PartnerStats *vitals;
37 s32 partner;
38 s32 i;
39
40 if (show) {
41 partner = GAME.funcs.getPartyMember(screen->partner);
42 vitals = GAME.funcs.getPartnerStats(partner);
43 GAME.funcs.computeStats(partner, &totals);
44 win->name->setString(win->name, vitals, -1);
45 win->level[0]->setString(win->level[0], FILE_CACHE.load(STGTRAIN_TEXT), 1);
46 win->level[1]->setNumber(win->level[1], 0, totals.fields.level);
47 win->level[1]->setRightAlign(win->level[1], 1);
48 win->hp[0]->setString(win->hp[0], FILE_CACHE.load(STGTRAIN_TEXT), 2);
49 win->hp[1]->setNumber(win->hp[1], 0, totals.fields.hp);
50 win->hp[2]->setNumber(win->hp[2], 0, totals.fields.maxHp);
51 for (i = 1; i < 3; i++) {
52 win->hp[i]->setPalette(win->hp[i], PALETTE_WHITE);
53 win->hp[i]->setRightAlign(win->hp[i], 1);
54 }
55 win->mp[0]->setString(win->mp[0], FILE_CACHE.load(STGTRAIN_TEXT), 3);
56 win->mp[1]->setNumber(win->mp[1], 0, totals.fields.mp);
57 win->mp[2]->setNumber(win->mp[2], 0, totals.fields.maxMp);
58 for (i = 1; i < 3; i++) {
59 win->mp[i]->setPalette(win->mp[i], PALETTE_WHITE);
60 win->mp[i]->setRightAlign(win->mp[i], 1);
61 }
62 for (i = 0; i < 2; i++) {
63 win->slashes[i]->setString(win->slashes[i], FILE_CACHE.load(STGTRAIN_TEXT), 0x43);
64 }
65 } else {
66 win->name->setVisible(win->name, 0);
67 for (i = 0; i < 2; i++) {
68 win->level[i]->setVisible(win->level[i], 0);
69 win->slashes[i]->setVisible(win->slashes[i], 0);
70 }
71 for (i = 0; i < 3; i++) {
72 win->hp[i]->setVisible(win->hp[i], 0);
73 }
74 for (i = 0; i < 3; i++) {
75 win->mp[i]->setVisible(win->mp[i], 0);
76 }
77 }
78}
79
80/* Shows or hides the selected partner's stats and resistances */
82 PartnerTotals totals;
83 s32 i;
84
85 if (show) {
87 for (i = 0; i < 6; i++) {
88 win->stats[i]->setNumber(win->stats[i], 0, totals.fields.battle[i]);
89 win->stats[i]->setRightAlign(win->stats[i], 1);
90 win->stats[i]->setPalette(win->stats[i], PALETTE_WHITE);
91 }
92 if (totals.fields.lowered[0] != 0) {
93 win->stats[0]->setPalette(win->stats[0], PALETTE_PURPLE);
94 }
95 if (totals.fields.lowered[1] != 0) {
96 win->stats[1]->setPalette(win->stats[1], PALETTE_PURPLE);
97 }
98 if (totals.fields.lowered[2] != 0) {
99 win->stats[4]->setPalette(win->stats[4], PALETTE_PURPLE);
100 }
101 for (i = 0; i < 7; i++) {
102 win->resistances[i]->setNumber(win->resistances[i], 0, totals.fields.resist[i]);
103 win->resistances[i]->setRightAlign(win->resistances[i], 1);
105 }
106 } else {
107 for (i = 0; i < 6; i++) {
108 win->stats[i]->setVisible(win->stats[i], 0);
109 }
110 for (i = 0; i < 7; i++) {
111 win->resistances[i]->setVisible(win->resistances[i], 0);
112 }
113 }
114}
115
116/* Shows or hides the selected partner's TP */
118 PartnerTotals totals;
119 s32 i;
120
121 if (show) {
123 win->tp[0]->setString(win->tp[0], FILE_CACHE.load(STGTRAIN_TEXT), 4);
124 win->tp[1]->setNumber(win->tp[1], 0, totals.fields.tp);
125 win->tp[1]->setRightAlign(win->tp[1], 1);
126 } else {
127 for (i = 0; i < 2; i++) {
128 win->tp[i]->setVisible(win->tp[i], 0);
129 }
130 }
131}
132
133/*
134 * Shows the selected partner's stats, in colour where they differ from
135 * before (NULL: just shows them). The MP label is given win->mp[3] (that
136 * is, slashes[0]) as its window, as in the original. The match depends on
137 * the stats and resistances being read as *(totals.fields.battle + i).
138 */
140 TrainScreenWindows *win = screen->children;
141 PartnerTotals totals;
142 s32 partner;
143 s32 i;
144
145 if (before == NULL) {
146 STGTRAIN_showVitals(screen, win, 1);
147 STGTRAIN_showBattleStats(screen, win, 1);
148 return;
149 }
150 partner = GAME.funcs.getPartyMember(screen->partner);
151 GAME.funcs.getPartnerStats(partner);
152 GAME.funcs.computeStats(partner, &totals);
153 win->hp[0]->setString(win->hp[0], FILE_CACHE.load(STGTRAIN_TEXT), 2);
154 win->hp[1]->setNumber(win->hp[1], 0, totals.fields.hp);
155 win->hp[2]->setNumber(win->hp[2], 0, totals.fields.maxHp);
156 for (i = 1; i < 3; i++) {
157 win->hp[i]->setRightAlign(win->hp[i], 1);
158 }
159 if (before->fields.maxHp < totals.fields.maxHp) {
160 win->hp[2]->setPalette(win->hp[2], PALETTE_BLUE);
161 } else if (totals.fields.maxHp < before->fields.maxHp) {
162 win->hp[2]->setPalette(win->hp[2], PALETTE_RED);
163 } else {
164 win->hp[2]->setPalette(win->hp[2], PALETTE_WHITE);
165 }
166 win->mp[0]->setString(win->mp[i], FILE_CACHE.load(STGTRAIN_TEXT), 3);
167 win->mp[1]->setNumber(win->mp[1], 0, totals.fields.mp);
168 win->mp[2]->setNumber(win->mp[2], 0, totals.fields.maxMp);
169 for (i = 1; i < 3; i++) {
170 win->mp[i]->setRightAlign(win->mp[i], 1);
171 }
172 if (before->fields.maxMp < totals.fields.maxMp) {
173 win->mp[2]->setPalette(win->mp[2], PALETTE_BLUE);
174 } else if (totals.fields.maxMp < before->fields.maxMp) {
175 win->mp[2]->setPalette(win->mp[2], PALETTE_RED);
176 } else {
177 win->mp[2]->setPalette(win->mp[2], PALETTE_WHITE);
178 }
179 for (i = 0; i < 2; i++) {
180 win->slashes[i]->setString(win->slashes[i], FILE_CACHE.load(STGTRAIN_TEXT), 0x43);
181 }
182 if (totals.fields.lowered[0] != 0) {
183 win->stats[0]->setPalette(win->stats[0], PALETTE_PURPLE);
184 }
185 if (totals.fields.lowered[1] != 0) {
186 win->stats[1]->setPalette(win->stats[1], PALETTE_PURPLE);
187 }
188 if (totals.fields.lowered[2] != 0) {
189 win->stats[4]->setPalette(win->stats[4], PALETTE_PURPLE);
190 }
191 for (i = 0; i < 6; i++) {
192 win->stats[i]->setNumber(win->stats[i], 0, *(totals.fields.battle + i));
193 win->stats[i]->setRightAlign(win->stats[i], 1);
194 if (before->fields.battle[i] < *(totals.fields.battle + i)) {
195 win->stats[i]->setPalette(win->stats[i], PALETTE_BLUE);
196 } else if (*(totals.fields.battle + i) < before->fields.battle[i]) {
197 win->stats[i]->setPalette(win->stats[i], PALETTE_RED);
198 }
199 }
200 for (i = 0; i < 7; i++) {
201 win->resistances[i]->setNumber(win->resistances[i], 0, *(totals.fields.resist + i));
202 win->resistances[i]->setRightAlign(win->resistances[i], 1);
203 if (before->fields.resist[i] < *(totals.fields.resist + i)) {
205 } else if (*(totals.fields.resist + i) < before->fields.resist[i]) {
207 }
208 }
209}
210
211/* Advances the selected partner's waiting animation, a frame every 13 ticks */
212static inline void STGTRAIN_animatePartner(TrainScreen *screen, s32 partner) {
213 if (GFX.funcs.getTime() - screen->time >= 0xD) {
214 screen->time = GFX.funcs.getTime();
215 screen->frame++;
216 if (screen->frame >= 7 || STGTRAIN_waitAnims[partner][screen->frame] == -1) {
217 screen->frame = 0;
218 }
219 }
220}
221
222/* Draws the screen: the panels, the party's sprites and the sign */
224 SpriteDrawer sprite;
225 s32 i;
226 s32 partner;
227
228 for (i = 0; i < screen->partyCount; i++) {
229 if (GFX.funcs.getTime() - screen->anims[i].time >= 0xD) {
230 screen->anims[i].time = GFX.funcs.getTime();
231 screen->anims[i].frame++;
232 partner = GAME.funcs.getPartyMember(i);
233 if (screen->anims[i].frame >= 7 || STGTRAIN_waitAnims[partner][screen->anims[i].frame] == -1) {
234 screen->anims[i].frame = 0;
235 }
236 }
237 }
238 partner = GAME.funcs.getPartyMember(screen->partner);
239 STGTRAIN_animatePartner(screen, partner);
240 initSpriteDrawer(&sprite);
241 sprite.setLayerId(screen->layerId, screen->depth);
242 if (screen->panels[0].level != 0) {
243 if (screen->panels[0].level != ONE) {
244 sprite.setScale(screen->panels[0].level, ONE, ONE);
245 sprite.setPivot(0, 0x2B);
246 } else {
247 sprite.setTexture(0x240, 0x100);
248 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), STGTRAIN_waitAnims[partner][screen->frame], 0x10, 0x16);
249 }
250 sprite.setTexture(0x140, 0);
251 sprite.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0xE, 0, 0xF);
252 sprite.setTexture(0x240, 0x100);
253 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x1F, 0, 0xF);
254 }
255 if (screen->panels[1].level != 0) {
256 if (screen->panels[1].level != ONE) {
257 sprite.setScale(screen->panels[1].level, ONE, ONE);
258 sprite.setPivot(0, 0x7F);
259 }
260 sprite.setTexture(0x140, 0);
261 sprite.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0xF, 0, 0x4B);
262 sprite.setTexture(0x240, 0x100);
263 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x20, 0, 0x4B);
264 }
265 if (screen->panels[2].level != 0) {
266 if (screen->panels[2].level != ONE) {
267 sprite.setScale(screen->panels[2].level, ONE, ONE);
268 sprite.setPivot(0, 0xC1);
269 }
270 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x21, 0, 0xB6);
271 }
272 if (screen->panels[5].level != 0) {
273 for (i = 0; i < screen->partyCount; i++) {
274 if (screen->panels[5].level != ONE) {
275 sprite.setScale(screen->panels[5].level, ONE, ONE);
276 sprite.setPivot(i * 0x30 + 0xB4, 0x8A);
277 }
278 partner = GAME.funcs.getPartyMember(i);
279 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), STGTRAIN_waitAnims[partner][screen->anims[i].frame], i * 0x30 + 0xA4, 0x81);
280 }
281 }
282 if (screen->cursorShown != 0) {
283 if (GFX.funcs.getTime() - screen->cursorTime >= 0xB) {
284 screen->cursorTime = GFX.funcs.getTime();
285 screen->cursorClut++;
286 if (screen->cursorClut >= 4) {
287 screen->cursorClut = 0;
288 }
289 }
290 sprite.setLayerId(screen->layerId, screen->depth - 2);
291 sprite.setTexture(0x140, 0);
292 sprite.setClutRow(screen->cursorClut);
293 sprite.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0xD, screen->partner * 0x30 + 0xA4, 0x65);
294 sprite.setClutRow(0);
295 }
296 if (screen->panels[6].level != 0) {
297 STRETCH_SPRITE(sprite, screen->panels[6].level, 0x140, 0x8A);
298 sprite.setLayerId(screen->layerId, screen->depth - 1);
299 sprite.setTexture(0x140, 0);
300 sprite.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0x10, 0x8F, 0x5F);
301 sprite.setLayerId(screen->layerId, screen->depth);
302 sprite.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 0x11, 0x8F, 0x5F);
303 sprite.setTexture(0x240, 0x100);
304 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x24, 0x8F, 0x5F);
305 }
306 if (screen->panels[3].level != 0) {
307 STRETCH_SPRITE(sprite, screen->panels[3].level, 0x140, 0x1D);
308 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x27, 0x8F, 0xF);
309 }
310 if (screen->panels[4].level != 0) {
311 if (screen->panels[4].level != ONE) {
312 sprite.setScale(screen->panels[4].level, ONE, ONE);
313 sprite.setPivot(0x140, 0x4E);
314 }
315 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), 0x22, 0x92, 0x43);
316 }
317 initSpriteDrawer(&sprite);
318 sprite.setLayerId(screen->layerId, 7);
319 sprite.setTexture(0x240, 0x100);
320 if (screen->bgTick != 0) {
321 screen->bgScroll++;
322 screen->bgScroll = screen->bgScroll < 0x60 ? screen->bgScroll : 0;
323 screen->bgTick = 0;
324 } else {
325 screen->bgTick = 1;
326 }
327 sprite.draw(FILE_CACHE.getEntry(STGTRAIN_SPRITES), screen->bgSprite, screen->bgScroll, screen->bgScroll);
328}
329
330/* Moves the cursor over the party (left, right), showing the partner's
331 stats, and picks the one to train (cross) or leaves (triangle) */
332static inline void STGTRAIN_pickPartner(TrainScreen *screen, TrainScreenWindows *win) {
333 s32 partner;
334
335 partner = screen->partner;
337 screen->partner--;
338 if (screen->partner < 0) {
339 screen->partner = 0;
340 }
342 screen->partner++;
343 if (screen->partner > screen->partyCount - 1) {
344 screen->partner = screen->partyCount - 1;
345 }
346 }
347 if (partner != screen->partner) {
349 STGTRAIN_showVitals(screen, win, 1);
350 STGTRAIN_showBattleStats(screen, win, 1);
351 STGTRAIN_showTp(screen, win, 1);
352 screen->frame = 0;
353 } else if (PAD_PRESSED(PAD_CROSS)) {
355 screen->substate = 0x14;
356 if (win->menu != NULL) {
357 win->menu->state = TASK_KILL;
358 }
359 } else if (PAD_PRESSED(PAD_TRIANGLE)) {
361 screen->substate = 0x32;
362 }
363}
364
365/* Closes the partner pick: hides the cursor, the prompt and the help, and
366 closes their panels */
368 STGTRAIN_state.startFade(&screen->panels[6], 0);
369 screen->cursorShown = 0;
370 STGTRAIN_state.startFade(&screen->panels[4], 0);
371 win->prompt->setVisible(win->prompt, 0);
372 STGTRAIN_state.startFade(&screen->panels[3], 0);
373 win->help->setVisible(win->help, 0);
374}
375
376/* Updates the fades of the partner pick's panels; whether they are done */
378 STGTRAIN_state.updateFade(&screen->panels[6]);
379 STGTRAIN_state.updateFade(&screen->panels[4]);
380 return STGTRAIN_state.updateFade(&screen->panels[3]);
381}
382
383/* Waits for the session: once it is training (its substate 0x23), ends the
384 last result first, then makes the next one with the TP shown; once it is
385 done, goes back to the menu */
386static inline void STGTRAIN_waitSession(TrainScreen *screen, TrainScreenWindows *win) {
387 if (win->session->substate == 0x23) {
388 if (win->result != NULL) {
389 win->result->state = TASK_KILL;
390 } else {
391 screen->substate = 0x23;
392 STGTRAIN_showTp(screen, win, 1);
393 }
394 } else if (win->session->state == TASK_DONE) {
395 win->session->state = TASK_KILL;
396 screen->substate = 0xA;
397 }
398}
399
400/* Starts leaving the screen: fades it out and closes every panel */
401static inline void STGTRAIN_startLeaving(TrainScreen *screen, TrainScreenWindows *win) {
402 s32 i;
403
404 win->fade = STGTRAIN_createFader();
405 win->fade->start(win->fade, 0, 30);
406 screen->panels[5].level = 0;
407 for (i = 0; i < 3; i++) {
408 STGTRAIN_state.startFade(&screen->panels[i], 0);
409 }
410 STGTRAIN_showVitals(screen, win, 0);
411 STGTRAIN_showBattleStats(screen, win, 0);
412 STGTRAIN_showTp(screen, win, 0);
413 STGTRAIN_closePartnerPick(screen, win);
414}
415
416/* Once the vitals' panel is open (with the help's), shows the vitals and
417 the help, and opens the battle stats' and the prompt's panels */
418static inline void STGTRAIN_openBattleStats(TrainScreen *screen, TrainScreenWindows *win) {
419 STGTRAIN_state.updateFade(&screen->panels[3]);
420 if (STGTRAIN_state.updateFade(&screen->panels[0])) {
421 STGTRAIN_showVitals(screen, win, 1);
423 STGTRAIN_state.startFade(&screen->panels[1], 1);
424 STGTRAIN_state.startFade(&screen->panels[4], 1);
425 screen->substate++;
426 }
427}
428
429/* Once the battle stats' panel is open, shows them and the prompt, and
430 opens the TP's panel and the party's window */
431static inline void STGTRAIN_openTp(TrainScreen *screen, TrainScreenWindows *win) {
432 STGTRAIN_state.updateFade(&screen->panels[4]);
433 if (STGTRAIN_state.updateFade(&screen->panels[1])) {
434 STGTRAIN_showBattleStats(screen, win, 1);
436 STGTRAIN_state.startFade(&screen->panels[2], 1);
437 STGTRAIN_state.startFade(&screen->panels[6], 1);
438 screen->substate++;
439 }
440}
441
442/* Once the TP's panel is open, shows the TP and opens the party's panel */
443static inline void STGTRAIN_openParty(TrainScreen *screen, TrainScreenWindows *win) {
444 STGTRAIN_state.updateFade(&screen->panels[6]);
445 if (STGTRAIN_state.updateFade(&screen->panels[2])) {
446 STGTRAIN_showTp(screen, win, 1);
447 STGTRAIN_state.startFade(&screen->panels[5], 1);
448 screen->substate++;
449 }
450}
451
452/* Waits for the menu to close: with a training picked it is gone, and the
453 training's session starts; without one (triangle) it is done, and the
454 partner pick reopens */
455static inline void STGTRAIN_waitMenu(TrainScreen *screen, TrainScreenWindows *win) {
456 if (win->menu == NULL) {
457 screen->substate = 0x1E;
458 } else if (win->menu->state == TASK_DONE) {
459 screen->training = 0;
460 win->menu->state = TASK_KILL;
461 screen->substate = 0x19;
462 }
463}
464
465/* Updates the fades of every panel as the screen closes; whether they are
466 done */
467static inline s32 STGTRAIN_screenClosed(TrainScreen *screen) {
468 s32 i;
469
470 for (i = 0; i < 3; i++) {
471 STGTRAIN_state.updateFade(&screen->panels[i]);
472 }
473 return STGTRAIN_partnerPickClosed(screen);
474}
475
476/* The training screen: opens the panels, picks the partner, runs the menu
477 and the trainings, and closes everything when leaving */
479 switch (screen->substate) {
480 case 0:
481 default:
482 STGTRAIN_state.startFade(&screen->panels[0], 1);
483 STGTRAIN_state.startFade(&screen->panels[3], 1);
484 screen->substate++;
485 break;
486 case 1:
487 STGTRAIN_openBattleStats(screen, win);
488 break;
489 case 2:
490 STGTRAIN_openTp(screen, win);
491 break;
492 case 3:
493 STGTRAIN_openParty(screen, win);
494 break;
495 case 4:
496 if (STGTRAIN_state.updateFade(&screen->panels[5])) {
497 screen->cursorShown = 1;
498 screen->substate++;
499 }
500 break;
501 case 5:
502 STGTRAIN_pickPartner(screen, win);
503 break;
504 case 0xA:
505 if (win->menu == NULL) {
506 win->menu = STGTRAIN_createMenu(screen);
507 screen->substate++;
508 }
509 break;
510 case 0xB:
511 STGTRAIN_waitMenu(screen, win);
512 break;
513 case 0x14:
514 screen->panels[5].level = 0;
515 STGTRAIN_closePartnerPick(screen, win);
516 screen->substate++;
517 break;
518 case 0x15:
519 if (STGTRAIN_partnerPickClosed(screen)) {
520 screen->substate = 0xA;
521 }
522 break;
523 case 0x19:
524 STGTRAIN_state.startFade(&screen->panels[3], 1);
525 screen->substate++;
526 break;
527 case 0x1A:
528 if (STGTRAIN_state.updateFade(&screen->panels[3])) {
530 STGTRAIN_state.startFade(&screen->panels[4], 1);
531 screen->substate++;
532 }
533 break;
534 case 0x1B:
535 if (STGTRAIN_state.updateFade(&screen->panels[4])) {
537 STGTRAIN_state.startFade(&screen->panels[6], 1);
538 screen->substate++;
539 }
540 break;
541 case 0x1C:
542 if (STGTRAIN_state.updateFade(&screen->panels[6])) {
543 STGTRAIN_state.startFade(&screen->panels[5], 1);
544 screen->substate = 4;
545 }
546 break;
547 case 0x1E:
548 if (win->session == NULL) {
549 win->session = STGTRAIN_createSession(screen);
550 screen->substate++;
552 }
553 break;
554 case 0x1F:
555 STGTRAIN_waitSession(screen, win);
556 break;
557 case 0x23:
558 if (STGTRAIN_state.getFile() != NULL && win->result == NULL) {
559 win->result = STGTRAIN_createResult(screen, GAME.funcs.getPartyMember(screen->partner), screen->training);
560 screen->substate++;
561 }
562 break;
563 case 0x24:
564 if (win->result == NULL) {
565 win->session->finish(win->session);
566 screen->substate++;
567 }
568 break;
569 case 0x25:
570 if (win->session == NULL) {
571 STGTRAIN_showBattleStats(screen, win, 1);
572 screen->substate = 0x19;
573 }
574 break;
575 case 0x32:
576 STGTRAIN_startLeaving(screen, win);
577 screen->substate++;
578 break;
579 case 0x33:
580 if (STGTRAIN_screenClosed(screen)) {
581 screen->substate++;
582 }
583 break;
584 case 0x34:
585 if (win->fade->state == TASK_DONE) {
586 screen->state = TASK_KILL;
587 }
588 break;
589 }
590}
591
592/* The training screen's update: loads its files, then runs the menu */
594 s32 i;
595
596 switch (screen->state) {
597 case TASK_INIT:
598 default:
599 switch (screen->substate) {
600 case 0:
601 default:
604 SOUND.loadBank(0x21);
605 screen->substate++;
606 break;
607 case 1:
609 screen->nextState(screen);
610 STGTRAIN_createScreenWindows(screen, win);
611 for (i = 0; i < 3; i++) {
612 if (GAME.funcs.getPartyMember(i) != -1) {
613 screen->partyCount++;
614 }
615 }
616 for (i = 0; i < 3; i++) {
617 screen->panels[i].duration = 10;
618 }
619 screen->panels[3].duration = 10;
620 screen->panels[4].duration = 10;
621 screen->panels[6].duration = 10;
622 screen->panels[5].duration = 8;
623 screen->setState(screen, TASK_DONE);
624 }
625 break;
626 }
627 break;
628 case TASK_RUN:
629 STGTRAIN_runScreen(screen, win);
630 STGTRAIN_drawScreen(screen);
631 break;
632 case TASK_DONE:
633 if (SOUND.isLoading() == 0) {
635 screen->setState(screen, TASK_RUN);
636 }
637 break;
638 case TASK_KILL:
641 break;
642 }
643}
644
645/* Creates the training screen */
648 s32 sign;
649
651 screen->layerId = SCREEN_LAYER;
652 screen->depth = 6;
653 /* the gym's sign, by the stage the player came from */
654 switch (GAME.funcs.getPrevMode()) {
655 case 0x23D: /* South Cape */
656 sign = 0x2E;
657 break;
658 case 0x24B: /* North Wind Wasteland East */
659 sign = 0x2F;
660 break;
661 case 0x267: /* the Legendary Gym */
662 sign = 0x30;
663 break;
664 case 0x28C: /* Central Park, in Amaterasu */
665 sign = 0x31;
666 break;
667 case 0x2AA: /* South Cape, in Amaterasu */
668 sign = 0x32;
669 break;
670 case 0x2B5: /* North Wind Wasteland East, in Amaterasu */
671 sign = 0x33;
672 break;
673 case 0x2CF: /* the Legendary Gym, in Amaterasu */
674 sign = 0x34;
675 break;
676 case 0x21D: /* Central Park */
677 default:
678 sign = 0x2D;
679 break;
680 }
681 screen->bgSprite = sign;
682 return screen;
683}
684
688#define FADER_DEPTH 6
690
691/* The partners' sprites while they wait, by partner: -1 ends a loop */
693 {7, 8, 9, 10, 9, 8, -1},
694 {14, 15, 16, 15, -1, -1, -1},
695 {11, 12, 13, 12, -1, -1, -1},
696 {3, 4, 5, 6, 5, 4, -1},
697 {25, 26, 27, 28, 27, 26, -1},
698 {0, 1, 2, 1, -1, -1, -1},
699 {17, 18, 19, 20, 19, 18, -1},
700 {21, 22, 23, 24, 23, 22, -1},
701};
#define NULL
Definition common.h:17
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
#define FILE_MENU_SPRITES
Files the engine loads by number.
Definition file.h:188
FileCache FILE_CACHE
The file cache.
Definition file_cache.c:7
TrainState STGTRAIN_state
Definition files.c:422
@ PARTNER_COUNT
Definition game_state.h:472
#define STRETCH_SPRITE(sprite, level, x, y)
Definition gfx.h:273
#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_SPRITES
its sprite bank
Definition gym.h:23
ScreenFade * STGTRAIN_createFader(void)
#define STGTRAIN_TEXT
The overlay's files: the discs number them differently.
Definition gym.h:19
TrainMenu * STGTRAIN_createMenu(TrainScreen *screen)
Creates the training menu.
Definition menu.c:437
static void STGTRAIN_openBattleStats(TrainScreen *screen, TrainScreenWindows *win)
Once the vitals' panel is open (with the help's), shows the vitals and the help, and opens the battle...
Definition screen.c:418
static s32 STGTRAIN_partnerPickClosed(TrainScreen *screen)
Updates the fades of the partner pick's panels; whether they are done.
Definition screen.c:377
void STGTRAIN_drawScreen(TrainScreen *screen)
Draws the screen: the panels, the party's sprites and the sign.
Definition screen.c:223
s32 STGTRAIN_waitAnims[PARTNER_COUNT][7]
The partners' sprites while they wait, by partner: -1 ends a loop.
Definition screen.c:692
void STGTRAIN_showTp(TrainScreen *screen, TrainScreenWindows *win, s32 show)
Shows or hides the selected partner's TP.
Definition screen.c:117
static void STGTRAIN_animatePartner(TrainScreen *screen, s32 partner)
Advances the selected partner's waiting animation, a frame every 13 ticks.
Definition screen.c:212
void STGTRAIN_runScreen(TrainScreen *screen, TrainScreenWindows *win)
The training screen: opens the panels, picks the partner, runs the menu and the trainings,...
Definition screen.c:478
static void STGTRAIN_openTp(TrainScreen *screen, TrainScreenWindows *win)
Once the battle stats' panel is open, shows them and the prompt, and opens the TP's panel and the par...
Definition screen.c:431
void STGTRAIN_showVitals(TrainScreen *screen, TrainScreenWindows *win, s32 show)
Shows or hides the selected partner's name, level, HP and MP.
Definition screen.c:34
static void STGTRAIN_pickPartner(TrainScreen *screen, TrainScreenWindows *win)
Moves the cursor over the party (left, right), showing the partner's stats, and picks the one to trai...
Definition screen.c:332
void STGTRAIN_showStatChanges(TrainScreen *screen, PartnerTotals *before)
Shows the selected partner's stats, in colour where they differ from before (NULL: just shows them).
Definition screen.c:139
static void STGTRAIN_waitSession(TrainScreen *screen, TrainScreenWindows *win)
Waits for the session: once it is training (its substate 0x23), ends the last result first,...
Definition screen.c:386
static s32 STGTRAIN_screenClosed(TrainScreen *screen)
Updates the fades of every panel as the screen closes; whether they are done.
Definition screen.c:467
TrainScreen * STGTRAIN_createScreen(void)
Creates the training screen.
Definition screen.c:646
static void STGTRAIN_closePartnerPick(TrainScreen *screen, TrainScreenWindows *win)
Closes the partner pick: hides the cursor, the prompt and the help, and closes their panels.
Definition screen.c:367
void STGTRAIN_showBattleStats(TrainScreen *screen, TrainScreenWindows *win, s32 show)
Shows or hides the selected partner's stats and resistances.
Definition screen.c:81
static void STGTRAIN_openParty(TrainScreen *screen, TrainScreenWindows *win)
Once the TP's panel is open, shows the TP and opens the party's panel.
Definition screen.c:443
void STGTRAIN_updateScreen(TrainScreen *screen, TrainScreenWindows *win)
The training screen's update: loads its files, then runs the menu.
Definition screen.c:593
void STGTRAIN_createScreenWindows(TrainScreen *screen, TrainScreenWindows *win)
Creates the screen's text windows.
Definition screen.c:7
static void STGTRAIN_waitMenu(TrainScreen *screen, TrainScreenWindows *win)
Waits for the menu to close: with a training picked it is gone, and the training's session starts; wi...
Definition screen.c:455
static void STGTRAIN_startLeaving(TrainScreen *screen, TrainScreenWindows *win)
Starts leaving the screen: fades it out and closes every panel.
Definition screen.c:401
#define PAD_CROSS
Definition pad.h:31
#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_LEFT
Definition pad.h:25
#define PAD_REPEATED(button)
Definition pad.h:141
TrainResult * STGTRAIN_createResult(TrainScreen *screen, s32 partner, s32 training)
Creates the results of a training of a partner.
Definition result.c:724
TrainSession * STGTRAIN_createSession(TrainScreen *screen)
Creates a training session.
Definition session.c:456
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 MUSIC_TRAINING
TRAINING: the gym's training.
Definition sound.h:107
#define SOUND_MENU_CONFIRM
SYSTEM07.
Definition sound.h:44
#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
s32(* isLoading)(s32 file)
Definition file.h:88
void(* request)(s32 file)
Definition file.h:90
void *(* getEntry)(u32 fileAndIndex)
Definition file.h:96
struct PartnerStats *(* getPartnerStats)(s32 partner)
Definition game_state.h:38
void(* computeStats)(s32 partner, union PartnerTotals *out)
Definition game_state.h:31
void(* requestMode)(s32 mode, s32 arg)
Definition game_state.h:21
s32(* getPrevMode)()
Definition game_state.h:23
s32(* getPartyMember)(u32 index)
Definition game_state.h:24
s32 fieldMode
where the menu returns to
Definition game_state.h:503
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
A partner Digimon from its name on (Partner.info), as getPartnerStats gives it.
Definition game_state.h:303
void(* start)(struct ScreenFade *fade, s32 fadeIn, s32 frames)
TASK_DONE when done.
Definition gfx.h:368
s32 state
Definition gfx.h:362
s32(* isLoading)(void)
Definition sound.h:193
void(* stopSound)(s32 id)
Definition sound.h:195
void(* loadBank)(s32 id)
Definition sound.h:190
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
void(* setPalette)(struct TextWindow *obj, u8 arg)
Definition text.h:174
void(* setRightAlign)()
no prototype: callers would truncate u8 args
Definition text.h:178
void(* setNumber)()
Definition text.h:166
void(* setString)()
Definition text.h:165
void(* setVisible)(struct TextWindow *obj, u8 arg)
Definition text.h:177
s32 state
Definition gym.h:150
s32 state
Definition gym.h:251
The children of the training screen.
Definition gym.h:131
TextWindow * stats[6]
Definition gym.h:137
TextWindow * tp[2]
Definition gym.h:139
TextWindow * slashes[2]
Definition gym.h:136
struct TrainSession * session
Definition gym.h:143
TextWindow * resistances[7]
Definition gym.h:138
TextWindow * level[2]
Definition gym.h:133
TextWindow * help
triangle stops training (string 5)
Definition gym.h:140
TextWindow * name
Definition gym.h:132
struct TrainResult * result
Definition gym.h:144
TextWindow * hp[3]
Definition gym.h:134
ScreenFade * fade
Definition gym.h:145
TextWindow * prompt
"Train which Digimon?" (string 6)
Definition gym.h:141
TextWindow * mp[3]
Definition gym.h:135
struct TrainMenu * menu
Definition gym.h:142
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
struct TrainScreen::@15 anims[3]
the party's sprites
s32 cursorTime
Definition gym.h:117
s32 partner
the one selected
Definition gym.h:114
void(* nextState)(struct TrainScreen *task)
Definition gym.h:107
s32 cursorClut
Definition gym.h:116
void(* showStats)(struct TrainScreen *screen, PartnerTotals *before)
Definition gym.h:127
PanelAnim panels[7]
Definition gym.h:126
s32 substate
Definition gym.h:107
s32 cursorShown
Definition gym.h:115
void * children
Definition gym.h:107
s32 time
Definition gym.h:122
s32 frame
the selected partner's sprite
Definition gym.h:121
s32 bgScroll
Definition gym.h:111
void(* setState)(struct TrainScreen *task, s32 state)
Definition gym.h:107
s32 bgTick
Definition gym.h:112
s32 state
Definition gym.h:107
s32 bgSprite
the gym's sign, by the mode it came from
Definition gym.h:110
s32 depth
Definition gym.h:109
s32 layerId
Definition gym.h:108
s32 partyCount
Definition gym.h:113
void(* finish)(struct TrainSession *session)
Definition gym.h:186
s32 substate
Definition gym.h:174
s32 state
Definition gym.h:174
s32(* requestFile)(s32 index)
Definition gym.h:351
void(* loadImages)(void)
Definition gym.h:346
u8 *(* getFile)(void)
Definition gym.h:352
s32(* updateFade)(PanelAnim *fade)
Definition gym.h:348
void(* startFade)(PanelAnim *fade, s32 fadeIn)
Definition gym.h:347
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105
#define PALETTE_BLUE
a light blue: what is highlighted or current
Definition text.h:113
#define PALETTE_PURPLE
Definition text.h:118
#define PALETTE_RED
Definition text.h:117
#define PALETTE_WHITE
The text windows' palettes (TextWindow.palette, setPalette): rows of the font's CLUTs,...
Definition text.h:112
TextWindow * createTextWindow(s16 layerId, s16 style, s16 x, s16 y)
A text window on a layer, in a font style, at (x, y)
computeStats' result: the stats with the equipment added, by STAT_* or by name.
Definition game_state.h:409
s16 tp
what the training's intensities cost
Definition game_state.h:413
s16 lowered[3]
taken from battle[0], [1] and [4]
Definition game_state.h:421
s16 battle[6]
strength (raised by weapons), defense (by armour), spirit, wisdom, speed and charisma (by all equipme...
Definition game_state.h:418
struct PartnerTotals::@10 fields