]> icculus.org git repositories - crow/jumpnbump.git/blob - sdl/gfx.c
Fixes for SDL and VisualC.
[crow/jumpnbump.git] / sdl / gfx.c
1 #include "globals.h"
2
3 #define JNB_BPP 8
4 static SDL_Surface *jnb_surface, *jnb_surface_page1;
5 static int fullscreen = 0;
6 static int vinited = 0;
7
8 void open_screen(void)
9 {
10         int lval = 0;
11
12         lval = SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_AUDIO);
13         if (lval < 0) {
14                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
15                 exit(EXIT_FAILURE);
16         }
17
18         jnb_surface = SDL_SetVideoMode(JNB_WIDTH, JNB_HEIGHT, JNB_BPP, SDL_HWSURFACE | SDL_DOUBLEBUF);
19         if (!jnb_surface) {
20                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
21                 exit(EXIT_FAILURE);
22         }
23
24         jnb_surface_page1 = SDL_CreateRGBSurface(SDL_HWSURFACE, JNB_WIDTH, JNB_HEIGHT, JNB_BPP, 0, 0, 0, 0);
25         if (!jnb_surface_page1) {
26                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
27                 exit(EXIT_FAILURE);
28         }
29
30         SDL_ShowCursor(0);
31
32         if (fullscreen) {
33                 lval = SDL_WM_ToggleFullScreen(jnb_surface);
34                 if (lval != 1) {
35                         fprintf(stderr, "SDL WARNING: %s\n", SDL_GetError());
36                         fullscreen = 0;
37                 }
38         }
39
40         vinited = 1;
41
42         return;
43 }
44
45 void fs_toggle()
46 {
47         if (!vinited) {
48                 fullscreen ^= 1;
49                 return;
50         }
51         if (SDL_WM_ToggleFullScreen(jnb_surface))
52                 fullscreen ^= 1;
53 }
54
55 void wait_vrt(void)
56 {
57         return;
58 }
59
60 void flippage(long page)
61 {
62         SDL_Surface *which;
63
64         which = (page == 1) ? jnb_surface_page1 : jnb_surface;
65
66         SDL_UpdateRect(which, 0, 0, 0, 0);
67 }
68
69 char *get_vgaptr(long page, long x, long y)
70 {
71         SDL_Surface *which;
72
73         which = (page == 1) ? jnb_surface_page1 : jnb_surface;
74
75         return (char *) &(((char *) which->pixels)[(y * JNB_WIDTH) + x]);
76 }
77
78 void setpalette(int index, int count, char *palette)
79 {
80         SDL_Color colors[256];
81         int i;
82
83         for (i = 0; i < count; i++) {
84                 colors[i].r = palette[i * 3 + 0] << 2;
85                 colors[i].g = palette[i * 3 + 1] << 2;
86                 colors[i].b = palette[i * 3 + 2] << 2;
87         }
88         SDL_SetColors(jnb_surface, colors, index, count);
89         SDL_SetColors(jnb_surface_page1, colors, index, count);
90 }
91
92 void fillpalette(int red, int green, int blue)
93 {
94         SDL_Color colors[256];
95         int i;
96
97         for (i = 0; i < 256; i++) {
98                 colors[i].r = red << 2;
99                 colors[i].g = green << 2;
100                 colors[i].b = blue << 2;
101         }
102         SDL_SetColors(jnb_surface, colors, 0, 256);
103         SDL_SetColors(jnb_surface_page1, colors, 0, 256);
104 }
105
106 void get_block(char page, long x, long y, long width, long height, char *buffer)
107 {
108         short w, h;
109         char *buffer_ptr, *vga_ptr;
110
111         if (x < 0)
112                 x = 0;
113         if (y < 0)
114                 y = 0;
115         if (y + height >= JNB_HEIGHT)
116                 height = JNB_HEIGHT - y;
117         if (x + width >= JNB_WIDTH)
118                 width = JNB_WIDTH - x;
119
120         for (h = 0; h < height; h++) {
121                 buffer_ptr = &buffer[h * width];
122
123                 vga_ptr = get_vgaptr(page, x, h + y);
124
125                 for (w = 0; w < width; w++) {
126                         unsigned char ch;
127                         ch = *vga_ptr;
128                         *buffer_ptr = ch;
129                         buffer_ptr++;
130                         vga_ptr++;
131                 }
132         }
133
134 }
135
136 void put_block(char page, long x, long y, long width, long height, char *buffer)
137 {
138         short w, h;
139         char *vga_ptr, *buffer_ptr;
140
141         if (x < 0)
142                 x = 0;
143         if (y < 0)
144                 y = 0;
145         if (y + height >= JNB_HEIGHT)
146                 height = JNB_HEIGHT - y;
147         if (x + width >= JNB_WIDTH)
148                 width = JNB_WIDTH - x;
149
150         for (h = 0; h < height; h++) {
151                 vga_ptr = get_vgaptr(page, x, y + h);
152
153                 buffer_ptr = &buffer[h * width];
154                 for (w = 0; w < width; w++) {
155                         *vga_ptr = *buffer_ptr;
156                         vga_ptr++;
157                         buffer_ptr++;
158                 }
159         }
160 }
161
162 void put_text(char page, int x, int y, char *text, char align)
163 {
164         int c1;
165         int t1;
166         int width;
167         int cur_x;
168         int image;
169
170         if (text == NULL || strlen(text) == 0)
171                 return;
172         if (font_gobs == NULL)
173                 return;
174
175         width = 0;
176         c1 = 0;
177         while (text[c1] != 0) {
178                 t1 = text[c1];
179                 c1++;
180                 if (t1 == ' ') {
181                         width += 5;
182                         continue;
183                 }
184                 if (t1 >= 33 && t1 <= 34)
185                         image = t1 - 33;
186
187                 else if (t1 >= 39 && t1 <= 41)
188                         image = t1 - 37;
189
190                 else if (t1 >= 44 && t1 <= 59)
191                         image = t1 - 39;
192
193                 else if (t1 >= 64 && t1 <= 90)
194                         image = t1 - 43;
195
196                 else if (t1 >= 97 && t1 <= 122)
197                         image = t1 - 49;
198
199                 else if (t1 == '~')
200                         image = 74;
201
202                 else if (t1 == 0x84)
203                         image = 75;
204
205                 else if (t1 == 0x86)
206                         image = 76;
207
208                 else if (t1 == 0x8e)
209                         image = 77;
210
211                 else if (t1 == 0x8f)
212                         image = 78;
213
214                 else if (t1 == 0x94)
215                         image = 79;
216
217                 else if (t1 == 0x99)
218                         image = 80;
219                 else
220                         continue;
221                 width += pob_width(image, font_gobs) + 1;
222         }
223
224         switch (align) {
225         case 0:
226                 cur_x = x;
227                 break;
228         case 1:
229                 cur_x = x - width;
230                 break;
231         case 2:
232                 cur_x = x - width / 2;
233                 break;
234         default:
235                 cur_x = 0;      /* this should cause error? -Chuck */
236                 break;
237         }
238         c1 = 0;
239
240         while (text[c1] != 0) {
241                 t1 = text[c1];
242                 c1++;
243                 if (t1 == ' ') {
244                         cur_x += 5;
245                         continue;
246                 }
247                 if (t1 >= 33 && t1 <= 34)
248                         image = t1 - 33;
249
250                 else if (t1 >= 39 && t1 <= 41)
251                         image = t1 - 37;
252
253                 else if (t1 >= 44 && t1 <= 59)
254                         image = t1 - 39;
255
256                 else if (t1 >= 64 && t1 <= 90)
257                         image = t1 - 43;
258
259                 else if (t1 >= 97 && t1 <= 122)
260                         image = t1 - 49;
261
262                 else if (t1 == '~')
263                         image = 74;
264
265                 else if (t1 == '\84')
266                         image = 75;
267
268                 else if (t1 == '\86')
269                         image = 76;
270
271                 else if (t1 == '\8e')
272                         image = 77;
273
274                 else if (t1 == '\8f')
275                         image = 78;
276
277                 else if (t1 == '\94')
278                         image = 79;
279
280                 else if (t1 == '\99')
281                         image = 80;
282
283                 else
284                         continue;
285                 put_pob(page, cur_x, y, image, font_gobs, 1, mask_pic);
286                 cur_x += pob_width(image, font_gobs) + 1;
287         }
288 }
289
290 void put_pob(char page, short x, short y, short image, char *pob_data, char mask, char *mask_pic)
291 {
292         long c1, c2;
293         long pob_offset;
294         char *pob_ptr, *vga_ptr, *mask_ptr;
295         long width, height;
296         long draw_width, draw_height;
297         char colour;
298
299         if (image < 0 || image >= *(short *) (pob_data))
300                 return;
301
302         vga_ptr = get_vgaptr(page, 0, 0);
303         pob_offset = *(unsigned long *) (pob_data + (image * 4) + 2);
304         width = draw_width = *(short *) (pob_data + pob_offset);
305         height = draw_height = *(short *) (pob_data + pob_offset + 2);
306         x -= *(short *) (pob_data + pob_offset + 4);
307         y -= *(short *) (pob_data + pob_offset + 6);
308         pob_offset += 8;
309         if ((x + width) <= 0 || x >= 400)
310                 return;
311         if ((y + height) <= 0 || y >= 256)
312                 return;
313         if (x < 0) {
314                 pob_offset -= x;
315                 draw_width += x;
316                 x = 0;
317         }
318         if ((x + width) > 400)
319                 draw_width -= x + width - 400;
320         if (y < 0) {
321                 pob_offset += -y * width;
322                 draw_height -= -y;
323                 y = 0;
324         }
325         if ((y + height) > 256)
326                 draw_height -= y + height - 256;
327
328         pob_ptr = &pob_data[pob_offset];
329
330
331 #ifndef USE_SDL
332         vga_ptr = (char *) (0xa0000 + (long) (page << 15) + (long) y * 100L + ((x + c3) >> 2) + __djgpp_conventional_base);
333 #else
334         vga_ptr = get_vgaptr(page, x, y);
335 #endif
336         mask_ptr = (char *) (mask_pic + (y * 400) + x);
337         for (c1 = 0; c1 < draw_height; c1++) {
338                 for (c2 = 0; c2 < draw_width; c2++) {
339                         colour = *mask_ptr;
340                         if (mask == 0 || (mask == 1 && colour == 0)) {
341                                 colour = *pob_ptr;
342                                 if (colour != 0)
343                                         *vga_ptr = colour;
344                         }
345                         pob_ptr++;
346                         vga_ptr++;
347                         mask_ptr++;
348                 }
349                 pob_ptr += width - c2;
350                 vga_ptr += (400 - c2);
351                 mask_ptr += (400 - c2);
352         }
353 }
354
355 char pob_col(short x1, short y1, short image1, char *pob_data1, short x2, short y2, short image2, char *pob_data2)
356 {
357         short c1, c2;
358         long pob_offset1, pob_offset2;
359         short width1, width2;
360         short height1, height2;
361         short check_width, check_height;
362         char *pob_ptr1, *pob_ptr2;
363
364         pob_offset1 = *(long *) (pob_data1 + image1 * 4 + 2);
365         width1 = *(short *) (pob_data1 + pob_offset1);
366         height1 = *(short *) (pob_data1 + pob_offset1 + 2);
367         x1 -= *(short *) (pob_data1 + pob_offset1 + 4);
368         y1 -= *(short *) (pob_data1 + pob_offset1 + 6);
369         pob_offset1 += 8;
370         pob_offset2 = *(long *) (pob_data2 + image2 * 4 + 2);
371         width2 = *(short *) (pob_data2 + pob_offset2);
372         height2 = *(short *) (pob_data2 + pob_offset2 + 2);
373         x2 -= *(short *) (pob_data2 + pob_offset2 + 4);
374         y2 -= *(short *) (pob_data2 + pob_offset2 + 6);
375         pob_offset2 += 8;
376
377         if (x1 < x2) {
378                 if ((x1 + width1) <= x2)
379                         return 0;
380
381                 else if ((x1 + width1) <= (x2 + width2)) {
382                         pob_offset1 += x2 - x1;
383                         check_width = x1 + width1 - x2;
384                 }
385
386                 else {
387                         pob_offset1 += x2 - x1;
388                         check_width = width2;
389                 }
390         }
391
392         else {
393                 if ((x2 + width2) <= x1)
394                         return 0;
395
396                 else if ((x2 + width2) <= (x1 + width1)) {
397                         pob_offset2 += x1 - x2;
398                         check_width = x2 + width2 - x1;
399                 }
400
401                 else {
402                         pob_offset2 += x1 - x2;
403                         check_width = width1;
404                 }
405         }
406         if (y1 < y2) {
407                 if ((y1 + height1) <= y2)
408                         return 0;
409
410                 else if ((y1 + height1) <= (y2 + height2)) {
411                         pob_offset1 += (y2 - y1) * width1;
412                         check_height = y1 + height1 - y2;
413                 }
414
415                 else {
416                         pob_offset1 += (y2 - y1) * width1;
417                         check_height = height2;
418                 }
419         }
420
421         else {
422                 if ((y2 + height2) <= y1)
423                         return 0;
424
425                 else if ((y2 + height2) <= (y1 + height1)) {
426                         pob_offset2 += (y1 - y2) * width2;
427                         check_height = y2 + height2 - y1;
428                 }
429
430                 else {
431                         pob_offset2 += (y1 - y2) * width2;
432                         check_height = height1;
433                 }
434         }
435         pob_ptr1 = (char *) (pob_data1 + pob_offset1);
436         pob_ptr2 = (char *) (pob_data2 + pob_offset2);
437         for (c1 = 0; c1 < check_height; c1++) {
438                 for (c2 = 0; c2 < check_width; c2++) {
439                         if (*pob_ptr1 != 0 && *pob_ptr2 != 0)
440                                 return 1;
441                         pob_ptr1++;
442                         pob_ptr2++;
443                 }
444                 pob_ptr1 += width1 - check_width;
445                 pob_ptr2 += width2 - check_width;
446         }
447         return 0;
448 }
449
450 short pob_width(short image, char *pob_data)
451 {
452         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2));
453 }
454
455 short pob_height(short image, char *pob_data)
456 {
457         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 2);
458 }
459
460 short pob_hs_x(short image, char *pob_data)
461 {
462         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 4);
463 }
464
465 short pob_hs_y(short image, char *pob_data)
466 {
467         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 6);
468 }
469
470 char read_pcx(FILE * handle, char *buffer, long buf_len, char *pal)
471 {
472         short c1;
473         short a, b;
474         long ofs1;
475         if (buffer != 0) {
476                 fseek(handle, 128, SEEK_CUR);
477                 ofs1 = 0;
478                 while (ofs1 < buf_len) {
479                         a = fgetc(handle);
480                         if ((a & 0xc0) == 0xc0) {
481                                 b = fgetc(handle);
482                                 a &= 0x3f;
483                                 for (c1 = 0; c1 < a && ofs1 < buf_len; c1++)
484                                         buffer[ofs1++] = (char) b;
485                         } else
486                                 buffer[ofs1++] = (char) a;
487                 }
488                 if (pal != 0) {
489                         fseek(handle, 1, SEEK_CUR);
490                         for (c1 = 0; c1 < 768; c1++)
491                                 pal[c1] = fgetc(handle) >> 2;
492                 }
493         }
494         return 0;
495 }
496
497 #ifndef _MSC_VER
498 long filelength(int handle)
499 {
500         struct stat buf;
501
502         if (fstat(handle, &buf) == -1) {
503                 perror("filelength");
504                 exit(EXIT_FAILURE);
505         }
506
507         return buf.st_size;
508 }
509 #endif