]> icculus.org git repositories - crow/jumpnbump.git/blob - sdl/gfx.c
More seperation of drawing and gameing logic. Added a nice scaler function with a...
[crow/jumpnbump.git] / sdl / gfx.c
1 #include "globals.h"
2
3 #define SCALE_UP
4 #define JNB_BPP 8
5 static int current_pal[256];
6 static SDL_Surface *jnb_surface;
7 static int fullscreen = 0;
8 static int vinited = 0;
9 static unsigned char screen_buffer[2][JNB_WIDTH*JNB_HEIGHT];
10 static int drawing_enable = 0;
11 static char *background;
12 static int background_drawn;
13
14 typedef unsigned char uint8;
15 typedef unsigned short uint16;
16 typedef unsigned int uint32;
17
18 char *get_vgaptr(int page, int x, int y)
19 {
20         assert(drawing_enable==1);
21
22         return &screen_buffer[page][y*JNB_WIDTH+x];
23 }
24
25
26 void open_screen(void)
27 {
28         int lval = 0;
29
30         lval = SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_AUDIO);
31         if (lval < 0) {
32                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
33                 exit(EXIT_FAILURE);
34         }
35
36 #ifdef SCALE_UP
37         if (fullscreen)
38                 jnb_surface = SDL_SetVideoMode(JNB_WIDTH*2, JNB_HEIGHT*2, 16, SDL_SWSURFACE | SDL_FULLSCREEN);
39         else
40                 jnb_surface = SDL_SetVideoMode(JNB_WIDTH*2, JNB_HEIGHT*2, 16, SDL_SWSURFACE);
41 #else
42         if (fullscreen)
43                 jnb_surface = SDL_SetVideoMode(JNB_WIDTH, JNB_HEIGHT, JNB_BPP, SDL_SWSURFACE | SDL_FULLSCREEN);
44         else
45                 jnb_surface = SDL_SetVideoMode(JNB_WIDTH, JNB_HEIGHT, JNB_BPP, SDL_SWSURFACE);
46 #endif
47         if (!jnb_surface) {
48                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
49                 exit(EXIT_FAILURE);
50         }
51
52         SDL_ShowCursor(0);
53
54         vinited = 1;
55
56         memset(current_pal, 0, sizeof(current_pal));
57
58         return;
59 }
60
61
62 void fs_toggle()
63 {
64         if (!vinited) {
65                 fullscreen ^= 1;
66                 return;
67         }
68         if (SDL_WM_ToggleFullScreen(jnb_surface))
69                 fullscreen ^= 1;
70 }
71
72
73 void wait_vrt(int mix)
74 {
75         return;
76 }
77
78
79 void clear_page(int page, int color)
80 {
81         assert(drawing_enable==1);
82
83         memset((void *) get_vgaptr(page, 0, 0), color, JNB_WIDTH * JNB_HEIGHT);
84 }
85
86
87 void clear_lines(int page, int y, int count, int color)
88 {
89         int i;
90
91         assert(drawing_enable==1);
92
93         for (i=0; i<count; i++)
94                 if ((i+y)<JNB_HEIGHT)
95                         memset((void *) get_vgaptr(page, 0, i+y), color, JNB_WIDTH);
96 }
97
98
99 int get_pixel(int page, int x, int y)
100 {
101         assert(drawing_enable==1);
102
103         return *(char *) get_vgaptr(page, x, y);
104 }
105
106
107 void set_pixel(int page, int x, int y, int color)
108 {
109         assert(drawing_enable==1);
110
111         *(char *) get_vgaptr(page, x, y) = color;
112 }
113
114
115 static uint32 colorMask = 0xF7DEF7DE;
116 static uint32 lowPixelMask = 0x08210821;
117 static uint32 qcolorMask = 0xE79CE79C;
118 static uint32 qlowpixelMask = 0x18631863;
119 static uint32 redblueMask = 0xF81F;
120 static uint32 greenMask = 0x7E0;
121
122 int Init_2xSaI (uint32 BitFormat)
123 {
124     if (BitFormat == 565)
125     {
126         colorMask = 0xF7DEF7DE;
127         lowPixelMask = 0x08210821;
128         qcolorMask = 0xE79CE79C;
129         qlowpixelMask = 0x18631863;
130         redblueMask = 0xF81F;
131         greenMask = 0x7E0;
132     }
133     else if (BitFormat == 555)
134     {
135         colorMask = 0x7BDE7BDE;
136         lowPixelMask = 0x04210421;
137         qcolorMask = 0x739C739C;
138         qlowpixelMask = 0x0C630C63;
139         redblueMask = 0x7C1F;
140         greenMask = 0x3E0;
141     }
142     else
143     {
144         return 0;
145     }
146
147 #ifdef MMX
148     Init_2xSaIMMX (BitFormat);
149 #endif
150
151     return 1;
152 }
153
154
155 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
156
157 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
158
159 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
160         + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
161
162 #define GET_COLOR(x) (current_pal[(x)])
163
164
165 void Super2xSaI2 (uint8 *src, uint32 src_pitch, int src_bytes_per_pixel,
166                  uint8 *dst, uint32 dst_pitch, int dst_bytes_per_pixel,
167                  int width, int height)
168 {
169         unsigned char *src_line[4];
170         unsigned char *dst_line[2];
171         int x, y;
172         unsigned long color[16];
173
174         /* Point to the first 3 lines. */
175         src_line[0] = src;
176         src_line[1] = src;
177         src_line[2] = src + src_pitch;
178         src_line[3] = src + (src_pitch * 2);
179         
180         dst_line[0] = dst;
181         dst_line[1] = dst + dst_pitch;
182         
183         x = 0, y = 0;
184         
185         if (src_bytes_per_pixel == 1) {
186                 unsigned char *sbp;
187                 sbp = src_line[0];
188                 color[0] = GET_COLOR(*sbp);       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
189                 color[4] = color[0];   color[5] = color[0];   color[6] = GET_COLOR(*(sbp + 1));  color[7] = GET_COLOR(*(sbp + 2));
190                 sbp = src_line[2];
191                 color[8] = GET_COLOR(*sbp);     color[9] = color[8];     color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
192                 sbp = src_line[3];
193                 color[12] = GET_COLOR(*sbp);    color[13] = color[12];   color[14] = GET_COLOR(*(sbp + 1)); color[15] = GET_COLOR(*(sbp + 2));
194         } else if (src_bytes_per_pixel == 2) {
195                 unsigned short *sbp;
196                 sbp = (unsigned short*)src_line[0];
197                 color[0] = *sbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
198                 color[4] = color[0];   color[5] = color[0];   color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
199                 sbp = (unsigned short*)src_line[2];
200                 color[8] = *sbp;     color[9] = color[8];     color[10] = *(sbp + 1); color[11] = *(sbp + 2);
201                 sbp = (unsigned short*)src_line[3];
202                 color[12] = *sbp;    color[13] = color[12];   color[14] = *(sbp + 1); color[15] = *(sbp + 2);
203         } else {
204                 unsigned long *lbp;
205                 lbp = (unsigned long*)src_line[0];
206                 color[0] = *lbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
207                 color[4] = color[0];   color[5] = color[0];   color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
208                 lbp = (unsigned long*)src_line[2];
209                 color[8] = *lbp;     color[9] = color[8];     color[10] = *(lbp + 1); color[11] = *(lbp + 2);
210                 lbp = (unsigned long*)src_line[3];
211                 color[12] = *lbp;    color[13] = color[12];   color[14] = *(lbp + 1); color[15] = *(lbp + 2);
212         }
213
214         for (y = 0; y < height; y++) {
215         
216                 /* Todo: x = width - 2, x = width - 1 */
217                 
218                 for (x = 0; x < width; x++) {
219                         unsigned long product1a, product1b, product2a, product2b;
220
221 //---------------------------------------  B0 B1 B2 B3    0  1  2  3
222 //                                         4  5* 6  S2 -> 4  5* 6  7
223 //                                         1  2  3  S1    8  9 10 11
224 //                                         A0 A1 A2 A3   12 13 14 15
225 //--------------------------------------
226                         if (color[9] == color[6] && color[5] != color[10]) {
227                                 product2b = color[9];
228                                 product1b = product2b;
229                         }
230                         else if (color[5] == color[10] && color[9] != color[6]) {
231                                 product2b = color[5];
232                                 product1b = product2b;
233                         }
234                         else if (color[5] == color[10] && color[9] == color[6]) {
235                                 int r = 0;
236
237                                 r += GET_RESULT(color[6], color[5], color[8], color[13]);
238                                 r += GET_RESULT(color[6], color[5], color[4], color[1]);
239                                 r += GET_RESULT(color[6], color[5], color[14], color[11]);
240                                 r += GET_RESULT(color[6], color[5], color[2], color[7]);
241
242                                 if (r > 0)
243                                         product1b = color[6];
244                                 else if (r < 0)
245                                         product1b = color[5];
246                                 else
247                                         product1b = INTERPOLATE(color[5], color[6]);
248                                         
249                                 product2b = product1b;
250
251                         }
252                         else {
253                                 if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12])
254                                         product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]);
255                                 else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15])
256                                         product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]);
257                                 else
258                                         product2b = INTERPOLATE(color[9], color[10]);
259
260                                 if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0])
261                                         product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]);
262                                 else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3])
263                                         product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]);
264                                 else
265                                         product1b = INTERPOLATE(color[5], color[6]);
266                         }
267
268                         if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14])
269                                 product2a = INTERPOLATE(color[9], color[5]);
270                         else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12])
271                                 product2a = INTERPOLATE(color[9], color[5]);
272                         else
273                                 product2a = color[9];
274
275                         if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2])
276                                 product1a = INTERPOLATE(color[9], color[5]);
277                         else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0])
278                                 product1a = INTERPOLATE(color[9], color[5]);
279                         else
280                                 product1a = color[5];
281         
282                         if (dst_bytes_per_pixel == 2) {
283                                 *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
284                                 *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
285                         } else {
286                                 *((unsigned long *) (&dst_line[0][x * 8])) = product1a;
287                                 *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
288                                 *((unsigned long *) (&dst_line[1][x * 8])) = product2a;
289                                 *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
290                         }
291                         
292                         /* Move color matrix forward */
293                         color[0] = color[1]; color[4] = color[5]; color[8] = color[9];   color[12] = color[13];
294                         color[1] = color[2]; color[5] = color[6]; color[9] = color[10];  color[13] = color[14];
295                         color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15];
296                         
297                         if (x < width - 3) {
298                                 x+=3;
299                                 if (src_bytes_per_pixel == 1) {
300                                         color[3] = GET_COLOR(*(((unsigned char*)src_line[0]) + x));
301                                         color[7] = GET_COLOR(*(((unsigned char*)src_line[1]) + x));
302                                         color[11] = GET_COLOR(*(((unsigned char*)src_line[2]) + x));
303                                         color[15] = GET_COLOR(*(((unsigned char*)src_line[3]) + x));
304                                 } else if (src_bytes_per_pixel == 2) {
305                                         color[3] = *(((unsigned short*)src_line[0]) + x);                                       
306                                         color[7] = *(((unsigned short*)src_line[1]) + x);
307                                         color[11] = *(((unsigned short*)src_line[2]) + x);
308                                         color[15] = *(((unsigned short*)src_line[3]) + x);
309                                 } else {
310                                         color[3] = *(((unsigned long*)src_line[0]) + x);
311                                         color[7] = *(((unsigned long*)src_line[1]) + x);
312                                         color[11] = *(((unsigned long*)src_line[2]) + x);
313                                         color[15] = *(((unsigned long*)src_line[3]) + x);
314                                 }
315                                 x-=3;
316                         }
317                 }
318
319                 /* We're done with one line, so we shift the source lines up */
320                 src_line[0] = src_line[1];
321                 src_line[1] = src_line[2];
322                 src_line[2] = src_line[3];              
323
324                 /* Read next line */
325                 if (y + 3 >= height)
326                         src_line[3] = src_line[2];
327                 else
328                         src_line[3] = src_line[2] + src_pitch;
329                         
330                 /* Then shift the color matrix up */
331                 if (src_bytes_per_pixel == 1) {
332                         unsigned char *sbp;
333                         sbp = src_line[0];
334                         color[0] = GET_COLOR(*sbp);     color[1] = color[0];    color[2] = GET_COLOR(*(sbp + 1));  color[3] = GET_COLOR(*(sbp + 2));
335                         sbp = src_line[1];
336                         color[4] = GET_COLOR(*sbp);     color[5] = color[4];    color[6] = GET_COLOR(*(sbp + 1));  color[7] = GET_COLOR(*(sbp + 2));
337                         sbp = src_line[2];
338                         color[8] = GET_COLOR(*sbp);     color[9] = color[8];    color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
339                         sbp = src_line[3];
340                         color[12] = GET_COLOR(*sbp);    color[13] = color[12];  color[14] = GET_COLOR(*(sbp + 1)); color[15] = GET_COLOR(*(sbp + 2));
341                 } else if (src_bytes_per_pixel == 2) {
342                         unsigned short *sbp;
343                         sbp = (unsigned short*)src_line[0];
344                         color[0] = *sbp;     color[1] = color[0];    color[2] = *(sbp + 1);  color[3] = *(sbp + 2);
345                         sbp = (unsigned short*)src_line[1];
346                         color[4] = *sbp;     color[5] = color[4];    color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
347                         sbp = (unsigned short*)src_line[2];
348                         color[8] = *sbp;     color[9] = color[9];    color[10] = *(sbp + 1); color[11] = *(sbp + 2);
349                         sbp = (unsigned short*)src_line[3];
350                         color[12] = *sbp;    color[13] = color[12];  color[14] = *(sbp + 1); color[15] = *(sbp + 2);
351                 } else {
352                         unsigned long *lbp;
353                         lbp = (unsigned long*)src_line[0];
354                         color[0] = *lbp;     color[1] = color[0];    color[2] = *(lbp + 1);  color[3] = *(lbp + 2);
355                         lbp = (unsigned long*)src_line[1];
356                         color[4] = *lbp;     color[5] = color[4];    color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
357                         lbp = (unsigned long*)src_line[2];
358                         color[8] = *lbp;     color[9] = color[9];    color[10] = *(lbp + 1); color[11] = *(lbp + 2);
359                         lbp = (unsigned long*)src_line[3];
360                         color[12] = *lbp;    color[13] = color[12];  color[14] = *(lbp + 1); color[15] = *(lbp + 2);
361                 }
362                 
363                 if (y < height - 1) {
364                         dst_line[0] += dst_pitch * 2;
365                         dst_line[1] += dst_pitch * 2;
366                 }
367         }
368 }
369
370
371 void flippage(int page)
372 {
373         int h;
374         int w;
375         char *src;
376         char *dest;
377
378         assert(drawing_enable==0);
379
380         SDL_LockSurface(jnb_surface);
381         dest=(char *)jnb_surface->pixels;
382         src=screen_buffer[page];
383 #ifdef SCALE_UP
384         Super2xSaI2(src, JNB_WIDTH, 1, dest, jnb_surface->pitch, 2, JNB_WIDTH, JNB_HEIGHT);
385 #else
386         w=(jnb_surface->clip_rect.w>JNB_WIDTH)?(JNB_WIDTH):(jnb_surface->clip_rect.w);
387         h=(jnb_surface->clip_rect.h>JNB_HEIGHT)?(JNB_HEIGHT):(jnb_surface->clip_rect.h);
388         for (; h>0; h--) {
389                 memcpy(dest,src,w);
390                 dest+=jnb_surface->pitch;
391                 src+=JNB_WIDTH;
392         }
393 #endif
394         SDL_UnlockSurface(jnb_surface);
395         SDL_Flip(jnb_surface);
396 }
397
398
399 void draw_begin(void)
400 {
401         assert(drawing_enable==0);
402
403         drawing_enable = 1;
404         if (background_drawn == 0) {
405                 if (background) {
406                         put_block(0, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
407                         put_block(1, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
408                 } else {
409                         clear_page(0, 0);
410                         clear_page(1, 0);
411                 }
412                 background_drawn = 1;
413         }
414 }
415
416
417 void draw_end(void)
418 {
419         assert(drawing_enable==1);
420
421         drawing_enable = 0;
422 }
423
424
425 void setpalette(int index, int count, char *palette)
426 {
427         SDL_Color colors[256];
428         int i;
429
430         assert(drawing_enable==0);
431
432         for (i = 0; i < count; i++) {
433                 colors[i+index].r = palette[i * 3 + 0] << 2;
434                 colors[i+index].g = palette[i * 3 + 1] << 2;
435                 colors[i+index].b = palette[i * 3 + 2] << 2;
436                 current_pal[i+index] = SDL_MapRGB(jnb_surface->format, colors[i+index].r, colors[i+index].g, colors[i+index].b);
437         }
438 #ifndef SCALE_UP
439         SDL_SetColors(jnb_surface, &colors[index], index, count);
440 #endif
441 }
442
443
444 void fillpalette(int red, int green, int blue)
445 {
446         SDL_Color colors[256];
447         int i;
448
449         assert(drawing_enable==0);
450
451         for (i = 0; i < 256; i++) {
452                 colors[i].r = red << 2;
453                 colors[i].g = green << 2;
454                 colors[i].b = blue << 2;
455                 current_pal[i] = SDL_MapRGB(jnb_surface->format, colors[i].r, colors[i].g, colors[i].b);
456         }
457 #ifndef SCALE_UP
458         SDL_SetColors(jnb_surface, colors, 0, 256);
459 #endif
460 }
461
462
463 void get_block(int page, int x, int y, int width, int height, char *buffer)
464 {
465         short w, h;
466         char *buffer_ptr, *vga_ptr;
467
468         assert(drawing_enable==1);
469
470         if (x < 0)
471                 x = 0;
472         if (y < 0)
473                 y = 0;
474         if (y + height >= JNB_HEIGHT)
475                 height = JNB_HEIGHT - y;
476         if (x + width >= JNB_WIDTH)
477                 width = JNB_WIDTH - x;
478
479         for (h = 0; h < height; h++) {
480                 buffer_ptr = &buffer[h * width];
481
482                 vga_ptr = get_vgaptr(page, x, h + y);
483
484                 for (w = 0; w < width; w++) {
485                         unsigned char ch;
486                         ch = *vga_ptr;
487                         *buffer_ptr = ch;
488                         buffer_ptr++;
489                         vga_ptr++;
490                 }
491         }
492
493 }
494
495
496 void put_block(int page, int x, int y, int width, int height, char *buffer)
497 {
498         short w, h;
499         char *vga_ptr, *buffer_ptr;
500
501         assert(drawing_enable==1);
502
503         if (x < 0)
504                 x = 0;
505         if (y < 0)
506                 y = 0;
507         if (y + height >= JNB_HEIGHT)
508                 height = JNB_HEIGHT - y;
509         if (x + width >= JNB_WIDTH)
510                 width = JNB_WIDTH - x;
511
512         for (h = 0; h < height; h++) {
513                 vga_ptr = get_vgaptr(page, x, y + h);
514
515                 buffer_ptr = &buffer[h * width];
516                 for (w = 0; w < width; w++) {
517                         *vga_ptr = *buffer_ptr;
518                         vga_ptr++;
519                         buffer_ptr++;
520                 }
521         }
522 }
523
524
525 void put_text(int page, int x, int y, char *text, int align)
526 {
527         int c1;
528         int t1;
529         int width;
530         int cur_x;
531         int image;
532
533         assert(drawing_enable==1);
534
535         if (text == NULL || strlen(text) == 0)
536                 return;
537         if (font_gobs == NULL)
538                 return;
539
540         width = 0;
541         c1 = 0;
542         while (text[c1] != 0) {
543                 t1 = text[c1];
544                 c1++;
545                 if (t1 == ' ') {
546                         width += 5;
547                         continue;
548                 }
549                 if (t1 >= 33 && t1 <= 34)
550                         image = t1 - 33;
551
552                 else if (t1 >= 39 && t1 <= 41)
553                         image = t1 - 37;
554
555                 else if (t1 >= 44 && t1 <= 59)
556                         image = t1 - 39;
557
558                 else if (t1 >= 64 && t1 <= 90)
559                         image = t1 - 43;
560
561                 else if (t1 >= 97 && t1 <= 122)
562                         image = t1 - 49;
563
564                 else if (t1 == '~')
565                         image = 74;
566
567                 else if (t1 == 0x84)
568                         image = 75;
569
570                 else if (t1 == 0x86)
571                         image = 76;
572
573                 else if (t1 == 0x8e)
574                         image = 77;
575
576                 else if (t1 == 0x8f)
577                         image = 78;
578
579                 else if (t1 == 0x94)
580                         image = 79;
581
582                 else if (t1 == 0x99)
583                         image = 80;
584
585                 else
586                         continue;
587                 width += pob_width(image, font_gobs) + 1;
588         }
589
590         switch (align) {
591         case 0:
592                 cur_x = x;
593                 break;
594         case 1:
595                 cur_x = x - width;
596                 break;
597         case 2:
598                 cur_x = x - width / 2;
599                 break;
600         default:
601                 cur_x = 0;      /* this should cause error? -Chuck */
602                 break;
603         }
604         c1 = 0;
605
606         while (text[c1] != 0) {
607                 t1 = text[c1];
608                 c1++;
609                 if (t1 == ' ') {
610                         cur_x += 5;
611                         continue;
612                 }
613                 if (t1 >= 33 && t1 <= 34)
614                         image = t1 - 33;
615
616                 else if (t1 >= 39 && t1 <= 41)
617                         image = t1 - 37;
618
619                 else if (t1 >= 44 && t1 <= 59)
620                         image = t1 - 39;
621
622                 else if (t1 >= 64 && t1 <= 90)
623                         image = t1 - 43;
624
625                 else if (t1 >= 97 && t1 <= 122)
626                         image = t1 - 49;
627
628                 else if (t1 == '~')
629                         image = 74;
630
631                 else if (t1 == 0x84)
632                         image = 75;
633
634                 else if (t1 == 0x86)
635                         image = 76;
636
637                 else if (t1 == 0x8e)
638                         image = 77;
639
640                 else if (t1 == 0x8f)
641                         image = 78;
642
643                 else if (t1 == 0x94)
644                         image = 79;
645
646                 else if (t1 == 0x99)
647                         image = 80;
648
649                 else
650                         continue;
651                 put_pob(page, cur_x, y, image, font_gobs, 1, mask_pic);
652                 cur_x += pob_width(image, font_gobs) + 1;
653         }
654 }
655
656
657 void put_pob(int page, int x, int y, int image, char *pob_data, int mask, char *mask_pic)
658 {
659         long c1, c2;
660         long pob_offset;
661         char *pob_ptr, *vga_ptr, *mask_ptr;
662         long width, height;
663         long draw_width, draw_height;
664         char colour;
665
666         assert(drawing_enable==1);
667
668         if (image < 0 || image >= *(short *) (pob_data))
669                 return;
670
671         vga_ptr = get_vgaptr(page, 0, 0);
672         pob_offset = *(unsigned long *) (pob_data + (image * 4) + 2);
673         width = draw_width = *(short *) (pob_data + pob_offset);
674         height = draw_height = *(short *) (pob_data + pob_offset + 2);
675         x -= *(short *) (pob_data + pob_offset + 4);
676         y -= *(short *) (pob_data + pob_offset + 6);
677         pob_offset += 8;
678         if ((x + width) <= 0 || x >= 400)
679                 return;
680         if ((y + height) <= 0 || y >= 256)
681                 return;
682         if (x < 0) {
683                 pob_offset -= x;
684                 draw_width += x;
685                 x = 0;
686         }
687         if ((x + width) > 400)
688                 draw_width -= x + width - 400;
689         if (y < 0) {
690                 pob_offset += -y * width;
691                 draw_height -= -y;
692                 y = 0;
693         }
694         if ((y + height) > 256)
695                 draw_height -= y + height - 256;
696
697         pob_ptr = &pob_data[pob_offset];
698
699
700         vga_ptr = get_vgaptr(page, x, y);
701         mask_ptr = (char *) (mask_pic + (y * 400) + x);
702         for (c1 = 0; c1 < draw_height; c1++) {
703                 for (c2 = 0; c2 < draw_width; c2++) {
704                         colour = *mask_ptr;
705                         if (mask == 0 || (mask == 1 && colour == 0)) {
706                                 colour = *pob_ptr;
707                                 if (colour != 0)
708                                         *vga_ptr = colour;
709                         }
710                         pob_ptr++;
711                         vga_ptr++;
712                         mask_ptr++;
713                 }
714                 pob_ptr += width - c2;
715                 vga_ptr += (400 - c2);
716                 mask_ptr += (400 - c2);
717         }
718 }
719
720
721 int pob_col(int x1, int y1, int image1, char *pob_data1, int x2, int y2, int image2, char *pob_data2)
722 {
723         short c1, c2;
724         long pob_offset1, pob_offset2;
725         short width1, width2;
726         short height1, height2;
727         short check_width, check_height;
728         char *pob_ptr1, *pob_ptr2;
729
730         pob_offset1 = *(long *) (pob_data1 + image1 * 4 + 2);
731         width1 = *(short *) (pob_data1 + pob_offset1);
732         height1 = *(short *) (pob_data1 + pob_offset1 + 2);
733         x1 -= *(short *) (pob_data1 + pob_offset1 + 4);
734         y1 -= *(short *) (pob_data1 + pob_offset1 + 6);
735         pob_offset1 += 8;
736         pob_offset2 = *(long *) (pob_data2 + image2 * 4 + 2);
737         width2 = *(short *) (pob_data2 + pob_offset2);
738         height2 = *(short *) (pob_data2 + pob_offset2 + 2);
739         x2 -= *(short *) (pob_data2 + pob_offset2 + 4);
740         y2 -= *(short *) (pob_data2 + pob_offset2 + 6);
741         pob_offset2 += 8;
742
743         if (x1 < x2) {
744                 if ((x1 + width1) <= x2)
745                         return 0;
746
747                 else if ((x1 + width1) <= (x2 + width2)) {
748                         pob_offset1 += x2 - x1;
749                         check_width = x1 + width1 - x2;
750                 }
751
752                 else {
753                         pob_offset1 += x2 - x1;
754                         check_width = width2;
755                 }
756         }
757
758         else {
759                 if ((x2 + width2) <= x1)
760                         return 0;
761
762                 else if ((x2 + width2) <= (x1 + width1)) {
763                         pob_offset2 += x1 - x2;
764                         check_width = x2 + width2 - x1;
765                 }
766
767                 else {
768                         pob_offset2 += x1 - x2;
769                         check_width = width1;
770                 }
771         }
772         if (y1 < y2) {
773                 if ((y1 + height1) <= y2)
774                         return 0;
775
776                 else if ((y1 + height1) <= (y2 + height2)) {
777                         pob_offset1 += (y2 - y1) * width1;
778                         check_height = y1 + height1 - y2;
779                 }
780
781                 else {
782                         pob_offset1 += (y2 - y1) * width1;
783                         check_height = height2;
784                 }
785         }
786
787         else {
788                 if ((y2 + height2) <= y1)
789                         return 0;
790
791                 else if ((y2 + height2) <= (y1 + height1)) {
792                         pob_offset2 += (y1 - y2) * width2;
793                         check_height = y2 + height2 - y1;
794                 }
795
796                 else {
797                         pob_offset2 += (y1 - y2) * width2;
798                         check_height = height1;
799                 }
800         }
801         pob_ptr1 = (char *) (pob_data1 + pob_offset1);
802         pob_ptr2 = (char *) (pob_data2 + pob_offset2);
803         for (c1 = 0; c1 < check_height; c1++) {
804                 for (c2 = 0; c2 < check_width; c2++) {
805                         if (*pob_ptr1 != 0 && *pob_ptr2 != 0)
806                                 return 1;
807                         pob_ptr1++;
808                         pob_ptr2++;
809                 }
810                 pob_ptr1 += width1 - check_width;
811                 pob_ptr2 += width2 - check_width;
812         }
813         return 0;
814 }
815
816
817 int pob_width(int image, char *pob_data)
818 {
819         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2));
820 }
821
822
823 int pob_height(int image, char *pob_data)
824 {
825         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 2);
826 }
827
828
829 int pob_hs_x(int image, char *pob_data)
830 {
831         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 4);
832 }
833
834
835 int pob_hs_y(int image, char *pob_data)
836 {
837         return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 6);
838 }
839
840
841 int read_pcx(FILE * handle, char *buffer, int buf_len, char *pal)
842 {
843         short c1;
844         short a, b;
845         long ofs1;
846         if (buffer != 0) {
847                 fseek(handle, 128, SEEK_CUR);
848                 ofs1 = 0;
849                 while (ofs1 < buf_len) {
850                         a = fgetc(handle);
851                         if ((a & 0xc0) == 0xc0) {
852                                 b = fgetc(handle);
853                                 a &= 0x3f;
854                                 for (c1 = 0; c1 < a && ofs1 < buf_len; c1++)
855                                         buffer[ofs1++] = (char) b;
856                         } else
857                                 buffer[ofs1++] = (char) a;
858                 }
859                 if (pal != 0) {
860                         fseek(handle, 1, SEEK_CUR);
861                         for (c1 = 0; c1 < 768; c1++)
862                                 pal[c1] = fgetc(handle) >> 2;
863                 }
864         }
865         return 0;
866 }
867
868
869 void register_background(char *pixels)
870 {
871         background = pixels;
872         background_drawn = 0;
873 }