First byte: tag for "Set position" instruction (default row 0, col 0)
Second byte: tag for run length instruction
Then comes image data, in 4 pixel (== 1 byte in multi-color mode) columns, wrapping around at the end of the column to the beginning of the next column. However, this in interlaced mode: The bytes map to every other line of the screen, at the end of the drawing area they wrap around to the second row. This can be changed with the set position tag. If that byte occurs, the next two bytes specify the row/col to continue drawing.
If a run length instruction byte occurs, the next byte says how often the byte after that one should be repeated (plus three more times).
Example program follows.
Code: Select all
#include <stdlib.h>
#include <stdio.h>
char *pixel[] = { " ", "..", "--", "[]" };
#define ROWS 128
#define COLS 160
unsigned char screen[ROWS][COLS];
static int len;
unsigned char
safe_getchar ()
{
int chr = getchar();
if (chr == EOF)
{
fprintf (stderr, "premature EOF");
exit (1);
}
len++;
return (unsigned char) chr;
}
void
decode ()
{
int row = 0;
int col = 0;
int val = 0;
int run = 0;
unsigned char tag_next_run;
unsigned char tag_next_pos;
tag_next_run = safe_getchar();
tag_next_pos = safe_getchar();
row = 0;
col = 0;
do
{
if (run == 0)
{
unsigned char chr = safe_getchar();
if (chr == tag_next_run)
{
run = safe_getchar() + 3;
val = safe_getchar();
continue;
}
else if (chr == tag_next_pos)
{
row = safe_getchar();
col = safe_getchar();
if (col == 0xff)
return;
continue;
}
else
val = chr;
}
else
run--;
screen[row][col / 4] = val;
/* Interlaced */
row += 2;
if (row >= ROWS)
{
row -= ROWS;
col += 4;
if (col >= COLS)
{
row++;
if (row >= 2)
return;
col = 0;
}
}
}
while (1);
}
int
main (int argc, char*argv[])
{
int r;
int c;
int val;
decode ();
printf ("Length: 0x%04x\n", len);
for (r = 0; r < ROWS; r++)
{
for (c = 0; c < COLS/4; c++)
{
val = screen[r][c];
printf ("%s%s%s%s", pixel[(val >> 6) & 3], pixel[(val >> 4) & 3], pixel[(val >> 2)&3], pixel[val&3]);
}
printf ("\n");
}
return 0;
}