Post subject: Lua help: press circle 1 frame before value changes (?)
Joined: 3/18/2006
Posts: 971
Location: Great Britain
It seems I have found the memory address for when a text-box can be skipped. The value 001FFE4E becomes non-zero when a text-box can be skipped. The only problem is that it is 1 frame late. So I need to create a script that can press Circle 1 frame before 001FFE4E becomes non-zero. Can someone help me to accomplish this lua script? I guess the script could see when the value becomes non-zero, load, and then press circle 1-frame before?
Site Admin, Skilled player (1256)
Joined: 4/17/2010
Posts: 11495
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Yep, it needs to save the state every 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.
Joined: 7/2/2007
Posts: 3960
Something like this, presumably:
save state
advance emulator one frame
if memory at 001FFE4E != 0:
    reload state
    press button
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
Post subject: Re: Lua help: press circle 1 frame before value changes (?)
Patashu
He/Him
Joined: 10/2/2005
Posts: 4045
antd wrote:
I guess the script could see when the value becomes non-zero, load, and then press circle 1-frame before?
Yep :) Congrats, you just discovered rubber duck programming: http://en.wikipedia.org/wiki/Rubber_duck_debugging
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Post subject: Re: Lua help: press circle 1 frame before value changes (?)
Lil_Gecko
He/Him
Player (98)
Joined: 4/7/2011
Posts: 520
antd wrote:
It seems I have found the memory address for when a text-box can be skipped. The value 001FFE4E becomes non-zero when a text-box can be skipped. The only problem is that it is 1 frame late. So I need to create a script that can press Circle 1 frame before 001FFE4E becomes non-zero. Can someone help me to accomplish this lua script? I guess the script could see when the value becomes non-zero, load, and then press circle 1-frame before?
X = savestate.create();

while true do
savestate.save(X);
emu.frameadvance();
if memory.readbyte(0x1FFE4E) ~= 0 then
savestate.load(X);
joypad.set(1,{["circle"]=true});
emu.frameadvance();
end;
end;
Post subject: Re: Lua help: press circle 1 frame before value changes (?)
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Lil_Gecko wrote:
antd wrote:
It seems I have found the memory address for when a text-box can be skipped. The value 001FFE4E becomes non-zero when a text-box can be skipped. The only problem is that it is 1 frame late. So I need to create a script that can press Circle 1 frame before 001FFE4E becomes non-zero. Can someone help me to accomplish this lua script? I guess the script could see when the value becomes non-zero, load, and then press circle 1-frame before?
X = savestate.create();

while true do
savestate.save(X);
emu.frameadvance();
if memory.readbyte(0x1FFE4E) ~= 0 then
savestate.load(X);
joypad.set(1,{["circle"]=true});
emu.frameadvance();
end;
end;
Many thanks! One more thing, the script makes the emulator run pretty slowly. Would it be possible to add something to speed it up. I'm thinking that the script wouldn't need to save a savestate if there is no textbox on screen. So could it not save a savestate when 00071E2C = 0 There's a textbox on screen only when 00071E2C = 1. Would this work?
Lil_Gecko
He/Him
Player (98)
Joined: 4/7/2011
Posts: 520
Sure.
X = savestate.create();

while true do
if memory.readbyte(0x71E2C) == 1 then
savestate.save(X);
emu.frameadvance();
if memory.readbyte(0x1FFE4E) ~= 0 then
savestate.load(X);
joypad.set(1,{["circle"]=true});
emu.frameadvance();
end;
else
emu.frameadvance();
end;
end;
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
Perhaps emulator developers could study the possibility of making savestates a lot more efficient so that they could be done on each frame without affecting the emulation speed...
Joined: 3/18/2006
Posts: 971
Location: Great Britain
Lil_Gecko wrote:
Sure.
X = savestate.create();

while true do
if memory.readbyte(0x71E2C) == 1 then
savestate.save(X);
emu.frameadvance();
if memory.readbyte(0x1FFE4E) ~= 0 then
savestate.load(X);
joypad.set(1,{["circle"]=true});
emu.frameadvance();
end;
else
emu.frameadvance();
end;
end;
<3!
Editor, Player (44)
Joined: 7/11/2010
Posts: 1029
Warp wrote:
Perhaps emulator developers could study the possibility of making savestates a lot more efficient so that they could be done on each frame without affecting the emulation speed...
That's unlikely. You either have to copy the entire internal state, which is much slower than just modifying things as they happen in normal execution, or somehow work out what's changed since the last time you savestated, which will typically halve the emulation speed because you have to record everything in two places rather than one.
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
If the complete state of the emulated hardware were in one continuous block of memory, it could be quickly copied to another location and handled by another thread...
Joined: 9/21/2012
Posts: 11
Location: Northern Virginia
If there's one thing I learned from my forays into emulator development, even from the perspective of someone doing ports, it's that things are complicated for a reason. Optimizing for state saving probably would have costs elsewhere.
Player (210)
Joined: 7/7/2006
Posts: 798
Location: US
To add: Since savestating is so suboptimal, I would create a savestate every 100 or so frames, then start a counter. When the frame is reached, reload the savestate and use the counter to advance frames until the button needs pressed, then start again. This should make the program run magnitudes faster.
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
ais523 wrote:
That's unlikely. You either have to copy the entire internal state
Which is what? Something like 2 kilobytes on the NES? Hardly sounds something that couldn't be copied around 60 times per second. (Even if we go to the SNES, it would be something like 128 kilobytes. Still sounds like an amount of data that can be copied around pretty fast.)
Warepire
He/Him
Editor
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
Warp wrote:
ais523 wrote:
That's unlikely. You either have to copy the entire internal state
Which is what? Something like 2 kilobytes on the NES? Hardly sounds something that couldn't be copied around 60 times per second. (Even if we go to the SNES, it would be something like 128 kilobytes. Still sounds like an amount of data that can be copied around pretty fast.)
When you reach the PlayStation we're talking ~4 megabytes of data.
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
Warp wrote:
Even if we go to the SNES, it would be something like 128 kilobytes. Still sounds like an amount of data that can be copied around pretty fast.
Internal status (maybe a few KB at most), 128KB WRAM, 64KB VRAM, 64KB APU RAM, ?KB SRAM, additional memory on special-chip cartridges.
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
Warepire wrote:
When you reach the PlayStation we're talking ~4 megabytes of data.
So because the state of the PlayStation takes 4 megabytes, it's impossible to make a fast savestate routine for a NES emulator?
creaothceann wrote:
Internal status (maybe a few KB at most), 128KB WRAM, 64KB VRAM, 64KB APU RAM, ?KB SRAM, additional memory on special-chip cartridges.
Do you know how much data is processed by a typical modern computer game on each frame, at 60 FPS? (After all, we are talking about modern PCs, not PCs of the early 90's.) Those amounts of data you are listing aren't much. They all fit into processor caches quite nicely, several times. Copying them around doesn't take much time. I don't think it's the amount of data that's the problem.
Warepire
He/Him
Editor
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
Warp wrote:
Warepire wrote:
When you reach the PlayStation we're talking ~4 megabytes of data.
So because the state of the PlayStation takes 4 megabytes, it's impossible to make a fast savestate routine for a NES emulator?
You did not specify that you were talking about NES only. Besides, as far as I know, the script in question is for FFVII on PSX, hence the PlayStation factoid.
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
Warp wrote:
I don't think it's the amount of data that's the problem.
Just wanted to make the "something like 128KB" a bit more correct. Btw. wouldn't it be easy for a developer to find out how much time saving a savestate takes? Might be useful to know for this discussion.