ゲームボーイアドバンス(GBA)非公式開発 Part2
■ このスレッドは過去ログ倉庫に格納されています
ゲームボーイのプログラム・改造マニュアル
ゲームボーイプログラミング入門
両方吸出し機とかの方に力入れてて全然役に立たなかった。
特に後者はGBAを表紙に入れておきながら殆ど触れていない。
一緒に買ったC言語超入門―Windowsでゲームボーイのプログラムを作ろう!は使えたなぁ。 すいません、質問させて下さい。
typedef unsigned char u8;
typedef unsigned short u16;
typedef signed char s8;
#define USE_SPRITE_NUM 8
typedef struct{
u8 tileno ; // 使用するタイル番号
u8 sizetype ; // スプライトの形状とサイズ。
s8 posx ; // 座標X
s8 posy ; // 座標Y
u8 mirror ; // 反転フラグ。bit0が左右でbit1が上下
u8 dummy[3] ;
} spritedata_t ;
typedef struct{
u16 tileno ; // 使用するタイルデータ番号
u8 usespritenum ; // 使用するスプライトの数
spritedata_t sprites[USE_SPRITE_NUM] ; // スプライトの情報
u8 dummy[1] ;
} graphicpat_t ;
こんな感じで、作ってるのですが、sizeof(graphicpat_t)でサイズを調べると、
VC++で作成したツール上で68、GBA上で72と、違いが出てくるのですが、
何故なのでしょうか?
境界揃えようとするから。
&graphicpat_t->sprites[0] でアドレス出力してみりゃいい。
typedef struct{
u16 tileno ; // 使用するタイルデータ番号
u8 usespritenum ; // 使用するスプライトの数
ここにダミーが1バイト
spritedata_t sprites[USE_SPRITE_NUM] ; // スプライトの情報
u8 dummy[1] ;
ここにダミーが3バイト
} graphicpat_t ;
多分こうなってる。 詳しいことはこちら。
ttp://www.jp.arm.com/tec_support/faqdev/ads037.html
対処法はこんな感じで。
#define __PACKED __attribute__ ((__packed__))
typedef struct{
u16 a;
u8 b;
u16 c;
} __PACKED ST_TEST; >>669-671
あれから自分でもパディングの事を調べてみたんですが、
パディングって構造体の最後だけじゃなくてメンバの途中にも入るんですね。
メンバがu8一つだけの構造体のサイズを調べると2バイトになっていたり、
u8二つの構造体のサイズは4バイトだったりするのが謎だったりで
まだちゃんと理解できてはいないのですがとりあえず
graphicpat_tのdummy[1]をusespritenumnumの次にする事でうまくいってます。
レスありがとうございました。
.cファイルに書いた場所(順番)によって、ポインタが指す場所が変わるのですが、
原因がわかる方はいらっしゃいますか?
具体的には
const u8 hogebindata[HOGE_SIZE] ; // .oファイルから
HOGE* pHoge1 = &hogebindata[0] ; // HOGE構造体のポインタ
HOGE* pHoge2 = &hogebindata[0] ;
これでpHoge1とpHoge2の指す場所が変わったのですが。
その現象は確認したことがないので
お役に立てないかも。
指す場所が変わったというけれど
1,2バイト程度のズレなのか、全然無関係な
アドレスを見ているのか気になります。
前者ならコンパイラの最適化の影響?
volatile修飾子つけてみてはどうでしょうか。
もしくは
HOGE* pHoge1;
HOGE* pHoge2;
pHoge2 = pHoge1 = &hogebindata[0];
でやってみるとか。 >674
レスありがとうございます。ズレも定義する位置毎に変わったり、
さらには他の部分の関数等の量(?)にも変わったりするので良く解りません。
とりあえず、今まではグローバルで定義と初期化をしていたのですが、
初期化をAgbmain()の冒頭にしたら見かけ上はうまく行きました。
原因が解らないのが気持ち悪いところではありますが…。
・u8型なのに、HOGE*型で参照しようとするので
キャストがおかしくなっているのかもしれない。
・Agbmain関数と聞いて、開発環境が
DevkitAdvanceではないかと思いました。
もしそうならばdevkitProに変えてみるといいかも。
・最終手段で、バグのままの状態でプロジェクト一式
アップしてみるとか(ぉ。
これぐらいしか思いつくことはないので
後は傍観させていただきます。 全部じゃなくても、そちらの環境で再現する最小限のソースをうpしてみなよ。 >676
片方が駄目で、片方は普通に使えるというのが謎なんですよね。
コンパイラの最適化関係で、何かされているのでしょうか。
makefileは他のサンプルをそのまま使っているので、
その辺のオプションは弄くれていないのでそういう事もあるかも知れないです。
それとお察しの通り、DevkitAdvanceを使ってます。
自分もdevkitProに変えたいのですが、いまいちやり方がわからず…。
もうちょい弄ってみます。
ソースは上げられませんが、HOGEの中身はu16 data[8]だけです。
>677
どれくらいの量でズレが起きるのかがイマイチ解りません。
新規に初めてみて試してみます。
2バイトパレットってBIT15は未使用のはずなのに、
ゲームによってはBIT15が1で、+8000hされてる色が
稀に使用されていたりして、用途がさっぱり解らないんだけど
誰かわかります?
色違いキャラなどで、同じ色が使用されている時に片方のみ
+8000hされてるなんて事はないから
意図的な設定なんだろうけど なんの根拠もないが、なんかのフラグで使ってるんじゃないか?
たとえば、パレットアニメの対象外にする時にビットを立てておくとか。
>662
変なのー。
周りのやる気をなくさせようという気がまんまんだね。
言ってることとやってることが違うと何だか腹立つ。
…やってること自体は簡単だから、「すごい」とか騙されては駄目だよ。
一介のプロのつもりなんだろうけど、むしろ手抜きが目立つね。
サウンドも背景もちゃんと凝った方が全体の評価は高い。 >>680
GBAだと使用しないけど、NDSだとBIT15は透過フラグになってて、モードによってはそのBITを立てて使う。
NDSのプログラムでも使えるようにしてるか、git(データの変換)なんかでフラグ立てる設定で
変換したのを間違ってそのまま使ってるんじゃないかな。
透過フラグの存在は初耳です。
でもキャラスプライトに二つ以上の透過色が
必要な使われ方はしてなかったようです。
何かのフラグが残ったままって可能性はありそう。
>>682
そういうケースもありそうですが、
パレットアニメが使われてた様子はないっぽいです 聞いたことないけど
もし'何かある'としたらブレンドモードだと思う。
どんな状況で表示されてるスプライトなんだ? >>685
NDSはスプライトにはタイルだけじゃなく、ビットマップも使えるようになってる。
ビットマップだと0番パレットみたいな透過色の代わりに、BIT15立てることによって透過を実現してるんじゃない。
俺にもビット15が0で色が表示されないと悩んでた時期があった
携帯電話の液晶を再利用したボードPC「DVIEW」
ttp://slashdot.jp/hardware/article.pl?sid=07/11/15/0122209
スプライトは使えないけど、オイラ的には実機でも動かしてみたいからこれ買うつもり
性能的にはこんなもん
CPU: ARM7TDMI Core (81MHz)
メモリ: On-Chip 40Kb SRAM (外部SD, FlashROMが利用可能)
ディスプレイ: 320x240、32K(RGB555)色
サウンド: 2ch,16bit audio-DAC for stereo/mono output (MP3, MIDI, ADPCM対応)
周辺機器: CMOS sensor input, VideoOut, SD Host I/F, UART, SPI, JTAG (拡張ボード利用で USB, LAN)
会社のページに繋がらないのは何故だ? >>692
最初に買ったパソコンはRAM16KBだったがいろいろ出来たぞ
全くの初心者なんですが質問させてください
既存のゲームをベースにポケモンやメダロットやFFなんかを、
テキストやら音楽やら絵やらパーツやらモンスターやらを追加したり差し替えたりして作りたいと思っているのですが
おおまかな手順と必要な知識を教えてください 簡単に言うと板違い。
gameurawazaに行って下さい。
難しく言うと
差し替え→コンスタント領域から該当箇所を見つけてリプレース
追加→コード領域からコンスタント領域参照部分を見つけて分岐もしくはテーブル書き換え
必要な知識→各種データフォーマット・LZ77圧縮法・ARM7インストラクション 算数知らないのに数学の教えを乞うようなモン
質問でもなんでもない
と書こうとしたら695が親切すぎて泣いた >>694
GBAは難しいからファミコンで練習するといいんじゃない。
super card上でデータを保存するにはどうすればいいんでしょうか
sramに書いたあと、自分でメニュー呼んでSDに保存できればいいのですが、どうパッチをあててもできず。
自作ソフトには付けられないんですかね、パッチ。
また、同じくsuper cardで新しめのファームウェアだと起動すらしないのですが、アプリ側でできる対処法などご存知の方いませんか 誰かwww.agbdev.netで配布してたデモ(Nok_Keysupd.zip、sprite.zipとか)
持ってる人いる?どんな中身か知りたいんだけどサイトが潰れちゃってさ。 すいません。この本「Linuxから目覚めるぼくらのゲームボーイ!」
を読みながら、第2章のbox_tile.cまで進んだんですが、
サンプルプログラムをそのまま使用して、
コンパイルまでできたのですが、VBAで実行させると画面が真っ暗なままで
何も起こりません。これは実機でないと動作しないのでしょうか? 半分あたり
その本はメモリからブートすることを前提にしているので
ROMからブートすることを前提にしているエミュだとそのままでは動作しない
VBAで動かすにはbox_tile.mb.binに名前を変えてあげな >>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/
マルチすまん
■ このスレッドは過去ログ倉庫に格納されています