Post subject: emu.frameadvance during event callback?
PikalaxALT
He/Him
Joined: 6/18/2017
Posts: 5
I'm trying to write a lua script that plays optimally through Pokemon Crystal (CGB). Right now I want to write an OnMemoryExecute event that triggers before the joypad polling begins for the Game Freak logo and intro movie skip (kinda important to get this right). Without getting into too many details, I want the routine to toggle the A button at the last frame before the intro routine starts checking whether a button was pressed. After the copyright information is displayed, the game unloads those graphics and loads in the graphics for the game freak logo. During this time, several frames elapse; the joypad is polled each frame, during vblank. Thus the only time an input will have any real effect is if it's sent the frame before it's used. As soon as the graphics loading routine returns, the game starts checking the buttons. If I register my OnMemoryExecute event there, I lose a frame. To save myself some time trying to figure out the optimal execution breakpoint to send my A input, I have decided to register an OnMemoryExecute event at the start of the graphics loading routine and insert emu.frameadvance calls in the callback to offset the A press. When I do that, though, I get this error in the lua console:
error running function attached by the event OnMemoryExecute
Error message: A .NET exception occured in user-code
It seems that emu.frameadvance within an OnMemoryExecute event is not allowed. emu.yield raises the same error. Is there another way for me to get the effect I want?
Working on lua scripting for Pokemon Crystal optimal play
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
I don't think you understand what you're asking for. An OnMemory* callback exists to let you do things before the native memory action happens. Right after you return from it, the native memory action happens. Advancing the emulation clock from inside such a callback isn't just impossible; it makes no sense. The usual way to do what I think you're actually trying to do is to set a flag inside the callback, which the rest of your code can respond to later.
Amaraticando
It/Its
Editor, Player (158)
Joined: 1/10/2012
Posts: 673
Location: Brazil
I'm quite sure the same caveats of Snes9x frameadvance function are valid, because this is not used to advance the frame, but to return to the script after that happens: Warning: Due to the way the code is written, the times this function may be called is restricted. Norably, it must not be called within a coroutine or under a [x]pcall(). You can use coroutines for your own purposes, but they must not call this function themselves. Furthermore, this function cannot be called from any "registered" callback function. An error will occur if you do.
PikalaxALT
He/Him
Joined: 6/18/2017
Posts: 5
Thanks for the explanation natt, that makes sense. Two other questions that arise: 1) Is the event guid or name passed to the callback? That would allow a callback to kill itself without the need for multiple copies of essentially the same callback. 2) Is it possible to specify a callback to fire in a domain other than System Bus? Because the Gameboy Color uses banked ROM, VRAM, SRAM, and WRAM, any function firing within a bankable domain would need to know what bank it's in.
Working on lua scripting for Pokemon Crystal optimal play
Editor, Emulator Coder
Joined: 8/7/2008
Posts: 1156
1) you dont need that, make each event handler a closure containing the name which you would then remove when its called 2. no, that's an architectural flaw in bizhawk right now.
PikalaxALT
He/Him
Joined: 6/18/2017
Posts: 5
zeromus wrote:
1) you dont need that, make each event handler a closure containing the name which you would then remove when its called 2. no, that's an architectural flaw in bizhawk right now.
Alright, thanks. One more quick question (for now): is there a lua command for hard reset?
Working on lua scripting for Pokemon Crystal optimal play
Editor, Emulator Coder
Joined: 8/7/2008
Posts: 1156
hard reset is a button on the console called power, if it exists. maybe you want "reboot core"
PikalaxALT
He/Him
Joined: 6/18/2017
Posts: 5
zeromus wrote:
hard reset is a button on the console called power, if it exists. maybe you want "reboot core"
In my experience, "reboot core" has led to emulator hard locks or crashes without dump on my machine, so I'd like to avoid that if at all possible. Is there a function to print the available buttons in the console?
Working on lua scripting for Pokemon Crystal optimal play
Editor, Emulator Coder
Joined: 8/7/2008
Posts: 1156
maybe you want "reboot core" to not be buggy. try print(joypad.get());
PikalaxALT
He/Him
Joined: 6/18/2017
Posts: 5
zeromus wrote:
maybe you want "reboot core" to not be buggy. try print(joypad.get());
Alright, that works for now. One more question: Is there a lua function to unregister all events? I know there's the F12 menu in the console but I was looking for something more automated.
Working on lua scripting for Pokemon Crystal optimal play
Editor, Emulator Coder
Joined: 8/7/2008
Posts: 1156
no