The XDC encoder uses input scripts to create video files. These scripts contain some mandatory directives such as the framerate of the input and where the audio file is, as well as the list of frame files that make up the video. Here’s an example of what a script looks like:
# sample TRON sequence screenmode=1 sourcefps=23.976 waveinput=d:\xdc\sources\tron\tron.wav d:\xdc\sources\tron\tr_00000.bmp d:\xdc\sources\tron\tr_00001.bmp d:\xdc\sources\tron\tr_00002.bmp d:\xdc\sources\tron\tr_00003.bmp d:\xdc\sources\tron\tr_00004.bmp d:\xdc\sources\tron\tr_00005.bmp d:\xdc\sources\tron\tr_00006.bmp # ...etc.
- Starts with a comment
- Defines the CGA screen mode this video is formatted for
- Defines the framerate of the source video
- Defines the location of the audio file for this video
- Ends with the complete list of video frames to include, in order
Other directives can be added (full list below), and you can also insert directives at multiple points in the script which is useful for handling multiple sections of the video differently.
When creating a script, it’s best to get the list of frames in the script first, then add directives at the top of the script later. Putting a list of all frames into a script is usually easy:
DOS or Windows: dir /b *.bmp > tron.scr UNIX: ls *.bmp > tron.scr
This dumps a bare listing of filenames only into “tron.scr”. As long as the script is in the same directory as the bitmap files, this works fine; or, you can perform search-and-replace with a text editor to put the full path back into every line as shown in the example script above.
As of this writing, the encoder implementation is in 16-bit DOS, so all filenames must adhere to 8.3 standards. See FAQs for background on why this is.
These directives must be in every script, included before the frame list:
- SCREENMODE: The screen mode to encode for. Values are 1 for CGA composite color output, 2 for 640×200 B&W mode, and 3 for Tandy 160×200 mode. Example: “screenmode=1”.
- SOURCEFPS: The original source framerate of the video. Values can be integer or floating point. This directive must be first in the script, as subsequent directives use values derived from it. Examples: “sourcefps=29.97”, “sourcefps=24”, etc.
- WAVEINPUT: Points to an 8-bit PCM (uncompressed) mono .wav file containing audio for the video.
It is also probably a good idea to specify these first three directives in this order.
The XDC encoder has default values that stress image quality over size, which means it can create extremely large files if the picture content is constantly changing at high framerates. Use of additional directives to control this is highly encouraged; at a bare minimum, you should know your target’s I/O maximum transfer rate and use MAXDISKRATE to set it, to ensure you’re not creating files that you can’t play without stuttering, or files that are so big they don’t fit on your hard disk.
- MAXDISKRATE: Specifies the maximum bitrate in KB. This is useful for ensuring your video will not exceed the capability of your disk subsystem. Possible values can be something like 150 for a 1X CDROM, 90 for an MFM drive, 160 for an XTIDE adapter, etc. Example: “maxdiskrate=150”.
- FRAMEINTEGRITY: Specifies the percentage of how much changed data is encoded before XDC considers the frame “done” and loads a new frame. Value is an integer anywhere from 0 to 100. A value of 0 will preserve motion at the expense of picture detail, and 100 will preserve picture detail at the expense of motion. Default value is 75, which works well for most sources and doesn’t have to be changed unless you’re unhappy with the resulting picture quality.
- SHAVEPIXELS: If enabled, single-pixel changes are discarded. This can lower the size of the video and stabilize areas of the picture, but can also create onscreen “trails” as moving picture areas are not erased correctly. To deal with “trails”, a full keyframe is encoded once every second. Values are ON or OFF; default is OFF.
- SHAVEDELTAS: Similar to SHAVEPIXELS, but stronger. If enabled, two-byte changes or smaller are discarded. Values are ON or OFF; default is OFF.
- CHEATING: If enabled, will encode every other line as blank. This reduces horizontal resolution and overall “dims” the resulting picture, but gives the encoder more bits to work with. Values are ON or OFF; default is OFF.
- DEBUG: Sets the level of output in the log file produced by the encoder. Default is 1; can be set from 0 to 3 where higher values increase verbosity.
- OVERRIDEBYTEPOOL: Forces the number of opcode bytes to be used to encode each video frame. For debugging purposes only. Values can range from 32 to 10000.
- OVERRIDECYCLES: Increases the number of available playback cycles to the full maximum available in a single CGA screen refresh. For debugging purposes only, as misuse of this will create videos that have stuttering playback. Only allowable value is “MAX” (ie. “overridecycles=max”).
- COMBINEDELTAS: Can be used to turn off one of the encoder optimization phases, which will generally result in a 20% encoding speedup at the expense of 20% larger/less efficient files. Values are ON or OFF.
- PAUSE: Will pause the encoder at that line in the script and wait for the user to hit a key to continue.
If you feed XDC source material where every single area of the screen is changing (ie. an action movie, a panning camera, etc.), you may find that the encoder has to drop frames to make everything fit within available bandwidth. The obvious fix is to increase the bandwidth you’re willing to give the encoder by increasing your MAXDISKRATE value. If you can’t do this (ie. it would exceed the capabilities of your transport medium), then try turning on SHAVEPIXELS to reduce encoder workload. If that doesn’t help, you can step it up by turning on SHAVEDELTAS. If the end result still doesn’t look good (ie. framerate is too slow, or the video is “smeary”), then use 160×100 input files or turn on CHEATING to cut the data you’re giving to the encoder in half.
If the resulting video looks mostly ok but has too many motion artifacts (ie. you see “smearing” or “trails” in the encoded video), set FRAMEINTEGRITY to 100. This will lower the effective framerate, but each frame that does display will display completely. Conversely, if you want to preserve motion and don’t care how much it smears, set FRAMEINTEGRITY to 0.
Color movies that play off of a 1X CDROM (this requires the movie to be broken up into parts no longer than 40 minutes each, due to the 65535-frame limit of XDV files, and also to fit two parts nicely onto a single 700MB/80-minute CDROM):
screenmode=1 sourcefps=23.976 maxdiskrate=150 frameintegrity=67
Stupid encoder tricks
If you omit the WAVEINPUT= line in the script, the encoder will not create a video file, but rather dump each encoded frame to an individual file with an extension of .xdc. This is useful for examining the code produced for a specific frame, ie.:
D:\AC\RAWFRAME\BA>debug ba3317.xdc -u 0856:0100 1E PUSH DS 0856:0101 0E PUSH CS 0856:0102 1F POP DS 0856:0103 BE6909 MOV SI,0969 0856:0106 B800B8 MOV AX,B800 0856:0109 8EC0 MOV ES,AX 0856:010B B500 MOV CH,00 0856:010D FC CLD 0856:010E BF631A MOV DI,1A63 0856:0111 B130 MOV CL,30 0856:0113 B0FF MOV AL,FF 0856:0115 F3 REPZ 0856:0116 AA STOSB 0856:0117 BFB31A MOV DI,1AB3 0856:011A B130 MOV CL,30 0856:011C F3 REPZ 0856:011D AA STOSB
Another use for this is displaying full-screen pictures in your own programming projects: Just set the video mode, preserve any registers you need preserved, then CALL the XDC encoder output data. (To ensure one single frame gets completely created for use this way, set frameintegrity=100 and overridebytepool=10000.)