PauseFlagに限らずSGLのシステム変数は、extern宣言して使ってください。
があります。
これは SL_DEF.H の中で記述されています。
この関数またはこれらのマクロを使用することでスプライトのカラー演算
の割合を設定することができます。
slPutSpriteを用いて、同じ座標に表示する場合に任意にプライオリティーを 付ける方法はないのでしょうか。
SOFTIMAGEのExportでのデフォルトでは、ソートの設定はSORT_CENに
なっていますが、これをSORT_MAXにするとZソーティングの基準点から
一番遠い所になりますので若干ポリゴンの欠ける位置が近くなります。
slZdspLevelには、0〜7迄の値が入ります。値が大きいほど手前まで
表示されます。
SGL内部では、ポリゴンの座標に対して、Z軸に対してはクリッピングを掛けますがXY成分に関しては、
クリッピング処理を行なっていないため、フレームバッファ空間に対して
オーバーフローやアンダーフローを起こし、画面にノイズが
走ってしまうことがあります。これを避けるための処理になります。
具体的には、手前に来たポリゴンを分割してしまうということです。
勿論テクスチャが貼ってあればテクスチャも分割する為アプリケーション側
で、一つのモデルに対して複数のモデルパターンとテクスチャを用意する必要
があります。
つまり、
slDispSprite(...); slSynch(); OtherProc(); ←この時点で表示されている筈だが slSynch(); OtherProc(); ←実際にはここで表示されているように見える
という現象がおきるのです。どおしてでしょう?
これは、VDP1がダブルフレームバッファを持っているためで、ユーザーが
コマンドバッファに書き込んだ内容は、次のフレームで裏フレームバッファに
書き込みます。
このため、裏バッファの内容を表示するのは、
コマンドバッファに書き込んだ次の次のフレームということになります。
つまり、
slDispSprite(...); slSynch(); ←この時、裏のフレームバッファにコマンドの内容を反映。 OtherProc(); slSynch(); ←この時点で裏のフレームバッファの内容をVDP2の映像と重ねる。 OtherProc(); ←ここで表示される。
といった流れになります。
つまり、通常の利用方法ではFormTblの内容は1単位処理内で変更を加えることは 出来ません。
これを回避するには以下にあげる2つの方法が考えられます。
ComRdPtr、ComWrPtr
という2つのシステム変数の内容を参考にします。
この2つのシステム変数は、スレーブがslPutPolygon等の処理を
行なっている時に参照されるデータで両者が一致している時、
スレーブは、SGLの処理を行なっていません。
但しスレーブCPUは常にキャッシュ領域を見ていますので、比較する アドレスもキャッシュの中でなくてはなりません。つまり、システム変数
ComWrPtr、ComRdPtr
をそのまま見るのではなく
ComWrPtr + 0x20000000
ComRdPtr + 0x20000000
を見なければなりません。
これらのレジスタは、スレーブがコマンドのリード及びライトを
行っているアドレスを指しておりこれらの値が同じであれば、スレーブは
待機状態であるとみることができますので、まずこの2つのレジスタの
値を比較し同じ値になるのを待ちます。
次にスレーブ側からslCashePurgeを実行しキャッシュをパージします。
これには、slSlaveFunctionを使います。
例えば、
slInitStstem( TV_320x224, TEXTURE_TBL, 1 )
のように、FormTblを指定した場合、後の変更を、
TEXTURE_TBL[ i ].Hsize = ....
TEXTURE_TBL[ i ].Vsize = ....
TEXTURE_TBL[ i ].CGadr = ....
TEXTURE_TBL[ i ].HVsize = ....
という風に変更するやり方です。この方法を採った場合、スレーブの状態を 把握しておく必要はなくなりますが、最初にslInitSystemに引き渡す段階で 充分なTEXTURE構造体配列のスペース(つまり表示スプライトのMAX)を 用意しておく必要があります。
※尚、キャラクタデータの転送タイミングによっては、表示するキャラクタが 化けることがあります。これは、VDP1がキャラクタデータをフレームバッファ に転送時、(まだ使用しているにも関わらず)VRAMのデータがキャラクタデータ 転送によって書き変えられている為と思われます。
そのようなことを避ける為にもキャラクタデータやルックアップテーブルデータ グーローデータの転送などは、slIntFunctionで指定する関数内で行なうか、 VDP1の描画終了を待って転送するなどしてください。
VDP1の描画終了を知るには、VDP1の転送終了状態レジスタ (VDP1ユーザーズマニュアル・4.6 転送終了状態レジスタを参照) を見ることで判断できます。
また、スプライトとスクロールのプライオリティ以外にも、両者間のシャドウや
カラー演算等も設定することができます。
この、スプライトの種類のことをVDP2でスプライトタイプと呼びます。
スプライトタイプはVDP1の設定時に各スプライト単位に与えることができます。
SGLでは、この設定をカラーパレットの設定の際行なうことができます。
以下に例を示しましょう。
まず、使用するスプライトタイプを選択します。
デフォルトでは、スプライトタイプ3です。変更するには、
slSpriteType()関数に引数にスプライトタイプを入れて呼び出します。
次に
#define PrioNo0 (0<<12) #define PrioNo1 (1<<12) #define PrioNo2 (2<<12) #define PrioNo3 (3<<12) #define PrioNo4 (4<<12) #define PrioNo5 (5<<12) #define PrioNo6 (6<<12) #define PrioNo7 (7<<12)
が定義されていたとします。
・ポリゴンの場合
ATTRIBUTE( Single_Plane, SORT_CEN, tex1, PrioNo4|0x0010, No_Gouraud,..ここでポリゴンのプライオリティナンバを4に設定しています。 つまりパレット番号にORを取る形で、プライオリティナンバ0〜7迄を設定 できます。
・slPutSprite、slDispSprite*の場合
SPR_ATTRIBUTE( 0, SprType6|0x0000, No_Gouraud, CL256Bnk, sprNofilp );
これも同様にパレットの指定の際にスプライトタイプ6を使うことを 指定しています。
以上いずれの場合も、ATTR、SPR_ATTR構造体のcolnoメンバに指定します。
・slSetSpriteの場合
SPRITE spr; spr.CTRL = FUNC_Sprite; spr.PMOD = MSBOn | WindowIn | MESHoff | ECenb; spr.COLR = PrioNo2 | 0x0020; : :というように、VDP1のコマンドテーブルのカラー制御ワードにパレットと 一緒に(これもORで)プライオリティナンバ(この場合2)を指定します。
また、各スプライトタイプに関するプライオリティの設定は、slPriorityまたは、
slPrioritySpr?関数を使います。(slPrioritySpr?はマクロ。)
用例としては、
slPriority( scnSPR6, 5 );
或は、
slPrioritySpr6( 5 );
とします。
スクロール側は、slPriorityNBG?やslPriorityRBG0などの関数を使います。
このこと自体はセガサターンの仕様ですのでどうしようもありませんが、ドットが ずれるのを回避するには、プログラムで回転に合わせて表示位置を変えるか、 スプライトデザインを設計する際に、回転によってドットがずれることを 予め考慮した図形を書くかして対応してください。
これはハードウェアが指定した表示サイズよりも1ドット大きく表示してしまう ためで、これを避けたい場合には スケールに 0.99999 を指定してください。 この値は、SL_DEF.H で ORIGINAL というマクロにより定義されています。