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