1 2
8 9
Post subject: Lua scripting in snes9x (looking good!)
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
For the hell of it, I added Lua scripting to the latest (as of when I posted this first) snes9x from gocha's modified snes9x (currently improvement 11 beta 17 (I think)). Latest version (0.06) Previous version (0.05) Sample scripts API (keep an eye on the version numbers!) I will be offering some tech support and scripting assistance for anyone who asks in this thread. Moderation note: this post was split from the thread by gocha.
Joined: 12/29/2006
Posts: 119
Location: Japan, Anjo
Good.
DiffCalc .NET Frameworks 3.5 required.
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
Updates! Bugs fixed:
  • Speed is now sane during script execution
  • Scripts exitting normally no longer give a Lua error on shutdown
  • Savestate functions work well enough to meet the specification set in the API docs
  • No longer depends on FMOD.dll
  • Less spam to stdout.txt (whoops!)
Known issues:
  • C:\Windows\Temp might get filled with anonymous savestates if shutdown of snes9x is not clean.
  • movie.record and playback not working
  • Joypad code believed correct but not tested
Link Edit: Turns out I didn't fix the speed bug as well as I had thought. If your version still exhibits high speed when a script runs, redownload. I've also renamed the executable to snes9x_lua.exe by request so as to not conflict with other emulators.
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
In an attempt to spark interest, I'll ask the general public: What features should a scripting language in an emulator support (ie. what should I add)? Would there be interest in adding this to the NES, N64, or other emulators? I don't think it would be very hard. My own suggestion would be to support drawing on the screen. If coordinates are calculated by a script, they could be rendered visually. gui.drawpixel(x,y) and gui.drawline(x1,y1,x2,y2) would be simple enough.
Joined: 10/3/2005
Posts: 1332
It would be nice to have in Mupen. It's better than the current alternative ways of watching memory addresses in that emulator, I think. As for features... well, I'm just pulling this out of my ass- I have no idea if it's feasible- but it would be extraordinarily cool if it we could compare a character's x/y coordinates (or memory values in general) across two movies, so as to have a constant and precise gauge of whether you've lost frames over a previous video. (As per this thread.) I'm very impressed by the power of Lua so far. Maybe it can be done?
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
You have access to the IO library in Lua. Have one script monitor a movie and save stats to a file. Then have a second load the stats. The IO code in Lua can be a bit confusing though. :/
Joined: 10/3/2005
Posts: 1332
Yes, I had just assumed the scripts were limited to functions in the host program. I'm thumbing through the index of the reference manual as I type this. It's getting very interesting. Hee hee hee...
upthorn
He/Him
Emulator Coder, Active player (391)
Joined: 3/24/2006
Posts: 1802
DeHackEd wrote:
My own suggestion would be to support drawing on the screen. If coordinates are calculated by a script, they could be rendered visually. gui.drawpixel(x,y) and gui.drawline(x1,y1,x2,y2) would be simple enough.
This would be my own suggestion, although I'd also suggest a gui.drawrectangle(x,y,w,h), or possibly gui.drawrectangle(x,y,w,h,anchorpoint) simply to avoid requiring multiple calls to C from LUA, which would presumably incur a performance hit. For reference, anchorpoint would be an enumeration representing top-left corner, top-midpoint, top-right, center-left, center, center-right, bottom-left, bottom-midpoint, or bottom-right. Additionally, I would add an RGB color arguement to each of these, so that, in the case of multiple hitbox and/or hotpoint types, they can be color coded
How fleeting are all human passions compared with the massive continuity of ducks.
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
upthorn wrote:
multiple calls to C from LUA, which would presumably incur a performance hit.
Technically speaking yeah, but Lua is pretty fast. It also makes the C code conform pretty close to the actual Lua internal format for function calls. All in all, I don't think it would be a significant hit for any situation where images going on screen would be important (user viewing, AVI encoding) Still, it's a good idea to include, and colour should be added as well...
Joined: 8/27/2006
Posts: 883
Even if I don't TAS, I really liked the movie of Sparster I think, with the hitbox drawn to the screen. it could be really nice for TASer. I personnaly likes how it was done. And it could be useful in a lot of place. Would it me possible to do gui.writetext(x,y, text) EDIT : I don't know exactly how it works, but is it possible to enabled and disabled the some part of the scripting ? Like I can script a convinient way to show information about the main character (like attack, defence etc) but I want it to be shown when I want (once in a while)
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
Getting input into the script is technically a problem for me since I have no experience with prorgamming into windows at this level. I'd basically need to make new input buttons to go with the normal SNES controllers. But it can read the normal gamepad. If there's a button that normally does nothing (eg. Select) then you can read it as a secret script command. I'll see if I can just extend the snes9x input code as is to support additional buttons.
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
I have no idea what I'm doing when I modify the windows GUI code. That one's going to be put off. The GUI code is up and working, and I've updated the API spec. I could release an updated version right now if I wanted to. GUI functions are draw pixel, draw line, draw box (outline only) and write text anywhere. Edit: would eliminating this one frame drawing delay be worth doing if it made scripts just that little bit more complicated? I can allow you to specify a function to be called just before the image is drawn, allowing the updated state to be viewed and the images drawn.
Active player (356)
Joined: 1/16/2008
Posts: 358
Location: The Netherlands
great work! I've been playing with it for a bit and will do some more soon, but i ran into something
When Lua execution starts, the emulator will be automatically unpaused if it is currently paused. If so, it will automatically be paused when the script exits
using "Snes9X v1.43+ v11 (beta15 + lua 0.02) for Windows" the game is not unpaused at start of execution and not paused at the end either. script to reproduce:
framecount = 0
while (framecount<100) do
	data = memory.readword(0x7e005a)
	snes9x.message("x_coordinate "..data) 
	framecount = framecount + 1
	snes9x.frameadvance()
