Tutorial.7 スプライト(1) †スプライト †スプライトとは8x8〜64x64サイズの画像を最大128個まで表示し、 今回登場する配置領域、及びデータ構造は以下のとおりです。
![]() キャラクタデータはタイルモードとビットマップモードでは位置が変わるので注意してください。 パレットデータ †データフォーマットはmode3で使った色データと同じです。 Color Palette RAM BG and OBJ palettes are using separate memory regions: 05000000-050001FF - BG Palette RAM (512 bytes, 256 colors) 05000200-050003FF - OBJ Palette RAM (512 bytes, 256 colors) Color Definitions Each color occupies two bytes (same as for 32768 color BG modes): Bit Expl. 0-4 Red Intensity (0-31) 5-9 Green Intensity (0-31) 10-14 Blue Intensity (0-31) 15 Not used OBJ Palette RAMが今回のターゲットです。 キャラクタデータ †キャラクタデータは、パレット番号を指定した集まりです。
16色の場合、4bitでちょうど16色指定できるのでピッタリのサイズですね。 キャラクタデータの格納 †たとえば以下のキャラクタデータがあったとしましょう。
このとき、キャラクタ番号は 空白 - 0 ! - 1 " - 2 # - 3 (以下略・・・) となります。8x8単位のみを扱うのでしたらこのキャラクタ番号を指定し、 ![]() こちらは先ほどの画像を2倍表示して8x8単位に点線を加えたものです。 ![]() 96, 97, 98・・・と取り出した為、円がきれいに表示されませんでした。 ![]() うまく行きました。 シューティングゲームなどでは頻繁にキャラクタデータの変更を行います。 入れ替えがない場合は2次元が使えます。 取り出す時の形状には、以下のようなサイズがあります。 // スプライトの指定サイズ enum SPRITE_SIZECODE { Sprite_8x8, Sprite_16x16, Sprite_32x32, Sprite_64x64, Sprite_16x8, Sprite_32x8, Sprite_32x16, Sprite_64x32, Sprite_8x16, Sprite_8x32, Sprite_16x32, Sprite_32x64 }; 属性(Object Attribute Memory) †スプライト1つ1つに対して、属性という単位で取り扱います。 今は軽く読み流す程度で結構です。 typedef struct { u16 attr0; u16 attr1; u16 attr2; u16 dummy; } OBJATTR; ![]() OBJ Attribute 0 (R/W) Bit Expl. 0-7 Y-Coordinate (0-255) 8 Rotation/Scaling Flag (0=Off, 1=On) When Rotation/Scaling used (Attribute 0, bit 8 set): 9 Double-Size Flag (0=Normal, 1=Double) When Rotation/Scaling not used (Attribute 0, bit 8 cleared): 9 OBJ Disable (0=Normal, 1=Not displayed) 10-11 OBJ Mode (0=Normal, 1=Semi-Transparent, 2=OBJ Window, 3=Prohibited) 12 OBJ Mosaic (0=Off, 1=On) 13 Colors/Palettes (0=16/16, 1=256/1) 14-15 OBJ Shape (0=Square,1=Horizontal,2=Vertical,3=Prohibited) OBJ Attribute 1 (R/W) Bit Expl. 0-8 X-Coordinate (0-511) When Rotation/Scaling used (Attribute 0, bit 8 set): 9-13 Rotation/Scaling Parameter Selection (0-31) (Selects one of the 32 Rotation/Scaling Parameters that can be defined in OAM, for details read next chapter.) When Rotation/Scaling not used (Attribute 0, bit 8 cleared): 9-11 Not used 12 Horizontal Flip (0=Normal, 1=Mirrored) 13 Vertical Flip (0=Normal, 1=Mirrored) 14-15 OBJ Size (0..3, depends on OBJ Shape, see Attr 0) Size Square Horizontal Vertical 0 8x8 16x8 8x16 1 16x16 32x8 8x32 2 32x32 32x16 16x32 3 64x64 64x32 32x64 OBJ Attribute 2 (R/W) Bit Expl. 0-9 Character Name (0-1023=Tile Number) 10-11 Priority relative to BG (0-3; 0=Highest) 12-15 Palette Number (0-15) (Not used in 256 color/1 palette mode) ![]() スプライト操作の汎用関数 †こちらで用意した関数を通して簡単な(大雑把な)扱いを知ってください。 void SpriteInit(void) { u32 i; for(i=0; i<128; i++) { SpriteMove(i, 240, 160); } } すべてのスプライトを画面外に移動させます。 void SpriteMove(u32 num, s32 x, s32 y) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr1 &= 0xfe00; sp->attr0 &= 0xff00; sp->attr1 |= (x & 0x01ff); sp->attr0 |= (y & 0x00ff); } スプライトの移動処理です。 void SpriteSetSize(u32 num, u32 size, u32 form, u32 col) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr0 &= 0x1fff; sp->attr1 &= 0x3fff; sp->attr0 |= col | form | (160); sp->attr1 |= size | (240); } スプライトの形状と色数を変更します。 void SpriteSetChr(u32 num, u32 ch) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr2 &= 0xfc00; sp->attr2 |= ch; } スプライトで使用するキャラクタ番号を指定します。
スプライトの表示例 †#include "lib/gba.h" #include "res.h" //--------------------------------------------------------------------------- void WaitForVsync(void) { while(*(vu16*)0x4000006 >= 160) {}; while(*(vu16*)0x4000006 < 160) {}; } //--------------------------------------------------------------------------- void SpriteMove(u32 num, s32 x, s32 y) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr1 &= 0xfe00; sp->attr0 &= 0xff00; sp->attr1 |= (x & 0x01ff); sp->attr0 |= (y & 0x00ff); } //--------------------------------------------------------------------------- void SpriteSetSize(u32 num, u32 size, u32 form, u32 col) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr0 &= 0x1fff; sp->attr1 &= 0x3fff; sp->attr0 |= col | form | (160); sp->attr1 |= size | (240); } //--------------------------------------------------------------------------- void SpriteSetChr(u32 num, u32 ch) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr2 &= 0xfc00; sp->attr2 |= ch; } //--------------------------------------------------------------------------- void SpriteInit(void) { u32 i; for(i=0; i<128; i++) { SpriteMove(i, 240, 160); } } //--------------------------------------------------------------------------- int main(void) { // モード設定 SetMode(MODE_0 | OBJ_ENABLE | OBJ_1D_MAP); u16* oam = OBJ_BASE_ADR; // キャラクタデータ u16* pal = OBJ_COLORS; // パレットデータ u32 i; for(i=0; i<sprTilesLen/2; i++) { oam[i] = sprTiles[i]; } for(i=0; i<16; i++) { pal[i] = sprPal[i]; } SpriteInit(); // !(ビックリマーク)の表示 SpriteSetSize(0, OBJ_SIZE(Sprite_8x8), OBJ_SQUARE, OBJ_16_COLOR); SpriteSetChr (0, 1); SpriteMove (0, 20, 20); u32 x = 40; u32 y = 40; // 円の表示 SpriteSetSize(1, OBJ_SIZE(Sprite_32x32), OBJ_SQUARE, OBJ_16_COLOR); SpriteSetChr (1, 224); SpriteMove (1, x, y); for(;;) { WaitForVsync(); if( !(REG_KEYINPUT & KEY_UP) ) y--; if( !(REG_KEYINPUT & KEY_DOWN) ) y++; if( !(REG_KEYINPUT & KEY_LEFT) ) x--; if( !(REG_KEYINPUT & KEY_RIGHT)) x++; SpriteMove (1, x, y); } } SetMode(MODE_0 | OBJ_ENABLE | OBJ_1D_MAP); スプライトを使用するにはOBJ_ENABLEを入れます。 // !(ビックリマーク)の表示 SpriteSetSize(0, OBJ_SIZE(Sprite_8x8), OBJ_SQUARE, OBJ_16_COLOR); SpriteSetChr (0, 1); SpriteMove (0, 20, 20); 引数の1番目はスプライト番号を表しています。ビットマップモードの場合、 動作画面とデバッグ画面 †![]() ![]() キー入力できます。適当に動かしてみてください。 履歴 †
|