1 2
7 8 9
Post subject: New ghost script for Super Mario World
Former player
Joined: 2/19/2007
Posts: 424
Location: UK
I have adapted the old Super Metroid TAS comparison scripts for Super Mario World. Here is an example of the script in action: http://www.youtube.com/watch?v=ieFFCRQBIeo http://www.youtube.com/watch?v=imsRpZ-WEds And here are the scripts themselves, along with two resource files: http://folk.uio.no/sigurdkn/smwrecord.lua http://folk.uio.no/sigurdkn/smwplayer.lua http://folk.uio.no/sigurdkn/smwdb.map http://folk.uio.no/sigurdkn/smwdb.png Surprisingly, making the super mario world version of this script was much harder than making the super metroid version, mostly because of inconsistent delays between when values appear in handy memory addresses and when things update on screen, as well as many composite sprites (the yoshi portion of the script is still somewhat hacky). Most of the options from the super metroid version are still there: You can choose between realtime and in-game modes (which make much less difference here than in super metroid. The video above was made using realtime mode.) both for displaying and syncing, and you can turn per-room resyncing on or off. Note that room syncing is not used on the overworld, so you can easily see the runs' relative position there. For using the script yourself, the procedure is the same as before: 1. Generate ghost files, which are text files containing destilled information about a run. This is done by loading the script smwrecord.lua, and then loading the movie file. Once you are done (fast forward does not disturb the script), exit the emulator, and a file named ghost.dump has been generated. Rename this to something sensible. Repeat this for each run you want to compare to. 2. Edit smwplayer.lua. What needs editing is only the the topmost portion. Edit the ghost_dumps list to indicate the dump files you generated earlier. 3. Load smwplayer.lua in snes9x, and either try playing against the ghosts yourself, or load a movie file. You will require the gd library for lua for this; otherwise you can only display hitboxes etc. Edit: The script now supports continuous offsets instead of just room offsets, and the offsets displayed can be controlled independently from the offsets actually used for the ghosts. The offsets used for the delays at the top are now calculated to sub-frame precision based on the ghost speed and distance from closest ghost pixel to the current player position. The status display has been corrected and expanded to show more useful information. Here is a demonstration of the script in action: http://www.youtube.com/watch?v=gRSVOPzxsKQ The new version can be found at the same locations listed above. Note that the ghost dump format has been changed, so you will need to rerun smwrecord.lua to generate new ghosts. Edit: Fixed room transition issue which sometimes happened when the same room was vistited multiple times. The smwplayer.lua linked above has been updated.
Post subject: Re: New ghost script for Super Mario World
gocha
Any
Emulator Coder, Former player
Joined: 6/21/2006
Posts: 401
Location: Japan, Nagoya
amaurea, I really love your impressive Lua works and comparison videos <3
I am usually available on Discord server or Twitter.
Experienced player (608)
Joined: 10/23/2004
Posts: 706
Simply awesome. I would love to see an all exits comparison.
Current Project: - Mario Kart 64
Emulator Coder, Site Developer, Former player
Joined: 11/6/2004
Posts: 833
You've earned yourself an "I saw it and I still don't believe it."
Post subject: Re: New ghost script for Super Mario World
gocha
Any
Emulator Coder, Former player
Joined: 6/21/2006
Posts: 401
Location: Japan, Nagoya
Alternate color! http://gocha.is.land.to/down/public/smwdb-2p.png Thanks pirohiko for processing it :p
I am usually available on Discord server or Twitter.
Post subject: Re: New ghost script for Super Mario World
Former player
Joined: 2/19/2007
Posts: 424
Location: UK
gocha wrote:
Alternate color! http://gocha.is.land.to/down/public/smwdb-2p.png Thanks pirohiko for processing it :p
Nice! With this, I can use Luigi for 96 exit ghosts, and mario for any% ghosts, for example. Even better, though, would be to have one sprite set for each of the ghosts. It could be mario, luigi, the princess, toad, sonic, etc. But making them would be a lot of work.. I have tested the script on 96 exit runs too, but it ended up less interesting imho, mostly because of very different overworld routes, and too few runs to compare with.
Post subject: REWIND SCRIPT HALP!
Joined: 4/2/2010
Posts: 2
So, I didn't want my first post here to be a request, but I've lost all of my sanity trying to figure out how the hell keypresses are read on LUA to trigger a rewind script, similar to the one for GENS in this thread... The problem is that unlike GENS, Snes9x doesn't have a register hotkey function. I know some scripts set hotkeys by searching the RAM for a nil value that turns into 1 when a button is held, but that would be game specific and I wanted this script to work without needing to search RAM addresses every time I load up a new game. Also I'm aware the code belongs to deltaphc but this fix would only change a line or two, so there shouldn't be any problems. So, TL;DR: Someone please make me a rewind script similar to this for Snes9x, that can be toggled by using a hotkey (eg: Ctrl), or a joypad combination (say, L+R+select). thanks in advance and keep up the great work, but please provide some sample scripts in the next release, haha. :)
BR?BR? heuHEUEHueuhEUEHuEheUehuHUEHeuEHhUheueHEHUE
Post subject: Re: REWIND SCRIPT HALP!
Joined: 10/3/2005
Posts: 1332
Nervoso_Ramirez wrote:
Someone please make me a rewind script similar to this for Snes9x, that can be toggled by using a hotkey (eg: Ctrl), or a joypad combination (say, L+R+select). thanks in advance and keep up the great work, but please provide some sample scripts in the next release, haha. :)
You can map joypad 5 to your hotkeys, and then define the behavior you want by hand:
hotkeypad = joypad.get(5)
if hotkeypad["X"] then doRewind() end
It doesn't run while the emulator is paused, but it's better than nothing. You can also find sample scripts with the other emulator packages that are (more or less) portable. As for the rewind script... yeah, someone should probably do that. Hopefully so that it would work reliably for this platform. I suspect there are (or at least, were, the last time I wrote a rewind script) issues in the emulator itself, since rewinding would throw userdata errors for no discernible reason. I've been tinkering with Snes9x lately. Maybe I should do something about these problems... :/
Joined: 4/2/2010
Posts: 2
Thanks for the help! I couldn't get player 5 to work on non-multitap games, so I just used player 2 instead, turns out Snes9x lags a little whenever a savestate is made -- or maybe it's just my crappy netbook, although ZSNES has had a rewind feature for ages and with no lag, also some ugly counter appears on screen while the script is running, so I guess I'll just give up on this one for now... Thanks again for the support, though, that was incredibly quick. EDIT: Yes, even after I used the lowest savestate compression level, still no luck.
BR?BR? heuHEUEHueuhEUEHuEheUehuHUEHeuEHhUheueHEHUE
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
Is there a script to suppress the HUD line flickering in Super Metroid when you play it with SNES9x 1.43? I think this was already mentioned somewhere, but I can't find it...
Player (246)
Joined: 8/6/2006
Posts: 784
Location: Connecticut, USA
Here's a (hackneyed) script I created, specifically for the Mega Man X 100% run. I really have next to no experience with scripting (other than what I've learned here), so it can definitely be cleaned up... a lot. But it works!
It includes: - X and Y speeds - X and Y positions (including subpixel position) - An approximate hitbox for Mega Man - Numerical values for health and weapons (in corresponding colors) - HP values for enemies - Predictors for Mega Man's buster charge (the colored 0s underneath him) - An "Upgrade Progress" bar for fun, which increments every time Mega Man gets a heart tank, energy tank, new weapon from a boss, or piece of armor. - Leftover attempt at a lag counter somewhere in the script
Former player
Joined: 2/19/2007
Posts: 424
Location: UK
That script looks not only useful, but also stylish! Thanks for making and publishing it! I had a look at the source code, and I have a few comments: * There is a lot of code duplication. Generally, when you find yourself wanting to make variables with names foo1, foo2, foo3, ..., that is an indication that you really want foo to be an array instead. That way you can loop instead of repeating code. * The weapon ammo formulas were extremely complicated! I tried rewriting them using arrays and loops, but the formulas were too different. Are you sure those memory addresses are the easiest way of getting at the ammo? * You said that the hitboxes were approximate? In what way are they approximate? Looking at your picture, they seem to have the right size and shape, but their location seems to be a bit off. Perhaps you are adding a Y value instead of subtracting it? It looks like the hitboxes for the bats would work better if they were flipped horizontally around their top. If that is not the case, perhaps you can look around at nearby memory addresses - they might contain extra information you need to make sense of the hitboxes.
Player (246)
Joined: 8/6/2006
Posts: 784
Location: Connecticut, USA
amaurea wrote:
That script looks not only useful, but also stylish! Thanks for making and publishing it! I had a look at the source code, and I have a few comments: * There is a lot of code duplication. Generally, when you find yourself wanting to make variables with names foo1, foo2, foo3, ..., that is an indication that you really want foo to be an array instead. That way you can loop instead of repeating code.
This was my main problem with cleaning up the script... like I said, I'm new to scripting and I could probably have figured out how to neaten it up, but I just left it as it is since it worked.
amaurea wrote:
* The weapon ammo formulas were extremely complicated! I tried rewriting them using arrays and loops, but the formulas were too different. Are you sure those memory addresses are the easiest way of getting at the ammo?
There's probably a better set of memory addresses to use or (more likely) I wasn't looking at them correctly (maybe I didn't check to see if they were misaligned or more bytes or something).
amaurea wrote:
* You said that the hitboxes were approximate? In what way are they approximate? Looking at your picture, they seem to have the right size and shape, but their location seems to be a bit off. Perhaps you are adding a Y value instead of subtracting it? It looks like the hitboxes for the bats would work better if they were flipped horizontally around their top. If that is not the case, perhaps you can look around at nearby memory addresses - they might contain extra information you need to make sense of the hitboxes.
The only actual hitbox I drew was the one around Mega Man, which I didn't get from any sort of memory address (in fact, I just tested by watching his collision with objects until it looked correct). The boxes around the enemies' HP are just there to make the numbers show up a bit better. I couldn't find any hitbox information tied to RAM, and I am unskilled at looking at ROM so I scrapped the hitbox thing. Anyway, thank you for your comments! I'm glad you like it.
Player (137)
Joined: 9/18/2007
Posts: 389
Here's a patch for the function snes9x.setrenderplanes(bool,bool,bool,bool,bool). It uses the same syntax as fceu.setrenderplanes, but it supports 4 background layers, so it needs 5 parameters. All of them must be present. for example, snes9x.setrenderplanes(true,false,true,false,false) would say "enable sprites, enable bg2, disable all others"
Index: lua-engine.cpp
===================================================================
--- lua-engine.cpp	(revision 21)
+++ lua-engine.cpp	(working copy)
@@ -2896,6 +2896,33 @@
 	return 4;
 }
 
