DQ7 TASでBizhawkのRAMの内容をAviutlで表示する方法


Category
Tags

こんにちは。今回は私が取り組んでいる、「DQ7 TAS」の動画で、どのようにメモリの内容を動画に反映させているかをここで紹介したいと思います。

まずはどのように動画上で表示されているのか、こちらの動画を御覧ください(ダイマ)。

この動画の右下のように、

  • フレーム数
  • 時間
  • 乱数
  • 戦闘キャラクターの位置

を動画に表示する方法を説明します。

環境

まずはDQ7 TASはどのような環境で制作が行われているか説明します。 以下の環境で制作が行われています。

  • Windows10(2004)
  • Bizhawk 2.5.2
  • Aviutl 1.10

TAS制作においてWindows以外のOSは人権が無いので、Windows環境を用意して下さい。 また、Bizhawkはバージョン2系あたりからパフォーマンスが劇的に向上して安定性も増しているので、特に理由がなければ最新版を使用することをお勧めします。 Aviutlはスクリプトを受け付けてくれる数少ないフリーの動画編集ソフトなので使用していますが、他にスクリプトを使用できる動画編集ソフトがあれば代替できます。(というかあったらぜひ教えていただきたいです。)

全体の流れ

では実際にどのようにして表示しているかを説明します。流れとしては、

  1. Bizhawkでのゲーム画面収録と同時に、RAM内容をテキストに書き出す(今回はCSV)Luaスクリプトを動作させる。
  2. AviutlでLuaスクリプトを使って上記のテキストファイルを読み込み、動画に反映する。

以上の内容となっています。順を追って説明します。

RAM内容を書き出す

Bizhawkでは下のように、 bizhawk TooldからLuaコンソールを呼び出すことができ、ここからLuaスクリプトを起動することができます。 ここで実際に実行しているコードは以下になります。

record.lua
require "utils"

START_FRAME = 0
STOP_FRAME = 91440

local function start(frame)
    if frame == START_FRAME then
        return false
    end
    return true
end

local function stop(frame)
    if frame == STOP_FRAME then
        return false
    end
    return true
end

local function mainloop()
    console.log("start frame: " .. START_FRAME)
    console.log("stop frame: " .. STOP_FRAME)
    local frame = emu.framecount()

    while start(frame) do
        emu.frameadvance()
    end

    local file = io.open("movie.csv", "w")
    console.log("file open")
    while stop(frame) do
        frame = emu.framecount()
        local time = getTime()
        local r_number = getRNum()
        local pos_x = getPosX()
        local pos_z = getPosZ()
        file:write(frame .. "," .. time .. "," .. r_number .. "," .. pos_x .. "," .. pos_z .. "\n")
        emu.frameadvance()
    end
    file:close()
    console.log("file close")
end

mainloop()

コード中に出てくる、getTime,getPosX等はそれぞれのゲームに合わせたメモリ値を返す関数です。自分が使用するゲームに合わせて変更して下さい。また、このスクリプトでは、最初にあるSTART_FRAME,STOP_FRAMEの値を変更することで、記録するフレームの範囲を指定することができます。 Bizhawkでは様々なLuaの組み込み関数が使用できるので、以下のサイトも参考にしてみて下さい。

http://tasvideos.org/Bizhawk/LuaFunctions.html

Aviutlでテキストを読み込ませる

BizhawkでRAMの内容をCSVに書き出せたところで、これをAviutlで読み込んで表示する方法を説明します。 Aviutlは拡張編集のプラグインを導入するところまで進めて下さい。 aviutl そして拡張編集でメディアオブジェクトの追加からテキストを生成します。 Aviutlのテキストでは、<? ?>で囲んだ部分はスクリプトとみなされるため、この中にスクリプトを書きます。 2021 01 25 14 26 26 実際に使っているスクリプトは以下になります。

aviutl.lua
CSV_PATH = ".\\script\\movie.csv"

local function split(str, d)
    local s = str
    local t = {}
    local p = "%s*(.-)%s*" .. d .. "%s*"
    local f = function(v)
        table.insert(t, v)
    end

    if s ~= nil then
        string.gsub(s, p, f)
        f(string.gsub(s, p, ""))
    end
    return t
end

function main()
    local csv_row = {}
    local row_num = 0

    for line in io.lines(CSV_PATH) do
        csv_row[row_num] = line
        row_num = row_num + 1
    end

    local row = split(csv_row[obj.frame], ",")
    local frame = string.format("%7d", row[1])
    local time = row[2]
    local r_num = string.format("%8s", row[3])
    local pos_x = string.format("%5d", tonumber(row[4]))
    local pos_z = string.format("%5d", tonumber(row[5]))

    local text = "Frame: " .. frame .. "\nTime: " .. time .. "\nR_NUM: " .. r_num
    local position = "\nX: " .. pos_x .. "  Z: " .. pos_z
    obj.mes(text .. position)
end

main()

先程Bizhawkから生成したCSVをAviutlのscriptフォルダの中に配置するか、スクリプトの1行目のCSV_PATHを変更するかして、CSVを読み込めるようにします。すると、 aviutl2 このようにCSVの内容を表示することができます。 あとは収録したゲーム動画を一緒に配置するだけです。

BizhawkのAV/WAV

基本的にBizhawkでゲーム画面を収録するときには、Bizhawkに実装されているAV/WAVを使用します。 2021 01 25 14 38 43 最近のBizhawkでは収録にffmpegが使用できるので、私は容量も考えてffmpegを使ってmp4で収録しています。 収録の際は右上のAlternate Syncを切る必要があります。 2021 01 25 14 52 52

Bizhawkで収録したPS1の動画は昔はフレームレートが59.29だったので非常に扱いにくかったのですが、バージョン2.5.0から修正され、現在は一般的な59.94で収録できるようになっています。 なぜフレームレートの話をしているかというと、先程のRAMの画面表示をYoutubeでの再生と合わせるためにはフレームレートを合わせることが重要だからです。Youtubeやニコニコに動画を上げることを考えると、ある程度一般的なフレームレートで動画を作成しないと、画面出力とのズレが大きくなってしまいます。 というわけで

  • Bizhawkで一般的なフレームレートで収録する
  • Aviutlで一般的なフレームレートで動画を作成する
  • 動画をYoutubeやニコニコに上げる

ということが必要です。これが満たされると、Youtubeでの再生時間と、画面表示の時間がだいたい合うようになります。 実際は、Youtubeで59.94fpsの動画を上げると60fpsとみなされ、少しずれてしまうのですが、59.29fpsのときはかなりずれていたので改善されてよかったと思います。

また、私が普段使っているLuaスクリプトはGithubで公開しています。 よかったらご覧になって下さい。

GitHub - jackjasonb/DQ7_TAS_Lua: My Lua Script for DQ7 TAS

jackjasonb.com

GitHub - jackjasonb/DQ7_TAS_Lua: My Lua Script for DQ7 TAS

参考

http://gocha.hatenablog.com/entry/20090923/RAMWatchOnVideoLua

以上です。お読みいただきありがとうございます。またよろしくお願いします。



2021.01.25 14:00  2021.01.25 14:00