XEBRA(プレイステーションエミュレータ)の使い方+αメモ(なんちゃって TAS 機能とか)

知っている人には今さらだと思いますが、XEBRA / ARBEX というエミュレータが互換性・速度の面で非常に良かったです。本体にマニュアルが付属しているので、その通りに使えば良いのですが、若干落とし穴や目立たない機能もあるのでメモしておきます。

だんだん「外部ツールを使って高度な機能を追加するには?」みたいになってきました。

雑多な情報

  • Help... ダイアログの表示をスクロールするとじつは日本語の説明もある
  • OS ROM(よく BIOS と呼ばれるもの)は OSROM というファイルで配置する*1
  • CD イメージファイルはイメージ本体を選択する(ccd や cue は同階層に配置するが、オープンダイアログでは iso, img などを選択する)
  • CD イメージの読み込み後は、Power(Run) を選択しないと起動しない
  • Controller... ダイアログでキー設定が可能。ただし、最初に「Controller 1」などの設定対象を選択しなければならないことに注意
  • Simulation Model Image はハードウェア動作のシミュレーション設定を記録したファイル(SIM.EXE で作成・編集、XEBRA 本体で読込)
  • Running Image がどこでもセーブ(savestate)に相当する
  • File/History にある Pad History (パッド履歴) はキームービーに近いもの(後述)
  • Sound Output... で Save にチェックを入れると SOUND.WAV にプレイ音声が出力される
  • .kkapture (1.01) で AVI 形式の動画を出力可能
  • PK201.DLL を置いてあれこれするとポケステもいけるらしいです(見てない)
  • Debug 周りは不明(気になる)
  • 本体は gccコンパイル、UPX で圧縮されていて、画面描画は OpenGL を使用

パッド履歴について(ムービー機能として使う)

File/History にある Pad History (パッド履歴) は強いて言えばキームービーに近いものです。ただし、あくまでムービー機能ではないので、パッドの入出力だけを扱い、ステートなどは一切記録しません。

最初に、インタフェースが独特であることを説明すべきでしょう。

  • Read Pad... - 既存のパッド履歴を読込、再生開始(ユーザー入力無効化、いわゆる「再生終了後」もそのまま)
  • Write Pad... - パッド履歴を新規作成、記録開始
  • Load Pad... - 記録中のパッド履歴の内容を、別のパッド履歴で丸ごと上書き(使い方は後述)
  • Save Pad... - 記録中のパッド履歴の複製を別名保存

「停止・クローズ」という選択肢はないので、別のファイルを新規作成するなりして行うしかなさそうです。

これを実行イメージ(Running Image)と組み合わせることで、一般的なムービー機能として動作します(どの程度 desync せずに動作するかは不明ですが)。

注:必要に応じて事前にメモリーカードを初期化・変更すべきかもしれません。(実行イメージに含まれるかもしれませんが未確認です)

注:より正確に記録するには Simulation Image の入出力が必要だと考えます。しかし、すべて下記の手順では省略しています。

電源投入時からのムービーを記録
  1. ムービーを記録
    1. CD イメージを読み込む
    2. File/History/Write Pad... でパッド履歴を新規作成(例:from_power_on.pad)
    3. Power(Run) でゲームを開始、普通にプレイ
    4. 記録を止めたくなったら Write Pad... で別のファイルに切り替える(例:dummy_for_close.pad)か、単に XEBRA を閉じる
  2. ムービーを再生
    1. CD イメージを読み込む
    2. File/History/Read Pad... でパッド履歴を読込
    3. Power(Run) でゲームを開始、鑑賞
