Saving Texmaster replays from Linux

Thread in 'Discussion' started by DrPete, 17 Jan 2015.

  1. Here's one I baked earlier (my first and so far only GM :3)
    http://www.petedeas.co.uk/tetris/Texmaster2009_NORMAL_GM_12.45.58.20140918.mp4

    If you're on Linux and you want to dump replays, you will need:
    • Texmaster (I'm using the 64-bit 2009-3, can't vouch for older releases but I assume the process is the same. 32 bit is almost certainly different)
    • gdb
    • ImageMagick
    • ffmpeg
    • a lot of disk space (dumping that one video above required 20GB of space to record the raw frame data to - you can reorder things so it needs less, at the cost of greatly slowing down the recording process)
    <blink><marquee>Disclaimer: The instructions below are for informational use only blah blah no warranty implied, I'm assuming everyone who cares about doing this knows enough gdb to tweak the recipe as needed, or is on irc to bug me about it. If it breaks, you get to keep both halves.</marquee></blink>

    Step 1: Dumping the raw frames

    Edit your texmaster.ini so that it runs in 320x240.

    Run 'gdb Texmaster2009-3'.

    Enter the following into gdb. Change /tmp/frames.raw to whatever file you want to dump the frame data to (this will get very big).

    Code:
    break SDL_UpdateRect
    commands 1
    silent
    set $buf = *((char **)($rdi + 32))
    append memory /tmp/frames.raw $buf $buf+(320*240*4)
    continue
    end
    Now, once you start running, it will start dumping frames to that file at a rate of about 30kb/frame (or ~18MB/s). Type "run" into gdb, switch to the Texmaster window, and start your replay. When it's done, hit Ctrl-C in the gdb window to stop recording and "quit" out. (The first time you try this, you probably want to ctrl-C after a few seconds and do the rest of the steps to make sure the video comes out okay).

    Step 2: Dumping .pngs from the raw frame log

    You can use this command to rip a bunch of frame00001.png (...) files from the dump. This will probably take a while. Anecdotally, the .pngs took about half as much disk space up as the frame log after ripping, so make sure you have at least that much spare.

    Code:
    split -a5 -b$((320*240*4)) -d1 --filter='convert -size 320x240 -depth 8 bgra:- -channel a -fx 255 +channel -define png:color-type=2 $FILE.png' - frame; printf '\007'
    Step 3: Encoding a video

    I'm not an ffmpeg expert, but I used this command:

    Code:
    ffmpeg -report -r 60 -i 'frame%05d.png' -c:v libx264 -r 60 out.mp4
    which will save a 60fps video to out.mp4. That's it; you're done.

    Appendix

    Technical information for those interested:

    $rdi is a pointer to an SDL_Surface (http://sdl.beuc.net/sdl.wiki/SDL_Surface) at the entry point to SDL_UpdateRect. This contains a pointer to the pixel buffer 32 bytes in (amd64), which is what we dereference to get $buf in gdb.

    The raw pixel format is kind of weird: four 8-bit channels; blue, green, red, alpha; where the alpha channel is all zeroes. (We patch this to all 0xff in the ImageMagick convert step because ImageMagick thinks 0 alpha means transparent and will otherwise dump invisible frames.)

    ffmpeg can/will trip over encoding a sequence of .png files if their pixel format changes in between files; unfortunately, ImageMagick sometimes does this (defaults to RGBA, but uses a more optimised format if <=256 colors are needed). That's what the -define png:color-type=2 is for in the convert step; to keep the pixel format consistent.
     
    steadshot, clincher and Qlex like this.
  2. Muf

    Muf

    This format is commonly known as RGBX, where "X" means something like "discard". It's basically just RGB24 aligned to 32 bits for performance reasons. You're "lucky" the alpha channel is zeroes, a lot of the time it will just be uninitialised memory (garbage).
     
    Qlex likes this.

Share This Page