Post subject: Skipping every other frame in 30fps games
Skilled player (1247)
Joined: 8/29/2014
Posts: 302
Is there any way to do this if BizHawk is not recognizing every other frame as non-input frames?
Post subject: Re: Skipping every other frame in 30fps games
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
BizHawk is shit at handling lag and 30fps games.
Spikestuff
They/Them
Editor, Publisher, Expert player (2643)
Joined: 10/12/2011
Posts: 6441
Location: The land down under.
How to play 30fps games, 2 frames an input. I honestly don't know how to do it in Hawk, FCEUX (for example) has a special thing which allows you to do 2 frames in input. Then again, I haven't payed attention to latest Hawk as much.
WebNations/Sabih wrote:
+fsvgm777 never censoring anything.
Disables Comments and Ratings for the YouTube account. Something better for yourself and also others.
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Fceux has an option to manually set lag flag when you feel like it (judging by whatever address the game uses as a lag flag). In bizhawk you only can get lag flag, and get/set lag count. It's not hard to implement, but adelikat refused the idea for some reason. Maybe because the possibility to skip such frames on demand wasn't considered. However, in TAStudio you can hide every other frame's row, though I don't know if it actually skips the frame.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Editor, Expert player (2098)
Joined: 8/25/2013
Posts: 1200
Config > Customize > Advanced > check 'Frame advance buttons skips non-input frames'. Should solve your problem.
effort on the first draft means less effort on any draft thereafter - some loser
Spikestuff
They/Them
Editor, Publisher, Expert player (2643)
Joined: 10/12/2011
Posts: 6441
Location: The land down under.
Ah, so there was a thing, still wouldn't use it. :3
WebNations/Sabih wrote:
+fsvgm777 never censoring anything.
Disables Comments and Ratings for the YouTube account. Something better for yourself and also others.
Skilled player (1247)
Joined: 8/29/2014
Posts: 302
arandomgameTASer wrote:
Config > Customize > Advanced > check 'Frame advance buttons skips non-input frames'. Should solve your problem.
This only works in games where every other frame is actually recognized as a non-input frame. Unfortunately they aren't in the game I'm TASing at the moment(I only checked 1 N64 and 1 PSX game, so maybe it's system-specific and not game-specific?).
Editor, Expert player (2479)
Joined: 4/8/2005
Posts: 1573
Location: Gone for a year, just for varietyyyyyyyyy!!
This kind of Lua script works flawlessly in Sega 32X Doom:
gens.registerafter( function()
local inputframe = memory.readbyte(0xffff94)
   if inputframe ~= 255 then
   gens.emulateframe()
   end
You could try to find a RAM address that has a specific value on every input frame. In this case the address 0xffff94 has value 255, when input is registered. This script tells the emulator to advance a frame, if the value is not 255.
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
The point is not to advance the frame, as it's done anyway, but to skip the usual delay that's added to simulate the target framerate of the console, as in, one needs to emulate the lag frame on turbo speed. This must be very possible in lua. EDIT: Wait, that's right! You need turbo speed for that frame, but you also need emu.frameadvance() when your address is lagged to actually skip it!
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
ALAKTORN
He/Him
Former player
Joined: 10/19/2009
Posts: 2527
Location: Italy
Aqfaq wrote:
You could try to find a RAM address that has a specific value on every input frame.
That seems like a very hacky solution, though…
Editor, Player (44)
Joined: 7/11/2010
Posts: 1029
If the game's reading input but not using it, you need to have some basis with which to determine whether the game's reading input or not. A RAM address is probably the least hacky way, actually.
MarbleousDave
He/Him
Player (13)
Joined: 9/12/2009
Posts: 1559
I took advantage of this in my TAS of Snoopy's Magic Show on the Game Boy. I'll probably submit it on Enterplayment and maybe upload an encode on Dailymotion. Whatever, 30fps games can be easier to TAS than 60fps games. Zelda: Ocarina of Time runs at 20fps, with menus at 30fps. Emulation of OoT runs at the same speed as the GameCube version. But Majora's Mask on emulators are emulated almost perfectly, with the exception of the GameCube version. I must be going off-topic. Anyway, Pokemon runs at 30fps with inputs at 60fps. Zelda: Four Swords Adventures runs at 60fps, but slows down on PC hardware due to having so many sprites. Speaking of slowdown, Starcraft 64 goes sluggish whenever the AI script 'Issue all units on random suicide missions' is called. The poor N64 can't keep up even with the speed set to max. There are a few missions on Starcraft 64 that benefit with the higher speed.
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
How about this: Download even-frames.lua
Language: lua

function skip() if emu.framecount()%2 > 0 then emu.frameadvance() end end while true do skip() emu.frameadvance() end
Change the condition to "emu.framecount()%2 == 0" if you want only odd frames.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Amaraticando
It/Its
Editor, Player (159)
Joined: 1/10/2012
Posts: 673
Location: Brazil
feos wrote:
Change the condition to "emu.framecount()%2 == 0" if you want only odd frames.
If I understood Hetfield90 correctly, (s)he doens't want to press frame advance twice while TASing, as every other frame is useless. Therefore, running emu.frameadvance() twice in the while loop won't solve the problem. And there're other problems for some games, like: 1) a lag frame occuring as a 3rd frame in this cycle; 2) the game stops this rule while loading a level and the parity changes; The following game specific script might work for all games, if the user is able to find the RAM address that acts as a flag for "input being applied".
Language: lua

-- Game: Crash Team Racing (U) local Input_frame, Frame_advance_mode while true do Frame_advance_mode = client.ispaused() Input_frame = mainmemory.readbyte(0x98800) ~= 0 -- game specific RAM address that determines whether the input'll be used -- Custom frame advance if not Input_frame then client.unpause() emu.frameadvance() if Frame_advance_mode then client.pause() end else emu.frameadvance() end end
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
I sent Hetfield90 the following script which he said worked. This script uses a special key to skip forward two frames. The space key is used as the special key; you can edit it to whatever you normally use as frame advance. For this to work, the actual frame advance key has to be set to something other than space. Note that the special key cannot be held down for key repeat.
Language: lua

local key="Space" local t={} local s=emu.framecount() local monitor=false local buttonheld=false while true do t=input.get() if t[key] and not buttonheld then s=emu.framecount() client.unpause() buttonheld=true monitor=true end if not t[key] and buttonheld then buttonheld=false end if emu.framecount()>=s+2 and monitor then client.pause() monitor=false end emu.yield() end
Note that emu.yield() instead of emu.frameadvance() allows the while loop to run even when emulation is paused. Please also remember that emu.frameadvance() does not advance emulation by one frame; it halts lua script execution until the next frame. This is an easy misunderstanding to make.
adelikat
He/Him
Emulator Coder, Site Developer, Site Owner, Expert player (3573)
Joined: 11/3/2004
Posts: 4754
Location: Tennessee
Eventually Bizhawk will make this easier by supporting an alternate notion of "lag" to mean a frame in which the video was not rendered. This way, the lag skipping feature will give you want you need. This is what we did for the N64 core, and similar to what odl PSCX-rr had. Also, if there was an emu.setislagged(boolean) function, it would make these skips a lot easier for creating your own notion of lag. This is on my todo list as well. I'll try to make sure it is released along with the PSXHawk change.
It's hard to look this good. My TAS projects
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
For the very recent commit, this code finally does it for me (as long as "frame advance skips lag" is checked):
Language: lua

function skip() if emu.framecount()%2>0 then emu.setislagged() end end event.onframeend(skip)
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.