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