Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
effects.c File Reference

Go to the source code of this file.

Macros

#define EFFECT_GLOBALS_TLB_IDX   0x10
 
#define FX_ENTRY(name, gfx_name)
 

Typedefs

typedef s32 TlbEntry[0x1000/4]
 
typedef TlbEntry TlbMappablePage[15]
 

Functions

void stub_effect_delegate (EffectInstance *effect)
 Used for unbound function points in effect structs.
 
void set_effect_pos_offset (EffectInstance *effect, f32 x, f32 y, f32 z)
 
void clear_effect_data (void)
 
void func_80059D48 (void)
 
void update_effects (void)
 
void render_effects_world (void)
 
void render_effects_UI (void)
 
EffectInstancecreate_effect_instance (EffectBlueprint *effectBp)
 
void remove_effect (EffectInstance *effectInstance)
 
void remove_all_effects (void)
 
s32 load_effect (s32 effectIndex)
 

Variables

BSS EffectGraphics gEffectGraphicsData [15]
 
EffectInstancegEffectInstances [96]
 
TlbMappablePage gEffectDataBuffer
 
Addr gEffectGlobals
 
s32 D_8007FEB8 [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 3, 4, 13, 60, 0, 512, 0, 0, 3, 0 }
 

Macro Definition Documentation

◆ EFFECT_GLOBALS_TLB_IDX

#define EFFECT_GLOBALS_TLB_IDX   0x10

Definition at line 8 of file effects.c.

Referenced by clear_effect_data().

◆ FX_ENTRY

#define FX_ENTRY ( name,
gfx_name )
Value:
{ \
name##_main, effect_##name##_ROM_START, effect_##name##_ROM_END, effect_##name##_VRAM, gfx_name##_ROM_START, \
gfx_name##_ROM_END \
}

Definition at line 16 of file effects.c.

16#define FX_ENTRY(name, gfx_name) { \
17 name##_main, effect_##name##_ROM_START, effect_##name##_ROM_END, effect_##name##_VRAM, gfx_name##_ROM_START, \
18 gfx_name##_ROM_END \
19}

Typedef Documentation

◆ TlbEntry

typedef s32 TlbEntry[0x1000/4]

Definition at line 5 of file effects.c.

◆ TlbMappablePage

typedef TlbEntry TlbMappablePage[15]

Definition at line 6 of file effects.c.

Function Documentation

◆ stub_effect_delegate()

void stub_effect_delegate ( EffectInstance * effect)

Used for unbound function points in effect structs.

Definition at line 26 of file effects.c.

26 {
27}

Referenced by create_effect_instance(), and render_effects_UI().

◆ set_effect_pos_offset()

void set_effect_pos_offset ( EffectInstance * effect,
f32 x,
f32 y,
f32 z )

Definition at line 29 of file effects.c.

29 {
30 s32* data = effect->data.any;
31
32 ((f32*)data)[1] = x;
33 ((f32*)data)[2] = y;
34 ((f32*)data)[3] = z;
35}
s32 * any
Definition effects.h:2463
EffectData data
Definition effects.h:2605

◆ clear_effect_data()

void clear_effect_data ( void )

Definition at line 37 of file effects.c.

37 {
38 s32 i;
39
40 for (i = 0; i < ARRAY_COUNT(gEffectGraphicsData); i++) {
42 }
43
44 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
45 gEffectInstances[i] = NULL;
46 }
47
48 osUnmapTLBAll();
49 osMapTLB(EFFECT_GLOBALS_TLB_IDX, OS_PM_4K, effect_globals_VRAM, (s32)&gEffectGlobals & 0xFFFFFF, -1, -1);
50 DMA_COPY_SEGMENT(effect_globals);
51}
EffectInstance * gEffectInstances[96]
Definition effects.c:11
Addr gEffectGlobals
BSS EffectGraphics gEffectGraphicsData[15]
Definition effects.c:10
#define EFFECT_GLOBALS_TLB_IDX
Definition effects.c:8
#define DMA_COPY_SEGMENT(segment)
Definition macros.h:525
#define ARRAY_COUNT(arr)
Definition macros.h:40

Referenced by load_demo_battle(), load_engine_data(), load_map_by_IDs(), state_init_logos(), state_init_title_screen(), state_step_demo(), state_step_intro(), and state_step_startup().

◆ func_80059D48()

void func_80059D48 ( void )

Definition at line 53 of file effects.c.

53 {
54}

◆ update_effects()

void update_effects ( void )

Definition at line 56 of file effects.c.