end
does not matter what game i use note that the message is being displayed, so the script does indeed run. ===================================== something else i noticed, I was unable to control/change the emulator speed script being run:
snes9x.speedmode("maximum")
framecount = 0

while framecount<100 do
	framecount = framecount + 1
	snes9x.frameadvance()
end
snes9x.speedmode("normal")
would expect to see the game 'skip' 100 frames, instead it just continues as usual trying changing some settings but nothing changes (e.g. 'toggle fast forward mode' and 'pause when inactive')
TASes: [URL=http://tasvideos.org/Movies-298up-Obs.html]Mr. Nutz (SNES), Young Merlin 100% (SNES), Animaniacs 100% (SNES)[/URL]
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
New version, 0.03 New features/changes:
  • GUI code! Draw on the screen!
  • snes9x.speedmode now works properly
  • Emulator should follow the spec on the API doc now.
  • Order of memory.write*() parameters was incorrect in previous versions.
  • Misc bugfixes
Known Issues:
  • Possible crash when a script exits normally. Reported by DK64_MASTER, not reproducible by me.
  • memory.register remains good and broke
The sample scripts are no longer included in the ZIP as the list has been growing. Now they're online.
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
Fix a memory leak. Otherwise, pressing load-state will eat about 730 KB of memory. Yeah that sucks. No other changes.
Player (105)
Joined: 1/30/2005
Posts: 564
Location: Québec, Canada
Random (lame) comment: Could we have the offset needed to make Snes9x Memory Watcher work with these new Snes9x's? It would make life just a little tiny bit easier for those of us who use it :)
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
I thought that's what that thing in the Help menu was for. Give it a look. And if it's not, I don't know how to help you. (Besides, that just takes away half the point of a scriptable emulator)
Player (105)
Joined: 1/30/2005
Posts: 564
Location: Québec, Canada
DeHackEd wrote:
I thought that's what that thing in the Help menu was for. Give it a look.
*slaps himself on the forehead* That was it. Thanks!
Joined: 10/3/2005
Posts: 1332
I wrote a rudimentary subtitling script for translations, director's commentaries, WIP annotations, and... other purposes. It would need a lot of tweaking to make the display look right in any given game, so I didn't concern myself with making it do anything more than what I specifically needed. Here's a package containing the script, a movie of Rushing Beat Shura (J), and my accompanying "translation." To use it, you'll need to load the ROM, start the movie, then execute the script. The script and the translation need to be in the same folder. It was a buttload of work, and not all the kinks have been solved, but there you go.
Joined: 12/29/2006
Posts: 119
Location: Japan, Anjo
DiffCalc .NET Frameworks 3.5 required.
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
I'm preparing to release a new version. Changes:
  • Will include source code, and Linux version will compile and work. Some assembly required.
  • Windows version will successfully load 3rd party libraries, such as those listed at luaforge.
  • Screen shot support, provided you install the GD library and use it.
  • Transparent drawing over the GUI display.
Anything else requested? These updates are listed in the API as requiring 0.04 or later (which doesn't exist yet)
Joined: 10/24/2005
Posts: 1080
Location: San Jose
Can it make me coffee? No, seriously, thank you for your hard work DeHackEd!
<agill> banana banana banana terracotta pie! <Shinryuu> ho-la terracotta barba-ra anal-o~
Joined: 2/12/2006
Posts: 432
what sort of things does this let you do?
Player (105)
Joined: 1/30/2005
Posts: 564
Location: Québec, Canada
Is there / will there be a signed version of memory.readword and/or memory.readbyte? Right now, there seems to be only an unsigned version of each. That would be pretty useful in some scripts. (For example, the speed address in Uniracers, amongst others)
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
snes9x's memory algorithm only provides unsigned numbers. If you want to convert to negative, subtract 256 or 65536 from the number as appropriate for the data size. Eg: -1 will be reported as 255 for a 8 bit value, and 255-256=-1. Of course, the number must be >= 128 or >= 32768 before you can apply this. Do you still want it provided via the interface anyways? It's not that it's hard, only that it's unnecessary.
1 2
8 9