]> icculus.org git repositories - crow/jumpnbump.git/blob - dos/gfx.c
Copyright and documentation update.
[crow/jumpnbump.git] / dos / gfx.c
1 /*
2  * gfx.h
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  * 
5  * Copyright (C) 2002 Florian Schulze - crow@icculus.org
6  *
7  * Portions of this code are from the MPEG software simulation group
8  * idct implementation. This code will be replaced with a new
9  * implementation soon.
10  *
11  * This file is part of Jump'n'Bump.
12  *
13  * Jump'n'Bump is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * Jump'n'Bump is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 #include "globals.h"
29
30
31 void open_screen(void)
32 {
33         __dpmi_regs regs;
34         char *ptr1;
35
36         regs.x.ax = 0x13;
37         __dpmi_int(0x10, &regs);
38
39         outportw(0x3c4, 0x0604);
40         outportw(0x3c4, 0x0100);
41         outportb(0x3c2, 0xe7);
42         outportw(0x3c4, 0x0300);
43
44         outportb(0x3d4, 0x11);
45         outportb(0x3d5, inportb(0x3d5) & 0x7f);
46
47         outportw(0x3d4, 0x7100);
48         outportw(0x3d4, 0x6301);
49         outportw(0x3d4, 0x6402);
50         outportw(0x3d4, 0x9203);
51         outportw(0x3d4, 0x6604);
52         outportw(0x3d4, 0x8205);
53         outportw(0x3d4, 0x2b06);
54         outportw(0x3d4, 0xb207);
55         outportw(0x3d4, 0x0008);
56         outportw(0x3d4, 0x6109);
57         outportw(0x3d4, 0x1310);
58         outportw(0x3d4, 0xac11);
59         outportw(0x3d4, 0xff12);
60         outportw(0x3d4, 0x3213);
61         outportw(0x3d4, 0x0014);
62         outportw(0x3d4, 0x0715);
63         outportw(0x3d4, 0x1a16);
64         outportw(0x3d4, 0xe317);
65
66         outportw(0x3d4, 0x3213);
67
68         ptr1 = (char *) (0xa0000 + __djgpp_conventional_base);
69         outportw(0x3c4, 0x0f02);
70         memset(ptr1, 0, 65535);
71
72 }
73
74
75 void wait_vrt(int mix)
76 {
77         if (mix) {
78                 while ((inportb(0x3da) & 8) == 0)
79                         dj_mix();
80                 while ((inportb(0x3da) & 8) == 8)
81                         dj_mix();
82         } else {
83                 while ((inportb(0x3da) & 8) == 0);
84                 while ((inportb(0x3da) & 8) == 8);
85         }
86 }
87
88 void clear_page(int page, int color)
89 {
90         outportw(0x3c4, 0x0f02);
91         memset((char *) (0xa0000 - __djgpp_base_address), 0, 32768);
92 }
93
94 void clear_lines(int page, int y, int count, int color)
95 {
96         int i;
97
98         outportw(0x3c4, 0x0f02);
99         for (i=0; i<count; i++)
100                 if ((i+y)<256)
101                         memset((char *) (0xa0000 + (i+y) * 100 + __djgpp_conventional_base), 0, 100);
102 }
103
104 int get_pixel(int page, int x, int y)
105 {
106         outportw(0x3ce, (((x) & 3) << 8) + 0x04);
107         //outportw(0x3c4, ((1 << ((x) & 3)) << 8) + 0x02);
108         return *(char *) (0xa0000 + (y * 100 + (x >> 2)) + ((long) page << 15) - __djgpp_base_address);
109 }
110
111 void set_pixel(int page, int x, int y, int color)
112 {
113         //outportw(0x3ce, (((x) & 3) << 8) + 0x04);
114         outportw(0x3c4, ((1 << ((x) & 3)) << 8) + 0x02);
115         *(char *) (0xa0000 + (y * 100 + (x >> 2)) + ((long) page << 15) - __djgpp_base_address) = color;
116 }
117
118 void flippage(int page)
119 {
120         outportw(0x3d4, (page << 23) + 0x0d);
121         outportw(0x3d4, ((page << 15) & 0xff00) + 0x0c);
122 }
123
124 #if 0
125 void get_block(char page, short x, short y, short width, short height, char *buffer)
126 {
127         short c1, c2, c3;
128         char *buffer_ptr, *vga_ptr;
129
130         for (c3 = 0; c3 < 4; c3++) {
131                 outportw(0x3ce, (((x + c3) & 3) << 8) + 0x04);
132                 for (c1 = 0; (c1 + c3) < width; c1 += 4) {
133                         buffer_ptr = &buffer[(c1 + c3) * height];
134                         vga_ptr = (char *) (0xa0000 + ((long) page << 15) + (long) y * 100 + ((x + c1 + c3) >> 2) + __djgpp_conventional_base);
135                         for (c2 = 0; c2 < height; c2++) {
136                                 *buffer_ptr = *vga_ptr;
137                                 buffer_ptr++;
138                                 vga_ptr += 100;
139                         }
140                 }
141         }
142
143 }
144 #endif
145
146 #if 0
147 void put_block(char page, short x, short y, short width, short height, char *buffer)
148 {
149         short c1, c2, c3;
150         char *vga_ptr, *buffer_ptr;
151
152         for (c3 = 0; c3 < 4; c3++) {
153                 outportw(0x3c4, ((1 << ((x + c3) & 3)) << 8) + 0x02);
154                 for (c1 = 0; (c1 + c3) < width; c1 += 4) {
155                         vga_ptr = (char *) (0xa0000 + ((long) page << 15) + (long) y * 100 + ((x + c1 + c3) >> 2) + __djgpp_conventional_base);
156                         buffer_ptr = &buffer[(c1 + c3) * height];
157                         for (c2 = 0; c2 < height; c2++) {
158                                 *vga_ptr = *buffer_ptr;
159                                 vga_ptr += 100;
160                                 buffer_ptr++;
161                         }
162                 }
163         }
164
165 }
166 #endif
167
168 void put_text(char page, int x, int y, char *text, char align)
169 {
170         int c1;
171         int t1;
172         int width;
173         int cur_x;
174         int image;
175
176         if (text == NULL || strlen(text) == 0)
177                 return;
178         if (font_gobs == NULL)
179                 return;
180
181         width = 0;
182         c1 = 0;
183         while (text[c1] != 0) {
184                 t1 = text[c1];
185                 c1++;
186                 if (t1 == ' ') {
187                         width += 5;
188                         continue;
189                 }
190                 if (t1 >= 33 && t1 <= 34)
191                         image = t1 - 33;
192                 else if (t1 >= 39 && t1 <= 41)
193                         image = t1 - 37;
194                 else if (t1 >= 44 && t1 <= 59)
195                         image = t1 - 39;
196                 else if (t1 >= 64 && t1 <= 90)
197                         image = t1 - 43;
198                 else if (t1 >= 97 && t1 <= 122)
199                         image = t1 - 49;
200                 else if (t1 == '~')
201                         image = 74;
202                 else if (t1 == 0x84)
203                         image = 75;
204                 else if (t1 == 0x86)
205                         image = 76;
206                 else if (t1 == 0x8e)
207                         image = 77;
208                 else if (t1 == 0x8f)
209                         image = 78;
210                 else if (t1 == 0x94)
211                         image = 79;
212                 else if (t1 == 0x99)
213                         image = 80;
214                 else
215                         continue;
216                 width += pob_width(image, font_gobs) + 1;
217         }
218
219         switch (align) {
220         case 0:
221                 cur_x = x;
222                 break;
223         case 1:
224                 cur_x = x - width;
225                 break;
226         case 2:
227                 cur_x = x - width / 2;
228                 break;
229         }
230         c1 = 0;
231         while (text[c1] != 0) {
232                 t1 = text[c1];
233                 c1++;
234                 if (t1 == ' ') {
235                         cur_x += 5;
236                         continue;
237                 }
238                 if (t1 >= 33 && t1 <= 34)
239                         image = t1 - 33;
240                 else if (t1 >= 39 && t1 <= 41)
241                         image = t1 - 37;
242                 else if (t1 >= 44 && t1 <= 59)
243                         image = t1 - 39;
244                 else if (t1 >= 64 && t1 <= 90)
245                         image = t1 - 43;
246                 else if (t1 >= 97 && t1 <= 122)
247                         image = t1 - 49;
248                 else if (t1 == '~')
249                         image = 74;
250                 else if (t1 == 0x84)
251                         image = 75;
252                 else if (t1 == 0x86)
253                         image = 76;
254                 else if (t1 == 0x8e)
255                         image = 77;
256                 else if (t1 == 0x8f)
257                         image = 78;
258                 else if (t1 == 0x94)
259                         image = 79;
260                 else if (t1 == 0x99)
261                         image = 80;
262                 else
263                         continue;
264                 put_pob(page, cur_x, y, image, font_gobs, 1, mask_pic);
265                 cur_x += pob_width(image, font_gobs) + 1;
266         }
267
268 }
269
270
271 void put_pob(char page, short x, short y, short image, char *pob_data, char mask, char *mask_pic)
272 {
273         long c1, c2, c3;
274         long pob_offset;
275         char *pob_ptr, *vga_ptr, *mask_ptr;
276         long width, height;
277         long draw_width, draw_height;
278         char colour;
279
280         if (image < 0 || image >= *(short *) (pob_data))
281                 return;
282
283         pob_offset = *(long *) (pob_data + image * 4 + 2);
284
285         width = draw_width = *(short *) (pob_data + pob_offset);
286         height = draw_height = *(short *) (pob_data + pob_offset + 2);
287         x -= *(short *) (pob_data + pob_offset + 4);
288         y -= *(short *) (pob_data + pob_offset + 6);
289
290         pob_offset += 8;
291
292         if ((x + width) <= 0 || x >= 400)
293                 return;
294         if ((y + height) <= 0 || y >= 256)
295                 return;
296         if (x < 0) {
297                 pob_offset -= x;
298                 draw_width += x;
299                 x = 0;
300         }
301         if ((x + width) > 400)
302                 draw_width -= x + width - 400;
303         if (y < 0) {
304                 pob_offset += -y * width;
305                 draw_height -= -y;
306                 y = 0;
307         }
308         if ((y + height) > 256)
309                 draw_height -= y + height - 256;
310
311         for (c3 = 0; c3 < 4; c3++) {
312                 outportw(0x3c4, ((1 << ((x + c3) & 3)) << 8) + 0x02);
313                 pob_ptr = &pob_data[pob_offset + c3];
314                 vga_ptr = (char *) (0xa0000 + (long) (page << 15) + (long) y * 100L + ((x + c3) >> 2) + __djgpp_conventional_base);
315                 mask_ptr = (char *) (mask_pic + (long) y * 400L + x + c3);
316                 for (c1 = 0; c1 < draw_height; c1++) {
317                         for (c2 = c3; c2 < draw_width; c2 += 4) {
318                                 colour = *mask_ptr;
319                                 if (mask == 0 || (mask == 1 && colour == 0)) {
320                                         colour = *pob_ptr;
321                                         if (colour != 0)
322                                                 *vga_ptr = colour;
323                                 }
324                                 pob_ptr += 4;
325                                 vga_ptr++;
326                                 mask_ptr += 4;
327                         }
328                         pob_ptr += width - c2 + c3;
329                         vga_ptr += (400 - c2 + c3) >> 2;
330                         mask_ptr += 400 - c2 + c3;
331                 }
332         }
333
334 }
335
336
337 char pob_col(short x1, short y1, short image1, char *pob_data1, short x2, short y2, short image2, char *pob_data2)
338 {
339         short c1, c2;
340         long pob_offset1, pob_offset2;
341         short width1, width2;
342         short height1, height2;
343         short check_width, check_height;
344         char *pob_ptr1, *pob_ptr2;
345
346         pob_offset1 = *(long *) (pob_data1 + image1 * 4 + 2);
347         width1 = *(short *) (pob_data1 + pob_offset1);
348         height1 = *(short *) (pob_data1 + pob_offset1 + 2);
349         x1 -= *(short *) (pob_data1 + pob_offset1 + 4);
350         y1 -= *(short *) (pob_data1 + pob_offset1 + 6);
351         pob_offset1 += 8;
352
353         pob_offset2 = *(long *) (pob_data2 + image2 * 4 + 2);
354         width2 = *(short *) (pob_data2 + pob_offset2);
355         height2 = *(short *) (pob_data2 + pob_offset2 + 2);
356         x2 -= *(short *) (pob_data2 + pob_offset2 + 4);
357         y2 -= *(short *) (pob_data2 + pob_offset2 + 6);
358         pob_offset2 += 8;
359
360         if (x1 < x2) {
361                 if ((x1 + width1) <= x2)
362                         return 0;
363                 else if ((x1 + width1) <= (x2 + width2)) {
364                         pob_offset1 += x2 - x1;
365                         check_width = x1 + width1 - x2;
366                 } else {
367                         pob_offset1 += x2 - x1;
368                         check_width = width2;
369                 }
370         } else {
371                 if ((x2 + width2) <= x1)
372                         return 0;
373                 else if ((x2 + width2) <= (x1 + width1)) {
374                         pob_offset2 += x1 - x2;
375                         check_width = x2 + width2 - x1;
376                 } else {
377                         pob_offset2 += x1 - x2;
378                         check_width = width1;
379                 }
380         }
381         if (y1 < y2) {
382                 if ((y1 + height1) <= y2)
383                         return 0;
384                 else if ((y1 + height1) <= (y2 + height2)) {
385                         pob_offset1 += (y2 - y1) * width1;
386                         check_height = y1 + height1 - y2;
387                 } else {
388                         pob_offset1 += (y2 - y1) * width1;
389                         check_height = height2;
390                 }
391         } else {
392                 if ((y2 + height2) <= y1)
393                         return 0;
394                 else if ((y2 + height2) <= (y1 + height1)) {
395                         pob_offset2 += (y1 - y2) * width2;
396                         check_height = y2 + height2 - y1;
397                 } else {
398                         pob_offset2 += (y1 - y2) * width2;
399                         check_height = height1;
400                 }
401         }
402
403         pob_ptr1 = (char *) (pob_data1 + pob_offset1);
404         pob_ptr2 = (char *) (pob_data2 + pob_offset2);
405         for (c1 = 0; c1 < check_height; c1++) {
406                 for (c2 = 0; c2 < check_width; c2++) {
407                         if (*pob_ptr1 != 0 && *pob_ptr2 != 0)
408                                 return 1;
409                         pob_ptr1++;
410                         pob_ptr2++;
411                 }
412                 pob_ptr1 += width1 - check_width;
413                 pob_ptr2 += width2 - check_width;
414         }
415
416         return 0;
417
418 }
419
420
421 short pob_width(short image, char *pob_data)
422 {
423         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2));
424 }
425
426
427 short pob_height(short image, char *pob_data)
428 {
429         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 2);
430 }
431
432
433 short pob_hs_x(short image, char *pob_data)
434 {
435         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 4);
436 }
437
438
439 short pob_hs_y(short image, char *pob_data)
440 {
441         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 6);
442 }
443
444
445 char read_pcx(FILE * handle, char *buffer, long buf_len, char *pal)
446 {
447         short c1;
448         short a, b;
449         long ofs1;
450
451         if (buffer != 0) {
452                 fseek(handle, 128, SEEK_CUR);
453
454                 ofs1 = 0;
455
456                 while (ofs1 < buf_len) {
457                         a = fgetc(handle);
458                         if ((a & 0xc0) == 0xc0) {
459                                 b = fgetc(handle);
460                                 a &= 0x3f;
461                                 for (c1 = 0; c1 < a; c1++)
462                                         buffer[ofs1++] = b;
463                         } else
464                                 buffer[ofs1++] = a;
465                 }
466
467                 if (pal != 0) {
468                         fseek(handle, 1, SEEK_CUR);
469                         for (c1 = 0; c1 < 768; c1++)
470                                 pal[c1] = fgetc(handle) >> 2;
471                 }
472
473         }
474
475         fclose(handle);
476         return 0;
477 }