2 ポイント 投稿者 GN⁺ 2025-01-01 | 1件のコメント | WhatsAppで共有

なぜZigでゲームボーイアドバンスのゲームを書いたのか

  • ゲームボーイアドバンスの魅力
    ゲームボーイアドバンスは現代的なCPU(32ビットARM、多数のレジスタ)を搭載している一方で、古いタイルベースのレンダラーを使っている。これはNESが80年代に使っていた方式に近い。任天堂における最後期のタイルベースシステムの1つであり、アフィン変換、透明度、スプライト効果など、さまざまな機能を備えている。

  • Zig言語を選んだ理由
    当初はC++でゲームボーイアドバンスのプロジェクトを始めたが、最初の完全なゲームはZigで書いた。Zigはまだベータ版で、ゲームボーイアドバンスの発売から15年後に作られた言語であるにもかかわらず、組み込みプログラミングに適した機能を備えている。

ツールチェーン

  • LinuxとdevKitPro
    Linuxを使う中でパッケージ管理の難しさを感じており、Nintendo DS向けの3Dシーンを作る際にはdevKitProを使う必要があった。これにはGCCツールチェーン、ライブラリ、開発ツールが含まれている。ArchLinuxのパッケージマネージャー経由でインストールしなければならない煩雑さがある。

  • Zigの利点
    Zigはクロスコンパイルを容易にし、複雑なパッケージマネージャーを設定する必要がない。Zigのビルドシステムは、build.zigファイルのbuild関数を実行してビルドを進める。これにより、ビルドプロセスが簡素化され、エラーも減る。

Packed Structs

  • Packed Structsの重要性
    ゲームボーイアドバンスは高級API呼び出しなしに、レジスタを通じてハードウェアを制御する。Zigのpacked structはメモリレイアウトを最適化し、ハードウェア制御を容易にしてくれる。これはゲームボーイアドバンスのプログラミングで非常に有用な機能である。

Comptime

  • コンパイル時のコード実行
    Zigはコンパイル時にコードを実行できる機能を提供している。これにより、実行時にデータを圧縮するのではなく、コンパイル時に圧縮できる。Zigのこの機能によって、データを簡単に圧縮できるようになる。

標準ライブラリ

  • Zigの柔軟な標準ライブラリ
    Zigの標準ライブラリはジェネリクスをサポートしており、メモリ確保関数にアロケータを引数として渡せる。これにより、独自のメモリ確保方式を利用できる。Zigの標準ライブラリは、ハードウェア制約のある環境でも柔軟に使える。

問題点

  • インラインアセンブリ
    Zigはインラインアセンブリをサポートしているが、出力は1つしかできない。これはGBAのBIOS関数で複数の値を出力する必要がある場合に問題となる。

  • Thumbコード/ARMコード
    ゲームボーイアドバンスのCPUはARMモードとThumbモードをサポートしている。ZigではARMモードとThumbモードを明示的に指定できない。

  • 奇妙なメモリ
    ゲームボーイアドバンスのビデオメモリは8ビット単位で書き込めず、そのためグラフィックが壊れる問題を引き起こす。Zigはメモリコピー時にmemcpyを使って最適化するが、これはGBAの「奇妙なメモリ」と衝突する可能性がある。

1件のコメント

 
GN⁺ 2025-01-01
Hacker Newsの意見
  • 特定のアドレス範囲に対するメモリアクセス方法を指定できる仕組みが必要。Zigのドキュメントどおりにvolatileを使っても解決しないなら、コンパイラにバグ報告することを勧める
  • 5年前にLinuxを使い始めた理由は、WindowsでPythonをセットアップする方法が分からなかったから。1997〜2015年のあいだWindowsが支配的なOSであり、その結果として若い世代の知識不足が深刻化した。初期にはインターネット接続が一般的ではなく、プログラミング環境のないOSはプログラミングの機会を失わせていた
  • Game Boy Advanceではビデオメモリに8ビット単位で書き込めず、そうするとグラフィックが壊れる。エミュレータでは動いたが、実機で問題を見つけて修正する必要があった。Nim言語向けのGBAツールチェーンも開発された
  • コンパイラがメモリコピー関数をmemcpyに置き換える最適化を行うことがある。この最適化はユーザー空間でのみ行われるものだと予想しており、-nostdlibオプションで自動的に防げることを期待していた
  • Cでpacked structを使う方法としてビットフィールドを提案。有効なCコードの例も示している
  • Game Boy Advanceのメモリ問題を解決する方法が必要。LLVMがこの機能をサポートしているのか気になっており、Zigへの統合もそれほど難しくないだろうと考えている