午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

Luaのメモ、Snes9x rerecording 1.51 v7のLuaでRewind再現

2015年5月1日追記
frameadvanceが動かなくてもregisterbeforeでよかった ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
↑の記事でここの記事は殆ど無意味になりました
追記ここまで
 
 
久しぶりにLuaを使おうと思ったらほとんど忘れていたのでメモ
Luaといってもゲームのエミュレータ用のLua

スーパーファミコンエミュレータのSnes9x rerecording 1.51 v7で動作確認

 
書いたのはRewind(巻き戻し、早戻し)の再現
新しい方の1.53なら最初からRewindがあるからこっちを使いたいんだけど
1.53のLuaだとframeadvanceが動いてくれないので
Rewindの機能がないけどframeadvanceが動く1.51のLuaを使って再現してみた(力技)
 
動作はステートセーブを一定間隔で通し番号を付けてどんどん溜めていくので
キーボードのRで前のロード、Tキーで次のロード
 
できは良くなくてセーブするたびに一瞬止まるからアクションゲームには向かない
1.53でframeadvanceが動けばこんなことしなくてもいいのに!
 
--[[フレームカウント一定間隔ごとにステートセーブ
Rキーで前のロード、Tキーで次のロード
EVERY_COUNT =  このフレームごとにステートセーブを記録する、60で約1秒
COUNT_DOWN =   待ち時間、60で約1秒、ステートロードを連続でする間隔、
               短いとキーをちょっと押しただけで2,3個戻ってしまうのを防ぐため
MAX_STATE_COUNT = ステートセーブの最大個数、これを超えると古いものから消えていく]]

local saveTable = {} --luaには配列はない替わりにテーブルを使う、添字は1から始まる
local saveObj-- = savestate.create()--セーブオブジェクト
local savecount = 0      --セーブオブジェクトの通し番号
local myCount = 0        --フレームのカウント用
local EVERY_COUNT = 600  --このフレームごとにステートセーブを記録する、60で約1秒
local mykey               --入力されたーキーボードのキー
local COUNT_DOWN = 20    --[[待ち時間、60で約1秒、ステートロードを連続でする間隔
                       、短いとキーをちょっと押しただけで2,3個戻ってしまうのを防ぐため]]
local mycountdown = 0    --待ち時間カウントダウン用
local MAX_STATE_COUNT = 5--ステートセーブの最大個数、これを超えると古いものから消えていく
myCount = EVERY_COUNT

function myframecount()
    if myCount == EVERY_COUNT then
        saveObj = savestate.create()--ここで毎回クリエイトしないと同じセーブファイルになる
        savestate.save(saveObj)     --オブジェクトにセーブ
        if savecount == MAX_STATE_COUNT then--セーブ個数が最大値を超えていたら
            table.remove(saveTable,1)       --一番目(古いもの)をテーブルから削除
        else                              --セーブ個数が最大値を超えていなければ通し番号を+1
            savecount = savecount +1
        end
        saveTable[savecount] = saveObj--ステートセーブをテーブルに追加
        print(emu.framecount().."_saveNumber "..savecount.." AddSave")
        myCount = 0--カウントを元に戻す
--     table.sort(saveTable)--エラーになる、ステートセーブには使えない?
    end
    myCount = myCount +1--カウントアップ
end

function myload()--現在より古いステートセーブをロード
    if savecount > 1 then
        savestate.load(saveTable[savecount-1])
        savecount = savecount -1
        print(savecount.."_Loaded")
        myCount = 0
    end
end
function mynextload()--次のステートロード
    if savecount < table.maxn(saveTable) then
        savestate.load(saveTable[savecount +1])
        savecount = savecount + 1
        print(savecount.."_Loaded")
        myCount = 0
    end
end

while true do
    myframecount()
    
    if mycountdown > 0 then
        mycountdown = mycountdown -1--カウントダウン
    else
        mykey = input.get()
        if mykey.R then --Rキーを押したら
            myload()    --古い方のステートをロード
            mycountdown = COUNT_DOWN
        elseif mykey.T then --Tキーを押したら
            mynextload()    --現在より新しいステートをロード
            mycountdown = COUNT_DOWN
        end
    end
    emu.frameadvance()
end
 
 

f:id:gogowaten:20191018121240p:plain

 
使う時は
イメージ 2
ゲームを起動してからLuaのウィンドウを出して
 
イメージ 3
Luaのウィンドウを出して、ファイルをBrowseで選んでRunで実行
イメージ 4
実行中の画面
 
1行目の
148_saveNumber 1 AddSaveは
148フレームの時に1番にセーブしましたって意味
一定時間ごとにセーブしていく、この一定時間の変更は12行目の数字
local EVERY_COUNT = 600
600だと約10秒毎にセーブになる
 
2547_saveNumber 5 AddSave
3147_saveNumber 5 AddSave
3747_saveNumber 5 AddSave
5番目にどんどんセーブしているのはセーブの個数を5個に制限しているからで
上限を超えたら1番を消している、この時セーブの2番だったものが1番に入って
同じように5番だったものが4番に入って、結果的に5番が空くので新しいセーブは
5番にどんどん入っている
セーブの個数の上限は
local MAX_STATE_COUNT = 5
これの5を変えればいい
 
4_Loaded
3_Loaded
2_Loaded
3_Loaded
4_Loaded
5_Loaded
4_Loaded
3_Loaded
このへんは何番をロードしましたよって意味
巻き戻しならキーボードのR、先送りならTにしている
 
4番まで記録して3番に巻き戻して次にセーブされる場所は5番ではなくて
4番に上書きされる
3_Loaded
3148_saveNumber 4 AddSave
3748_saveNumber 5 AddSave
 
 
Luaテーブルの要素を消去した時の動作で
table.remove(saveTable,1)
saveTableの1番を消去すると自動で2番だったものが1番に入って3番だったものが2番に入るっていうのは面白い
最初は1番を消去したら1番は空白になるだけなのかと思っていた
 
table.maxn(saveTable)
table.maxnを使うとテーブルの要素数を取得できる
 
Luaは大文字と小文字を区別している
 
Luaのコードを書くときに使っているテキストエディタ
イメージ 5
Ctrl+Spaceで入力候補が出てくる!
文字の色分けしてくれるから見やすい
素晴らしいアプリ
MeryWiki
 
 
参照したところ
八角研究所 : 高速スクリプト言語Lua」を始めよう!(2) - 高速スクリプト言語Lua」を始めよう!(2)
 
ここでテーブルの要素を削除するとずれるのを知った
 
Rewinder.lua in digs/Zelda/fceux/luaScripts – Computer Archeology
 
 
ダウンロード
ファイル名:snes9x1.51_rr_v7用、巻き戻しテスト1.lua