1 ポイント 投稿者 GN⁺ 2024-02-26 | 1件のコメント | WhatsAppで共有
  • Magicore Anomalaは、1985年に発売されたAmigaのグラフィック・サウンド能力を使ってフルスクリーンCGとアニメ風の切り替えを実現しているが、ゲームエンジン内ではRAM配置、画面分割、スプライト制約を同時に解かなければならない
  • 一般的なAmiga 500構成では、グラフィック・サウンドに使えるChip RAMは512KBしかなく、320x240・32色CGの非圧縮サイズ48KBは大きな負担になる
  • CGはZX0圧縮で約8KBまで縮小して拡張RAMに置き、表示直前にChip RAMへ展開しながら既存の画面メモリ48,000バイトを再利用する
  • 切り替え効果は、copperが特定のスキャンラインでハードウェアレジスタを変更し、bitplane DMAをオフ・オンする方式で作られ、CPUは毎フレームsplit幅に合わせてcopperlistの値を調整する
  • 背景のmotion linesは、Amigaスプライトの色・再利用・bitplane依存性を回避する必要があり、attached spritesとダミー制御ビット、1枚のbitplane維持、BPLMOD1調整が中核となる仕掛けになっている

Amiga 500でフルスクリーンCGを入れるRAM問題

  • Magicore Anomalaの対象プラットフォームは一般的なAmiga 500で、構成は512KBのChip RAMと512KBの拡張RAM
    • Amigaチップセットがグラフィックとサウンド出力に使えるメモリはChip RAMだけ
    • 拡張RAMはCPUしかアクセスできないため、グラフィック・サウンド用として直接使いにくい
  • フルスクリーンのキャラクターグラフィック(CG)は320x240ビットマップの32色画像で、非圧縮では48KBを占める
    • 共通アセット、レベルデータ、画面メモリ割り当てまで考えると48KBは大きなオーバーヘッド
  • 最近追加されたアセット圧縮サポートはZX0圧縮形式を使う
    • 圧縮後のCGは約8KBまで縮む
    • レベルアセット読み込み時に圧縮済みCGを拡張RAMへ置く
    • 表示直前にChip RAMへ展開する

新たに48KBのChip RAMを確保しない方法

  • CGのために別途48KBの空きChip RAMを探すのではなく、既存の画面メモリの一部を再利用する
    • 部屋の背景画像
    • 危険オブジェクト描画用の画面レイヤー
    • テキストボックスの画面領域
  • この3つのメモリ領域はRAM上で連続しており、合計サイズは48,000バイトでCGの正確なサイズと一致する
  • 部屋の背景画像はCG表示終了後に復元できるため、上書きしても問題ない
  • CGの展開には約500msかかるが、カットシーンの流れに組み込むことでローディングには見えないようにしている
  • Magicore Anomalaのゲームプレイproof-of-concept映像はYouTubeで見られる

画面分割効果とcopperの使用

  • 当初は縦wipe切り替えを考えていたが、見栄えよくするにはスキャンラインごとのカラーパレット調整によるグラデーションが必要だった
    • copperだけでは1回の水平ブランク中に32色すべてを設定するのは難しいと判断した
    • 「racing the beam」を扱いたくなかったため、画面分割効果を選んだ
  • 画面分割効果は一般の視聴者にもより派手に見え、Amigaのcopperはまるでこうした効果のために設計されたかのように動く
    • 類似の効果がAmiga Workbenchに組み込まれている例はこの動画で確認できる
  • 実装にはAmigaの2つの機能を組み合わせて使う
    • copperはCPUと並列に独自の命令リストを実行し、特定の画面ラインでハードウェアレジスタを変更できる
    • 画面ポインタをハードウェアレジスタに設定することで、画面メモリをChip RAM内の任意の位置へ切り替えられる

bitplane DMAを止めてから再開して描画する

  • 例としてメイン画面メモリが0x20000から始まる場合、通常はcopperがbitplane DMAレジスタにこのアドレスを設定する
    • bitplaneを有効にすると、DMAはそのメモリ領域を順番に読み取りながら画面へ描画する
  • 各水平ラインが0x100バイトを占めるとき、画面ポインタを0x20800に設定すると画面が8ライン上へスクロールしたように見える
    • 画面の開始位置がメモリ上で8ライン下へ移動するため
  • 分割の上半分はこの方法で上にスクロールさせる
  • split地点でcopperはbitplane DMAをオフにし、背景色を赤へ変更する
    • bitplane関連のハードウェアレジスタはその時点で事実上停止する
    • splitの下側に達したら背景色を元に戻し、bitplane DMAを再びオンにする
    • 画面は停止していた位置から描画を再開するが、実際の表示位置はさらに下になっている
  • 毎フレームCPUはsplitの現在の幅に応じてvs_TCopTopvs_TCopBottomを調整する
    • 上側split用の画面ポインタ調整も同時に行われるが、コード例には含まれていない

