Demo recording/playback for debugging purposes (Ep 1-3)

Completed patches for Keen1.
Post Reply
NY00123
Posts: 85
Joined: Thu Sep 24, 2009 8:03 am

Demo recording/playback for debugging purposes (Ep 1-3)

Post by NY00123 »

UPDATE (Dec 24th, 2016): Edited download link since Dropbox' "Public" folder is expected to become private by March 2017.

Hey all,

There is a patch I have added to the KeenWiki today that takes advantage of unused code found in the Keen executables for recording and playing back demos. Note that the demo files are much larger than what you get for Keen 4-6, but I stayed with what was experimented with back then (as observed by the unused code).

Further note that the patch overrides the function letting you load a saved game. In fact, from the main menu you may record a demo, rather than load a saved. To watch recorded demos, simply hide the menu while still having the title in the background.

I know this may seem to make the patch useless. But, I still have found a way to take advantage of it... Furthermore, some code reshuffling may probably let you support demo playback and saved game loading altogether (possibly with the cost of losing some other feature).

Patch page on the KeenWiki: http://www.shikadi.net/keenwiki/Patch:Demo

Link to an archive containing the patches, along with ASM sources and sample demo files: https://www.dropbox.com/s/3fl8ah3khjg39 ... 8.zip?dl=0
Last edited by NY00123 on Sat Dec 24, 2016 8:54 am, edited 4 times in total.
levellass
Posts: 3001
Joined: Wed Oct 11, 2006 12:03 pm
Location: Ngaruawahia New Zealand

Post by levellass »

So why does it disable the continue game code? Is there a lack of space in the menu or does the code overwriting wipe out the continue game code?
NY00123
Posts: 85
Joined: Thu Sep 24, 2009 8:03 am

Post by NY00123 »

Well, it basically goes like this:
- The menu loop code is modified so, after displaying the title (without the menu) for not much more than a second it goes to demo playback loop. Basically, for Keen 1 it loads and plays back DEMO0.CK1 if the file is found, then repeats this with DEMO1.CK1 and so on, up to DEMO9.CK1. If a file is not found then it is simply skipped. Furthermore, once it's done with DEMO9.CK1, the loop restarts. Finally, the user can halt demo playback by pressing on the 'ESC' key and then on any of the 'T' and 'D' keys, the same way it's done in an actual game.
- Some of the continue_game code is overwritten with demo recording functionality.
- Finally, a different portion of the continue_game code is overwritten with a couple of functions used for recording and playback altogether. Each of these functions resets some things. The first does so *before* demo recording/playback, resetting a few things that usually the worldmap loop resets when started (like the player's score). It also resets the player's position to (0,0), a workaround done to counter a vanilla Keen bug*. The second does the same *after* demo recording/playback, resetting stuff that generally the menu loop function resets when it is called (such as the amount of gun shots).
- It worths to note that some things, like cheat codes, may still be (de)activated during demo recording/playback.

Again, yeah, this patch may seem useless due to the absence of continue_game with no modification applied, but I have my own reason for this kind of implementation, which (assuming things go as planned) is going to be revealed soon.

* Vanilla Keen bug description: When an actual level map (not the world map) is loaded, a loop goes over the map checking for sprites. For some sprites the player's location is queried, usually to determine if a creature should initially walk to the left or to the right. Problem is that the player may have not yet been found on the map...
So, what happens? Well, usually, when something goes wrong, the player's location *on the world map* is queried. One may see the problem such a thing can have on the ability to record/playback demos, independently of any world map. So, as a workaround the player's location is initially set to a pair of zeros before demo recording/playback begins.
levellass
Posts: 3001
Joined: Wed Oct 11, 2006 12:03 pm
Location: Ngaruawahia New Zealand

Post by levellass »

Interesting. Well with the tile space patch I'm sure there would be enough space to have both demo and continue game.

Also, are the patches in the archive you linked complete for Keen2 and 3 or are modifications require to integrate them?
NY00123
Posts: 85
Joined: Thu Sep 24, 2009 8:03 am

Post by NY00123 »

Yeah, the patches for all episodes (as given in the .PAT files) should be complete. The ASM files are what I've used for some portions of code, to be compiled to binary files with NASM and then patched either:
- using %patchfile (which luckily works since there is no relative address to fix),
- or by converting the binary contents to textual hex values understood by CKPATCH, when used with %patch. (That has been done for having self-contained patches on the KeenWiki.)
levellass
Posts: 3001
Joined: Wed Oct 11, 2006 12:03 pm
Location: Ngaruawahia New Zealand

Post by levellass »

Cool. I may have to tweak that entry to allow people to see both the archive you linked and the self contained patches.
User avatar
ckguy
Posts: 465
Joined: Tue Oct 14, 2003 11:20 am
Location: Wakefield, RI, US
Contact:

Post by ckguy »

Cool!

Is the reason that the files are bigger for these demos than in Galaxy that all of the enemies' movements need to be stored? I recall that in Galaxy in demo recording mode, only Keen's movements are stored, and all the other sprites go into a special 'no-randomness' mode so the demos are reproducible.
NY00123
Posts: 85
Joined: Thu Sep 24, 2009 8:03 am

Post by NY00123 »

ckguy wrote:Cool!

Is the reason that the files are bigger for these demos than in Galaxy that all of the enemies' movements need to be stored? I recall that in Galaxy in demo recording mode, only Keen's movements are stored, and all the other sprites go into a special 'no-randomness' mode so the demos are reproducible.
Thanks!

Actually, all that is stored in the Vorticons demo files is the game-related input, although in a way which does take much more space than similar Galaxy demo files.

Basically, there is this function that I refer to by the name of "handle_ctrl", which returns a struct telling:
- Keen's direction of movement on the worldmap or in an ordinary level (if any).
- If the jump key/button is pressed.
- If the pogo key/button is pressed.

In practice, this function is also called from the menu code and more places, but you get the idea.

If I haven't missed anything, then while an actual level playback is in session, one call to handle_ctrl is done per "level loop iteration" (corresponding to a new frame displayed on screen). There are approximately 24.26666 such iterations per second.

While demo recording is in session, the value to be returned by a call to handle_ctrl is packed into a single byte and added to a temporarily buffer. Eventually the buffer's contents are saved to the demo file. Note that the very first byte of the demo file tells the level number.
For demo playback, the file is simply loaded to the same buffer and handle_ctrl acts differently, retrieving an action from the buffer rather than actual input devices.
Post Reply