OSDN Git Service

added a file which explains something important
[proj16/16.git] / src / vrldbg.c
1 /* VRL run-length debugging tool.\r
2  *\r
3  * For sparky4 / Project 16 and anyone else needing to debug the VRL structure */\r
4 \r
5 #include <stdio.h>\r
6 #include <fcntl.h>\r
7 #include <ctype.h>\r
8 #include <errno.h>\r
9 #include <assert.h>\r
10 #include <stdint.h>\r
11 #include <stdlib.h>\r
12 #include <string.h>\r
13 #include <unistd.h>\r
14 \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
19 \r
20 #ifndef O_BINARY\r
21 #define O_BINARY (0)\r
22 #endif\r
23 \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
28 }\r
29 \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
34     size_t rawlen;\r
35     long l;\r
36     int fd;\r
37 \r
38     if (argc < 2) {\r
39         help();\r
40         return 1;\r
41     }\r
42 \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
47     rawlen = (size_t)l;\r
48 \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
53     close(fd);\r
54     fence = raw + rawlen;\r
55 \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
59 \r
60 #if 0\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
69 };                                                      // =0x10\r
70 #pragma pack(pop)\r
71 #endif\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
79 \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
84      *\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
90         y=0;\r
91 \r
92         if (raw >= fence) {\r
93             printf("* unexpected end of data\n");\r
94             break;\r
95         }\r
96 \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
99         do {\r
100             if (raw >= fence) {\r
101                 printf("* unexpected end of data in column x=%u at y=%u\n",x,y);\r
102                 break;\r
103             }\r
104 \r
105             if (*raw == 0xFF) {/* end of column */\r
106                 raw++;\r
107                 break;\r
108             }\r
109 \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
113                     break;\r
114                 }\r
115 \r
116                 {\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
121 \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
124 \r
125                     y += strip_len + skip_len;\r
126                 }\r
127             }\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
131                     break;\r
132                 }\r
133 \r
134                 {\r
135                     /* <run length> <skip length> [strip of pixels] */\r
136                     unsigned char strip_len = (*raw++);\r
137                     unsigned char skip_len = (*raw++);\r
138 \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
141 \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
144                         break;\r
145                     }\r
146 \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
150                         printf("\n");\r
151                     }\r
152 \r
153                     y += strip_len + skip_len;\r
154                     raw += strip_len;\r
155                 }\r
156             }\r
157         } while(1);\r
158 \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
161     }\r
162 \r
163     if (raw < fence) {\r
164         printf("* warning: %u bytes remain after decoding\n",(unsigned int)(fence-raw));\r
165     }\r
166 \r
167     free(base);\r
168         return 0;\r
169 }\r