56 {
58 EffectGraphics* effectGraphics;
59 s32 i;
60
61 // reset free delay for each EffectGraphics touched in previous update
62 for (i = 0, effectGraphics = gEffectGraphicsData; i < ARRAY_COUNT(gEffectGraphicsData); i++, effectGraphics++) {
63 if (effectGraphics->flags & FX_GRAPHICS_LOADED) {
64 if (!(effectGraphics->flags & FX_GRAPHICS_CAN_FREE)) {
65 effectGraphics->flags |= FX_GRAPHICS_CAN_FREE;
66 effectGraphics->freeDelay = 3;
67 }
68 }
69 }
70
71 // update each EffectInstances
72 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
73 EffectInstance* effectInstance = gEffectInstances[i];
74
75 if (effectInstance != NULL && (effectInstance->flags & FX_INSTANCE_FLAG_ENABLED)) {
76 effectInstance->graphics->flags &= ~FX_GRAPHICS_CAN_FREE;
77
79 if (effectInstance->flags & FX_INSTANCE_FLAG_BATTLE) {
80 effectInstance->graphics->update(effectInstance);
81 effectInstance->flags |= FX_INSTANCE_FLAG_HAS_UPDATED;
82 }
83 } else {
84 if (!(effectInstance->flags & FX_INSTANCE_FLAG_BATTLE)) {
85 effectInstance->graphics->update(effectInstance);
86 effectInstance->flags |= FX_INSTANCE_FLAG_HAS_UPDATED;
87 }
88 }
89 }
90 }
91
92 // free any EffectGraphics which haven't been used recently
93 for (i = 0, effectGraphics = gEffectGraphicsData; i < ARRAY_COUNT(gEffectGraphicsData); i++, effectGraphics++) {
94 if (effectGraphics->flags & FX_GRAPHICS_LOADED) {
95 if (effectGraphics->flags & FX_GRAPHICS_CAN_FREE) {
96 if (effectGraphics->freeDelay != 0) {
97 effectGraphics->freeDelay--;
98 } else {
99 if (effectGraphics->data != NULL) {
100 general_heap_free(effectGraphics->data);
101 effectGraphics->data = NULL;
102 }
103 effectGraphics->flags = FX_GRAPHICS_DISABLED;
104 osUnmapTLB(i);
105 }
106 }
107 }
108 }
109 }
110}
struct EffectGraphics * graphics
Definition effects.h:2606
@ FX_INSTANCE_FLAG_BATTLE
Definition enums.h:3515
@ FX_INSTANCE_FLAG_ENABLED
Definition enums.h:3514
@ FX_INSTANCE_FLAG_HAS_UPDATED
Definition enums.h:3516
@ FX_GRAPHICS_DISABLED
Definition enums.h:3521
@ FX_GRAPHICS_CAN_FREE
Definition enums.h:3523
@ FX_GRAPHICS_LOADED
Definition enums.h:3522
@ CONTEXT_WORLD
Definition enums.h:3529
@ GLOBAL_OVERRIDES_800
Definition enums.h:4330
@ GLOBAL_OVERRIDES_400
Definition enums.h:4329
s32 general_heap_free(void *data)
Definition heap.c:18
void(* update)(EffectInstance *effectInst)
Definition effects.h:2663
s32 gOverrideFlags
Definition main_loop.c:11
GameStatus * gGameStatusPtr
Definition main_loop.c:32

Referenced by state_step_battle(), state_step_change_map(), state_step_enter_world(), state_step_game_over(), state_step_intro(), state_step_pause(), state_step_unpause(), and state_step_world().

◆ render_effects_world()

void render_effects_world ( void )

Definition at line 112 of file effects.c.

112 {
113 s32 i;
114
115 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
116 EffectInstance* effectInstance = gEffectInstances[i];
117
118 if (effectInstance != NULL) {
119 if (effectInstance->flags & FX_INSTANCE_FLAG_ENABLED) {
120 if (effectInstance->flags & FX_INSTANCE_FLAG_HAS_UPDATED) {
122 if (effectInstance->flags & FX_INSTANCE_FLAG_BATTLE) {
123 effectInstance->graphics->renderWorld(effectInstance);
124 }
125 } else {
126 if (!(effectInstance->flags & FX_INSTANCE_FLAG_BATTLE)) {
127 effectInstance->graphics->renderWorld(effectInstance);
128 }
129 }
130 }
131 }
132 }
133 }
134}
void(* renderWorld)(EffectInstance *effectInst)
Definition effects.h:2664

Referenced by render_frame().

◆ render_effects_UI()

void render_effects_UI ( void )

Definition at line 136 of file effects.c.

