]> icculus.org git repositories - crow/jumpnbump.git/blob - sdl/gfx.c
Added FreeBSD makefiles and related changes.
[crow/jumpnbump.git] / sdl / gfx.c
1 /*
2  * gfx.c
3  * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
4  * 
5  * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
6  *
7  * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
8  *
9  * Portions of this code are from the MPEG software simulation group
10  * idct implementation. This code will be replaced with a new
11  * implementation soon.
12  *
13  * This file is part of Jump'n'Bump.
14  *
15  * Jump'n'Bump is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * Jump'n'Bump is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  */
29
30 #include "globals.h"
31 #include "SDL_endian.h"
32
33 #ifdef _MSC_VER
34     #include "jumpnbump32.xpm"
35 #elif __APPLE__
36     #include "jumpnbump128.xpm"
37 #else
38     #include "jumpnbump64.xpm"
39 #endif
40 SDL_Surface *icon;
41
42 int screen_width=400;
43 int screen_height=256;
44 int screen_pitch=400;
45 int scale_up=0;
46 int bytes_per_pixel=1;
47 int dirty_block_shift=4;
48
49 static int current_pal[256];
50 static SDL_Surface *jnb_surface;
51 static int fullscreen = 0;
52 static int vinited = 0;
53 static void *screen_buffer[2];
54 static int drawing_enable = 0;
55 static void *background = NULL;
56 static int background_drawn;
57 static void *mask = NULL;
58 static int dirty_blocks[2][25*16*2];
59
60 static SDL_Surface *load_xpm_from_array(char **xpm)
61 {
62 #define NEXT_TOKEN { \
63         while ((*p != ' ') && (*p != '\t')) p++; \
64         while ((*p == ' ') || (*p == '\t')) p++; }
65
66         SDL_Surface *surface;
67         char *p;
68         int width;
69         int height;
70         int colors;
71         int images;
72         int color;
73         int pal[256];
74         int x,y;
75
76         p = *xpm++;
77
78         width = atoi(p);
79         if (width <= 0)
80                 return NULL;
81         NEXT_TOKEN;
82
83         height = atoi(p);
84         if (height <= 0)
85                 return NULL;
86         NEXT_TOKEN;
87
88         colors = atoi(p);
89         if (colors <= 0)
90                 return NULL;
91         NEXT_TOKEN;
92
93         images = atoi(p);
94         if (images <= 0)
95                 return NULL;
96
97         surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
98         if (!surface)
99                 return NULL;
100
101         SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
102         while (colors--) {
103                 p = *xpm++;
104
105                 color = *p++;
106                 NEXT_TOKEN;
107
108                 if (*p++ != 'c') {
109                         SDL_FreeSurface(surface);
110                         return NULL;
111                 }
112                 NEXT_TOKEN;
113
114                 if (*p == '#')
115                         pal[color] = strtoul(++p, NULL, 16) | 0xff000000;
116                 else
117                         pal[color] = 0;
118         }
119
120         y = 0;
121         while (y < height) {
122                 int *pixels;
123
124                 p = *xpm++;
125
126                 pixels = (int *)&((char *)surface->pixels)[y++ * surface->pitch];
127                 x = 0;
128                 while (x < width) {
129                         Uint8 r,g,b,a;
130
131                         if (*p == '\0') {
132                                 SDL_FreeSurface(surface);
133                                 return NULL;
134                         }
135                         r = (pal[(int)*p] >> 16) & 0xff;
136                         b = (pal[(int)*p] & 0xff);
137                         g = (pal[(int)*p] >> 8) & 0xff;
138                         a = (pal[(int)*p] >> 24) & 0xff;
139                         pixels[x] = SDL_MapRGBA(surface->format, r, g, b, a);
140                         x++;
141                         p++;
142                 }
143         }
144
145         return surface;
146 }
147
148 void *get_vgaptr(int page, int x, int y)
149 {
150         assert(drawing_enable==1);
151
152         return (unsigned char *)screen_buffer[page] + (y*screen_pitch)+(x*bytes_per_pixel);
153 }
154
155
156 void set_scaling(int scale)
157 {
158         if (scale==1) {
159                 screen_width=800;
160                 screen_height=512;
161                 scale_up=1;
162                 bytes_per_pixel=2;
163                 dirty_block_shift=5;
164                 screen_pitch=screen_width*bytes_per_pixel;
165         } else {
166                 screen_width=400;
167                 screen_height=256;
168                 scale_up=0;
169                 bytes_per_pixel=1;
170                 dirty_block_shift=4;
171                 screen_pitch=screen_width*bytes_per_pixel;
172         }
173 }
174
175 void open_screen(void)
176 {
177         int lval = 0;
178         int bpp;
179         int flags;
180
181         lval = SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
182         if (lval < 0) {
183                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
184                 exit(EXIT_FAILURE);
185         }
186
187         if (scale_up)
188                 bpp = 16;
189         else
190                 bpp = 8;
191         flags = SDL_SWSURFACE;
192         if (fullscreen)
193                 flags |= SDL_FULLSCREEN;
194         jnb_surface = SDL_SetVideoMode(screen_width, screen_height, bpp, flags);
195
196         if (!jnb_surface) {
197                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
198                 exit(EXIT_FAILURE);
199         }
200
201         if(fullscreen)
202                 SDL_ShowCursor(0);
203         else
204                 SDL_ShowCursor(1);
205
206         SDL_WM_SetCaption("Jump n Bump","");
207
208         icon=load_xpm_from_array(jumpnbump_xpm);
209         if (icon==NULL) {
210             printf("Couldn't load icon\n");
211         } else {
212             SDL_WM_SetIcon(icon,NULL);
213         }
214
215         vinited = 1;
216
217         memset(current_pal, 0, sizeof(current_pal));
218         memset(dirty_blocks, 0, sizeof(dirty_blocks));
219
220         screen_buffer[0]=malloc(screen_width*screen_height*bytes_per_pixel);
221         screen_buffer[1]=malloc(screen_width*screen_height*bytes_per_pixel);
222
223 /*
224         dirty_blocks[0]=malloc(sizeof(int)*25*16+1000);
225         dirty_blocks[1]=malloc(sizeof(int)*25*16+1000);
226 */
227
228         return;
229 }
230
231
232 void fs_toggle()
233 {
234         if (!vinited) {
235                 fullscreen ^= 1;
236                 return;
237         }
238         if (SDL_WM_ToggleFullScreen(jnb_surface))
239                 fullscreen ^= 1;
240 }
241
242
243 void wait_vrt(int mix)
244 {
245         return;
246 }
247
248
249 void clear_page(int page, int color)
250 {
251         int i,j;
252
253         assert(drawing_enable==1);
254
255         for (i=0; i<(25*16); i++)
256                 dirty_blocks[page][i] = 1;
257
258         if (bytes_per_pixel==1) {
259                 unsigned char *buf = get_vgaptr(page, 0, 0);
260
261                 for (i=0; i<screen_height; i++)
262                         for (j=0; j<screen_width; j++)
263                                 *buf++ = color;
264         } else if (bytes_per_pixel==2) {
265                 unsigned short *buf = get_vgaptr(page, 0, 0);
266
267                 for (i=0; i<screen_height; i++)
268                         for (j=0; j<screen_width; j++)
269                                 *buf++ = color;
270         } else {
271                 unsigned int *buf = get_vgaptr(page, 0, 0);
272
273                 for (i=0; i<screen_height; i++)
274                         for (j=0; j<screen_width; j++)
275                                 *buf++ = color;
276         }
277 }
278
279
280 void clear_lines(int page, int y, int count, int color)
281 {
282         int i,j;
283
284         assert(drawing_enable==1);
285
286         if (scale_up) {
287                 count *= 2;
288                 y *= 2;
289         }
290
291         if (bytes_per_pixel==1) {
292                 for (i=0; i<count; i++) {
293                         if ((i+y)<screen_height) {
294                                 unsigned char *buf = get_vgaptr(page, 0, i+y);
295                                 for (j=0; j<screen_width; j++)
296                                         *buf++ = color;
297                         }
298                 }
299         } else if (bytes_per_pixel==2) {
300                 for (i=0; i<count; i++) {
301                         if ((i+y)<screen_height) {
302                                 unsigned short *buf = get_vgaptr(page, 0, i+y);
303                                 for (j=0; j<screen_width; j++)
304                                         *buf++ = color;
305                         }
306                 }
307         } else {
308                 for (i=0; i<count; i++) {
309                         if ((i+y)<screen_height) {
310                                 unsigned int *buf = get_vgaptr(page, 0, i+y);
311                                 for (j=0; j<screen_width; j++)
312                                         *buf++ = color;
313                         }
314                 }
315         }
316         count = ((y+count)>>dirty_block_shift) - (y>>dirty_block_shift) + 1;
317         y >>= dirty_block_shift;
318         for (i=0; i<count; i++)
319                 for (j=0; j<25; j++)
320                         dirty_blocks[page][(y+i)*25+j] = 1;
321 }
322
323
324 int get_color(int color, char pal[768])
325 {
326         assert(color<256);
327         assert(pal);
328         return SDL_MapRGB(jnb_surface->format, (Uint8)(pal[color*3+0]<<2), (Uint8)(pal[color*3+1]<<2), (Uint8)(pal[color*3+2]<<2));
329 }
330
331
332 int get_pixel(int page, int x, int y)
333 {
334         assert(drawing_enable==1);
335
336         if (scale_up) {
337                 x *= 2;
338                 y *= 2;
339         }
340
341         assert(x<screen_width);
342         assert(y<screen_height);
343
344         if (bytes_per_pixel==1)
345                 return *(unsigned char *)get_vgaptr(page, x, y);
346         else if (bytes_per_pixel==2)
347                 return *(unsigned short *)get_vgaptr(page, x, y);
348         else
349                 return *(unsigned int *)get_vgaptr(page, x, y);
350 }
351
352
353 void set_pixel(int page, int x, int y, int color)
354 {
355         assert(drawing_enable==1);
356
357         if (scale_up) {
358                 x *= 2;
359                 y *= 2;
360         }
361
362         assert(x<screen_width);
363         assert(y<screen_height);
364
365         dirty_blocks[page][(y>>dirty_block_shift)*25+(x>>dirty_block_shift)] = 1;
366
367         if (bytes_per_pixel==1)
368                 *(unsigned char *)get_vgaptr(page, x, y) = color;
369         else if (bytes_per_pixel==2)
370                 *(unsigned short *)get_vgaptr(page, x, y) = color;
371         else
372                 *(unsigned int *)get_vgaptr(page, x, y) = color;
373 }
374
375
376 static unsigned int colorMask = 0xF7DEF7DE;
377 static unsigned int lowPixelMask = 0x08210821;
378 static unsigned int qcolorMask = 0xE79CE79C;
379 static unsigned int qlowpixelMask = 0x18631863;
380 static unsigned int redblueMask = 0xF81F;
381 static unsigned int greenMask = 0x7E0;
382
383 int Init_2xSaI (unsigned int BitFormat)
384 {
385     if (BitFormat == 565)
386     {
387         colorMask = (0xF7DEF7DE);
388         lowPixelMask = (0x08210821);
389         qcolorMask = (0xE79CE79C);
390         qlowpixelMask = (0x18631863);
391         redblueMask = (0xF81F);
392         greenMask = (0x7E0);
393     }
394     else if (BitFormat == 555)
395     {
396         colorMask = (0x7BDE7BDE);
397         lowPixelMask = (0x04210421);
398         qcolorMask = (0x739C739C);
399         qlowpixelMask = (0x0C630C63);
400         redblueMask = (0x7C1F);
401         greenMask = (0x3E0);
402     }
403     else
404     {
405         return 0;
406     }
407
408 #ifdef MMX
409     Init_2xSaIMMX (BitFormat);
410 #endif
411
412     return 1;
413 }
414
415
416 void Scale2x (unsigned char *src, unsigned int src_pitch, int src_bytes_per_pixel,
417                  unsigned char *dst, unsigned int dst_pitch, int dst_bytes_per_pixel,
418                  int width, int height, int pal[256])
419 {
420 #define GET_COLOR(x) (pal[(x)])
421
422         int x,y;
423         unsigned char *src_line;
424         unsigned char *dst_line[2];
425
426         src_line = src;
427         dst_line[0] = dst;
428         dst_line[1] = dst + dst_pitch;
429         for (y=0; y<height; y++) {
430                 for (x=0; x<width; x++) {
431                         int color;
432
433                         if (src_bytes_per_pixel == 1) {
434                                 color = GET_COLOR(*(((unsigned char*)src_line) + x));
435                         } else if (src_bytes_per_pixel == 2) {
436                                 color = *(((unsigned short*)src_line) + x);
437                         } else {
438                                 color = *(((unsigned int*)src_line) + x);
439                         }
440
441                         if (dst_bytes_per_pixel == 2) {
442                                 *((unsigned long *) (&dst_line[0][x * 4])) = color | (color << 16);
443                                 *((unsigned long *) (&dst_line[1][x * 4])) = color | (color << 16);
444                         } else {
445                                 *((unsigned long *) (&dst_line[0][x * 8])) = color;
446                                 *((unsigned long *) (&dst_line[0][x * 8 + 4])) = color;
447                                 *((unsigned long *) (&dst_line[1][x * 8])) = color;
448                                 *((unsigned long *) (&dst_line[1][x * 8 + 4])) = color;
449                         }
450                 }
451
452                 src_line += src_pitch;
453
454                 if (y < height - 1) {
455                         dst_line[0] += dst_pitch * 2;
456                         dst_line[1] += dst_pitch * 2;
457                 }
458         }
459 }
460
461
462 void Super2xSaI (unsigned char *src, unsigned int src_pitch, int src_bytes_per_pixel,
463                  unsigned char *dst, unsigned int dst_pitch, int dst_bytes_per_pixel,
464                  int width, int height, int pal[256])
465 {
466 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
467
468 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
469
470 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
471         + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
472
473 #define GET_COLOR(x) (pal[(x)])
474
475         unsigned char *src_line[4];
476         unsigned char *dst_line[2];
477         int x, y;
478         unsigned long color[16];
479
480         if ( (width<2) || (height<2) ) {
481                 Scale2x(src, src_pitch, src_bytes_per_pixel, dst, dst_pitch, dst_bytes_per_pixel, width, height, pal);
482                 return;
483         }
484
485         /* Point to the first 3 lines. */
486         src_line[0] = src;
487         src_line[1] = src;
488         src_line[2] = src + src_pitch;
489         src_line[3] = src + (src_pitch * 2);
490         
491         dst_line[0] = dst;
492         dst_line[1] = dst + dst_pitch;
493         
494         x = 0, y = 0;
495         
496         if (src_bytes_per_pixel == 1) {
497                 unsigned char *sbp;
498                 sbp = src_line[0];
499                 color[0] = GET_COLOR(*sbp);       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
500                 color[4] = color[0];   color[5] = color[0];   color[6] = GET_COLOR(*(sbp + 1));  color[7] = GET_COLOR(*(sbp + 2));
501                 sbp = src_line[2];
502                 color[8] = GET_COLOR(*sbp);     color[9] = color[8];     color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
503                 sbp = src_line[3];
504                 color[12] = GET_COLOR(*sbp);    color[13] = color[12];   color[14] = GET_COLOR(*(sbp + 1)); color[15] = GET_COLOR(*(sbp + 2));
505         } else if (src_bytes_per_pixel == 2) {
506                 unsigned short *sbp;
507                 sbp = (unsigned short*)src_line[0];
508                 color[0] = *sbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
509                 color[4] = color[0];   color[5] = color[0];   color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
510                 sbp = (unsigned short*)src_line[2];
511                 color[8] = *sbp;     color[9] = color[8];     color[10] = *(sbp + 1); color[11] = *(sbp + 2);
512                 sbp = (unsigned short*)src_line[3];
513                 color[12] = *sbp;    color[13] = color[12];   color[14] = *(sbp + 1); color[15] = *(sbp + 2);
514         } else {
515                 unsigned long *lbp;
516                 lbp = (unsigned long*)src_line[0];
517                 color[0] = *lbp;       color[1] = color[0];   color[2] = color[0];    color[3] = color[0];
518                 color[4] = color[0];   color[5] = color[0];   color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
519                 lbp = (unsigned long*)src_line[2];
520                 color[8] = *lbp;     color[9] = color[8];     color[10] = *(lbp + 1); color[11] = *(lbp + 2);
521                 lbp = (unsigned long*)src_line[3];
522                 color[12] = *lbp;    color[13] = color[12];   color[14] = *(lbp + 1); color[15] = *(lbp + 2);
523         }
524
525         for (y = 0; y < height; y++) {
526         
527                 /* Todo: x = width - 2, x = width - 1 */
528                 
529                 for (x = 0; x < width; x++) {
530                         unsigned long product1a, product1b, product2a, product2b;
531
532 /*
533
534 //---------------------------------------  B0 B1 B2 B3    0  1  2  3
535 //                                         4  5* 6  S2 -> 4  5* 6  7
536 //                                         1  2  3  S1    8  9 10 11
537 //                                         A0 A1 A2 A3   12 13 14 15
538 //--------------------------------------
539
540 */
541
542                         if (color[9] == color[6] && color[5] != color[10]) {
543                                 product2b = color[9];
544                                 product1b = product2b;
545                         }
546                         else if (color[5] == color[10] && color[9] != color[6]) {
547                                 product2b = color[5];
548                                 product1b = product2b;
549                         }
550                         else if (color[5] == color[10] && color[9] == color[6]) {
551                                 int r = 0;
552
553                                 r += GET_RESULT(color[6], color[5], color[8], color[13]);
554                                 r += GET_RESULT(color[6], color[5], color[4], color[1]);
555                                 r += GET_RESULT(color[6], color[5], color[14], color[11]);
556                                 r += GET_RESULT(color[6], color[5], color[2], color[7]);
557
558                                 if (r > 0)
559                                         product1b = color[6];
560                                 else if (r < 0)
561                                         product1b = color[5];
562                                 else
563                                         product1b = INTERPOLATE(color[5], color[6]);
564                                         
565                                 product2b = product1b;
566
567                         }
568                         else {
569                                 if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12])
570                                         product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]);
571                                 else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15])
572                                         product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]);
573                                 else
574                                         product2b = INTERPOLATE(color[9], color[10]);
575
576                                 if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0])
577                                         product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]);
578                                 else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3])
579                                         product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]);
580                                 else
581                                         product1b = INTERPOLATE(color[5], color[6]);
582                         }
583
584                         if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14])
585                                 product2a = INTERPOLATE(color[9], color[5]);
586                         else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12])
587                                 product2a = INTERPOLATE(color[9], color[5]);
588                         else
589                                 product2a = color[9];
590
591                         if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2])
592                                 product1a = INTERPOLATE(color[9], color[5]);
593                         else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0])
594                                 product1a = INTERPOLATE(color[9], color[5]);
595                         else
596                                 product1a = color[5];
597         
598                         if (dst_bytes_per_pixel == 2) {
599                                 unsigned long tmp;
600                                 tmp = SDL_SwapLE16(product1a) | SDL_SwapLE16(product1b) << 16;
601                                 *((unsigned long *) (&dst_line[0][x * 4])) = SDL_SwapLE32(tmp);
602                                 tmp = SDL_SwapLE16(product2a) | SDL_SwapLE16(product2b) << 16;
603                                 *((unsigned long *) (&dst_line[1][x * 4])) = SDL_SwapLE32(tmp);
604                         } else {
605                                 *((unsigned long *) (&dst_line[0][x * 8])) = product1a;
606                                 *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
607                                 *((unsigned long *) (&dst_line[1][x * 8])) = product2a;
608                                 *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
609                         }
610                         
611                         /* Move color matrix forward */
612                         color[0] = color[1]; color[4] = color[5]; color[8] = color[9];   color[12] = color[13];
613                         color[1] = color[2]; color[5] = color[6]; color[9] = color[10];  color[13] = color[14];
614                         color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15];
615                         
616                         if (x < width - 3) {
617                                 x+=3;
618                                 if (src_bytes_per_pixel == 1) {
619                                         color[3] = GET_COLOR(*(((unsigned char*)src_line[0]) + x));
620                                         color[7] = GET_COLOR(*(((unsigned char*)src_line[1]) + x));
621                                         color[11] = GET_COLOR(*(((unsigned char*)src_line[2]) + x));
622                                         color[15] = GET_COLOR(*(((unsigned char*)src_line[3]) + x));
623                                 } else if (src_bytes_per_pixel == 2) {
624                                         color[3] = *(((unsigned short*)src_line[0]) + x);                                       
625                                         color[7] = *(((unsigned short*)src_line[1]) + x);
626                                         color[11] = *(((unsigned short*)src_line[2]) + x);
627                                         color[15] = *(((unsigned short*)src_line[3]) + x);
628                                 } else {
629                                         color[3] = *(((unsigned long*)src_line[0]) + x);
630                                         color[7] = *(((unsigned long*)src_line[1]) + x);
631                                         color[11] = *(((unsigned long*)src_line[2]) + x);
632                                         color[15] = *(((unsigned long*)src_line[3]) + x);
633                                 }
634                                 x-=3;
635                         }
636                 }
637
638                 /* We're done with one line, so we shift the source lines up */
639                 src_line[0] = src_line[1];
640                 src_line[1] = src_line[2];
641                 src_line[2] = src_line[3];              
642
643                 /* Read next line */
644                 if (y + 3 >= height)
645                         src_line[3] = src_line[2];
646                 else
647                         src_line[3] = src_line[2] + src_pitch;
648                         
649                 /* Then shift the color matrix up */
650                 if (src_bytes_per_pixel == 1) {
651                         unsigned char *sbp;
652                         sbp = src_line[0];
653                         color[0] = GET_COLOR(*sbp);     color[1] = color[0];    color[2] = GET_COLOR(*(sbp + 1));  color[3] = GET_COLOR(*(sbp + 2));
654                         sbp = src_line[1];
655                         color[4] = GET_COLOR(*sbp);     color[5] = color[4];    color[6] = GET_COLOR(*(sbp + 1));  color[7] = GET_COLOR(*(sbp + 2));
656                         sbp = src_line[2];
657                         color[8] = GET_COLOR(*sbp);     color[9] = color[8];    color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
658                         sbp = src_line[3];
659                         color[12] = GET_COLOR(*sbp);    color[13] = color[12];  color[14] = GET_COLOR(*(sbp + 1)); color[15] = GET_COLOR(*(sbp + 2));
660                 } else if (src_bytes_per_pixel == 2) {
661                         unsigned short *sbp;
662                         sbp = (unsigned short*)src_line[0];
663                         color[0] = *sbp;     color[1] = color[0];    color[2] = *(sbp + 1);  color[3] = *(sbp + 2);
664                         sbp = (unsigned short*)src_line[1];
665                         color[4] = *sbp;     color[5] = color[4];    color[6] = *(sbp + 1);  color[7] = *(sbp + 2);
666                         sbp = (unsigned short*)src_line[2];
667                         color[8] = *sbp;     color[9] = color[9];    color[10] = *(sbp + 1); color[11] = *(sbp + 2);
668                         sbp = (unsigned short*)src_line[3];
669                         color[12] = *sbp;    color[13] = color[12];  color[14] = *(sbp + 1); color[15] = *(sbp + 2);
670                 } else {
671                         unsigned long *lbp;
672                         lbp = (unsigned long*)src_line[0];
673                         color[0] = *lbp;     color[1] = color[0];    color[2] = *(lbp + 1);  color[3] = *(lbp + 2);
674                         lbp = (unsigned long*)src_line[1];
675                         color[4] = *lbp;     color[5] = color[4];    color[6] = *(lbp + 1);  color[7] = *(lbp + 2);
676                         lbp = (unsigned long*)src_line[2];
677                         color[8] = *lbp;     color[9] = color[9];    color[10] = *(lbp + 1); color[11] = *(lbp + 2);
678                         lbp = (unsigned long*)src_line[3];
679                         color[12] = *lbp;    color[13] = color[12];  color[14] = *(lbp + 1); color[15] = *(lbp + 2);
680                 }
681                 
682                 if (y < height - 1) {
683                         dst_line[0] += dst_pitch * 2;
684                         dst_line[1] += dst_pitch * 2;
685                 }
686         }
687 }
688
689
690 void flippage(int page)
691 {
692         int x,y;
693         unsigned char *src;
694         unsigned char *dest;
695
696         assert(drawing_enable==0);
697
698         SDL_LockSurface(jnb_surface);
699         if (!jnb_surface->pixels) {
700                 
701                 for (x=0; x<(25*16); x++) {
702                         dirty_blocks[0][x] = 1;
703                         dirty_blocks[1][x] = 1;
704                 }
705
706                 return;
707         }
708 #ifdef SCALE_UP
709         dest=(unsigned char *)jnb_surface->pixels;
710         src=screen_buffer[page];
711         Super2xSaI(src, JNB_WIDTH, 1, dest, jnb_surface->pitch, 2, JNB_WIDTH, JNB_HEIGHT, current_pal);
712 #else
713         dest=(unsigned char *)jnb_surface->pixels;
714         src=screen_buffer[page];
715         for (y=0; y<screen_height; y++) {
716                 for (x=0; x<25; x++) {
717                         int count;
718                         int test_x;
719
720                         count=0;
721                         test_x=x;
722                         while ( (test_x<25) && (dirty_blocks[page][(y>>dirty_block_shift)*25+test_x]) ) {
723                                 count++;
724                                 test_x++;
725                         }
726                         if (count) {
727                                 memcpy( &dest[y*jnb_surface->pitch+(x<<dirty_block_shift)*bytes_per_pixel],
728                                         &src[y*screen_pitch+((x<<dirty_block_shift)*bytes_per_pixel)],
729                                         ((16<<dirty_block_shift)>>4)*bytes_per_pixel*count);
730                         }
731                         x = test_x;
732                 }
733         }
734         memset(&dirty_blocks[page], 0, sizeof(int)*25*16);
735 #endif
736         SDL_UnlockSurface(jnb_surface);
737         SDL_Flip(jnb_surface);
738 }
739
740
741 void draw_begin(void)
742 {
743         assert(drawing_enable==0);
744
745         drawing_enable = 1;
746         if (background_drawn == 0) {
747                 if (background) {
748                         put_block(0, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
749                         put_block(1, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
750                 } else {
751                         clear_page(0, 0);
752                         clear_page(1, 0);
753                 }
754                 background_drawn = 1;
755         }
756 }
757
758
759 void draw_end(void)
760 {
761         assert(drawing_enable==1);
762
763         drawing_enable = 0;
764 }
765
766
767 void setpalette(int index, int count, char *palette)
768 {
769         SDL_Color colors[256];
770         int i;
771
772         assert(drawing_enable==0);
773
774         for (i = 0; i < count; i++) {
775                 colors[i+index].r = palette[i * 3 + 0] << 2;
776                 colors[i+index].g = palette[i * 3 + 1] << 2;
777                 colors[i+index].b = palette[i * 3 + 2] << 2;
778                 current_pal[i+index] = SDL_MapRGB(jnb_surface->format, colors[i+index].r, colors[i+index].g, colors[i+index].b);
779         }
780         if (!scale_up)
781                 SDL_SetColors(jnb_surface, &colors[index], index, count);
782 }
783
784
785 void fillpalette(int red, int green, int blue)
786 {
787         SDL_Color colors[256];
788         int i;
789
790         assert(drawing_enable==0);
791
792         for (i = 0; i < 256; i++) {
793                 colors[i].r = red << 2;
794                 colors[i].g = green << 2;
795                 colors[i].b = blue << 2;
796                 current_pal[i] = SDL_MapRGB(jnb_surface->format, colors[i].r, colors[i].g, colors[i].b);
797         }
798         if (!scale_up)
799                 SDL_SetColors(jnb_surface, colors, 0, 256);
800 }
801
802
803 void get_block(int page, int x, int y, int width, int height, void *buffer)
804 {
805         unsigned char *buffer_ptr, *vga_ptr;
806         int h;
807
808         assert(drawing_enable==1);
809
810         if (scale_up) {
811                 x *= 2;
812                 y *= 2;
813                 width *= 2;
814                 height *= 2;
815         }
816
817         if (x < 0)
818                 x = 0;
819         if (y < 0)
820                 y = 0;
821         if (y + height >= screen_height)
822                 height = screen_height - y;
823         if (x + width >= screen_width)
824                 width = screen_width - x;
825         if (width<=0)
826                 return;
827         if(height<=0)
828                 return;
829
830         vga_ptr = get_vgaptr(page, x, y);
831         buffer_ptr = buffer;
832         for (h = 0; h < height; h++) {
833                 memcpy(buffer_ptr, vga_ptr, width * bytes_per_pixel);
834                 vga_ptr += screen_pitch;
835                 buffer_ptr += width * bytes_per_pixel;
836         }
837
838 }
839
840
841 void put_block(int page, int x, int y, int width, int height, void *buffer)
842 {
843         int h;
844         unsigned char *vga_ptr, *buffer_ptr;
845
846         assert(drawing_enable==1);
847
848         if (scale_up) {
849                 x *= 2;
850                 y *= 2;
851                 width *= 2;
852                 height *= 2;
853         }
854
855         if (x < 0)
856                 x = 0;
857         if (y < 0)
858                 y = 0;
859         if (y + height >= screen_height)
860                 height = screen_height - y;
861         if (x + width >= screen_width)
862                 width = screen_width - x;
863         if (width<=0)
864                 return;
865         if(height<=0)
866                 return;
867
868         vga_ptr = get_vgaptr(page, x, y);
869         buffer_ptr = buffer;
870         for (h = 0; h < height; h++) {
871                 memcpy(vga_ptr, buffer_ptr, width * bytes_per_pixel);
872                 vga_ptr += screen_pitch;
873                 buffer_ptr += width * bytes_per_pixel;
874         }
875         width = ((x+width)>>dirty_block_shift) - (x>>dirty_block_shift) + 1;
876         height = ((y+height)>>dirty_block_shift) - (y>>dirty_block_shift) + 1;
877         x >>= dirty_block_shift;
878         y >>= dirty_block_shift;
879         while (width--)
880                 for (h=0; h<height; h++)
881                         dirty_blocks[page][(y+h)*25+(x+width)] = 1;
882 }
883
884
885 void put_text(int page, int x, int y, char *text, int align)
886 {
887         int c1;
888         int t1;
889         int width;
890         int cur_x;
891         int image;
892
893         assert(drawing_enable==1);
894
895         if (text == NULL || strlen(text) == 0)
896                 return;
897         if (font_gobs.num_images == 0)
898                 return;
899
900         width = 0;
901         c1 = 0;
902         while (text[c1] != 0) {
903                 t1 = text[c1];
904                 c1++;
905                 if (t1 == ' ') {
906                         width += 5;
907                         continue;
908                 }
909                 if (t1 >= 33 && t1 <= 34)
910                         image = t1 - 33;
911
912                 else if (t1 >= 39 && t1 <= 41)
913                         image = t1 - 37;
914
915                 else if (t1 >= 44 && t1 <= 59)
916                         image = t1 - 39;
917
918                 else if (t1 >= 64 && t1 <= 90)
919                         image = t1 - 43;
920
921                 else if (t1 >= 97 && t1 <= 122)
922                         image = t1 - 49;
923
924                 else if (t1 == '~')
925                         image = 74;
926
927                 else if (t1 == 0x84)
928                         image = 75;
929
930                 else if (t1 == 0x86)
931                         image = 76;
932
933                 else if (t1 == 0x8e)
934                         image = 77;
935
936                 else if (t1 == 0x8f)
937                         image = 78;
938
939                 else if (t1 == 0x94)
940                         image = 79;
941
942                 else if (t1 == 0x99)
943                         image = 80;
944
945                 else
946                         continue;
947                 width += pob_width(image, &font_gobs) + 1;
948         }
949
950         switch (align) {
951         case 0:
952                 cur_x = x;
953                 break;
954         case 1:
955                 cur_x = x - width;
956                 break;
957         case 2:
958                 cur_x = x - width / 2;
959                 break;
960         default:
961                 cur_x = 0;      /* this should cause error? -Chuck */
962                 break;
963         }
964         c1 = 0;
965
966         while (text[c1] != 0) {
967                 t1 = text[c1];
968                 c1++;
969                 if (t1 == ' ') {
970                         cur_x += 5;
971                         continue;
972                 }
973                 if (t1 >= 33 && t1 <= 34)
974                         image = t1 - 33;
975
976                 else if (t1 >= 39 && t1 <= 41)
977                         image = t1 - 37;
978
979                 else if (t1 >= 44 && t1 <= 59)
980                         image = t1 - 39;
981
982                 else if (t1 >= 64 && t1 <= 90)
983                         image = t1 - 43;
984
985                 else if (t1 >= 97 && t1 <= 122)
986                         image = t1 - 49;
987
988                 else if (t1 == '~')
989                         image = 74;
990
991                 else if (t1 == 0x84)
992                         image = 75;
993
994                 else if (t1 == 0x86)
995                         image = 76;
996
997                 else if (t1 == 0x8e)
998                         image = 77;
999
1000                 else if (t1 == 0x8f)
1001                         image = 78;
1002
1003                 else if (t1 == 0x94)
1004                         image = 79;
1005
1006                 else if (t1 == 0x99)
1007                         image = 80;
1008
1009                 else
1010                         continue;
1011                 put_pob(page, cur_x, y, image, &font_gobs, 1, mask_pic);
1012                 cur_x += pob_width(image, &font_gobs) + 1;
1013         }
1014 }
1015
1016
1017 void put_pob(int page, int x, int y, int image, gob_t *gob, int use_mask, void *mask_pic)
1018 {
1019         int c1, c2;
1020         int pob_x, pob_y;
1021         int width, height;
1022         int draw_width, draw_height;
1023         int colour;
1024
1025         assert(drawing_enable==1);
1026         assert(gob);
1027         assert(image>=0);
1028         assert(image<gob->num_images);
1029
1030         if (scale_up) {
1031                 x *= 2;
1032                 y *= 2;
1033                 width = draw_width = gob->width[image]*2;
1034                 height = draw_height = gob->height[image]*2;
1035                 x -= gob->hs_x[image]*2;
1036                 y -= gob->hs_y[image]*2;
1037         } else {
1038                 width = draw_width = gob->width[image];
1039                 height = draw_height = gob->height[image];
1040                 x -= gob->hs_x[image];
1041                 y -= gob->hs_y[image];
1042         }
1043
1044         if ((x + width) <= 0 || x >= screen_width)
1045                 return;
1046         if ((y + height) <= 0 || y >= screen_height)
1047                 return;
1048
1049         pob_x = 0;
1050         pob_y = 0;
1051         if (x < 0) {
1052                 pob_x -= x;
1053                 draw_width += x;
1054                 x = 0;
1055         }
1056         if ((x + width) > screen_width)
1057                 draw_width -= x + width - screen_width;
1058         if (y < 0) {
1059                 pob_y -= y;
1060                 draw_height += y;
1061                 y = 0;
1062         }
1063         if ((y + height) > screen_height)
1064                 draw_height -= y + height - screen_height;
1065
1066
1067         if (bytes_per_pixel==1) {
1068                 unsigned char *vga_ptr;
1069                 unsigned char *pob_ptr;
1070                 unsigned char *mask_ptr;
1071
1072                 vga_ptr = get_vgaptr(page, x, y);
1073                 pob_ptr = ((unsigned char *)gob->data[image]) + ((pob_y * width) + pob_x);
1074                 mask_ptr = ((unsigned char *)mask) + ((y * screen_pitch) + (x*bytes_per_pixel));
1075                 for (c1 = 0; c1 < draw_height; c1++) {
1076                         for (c2 = 0; c2 < draw_width; c2++) {
1077                                 colour = *mask_ptr;
1078                                 if (use_mask == 0 || (use_mask == 1 && colour == 0)) {
1079                                         colour = *pob_ptr;
1080                                         if (colour != 0) {
1081                                                 *vga_ptr = colour;
1082                                         }
1083                                 }
1084                                 vga_ptr++;
1085                                 pob_ptr++;
1086                                 mask_ptr++;
1087                         }
1088                         pob_ptr += width - c2;
1089                         vga_ptr += (screen_width - c2);
1090                         mask_ptr += (screen_width - c2);
1091                 }
1092         } else if (bytes_per_pixel==2) {
1093                 unsigned short *vga_ptr;
1094                 unsigned short *pob_ptr;
1095                 unsigned short *mask_ptr;
1096
1097                 vga_ptr = get_vgaptr(page, x, y);
1098                 pob_ptr = (unsigned short *)(((unsigned char *)gob->data[image]) + ((pob_y * width) + pob_x));
1099                 mask_ptr = (unsigned short *)(((unsigned char *)mask) + ((y * screen_pitch) + (x*bytes_per_pixel)));
1100                 for (c1 = 0; c1 < draw_height; c1++) {
1101                         for (c2 = 0; c2 < draw_width; c2++) {
1102                                 colour = *mask_ptr;
1103                                 if (use_mask == 0 || (use_mask == 1 && colour == 0)) {
1104                                         colour = *pob_ptr;
1105                                         if (colour != 0) {
1106                                                 *vga_ptr = colour;
1107                                         }
1108                                 }
1109                                 vga_ptr++;
1110                                 pob_ptr++;
1111                                 mask_ptr++;
1112                         }
1113                         pob_ptr += width - c2;
1114                         vga_ptr += (screen_width - c2);
1115                         mask_ptr += (screen_width - c2);
1116                 }
1117         } else {
1118                 unsigned int *vga_ptr;
1119                 unsigned int *pob_ptr;
1120                 unsigned int *mask_ptr;
1121
1122                 vga_ptr = get_vgaptr(page, x, y);
1123                 pob_ptr = (unsigned int *)(((unsigned char *)gob->data[image]) + ((pob_y * width) + pob_x));
1124                 mask_ptr = (unsigned int *)(((unsigned char *)mask) + ((y * screen_pitch) + (x*bytes_per_pixel)));
1125                 for (c1 = 0; c1 < draw_height; c1++) {
1126                         for (c2 = 0; c2 < draw_width; c2++) {
1127                                 colour = *mask_ptr;
1128                                 if (use_mask == 0 || (use_mask == 1 && colour == 0)) {
1129                                         colour = *pob_ptr;
1130                                         if (colour != 0) {
1131                                                 *vga_ptr = colour;
1132                                         }
1133                                 }
1134                                 vga_ptr++;
1135                                 pob_ptr++;
1136                                 mask_ptr++;
1137                         }
1138                         pob_ptr += width - c2;
1139                         vga_ptr += (screen_width - c2);
1140                         mask_ptr += (screen_width - c2);
1141                 }
1142         }
1143         draw_width = ((x+draw_width)>>dirty_block_shift) - (x>>dirty_block_shift) + 1;
1144         draw_height = ((y+draw_height)>>dirty_block_shift) - (y>>dirty_block_shift) + 1;
1145         x >>= dirty_block_shift;
1146         y >>= dirty_block_shift;
1147         while (draw_width--)
1148                 for (c1=0; c1<draw_height; c1++)
1149                         dirty_blocks[page][(y+c1)*25+(x+draw_width)] = 1;
1150 }
1151
1152
1153 int pob_width(int image, gob_t *gob)
1154 {
1155         assert(gob);
1156         assert(image>=0);
1157         assert(image<gob->num_images);
1158         return gob->width[image];
1159 }
1160
1161
1162 int pob_height(int image, gob_t *gob)
1163 {
1164         assert(gob);
1165         assert(image>=0);
1166         assert(image<gob->num_images);
1167         return gob->height[image];
1168 }
1169
1170
1171 int pob_hs_x(int image, gob_t *gob)
1172 {
1173         assert(gob);
1174         assert(image>=0);
1175         assert(image<gob->num_images);
1176         return gob->hs_x[image];
1177 }
1178
1179
1180 int pob_hs_y(int image, gob_t *gob)
1181 {
1182         assert(gob);
1183         assert(image>=0);
1184         assert(image<gob->num_images);
1185         return gob->hs_y[image];
1186 }
1187
1188
1189 int read_pcx(unsigned char * handle, void *buf, int buf_len, char *pal)
1190 {
1191         unsigned char *buffer=buf;
1192         short c1;
1193         short a, b;
1194         long ofs1;
1195         if (buffer != 0) {
1196                 handle += 128;
1197                 ofs1 = 0;
1198                 while (ofs1 < buf_len) {
1199                         a = *(handle++);
1200                         if ((a & 0xc0) == 0xc0) {
1201                                 b = *(handle++);
1202                                 a &= 0x3f;
1203                                 for (c1 = 0; c1 < a && ofs1 < buf_len; c1++)
1204                                         buffer[ofs1++] = (char) b;
1205                         } else
1206                                 buffer[ofs1++] = (char) a;
1207                 }
1208                 if (pal != 0) {
1209                         handle++;
1210                         for (c1 = 0; c1 < 768; c1++)
1211                                 pal[c1] = *(handle++) /*fgetc(handle)*/ >> 2;
1212                 }
1213         }
1214         return 0;
1215 }
1216
1217
1218 void register_background(char *pixels, char pal[768])
1219 {
1220         if (background) {
1221                 free(background);
1222                 background = NULL;
1223         }
1224         background_drawn = 0;
1225         if (!pixels)
1226                 return;
1227         assert(pal);
1228         if (scale_up) {
1229                 int int_pal[256];
1230                 int i;
1231
1232                 for (i=0; i<256; i++)
1233                         int_pal[i] = SDL_MapRGB(jnb_surface->format, (Uint8)(pal[i*3+0]<<2), (Uint8)(pal[i*3+1]<<2), (Uint8)(pal[i*3+2]<<2));
1234                 background = malloc(screen_pitch*screen_height);
1235                 assert(background);
1236                 Init_2xSaI(565);
1237                 Super2xSaI((unsigned char *)pixels, JNB_WIDTH, 1, (unsigned char *)background, screen_pitch, bytes_per_pixel, JNB_WIDTH, JNB_HEIGHT, int_pal);
1238         } else {
1239                 background = malloc(JNB_WIDTH*JNB_HEIGHT);
1240                 assert(background);
1241                 memcpy(background, pixels, JNB_WIDTH*JNB_HEIGHT);
1242         }
1243 }
1244
1245 int register_gob(unsigned char *handle, gob_t *gob, int len)
1246 {
1247         unsigned char *gob_data;
1248         int i;
1249
1250         gob_data = malloc(len);
1251         memcpy(gob_data, handle, len);
1252
1253         gob->num_images = (short)((gob_data[0]) + (gob_data[1] << 8));
1254
1255         gob->width = malloc(gob->num_images*sizeof(int));
1256         gob->height = malloc(gob->num_images*sizeof(int));
1257         gob->hs_x = malloc(gob->num_images*sizeof(int));
1258         gob->hs_y = malloc(gob->num_images*sizeof(int));
1259         gob->data = malloc(gob->num_images*sizeof(void *));
1260         gob->orig_data = malloc(gob->num_images*sizeof(void *));
1261         for (i=0; i<gob->num_images; i++) {
1262                 int image_size;
1263                 int offset;
1264
1265                 offset = (gob_data[i*4+2]) + (gob_data[i*4+3] << 8) + (gob_data[i*4+4] << 16) + (gob_data[i*4+5] << 24);
1266
1267                 gob->width[i]  = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
1268                 gob->height[i] = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
1269                 gob->hs_x[i]   = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
1270                 gob->hs_y[i]   = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
1271
1272                 image_size = gob->width[i] * gob->height[i];
1273                 gob->orig_data[i] = malloc(image_size);
1274                 memcpy(gob->orig_data[i], &gob_data[offset], image_size);
1275                 if (scale_up) {
1276                         image_size = gob->width[i] * gob->height[i] * 4 * bytes_per_pixel;
1277                         gob->data[i] = malloc(image_size);
1278                 } else {
1279                         gob->data[i] = (unsigned short *)gob->orig_data[i];
1280                 }
1281         }
1282         free(gob_data);
1283         return 0;
1284 }
1285
1286
1287 void recalculate_gob(gob_t *gob, char pal[768])
1288 {
1289         int int_pal[256];
1290         int i;
1291
1292         if (!scale_up)
1293                 return;
1294
1295         Init_2xSaI(565);
1296
1297         for (i=1; i<256; i++) {
1298                 int_pal[i] = SDL_MapRGB(jnb_surface->format, (Uint8)(pal[i*3+0]<<2), (Uint8)(pal[i*3+1]<<2), (Uint8)(pal[i*3+2]<<2));
1299                 if (int_pal[i] == 0)
1300                         int_pal[i] = SDL_MapRGB(jnb_surface->format, 8, 8, 8);
1301         }
1302         int_pal[0] = 0;
1303
1304         for (i=0; i<gob->num_images; i++) {
1305                 Super2xSaI(gob->orig_data[i], gob->width[i], 1, (unsigned char *)gob->data[i], gob->width[i]*2*bytes_per_pixel, bytes_per_pixel, gob->width[i], gob->height[i], int_pal);
1306         }
1307 }
1308
1309 void register_mask(void *pixels)
1310 {
1311         if (mask) {
1312                 free(mask);
1313                 mask = NULL;
1314         }
1315         assert(pixels);
1316         if (scale_up) {
1317                 int int_pal[256];
1318                 int i;
1319
1320                 int_pal[0] = 0;
1321                 for (i=1; i<256; i++)
1322                         int_pal[i] = 0xffffffff;
1323                 mask = malloc(screen_pitch*screen_height);
1324                 assert(mask);
1325                 Init_2xSaI(565);
1326                 Scale2x(pixels, JNB_WIDTH, 1, (unsigned char *)mask, screen_pitch, bytes_per_pixel, JNB_WIDTH, JNB_HEIGHT, int_pal);
1327         } else {
1328                 mask = malloc(JNB_WIDTH*JNB_HEIGHT);
1329                 assert(mask);
1330                 memcpy(mask, pixels, JNB_WIDTH*JNB_HEIGHT);
1331         }
1332 }