ゲームボーイアドバンス(GBA)非公式開発 Part2
■ このスレッドは過去ログ倉庫に格納されています
>>701 レスありがとうございます。 ファイル名を変えてやってみましたがうまくいきませんでした。。 代わりにリンカスクリプトでプログラムの開始アドレスを0x08000000に変えたら動きました! おかげで挫折する期間が延びましたwありがとうございました。 しかしbox_tile.cより前に出てくるプログラムは何で内部メモリブートでもうまくいったのかなあ すいません。「Linuxから目覚めるぼくらのゲームボーイ!」 を第3章まで読み進めたのですが、clock.cがうまく動作しません。 割り込みハンドラの中でvolatile修飾したグローバル変数の値を書き換えているのに 全く値が変わりません。なにか考えられる原因はありますか? ちなみに割り込みハンドラ自体が実行されていることは自作のprintf文の実行結果から 画面に文字が出力されるので間違いありません。 >ちなみに割り込みハンドラ自体が実行されていることは自作のprintf文の実行結果から >画面に文字が出力されるので間違いありません。 釈然としない どう出力されたからそう思ったの? ちょっと貼ってみてよ 該当部分のソースを張ります。 これでタイマー0がオーバーフローしたときに下記関数が実行されて、 VBAver1.7.2だとなぜか0110100100111010が常に表示されます。 volatile int tmr0_cnt = 0x0000; void int_handler(void){ int flag; int i; register(INT_IME) = INT_IME_OFF; flag = register(INT_IF); if(flag & INT_TMR0){ tmr0_cnt++; draw_str("タイマーわりこみ", 0, 13, BG_1); for(i=0; i<16; i++){ if(((tmr0_cnt >> i) & 0x0001) == 1){ draw_str("1", 16-i, 1, BG_1); } else{ draw_str("0", 16-i, 1, BG_1); } } } register(INT_IF) = flag; register(INT_IME) = INT_IME_ON; } ちなみにメイン関数の方では下記処理を行っており、 タイマ0のカウンタは正常にカウントアップしていることが画面表示から確認できました。 何か分かりますでしょうか。よろしくお願い致します。 while(1){ sec = register(TMR_COUNT0); for(i=0; i<16; i++){ if(((sec >> i) & 0x0001) == 1){ draw_str("1", 16-i, 0, BG_1); } else{ draw_str("0", 16-i, 0, BG_1); } } } あと、リンカスクリプトを書き換えて、テキストセクションの開始アドレスを 0x80000000にしているのですが、このことが何か関係があるのでしょうか。。 ひょっとして全て理解した上でからかってる? >>707 はたしかに関係ある テキストセクションを0x08000000に置いたあと以降の 連続した領域にBSSセクションとデータセクションを置いているので グローバル変数に書き込みたくてもROMだから書きこめない 今までよく動いてたな。。。 リンカスクリプトについての理解が不十分でした。 下記ホームページを参考にリンカスクリプトを書き換えたら、 見事1秒ごとにtmr0_cntが0からカウントアップされるようになりました。 おかげで挫折する期間が延びました。ありがとうございました。 http://www.nextappli.com/index.php?GBA%2FROM%B2%BD#content_1_0 例えば mov r1, #128 strh r1, [r3, #0] ldrh r3, [r2, #0] を実行するのに、何クロック掛かるか・・という事を説明してくれる 本やサイトご存知内ですか? 数十曲の音楽データをROMに格納したいのですが容量が足りません。 何か工夫が必要なのでしょうか。 マザー3なんかは100曲ものBGMが入ってましたがあれはどうやって実現しているのでしょうか。 すいません。100曲でなく250曲の間違いでした。 譜面データと、音源データを分けて持っているから、かな? MIDI見たいな感じで。 それに、要所要所でPCMをかぶせれば 大抵の曲は再現できそう。 あとは、圧縮をかけるだね。 (譜面データにたいして、また、ADPCMとは言わないが適当な圧縮形式で。) そんなのは俺の手に負えねえ。ここで挫折しまするわ。 ここでGBの事聞いても大丈夫かな? バンク切り替えの事について調べてるんですけど MBC2のバンク切り替えについてすずめさんところのウェブアーカイブと お受験に出るゲームボーイのページを調べてみたんですけどMBC2に関する情報が載っていなくて… 恐らく0x2000番地への書き込みだと思うんですけどどこか正確な情報がある場所ってないでしょうか? それと現在自分がどのバンクを操作しているのか判別する方法があるかないかご存知の方いらっしゃいますか? もしかしてバンクの位置情報はどこにも展開されず完全に自分で管理する必要があるんでしょうか? デバッグの際にバンク情報がないと調べるのが大変で… スレ違い ttp://www.geocities.co.jp/Playtown/2004/gmbspecj.txt ttp://fms.komkon.org/GameBoy/Tech/Software.html エミュレータのソースも併せて読むといい すみません該当するようなスレが無かった物で。 挙げて頂いた上記サイト等も参考にしてみます。 エミュのソースをみれば確かに内部動作はカンペキに把握できますね。 GBのエミュも大分こなれてる様なのでその辺も参考にしてみます。 ご親切にどうもありがとうございました。スレ汚し失礼しました。 >>712-715 GBA用のFreeのMODライブラリでも使って組み込めばそれで終わり。 問題は、MODを作れるかどうかだがw devkitProを使ってGBAでゲームを作っているのですが、 const int hoge1 = 1 ; const int hoge2 = hoge1 ; のようにすると、「initializer element is not constant」と出てしまいます。 VC++だと普通にコンパイルが成功しました。 Cではこういう事は出来ないのでしょうか? >>720 スレ違いだが回答。 C言語とC++のconst修飾子の動作の違いのために起きる問題。 const int hoge1 = 1 ; がC言語では変数として定義されるのに対し、C++では定数として定義される。 このため、 const int hoge2 = hoge1 ; がエラーとなる(初期値つき変数に定数以外を指定したから)。 結論:C++でなくC言語で書くなら、定数はマクロやenumで定義しましょう。 余談だが、const修飾子には他にも違いがあり、グローバル変数をconst修飾した場合に、 C言語ではデフォルトで外部リンケージ(要するにextern)になるのに対し、 C++では内部リンケージ(要するにstatic)となる。 >>721 スレ違うというか板違いでしたね。 あと、一応補足。 当たり前だけどC++でグローバルな const int hoge0 = 1; static const int hoge1 = 1; extern const int hoge2 = 1; を定義すると、hoge0とhoge1は定数、hoge2は変数となる。 >>722 変数と定数と、どう言い分けてるの? 挙げられた例だと全部定数式として使えるはずだよ。 >>723 スマン。内容に不足があった。 ×hoge2は変数となる ○hoge2は定数であると同時に外部リンケージの変数も定義される なるほど、そもそもCとC++じゃconstの仕様が違うのですね。 良く分かりました。 板違いの質問に答えて頂き、ありがとうございました。 >>724 やっぱり変数と定数の意味に無理があるだろ。どこで そんなネタ仕込まれたんだ? 722 の3つは全部 const int 型変数の定義。 const int 型変数が定数式で初期化されていれば、 それもまた定数式となる。 リンケージはそれぞれ決まっているし、外部リンケージ じゃなければ初期化が必須だったりするけど、それらは 定数式として使えるかどうかとは別の話。 GB音源(例えばチャンネル1)でエンベロープをハードウェアでは無く自力でやりたい場合、 SOUND1CNT_Hのbit12-15をいじって、 SOUND1CNT_Xのbit15を立てて初期化するしかないのでしょうか? これだと発音中の波形の状態も最初に戻ってしまうらしく、 音が自然にならないので困っています。 何か良い方法をご存知の方はいらっしゃらないでしょうか? その方法しか無いがチャンネル1と2は必ず発音がリセットされるので実質使えない チャンネル3はリセットされないからソフト制御可能 GBAのスペックに サウンド:アナログ(パルス波2ch+波形メモリ1ch+ノイズ1chの音源、従来機と同様)+デジタル(PCM)2ch ってあるけどこれと同時発音数は別の話だよね もっと沢山鳴らしてるようなメガデモはあるし、実際は何音までなんでしょ では同じトラック三つコピペして全部違うPCMにしても 音切れがないのはどういう仕組み? >>731 複数の音をリアルタイムに合成すればいいんじゃないの? デジタル(PCM)2chって書いてあるけど 合成すればいいってんなら何音まで? >>734 好きなだけ重ねればいいんじゃないかな。 あとは処理時間を見て4音や8音などに制限していくとか。 「GBA PCM 合成」でググってみるといいかもよ。 >728 うへぇそうなんですかorz レスありがとうございます。 こんなキッツイ制限があるのにGBのゲームには一杯名曲があるというのが信じられません。 というかFCよりもキツイですねこれは。 FCミニとか、エミュレーターとかも結構苦労して再現してそうですね。 Raylight Studios - Resident Evil GBA + Bonus http://jp.youtube.com/watch?v=DBHNtTNPzV0 やっぱ出なかったのは容量の問題かな devkitProを使ってみようかと思ってるのですが、 コレを使ってGBAソフトを作ってネットで配布する場合、 ソースも配布可能にしなきゃいけないのでしょうか? ライブラリを改変しなければ配布しなくてもよかったと思います。 >>740 ソースクレクレ厨が出てきたら、改変して売りつける悪質な業者だと思ったほうがいいよ 配布には十分注意しる まぁ、GBAだからもう居ないと思うけどね・・・ >>741 そのまま組み込めば、配布しなくてもOKって事ですか、分かりました。 教えていただきありがとうございます。 >>742 配布しなくちゃいけなくなった場合に、そういう輩も出てくるんじゃないかと 懸念していたのですが、どうやら大丈夫みたいですね。 海外ソフトの和訳ハックとか作れますか? もし可能性が少しでもあるなら頑張ってみようかなと・・・ 予備知識ゼロだけど・・・orz >>746 GBXchangerと任天堂パワーのGB用カートリッジがあれば、似たようなことができると思う この手のものは時期逃すと手に入りにくいからなあ・・・ 数年前なら、数少ないが売っている店はあった あとは今あるとしたらオークション GBのマジコンって今でも需要あるんだね KOMAKUYAはもうスターターキット出さないのかな void line(hword Xa, hword Ya, hword Xb, hword Yb, hword color) { hword x, y; int j = Ya; int e = 0; for(x = Xa; x < Xb; x++) { draw_point(x, j, color); e = e + (Yb-Ya); if((Xb-Xa)< e) { e = e - (Xb - Xa); j = j + 1; } } } このメソッドがどのように動いて斜線を引いているか分かり易く教えていただけないでしょうか? draw_pointメソッドは指定された(x,j)座標にcolorで指定した色のドットを表示するメソッドです。 斜線の範囲は(Xa, Ya)から(Xb, Yb)です。 void line(hword Xa, hword Ya, hword Xb, hword Yb, hword color) { hword x, y; int j = Ya; int e = 0; for(x = Xa; x < Xb; x++) { draw_point(x, j, color); e = e + (Yb-Ya); if((Xb-Xa)< e) { e = e - (Xb - Xa); j = j + 1; } } } このメソッドがどのように動いて斜線を引いているか分かり易く教えていただけないでしょうか? draw_pointメソッドは指定された(x,j)座標にcolorで指定した色のドットを表示するメソッドです。 斜線の範囲は(Xa, Ya)から(Xb, Yb)です。 ブレゼンハムでググれ こんなところで聞くよりいい解説がどこかにある デジタル微分解析(DDA)でググ・・・ったら余計わからんくて俺が吹いた 厳密に考えるとやっかいなところは多々あるが 2Dで直線や多角形描くぐらいならただの差分方程式だろ GBAで1〜10までのランダム値を取ろうと思ったらどうすればよいのでしょうか? rand()は使えませんよね >>757 rand() % 10 + 1 …ってスレ違いだね。 プログラミング初心者向けのスレに行くといいよ。 Homebrew BOF ゲーム機など開発環境が公開されていないハード、及びマイナーハード開発者の集いを企画しています。 日時:コミケ(12/28-30)前後 当日なら17-19時くらい + 宴会 場所:東京都区内 費用:会場実費(0-数百円?) たぶん日本全体で100人もいないんじゃないかと思いますが、 コミケで上京する人もいるでしょうからその時期を予定しています。 http://www27.atwiki.jp/homebrew/ マルチすまん サウンドプレイヤーを自作したいと思っています。20曲程入れたいんですが何らかの形で圧縮して組み込みことが必要だと思うのですがどうしたらいいですか。 PCではDXライブラリを使えばMP3の再生ができるので作れることが分かっています。 じゃ、DXライブラリ使わずにmp3再生できるように頑張れ DMA1&2とTIMER0&1を使って、ダイレクトサウンドA&Bで同時に音を鳴らしたいのですが 片方しか音が鳴りません。 VBAのIOViewerでFIFOが変化しているのは確認したのですが 何も音がしない理由としては、どんな事が考えられますか? SGCNT0_H(0x4000082) SGCNT1(0x4000084) の音量他もちゃんと値が入ってます。 本当に値が正しいなら あとはVBA側でDirect Sound A,Bのどちらかがオフになってる位しか無いな レスありがとうございます。 VBAの設定も間違いなかったみたいです。 あれから色々試してました。 実は多重再生の為に、FIFOにコピーするバッファはサウンドデータと別にしていて、 TIMERのハンドラ内で手動でDMAを使ってFIFOにコピーをしてました。 鳴らないのはダイレクトサウンドAの方(BGM用)で、 ダイレクトサウンドB(効果音用)が鳴った時に何故かAも鳴ったので 調べてみると、効果音用のTIMER1が動くと鳴ると解りました。 とりあえず、AとBのFIFOコピーにどちらもTIMER1を使用することで一応解決しました。 タイマーを分けると鳴らなくなる理由がわからないままですが。 もしやDSOUNDCTRL(0x4000082)以外にも、 TIMERとダイレクトサウンドを関連付けるレジスタがあるのでしょうか? 原因が解りました…。 DSOUNDCTRLの初期化にor演算子しか使っていなかったこと (タイマーを指定するのに、DSOUNDCTRL |= DSOUNDCTRL_ATIMER(0)としかやってませんでした) 自分の使っているgba_sound.hのDSOUNDCTRL_ARESETが 0x0400と定義されていた事(実際は0x0800。0x0400はタイマーの指定に使用) が原因でした…。 お騒がせしてしまってすみませんでした。 GBAとかファミコンは開発環境が強力じゃないから そういう所でハマっちゃうと、抜けるの大変だよね GBAではないですが、GBCの板が見当たらなかったので試しに書いてみます。 ttp://nagasaki.cool.ne.jp/xor-a/ ユーザーアプリがロッピーとかで配信出来たらなぁと思うのは愚痴ですが。 GBCの板は昔あったんだが、過疎すぎて落ちちゃった VCとかに配信できたら面白そうだけどね>自作ゲーム 今まではメインループの始めにV-Blankを待って、それから各処理を行っていたのですが、 開発が進むにつれてV-Blank中だけじゃ処理が間に合わなくなってしまいました。 そこでゲーム処理と描画関係の処理にわけて while( V_COUNT != 0 ){} GameProc() ; // ゲーム処理 while( V_COUNT < 160) {} GraphicProc() ; // 描画関係の処理 と、二つに分けてやる事にしました。 表面上はうまく動いているように見えるのですが、 こういう事をやってしまっても大丈夫なのでしょうか? 分けること自体は問題ないけど ゲーム処理でV_COUNT != 0を待つ意味は無いよ 描画が終わったらすぐに処理を始めていい while( V_COUNT < 160) ; GraphicProc(); GameProc(); >780 おおなるほど。 確かにそうした方が処理時間をより多くさけますね。 レスありがとうございます。 ここってまだ人いますかね…… 自分で作ったプログラムをPogoShellから起動する場合,「終了してPogoShellに戻る」 という機能をつけると便利だと思うんですが,やりかたがさっぱりわかりません. どこで調べればいいのかご存知のかた,教えてくださいませ. Pogoshell resetでググってみた。 ttp://boards.pocketheaven.com/viewtopic.php?p=52627&sid=a2b1ee533e1a9b52029d305b2c611034 になんか書いてあるような気がする。 あとは自分でガンバレ カートリッジのバンクセレクタを元に戻してswi 1, swi 0の順でリセットかければおk Visoly系(F2A)とEZ/XG-Flashはlibpogoのrestart.Sを使えばいいよ おお,回答ありがとうございます. リブート自体はbiosコールでできるのかなとは思ってたんですが, バンクセレクタ云々というのが俺がよくわかってない点のようですね. F2Aを使ってるので,とりあえずrestart.sを見てみます. 実はC言語しか知らないので時間がかかりそうですが. 圧縮した音楽ファイルはどうやって再生すればいいのでしょうか。wavじゃサイズ大きすぎる。 何で圧縮した音楽ファイル?まずはそこからだけど。 mp3は再生できないよ。 そもそも、サンプリングされた音の再生がGBAじゃ無理だと思うんだが スペックが足りない それはさすがにGBAなめすぎ。 44kHzで16トラック合成出来るくらいのスペックはあるよ。 >>786 > wavじゃサイズ大きすぎる というのはちょっと理解が足りないと思います。 wavやaviは単なる入れ物なので、中身が問題。 多分、PCM(非圧縮)のことを言ってるのですよね? 同じwavでも中身がmp3だったりADPCMだったりするならサイズは小さくなります。 IMA ADPCMなら約1/4になるし、デコード処理も軽いのでオススメ。 また、Windows付属のサウンドレコーダーでデータが作成できるので手軽。 http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM http://wiki.multimedia.cx/index.php?title=IMA_ADPCM が参考になります。 wav内での格納形式は前者のURL、デコード処理は後者のURLを参照して作ってください。 データはwav内のブロック単位で処理し、ブロック内でデータは完結します。 デコード処理はURLに書かれている4行の処理が全てです(最適化についても書かれていますが)。 また、sox等のソースも参考になります。 効果音の周波数って、どれくらいが良いんでしょうか? アクションゲームを作っているのですが、 現在8000kHzで同時再生させる為に自力合成で結構処理が重いです。 >>791 の8000kHzは8000Hzの間違いでしたw >>792 77.8MHzという事は77800000Hzですか。 8000Hzでヒーコラ言ってるので自分では無理っぽいですね。 >>792 ZIP-FMか! >>793 ネタをネタと(ry なん・・・だと? 出来るかわかりませんが市販のゲームを調べてみます。 8kHzくらいで重くなるってことはほとんど無いから なにかやり方間違ってるんじゃないの? DirectSoundからサウンド要求があるたびに割り込んでたりとか やっぱり8000Hzは低い部類になるって事ですね。 現在は、合成用バッファを1フレームで消費する量の2倍確保して、 前半を再生中なら後半に書き込み、後半を再生中なら前半を書き込む処理を 1フレームに一度呼び出す方法を取っています。 2チャンネル同時再生するとHBlankの数値が30弱くらいの重さです。 やっぱり何かやり方が間違ってそうなので、ソース見直して見ます。 重いというからどれほどかと思ったら2音合成でHBlank30ライン分か。 チューニングしてなければ、それくらいはいくかもね。 軽くポイントだけ。 7884Hzにしろ8121Hzにしろバッファのサイズは4の倍数なのでループを4回分展開出来るな。 10512Hzだと16の倍数になるから、16回展開出来る分更に速いかもしれない。 どっちにしてもDuff's Deviceを使えばいい。 効果音は1フレーム単位のサイズに揃えれば、終了判定は毎フレ1回/チャンネルに抑えられる。 これをやった上でそれ以上速くしたかったら、既成のライブラリを検討した方がいいかもしれないよ。 void mixAudio(); // プロトタイプ宣言 void mixAudio() { ... } // コード があるとして void mixAudio() IWRAM_CODE; IWRAM_CODE void mixAudio() { ... } にして、そのソースを-marmでコンパイルするだけで、おそらく負荷が1/3になる。 手元で軽く組んでみたが馬鹿正直に作って2チャンネル合成でHBlank30弱だったのが IWRAM_CODEにしたら10弱になった。 >798 ループの展開…?forループを全部べた書きするという事なのか…?と思いつつ、 「Duff's Device」というのを知らなかったのでググって見たのですが、 これは凄いですね。こんな方法は自分では絶対に思いつかないです。 >799 わざわざ検証して頂いてありがとうございます。 IWRAM_CODEという存在は知っていたのですが、 効果音再生よりも重い処理があったら困るので、 これは最後の切り札にしようと思ってました。 ループで成り立っている高負荷な処理は、切り札と言わず全てIWRAM_CODEにすればいいよ。 ぶっちゃけループ展開はする必要ない。 俺はPCM合成の他にアニメーション処理や当たり判定をIWRAM_CODEにしてる。 This guy was lying in bed, tossing and turning and groaning, and finally he sits up, opens his mouth, and shoots a six-foot flame across the room. , ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる