English
SGL User's ManualPROGRAMMER'S TUTORIAL
戻る進む
PROGRAMMER'S TUTORIAL

9.コントローラ入力


 本章では、セガサターンのデータ入力用デバイスの認識法と実際の動作を、セガサターンの代表的な入力用デバイスであるセガサターンPADを用いて解説します。
セガサターンPADには4つの方向を表す方向キー、ABCXYZの各ボタン、コントローラ上部にあるLRボタン及びスタートボタンが入力装置として存在します。
これらコントローラの各入力装置を用いて入力されるデータが、どの様にセガサターン内部で判断されているかを、サンプルプログラムと共に解説していきます。

9-1. セガサターンで使用される入力系

 セガサターンでは、入力ポートに接続された各種データ入力用デバイスからのデータを受けとり、それらのデータをプログラムに反映させることができます。

セガサターンで主に使用されるデータ入力用デバイスは、セガサターンPADと呼ばれる、本体付属のコントロールPADです
セガサターンPADは、4方向を指すように配置された方向キー、スタートボタン、ABCボタン、XYZボタン、LRボタンで構成される入力デバイスです。

図9-1 入力用デバイス例(セガサターンPAD)

●セガサターンPADの場合、以下のデータ入力が可能です。

 また、セガサターンPAD以外にもセガサターンでは表9-1のような入力用デバイスをサポートしています。
ただし、この表に含まれるデバイスの中には、現在発売されていないもの(将来的には発売の予定あり)もあるので注意してください。

表9-1 入力装置一覧
 属 性 
     名  称     
     入 力 構 成     
      備  考      
デジタル セガサターンPAD方向キー、スタート、8ボタンセガサターン標準パット
セガサターンマウスXY移動量、スタート、3ボタンマウス移動量は、絶対値としてデータ格納
メガドラ3ボタンパット方向キー、スタート、3ボタンセガタップで接続可能
メガドラ6ボタンパット方向キー、スタート、6ボタンセガタップで接続可能
アナログ アナログジョイスティック
(ミッションスティック)
方向レバー、スタート、8ボタン移動量は、符号なしA/D出力の絶対値
特殊 セガサターンキーボードIBMキーボードとの互換性あり
補助装置 セガサターン6Pマルチタップコネクト数6
セガタップコネクト数4メガドラPADの接続に使用
注)各入力装置の詳細は“HARDWARE MANUAL/SMPCユーザーズマニュアル”を参照してください。

9-2. 実際の動作

 入力ポートに接続された入力用デバイスは、デバイスの入力装置(方向キーやボタンなど)がONになると、セガサターン本体に向けて信号を発信します。
セガセガサターンはこの信号を受けて、システムに用意されたデバイス用ビットを変化させ、この変化を読みとることで、プログラマは入力用デバイスの状態を読みとることができます。
そこで本章では、セガサターンの代表的な入力用デバイスであるセガサターンPADを用いて、実際の動作内容を解説していきます。

入力系に使用されるビット

 入力ポートに接続されたデバイス(セガサターンPAD等)はシステムにより認識され、各デバイスに応じた一定の領域がシステム中に確保されます。
この領域中には、デバイス種認識用ビット列(各デバイス固有)であるペリフェラルID(8bit)とそれに続く入力状態ビット列が含まれます。
入力状態用ビット列は1データ列8bitで構成され、接続されているデバイスに必要な分のデータ列が用意されます。
入力状態用ビット列のビット値は、入力がない場合は1の状態を保ち、入力があった時(キーまたはボタンが押されている間)だけ状態を0に変化します。

 セガサターンPADは次のようなビットの集合として処理されます。

表9-2 セガサターンPADのペリフェラルデータフォーマット
bit7bit6bit5bit4bit3bit2bit1bit0
ペリフェラルID
1st DATA Start
2nd DATA
注)2nd DATAの末尾3ビットは、未使用のため便宜上1になっています。

参 照:
セガサターンPAD以外の入力用デバイスのペリフェラルデータフォーマットについては、
「HARDWARE MANUAL」/「SMPCユーザーズマニュアル」■3.3 サポートペリフェラルデータフォーマット
を参照してください。

