1: 2004-01-22 (木) 23:28:42 [5] | |||
---|---|---|---|
Line 1: | Line 1: | ||
+ | [[introx]] | ||
+ | |||
+ | "mt_xor1.c"の解説 | ||
+ | 2004/01/22 | ||
+ | ベイサイド(bayside_yokohama@yahoo.co.jp) | ||
+ | |||
+ | このドキュメントは、"mt_xor1.c"の説明だけをするものです。最初に読むべきドキュ | ||
+ | メントではありません。最初に読むべきドキュメントは"document.txt"です。"mt_xor0 | ||
+ | .c"との違いは32ビットグラフィックボックスを使うことです。 | ||
+ | |||
+ | |||
+ | 1.アルゴリズム | ||
+ | |||
+ | 今まで説明してきた描画方法は点を打つとか線を引くというものでした。しかし実際 | ||
+ | のプログラムでは、もっと込み入ったことがやりたいというのはよくあることです。そ | ||
+ | の場合、あたかもビデオメモリにアクセスするように自由に読み書きできれば、なにか | ||
+ | と便利でしょう。・・・ここでは、そういうアクセス方法を説明します。 | ||
+ | |||
+ | このアクセス方法は2つの手順で構成されます。まず、指定されたバッファ内に自由に | ||
+ | 読み書きします。このバッファはグラフィックボックスに対応しており、1バイトが1ド | ||
+ | ットになっています(パックドピクセル)。そして一通りのアクセスが済んだらいじった | ||
+ | 部分をflushします。flushというのは、メモリ内のバッファの内容を画面に確実に反映 | ||
+ | させる方法だと理解してください。この操作をしなくてもOS側の都合でバッファの内容 | ||
+ | が画面に反映されることはありますが、それは保証されていないことですのであてには | ||
+ | できません。いじったら必ずflushしてください(リードアクセスしかしていないときは | ||
+ | flushしなくてもよい)。 | ||
+ | |||
+ | グラフィックボックスのバッファ構造は、(int *) gbox + 16から後ろのxsize * ysi | ||
+ | ze * 4がそっくりそのままバッファになっています。単純明快です。詳しいことはソー | ||
+ | スをご覧ください。 | ||
+ | |||
+ | このプログラムはその方法でたくさんの点を描画して、ちょっとした「山」を描きま | ||
+ | す。 | ||
+ | |||
+ | |||
+ | 2.ライブラリ関数の説明 | ||
+ | |||
+ | 引数の型については、guigui00.hを参照してください。 | ||
+ | |||
+ | lib_flushgraphbox(opt, win, x, y, sx, sy, skip, p) : | ||
+ | |||
+ | グラフィックボックスをflushします。optは0x8024にしてください。winはグラフィッ | ||
+ | クボックスが所属するウィンドウです。残りのパラメーターが少々ややこしいです。ま | ||
+ | ずグラフィックボックス全体をflushするなら、 | ||
+ | |||
+ | x, y : グラフィックボックスオープン時に指定したx_pos, y_posの値 | ||
+ | sx, sy : グラフィックボックスオープン時に指定したx_size, y_sizeの値 | ||
+ | skip : 必ず0 | ||
+ | p : (int *) gbox + 16 | ||
+ | |||
+ | という風に指定します。しかしいじった範囲がグラフィックボックスのごく一部である | ||
+ | という場合もよくあるでしょう。そんなときこのような全範囲flushをすると処理時間に | ||
+ | おいてかなりの無駄になります。そんな時は部分flushを使います。 | ||
+ | |||
+ | x, y : 部分flushしたい範囲の左上の座標(window内の座標系で指定・・・gboxの | ||
+ | 座標ではない) | ||
+ | sx, sy : 部分flushしたい範囲のサイズ | ||
+ | skip : (グラフィックボックスオープン時に指定したx_size - この時のsx) * 4 | ||
+ | p : x, yで指定した座標に相当するドットを指し示すintポインタ | ||
+ | |||
+ | これをよくご覧になれば分かるように、結局は全範囲flushも部分flushも同じルールで | ||
+ | す。 | ||
+ | |||
+ | もしたとえば画面内でキャラクターが走っているとすれば、まずはバッファにアクセ | ||
+ | スして、元いた場所を背景に戻して移動先にキャラクターを書き込むでしょう。そして | ||
+ | flushすることになります。この場合、移動距離がある程度あれば、flushは2回やるべき | ||
+ | です。つまり移動元の部分と移動先の部分です。移動元と移動先を含むような広範囲のf | ||
+ | lushを1回やることでももちろん代用できますが、flushはOSにとって高負荷な処理です | ||
+ | 。できるだけ狭い範囲に分解してやりましょう。・・・この時以下の2つの方法のどちら | ||
+ | がいいかと迷われるかもしれません。 | ||
+ | |||
+ | 1.移動元書き換え → 移動元flush → 移動先書き換え → 移動先flush | ||
+ | 2.移動元書き換え → 移動先書き換え → 移動元flush → 移動先flush | ||
+ | |||
+ | もちろんどちらの手順でも問題なく実行できますが、どちらかといえば2.の方がおす | ||
+ | すめです。というのは、結局画面に反映されるのはflushの時なので、2.の方法の方が | ||
+ | キャラクターが画面上から消えている時間が短くて済むせいです。もし複数のキャラク | ||
+ | ターが介在しているのなら、まずはバッファ内の書き換えを集中させ、その後にflushを | ||
+ | 集中的にやる方が良いでしょう。 | ||
+ | |||
+ | 3.改造への指針 | ||
+ | |||
+ | このバッファへのアクセスとflushを使えば、かなり自由にグラフィック処理ができる | ||
+ | はずです。しかしflushの際にはVRAMへアクセスすることになり、これは結構重たい処理 | ||
+ | です。広い範囲を細かい時間間隔でflushするのは今のところやらない方がいいでしょう | ||
+ | 。そういう見栄えのするゲームは、OSASKがグラフィックアクセラレーターを使いこなせ | ||
+ | るようになるまではちょっと無理かもしれません。・・・それでもマシンパワーのある | ||
+ | マシンなら、なんとかゲームにはなるかもしれません。 |
(This host) = http://osask.net