Post subject: Potential LUA bug... savesates not working properly.
Joined: 2/5/2014
Posts: 28
I've started a project to make an in-game menu system for all the lua-enabled console emulators. Basically I'm trying to make it to where you can access all the pertinent functions via your gamepad instead of having to whip out a keyboard. Anyway... fceux is giving me issues. savestate.load and savestate.save aren't working properly. First off if I try to create a state on the fly, it doesn't work..... like say my function for save is setup like: ss1=savestate.create(1); savestate.save(ss1); and load is: ss1=savestate.create(1); savestate.load(ss1); If coded like this nothing happens. What I have to do to get any functionality at all is to put a loop waiting for the emulation to start at the top of the script and create the state object once and only once at the beginning. Even then it doesn't work properly. savestate.save never saves the state to file, rather it saves it to memory and yes I am using valid numbers to create the state as per the documentation. Strangely enough savestate.load WILL load a state that I've created manually. So long story short I think savestate.save is broken completely... it saves to memory, but not to file.
Post subject: Re: Potential LUA bug... savesates not working properly.
Emulator Coder, Skilled player (1141)
Joined: 5/1/2010
Posts: 1217
HowardC wrote:
Even then it doesn't work properly. savestate.save never saves the state to file, rather it saves it to memory and yes I am using valid numbers to create the state as per the documentation.
Maybe using savestate.persist might help? At least the documentation looks like it might be relevant.
Post subject: Re: Potential LUA bug... savesates not working properly.
Joined: 2/5/2014
Posts: 28
Ilari wrote:
HowardC wrote:
Even then it doesn't work properly. savestate.save never saves the state to file, rather it saves it to memory and yes I am using valid numbers to create the state as per the documentation.
Maybe using savestate.persist might help? At least the documentation looks like it might be relevant.
Well yeah that seems to have helped. Apparently to save to file you need to do a savestate.persist immediately AFTER saving the slot. I'm not sure if this will fix the other issues (having to make the save object at launch only) but I can work with it regardless. Thanks. You know I've been working on this project for a couple of days and I'm a bit perplexed as to why each emulator seems do want slightly different scripting even though it's obvious that the lua was implemented with the idea of scripts having universal syntax. I've got a working menu system for Gens but it doesn't have a emu.reset, so I have to make a savestate on load and fake it that way. Ditto for snes9x... fceux on the other hand... emu.reset works just fine. Snes9x is similar to Gens, but my infinite loop to wait for the emulator to start crashes the emulator if I don't have the rom loaded first. Also snes9x crashes if you attempt to load a save state that doesn't exist while gens just silently prints the error to screen as it should. Fceux's gui.text function draws a different font of text than the other two with an ugly blue background. I'm new to these forums so I'm wondering where would be the best place to post about this project. I think it's long overdo that these emulators get an interface that you can navigate via the original gamepads instead of fiddling with a keyboard all the time.
Post subject: Re: Potential LUA bug... savesates not working properly.
Emulator Coder, Skilled player (1141)
Joined: 5/1/2010
Posts: 1217
HowardC wrote:
You know I've been working on this project for a couple of days and I'm a bit perplexed as to why each emulator seems do want slightly different scripting even though it's obvious that the lua was implemented with the idea of scripts having universal syntax.
Each emulator has its own implementation of Lua (and also a bit different features)...
Joined: 2/5/2014
Posts: 28
Well yeah, obviously the implementation is different, but that's not what I mean. It looks like universal function names were decided upon.... savestate.load emu.pause ect But what they do and how you use them is often completely different. It makes things quite counter-intuitive.
Editor, Skilled player (1938)
Joined: 6/15/2005
Posts: 3246
HowardC wrote:
But what they do and how you use them is often completely different. It makes things quite counter-intuitive.
Most emulators were not written with universality (with each other) in mind, so Lua can't do any better. That's the way it is, unfortunately. BizHawk strives to be as universal as possible, so Lua is probably more consistent there. I haven't tested though.
Emulator Coder, Skilled player (1141)
Joined: 5/1/2010
Posts: 1217
FractalFusion wrote:
HowardC wrote:
But what they do and how you use them is often completely different. It makes things quite counter-intuitive.
Most emulators were not written with universality (with each other) in mind, so Lua can't do any better. That's the way it is, unfortunately. BizHawk strives to be as universal as possible, so Lua is probably more consistent there. I haven't tested though.
Of course, it is different from everything else. This is about how Lua scripting differs between emulators, not inconsistencies within single emulator.
Editor, Skilled player (1938)
Joined: 6/15/2005
Posts: 3246
What I was saying was that, since different emulators handle core functions (e.g. resets, savestates, etc.) in different ways, it is likely to cause divergence in Lua functionality (this might even be the only suitable option). For example, if emulator X handles savestates in one way, and emulator Y handles savestates in a very different way, then likely savestate.load version X will handle differently compared to savestate.load version Y. It is possible though that there are some needless Lua inconsistencies, but that has been mostly because emulators are independent, and so it is easy to write independent Lua systems for each of them (this is where inconsistency happens).
Joined: 2/5/2014
Posts: 28
Well it solved my issue so thanks on that. I don't mean to argue by I still don't think you guys are getting my point. Yeah these emulators were developed separately, of course. But the lua implementation, that was decided upon by the community and the syntax was purposefully made universal (stuff like fceux.function has been depreciated by emu.function, specifically so that code is universal). So how the emulator handles savestates and what have you is irrelevant. Because when the lua was implemented and modeled specifically after another emulator's lua implementation (I believe in this case snes9xrr) it should have been hooked up in such a way that it worked identically. I'm a programmer I assure you this is possible. Just to use this specific issue as an example: Ok so I need to call savestate.persist first. Why? Why wasn't lua hooked up to automatically do whatever savestate.persist is doing behind the scenes when savestate.load or save is called so that it operates exactly like snes9x or Gens? The authors want to add non-persistant states? Well then make an option for that, don't make persistence the option as it breaks universal scripting support. Remember, lua is "hooked up" to functions native to the emulator. So any differences in the functions, extra stuff that needs done ect, should be handled, internally, not at the scripting level. I've got a gens menu finished, and it's working quite well: http://youtu.be/Fi6g55hfpNw For the most part scripting is fairly consistent between the two, except for the save/load state issues. Now I've got to try and figure out how to fake a pause in FCEUX, because the function available in Gens isn't available in this emulator.
Editor, Skilled player (1172)
Joined: 9/27/2008
Posts: 1085
Here's more inconsistency: FCEUX has a gui.register that runs while emulation is actually paused. DeSmuME also runs that function's code while paused. Snes9x doesn't do that. You'll need to fake a pause, I believe. VBA doesn't either. Don't know about Gens, but you've certainly went through it carefully already. gui.register takes a function as a parameter. The function is to be called whenever the display updates. For some reason, FCEUX's display is updated fairly frequently when emulation is paused. Therefore, you can pause emulation and still have code running. Use emu.pause and emu.unpause as well to get things holding still or going. I'm not sure why the different emulators are all over the map with these functions. Most of them are similar, but there are a few irritating moments. I couldn't port my old Multitrack2 script to VBA at all. EDIT: As a bonus, when I was first messing around with gui.register, the help texts gave no mention of this "run while paused" feature. FCEUX 2.2.1 help still gives no mention of this.
Joined: 2/5/2014
Posts: 28
FatRatKnight wrote:
Here's more inconsistency: FCEUX has a gui.register that runs while emulation is actually paused. DeSmuME also runs that function's code while paused. Snes9x doesn't do that. You'll need to fake a pause, I believe. VBA doesn't either. Don't know about Gens, but you've certainly went through it carefully already. gui.register takes a function as a parameter. The function is to be called whenever the display updates. For some reason, FCEUX's display is updated fairly frequently when emulation is paused. Therefore, you can pause emulation and still have code running. Use emu.pause and emu.unpause as well to get things holding still or going. I'm not sure why the different emulators are all over the map with these functions. Most of them are similar, but there are a few irritating moments. I couldn't port my old Multitrack2 script to VBA at all. EDIT: As a bonus, when I was first messing around with gui.register, the help texts gave no mention of this "run while paused" feature. FCEUX 2.2.1 help still gives no mention of this.
Well darn, I should have checked out this reply first. Note my other post. I'm almost there anyway. Let me ask you this though. Is gui.regster called multiple times per frame? If so then it might hurt performance and/or effect my de-bounce code for navigation.
Editor, Skilled player (1172)
Joined: 9/27/2008
Posts: 1085
Through gui.register, a function is called once every time the emulator wants to update the screen. If the emulator is currently playing, it is exactly once per frame. If the emulator is paused, it looks like it tries to be called roughly 20 times per second. That should give you an idea. If you want a short piece of test code:
Language: lua

local a= 0 local function GuiStuff() -- Simply counts how many times it's called gui.text(8,8,a) a= a+1 end gui.register(GuiStuff)
Joined: 2/5/2014
Posts: 28
Thanks for the code, but unfortunately this looks like a bust anyway. Any calls to gui.text seem to update fine while the game is paused, but absolutely nothing else does. Even with joypad.getimmediate, the gamepad state doesn't update and none of my gdoverlay calls are working. If you have any ideas let me know.
Joined: 2/5/2014
Posts: 28
Hmm... nevermind. The framerate drop was so great that I had to adjust my de-bounce code waaay down. The game was responding, just very slowly. I think I can work with this, thanks a ton!