136 {
137 s32 cond = TRUE;
138 s32 i;
139
140 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
141 EffectInstance* effectInstance = gEffectInstances[i];
142
143 if (effectInstance != NULL) {
144 if (effectInstance->flags & FX_INSTANCE_FLAG_ENABLED) {
145 if (effectInstance->flags & FX_INSTANCE_FLAG_HAS_UPDATED) {
146 void (*renderUI)(EffectInstance* effect);
147
148 if (gGameStatusPtr->context != CONTEXT_WORLD && !(effectInstance->flags & FX_INSTANCE_FLAG_BATTLE)) {
149 continue;
150 }
151
153 continue;
154 }
155
156 renderUI = effectInstance->graphics->renderUI;
157 if (renderUI != stub_effect_delegate) {
158 if (cond) {
159 Camera* camera = &gCameras[gCurrentCameraID];
160
161 gDPPipeSync(gMainGfxPos++);
162 gSPViewport(gMainGfxPos++, &camera->vp);
163 gSPClearGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG |
164 G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD |
165 G_SHADING_SMOOTH | G_CLIPPING | 0x40F9FA);
166 gSPSetGeometryMode(gMainGfxPos++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH);
167 gDPSetScissor(gMainGfxPos++, G_SC_NON_INTERLACE,
168 camera->viewportStartX,
169 camera->viewportStartY,
170 camera->viewportStartX + camera->viewportW,
171 camera->viewportStartY + camera->viewportH);
172 gSPClipRatio(gMainGfxPos++, FRUSTRATIO_2);
173
174 cond = FALSE;
175 if (!(camera->flags & CAMERA_FLAG_ORTHO)) {
176 gSPPerspNormalize(gMainGfxPos++, camera->perspNorm);
178 G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
179 }
180 }
181
182 renderUI(effectInstance);
183 }
184 }
185 }
186 }
187 }
188}
void stub_effect_delegate(EffectInstance *effect)
Used for unbound function points in effect structs.
Definition effects.c:26
@ CAMERA_FLAG_ORTHO
Definition enums.h:4724
s16 viewportStartX
s16 viewportStartY
void(* renderUI)(EffectInstance *effectInst)
Definition effects.h:2665
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
s32 gCurrentCameraID
Definition cam_math.c:4
DisplayContext * gDisplayContext
Definition cam_main.c:16

Referenced by gfx_draw_frame().

◆ create_effect_instance()

EffectInstance * create_effect_instance ( EffectBlueprint * effectBp)

Definition at line 190 of file effects.c.

190 {
191 EffectInstance* newEffectInst;
192 EffectGraphics* effectGraphics;
193 s32 i;
194
195 // Search for an unused instance
196 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
197 if (gEffectInstances[i] == NULL) {
198 break;
199 }
200 }
201
203
204 // Allocate space for the new instance
205 gEffectInstances[i] = newEffectInst = general_heap_malloc(sizeof(*newEffectInst));
206 ASSERT(newEffectInst != NULL);
207
208 effectGraphics = &gEffectGraphicsData[0];
209 newEffectInst->effectIndex = effectBp->effectID;
210 newEffectInst->flags = FX_INSTANCE_FLAG_ENABLED;
211
212 // Look for a loaded effect of the proper index
213 for (i = 0; i < ARRAY_COUNT(gEffectGraphicsData); i++) {
214 if ((effectGraphics->flags & FX_GRAPHICS_LOADED) && (effectGraphics->effectIndex == effectBp->effectID)) {
215 break;
216 }
217 effectGraphics++;
218 }
219
221
222 // If this is the first new instance of the effect, initialize the function pointers
223 if (effectGraphics->instanceCounter == 0) {
224 effectGraphics->update = effectBp->update;
225 if (effectGraphics->update == NULL) {
226 effectGraphics->update = stub_effect_delegate;
227 }
228
229 effectGraphics->renderWorld = effectBp->renderWorld;
230 if (effectGraphics->renderWorld == NULL) {
231 effectGraphics->renderWorld = stub_effect_delegate;
232 }
233
234 effectGraphics->renderUI = effectBp->renderUI;
235 if (effectGraphics->renderUI == NULL) {
236 effectGraphics->renderUI = stub_effect_delegate;
237 }
238 }
239
240 effectGraphics->instanceCounter++;
241 newEffectInst->graphics = effectGraphics;
242
243 if (effectBp->init != NULL) {
244 effectBp->init(newEffectInst);
245 }
246
248 newEffectInst->flags |= FX_INSTANCE_FLAG_BATTLE;
249 }
250 return newEffectInst;
251}
#define general_heap_malloc
#define ASSERT(condition)
void(* renderUI)(EffectInstance *effectInst)
Definition effects.h:2655
void(* init)(EffectInstance *effectInst)
Definition effects.h:2652
void(* update)(EffectInstance *effectInst)
Definition effects.h:2653
void(* renderWorld)(EffectInstance *effectInst)
Definition effects.h:2654
s32 instanceCounter
Definition effects.h:2661

◆ remove_effect()

void remove_effect ( EffectInstance * effectInstance)