+
+// gui.setrenderplanes{5 booleans}
+// 
+
+#ifndef luaL_checkbool
+#define luaL_checkbool(L, i) (lua_isboolean(L,i) ? lua_toboolean(L,i) : luaL_checkint(L,i)) 
+#endif
+
+static int snes9x_setrenderplanes(lua_State *L) {
+	bool sprites, bg1, bg2, bg3, bg4;
+	bg1 = luaL_checkbool(L,2);
+	bg2 = luaL_checkbool(L,3);
+	bg3 = luaL_checkbool(L,4);
+	bg4 = luaL_checkbool(L,5);
+	sprites = luaL_checkbool(L,1);
+
+	int l1, l2, l3, l4, l5;
+	l1 = (bg1 ? 0 : 1);
+	l2 = (bg2 ? 0 : 2);
+	l3 = (bg3 ? 0 : 4);
+	l4 = (bg4 ? 0 : 8);
+	l5 = (sprites ? 0 : 16);
+	Settings.BG_Forced = l1 | l2 | l3 | l4 | l5;
+	
+	return 0;
+}
+
 // gui.gdscreenshot()
 //
 //  Returns a screen shot as a string in gd's v1 file format.
@@ -4175,6 +4202,7 @@
 	{"registerexit", snes9x_registerexit},
 	{"message", snes9x_message},
 	{"print", print}, // sure, why not
