Import jumpnbump/1.50
[jumpnbump.git] / dos / gfx.c
blob5b40d0af17a743cff6abdb3e7d0f6db846200803
1 /*
2 * gfx.h
3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4 *
5 * Copyright (C) 2002 Florian Schulze - crow@icculus.org
7 * This file is part of Jump'n'Bump.
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.
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.
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
24 #include "globals.h"
27 void open_screen(void)
29 __dpmi_regs regs;
30 char *ptr1;
32 regs.x.ax = 0x13;
33 __dpmi_int(0x10, &regs);
35 outportw(0x3c4, 0x0604);
36 outportw(0x3c4, 0x0100);
37 outportb(0x3c2, 0xe7);
38 outportw(0x3c4, 0x0300);
40 outportb(0x3d4, 0x11);
41 outportb(0x3d5, inportb(0x3d5) & 0x7f);
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);
62 outportw(0x3d4, 0x3213);
64 ptr1 = (char *) (0xa0000 + __djgpp_conventional_base);
65 outportw(0x3c4, 0x0f02);
66 memset(ptr1, 0, 65535);
71 void wait_vrt(int mix)
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);
84 void clear_page(int page, int color)
86 outportw(0x3c4, 0x0f02);
87 memset((char *) (0xa0000 - __djgpp_base_address), 0, 32768);
90 void clear_lines(int page, int y, int count, int color)
92 int i;
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);
100 int get_pixel(int page, int x, int y)
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);
107 void set_pixel(int page, int x, int y, int color)
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;
114 void flippage(int page)
116 outportw(0x3d4, (page << 23) + 0x0d);
117 outportw(0x3d4, ((page << 15) & 0xff00) + 0x0c);
120 #if 0
121 void get_block(char page, short x, short y, short width, short height, char *buffer)
123 short c1, c2, c3;
124 char *buffer_ptr, *vga_ptr;
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;
140 #endif
142 #if 0
143 void put_block(char page, short x, short y, short width, short height, char *buffer)
145 short c1, c2, c3;
146 char *vga_ptr, *buffer_ptr;
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++;
162 #endif
164 void put_text(char page, int x, int y, char *text, char align)
166 int c1;
167 int t1;
168 int width;
169 int cur_x;
170 int image;
172 if (text == NULL || strlen(text) == 0)
173 return;
174 if (font_gobs == NULL)
175 return;
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;
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;
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;
226 c1 = 0;
227 while (text[c1] != 0) {
228 t1 = text[c1];
229 c1++;
230 if (t1 == ' ') {
231 cur_x += 5;
232 continue;
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;
267 void put_pob(char page, short x, short y, short image, char *pob_data, char mask, char *mask_pic)
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;
276 if (image < 0 || image >= *(short *) (pob_data))
277 return;
279 pob_offset = *(long *) (pob_data + image * 4 + 2);
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);
286 pob_offset += 8;
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;
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;
304 if ((y + height) > 256)
305 draw_height -= y + height - 256;
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;
320 pob_ptr += 4;
321 vga_ptr++;
322 mask_ptr += 4;
324 pob_ptr += width - c2 + c3;
325 vga_ptr += (400 - c2 + c3) >> 2;
326 mask_ptr += 400 - c2 + c3;
333 char pob_col(short x1, short y1, short image1, char *pob_data1, short x2, short y2, short image2, char *pob_data2)
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;
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;
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;
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;
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;
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;
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;
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++;
408 pob_ptr1 += width1 - check_width;
409 pob_ptr2 += width2 - check_width;
412 return 0;
417 short pob_width(short image, char *pob_data)
419 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2));
423 short pob_height(short image, char *pob_data)
425 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 2);
429 short pob_hs_x(short image, char *pob_data)
431 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 4);
435 short pob_hs_y(short image, char *pob_data)
437 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 6);
441 char read_pcx(FILE * handle, char *buffer, long buf_len, char *pal)
443 short c1;
444 short a, b;
445 long ofs1;
447 if (buffer != 0) {
448 fseek(handle, 128, SEEK_CUR);
450 ofs1 = 0;
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;
463 if (pal != 0) {
464 fseek(handle, 1, SEEK_CUR);
465 for (c1 = 0; c1 < 768; c1++)
466 pal[c1] = fgetc(handle) >> 2;
471 fclose(handle);
472 return 0;