目次
概要
本記事では、GBDK-2020とGameboy Tile Designer / Gameboy Map BuilderでGame Boy Color1に対応した背景を表示するまでの流れを記載しております。
筆者はGBDK-2020にもC言語にも疎い状態で本記事を執筆しています。執筆に際しなるべく正確な内容を心がけましたが、誤った認識・理解に基づいている可能性がございます。C言語についても、定石を無視した実装例を掲載しているかもしれません。
もし誤った/不適切な記載を発見された場合、ぜひコメントでご一報ください。
本記事内では「ポケットモンスター金(©1995, 1999 Nintendo/Creatures inc./GAMEFREAK inc.)」内の画像を筆者がトレースした画像を利用しております。元となった画像の著作権は各著作権所持企業に帰属しています。また、本記事内ではトレードマーク(TM)を省略しております。
以下が今回筆者が作成したGBCROMイメージをエミュレーターで動作させた様子です。ポケモン金のポケモンセンター1Fのマップが色つきで表示されています。
流れ
GB2ソフトの開発環境構築
2024/05/06現在、GBソフトの開発に利用できる技術スタックは以下3つに大別できます。
-
アセンブリ言語 + RGBDS
GBのネイティブ言語であるアセンブラで開発する -
C言語 + GBDK-2020
C言語で開発する -
GB Studio
GUIで開発する。プログラミングを必要としない代わり表現に制限がある
プログラミングでGBソフトを作成するにあたり、アセンブリ言語よりC言語のほうが現在では学習の敷居が低いと考えられるので、本記事では2の C言語 + GBDK-2020 を利用します。
各種ツールのインストール
まずは以下の各種ツールをインストールします。
-
GBDK-2020
C言語でGBソフトを開発できるようにするツール一式。Latest
タグの付いているリリースに添付されているAssets
のうち、利用環境にあったファイルをダウンロードしてください。例えば64bitのWindowsであればgbdk-win64.zip
をダウンロードします。
ダウンロード後、WindowsであればC:
、Macであれば/opt
配下でダウンロードした圧縮ファイルを展開したフォルダを配置してください3。
CファイルをROMイメージにビルドする際、lcc
というコマンドを利用します。このコマンドは展開したフォルダgbdk
配下のフォルダbin
に存在しています。コマンドプロンプト/ターミナルでlcc
を利用できるよう、環境変数にC:\gbdk\bin
(Windows)、/opt/gbdk/bin
(Mac)を加えておくことをおすすめします。
-
Gameboy Tile Designer / Gameboy Map Builder
GBの背景およびスプライト(前景)の作成、作成した背景/前景データのCファイル/Hファイルへの変換を行うツール。Tile Designerは背景/前景の最小構成要素である『タイル』、Map Builderは『タイル』を敷き詰めた『マップ』を作成するために利用します。略称はそれぞれ「GBTD」、「GBMB」でありどちらもWindows向けアプリであるため、Macでの利用にはWine(無償)やParallels(有償)といった仮想環境の用意が必要です。
こちらもLatest
タグの付いているリリースに添付されているAssets
にあるGBTD_GBMB_release.zip
をダウンロードし、任意の場所で展開してください。展開したフォルダ内にはGBTD本体(gbtd.exe
)とGBMD本体(gbmb.exe
)が含まれます。
👇 GBTD
👇 GBMB
-
Visual Boy Advance
成果物であるROMイメージファイルで遊ぶために使うGB対応エミュレーター。Windows/Mac/Linux対応。Windowsであれば、多機能さで知られるエミュレーターBGBで代用してもよいでしょう。 -
Visual Studio Code
Cファイルの作成に利用する、テキストエディターの代名詞。サクラエディターをはじめとしたほかエディターでもいいのですが、C言語向け拡張機能をはじめとした便利な機能が利用できるため、VS Codeがおすすめです。
Cファイル作成時にVS Codeの自動補完機能でGBDKの提供する関数・変数も参照されるよう、インクルードパスにC:\gbdk\include
(Windows)、/opt/gbdk/include
(Mac)を加えておくとコーディング時に便利です。
背景タイルの作成/出力
続いてGBTDを使い、背景タイルを作成していきます。
背景タイルの作成
タイル一覧で編集するタイルを選び、画面左側の8×8の方眼にペンツールで左右クリックを使って模様を描いていきます。ドット絵の完成形をイメージしながら描く必要があるため、事前に方眼ノートなどで8×8や8×16など8の倍数で構成されたドット絵を用意しておくとスムーズです。
デフォルトではGBに倣ったモノクロ調のカラーセットになっています。GBC用のタイルを作成するため、View > Color set > Gameboy Color
を選択してください。すると今度は明度の異なる緑4色によるパレットが適用されます。今度はカラーパレットを編集していきます。
View > Palette
をクリックすると、パレットの色を編集できます。GBCでは8種のパレットがあり、パレットごとに4種の色を利用することになります。4種の色はRGBで指定しますが、GBCの特徴上0〜31の32段階で指定します。現代では256段階の16進数で指定することが多いですが、256段階で示されたRGBは各色の数値を8で割ることで32段階に落とし込めます。
以下にGBTDでの作業で留意すべきポイントをまとめました。ご一読の上、ドット絵職人としての腕を振るってください。
- タイル一覧0番目のタイルは、背景のうちタイル指定のない部分に自動で敷き詰められます。そのため、1番から描き進めることをおすすめします
- タイルごとに1パレットを指定することになるため、必然的に1タイルには4色しか利用できません。また、パレットは8つしかないため、全タイルは32色以内の色彩で表現する必要があります
- こまめに保存ましょう。
File > Save As
で名前をつけて保存、File > Save
で上書き保存が可能です - 保存はタイル1枚ごとではなく、 タイル一覧まるごと 記録されます。また、カラーセットとカラーパレットもあわせて保存されます。ファイルの拡張子は
.gbr
です - タイルごとのコピペや、左右/上下反転、塗りつぶし、1行/列ずつの移動などの機能が用意されています。ご活用ください
背景タイルの出力
できあがったタイル一覧をコードから参照できる形にするため出力を行いますが、出力の前にどのような出力を行うかをFile > Export to…
で設定する必要があります。ここで以下の設定を行います。
- Standardタブ
- File
- Filename
出力先の任意のファイルパス。ファイルの種類はGBDK C files
を選択 - Type
出力するファイルの種類。GBDK C file
を選択
- Filename
- Settings
- Label
コーディング時に利用する、出力されたデータが格納された変数の名称。任意の文字列 - Bank
0
のままにする - From / To
利用するタイルの範囲。タイル一覧の番号で指定する - Format
形式の設定。Gameboy 4 color
のままにする - Counter
出力するファイルにタイル数を記録するかどうかの設定。None
のままにする - Export tiles as one unit
おそらく指定範囲のタイルを一つの配列として出力するかどうか。チェックをつける - GB-Compress data
おそらくGB用の圧縮方法でデータを圧縮するか。チェックは外したままにする
- Label
- File
- Advancedタブ
- Colors
- Include palette colors
各パレットの色情報を出力するかどうか。チェックをつける - SGB palettes
SGB(Super Game Boy)向けのパレットを出力するかどうか。None
のままにする - CGB palettes
CGB向けのパレットを出力するかどうか。Constant per entry(エントリーごとに定数を作成)
を選択
- Include palette colors
- Metatiles
おそらくメタ情報を含ませるかどうかの項目だが、今回は触れないままでOK - Split data
出力データを分割するかどうかの項目だが、今回は触れないままでOK
- Colors
以上の設定が終了したら、File > Export
で出力してください。出力されたCファイル、Hファイルはコーディング時に読み込ませて利用することになります。
背景マップの作成/出力
作成したタイルを並べマップデータを作っていきます。
GBMBを開いた時点では利用するタイル群の設定がされていないので、まずFile > Map properties…
からGBTDで作成・保存したGBRファイルを指定します。また、タイルを敷き詰めるキャンバスのサイズもここで指定しておきます。GBCであれば横20マス、縦18マスで画面いっぱいに表示されます。
また、デフォルトではカラーセットがモノクロ調のGameboy Pocket
に設定されています。View > Color set
からGameboy Color
を選択しておきましょう。
設定したタイル群が表示されたタイル一覧から貼りつけるタイルを選択し、ペンツールでキャンバスに右クリックで貼りつけていきます。
以下にGBMBでの作業で留意すべきポイントをまとめました。
- こまめに保存しましょう。GBTDと同じく
File > Save As
で名前をつけて保存、File > Save
で上書き保存が可能です - キャンバスの縮尺、貼りつけたタイルごとに宛てがうパレットの変更や垂直/水平反転、列/行の挿入/削除、塗りつぶしなどの機能が利用できます
背景マップの出力
マップの作成が終わったあとは出力する前に出力の設定をSave > Export to…
で以下のように行う必要があります。
- Standardタブ
- File
- Filename
出力先の任意のファイルパス。ファイルの種類はGBDK C files
を選択 - Type
出力するファイルの種類。GBDK C file
を選択
- Filename
- Settings
- Label
コーディング時に利用する、出力されたデータが格納された変数の名称。任意の文字列 - Section
用途不明。今回は触れないままでOK - Bank
用途不明。今回は0
のままでOK
- Label
- Split data
出力データを分割するかどうかの項目。今回は触れないままでOK
- File
- Location format
タイルの種類以外に併せて出力するデータとそのデータがタイルごとに持たせたいbit数。以下の設定を行う- [Tile number: Low 8]: 8
8bitのタイル番号。後続の[GBC BG Attribute]
を9bit目から始めるため、7bitの[Tile number]
ではなく8bit指定のこの項目を選ぶ - [GBC BG Attribute]: 8
使用するパレットや垂直/水平反転するかといった情報を格納するGBC専用の各種プロパティ。各ビットが示す情報はこちらが詳しい
- Map layout
マップのタイルを横向きに出力するか縦向きに出力するか。今回はRows(横向き)
のままでOK - Plane count
タイル1マスに対して与えるビット数。Planeはあまり聞かない単位だが、1planeは8bitに等しい。出力したいプロパティの総bit数が16であるため、2 planes (16bits)
を選択 - Plane order
マップを出力する際、Planeごとに分割するかどうか。今回はPlaneごとに分割するためPlanes are continues
を選択 - Tile offset
マップに配置したタイルそれぞれのタイル番号に設定した値分加算した番号に対応するタイルとして出力する。ずらす必要がなければ0
のままでOK
- [Tile number: Low 8]: 8
以上の設定を終えれば出力の準備完了です。File > Export
でCファイル/Hファイルを出力しましょう。
背景を表示するコードの作成/出力
ここまでで、背景タイルのCファイルとHファイル、そして背景マップのCファイルとHファイルを作り出せました。これらのファイルと同じディレクトリに空のCファイルを作成し、VS Codeでメインの処理を書いていきます。
背景を表示するコードの作成
記載する内容は以下のとおりです。
- 背景表示に必要なパッケージ、背景タイル/マップの読み込み
- カラーパレットの再定義
- main関数の定義
- パレットの指定
- タイル群の指定
- VRAM 1への切り替え
- GBC用の属性の読み込み
- VRAM 0への切り替え
- マップデータの読み込み
- 背景の表示
- ディスプレイの表示
以上の処理を一つずつ書いていきます。
背景表示に必要なパッケージ、背景タイル/マップの読み込み
#include <gb/gb.h>
#include <gb/cgb.h>
まずGBDK-2020内のGB、GBC特有の機能の利用に必要な関数、変数を参照できるようにgb/gb.h
、gb/cgb.h
をインクルードします。
続けて、背景タイル/背景マップのデータを参照できるようにする為、出力したHファイルをインクルードします。
#include "pokemon_center_tiles.h"
#include "pokemon_center_1f_map.h"
カラーパレットの再定義
続けて、後続のパレットの指定のためにカラーパレットをpalette_color_t
型定数配列に格納し直します。例えば0番目のカラーパレット4色はそれぞれlabelNameCGBPal0c0
、labelNameCGBPal0c1
、labelNameCGBPal0c2
、labelNameCGBPal0c3
というような、<Export to…で指定した変数名>CGBPal<パレット番号(0〜7)>c<カラー番号(0〜3)>
という命名形式の変数に格納されています。
筆者の場合はカラーパレットを0〜5の6つのみを参照すれば問題なかったため、以下のように格納し直しました。
const palette_color_t backgroundPalette[] = {
/* カラーパレット0 */
pokemonCenterTilesCGBPal0c0,
pokemonCenterTilesCGBPal0c1,
pokemonCenterTilesCGBPal0c2,
pokemonCenterTilesCGBPal0c3,
/* カラーパレット1 */
pokemonCenterTilesCGBPal1c0,
pokemonCenterTilesCGBPal1c1,
pokemonCenterTilesCGBPal1c2,
pokemonCenterTilesCGBPal1c3,
/* カラーパレット2 */
pokemonCenterTilesCGBPal2c0,
pokemonCenterTilesCGBPal2c1,
pokemonCenterTilesCGBPal2c2,
pokemonCenterTilesCGBPal2c3,
/* カラーパレット3 */
pokemonCenterTilesCGBPal3c0,
pokemonCenterTilesCGBPal3c1,
pokemonCenterTilesCGBPal3c2,
pokemonCenterTilesCGBPal3c3,
/* カラーパレット4 */
pokemonCenterTilesCGBPal4c0,
pokemonCenterTilesCGBPal4c1,
pokemonCenterTilesCGBPal4c2,
pokemonCenterTilesCGBPal4c3,
/* カラーパレット5 */
pokemonCenterTilesCGBPal5c0,
pokemonCenterTilesCGBPal5c1,
pokemonCenterTilesCGBPal5c2,
pokemonCenterTilesCGBPal5c3,
};
main関数の定義
ついにソフトを起動した際の処理を書いていきます。
void main()
{
// 以降の処理はここに記載
}
パレットの指定
カラーパレットの再定義で定義した配列を使って、背景タイルの描画に使うパレットを指定します。指定にはset_bkg_palette()
関数を利用します。
set_bkg_palette(0, 6, &backgroundPalette[0]);
set_bkg_palette()4
戻り値:void
データ型 | パラメーター名 | 説明 |
---|---|---|
uint8_t |
first_palette |
パレットのうち最初に利用させるものをパレット番号(0 〜7 )で指定する |
uint8_t |
nb_palettes |
利用するパレットの数。最大値は8 - first_palette
|
const palette_color_t |
rgb_data |
カラーパレットのポインター |
GBCの背景タイルの描画に利用するカラーパレットを指定します。gb/cgb.h
をインクルードすることで利用可能
タイル群の指定
GBTDで作成/出力したタイルデータの配列を利用して背景に使うタイル群を指定します。指定にはset_bkg_data()
関数を利用します。
set_bkg_data(0, 53, pokemonCenterTiles);
VRAM 1への切り替え
GBCでは背景の描画に2つのVRAMを利用します。VRAM 0 が通常の背景マップのデータを、VRAM 1 が背景マップで利用されているタイルの属性を司っており、まずはVRAM 1へ属性を書き込むためにVBK_REG
変数に1を代入します。
VBK_REG = 1;
GBC用の属性の読み込み
背景マップで利用されているタイルの属性を指定します。指定にはset_bkg_tiles()
を利用します。属性と言いつつも、通常の背景マップの指定とほとんど同じ記述であり、最後の引数が<Export to…で指定した変数名>PLN1
という命名形式の変数である点以外は画面上の表示位置、表示域を指定する形で変わりません。第3引数、第4引数には<Export to…で指定した変数名>Width
、<Export to…で指定した変数名>Height
という命名形式の変数を利用して指定できます。
set_bkg_tiles(0, 0, pokemonCenter1FMapWidth, pokemonCenter1FMapHeight, pokemonCenter1FMapPLN1);
VRAM 0への切り替え
今度はマップデータを指定するため、VRAMを 0 にします。
VBK_REG = 0;
マップデータの読み込み
そしてマップデータを読み込ませます。属性の指定時とは第5引数以外は同じです。第5引数は<Export to…で指定した変数名>PLN0
という命名形式の変数を利用してください。
set_bkg_tiles(0, 0, pokemonCenter1FMapWidth, pokemonCenter1FMapHeight, pokemonCenter1FMapPLN0);
背景の表示
これまでで背景表示に必要なカラーパレット、背景タイル、背景マップの情報を指定できました。あとは画面に表示するだけです!
まず背景を表示するため、マクロSHOW_BKG
を実行します。
SHOW_BKG;
ディスプレイの表示
最後にディスプレイを表示するため、マクロDISPLAY_ON
を実行します。
DISPLAY_ON;
以上でコードは完成です。
#include <gb/gb.h>
#include <gb/cgb.h>
#include "pokemon_center_tiles.h"
#include "pokemon_center_1f_map.h"
const palette_color_t backgroundPalette[] = {
/* カラーパレット0 */
pokemonCenterTilesCGBPal0c0,
pokemonCenterTilesCGBPal0c1,
pokemonCenterTilesCGBPal0c2,
pokemonCenterTilesCGBPal0c3,
/* カラーパレット1 */
pokemonCenterTilesCGBPal1c0,
pokemonCenterTilesCGBPal1c1,
pokemonCenterTilesCGBPal1c2,
pokemonCenterTilesCGBPal1c3,
/* カラーパレット2 */
pokemonCenterTilesCGBPal2c0,
pokemonCenterTilesCGBPal2c1,
pokemonCenterTilesCGBPal2c2,
pokemonCenterTilesCGBPal2c3,
/* カラーパレット3 */
pokemonCenterTilesCGBPal3c0,
pokemonCenterTilesCGBPal3c1,
pokemonCenterTilesCGBPal3c2,
pokemonCenterTilesCGBPal3c3,
/* カラーパレット4 */
pokemonCenterTilesCGBPal4c0,
pokemonCenterTilesCGBPal4c1,
pokemonCenterTilesCGBPal4c2,
pokemonCenterTilesCGBPal4c3,
/* カラーパレット5 */
pokemonCenterTilesCGBPal5c0,
pokemonCenterTilesCGBPal5c1,
pokemonCenterTilesCGBPal5c2,
pokemonCenterTilesCGBPal5c3,
};
void main()
{
set_bkg_palette(0, 6, &backgroundPalette[0]);
set_bkg_data(0, 53, pokemonCenterTiles);
VBK_REG = 1;
set_bkg_tiles(0, 0, pokemonCenter1FMapWidth, pokemonCenter1FMapHeight, pokemonCenter1FMapPLN1);
VBK_REG = 0;
set_bkg_tiles(0, 0, pokemonCenter1FMapWidth, pokemonCenter1FMapHeight, pokemonCenter1FMapPLN0);
SHOW_BKG;
DISPLAY_ON;
}
背景を表示するコードの出力
背景タイルのCファイル/Hファイル、背景マップのCファイル/Hファイル、背景を表示するコードのCファイルを組み合わせてGBCソフトのイメージに持っていきます。コマンドプロンプト/ターミナルでlcc
コマンドを利用します。まずCファイル3つを中間ファイルであるOファイルに変換し、それらOファイルからGBCソフトイメージを生成します。開発中に何度もGBCソフトのイメージをビルドするような場合はBATファイル(Windows)やSHファイル(Mac)にまとめておくとビルドごとに書くコマンドが少なくて楽です。
lcc -c -o PokemonCenter1FMap.o pokemon_center_1f_map.c
lcc -c -o PokemonCenterTiles.o pokemon_center_tiles.c
lcc -c -o ShowBackground.o ShowBackground.c
lcc -Wm-yn"ShowBackground" -Wm-yc -o ShowBackground.gbc PokemonCenter1FMap.o PokemonCenterTiles.o ShowBackground.o
これでGBC用背景を出力できるようになりました!
Visual Boy AdvanceでGBCイメージを起動すると、本記事の最初に提示された以下の背景が表示されます。
おわりに
すでにGDBKやGBTD/GBMBの利用方法については多くの先達が分かりやすい記事を残していらっしゃいますが、躓きポイントは大量に存在しています。本記事がその躓きを事前に防ぐ/沼から漕ぎ出すための一助になると幸いです。
編集後記
「Analogue Pocket買ったンゴ」
「ポケモン金楽しい〜!!!」
「そういやGBのソフトとか自作できたりするんかな…」カタカタ…
「GBDK…そういうのもあるのか…」
「C言語知らんけど…Javaのお勉強したことあるしいけるやろ(ハナホジ)」
そんなノリで休日2日間を費やした結果背景出力までできたので、メモ代わりに本記事を書きました。その2日間の中で、GBMBでのGBC向けの出力設定で1日沼ってしまいました。インターネットの大海で答えを探し見つけられなかった末、筆者が自身で[Tile number: Low 8]
と[GBC BG Attribute]
の組み合わせでうまく動作することを発見し沼を脱せました。これからGBCの背景出力で困った方の糸口になれたら嬉しいです。