データフォーマットの格納について

 各デバイスの状態を表すビット列は、システムにより指定された領域中に自動的に格納されます。

ペリフェラルとは

 ペリフェラルとは、入出力など全ての周辺機器の総称であり、ペリフェラルIDとは周辺機器識別用のIDのことを言います。

入力によるビット動作

 入力ポートに接続されたデバイスの情報は、ペリフェラルIDとそれに続くデータ列(デバイスの入力状態を示す)の集合としてシステム領域中に確保されます。
以後、デバイスの状態変化は指定領域の状態変化として表現され、プログラマはこの領域の状態を照合するだけで入力用デバイスからの情報を受け取ることができます。

 図9-2は、セガサターンPADのデバイス情報の内、ペリフェラルID部分を除いた純粋なデバイス状態情報のみを抽出し、16bit長のデータ列に展開したものです(SGLがペリフェラルデータとして出力するデータもこの型に展開されている)。
また、セガサターンPAD以外のデバイスの場合も、実際のデバイス処理に利用するのは、この部分だけ(ただし、デバイスによりデータ長は異なる)になります。
入力状態ビットは、入力が全くない場合は全て1で表され、入力があった場合(キーまたはボタンが押されている間)のみ、入力装置に応じたビットが0に変化します。

図9-2 セガサターンPADの入力状態ビット配列(16bit表示)

 図9-3は、セガサターンPADにおいて、入力がまったくない状態から、順次入力があった場合の状態ビット列(16bit)の変化を表したものです。

図9-3 入力状態ビット列の変化(セガサターンPAD)

SGLにおけるデバイス情報の扱い

 SGLの場合、入力ポートに接続されたセガサターンPADの情報は、システム変数“Smpc_Peripheral[n]”(n=0〜29)に格納されます。

 入力ポート1および入力ポート2に現在接続されているデバイスの合計数は、システム変数“Per_Connect1”および“Per_Connect2”に格納されます。
また、マルチタップが接続されている場合は、デバイス情報は“Smpc_Peripheral[n]”(n=0〜14, 15〜29)の領域に格納されます。

 システム変数“Smpc_Peripheral[ ]”には、システムで定義されたPerDigital型の構造体が格納され、構造体の各メンバには下図のような情報が含まれています。

図9-4 “PerDigital”構造体の定義
● PerDigital構造体の定義内容 ●

typedef struct{		/* デジタルデバイス */
	Uint8	id;	/* ペリフェラルID */
	Uint16	data;	/* 現在のペリフェラルデータ */
	Uint16	push	/* 押されたスイッチのデータ */
	Uint16	pull	/* 離されたスイッチのデータ */
}PerDigital;

注)上記構造体は、システム付属のヘッダファイル“sl_def.h”内で定義されています。

data:16bit長のペリフェラルデータ(現在のビット状態を示す)
push:16bit長のペリフェラルデータ(入力が実行された瞬間のみビットを変化させる)
pull:16bit長のペリフェラルデータ(入力が解除された瞬間のみビットを変化させる)
id  :デバイスのペリフェラルIDを示す8bitのデータ列

 ペリフェラルデータとは、前述したデータの集合の内、ペリフェラルIDを除いた、入力状態のみを表すビットの集合であり、セガサターンPADの場合、入力状態ビットを16bit長に展開した形で表されます。

ペリフェラルデータ出力について

 ここで紹介したセガサターンPADのデータを示す構造体のメンバは、ペリフェラルID(8bit)と入力装置のスイッチのON/OFF情報(16bit)だけから構成されていますが、セガサターンPAD以外のデバイスに対応した構造体が必ずしも同じとは限りません。
例えば、ポインティングデバイスであるセガサターンマウスの場合、ペリフェラルデータは、デジタルデバイスとしてのスイッチのON/OFF(16bit)の他に、マウスポインタのX座標およびY座標を保持しています。 ただし、すべてのデバイスにおいて構造体の大きさが統一されているため、セガサターンマウスのデータをセガサターンPAD型として参照することも可能です。

注意
ペリフェラルに関する詳細は、“HARDWEAR MANUAL vol.1”及びシステム付属のヘッダファイル“sl_def.h”を参照してください。

