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