「コントローラ確認・BG&スプライト出力」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
#contents()
*kihon.hの作成
メモ帳に以下の内容を書き、kihon.hという名前でcc65/includeに保存します。
#highlight(c){{{
/////////////////////////////////////////////////////////////////////////////////
// 2016.10.19 ver 0.15
// 煮るなり焼くなりお好きにどうぞ。
// -----------------------------------------------------------------------------
// cc65@wiki
// http://www34.atwiki.jp/cc65/
/////////////////////////////////////////////////////////////////////////////////
#define REGIST_PPU_CTRL1 (char*)0x2000
#define REGIST_PPU_CTRL2 (char*)0x2001
#define REGIST_PPU_STS (char*)0x2002
#define REGIST_SPR_ADR (char*)0x2003
#define REGIST_SPR_GRA (char*)0x2004
#define REGIST_SCROLL (char*)0x2005
#define REGIST_ADR (char*)0x2006
#define REGIST_GRA (char*)0x2007
#define REGIST_DMA (char*)0x4014
#define JOYPAD (char*)0x4016
#define BTN_A 0x80
#define BTN_B 0x40
#define BTN_SELECT 0x20
#define BTN_START 0x10
#define BTN_UP 0x08
#define BTN_DOWN 0x04
#define BTN_LEFT 0x02
#define BTN_RIGHT 0x01
#define GUN_TRIGGER 0x10
#define GUN_HIT 0x08
#define MIC_USE 0x04
unsigned char padinfo[2][2];
unsigned char padother;
//コントローラ確認
void CheckPad()
{
unsigned char i,j,ret;
*JOYPAD = 1;
*JOYPAD = 0;
padother= 0;
for(i=0; i < 2; i++) {
padinfo[i][1] = padinfo[i][0];
padinfo[i][0]= 0;
for(j=0; j < 8; j++) {
ret = *(JOYPAD + i);
padinfo[i][0] <<= 1;
padinfo[i][0] += (ret & 0x01);
padother |= (ret & 0x0F);
}
}
}
//ボタン押しっぱなし player:0=1P , 1=2P
char ButtonDown(unsigned char player,unsigned char btn)
{
if(padinfo[player][0] & btn) {
return 1;
} else {
return 0;
}
}
//ボタン押す
char ButtonPush(unsigned char player,unsigned char btn)
{
if((padinfo[player][0] & btn) && ! (padinfo[player][1] & btn)) {
return 1;
} else {
return 0;
}
}
//マイク・光線銃など
char ControlOther(unsigned char btn)
{
if(padother & btn) {
return 1;
} else {
return 0;
}
}
// PPUコントロールレジスタの初期化
void InitPPU()
{
*REGIST_PPU_CTRL1 = 0x00;
*REGIST_PPU_CTRL2 = 0x00;
}
// PPUコントロールレジスタの設定
void SetPPU(unsigned char flag1,unsigned char flag2)
{
*REGIST_PPU_CTRL1 = flag1;
*REGIST_PPU_CTRL2 = flag2;
}
// スクロール設定
void SetScroll(unsigned char x, unsigned char y)
{
*REGIST_SCROLL = x;
*REGIST_SCROLL = y;
}
//背景設定(繰り返し)
void FillBackground(unsigned char address1, unsigned char address2, unsigned char val, unsigned char cnt)
{
char i;
*REGIST_ADR = address1;
*REGIST_ADR = address2;
for (i = 0; i < cnt; i++)
{
*REGIST_GRA = val;
}
}
//背景設定
void SetBackground(unsigned char address1, unsigned char address2, unsigned char *bg, unsigned char cnt)
{
char i;
*REGIST_ADR = address1;
*REGIST_ADR = address2;
for (i = 0; i < cnt; i++)
{
*REGIST_GRA = *(bg + i);
}
}
//座標から背景のアドレス計算
void GetBackgroundAddress(unsigned char screen, unsigned char x, unsigned char y, char *ret)
{
unsigned int pos;
switch (screen) {
case 0: //左下
pos = 0x2000;
break;
case 1: //右下
pos = 0x2800;
break;
case 2: //左上
pos = 0x2400;
break;
case 3: //右上
pos = 0x2c00;
break;
}
pos += y * 0x20 + x;
*(ret + 0) = (pos & 0xff00) >> 8;
*(ret + 1) = pos & 0x00ff;
}
//属性設定(繰り返し)
void FillAttribute(unsigned char address1, unsigned char address2, unsigned char val, unsigned char cnt)
{
FillBackground(address1,address2,val,cnt);
}
//属性設定
void SetAttribute(unsigned char address1, unsigned char address2, unsigned char *atr, unsigned char cnt)
{
SetBackground(address1,address2,atr,cnt);
}
//パレット設定
void SetPalette(unsigned char *palette,unsigned char sprite)
{
char i;
*REGIST_ADR = 0x3f;
if (sprite) {
*REGIST_ADR = 0x10;
} else {
*REGIST_ADR = 0x00;
}
for (i = 0; i < 16; i++)
{
*REGIST_GRA = *(palette + i);
}
}
//スプライト設定
void SetSprite(unsigned char first,unsigned char x,unsigned char y,unsigned char index,unsigned char flag)
{
if (first) {
*REGIST_SPR_ADR=0x00;
}
*REGIST_SPR_GRA=y;
*REGIST_SPR_GRA=index;
*REGIST_SPR_GRA=flag;
*REGIST_SPR_GRA=x;
}
//DMA転送領域初期化
void InitDMA(unsigned char *address)
{
int i;
for(i=0; i < 256; i++) {
*(address + i)=0;
}
}
//DMA転送準備
void SetDMA(unsigned char *address,unsigned char first,unsigned char x,unsigned char y,unsigned char index,unsigned char flag)
{
static unsigned char cnt;
if (first) { cnt = 0; }
*(address + cnt + 0)=y;
*(address + cnt + 1)=index;
*(address + cnt + 2)=flag;
*(address + cnt + 3)=x;
cnt+=4;
}
//DMA転送
void SendDMA(unsigned char address)
{
*REGIST_DMA = address;
}
//VBlank待ち
void VBlank()
{
while (! (*REGIST_PPU_STS & 0x80) );
}
//0爆弾待ち
void ZeroSprite()
{
while ( (*REGIST_PPU_STS & 0x70) );
while (! (*REGIST_PPU_STS & 0x70) );
}
}}}
*kihon.hの解説
-CheckPad:コントローラの確認。基本的に毎回呼び出す。
-ButtonDown:押されたボタンの確認。(押し続ける)
-ButtonPush:押されたボタンの確認。(押す→離す)
-ControlOther:マイク・光線銃の確認。
-InitPPU:PPUコントロールレジスタの初期化。
-SetPPU:PPUコントロールレジスタの設定。
--flag1:PPUコントロールレジスタ1の設定。
---bit7:VBlank時にNMIを実行
---bit6:PPUマスター/スレーブセレクト
---bit5:スプライトサイズ(0:8x8,1:8x16)
---bit4:BGパターンテーブルアドレス(0:$0000,1:$1000)
---bit3:スプライトパターンテーブルアドレス(0:$0000,1:$1000)
---bit2:PPUアドレスインクリメント(0:+1,1:+32)
---bit0,1:表示するネームテーブルアドレス番号(00:$2000・左下、01:$2400・左上、10:$2800・右下、11:$2C00・右上)
--flag2:PPUコントロールレジスタ2の設定。
---bit5-7:bit0=1のとき背景色/bit0=1のとき色強調&br()000:なし・001:緑・010:青・100:赤(それ以外の数字は不可)
---bit4:スプライト表示(0:非表示,1:表示)
---bit3:BG表示(0:非表示,1:表示)
---bit2:スプライトクリップ(0:画面の左8ドットを表示しない,1:クリップなし)
---bit1:BGクリップ(0:画面の左8ドットを表示しない,1:クリップなし)
---bit0:ディスプレイタイプ(0:カラー,1:モノクロ)
-SetScroll:背景のスクロール。
--x:横位置。
--y:縦位置。
-FillBackground:背景の設定(繰り返し)。
--address1:出力開始位置(上位2バイト)
--address2:出力開始位置(下位2バイト)
--val:出力内容(マスの番号)
--cnt:出力を繰り返す数
-SetBackground:背景の設定。
--address1:出力開始位置(上位2バイト)
--address2:出力開始位置(下位2バイト)
--*bg:出力内容のポインタ
--cnt:出力内容のバイト数
-GetBackgroundAddress:座標から背景のアドレスを算出。
--screen:画面(0:左下・初期画面,1:右下,2:左上,3:右上)
--x:横位置。
--y:縦位置。
--*ret:アドレスを格納する1バイト×2の配列
-SetPalette:パレットの設定。
--*palette:パレット内容のポインタ
--sprite:0:背景用パレット 1:スプライト用パレット
-FillAttribute:属性(背景4マス×4マス毎にどのパレットを使うか)の設定。(繰り返し)
--address1:出力先(上位2バイト)
--address2:出力先(下位2バイト)
--val:出力内容
--cnt:出力を繰り返す数
-SetAttribute:属性(背景4マス×4マス毎にどのパレットを使うか)の設定。
--address1:出力先(上位2バイト)
--address2:出力先(下位2バイト)
--*atr:出力内容のポインタ
--cnt:出力内容のバイト数
-SetSprite:スプライトの設定。
--first:1=1つ目のスプライト 0=2つ目以降
--x:横位置
--y:縦位置
--index:何コマ目の画像を表示するか
--flag:表示条件
---7bit:上下反転
---6bit:左右反転
---5bit:背景よりも後ろに表示
---0,1bit:パレット番号
-SetDMA:DMA転送準備。(スプライト用領域の設定)
--*address:スプライト用領域の開始アドレス
--first:1=1つ目のスプライト 0=2つ目以降
--x,y,index,flag:SetSpriteと同内容。
-SendDMA:DMA転送
--address:スプライト用領域の開始アドレスの三桁目 0x1=0x0100
-VBlank:VBlank待ち処理。
-ZeroSprite:0爆弾待ち処理。
&color(red){※SetRegister・SetBackground・SetAttribute・SetPaletteは便宜上分けているだけで、やっている処理は同じです。}
&color(red){※FillBackgroundとFillAttributeも同様。}
*&spanid(ryuui){留意事項}
-SetBackgroundによる描画が間に合わない場合、背景がまだらに表示されます。
#highlight(c){{{
VBlank()
SetBackground(0x20,0x00,(char *)bg,32);
SetScroll( 0, 0 );
}}}
-一時的に背景の描画を停止し、その間に描画することで回避できます。
#highlight(c){{{
SetPPU(0x08,0x06);
SetBackground(0x20,0x00,(char *)bg,32);
SetScroll( 0, 0 );
SetPPU(0x08,0x1e);
}}}
-描画する範囲を狭めることでも回避できます。
#highlight(c){{{
VBlank();
SetBackground(0x20,0x00,(char *)bg,10)
SetScroll( 0, 0 );
VBlank();
SetBackground(0x20,0x0a,(char *)bg,10)
SetScroll( 0, 0 );
VBlank();
SetBackground(0x20,0x14,(char *)bg,12)
SetScroll( 0, 0 );
}}}
-SetBackgroundを呼び出さずにベタに処理を書くとより効果的です。&br()(#defineの使用は問題ありません。)
#highlight(c){{{
*REGIST_ADR = 0x20;
*REGIST_ADR = 0x00;
*REGIST_GRA = 0;
*REGIST_GRA = 1;
:
:
*REGIST_GRA = 31;
}}}
#contents()
*kihon.hの作成
メモ帳に以下の内容を書き、kihon.hという名前でcc65/includeに保存します。
#highlight(c){{{
/////////////////////////////////////////////////////////////////////////////////
// 2016.10.19 ver 0.15
// 煮るなり焼くなりお好きにどうぞ。
// -----------------------------------------------------------------------------
// cc65@wiki
// http://www34.atwiki.jp/cc65/
/////////////////////////////////////////////////////////////////////////////////
#define REGIST_PPU_CTRL1 (char*)0x2000
#define REGIST_PPU_CTRL2 (char*)0x2001
#define REGIST_PPU_STS (char*)0x2002
#define REGIST_SPR_ADR (char*)0x2003
#define REGIST_SPR_GRA (char*)0x2004
#define REGIST_SCROLL (char*)0x2005
#define REGIST_ADR (char*)0x2006
#define REGIST_GRA (char*)0x2007
#define REGIST_DMA (char*)0x4014
#define JOYPAD (char*)0x4016
#define BTN_A 0x80
#define BTN_B 0x40
#define BTN_SELECT 0x20
#define BTN_START 0x10
#define BTN_UP 0x08
#define BTN_DOWN 0x04
#define BTN_LEFT 0x02
#define BTN_RIGHT 0x01
#define GUN_TRIGGER 0x10
#define GUN_HIT 0x08
#define MIC_USE 0x04
unsigned char padinfo[2][2];
unsigned char padother;
//コントローラ確認
void CheckPad()
{
unsigned char i,j,ret;
*JOYPAD = 1;
*JOYPAD = 0;
padother= 0;
for(i=0; i < 2; i++) {
padinfo[i][1] = padinfo[i][0];
padinfo[i][0]= 0;
for(j=0; j < 8; j++) {
ret = *(JOYPAD + i);
padinfo[i][0] <<= 1;
padinfo[i][0] += (ret & 0x01);
padother |= (ret & 0x0F);
}
}
}
//ボタン押しっぱなし player:0=1P , 1=2P
char ButtonDown(unsigned char player,unsigned char btn)
{
if(padinfo[player][0] & btn) {
return 1;
} else {
return 0;
}
}
//ボタン押す
char ButtonPush(unsigned char player,unsigned char btn)
{
if((padinfo[player][0] & btn) && ! (padinfo[player][1] & btn)) {
return 1;
} else {
return 0;
}
}
//マイク・光線銃など
char ControlOther(unsigned char btn)
{
if(padother & btn) {
return 1;
} else {
return 0;
}
}
// PPUコントロールレジスタの初期化
void InitPPU()
{
*REGIST_PPU_CTRL1 = 0x00;
*REGIST_PPU_CTRL2 = 0x00;
}
// PPUコントロールレジスタの設定
void SetPPU(unsigned char flag1,unsigned char flag2)
{
*REGIST_PPU_CTRL1 = flag1;
*REGIST_PPU_CTRL2 = flag2;
}
// スクロール設定
void SetScroll(unsigned char x, unsigned char y)
{
*REGIST_SCROLL = x;
*REGIST_SCROLL = y;
}
//背景設定(繰り返し)
void FillBackground(unsigned char address1, unsigned char address2, unsigned char val, unsigned char cnt)
{
char i;
*REGIST_ADR = address1;
*REGIST_ADR = address2;
for (i = 0; i < cnt; i++)
{
*REGIST_GRA = val;
}
}
//背景設定
void SetBackground(unsigned char address1, unsigned char address2, unsigned char *bg, unsigned char cnt)
{
char i;
*REGIST_ADR = address1;
*REGIST_ADR = address2;
for (i = 0; i < cnt; i++)
{
*REGIST_GRA = *(bg + i);
}
}
//座標から背景のアドレス計算
void GetBackgroundAddress(unsigned char screen, unsigned char x, unsigned char y, char *ret)
{
unsigned int pos;
switch (screen) {
case 0: //左下
pos = 0x2000;
break;
case 1: //右下
pos = 0x2800;
break;
case 2: //左上
pos = 0x2400;
break;
case 3: //右上
pos = 0x2c00;
break;
}
pos += y * 0x20 + x;
*(ret + 0) = (pos & 0xff00) >> 8;
*(ret + 1) = pos & 0x00ff;
}
//属性設定(繰り返し)
void FillAttribute(unsigned char address1, unsigned char address2, unsigned char val, unsigned char cnt)
{
FillBackground(address1,address2,val,cnt);
}
//属性設定
void SetAttribute(unsigned char address1, unsigned char address2, unsigned char *atr, unsigned char cnt)
{
SetBackground(address1,address2,atr,cnt);
}
//パレット設定
void SetPalette(unsigned char *palette,unsigned char sprite)
{
char i;
*REGIST_ADR = 0x3f;
if (sprite) {
*REGIST_ADR = 0x10;
} else {
*REGIST_ADR = 0x00;
}
for (i = 0; i < 16; i++)
{
*REGIST_GRA = *(palette + i);
}
}
//スプライト設定
void SetSprite(unsigned char first,unsigned char x,unsigned char y,unsigned char index,unsigned char flag)
{
if (first) {
*REGIST_SPR_ADR=0x00;
}
*REGIST_SPR_GRA=y;
*REGIST_SPR_GRA=index;
*REGIST_SPR_GRA=flag;
*REGIST_SPR_GRA=x;
}
//DMA転送領域初期化
void InitDMA(unsigned char *address)
{
int i;
for(i=0; i < 256; i++) {
*(address + i)=0;
}
}
//DMA転送準備
void SetDMA(unsigned char *address,unsigned char first,unsigned char x,unsigned char y,unsigned char index,unsigned char flag)
{
static unsigned char cnt;
if (first) { cnt = 0; }
*(address + cnt + 0)=y;
*(address + cnt + 1)=index;
*(address + cnt + 2)=flag;
*(address + cnt + 3)=x;
cnt+=4;
}
//DMA転送
void SendDMA(unsigned char address)
{
*REGIST_DMA = address;
}
//VBlank待ち
void VBlank()
{
while (! (*REGIST_PPU_STS & 0x80) );
}
//0爆弾待ち
void ZeroSprite()
{
while ( (*REGIST_PPU_STS & 0x40) );
while (! (*REGIST_PPU_STS & 0x40) );
}
}}}
*kihon.hの解説
-CheckPad:コントローラの確認。基本的に毎回呼び出す。
-ButtonDown:押されたボタンの確認。(押し続ける)
-ButtonPush:押されたボタンの確認。(押す→離す)
-ControlOther:マイク・光線銃の確認。
-InitPPU:PPUコントロールレジスタの初期化。
-SetPPU:PPUコントロールレジスタの設定。
--flag1:PPUコントロールレジスタ1の設定。
---bit7:VBlank時にNMIを実行
---bit6:PPUマスター/スレーブセレクト
---bit5:スプライトサイズ(0:8x8,1:8x16)
---bit4:BGパターンテーブルアドレス(0:$0000,1:$1000)
---bit3:スプライトパターンテーブルアドレス(0:$0000,1:$1000)
---bit2:PPUアドレスインクリメント(0:+1,1:+32)
---bit0,1:表示するネームテーブルアドレス番号(00:$2000・左下、01:$2400・左上、10:$2800・右下、11:$2C00・右上)
--flag2:PPUコントロールレジスタ2の設定。
---bit5-7:bit0=1のとき背景色/bit0=1のとき色強調&br()000:なし・001:緑・010:青・100:赤(それ以外の数字は不可)
---bit4:スプライト表示(0:非表示,1:表示)
---bit3:BG表示(0:非表示,1:表示)
---bit2:スプライトクリップ(0:画面の左8ドットを表示しない,1:クリップなし)
---bit1:BGクリップ(0:画面の左8ドットを表示しない,1:クリップなし)
---bit0:ディスプレイタイプ(0:カラー,1:モノクロ)
-SetScroll:背景のスクロール。
--x:横位置。
--y:縦位置。
-FillBackground:背景の設定(繰り返し)。
--address1:出力開始位置(上位2バイト)
--address2:出力開始位置(下位2バイト)
--val:出力内容(マスの番号)
--cnt:出力を繰り返す数
-SetBackground:背景の設定。
--address1:出力開始位置(上位2バイト)
--address2:出力開始位置(下位2バイト)
--*bg:出力内容のポインタ
--cnt:出力内容のバイト数
-GetBackgroundAddress:座標から背景のアドレスを算出。
--screen:画面(0:左下・初期画面,1:右下,2:左上,3:右上)
--x:横位置。
--y:縦位置。
--*ret:アドレスを格納する1バイト×2の配列
-SetPalette:パレットの設定。
--*palette:パレット内容のポインタ
--sprite:0:背景用パレット 1:スプライト用パレット
-FillAttribute:属性(背景4マス×4マス毎にどのパレットを使うか)の設定。(繰り返し)
--address1:出力先(上位2バイト)
--address2:出力先(下位2バイト)
--val:出力内容
--cnt:出力を繰り返す数
-SetAttribute:属性(背景4マス×4マス毎にどのパレットを使うか)の設定。
--address1:出力先(上位2バイト)
--address2:出力先(下位2バイト)
--*atr:出力内容のポインタ
--cnt:出力内容のバイト数
-SetSprite:スプライトの設定。
--first:1=1つ目のスプライト 0=2つ目以降
--x:横位置
--y:縦位置
--index:何コマ目の画像を表示するか
--flag:表示条件
---7bit:上下反転
---6bit:左右反転
---5bit:背景よりも後ろに表示
---0,1bit:パレット番号
-SetDMA:DMA転送準備。(スプライト用領域の設定)
--*address:スプライト用領域の開始アドレス
--first:1=1つ目のスプライト 0=2つ目以降
--x,y,index,flag:SetSpriteと同内容。
-SendDMA:DMA転送
--address:スプライト用領域の開始アドレスの三桁目 0x1=0x0100
-VBlank:VBlank待ち処理。
-ZeroSprite:0爆弾待ち処理。
&color(red){※SetRegister・SetBackground・SetAttribute・SetPaletteは便宜上分けているだけで、やっている処理は同じです。}
&color(red){※FillBackgroundとFillAttributeも同様。}
*&spanid(ryuui){留意事項}
-SetBackgroundによる描画が間に合わない場合、背景がまだらに表示されます。
#highlight(c){{{
VBlank()
SetBackground(0x20,0x00,(char *)bg,32);
SetScroll( 0, 0 );
}}}
-一時的に背景の描画を停止し、その間に描画することで回避できます。
#highlight(c){{{
SetPPU(0x08,0x06);
SetBackground(0x20,0x00,(char *)bg,32);
SetScroll( 0, 0 );
SetPPU(0x08,0x1e);
}}}
-描画する範囲を狭めることでも回避できます。
#highlight(c){{{
VBlank();
SetBackground(0x20,0x00,(char *)bg,10)
SetScroll( 0, 0 );
VBlank();
SetBackground(0x20,0x0a,(char *)bg,10)
SetScroll( 0, 0 );
VBlank();
SetBackground(0x20,0x14,(char *)bg,12)
SetScroll( 0, 0 );
}}}
-SetBackgroundを呼び出さずにベタに処理を書くとより効果的です。&br()(#defineの使用は問題ありません。)
#highlight(c){{{
*REGIST_ADR = 0x20;
*REGIST_ADR = 0x00;
*REGIST_GRA = 0;
*REGIST_GRA = 1;
:
:
*REGIST_GRA = 31;
}}}