入力データの判別

 デバイスからの入力情報の判別は、前述したペリフェラルデータと、次に説明するアサインデータとの照合で行います。
アサインデータはシステム付属のヘッダファイル“sl_def.h”中で定義され、例えばセガサターンPADの各入力装置に対応したアサインは次図のように定義されています。

図9-5 アサインデータの#define値(セガサターンPAD)
● パットアサイン ●
#define	PER_DGT_KR	(1<<15)	/* 方向キー(→) */
#define	PER_DGT_KL	(1<<14)	/* 方向キー(←) */
#define	PER_DGT_KD	(1<<13)	/* 方向キー(↓) */
#define	PER_DGT_KU	(1<<12)	/* 方向キー(↑) */
#define	PER_DGT_ST	(1<<11)	/* スタートボタン */
#define	PER_DGT_TA	(1<<10)	/* Aボタン    */
#define	PER_DGT_TC	(1<<9)	/* Cボタン    */
#define	PER_DGT_TB	(1<<8)	/* Bボタン    */
#define	PER_DGT_TR	(1<<7)	/* Rトリガー   */
#define	PER_DGT_TX	(1<<6)	/* Xボタン    */
#define	PER_DGT_TY	(1<<5)	/* Yボタン    */
#define	PER_DGT_TZ	(1<<4)	/* Zボタン    */
#define	PER_DGT_TL	(1<<3)	/* Lトリガー   */

 これらアサインは、ペリフェラルデータとの照合に用いるので、各デバイスのペリフェラルデータ長に対応しており、例えばセガサターンPADのAボタン用アサインは次図のように展開されます(16bit長)。また、アサインデータは、判別する入力装置に対応した位 のビットを1、その他のビットを0に設定してあります。

図9-6 パッドアサインの内容(PER_DGT_TAの場合)

注)Aボタン入力があったときに動作するのと同じ位のビット(第10ビット)のみ、1になっている

 セガサターンPADの場合、入力装置は単純なスイッチのON/OFFで構成されるので、アサインデータとペリフェラルデータの論理演算で、スイッチの状態が確認できます。

 図9-7はペリフェラルデータとアサインデータのAND演算で入力状態を確認した例です。 アサインデータが指定する入力装置がONであれば、演算結果として0が出力されます。

 サンプルプログラムでもこの方法が採用され、パッドアサインの指す入力装置がONの状態にあれば、画面にスプライトを表示するように設計してあります。

図9-7 アサインデータを用いた入力状態の確認

 また、ここではペリフェラルデータとアサインデータのAND演算でデータ照合を行いましたが、当然のことながら、必ずしもこの方法を採択する必要はありません。

9-3. サンプルプログラム

 サンプルプログラム(リスト9-1)は、コントローラ入力のテストのために作成されたものです。
プログラムは、画面にセガ サターンPADを模したグラフィックを表示し、コントローラ入力があった場合、コントローラ入力に対応した位置のボタン上に指示マーク(指の形)を表示させます。
また、当プログラムでは、指示マークなどにスプライトを使用しています。

リスト9-1 sample_9_1:入力テスト(main.c)


/*----------------------------------------------------------------------*/
/*	Pad Control							*/
/*----------------------------------------------------------------------*/
#include	"sgl.h"
#include	"sega_sys.h"

#define		NBG1_CEL_ADR		( VDP2_VRAM_B1 + 0x02000 )
#define		NBG1_MAP_ADR		( VDP2_VRAM_B1 + 0x12000 )
#define		NBG1_COL_ADR		( VDP2_COLRAM + 0x00200 )
#define		BACK_COL_ADR		( VDP2_VRAM_A1 + 0x1fffe )
#define		PAD_NUM			13

static Uint16 pad_asign[] = {
	PER_DGT_KU,
	PER_DGT_KD,
	PER_DGT_KR,
	PER_DGT_KL,
	PER_DGT_TA,
	PER_DGT_TB,
	PER_DGT_TC,
	PER_DGT_ST,
	PER_DGT_TX,
	PER_DGT_TY,
	PER_DGT_TZ,
	PER_DGT_TR,
	PER_DGT_TL,
};

