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 extern s16 nspriteanims;
00121 typedef struct{
00122 u16 firstframe, lastframe, currentframe;
00123 u16 time;
00124 u8 lx, ly;
00125 bool colors;
00126 s16 speed;
00127 bool play;
00128 } spriteanim;
00129 extern spriteanim spriteanims[2][128];
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 #define OAM0 0x07000000
00143 #define OAM1 0x07000400
00144
00145
00157
00158 #define PA_UpdateOAM()s16 i;\
00159 for (i = 0; i < 256; i++) {\
00160 OAM[(i << 2)] = PA_obj[0][i].atr0;\
00161 OAM[1+(i << 2)] = PA_obj[0][i].atr1;\
00162 OAM[2+(i << 2)] = PA_obj[0][i].atr2;\
00163 OAM[3+(i << 2)] = PA_obj[0][i].atr3;}
00164
00165
00171 #define PA_UpdateOAM0() DMA_Copy((void*)PA_obj, (void*)OAM0, 256, DMA_32NOW)
00172
00178 #define PA_UpdateOAM1() DMA_Copy((void*)PA_obj + 256, (void*)OAM1, 256, DMA_32NOW)
00179
00180
00202 u16 PA_CreateGfx(bool screen, void* obj_data, u8 obj_shape, u8 obj_size, u8 color_mode);
00203
00209 void PA_ResetSpriteSys(void);
00210
00211
00212
00245 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) {
00246 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, obj_data, obj_shape, obj_size, color_mode) + (palette << 12);
00247 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (color_mode << 13) + (obj_shape << 14);
00248 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (obj_size << 14);
00249 };
00250
00301 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) {
00302 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, obj_data, obj_shape, obj_size, color_mode) + (prio << 10) + (palette << 12);
00303 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (obj_mode << 10) + (mosaic << 12) + ((color_mode) << 13) + (obj_shape << 14);
00304 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00305 };
00306
00307
00308
00309
00310
00352 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){
00353 u16 mem_size = PA_obj_sizes[obj_size][obj_shape] << 1;
00354 u16 *gfx = (u16*)malloc(mem_size);
00355 mem_size = mem_size >> 1;
00356 s32 i;
00357 u16 *data = (u16*)obj_data;
00358 for (i = 0; i < mem_size; i++) gfx[i] = data[i] + (1 << 15);
00359
00360 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, gfx, obj_shape, obj_size, 2) + (prio << 10) + (15 << 12);
00361 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (3 << 10) + (mosaic << 12) + (0 << 13) + (obj_shape << 14);
00362 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00363
00364 free(gfx);
00365 }
00366
00367
00368
00395 extern inline void PA_Create16bitSprite(bool screen, u8 obj_number, void* obj_data, u8 obj_shape, u8 obj_size, s16 x, s16 y){
00396 PA_Create16bitSpriteEx(screen, obj_number, obj_data, obj_shape, obj_size, 0, 0, 0, 0, 0, x, y);
00397 }
00398
00399
00400
00401
00434 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) {
00435 PA_obj[screen][obj_number].atr2 = obj_gfx + (palette << 12);
00436 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (color_mode << 13) + (obj_shape << 14);
00437 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (obj_size << 14);
00438 ++obj_per_gfx[screen][obj_gfx];
00439 };
00440
00491 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) {
00492 PA_obj[screen][obj_number].atr2 = obj_gfx + (prio << 10) + (palette << 12);
00493 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (obj_mode << 10) + (mosaic << 12) + (color_mode << 13) + (obj_shape << 14);
00494 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00495 ++obj_per_gfx[screen][obj_gfx];
00496 };
00497
00498
00513 #define PA_UpdateSpriteGfx(screen, obj_number, obj_data) PA_UpdateGfx(screen, PA_GetSpriteGfx(screen, obj_number), obj_data)
00514
00529 #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);}
00530
00531
00532
00544 void PA_DeleteGfx(bool screen, u16 obj_gfx);
00545
00546
00558 void PA_DeleteSprite(bool screen, u8 obj_number);
00559
00560
00576 #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);}
00577
00589 #define PA_SetSpriteRotDisable(screen, sprite) {PA_obj[screen][sprite].atr0 &= ALL_BUT(OBJ_ROT); PA_obj[screen][sprite].atr1 &= ALL_BUT_ROTSET;}
00590
00591
00613 extern inline void PA_SetRotset(bool screen, u8 rotset, s16 angle, u16 zoomx, u16 zoomy) {
00614 u8 obj_num = (rotset << 2);
00615 PA_obj[screen][obj_num].atr3 = (PA_Cos(angle) * zoomx) >> 8;
00616 PA_obj[screen][obj_num + 1].atr3 = (-PA_Sin(angle) * zoomy) >> 8;
00617 PA_obj[screen][obj_num + 2].atr3 = (PA_Sin(angle) * zoomx) >> 8;
00618 PA_obj[screen][obj_num + 3].atr3 = (PA_Cos(angle) * zoomy) >> 8;
00619 }
00620
00635 extern inline void PA_SetRotsetNoZoom(bool screen, u8 rotset, s16 angle) {
00636 u8 obj_num = (rotset << 2);
00637 PA_obj[screen][obj_num].atr3 = PA_Cos(angle);
00638 PA_obj[screen][obj_num + 1].atr3 = -PA_Sin(angle);
00639 PA_obj[screen][obj_num + 2].atr3 = PA_Sin(angle);
00640 PA_obj[screen][obj_num + 3].atr3 = PA_Cos(angle);
00641 }
00642
00660 extern inline void PA_SetRotsetNoAngle(bool screen, u8 rotset, u16 zoomx, u16 zoomy) {
00661 u8 obj_num = (rotset << 2);
00662 PA_obj[screen][obj_num].atr3 = zoomx;
00663 PA_obj[screen][obj_num + 1].atr3 = 0;
00664 PA_obj[screen][obj_num + 2].atr3 = 0;
00665 PA_obj[screen][obj_num + 3].atr3 = zoomy;
00666 }
00667
00668
00669
00670
00671
00672
00673
00690 #define PA_SetSpriteX(screen, obj, x) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_X)) + ((x) & OBJ_X)
00691
00704 #define PA_GetSpriteX(screen, obj) (PA_obj[screen][obj].atr1 & (OBJ_X))
00705
00706
00721 #define PA_SetSpriteY(screen, obj, y) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(OBJ_Y)) + ((y) & OBJ_Y)
00722
00735 #define PA_GetSpriteY(screen, obj) (PA_obj[screen][obj].atr0 & OBJ_Y)
00736
00737
00738
00756 extern inline void PA_SetSpriteXY(bool screen, u8 sprite, s16 x, s16 y) {
00757 PA_SetSpriteX(screen, sprite, x);
00758 PA_SetSpriteY(screen, sprite, y);
00759 }
00760
00761
00762
00777 #define PA_SetSpritePal(screen, obj, pal) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT_PAL) + ((pal) << 12)
00778
00790 #define PA_GetSpritePal(screen, obj) (PA_obj[screen][obj].atr2 >> 12)
00791
00792
00807 #define PA_SetSpriteDblsize(screen, obj, dblsize) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(DBLSIZE)) + ((dblsize) << 9)
00808
00820 #define PA_GetSpriteDblsize(screen, obj) ((PA_obj[screen][obj].atr0 & DBLSIZE) >> 9)
00821
00822
00837 #define PA_SetSpriteColors(screen, sprite, n_colors) PA_obj[screen][sprite].atr0 = (PA_obj[screen][sprite].atr0 & ALL_BUT(N_COLORS)) + ((n_colors) << 13)
00838
00850 #define PA_GetSpriteColors(screen, sprite) ((PA_obj[screen][sprite].atr0 & N_COLORS) >> 13)
00851
00852
00853
00868 #define PA_SetSpriteMode(screen, sprite, obj_mode) PA_obj[screen][sprite].atr0 = (PA_obj[screen][sprite].atr0 & ALL_BUT(OBJ_MODE)) + ((obj_mode) << 10)
00869
00881 #define PA_GetSpriteMode(screen, obj) ((PA_obj[screen][obj].atr0 & OBJ_MODE) >> 10)
00882
00883
00898 #define PA_SetSpriteMosaic(screen, obj, mosaic) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(OBJ_MOSAIC)) + ((mosaic) << 12)
00899
00911 #define PA_GetSpriteMosaic(screen, obj) ((PA_obj[screen][obj].atr0 & OBJ_MOSAIC) >> 12)
00912
00913
00914
00929 #define PA_SetSpriteHflip(screen, obj, hflip) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_HFLIP)) + ((hflip) << 12)
00930
00942 #define PA_GetSpriteHflip(screen, obj) ((PA_obj[screen][obj].atr1 & OBJ_HFLIP) >> 12)
00943
00944
00959 #define PA_SetSpriteVflip(screen, obj, vflip) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_VFLIP)) + ((vflip) << 13)
00960
00972 #define PA_GetSpriteVflip(screen, obj) ((PA_obj[screen][obj].atr1 & OBJ_VFLIP) >> 13)
00973
00974
00989 #define PA_SetSpriteGfx(screen, obj, gfx) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT(OBJ_GFX)) + ((gfx) & OBJ_GFX)
00990
01002 #define PA_GetSpriteGfx(screen, obj) (PA_obj[screen][obj].atr2 & OBJ_GFX)
01003
01004
01005
01020 #define PA_SetSpritePrio(screen, obj, prio) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT(OBJ_PRIO)) + ((prio) << 10)
01021
01033 #define PA_GetSpritePrio(screen, obj) ((PA_obj[screen][obj].atr2 & OBJ_PRIO) >> 10)
01034
01035
01047 #define PA_GetSpriteLx(screen, sprite) PA_size[PA_obj[screen][sprite].atr0 >> 14][PA_obj[screen][sprite].atr1 >> 14].lx
01048
01049
01061 #define PA_GetSpriteLy(screen, sprite)PA_size[PA_obj[screen][sprite].atr0 >> 14][PA_obj[screen][sprite].atr1 >> 14].ly
01062
01063
01078 #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)];}
01079
01080
01081
01082
01083
01084
01085
01086
01110 extern inline void PA_SetSpriteAnimEx(bool screen, u8 sprite, u8 lx, u8 ly, u8 ncolors, s16 animframe){
01111 PA_UpdateSpriteGfx(screen, sprite, (void*)(PA_SpriteAnimP[screen][PA_GetSpriteGfx(screen, sprite)] + (animframe * (lx * ly) >> (2 - ncolors))));
01112 }
01113
01128 extern inline void PA_SetSpriteAnim(bool screen, u8 sprite, s16 animframe){
01129 PA_SetSpriteAnimEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteLy(screen, sprite), PA_GetSpriteColors(screen, sprite), animframe);
01130 }
01131
01132
01133
01134
01155 void PA_StartSpriteAnim(bool screen, u8 sprite, s16 firstframe, s16 lastframe, s16 speed);
01156
01157
01158
01170 extern inline void PA_StopSpriteAnim(bool screen, u8 sprite)
01171 {
01172 if (spriteanims[screen][sprite].play) nspriteanims--;
01173 spriteanims[screen][sprite].play = 0;
01174 }
01175
01190 extern inline void PA_SetSpriteAnimFrame(bool screen, u8 sprite, u16 frame)
01191 {
01192 if(spriteanims[screen][sprite].currentframe != frame){
01193 PA_SetSpriteAnimEx(screen, sprite, spriteanims[screen][sprite].lx, spriteanims[screen][sprite].ly, spriteanims[screen][sprite].colors, spriteanims[screen][sprite].currentframe);
01194 spriteanims[screen][sprite].currentframe = frame;
01195 }
01196 }
01197
01198
01210 extern inline u16 PA_GetSpriteAnimFrame(bool screen, u8 sprite)
01211 {
01212 return spriteanims[screen][sprite].currentframe;
01213 }
01214
01215
01216
01231 extern inline void PA_SetSpriteAnimSpeed(bool screen, u8 sprite, s16 speed)
01232 {
01233 spriteanims[screen][sprite].speed = speed;
01234 }
01235
01247 extern inline u16 PA_GetSpriteAnimSpeed(bool screen, u8 sprite)
01248 {
01249 return spriteanims[screen][sprite].speed;
01250 }
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01275 extern inline void PA_SpriteAnimPause(bool screen, u8 sprite, bool pause)
01276 {
01277 if (pause&&spriteanims[screen][sprite].play) nspriteanims--;
01278 else if ((!pause)&&(!spriteanims[screen][sprite].play)) nspriteanims++;
01279 spriteanims[screen][sprite].play = !pause;
01280 }
01281
01282
01283
01284
01285
01286
01287
01314 void PA_SetSpritePixelEx(bool screen, u8 sprite, u8 hsize, u8 n_colors, u8 x, u8 y, u8 color);
01315
01316
01317
01338 #define PA_SetSpritePixel(screen, sprite, x, y, color) PA_SetSpritePixelEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteColors(screen, sprite), x, y, color)
01339
01340
01364 u8 PA_GetSpritePixelEx(bool screen, u8 sprite, u8 hsize, u8 n_colors, u8 x, u8 y);
01365
01366
01384 #define PA_GetSpritePixel(screen, sprite, x, y) PA_GetSpritePixelEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteColors(screen, sprite), x, y)
01385
01386
01404 void PA_InitSpriteDraw(bool screen, u8 sprite, u8 draw_number, u8 drawsize);
01405
01406
01424 void PA_SpriteDraw(u8 draw_number, s16 x, s16 y, u16 color);
01425
01426
01435 #define PA_SpriteDrawNot(draw_number) PA_DrawSprite[draw_number].wasdrawing = 0
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01449
01450
01451
01452
01453
01454 void PA_UpdateSpriteAnims(void);
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475 #endif
01476
01477