cc65での固定小数点(cos,sinテーブル)に関して

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
KEYONN_
記事: 70
登録日時: 14年前

cc65での固定小数点(cos,sinテーブル)に関して

#1

投稿記事 by KEYONN_ » 14年前

こんばんわ。TKOZです。
cc65でちょっとしたデモを作ろうとしました。
どういうデモかというと、星の形をしたスプライトを円状にぐるりと反時計回りに回転するデモです。
しかし、問題が起きました。下でしめすソースコードで、

x=128+(addx*(+radius))/100;
y=120-(addy*(+radius))/100;

x=128+(addx*30)/100;
y=120-(addy*30)/100;
にすると、正常に動くのですがstatic signed char radius=30;としたのに動きませんでした。
何か問題があるのでしょうか?

あと、
sin.binとcos.binをプログラムROM上のaddress=0xc000,0xc168に置き、
(sin.binとcos.binは、VC++6で作成,sin関数とcos関数を360度分だけ100倍し、fwriteしました)

char *cos;
signed char movx;
cos=0xc000;
movx+=*(cos+angle);
x+=(movx*30)/100;
固定小数点は、シフト演算を使うのが一般的みたいですが、(3.14*100*3)/100の方が分かりやすいので
そうしました。
固定小数点を今日の仕事中に考えていて、閃いたのが、上のコードです。
なんか、頭悪いですが、100*3/100=3(sin(90))なんだから、当たり前といえば当たり前ですね。

あと、ところどころ問題があるみたいです。
スプライトが正常に表示されないのは、よく分からないのと、
90度位置の真下に移動してしまうバグがあります。
なんででしょうか?



コード:

void MoveCircle()
{
	static int angle=0;
	static char x[12];
	static char y[12];
	signed char addx;
	signed char addy;
	int i;
	static int flag=1;
	static int index=0;
	static signed char radius=30;
	char s1,s2,s3;

	sin=0xC000;
	cos=0xC168;
	
	//VBlank();
	for(i=0;i<12;i++)
	{
		addx=(signed char)*(cos+angle+(i*30)) ;//*30)/100;
		addy=(signed char)*(sin+angle+(i*30)) ;//*30)/100;
		x[i]=128+(addx*(+radius))/100;
		y[i]=120-(addy*(+radius))/100;
		
		DrawSprite(x[i],y[i],index,1,flag);
		
		index=(index+1)%4;
		flag=0;
	}
	
	s1=(radius/100)%10;
	s2=(radius/10)%10;
	s3=(radius/1)%10;
	DrawSprite(18*8,20*8,0,s1+0x30,0);
	DrawSprite(19*8,20*8,0,s2+0x30,0);
	DrawSprite(20*8,20*8,0,s3+0x30,0);
	if(Pad & A) {
		radius++;
		if(radius>120)
			radius=120;
	}
	if(Pad & B) {
		radius--;
		if(radius<5) 
		radius=5;
	}
	
	angle=(angle+5)%360;

	
}
添付ファイル
sincos_cc65.zip
(235.77 KiB) ダウンロード数: 121 回
circle.png
circle.png (9.08 KiB) 閲覧数: 3833 回

box
記事: 2002
登録日時: 14年前

Re: cc65での固定小数点(cos,sinテーブル)に関して

#2

投稿記事 by box » 14年前

TKOZ さんが書きました:

コード:

		x[i]=128+(addx*(+radius))/100;
		y[i]=120-(addy*(+radius))/100;
+radius
っていうのはどういうことをしようとしているんでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
KEYONN_
記事: 70
登録日時: 14年前

Re: cc65での固定小数点(cos,sinテーブル)に関して

#3

投稿記事 by KEYONN_ » 14年前

x=128+(addx*(+radius))/100;
y=120-(addy*(+radius))/100;

+radiusというのは、
例えば、例を示すと
int a=120;
int b=3;
double c;

c=a*b;
とすると、変数cには、double型じゃなくて、int型の数値が入りますね?

しかし、
c=(double)a*(double)b;とすれば、変数cには、double型の数値が入りますよね?(多分ですが

それと同様に、signed char addx;
にradiusを掛けると、値がへんてこな値になってしまうのでは?と思い、
+という明示的なキャストを狙いました。

box
記事: 2002
登録日時: 14年前

Re: cc65での固定小数点(cos,sinテーブル)に関して

#4

投稿記事 by box » 14年前

TKOZ さんが書きました: c=a*b;
とすると、変数cには、double型じゃなくて、int型の数値が入りますね?
そんなことはありません。右辺はまちがいなくint型ですが、cに代入する際、doubleに型変換します。
cに360という整数が入っているのであれば、printf()か何かでcを出力する際、書式指定文字は"%d"で
かまわないはずですが、実際にやってみるとどうなるでしょう。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
KEYONN_
記事: 70
登録日時: 14年前

Re: cc65での固定小数点(cos,sinテーブル)に関して

#5

投稿記事 by KEYONN_ » 14年前

TKOZです。
BCC Developerで変数cは、printfで%dを指定したら、0が表示されました。
double変数は掛け算では左右されないということでしょうか?
割り算ではどうでしょうか?ちょっとやってみます。
[追記]0が表示されました。ああ、何かと間違えてました私は。
これです。

コード:

#include<stdio.h>

int main()
{
    int a=11,b=3;
    double c;
    c=a/b;
    
    printf("c=%f",c);
    
    return 0;
}
とすると、c=3.000000と表示されるのと誤解してました。

あと、何故か、static signed char radius=30;を
signed char radius=30;
に変えたら、動きました。
でも、変数radiusをMoveCircle関数内で変えたいので、なんとかしたいところです。

box
記事: 2002
登録日時: 14年前

Re: cc65での固定小数点(cos,sinテーブル)に関して

#6

投稿記事 by box » 14年前

TKOZ さんが書きました: c=3.000000と表示されるのと誤解してました。
本題の件とはそれてしまいますが、これは、3.000000って出力するはずですよ。
int型同士の割り算をした結果、小数点以下を切り捨てた3という値を
型変換してdouble型に入れて、それを"%f"で出力してるんですから。
そうでないと、さっきの掛け算の件と矛盾してしまいますよね。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
KEYONN_
記事: 70
登録日時: 14年前

Re: cc65での固定小数点(cos,sinテーブル)に関して

#7

投稿記事 by KEYONN_ » 14年前

一応解決しました。ポインタを使いました。
ただ、何故static char r=30;でrが30に初期化されないのか不思議です。

画像とファイルを添付します。

[追記]
boxさん、回答ありがとうございました。最近ありがとうと書き込むのを忘れてました。
これって大事ですね。
添付ファイル
sincos_cc65.zip
(28.1 KiB) ダウンロード数: 134 回
gazou.PNG
gazou.PNG (10.53 KiB) 閲覧数: 3760 回

閉鎖

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