Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
message.c
Go to the documentation of this file.
1/* FIGHTSTG's message box and its messages. */
2
4
5/* Draws the message box and, once its lines are out, its blinking arrow */
7 SpriteDrawer drawer;
8 void *sheet;
9
10 initSpriteDrawer(&drawer);
12 if (task->showArrow != 0) {
13 if (GFX.funcs.getTime() - task->arrowTime >= 4) {
14 task->arrowTime = GFX.funcs.getTime();
15 task->arrowPalette++;
16 if (task->arrowPalette >= 5) {
17 task->arrowPalette = 0;
18 }
19 }
20 drawer.setTexture(0x140, 0);
21 drawer.setClutRow(task->arrowPalette);
22 drawer.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), 10, 0x123, 0xD0);
23 drawer.setClutRow(0);
24 }
26 drawer.setTexture(0x200, 0);
27 drawer.draw(sheet, 0x31, 0xB, 0xBC);
28}
29
30/* Shows the message's lines one by one, 3 frames apart, then on cross shows
31 the queue's next message or ends; after finish (substate 4) it ends after
32 0x14 frames or on cross */
34 switch (task->substate) {
35 case 0:
36 default:
37 if (task->started != 0) {
38 task->substate++;
39 }
40 break;
41 case 1:
42 task->shownTime = GFX.funcs.getTime();
43 task->interval = 3;
44 windows->lines[task->shown]->setVisible(windows->lines[task->shown], 1);
45 task->substate++;
46 break;
47 case 2:
48 if (task->interval < GFX.funcs.getTime() - task->shownTime) {
49 if (++task->shown >= task->count) {
50 task->showArrow = 1;
51 task->substate++;
52 } else {
53 task->substate = 1;
54 }
55 }
56 break;
57 case 3:
58 if (PAD.getPressed(0) & (1 << PAD_CROSS)) {
60 if (task->queue[++task->next] == 0) {
61 task->state = 3;
62 } else {
63 task->show(task, task->queue[task->next], 0);
64 task->setSubstate(task, 0);
65 }
66 task->showArrow = 0;
67 }
68 break;
69 case 4:
70 if (GFX.funcs.getTime() - task->step > 0x14 || (PAD.getPressed(0) & (1 << PAD_CROSS))) {
71 task->state = 3;
72 }
73 break;
74 }
75}
76
77/* The battle message box's task: draws it and steps its message each frame */
78void FIGHTSTG_updateMessage(BattleMessageBox *task, void *children) {
79 switch (task->state) {
80 case TASK_INIT:
81 default:
82 task->nextState(task);
83 break;
84 case TASK_RUN:
86 FIGHTSTG_stepMessage(task, children);
87 break;
88 case TASK_DONE:
89 case TASK_KILL:
90 break;
91 }
92}
93
94/* Puts the name of side's fighter index (a partner's own, an enemy's from the
95 battle table) into the message's first line */
97 BattleFighter *fighter;
98 BattleTableEntry *entry;
99
100 if (side == 0) {
102 } else {
103 fighter = &FIGHTSTG_battle.state.fighters[1][index];
104 entry = FIGHTSTG_battleTableFunc(fighter->id);
106 }
107}
108
109/* Lists in task's found the fighters of filter's side that its type picks: 0
110 the hurt, 1 the poisoned, 2 the paralyzed, 3 the confused, 4 those with
111 any status, 5 the knocked out, 6 all, 7-9 those standing */
113 s32 side = filter->side != 0;
114 BattleFighter *fighters;
115 s32 i;
116
117 task->foundCount = 0;
118 fighters = FIGHTSTG_battle.state.fighters[side];
119 switch (filter->type) {
120 case 0:
121 default:
122 for (i = 0; i < 3; i++) {
123 if (fighters[i].id != 0 && fighters[i].hp != 0 && fighters[i].hp < fighters[i].maxHp) {
124 task->found[task->foundCount++] = i;
125 }
126 }
127 break;
128 case 1:
129 for (i = 0; i < 3; i++) {
130 if (fighters[i].id != 0 && fighters[i].hp != 0 && (fighters[i].flags & FIGHTER_POISONED)) {
131 task->found[task->foundCount++] = i;
132 }
133 }
134 break;
135 case 2:
136 for (i = 0; i < 3; i++) {
137 if (fighters[i].id != 0 && fighters[i].hp != 0 && (fighters[i].flags & FIGHTER_PARALYZED)) {
138 task->found[task->foundCount++] = i;
139 }
140 }
141 break;
142 case 3:
143 for (i = 0; i < 3; i++) {
144 if (fighters[i].id != 0 && fighters[i].hp != 0 && (fighters[i].flags & FIGHTER_CONFUSED)) {
145 task->found[task->foundCount++] = i;
146 }
147 }
148 break;
149 case 4:
150 for (i = 0; i < 3; i++) {
151 if (fighters[i].id != 0 && fighters[i].hp != 0 && fighters[i].flags != 0) {
152 task->found[task->foundCount++] = i;
153 }
154 }
155 break;
156 case 5:
157 for (i = 0; i < 3; i++) {
158 if (fighters[i].id != 0 && fighters[i].hp == 0) {
159 task->found[task->foundCount++] = i;
160 }
161 }
162 break;
163 case 6:
164 for (i = 0; i < 3; i++) {
165 if (fighters[i].id != 0) {
166 task->found[task->foundCount++] = i;
167 }
168 }
169 break;
170 case 7:
171 case 8:
172 case 9:
173 for (i = 0; i < 3; i++) {
174 if (fighters[i].id != 0 && fighters[i].hp != 0) {
175 task->found[task->foundCount++] = i;
176 }
177 }
178 break;
179 }
180}
181
182/* Sets up a message about the fighters FIGHTSTG_findFighters found: their
183 names (text 0x15 plus their count) and what happened to them by msg's kind,
184 or text 0x2F when there are none */
186 BattleFighter *fighter;
187 BattleTableEntry *entry;
188 s32 member;
189 u8 side;
190 s32 kind;
191 s32 i;
192
193 if (task->foundCount != 0) {
194 side = msg->side;
195 kind = msg->kind;
197 if (side == 0) {
198 for (i = 0; i < task->foundCount; i++) {
199 member = GAME.funcs.getPartyMember(task->found[i]);
200 if (member >= 0) {
201 w->lines[0]->setSubString(w->lines[0], GAME.funcs.getPartnerStats(member), -1, i + 1);
202 }
203 }
204 } else {
205 for (i = 0; i < task->foundCount; i++) {
206 fighter = &FIGHTSTG_battle.state.fighters[1][task->found[i]];
207 if (fighter->id != 0) {
208 entry = FIGHTSTG_battleTableFunc(fighter->id);
210 }
211 }
212 }
213 switch (kind) {
214 case 0:
215 default:
217 w->lines[1]->setNumber(w->lines[1], 1, msg->value);
218 break;
219 case 1:
221 break;
222 case 2:
224 break;
225 case 3:
227 break;
228 case 4:
230 break;
231 case 5:
233 break;
234 case 6:
236 break;
237 case 7:
239 break;
240 case 8:
242 break;
243 case 9:
245 break;
246 }
247 task->count = 2;
248 } else {
250 task->count = 1;
251 }
252}
253
254/* The message box's show: sets up the lines of message type from data, mostly
255 a fighter's name with a text, a technique or a number, and starts showing
256 them */
259 s32 total;
260 s32 side;
261
262 task->started = 1;
263 if (w->lines[0] == NULL) {
264 w->lines[0] = createTextWindow(BATTLE_LAYER_MENUS, 1, 0x14, 0xC2);
265 }
266 if (w->lines[1] == NULL) {
267 w->lines[1] = createTextWindow(BATTLE_LAYER_MENUS, 1, 0x14, 0xD0);
268 }
269 task->shown = 0;
270 switch (type) {
271 case 1:
273 task->count = 1;
274 break;
275 case 2:
278 task->count = 2;
279 FIGHTSTG_setMessageName(task, w, data[1], FIGHTSTG_battle.state.active[data[1] != 0]);
280 break;
281 case 3:
284 w->lines[1]->setSubString(w->lines[1], FILE_CACHE.load(TEXT_FILE(TEXT_SKILL_NAMES)), data[1], 1);
285 task->count = 2;
286 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
287 break;
288 case 4:
291 w->lines[1]->setNumber(w->lines[1], 1, data[1]);
292 task->count = 2;
293 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
294 break;
295 case 5:
298 w->lines[1]->setSubString(w->lines[1], FILE_CACHE.load(TEXT_FILE(TEXT_SKILL_NAMES)), data[1], 1);
299 task->count = 2;
300 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
301 break;
302 case 6:
305 task->count = 2;
306 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
307 break;
308 case 7:
311 task->count = 2;
312 FIGHTSTG_setMessageName(task, w, data[1], data[2]);
313 break;
314 case 8:
317 w->lines[1]->setNumber(w->lines[1], 1, data[1]);
318 task->count = 2;
319 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
320 break;
321 case 9:
322 /* its args are read both as which fighters to find and as what to
323 say of them */
326 break;
327 case 10:
330 task->count = 2;
331 FIGHTSTG_setMessageName(task, w, data[0], data[1]);
332 task->queue[1] = 11;
333 task->queue[2] = data[0];
334 task->queue[3] = data[1];
335 task->queue[4] = data[2];
336 break;
337 case 11:
338 data = &task->queue[task->next + 1];
341 w->lines[1]->setNumber(w->lines[1], 1, data[2]);
342 task->count = 2;
343 FIGHTSTG_setMessageName(task, w, data[0], data[1]);
344 task->next += 3;
345 break;
346 case 12:
350 task->count = 2;
351 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
352 break;
353 case 13:
357 task->count = 2;
358 break;
359 case 14:
362 w->lines[1]->setSubString(w->lines[1], FILE_CACHE.load(TEXT_FILE(TEXT_ITEM_NAMES)), data[1], 1);
363 task->count = 2;
364 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
365 break;
366 case 15:
369 w->lines[1]->setNumber(w->lines[1], 1, data[2]);
370 task->count = 2;
371 FIGHTSTG_setMessageName(task, w, data[0], data[1]);
372 break;
373 case 16:
376 total = data[1] * data[2];
377 w->lines[1]->setNumber(w->lines[1], 1, data[1]);
378 w->lines[1]->setNumber(w->lines[1], 2, data[2]);
379 w->lines[1]->setNumber(w->lines[1], 3, total);
380 task->count = 2;
381 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
382 break;
383 case 17:
386 w->lines[1]->setSubString(w->lines[1], FILE_CACHE.load(TEXT_FILE(TEXT_ITEM_NAMES)), data[0], 1);
387 task->count = 2;
388 break;
389 case 18:
391 if (data[2] == 0) {
393 } else {
395 }
396 w->lines[1]->setNumber(w->lines[1], 1, data[1]);
397 task->count = 2;
398 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
399 break;
400 case 19:
402 w->lines[1]->setString(w->lines[1], FILE_CACHE.load(TEXT_FILE(TEXT_BATTLE_MENU)), data[1] + 0x49);
403 task->count = 2;
404 FIGHTSTG_setMessageName(task, w, data[0], FIGHTSTG_battle.state.active[data[0] != 0]);
405 break;
406 case 20:
407 FIGHTSTG_showMessage(task, 4, data);
408 task->queue[1] = 21;
409 task->queue[2] = (data[0] == 0) << 4;
410 task->queue[3] = data[1];
411 break;
412 case 21:
413 side = task->queue[task->next + 1];
416 w->lines[1]->setNumber(w->lines[1], 1, task->queue[task->next + 2]);
417 task->count = 2;
418 FIGHTSTG_setMessageName(task, w, side, FIGHTSTG_battle.state.active[side != 0]);
419 task->next += 2;
420 break;
421 case 22:
424 w->lines[1]->setSubString(w->lines[1], FILE_CACHE.load(TEXT_FILE(TEXT_SKILL_NAMES)), data[0], 1);
425 task->count = 2;
426 break;
427 }
428 w->lines[0]->setVisible(w->lines[0], 0);
429 w->lines[1]->setVisible(w->lines[1], 0);
430}
431
432/* The message box's finish: closes it after 0x14 frames or on cross */
434 task->substate = 4;
435 task->showArrow = 0;
436 task->step = GFX.funcs.getTime();
437}
438
439/* Creates a battle message box (FIGHTSTG_updateMessage) */
Battle FIGHTSTG_battle
the battle: its fighters, speed and drawing functions
Definition battle.c:16
#define FIGHTER_PARALYZED
loses turns at random (FIGHTSTG_battleFuncs.testParalysis)
Definition battle.h:183
#define FIGHTER_POISONED
BattleFighter.flags: the statuses, which the techniques give (FIGHTSTG_inflict*) and events of type E...
Definition battle.h:182
#define FIGHTER_CONFUSED
Definition battle.h:184
#define BATTLE_LAYER_MENUS
the HUD, the menus and the messages
Definition types.h:31
FIGHTSTG.PRO: the battle.
BattleTableEntry *(* FIGHTSTG_battleTableFunc)(s32 id)
how the fight stage and WFIGHTMN read the battle table
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
unsigned char u8
Definition common.h:8
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 TEXT_BATTLE_MENU
MFIGHT: WFIGHTMN's.
Definition file.h:218
#define TEXT_SKILL_NAMES
SKLNAM.
Definition file.h:223
#define TEXT_FILE(file)
Definition file.h:190
#define TEXT_DIGIMON_NAMES
DIGNAM.
Definition file.h:211
#define FILE_BATTLE_MENU
The battle menu's files (WFIGHTMN, WFIGHTTS): FILE_BATTLE_IMAGES is an archive whose entries go throu...
Definition file.h:294
#define TEXT_ITEM_NAMES
ITMNAM.
Definition file.h:215
#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
void FIGHTSTG_drawMessageBox(BattleMessageBox *task)
Draws the message box and, once its lines are out, its blinking arrow.
Definition message.c:6
BattleMessageBox * FIGHTSTG_createMessage(void)
Creates a battle message box (FIGHTSTG_updateMessage)
Definition message.c:440
void FIGHTSTG_showFightersMessage(BattleMessageBox *task, BattleMessageBoxWindows *w, BattleMessage *msg)
Sets up a message about the fighters FIGHTSTG_findFighters found: their names (text 0x15 plus their c...
Definition message.c:185
void FIGHTSTG_showMessage(BattleMessageBox *task, s32 type, s32 *data)
The message box's show: sets up the lines of message type from data, mostly a fighter's name with a t...
Definition message.c:257
void FIGHTSTG_setMessageName(BattleMessageBox *task, BattleMessageBoxWindows *w, s32 side, s32 index)
Puts the name of side's fighter index (a partner's own, an enemy's from the battle table) into the me...
Definition message.c:96
void FIGHTSTG_updateMessage(BattleMessageBox *task, void *children)
The battle message box's task: draws it and steps its message each frame.
Definition message.c:78
void FIGHTSTG_findFighters(BattleMessageBox *task, FighterFilter *filter)
Lists in task's found the fighters of filter's side that its type picks: 0 the hurt,...
Definition message.c:112
void FIGHTSTG_stepMessage(BattleMessageBox *task, BattleMessageBoxWindows *windows)
Shows the message's lines one by one, 3 frames apart, then on cross shows the queue's next message or...
Definition message.c:33
void FIGHTSTG_finishMessage(BattleMessageBox *task)
The message box's finish: closes it after 0x14 frames or on cross.
Definition message.c:433
PadState PAD
Controller input: cleared by initPad, then the methods.
Definition pad.c:168
#define PAD_CROSS
Definition pad.h:31
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_CONFIRM
SYSTEM07.
Definition sound.h:44
void initSpriteDrawer(SpriteDrawer *obj)
Clears a sprite drawer to neutral (no scale, gray tint, follows the scroll), gives it its methods and...
One of the battle's fighters, three on each side (WFIGHTMN's BattleUnit): a partner's HP and MP go ba...
Definition battle.h:191
s16 id
the Digimon (DIGIMON_DATA)
Definition battle.h:192
FIGHTSTG_updateMessage's children: the lines it shows one by one.
Definition menu.h:187
TextWindow * lines[2]
Definition menu.h:188
A battle message box (FIGHTSTG_createMessage): shows its messages a line at a time,...
Definition menu.h:167
s32 arrowTime
when it last changed
Definition menu.h:178
s32 interval
the time between them
Definition menu.h:173
void(* nextState)(struct BattleMessageBox *task)
Definition menu.h:168
s32 shown
the window being shown
Definition menu.h:171
void(* setSubstate)(struct BattleMessageBox *task, s32 substate)
Definition menu.h:168
void * children
Definition menu.h:168
void(* finish)(struct BattleMessageBox *task)
FIGHTSTG_finishMessage: closes after 0x14 ticks or Cross.
Definition menu.h:183
s32 count
how many
Definition menu.h:172
s32 arrowPalette
the arrow's palette, 0-4
Definition menu.h:177
s32 found[3]
the fighters FIGHTSTG_findFighters found
Definition menu.h:180
s32 showArrow
show the arrow
Definition menu.h:179
void(* show)()
FIGHTSTG_showMessage: (task, type, data)
Definition menu.h:182
s32 started
set by show
Definition menu.h:170
s32 queue[9]
message types for show, some with args after them; 0 ends them
Definition menu.h:169
s32 next
in queue
Definition menu.h:175
What FIGHTSTG_updateMessage's messages say, for some of their types.
Definition menu.h:192
s32 value
Definition menu.h:195
s32 active[2]
each side's fighter
Definition battle.h:226
BattleFighter fighters[2][3]
Definition battle.h:227
s16 nameId
string in file 0x4F
Definition battle.h:62
BattleState state
Definition battle.h:240
Which fighters FIGHTSTG_findFighters looks for.
Definition menu.h:338
void *(* load)(u32 file)
Definition file.h:92
void *(* getEntry)(u32 fileAndIndex)
Definition file.h:96
struct PartnerStats *(* getPartnerStats)(s32 partner)
Definition game_state.h:38
s32(* getPartyMember)(u32 index)
Definition game_state.h:24
GameFuncs funcs
Definition game_state.h:582
s32(* getTime)(void)
Definition gfx.h:31
GfxFuncs funcs
Definition gfx.h:77
s32(* getPressed)(s32 pad)
Definition pad.h:125
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(* 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(* setSubString)()
Definition text.h:168
void(* setNumber)()
Definition text.h:166
void(* setString)()
Definition text.h:165
void(* setVisible)(struct TextWindow *obj, u8 arg)
Definition text.h:177
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)