Definition at line 253 of file effects.c.

253 {
254 s32 i;
255
256 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
257 if (gEffectInstances[i] == effectInstance) {
258 break;
259 }
260 }
261
263
264 if (effectInstance->data.any == NULL) {
265 general_heap_free(effectInstance);
266 gEffectInstances[i] = NULL;
267 } else {
268 general_heap_free(effectInstance->data.any);
269 general_heap_free(effectInstance);
270 gEffectInstances[i] = NULL;
271 }
272}

◆ remove_all_effects()

void remove_all_effects ( void )

Definition at line 274 of file effects.c.

274 {
275 s32 i;
276
277 for (i = 0; i < ARRAY_COUNT(gEffectInstances); i++) {
278 EffectInstance* effect = gEffectInstances[i];
279
280 if (effect != NULL && effect->flags & FX_INSTANCE_FLAG_BATTLE) {
281 if (effect->data.any != NULL) {
282 general_heap_free(effect->data.any);
283 }
284 general_heap_free(effect);
285 gEffectInstances[i] = NULL;
286 }
287 }
288}

Referenced by btl_state_update_end_battle(), and btl_state_update_end_demo_battle().

◆ load_effect()

s32 load_effect ( s32 effectIndex)

Definition at line 290 of file effects.c.

290 {
291 EffectTableEntry* effectEntry = &gEffectTable[effectIndex];
292 EffectGraphics* effectGraphics;
293 TlbMappablePage* tlbMappablePages;
294 s32 i;
295
296 // Look for a loaded effect matching the desired index
297 for (i = 0, effectGraphics = &gEffectGraphicsData[0]; i < ARRAY_COUNT(gEffectGraphicsData); i++) {
298 if (effectGraphics->flags & FX_GRAPHICS_LOADED && effectGraphics->effectIndex == effectIndex) {
299 break;
300 }
301 effectGraphics++;
302 }
303
304 // If an effect was found within the table, initialize it and return
306 effectGraphics->effectIndex = effectIndex;
307 effectGraphics->instanceCounter = 0;
308 effectGraphics->flags = FX_GRAPHICS_LOADED;
309 return 1;
310 }
311
312 // If a loaded effect wasn't found, look for the first empty space
313 for (i = 0, effectGraphics = &gEffectGraphicsData[0]; i < ARRAY_COUNT(gEffectGraphicsData); i++) {
314 if (!(effectGraphics->flags & FX_GRAPHICS_LOADED)) {
315 break;
316 }
317 effectGraphics++;
318 }
319
320 // If no empty space was found, panic
322
323 // Map space for the effect
324 tlbMappablePages = &gEffectDataBuffer;
325 osMapTLB(i, OS_PM_4K, effectEntry->dmaDest, (s32)((*tlbMappablePages)[i]) & 0xFFFFFF, -1, -1);
326
327 // Copy the effect into the newly mapped space
328 dma_copy(effectEntry->dmaStart, effectEntry->dmaEnd, effectEntry->dmaDest);
329
330 // If there's graphics data for the effect, allocate space and copy into the new space
331 if (effectEntry->graphicsDmaStart != NULL) {
332 void* effectDataBuf = general_heap_malloc(effectEntry->graphicsDmaEnd - effectEntry->graphicsDmaStart);
333 effectGraphics->data = effectDataBuf;
334 ASSERT(effectDataBuf != NULL);
335 dma_copy(effectEntry->graphicsDmaStart, effectEntry->graphicsDmaEnd, effectGraphics->data);
336 }
337
338 // Initialize the newly loaded effect data
339 effectGraphics->effectIndex = effectIndex;
340 effectGraphics->instanceCounter = 0;
341 effectGraphics->flags = FX_GRAPHICS_LOADED;
342 return 1;
343}
TlbEntry TlbMappablePage[15]
Definition effects.c:6
TlbMappablePage gEffectDataBuffer
void * graphicsDmaStart
Definition effects.h:2674
void * graphicsDmaEnd
Definition effects.h:2675
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:444

Variable Documentation

◆ gEffectGraphicsData

BSS EffectGraphics gEffectGraphicsData[15]

Definition at line 10 of file effects.c.

Referenced by clear_effect_data(), create_effect_instance(), load_effect(), and update_effects().

◆ gEffectInstances

◆ gEffectDataBuffer

TlbMappablePage gEffectDataBuffer
extern

Referenced by load_effect().

◆ gEffectGlobals

BSS u8 gEffectGlobals
extern

Referenced by clear_effect_data().

◆ D_8007FEB8

s32 D_8007FEB8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 3, 4, 13, 60, 0, 512, 0, 0, 3, 0 }

Definition at line 23 of file effects.c.

23{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 3, 4, 13, 60, 0, 512, 0, 0, 3, 0 };