1 /* VRL run-length debugging tool.
\r
3 * For sparky4 / Project 16 and anyone else needing to debug the VRL structure */
\r
15 #include "src/lib/doslib/hw/vga/vrl.h"
\r
16 #include "src/lib/doslib/hw/vga/vrs.h"
\r
17 //#include "src/lib/doslib/hw/vga/pcxfmt.h"
\r
18 //#include "src/lib/doslib/hw/vga/comshtps.h"
\r
21 #define O_BINARY (0)
\r
24 static void help() {
\r
25 fprintf(stderr,"VRLDBG (C) 2016 Jonathan Campbell\n");
\r
26 fprintf(stderr,"\n");
\r
27 fprintf(stderr,"vrldbg file\n");
\r
30 int main(int argc,char **argv) {
\r
31 unsigned char *base,*raw,*fence;
\r
32 struct vrl1_vgax_header *hdr;
\r
33 unsigned int x,y,cc;
\r
43 fd = open(argv[1],O_RDONLY|O_BINARY);
\r
44 if (fd < 0) return 1;
\r
45 l = (long)lseek(fd,0,SEEK_END);
\r
46 if (l < 16 || l > VRL_MAX_SIZE) return 1;
\r
49 base = raw = malloc(rawlen);
\r
50 if (raw == NULL) return 1;
\r
51 if (lseek(fd,0,SEEK_SET) != 0) return 1;
\r
52 if (read(fd,raw,rawlen) != rawlen) return 1;
\r
54 fence = raw + rawlen;
\r
56 hdr = (struct vrl1_vgax_header*)raw;
\r
57 if (memcmp(hdr->vrl_sig,"VRL1",4)) return 1;
\r
58 if (memcmp(hdr->fmt_sig,"VGAX",4)) return 1;
\r
61 #pragma pack(push,1)
\r
62 struct vrl1_vgax_header {
\r
63 uint8_t vrl_sig[4]; // +0x00 "VRL1"
\r
64 uint8_t fmt_sig[4]; // +0x04 "VGAX"
\r
65 uint16_t height; // +0x08 Sprite height
\r
66 uint16_t width; // +0x0A Sprite width
\r
67 int16_t hotspot_x; // +0x0C Hotspot offset (X) for programmer's reference
\r
68 int16_t hotspot_y; // +0x0E Hotspot offset (Y) for programmer's reference
\r
72 printf("VRL header:\n");
\r
73 printf(" vrl_sig: \"VRL1\"\n"); // already validated
\r
74 printf(" fmt_sig: \"VGAX\"\n"); // already validated
\r
75 printf(" height: %u pixels\n",hdr->height);
\r
76 printf(" width: %u pixels\n",hdr->width);
\r
77 printf(" hotspot_x: %d pixels\n",hdr->hotspot_x);
\r
78 printf(" hotspot_y: %d pixels\n",hdr->hotspot_y);
\r
80 /* strips are encoded in column order, top to bottom.
\r
81 * each column ends with a special code, which is a cue to begin the next column and decode more.
\r
82 * each strip has a length and a skip count. the skip count is there to allow for sprite
\r
83 * transparency by skipping pixels.
\r
85 * the organization of this format is optimized for display on VGA hardware in "mode x"
\r
86 * unchained 256-color mode (where the planar memory organization of the VGA is exposed) */
\r
87 raw = base + sizeof(*hdr);
\r
88 for (x=0;x < hdr->width;x++) {/* for each column */
\r
89 printf("Begin column x=%u\n",x);
\r
93 printf("* unexpected end of data\n");
\r
97 /* each column is a series of vertical strips with a two byte header, until
\r
98 * the first occurrence where the first byte is 0xFF. */
\r
100 if (raw >= fence) {
\r
101 printf("* unexpected end of data in column x=%u at y=%u\n",x,y);
\r
105 if (*raw == 0xFF) {/* end of column */
\r
110 if (*raw >= 0x80) { /* single-color run */
\r
111 if ((raw+3) > fence) {
\r
112 printf("* unexpected end of data in column x=%u at y=%u with %u byte(s) left\n",x,y,(unsigned int)(fence-raw));
\r
117 /* <run length + 0x80)> <skip length> <color value> */
\r
118 unsigned char strip_len = (*raw++) - 0x80;
\r
119 unsigned char skip_len = (*raw++);
\r
120 unsigned char color = (*raw++);
\r
122 printf(" y=%u. after skip, y=%u. single-color strip length=%u + skip=%u with color=0x%02x\n",
\r
123 y,y+skip_len,strip_len,skip_len,color);
\r
125 y += strip_len + skip_len;
\r
128 else { /* copy strip */
\r
129 if ((raw+2) > fence) {
\r
130 printf("* unexpected end of data in column x=%u at y=%u with %u byte(s) left\n",x,y,(unsigned int)(fence-raw));
\r
135 /* <run length> <skip length> [strip of pixels] */
\r
136 unsigned char strip_len = (*raw++);
\r
137 unsigned char skip_len = (*raw++);
\r
139 printf(" y=%u. after skip, y=%u. strip length=%u + skip=%u\n",
\r
140 y,y+skip_len,strip_len,skip_len);
\r
142 if ((raw+strip_len) > fence) {
\r
143 printf("* unexpected end of data in strip x=%u at y=%u with %u byte(s) left\n",x,y,(unsigned int)(fence-raw));
\r
147 if (strip_len != 0) {
\r
148 printf(" pixels: ");
\r
149 for (cc=0;cc < strip_len;cc++) printf("0x%02x ",raw[cc]);
\r
153 y += strip_len + skip_len;
\r
159 if (y > hdr->height)
\r
160 printf("* warning: y coordinate y=%u overruns height of VRL height=%u\n",(unsigned int)y,(unsigned int)hdr->height);
\r
164 printf("* warning: %u bytes remain after decoding\n",(unsigned int)(fence-raw));
\r