TASVideos

Tool-assisted console game movies
When human skills are just not enough

Hex Editing

Hex editing is a method of editing binary files (files that are not plain text, such as executable files, or image files). In this case, you want to hex edit movie input files so that input from one source is written to part of another.

What to know before using hex editing

  • Always make backups before hex editing a file. Correct results are not guaranteed.

  • Do not rely on hex editing to save you, ever.

  • If you make a mistake some time ago when TASing, fix it right away (if you can with reasonable effort). Never assume hex editing will fix it later.

When to use hex editing

  • Hex editing can be used to copy input (say from a previous TAS) into your TAS. Hex editing does not ensure that the newly modified movie plays as intended; it may or may not.

  • Hex editing can also be used to try to correct desyncs by adding or deleting inputs from the movie input file. This is time-consuming unfortunately.

  • Hex editing can even be used to insert repetitive input, although if an emulator supports it, Lua scripting is better used for this task.

  • Do not use hex editing if there is no hope that a newly modified movie plays back correctly or can be fixed without too much effort. This applies especially to games with a high degree of randomness.

Hex-editing programs

There are a number of hex-editing programs you can use. Xvi32 is recommended.

How to read bytes

Bytes are always displayed as a two-digit hexadecimal number. Hexadecimal numbers, unlike the more familiar decimal numbers, have digits that take one of 16 values: 0, 1, ..., 9, 10=A, 11=B, 12=C, 13=D, 14=E, 15=F. For example, DF in hexadecimal is 223 in decimal (DF means 13 * 16 + 15 = 223).

Numbers that require two or more bytes to store are typically stored in little-endian format. That is, the byte order is reversed when viewed in a hex editor. For example, the byte sequence 00 AB CD 12 represents the hex number 12CDAB00 (if it represents a number at all). Big-endian formats (the opposite) are used occasionally in other systems. In all movie formats, little-endian is used.

How movie formats are structured

Most movie formats begin with a header that contains a pointer to the controller data (the input). The pointer is simply a number that tells us where the input begins. For example, if the pointer contains the value 0x100 (0x means hexadecimal), the input begins on byte 0x100.

Input is usually given as a fixed number of bytes per frame. How many bytes this is depends on the emulated system, number of used ports, and emulated peripherals. For example, the number of bytes per frame for 2-player movies is twice that of 1-player movies, while an analog PSX joypad uses more bytes per frame than a standard (non-analog) one.

Some movie formats are plaintext. For all intents and purposes, they still have a fixed number of bytes per frame, although any text editor with a line number function is better suited to editing such files than a hex editor.

Rarely, some movie formats use compressed data. This is difficult to hex-edit correctly.

Mupen64 also ignores lagged frames, so the input data does not correspond exactly to each frame.

In FBA, the meaning of inputs depends on the game.

This article will assume you are hex editing in a non-plaintext movie format with a fixed number of bytes per frame.

Editing a movie

Before editing a movie, always back up the file.

For these steps, a calculator that can convert hexadecimal to decimal and vice versa may be required. A notepad is recommended, so you don't have to remember all the frame numbers.

First, find the location where the pointer points to:

Emulator Address of pointer
Snes9x 0x1C
Dega 0x18
Gens None, data begins at 0x40
VBA 0x3C
PCSX 0x2C
Mednafen None, data begins at 0x100

Let's call the value where this pointer points to as P. For Gens and Mednafen, let P=0x40 and 0x100, respectively. Let F be the frame number of the movie, and S the number of bytes per frame. Then the offset of the input corresponding to that frame starts at P + F*S. To go to that offset, using your hex editor's goto function is recommended.

Especially important to note is that the first frame is frame 0, and input displayed applies to the previous frame, so if, for example, the emulator says it is on frame 123, it is actually waiting for that frame, and the input shown is for frame 122.

It is recommended to check and see if the input you see corresponds to what it should be. It is also recommended to place a marker of some kind (while TASing in the emulator), such as a little-used input (select, for example), so it is easier to verify and hex-edit.

Changing the input

To change the input, simply find it and change it according to the appropriate movie format. When inserting or deleting bytes, use the hex editor's insert mode. When replacing, use overwrite mode.

Importing data from another movie.

Do these steps and find the data chunk which you wish to copy. Copy the data and switch to the movie in which you want to insert the data. Find the place where you want to insert it and paste it in. Do an "insert paste" rather than an "overwrite paste" since the editor cannot overwrite if the remaining data is too short.

Finally, remember to change the length in frames of the movie. If in doubt, make it well long. You will change this to its proper length when using the emulator anyway.

Emulator Address of movie length
Snes9x 0x10
Dega 0x08
Gens None, automatically calculated
VBA 0x0C
PCSX 0x10
Mednafen None

Verifying if the movie works

Now just play the movie in the emulator to see if the change worked. If it didn't work, stop the movie and either try hex-editing again or give up.

Keep the hex-editing work open until you are done.

Always recreate savestates that occur past where you edited the movie (if you are still using them), or you risk either having a desync later on, or erasing your changes (and possibly not knowing about it).

Case Study: SNES Mega Man X: Eliminating a missed shot

At or near frame 58090, DeHackEd discovered a missed shot while climbing the last segment of Boomer Kuwanger's stage. The targeted enemy was destroyed in 3 hits, but 4 shots were fired. Having already done a boss battle and started on the next level, DeHackEd did not want to rerecord over his work to fix it, but the stray shot still had to be eliminated.

The first step is to find where the shot is stored. Here is the header for the SMV. It is the same as the one in the SMV format section.

    53 4D 56 1A  01 00 00 00  77 77 77 77  69 29 00 00
    2B B0 01 00  01 01 00 00  20 00 00 00  C3 00 00 00
    1F 8B 08 00  00 00 00 00  00 03 ED C1  31 01 00 00
The controller offset is 0xC3 (195 bytes). The frame number is near 58090 and there are 2 bytes per frame, so our starting point will be 195 + 2*58090 = 116375 (0x1C697). Here is some of the file's contents around that area as viewed from a hex editor.

  (Hex position) (bytes)
  0001C670       81 80 81 80  81 80 81 80  81 80 81 80  81 80 81 80
  0001C680       81 00 81 00  81 30 81 00  C1 00 81 00  C1 00 81 00
  0001C690       C1 00 81 00  41 c0 81 80  81 80 81 80  81 80 81 80
  0001C6A0       81 80 80 80  81 80 82 80  82 80 82 80  82 80 82 80
Remember that each line is an even number of bytes, but our starting offset is an odd number. The portion in bold is found to be our 7 frames consisting of shooting. This is because firing is by having one frame pressing Fire (Y), one frame without, one frame with Fire held, and so on. The code for Y is 00 40 which shows up in alternating frames in the bolded section.

We now have our choice of which frame we want to eliminate. For simplicity, DeHackEd eliminated the last one. Thus the movie's line

  0001C690       C1 00 81 00  41 c0 81 80  81 80 81 80  81 80 81 80
becomes
  0001C690       C1 00 81 00  01 c0 81 80  81 80 81 80  81 80 81 80
After watching the movie again to ensure the shot was eliminated and there were no desyncs (there were not), recording resumed.

RSS
HexEditing last edited by sgrunt on 2010-03-06 03:08:34
Page info and history | Latest diff | List referrers