]> icculus.org git repositories - crow/jumpnbump.git/blob - dos/gfx.c
Speeded up scaling engine using dirty rects. Hacked a fix for the score screen.
[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 int get_pixel(int page, int x, int y)
78 {
79         outportw(0x3ce, (((x) & 3) << 8) + 0x04);
80         //outportw(0x3c4, ((1 << ((x) & 3)) << 8) + 0x02);
81         return *(char *) (0xa0000 + (y * 100 + (x >> 2)) + ((long) page << 15) - __djgpp_base_address);
82 }
83
84 void set_pixel(int page, int x, int y, int color)
85 {
86         //outportw(0x3ce, (((x) & 3) << 8) + 0x04);
87         outportw(0x3c4, ((1 << ((x) & 3)) << 8) + 0x02);
88         *(char *) (0xa0000 + (y * 100 + (x >> 2)) + ((long) page << 15) - __djgpp_base_address) = color;
89 }
90
91 void flippage(int page)
92 {
93         outportw(0x3d4, (page << 23) + 0x0d);
94         outportw(0x3d4, ((page << 15) & 0xff00) + 0x0c);
95 }
96
97 #if 0
98 void get_block(char page, short x, short y, short width, short height, char *buffer)
99 {
100         short c1, c2, c3;
101         char *buffer_ptr, *vga_ptr;
102
103         for (c3 = 0; c3 < 4; c3++) {
104                 outportw(0x3ce, (((x + c3) & 3) << 8) + 0x04);
105                 for (c1 = 0; (c1 + c3) < width; c1 += 4) {
106                         buffer_ptr = &buffer[(c1 + c3) * height];
107                         vga_ptr = (char *) (0xa0000 + ((long) page << 15) + (long) y * 100 + ((x + c1 + c3) >> 2) + __djgpp_conventional_base);
108                         for (c2 = 0; c2 < height; c2++) {
109                                 *buffer_ptr = *vga_ptr;
110                                 buffer_ptr++;
111                                 vga_ptr += 100;
112                         }
113                 }
114         }
115
116 }
117 #endif
118
119 #if 0
120 void put_block(char page, short x, short y, short width, short height, char *buffer)
121 {
122         short c1, c2, c3;
123         char *vga_ptr, *buffer_ptr;
124
125         for (c3 = 0; c3 < 4; c3++) {
126                 outportw(0x3c4, ((1 << ((x + c3) & 3)) << 8) + 0x02);
127                 for (c1 = 0; (c1 + c3) < width; c1 += 4) {
128                         vga_ptr = (char *) (0xa0000 + ((long) page << 15) + (long) y * 100 + ((x + c1 + c3) >> 2) + __djgpp_conventional_base);
129                         buffer_ptr = &buffer[(c1 + c3) * height];
130                         for (c2 = 0; c2 < height; c2++) {
131                                 *vga_ptr = *buffer_ptr;
132                                 vga_ptr += 100;
133                                 buffer_ptr++;
134                         }
135                 }
136         }
137
138 }
139 #endif
140
141 void put_text(char page, int x, int y, char *text, char align)
142 {
143         int c1;
144         int t1;
145         int width;
146         int cur_x;
147         int image;
148
149         if (text == NULL || strlen(text) == 0)
150                 return;
151         if (font_gobs == NULL)
152                 return;
153
154         width = 0;
155         c1 = 0;
156         while (text[c1] != 0) {
157                 t1 = text[c1];
158                 c1++;
159                 if (t1 == ' ') {
160                         width += 5;
161                         continue;
162                 }
163                 if (t1 >= 33 && t1 <= 34)
164                         image = t1 - 33;
165                 else if (t1 >= 39 && t1 <= 41)
166                         image = t1 - 37;
167                 else if (t1 >= 44 && t1 <= 59)
168                         image = t1 - 39;
169                 else if (t1 >= 64 && t1 <= 90)
170                         image = t1 - 43;
171                 else if (t1 >= 97 && t1 <= 122)
172                         image = t1 - 49;
173                 else if (t1 == '~')
174                         image = 74;
175                 else if (t1 == 0x84)
176                         image = 75;
177                 else if (t1 == 0x86)
178                         image = 76;
179                 else if (t1 == 0x8e)
180                         image = 77;
181                 else if (t1 == 0x8f)
182                         image = 78;
183                 else if (t1 == 0x94)
184                         image = 79;
185                 else if (t1 == 0x99)
186                         image = 80;
187                 else
188                         continue;
189                 width += pob_width(image, font_gobs) + 1;
190         }
191
192         switch (align) {
193         case 0:
194                 cur_x = x;
195                 break;
196         case 1:
197                 cur_x = x - width;
198                 break;
199         case 2:
200                 cur_x = x - width / 2;
201                 break;
202         }
203         c1 = 0;
204         while (text[c1] != 0) {
205                 t1 = text[c1];
206                 c1++;
207                 if (t1 == ' ') {
208                         cur_x += 5;
209                         continue;
210                 }
211                 if (t1 >= 33 && t1 <= 34)
212                         image = t1 - 33;
213                 else if (t1 >= 39 && t1 <= 41)
214                         image = t1 - 37;
215                 else if (t1 >= 44 && t1 <= 59)
216                         image = t1 - 39;
217                 else if (t1 >= 64 && t1 <= 90)
218                         image = t1 - 43;
219                 else if (t1 >= 97 && t1 <= 122)
220                         image = t1 - 49;
221                 else if (t1 == '~')
222                         image = 74;
223                 else if (t1 == 0x84)
224                         image = 75;
225                 else if (t1 == 0x86)
226                         image = 76;
227                 else if (t1 == 0x8e)
228                         image = 77;
229                 else if (t1 == 0x8f)
230                         image = 78;
231                 else if (t1 == 0x94)
232                         image = 79;
233                 else if (t1 == 0x99)
234                         image = 80;
235                 else
236                         continue;
237                 put_pob(page, cur_x, y, image, font_gobs, 1, mask_pic);
238                 cur_x += pob_width(image, font_gobs) + 1;
239         }
240
241 }
242
243
244 void put_pob(char page, short x, short y, short image, char *pob_data, char mask, char *mask_pic)
245 {
246         long c1, c2, c3;
247         long pob_offset;
248         char *pob_ptr, *vga_ptr, *mask_ptr;
249         long width, height;
250         long draw_width, draw_height;
251         char colour;
252
253         if (image < 0 || image >= *(short *) (pob_data))
254                 return;
255
256         pob_offset = *(long *) (pob_data + image * 4 + 2);
257
258         width = draw_width = *(short *) (pob_data + pob_offset);
259         height = draw_height = *(short *) (pob_data + pob_offset + 2);
260         x -= *(short *) (pob_data + pob_offset + 4);
261         y -= *(short *) (pob_data + pob_offset + 6);
262
263         pob_offset += 8;
264
265         if ((x + width) <= 0 || x >= 400)
266                 return;
267         if ((y + height) <= 0 || y >= 256)
268                 return;
269         if (x < 0) {
270                 pob_offset -= x;
271                 draw_width += x;
272                 x = 0;
273         }
274         if ((x + width) > 400)
275                 draw_width -= x + width - 400;
276         if (y < 0) {
277                 pob_offset += -y * width;
278                 draw_height -= -y;
279                 y = 0;
280         }
281         if ((y + height) > 256)
282                 draw_height -= y + height - 256;
283
284         for (c3 = 0; c3 < 4; c3++) {
285                 outportw(0x3c4, ((1 << ((x + c3) & 3)) << 8) + 0x02);
286                 pob_ptr = &pob_data[pob_offset + c3];
287                 vga_ptr = (char *) (0xa0000 + (long) (page << 15) + (long) y * 100L + ((x + c3) >> 2) + __djgpp_conventional_base);
288                 mask_ptr = (char *) (mask_pic + (long) y * 400L + x + c3);
289                 for (c1 = 0; c1 < draw_height; c1++) {
290                         for (c2 = c3; c2 < draw_width; c2 += 4) {
291                                 colour = *mask_ptr;
292                                 if (mask == 0 || (mask == 1 && colour == 0)) {
293                                         colour = *pob_ptr;
294                                         if (colour != 0)
295                                                 *vga_ptr = colour;
296                                 }
297                                 pob_ptr += 4;
298                                 vga_ptr++;
299                                 mask_ptr += 4;
300                         }
301                         pob_ptr += width - c2 + c3;
302                         vga_ptr += (400 - c2 + c3) >> 2;
303                         mask_ptr += 400 - c2 + c3;
304                 }
305         }
306
307 }
308
309
310 char pob_col(short x1, short y1, short image1, char *pob_data1, short x2, short y2, short image2, char *pob_data2)
311 {
312         short c1, c2;
313         long pob_offset1, pob_offset2;
314         short width1, width2;
315         short height1, height2;
316         short check_width, check_height;
317         char *pob_ptr1, *pob_ptr2;
318
319         pob_offset1 = *(long *) (pob_data1 + image1 * 4 + 2);
320         width1 = *(short *) (pob_data1 + pob_offset1);
321         height1 = *(short *) (pob_data1 + pob_offset1 + 2);
322         x1 -= *(short *) (pob_data1 + pob_offset1 + 4);
323         y1 -= *(short *) (pob_data1 + pob_offset1 + 6);
324         pob_offset1 += 8;
325
326         pob_offset2 = *(long *) (pob_data2 + image2 * 4 + 2);
327         width2 = *(short *) (pob_data2 + pob_offset2);
328         height2 = *(short *) (pob_data2 + pob_offset2 + 2);
329         x2 -= *(short *) (pob_data2 + pob_offset2 + 4);
330         y2 -= *(short *) (pob_data2 + pob_offset2 + 6);
331         pob_offset2 += 8;
332
333         if (x1 < x2) {
334                 if ((x1 + width1) <= x2)
335                         return 0;
336                 else if ((x1 + width1) <= (x2 + width2)) {
337                         pob_offset1 += x2 - x1;
338                         check_width = x1 + width1 - x2;
339                 } else {
340                         pob_offset1 += x2 - x1;
341                         check_width = width2;
342                 }
343         } else {
344                 if ((x2 + width2) <= x1)
345                         return 0;
346                 else if ((x2 + width2) <= (x1 + width1)) {
347                         pob_offset2 += x1 - x2;
348                         check_width = x2 + width2 - x1;
349                 } else {
350                         pob_offset2 += x1 - x2;
351                         check_width = width1;
352                 }
353         }
354         if (y1 < y2) {
355                 if ((y1 + height1) <= y2)
356                         return 0;
357                 else if ((y1 + height1) <= (y2 + height2)) {
358                         pob_offset1 += (y2 - y1) * width1;
359                         check_height = y1 + height1 - y2;
360                 } else {
361                         pob_offset1 += (y2 - y1) * width1;
362                         check_height = height2;
363                 }
364         } else {
365                 if ((y2 + height2) <= y1)
366                         return 0;
367                 else if ((y2 + height2) <= (y1 + height1)) {
368                         pob_offset2 += (y1 - y2) * width2;
369                         check_height = y2 + height2 - y1;
370                 } else {
371                         pob_offset2 += (y1 - y2) * width2;
372                         check_height = height1;
373                 }
374         }
375
376         pob_ptr1 = (char *) (pob_data1 + pob_offset1);
377         pob_ptr2 = (char *) (pob_data2 + pob_offset2);
378         for (c1 = 0; c1 < check_height; c1++) {
379                 for (c2 = 0; c2 < check_width; c2++) {
380                         if (*pob_ptr1 != 0 && *pob_ptr2 != 0)
381                                 return 1;
382                         pob_ptr1++;
383                         pob_ptr2++;
384                 }
385                 pob_ptr1 += width1 - check_width;
386                 pob_ptr2 += width2 - check_width;
387         }
388
389         return 0;
390
391 }
392
393
394 short pob_width(short image, char *pob_data)
395 {
396         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2));
397 }
398
399
400 short pob_height(short image, char *pob_data)
401 {
402         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 2);
403 }
404
405
406 short pob_hs_x(short image, char *pob_data)
407 {
408         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 4);
409 }
410
411
412 short pob_hs_y(short image, char *pob_data)
413 {
414         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 6);
415 }
416
417
418 char read_pcx(FILE * handle, char *buffer, long buf_len, char *pal)
419 {
420         short c1;
421         short a, b;
422         long ofs1;
423
424         if (buffer != 0) {
425                 fseek(handle, 128, SEEK_CUR);
426
427                 ofs1 = 0;
428
429                 while (ofs1 < buf_len) {
430                         a = fgetc(handle);
431                         if ((a & 0xc0) == 0xc0) {
432                                 b = fgetc(handle);
433                                 a &= 0x3f;
434                                 for (c1 = 0; c1 < a; c1++)
435                                         buffer[ofs1++] = b;
436                         } else
437                                 buffer[ofs1++] = a;
438                 }
439
440                 if (pal != 0) {
441                         fseek(handle, 1, SEEK_CUR);
442                         for (c1 = 0; c1 < 768; c1++)
443                                 pal[c1] = fgetc(handle) >> 2;
444                 }
445
446         }
447
448         fclose(handle);
449         return 0;
450 }