1 /* Figures out minimum jump height to clear the various rocks for various
2  * pixel offsets.
3  */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9 
10 /*
11  *          BUGGY GRAPHIC:
12  *
13  *       0123456789ABCDEFGHIJ
14  *    -8    ##   ====        8-
15  *    -7    ## ==            7-
16  *    -6    ##===            6-
17  *    -5   ==============    5-
18  *    -4 =============###### 4-
19  *    -3 ===##==##==##===    3-
20  *    -2   =##==##==##=      2-
21  *    -1    ##  ##  ##       1-
22  *     0                     0
23  *       0123456789ABCDEFGHI
24  *
25  */
26 
27 
28 /*
29  *
30  *     How do we define offsets relative to the buggy?
31  *
32  *     card_x0 = (buggy_x >> 3) - 1
33  *     card_x1 = card_x0 + 1;
34  *     card_x2 = card_x0 + 2;
35  *     card_x3 = card_x0 + 3;
36  *
37  *     ofs0    =  8 - (buggy_x & 7) - (ground & 7);
38  *     ofs1    = 16 - (buggy_x & 7) - (ground & 7);
39  *     ofs2    = 24 - (buggy_x & 7) - (ground & 7);
40  *     ofs3    = 32 - (buggy_x & 7) - (ground & 7);
41  *
42  */
43 
44        /*  n  o  y  x */
45 char card[12][8][8][8];
46 
parse_rockcrat(void)47 void parse_rockcrat(void)
48 {
49     FILE *f;
50     int n, o, y, x, b;
51     char buf[256], *s;
52 
53     f = fopen("rockcrat.asm", "r");
54     if (!f) { perror("fopen(rockcrat.asm)"); exit(1); }
55 
56     n = 0;
57     o = 0;
58     y = 0;
59     while (fgets(buf, 256, f) != NULL)
60     {
61         if (NULL != (s = strstr(buf, "DECLE   $")))
62         {
63             sscanf(s + 9, "%x", &b);
64             for(x = 0; x < 8; x++)
65                 card[n][o][y][x] = 1 & (b >> (7 - x));
66 
67             y++;
68 
69             for(x = 0; x < 8; x++)
70                 card[n][o][y][x] = 1 & (b >> (15 - x));
71 
72             y++;
73         }
74 
75         if (y == 8)
76         {
77             y = 0;
78 
79             n++;
80             if (n == 12)
81             {
82                 n = 0;
83                 o++;
84             }
85         }
86 
87         if (o > 7)
88             break;
89     }
90 
91 #ifdef DEBUG_PRC
92     for (n = 0; n < 7; n++)
93     {
94         printf("Card #%d\n", n);
95         for (y = 0; y < 8; y++)
96         {
97             for (o = 0; o < 8; o++)
98             {
99                 for (x = 0; x < 8; x++)
100                     putchar(card[n][o][y][x] ? '#' : '.');
101                 putchar(' ');
102             }
103             putchar('\n');
104         }
105         putchar('\n');
106     }
107 #endif
108 
109     fclose(f);
110 }
111 
112         /*n  o  y   x */
113 char rock[5][8][8][32];
114 
assemble_rocks()115 void assemble_rocks()
116 {
117     int x, y, n, nn, xx, o;
118     int xofs[12] = { 0, 8, 0, 8, 0, 8, 16, 0, 8, 0, 8, 16 };
119     int newn[12] = { 0, 0, 1, 1, 2, 2, 2,  3, 3, 4, 4, 4  };
120 
121     memset((void *)rock, 0, sizeof(rock));
122 
123     for (n = 0; n < 12; n++)
124     {
125         nn = newn[n];
126         for (o = 0; o < 7; o++)
127             for (y = 0; y < 8; y++)
128                 for (x = 0; x < 8; x++)
129                 {
130                     xx = xofs[n] + x;
131                     rock[nn][o][y][xx] = card[n][o][y][x];
132                 }
133     }
134 
135 #ifdef DEBUG_ARK
136     for (n = 0; n < 3; n++)
137     {
138         printf("Rock #%d\n", n);
139         for (y = 0; y < 8; y++)
140         {
141             for (x = 0; x < 32; x++)
142                 putchar(rock[n][0][y][x] ? '#' : '.');
143             putchar('\n');
144         }
145         putchar('\n');
146     }
147 #endif
148 }
149 
150 
151 /*
152  * Now convolve the buggy with the rocks to figure out the minimum height
153  * of the buggy relative to each of the three rocks for all 32 possible
154  * relative offsets.
155  *
156  * Offset analysis:
157  *
158  *
159  *                      ##   ====
160  *                      ## ==
161  *                      ##===
162  *                     ==============
163  *                   =============######
164  *                   ===##==##==##===
165  *                     =##==##==##=
166  *                      ##  ##  ##
167  *
168  *   000000000011111111112222222222233333
169  *   012345678901234567890123456789012345
170  *   |###############                   |###############
171  *   |###############                   |###############
172  *   |###############                   |###############
173  *
174  * Notice that there are 34 offsets (1 through 24) that cause at least 1
175  * column of a 16-pixel rock to overlap with our 19-pixel buggy.  Icky.
176  *
177  *                      ##   ====
178  *                      ## ==
179  *                      ##===
180  *                     ==============
181  *                   =============######
182  *                   ===##==##==##===
183  *                     =##==##==##=
184  *                      ##  ##  ##
185  *
186  *           0000000000111111111122222222
187  *           0123456789012345678901234567
188  *           |#######                   |#######
189  *           |#######                   |#######
190  *           |#######                   |#######
191  *
192  * For 8-pixel rocks, it's not so bad.  We only have 26 offsets we overlap
193  * by.
194  *
195  * ASIDE:  You know what, I don't really need the 8 different offset pictures
196  * to do this calculation.  :-)  I do all the calculation for offset 0,
197  * and then in the game, I'll subtract the actual offset from the buggy's
198  * X position.
199  */
200 
get_pixel(int n,int x,int y)201 int get_pixel(int n, int x, int y)
202 {
203     int mx = n == 2 ? 24 : 16;
204 
205     if (x < 0 || x >= mx) return 0;
206     if (y < 0 || y >= 8)  return 0;
207     return rock[n][0][y][x];
208 }
209 
210 /*           | | | |#|#| | | |=|=|=|=| | | | | | | |
211  *           | | | |#|#| |=|=| | | | | | | | | | | |
212  *           | | | |#|#|=|=|=| | | | | | | | | | | |
213  *           | | |=|=|=|=|=|=|=|=|=|=|=|=|=|=| | | |
214  *           |=|=|=|=|=|=|=|=|=|=|=|=|=|#|#|#|#|#|#|
215  *           |=|=|=|#|#|=|=|#|#|=|=|#|#|=|=|=| | | |
216  *           | | |=|#|#|=|=|#|#|=|=|#|#|=| | | | | |
217  *           | | | |#|#| | |#|#| | |#|#| | | | | | |
218  *           | | | | | | | | | | | | | | | | | | | |
219  */
220 int bbot[32]={2,2,1,0,0,1,1,0,0,1,1,0,0,1,2,2,3,3,3,9,9,9,9,9,9,9,9,9,9,9,9,9};
221 
222 int min_ht[5][35];
223 
convolve(void)224 void convolve(void)
225 {
226     int o, n, mx, x, y, bx, by;
227 
228     for (n = 0; n < 3; n++)
229     {
230         mx = n == 2 ? 16 : 8;
231         for (o = 0; o < 35; o++)
232         {
233             for (x = 0; x < mx; x++)
234             {
235                 bx = x - 16 + o;
236                 for (y = 7; y >= 0; y--)
237                     if (rock[n][0][7 - y][x + 8])
238                         break;
239 
240 
241                 by = bx <  0 ? 0 :
242                      bx > 19 ? 0 : (y - bbot[bx] + 1);
243 
244 #ifdef DEBUG_CNV
245 printf("Rock %d, X=%-2d, Y=%-3d, bx=%-3d, by=%-2d\n", n, x, y, bx, by);
246 #endif
247 
248                 if (by < 0) by = 0;
249 
250                 if (by > min_ht[n][o])
251                     min_ht[n][o] = by;
252             }
253         }
254     }
255     for (n = 3; n < 5; n++)
256     {
257         mx = n == 4 ? 16 : 8;
258         for (o = 0; o < 35; o++)
259         {
260             for (x = 0; x < mx; x++)
261             {
262                 bx = x - 16 + o;
263                 for (y = 7; y >= 0; y--)
264                     if (rock[n][0][7 - y][x + 8])
265                         break;
266 
267 
268                 by = bx <  0 ? 0 :
269                      bx > 19 ? 0 :
270                      y == 7 || bbot[bx] > 0 ? 0 : 1;
271 
272 #ifdef DEBUG_CNV2
273 printf("Rock %d, X=%-2d, Y=%-3d, bx=%-3d, by=%-2d\n", n, x, y, bx, by);
274 #endif
275 
276                 if (by < 0) by = 0;
277 
278                 if (by > min_ht[n][o])
279                     min_ht[n][o] = by;
280             }
281         }
282     }
283 }
284 
print_table(void)285 void print_table(void)
286 {
287     int i;
288     int n;
289 
290     const char *lbl[5] =
291     {
292         "@@rock1",
293         "@@rock2",
294         "@@rock3",
295         "@@crat1",
296         "@@crat2",
297     };
298     const char *name[5] =
299     {
300         "Rock #1",
301         "Rock #2",
302         "Rock #3",
303         "Crat #1",
304         "Crat #2",
305     };
306 
307     printf(";; Minimum Jump Height Table\n");
308     printf("MJHTBL  PROC\n");
309 
310 
311     for (n = 0; n < 5; n++)
312     {
313         printf("        ;; %s\n", name[n]);
314 
315         printf("        DECLE   ");
316         for (i = 0; i < 8; i++)
317             printf("%3d%s", 0,
318                     i == 7 ? "  ; Padding\n":", ");
319 
320 
321         if (n == 2 || n == 4)
322         {
323             printf("        DECLE   ");
324             for (i = 0; i < 8; i++)
325                 printf("%3d%s", min_ht[n][i]*32,
326                         i == 7 ? "  ; -16 thru -9\n":", ");
327         }
328 
329         printf("        DECLE   ");
330         for (i = 8; i < 16; i++)
331             printf("%3d%s", min_ht[n][i]*32,
332                     i == 15 ? "  ;  -8 thru -1\n": ", ");
333 
334         printf("%s DECLE   ", lbl[n]);
335         for (i = 16; i < 24; i++)
336             printf("%3d%s", min_ht[n][i]*32,
337                     i == 23 ? "  ;   0 thru  7\n": ", ");
338 
339         printf("        DECLE   ");
340         for (i = 24; i < 32; i++)
341             printf("%3d%s", min_ht[n][i]*32,
342                     i == 31 ? "  ;   8 thru 15\n": ", ");
343 
344         printf("        DECLE   ");
345         for (i = 32; i < 36; i++)
346             printf("%3d%s", min_ht[n][i]*32,
347                     i == 35 ? "                      ;  16 thru 19\n" : ", ");
348     }
349     printf("        DECLE   ");
350     for (i = 0; i < 8; i++)
351         printf("%3d%s", 0,
352                 i == 7 ? "  ; Padding\n":", ");
353     printf("        ENDP\n");
354 }
355 
main()356 main()
357 {
358     parse_rockcrat();
359     assemble_rocks();
360     convolve();
361     print_table();
362     return 0;
363 }
364