Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
sprite.c
Go to the documentation of this file.
1#include "sprite.h"
2#include "sprite/player.h"
3
4#define MAX_SPRITE_ID 0xFF // todo generate this
5
8
23
26void spr_init_player_raster_cache(s32 cacheSize, s32 maxRasterSize);
27
29 {
30 {{{ -16, 56, 0 }, FALSE, { 0, 0 }, { 240, 240, 240, 255 }}},
31 {{{ 16, 56, 0 }, FALSE, { 1024, 0 }, { 120, 120, 120, 255 }}},
32 {{{ 16, 0, 0 }, FALSE, { 1024, 1792 }, { 0, 0, 0, 255 }}},
33 {{{ -16, 0, 0 }, FALSE, { 0, 1792 }, { 120, 120, 120, 255 }}},
34 }
35};
36
38 { 640, 480, 511, 0 },
39 { 640, 480, 511, 0 },
40 }
41};
42
44 { 640, 480, 511, 0 },
45 { 640, 480, 512, 0 },
46 }
47};
48
49Gfx D_802DF3F0[] = {
50 gsSPClearGeometryMode(G_CULL_BOTH | G_LIGHTING),
51 gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
52 gsSPTexture(-1, -1, 0, G_TX_RENDERTILE, G_ON),
53 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH),
54 gsDPSetRenderMode(AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM), AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)),
55 gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 18, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_RGBA16 | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE),
56 gsSPEndDisplayList(),
57};
58
59Gfx D_802DF428[] = {
60 gsSPClearGeometryMode(G_CULL_BOTH | G_LIGHTING),
61 gsDPSetCombineMode(PM_CC_02, PM_CC_02),
62 gsSPTexture(-1, -1, 0, G_TX_RENDERTILE, G_ON),
63 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH),
64 gsDPSetRenderMode(G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2),
65 gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 18, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_RGBA16 | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE),
66 gsSPEndDisplayList(),
67};
68
69Gfx D_802DF460[] = {
70 gsSPClearGeometryMode(G_CULL_BOTH | G_LIGHTING),
71 gsSPTexture(-1, -1, 0, G_TX_RENDERTILE, G_ON),
72 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH),
73 gsDPSetRenderMode(AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | G_RM_PASS, AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)),
74 gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 18, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_RGBA16 | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_2CYCLE | G_PM_NPRIMITIVE),
75 gsSPEndDisplayList(),
76};
77
78Gfx D_802DF490[] = {
79 gsSPClearGeometryMode(G_CULL_BOTH | G_LIGHTING),
80 gsSPTexture(-1, -1, 0, G_TX_RENDERTILE, G_ON),
81 gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH),
82 gsDPSetRenderMode(G_RM_PASS, G_RM_ZB_CLD_SURF2),
83 gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 18, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_RGBA16 | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_2CYCLE | G_PM_NPRIMITIVE),
84 gsSPEndDisplayList(),
85};
86
88
89#define MARIO_SPRITE_COMMON_BITS \
90 1 << SPR_Mario1 \
91 | 1 << SPR_Mario1_Back \
92
93#define MARIO_SPRITE_WORLD_BITS \
94 MARIO_SPRITE_COMMON_BITS \
95 | 1 << SPR_MarioW1 \
96 | 1 << SPR_MarioW1_Back \
97 | 1 << SPR_MarioW2 \
98 | 1 << SPR_MarioW3
99
100#define MARIO_SPRITE_BATTLE_BITS \
101 MARIO_SPRITE_COMMON_BITS \
102 | 1 << SPR_MarioB1 \
103 | 1 << SPR_MarioB2 \
104 | 1 << SPR_MarioB3
105
106#define PEACH_SPRITE_BITS \
107 1 << SPR_Peach1 \
108 | 1 << SPR_Peach1_Back \
109 | 1 << SPR_Peach2 \
110 | 1 << SPR_Peach3 \
111
112// TODO(player raster splat header generation):
113// - macroify rasterSize based on the biggest raster
123
125 s32 i;
126
128
129 for (i = 0; i < ARRAY_COUNT(D_802DFE48); i++) {
130 D_802DFE48[i] = -1;
131 }
132}
133
134Quad* spr_get_cached_quad(s32 quadIndex) {
135 s32* temp_v1 = &D_802DFE48[quadIndex];
136
137 *temp_v1 |= 0x1F;
138 return &D_802DFE44[quadIndex];
139}
140
141void spr_make_quad_for_size(Quad* quad, s32 width, s32 height) {
142 Vtx* vtx = &quad->v[0];
143
144 *quad = spr_defaultQuad;
145
146 vtx->v.ob[0] = -width / 2;
147 vtx->v.ob[1] = height;
148 vtx->v.tc[0] = 0x2000;
149 vtx->v.tc[1] = 0x2000;
150
151 vtx++;
152 vtx->v.ob[0] = width / 2;
153 vtx->v.ob[1] = height;
154 vtx->v.tc[0] = (width + 256) * 32;
155 vtx->v.tc[1] = 0x2000;
156
157 vtx++;
158 vtx->v.tc[0] = (width + 256) * 32;
159 vtx->v.ob[0] = width / 2;
160 vtx->v.tc[1] = (height + 256) * 32;
161
162 vtx++;
163 vtx->v.ob[0] = -width / 2;
164 vtx->v.tc[0] = 0x2000;
165 vtx->v.tc[1] = (height + 256) * 32;
166}
167
168Quad* spr_get_quad_for_size(s32* quadIndex, s32 width, s32 height) {
169 Quad* quad;
170 s32 qi;
171 s32 dimensions;
172 s32 i;
173
174 if ((width * height) / 2 <= 0x800) {
175 dimensions = (width << 0x18) + (height << 0x10);
176 qi = *quadIndex;
177 if (qi != -1 && (dimensions == (D_802DFE48[qi] & 0xFFFF0000))) {
178 return spr_get_cached_quad(qi);
179 }
180
181 for (i = 0; i < ARRAY_COUNT(D_802DFE48); i++) {
182 if (dimensions == (D_802DFE48[i] & 0xFFFF0000)) {
183 *quadIndex = i;
184 return spr_get_cached_quad(i);
185 }
186 }
187
188 for (i = 0; i < ARRAY_COUNT(D_802DFE48); i++) {
189 if (D_802DFE48[i] == -1) {
190 break;
191 }
192 }
193
194 if (i != ARRAY_COUNT(D_802DFE48)) {
195 *quadIndex = i;
196 D_802DFE48[i] = dimensions;
197 quad = spr_get_cached_quad(i);
198 spr_make_quad_for_size(quad, width, height);
199 return quad;
200 }
201 }
202 return NULL;
203}
204
206 s32 i;
207
208 for (i = 0; i < ARRAY_COUNT(D_802DFE48); i++) {
209 if (D_802DFE48[i] != -1) {
210 D_802DFE48[i]--;
211 if (!(D_802DFE48[i] & 0xFFFF)) {
212 D_802DFE48[i] = -1;
213 }
214 }
215 }
216}
217
219 Quad* vertices,
220 IMG_PTR raster, PAL_PTR palette,
221 s32 width, s32 height,
222 f32 arg5,
223 Matrix4f mtx,
224 s32 alpha
225) {
226 gDPLoadTLUT_pal16(gMainGfxPos++, 0, palette);
228 gDPScrollMultiTile2_4b(gMainGfxPos++, raster, G_IM_FMT_CI, width, height,
229 0, 0, width - 1, height - 1, 0,
230 G_TX_CLAMP, G_TX_CLAMP, 8, 8, G_TX_NOLOD, G_TX_NOLOD,
231 256, 256);
232 gDPSetTile(gMainGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, 0x0100, 2, 0, G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD);
233 gDPSetTileSize(gMainGfxPos++, 2, 0, 0, 63 << 2, 0);
235 Camera* camera = &gCameras[gCurrentCamID];
237 gSPViewport(gMainGfxPos++, &SprPauseVpAlt);
238 } else {
239 gSPViewport(gMainGfxPos++, &camera->vpAlt);
240 }
241
242 if (alpha == 255) {
243 gDPSetRenderMode(gMainGfxPos++, AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
244 G_RM_PASS, AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
245 GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM));
246 } else {
247 gDPSetRenderMode(gMainGfxPos++, G_RM_PASS, G_RM_ZB_CLD_SURF2);
248 }
249
250 gDPSetEnvColor(gMainGfxPos++, 0, 0, 0, alpha);
251 gDPSetCombineMode(gMainGfxPos++, PM_CC_0B, PM_CC_0C);
252 gSPVertex(gMainGfxPos++, vertices, 4, 0);
253 gSP2Triangles(gMainGfxPos++, 0, 2, 1, 0, 0, 3, 2, 0);
254 gDPPipeSync(gMainGfxPos++);
255 }
256 create_shading_palette(mtx, 0, 0, width, height, alpha, alpha == 255 ? 0x111238 : 0x104B50); // TODO make macro for render mode
257 } else {
258 gDPScrollTextureBlock_4b(gMainGfxPos++, raster, G_IM_FMT_CI, width, height, 0,
259 G_TX_CLAMP, G_TX_CLAMP, 8, 8, G_TX_NOLOD, G_TX_NOLOD,
260 256, 256);
262 Camera* camera = &gCameras[gCurrentCamID];
264 gSPViewport(gMainGfxPos++, &SprPauseVpAlt);
265 } else {
266 gSPViewport(gMainGfxPos++, &camera->vpAlt);
267 }
268 if (alpha == 255) {
269 gDPSetRenderMode(gMainGfxPos++, AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | ALPHA_CVG_SEL | GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM), AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA | ALPHA_CVG_SEL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM));
270 } else {
271 gDPSetRenderMode(gMainGfxPos++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2);
272 }
273
274 gDPSetEnvColor(gMainGfxPos++, 0, 0, 0, alpha);
275 gDPSetCombineMode(gMainGfxPos++, PM_CC_0A, PM_CC_0A);
276 gSPVertex(gMainGfxPos++, vertices, 4, 0);
277 gSP2Triangles(gMainGfxPos++, 0, 2, 1, 0, 0, 3, 2, 0);
278 gDPPipeSync(gMainGfxPos++);
279
280 if (alpha == 255) {
281 gDPSetRenderMode(gMainGfxPos++, AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
282 GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM),
283 AA_EN | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
284 GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM));
285 } else {
286 gDPSetRenderMode(gMainGfxPos++, G_RM_ZB_CLD_SURF, G_RM_ZB_CLD_SURF2);
287 }
288
289 gDPSetEnvColor(gMainGfxPos++, 100, 100, 100, 255);
290 gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, alpha);
291 gDPSetCombineMode(gMainGfxPos++, PM_CC_3D, PM_CC_3D);
292 gDPSetColorDither(gMainGfxPos++, G_CD_MAGICSQ);
293 }
294 }
295
297 Camera* camera = &gCameras[gCurrentCamID];
298
300 gSPViewport(gMainGfxPos++, &SprPauseVp);
301 SprPauseVpAlt.vp.vtrans[0] = SprPauseVp.vp.vtrans[0] + gGameStatusPtr->altViewportOffset.x;
302 SprPauseVpAlt.vp.vtrans[1] = SprPauseVp.vp.vtrans[1] + gGameStatusPtr->altViewportOffset.y;
303 } else {
304 gSPViewport(gMainGfxPos++, &camera->vp);
305 }
306 }
307
308 gSPVertex(gMainGfxPos++, vertices, 4, 0);
309 gSP2Triangles(gMainGfxPos++, 0, 2, 1, 0, 0, 3, 2, 0);
310 gDPPipeSync(gMainGfxPos++);
311}
312
315 f32 dx, f32 dy, f32 dz,
316 f32 rotX, f32 rotY, f32 rotZ,
317 f32 scaleX, f32 scaleY, f32 scaleZ,
318 s32 opacity, PAL_PTR palette, Matrix4f mtx)
319{
320 Matrix4f mtxTransform;
321 Matrix4f mtxTemp;
322 ImgFXTexture ifxImg;
323 s32 quadIndex;
324 Quad* quad;
325 s32 width;
326 s32 height;
327
328 guTranslateF(mtxTemp, dx, dy, dz);
329 guMtxCatF(mtxTemp, mtx, mtxTransform);
330
331 if (rotY != 0.0f) {
332 guRotateF(mtxTemp, rotY, 0.0f, 1.0f, 0.0f);
333 guMtxCatF(mtxTemp, mtxTransform, mtxTransform);
334 }
335 if (rotZ != 0.0f) {
336 guRotateF(mtxTemp, rotZ, 0.0f, 0.0f, 1.0f);
337 guMtxCatF(mtxTemp, mtxTransform, mtxTransform);
338 }
339 if (rotX != 0.0f) {
340 guRotateF(mtxTemp, rotX, 1.0f, 0.0f, 0.0f);
341 guMtxCatF(mtxTemp, mtxTransform, mtxTransform);
342 }
343
344 if (scaleX != 1.0f || scaleY != 1.0f || scaleZ != 1.0f) {
345 guScaleF(mtxTemp, scaleX, scaleY, scaleZ);
346 guMtxCatF(mtxTemp, mtxTransform, mtxTransform);
347 }
348
351 G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
352
354 if ((u8) opacity == 255) {
355 gSPDisplayList(gMainGfxPos++, D_802DF460);
356 } else {
357 gSPDisplayList(gMainGfxPos++, D_802DF490);
358 }
359 } else {
360 if ((u8) opacity == 255) {
361 gSPDisplayList(gMainGfxPos++, D_802DF3F0);
362 } else {
363 gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, (u8) opacity);
364 gSPDisplayList(gMainGfxPos++, D_802DF428);
365 }
366 }
367
368 width = cache->width;
369 height = cache->height;
370 quadIndex = cache->quadCacheIndex;
371 quad = NULL;
373 quad = spr_get_quad_for_size(&quadIndex, width, height);
374 cache->quadCacheIndex = quadIndex;
375 }
376
377 if (quad != NULL) {
378 spr_appendGfx_component_flat(quad, cache->image, palette, width, height, rotY, mtxTransform, (u8) opacity);
379 } else {
380 ifxImg.raster = cache->image;
381 ifxImg.palette = palette;
382 ifxImg.width = width;
383 ifxImg.height = height;
384 ifxImg.xOffset = -(width / 2);
385 ifxImg.yOffset = height;
386 ifxImg.alpha = opacity;
387 if (imgfx_appendGfx_component((u8) D_802DF540, &ifxImg, IMGFX_FLAG_80000, mtxTransform) == 1) {
388 D_802DF540 &= ~SPR_IMGFX_FLAG_ALL;
389 }
390 }
391 gSPPopMatrix(gMainGfxPos++, G_MTX_MODELVIEW);
392}
393
394void spr_transform_point(s32 rotX, s32 rotY, s32 rotZ, f32 inX, f32 inY, f32 inZ, f32* outX, f32* outY, f32* outZ) {
395 if (rotX == 0 && rotY == 0 && rotZ == 0) {
396 *outX = inX;
397 *outY = inY;
398 *outZ = inZ;
399 } else {
400 Matrix4f mtxTransform, mtxTemp;
401 f32 xx, yx, zx, xy, yy, zy, xz, yz, zz;
402
403 guRotateF(mtxTransform, rotY, 0.0f, 1.0f, 0.0f);
404 guRotateF(mtxTemp, rotZ, 0.0f, 0.0f, 1.0f);
405 guMtxCatF(mtxTemp, mtxTransform, mtxTransform);
406 guRotateF(mtxTemp, rotX, 1.0f, 0.0f, 0.0f);
407 guMtxCatF(mtxTemp, mtxTransform, mtxTransform);
408
409 xx = (mtxTransform[0][0] * inX);
410 yx = (mtxTransform[1][0] * inY);
411 zx = (mtxTransform[2][0] * inZ);
412 xy = (mtxTransform[0][1] * inX);
413 yy = (mtxTransform[1][1] * inY);
414 zy = (mtxTransform[2][1] * inZ);
415 xz = (mtxTransform[0][2] * inX);
416 yz = (mtxTransform[1][2] * inY);
417 zz = (mtxTransform[2][2] * inZ);
418
419 *outX = xx + yx + zx;
420 *outY = xy + yy + zy;
421 *outZ = xz + yz + zz;
422 }
423}
424
425void spr_draw_component(s32 drawOpts, SpriteComponent* component, SpriteAnimComponent* anim,
426 SpriteRasterCacheEntry** cache, PAL_PTR* palettes, f32 zscale, Matrix4f mtx) {
427 SpriteRasterCacheEntry* cacheEntry;
428 s32 paletteIdx;
429 PAL_PTR pal;
430 f32 dx, dy, dz;
431 f32 rotX, rotY, rotZ;
432 f32 inX, inY, inZ;
433
434 if (component->initialized && component->curRaster != -1) {
435 rotX = D_802DFEA0[0];
436 rotY = D_802DFEA0[1];
437 rotZ = D_802DFEA0[2];
438 inX = component->compPos.x + anim->compOffset.x;
439 inY = component->compPos.y + anim->compOffset.y;
440 inZ = component->compPos.z + anim->compOffset.z;
441
442 spr_transform_point(rotX, rotY, rotZ, inX, inY, inZ * zscale, &dx, &dy, &dz);
443 cacheEntry = cache[component->curRaster];
444 paletteIdx = component->curPalette;
445 if (drawOpts & DRAW_SPRITE_USE_PLAYER_RASTERS) {
446 cacheEntry->image = spr_get_player_raster(component->curRaster & 0xFFF, D_802DF57C);
447 }
448 D_802DF540 = component->imgfxIdx;
449 pal = palettes[paletteIdx];
450
452 cacheEntry,
453 dx, dy, dz,
454 rotX + component->rot.x,
455 rotY + component->rot.y,
456 rotZ + component->rot.z,
457 component->scale.x,
458 component->scale.y,
459 component->scale.z,
460 drawOpts, pal, mtx
461 );
462 component->imgfxIdx = D_802DF540;
463 }
464}
465
467 s32 temp = val & 0xFFF;
468
469 if (temp & 0x800) {
470 return temp | ~0xFFF;
471 } else {
472 return temp;
473 }
474}
475
477 s32 temp = val & 0xFFFF;
478
479 if (temp & 0x8000) {
480 return temp | ~0xFFFF;
481 } else {
482 return temp;
483 }
484}
485
487 f32 posX, posY, posZ;
488 f32 rotX, rotY, rotZ;
489 f32 scaleX, scaleY, scaleZ;
490 s32 changedFlags;
491
492 u16* bufPos;
493 u16* gotoPos;
494 s32 cmdValue;
495
496 if (comp->initialized) {
497 scaleZ = 1.0f;
498 scaleY = 1.0f;
499 scaleX = 1.0f;
500 changedFlags = 0;
501
502 bufPos = comp->readPos;
503 gotoPos = (u16*) -1;
504
506
507 while (comp->waitTime <= 0.0f) {
508 // overflow check
509 if (bufPos >= &anim->cmdList[anim->cmdListSize / 2]) {
510 bufPos = anim->cmdList;
511 break;
512 }
513
514 switch (*bufPos & 0xF000) {
515 // 0VVV
516 // Wait
517 case 0x0000:
518 comp->waitTime = *bufPos++ & 0xFFF;
519 if (comp->waitTime == 0.0f) {
520 comp->waitTime = 4095.0f;
521 }
522 comp->posOffset.z = 0.0f;
523 comp->posOffset.y = 0.0f;
524 comp->posOffset.x = 0.0f;
525 comp->rot.z = 0;
526 comp->rot.y = 0;
527 comp->rot.x = 0;
528 comp->scale.z = 1.0f;
529 comp->scale.y = 1.0f;
530 comp->scale.x = 1.0f;
531 break;
532 // 2VVV
533 // Goto -- jump to another position in the list
534 case 0x2000:
535 bufPos = &anim->cmdList[spr_unpack_signed_12bit(*bufPos)];
536 if (bufPos == gotoPos) {
537 bufPos = anim->cmdList;
538 comp->waitTime = 1.0f;
539 }
540 gotoPos = bufPos;
541 break;
542 // 1VVV
543 // SetImage -- FFF is valid value for "no image"
544 case 0x1000:
545 cmdValue = *bufPos++ & 0xFFF;
546 if (cmdValue != 0xFFF) {
547 comp->curRaster = cmdValue;
548 } else {
549 comp->curRaster = -1;
550 }
551 comp->curPalette = -1;
552 break;
553 // 6VVV
554 // SetPalette -- FFF to clear
555 case 0x6000:
556 cmdValue = *bufPos++ & 0xFFF;
557 if (cmdValue != 0xFFF) {
558 comp->curPalette = cmdValue;
559 } else {
560 comp->curPalette = -1;
561 }
562 break;
563 // 8VUU
564 // SetProperty
565 // 81-XX parent to component XX
566 // 82-YY set notify value to YY
567 case 0x8000:
568 cmdValue = *bufPos++;
569 switch (cmdValue & 0xF00) {
570 case 0x100: // set parent
571 comp->properties = (comp->properties & 0xFFFF0000) | cmdValue;
572 break;
573 case 0x200: // set notify value
574 SpriteUpdateNotifyValue = cmdValue & 0xFF;
575 comp->properties = (comp->properties & 0xFF00FFFF) | (SpriteUpdateNotifyValue << 0x10);
576 break;
577 }
578 break;
579 // 3VVV XXXX YYYY ZZZZ
580 // SetPosition -- what does the flag do?
581 case 0x3000:
582 switch (*bufPos++ & 0xF) {
583 case 0:
584 case 1:
585 posX = spr_unpack_signed_16bit(*bufPos++);
586 posY = spr_unpack_signed_16bit(*bufPos++);
587 posZ = spr_unpack_signed_16bit(*bufPos++);
588 changedFlags |= 1;
589 break;
590 }
591 break;
592 // 4XXX YYYY ZZZZ
593 // SetRotation (euler angles)
594 case 0x4000:
595 rotX = spr_unpack_signed_12bit(*bufPos++);
596 rotY = spr_unpack_signed_16bit(*bufPos++);
597 rotZ = spr_unpack_signed_16bit(*bufPos++);
598 changedFlags |= 2;
599 break;
600 // 5VVV UUUU
601 // SetScale (%)
602 case 0x5000:
603 switch (*bufPos++ & 0xF) {
604 case 0:
605 scaleZ = *bufPos++ / 100.0f;
606 scaleY = scaleZ;
607 scaleX = scaleZ;
608 break;
609 case 1:
610 scaleX = *bufPos++ / 100.0f;
611 break;
612 case 2:
613 scaleY = *bufPos++ / 100.0f;
614 break;
615 case 3:
616 scaleZ = *bufPos++ / 100.0f;
617 break;
618 }
619 changedFlags |= 4;
620 break;
621 // 7VVV UUUU
622 // Loop -- VV iterations jumping back to UUUU
623 case 0x7000:
624 if (comp->loopCounter != 0) {
625 comp->loopCounter--;
626 if (comp->loopCounter == 0) {
627 bufPos += 2;
628 break;
629 }
630 } else {
631 comp->loopCounter = bufPos[1];
632 }
633 bufPos = &anim->cmdList[spr_unpack_signed_12bit(*bufPos)];
634 break;
635 // invalid command
636 default:
637 bufPos = anim->cmdList;
638 comp->waitTime = 1.0f;
639 break;
640 }
641 } // end loop
642
643 comp->readPos = bufPos;
644 if (changedFlags & 1) {
645 comp->posOffset.x = posX;
646 comp->posOffset.y = posY;
647 comp->posOffset.z = posZ;
648 }
649 if (changedFlags & 2) {
650 comp->rot.x = rotX;
651 comp->rot.y = rotY;
652 comp->rot.z = rotZ;
653 }
654 if (changedFlags & 4) {
655 comp->scale.x = scaleX;
656 comp->scale.y = scaleY;
657 comp->scale.z = scaleZ;
658 }
659 }
660}
661
663 SpriteRasterCacheEntry** rasterCacheEntry, s32 overridePalette)
664{
665 SpriteComponent* listComp;
667
668 if (comp->initialized) {
669 comp->compPos.x = comp->posOffset.x;
670 comp->compPos.y = comp->posOffset.y;
671 comp->compPos.z = comp->posOffset.z;
672
673 if ((comp->properties & 0xF00) == 0x100) {
674 listComp = compList[comp->properties & 0xFF];
675 comp->compPos.x += listComp->compPos.x;
676 comp->compPos.y += listComp->compPos.y;
677 comp->compPos.z += listComp->compPos.z;
678 }
679
680 if (comp->curRaster != -1) {
681 cache = rasterCacheEntry[comp->curRaster];
682 if (comp->curPalette == -1) {
683 comp->curPalette = cache->palette;
684 if (overridePalette != 0 && comp->curPalette == 0) {
685 comp->curPalette = overridePalette;
686 }
687 }
688 }
689 }
690}
691
692s32 spr_component_update(s32 curNotifyValue, SpriteComponent** compList, SpriteAnimComponent** animList,
693 SpriteRasterCacheEntry** rasterCache, s32 overridePalette) {
694 SpriteComponent** compListIt;
695
696 SpriteUpdateNotifyValue = curNotifyValue;
697
698 compListIt = compList;
699 while (*compListIt != PTR_LIST_END) {
700 spr_component_update_commands(*compListIt++, *animList);
701 if (*animList != PTR_LIST_END) {
702 animList++;
703 }
704 }
705
706 compListIt = compList;
707 while (*compListIt != PTR_LIST_END) {
708 spr_component_update_finish(*compListIt++, compList, rasterCache, overridePalette);
709 }
710
712}
713
715 if (anim == PTR_LIST_END) {
716 comp->initialized = FALSE;
717 return;
718 }
719
720 comp->initialized = TRUE;
721 comp->properties = 0;
722 comp->readPos = anim->cmdList;
723 comp->waitTime = 0;
724 comp->loopCounter = 0;
725 comp->curRaster = -1;
726 comp->curPalette = -1;
727 comp->posOffset.x = 0.0f;
728 comp->posOffset.y = 0.0f;
729 comp->posOffset.z = 0.0f;
730 comp->compPos.x = 0.0f;
731 comp->compPos.y = 0.0f;
732 comp->compPos.z = 0.0f;
733 comp->rot.x = 0.0f;
734 comp->rot.y = 0.0f;
735 comp->rot.z = 0.0f;
736 comp->scale.x = 1.0f;
737 comp->scale.y = 1.0f;
738 comp->scale.z = 1.0f;
739}
740
742 while (*compList != PTR_LIST_END) {
743 SpriteComponent* component = *compList++;
744 spr_init_component_anim_state(component, *animList);
745 if (*animList != PTR_LIST_END) {
746 animList++;
747 }
748 }
749}
750
751void spr_set_anim_timescale(f32 timescale) {
752 spr_animUpdateTimeScale = timescale * 2.0f;
753}
754
755void spr_load_player_sprite(s32 spriteIndex) {
756 SpriteAnimData* playerSprite = spr_load_sprite(spriteIndex - 1, TRUE, FALSE);
757
758 spr_playerSprites[spriteIndex - 1] = playerSprite;
759 if (spr_playerMaxComponents < playerSprite->maxComponents) {
761 }
762}
763
764void spr_init_sprites(s32 playerSpriteSet) {
765 s32 loadedFlags;
766 s32 i;
767
770 imgfx_init();
771
772 for (i = 0; i < ARRAY_COUNT(spr_playerSprites); i++) {
773 SpriteAnimData** playerSprites = spr_playerSprites;
774 playerSprites[i] = 0;
775 }
776
778
780 playerSpriteSet = PLAYER_SPRITES_PEACH_WORLD;
781 }
782
783 loadedFlags = (&spr_playerSpriteSets[playerSpriteSet])->initiallyLoaded;
784 spr_init_player_raster_cache((&spr_playerSpriteSets[playerSpriteSet])->cacheSize,
785 (&spr_playerSpriteSets[playerSpriteSet])->rasterSize);
786
787 for (i = 1; i <= SPR_Peach3; i++) {
788 if ((loadedFlags >> i) & 1) {
790 }
791 }
792
793 for (i = 0; i < ARRAY_COUNT(spr_playerCurrentAnimInfo); i++) {
796 }
797
798 for (i = 0; i < ARRAY_COUNT(NpcSpriteData); i++) {
799 NpcSpriteData[i] = NULL;
801 }
802
803 for (i = 0; i < ARRAY_COUNT(SpriteInstances); i++) {
806 SpriteInstances[i].spriteData = NULL;
809 }
810
812}
813
818
819s32 func_802DDA84(void) {
820 return 0;
821}
822
823s32 spr_update_player_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale) {
824 u32* spriteData;
825 SpriteComponent** compList;
826 SpriteComponent* component;
827 SpriteAnimComponent** animList;
828 SpriteRasterCacheEntry** rasterList;
829 s32 spriteId = ((animID >> 16) & 0xFF) - 1;
830 s32 instanceIdx = spriteInstanceID & 0xFF;
831 s32 animIndex = animID & 0xFF;
832 D_802DF57C = spriteId;
833
834 if (spr_playerCurrentAnimInfo[instanceIdx].componentList == NULL) {
836 spr_playerCurrentAnimInfo[instanceIdx].componentList = compList;
837 while (*compList != PTR_LIST_END) {
838 component = *compList;
839 component->imgfxIdx = imgfx_get_free_instances(1);
840 compList++;
841 }
842 }
843
844 spriteData = (u32*)spr_playerSprites[spriteId];
845 compList = spr_playerCurrentAnimInfo[instanceIdx].componentList;
846
847 if (spriteData == NULL) {
848 return 0;
849 }
850
851 rasterList = (SpriteRasterCacheEntry**)*spriteData;
852 spriteData += 4 + animIndex;
853 animList = (SpriteAnimComponent**)*spriteData;
854
855 spr_set_anim_timescale(timeScale);
856 if ((spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) ||
857 (animID & ~SPRITE_ID_BACK_FACING) != (spr_playerCurrentAnimInfo[instanceIdx].animID & ~SPRITE_ID_BACK_FACING))
858 {
859 spr_init_anim_state(compList, animList);
860 spr_playerCurrentAnimInfo[instanceIdx].notifyValue = 0;
861 }
862
863 spr_playerCurrentAnimInfo[instanceIdx].animID = animID;
864
865 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
867 compList, animList, rasterList, 0);
868 }
869 return spr_playerCurrentAnimInfo[instanceIdx].notifyValue;
870}
871
872s32 spr_draw_player_sprite(s32 spriteInstanceID, s32 yaw, s32 alphaIn, PAL_PTR* paletteList, Matrix4f mtx) {
873 s32 instanceIdx = spriteInstanceID & 0xFF;
874 s32 animID = spr_playerCurrentAnimInfo[instanceIdx].animID;
875 SpriteRasterCacheEntry** rasters;
876 PAL_PTR* palettes;
877 SpriteAnimComponent** animComponents;
878 SpriteComponent** components;
879 f32 zscale;
880 u32 alpha;
881 u32* spriteData;
882 s32 spriteId;
883 s32 spriteIdBackFacing;
884
885 if (animID == ANIM_LIST_END) {
886 return FALSE;
887 }
888
889 D_802DF57C = spriteId = ((animID >> 0x10) & 0xFF) - 1;
890 spriteData = (u32*)spr_playerSprites[spriteId];
891 if (spriteData == NULL) {
892 return FALSE;
893 }
894
895 // TODO: fake match or not?
896 rasters = (SpriteRasterCacheEntry**)*spriteData++;
897 palettes = (PAL_PTR*)*spriteData++;
898 spriteData++;
899 spriteData++;
900 animComponents = (SpriteAnimComponent**)spriteData[animID & 0xFF];
901
902 if (animID & SPRITE_ID_BACK_FACING) {
903 switch (spriteId) {
904 case 0:
905 case 5:
906 case 9:
907 spriteIdBackFacing = spriteId + 1;
908 // TODO find better match
909 rasters = (SpriteRasterCacheEntry**)spr_playerSprites[spriteIdBackFacing];
910 D_802DF57C = spriteIdBackFacing;
911 rasters = (SpriteRasterCacheEntry**)*rasters;
912 break;
913 }
914 }
915
916 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
917 yaw += (s32)-gCameras[gCurrentCamID].curYaw;
918 if (yaw > 360) {
919 yaw -= 360;
920 }
921 if (yaw < -360) {
922 yaw += 360;
923 }
924 }
925
926 if (yaw > 90 && yaw <= 270 || yaw >= -270 && yaw < -90) {
927 zscale = -1.5f;
928 } else {
929 zscale = 1.5f;
930 }
931
932 if (spriteInstanceID & DRAW_SPRITE_UPSIDE_DOWN) {
933 zscale = 0.0f - zscale;
934 }
935
936 D_802DFEA0[0] = 0;
937 D_802DFEA0[1] = yaw;
938 D_802DFEA0[2] = 0;
939
940
941 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) {
942 alpha = alphaIn & 0xFF;
943 if (alphaIn == 0) {
944 return FALSE;
945 }
946 } else {
947 alpha = 255;
948 }
949
950 components = spr_playerCurrentAnimInfo[instanceIdx].componentList;
951 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_PALETTES) {
952 palettes = paletteList;
953 }
954
955 while (*components != PTR_LIST_END) {
956 spr_draw_component(alpha | DRAW_SPRITE_USE_PLAYER_RASTERS, *components++, *animComponents, rasters, palettes, zscale, mtx);
957 if (*animComponents != PTR_LIST_END) {
958 animComponents++;
959 }
960 }
961
962 return TRUE;
963}
964
965s32 func_802DDEC4(s32 spriteIdx) {
966 return spr_playerCurrentAnimInfo[spriteIdx].notifyValue;
967}
968
969void set_player_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 flags) {
970 SpriteComponent* component;
971 SpriteComponent** componentListIt;
972 s32 i;
973
974 if (spr_playerCurrentAnimInfo[spriteIdx].componentList != NULL) {
975 componentListIt = spr_playerCurrentAnimInfo[spriteIdx].componentList;
976 i = 0;
977
978 while (*componentListIt != PTR_LIST_END) {
979 component = *componentListIt;
980 if (compIdx == -1 || i == compIdx) {
981 imgfx_update(component->imgfxIdx & 0xFF, imgfx, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, flags);
982 if (imgfx != IMGFX_CLEAR) {
983 component->imgfxIdx |= SPR_IMGFX_FLAG_10000000;
984 } else {
985 component->imgfxIdx &= ~SPR_IMGFX_FLAG_ALL;
986 }
987 }
988 componentListIt++;
989 i++;
990 }
991 }
992}
993
994// applied to all components
995void set_player_imgfx_all(s32 animID, ImgFXType imgfxType, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) {
996 set_player_imgfx_comp(PLAYER_SPRITE_MAIN, -1, imgfxType, arg2, arg3, arg4, arg5, arg6);
997}
998
999void spr_get_player_raster_info(SpriteRasterInfo* out, s32 playerSpriteID, s32 rasterIndex) {
1000 SpriteAnimData* sprite;
1002 u16** paletteOffsetCopy;
1003
1004 playerSpriteID--;
1005 sprite = spr_playerSprites[playerSpriteID];
1006 if (sprite != NULL) {
1007 paletteOffsetCopy = sprite->palettesOffset;
1008 cache = sprite->rastersOffset[rasterIndex];
1009 out->width = cache->width;
1010 out->height = cache->height;
1011 out->defaultPal = paletteOffsetCopy[cache->palette];
1012 out->raster = spr_get_player_raster(rasterIndex, playerSpriteID);
1013 }
1014}
1015
1017 SpriteAnimData* sprites = spr_playerSprites[spriteIndex - 1];
1018
1019 if (sprites == NULL) {
1020 return NULL;
1021 } else {
1022 return sprites->palettesOffset;
1023 }
1024}
1025
1026s32 spr_load_npc_sprite(s32 animID, u32* extraAnimList) {
1027 SpriteAnimData* header;
1028 SpriteComponent** compList;
1029 s32 listIndex;
1030 s32 i;
1031
1032 s32 spriteIndex = (animID >> 0x10) & 0x7FFF;
1033 s32 useTailAlloc = (u32)animID >> 0x1F;
1034
1035 for (i = 0; i < ARRAY_COUNT(SpriteInstances); i++) {
1036 if (SpriteInstances[i].spriteIndex == 0) {
1037 break;
1038 }
1039 }
1040 if (MaxLoadedSpriteInstanceID < i) {
1042 }
1043 if (i == ARRAY_COUNT(SpriteInstances)) {
1044 return -1;
1045 }
1046 listIndex = i;
1047 if (NpcSpriteData[spriteIndex] != NULL) {
1048 NpcSpriteInstanceCount[spriteIndex]++;
1049 header = NpcSpriteData[spriteIndex];
1050 SpriteInstances[listIndex].spriteData = header;
1051 } else {
1052 NpcSpriteInstanceCount[spriteIndex] = 1;
1053 header = spr_load_sprite(spriteIndex - 1, FALSE, useTailAlloc);
1054 SpriteInstances[listIndex].spriteData = header;
1055 NpcSpriteData[spriteIndex] = header;
1056 if (extraAnimList != NULL) {
1057 spr_load_npc_extra_anims(header, extraAnimList);
1058 }
1059 }
1060 compList = spr_allocate_components(header->maxComponents);
1061 SpriteInstances[listIndex].componentList = compList;
1062 while (*compList != PTR_LIST_END) {
1063 SpriteComponent* comp = *compList;
1065 compList++;
1066 }
1067 SpriteInstances[listIndex].spriteIndex = spriteIndex;
1068 SpriteInstances[listIndex].curAnimID = -1;
1069 return listIndex;
1070}
1071
1072s32 spr_update_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale) {
1073 u32* spriteData;
1074 SpriteComponent** compList;
1075 SpriteAnimComponent** animList;
1076 SpriteRasterCacheEntry** rasterList;
1077
1078 s32 palID;
1079 s32 i = spriteInstanceID & 0xFF;
1080 s32 animIndex = animID & 0xFF;
1081
1082 ASSERT_MSG(i <= MaxLoadedSpriteInstanceID, "Invalid sprite instance ID %x", spriteInstanceID);
1083
1084 compList = SpriteInstances[i].componentList;
1085 spriteData = (u32*)SpriteInstances[i].spriteData;
1086
1087 rasterList = (SpriteRasterCacheEntry**)*spriteData;
1088 spriteData += 4 + animIndex;
1089 animList = (SpriteAnimComponent**)*spriteData;
1090
1091 palID = (animID >> 8) & 0xFF;
1092 spr_set_anim_timescale(timeScale);
1093 if ((spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) || ((SpriteInstances[i].curAnimID & 0xFF) != animIndex)) {
1094 ASSERT_MSG(animList != -1, "Anim %x is not loaded", animID);
1095 spr_init_anim_state(compList, animList);
1096 SpriteInstances[i].curAnimID = (palID << 8) | animIndex;
1098 }
1099 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
1101 compList, animList, rasterList, palID);
1102 }
1103 return SpriteInstances[i].notifyValue;
1104}
1105
1106s32 spr_draw_npc_sprite(s32 spriteInstanceID, s32 yaw, s32 arg2, PAL_PTR* paletteList, Matrix4f mtx) {
1107 s32 i = spriteInstanceID & 0xFF;
1108 s32 animID = SpriteInstances[i].curAnimID;
1109 SpriteRasterCacheEntry** rasters;
1110 PAL_PTR* palettes;
1111 SpriteAnimComponent** animComponents;
1112 SpriteComponent** components;
1113 f32 zscale;
1114 u32 alpha;
1115 u32* spriteData;
1116
1117 if (animID == ANIM_LIST_END) {
1118 return FALSE;
1119 }
1120
1121 spriteData = (u32*)SpriteInstances[i].spriteData;
1122
1123 // TODO: fake match or not?
1124 rasters = (SpriteRasterCacheEntry**)*spriteData++;
1125 palettes = (PAL_PTR*)*spriteData++;
1126 spriteData++;
1127 spriteData++;
1128 animComponents = (SpriteAnimComponent**)spriteData[animID & 0xFF];
1129
1130 D_802DFEA0[0] = 0;
1131 D_802DFEA0[1] = yaw;
1132 D_802DFEA0[2] = 0;
1133
1134 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
1136 if (yaw > 360) {
1137 yaw -= 360;
1138 }
1139 if (yaw < -360) {
1140 yaw += 360;
1141 }
1142 }
1143
1144 if (yaw > 90 && yaw <= 270 || yaw >= -270 && yaw < -90) {
1145 zscale = -1.5f;
1146 } else {
1147 zscale = 1.5f;
1148 }
1149
1150 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) {
1151 alpha = arg2 & 0xFF;
1152 if (arg2 == 0) {
1153 return FALSE;
1154 }
1155 } else {
1156 alpha = 255;
1157 }
1158
1159 components = SpriteInstances[i].componentList;
1160 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_PALETTES) {
1161 palettes = paletteList;
1162 }
1163
1164 while (*components != PTR_LIST_END) {
1165 spr_draw_component(alpha, *components++, *animComponents, rasters, palettes, zscale, mtx);
1166 if (*animComponents != PTR_LIST_END) {
1167 animComponents++;
1168 }
1169 }
1170
1171 return TRUE;
1172}
1173
1174s32 spr_get_notify_value(s32 spriteIndex) {
1175 return SpriteInstances[spriteIndex].notifyValue;
1176}
1177
1178s32 spr_free_sprite(s32 spriteInstanceID) {
1179 SpriteInstance* sprite = &SpriteInstances[spriteInstanceID];
1180 SpriteAnimData* spriteData;
1181 SpriteComponent** compList;
1182 s32 spriteIndex = sprite->spriteIndex;
1183
1184 if (spriteIndex == 0 || spriteIndex >= ARRAY_COUNT(NpcSpriteData)) {
1185 return spriteInstanceID;
1186 }
1187
1188 NpcSpriteInstanceCount[spriteIndex]--;
1189 spriteData = sprite->spriteData;
1190
1191 compList = sprite->componentList;
1192 while (*compList != PTR_LIST_END) {
1193 SpriteComponent* comp = *compList;
1194 imgfx_release_instance(comp->imgfxIdx & 0xFF);
1195 compList++;
1196 }
1197
1198 compList = SpriteInstances[spriteInstanceID].componentList;
1199
1200 if (NpcSpriteInstanceCount[spriteIndex] == 0) {
1201 NpcSpriteData[spriteIndex] = NULL;
1202 _heap_free(&heap_spriteHead, spriteData);
1203 }
1204
1206 _heap_free(&heap_generalHead, compList);
1207 } else {
1208 _heap_free(&heap_spriteHead, compList);
1209 }
1210
1211 SpriteInstances[spriteInstanceID].spriteIndex = 0;
1212 SpriteInstances[spriteInstanceID].componentList = NULL;
1213 SpriteInstances[spriteInstanceID].spriteData = NULL;
1214 SpriteInstances[spriteInstanceID].curAnimID = -1;
1215 return 0;
1216}
1217
1218s32 get_npc_comp_imgfx_idx(s32 spriteIdx, s32 compIdx) {
1219 SpriteComponent** componentList = SpriteInstances[spriteIdx].componentList;
1220
1221 if (componentList == NULL) {
1222 return -1;
1223 } else {
1224 return componentList[compIdx]->imgfxIdx & 0xFF;
1225 }
1226}
1227
1228void set_npc_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5) {
1229 SpriteInstance* sprite = &SpriteInstances[spriteIdx];
1230 SpriteComponent** componentList;
1231 s32 i;
1232
1233 if (sprite->componentList != NULL) {
1234 componentList = sprite->componentList;
1235 i = 0;
1236
1237 while (*componentList != PTR_LIST_END) {
1238 SpriteComponent* comp = *componentList;
1239
1240 if (compIdx == -1 || i == compIdx) {
1241 imgfx_update((u8)comp->imgfxIdx, imgfx, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, imgfxArg5);
1242 if (imgfx != IMGFX_CLEAR) {
1244 } else {
1245 comp->imgfxIdx &= ~SPR_IMGFX_FLAG_ALL;
1246 }
1247 }
1248 componentList++;
1249 i++;
1250 }
1251 }
1252}
1253
1254void set_npc_imgfx_all(s32 spriteIdx, ImgFXType imgfxType, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5) {
1255 set_npc_imgfx_comp(spriteIdx, -1, imgfxType, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, imgfxArg5);
1256}
1257
1258s32 spr_get_comp_position(s32 spriteIdx, s32 compListIdx, s32* outX, s32* outY, s32* outZ) {
1259 SpriteInstance* sprite = &SpriteInstances[spriteIdx];
1260 SpriteAnimComponent** animCompList;
1261 SpriteAnimComponent* anim;
1262 SpriteComponent** compList;
1263 SpriteComponent* comp;
1264 u8 animID;
1265 s32 i;
1266 u32* spriteData;
1267
1268 if (sprite->componentList == NULL) {
1269 return; // bug: does not return a value
1270 }
1271
1272 animID = sprite->curAnimID;
1273 if (animID != 255) {
1274 // following 3 lines equivalent to:
1275 // animCompList = sprite->spriteData->animListStart[animID];
1276 spriteData = (u32*)sprite->spriteData;
1277 spriteData += 4 + animID;
1278 animCompList = (SpriteAnimComponent**)*spriteData;
1279 compList = sprite->componentList;
1280 i = 0;
1281 while (*compList != PTR_LIST_END) {
1282 if (i == compListIdx) {
1283 anim = *animCompList;
1284 comp = *compList;
1285 *outX = comp->compPos.x + anim->compOffset.x;
1286 *outY = comp->compPos.y + anim->compOffset.y;
1287 *outZ = comp->compPos.z + anim->compOffset.z;
1288 return 0;
1289 }
1290 i++;
1291 compList++;
1292 if (*animCompList != PTR_LIST_END) {
1293 animCompList++;
1294 }
1295 }
1296 } else {
1297 return; // bug: does not return a value
1298 }
1299 return -1;
1300}
1301
1302s32 spr_get_npc_raster_info(SpriteRasterInfo* out, s32 npcSpriteID, s32 rasterIndex) {
1303 SpriteAnimData* sprite = NpcSpriteData[npcSpriteID];
1305 PAL_PTR* paletteOffsetCopy;
1306
1307 if (sprite != NULL) {
1308 paletteOffsetCopy = sprite->palettesOffset;
1309 cache = sprite->rastersOffset[rasterIndex];
1310 out->raster = cache->image;
1311 out->width = cache->width;
1312 out->height = cache->height;
1313 out->defaultPal = paletteOffsetCopy[cache->palette];
1314 return TRUE;
1315 }
1316 return FALSE;
1317}
1318
1320 SpriteAnimData* sprite = NpcSpriteData[npcSpriteID];
1321
1322 if (sprite != NULL) {
1323 return sprite->palettesOffset;
1324 } else {
1325 return NULL;
1326 }
1327}
1328
1329s32 spr_get_npc_color_variations(s32 npcSpriteID) {
1330 SpriteAnimData* sprite = NpcSpriteData[npcSpriteID];
1331
1332 if (sprite != NULL) {
1333 return sprite->colorVariations;
1334 } else {
1335 return -1;
1336 }
1337}
IMG_PTR spr_get_player_raster(s32 rasterIndex, s32 playerSpriteID)
void spr_update_player_raster_cache(void)
SpriteAnimData * spr_load_sprite(s32 idx, s32 isPlayerSprite, s32 useTailAlloc)
Vec2b altViewportOffset
Mtx matrixStack[0x200]
#define PAL_PTR
#define IMG_PTR
f32 Matrix4f[4][4]
s8 flags
Definition demo_api.c:15
#define guRotateF
#define guMtxF2L
#define guTranslateF
#define guMtxCatF
#define guScaleF
@ SPR_SHADING_FLAG_SET_VIEWPORT
Definition enums.h:5208
@ SPR_SHADING_FLAG_ENABLED
Definition enums.h:5207
ImgFXType
Definition enums.h:5116
@ IMGFX_CLEAR
Definition enums.h:5117
@ PEACH_FLAG_IS_PEACH
Definition enums.h:2488
@ SPR_IMGFX_FLAG_ALL
Definition enums.h:5203
@ SPR_IMGFX_FLAG_10000000
Definition enums.h:5199
@ CONTEXT_PAUSE
Definition enums.h:3531
@ PLAYER_SPRITES_MARIO_WORLD
Definition enums.h:6346
@ PLAYER_SPRITES_PEACH_WORLD
Definition enums.h:6350
@ PLAYER_SPRITES_COMBINED_EPILOGUE
Definition enums.h:6348
@ PLAYER_SPRITES_MARIO_REFLECT_FLOOR
Definition enums.h:6347
@ PLAYER_SPRITES_PEACH_BATTLE
Definition enums.h:6352
@ PLAYER_SPRITES_MARIO_PARADE
Definition enums.h:6349
@ PLAYER_SPRITES_MARIO_BATTLE
Definition enums.h:6351
@ IMGFX_FLAG_80000
Definition enums.h:5112
s32 imgfx_appendGfx_component(s32, ImgFXTexture *, u32, Matrix4f)
Definition imgfx.c:704
s32 imgfx_get_free_instances(s32)
Definition imgfx.c:338
void * _heap_malloc(HeapNode *head, u32 size)
Definition 43F0.c:78
u32 _heap_free(HeapNode *heapNodeList, void *addrToFree)
Definition 43F0.c:221
void imgfx_release_instance(u32)
Definition imgfx.c:386
void imgfx_update(u32, ImgFXType, s32, s32, s32, s32, s32)
Definition imgfx.c:487
HeapNode * _heap_create(HeapNode *addr, u32 size)
Definition 43F0.c:63
#define gDPScrollMultiTile2_4b(pkt, timg, fmt, width, height, uls, ult, lrs, lrt, pal, cms, cmt, masks, maskt, shifts, shiftt, scrolls, scrollt)
Definition gbi_custom.h:6
#define gDPScrollTextureBlock_4b(pkt, timg, fmt, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt, scrolls, scrollt)
Definition gbi_custom.h:67
void imgfx_init(void)
Definition imgfx.c:243
#define PM_CC_0A
Definition macros.h:285
#define PM_CC_0C
Definition macros.h:289
#define PM_CC_0B
Definition macros.h:287
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define SPRITE_HEAP_SIZE
Definition macros.h:113
#define ASSERT_MSG(condition, msg, args...)
Definition macros.h:66
#define PM_CC_3D
Definition macros.h:406
#define PTR_LIST_END
Definition macros.h:42
#define VIRTUAL_TO_PHYSICAL(addr)
Definition macros.h:47
#define PM_CC_02
Definition macros.h:277
Quad * spr_get_cached_quad(s32 quadIndex)
Definition sprite.c:134
Quad * spr_get_quad_for_size(s32 *quadIndex, s32 width, s32 height)
Definition sprite.c:168
void spr_draw_component(s32 drawOpts, SpriteComponent *component, SpriteAnimComponent *anim, SpriteRasterCacheEntry **cache, PAL_PTR *palettes, f32 zscale, Matrix4f mtx)
Definition sprite.c:425
void spr_transform_point(s32 rotX, s32 rotY, s32 rotZ, f32 inX, f32 inY, f32 inZ, f32 *outX, f32 *outY, f32 *outZ)
Definition sprite.c:394
void spr_component_update_commands(SpriteComponent *comp, SpriteAnimComponent *anim)
Definition sprite.c:486
BSS s32 spr_allocateBtlComponentsOnWorldHeap
Definition sprite.c:9
void spr_init_quad_cache(void)
Definition sprite.c:124
void spr_make_quad_for_size(Quad *quad, s32 width, s32 height)
Definition sprite.c:141
s32 spr_draw_npc_sprite(s32 spriteInstanceID, s32 yaw, s32 arg2, PAL_PTR *paletteList, Matrix4f mtx)
Definition sprite.c:1106
void spr_get_player_raster_info(SpriteRasterInfo *out, s32 playerSpriteID, s32 rasterIndex)
Definition sprite.c:999
BSS s32 D_802DFEA0[3]
Definition sprite.c:21
void spr_init_component_anim_state(SpriteComponent *comp, SpriteAnimComponent *anim)
Definition sprite.c:714
BSS SpriteAnimData * NpcSpriteData[0xFF]
Definition sprite.c:16
BSS SpriteAnimData * spr_playerSprites[13]
Definition sprite.c:12
BSS s32 D_802DFE48[22]
Definition sprite.c:20
void spr_render_init(void)
Definition sprite.c:814
BSS s32 spr_playerMaxComponents
Definition sprite.c:14
s32 spr_update_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale)
Definition sprite.c:1072
s32 spr_free_sprite(s32 spriteInstanceID)
Definition sprite.c:1178
s32 spr_get_notify_value(s32 spriteIndex)
Definition sprite.c:1174
#define MAX_SPRITE_ID
Definition sprite.c:4
void set_npc_imgfx_all(s32 spriteIdx, ImgFXType imgfxType, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5)
Definition sprite.c:1254
s32 spr_get_npc_color_variations(s32 npcSpriteID)
Definition sprite.c:1329
Gfx D_802DF3F0[]
Definition sprite.c:49
PlayerSpriteSet spr_playerSpriteSets[]
Definition sprite.c:114
BSS Quad * D_802DFE44
Definition sprite.c:19
BSS SpriteInstance SpriteInstances[51]
Definition sprite.c:18
void spr_appendGfx_component_flat(Quad *vertices, IMG_PTR raster, PAL_PTR palette, s32 width, s32 height, f32 arg5, Matrix4f mtx, s32 alpha)
Definition sprite.c:218
void spr_set_anim_timescale(f32 timescale)
Definition sprite.c:751
void spr_appendGfx_component(SpriteRasterCacheEntry *cache, f32 dx, f32 dy, f32 dz, f32 rotX, f32 rotY, f32 rotZ, f32 scaleX, f32 scaleY, f32 scaleZ, s32 opacity, PAL_PTR palette, Matrix4f mtx)
Definition sprite.c:313
BSS u8 NpcSpriteInstanceCount[0xFF]
Definition sprite.c:17
Vp SprPauseVp
Definition sprite.c:37
s32 func_802DDA84(void)
Definition sprite.c:819
s32 spr_get_npc_raster_info(SpriteRasterInfo *out, s32 npcSpriteID, s32 rasterIndex)
Definition sprite.c:1302
Gfx D_802DF428[]
Definition sprite.c:59
void spr_load_npc_extra_anims(SpriteAnimData *, u32 *)
void spr_load_player_sprite(s32 spriteIndex)
Definition sprite.c:755
Quad spr_defaultQuad
Definition sprite.c:28
s32 spr_unpack_signed_12bit(u16 val)
Definition sprite.c:466
BSS PlayerCurrentAnimInfo spr_playerCurrentAnimInfo[3]
Definition sprite.c:15
void spr_component_update_finish(SpriteComponent *comp, SpriteComponent **compList, SpriteRasterCacheEntry **rasterCacheEntry, s32 overridePalette)
Definition sprite.c:662
void set_player_imgfx_all(s32 animID, ImgFXType imgfxType, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6)
Definition sprite.c:995
#define MARIO_SPRITE_WORLD_BITS
Definition sprite.c:93
s32 spr_unpack_signed_16bit(u16 val)
Definition sprite.c:476
void spr_init_sprites(s32 playerSpriteSet)
Definition sprite.c:764
HeapNode heap_generalHead
Definition heaps3.c:3
Gfx D_802DF490[]
Definition sprite.c:78
s32 spr_component_update(s32 curNotifyValue, SpriteComponent **compList, SpriteAnimComponent **animList, SpriteRasterCacheEntry **rasterCache, s32 overridePalette)
Definition sprite.c:692
PAL_PTR * spr_get_npc_palettes(s32 npcSpriteID)
Definition sprite.c:1319
#define MARIO_SPRITE_BATTLE_BITS
Definition sprite.c:100
SpriteComponent ** spr_allocate_components(s32)
s32 spr_get_comp_position(s32 spriteIdx, s32 compListIdx, s32 *outX, s32 *outY, s32 *outZ)
Definition sprite.c:1258
BSS s32 SpriteUpdateNotifyValue
Definition sprite.c:22
HeapNode heap_spriteHead
Definition heaps3.c:4
s32 func_802DDEC4(s32 spriteIdx)
Definition sprite.c:965
f32 spr_animUpdateTimeScale
Definition sprite.c:87
BSS s32 D_802DF540
Definition sprite.c:11
s32 spr_load_npc_sprite(s32 animID, u32 *extraAnimList)
Definition sprite.c:1026
s32 spr_draw_player_sprite(s32 spriteInstanceID, s32 yaw, s32 alphaIn, PAL_PTR *paletteList, Matrix4f mtx)
Definition sprite.c:872
void set_npc_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5)
Definition sprite.c:1228
void spr_clear_quad_cache(void)
Definition sprite.c:205
PAL_PTR * spr_get_player_palettes(s32 spriteIndex)
Definition sprite.c:1016
void spr_init_anim_state(SpriteComponent **compList, SpriteAnimComponent **animList)
Definition sprite.c:741
#define MARIO_SPRITE_COMMON_BITS
Definition sprite.c:89
BSS s32 D_802DF57C
Definition sprite.c:13
#define PEACH_SPRITE_BITS
Definition sprite.c:106
Gfx D_802DF460[]
Definition sprite.c:69
s32 spr_update_player_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale)
Definition sprite.c:823
s32 get_npc_comp_imgfx_idx(s32 spriteIdx, s32 compIdx)
Definition sprite.c:1218
void set_player_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 flags)
Definition sprite.c:969
Vp SprPauseVpAlt
Definition sprite.c:43
BSS s32 MaxLoadedSpriteInstanceID
Definition sprite.c:10
void spr_init_player_raster_cache(s32 cacheSize, s32 maxRasterSize)
Vec3f posOffset
Definition sprite.h:45
SpriteAnimData * spriteData
Definition sprite.h:85
s32 spriteIndex
Definition sprite.h:83
Vec3f compPos
Definition sprite.h:46
s32 properties
AABBCCCC : AA = unused?, BB = parent, CCCC = notify value.
Definition sprite.h:39
void create_shading_palette(Matrix4f mtx, s32 uls, s32 ult, s32 lrs, s32 lrt, s32 alpha, s32)
s16 * readPos
Definition sprite.h:40
SpriteRasterCacheEntry ** rastersOffset
Definition sprite.h:75
s32 curAnimID
Definition sprite.h:86
@ PLAYER_SPRITE_MAIN
Definition sprite.h:26
SpriteComponent ** componentList
Definition sprite.h:84
@ DRAW_SPRITE_OVERRIDE_YAW
Definition sprite.h:21
@ DRAW_SPRITE_OVERRIDE_ALPHA
Definition sprite.h:22
@ DRAW_SPRITE_OVERRIDE_PALETTES
Definition sprite.h:20
@ DRAW_SPRITE_UPSIDE_DOWN
Definition sprite.h:19
@ DRAW_SPRITE_USE_PLAYER_RASTERS
Definition sprite.h:18
s32 initialized
Definition sprite.h:38
Vtx v[4]
Definition sprite.h:116
SpriteComponent ** componentList
Definition sprite.h:53
s32 loopCounter
Definition sprite.h:42
PAL_PTR * palettesOffset
Definition sprite.h:76
s32 notifyValue
Definition sprite.h:87
Vec3f scale
Definition sprite.h:48
@ SPRITE_ID_BACK_FACING
Definition sprite.h:13
s32 colorVariations
Definition sprite.h:78
s32 maxComponents
Definition sprite.h:77
Definition sprite.h:115
Sprite data header.
Definition sprite.h:74
#define ANIM_LIST_END
Terminates an extraAnimationList.
Definition types.h:22
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
u16 gMatrixListPos
Definition main_loop.c:45
SpriteShadingProfile * gSpriteShadingProfile
DisplayContext * gDisplayContext
Definition cam_main.c:16
s16 gCurrentCamID
Definition cam_main.c:13