Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
digimon_change.c
Go to the documentation of this file.
1/* FIGHTSTG's Digimon change: the effect of a digivolution, or of a blast's. */
2
4
5/* where FIGHTSTG_updateDigimonChange's effects are: the first (1000, 1001
6 or 1007) when the old Digimon starts being wiped away, the second (1002)
7 once it's gone, the third (1003 or 1008), behind (z -1), once the new one
8 is shown whole; all are screen positions */
9const SVECTOR FIGHTSTG_changeStartPos = { 0, 0, 0x7FFF, 0 };
10const SVECTOR FIGHTSTG_changeMidPos = { 160, 120, 0x7FFF, 0 };
11const SVECTOR FIGHTSTG_changeEndPos = { -160, -120, -1, 0 };
12
13/* Applies the wipe: clips BATTLE_LAYER_MODELS to clip0 and
14 BATTLE_LAYER_WIREFRAME to clip1 */
15static inline void setChangeClips(DigimonChange *task) {
17
18 layer->setClipPos(layer, task->clip0.x, task->clip0.y);
19 layer->setClipSize(layer, task->clip0.w, task->clip0.h);
21 layer->setClipPos(layer, task->clip1.x, task->clip1.y);
22 layer->setClipSize(layer, task->clip1.w, task->clip1.h);
23}
24
25/* Once the change's stage is set, plays the change sound and adds the new
26 Digimon as model 1, then lets it show for 180 frames */
27static inline void addNewDigimon(DigimonChange *task, Models *models, FightStage *stage) {
28 switch (task->step) {
29 case 0:
30 default:
31 if (stage->state == 2) {
32 break;
33 }
34 SOUND.playSound(0x41140000);
35 models->add(models, 1, task->key1, 0);
36 task->nextStep(task);
37 /* fallthrough */
38 case 1:
39 task->counter += GFX.funcs.getFrameTime();
40 if (task->counter >= 180) {
41 task->nextSubstate(task);
42 }
43 break;
44 }
45}
46
47/* Starts the change: the clips at the old Digimon whole, the camera on the
48 partner, its wireframe layer and change motion, and the first effects */
49static inline void startChange(DigimonChange *task, DigimonChangeChildren *children, Models *models, BattleCamera *camera) {
50 ModelControl *control;
51 s32 z;
52
53 task->clip0.x = 0;
54 task->clip0.y = 0;
55 task->clip0.w = 320;
56 task->clip0.h = 240;
57 task->clip1.x = 0;
58 task->clip1.y = 240;
59 task->clip1.w = 320;
60 task->clip1.h = 0;
61 control = models->get(models, 0);
62 camera->getFighterView(camera, 0, 9);
63 z = -control->homePos.z;
66 camera->set(camera, &FIGHTSTG_fighterView);
67 control->layers[1].enabled = 1;
68 control->layers[1].wireframe = 1;
70 control->pos.x = 0;
71 control->pos.z = 0;
72 control->rot.x = 0;
73 control->rot.y = 0x800;
74 control->rot.z = 0;
75 control->pos.y = control->homePos.y;
76 if (task->key2 != 0) {
77 control->motion = 14;
78 } else {
79 control->motion = 13;
80 }
81 models->get(models, 0x10)->layers[0].enabled = 0;
82 if (task->key2 == 0) {
85 } else {
87 }
88}
89
90/* Wipes the old Digimon away into its wireframe; once it's all wireframe,
91 hides its model layer and starts the second effect */
92static inline void wipeToWireframe(DigimonChange *task, DigimonChangeChildren *children, Models *models) {
93 s32 t;
94
96 task->clip0.h -= t * 2;
97 task->clip1.h += t * 2;
98 task->clip1.y -= t * 2;
99 if (task->clip1.y <= 0) {
100 task->clip0.h = 0;
101 task->clip1.h = 240;
102 task->clip1.y = 0;
103 models->get(models, 0)->layers[0].enabled = 0;
105 task->nextSubstate(task);
106 }
107 setChangeClips(task);
108}
109
110/* Puts the new Digimon in the partner's place (model 1 becomes model 0) with
111 both layers on, the camera on it and the clips at the wireframe whole */
112static inline void swapInNewDigimon(DigimonChange *task, Models *models, BattleCamera *camera) {
113 ModelControl *control;
114 s32 z;
115
116 models->setId(models, 1, 0);
117 control = models->get(models, 0);
118 control->layers[0].enabled = 1;
119 control->layers[0].layerId = BATTLE_LAYER_MODELS;
120 control->layers[0].wireframe = 0;
121 control->layers[1].enabled = 1;
122 control->layers[1].wireframe = 1;
124 models->face(models, 0);
125 camera->getFighterView(camera, 0, 9);
126 z = -control->homePos.z;
129 camera->set(camera, &FIGHTSTG_fighterView);
130 control->pos.x = 0;
131 control->pos.z = 0;
132 control->rot.x = 0;
133 control->rot.y = 0x800;
134 control->rot.z = 0;
135 control->pos.y = control->homePos.y;
136 task->clip0.x = 0;
137 task->clip0.y = 0;
138 task->clip0.w = 320;
139 task->clip0.h = 0;
140 task->clip1.x = 0;
141 task->clip1.y = 0;
142 task->clip1.w = 320;
143 task->clip1.h = 240;
144}
145
146/* Wipes the new Digimon in over its wireframe; once it's whole, hides the
147 wireframe layer and starts the third effect */
148static inline void wipeFromWireframe(DigimonChange *task, DigimonChangeChildren *children, Models *models) {
149 s32 t;
150
151 t = GFX.funcs.getFrameTime();
152 task->clip0.h += t * 2;
153 task->clip1.y += t * 2;
154 task->clip1.h -= t * 2;
155 if (task->clip0.h >= 240) {
156 task->clip0.h = 240;
157 task->clip1.y = 240;
158 task->clip1.h = 0;
159 models->get(models, 0)->layers[1].enabled = 0;
160 children->effects[3] = FIGHTSTG_startSpriteEffect(task->key2 == 0 ? 1003 : 1008, &FIGHTSTG_changeEndPos);
161 task->nextSubstate(task);
162 }
163 setChangeClips(task);
164}
165
166/* Goes back to the battle: shows model 0x10 again, gives the new Digimon its
167 idle motion, turns the camera to the enemy and plays the battle music, then
168 ends the change */
169static inline void returnToBattle(DigimonChange *task, Models *models, BattleCamera *camera) {
170 switch (task->step) {
171 case 0:
172 default:
173 models->get(models, 0x10)->layers[0].enabled = 1;
174 models->get(models, 0)->motion = task->key2 != 0 || task->idleMotion == 0 ? 1 : 2;
175 camera->fade(camera, NULL, camera->getEnemyView(camera), 60);
177 task->nextStep(task);
178 break;
179 case 1:
180 task->counter += GFX.funcs.getFrameTime();
181 if (task->counter >= 60) {
182 task->setState(task, 3);
183 }
184 break;
185 }
186}
187
188/* A partner Digimon's change: a stage of its own (addNewDigimon), the new
189 Digimon's model in front of a sprite effect, the old one wiped away by the
190 clips of BATTLE_LAYER_MODELS and BATTLE_LAYER_WIREFRAME (startChange,
191 wipeToWireframe, swapInNewDigimon, wipeFromWireframe), and a fade back to
192 the battle (returnToBattle). The match depends on substate 2's control
193 kept in startChange, on the if/else of the motion, on clip1.h written
194 before clip1.y in wipeToWireframe and on the layers kept in
195 setChangeClips */
197 Models *models = task->models;
198 BattleCamera *camera = task->camera;
199 FightStage *stage = task->stage;
200 TimLoader loader;
201
202 switch (task->state) {
203 case 0:
204 default:
205 switch (task->substate) {
206 case 0:
207 default:
208 switch (task->step) {
209 case 0:
210 default:
211 SOUND.loadBank(0x45);
212 task->nextStep(task);
213 /* fallthrough */
214 case 1:
215 if (SOUND.isLoading() == 0) {
216 task->nextSubstate(task);
217 }
218 break;
219 }
220 break;
221 case 1:
222 models = TASK_REGISTRY.funcs.find(BATTLE_TASK_MODELS, -1, -1);
223 task->models = models;
226 task->file = FIGHTSTG_fighterCache.funcs.getInfo(task->key1)->model >> 16;
227 FILE_CACHE.request(task->file);
228 task->idleMotion = models->get(models, 0)->idleMotion;
229 task->nextSubstate(task);
230 /* fallthrough */
231 case 2:
232 if (FILE_CACHE.isLoading(task->file) != 0) {
233 break;
234 }
236 task->nextSubstate(task);
237 /* fallthrough */
238 case 3:
239 if (FILE_CACHE.isLoading(FILE_CHANGE) != 0) {
240 break;
241 }
242 initTimLoader(&loader);
243 loader.setImagePos(0x300, 0x100);
244 loader.loadArchive(FILE_CACHE.getEntry((FILE_CHANGE << 16) | 5));
245 task->nextState(task);
246 break;
247 }
248 break;
249 case 1:
250 switch (task->substate) {
251 case 0:
252 default:
253 stage->setStage(stage, task->key2 != 0 ? 0x1F : 0x1C, 0x20, 0x20);
254 task->nextSubstate(task);
255 /* fallthrough */
256 case 1:
257 addNewDigimon(task, models, stage);
258 break;
259 case 2:
260 startChange(task, children, models, camera);
261 task->nextSubstate(task);
262 /* fallthrough */
263 case 3:
264 wipeToWireframe(task, children, models);
265 break;
266 case 4:
267 task->counter += GFX.funcs.getFrameTime();
268 if (task->counter >= 120) {
269 task->nextSubstate(task);
270 }
271 break;
272 case 5:
273 switch (task->step) {
274 case 0:
275 default:
276 children->fade = FIGHTSTG_startWhiteFlash(32);
277 task->nextStep(task);
278 break;
279 case 1:
280 if (children->fade->substate != 0) {
281 task->nextSubstate(task);
282 }
283 break;
284 }
285 break;
286 case 6:
287 swapInNewDigimon(task, models, camera);
288 task->nextSubstate(task);
289 /* fallthrough */
290 case 7:
291 switch (task->step) {
292 case 0:
293 default:
294 children->fade->setState(children->fade, 2);
295 task->nextStep(task);
296 break;
297 case 1:
298 if (children->fade == NULL) {
299 task->nextSubstate(task);
300 }
301 break;
302 }
303 break;
304 case 8:
305 wipeFromWireframe(task, children, models);
306 break;
307 case 9:
308 models->get(models, 0)->motion = 13;
309 task->nextSubstate(task);
310 /* fallthrough */
311 case 10:
312 task->counter += GFX.funcs.getFrameTime();
313 if (task->counter >= 180) {
314 task->nextSubstate(task);
315 }
316 break;
317 case 11:
318 stage->setStage(stage, BATTLE_SETUP.stage, 0x20, 0x20);
319 task->nextSubstate(task);
320 /* fallthrough */
321 case 12:
322 if (stage->state != 2) {
323 models->face(models, 0);
324 camera->set(camera, camera->getFighterView(camera, 0, 9));
325 task->nextSubstate(task);
326 }
327 break;
328 case 13:
329 task->nextSubstate(task);
330 break;
331 case 14:
332 returnToBattle(task, models, camera);
333 break;
334 }
335 break;
336 case 2:
337 case 3:
338 break;
339 }
340}
341
342/* Starts a partner's Digimon change (FIGHTSTG_updateDigimonChange) */
345
346 task->key1 = key1;
347 task->key2 = key2;
348 return task;
349}
FighterCache FIGHTSTG_fighterCache
the fighters' data, loaded one at a time
Definition battle.c:21
#define BATTLE_LAYER_WIREFRAME
the models' wireframe copies, in a Digimon change
Definition types.h:29
#define BATTLE_TASK_CAMERA
Definition types.h:21
#define BATTLE_TASK_MODELS
the fighters'
Definition types.h:23
#define BATTLE_TASK_STAGE
Definition types.h:24
#define BATTLE_LAYER_MODELS
Definition types.h:30
FIGHTSTG.PRO: the battle.
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
static void startChange(DigimonChange *task, DigimonChangeChildren *children, Models *models, BattleCamera *camera)
Starts the change: the clips at the old Digimon whole, the camera on the partner, its wireframe layer...
static void wipeFromWireframe(DigimonChange *task, DigimonChangeChildren *children, Models *models)
Wipes the new Digimon in over its wireframe; once it's whole, hides the wireframe layer and starts th...
const SVECTOR FIGHTSTG_changeEndPos
static void wipeToWireframe(DigimonChange *task, DigimonChangeChildren *children, Models *models)
Wipes the old Digimon away into its wireframe; once it's all wireframe, hides its model layer and sta...
const SVECTOR FIGHTSTG_changeMidPos
void FIGHTSTG_updateDigimonChange(DigimonChange *task, DigimonChangeChildren *children)
A partner Digimon's change: a stage of its own (addNewDigimon), the new Digimon's model in front of a...
static void addNewDigimon(DigimonChange *task, Models *models, FightStage *stage)
Once the change's stage is set, plays the change sound and adds the new Digimon as model 1,...
static void swapInNewDigimon(DigimonChange *task, Models *models, BattleCamera *camera)
Puts the new Digimon in the partner's place (model 1 becomes model 0) with both layers on,...
DigimonChange * FIGHTSTG_startDigimonChange(s32 key1, s32 key2)
Starts a partner's Digimon change (FIGHTSTG_updateDigimonChange)
static void setChangeClips(DigimonChange *task)
Applies the wipe: clips BATTLE_LAYER_MODELS to clip0 and BATTLE_LAYER_WIREFRAME to clip1.
const SVECTOR FIGHTSTG_changeStartPos
where FIGHTSTG_updateDigimonChange's effects are: the first (1000, 1001 or 1007) when the old Digimon...
static void returnToBattle(DigimonChange *task, Models *models, BattleCamera *camera)
Goes back to the battle: shows model 0x10 again, gives the new Digimon its idle motion,...
GfxState GFX
GFX: the graphics state and its methods.
Definition display.c:209
#define FILE_CHANGE
The images of a Digimon's change (FIGHTSTG_updateDigimonChange): entry 5.
Definition effect.h:13
FileCache FILE_CACHE
The file cache.
Definition file_cache.c:7
BattleSetup BATTLE_SETUP
Definition items.c:886
CameraView FIGHTSTG_fighterView
the view FIGHTSTG_getFighterView makes
TaskRegistry TASK_REGISTRY
Definition registry.c:122
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
SpriteEffect * FIGHTSTG_startSpriteEffect(s32 effect, const SVECTOR *pos)
Starts 2D effect effect (FIGHTSTG_spriteEffects) at pos; killed at once when it has no entry.
The battle camera (FIGHTSTG_createBattleCamera), registered as BATTLE_TASK_CAMERA on a layer: set put...
Definition camera.h:66
CameraView *(* getFighterView)(struct BattleCamera *task, s32 id, s32 camera)
Definition camera.h:77
CameraView *(* getEnemyView)(struct BattleCamera *task)
Definition camera.h:76
void(* set)(struct BattleCamera *task, CameraView *view)
Definition camera.h:74
void(* fade)(struct BattleCamera *task, CameraView *from, CameraView *to, s32 time)
from: NULL for the current
Definition camera.h:75
s32 music
the battle's music
Definition game_state.h:385
s32 stage
the battle's fight stage
Definition game_state.h:383
s32 vpz
Definition camera.h:52
s32 vrz
Definition camera.h:55
struct WhiteFlash * fade
Definition effect.h:125
struct SpriteEffect * effects[4]
Definition effect.h:127
A partner Digimon's change (FIGHTSTG_startDigimonChange): key1 the new Digimon, key2 the side.
Definition effect.h:113
struct Models * models
Definition effect.h:115
s32 file
the new Digimon's model's
Definition effect.h:121
void(* nextStep)(struct DigimonChange *task)
Definition effect.h:114
void(* nextState)(struct DigimonChange *task)
Definition effect.h:114
struct FightStage * stage
Definition effect.h:117
RECT clip0
BATTLE_LAYER_MODELS's.
Definition effect.h:119
RECT clip1
BATTLE_LAYER_WIREFRAME's.
Definition effect.h:120
struct BattleCamera * camera
Definition effect.h:116
s32 idleMotion
the old Digimon's
Definition effect.h:118
void(* setState)(struct DigimonChange *task, s32 state)
Definition effect.h:114
void(* nextSubstate)(struct DigimonChange *task)
Definition effect.h:114
The fight stage (FIGHTSTG_createStage), registered as BATTLE_TASK_STAGE: its model,...
Definition stage.h:38
void(* setStage)(struct FightStage *task, s32 stage, s32 fadeOutTime, s32 fadeInTime)
Definition stage.h:54
s32 state
Definition stage.h:39
FighterInfoFuncs funcs
Definition model.h:272
FighterInfo *(* getInfo)(s32 id)
Definition model.h:258
s32 model
Definition model.h:226
s32(* isLoading)(s32 file)
Definition file.h:88
void(* request)(s32 file)
Definition file.h:90
void *(* getEntry)(u32 fileAndIndex)
Definition file.h:96
s32(* getFrameTime)(void)
Definition gfx.h:32
struct Layer *(* getLayer)(s32 id)
Definition gfx.h:28
GfxFuncs funcs
Definition gfx.h:77
A drawing layer (GFX.funcs.createLayer): a DRAWENV with a pair of ordering tables,...
Definition gfx.h:128
void(* setClipSize)()
no prototype: callers would truncate s16 args
Definition gfx.h:146
void(* setClipPos)()
no prototype: callers would truncate s16 args
Definition gfx.h:145
What drives a Model, owned by whoever created it.
Definition model.h:99
ShortVec3 rot
Definition model.h:108
s32 wireframe
they are drawn as wireframe (Mesh.drawWireframe)
Definition model.h:114
s32 enabled
Definition model.h:112
ShortVec3 pos
Definition model.h:107
s32 layerId
the layer its meshes are drawn in
Definition model.h:113
struct ModelControl::@3 layers[2]
the model is drawn once for each one enabled
ShortVec3 homePos
Definition model.h:109
s32 motion
the motion to play
Definition model.h:102
s32 idleMotion
Definition model.h:106
The fighters' models (FIGHTSTG_createModels), registered as BATTLE_TASK_MODELS: up to four,...
Definition model.h:284
void(* setId)(struct Models *task, s32 id, s32 newId)
Definition model.h:290
void(* face)(struct Models *task, s32 id)
ids under 0x10 are one side
Definition model.h:292
void(* add)(struct Models *task, s32 id, s32 fighter, s32 visible)
Definition model.h:288
ModelControl *(* get)(struct Models *task, s32 id)
Definition model.h:289
s16 x
Definition model.h:15
s16 z
Definition model.h:17
s16 y
Definition model.h:16
s32(* isLoading)(void)
Definition sound.h:193
void(* loadBank)(s32 id)
Definition sound.h:190
short(* playSound)(s32 id)
returns the voice of a key-on
Definition sound.h:187
void *(* find)(s32 id, s32 key1, s32 key2)
Definition task.h:18
TaskFuncs funcs
Definition task.h:76
Any task, seen through its header.
Definition task.h:62
Uploads TIM images to VRAM (initTimLoader); acts on TIM_LOADER.
Definition gfx.h:325
void(* setImagePos)()
(x, y)
Definition gfx.h:336
void(* loadArchive)()
(archive): each image 64 halfwords to the right
Definition gfx.h:338
void(* setState)(struct WhiteFlash *task, s32 state)
Definition effect.h:106
s32 substate
Definition effect.h:106
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105
void initTimLoader(TimLoader *obj)
Clears a TIM loader, gives it its methods and binds it.
Definition tim_loader.c:119
WhiteFlash * FIGHTSTG_startWhiteFlash(s32 frames)
Starts a white flash that whitens the screen over FRAMES.
Definition white_flash.c:70