「woosh」モーションラインのためのスプライト回避策

  • アニメ風背景のmotion linesはスプライトで描く
    • スプライトは画面メモリと独立して描画・移動できるため、この用途に向いている
    • ただしAmigaスプライトは制約が多く、扱いも複雑
  • 色の制約

    • スプライトはbitplaneとカラーパレットを共有するため、使う色はできるだけ少なくする必要がある
    • motion linesは3色だけを使い、CGに28色、背景に1色を残す
    • Amigaではスプライトのペアごとに使えるパレット色範囲が異なる
      • 最初の2つのスプライトは色16-19を使う
      • 次の2つのスプライトは色20-23を使う
    • 2つのスプライトをattachすると、16色パレットを持つ1つのスプライトのように動作し、色16-31を使える
    • motion linesは4つのattached spritesを使い、グラフィックでは色29-31だけを使う
  • 同じスプライトグラフィックを複数位置で使う

    • スプライトグラフィックの先頭4バイトは、位置と高さを指定する制御ビット
    • 同じグラフィックを複数位置に描くには、この構造が問題になる
    • ハードウェアレジスタでスプライト制御ビットを直接設定しようとしたが、画面に表示させることはできなかった
    • Amigaのsprite DMAはbitplane DMAと同様にスプライトデータポインタをたどって画面へ描画する
    • 解決方法は、4バイトの偽スプライトを8個作ること
      • この偽スプライトは制御ビットだけを含む
      • すべてのスプライトポインタをまず偽スプライトへ設定する
      • 約19ラインの位置でsprite DMAがポインタを参照して制御ビットをロードする
      • その後すべてのポインタを実際の「motion line」グラフィックへ切り替える
    • 結果としてDMAは異なる位置にスプライトを描くようロードされた状態で同じグラフィックを使い、この切り替えはcopperlist内で処理される

bitplaneをオフにするとスプライトも消える問題

  • CGが画面上端に到達する前は、画面上側とCG開始位置の間に空白領域がある
    • このときbitplaneをオンのままにすると、画面にゴミデータが描かれてしまう
  • この領域ではbitplaneをオフにして、DMAがゴミデータを読まないようにする必要がある
  • 問題は、bitplaneをオフにするとスプライトも描画されなくなること
    • motion linesがCGの境界内でしか見えなくなる現象が起きる
  • 解決策は、bitplaneを完全にはオフにせず1枚だけ有効にし、画面ポインタを空データへ向ける方法
    • 画面には何かが描かれるが、結果として何も見えない
  • 空の画面全体を用意する必要はない
    • 1ビットピクセルで320ピクセルの1ラインは320ビット、つまり40バイト
    • BPLMOD1-40に設定すると、各ラインの後でポインタが40バイト戻るため、同じ40バイトを繰り返し描画する
    • 画面のsafety margin内にある先頭40バイトを空にしておけば十分

結果と残る細かな課題

  • 当初はRAM要求量のため、このようなCGをゲームに入れるべきか確信が持てなかったが、データ圧縮を実装した後はオーバーヘッドが非常に妥当な水準だと確認できた
  • Magicoreに追加の視覚的演出を入れられるようになった
  • 取り上げていない細かな課題も残っている
    • たとえば、100pxのmotion lineが画面上へ抜けたあと、下端が突然消えないようにする問題
  • この効果はblitterを一切使っていない
  • Amigaは、1980年代後半の人々に強い印象を与えたのと同じように、今でもカラーグラフィック表示能力によって人々を驚かせられるプラットフォームであり続けている

1件のコメント

 
GN⁺ 2024-02-26
Hacker Newsのコメント
  • Racing the beam」が何を意味するのか、これで完全に分かる。昔は vsync されたルーチンの開始時と終了時でビームの色を変えて、1フレームあたり何本分のスキャンライン相当の CPU 時間を使えるか測っていた
    この用途で使っていたアドレスが $dff180 だったのを覚えている。カラーパレット 0 なので、ビットマップ領域の外側にある画面の縁でも常に見えていた
    その手法もインターネット抜きですべて口コミで覚えたし、今でもあのチップセットからさらに引き出そうとしている人たちがいるとは思わなかった

  • Amiga でゲームを作る時間を確保しているのが実際どんな人たちなのか、本当に気になる。若い人はこういう古いコンピュータに興味がなさそうだし、それで育った人たちは家族や仕事で忙しいはずだ
    たとえ忙しくなくても、同じくらい楽しくて今っぽさも保てるプロジェクトはいくらでもある。それでも本当にすごいと思う

    • 自分は 1991 年生まれで、Windows 95 の PC に移る前は家に Amiga 1000 があった。だからずっと Amiga に郷愁があったし、その性能を支えた独特で強力なチップ群を理解するほど愛着も深まった
      今はフルタイムのインディーゲーム開発者として働いている。Amiga のゲームを作るのは生涯の夢に近くて、今ならそれを実現できる技術があると思っている
      現代のツールと広く共有された知識を活用すれば、モダンな設計原則を持つゲーム体験によって、愛されたクラシックハードウェアに新しい命を吹き込めることを示したい
    • 多くの人にとっては、Amiga、C64、Atari、ZX Spectrum 以上に面白いものはない
      人生のすべてをキャリアに結びつけてしまうと、人生全体が仕事になってしまう
      Photoshop があるのに、なぜ油絵を練習するのかと尋ねたり、Tesla があるのに、なぜヴィンテージカーをレストアするのかと聞くようなものだ
    • この集団に入るには若すぎるかもしれないが、自分の時代より少し前のコンピュータがかなり好きだ。Commodore 64 を手に入れてコンデンサを交換し、PLA も取り替え、デュアル SID と「リージョン切り替え」改造まで入れた
      リージョン切り替え改造は VIC-II を 2 個と発振器を 2 個切り替える必要があるので、かなり複雑だ。MSX2 も持っていて、あまり触れてはいないがとても魅力がある
      こういうマシン向けに実際にコードを書く時間を作るのは難しいが、たいていの社会人の趣味と同じで、ひらめいたときに夜や週末を注ぎ込む類いの話だと思う
      レトロコンピューティング は魅力的でやりがいのある素晴らしい趣味だ。ただ、不満があるとすれば時間よりも部品の値段と入手の難しさのほうだ
      コンピュータ市場では「アンティーク」や「ヴィンテージ」の札を付けて、何でも高く売ろうとする人が増えた気がして残念だ
      もっと年上の層については自分で語るのは難しいが、今でも Commodore 64 のデモを作っている人の中には、子ども時代と再びつながりたい気持ちが強そうな人もいる
      Bonzai と Pretzel Logic の比較的新しいデモ「Mojo」のように、ほとんどそのことを直接語っているような作品もある。demoscene 作品で「真面目な」ストーリーテリングをやろうとするのは少し気恥ずかしいが、それでも親しみがあって好きだ
      時間のかかる趣味ではあるが、本当に時間を作りたいなら結局は方法を見つけるものだ
      [1]: https://csdb.dk/release/?id=232966, https://www.youtube.com/watch?v=HXi3oJ9huiI
    • 新しいゲームコントローラを古いコンピュータにつなぐインターフェースを作っている友人がいる。ここでは Nintendo Balance Board を Commodore 64 の Decathlon で遊べるようにつないでいる
      [1] https://retro.moe/2024/02/04/bluepad32-v4-0/
      [2] https://www.youtube.com/watch?v=Nj5fZlt_834
    • 元記事の作者より 5 歳年上だ。パンデミック初期に、趣味でアセンブリを学ぼうと思って Atari、Amiga といくつかの資料を集めた。Udemy の講座もある
      https://www.udemy.com/course/programming-games-for-the-atari...
      在宅勤務をすれば自由時間が増えると思っていたが、現実はそうではなかった。それでもいつか続きをやらなければならない
  • Amiga で 日本のコンソール風ゲーム がどう見えたのか、そして Amiga の性能が足りなかったのか、それとも単に大半のゲームのデザインが自分の好みではなかっただけなのか、ずっと気になっていた
    Bonk は Factor 5 が見事に移植したが、彼らはほとんど魔法使いのような存在だった

  • 「普通の Amiga 500 には 512KB の Chip RAM と 512KB の拡張 RAM がある」という部分は少し不正確だ。標準の A500 には 512KB の Chip RAM しかなかった
    多くのユーザーは A501 RAM 拡張を追加して、グラフィックスハードウェアが直接アクセスできない 512KB の Fast RAM を増設していた
    Fast RAM と表記されていたが、拡張の仕組みのせいで実際の Fast RAM より遅かった

    • いわゆる Slow RAM
      ほとんどの A500 所有者は 512KB のトラップドア拡張を持っていた。Monkey Island のようなゲームを含め、多くのソフトウェアは合計 1MB の RAM がないと動かなかった
      今ではオープンハードウェア設計の安価なトラップドア拡張が広く出回っていて、1.5MB の Slow RAM、合計 1MB になるようにする 512KB の Chip RAM、RTC まで提供している
  • こうした 制約の中でコーディングする ことには、信じがたいほど強く惹かれる何かがある

    • 「芸術の敵は 制約の欠如 だ」
  • IE うれしい。Amiga を掘り下げているのを見るのはいいね

  • 自分が触っていた Amiga と、ここで語られている Amiga は別物だったのではという気がする。見栄えのいいゲームは確かにあったが、Nintendo NES もそうだったし、どちらもそこまで郷愁を持って振り返ることはない
    それでも、こうしたアニメーションがどう作られたのかを見せてくれるのはとても素晴らしい

    • 両方持っていたが、Amiga は正直 2 世代先のマシン のように感じられた。ハードウェアの違いを見れば驚くことではない
      Amiga は本当に全部入りのシステムだった。高性能な 32 ビット CPU、グラフィックスアクセラレーション、優れたオーディオ、そして NES の文字通り 256 倍の RAM を備えていた
      SNES ですら近づけず、Sega Saturn の時代になって初めて Amiga を上回るマシンを見た
    • 念のため確認したいが、これは今まさに開発中の 新作ゲーム だということは分かっている?
      https://www.youtube.com/watch?v=4SB20aFHc08