extern pad_cel[];
extern pad_map[];
extern pad_pal[];
extern TEXTURE tex_spr[];
extern PICTURE pic_spr[];
extern FIXED stat[][XYZS];
extern SPR_ATTR attr[];
extern ANGLE angz[];

static void set_sprite(PICTURE *pcptr , Uint32 NbPicture)
{
	TEXTURE *txptr;
 
	for(; NbPicture-- > 0; pcptr++){
		txptr = tex_spr + pcptr->texno;
		slDMACopy((void *)pcptr->pcsrc,
			(void *)(SpriteVRAM + ((txptr->CGadr) << 3)),
			(Uint32)((txptr->Hsize * txptr->Vsize * 4) >> (pcptr->cmode)));
	}
}

static void disp_sprite()
{
	static Sint32 i;
	Uint16 data;

	if(!Per_Connect1) return;
	data = Smpc_Peripheral[0].data;

	for(i=0;i<PAD_NUM;i++){
		if((data & pad_asign[i])==0){
			slDispSprite((FIXED *)stat[i],
				(SPR_ATTR *)(&attr[i].texno),(ANGLE)angz[i]);
		}
	}
}

void ss_main(void)
{
	slInitSystem(TV_320x224,tex_spr,1);
	slTVOff();
	set_sprite(pic_spr,1);
	slPrint("Sample program 9.1" , slLocate(9,2));
	
	slColRAMMode(CRM16_1024);
	slBack1ColSet((void *)BACK_COL_ADR , 0);

	slCharNbg1(COL_TYPE_256 , CHAR_SIZE_1x1);
	slPageNbg1((void *)NBG1_CEL_ADR , 0 , PNB_1WORD|CN_12BIT);
	slPlaneNbg1(PL_SIZE_1x1);
	slMapNbg1((void *)NBG1_MAP_ADR , (void *)NBG1_MAP_ADR , (void *)NBG1_MAP_ADR , (void *)NBG1_MAP_ADR);
	Cel2VRAM(pad_cel , (void *)NBG1_CEL_ADR , 483*64);
	Map2VRAM(pad_map , (void *)NBG1_MAP_ADR , 32 , 19 , 1 , 256);
	Pal2CRAM(pad_pal , (void *)NBG1_COL_ADR , 256);

	slScrPosNbg1(toFIXED(-32.0) , toFIXED(-36.0));
	slScrAutoDisp(NBG0ON | NBG1ON);
	slTVOn();
	
	while(1) {
		disp_sprite();
		slSynch();
	} 
}

9-4. サンプルで使用されたライブラリ関数

 ここでは、サンプルプログラムで使用されたライブラリ関数の内、ここまでの章で解説されなかったものの中で特に重要と思われるものについて簡単な紹介を行います。また同時に、それら関数に関係する幾つかの関数も紹介します。

スプライト関数

 スプライトを表示するための関数です。
スプライトとは、スクロールと異なり、より小さな単位で複数のものを自由に動かして表示させたいとき使用するグラフィックデータ種です。
スプライトは、2Dグラフィックスを利用したゲームの動体キャラクタなどに多く使用されます。

【void slDispSprite ( FIXED *pos , ATTR *atrb , ANGLE Zrot ) ;】
位置・スケール・表示角を指定してスプライトを画面に表示します。
パラメータには、XYZ座標値及びスケール値を表す4次元配列FIXED型変数のポインタ、スプライトデータの格納される領域の先頭アドレス、表示角を代入します。
ライブラリ関数“slPutPolygon”と同様にZ値によるソーティングも実行しますが、カレントマトリクスの影響は全く受けません。
また、スケール値に負の値を代入した場合、Zポジションによりスケールを計算した後、パラメータのスケール値の補数を掛け合わせて表示用スケールとします。
例えば、スケール値に-2.0を指定した時、0.5倍で表示されるような位置にスプライトがあれば、実際は1.0倍のスケールで表示され