特定のステートからムービーを記録
  1. ムービーを記録
    1. 記録を開始したい箇所で Pause する
    2. File/Save/Running Image... で実行イメージを保存(例:from_snapshot.sav)
    3. File/History/Write Pad... でパッド履歴を新規作成(例:from_snapshot.pad)
    4. Power(Run) でゲームを開始、普通にプレイ
    5. 記録を止めたくなったら Write Pad... で別のファイルに切り替える(例:dummy_for_close.pad)か、単に XEBRA を閉じる
  2. ムービーを再生
    1. CD イメージを読み込んだ状態で Pause する
    2. File/Open/Running Image... で実行イメージを読込
    3. File/History/Read Pad... でパッド履歴を読込
    4. Power(Run) でゲームを開始、鑑賞
ムービースナップショットの記録と追記

いわゆる追記(rerecording)もじつはできます。

  1. ムービースナップショットの作成
    1. パッド履歴(例:main.pad)記録中に、スナップショットを作成したい時点で Pause する
    2. File/Save/Running Image... で実行イメージを保存(例:snapshot.sav)
    3. File/History/Save Pad... でパッド履歴を複製保存(例:snapshot.pad)
  2. ムービースナップショットの読込
    1. CD イメージを読み込む
    2. File/History/Write Pad... で記録対象のパッド履歴(例:main.pad)を選択する(この時点で内容が失われるので、不安ならバックアップしておくこと!)
    3. File/Open/Running Image... で実行イメージ(例:snapshot.sav)を読込
    4. File/History/Load Pad... でパッド履歴(例:snapshot.pad)を読込
    5. Power(Run) でゲームを開始、記録続行
プレイ速度も変えたい!

本体の機能である程度のスローダウンが可能でした(後述)

すろぉもぉしょん というアプリを使うとこの上なく簡潔にスローダウンできます(XEBRA 本体とホットキーが重複していますが)。

もっと柔軟に!という方には MHS (Memory Hacking Software)Cheat Engine という2つのツールを紹介します。どちらもプロセスメモリエディタですが、Hotkey に Speed Hack (スロー・倍速)や Process Pause を割り当てて使うことができます。私はメモリエディタとしては MHS を好んでいますが、Speed Hack 用途では Cheat Engine の方が使いやすいように感じました。試してみて好きな方を使ってください。速度変更を行ってもフレームスキップ(?)が動作して操作単位が大まかになってしまうらしいので、"それなり"の効果しか期待できないかもしれません。

フレーム単位で操作するというのは現状では無理そうです。フレームカウンタに相当するものをメモリから探して、監視しながら動かすと、どの程度スローダウンに成功しているか確認できます。

見落としていましたが本体の機能で一定のスローダウンが可能です。起動後、Run/Sync を選択し(デフォルトで on なのが off になる)、その後 Run/Misc/Slow を選択することで速度を落とせます。4段階変速で、選択するたび 0→1→2→3→0... と変化します。より遅くしたければ複数回 Slow を選択してください。

チート(改造コード)

XEBRA の作者は cep というプロセスメモリエディタも公開しています。PAR コードが使えるのできっとおすすめです。プロセスメモリエディタなので XEBRA 向けの設定行を BASEARCH.TXT に書かなければなりませんが、ググれば出てくると思います(希望的観測)。

メインメモリ上の変数を入出力したいだけなら、どのプロセスメモリエディタでも簡単だと思います(本体からメモリ内容をダンプできるのでサーチが楽)。私は MHS を使用しました*2

ショートカット

Help ダイアログから抜粋。今後変更される可能性も考えられます。

  • F1 .... = メニュー : File/Save/Running Image/XEBRA.RUN
  • F2 .... = メニュー : File/Save/Running Image/????????.000
  • F3 .... = メニュー : File/Save/Running Image/????????.001
  • F4 .... = メニュー : File/Run/Sync
  • F5 .... = メニュー : File/Run/Power(Run)
  • F6 .... = メニュー : File/Run/Pause
  • F7 .... = メニュー : File/Open/Running Image/XEBRA.RUN
  • F8 .... = メニュー : File/Open/Running Image/????????.000
  • F9 .... = メニュー : File/Open/Running Image/????????.001
  • F12 ... = メニュー : View/Full Screen/

