Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
I'll fix this in the next version (EDIT: it's fixed now), but in the meantime you can remap Shift to work around it. In the menu, choose "Input > Configure Game Input...", then click on the row for Shift (it's near the middle of the first page), then click the "Reassign..." button at the bottom-left, and press whatever key you want to use instead of Shift. (Try using a letter key, or a joypad button if you have a pad plugged in.)
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
There's a new version, it's only a small update but it should have less freezing problems with DirectSound (though it's still better in most games to disable it while TASing), and it might sync better and should be able to capture AVIs in Geoffrey the Fly (which wants to run at 47.6 FPS so I still recommend setting 48 or 50 for it). Sync may have changed for some games, mainly MMF games.
It's a known issue that whatever controls the music streaming source position in Geoffrey the Fly and Perfect Cherry Blossom doesn't reset properly when loading a savestate. (Maybe something in bass.dll is hiding from the savestate code, or maybe it's using KUSER_SHARED_DATA directly, or maybe I have a simple bug somewhere.)
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
I think it runs with default settings as long as you choose "Disable DirectSound Creation", which actually does permit sound, it just doesn't play it through your speakers (yet) but it will still let you record sound to AVI. However, this particular game plays its music through low-level MIDI calls that I don't support recording yet, so an AVI would have SFX but not music, which is the main reason this game isn't on the list of supported games.
EDIT: You're describing a different problem than I thought you were. Refreshing works for this game already. This is harder to fix since it has to do with the game unloading or reinitializing something in-between rooms that isn't stored in the savestates, and I'm not sure what it is yet.
Yes, that's a known drawback: savestates are never saved to disk and they become invalid as soon as the game stops running. It's being punted on until later because it's still possible to make TASes without it (actually it's a good idea to watch the run every once in a while to make sure it syncs), and because it's a really difficult problem to solve (there are some doubts about whether it's even possible, but I'll try doing it eventually).
I guess you're using Windows 7? I'm not able to test that OS at the moment and it probably wouldn't be hard to fix this if I could, but it seems like they disabled the ability to force-stop other processes in that OS (i.e. TerminateProcess doesn't work even if the application calling it has permission to use it on the target application). "Stop Running" should work anyway under normal circumstances because it actually asks the game process to kill itself first, but if you hit Stop before the first frame or after the last frame the game renders then it won't get that request either. Note that if you close the Hourglass program, that's guaranteed to always cleanup any game processes it started (even if you force-terminate Hourglass it won't leave anything extra running).
Oh, I didn't know about this. It doesn't sound hard to fix, I probably just have to remove some incorrect hack I made in the input message generation code and I already have some idea of what it is.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
Yes. IWBTG and La-Mulana have variable frame rate, and Ikachan has a modal dialog on startup, and those games work fine. Things done in dialogs or other windows or menus aren't recorded yet, though, so that might be a problem for certain games.
That's probably just a coincidence (that it works like that in this game, I'm not saying it won't be repeatable)... I'll try looking for a sync bug with Geoffrey the Fly. What other options did you set besides the framerate (such as sound or multithreading options)?
Did you revert any save files the game created or changed (everything in the "save" and "replay" directories) before playing it back? I think this is one of those games I was just talking about where you need to do that, at least until this issue is fixed. Also, it's best to start from a clean new game. If you still have problems with it, please send me the movie file and let me know which version of the game it's for.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
I'm not sure why this game would be a priority, but it's not TASable yet. I'd stick with things on this list for now (or at least test it yourself before assuming it will work).
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
Maybe there should there be another forum for TASing discussion about (probably mainly Windows) PC games? Since it doesn't exactly fit in with "DOS Games" or "PCE Games", unless everyone's fine with keeping such discussions in "Other Games".
That's good. I'm a little surprised we got this to work at all, because the 64-bit OS basically adds an extra emulation layer on top of Hourglass and totally changes the system DLLs, and apparently it still manages to sync. (Thanks for all the help with testing stuff, by the way.)
Note that it's best to round up if it's not exactly a whole number. 50 would be reasonable here. I've seen a few games with weird framerates like 37.6 or 47.3 but as far as I can tell that is the correct speed for those games to be running at.
There's some more to be done to make AVI capture work for that game, as well as make it so you can run it without needing to enable fullscreen mode. (Actually I think non-fullscreen works too if you switch your display depth to 8-bit in your advanced display settings.) But yeah, it's mostly there.
One thing I forgot to warn about earlier: Due to this issue, if you're TASing a game that automatically creates a save file, and if the save file contents actually affect sync (in some games it doesn't matter), then you'll have to manually delete the save file before starting playback or recording.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
OK, I'm finally making this public, and I decided to call it Hourglass after all. There's still a lot more work to do, but think of this as a demo for anyone that wants to get a head start on Windows TASing.
http://code.google.com/p/hourglass-win32/
A build is available for download there, as is the current source code. If anyone wants to contribute, let me know and I'll give you commit privileges. I think I said I would wait longer before posting this, but actually I see no reason to do that, since it's not like progress can't continue on it.
For anyone who wants to try actually TASing something with this now/soon:
Let me know if you run into problems. PM me about it, preferably. Same for feature requests, although I'd suggest posting those directly to the googlecode issues page instead. Keep in mind this is in the early stages and that it's an especially unusual environment for making TASes because it's not an emulator. Also keep in mind that things are likely to change, including the movie format.
All of the games on that list should be possible to create TASes of in the program's current state, but not all of them are supported equally well. There are several gotchas to work around. For example, games that use multiple threads have stability problems (the game crashes sometimes after loading a savestate), and as a workaround for this, there are several options for forcing the program to be more single-threaded, such as disabling DirectSound or disabling thread creation. So making a serious TAS would involve disabling that stuff and TASing the game with the sound off, then re-enabling it to check sync and record an AVI with audio.
Also, there's a Frames per Second field you'll have to fill in before starting recording, which depends on the game. In general, if you get this number wrong, the game will either run too slowly, or it will run at the correct speed but with unnecessary "lag frames". I haven't made any sort of database yet of what these should be, but for now: Cave Story and IWBTG are 50 FPS, Hero Core is 40 FPS, Iji is 30 FPS, and almost everything else (including La-Mulana) should be set to 60 FPS.
The game most likely to work with all existing features is Cave Story. It's simply the game that got tested the most and it's probably the most fault-tolerant game of all the ones I've tried running through this.
The target OS for Hourglass is Windows XP. It has been tested somewhat on Windows Vista and Windows 7 64-bit, but it's most likely to work as intended on XP. Theoretically it should also be able to work in Windows 2000 and Wine, but it almost certainly doesn't work in those yet.
By the way, here are some tool-assisted non-speedrun videos (they're not that special and I'm probably playing them all wrong, but I did use some savestates and some frame advance) that I made just now to convince myself a TAS could be made of these games all the way through to an AVI: Perfect Cherry Blossom, Tumiki Fighters, Legend of Princess. And if you missed it earlier, there was also this for Hero Core.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
No, I'm sure that won't work (and that would be slightly cheating anyway).
I think having a lower level does nothing besides decrease your HP and increase your chance to get drops. But since keeping it at level 1 would mean opening the menu every time you level up, and the level probably doesn't make much difference for a TAS (kind of like starting with fewer lives in a run that would have avoided death anyway), maybe it would be better to only reset it to 1 whenever you have to open the menu for other reasons? Then again, there won't be that many levels gained that it would waste a significant amount of time opening menus, so it might be cleaner to just always set it to 1 and claim it as a goal of the run to not fight any battles above level 1.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
One more time... does everyone still like the name "Hourglass"? The main thing I didn't like about that name was how ubiquitous a word it is (hard to search for, and there must be programs already called that). Right now it's still called winTASer, which I don't think is such a bad name really, but I could see it switching to Hourglass, or something else if anyone has any new ideas on the name.
Most likely. At least, a (somewhat old?) demo version I tried worked quite well.
It doesn't yet. That game apparently does all of its drawing by locking the frontbuffer and setting pixels in a palettized display mode, which fails to fit the pattern of other games I'm supporting in at least 3 different ways. I don't think there would be anything truly difficult about adding support for it, though. (Just a little time-consuming.)
It works very similarly to kkapture (except trying to do a lot more than just recording), combined with kind of a debugger for maintaining interactive control over and getting feedback from the game. Movie input is recorded at a fixed framerate that you have to specify before creating the movie, but if you choose a framerate that's higher than the natural speed of the game, "lag frames" will automatically be inserted to compensate, so even games that are supposed to run at weird or variable framerates are supported. Like in re-recording emulators, there is built-in AVI recording, and you could record to AVI while playing the game if you want to but it makes more sense to wait until movie playback to do that. Pause and frame advance are implemented by suspending threads, and controlling timing. Fast-forward is implemented by simply switching off delays while continuing to track them. Savestates are implemented by reading from or writing to all of the game process's writable RAM.
The interface has two parts. The first part is the TASer program, which is basically just a movie play/record dialog with some menu options and the ability to select and launch a game. The second part of the interface is what you actually use to do TASing, which is the game itself after it starts up, i.e. there is no special interface except for the fact that you can press various hotkeys in the game (fast-forward, frame advance, pause/unpause, savestate/loadstate 1-10, and toggle movie read-only). The game is (optionally) forced to run inside a window if it's a fullscreen game, so that you can still see the TASer program in the background, which continues updating its frame count display and stuff while the game is running (and can still be used to configure options or initiate actions such as starting an AVI capture).
The TASer program itself currently looks like this:
The compatibility list I've been neglecting maintaining looks like this right now:
1: Timing
2: Stability
3: Pause and Frame Advance
4: Savestates
5: Playback Sync
6: AVI Video recording
7: AVI Audio capture
1 2 3 4 5 6 7
Cave Story: good good good good good good good !!
La-Mulana: good good good good good good good !!
Ika-Chan: good good good good good good good !!
Eversion: good ok good good good good good !!
Bunny Must Die: good ok good good good good good !!
Streets of Rage Remake: ok good good good good good good !!
MegaMari: ok ok good good good good good !!
Super Marisa Land: ok ok good ok good good good !!
Iji: ok ok good ok good good good !!
Tumiki Fighters: ok ok good ok good ok good !!
Rescue: The Beagles: good good? good good? good good good !!
RotateGear: ok? good? good good good good good !!
Hero Core: ok ok good good good good good !!
Perfect Cherry Blossom: ok? ok? good ok? good? good good !
Rosenkreuzstilette: ok? ok? good ok ok? good good !
Eternal Daughter: ok ok good ok ok? ok BAD
Lyle in Cube Sector: good ok? good ok? ok? NO good?
Within a Deep Forest: ok? ok ok ok BAD? NO good
I Wanna Be The Guy: ok? ok ok good good? NO good
!! == Fully TASable (criteria: everything is "ok" or better, and playback sync must be confirmed "good")
! == Possibly TASable (criteria: everything except stability is "ok" or better)
? == item not fully tested
So, uh, it probably doesn't have very good compatibility compared to regular emulators for other platforms, and there are many games that almost but don't quite work yet so it's tempting to keep expanding the list of compatible games, but I guess I should make an initial release sometime sort-of soon because I'd like to get to the point where somebody else than me would be willing to make contributions to the code.
The main things preventing a release right now are kind of stupid things such as the hotkeys not being configurable yet and the movie file format not storing some things that can affect movie sync and the source code having lots of commented-out temporary testing stuff that should be cleaned up. (That, and some of the recent changes I've made need to be verified on more computers, in case some things need to be reworked to be more compatible.)
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
They didn't, but now Lyle in Cube Sector works.
EDIT: oops, except it's missing video output in AVI capture, shouldn't be hard but I still need to add that.
EDIT2: added, it's fully supported now. The v1.04 version at least, and some other MMF games like IWBTG and Legend of Princess.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
Update: I started working on this again a little. Sorry it's taking so long. I think I've finally solved the Iji desync issues (enemies had different randomness every playback of a movie file, but now it's consistent), so I'm moving on to other things (for example, I added OpenGL support for games like Tumiki Fighters, which is TASable now too).
I just added D3D9 support too, so, yes. The Touhou games I've tried all seem to be pretty TAS-friendly in terms of sync-stability and such.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
If you're only trying to match up hitbox drawing with the game's graphics, then usually you can simply render collision data from 1 or 2 frames in the past.
To get rid of the game's rendering delay in general, I'm not sure if it's possible to do much better than your script without changing the current API. I suspect that the "better way" to do it involves adding some missing functionality to Snes9x. By the way, this is a lot more elegant to do in Gens, so here's an example of that for reference (this eliminates 2 frames of delay, works fine with regular frame advance controls, and doesn't cause graphical or audio weirdness):
local tempsave = savestate.create()
local recursing = false
emu.registerbefore(function()
if recursing then return else recursing = true end
emu.emulateframeinvisible()
savestate.save(tempsave)
emu.emulateframeinvisible()
recursing = false
end)
emu.registerafter(function()
savestate.load(tempsave)
end)
But that script won't work in Snes9x because the following things are missing from Snes9x Lua:
a way to emulate a frame without pausing afterward if the user is using the frame advance hotkey (this one really hurts)
a way to emulate frames within callbacks such as emu.registerbefore (but, workarounds exist)
a way to load a savestate without rendering it (workarounds exist)
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
Awesome. I'm glad this was done "from scratch" instead of reusing input from... 2006. This was impressive and really fun to watch.
Here's another screenshot to consider, it looks pretty dynamic here compared to in the previous run, although maybe the Aquatic Ruin one is better for other reasons.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
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).
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
That was only in the oldest version that supported Lua scripting, because emu.frameadvance hadn't been implemented yet, but it exists now. Although for all I know somebody broke emu.frameadvance in a later version (can somebody explain why the LuaScripting page says it's 'bugged'?).
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
Nice run, many of the levels look so much faster that I'm surprised it's only 1 minute faster in total. The only negatives I can think of aren't your (Ryuto's) fault (some bosses were more boring in order to avoid lag, and the time isn't 13:37 anymore).
Now I wonder when the Super Bomberman 2 TAS (which is even older than what this is obsoleting) will get an update...
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
Now I'm wondering if they fixed it as early as Sonic Rush Adventure...
What about on sloped rails? I suspect they have some totally different programming from regular slopes. Certain rails seem not to allow falling through them either, although even on ones that do, maybe landing near the bottom of a rail and immediately jumping again while holding backwards would give a respectable speedup.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
I think all that matters is that you have a high enough speed (say, 5000+ at the scale shown by the Lua script). But, landing on a slope itself gives you a pretty big speed boost for 1 frame (which you can keep for longer if you jump on that frame), and that boost tends to be the most practical way of getting enough speed to perform the trick. Although in Sonic Colors, so far I've only seen that 1 frame boost happen on rails.
Try this (in DeSmuME 0.9.7, with advanced bus timing enabled, sonic rush (U)).
Frame numbers where interesting things happen:
1025, 3537, 3815, 4557 (landing on a slope as described)
3592 (shows that landing with high speed works as well as with high xvel)
3619 (speed and velocity magically becomes negative)
4118 (going fast enough to get a boost from running down a curve and jumping)
4149 (boost from a sloped rail)
It's probably a lot harder to do this stuff in Sonic Colors because they removed airdash-boosting and might have added more speed caps and fixed various bugs, but maybe there are some situations where it's possible anyway.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
You can also go into a roll while holding backward, then after the roll starts you can hold forward to cut down on the speed loss even more. It's more effective than sliding, at least in some cases.
I've used it a bit in Sonic Rush, although going at 8 times max ground speed is typical so I can only touch the ground for a few frames at a time anyway and it doesn't make much of a difference whether I roll or skid. Speaking of which, in case they didn't fix that bug, be on the lookout for any instances where you can land on a flat shallow downhill slope while you have a very high x velocity (the higher the better, but slightly below max ground speed is the minimum). In Sonic Rush, those are the conditions where jumping gives you an uncapped speed boost and causes you to immediately land again.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
By the way, the sound and music in this game isn't quite this bad, that's the emulator having problems (notes playing double or cutting off early, car collision effects repeating endlessly)... If you try the game in Snes9x 1.52 those problems go away.
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
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:
Emulator Coder, Experienced Forum User, Published Author, Skilled player
(1301)
Joined: 12/21/2004
Posts: 2687
DeSmuME 0.9.7 introduced a bug in Lua that basically makes all the GUI drawing functions read color values incorrectly, which breaks the script I posted earlier. So I updated the script to work around the problem. You can either redownload it from the link in my earlier post, or add this to the top or bottom of the previous version of the script:
-- hack fix for new bug in desmume 0.9.7 with integers > 0x7FFFFFFF getting mangled when read in by the emulator
local function fixcolor(c) return type(c)=='number' and OR(c,0) or c end
local origdrawtext,origdrawline,origdrawbox = gui.text,gui.drawline,gui.drawbox
gui.text = function(x,y,s,c1,c2) return origdrawtext(x,y,s,fixcolor(c1),fixcolor(c2)) end
gui.drawline = function(x1,y1,x2,y2,c1,s) return origdrawline(x1,y1,x2,y2,fixcolor(c1),s) end
gui.drawbox = function(x1,y1,x2,y2,c1,c2) return origdrawbox(x1,y1,x2,y2,fixcolor(c1),fixcolor(c2)) end