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