ファミコンプログラムをCC65でやってるんですが…

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
KEYONN_

ファミコンプログラムをCC65でやってるんですが…

#1

投稿記事 by KEYONN_ » 15年前

http://www.cc65.org/
cc65というのは、ファミコン用のC言語開発環境の1つです。
そこで、パッド入力判定を以下のページを参考に作ってみたのですが、どこがおかしいでしょうか?
http://gikofami.fc2web.com/nes/nes006.html
void KeyInput(char *x,char *y)
{
	char A,B,Sel,Start,Up,Down,Left,Right;
	
	*(char*)0x4016 = 1;
	*(char*)0x4016 = 0;
	
	A=*(char*)0x4016;
	B=*(char*)0x4016;
	Sel=*(char*)0x4016;
	Start=*(char*)0x4016;
	Up=*(char*)0x4016;
	Down=*(char*)0x4016;
	Left=*(char*)0x4016;
	Right=*(char*)0x4016;
	
	if(Up&1) *y--;
	if(Down&1) *y++;
	if(Left&1) *x--;
	if(Right&1) *x++;
}

Poco

Re:ファミコンプログラムをCC65でやってるんですが…

#2

投稿記事 by Poco » 15年前

端的に言えば、質問がおかしいです。

cc65コマンドでコンパイルは通りました。
TKOZさんが書いたとおりに動くはずです。

TKOZさんはこのプログラムに何を期待して、何が期待と異なったのでしょうか?

Poco

Re:ファミコンプログラムをCC65でやってるんですが…

#3

投稿記事 by Poco » 15年前

もしかして、これが期待通りの動きですか?
(略)
	if(Up&1) (*y)--;
	if(Down&1) (*y)++;
	if(Left&1) (*x)--;
	if(Right&1) (*x)++;

Poco

Re:ファミコンプログラムをCC65でやってるんですが…

#4

投稿記事 by Poco » 15年前

No:41531でsoftyaさんに指摘を頂いたので、以下の発言は
取り消させていただきます。

----
ファミコンの仕様が分からないので、他におかしいと思った
箇所を指摘しておきます。
void KeyInput(char *x,char *y)
{
	char A,B,Sel,Start,Up,Down,Left,Right;
	
	*(char*)0x4016 = 1;
	*(char*)0x4016 = 0;
	
	A=*(char*)0x4016;
	B=*(char*)0x4016;
	Sel=*(char*)0x4016;
	Start=*(char*)0x4016;
	Up=*(char*)0x4016;
	Down=*(char*)0x4016;
	Left=*(char*)0x4016;
	Right=*(char*)0x4016;
	
	/*
	どう考えても、マスクがおかしい。
	Up&1とDown&1は必ず同じ値(4016hの1ビット目)を取るから、
	(*y)の値は結果として変わらない。
	Up&1が正しいなら、Down&2とかDown&4とかになるのでは?
	同様に、LeftとRightにも同じことが言える。
	*/
	if(Up&1) (*y)--;
	if(Down&1) (*y)++;
	if(Left&1) (*x)--;
	if(Right&1) (*x)++;
}
----

softya

Re:ファミコンプログラムをCC65でやってるんですが…

#5

投稿記事 by softya » 15年前

ここを見る限りではアーキテクチャとしては合っているみたいですよ。
http://hp.vector.co.jp/authors/VA042397/nes/joypad.html
ハードで特殊なシフト処理を行っていますので、同じポートにアクセスしても毎回違う値が得られます。

KEYONN_

Re:ファミコンプログラムをCC65でやってるんですが…

#6

投稿記事 by KEYONN_ » 15年前

>>ぽこさん
>>softyaさん
返信ありがとうございます。

質問の仕方が悪かったようです。

パッド入力判定で、上下左右にスプライトが動かないのがおかしいです。
しかし、指摘された部分で()で囲み修正したら、

if(Up&1) (*y)--;
if(Down&1) (*y)++;
if(Left&1) (*x)--;
if(Right&1) (*x)++;

↑ボタンを押したら、スプライトが下に移動しました。
↓ボタンを押したら、スプライトが左に移動しました。
←ボタンを押したら、スプライトが右に移動しました。
→ボタンを押したら、スプライトは動きませんでした。

KEYONN_

Re:ファミコンプログラムをCC65でやってるんですが…

#7

投稿記事 by KEYONN_ » 15年前

NesterJとgnesだと、さっき書いた通りにスプライトが動いたのですが、
virtuanesだと、BGとスプライトが表示されるものの、スプライトは
全く動きませんでした。
fcfanplusだと、読み込み実行したら、エラーが出て強制終了しました。

KEYONN_

Re:ファミコンプログラムをCC65でやってるんですが…

#8

投稿記事 by KEYONN_ » 15年前

問題が解決しました。
皆様、ありがとうございました。
#define A 0x80
#define B 0x40
#define SELECT 0x20
#define START 0x10
#define UP 0x08
#define DOWN 0x04
#define LEFT 0x02
#define RIGHT 0x01

unsigned char PadState;

void KeyInput(char *x,char *y)
{
	unsigned char t;
	char i;
	
	*(char*)0x4016 = 1;
	*(char*)0x4016 = 0;
	
	for (i = 0; i < 8; i++) {
		t = *(char *)0x4016;
		t &= 0x01;
		PadState <<= 1;
		PadState += t;
	}
    
	if(PadState & UP) (*y)--;
	if(PadState & DOWN) (*y)++;
	if(PadState & LEFT) (*x)--;
	if(PadState & RIGHT) (*x)++;
}
として、上下左右に見事動かす事が出来ました。ありがとうございました。

toyo

Re:ファミコンプログラムをCC65でやってるんですが…

#9

投稿記事 by toyo » 15年前

A=*(char*)0x4016;
B=*(char*)0x4016;
Sel=*(char*)0x4016;
Start=*(char*)0x4016;
Up=*(char*)0x4016;
Down=*(char*)0x4016;
Left=*(char*)0x4016;
Right=*(char*)0x4016;
で最適化処理されちゃいそうですね
*(char*)0x4016

*(volatile char*)0x4016
にしたほうがいいのでは
自分なら
#define IO_PAD (*(volatile char*)0x4016)
のように定義して使うかな

閉鎖

“C言語何でも質問掲示板” へ戻る