00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #ifndef _libnds_sprite_h_
00036 #define _libnds_sprite_h_
00037
00038 #ifndef ARM9
00039 #error Sprites are only available on the ARM9
00040 #endif
00041
00042 #include "nds/ndstypes.h"
00043 #include "nds/arm9/video.h"
00044 #include "nds/memory.h"
00045 #include "nds/system.h"
00046
00047
00048
00049
00050 #define ATTR0_NORMAL (0<<8)
00051 #define ATTR0_ROTSCALE (1<<8)
00052 #define ATTR0_DISABLED (2<<8)
00053 #define ATTR0_ROTSCALE_DOUBLE (3<<8)
00054
00055 #define ATTR0_TYPE_NORMAL (0<<10)
00056 #define ATTR0_TYPE_BLENDED (1<<10)
00057 #define ATTR0_TYPE_WINDOWED (2<<10)
00058 #define ATTR0_BMP (3<<10)
00059
00060 #define ATTR0_MOSAIC (1<<12)
00061
00062 #define ATTR0_COLOR_16 (0<<13) //16 color in tile mode...16 bit in bitmap mode
00063 #define ATTR0_COLOR_256 (1<<13)
00064
00065 #define ATTR0_SQUARE (0<<14)
00066 #define ATTR0_WIDE (1<<14)
00067 #define ATTR0_TALL (2<<14)
00068
00069 #define OBJ_Y(m) ((m)&0x00ff)
00070
00071
00072 #define ATTR1_ROTDATA(n) ((n)<<9) // note: overlaps with flip flags
00073 #define ATTR1_FLIP_X (1<<12)
00074 #define ATTR1_FLIP_Y (1<<13)
00075 #define ATTR1_SIZE_8 (0<<14)
00076 #define ATTR1_SIZE_16 (1<<14)
00077 #define ATTR1_SIZE_32 (2<<14)
00078 #define ATTR1_SIZE_64 (3<<14)
00079
00080 #define OBJ_X(m) ((m)&0x01ff)
00081
00082
00083 #define ATTR2_PRIORITY(n) ((n)<<10)
00084 #define ATTR2_PALETTE(n) ((n)<<12)
00085 #define ATTR2_ALPHA(n) ((n)<<12)
00086
00088 typedef enum
00089 {
00090 OBJMODE_NORMAL,
00091 OBJMODE_BLENDED,
00092 OBJMODE_WINDOWED,
00093 OBJMODE_BITMAP,
00095 } ObjBlendMode;
00096
00098 typedef enum {
00099 OBJSHAPE_SQUARE,
00100 OBJSHAPE_WIDE,
00101 OBJSHAPE_TALL,
00102 OBJSHAPE_FORBIDDEN,
00103 } ObjShape;
00104
00106 typedef enum {
00107 OBJSIZE_8,
00108 OBJSIZE_16,
00109 OBJSIZE_32,
00110 OBJSIZE_64,
00111 } ObjSize;
00112
00114 typedef enum {
00115 OBJCOLOR_16,
00116 OBJCOLOR_256,
00117 } ObjColMode;
00118
00120 typedef enum {
00121 OBJPRIORITY_0,
00122 OBJPRIORITY_1,
00123 OBJPRIORITY_2,
00124 OBJPRIORITY_3,
00125 } ObjPriority;
00126
00131 typedef union SpriteEntry {
00132 struct {
00133
00134 struct {
00135 u16 y :8;
00136 union {
00137 struct {
00138 u8 :1;
00139 bool isHidden :1;
00140 u8 :6;
00141 };
00142 struct {
00143 bool isRotateScale :1;
00144 bool isSizeDouble :1;
00145 ObjBlendMode blendMode :2;
00146 bool isMosaic :1;
00147 ObjColMode colorMode :1;
00148 ObjShape shape :2;
00149 };
00150 };
00151 };
00152
00153 union {
00154 struct {
00155 u16 x :9;
00156 u8 :7;
00157 };
00158 struct {
00159 u8 :8;
00160 union {
00161 struct {
00162 u8 :4;
00163 bool hFlip :1;
00164 bool vFlip :1;
00165 u8 :2;
00166 };
00167 struct {
00168 u8 :1;
00169 u8 rotationIndex :5;
00170 ObjSize size :2;
00171 };
00172 };
00173 };
00174 };
00175
00176 struct {
00177 u16 gfxIndex :10;
00178 ObjPriority priority :2;
00180 u8 palette :4;
00183 };
00184
00185 u16 attribute3;
00186 };
00187
00188 struct {
00189 uint16 attribute[3];
00190 uint16 filler;
00191 };
00192
00193 } SpriteEntry, * pSpriteEntry;
00194
00199 typedef struct SpriteRotation {
00200 uint16 filler1[3];
00201 int16 hdx;
00203 uint16 filler2[3];
00204 int16 hdy;
00206 uint16 filler3[3];
00207 int16 vdx;
00209 uint16 filler4[3];
00210 int16 vdy;
00212 } SpriteRotation, * pSpriteRotation;
00213
00214 #define SPRITE_COUNT 128
00215 #define MATRIX_COUNT 32
00216
00217
00218 typedef union OAMTable {
00219 SpriteEntry oamBuffer[SPRITE_COUNT];
00220 SpriteRotation matrixBuffer[MATRIX_COUNT];
00221 } OAMTable;
00222
00226 typedef enum {
00227 SpriteSize_8x8 = (OBJSIZE_8 << 14) | (OBJSHAPE_SQUARE << 12) | (8*8>>5),
00228 SpriteSize_16x16 = (OBJSIZE_16 << 14) | (OBJSHAPE_SQUARE << 12) | (16*16>>5),
00229 SpriteSize_32x32 = (OBJSIZE_32 << 14) | (OBJSHAPE_SQUARE << 12) | (32*32>>5),
00230 SpriteSize_64x64 = (OBJSIZE_64 << 14) | (OBJSHAPE_SQUARE << 12) | (64*64>>5),
00232 SpriteSize_16x8 = (OBJSIZE_8 << 14) | (OBJSHAPE_WIDE << 12) | (16*8>>5),
00233 SpriteSize_32x8 = (OBJSIZE_16 << 14) | (OBJSHAPE_WIDE << 12) | (32*8>>5),
00234 SpriteSize_32x16 = (OBJSIZE_32 << 14) | (OBJSHAPE_WIDE << 12) | (32*16>>5),
00235 SpriteSize_64x32 = (OBJSIZE_64 << 14) | (OBJSHAPE_WIDE << 12) | (64*32>>5),
00237 SpriteSize_8x16 = (OBJSIZE_8 << 14) | (OBJSHAPE_TALL << 12) | (8*16>>5),
00238 SpriteSize_8x32 = (OBJSIZE_16 << 14) | (OBJSHAPE_TALL << 12) | (8*32>>5),
00239 SpriteSize_16x32 = (OBJSIZE_32 << 14) | (OBJSHAPE_TALL << 12) | (16*32>>5),
00240 SpriteSize_32x64 = (OBJSIZE_64 << 14) | (OBJSHAPE_TALL << 12) | (32*64>>5)
00242 }SpriteSize;
00243
00244 #define SPRITE_SIZE_SHAPE(size) (((size) >> 12) & 0x3)
00245 #define SPRITE_SIZE_SIZE(size) (((size) >> 14) & 0x3)
00246 #define SPRITE_SIZE_PIXELS(size) (((size) & 0xFFF) << 5)
00247
00251 typedef enum{
00252 SpriteMapping_1D_32 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_32 | (0 << 28) | 0,
00253 SpriteMapping_1D_64 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_64 | (1 << 28) | 1,
00254 SpriteMapping_1D_128 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_128 | (2 << 28) | 2,
00255 SpriteMapping_1D_256 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_256 | (3 << 28) | 3,
00256 SpriteMapping_2D = DISPLAY_SPR_2D | (4 << 28),
00257 SpriteMapping_Bmp_1D_128 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_128 | DISPLAY_SPR_1D_BMP |DISPLAY_SPR_1D_BMP_SIZE_128 | (5 << 28) | 2,
00258 SpriteMapping_Bmp_1D_256 = DISPLAY_SPR_1D | DISPLAY_SPR_1D_SIZE_256 | DISPLAY_SPR_1D_BMP |DISPLAY_SPR_1D_BMP_SIZE_256 | (6 << 28) | 3,
00259 SpriteMapping_Bmp_2D_128 = DISPLAY_SPR_2D | DISPLAY_SPR_2D_BMP_128 | (7 << 28) | 2,
00260 SpriteMapping_Bmp_2D_256 = DISPLAY_SPR_2D | DISPLAY_SPR_2D_BMP_256 | (8 << 28) | 3
00261 }SpriteMapping;
00262
00266 typedef enum{
00267 SpriteColorFormat_16Color = OBJCOLOR_16,
00268 SpriteColorFormat_256Color = OBJCOLOR_256,
00269 SpriteColorFormat_Bmp = OBJMODE_BITMAP
00270 }SpriteColorFormat;
00271
00272
00273 typedef struct AllocHeader
00274 {
00275 u16 nextFree;
00276 u16 size;
00277 }AllocHeader;
00278
00283 typedef struct OamState
00284 {
00285 int gfxOffsetStep;
00286 s16 firstFree;
00287 AllocHeader *allocBuffer;
00288 s16 allocBufferSize;
00289 union
00290 {
00291 SpriteEntry *oamMemory;
00292 SpriteRotation *oamRotationMemory;
00293 };
00294 SpriteMapping spriteMapping;
00295
00296 }OamState;
00297
00298 #ifdef __cplusplus
00299 extern "C" {
00300 #endif
00301
00303 extern OamState oamMain;
00305 extern OamState oamSub;
00306
00316 void oamInit(OamState* oam, SpriteMapping mapping, bool extPalette);
00317
00322 void oamDisable(OamState* oam );
00327 void oamEnable(OamState* oam );
00328
00335 u16* oamGetGfxPtr(OamState* oam, int gfxOffsetIndex);
00336
00344 u16* oamAllocateGfx(OamState *oam, SpriteSize size, SpriteColorFormat colorFormat);
00345
00351 void oamFreeGfx(OamState *oam, const void* gfxOffset);
00352
00353 static inline
00359 void oamSetMosaic(unsigned int dx, unsigned int dy) {
00360 sassert(dx < 16 && dy < 16, "Mosaic range is 0 to 15");
00361
00362 mosaicShadow = ( mosaicShadow & 0x00ff) | (dx << 8)| (dy << 12);
00363 REG_MOSAIC = mosaicShadow;
00364 }
00365
00366 static inline
00372 void oamSetMosaicSub(unsigned int dx, unsigned int dy){
00373 sassert(dx < 16 && dy < 16, "Mosaic range is 0 to 15");
00374
00375 mosaicShadowSub = ( mosaicShadowSub & 0x00ff) | (dx << 8)| (dy << 12);
00376 REG_MOSAIC_SUB = mosaicShadowSub;
00377 }
00378
00397 void oamSet(OamState* oam, int id, int x, int y, int priority, int palette_alpha, SpriteSize size, SpriteColorFormat format, const void* gfxOffset, int affineIndex, bool sizeDouble, bool hide, bool hflip, bool vflip, bool mosaic);
00398
00405 void oamClear(OamState *oam, int start, int count);
00406
00411 void oamUpdate(OamState* oam);
00412
00421 void oamRotateScale(OamState* oam, int rotId, int angle, int sx, int sy);
00422
00423 static inline
00437 void oamAffineTransformation(OamState* oam, int rotId, int hdx, int hdy, int vdx, int vdy) {
00438 sassert(rotId >= 0 && rotId < 32, "oamAffineTransformation() rotId is out of bounds, must be 0-31");
00439
00440 oam->oamRotationMemory[rotId].hdx = hdx >>12;
00441 oam->oamRotationMemory[rotId].hdy = hdy >>12;
00442 oam->oamRotationMemory[rotId].vdx = vdx >>12;
00443 oam->oamRotationMemory[rotId].vdy = vdy >>12;
00444 }
00445
00450 int oamCountFragments(OamState *oam);
00451
00452 void oamAllocReset(OamState *oam);
00453
00454 unsigned int oamGfxPtrToOffset(OamState *oam, const void* offset);
00455
00456
00457 #ifdef __cplusplus
00458 }
00459 #endif
00460
00461 #endif // _libnds_sprite_h_