【void slPutSprite ( FIXED *pos , ATTR *atrb , ANGLE Zrot ) ;】
カレントマトリクスを使用してポジションを算出し、透視変換にあわせてスケーリングされたスプライトを画面に表示します。 パラメータには、XYZ座標値及びスケール値を表す4次元配列FIXED型変数のポインタ、スプライトデータの格納される領域の先頭アドレス、表示角を代入します。 “slDispSprite”と同様に、スプライトは指定されたスケール値でスケーリングされますが、負の値を代入した場合は、スプライトは上下左右反転した状態で画面に表示されます。

【void slSetSprite ( SPRITE *parms , FIXED Zpos ) ;】
ハードウェアに渡すスプライトコントロールコマンドデータを転送リストにセットします。 パラメータには、スプライトデータの格納される領域の先頭アドレス、Z座標位置を代入します。 この関数は、ライブラリ関数では作成できないような変形スプライトや、特定のスプライトにのみ影響するウィンドウの設定をしたい場合などに使用します。

その他関数

 ここで紹介する2つの関数はともに、DMA転送に関わるものです。
サンプルプログラム中では、スプライト用ピクチャーデータの転送(ピクチャーデータ格納領域からキャラクタジェネレータ領域へのデータ転送)に関数“slDMACopy”を使用しています。

【void slDMACopy ( void *src , void *dst , Uint32 cnt ) ;】
CPUに内蔵されたDMAを使用してデータのブロック転送を行います。
パラメータには、転送元メモリ領域の先頭アドレス、転送先メモリ領域の先頭アドレス、ブロック転送量(単位:バイト)をそれぞれ代入します。
この関数は、DMA起動後すぐに転送を終了するため、転送完了を知りたい場合は、“slDMAWait”を使用してください。

【void slDMAWait ( void ) ;】
“slDMACopy”で起動されたDMAの転送終了を待ちます。
“slDMACopy”は常に同じチャンネルを使用してデータ転送を行いますが、本関数を使用すれば、先に実行したDMA転送が実行中であれば転送終了を待ち、転送終了後に次のデータ転送が起動されます。

【void slDMAXCopy ( void *src , void *dst , Uint32 cnt , Uint16 mode ) ;】
ライブラリ関数“slDMACopy”のポインタの動かし方を指定できるようにしたものです。パラメータには、転送元メモリ領域の転送開始アドレス、ブロック転送量(単位 : バイト)、転送モードフラグをそれぞれ代入します。 転送モードフラグには、転送元メモリ領域のアドレスをどうするか、転送先メモリ領域のアドレスをどうするか、転送単位をどうするかを指定します。指定方法は以下のようになります。

図9-8 “slDMAXCopy”のパラメータ代入値(mode)
 転 送 先 
インクリメントデクリメント固定


インクリメントSinc_Dinc_ByteSinc_Ddec_ByteSinc_Dfix_Byte
デクリメントSdec_Dinc_Byte禁止Sdec_Dfix_Byte
固定Sfix_Dinc_ByteSfix_Ddec_Byte禁止
注)上記の値は、"sl_def.h"で定義されています。
注)上記は転送単位を"Byte"としたときの値です。その他の転送単位として"Word"および"Long"を指定できます。

付記 本章に登場したSGLライブラリ関数

 本章では、次表の関数を解説しました。

表9-3 本章に登場したライブラリ関数
関数型
   関 数 名   
     パ ラ メ ー タ    
         機   能         
voidslDispSpriteFIXED *pos,ATTR *atrb,ANGLE Zrot位置・スケール・表示角を指定してスプライト表示
voidslPutSpriteFIXED *pos,ATTR *atrb,ANGLE Zrot透視変換に合わせてスプライト表示
voidslSetSpriteSPRITE *parms,FIXED Zposスプライトデータをハードウェアに転送するためのバッファにセット
voidslDMACopyvoid *src,void *dst,Uint32 cntAからBにCだけDMA転送(同一バス転送可能)
voidslDMAWaitvoidDMA転送終了するまで待機
voidslDMAXCopyvoid *src,void *dst,Uint32 cnt,Uint16 modeAからBにCだけDの転送モードでDMA転送(同一バス転送可能)


戻る進む
SGL User's ManualPROGRAMMER'S TUTORIAL
Copyright SEGA ENTERPRISES, LTD., 1997