More code cleanups. Separated some stuff into new functions.
[crow/jumpnbump.git] / dos / gfx.c
1 #include "globals.h"
2
3
4 void open_screen(void)
5 {
6         __dpmi_regs regs;
7         char *ptr1;
8
9         regs.x.ax = 0x13;
10         __dpmi_int(0x10, &regs);
11
12         outportw(0x3c4, 0x0604);
13         outportw(0x3c4, 0x0100);
14         outportb(0x3c2, 0xe7);
15         outportw(0x3c4, 0x0300);
16
17         outportb(0x3d4, 0x11);
18         outportb(0x3d5, inportb(0x3d5) & 0x7f);
19
20         outportw(0x3d4, 0x7100);
21         outportw(0x3d4, 0x6301);
22         outportw(0x3d4, 0x6402);
23         outportw(0x3d4, 0x9203);
24         outportw(0x3d4, 0x6604);
25         outportw(0x3d4, 0x8205);
26         outportw(0x3d4, 0x2b06);
27         outportw(0x3d4, 0xb207);
28         outportw(0x3d4, 0x0008);
29         outportw(0x3d4, 0x6109);
30         outportw(0x3d4, 0x1310);
31         outportw(0x3d4, 0xac11);
32         outportw(0x3d4, 0xff12);
33         outportw(0x3d4, 0x3213);
34         outportw(0x3d4, 0x0014);
35         outportw(0x3d4, 0x0715);
36         outportw(0x3d4, 0x1a16);
37         outportw(0x3d4, 0xe317);
38
39         outportw(0x3d4, 0x3213);
40
41         ptr1 = (char *) (0xa0000 + __djgpp_conventional_base);
42         outportw(0x3c4, 0x0f02);
43         memset(ptr1, 0, 65535);
44
45 }
46
47
48 void wait_vrt(int mix)
49 {
50         if (mix) {
51                 while ((inportb(0x3da) & 8) == 0)
52                         dj_mix();
53                 while ((inportb(0x3da) & 8) == 8)
54                         dj_mix();
55         } else {
56                 while ((inportb(0x3da) & 8) == 0);
57                 while ((inportb(0x3da) & 8) == 8);
58         }
59 }
60
61 void clear_page(int page, int color)
62 {
63         outportw(0x3c4, 0x0f02);
64         memset((char *) (0xa0000 - __djgpp_base_address), 0, 32768);
65 }
66
67 void clear_lines(int page, int y, int count, int color)
68 {
69         int i;
70
71         outportw(0x3c4, 0x0f02);
72         for (i=0; i<count; i++)
73                 if ((i+y)<256)
74                         memset((char *) (0xa0000 + (i+y) * 100 + __djgpp_conventional_base), 0, 100);
75 }
76
77 void flippage(int page)
78 {
79         outportw(0x3d4, (page << 23) + 0x0d);
80         outportw(0x3d4, ((page << 15) & 0xff00) + 0x0c);
81 }
82
83 #if 0
84 void get_block(char page, short x, short y, short width, short height, char *buffer)
85 {
86         short c1, c2, c3;
87         char *buffer_ptr, *vga_ptr;
88
89         for (c3 = 0; c3 < 4; c3++) {
90                 outportw(0x3ce, (((x + c3) & 3) << 8) + 0x04);
91                 for (c1 = 0; (c1 + c3) < width; c1 += 4) {
92                         buffer_ptr = &buffer[(c1 + c3) * height];
93                         vga_ptr = (char *) (0xa0000 + ((long) page << 15) + (long) y * 100 + ((x + c1 + c3) >> 2) + __djgpp_conventional_base);
94                         for (c2 = 0; c2 < height; c2++) {
95                                 *buffer_ptr = *vga_ptr;
96                                 buffer_ptr++;
97                                 vga_ptr += 100;
98                         }
99                 }
100         }
101
102 }
103 #endif
104
105 #if 0
106 void put_block(char page, short x, short y, short width, short height, char *buffer)
107 {
108         short c1, c2, c3;
109         char *vga_ptr, *buffer_ptr;
110
111         for (c3 = 0; c3 < 4; c3++) {
112                 outportw(0x3c4, ((1 << ((x + c3) & 3)) << 8) + 0x02);
113                 for (c1 = 0; (c1 + c3) < width; c1 += 4) {
114                         vga_ptr = (char *) (0xa0000 + ((long) page << 15) + (long) y * 100 + ((x + c1 + c3) >> 2) + __djgpp_conventional_base);
115                         buffer_ptr = &buffer[(c1 + c3) * height];
116                         for (c2 = 0; c2 < height; c2++) {
117                                 *vga_ptr = *buffer_ptr;
118                                 vga_ptr += 100;
119                                 buffer_ptr++;
120                         }
121                 }
122         }
123
124 }
125 #endif
126
127 void put_text(char page, int x, int y, char *text, char align)
128 {
129         int c1;
130         int t1;
131         int width;
132         int cur_x;
133         int image;
134
135         if (text == NULL || strlen(text) == 0)
136                 return;
137         if (font_gobs == NULL)
138                 return;
139
140         width = 0;
141         c1 = 0;
142         while (text[c1] != 0) {
143                 t1 = text[c1];
144                 c1++;
145                 if (t1 == ' ') {
146                         width += 5;
147                         continue;
148                 }
149                 if (t1 >= 33 && t1 <= 34)
150                         image = t1 - 33;
151                 else if (t1 >= 39 && t1 <= 41)
152                         image = t1 - 37;
153                 else if (t1 >= 44 && t1 <= 59)
154                         image = t1 - 39;
155                 else if (t1 >= 64 && t1 <= 90)
156                         image = t1 - 43;
157                 else if (t1 >= 97 && t1 <= 122)
158                         image = t1 - 49;
159                 else if (t1 == '~')
160                         image = 74;
161                 else if (t1 == 0x84)
162                         image = 75;
163                 else if (t1 == 0x86)
164                         image = 76;
165                 else if (t1 == 0x8e)
166                         image = 77;
167                 else if (t1 == 0x8f)
168                         image = 78;
169                 else if (t1 == 0x94)
170                         image = 79;
171                 else if (t1 == 0x99)
172                         image = 80;
173                 else
174                         continue;
175                 width += pob_width(image, font_gobs) + 1;
176         }
177
178         switch (align) {
179         case 0:
180                 cur_x = x;
181                 break;
182         case 1:
183                 cur_x = x - width;
184                 break;
185         case 2:
186                 cur_x = x - width / 2;
187                 break;
188         }
189         c1 = 0;
190         while (text[c1] != 0) {
191                 t1 = text[c1];
192                 c1++;
193                 if (t1 == ' ') {
194                         cur_x += 5;
195                         continue;
196                 }
197                 if (t1 >= 33 && t1 <= 34)
198                         image = t1 - 33;
199                 else if (t1 >= 39 && t1 <= 41)
200                         image = t1 - 37;
201                 else if (t1 >= 44 && t1 <= 59)
202                         image = t1 - 39;
203                 else if (t1 >= 64 && t1 <= 90)
204                         image = t1 - 43;
205                 else if (t1 >= 97 && t1 <= 122)
206                         image = t1 - 49;
207                 else if (t1 == '~')
208                         image = 74;
209                 else if (t1 == 0x84)
210                         image = 75;
211                 else if (t1 == 0x86)
212                         image = 76;
213                 else if (t1 == 0x8e)
214                         image = 77;
215                 else if (t1 == 0x8f)
216                         image = 78;
217                 else if (t1 == 0x94)
218                         image = 79;
219                 else if (t1 == 0x99)
220                         image = 80;
221                 else
222                         continue;
223                 put_pob(page, cur_x, y, image, font_gobs, 1, mask_pic);
224                 cur_x += pob_width(image, font_gobs) + 1;
225         }
226
227 }
228
229
230 void put_pob(char page, short x, short y, short image, char *pob_data, char mask, char *mask_pic)
231 {
232         long c1, c2, c3;
233         long pob_offset;
234         char *pob_ptr, *vga_ptr, *mask_ptr;
235         long width, height;
236         long draw_width, draw_height;
237         char colour;
238
239         if (image < 0 || image >= *(short *) (pob_data))
240                 return;
241
242         pob_offset = *(long *) (pob_data + image * 4 + 2);
243
244         width = draw_width = *(short *) (pob_data + pob_offset);
245         height = draw_height = *(short *) (pob_data + pob_offset + 2);
246         x -= *(short *) (pob_data + pob_offset + 4);
247         y -= *(short *) (pob_data + pob_offset + 6);
248
249         pob_offset += 8;
250
251         if ((x + width) <= 0 || x >= 400)
252                 return;
253         if ((y + height) <= 0 || y >= 256)
254                 return;
255         if (x < 0) {
256                 pob_offset -= x;
257                 draw_width += x;
258                 x = 0;
259         }
260         if ((x + width) > 400)
261                 draw_width -= x + width - 400;
262         if (y < 0) {
263                 pob_offset += -y * width;
264                 draw_height -= -y;
265                 y = 0;
266         }
267         if ((y + height) > 256)
268                 draw_height -= y + height - 256;
269
270         for (c3 = 0; c3 < 4; c3++) {
271                 outportw(0x3c4, ((1 << ((x + c3) & 3)) << 8) + 0x02);
272                 pob_ptr = &pob_data[pob_offset + c3];
273                 vga_ptr = (char *) (0xa0000 + (long) (page << 15) + (long) y * 100L + ((x + c3) >> 2) + __djgpp_conventional_base);
274                 mask_ptr = (char *) (mask_pic + (long) y * 400L + x + c3);
275                 for (c1 = 0; c1 < draw_height; c1++) {
276                         for (c2 = c3; c2 < draw_width; c2 += 4) {
277                                 colour = *mask_ptr;
278                                 if (mask == 0 || (mask == 1 && colour == 0)) {
279                                         colour = *pob_ptr;
280                                         if (colour != 0)
281                                                 *vga_ptr = colour;
282                                 }
283                                 pob_ptr += 4;
284                                 vga_ptr++;
285                                 mask_ptr += 4;
286                         }
287                         pob_ptr += width - c2 + c3;
288                         vga_ptr += (400 - c2 + c3) >> 2;
289                         mask_ptr += 400 - c2 + c3;
290                 }
291         }
292
293 }
294
295
296 char pob_col(short x1, short y1, short image1, char *pob_data1, short x2, short y2, short image2, char *pob_data2)
297 {
298         short c1, c2;
299         long pob_offset1, pob_offset2;
300         short width1, width2;
301         short height1, height2;
302         short check_width, check_height;
303         char *pob_ptr1, *pob_ptr2;
304
305         pob_offset1 = *(long *) (pob_data1 + image1 * 4 + 2);
306         width1 = *(short *) (pob_data1 + pob_offset1);
307         height1 = *(short *) (pob_data1 + pob_offset1 + 2);
308         x1 -= *(short *) (pob_data1 + pob_offset1 + 4);
309         y1 -= *(short *) (pob_data1 + pob_offset1 + 6);
310         pob_offset1 += 8;
311
312         pob_offset2 = *(long *) (pob_data2 + image2 * 4 + 2);
313         width2 = *(short *) (pob_data2 + pob_offset2);
314         height2 = *(short *) (pob_data2 + pob_offset2 + 2);
315         x2 -= *(short *) (pob_data2 + pob_offset2 + 4);
316         y2 -= *(short *) (pob_data2 + pob_offset2 + 6);
317         pob_offset2 += 8;
318
319         if (x1 < x2) {
320                 if ((x1 + width1) <= x2)
321                         return 0;
322                 else if ((x1 + width1) <= (x2 + width2)) {
323                         pob_offset1 += x2 - x1;
324                         check_width = x1 + width1 - x2;
325                 } else {
326                         pob_offset1 += x2 - x1;
327                         check_width = width2;
328                 }
329         } else {
330                 if ((x2 + width2) <= x1)
331                         return 0;
332                 else if ((x2 + width2) <= (x1 + width1)) {
333                         pob_offset2 += x1 - x2;
334                         check_width = x2 + width2 - x1;
335                 } else {
336                         pob_offset2 += x1 - x2;
337                         check_width = width1;
338                 }
339         }
340         if (y1 < y2) {
341                 if ((y1 + height1) <= y2)
342                         return 0;
343                 else if ((y1 + height1) <= (y2 + height2)) {
344                         pob_offset1 += (y2 - y1) * width1;
345                         check_height = y1 + height1 - y2;
346                 } else {
347                         pob_offset1 += (y2 - y1) * width1;
348                         check_height = height2;
349                 }
350         } else {
351                 if ((y2 + height2) <= y1)
352                         return 0;
353                 else if ((y2 + height2) <= (y1 + height1)) {
354                         pob_offset2 += (y1 - y2) * width2;
355                         check_height = y2 + height2 - y1;
356                 } else {
357                         pob_offset2 += (y1 - y2) * width2;
358                         check_height = height1;
359                 }
360         }
361
362         pob_ptr1 = (char *) (pob_data1 + pob_offset1);
363         pob_ptr2 = (char *) (pob_data2 + pob_offset2);
364         for (c1 = 0; c1 < check_height; c1++) {
365                 for (c2 = 0; c2 < check_width; c2++) {
366                         if (*pob_ptr1 != 0 && *pob_ptr2 != 0)
367                                 return 1;
368                         pob_ptr1++;
369                         pob_ptr2++;
370                 }
371                 pob_ptr1 += width1 - check_width;
372                 pob_ptr2 += width2 - check_width;
373         }
374
375         return 0;
376
377 }
378
379
380 short pob_width(short image, char *pob_data)
381 {
382         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2));
383 }
384
385
386 short pob_height(short image, char *pob_data)
387 {
388         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 2);
389 }
390
391
392 short pob_hs_x(short image, char *pob_data)
393 {
394         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 4);
395 }
396
397
398 short pob_hs_y(short image, char *pob_data)
399 {
400         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 6);
401 }
402
403
404 char read_pcx(FILE * handle, char *buffer, long buf_len, char *pal)
405 {
406         short c1;
407         short a, b;
408         long ofs1;
409
410         if (buffer != 0) {
411                 fseek(handle, 128, SEEK_CUR);
412
413                 ofs1 = 0;
414
415                 while (ofs1 < buf_len) {
416                         a = fgetc(handle);
417                         if ((a & 0xc0) == 0xc0) {
418                                 b = fgetc(handle);
419                                 a &= 0x3f;
420                                 for (c1 = 0; c1 < a; c1++)
421                                         buffer[ofs1++] = b;
422                         } else
423                                 buffer[ofs1++] = a;
424                 }
425
426                 if (pal != 0) {
427                         fseek(handle, 1, SEEK_CUR);
428                         for (c1 = 0; c1 < 768; c1++)
429                                 pal[c1] = fgetc(handle) >> 2;
430                 }
431
432         }
433
434         fclose(handle);
435         return 0;
436 }