- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2023-04-12T00:11:06+09:00","","")
* Doc.3 画像加工ツールgritの使い方 [#f485af67]
#freeze
#author("2023-07-01T11:14:53+09:00;2023-05-29T23:45:33+09:00","","")
* メモリエリア [#kdefa676]
ここではザックリと概要のみ説明しますので詳細はGBATEKを読んでください。
** grit [#x985a128]
gritとは、BMP,PNGなどの画像ファイルをGBA用のフォーマットに変換してくれるツールのことです。~
実行ファイルは「C:\devkitPro\tools\bin」にあります。
| エリア | 開始位置 | 終了位置 | 大きさ |
| System ROM | 0000:0000h | 0000:3fffh | 16kb |
| EWRAM | 0200:0000h | 0203:ffffh | 256kb |
| IWRAM | 0300:0000h | 0300:7fffh | 32kb |
| IO RAM | 0400:0000h | 0401:03ffh | 1kb |
| PAL RAM | 0500:0000h | 0500:03ffh | 1kb |
| VRAM | 0600:0000h | 0601:7fffh | 96kb |
| OAM | 0700:0000h | 0700:03ffh | 1kb |
| PAK ROM | 0800:0000h | - | - |
| Cart RAM | 0e00:0000h | - | - |
** 使用方法 [#aac23f78]
使い方はとても簡単です。~
コンソール上でコマンドを入力して、いくつかの変換オプションを指定してあげます。~
makefileに設定することや、バッチ処理として組むことも可能です。以下に簡単な例を表します。~
*** System ROM [#oa891977]
別名BIOSと言われていて、自前の関数群だと思ってください。除算やLZ77圧縮画像を解凍する関数などは使用頻度が高いようです。電源ONした時に一番最初に表示されるタイトルロゴやコードも、この中に含まれます。
- モード0に使用する画像の変換例~
grit.exe image.bmp -gt -gB4 -fts -gu16
| オプション | カテゴリー | 指定内容 |
| -gt | フォーマット | タイル |
| -gB4 | 色 | 16色 |
| -fts | 出力タイプ | GNU asm |
| -gu16 | 配列のサイズ | 16bit |
*** EWRAM [#d49c4d87]
External work RAMの略でゲーム上で使用される画像やコードを置いたりします。もしカードリッジを挿さない状態でマルチブートケーブルを使用した場合、転送されたデータはEWRAM領域に配置されます。
- モード3に使用する画像の変換例~
grit.exe image.bmp -gb -gB16 -fts -gu16
| オプション | カテゴリー | 指定内容 |
| -gb | フォーマット | ビットマップ |
| -gB16 | 色 | 15bitColor |
| -fts | 出力タイプ | GNU asm |
| -gu16 | 配列のサイズ | 16bit |
*** IWRAM [#uaf33fb1]
GBAの中でもっとも高速な領域です。スピードを求められる処理はIWRAMに置くことをお奨めします。ただし大きさが32kbしかないため、何を置くか慎重に選ぶ必要があります。
*** 出力例 [#d3f2d2a1]
上記の例(モード3)での出力結果は次のとおりです。
*** IO RAM [#a514e691]
GBAのグラフィックやサウンド、ボタンなどをコントロールしています。アクセス方法は変数を読む込んだり、書き込んだりする方法と同じです。ヘッダファイルにメモリの位置をdefineしてアクセスします。
- image.h
- libgbaのヘッダファイルより一部抜粋
#define REG_BASE 0x04000000
#define REG_KEYINPUT *(vu16*)(REG_BASE + 0x130) // Key Input
#define REG_KEYCNT *(vu16*)(REG_BASE + 0x132) // Key Control
//======================================================================
//
// image, 240x160@16,
// + bitmap not compressed
// Total size: 76800 = 76800
//
// Time-stamp: 2007-09-07, 16:28:51
// Exported by Cearn's GBA Image Transmogrifier
// ( http://www.coranac.com )
//
//======================================================================
*** PAL RAM [#i7cc4b29]
BG(画面)とスプライトのパレットを設定する領域です。
*** VRAM [#t1210187]
VRAM領域は画面と反映像になっています。数字を書き換えることで画面が即座に変化します。この書き換えは高速である為、画面更新期間(垂直帰線期間)を無視して描画を行った場合、画面がチラついてしまうので注意が必要です。
*** OAM [#za7e6d6c]
スプライトの設定をする領域です。
*** PAK ROM [#u87d0a1b]
カードリッジの領域です。
*** Cart RAM [#w32d752b]
ゲームのセーブデータに使用されます。Cart RAMには様々な種類があってSRAM、EEPROM、Flash ROMなどがあります。自作ゲーム開発では簡単に実装できるSRAMが人気のようです。
** メモリのアクセス [#ga6db0fa]
Address Bus Width and CPU Read/Write Access Widths
Shows the Bus-Width, supported read and write widths,
and the clock cycles for 8/16/32bit accesses.
#ifndef __IMAGE__
#define __IMAGE__
Region Bus Read Write Cycles
BIOS ROM 32 8/16/32 - 1/1/1
Work RAM 32K 32 8/16/32 8/16/32 1/1/1
I/O 32 8/16/32 8/16/32 1/1/1
OAM 32 8/16/32 16/32 1/1/1 *
Work RAM 256K 16 8/16/32 8/16/32 3/3/6 **
Palette RAM 16 8/16/32 16/32 1/1/2 *
VRAM 16 8/16/32 16/32 1/1/2 *
GamePak ROM 16 8/16/32 - 5/5/8 **/***
GamePak Flash 16 8/16/32 16/32 5/5/8 **/***
GamePak SRAM 8 8 8 5 **
#define imageBitmapLen 76800
extern const unsigned short imageBitmap[38400];
Timing Notes:
#endif // __IMAGE__
* Plus 1 cycle if GBA accesses video memory at the same time.
** Default waitstate settings, see System Control chapter.
*** Separate timings for sequential, and non-sequential accesses.
One cycle equals approx. 59.59ns (ie. 16.78MHz clock).
All memory (except GamePak SRAM) can be accessed by 16bit and 32bit DMA.
表のRead, Writeは、そのメモリにアクセスできるビット単位を表しています。よくみるとVRAMは8bit単位で読めるが、8bit単位で書き込めないことがわかります。これはハードウェアの制約なので十分注意してプログラミングしなくてはなりません。エミュレータで動くが実機で動かない、というよくあるハマりポイントの1つです。また、CyclesはIWRAMが1/1/1に対して、GamePak ROMは5/5/8なのでアクセススピードだけでも5倍違うということが分かります。忘れずに覚えておいてください。
- image.s
** 指定したいメモリ位置にコードを置く方法 [#k1c08154]
自分の書いたコードを指定したメモリ位置に置くにはマクロを使います。使い方は次のとおりです。
@=======================================================================
@
@ image, 240x160@16,
@ + bitmap not compressed
@ Total size: 76800 = 76800
@
@ Time-stamp: 2007-09-07, 16:28:51
@ Exported by Cearn's GBA Image Transmogrifier
@ ( http://www.coranac.com )
@
@=======================================================================
.section .rodata
.align 2
.global imageBitmap @ 76800 unsigned chars
imageBitmap:
.hword 0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F
.hword 0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F,0x4A5F
...(以下略)
- libgbaのgba_base.hより抜粋
#define IWRAM_CODE __attribute__((section(".iwram"), long_call))
#define EWRAM_CODE __attribute__((section(".ewram"), long_call))
#define IWRAM_DATA __attribute__((section(".iwram")))
#define EWRAM_DATA __attribute__((section(".ewram")))
#define EWRAM_BSS __attribute__((section(".sbss")))
#define ROM_DATA __attribute__((section(".roda")))
注意点として画像ファイルの名前がそのまま変数名に使われます。~
image.bmpを変換すると''image''BitmapLen、''image''Bitmapとなります。~
// IWRAM領域
IWRAM_CODE void SpriteInit()
{
//
}
画像サイズを奇数でつくった場合はgritがアライメントを考慮してサイズ変更します。
作る前から余計な苦労をしない為にも画像データは偶数で統一してください。
// EWRAM領域
EWRAM_CODE void SpriteInit()
{
//
}
** grit-readme.txt [#d4218655]
オプションは一読する価値がありますので時間があったときにでも読んでおくことをオススメします。~
[[https://www.coranac.com/files/grit-readme.txt]]
// ROM領域(指定なし)
void SpriteInit()
{
//
}
** demo project [#e28bcaad]
公式サイトには使い方を説明したソースコードがあるのでダウンロードしてみることをおすすめします。~
コンパイルが面倒という方は[[こちら:http://akkera102.sakura.ne.jp/test/gritdemo.zip]]をどうぞ。~
#ref(clip_1.png,nolink)
ヘッダファイル(.h)内のプロトタイプ宣言にも同じように指定することを忘れないでください。一方、変数の定義は次のように指定することができます。指定なしの場合、IWRAMになるので注意してください。
u32 test1 EWRAM_BSS; // EWRAM領域
u32 test2 IWRAM_DATA; // IWRAM領域
u32 test3; // IWRAM領域(指定なし)
** 履歴 [#k390a23f]
- 2023/04/11
- 2014/10/28
- 2007/09/07
ファイルは「C:\devkitPro\libgba\include\gba_base.h」([[github:https://github.com/devkitPro/libgba/blob/master/include/gba_base.h#L99]])内で定義されています。正しくメモリ上に置かれているか確認する方法については、コンパイル後に生成されるマップファイル(.map)を読んでください。
** 履歴 [#ocd95ce7]
- 2023/04/12
- 2007/09/11