Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
skill_panel.c
Go to the documentation of this file.
1/* The second screen's skill panel, where a slot's Digimon's skills are marked */
2
3#include "menus/digimon_lab.h"
4
5/* Creates the panel's windows and cursors */
7 s32 i;
8 TextWindow **items;
9
10 windows->digimonName = createTextWindow(panel->layer, 1, 0x9A, 0x46);
11 windows->learnedLabel = createTextWindow(panel->layer, 1, 0x122, 0x46);
12 windows->learned = createTextWindow(panel->layer, 1, 0x121, 0x46);
13 for (i = 0; i < 6; i++) {
14 windows->left[i] = createTextWindow(panel->layer, 1, 0x6B, i * 0x11 + 0x58);
15 windows->right[i] = createTextWindow(panel->layer, 1, 0xF1, i * 0x11 + 0x58);
16 }
17 windows->message = createTextWindow(panel->layer, 1, 0x9A, 0x1A);
18 windows->yes = createTextWindow(panel->layer, 1, 0xC3, 0x38);
19 windows->no = createTextWindow(panel->layer, 1, 0xC3, 0x48);
20 windows->help = createTextWindow(panel->layer, 1, 0x14, 0xC3);
21 windows->help->setLines(windows->help, 2);
22 windows->mpLabel = createTextWindow(panel->layer, 1, 0x109, 0xD1);
23 windows->mp = createTextWindow(panel->layer, 1, 0x12C, 0xD1);
24 for (i = 0, items = panel->children; i < panel->childCount - 2; i++, items++) {
25 if (*items != NULL) {
26 (*items)->setDepth(*items, panel->depth - 1);
27 }
28 }
29 windows->yes->setDepth(windows->yes, 0);
30 windows->no->setDepth(windows->no, 0);
31 windows->optionCursor = createCursor(panel->layer, 0, 0xB8, 0x38);
32 windows->optionCursor->setVisible(windows->optionCursor, 0);
33 windows->cursor = createCursor(panel->layer, panel->depth - 1, 0x4C, 0x58);
34 windows->cursor->setVisible(windows->cursor, 0);
35}
36
37/* Shows the slot's Digimon's skills, each marked or not and in the palette of
38 marked, last or unknown ones, how many are marked, and the cursor's skill's
39 description and MP; or hides the panel's windows */
41 TextWindow **items;
42 u16 skill;
43 s32 id;
44 s32 i;
45
46 if (show) {
47 if (panel->entry.id >= 3) {
49 GET_DIGIMON(panel->entry.id)->nameId);
50 panel->learned = 0;
51 for (i = 0; i < panel->skillCount; i++) {
52 skill = panel->entry.skills[i];
53 if (panel->entry.skills[i] != 0) {
54 windows->left[i]->setString(windows->left[i], FILE_CACHE.load(TEXT_FILE(TEXT_SKILL_NAMES)), skill & SKILL_ID);
55 if (skill & SKILL_MARKED) {
56 windows->right[i]->setString(windows->right[i], FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), 0x11);
57 panel->learned++;
58 } else {
59 windows->right[i]->setString(windows->right[i], FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), 0x12);
60 }
61 if (skill & SKILL_MARKED) {
62 windows->left[i]->setPalette(windows->left[i], PALETTE_GREEN);
63 windows->right[i]->setPalette(windows->right[i], PALETTE_GREEN);
64 } else if (skill & SKILL_LAST) {
65 windows->left[i]->setPalette(windows->left[i], PALETTE_YELLOW);
66 windows->right[i]->setPalette(windows->right[i], PALETTE_YELLOW);
67 } else if (!(skill & SKILL_KNOWN)) {
68 windows->left[i]->setPalette(windows->left[i], PALETTE_GREY);
69 windows->right[i]->setPalette(windows->right[i], PALETTE_GREY);
70 } else {
71 windows->left[i]->setPalette(windows->left[i], PALETTE_WHITE);
72 windows->right[i]->setPalette(windows->right[i], PALETTE_WHITE);
73 }
74 } else {
75 windows->left[i]->setVisible(windows->left[i], 0);
76 windows->right[i]->setVisible(windows->right[i], 0);
77 }
78 }
80 windows->learned->setNumber(windows->learned, 0, panel->learned);
81 windows->learned->setRightAlign(windows->learned, 1);
82 id = panel->entry.skills[panel->cursor] & SKILL_ID;
83 if (id != 0) {
84 windows->help->setString(windows->help, FILE_CACHE.load(TEXT_FILE(TEXT_SKILL_INFO)), id);
86 windows->mp->setNumber(windows->mp, 0, TECHS[id - 1].mp);
87 windows->mp->setRightAlign(windows->mp, 1);
88 } else {
89 windows->help->setVisible(windows->help, 0);
90 windows->mpLabel->setVisible(windows->mpLabel, 0);
91 windows->mp->setVisible(windows->mp, 0);
92 }
93 }
94 } else {
95 for (i = 0, items = panel->children; i < panel->childCount - 2; i++, items++) {
96 if (*items != NULL) {
97 (*items)->setVisible(*items, 0);
98 }
99 }
100 }
101}
102
103/* Draws the panel, its skills' icons once it is open, and the yes/no box */
104static inline void STGDGLAB_drawSkillPanel(LabSkillPanel *panel) {
105 SpriteDrawer sprite;
106 s32 id;
107 s32 i;
108
109 initSpriteDrawer(&sprite);
110 sprite.setLayerId(panel->layer, panel->depth);
111 if (panel->fade.level != ONE) {
112 sprite.setScale(panel->fade.level, ONE, ONE);
113 sprite.setPivot(0x140, 0x7D);
114 } else {
115 sprite.setTexture(0x140, 0);
116 for (i = 0; i < 6; i++) {
117 if (panel->entry.skills[i] != 0) {
118 id = panel->entry.skills[i] & SKILL_ID;
119 sprite.draw(FILE_CACHE.getEntry(FILE_MENU_SPRITES << 16), TECHS[id - 1].icon + 0x37, 0x5D,
120 i * 0x11 + 0x58);
121 }
122 }
123 }
124 sprite.setTexture(0x280, 0x100);
125 sprite.draw(FILE_CACHE.getEntry(FILE_LAB_SPRITES << 16), 0x28, 0x46, 0x41);
126 if (panel->fade.level != ONE) {
127 sprite.setPivot(0, 0xD0);
128 }
129 sprite.draw(FILE_CACHE.getEntry(FILE_LAB_SPRITES << 16), 0x2B, 0, 0xBF);
130 if (panel->fade.level != ONE) {
131 sprite.setPivot(0x140, 0x1F);
132 }
133 sprite.draw(FILE_CACHE.getEntry(FILE_LAB_SPRITES << 16), 0x24, 0x92, 0x13);
134 if (panel->confirm.level != 0) {
135 STRETCH_SPRITE(sprite, panel->confirm.level, 0x140, 0x46);
136 sprite.setLayerId(panel->layer, 1);
137 sprite.draw(FILE_CACHE.getEntry(FILE_LAB_SPRITES << 16), 0x23, 0xAE, 0x32);
138 }
139}
140
141/* Asks whether to unmark (message 7) or mark (8) the skill, yes first */
142static inline void STGDGLAB_askMark(LabSkillPanel *panel, LabSkillPanelWindows *windows, s32 message) {
143 windows->message->setString(windows->message, FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), message);
144 windows->yes->setString(windows->yes, FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), 0xC);
145 windows->no->setString(windows->no, FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), 0xD);
146 panel->choice = 0;
147 windows->optionCursor->setVisible(windows->optionCursor, 1);
148 windows->optionCursor->setPos(windows->optionCursor, 0xB8, panel->choice * 0x10 + 0x38);
149 panel->substate++;
150}
151
152/* The yes/no answer: yes marks the skill (or unmarks it), and either closes
153 the question */
154static inline void STGDGLAB_answerMark(LabSkillPanel *panel, LabSkillPanelWindows *windows, s32 mark) {
155 s32 old;
156
157 old = panel->choice;
158 if (PAD_PRESSED(PAD_UP)) {
159 panel->choice = 0;
160 } else if (PAD_PRESSED(PAD_DOWN)) {
161 panel->choice = 1;
162 }
163 if (old != panel->choice) {
165 windows->optionCursor->setPos(windows->optionCursor, 0xB8, panel->choice * 0x10 + 0x38);
166 }
167 if (PAD_PRESSED(PAD_CROSS)) {
169 if (panel->choice == 0) {
170 if (mark) {
171 panel->entry.skills[panel->cursor] |= SKILL_MARKED;
172 } else {
173 panel->entry.skills[panel->cursor] &= ~SKILL_MARKED;
174 }
175 }
176 windows->yes->setVisible(windows->yes, 0);
177 windows->no->setVisible(windows->no, 0);
178 windows->cursor->setStill(windows->cursor, 0);
179 panel->setSubstate(panel, 7);
180 panel->step = 0;
181 } else if (PAD_PRESSED(PAD_TRIANGLE)) {
183 windows->yes->setVisible(windows->yes, 0);
184 windows->no->setVisible(windows->no, 0);
185 windows->cursor->setStill(windows->cursor, 0);
186 panel->setSubstate(panel, 7);
187 panel->step = 0;
188 }
189}
190
191/* The skill list: up and down move the cursor; cross marks the skill or
192 unmarks it, after a yes/no, or says why it can't; triangle closes the panel */
193static inline void STGDGLAB_pickSkill(LabSkillPanel *panel, LabSkillPanelWindows *windows) {
194 s32 skill;
195 s32 old;
196
197 old = panel->cursor;
199 panel->cursor--;
200 if (panel->cursor < 0) {
201 panel->cursor = 0;
202 }
203 } else if (PAD_PRESSED(PAD_DOWN) || PAD_REPEATED(PAD_DOWN)) {
204 panel->cursor++;
205 if (panel->cursor > panel->skillCount - 1) {
206 panel->cursor = panel->skillCount - 1;
207 }
208 }
209 if (old != panel->cursor) {
211 STGDGLAB_showSkillPanel(panel, windows, 1);
212 windows->cursor->setPos(windows->cursor, 0x4C, panel->cursor * 0x11 + 0x58);
213 } else {
214 skill = panel->entry.skills[old];
215 if (PAD_PRESSED(PAD_CROSS)) {
217 if (skill != 0) {
218 if (skill & SKILL_MARKED) {
219 panel->substate = 5;
220 panel->step = 10;
221 } else if (skill & SKILL_LAST) {
222 windows->message->setString(windows->message, FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), 0xB);
223 panel->substate = 30;
224 } else if (!(skill & SKILL_KNOWN)) {
225 windows->message->setString(windows->message, FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), 0xA);
226 panel->substate = 30;
227 } else if (panel->learned >= 3) {
229 panel->substate = 30;
230 } else {
231 panel->substate = 5;
232 panel->step = 20;
233 }
234 windows->cursor->setPalette(windows->cursor, PALETTE_GREY);
235 windows->cursor->setStill(windows->cursor, 1);
236 }
237 } else if (PAD_PRESSED(PAD_TRIANGLE)) {
239 panel->setSubstate(panel, 40);
240 STGDGLAB_data.funcs.startFade(&panel->fade, 0);
241 windows->optionCursor->setVisible(windows->optionCursor, 0);
242 windows->cursor->setVisible(windows->cursor, 0);
243 STGDGLAB_showSkillPanel(panel, windows, 0);
244 }
245 }
246}
247
248/* The panel of a partner's Digimon's skills: up and down pick one, cross
249 marks it to pass on or unmarks it, after a yes/no, or says why it can't be
250 marked, and triangle saves the entry and closes the panel */
252 switch (panel->state) {
253 case TASK_INIT:
254 default:
255 panel->nextState(panel);
256 panel->fade.duration = 10;
257 panel->confirm.duration = 10;
258 STGDGLAB_data.funcs.startFade(&panel->fade, 1);
259 GAME.funcs.getPartnerSlots(panel->member, panel->slots);
260 GAME.funcs.getPartnerEntry(panel->member, panel->slots[panel->slot], &panel->entry);
261 /* BEC form: the match needs the store in a block of its own, whose loop
262 notes keep it before the call's arguments past sched2; as in Digimon
263 World 2's Stg10_TitleUpdate and Stg20_ShopListUpdate */
264 do {
265 panel->skillCount = 6;
266 } while (0);
267 STGDGLAB_createSkillPanelWindows(panel, windows);
268 break;
269 case TASK_RUN:
270 switch (panel->substate) {
271 default:
272 panel->setState(panel, TASK_KILL);
273 /* fallthrough */
274 case 0:
275 if (STGDGLAB_data.funcs.updateFade(&panel->fade)) {
276 STGDGLAB_showSkillPanel(panel, windows, 1);
277 windows->message->setString(windows->message, FILE_CACHE.load(TEXT_FILE(TEXT_DIGI_LAB)), 0x26);
278 windows->cursor->setPos(windows->cursor, 0x4C, panel->cursor * 0x11 + 0x58);
279 windows->cursor->setVisible(windows->cursor, 1);
280 windows->cursor->setPalette(windows->cursor, PALETTE_WHITE);
281 windows->optionCursor->setVisible(windows->optionCursor, 0);
282 panel->substate++;
283 }
284 break;
285 case 1:
286 STGDGLAB_pickSkill(panel, windows);
287 break;
288 case 5:
290 panel->substate++;
291 break;
292 case 6:
293 if (STGDGLAB_data.funcs.updateFade(&panel->confirm)) {
294 panel->substate = panel->step;
295 panel->setStep(panel, 0);
296 }
297 break;
298 case 7:
299 windows->optionCursor->setVisible(windows->optionCursor, 0);
301 panel->substate = 6;
302 break;
303 case 10:
304 STGDGLAB_askMark(panel, windows, 7);
305 break;
306 case 11:
307 STGDGLAB_answerMark(panel, windows, 0);
308 break;
309 case 20:
310 STGDGLAB_askMark(panel, windows, 8);
311 break;
312 case 21:
313 STGDGLAB_answerMark(panel, windows, 1);
314 break;
315 case 30:
316 if (PAD_PRESSED(PAD_CROSS)) {
318 windows->cursor->setStill(windows->cursor, 0);
319 panel->setSubstate(panel, 0);
320 }
321 break;
322 case 40:
323 if (STGDGLAB_data.funcs.updateFade(&panel->fade)) {
324 GAME.funcs.setPartnerEntry(panel->member, panel->slots[panel->slot], &panel->entry);
325 panel->setState(panel, TASK_KILL);
326 }
327 break;
328 }
330 break;
331 case TASK_DONE:
332 case TASK_KILL:
333 break;
334 }
335}
336
337/* Creates the second screen's skill panel (task) for a slot of a partner (the
338 MEMBER parameter is a partner id, from getPartyMember) */
341
342 panel->layer = SCREEN_LAYER;
343 panel->depth = 2;
344 panel->member = member;
345 panel->slot = slot;
346 return panel;
347}
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
unsigned short u16
Definition common.h:10
STGDGLAB.PRO: the Digimon Lab (MODE_DIGI_LAB; "デジモンラボ" in STAGSLCT's list of scenes),...
#define FILE_LAB_SPRITES
The lab's sprite sheet; the next file is its texture archive.
Definition digimon_lab.h:25
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
Cursor * createCursor(s16 layerId, s32 depth, s16 x, s16 y)
A menu cursor on a layer at (x, y)
Definition cursor.c:92
#define TEXT_DIGI_LAB
DGLABO: STGDGLAB's.
Definition file.h:208
#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 TEXT_SKILL_INFO
SKLINF.
Definition file.h:222
#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
#define SKILL_MARKED
marked in the lab (STGDGLAB_updateSkillPanel)
Definition game_state.h:257
#define SKILL_KNOWN
Definition game_state.h:256
#define SKILL_LAST
the sixth skill
Definition game_state.h:258
#define SKILL_ID
PartnerEntry.skills.
Definition game_state.h:255
DigimonData *(* GET_DIGIMON)(s32 id)
getDigimon for the overlays, in the small data (.sdata) between game/items.c's and file/file_table....
Definition get_digimon.c:10
#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
TechData TECHS[443]
The techniques, from 1: technique n is TECHS[n - 1].
Definition items.c:906
LabData STGDGLAB_data
Definition lab.c:611
#define PAD_CROSS
Definition pad.h:31
#define PAD_DOWN
Definition pad.h:24
#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_REPEATED(button)
Definition pad.h:141
static void STGDGLAB_pickSkill(LabSkillPanel *panel, LabSkillPanelWindows *windows)
The skill list: up and down move the cursor; cross marks the skill or unmarks it, after a yes/no,...
LabSkillPanel * STGDGLAB_createSkillPanel(s32 member, s32 slot)
Creates the second screen's skill panel (task) for a slot of a partner (the MEMBER parameter is a par...
void STGDGLAB_showSkillPanel(LabSkillPanel *panel, LabSkillPanelWindows *windows, s32 show)
Shows the slot's Digimon's skills, each marked or not and in the palette of marked,...
Definition skill_panel.c:40
void STGDGLAB_createSkillPanelWindows(LabSkillPanel *panel, LabSkillPanelWindows *windows)
Creates the panel's windows and cursors.
Definition skill_panel.c:6
static void STGDGLAB_answerMark(LabSkillPanel *panel, LabSkillPanelWindows *windows, s32 mark)
The yes/no answer: yes marks the skill (or unmarks it), and either closes the question.
static void STGDGLAB_askMark(LabSkillPanel *panel, LabSkillPanelWindows *windows, s32 message)
Asks whether to unmark (message 7) or mark (8) the skill, yes first.
void STGDGLAB_updateSkillPanel(LabSkillPanel *panel, LabSkillPanelWindows *windows)
The panel of a partner's Digimon's skills: up and down pick one, cross marks it to pass on or unmarks...
static void STGDGLAB_drawSkillPanel(LabSkillPanel *panel)
Draws the panel, its skills' icons once it is open, and the yes/no box.
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_SELECT
Sounds the overlays share, with SOUNDTST's names.
Definition sound.h:38
#define SOUND_MENU_CANCEL
SYSTEM01.
Definition sound.h:39
#define SOUND_CURSOR
SYSTEM02: a cursor moves.
Definition sound.h:40
void initSpriteDrawer(SpriteDrawer *obj)
Clears a sprite drawer to neutral (no scale, gray tint, follows the scroll), gives it its methods and...
void(* setPalette)()
Definition text.h:35
void(* setPos)()
(cursor, x, y)
Definition text.h:34
void(* setStill)()
Definition text.h:38
void(* setVisible)()
(cursor, visible)
Definition text.h:33
u8 nameId
string in file 0x4F
Definition game_state.h:105
void *(* load)(u32 file)
Definition file.h:92
void *(* getEntry)(u32 fileAndIndex)
Definition file.h:96
s32(* setPartnerEntry)()
Definition game_state.h:37
s32(* getPartnerEntry)()
-1 if it hasn't the Digimon
Definition game_state.h:36
s32(* getPartnerSlots)()
(partner, s16 *out): the count
Definition game_state.h:32
GameFuncs funcs
Definition game_state.h:582
LabFuncs funcs
s32(* updateFade)(PanelAnim *fade)
void(* startFade)(PanelAnim *fade, s32 fadeIn)
TextWindow * message
TextWindow * learned
how many skills are marked
TextWindow * mpLabel
TextWindow * learnedLabel
TextWindow * mp
the picked skill's
TextWindow * left[6]
TextWindow * right[6]
TextWindow * digimonName
A panel of the second screen (STGDGLAB_createSkillPanel)
void(* nextState)(struct LabSkillPanel *task)
void(* setState)(struct LabSkillPanel *task, s32 state)
PanelAnim confirm
void(* setStep)(struct LabSkillPanel *task, s32 step)
PanelAnim fade
PartnerEntry entry
void(* setSubstate)(struct LabSkillPanel *task, s32 substate)
s32 level
Definition menu.h:21
s32 duration
Definition menu.h:19
s16 skills[6]
SKILL_ID and the flags below, 0 for none.
Definition game_state.h:251
s16 id
FIRST_ENTRY_ID and up.
Definition game_state.h:248
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(* draw)()
(sheet, frame, x, y)
Definition gfx.h:246
void(* setTexture)()
(x, y)
Definition gfx.h:242
u16 mp
its cost
Definition game_state.h:111
u8 icon
a frame of the menu sprites, from 0x37
Definition game_state.h:113
A text window (createTextWindow): up to six text buffers (0 is shown, 1-5 are "work" buffers that con...
Definition text.h:131
void(* setPalette)(struct TextWindow *obj, u8 arg)
Definition text.h:174
void(* setDepth)()
Definition text.h:183
void(* setRightAlign)()
no prototype: callers would truncate u8 args
Definition text.h:178
void(* setLines)()
no prototype: callers would truncate u8 args
Definition text.h:184
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
#define PALETTE_GREEN
Definition text.h:116
#define PALETTE_WHITE
The text windows' palettes (TextWindow.palette, setPalette): rows of the font's CLUTs,...
Definition text.h:112
#define PALETTE_YELLOW
Definition text.h:115
#define PALETTE_GREY
what is unavailable
Definition text.h:119
TextWindow * createTextWindow(s16 layerId, s16 style, s16 x, s16 y)
A text window on a layer, in a font style, at (x, y)