+	{"setrenderplanes", snes9x_setrenderplanes}, //NEW FUNCTION: snes9x.setrenderplanes()!
 	{NULL,NULL}
 };
Joined: 10/20/2006
Posts: 1248
Something like that would be very useful to have in any emulator. Thanks, partyboy1a. I think an interface reminiscent of snes9x.setrenderplanes(snes9x.BG_LAYER_ONE | snes9x.BG_LAYER_TWO) would generally be preferred, however [URL=http://lua-users.org/wiki/BitwiseOperators]I've just read[/URL] that lua doesn't support bitwise operators in its standard definition. I should also note that I have no experience with the lua/c inteface at all. Hm.
Player (137)
Joined: 9/18/2007
Posts: 389
Don't just thank me, I used some code Dario_ff has written for the Atlasizer modifications for Snes9x. It'll take a while until all the bugs are fixed and all the necessary features are implemented, but I think we'll get it finished...
Joined: 10/1/2007
Posts: 52
Amaurea, I really wanted to use your animated ghost script for Super Metroid to practice speedrunning against one of my runs. I was able to get the old version to work, but this new version (requiring the Lua GD Library) is beyond my area of knowledge. The only tutorial I came across contained overly complicated explanations of programming commands that I don't care to spend 3 or more hours learning. If you could walk me through the process, i'd be entirely grateful. Or even if you could tell me how to install the library. Thanks.
Emulator Coder, Skilled player (1310)
Joined: 12/21/2004
Posts: 2687
ICheatAtGolf wrote:
If you could walk me through the process, i'd be entirely grateful. Or even if you could tell me how to install the library. Thanks.
I haven't tried the script you're trying to use and I don't know what instructions came with it, but if you're asking how to install the GD library for Lua, and you're using Windows, then there's this description I wrote a while ago: Listed here are the steps I followed to install Lua-GD for Win32. They worked for me, but they might not exactly match up with your environment, so I'd suggest following the official installation instructions if these don't help:
  1. I downloaded a package called lua-gd-2.0.33r2-win32 at one of the Lua-GD download pages, and extracted it.
  2. I copied gd.dll to where my emulator .exe was located.
  3. I copied freetype6.dll, jpeg62.dll, libgd2.dll, libiconv2.dll, libpng13.dll, xpm4.dll, and zlib1.dll to C:\WINDOWS\system32
  4. I downloaded a package called lua5_1_4_Win32_bin at the Lua Binaries download page, and extracted it.
  5. I copied both lua51.dll and lua5.1.dll to C:\WINDOWS\system32
After that I was able to use gd in any Lua script simply by putting the following code at the top:
require "gd"
Former player
Joined: 2/19/2007
Posts: 424
Location: UK
ICheatAtGolf wrote:
Amaurea, I really wanted to use your animated ghost script for Super Metroid to practice speedrunning against one of my runs. I was able to get the old version to work, but this new version (requiring the Lua GD Library) is beyond my area of knowledge.
It's been a long time since I installed gd for lua, but I think I downloaded lua-gd from http://luaforge.net/frs/download.php/1592/lua-gd-2.0.33r2.tar.gz, compiled it, and installed it in /usr/lib/lua/5.1/gs.so in my area for 32-bit programs. But that was for linux, and you're most likely on windows, so your best bet is probably following Nitsuja's instructions above. If everything should fail, I should note that only the minimap and ghost graphics require gd, and if you turn those two options off, the script will automatically not require gd. If you look at the script, you will see that the top of it is a configuration section. For running in non-gd mode, you should turn off the minimap and ghost_gfx, and turn on ghost hitboxes. But it looks much better with proper graphics, so I hope you get that working.
Player (137)
Joined: 9/18/2007
Posts: 389
Here is another little useful program: it marks all sprites which appear on-screen. This should give quite a good hint for hitboxes and such... and you can see the enemies before they appear!
Player (137)
Joined: 9/18/2007
Posts: 389
I want to create a Lua script which expands the normal screen to 480 x 256 pixels, drawing all the offscreen sprites at the right position. This would bring you such a view as I demonstrate in this Super Mario World Video , but you would see it while playing... I think this would be very useful. I want to do such a thing with Lua, LuaGd (because that's the format delivered by lua.gdscreenshot), and wxLua. I couldn't find a way to use images together with wxLua. Can someone provide a minimal Lua script which opens a (non-modal) dialog, loads an image either from a gdstring or from a png, and displays it somewhere on the dialog? (I tried to use IUP with snes9x 1.43. I'm using 1.43 because the above script doesn't work with the newer versions. It works perfectly with FCEU, but I can't get anything running with snes9x, not even a single line like ' require "iup" ' or ' require "auxlib" '. If you can tell me exactly which files from which source I need, that would be nice.)
Editor, Active player (297)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Mouse input support (as in, synthesize events for the snes's mouse input device). Yes, no? I cannot find any mention of it in the documentation. I am thinking of Mario Paint. It's been four years since this topic was brought up. Has there been any progress?
Emulator Coder, Skilled player (1310)
Joined: 12/21/2004
Posts: 2687
Bisqwit wrote:
Mouse input support (as in, synthesize events for the snes's mouse input device). Yes, no? I cannot find any mention of it in the documentation. I am thinking of Mario Paint. It's been four years since this topic was brought up. Has there been any progress?
Yes. Here's a simple demo script:
assert(joypad.gettype and joypad.gettype(1) == 'mouse', "You must be running Snes9x 1.51 with mouse enabled in port 1.")
while true do

	-- move the mouse in a circle at an arbitrary speed
	local xpos = 128 + 64*math.cos(emu.framecount()*0.125)
	local ypos = 128 + 64*math.sin(emu.framecount()*0.125)
	joypad.set(1,{x=xpos,y=ypos})

	-- hold left click except on every 64th frame
	if AND(63,emu.framecount())~=0 then
		joypad.set(1,{left=true})
	end

	emu.frameadvance()

end
If I leave it running a little while I get this: One important caveat not shown by the above demo: the mouse movement is completely relative, although Snes9x both provides and expects the mouse input position in "unbounded" absolute coordinates. Only the game knows where the cursor is really positioned, so if you want to put it at a certain logical position you'll have to move it relative to the value the game has stored for it but represent it relative to the emulator's coordinates. So, here's an example of how to move the cursor to the middle of the screen in Mario Paint:
	local cur_game_x,cur_game_y = memory.readwordsigned(0x7e04dc), memory.readwordsigned(0x7e04de) -- where the game thinks the cursor is
	local cur_virt_x,cur_virt_y = joypad.get(1).x, joypad.get(1).y -- where the emulator thinks the cursor is
	local new_game_x,new_game_y = 128, 112 -- where we want to put the cursor onscreen (the middle of the screen)
	local new_virt_x,new_virt_y = cur_virt_x+new_game_x-cur_game_x, cur_virt_y+new_game_y-cur_game_y -- final input to emulator
	joypad.set(1,{x=new_virt_x, y=new_virt_y})
Also, although this issue isn't specific to Lua scripting, keep in mind that the game usually imposes some limit on how far the cursor can actually move in a frame (such as at most +/- 128 pixels on each axis per frame, or 0 pixels if the game is busy thinking).
Site Admin, Skilled player (1250)
Joined: 4/17/2010
Posts: 11473
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Can ability to work with palette be added to snes9x? Upthorn made it for gens-rerecording, and it helped personally me with level mapping - we just made a script that changes the canvas color (seen when all layers are disabled). Sprites ripping is also here. But it gives much more abilities, I consider.
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.
Editor, Active player (297)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
nitsuja wrote:
Also, although this issue isn't specific to Lua scripting, keep in mind that the game usually imposes some limit on how far the cursor can actually move in a frame (such as at most +/- 128 pixels on each axis per frame, or 0 pixels if the game is busy thinking).
Thanks Nitsuja. I got it working, though several issues makes it rather difficult, including the fact that the game reacts by several frames delay and outright ignores completely the input at some points...
1 2
7 8 9