00001 #ifndef _PA_Sprite
00002 #define _PA_Sprite
00003
00004
00011
00012
00013
00014 #define EWRAM_DATA __attribute__((section(".ewram")))
00015 #define EWRAM_BSS __attribute__((section(".sbss")))
00016 #define PA_Cos(angle) PA_SIN[((angle) + 128)&511]
00017 #define PA_Sin(angle) PA_SIN[((angle))&511]
00018 extern const s16 PA_SIN[512];
00019
00020 #define MAX_DRAW 16 // Maximum 16 sprites dessinables...
00021
00022
00024
00026
00027
00028 #define OBJ_SIZE_8X8 0,0
00029 #define OBJ_SIZE_16X16 0,1
00030 #define OBJ_SIZE_32X32 0,2
00031 #define OBJ_SIZE_64X64 0,3
00032 #define OBJ_SIZE_16X8 1,0
00033 #define OBJ_SIZE_32X8 1,1
00034 #define OBJ_SIZE_32X16 1,2
00035 #define OBJ_SIZE_64X32 1,3
00036 #define OBJ_SIZE_8X16 2,0
00037 #define OBJ_SIZE_8X32 2,1
00038 #define OBJ_SIZE_16X32 2,2
00039 #define OBJ_SIZE_32X64 2,3
00040
00041 typedef struct {
00042 u8 lx, ly;
00043 } PA_sizes;
00044
00045 extern const PA_sizes PA_size[3][4];
00046
00047
00048 #define BITS_16 65535
00049 #define ALL_BUT(ATR) (BITS_16 - ATR)
00050
00051 #define OBJ_X 511 //511, debugging...
00052 #define OBJ_Y 255
00053 #define OBJ_ROT 256
00054 #define ALL_BUT_ROTSET 49663 // Numéro du rotset
00055 #define ALL_BUT_PAL 4095
00056
00057 #define DBLSIZE 512
00058 #define N_COLORS (1 << 13)
00059 #define OBJ_MODE 3072
00060 #define OBJ_MOSAIC 4096
00061 #define OBJ_HFLIP 4096
00062 #define OBJ_VFLIP 8192
00063
00064 #define OBJ_GFX 1023
00065 #define OBJ_PRIO 3072
00066
00067 #define COLORS_256 1
00068 #define COLORS_16 0
00069
00070
00071
00072 #define MEM_DECAL 5
00073 #define NUMBER_DECAL 7
00074
00075
00076
00077
00078 typedef struct {
00079 u16 mem_block;
00080 u16 free;
00081 } mem_usage;
00082
00083 extern u16 n_free_mem[2];
00084 extern u8 used_mem[2][1024];
00085 extern u8 obj_per_gfx[2][1024];
00086 extern mem_usage free_mem[2][1024];
00087
00088 extern u16 FirstGfx[2];
00089
00090 extern const u16 PA_obj_sizes[4][3];
00091
00092 typedef struct {
00093 u16 atr0, atr1, atr2, atr3;
00094 }obj_inf;
00095 extern obj_inf PA_obj[2][128];
00096
00097
00098
00099
00100 typedef struct {
00101 bool screen;
00102 u8 sprite;
00103 bool wasdrawing;
00104 s8 x, y;
00105 u8 hsize, vsize;
00106 u8 n_colors;
00107 u8 drawsize;
00108 u32 *gfxpointer;
00109 } PA_DrawSprites;
00110
00111
00112 extern PA_DrawSprites PA_DrawSprite[MAX_DRAW];
00113
00114
00115 extern unsigned char *PA_SpriteBuffer[MAX_DRAW];
00116
00117 extern u16 *PA_SpriteAnimP[2][1024];
00118
00119
00120
00121 #define OAM0 0x07000000
00122 #define OAM1 0x07000400
00123
00124
00136
00137 #define PA_UpdateOAM()s16 i;\
00138 for (i = 0; i < 256; i++) {\
00139 OAM[(i << 2)] = PA_obj[0][i].atr0;\
00140 OAM[1+(i << 2)] = PA_obj[0][i].atr1;\
00141 OAM[2+(i << 2)] = PA_obj[0][i].atr2;\
00142 OAM[3+(i << 2)] = PA_obj[0][i].atr3;}
00143
00144
00150 #define PA_UpdateOAM0() DMA_Copy((void*)PA_obj, (void*)OAM0, 256, DMA_32NOW)
00151
00157 #define PA_UpdateOAM1() DMA_Copy((void*)PA_obj + 256, (void*)OAM1, 256, DMA_32NOW)
00158
00159
00181 u16 PA_CreateGfx(bool screen, void* obj_data, u8 obj_shape, u8 obj_size, u8 color_mode);
00182
00188 void PA_ResetSpriteSys(void);
00189
00190
00191
00224 extern inline void PA_CreateSprite(bool screen, u8 obj_number, void* obj_data, u8 obj_shape, u8 obj_size, u8 color_mode, u8 palette, s16 x, s16 y) {
00225 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, obj_data, obj_shape, obj_size, color_mode) + (palette << 12);
00226 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (color_mode << 13) + (obj_shape << 14);
00227 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (obj_size << 14);
00228 };
00229
00280 extern inline void PA_CreateSpriteEx(bool screen, u8 obj_number, void* obj_data, u8 obj_shape, u8 obj_size, u8 color_mode, u8 palette, u8 obj_mode, bool mosaic, bool hflip, bool vflip, u8 prio, bool dblsize, s16 x, s16 y) {
00281 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, obj_data, obj_shape, obj_size, color_mode) + (prio << 10) + (palette << 12);
00282 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (obj_mode << 10) + (mosaic << 12) + ((color_mode) << 13) + (obj_shape << 14);
00283 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00284 };
00285
00286
00287
00288
00289
00331 extern inline void PA_Create16bitSpriteEx(bool screen, u8 obj_number, void* obj_data, u8 obj_shape, u8 obj_size, bool mosaic, bool hflip, bool vflip, u8 prio, bool dblsize, s16 x, s16 y){
00332 u16 mem_size = PA_obj_sizes[obj_size][obj_shape] << 1;
00333 u16 *gfx = (u16*)malloc(mem_size);
00334 mem_size = mem_size >> 1;
00335 s32 i;
00336 u16 *data = (u16*)obj_data;
00337 for (i = 0; i < mem_size; i++) gfx[i] = data[i] + (1 << 15);
00338
00339 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, gfx, obj_shape, obj_size, 2) + (prio << 10) + (15 << 12);
00340 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (3 << 10) + (mosaic << 12) + (0 << 13) + (obj_shape << 14);
00341 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00342
00343 free(gfx);
00344 }
00345
00346
00347
00374 extern inline void PA_Create16bitSprite(bool screen, u8 obj_number, void* obj_data, u8 obj_shape, u8 obj_size, s16 x, s16 y){
00375 PA_Create16bitSpriteEx(screen, obj_number, obj_data, obj_shape, obj_size, 0, 0, 0, 0, 0, x, y);
00376 }
00377
00378
00379
00380
00413 extern inline void PA_CreateSpriteFromGfx(bool screen, u8 obj_number, u16 obj_gfx, u8 obj_shape, u8 obj_size, u8 color_mode, u8 palette, s16 x, s16 y) {
00414 PA_obj[screen][obj_number].atr2 = obj_gfx + (palette << 12);
00415 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (color_mode << 13) + (obj_shape << 14);
00416 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (obj_size << 14);
00417 ++obj_per_gfx[screen][obj_gfx];
00418 };
00419
00470 extern inline void PA_CreateSpriteExFromGfx(bool screen, u8 obj_number, u16 obj_gfx, u8 obj_shape, u8 obj_size, u8 color_mode, u8 palette, u8 obj_mode, bool mosaic, bool hflip, bool vflip, u8 prio, bool dblsize, s16 x, s16 y) {
00471 PA_obj[screen][obj_number].atr2 = obj_gfx + (prio << 10) + (palette << 12);
00472 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (obj_mode << 10) + (mosaic << 12) + (color_mode << 13) + (obj_shape << 14);
00473 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00474 ++obj_per_gfx[screen][obj_gfx];
00475 };
00476
00477
00492 #define PA_UpdateSpriteGfx(screen, obj_number, obj_data) PA_UpdateGfx(screen, PA_GetSpriteGfx(screen, obj_number), obj_data)
00493
00508 #define PA_UpdateGfx(screen, gfx_number, obj_data) {DMA_Copy(obj_data, (void*)(SPRITE_GFX1 + (0x200000 * screen) + (gfx_number << NUMBER_DECAL)), (used_mem[screen][gfx_number] << MEM_DECAL), DMA_32NOW);}
00509
00510
00511
00523 void PA_DeleteGfx(bool screen, u16 obj_gfx);
00524
00525
00537 void PA_DeleteSprite(bool screen, u8 obj_number);
00538
00539
00555 #define PA_SetSpriteRotEnable(screen, sprite, rotset) {PA_obj[screen][sprite].atr0 |= OBJ_ROT; PA_obj[screen][sprite].atr1 = (PA_obj[screen][sprite].atr1 & ALL_BUT_ROTSET) + ((rotset) << 9);}
00556
00568 #define PA_SetSpriteRotDisable(screen, sprite) {PA_obj[screen][sprite].atr0 &= ALL_BUT(OBJ_ROT); PA_obj[screen][sprite].atr1 &= ALL_BUT_ROTSET;}
00569
00570
00592 extern inline void PA_SetRotset(bool screen, u8 rotset, s16 angle, u16 zoomx, u16 zoomy) {
00593 u8 obj_num = (rotset << 2);
00594 PA_obj[screen][obj_num].atr3 = (PA_Cos(angle) * zoomx) >> 8;
00595 PA_obj[screen][obj_num + 1].atr3 = (-PA_Sin(angle) * zoomy) >> 8;
00596 PA_obj[screen][obj_num + 2].atr3 = (PA_Sin(angle) * zoomx) >> 8;
00597 PA_obj[screen][obj_num + 3].atr3 = (PA_Cos(angle) * zoomy) >> 8;
00598 }
00599
00614 extern inline void PA_SetRotsetNoZoom(bool screen, u8 rotset, s16 angle) {
00615 u8 obj_num = (rotset << 2);
00616 PA_obj[screen][obj_num].atr3 = PA_Cos(angle);
00617 PA_obj[screen][obj_num + 1].atr3 = -PA_Sin(angle);
00618 PA_obj[screen][obj_num + 2].atr3 = PA_Sin(angle);
00619 PA_obj[screen][obj_num + 3].atr3 = PA_Cos(angle);
00620 }
00621
00639 extern inline void PA_SetRotsetNoAngle(bool screen, u8 rotset, u16 zoomx, u16 zoomy) {
00640 u8 obj_num = (rotset << 2);
00641 PA_obj[screen][obj_num].atr3 = zoomx;
00642 PA_obj[screen][obj_num + 1].atr3 = 0;
00643 PA_obj[screen][obj_num + 2].atr3 = 0;
00644 PA_obj[screen][obj_num + 3].atr3 = zoomy;
00645 }
00646
00647
00648
00649
00650
00651
00652
00669 #define PA_SetSpriteX(screen, obj, x) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_X)) + ((x) & OBJ_X)
00670
00683 #define PA_GetSpriteX(screen, obj) (PA_obj[screen][obj].atr1 & (OBJ_X))
00684
00685
00700 #define PA_SetSpriteY(screen, obj, y) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(OBJ_Y)) + ((y) & OBJ_Y)
00701
00714 #define PA_GetSpriteY(screen, obj) (PA_obj[screen][obj].atr0 & OBJ_Y)
00715
00716
00717
00735 extern inline void PA_SetSpriteXY(bool screen, u8 sprite, s16 x, s16 y) {
00736 PA_SetSpriteX(screen, sprite, x);
00737 PA_SetSpriteY(screen, sprite, y);
00738 }
00739
00740
00741
00756 #define PA_SetSpritePal(screen, obj, pal) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT_PAL) + ((pal) << 12)
00757
00769 #define PA_GetSpritePal(screen, obj) (PA_obj[screen][obj].atr2 >> 12)
00770
00771
00786 #define PA_SetSpriteDblsize(screen, obj, dblsize) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(DBLSIZE)) + ((dblsize) << 9)
00787
00799 #define PA_GetSpriteDblsize(screen, obj) ((PA_obj[screen][obj].atr0 & DBLSIZE) >> 9)
00800
00801
00816 #define PA_SetSpriteColors(screen, sprite, n_colors) PA_obj[screen][sprite].atr0 = (PA_obj[screen][sprite].atr0 & ALL_BUT(N_COLORS)) + ((n_colors) << 13)
00817
00829 #define PA_GetSpriteColors(screen, sprite) ((PA_obj[screen][sprite].atr0 & N_COLORS) >> 13)
00830
00831
00832
00847 #define PA_SetSpriteMode(screen, sprite, obj_mode) PA_obj[screen][sprite].atr0 = (PA_obj[screen][sprite].atr0 & ALL_BUT(OBJ_MODE)) + ((obj_mode) << 10)
00848
00860 #define PA_GetSpriteMode(screen, obj) ((PA_obj[screen][obj].atr0 & OBJ_MODE) >> 10)
00861
00862
00877 #define PA_SetSpriteMosaic(screen, obj, mosaic) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(OBJ_MOSAIC)) + ((mosaic) << 12)
00878
00890 #define PA_GetSpriteMosaic(screen, obj) ((PA_obj[screen][obj].atr0 & OBJ_MOSAIC) >> 12)
00891
00892
00893
00908 #define PA_SetSpriteHflip(screen, obj, hflip) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_HFLIP)) + ((hflip) << 12)
00909
00921 #define PA_GetSpriteHflip(screen, obj) ((PA_obj[screen][obj].atr1 & OBJ_HFLIP) >> 12)
00922
00923
00938 #define PA_SetSpriteVflip(screen, obj, vflip) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_VFLIP)) + ((vflip) << 13)
00939
00951 #define PA_GetSpriteVflip(screen, obj) ((PA_obj[screen][obj].atr1 & OBJ_VFLIP) >> 13)
00952
00953
00968 #define PA_SetSpriteGfx(screen, obj, gfx) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT(OBJ_GFX)) + ((gfx) & OBJ_GFX)
00969
00981 #define PA_GetSpriteGfx(screen, obj) (PA_obj[screen][obj].atr2 & OBJ_GFX)
00982
00983
00984
00999 #define PA_SetSpritePrio(screen, obj, prio) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT(OBJ_PRIO)) + ((prio) << 10)
01000
01012 #define PA_GetSpritePrio(screen, obj) ((PA_obj[screen][obj].atr2 & OBJ_PRIO) >> 10)
01013
01014
01026 #define PA_GetSpriteLx(screen, sprite) PA_size[PA_obj[screen][sprite].atr0 >> 14][PA_obj[screen][sprite].atr1 >> 14].lx
01027
01028
01040 #define PA_GetSpriteLy(screen, sprite)PA_size[PA_obj[screen][sprite].atr0 >> 14][PA_obj[screen][sprite].atr1 >> 14].ly
01041
01042
01057 #define PA_CloneSprite(screen, obj, target) {PA_obj[screen][obj].atr0 = PA_obj[screen][target].atr0; PA_obj[screen][obj].atr1 = PA_obj[screen][target].atr1; PA_obj[screen][obj].atr2 = PA_obj[screen][target].atr2; ++obj_per_gfx[screen][PA_GetSpriteGfx(screen, target)];}
01058
01059
01060
01061
01062
01063
01064
01065
01089 extern inline void PA_SetSpriteAnimEx(bool screen, u8 sprite, u8 lx, u8 ly, u8 ncolors, s16 animframe){
01090 PA_UpdateSpriteGfx(screen, sprite, (void*)(PA_SpriteAnimP[screen][PA_GetSpriteGfx(screen, sprite)] + (animframe * (lx * ly) >> (2 - ncolors))));
01091 }
01092
01107 extern inline void PA_SetSpriteAnim(bool screen, u8 sprite, s16 animframe){
01108 PA_SetSpriteAnimEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteLy(screen, sprite), PA_GetSpriteColors(screen, sprite), animframe);
01109 }
01110
01111
01112
01113
01114
01115
01116
01117
01144 void PA_SetSpritePixelEx(bool screen, u8 sprite, u8 hsize, u8 n_colors, u8 x, u8 y, u8 color);
01145
01146
01147
01168 #define PA_SetSpritePixel(screen, sprite, x, y, color) PA_SetSpritePixelEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteColors(screen, sprite), x, y, color)
01169
01170
01194 u8 PA_GetSpritePixelEx(bool screen, u8 sprite, u8 hsize, u8 n_colors, u8 x, u8 y);
01195
01196
01214 #define PA_GetSpritePixel(screen, sprite, x, y) PA_GetSpritePixelEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteColors(screen, sprite), x, y)
01215
01216
01234 void PA_InitSpriteDraw(bool screen, u8 sprite, u8 draw_number, u8 drawsize);
01235
01236
01254 void PA_SpriteDraw(u8 draw_number, s16 x, s16 y, u16 color);
01255
01256
01265 #define PA_SpriteDrawNot(draw_number) PA_DrawSprite[draw_number].wasdrawing = 0
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 #endif
01306
01307