コマンドライン

これも抜粋。不必要だと思う人もいるかもしれませんが、.kkapture を使いたいときなどは楽になりそうです。

  • -SPTI "PATH" .... = メニュー : File/Open/CD-ROM via SPTI/"PATH"
  • -IMAGE "PATH" ... = メニュー : File/Open/CD-ROM Image/"PATH"
  • -OSROM "PATH" ... = メニュー : File/Open/OS ROM Image/"PATH"
  • -BU00 "PATH" .... = メニュー : File/Open/Memory Card 1 Image/"PATH"
  • -BU10 "PATH" .... = メニュー : File/Open/Memory Card 2 Image/"PATH"
  • -SIM "PATH" ..... = メニュー : File/Open/Simulation Image/"PATH"
  • -RUN "PATH" ..... = メニュー : File/Open/Running Image/"PATH"
  • -TOC "PATH" ..... = メニュー : View/CD-ROM Drive/Open TOC/"PATH"
  • -CUE "PATH" ..... = メニュー : View/CD-ROM Drive/Open TOC/"PATH" .. CUE
  • -CCD "PATH" ..... = メニュー : View/CD-ROM Drive/Open TOC/"PATH" .. CCD
  • -INI "PATH" ..... 初期設定イメージのロード
  • -RUN1 ..... = メニュー : Run/Power(Run)
  • -RUN2 ..... = メニュー : Run/Debug Run/No I Cache
  • -RUN3 ..... = メニュー : Run/Debug Run/I Cache
  • -RUN4 ..... = メニュー : Run/Debug Run/I Cache Compile
  • -SYNC ..... = メニュー : Run/Sync
  • -BLANK .... = メニュー : Run/Misc/Blank
  • -FULL ..... = メニュー : View/Full Screen/

アイコンにドロップ = XEBRA.EXE "PATH" = XEBRA.EXE -IMAGE "PATH" -RUN1

AutoHotKey によるホットキー追加

AutoHotkey を流行らせるページを見ると、AutoHotkey というアプリケーションで、スクリプトを使った高度なホットキー割り当てが記述できそうです。AutoHotkeyJp に日本語のリファレンスも充実しています。

下記、試しに擬似 Movie Snapshot の保存を行うホットキーを追加してみました。AutoHotkey.ahk の末尾に下記の記述を追加して保存し、XEBRA を起動後に AutoHotkey を起動すると、追加のホットキーが使えるようになっているはずです。

あくまで擬似的なものなので、動作に失敗することもありますが、何もないよりマシです。

また、XEBRA の挙動が変わればスクリプトも修正が必要になると思います。

  • 【重要】前提条件:予め CD イメージを読込済で、かつ Write Pad... で適当なパッド履歴を出力対象に指定済であること。
  • 作業ファイルはデスクトップに保存されますが、嫌ならスクリプト中の A_Desktop を変更すれば良いです。
  • Xebra_AutoUnpause を 0 にすると読み書き後の Pause 解除を行いません(F5 で手動解除することになります)……という感じだったのですが一長一短あるので、Backspace を独自の Pause に割り当てて、このキーが使用された際にスナップショット入出力後の Pause 解除の有無をトグル切り替えするようにしました。
  • ダイアログへのキー送信がうまくいかなかった場合、Pause 状態のはずなので落ち着いてダイアログを閉じて、もう一度保存しなおせば多分大丈夫です。多分……。
; XEBRA (PlayStation emulator)
#IfWinActive XEBRA
Xebra_AutoUnpause := 1

