TASEmulators / BizHawk

BizHawk is a multi-system emulator written in C#. BizHawk provides nice features for casual gamers such as full screen, and joypad support in addition to full rerecording and debugging tools for all system cores.
http://tasvideos.org/BizHawk.html
Other
2.18k stars 382 forks source link

emu.setislagged() doesn't work #3447

Open ThunderAxe31 opened 1 year ago

ThunderAxe31 commented 1 year ago

It only sets lag when the movie is playing in recording mode, which completely defeats its purpose. I put inputs in the TAStudio window, so I HAVE to keep recording mode disabled.

YoshiRulz commented 1 year ago

workaround: tastudio.setlag, or you could even customise the colours:

tastudio.onqueryitembg(function(frame_index, column)
    return mark_lag(frame_index) and "red" or "green";
end);

Not sure if emu.setislagged was intended to work with TAStudio. It wasn't. Kinda confusing, I agree.

ThunderAxe31 commented 1 year ago

Oh right, there is a function specifically for TAStudio: tastudio.setlag(int frame, bool? value)

It works now. Though I musta say it's quite counterintuitive to have two separate functions for doing the same thing.

Edit: however, it doesn't work when recording mode IS active. So I basically have to use both functions. It doesn't make sense.

CasualPokePlayer commented 1 year ago

emu.setislagged() doesn't have any special semantics when recording mode is enabled. The issue I think is just when the lag frame info is set by lua vs when tastudio reads it. I guess recording mode makes tastudio read it (probably redundantly?) later? In any case, it does "work" if you are careful in ensuring it's set before tastudio can read it. https://github.com/CasualPokePlayer/PokemonGBTASTool/blob/master/src/Callbacks.cs#L274-L292 (normally I'd recommend oninputpoll but that's not even a guarantee to be implemented and doesn't work in this case sometimes due to IsLagFrame getting set by the core after the callback for some cores, also not applicable in every case)

Not sure really what's the best solution. You can just set the lag info using both functions at once and that should work anyways. Although perhaps there should be some semantics ensuring lua is ran before tastudio can.

ThunderAxe31 commented 1 year ago

emu.setislagged() doesn't have any special semantics when recording mode is enabled.

It seems to me that the problem is that non-recording mode does override any previously set lag frame.

CasualPokePlayer commented 1 year ago

TAStudio doesn't edit the core's internal lag frame flag (why would it?). The issue is more it reads the lag frame flag before you can set it (and recording mode is probably just making it read the flag again at a later point, at which point your lua script would have modified it).

vadosnaprimer commented 1 year ago

Does it help if the flag is set on a callback after which we know input won't be read?

CasualPokePlayer commented 1 year ago

it does "work" if you are careful in ensuring it's set before tastudio can read it. https://github.com/CasualPokePlayer/PokemonGBTASTool/blob/master/src/Callbacks.cs#L274-L292

Yes, this is what this workaround I mentioned does.

vadosnaprimer commented 1 year ago

There's a lot of overhead required to make it work the way it's needed. Part of the problem is hawk's frame counter flashes in red when you set islagged, but that doesn't increment hawk's own lag counter! Which is probably why it doesn't go to tastudio either.

if emu.registerafter ~= nil then
    -- FCEUX
    emu.registerafter(function()
        emu.setlagflag(memory.readbyte(0xCC) ~= 0)
    end)
else
    -- BizHawk
    event.onframeend(function()
        local lag = memory.readbyte(0xCC) ~= 0
        emu.setislagged(lag)
        tastudio.setlag(emu.framecount(), lag)
        lagcount = emu.lagcount()
        if lag then
            lagcount = lagcount+1
            emu.setlagcount(lagcount)
        end
    end)

    event.onloadstate(function()
        lagcount = emu.lagcount()
    end)
end

Ideally, it should be a fceux kind of one liner too.

YoshiRulz commented 1 year ago

Frontend should probably keep track of ApiHawk- and Lua-set lag frames. Overwriting the lag count like that feels wrong. Does emu.setlagcount exist solely to enable that workaround?

vadosnaprimer commented 1 year ago

IIRC overriding the counter existed before the ability to set the flag for the current frame. If the flag is global, the counter should naturally increment without editing it manually.

CasualPokePlayer commented 1 year ago

Looks like TAStudio, when not in recording mode, handles setting lag info in MovieSession.HandleFrameAfter, which is called right after the core's FrameAdvance. UpdateToolsAfter and ResumeScripts comes after this, so they can't set lag info before TAStudio sees it.

When in recording mode, RecordFrame is called within MovieSession.HandleFrameBefore. This sets lag info too. But since this is before emulation, it ends up picking up lua setting lag from UpdateToolsAfter/ResumeScripts.

vadosnaprimer commented 1 year ago

What if we have a special callback for when the emu handles lag info, and do the memory checks there, without having to override the values post-factum?