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// perhaps extend to 0x200 and change animID fields for dx from SSSSPPAA --> SSSPPAAA
5#define MAX_SPRITE_ID 0xFF
6
9
21BSS s32 SpriteQuadCacheInfo[22]; // upper bytes: width, height; lower 16 bits: time left
24
28
30 {
31 {{{ -16, 56, 0 }, FALSE, { 0, 0 }, { 240, 240, 240, 255 }}},
32 {{{ 16, 56, 0 }, FALSE, { 1024, 0 }, { 120, 120, 120, 255 }}},
33 {{{ 16, 0, 0 }, FALSE, { 1024, 1792 }, { 0, 0, 0, 255 }}},
34 {{{ -16, 0, 0 }, FALSE, { 0, 1792 }, { 120, 120, 120, 255 }}},
35 }
36};
37
39 { 640, 480, 511, 0 },
40 { 640, 480, 511, 0 },
41 }
42};
43
45 { 640, 480, 511, 0 },
46 { 640, 480, 512, 0 },
47 }
48};
49
59
69
78
87
89
90#define MARIO_SPRITE_COMMON_BITS \
91 1 << SPR_Mario1 \
92 | 1 << SPR_Mario1_Back \
93
94#define MARIO_SPRITE_WORLD_BITS \
95 MARIO_SPRITE_COMMON_BITS \
96 | 1 << SPR_MarioW1 \
97 | 1 << SPR_MarioW1_Back \
98 | 1 << SPR_MarioW2 \
99 | 1 << SPR_MarioW3
100
101#define MARIO_SPRITE_BATTLE_BITS \
102 MARIO_SPRITE_COMMON_BITS \
103 | 1 << SPR_MarioB1 \
104 | 1 << SPR_MarioB2 \
105 | 1 << SPR_MarioB3
106
107#define PEACH_SPRITE_BITS \
108 1 << SPR_Peach1 \
109 | 1 << SPR_Peach1_Back \
110 | 1 << SPR_Peach2 \
111 | 1 << SPR_Peach3 \
112
113// TODO(player raster splat header generation):
114// - macroify rasterSize based on the biggest raster
124
126 s32 i;
127
129
130 for (i = 0; i < ARRAY_COUNT(SpriteQuadCacheInfo); i++) {
131 SpriteQuadCacheInfo[i] = -1;
132 }
133}
134
137
138 *quadInfo |= 0x1F; // reset life timer
139 return &SpriteQuadCache[quadIndex];
140}
141
142void spr_make_quad_for_size(Quad* quad, s32 width, s32 height) {
143 Vtx* vtx = &quad->v[0];
144
146
147 vtx->v.ob[0] = -width / 2;
148 vtx->v.ob[1] = height;
149 vtx->v.tc[0] = 0x2000;
150 vtx->v.tc[1] = 0x2000;
151
152 vtx++;
153 vtx->v.ob[0] = width / 2;
154 vtx->v.ob[1] = height;
155 vtx->v.tc[0] = (width + 256) * 32;
156 vtx->v.tc[1] = 0x2000;
157
158 vtx++;
159 vtx->v.tc[0] = (width + 256) * 32;
160 vtx->v.ob[0] = width / 2;
161 vtx->v.tc[1] = (height + 256) * 32;
162
163 vtx++;
164 vtx->v.ob[0] = -width / 2;
165 vtx->v.tc[0] = 0x2000;
166 vtx->v.tc[1] = (height + 256) * 32;
167}
168
170 Quad* quad;
171 s32 qi;
173 s32 i;
174
175 if ((width * height) / 2 <= 0x800) {
176 dimensions = (width << 0x18) + (height << 0x10);
177 qi = *quadIndex;
178 if (qi != -1 && (dimensions == (SpriteQuadCacheInfo[qi] & 0xFFFF0000))) {
179 return spr_get_cached_quad(qi);
180 }
181
182 for (i = 0; i < ARRAY_COUNT(SpriteQuadCacheInfo); i++) {
183 if (dimensions == (SpriteQuadCacheInfo[i] & 0xFFFF0000)) {
184 *quadIndex = i;
185 return spr_get_cached_quad(i);
186 }
187 }
188
189 for (i = 0; i < ARRAY_COUNT(SpriteQuadCacheInfo); i++) {
190 if (SpriteQuadCacheInfo[i] == -1) {
191 break;
192 }
193 }
194
196 *quadIndex = i;
199 spr_make_quad_for_size(quad, width, height);
200 return quad;
201 }
202 }
203 return NULL;
204}
205
207 s32 i;
208
209 for (i = 0; i < ARRAY_COUNT(SpriteQuadCacheInfo); i++) {
210 if (SpriteQuadCacheInfo[i] != -1) {
212 if ((SpriteQuadCacheInfo[i] & 0xFFFF) == 0) {
213 SpriteQuadCacheInfo[i] = -1;
214 }
215 }
216 }
217}
218
220 Quad* vertices,
221 IMG_PTR raster, PAL_PTR palette,
222 s32 width, s32 height,
223 f32 arg5,
224 Matrix4f mtx,
225 s32 alpha
226) {
227 gDPLoadTLUT_pal16(gMainGfxPos++, 0, palette);
229 gDPScrollMultiTile2_4b(gMainGfxPos++, raster, G_IM_FMT_CI, width, height,
230 0, 0, width - 1, height - 1, 0,
232 256, 256);
234 gDPSetTileSize(gMainGfxPos++, 2, 0, 0, 63 << 2, 0);
239 } else {
240 gSPViewport(gMainGfxPos++, &camera->vpAlt);
241 }
242
243 if (alpha == 255) {
247 } else {
249 }
250
251 gDPSetEnvColor(gMainGfxPos++, 0, 0, 0, alpha);
253 gSPVertex(gMainGfxPos++, vertices, 4, 0);
254 gSP2Triangles(gMainGfxPos++, 0, 2, 1, 0, 0, 3, 2, 0);
256 }
257 create_shading_palette(mtx, 0, 0, width, height, alpha, alpha == 255 ? 0x111238 : 0x104B50); // TODO make macro for render mode
258 } else {
259 gDPScrollTextureBlock_4b(gMainGfxPos++, raster, G_IM_FMT_CI, width, height, 0,
261 256, 256);
266 } else {
267 gSPViewport(gMainGfxPos++, &camera->vpAlt);
268 }
269 if (alpha == 255) {
271 } else {
273 }
274
275 gDPSetEnvColor(gMainGfxPos++, 0, 0, 0, alpha);
277 gSPVertex(gMainGfxPos++, vertices, 4, 0);
278 gSP2Triangles(gMainGfxPos++, 0, 2, 1, 0, 0, 3, 2, 0);
280
281 if (alpha == 255) {
286 } else {
288 }
289
290 gDPSetEnvColor(gMainGfxPos++, 100, 100, 100, 255);
291 gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, alpha);
294 }
295 }
296
299
302 SpritePauseVpAlt.vp.vtrans[0] = SpritePauseVp.vp.vtrans[0] + gGameStatusPtr->altViewportOffset.x;
303 SpritePauseVpAlt.vp.vtrans[1] = SpritePauseVp.vp.vtrans[1] + gGameStatusPtr->altViewportOffset.y;
304 } else {
306 }
307 }
308
309 gSPVertex(gMainGfxPos++, vertices, 4, 0);
310 gSP2Triangles(gMainGfxPos++, 0, 2, 1, 0, 0, 3, 2, 0);
312}
313
316 f32 dx, f32 dy, f32 dz,
317 f32 rotX, f32 rotY, f32 rotZ,
318 f32 scaleX, f32 scaleY, f32 scaleZ,
319 s32 opacity, PAL_PTR palette, Matrix4f mtx)
320{
325 Quad* quad;
326 s32 width;
327 s32 height;
328
331
332 if (rotY != 0.0f) {
333 guRotateF(mtxTemp, rotY, 0.0f, 1.0f, 0.0f);
335 }
336 if (rotZ != 0.0f) {
337 guRotateF(mtxTemp, rotZ, 0.0f, 0.0f, 1.0f);
339 }
340 if (rotX != 0.0f) {
341 guRotateF(mtxTemp, rotX, 1.0f, 0.0f, 0.0f);
343 }
344
345 if (scaleX != 1.0f || scaleY != 1.0f || scaleZ != 1.0f) {
346 guScaleF(mtxTemp, scaleX, scaleY, scaleZ);
348 }
349
353
355 if ((u8) opacity == 255) {
357 } else {
359 }
360 } else {
361 if ((u8) opacity == 255) {
363 } else {
364 gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, (u8) opacity);
366 }
367 }
368
369 width = cache->width;
370 height = cache->height;
371 quadIndex = cache->quadCacheIndex;
372 quad = NULL;
374 quad = spr_get_quad_for_size(&quadIndex, width, height);
375 cache->quadCacheIndex = quadIndex;
376 }
377
378 if (quad != NULL) {
379 spr_appendGfx_component_flat(quad, cache->image, palette, width, height, rotY, mtxTransform, (u8) opacity);
380 } else {
381 ifxImg.raster = cache->image;
382 ifxImg.palette = palette;
383 ifxImg.width = width;
384 ifxImg.height = height;
385 ifxImg.xOffset = -(width / 2);
386 ifxImg.yOffset = height;
387 ifxImg.alpha = opacity;
390 }
391 }
393}
394
395void spr_transform_point(s32 rotX, s32 rotY, s32 rotZ, f32 inX, f32 inY, f32 inZ, f32* outX, f32* outY, f32* outZ) {
396 if (rotX == 0 && rotY == 0 && rotZ == 0) {
397 *outX = inX;
398 *outY = inY;
399 *outZ = inZ;
400 } else {
402 f32 xx, yx, zx, xy, yy, zy, xz, yz, zz;
403
404 guRotateF(mtxTransform, rotY, 0.0f, 1.0f, 0.0f);
405 guRotateF(mtxTemp, rotZ, 0.0f, 0.0f, 1.0f);
407 guRotateF(mtxTemp, rotX, 1.0f, 0.0f, 0.0f);
409
410 xx = (mtxTransform[0][0] * inX);
411 yx = (mtxTransform[1][0] * inY);
412 zx = (mtxTransform[2][0] * inZ);
413 xy = (mtxTransform[0][1] * inX);
414 yy = (mtxTransform[1][1] * inY);
415 zy = (mtxTransform[2][1] * inZ);
416 xz = (mtxTransform[0][2] * inX);
417 yz = (mtxTransform[1][2] * inY);
418 zz = (mtxTransform[2][2] * inZ);
419
420 *outX = xx + yx + zx;
421 *outY = xy + yy + zy;
422 *outZ = xz + yz + zz;
423 }
424}
425
430 PAL_PTR pal;
431 f32 dx, dy, dz;
432 f32 rotX, rotY, rotZ;
433 f32 inX, inY, inZ;
434
435 if (component->initialized && component->curRaster != -1) {
436 rotX = SpriteCurBaseRot[0];
437 rotY = SpriteCurBaseRot[1];
438 rotZ = SpriteCurBaseRot[2];
439 inX = component->compPos.x + anim->compOffset.x;
440 inY = component->compPos.y + anim->compOffset.y;
441 inZ = component->compPos.z + anim->compOffset.z;
442
443 spr_transform_point(rotX, rotY, rotZ, inX, inY, inZ * zscale, &dx, &dy, &dz);
444 cacheEntry = cache[component->curRaster];
445 paletteIdx = component->curPalette;
448 }
449 CurSpriteImgFX = component->imgfxIdx;
451
454 dx, dy, dz,
455 rotX + component->rot.x,
456 rotY + component->rot.y,
457 rotZ + component->rot.z,
458 component->scale.x,
459 component->scale.y,
460 component->scale.z,
461 drawOpts, pal, mtx
462 );
463 component->imgfxIdx = CurSpriteImgFX;
464 }
465}
466
468 s32 temp = val & 0xFFF;
469
470 if (temp & 0x800) {
471 return temp | ~0xFFF;
472 } else {
473 return temp;
474 }
475}
476
478 s32 temp = val & 0xFFFF;
479
480 if (temp & 0x8000) {
481 return temp | ~0xFFFF;
482 } else {
483 return temp;
484 }
485}
486
488 f32 posX, posY, posZ;
489 f32 rotX, rotY, rotZ;
490 f32 scaleX, scaleY, scaleZ;
492
493 u16* bufPos;
494 u16* gotoPos;
496
497 if (comp->initialized) {
498 scaleZ = 1.0f;
499 scaleY = 1.0f;
500 scaleX = 1.0f;
501 changedFlags = 0;
502
503 bufPos = comp->readPos;
504 gotoPos = (u16*) -1;
505
506 comp->waitTime -= SpriteAnimUpdateTimescale;
507
508 while (comp->waitTime <= 0.0f) {
509 // overflow check
510 if (bufPos >= &anim->cmdList[anim->cmdListSize / 2]) {
511 bufPos = anim->cmdList;
512 break;
513 }
514
515 switch (*bufPos & 0xF000) {
516 // 0VVV
517 // Wait
518 case 0x0000:
519 comp->waitTime = *bufPos++ & 0xFFF;
520 if (comp->waitTime == 0.0f) {
521 comp->waitTime = 4095.0f;
522 }
523 comp->posOffset.z = 0.0f;
524 comp->posOffset.y = 0.0f;
525 comp->posOffset.x = 0.0f;
526 comp->rot.z = 0;
527 comp->rot.y = 0;
528 comp->rot.x = 0;
529 comp->scale.z = 1.0f;
530 comp->scale.y = 1.0f;
531 comp->scale.x = 1.0f;
532 break;
533 // 2VVV
534 // Goto -- jump to another position in the list
535 case 0x2000:
537 if (bufPos == gotoPos) {
538 bufPos = anim->cmdList;
539 comp->waitTime = 1.0f;
540 }
541 gotoPos = bufPos;
542 break;
543 // 1VVV
544 // SetImage -- FFF is valid value for "no image"
545 case 0x1000:
546 cmdValue = *bufPos++ & 0xFFF;
547 if (cmdValue != 0xFFF) {
548 comp->curRaster = cmdValue;
549 } else {
550 comp->curRaster = -1;
551 }
552 comp->curPalette = -1;
553 break;
554 // 6VVV
555 // SetPalette -- FFF to clear
556 case 0x6000:
557 cmdValue = *bufPos++ & 0xFFF;
558 if (cmdValue != 0xFFF) {
559 comp->curPalette = cmdValue;
560 } else {
561 comp->curPalette = -1;
562 }
563 break;
564 // 8VUU
565 // SetProperty
566 // 81-XX parent to component XX
567 // 82-YY set notify value to YY
568 case 0x8000:
569 cmdValue = *bufPos++;
570 switch (cmdValue & 0xF00) {
571 case 0x100: // set parent
572 comp->properties = (comp->properties & 0xFFFF0000) | cmdValue;
573 break;
574 case 0x200: // set notify value
576 comp->properties = (comp->properties & 0xFF00FFFF) | (SpriteUpdateNotifyValue << 0x10);
577 break;
578 }
579 break;
580 // 3VVV XXXX YYYY ZZZZ
581 // SetPosition -- what does the flag do?
582 case 0x3000:
583 switch (*bufPos++ & 0xF) {
584 case 0:
585 case 1:
589 changedFlags |= 1;
590 break;
591 }
592 break;
593 // 4XXX YYYY ZZZZ
594 // SetRotation (euler angles)
595 case 0x4000:
599 changedFlags |= 2;
600 break;
601 // 5VVV UUUU
602 // SetScale (%)
603 case 0x5000:
604 switch (*bufPos++ & 0xF) {
605 case 0:
606 scaleZ = *bufPos++ / 100.0f;
607 scaleY = scaleZ;
608 scaleX = scaleZ;
609 break;
610 case 1:
611 scaleX = *bufPos++ / 100.0f;
612 break;
613 case 2:
614 scaleY = *bufPos++ / 100.0f;
615 break;
616 case 3:
617 scaleZ = *bufPos++ / 100.0f;
618 break;
619 }
620 changedFlags |= 4;
621 break;
622 // 7VVV UUUU
623 // Loop -- VV iterations jumping back to UUUU
624 case 0x7000:
625 if (comp->loopCounter != 0) {
626 comp->loopCounter--;
627 if (comp->loopCounter == 0) {
628 bufPos += 2;
629 break;
630 }
631 } else {
632 comp->loopCounter = bufPos[1];
633 }
635 break;
636 // invalid command
637 default:
638 bufPos = anim->cmdList;
639 comp->waitTime = 1.0f;
640 break;
641 }
642 } // end loop
643
644 comp->readPos = bufPos;
645 if (changedFlags & 1) {
646 comp->posOffset.x = posX;
647 comp->posOffset.y = posY;
648 comp->posOffset.z = posZ;
649 }
650 if (changedFlags & 2) {
651 comp->rot.x = rotX;
652 comp->rot.y = rotY;
653 comp->rot.z = rotZ;
654 }
655 if (changedFlags & 4) {
656 comp->scale.x = scaleX;
657 comp->scale.y = scaleY;
658 comp->scale.z = scaleZ;
659 }
660 }
661}
662
665{
668
669 if (comp->initialized) {
670 comp->compPos.x = comp->posOffset.x;
671 comp->compPos.y = comp->posOffset.y;
672 comp->compPos.z = comp->posOffset.z;
673
674 if ((comp->properties & 0xF00) == 0x100) {
675 listComp = compList[comp->properties & 0xFF];
676 comp->compPos.x += listComp->compPos.x;
677 comp->compPos.y += listComp->compPos.y;
678 comp->compPos.z += listComp->compPos.z;
679 }
680
681 if (comp->curRaster != -1) {
682 cache = rasterCacheEntry[comp->curRaster];
683 if (comp->curPalette == -1) {
684 comp->curPalette = cache->palette;
685 if (overridePalette != 0 && comp->curPalette == 0) {
686 comp->curPalette = overridePalette;
687 }
688 }
689 }
690 }
691}
692
714
716 if (anim == PTR_LIST_END) {
717 comp->initialized = FALSE;
718 return;
719 }
720
721 comp->initialized = TRUE;
722 comp->properties = 0;
723 comp->readPos = anim->cmdList;
724 comp->waitTime = 0;
725 comp->loopCounter = 0;
726 comp->curRaster = -1;
727 comp->curPalette = -1;
728 comp->posOffset.x = 0.0f;
729 comp->posOffset.y = 0.0f;
730 comp->posOffset.z = 0.0f;
731 comp->compPos.x = 0.0f;
732 comp->compPos.y = 0.0f;
733 comp->compPos.z = 0.0f;
734 comp->rot.x = 0.0f;
735 comp->rot.y = 0.0f;
736 comp->rot.z = 0.0f;
737 comp->scale.x = 1.0f;
738 comp->scale.y = 1.0f;
739 comp->scale.z = 1.0f;
740}
741
743 while (*compList != PTR_LIST_END) {
746 if (*animList != PTR_LIST_END) {
747 animList++;
748 }
749 }
750}
751
755
756void spr_load_player_sprite(s32 spriteIndex) {
758
759 PlayerSprites[spriteIndex - 1] = playerSprite;
762 }
763}
764
765void spr_init_sprites(s32 playerSpriteSet) {
767 s32 i;
768
771 imgfx_init();
772
773 for (i = 0; i < ARRAY_COUNT(PlayerSprites); i++) {
775 playerSprites[i] = 0;
776 }
777
779
781 playerSpriteSet = PLAYER_SPRITES_PEACH_WORLD;
782 }
783
784 loadedFlags = (&PlayerSpriteSets[playerSpriteSet])->initiallyLoaded;
785 spr_init_player_raster_cache((&PlayerSpriteSets[playerSpriteSet])->cacheSize,
786 (&PlayerSpriteSets[playerSpriteSet])->rasterSize);
787
788 for (i = 1; i <= SPR_Peach3; i++) {
789 if ((loadedFlags >> i) & 1) {
791 }
792 }
793
794 for (i = 0; i < ARRAY_COUNT(CurPlayerAnimInfo); i++) {
797 }
798
799 for (i = 0; i < ARRAY_COUNT(NpcSpriteData); i++) {
800 NpcSpriteData[i] = NULL;
802 }
803
804 for (i = 0; i < ARRAY_COUNT(SpriteInstances); i++) {
810 }
811
813}
814
819
820s32 spr_update_player_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale) {
821 SpriteAnimData* spriteData;
824 SpriteAnimComponent** animList;
826 s32 spriteID = SPR_UNPACK_SPR(animID);
827 s32 instanceIdx = spriteInstanceID & 0xFF;
829
830 if (CurPlayerAnimInfo[instanceIdx].componentList == NULL) {
833 while (*compList != PTR_LIST_END) {
836 compList++;
837 }
838 }
839
842
843 if (spriteData == NULL) {
844 return 0;
845 }
846
847 rasterList = spriteData->rastersOffset;
848 animList = spriteData->animListStart[SPR_UNPACK_ANIM(animID)];
849
850 spr_set_anim_timescale(timeScale);
851 if ((spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) ||
853 {
854 spr_init_anim_state(compList, animList);
856 }
857
859
860 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
862 compList, animList, rasterList, 0);
863 }
865}
866
868 SpriteAnimData* spriteData;
870 SpriteAnimComponent** animList;
873 f32 zscale;
874 u32 alpha;
876 s32 instanceIdx = spriteInstanceID & 0xFF;
878
879 if (animID == ANIM_LIST_END) {
880 return FALSE;
881 }
882
883 spriteID = SPR_UNPACK_SPR(animID);
885
887 if (spriteData == NULL) {
888 return FALSE;
889 }
890
891 rasterList = spriteData->rastersOffset;
892 palettes = spriteData->palettesOffset;
893 animList = spriteData->animListStart[SPR_UNPACK_ANIM(animID)];
894
895 if (animID & SPRITE_ID_BACK_FACING) {
896 switch (spriteID) {
897 case SPR_Mario1:
898 case SPR_MarioW1:
899 case SPR_Peach1:
900 CurPlayerSpriteIndex++; // use the following sprite index if using back sprite
902 break;
903 }
904 }
905
906 if (yaw > 90 && yaw <= 270 || yaw >= -270 && yaw < -90) {
907 zscale = -1.5f;
908 } else {
909 zscale = 1.5f;
910 }
911
912 if (spriteInstanceID & DRAW_SPRITE_UPSIDE_DOWN) {
913 zscale = -zscale;
914 }
915
916 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
918 if (yaw > 360) {
919 yaw -= 360;
920 }
921 if (yaw < -360) {
922 yaw += 360;
923 }
924 }
925
926 SpriteCurBaseRot[0] = 0;
927 SpriteCurBaseRot[1] = yaw;
928 SpriteCurBaseRot[2] = 0;
929
930 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) {
931 alpha = alphaIn & 0xFF;
932 if (alphaIn == 0) {
933 return FALSE;
934 }
935 } else {
936 alpha = 255;
937 }
938
940 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_PALETTES) {
942 }
943
944 while (*compList != PTR_LIST_END) {
946 if (*animList != PTR_LIST_END) {
947 animList++;
948 }
949 }
950
951 return TRUE;
952}
953
957
958void set_player_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 flags) {
961 s32 i;
962
963 if (CurPlayerAnimInfo[spriteIdx].componentList != NULL) {
965 i = 0;
966
967 while (*componentListIt != PTR_LIST_END) {
969 if (compIdx == -1 || i == compIdx) {
970 imgfx_update(component->imgfxIdx & 0xFF, imgfx, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, flags);
971 if (imgfx != IMGFX_CLEAR) {
973 } else {
974 component->imgfxIdx &= ~SPR_IMGFX_FLAG_ALL;
975 }
976 }
978 i++;
979 }
980 }
981}
982
983// applied to all components
984void set_player_imgfx_all(s32 animID, ImgFXType imgfxType, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) {
985 set_player_imgfx_comp(PLAYER_SPRITE_MAIN, -1, imgfxType, arg2, arg3, arg4, arg5, arg6);
986}
987
992
995 if (sprite != NULL) {
997 cache = sprite->rastersOffset[rasterIndex];
998 out->width = cache->width;
999 out->height = cache->height;
1000 out->defaultPal = paletteOffsetCopy[cache->palette];
1001 out->raster = spr_get_player_raster(rasterIndex, playerSpriteID);
1002 }
1003}
1004
1006 SpriteAnimData* sprites = PlayerSprites[spriteIndex - 1];
1007
1008 if (sprites == NULL) {
1009 return NULL;
1010 } else {
1011 return sprites->palettesOffset;
1012 }
1013}
1014
1015s32 spr_load_npc_sprite(s32 animID, u32* extraAnimList) {
1016 SpriteAnimData* header;
1018 s32 listIndex;
1019 s32 i;
1020
1021 s32 spriteIndex = (animID >> 0x10) & 0x7FFF;
1022 s32 useTailAlloc = (u32)animID >> 0x1F;
1023
1024 for (i = 0; i < ARRAY_COUNT(SpriteInstances); i++) {
1025 if (SpriteInstances[i].spriteIndex == 0) {
1026 break;
1027 }
1028 }
1029 if (MaxLoadedSpriteInstanceID < i) {
1031 }
1032 if (i == ARRAY_COUNT(SpriteInstances)) {
1033 return -1;
1034 }
1035 listIndex = i;
1036 if (NpcSpriteData[spriteIndex] != NULL) {
1037 NpcSpriteInstanceCount[spriteIndex]++;
1038 header = NpcSpriteData[spriteIndex];
1039 SpriteInstances[listIndex].spriteData = header;
1040 } else {
1041 NpcSpriteInstanceCount[spriteIndex] = 1;
1042 header = spr_load_sprite(spriteIndex - 1, FALSE, useTailAlloc);
1043 SpriteInstances[listIndex].spriteData = header;
1044 NpcSpriteData[spriteIndex] = header;
1045 if (extraAnimList != NULL) {
1046 spr_load_npc_extra_anims(header, extraAnimList);
1047 }
1048 }
1051 while (*compList != PTR_LIST_END) {
1054 compList++;
1055 }
1056 SpriteInstances[listIndex].spriteIndex = spriteIndex;
1057 SpriteInstances[listIndex].curAnimID = -1;
1058 return listIndex;
1059}
1060
1061s32 spr_update_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale) {
1062 SpriteAnimData* spriteData;
1064 SpriteAnimComponent** animList;
1066
1067 s32 palID;
1068 s32 i = spriteInstanceID & 0xFF;
1069 s32 animIndex = SPR_UNPACK_ANIM(animID);
1070
1071 ASSERT_MSG(i <= MaxLoadedSpriteInstanceID, "Invalid sprite instance ID %x", spriteInstanceID);
1072
1074 spriteData = SpriteInstances[i].spriteData;
1075
1076 rasterList = spriteData->rastersOffset;
1077 animList = spriteData->animListStart[animIndex];
1078
1079 palID = SPR_UNPACK_PAL(animID);
1080 spr_set_anim_timescale(timeScale);
1081 if ((spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) || (SPR_UNPACK_ANIM(SpriteInstances[i].curAnimID) != animIndex)) {
1082 ASSERT_MSG(animList != -1, "Anim %lx is not loaded", animID);
1083 spr_init_anim_state(compList, animList);
1086 }
1087 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
1089 compList, animList, rasterList, palID);
1090 }
1091 return SpriteInstances[i].notifyValue;
1092}
1093
1095 SpriteAnimData* spriteData;
1098 SpriteRasterCacheEntry** rasters;
1100 f32 zscale;
1101 u32 alpha;
1102 s32 instanceIdx = spriteInstanceID & 0xFF;
1104
1105 if (animID == ANIM_LIST_END) {
1106 return FALSE;
1107 }
1108
1110 rasters = spriteData->rastersOffset;
1111 palettes = spriteData->palettesOffset;
1112 animComps = spriteData->animListStart[SPR_UNPACK_ANIM(animID)];
1113
1114 SpriteCurBaseRot[0] = 0;
1115 SpriteCurBaseRot[1] = yaw;
1116 SpriteCurBaseRot[2] = 0;
1117
1118 if (!(spriteInstanceID & DRAW_SPRITE_OVERRIDE_YAW)) {
1120 if (yaw > 360) {
1121 yaw -= 360;
1122 }
1123 if (yaw < -360) {
1124 yaw += 360;
1125 }
1126 }
1127
1128 if (yaw > 90 && yaw <= 270 || yaw >= -270 && yaw < -90) {
1129 zscale = -1.5f;
1130 } else {
1131 zscale = 1.5f;
1132 }
1133
1134 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_ALPHA) {
1135 alpha = alphaIn & 0xFF;
1136 if (alphaIn == 0) {
1137 return FALSE;
1138 }
1139 } else {
1140 alpha = 255;
1141 }
1142
1144 if (spriteInstanceID & DRAW_SPRITE_OVERRIDE_PALETTES) {
1146 }
1147
1148 while (*components != PTR_LIST_END) {
1149 spr_draw_component(alpha, *components++, *animComps, rasters, palettes, zscale, mtx);
1150 if (*animComps != PTR_LIST_END) {
1151 animComps++;
1152 }
1153 }
1154
1155 return TRUE;
1156}
1157
1158s32 spr_get_notify_value(s32 spriteInstanceID) {
1159 return SpriteInstances[spriteInstanceID].notifyValue;
1160}
1161
1162s32 spr_free_sprite(s32 spriteInstanceID) {
1163 SpriteInstance* sprite = &SpriteInstances[spriteInstanceID];
1164 SpriteAnimData* spriteData;
1166 s32 spriteIndex = sprite->spriteIndex;
1167
1168 if (spriteIndex == 0 || spriteIndex >= ARRAY_COUNT(NpcSpriteData)) {
1169 return spriteInstanceID;
1170 }
1171
1172 NpcSpriteInstanceCount[spriteIndex]--;
1173 spriteData = sprite->spriteData;
1174
1175 compList = sprite->componentList;
1176 while (*compList != PTR_LIST_END) {
1178 imgfx_release_instance(comp->imgfxIdx & 0xFF);
1179 compList++;
1180 }
1181
1182 compList = SpriteInstances[spriteInstanceID].componentList;
1183
1184 if (NpcSpriteInstanceCount[spriteIndex] == 0) {
1185 NpcSpriteData[spriteIndex] = NULL;
1186 _heap_free(&heap_spriteHead, spriteData);
1187 }
1188
1191 } else {
1193 }
1194
1195 SpriteInstances[spriteInstanceID].spriteIndex = 0;
1196 SpriteInstances[spriteInstanceID].componentList = NULL;
1197 SpriteInstances[spriteInstanceID].spriteData = NULL;
1198 SpriteInstances[spriteInstanceID].curAnimID = -1;
1199 return 0;
1200}
1201
1204
1205 if (componentList == NULL) {
1206 return -1;
1207 } else {
1208 return componentList[compIdx]->imgfxIdx & 0xFF;
1209 }
1210}
1211
1212void set_npc_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5) {
1214 SpriteComponent** componentList;
1215 s32 i;
1216
1217 if (sprite->componentList != NULL) {
1218 componentList = sprite->componentList;
1219 i = 0;
1220
1221 while (*componentList != PTR_LIST_END) {
1222 SpriteComponent* comp = *componentList;
1223
1224 if (compIdx == -1 || i == compIdx) {
1225 imgfx_update((u8)comp->imgfxIdx, imgfx, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, imgfxArg5);
1226 if (imgfx != IMGFX_CLEAR) {
1227 comp->imgfxIdx |= SPR_IMGFX_FLAG_10000000;
1228 } else {
1229 comp->imgfxIdx &= ~SPR_IMGFX_FLAG_ALL;
1230 }
1231 }
1232 componentList++;
1233 i++;
1234 }
1235 }
1236}
1237
1238void set_npc_imgfx_all(s32 spriteIdx, ImgFXType imgfxType, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5) {
1239 set_npc_imgfx_comp(spriteIdx, -1, imgfxType, imgfxArg1, imgfxArg2, imgfxArg3, imgfxArg4, imgfxArg5);
1240}
1241
1248 u8 animID;
1249 s32 i;
1250
1251 if (sprite->componentList == NULL) {
1252 return -1;
1253 }
1254
1255 animID = sprite->curAnimID;
1256 if (animID != 255) {
1257 animComps = sprite->spriteData->animListStart[animID];
1258 compList = sprite->componentList;
1259 i = 0;
1260 while (*compList != PTR_LIST_END) {
1261 if (i == compListIdx) {
1263 comp = *compList;
1264 *outX = comp->compPos.x + animComp->compOffset.x;
1265 *outY = comp->compPos.y + animComp->compOffset.y;
1266 *outZ = comp->compPos.z + animComp->compOffset.z;
1267 return 0;
1268 }
1269 i++;
1270 compList++;
1271 if (*animComps != PTR_LIST_END) {
1272 animComps++;
1273 }
1274 }
1275 }
1276 return -1;
1277}
1278
1283
1284 if (sprite != NULL) {
1285 paletteOffsetCopy = sprite->palettesOffset;
1286 cache = sprite->rastersOffset[rasterIndex];
1287 out->raster = cache->image;
1288 out->width = cache->width;
1289 out->height = cache->height;
1290 out->defaultPal = paletteOffsetCopy[cache->palette];
1291 return TRUE;
1292 }
1293 return FALSE;
1294}
1295
1298
1299 if (sprite != NULL) {
1300 return sprite->palettesOffset;
1301 } else {
1302 return NULL;
1303 }
1304}
1305
1308
1309 if (sprite != NULL) {
1310 return sprite->colorVariations;
1311 } else {
1312 return -1;
1313 }
1314}
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)
BSS s32 PopupMenu_SelectedIndex
Vec2b altViewportOffset
Mtx matrixStack[0x200]
#define PAL_PTR
#define IMG_PTR
s32 b32
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:4793
@ SPR_SHADING_FLAG_ENABLED
Definition enums.h:4792
ImgFXType
Definition enums.h:4701
@ IMGFX_CLEAR
Definition enums.h:4702
@ PEACH_FLAG_IS_PEACH
Definition enums.h:2474
@ SPR_IMGFX_FLAG_ALL
Definition enums.h:4788
@ SPR_IMGFX_FLAG_10000000
Definition enums.h:4784
@ CONTEXT_PAUSE
Definition enums.h:3564
PlayerSpriteSets
Definition enums.h:5930
@ PLAYER_SPRITES_MARIO_WORLD
Definition enums.h:5931
@ PLAYER_SPRITES_PEACH_WORLD
Definition enums.h:5935
@ PLAYER_SPRITES_COMBINED_EPILOGUE
Definition enums.h:5933
@ PLAYER_SPRITES_MARIO_REFLECT_FLOOR
Definition enums.h:5932
@ PLAYER_SPRITES_PEACH_BATTLE
Definition enums.h:5937
@ PLAYER_SPRITES_MARIO_PARADE
Definition enums.h:5934
@ PLAYER_SPRITES_MARIO_BATTLE
Definition enums.h:5936
@ IMGFX_FLAG_80000
Definition enums.h:4697
s32 imgfx_appendGfx_component(s32, ImgFXTexture *, u32, Matrix4f)
Definition imgfx.c:703
s32 imgfx_get_free_instances(s32)
Definition imgfx.c:337
void * _heap_malloc(HeapNode *head, u32 size)
Definition 43F0.c:77
u32 _heap_free(HeapNode *heapNodeList, void *addrToFree)
Definition 43F0.c:219
void imgfx_release_instance(u32)
Definition imgfx.c:385
void imgfx_update(u32, ImgFXType, s32, s32, s32, s32, s32)
Definition imgfx.c:486
HeapNode * _heap_create(HeapNode *addr, u32 size)
Definition 43F0.c:62
#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:242
#define PM_CC_0A
Definition macros.h:298
#define PM_CC_0C
Definition macros.h:302
#define PM_CC_0B
Definition macros.h:300
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define SPRITE_HEAP_SIZE
Definition macros.h:125
#define ASSERT_MSG(condition, msg, args...)
Definition macros.h:66
#define PM_CC_3D
Definition macros.h:419
#define PTR_LIST_END
Definition macros.h:42
#define VIRTUAL_TO_PHYSICAL(addr)
Definition macros.h:47
#define PM_CC_02
Definition macros.h:289
Quad * spr_get_cached_quad(s32 quadIndex)
Definition sprite.c:135
Quad * spr_get_quad_for_size(s32 *quadIndex, s32 width, s32 height)
Definition sprite.c:169
void spr_draw_component(s32 drawOpts, SpriteComponent *component, SpriteAnimComponent *anim, SpriteRasterCacheEntry **cache, PAL_PTR *palettes, f32 zscale, Matrix4f mtx)
Definition sprite.c:426
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:395
s32 spr_get_notify_value(s32 spriteInstanceID)
Definition sprite.c:1158
void spr_component_update_commands(SpriteComponent *comp, SpriteAnimComponent *anim)
Definition sprite.c:487
BSS b32 SpriteUseGeneralHeap
Definition sprite.c:10
void spr_init_quad_cache(void)
Definition sprite.c:125
void spr_make_quad_for_size(Quad *quad, s32 width, s32 height)
Definition sprite.c:142
void spr_get_player_raster_info(SpriteRasterInfo *out, s32 playerSpriteID, s32 rasterIndex)
Definition sprite.c:988
void spr_init_component_anim_state(SpriteComponent *comp, SpriteAnimComponent *anim)
Definition sprite.c:715
BSS SpriteAnimData * NpcSpriteData[0xFF]
Definition sprite.c:17
f32 SpriteAnimUpdateTimescale
Definition sprite.c:88
void spr_render_init(void)
Definition sprite.c:815
s32 spr_update_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale)
Definition sprite.c:1061
s32 spr_free_sprite(s32 spriteInstanceID)
Definition sprite.c:1162
#define MAX_SPRITE_ID
Definition sprite.c:5
void set_npc_imgfx_all(s32 spriteIdx, ImgFXType imgfxType, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5)
Definition sprite.c:1238
Quad SpriteQuadTemplate
Definition sprite.c:29
s32 spr_get_npc_color_variations(s32 npcSpriteID)
Definition sprite.c:1306
BSS PlayerCurrentAnimInfo CurPlayerAnimInfo[3]
Definition sprite.c:16
Gfx OpaqueSpriteGfx[]
Definition sprite.c:50
BSS s32 SpriteQuadCacheInfo[22]
Definition sprite.c:21
BSS SpriteInstance SpriteInstances[51]
Definition sprite.c:19
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:219
void spr_set_anim_timescale(f32 timescale)
Definition sprite.c:752
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:314
BSS u8 NpcSpriteInstanceCount[0xFF]
Definition sprite.c:18
BSS s32 CurSpriteImgFX
Definition sprite.c:12
s32 spr_get_npc_raster_info(SpriteRasterInfo *out, s32 npcSpriteID, s32 rasterIndex)
Definition sprite.c:1279
void spr_load_npc_extra_anims(SpriteAnimData *, u32 *)
void spr_load_player_sprite(s32 spriteIndex)
Definition sprite.c:756
Gfx TranslucentSpriteGfx[]
Definition sprite.c:60
s32 spr_unpack_signed_12bit(u16 val)
Definition sprite.c:467
Gfx OpaqueShadedSpriteGfx[]
Definition sprite.c:70
void spr_component_update_finish(SpriteComponent *comp, SpriteComponent **compList, SpriteRasterCacheEntry **rasterCacheEntry, s32 overridePalette)
Definition sprite.c:663
void set_player_imgfx_all(s32 animID, ImgFXType imgfxType, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6)
Definition sprite.c:984
#define MARIO_SPRITE_WORLD_BITS
Definition sprite.c:94
s32 spr_unpack_signed_16bit(u16 val)
Definition sprite.c:477
s32 spr_draw_npc_sprite(s32 spriteInstanceID, s32 yaw, s32 alphaIn, PAL_PTR *paletteList, Matrix4f mtx)
Definition sprite.c:1094
void spr_init_sprites(s32 playerSpriteSet)
Definition sprite.c:765
BSS s32 SpriteCurBaseRot[3]
Definition sprite.c:22
HeapNode heap_generalHead
Definition heaps3.c:3
s32 spr_component_update(s32 curNotifyValue, SpriteComponent **compList, SpriteAnimComponent **animList, SpriteRasterCacheEntry **rasterCache, s32 overridePalette)
Definition sprite.c:693
PAL_PTR * spr_get_npc_palettes(s32 npcSpriteID)
Definition sprite.c:1296
#define MARIO_SPRITE_BATTLE_BITS
Definition sprite.c:101
Gfx TranslucentShadedSpriteGfx[]
Definition sprite.c:79
SpriteComponent ** spr_allocate_components(s32)
s32 spr_get_comp_position(s32 spriteIdx, s32 compListIdx, s32 *outX, s32 *outY, s32 *outZ)
Definition sprite.c:1242
BSS Quad * SpriteQuadCache
Definition sprite.c:20
BSS s32 SpriteUpdateNotifyValue
Definition sprite.c:23
HeapNode heap_spriteHead
Definition heaps3.c:4
s32 func_802DDEC4(s32 spriteIdx)
Definition sprite.c:954
s32 spr_load_npc_sprite(s32 animID, u32 *extraAnimList)
Definition sprite.c:1015
Vp SpritePauseVp
Definition sprite.c:38
s32 spr_draw_player_sprite(s32 spriteInstanceID, s32 yaw, s32 alphaIn, PAL_PTR *paletteList, Matrix4f mtx)
Definition sprite.c:867
BSS SpriteAnimData * PlayerSprites[13]
Definition sprite.c:13
void set_npc_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 imgfxArg5)
Definition sprite.c:1212
void spr_clear_quad_cache(void)
Definition sprite.c:206
BSS s32 MaxPlayerSpriteComponents
Definition sprite.c:15
PAL_PTR * spr_get_player_palettes(s32 spriteIndex)
Definition sprite.c:1005
void spr_init_anim_state(SpriteComponent **compList, SpriteAnimComponent **animList)
Definition sprite.c:742
#define MARIO_SPRITE_COMMON_BITS
Definition sprite.c:90
BSS s32 CurPlayerSpriteIndex
Definition sprite.c:14
#define PEACH_SPRITE_BITS
Definition sprite.c:107
Vp SpritePauseVpAlt
Definition sprite.c:44
s32 spr_update_player_sprite(s32 spriteInstanceID, s32 animID, f32 timeScale)
Definition sprite.c:820
s32 get_npc_comp_imgfx_idx(s32 spriteIdx, s32 compIdx)
Definition sprite.c:1202
void set_player_imgfx_comp(s32 spriteIdx, s32 compIdx, ImgFXType imgfx, s32 imgfxArg1, s32 imgfxArg2, s32 imgfxArg3, s32 imgfxArg4, s32 flags)
Definition sprite.c:958
BSS s32 MaxLoadedSpriteInstanceID
Definition sprite.c:11
void spr_init_player_raster_cache(s32 cacheSize, s32 maxRasterSize)
SpriteAnimComponent ** animListStart[VLA]
Definition sprite.h:83
SpriteAnimData * spriteData
Definition sprite.h:89
s32 spriteIndex
Definition sprite.h:87
Vec3f compPos
Definition sprite.h:50
#define SPR_UNPACK_PAL(animID)
Definition sprite.h:10
#define SPR_UNPACK_ANIM(animID)
Definition sprite.h:11
void create_shading_palette(Matrix4f mtx, s32 uls, s32 ult, s32 lrs, s32 lrt, s32 alpha, s32)
SpriteRasterCacheEntry ** rastersOffset
Definition sprite.h:79
s32 curAnimID
Definition sprite.h:90
SpriteComponent ** componentList
Definition sprite.h:88
@ DRAW_SPRITE_OVERRIDE_YAW
Definition sprite.h:25
@ DRAW_SPRITE_OVERRIDE_ALPHA
Definition sprite.h:26
@ DRAW_SPRITE_OVERRIDE_PALETTES
Definition sprite.h:24
@ DRAW_SPRITE_UPSIDE_DOWN
Definition sprite.h:23
@ DRAW_SPRITE_USE_PLAYER_RASTERS
Definition sprite.h:22
#define SPR_UNPACK_SPR(animID)
Definition sprite.h:9
Vtx v[4]
Definition sprite.h:120
SpriteComponent ** componentList
Definition sprite.h:57
@ PLAYER_SPRITE_MAIN
Definition sprite.h:30
PAL_PTR * palettesOffset
Definition sprite.h:80
s32 notifyValue
Definition sprite.h:91
@ SPRITE_ID_BACK_FACING
Definition sprite.h:17
s32 colorVariations
Definition sprite.h:82
s32 maxComponents
Definition sprite.h:81
Definition sprite.h:119
Sprite data header.
Definition sprite.h:78
#define ANIM_LIST_END
Terminates an extraAnimationList.
Definition types.h:22
GameStatus * gGameStatusPtr
Definition main_loop.c:31
Camera gCameras[4]
Definition cam_main.c:16
Gfx * gMainGfxPos
Definition cam_main.c:14
u16 gMatrixListPos
Definition main_loop.c:44
SpriteShadingProfile * gSpriteShadingProfile
DisplayContext * gDisplayContext
Definition cam_main.c:15
s16 gCurrentCamID
Definition cam_main.c:12