XebraLoadMovieSnapshot(TargetPath, AutoUnpause)
{
	; Pause
	;SendInput,!rp{Enter}
	SendInput,{F6}
	; File/Open/Running Image...
	SendInput,!for
	Sleep 400
	SendInput,%TargetPath%.RUN{Enter}
	Sleep 100
	; File/History/Load Pad...
	SendInput,!fhl
	Sleep 400
	SendInput,%TargetPath%.PAD{Enter}
	Sleep 100
	; Power(Run)
	if (AutoUnpause)
	{
		;SendInput,!r{Enter}
		SendInput,{F5}
	}
}

XebraSaveMovieSnapshot(TargetPath, AutoUnpause)
{
	; Pause
	SendInput,!rp{Enter}
	SendInput,{F6}
	; File/Save/Running Image...
	SendInput,!fsr
	Sleep 500
	SendInput,%TargetPath%.RUN{Enter}
	; File/History/Save Pad...
	SendInput,!fhs
	Sleep 400
	SendInput,%TargetPath%.PAD{Enter}
	Sleep 100
	; Power(Run)
	if (AutoUnpause)
	{
		;SendInput,!r{Enter}
		SendInput,{F5}
	}
}

; 1
1::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_001", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+1
+1::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_001", Xebra_AutoUnpause)
	BlockInput Off
	return
; 2
2::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_002", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+2
+2::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_002", Xebra_AutoUnpause)
	BlockInput Off
	return
; 3
3::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_003", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+3
+3::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_003", Xebra_AutoUnpause)
	BlockInput Off
	return
; 4
4::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_004", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+4
+4::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_004", Xebra_AutoUnpause)
	BlockInput Off
	return
; 5
5::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_005", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+5
+5::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_005", Xebra_AutoUnpause)
	BlockInput Off
	return
; 6
6::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_006", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+6
+6::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_006", Xebra_AutoUnpause)
	BlockInput Off
	return
; 7
7::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_007", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+7
+7::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_007", Xebra_AutoUnpause)
	BlockInput Off
	return
; 8
8::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_008", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+8
+8::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_008", Xebra_AutoUnpause)
	BlockInput Off
	return
; 9
9::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_009", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+9
+9::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_009", Xebra_AutoUnpause)
	BlockInput Off
	return
; 0
0::
	BlockInput On
	XebraLoadMovieSnapshot(A_Desktop . "\XEBRA_000", Xebra_AutoUnpause)
	BlockInput Off
	return
; Shift+0
+0::
	BlockInput On
	XebraSaveMovieSnapshot(A_Desktop . "\XEBRA_000", Xebra_AutoUnpause)
	BlockInput Off
	return
; Backspace
BS::
	Xebra_AutoUnpause ^= 1
	if (Xebra_AutoUnpause)
	{
		; Power(Run)
		;SendInput,!r{Enter}
		SendInput,{F5}
	}
	else
	{
		; Pause
		;SendInput,!rp{Enter}
		SendInput,{F6}
	}
	return
#IfWinActive

TAS 的な機能について

小手先ではどうしても実用的に厳しいものがあります(操作性の面で)。当たり前ですが。

ただ、上述の通り rerecording できる仕組み自体は整っているようなので、技術を持った人であれば、本体を UPX で展開して、適当に解析して、適当にコード改変すれば、その手の方法にしては比較的簡単にまともな TAS 機能が付けられるのではないかと私は思います。*3

興味のある人はチャレンジしてみてはどうでしょうか?

それと、もう一つ違う方法を提案することができます。パッド履歴の中身はおそらく単純なキーコードで構成されているので、調べれば簡単に編集できると思います。根気のある人はバイナリエディタと再生確認の繰り返しだけで動画を作ることができるかもしれません。

*1:ただし、ARBEX は OS ROM を使わないので、OSROM を配置する必要はない。

*2:執筆時点では [0x454D78] + オフセット でメインメモリの内容をウォッチできましたが、バージョンアップされたら変わると思うので再度サーチが必要です

*3:パッド履歴の記録はフレームスキップとは無関係に行われますので、(後々出力先を応用することを考えても)パッド履歴出力周りを起点に解析するとやりやすいかもしれません。