スクリーンの便利な機能


重ね合わせと透過色

ワンダーウィッチにはスクリーン1と2の2枚の描画スクリーンがあります。これにキャラクタなどを 動かすために用いるスプライトを組み合わせてプログラミングします。
スクリーン2は常にスクリーン1の上に重ねられて表示されますが、スクリーン2の表示を オフにすればスクリーン1の表示が見えます。
スプライトはそれぞれのキャラクタ毎に、スクリーン2の上、スクリーン1と2の間に表示位置が設定できます。
また、表示するキャラクタには『透明色』が設定でき、その部分は下のスクリーンが透けて見えます。 スクリーン1に透明色が設定された場合はボーダーカラーと呼ばれるあらかじめ設定した色となります。


スクリーンの表示/非表示

スクリーンの表示/非表示などの設定は「display_control」関数で行います。

実際には「sys/disp.h」の中で次のように宣言されているため、例のように記述します。

#define DCM_SCR1             0x0001
#define DCM_SCR2             0x0002
#define DCM_SPR              0x0004
#define DCM_SPR_WIN          0x0008
#define DCM_SCR2_WIN_INSIDE  0x0020
#define DCM_SCR2_WIN_OUTSIDE 0x0030


#include <sys/bios.h>

void main(void)
{
    display_control( DCM_SCR1 | DCM_SCR2 | DCM_SCR2_WIN_INSIDE );
    ……
    …


スクリーン2のウインド機能(外側を表示)

スクリーン1にキャラクタを描画し、スクリーン2に設定したウィンドをしだいに 大きくしていくことによってスクリーン1を表示させます。ゲームのオオープニングなどに 使えそうな効果です。
#include 
#include "fuuka.h"                /* 画面一杯のキャラクタデータ bmpcnv で作成 */

void main()
{
    unsigned fuuka[28 * 18];
    int i;

    for(i=1;i<=28 * 18;i++)
        fuuka[i-1]=i;
    font_set_colordata(1, 28 * 18, bmp_fuuka);
    screen_set_char(SCREEN1, 0, 0, 28, 18, fuuka); /* スクリーン1にキャラクタ設定 */

    key_wait();                                    /* キー入力待ち */

    display_control( DCM_SCR1 | DCM_SCR2 | DCM_SCR2_WIN_OUTSIDE ); /* ディスプレイ設定 */

    for(i=144/2;i>=0;i--){
        screen2_set_window(i, i, 28*8-i*2, 18*8-i*2);      /* ウインドをだんだん大きく */
        sys_wait(1);                                       /* タイムディレイ */
    }

    key_wait();                                    /* キー入力待ち */
}





スクリーンのスクロール

ハードウェアスクロール機能により、スクリーン1、スクリーン2それぞれについて、 1ドット単位でLCDパネル上に実際に表示される範囲を設定できます。 スクロールして画面から途切れた部分は、逆側へつながるようにつながります。

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

#include <sys/bios.h>

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

void main()
{
    int x,i;

    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( key_press_check() == 0 ){                     /* キーが押されたら終了 */
        x = x>254 ? 0 : x+1 ;                        /* 座標を戻す 必要ない? */
        screen_set_scroll(SCREEN2, x, 0);       /* スクロール(絶対座標値) */
        sys_wait(2);                                           /* タイムディレイ */
    }
}


スクリーンのスクロールA(シューティング風)

星を散りばめた宇宙空間?をロケットが飛行していくサンプルです。2つの星のキャラクタを乱数で スクリーンにばらまき、それをスクロールさせています。Yキーの入力でロケットが移動しているように スクロールを加速等させています。STARTキーで終了です。
#include <sys/bios.h>

#include "star0.h"
#include "star1.h"
unsigned star0[]={2};
unsigned star1[]={3};
#include "rocket.h"

unsigned char bmp_black[]={ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

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

    display_control( DCM_SCR2 | DCM_SPR );

    font_set_monodata( 1, 1, bmp_black);                    /* 背景の黒 */
    font_set_colordata( 2, 1, bmp_star0);                   /* 小さな星 */
    font_set_colordata( 3, 1, bmp_star1);                   /* 大きな星 */

    font_set_colordata(4, 4*4, bmp_rocket);                /* ロケット */
    for(i=0;i<16;i++) 
        sprite_set_char(i,(i+4) | 4<<9 | CFM_SPR_UPPER);
    sprite_set_range( 0, 16 );

    screen_fill_char(SCREEN2, 0, 0, 32, 32, 1);             /* 全てを黒に */

    for(i=0;i<200;i++){                                    
        x = rand() % 31;
        y = rand() % 31;
        star0[0]= 2 | (rand()%3)<<14;
        if(i<180)
            screen_set_char(SCREEN2, x, y, 1 , 1 , star0);  /* 小さな星を表示 */
        else
            screen_set_char(SCREEN2, x, y, 1 , 1 , star1);  /* 大きな星を表示 */
    }

    x=30; y=56;                                            /* ロケットを表示 */
    for ( i=0; i<4; i++ ) {
        for ( j=0; j<4; j++ ) {
            sprite_set_location( i*4+j, x+j*8, y+i*8 );
        }
    }

    x=0; y=0;
    while( (k=key_press_check() ) != KEY_START ){           /* STARTボタンで終了 */
	switch (k) {
	    case KEY_RIGHT2:x+=1; break;                        /* キー入力でスクロール */
	    case KEY_DOWN2: y+=1; break;
	    case KEY_UP2:   y-=1; break;
	}
        x+=1;                                               /* 常に前進するようスクロール */
        screen_set_scroll(SCREEN2, x, y);
        sys_wait(2);                                        /* タイムディレイ */
    }
}


ウインド機能+スクロール(RPG風)

簡単なマップデータを配列で設定し、ブロックでマップを画面左側に表示します。 上下左右のキー入力でマップをスクロールさせ、画面右側にはx、yそれぞれの スクロール値を表示させています。
#include <sys/bios.h>

#include "b.h"
unsigned b[]={1,2,3,4};

unsigned short bmp_clr[] = {0x0000, 0x0000, 0x0000, 0x0000};

int m[][16]={
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
	{1,0,0,0,1,0,1,0,0,1,0,0,0,0,0,1},
	{1,0,1,0,1,0,0,1,0,1,0,1,1,1,0,1},
	{1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1},
	{1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,1},
	{1,0,0,0,0,0,1,0,1,1,0,1,1,0,1,1},
	{1,1,0,1,1,0,1,0,1,1,0,1,1,0,1,1},
	{1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1},
	{1,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1},
	{1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,1},
	{1,0,1,1,1,0,1,1,0,1,0,1,0,0,0,1},
	{1,0,1,0,0,0,0,0,0,0,0,1,0,1,1,1},
	{1,0,0,0,1,1,1,0,1,0,1,1,0,0,0,1},
	{1,0,0,1,1,1,1,0,1,0,0,1,0,1,0,1},
	{1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};

void main()
{
    int x,y,k;
 
    font_set_monodata(0, 1, bmp_clr);
    screen_fill_char(SCREEN1, 0,0,32,32,0); 

    display_control( DCM_SCR1 | DCM_SCR2 | DCM_SCR2_WIN_OUTSIDE );
    screen2_set_window(0, 0, 18*8, 18*8);
    text_window_init(18,0,8,18,5);
    text_put_string(1,5,"ワンダースワン");

    font_set_colordata(1, b_width * b_height, bmp_b);
    for(y=0;y<16;y++){
        for(x=0;x<16;x++){
            if(m[y][x]==1)
                screen_set_char(SCREEN1, x*2, y*2, b_width , b_height , b);
        }
    }
    x=0; y=0;
    while( (k=key_wait()) != KEY_START ){
        switch (k) {
            case KEY_LEFT1: if(x>0) x-=16;
                            break;
            case KEY_RIGHT1:if(x<256-18*8) x+=16;
                            break;
            case KEY_DOWN1: if(y<256-144) y+=16;
                            break;
            case KEY_UP1:   if(y>0) y-=16;
                            break;
        }
        screen_set_scroll(SCREEN1, x, y);
        text_put_numeric(1,7,5,NUM_ALIGN_RIGHT,x);
        text_put_numeric(1,9,5,NUM_ALIGN_RIGHT,y);
    }
}