キー入力の処理


キー配置と押下データ値

WonderSwan本体上に配置されている、X(上下左右)、Y(上下左右)、A、B、および、 STARTの各ボタンの押下状態を得ることができます。SOUNDボタンの状態を得ることはできません。

ぞれぞれの押下時の値はkey.hの中で次のように定義されており、キーBIOSの関数を使って この情報を得ることができます。


#define KEY_START   0x002
#define KEY_A       0x004
#define KEY_B       0x008
#define KEY_UP1     0x010
#define KEY_RIGHT1  0x020
#define KEY_DOWN1   0x040
#define KEY_LEFT1   0x080
#define KEY_UP2     0x100
#define KEY_RIGHT2  0x200
#define KEY_DOWN2   0x400
#define KEY_LEFT2   0x800

キー入力のチェック

簡単なプログラムでキー入力のチェックをしてみましょう。使用している関数は、 現在のキーの状態を返す『key_press_check()』です。ほかにもキー入力があるまで 待ってその値を返す『key_wait()』もあります。どちらも返される値は同じです。

text_put_numeric は数値をテキスト表示する関数です。 この例では押下されたキーの値を、16進4桁で表示させています。

複数のキースキャンにも対応しています。例えばX1キーとAキーを同時に 押せば KEY_A(0x0004)とKEY_UP1(0x0010)が合成された0014 が表示されます。

START キーで終了します。

#include <sys/bios.h>

void main(void)
{
    int k;
    text_screen_init();
    while( (k=key_press_check()) != KEY_START ){
        text_put_numeric(1,1,4,NUM_HEXA | NUM_PADZERO ,k);
    }
}


キー入力でスクリーンのスクロール
図のようなキャラクタをスクリーンに設定して、左右のキー入力でスクロールさせます。
データは図の左右でシームレス(つなぎ目をなくす)にしてあります。

#include <sys/bios.h>

#include "yama.h"
unsigned yama[yama_width * yama_height];

void main()
{
    int x,i,k;
    for(i=0;i<yama_width * yama_height;i++)
        yama[i]=i+1;
    font_set_colordata(1, yama_width * yama_height, bmp_yama);
    screen_set_char(SCREEN2, 0, 6, yama_width , yama_height , yama);

    x=0;
    while( (k=key_press_check()) != KEY_START ){
        switch (k) {
            case KEY_LEFT1: x--; break;
            case KEY_RIGHT1:x++; break;
        }
        screen_set_scroll(SCREEN2, x, 0);
        sys_wait(1);
    }
}


キー入力でスプライトを動かす

X群キーの上下左右の押下でスプライトを移動するサンプルです。
キー入力には、現在のキーの状態をスキャンする『key_press_check()』関数 を使っています。戻り値は key_wait() と共通です。
STARTキ−で終了します。タイムディレイ( sys_wait )を入れないと移動が 早過ぎます。

実機ではスクリーン1にはOSの画面が表示されたまま、スプライトが移動します。

#include <sys/bios.h>

#include "witch.h"

int sprite_set(int, int, int, int, int);

void main()
{
    int i,x,y,k;

    display_control( DCM_SCR1 | DCM_SPR );
    font_set_colordata(1, witch_width * witch_height, bmp_witch);
    for(i=0;i<16;i++) 
        sprite_set_char(i,(i+1) | 4<<9 | CFM_SPR_UPPER);
    sprite_set_range( 0, 16 );

    x=100; y=70;
    while((k=key_press_check()) != KEY_START){
        switch (k) {
            case KEY_UP1   : y-=1; break;
            case KEY_DOWN1 : y+=1; break;
            case KEY_LEFT1 : x-=1; break;
            case KEY_RIGHT1: x+=1; break;
	}
        sprite_set(x,y,witch_width,witch_height,0);
        sys_wait(1);
    }
}

int sprite_set(int x, int y, int width, int height, int no)
{
    int i,j;
    for ( i=0; i<height; i++ ) {
        for ( j=0; j<width; j++ ) {
            sprite_set_location( no+i*width+j, x+j*8, y+i*8 );
        }
    }
}



スクリーンスクロール + スプライトの移動
スクリーンがスクロールしている上でスプライトの移動を行います。
山の景色の中を魔女が飛んでいくという感じのプログラムです。
#include <sys/bios.h>

int sprite_set(int, int, int, int, int);

#include "witch.h"
unsigned witch[witch_width * witch_height];

#include "yama.h"
unsigned yama[yama_width * yama_height];

void main()
{
    int x,y,i,j,sx,k;

    display_control( DCM_SCR2 | DCM_SPR );

    font_set_colordata(1, witch_width * witch_height, bmp_witch);
    for(i=0;i<16;i++) 
        sprite_set_char(i,(i+1) | 4<<9 | CFM_SPR_UPPER);
    sprite_set_range( 0, 16 );
    x=100; y=40;
    for ( i=0; i<4; i++ ) {
        for ( j=0; j<4; j++ ) {
            sprite_set_location( i*4+j, x+j*8, y+i*8 );
        }
    }

    font_set_colordata(17, yama_width * yama_height, bmp_yama);
    for(i=0;i<yama_width * yama_height;i++)
        yama[i]=i+17;
    screen_set_char(SCREEN2, 0, 6, yama_width , yama_height , yama);

    sx=0;
    while((k=key_press_check()) != KEY_START){
	switch (k) {
	    case KEY_UP1: y-=1; break;
	    case KEY_DOWN1:y+=1; break;
	    case KEY_LEFT1: x-=1; break;
	    case KEY_RIGHT1:x+=1; break;
	}
        sprite_set(x, y, witch_width, witch_height, 0 );
        sx=sx>254?0:sx+1;
        screen_set_scroll(SCREEN2, sx, 0);
        sys_wait(2);
    }


}

int sprite_set(int x, int y, int width, int height, int no)
{
    int i,j;
    for ( i=0; i<height; i++ ) {
        for ( j=0; j<width; j++ ) {
            sprite_set_location( no+i*width+j, x+j*8, y+i*8 );
        }
    }

}