Example first:
$ lua -l obelix
joypad[0]=snes9x.SNES_Y_MASK+snes9x.SNES_RIGHT_MASK
while game.x_pos < 500
do
snes9x.swig_mainloop(snes9x.TRUE)
end
joypad[0]=0
-> Presses the run key until obelix reaches position 500.
(game.x_pos was found automatically via searching and comparing values, see example 3)
Example 2:
print(ram_word[4473])
-> prints the current frame counter.
Example 3:
-- Init the search
s_erg = search.search_ram(ram_word, nil)
-- Press right all the time
joypad[0]=snes9x.SNES_RIGHT_MASK
for i=1,20 do
-- run for 5 frames
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
-- Search more
s_erg = search.search_ram(ram_word, s_erg, function (a,b) return a>b end)
end
-- Now we run backwards
-- Press left all the time
joypad[0]=snes9x.SNES_LEFT_MASK
-- Wait 40 frames to be running backwards again
for i=1,40 do snes9x.swig_mainloop(snes9x.TRUE) end
for i=1,10 do
-- run for 5 frames
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
snes9x.swig_mainloop(snes9x.TRUE)
-- Search more
s_erg = search.search_ram(ram_word, s_erg, function (a,b) return a<b end)
end
print("Search erg: ")
search.print_search(s_erg)
The result is:
> obelix.find_x_counter()
Search erg:
152 27648 25600
112 27136 25344
113 106 99
153 108 100
Okay 113 and 153 look like coordinates. While 112 and 152 just seem to be found by looking from the wrong offset. Lets put a watch on it:
> while true do print(ram_word[113], ram_word[153]) snes9x.swig_mainloop(snes9x.TRUE) end
The result is now that we can play the game and watch the value change in real time.
Neat!
- So what do we need to do now?
- I need someone who has Visual C++ and can compile it for windows.
- For those that have linux and lua5.1 it might be possible to just download snes9x.so to try it out:
http://studwww.ira.uka.de/~s_franz2/snes9x/snes9x.so
Then do:
lua -l snes9x
To have the search.lua and obelix.lua just apply the diff found below.
Else you need to compile snes9x and apply the following patch:
http://studwww.ira.uka.de/~s_franz2/snes9x/initial_scripting_with_swig-v5.diff
Old instructions follow:
--
Hi,
I implemented initial scripting support for snes9x via swig/lua plus swig/python, swig/php and swig/perl.
It is not yet completely finished, but it was much easier than I thought with the help of swig (www.swig.org).
And with swig using for example python instead of lua is just a matter of changing the Makefile!
(Set SWIG_PYTHON=1 and comment SWIG_LUA = 1, touch snes9x.i and make again!)
This means everyone can use their favorite scripting language with snes9x and is not dependant on lua.
The patch is rather small and still one can already change all non-pointer settings.
And one can also control the main loop as well as all MovieFunctions and access or change all of main memory.
It is however not yet possible to 'hook' somewhere into the code and it will just load Themepark by default ;-).
And sorry patch is for unix/linux only at the moment as thats what I'm using. (But if you want to try it out, too, what about downloading some Knoppix DVD and run it from Windows via CoLinux (included) or directly boot it)
How to build it:
- Install lua5.1
- Install swig either from source or via a package and make sure swig has lua and/or python support.
- Get the patch from
http://studwww.ira.uka.de/~s_franz2/snes9x/initial_scripting_with_swig-v3.diff
Use snes9x-1.43-WIP1-src.tar.gz.
(You can get it from one of the mirrors)
Unpack it.
Build it.
- patch -p1 < ../initial_scripting*.diff
- ./configure
- make
If everything was okay you now have snes9x.so for lua and _snes9x.so+snes9x.py for python.
To use it do for example the following for python:
Python 2.3.5 (#2, Oct 16 2006, 19:19:48)
[GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import snes9x
Rate: 48000, Buffer size: 2048, 16-bit: yes, Stereo: yes, Encoded: no
Found ROM file header (and ignored it).
"THEME PARK" [checksum ok] LoROM, 8Mbits, Type: ROM only, Mode: 20, TV: PAL, S-RAM: 0KB, ROMId: ATQP Company: 67 CRC32: CA0E041C
joystick: No joystick found.
>>> x = snes9x.MovieInfo()
>>> snes9x.S9xMovieCreate("test345.smv", 0x1F, snes9x.MOVIE_OPT_FROM_RESET, x.Metadata, 0)
Movie record
1
>>> snes9x.my_mainloop()
Or what about the following in php or perl:
# php runme.php
# perl runme.pl
Or another nice example in lua:
# lua -l snes9x
Rate: 48000, Buffer size: 2048, 16-bit: yes, Stereo: yes, Encoded: no
Found ROM file header (and ignored it).
"THEME PARK" [checksum ok] LoROM, 8Mbits, Type: ROM only, Mode: 20, TV: PAL, S-RAM: 0KB, ROMId: ATQP Company: 67 CRC32: CA0E041C
joystick: No joystick found.
Lua 5.1.1 Copyright (C) 1994-2006 Lua.org, PUC-Rio
> -- Lets create a new movie
> snes9x.S9xMovieCreate("test345.smv", 0x1F, snes9x.MOVIE_OPT_FROM_RESET, snes9x.char_to_wchar(""), 0)
> -- We need to convert to wchar_t* as swig does not know that type.
Movie record
> j=snes9x.uint32Array_frompointer(snes9x.joypads)
-- We need a new variable first and need to use this helper functions, but it works.
> = snes9x.uint32Array_getitem(j, 0) -- Joypad = 0
0
> -- Lets press and hold START
> return snes9x.uint32Array_setitem(j, 0, snes9x.SNES_START_MASK )
> return snes9x.uint32Array_getitem(j, 0)
4096
> -- Okay lets wait 100 frames for our start to be accepted
> for i = 1,100 do snes9x.my_mainloop() end
> return snes9x.uint32Array_getitem(j, 0)
4096
> snes9x.uint32Array_setitem(j, 0, snes9x. 0 )
> for i = 1,100 do snes9x.my_mainloop() end
> snes9x.uint32Array_setitem(j, 0, snes9x.SNES_START_MASK )
> for i = 1,100 do snes9x.my_mainloop() end
> -- Okay enough keys pressed lets examine memory
> ram=snes9x.uint8Array_frompointer(snes9x.Memory.RAM)
> addr = 0x7E8900 - 0x7E0000 -- As RAM is mapped at 0x7E of Memory we need to strip the base address
> = snes9x.uint8Array_getitem(ram, addr)
> -- Okay we have finished our task, lets save that movie
> snes9x.S9xMovieStop(snes9x.FALSE)
Movie stop
> snes9x.S9xExit()
--
I hope you enjoy the scripting engine and comments are appreciated, but now I'm much too tired to write anything more.
cu
Fabian
Author: Fabian Franz <snes9x@fabian-franz.de>