Dolphin-Lua-Core icon indicating copy to clipboard operation
Dolphin-Lua-Core copied to clipboard

[Feature Request] -Frame Control

Open Crain-32 opened this issue 4 years ago • 1 comments

A callable function to advance a frame would be nice. This would allow for easier comparison if you stalled the update() function until after the frame advance is complete.

This would be best integrated with two functions

AdvanceFrame( Integer Amount ) -Advances the game a set number of frame, pausing on the game after X frames, if Amount is blank, advances 1 frame. All scripts are stalled until the frame advance is finished. Calls OnFrameAdvance() after Amount frames pass.

OnFrameAdvance() -Default Action would be to call the Script's OnUpdate.

This would allow for more scripts to do post action comparision, and restrict the testable frames.

Functions that could work well with this would be.

PauseGame() -Pauses the Emulator. Could be called by AdvanceFrame() when it calls OnFrameAdvance()

UnpauseGame() -Unpauses the Emulator

Just for ability for scripts to pause the emulator, start a testing script, get the results, and then unpause the emulator. But the first two function could be written to do this.

Crain-32 avatar Jan 23 '21 01:01 Crain-32

If your goal is to "execute this code, after X number of frames" you could set up something like this within your lua script:

local delayedFunctions = {}
local lastFrame = -1

local function ExecuteDelayedFunctions()
    local newDelayedFunctions = {} -- used to remove functions that get called
    for i = 1, #delayedFunctions do
        if GetFrameCount() == delayedFunctions[i][2] then
            delayedFunctions[i][1]()
        else
            table.insert(newDelayedFunctions, {delayedFunctions[i][1], delayedFunctions[i][2] - 1})
        end
    end
    delayedFunctions = newDelayedFunctions
end

local function ActionStarts()
    return (ReadValue8(0x661210) + 128) % 256 == 42 -- check whatever condition you want here
end

local function ActionAnalysis()
    SetScreenText("...")
end

local function OtherActionStarts()
    return (ReadValue8(0x661210) + 128) % 256 == 127
end

local function OtherActionAnalysis()
    SetScreenText("... (2)")
end

function onScriptUpdate()
    if GetFrameCount() ~= lastFrame then -- run once per frame
        lastFrame = GetFrameCount()
        SetScreenText("")
        ExecuteDelayedFunctions()
        if ActionStarts() then
            -- call ActionAnalysis() after 5 frames (barring off-by-one errors)
            table.insert(delayedFunctions, {ActionAnalysis, GetFrameCount() + 5}) 
        end
        if OtherActionStarts() then
            table.insert(delayedFunctions, {OtherActionAnalysis, GetFrameCount() + 7}) -- run this after 7 frames
        end
    end
end

If you want to stop all code execution in onScriptUpdate() until that certain number of frames has passed, I think it's possible to work that into the logic (doesn't necessarily need to be a built in dolphin-lua function imo).

I do think a pause function would be useful (this isnt something a lua script can do alone)

MikeXander avatar May 05 '21 18:05 MikeXander