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][128];
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_SpriteAnimP[screen][obj_number] = (u16*)obj_data;
00226 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, obj_data, obj_shape, obj_size, color_mode) + (palette << 12);
00227 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (color_mode << 13) + (obj_shape << 14);
00228 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (obj_size << 14);
00229 };
00230
00281 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) {
00282 PA_SpriteAnimP[screen][obj_number] = (u16*)obj_data;
00283 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, obj_data, obj_shape, obj_size, color_mode) + (prio << 10) + (palette << 12);
00284 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (obj_mode << 10) + (mosaic << 12) + ((color_mode) << 13) + (obj_shape << 14);
00285 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00286 };
00287
00288
00289
00290
00291
00333 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){
00334 u16 mem_size = PA_obj_sizes[obj_size][obj_shape] << 1;
00335 u16 *gfx = malloc(mem_size);
00336 mem_size = mem_size;
00337 s32 i;
00338 u16 *data = (u16*)obj_data;
00339 for (i = 0; i < mem_size; i++) gfx[i] = data[i] + (1 << 15);
00340
00341 PA_SpriteAnimP[screen][obj_number] = (u16*)obj_data;
00342 PA_obj[screen][obj_number].atr2 = PA_CreateGfx(screen, gfx, obj_shape, obj_size, 2) + (prio << 10) + (15 << 12);
00343 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (3 << 10) + (mosaic << 12) + (0 << 13) + (obj_shape << 14);
00344 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00345
00346 free(gfx);
00347 }
00348
00349
00350
00377 extern inline void PA_Create16bitSprite(bool screen, u8 obj_number, void* obj_data, u8 obj_shape, u8 obj_size, s16 x, s16 y){
00378 PA_Create16bitSpriteEx(screen, obj_number, obj_data, obj_shape, obj_size, 0, 0, 0, 0, 0, x, y);
00379 }
00380
00381
00382
00383
00416 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) {
00417 PA_obj[screen][obj_number].atr2 = obj_gfx + (palette << 12);
00418 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (color_mode << 13) + (obj_shape << 14);
00419 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (obj_size << 14);
00420 ++obj_per_gfx[screen][obj_gfx];
00421 };
00422
00473 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) {
00474 PA_obj[screen][obj_number].atr2 = obj_gfx + (prio << 10) + (palette << 12);
00475 PA_obj[screen][obj_number].atr0 = (y&OBJ_Y) + (dblsize << 9) + (obj_mode << 10) + (mosaic << 12) + (color_mode << 13) + (obj_shape << 14);
00476 PA_obj[screen][obj_number].atr1 = (x & OBJ_X) + (hflip << 12) + (vflip << 13) + (obj_size << 14);
00477 ++obj_per_gfx[screen][obj_gfx];
00478 };
00479
00480
00495 #define PA_UpdateSpriteGfx(screen, obj_number, obj_data) PA_UpdateGfx(screen, PA_GetSpriteGfx(screen, obj_number), obj_data)
00496
00511 #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);}
00512
00513
00514
00526 void PA_DeleteGfx(bool screen, u16 obj_gfx);
00527
00528
00540 void PA_DeleteSprite(bool screen, u8 obj_number);
00541
00542
00558 #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);}
00559
00571 #define PA_SetSpriteRotDisable(screen, sprite) {PA_obj[screen][sprite].atr0 &= ALL_BUT(OBJ_ROT); PA_obj[screen][sprite].atr1 &= ALL_BUT_ROTSET;}
00572
00573
00595 extern inline void PA_SetRotset(bool screen, u8 rotset, s16 angle, u16 zoomx, u16 zoomy) {
00596 u8 obj_num = (rotset << 2);
00597 PA_obj[screen][obj_num].atr3 = (PA_Cos(angle) * zoomx) >> 8;
00598 PA_obj[screen][obj_num + 1].atr3 = (-PA_Sin(angle) * zoomy) >> 8;
00599 PA_obj[screen][obj_num + 2].atr3 = (PA_Sin(angle) * zoomx) >> 8;
00600 PA_obj[screen][obj_num + 3].atr3 = (PA_Cos(angle) * zoomy) >> 8;
00601 }
00602
00617 extern inline void PA_SetRotsetNoZoom(bool screen, u8 rotset, s16 angle) {
00618 u8 obj_num = (rotset << 2);
00619 PA_obj[screen][obj_num].atr3 = PA_Cos(angle);
00620 PA_obj[screen][obj_num + 1].atr3 = -PA_Sin(angle);
00621 PA_obj[screen][obj_num + 2].atr3 = PA_Sin(angle);
00622 PA_obj[screen][obj_num + 3].atr3 = PA_Cos(angle);
00623 }
00624
00642 extern inline void PA_SetRotsetNoAngle(bool screen, u8 rotset, u16 zoomx, u16 zoomy) {
00643 u8 obj_num = (rotset << 2);
00644 PA_obj[screen][obj_num].atr3 = zoomx;
00645 PA_obj[screen][obj_num + 1].atr3 = 0;
00646 PA_obj[screen][obj_num + 2].atr3 = 0;
00647 PA_obj[screen][obj_num + 3].atr3 = zoomy;
00648 }
00649
00650
00651
00652
00653
00654
00655
00672 #define PA_SetSpriteX(screen, obj, x) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_X)) + ((x) & OBJ_X)
00673
00686 #define PA_GetSpriteX(screen, obj) (PA_obj[screen][obj].atr1 & (OBJ_X))
00687
00688
00703 #define PA_SetSpriteY(screen, obj, y) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(OBJ_Y)) + ((y) & OBJ_Y)
00704
00717 #define PA_GetSpriteY(screen, obj) (PA_obj[screen][obj].atr0 & OBJ_Y)
00718
00719
00720
00738 extern inline void PA_SetSpriteXY(bool screen, u8 sprite, s16 x, s16 y) {
00739 PA_SetSpriteX(screen, sprite, x);
00740 PA_SetSpriteY(screen, sprite, y);
00741 }
00742
00743
00744
00759 #define PA_SetSpritePal(screen, obj, pal) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT_PAL) + ((pal) << 12)
00760
00772 #define PA_GetSpritePal(screen, obj) (PA_obj[screen][obj].atr2 >> 12)
00773
00774
00789 #define PA_SetSpriteDblsize(screen, obj, dblsize) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(DBLSIZE)) + ((dblsize) << 9)
00790
00802 #define PA_GetSpriteDblsize(screen, obj) ((PA_obj[screen][obj].atr0 & DBLSIZE) >> 9)
00803
00804
00819 #define PA_SetSpriteColors(screen, sprite, n_colors) PA_obj[screen][sprite].atr0 = (PA_obj[screen][sprite].atr0 & ALL_BUT(N_COLORS)) + ((n_colors) << 13)
00820
00832 #define PA_GetSpriteColors(screen, sprite) ((PA_obj[screen][sprite].atr0 & N_COLORS) >> 13)
00833
00834
00835
00850 #define PA_SetSpriteMode(screen, sprite, obj_mode) PA_obj[screen][sprite].atr0 = (PA_obj[screen][sprite].atr0 & ALL_BUT(OBJ_MODE)) + ((obj_mode) << 10)
00851
00863 #define PA_GetSpriteMode(screen, obj) ((PA_obj[screen][obj].atr0 & OBJ_MODE) >> 10)
00864
00865
00880 #define PA_SetSpriteMosaic(screen, obj, mosaic) PA_obj[screen][obj].atr0 = (PA_obj[screen][obj].atr0 & ALL_BUT(OBJ_MOSAIC)) + ((mosaic) << 12)
00881
00893 #define PA_GetSpriteMosaic(screen, obj) ((PA_obj[screen][obj].atr0 & OBJ_MOSAIC) >> 12)
00894
00895
00896
00911 #define PA_SetSpriteHflip(screen, obj, hflip) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_HFLIP)) + ((hflip) << 12)
00912
00924 #define PA_GetSpriteHflip(screen, obj) ((PA_obj[screen][obj].atr1 & OBJ_HFLIP) >> 12)
00925
00926
00941 #define PA_SetSpriteVflip(screen, obj, vflip) PA_obj[screen][obj].atr1 = (PA_obj[screen][obj].atr1 & ALL_BUT(OBJ_VFLIP)) + ((vflip) << 13)
00942
00954 #define PA_GetSpriteVflip(screen, obj) ((PA_obj[screen][obj].atr1 & OBJ_VFLIP) >> 13)
00955
00956
00971 #define PA_SetSpriteGfx(screen, obj, gfx) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT(OBJ_GFX)) + ((gfx) & OBJ_GFX)
00972
00984 #define PA_GetSpriteGfx(screen, obj) (PA_obj[screen][obj].atr2 & OBJ_GFX)
00985
00986
00987
01002 #define PA_SetSpritePrio(screen, obj, prio) PA_obj[screen][obj].atr2 = (PA_obj[screen][obj].atr2 & ALL_BUT(OBJ_PRIO)) + ((prio) << 10)
01003
01015 #define PA_GetSpritePrio(screen, obj) ((PA_obj[screen][obj].atr2 & OBJ_PRIO) >> 10)
01016
01017
01029 #define PA_GetSpriteLx(screen, sprite) PA_size[PA_obj[screen][sprite].atr0 >> 14][PA_obj[screen][sprite].atr1 >> 14].lx
01030
01031
01043 #define PA_GetSpriteLy(screen, sprite)PA_size[PA_obj[screen][sprite].atr0 >> 14][PA_obj[screen][sprite].atr1 >> 14].ly
01044
01045
01060 #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)];}
01061
01062
01063
01064
01065
01066
01081 extern inline void PA_InitSpriteAnim(bool screen, u8 sprite, void* graphics){
01082 PA_SpriteAnimP[screen][sprite] = (u16*)graphics;
01083 }
01084
01085
01086
01087
01111 extern inline void PA_SetSpriteAnimEx(bool screen, u8 sprite, u8 lx, u8 ly, u8 ncolors, s16 animframe){
01112 PA_UpdateSpriteGfx(screen, sprite, (void*)(PA_SpriteAnimP[screen][sprite] + (animframe * (lx * ly) >> (2 - ncolors))));
01113 }
01114
01129 extern inline void PA_SetSpriteAnim(bool screen, u8 sprite, s16 animframe){
01130 PA_SetSpriteAnimEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteLy(screen, sprite), PA_GetSpriteColors(screen, sprite), animframe);
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01166 void PA_SetSpritePixelEx(bool screen, u8 sprite, u8 hsize, u8 n_colors, u8 x, u8 y, u8 color);
01167
01168
01169
01190 #define PA_SetSpritePixel(screen, sprite, x, y, color) PA_SetSpritePixelEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteColors(screen, sprite), x, y, color)
01191
01192
01216 u8 PA_GetSpritePixelEx(bool screen, u8 sprite, u8 hsize, u8 n_colors, u8 x, u8 y);
01217
01218
01236 #define PA_GetSpritePixel(screen, sprite, x, y) PA_GetSpritePixelEx(screen, sprite, PA_GetSpriteLx(screen, sprite), PA_GetSpriteColors(screen, sprite), x, y)
01237
01238
01256 void PA_InitSpriteDraw(bool screen, u8 sprite, u8 draw_number, u8 drawsize);
01257
01258
01276 void PA_SpriteDraw(u8 draw_number, s16 x, s16 y, u16 color);
01277
01278
01287 #define PA_SpriteDrawNot(draw_number) PA_DrawSprite[draw_number].wasdrawing = 0
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327 #endif
01328
01329