Here's something I have been recently working on.
http://bisqwit.iki.fi/source/animmerger.html
It is based on the code behind the engine described here,
http://tasvideos.org/Bisqwit/Source/TileTracker.html
which is used for:
― Creating animations for RockmanTricks and SuperMarioBrosTricks
― Creating
automatic maps
― Creating
motion trails
― Creating
lemmings!
It reads a number of PNG files, each file corresponding to a single frame of an animation, and tries to align them together in order to form a map.
The map can be formed in a number of different ways, including:
― "Most common pixel", i.e. produce a static picture that represents what most likely is the background picture for the entire scene represented; use this for creating static level layout maps.
― "Average pixel"; i.e. produce a static picture that displays motion trails for everything that moved.
― "Changelog pixel"; i.e. produce an animation corresponding to the entire input. The animation is affixed to the global frame of reference, i.e. the background picture, as opposed to the local frame of reference that is the player character.
― "Loopinglog pixel"; i.e. Lemmings mode; a slight variation of the changelog method.
How to use:
① Produce screenshots, for example pressing F9 every few frames in FCEU while a movie plays. animmerger needs to be able to deduce reliably how to stitch the screenshots together, so the screenshots should be produced intervals such that the relative motion of the background picture between two screenshots is not larger than 16 pixels. At most 4 pixels is preferred. (Ⓔ
② Run animmerger on them. Be sure to set the changelog method (commandline option -pc) for best results. Result: tile-0000.png, tile-0001.png, and so on. (Ⓕ
③ Merge them into a GIF animation.
mogrify -format gif tile-*.png; gifsicle -O2 -o result.gif -l0 -d3 tile-*.gif
Why to use?
― You want automatic level maps
― Animations anchored in the global frame of reference take considerably less disk space as GIF animations and look cooler than animations anchored in the local frame of reference, because there's less stuff that needs to be redrawn every frame. This is beneficial for the GameResources subpages.
Caveats:
― Strictly 2D only (can not do perspective correction)
― Any change of global brightness (such as bomb blasts in Super Metroid) will likely confuse the image aligner (ⒶⒹ
― Any chance of perspective / zooming will definitely confuse the image aligner (Ⓐ
― A screen that is full of moving objects will likely confuse the image aligner, making it unable to figure out what is background and how it has moved. (ⒷⒹⒻ
― Scene transitions, including dedicated status screens will likely confuse the image aligner (Ⓒ(Ⓐ
― Converging scenes temporally apart will most likely not be stitched together properly (as in, if after a level transition you arrive into a place you've been to before, but from a different direction) (Ⓒ(Ⓐ
― If given a GIF file, only reads the first frame. You can extract the GIF file into individual frames using gifsicle, but when recombining the frames, you must manually indicate the frame delays. (ⒶⒺ
― Parallax scrolling undermines the benefits of global frame of reference. To make maps / animations of SNES games, you must first disable parallax animation. This is best done by hacking the emulator to force the scrolling offsets of all background layers to be the same. Doing so left for exercise.
Workarounds for the caveats and other notes:
Ⓐ) If you are a programmer, consider contributing code in animmerger and making it better. Begin by cloning
git://bisqwit.iki.fi/animmerger.git
Ⓑ) Consider hacking the ROM to disable animation of background objects.
Ⓒ) Could possibly overcome this by ignoring frames that trigger scene shift alerts, and by processing them after everything else.
Ⓓ) In the past, TILE_Tracker was patched directly to the emulator and read the scrolling offsets directly from the PPU, solving the problem. Now, when it has to rely on image content exclusively, the situation is different.
Ⓔ) You can produce screenshots also by extracting individual frames from an existing GIF animation:
gifsicle -U -E animation.gif
Ⓕ) Heads-up-displays (scores, life meters, etc.) are usually anchored to the local frame of reference. When the animation becomes of global frame of reference, suddenly you find that HUDs are annoyingly travelling around, following the player character's movements. It makes sense to hide them. Study the
--mask option of animmerger to remove them from contributing to the animation. Or hack the ROM / emulator to do so for you.
-----------
EDIT: More lemmings! I added example images on the webpage.