VRAMのアドレスのように、システムで一意に決まっている値は#defineしちゃった方がよい。
#define VRAM_TOP 0xa0000
解像度は微妙で、定義しちゃっても良い気がするが、そこは今後の展開を見てみないと
どうなるのかわからない。ただ320と書くよりはべたべたでも定義した方が、後から
見るときに役に立つ。
#define XRESOLUTION 320
#define YRESOLUTION 200
もちろん#define XRESOLUTION320 とかで定義しても良いが、#define CONST320とかは
駄目。ようするに、320という値が解像度ですよ、と宣言することが大事。
できるだけ即値を書かないこと。
同じ理由で、色の#defineも読める形に。
#define BLACK 0 でも良いけど順番に値が入っているから列挙体使っても良いかな。
enum palette_color {
BLACK,
RED, ・・・
};
こうしちゃうと、実際の設定している値0x00ffffと色の対応が取れなくなるのが
ちょっと嫌だけどしょうがない。パレットの定義を変えたら、こっちの色も自動的
に変わるとか、コンパイルでエラーがでてくれたら理想だけど、さっと良い方法が
思いつかない。色テーブルの定義をこの宣言の近くにしてコメントを書こう。
boxfill8の関数もこんな感じで。
void boxfill8(enum palette_color color, int x0, int y0, int x1, int y1)
{
int x, y;
volatile unsigned char *vram_adr;
vram_adr = (volatile unsigned char *)VRAM_TOP;
for(y=y0;y<=y1;y++){
for(x=x0;x<=x1;x++){
*(vram_adr + y * XRESOLUTION + x) = color;
}
}
return;
}
教科書的には、(x,y)か、(x0,y0,x1,y1)を構造体にするべきだけど、そこまで
しなくて良いかな。構造体にすると、座標を渡していることが明確になるので
よりベター。
構造体のポインターを渡すことで高速化のメリットもあるけど、それよりも
引数の意味がはっきりする方が、メリットが大きい。
あと、このコードは引数を間違えると、メモリ空間をどこだろうがお構いなしに
色の値で書き込んでいく。かなり危険。本当なら、assertを入れて、範囲チェックを
入れたいところだけど、今の環境じゃassertを入れてもどうしようもないので、
とりあえずこのまま。
今日はこんな所。