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