[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[WitchTech 00422] LCD 階調倍増計画



MXYと申します。

VBLANK毎の画面切り替えによって、表示可能な階調数を増やす
実験をしています。

もう、すでに取り組んでいる方も多いと思いますが、私のやっている
方法を紹介します。

基本仕様

 4VBLANKで1画面
 使用キャラクタパレット数 1組(但し、LCDパレット4/8使用)
 各キャラクタで同じパレットを使用する。

 VBLANK毎にキャラクタパターンとLCDパレットを切り替える。

 LCDパレットを4段階に切り替えることで、多階調化実現

問題点

 フル画面でうまく動かない
   これは、下記のサンプルではありません。
   やはり、全画面のキャラクタデータの読み込みは1Vでは無理の
   ようです。
   これについては、ライン検知割り込みを使用して、対応を検討中。

 LCDパレットが半分この表示のために占領されてしまう。

 ちらつく(当たり前(^^;

 パターンと階調の対応がわからない(^^;


サンプルソースを下記に記載します。
但し、キャラクターパターンの書き換えは、本来考えている方法とは
違います。

VBLANK割り込みのかわりにDISPLINE割り込みをライン指定なしで
呼んでます(多分0ラインを検知(^^;
このほうがうまくいくみたいなんで(手探り状態からの使用(^^;

あ、使用コンパイラはLSI-Cです。
汚いソースですみません。

/*-- sample source --*/

#define BIOS_INLINE

#include <stdio.h>
#include <sys/bios.h>
#include <sys/fcntl.h>

#define SCR_BG SCREEN1

#define CTDF(c,p,f)  ((f&0xc000)|((p<<9)&0x1e00)|(c&0x01ff))

#define XMAX 16
#define YMAX 16
#define VscrL(x,y,p) (p*YMAX*XMAX+y*XMAX+x)

/* define prototype */
void set_callback(int type, void (far*)(),intvector_t*);
void far DL_int(void);

/* static data */

static unsigned int fontc[]=
{
 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
 0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,
 0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,
 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff
};

static unsigned int LCDpalL[]=
{
 0xFDB0,0xFC90,0xF630,0xF420
/*eoc*/
/* 0xFDB0,0xFC90,0xFB70,0xFA50
/*eoc*/
/* 0xFDB9,0xFC96,0xFB73,0xFA50
/*eoc*/
};

static unsigned int Vscr[16*16*4],Key;

static intvector_t DL_v;
static int DL_p=0;

#ifdef LSI_C
int _asm_inline(char near *asm);
#define _CS _asm_inline("\tmov\tax,cs");
#define _DS _asm_inline("\tmov\tax,ds");
#endif

void main(int argc, char *argv[])
{
 int i,j,k;
 text_set_screen(SCR_BG);
 text_screen_init();
 display_control(DCM_SCR1|DCM_SPR);
 sprite_set_range(0,2);
 font_set_colordata(0,4,fontc);
 palette_set_color(0,0x3210);
 lcd_set_color(0xfedc,LCDpalL[0]);
 for(i=0;i<YMAX;i++)
 for(j=0;j<XMAX;j++)
 {
  k=i*XMAX+j;
  Vscr[VscrL(j,i,0)]=k%4;
  Vscr[VscrL(j,i,1)]=(int)(k/4)%4;
  Vscr[VscrL(j,i,2)]=(int)(k/16)%4;
  Vscr[VscrL(j,i,3)]=(int)(k/64);
/*eoc*/
 }
 screen_set_char(SCR_BG,6,1,16,16,Vscr);
 set_callback(SYS_INT_DISPLINE,DL_int,&DL_v);
 key_wait();
}

void set_callback(int type, void (far *callback)(),intvector_t *v)
{
#ifdef LSI_C
 (*v).callback = (void (near *)())FP_OFF(callback);
#else
 (*v).callback = (void (near *)())callback;
#endif
 (*v).cs = _CS;
 (*v).ds = _DS;
 sys_interrupt_set_hook(type, v, NULL);
}

void far DL_int(void)
{
 lcd_set_color(0xfedc,LCDpalL[DL_p]);
 screen_set_char(SCR_BG,6,1,16,16,&Vscr[VscrL(0,0,DL_p)]);
/**/
 DL_p++;
 DL_p = DL_p&0xf3;
}

/*---- end of source list ---*/





ML Archives