「コントローラ確認・BG&スプライト出力」の編集履歴(バックアップ)一覧はこちら

コントローラ確認・BG&スプライト出力」(2016/10/20 (木) 23:30:24) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

#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; }}}

表示オプション

横に並べて表示:
変化行の前後のみ表示: