2 ポイント 投稿者 GN⁺ 2024-04-22 | 1件のコメント | WhatsAppで共有
  • doom-htop は、htop のプロセス一覧をグラフィック出力のように使い、Doom 系ゲームの画面を ASCII 形式で表示する実験的プロジェクト
  • 実行には WAD ゲームデータファイルが必要で、リポジトリには freedoom1.wad が含まれており、classic shareware の DOOM1.wad は別途ダウンロード対象として案内されている
  • 動作方式は、Doom プロセスが画面の行数分だけ子プロセスを作成し、各プロセスが共有メモリから受け取った 1 行を自身の argv[0] に書き込み、htop のプロセス名領域にフレームを構成するというもの
  • htop はプロセス名を毎回更新するよう設定する必要があり、-d 1 で約 10 FPS のリフレッシュを目標にし、-s M_VIRT で仮想メモリ基準のソートを使用する
  • キーボード入力はキーボードデバイスを開く簡単な keylogger 方式のため sudo が必要になる場合があり、Ubuntu 22.04 でのみテストされていて、WSL と Arch ではデバイスパスの調整が必要

プロジェクトの目的と実行形態

  • doom-htop は、htop を古典的なビデオゲームのグラフィック描画に使えるか確認するために作られたプロジェクト
  • 結果画面は Doom を htop のプロセス一覧上に ASCII 映像のように表示する形になる
  • プロジェクトは ozkl/doomgeneric をフォークしており、Doom 実行に関する重い処理は同プロジェクトが担当する

ビルドと必要なゲームデータ

  • ビルドは doomgeneric ディレクトリで make -j8 を実行する
cd doomgeneric
make -j8
  • 実行するには WAD ゲームデータファイル が必要
    • リポジトリには freedoom1.wad が含まれており、クレジットは The Freedoom project にある
    • classic free shareware 版の DOOM1.wadDoom Wiki から入手できる
    • DOOM1.wad は GitHub にアップロードしても法的に問題ないか確信できなかったため含めていない

実行方法と htop の設定

  • 実行前に重要な作業を保存するよう案内があり、テスト環境は 12 年前の Lenovo ThinkPad T430s、8GB RAM、Intel Core i7-3520M @ 2.90GHz、Ubuntu 22.04 で、正常に動作した
  • 基本的な実行コマンドは次のとおり
sed -i 's/update_process_names=0/update_process_names=1/' ~/.config/htop/htoprc
sudo ./doom-htop -iwad freedoom1.wad
htop -d 1 -s M_VIRT
  • doom-htophtop はどちらを先に起動してもかまわない
  • sudo はキーボードデバイスを開くためだけに必要
    • sudo なしで実行すると入力は難しいが、画面は見られる
  • htop -d 110 FPS のリフレッシュを狙った設定
  • htop -s M_VIRT は仮想メモリ割り当て量を基準にプロセスをソートし、関連プロセスが見やすくまとまるようにするための設定
  • ソートがうまく合わない場合は main.cPROCS_MALLOC_SIZE の値を調整できる
  • sed コマンドは、htop がデフォルトではプロセス名を毎回更新しないため必要

内部の動作方式

  • リポジトリは既存の doomgeneric に主に 3 つのファイルを追加している
    • main.c
    • keylogger.c
    • ascii_stuff.c
  • ascii_stuff.c には、単純な 画像-to-ASCII 変換器 が生成した長い if 文が入っている
  • メインの Doom プロセスは、ASCII 変換画像の行数分だけプロセスを fork で生成する
  • メインプロセスは各子プロセスと 共有メモリセグメント を作成し、画像の各行を対応するプロセスのメモリセグメントにコピーする
  • 各子プロセスは自身のセグメントから内容をコピーして argv[0] を上書きする
  • htop はプロセス名として表示される argv[0] の値を更新しながら、画面の 1 行ずつを表示することになる

ソートのアイデアと入力処理

  • 初期のアイデアは CPU 使用率基準のソートで、特定の CPU 使用率を消費するプロセスを作ろうとしたが、実装は難しかった
  • Linux の nice 値も検討したが、一般ユーザーが設定できる値は 19 個しかないため、より良いグラフィックには不足すると判断した
  • 最終的に 仮想メモリ割り当て量 を使用し、プロセスごとにかなり具体的に調整できると見た
  • すべての fork プロセスが同じ量のメモリを割り当てても、テストシステムでは htop がフレームを正しい順序で表示した
    • 同率の場合は生成時刻基準でソートされているのかもしれないと推測している
    • ただし他のシステムでどう動作するか確信できないため、同じ値には依存していない
  • キー入力はキーボードデバイスを開く簡単な keylogger で処理する
    • この方式のおかげで、htop が開いていなくてもゲームはバックグラウンドで実行され続ける

プラットフォームとトラブルシューティング

  • テストは Ubuntu 22.04 でのみ行われた
  • WSL と Arch ではキーボードデバイス名が異なり、移植が必要
  • キーボードが動作しない場合は main.c#define KEYBOARD_DEVICE の値を確認する必要がある
    • /dev/input/by-pathkbd を含む項目を探して選択する方法が案内されている
  • フレームが停止している場合は、sed コマンドが適用されていない可能性がある
    • htop で F2 → “Display options” → “Update process names on every refresh” をチェックして手動で設定できる
  • ~/.config/htop/htoprc がないというエラーは、htop を一度も実行していないときに発生することがある
    • htop を起動して終了した後、sed コマンドを再実行すればよい
  • メインの Doom プロセスがクラッシュしてゾンビプロセスが大量に残った場合は、次のコマンドで整理する
sudo pkill doom-htop

残作業とライセンス

  • htop は方向キーで移動するときに画面を動かすため、ゲーム操作中に不便な場合がある
    • ゲーム開始後に a を押してプロセッサ選択メニューへフォーカスを移す、単純な回避策が提案されている
  • 制作理由は funny だった
  • Freedoom はメインディレクトリの freedoom-license.txt にある BSD 類似ライセンスで配布されている
  • 残りのコードは GPL のようだと案内されている

1件のコメント

 
GN⁺ 2024-04-22
Hacker News のコメント
  • 考えてみると、「動画」を ASCII でレンダリングしてからプロセス名に入れるのは、かなり簡単そうにも見える
    DNS 上で動くお遊びプロジェクトに似ているし、README でも作業の大半は別のプロジェクトがやったと書いてあるので、特別には見えないかもしれない
    一方で、htop を何かのレンダリングエンジンとして見る発想はまったくなかったと思うので、本当に驚くほど印象的なソフトウェアハックだ

    • ざっくり考えると簡単そうに見えるが、実際には良いコントラストと性能を得るのはそんなに些細なことではない
      libaa や libcaca を見ても、このテーマに何百時間も費やした例がある
    • 概念的には理解しやすいかもしれないが、実装はかなり難しそうだ
  • 逆向きの PSDoom[1] みたいなものなのだろう
    この投稿はプロセスマネージャで Doom をプレイするもので、PSDoom は Doom でプロセス管理をするものだ
    [1]: https://psdoom.sourceforge.net

    • 逆方向も見てみたいと書こうとしたが、すでに存在するのは驚くことではない
      現在の Linux で動くように移植した動画もある: https://youtu.be/Pf7rpde49NU
      ただし top の代替として、もう少し実用的だといい。モンスターの大きさはメモリ使用量、攻撃性は CPU 使用率に基づき、部屋はユーザーごとに分け、スレッドや親子プロセスの関係も見えるようにできる
      スリープ中のプロセスは当然眠らせ、ゾンビプロセスは空間に凍り付かせるか、透明で通り抜け可能にできる。武器は kill シグナルに対応させればよい
      さらに追加できることはたくさんあるが、そうするとだんだん Doom から離れていく
    • rm -rf と一緒に使うと面白そう
  • こういうものを作る時間をどうやって捻出しているのか、本当に気になる
    こういうすごいものを見るほど、自分の能力への自信がどんどん薄れていく
    既存の成果を使って ASCII で再レンダリングし、プロセスにマッピングしたものだという話もあったが、それは決して少ない作業ではない
    どれくらい時間がかかったのか気になるし、この業界にかなり長くいるのに何も分かっていない気がする。素晴らしいが、自分がものすごく馬鹿に思えてくる

    • 温かい言葉をありがとう。そんなに自分を責めなくていい
      あなたは自分で思っているより、ずっと多くのことを知っている可能性が高い
      これは週末まるごとと1日程度、それに時間があるときに数日ほど少しずつ作業して作った
      コメントのどこかや README にも書いたように、Doom をより移植しやすくする難しい作業は、fork 元の doom-generic プロジェクトがやってくれている: https://github.com/ozkl/doomgeneric
    • 1日8時間働いて通勤が1時間なら、15時間残る
      食べて寝てシャワーを浴びてあれこれしなければならないが、そういうことを気にしなければ15時間がそのまま残る
      3年あれば十分に作る時間がある
      さて、6502 向けのレイキャスターを仕上げなければ
    • すごく身に覚えがある感覚だ
      友人たちの Instagram に上がる完璧な家の写真を見て自尊心を削られることの、プログラマー版みたいなものだ
      ほとんどの人はたまにはそう感じるだろうし、対処法もあるが、賢い人たちの周りにいると生じるごく普通の副作用だ
    • こういうものを見るたび、子どもがいなかった頃を思い出す
  • 「何かに Doom を入れる」流れはほぼ完成段階に達した感じがあり、これからは日常的なものを Doom の中に入れる時期に来ている
    Doom の中の Todo リストやカレンダーを想像すればいい

    • 厳密に言うと、それは Doom の中の Todo リストやカレンダーではなく、Todo リストやカレンダーの中で動く Doom だ
      Todo アプリ側には、すでにチェックボックスでレンダリングした Doom があるので[1]、それを Todo アプリに統合するのは読者への演習として残しておけばいい
      [1]: https://healeycodes.github.io/doom-checkboxes/
    • 「何かに Doom を入れる」流れが終わりつつあると感じるなら、まだこの世界に来たばかりなのだと思う
    • 「鳥が DOOM をプレイする」を見たときも、まったく同じことを考えた
  • このプロジェクトを1週間ほど前に偶然見つけてここに投稿したが、反応はなかった
    今になってフロントページに載っているのを見るとうれしいし、こういう楽しさ重視のハッキーなプロジェクトが上がってくるのはいい

  • 見事なハックだ
    ハッカー精神がまだ生きているのを見ると気分が良くなる

  • 時々、人は技術を行き過ぎたところまで持っていくが、今回はそうではない

  • Windows タスクマネージャーで動かした Bad Apple を思い出した
    https://youtu.be/sBeI30ccb6g

  • 純粋で素晴らしい狂気だ。A+

  • 今後このゲームがまたどこで動くのか、想像もつかない