Added AI by Ricardo Cruz. This also adds mouse controls.
[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  * This file is part of Jump'n'Bump.
10  *
11  * Jump'n'Bump is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * Jump'n'Bump is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26 #include "globals.h"
27 #include "SDL_endian.h"
28 #include "filter.h"
29
30 #ifdef _MSC_VER
31     #include "jumpnbump32.xpm"
32 #elif __APPLE__
33     #include "jumpnbump128.xpm"
34 #else
35     #include "jumpnbump64.xpm"
36 #endif
37 SDL_Surface *icon;
38
39 int screen_width=400;
40 int screen_height=256;
41 int screen_pitch=400;
42 int scale_up=0;
43 int dirty_block_shift=4;
44
45 static SDL_Surface *jnb_surface;
46 static int fullscreen = 0;
47 static int vinited = 0;
48 static void *screen_buffer[2];
49 static int drawing_enable = 0;
50 static void *background = NULL;
51 static int background_drawn;
52 static void *mask = NULL;
53 static int dirty_blocks[2][25*16*2];
54
55 static SDL_Surface *load_xpm_from_array(char **xpm)
56 {
57 #define NEXT_TOKEN { \
58         while ((*p != ' ') && (*p != '\t')) p++; \
59         while ((*p == ' ') || (*p == '\t')) p++; }
60
61         SDL_Surface *surface;
62         char *p;
63         int width;
64         int height;
65         int colors;
66         int images;
67         int color;
68         int pal[256];
69         int x,y;
70
71         p = *xpm++;
72
73         width = atoi(p);
74         if (width <= 0)
75                 return NULL;
76         NEXT_TOKEN;
77
78         height = atoi(p);
79         if (height <= 0)
80                 return NULL;
81         NEXT_TOKEN;
82
83         colors = atoi(p);
84         if (colors <= 0)
85                 return NULL;
86         NEXT_TOKEN;
87
88         images = atoi(p);
89         if (images <= 0)
90                 return NULL;
91
92         surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
93         if (!surface)
94                 return NULL;
95
96         SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
97         while (colors--) {
98                 p = *xpm++;
99
100                 color = *p++;
101                 NEXT_TOKEN;
102
103                 if (*p++ != 'c') {
104                         SDL_FreeSurface(surface);
105                         return NULL;
106                 }
107                 NEXT_TOKEN;
108
109                 if (*p == '#')
110                         pal[color] = strtoul(++p, NULL, 16) | 0xff000000;
111                 else
112                         pal[color] = 0;
113         }
114
115         y = 0;
116         while (y < height) {
117                 int *pixels;
118
119                 p = *xpm++;
120
121                 pixels = (int *)&((char *)surface->pixels)[y++ * surface->pitch];
122                 x = 0;
123                 while (x < width) {
124                         Uint8 r,g,b,a;
125
126                         if (*p == '\0') {
127                                 SDL_FreeSurface(surface);
128                                 return NULL;
129                         }
130                         r = (pal[(int)*p] >> 16) & 0xff;
131                         b = (pal[(int)*p] & 0xff);
132                         g = (pal[(int)*p] >> 8) & 0xff;
133                         a = (pal[(int)*p] >> 24) & 0xff;
134                         pixels[x] = SDL_MapRGBA(surface->format, r, g, b, a);
135                         x++;
136                         p++;
137                 }
138         }
139
140         return surface;
141 }
142
143 unsigned char *get_vgaptr(int page, int x, int y)
144 {
145         assert(drawing_enable==1);
146
147         return (unsigned char *)screen_buffer[page] + (y*screen_pitch)+(x);
148 }
149
150
151 void set_scaling(int scale)
152 {
153         if (scale==1) {
154                 screen_width=800;
155                 screen_height=512;
156                 scale_up=1;
157                 dirty_block_shift=5;
158                 screen_pitch=screen_width;
159         } else {
160                 screen_width=400;
161                 screen_height=256;
162                 scale_up=0;
163                 dirty_block_shift=4;
164                 screen_pitch=screen_width;
165         }
166 }
167
168 void open_screen(void)
169 {
170         int lval = 0;
171         int flags;
172
173         lval = SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
174         if (lval < 0) {
175                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
176                 exit(EXIT_FAILURE);
177         }
178
179         flags = SDL_SWSURFACE;
180         if (fullscreen)
181                 flags |= SDL_FULLSCREEN;
182         jnb_surface = SDL_SetVideoMode(screen_width, screen_height, 8, flags);
183
184         if (!jnb_surface) {
185                 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
186                 exit(EXIT_FAILURE);
187         }
188
189         if(fullscreen)
190                 SDL_ShowCursor(0);
191         else
192                 SDL_ShowCursor(1);
193
194         SDL_WM_SetCaption("Jump'n'Bump","");
195
196         icon=load_xpm_from_array(jumpnbump_xpm);
197         if (icon==NULL) {
198             printf("Couldn't load icon\n");
199         } else {
200             SDL_WM_SetIcon(icon,NULL);
201         }
202
203         vinited = 1;
204
205         memset(dirty_blocks, 0, sizeof(dirty_blocks));
206
207         screen_buffer[0]=malloc(screen_width*screen_height);
208         screen_buffer[1]=malloc(screen_width*screen_height);
209
210 /*
211         dirty_blocks[0]=malloc(sizeof(int)*25*16+1000);
212         dirty_blocks[1]=malloc(sizeof(int)*25*16+1000);
213 */
214
215         return;
216 }
217
218
219 void fs_toggle()
220 {
221         if (!vinited) {
222                 fullscreen ^= 1;
223                 return;
224         }
225         if (SDL_WM_ToggleFullScreen(jnb_surface))
226                 fullscreen ^= 1;
227 }
228
229
230 void wait_vrt(int mix)
231 {
232         return;
233 }
234
235
236 void clear_page(int page, int color)
237 {
238         int i,j;
239         unsigned char *buf = get_vgaptr(page, 0, 0);
240
241         assert(drawing_enable==1);
242
243         for (i=0; i<(25*16); i++)
244                 dirty_blocks[page][i] = 1;
245
246         for (i=0; i<screen_height; i++)
247                 for (j=0; j<screen_width; j++)
248                         *buf++ = color;
249 }
250
251
252 void clear_lines(int page, int y, int count, int color)
253 {
254         int i,j;
255
256         assert(drawing_enable==1);
257
258         if (scale_up) {
259                 count *= 2;
260                 y *= 2;
261         }
262
263         for (i=0; i<count; i++) {
264                 if ((i+y)<screen_height) {
265                         unsigned char *buf = get_vgaptr(page, 0, i+y);
266                         for (j=0; j<screen_width; j++)
267                                 *buf++ = color;
268                 }
269         }
270         count = ((y+count)>>dirty_block_shift) - (y>>dirty_block_shift) + 1;
271         y >>= dirty_block_shift;
272         for (i=0; i<count; i++)
273                 for (j=0; j<25; j++)
274                         dirty_blocks[page][(y+i)*25+j] = 1;
275 }
276
277
278 int get_color(int color, char pal[768])
279 {
280         assert(color<256);
281         assert(pal);
282         return SDL_MapRGB(jnb_surface->format, (Uint8)(pal[color*3+0]<<2), (Uint8)(pal[color*3+1]<<2), (Uint8)(pal[color*3+2]<<2));
283 }
284
285
286 int get_pixel(int page, int x, int y)
287 {
288         assert(drawing_enable==1);
289
290         if (scale_up) {
291                 x *= 2;
292                 y *= 2;
293         }
294
295         assert(x<screen_width);
296         assert(y<screen_height);
297
298         return *(unsigned char *)get_vgaptr(page, x, y);
299 }
300
301
302 void set_pixel(int page, int x, int y, int color)
303 {
304         assert(drawing_enable==1);
305
306         if (scale_up) {
307                 x *= 2;
308                 y *= 2;
309         }
310
311         assert(x<screen_width);
312         assert(y<screen_height);
313
314         dirty_blocks[page][(y>>dirty_block_shift)*25+(x>>dirty_block_shift)] = 1;
315
316         *(unsigned char *)get_vgaptr(page, x, y) = color;
317 }
318
319
320 void flippage(int page)
321 {
322         int x,y;
323         unsigned char *src;
324         unsigned char *dest;
325
326         assert(drawing_enable==0);
327
328         SDL_LockSurface(jnb_surface);
329         if (!jnb_surface->pixels) {
330                 
331                 for (x=0; x<(25*16); x++) {
332                         dirty_blocks[0][x] = 1;
333                         dirty_blocks[1][x] = 1;
334                 }
335
336                 return;
337         }
338         dest=(unsigned char *)jnb_surface->pixels;
339         src=screen_buffer[page];
340         for (y=0; y<screen_height; y++) {
341                 for (x=0; x<25; x++) {
342                         int count;
343                         int test_x;
344
345                         count=0;
346                         test_x=x;
347                         while ( (test_x<25) && (dirty_blocks[page][(y>>dirty_block_shift)*25+test_x]) ) {
348                                 count++;
349                                 test_x++;
350                         }
351                         if (count) {
352                                 memcpy( &dest[y*jnb_surface->pitch+(x<<dirty_block_shift)],
353                                         &src[y*screen_pitch+((x<<dirty_block_shift))],
354                                         ((16<<dirty_block_shift)>>4)*count);
355                         }
356                         x = test_x;
357                 }
358         }
359         memset(&dirty_blocks[page], 0, sizeof(int)*25*16);
360         SDL_UnlockSurface(jnb_surface);
361         SDL_Flip(jnb_surface);
362 }
363
364
365 void draw_begin(void)
366 {
367         assert(drawing_enable==0);
368
369         drawing_enable = 1;
370         if (background_drawn == 0) {
371                 if (background) {
372                         put_block(0, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
373                         put_block(1, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
374                 } else {
375                         clear_page(0, 0);
376                         clear_page(1, 0);
377                 }
378                 background_drawn = 1;
379         }
380 }
381
382
383 void draw_end(void)
384 {
385         assert(drawing_enable==1);
386
387         drawing_enable = 0;
388 }
389
390
391 void setpalette(int index, int count, char *palette)
392 {
393         SDL_Color colors[256];
394         int i;
395
396         assert(drawing_enable==0);
397
398         for (i = 0; i < count; i++) {
399                 colors[i+index].r = palette[i * 3 + 0] << 2;
400                 colors[i+index].g = palette[i * 3 + 1] << 2;
401                 colors[i+index].b = palette[i * 3 + 2] << 2;
402         }
403         SDL_SetColors(jnb_surface, &colors[index], index, count);
404 }
405
406
407 void fillpalette(int red, int green, int blue)
408 {
409         SDL_Color colors[256];
410         int i;
411
412         assert(drawing_enable==0);
413
414         for (i = 0; i < 256; i++) {
415                 colors[i].r = red << 2;
416                 colors[i].g = green << 2;
417                 colors[i].b = blue << 2;
418         }
419         SDL_SetColors(jnb_surface, colors, 0, 256);
420 }
421
422
423 void get_block(int page, int x, int y, int width, int height, void *buffer)
424 {
425         unsigned char *buffer_ptr, *vga_ptr;
426         int h;
427
428         assert(drawing_enable==1);
429
430         if (scale_up) {
431                 x *= 2;
432                 y *= 2;
433                 width *= 2;
434                 height *= 2;
435         }
436
437         if (x < 0)
438                 x = 0;
439         if (y < 0)
440                 y = 0;
441         if (y + height >= screen_height)
442                 height = screen_height - y;
443         if (x + width >= screen_width)
444                 width = screen_width - x;
445         if (width<=0)
446                 return;
447         if(height<=0)
448                 return;
449
450         vga_ptr = get_vgaptr(page, x, y);
451         buffer_ptr = buffer;
452         for (h = 0; h < height; h++) {
453                 memcpy(buffer_ptr, vga_ptr, width);
454                 vga_ptr += screen_pitch;
455                 buffer_ptr += width;
456         }
457
458 }
459
460
461 void put_block(int page, int x, int y, int width, int height, void *buffer)
462 {
463         int h;
464         unsigned char *vga_ptr, *buffer_ptr;
465
466         assert(drawing_enable==1);
467
468         if (scale_up) {
469                 x *= 2;
470                 y *= 2;
471                 width *= 2;
472                 height *= 2;
473         }
474
475         if (x < 0)
476                 x = 0;
477         if (y < 0)
478                 y = 0;
479         if (y + height >= screen_height)
480                 height = screen_height - y;
481         if (x + width >= screen_width)
482                 width = screen_width - x;
483         if (width<=0)
484                 return;
485         if(height<=0)
486                 return;
487
488         vga_ptr = get_vgaptr(page, x, y);
489         buffer_ptr = buffer;
490         for (h = 0; h < height; h++) {
491                 memcpy(vga_ptr, buffer_ptr, width);
492                 vga_ptr += screen_pitch;
493                 buffer_ptr += width;
494         }
495         width = ((x+width)>>dirty_block_shift) - (x>>dirty_block_shift) + 1;
496         height = ((y+height)>>dirty_block_shift) - (y>>dirty_block_shift) + 1;
497         x >>= dirty_block_shift;
498         y >>= dirty_block_shift;
499         while (width--)
500                 for (h=0; h<height; h++)
501                         dirty_blocks[page][(y+h)*25+(x+width)] = 1;
502 }
503
504
505 void put_text(int page, int x, int y, char *text, int align)
506 {
507         int c1;
508         int t1;
509         int width;
510         int cur_x;
511         int image;
512
513         assert(drawing_enable==1);
514
515         if (text == NULL || strlen(text) == 0)
516                 return;
517         if (font_gobs.num_images == 0)
518                 return;
519
520         width = 0;
521         c1 = 0;
522         while (text[c1] != 0) {
523                 t1 = text[c1];
524                 c1++;
525                 if (t1 == ' ') {
526                         width += 5;
527                         continue;
528                 }
529                 if (t1 >= 33 && t1 <= 34)
530                         image = t1 - 33;
531
532                 else if (t1 >= 39 && t1 <= 41)
533                         image = t1 - 37;
534
535                 else if (t1 >= 44 && t1 <= 59)
536                         image = t1 - 39;
537
538                 else if (t1 >= 64 && t1 <= 90)
539                         image = t1 - 43;
540
541                 else if (t1 >= 97 && t1 <= 122)
542                         image = t1 - 49;
543
544                 else if (t1 == '~')
545                         image = 74;
546
547                 else if (t1 == 0x84)
548                         image = 75;
549
550                 else if (t1 == 0x86)
551                         image = 76;
552
553                 else if (t1 == 0x8e)
554                         image = 77;
555
556                 else if (t1 == 0x8f)
557                         image = 78;
558
559                 else if (t1 == 0x94)
560                         image = 79;
561
562                 else if (t1 == 0x99)
563                         image = 80;
564
565                 else
566                         continue;
567                 width += pob_width(image, &font_gobs) + 1;
568         }
569
570         switch (align) {
571         case 0:
572                 cur_x = x;
573                 break;
574         case 1:
575                 cur_x = x - width;
576                 break;
577         case 2:
578                 cur_x = x - width / 2;
579                 break;
580         default:
581                 cur_x = 0;      /* this should cause error? -Chuck */
582                 break;
583         }
584         c1 = 0;
585
586         while (text[c1] != 0) {
587                 t1 = text[c1];
588                 c1++;
589                 if (t1 == ' ') {
590                         cur_x += 5;
591                         continue;
592                 }
593                 if (t1 >= 33 && t1 <= 34)
594                         image = t1 - 33;
595
596                 else if (t1 >= 39 && t1 <= 41)
597                         image = t1 - 37;
598
599                 else if (t1 >= 44 && t1 <= 59)
600                         image = t1 - 39;
601
602                 else if (t1 >= 64 && t1 <= 90)
603                         image = t1 - 43;
604
605                 else if (t1 >= 97 && t1 <= 122)
606                         image = t1 - 49;
607
608                 else if (t1 == '~')
609                         image = 74;
610
611                 else if (t1 == 0x84)
612                         image = 75;
613
614                 else if (t1 == 0x86)
615                         image = 76;
616
617                 else if (t1 == 0x8e)
618                         image = 77;
619
620                 else if (t1 == 0x8f)
621                         image = 78;
622
623                 else if (t1 == 0x94)
624                         image = 79;
625
626                 else if (t1 == 0x99)
627                         image = 80;
628
629                 else
630                         continue;
631                 put_pob(page, cur_x, y, image, &font_gobs, 1, mask_pic);
632                 cur_x += pob_width(image, &font_gobs) + 1;
633         }
634 }
635
636
637 void put_pob(int page, int x, int y, int image, gob_t *gob, int use_mask, void *mask_pic)
638 {
639         int c1, c2;
640         int pob_x, pob_y;
641         int width, height;
642         int draw_width, draw_height;
643         int colour;
644         unsigned char *vga_ptr;
645         unsigned char *pob_ptr;
646         unsigned char *mask_ptr;
647
648         assert(drawing_enable==1);
649         assert(gob);
650         assert(image>=0);
651         assert(image<gob->num_images);
652
653         if (scale_up) {
654                 x *= 2;
655                 y *= 2;
656                 width = draw_width = gob->width[image]*2;
657                 height = draw_height = gob->height[image]*2;
658                 x -= gob->hs_x[image]*2;
659                 y -= gob->hs_y[image]*2;
660         } else {
661                 width = draw_width = gob->width[image];
662                 height = draw_height = gob->height[image];
663                 x -= gob->hs_x[image];
664                 y -= gob->hs_y[image];
665         }
666
667         if ((x + width) <= 0 || x >= screen_width)
668                 return;
669         if ((y + height) <= 0 || y >= screen_height)
670                 return;
671
672         pob_x = 0;
673         pob_y = 0;
674         if (x < 0) {
675                 pob_x -= x;
676                 draw_width += x;
677                 x = 0;
678         }
679         if ((x + width) > screen_width)
680                 draw_width -= x + width - screen_width;
681         if (y < 0) {
682                 pob_y -= y;
683                 draw_height += y;
684                 y = 0;
685         }
686         if ((y + height) > screen_height)
687                 draw_height -= y + height - screen_height;
688
689         vga_ptr = get_vgaptr(page, x, y);
690         pob_ptr = ((unsigned char *)gob->data[image]) + ((pob_y * width) + pob_x);
691         mask_ptr = ((unsigned char *)mask) + ((y * screen_pitch) + (x));
692         for (c1 = 0; c1 < draw_height; c1++) {
693                 for (c2 = 0; c2 < draw_width; c2++) {
694                         colour = *mask_ptr;
695                         if (use_mask == 0 || (use_mask == 1 && colour == 0)) {
696                                 colour = *pob_ptr;
697                                 if (colour != 0) {
698                                         *vga_ptr = colour;
699                                 }
700                         }
701                         vga_ptr++;
702                         pob_ptr++;
703                         mask_ptr++;
704                 }
705                 pob_ptr += width - c2;
706                 vga_ptr += (screen_width - c2);
707                 mask_ptr += (screen_width - c2);
708         }
709         draw_width = ((x+draw_width)>>dirty_block_shift) - (x>>dirty_block_shift) + 1;
710         draw_height = ((y+draw_height)>>dirty_block_shift) - (y>>dirty_block_shift) + 1;
711         x >>= dirty_block_shift;
712         y >>= dirty_block_shift;
713         while (draw_width--)
714                 for (c1=0; c1<draw_height; c1++)
715                         dirty_blocks[page][(y+c1)*25+(x+draw_width)] = 1;
716 }
717
718
719 int pob_width(int image, gob_t *gob)
720 {
721         assert(gob);
722         assert(image>=0);
723         assert(image<gob->num_images);
724         return gob->width[image];
725 }
726
727
728 int pob_height(int image, gob_t *gob)
729 {
730         assert(gob);
731         assert(image>=0);
732         assert(image<gob->num_images);
733         return gob->height[image];
734 }
735
736
737 int pob_hs_x(int image, gob_t *gob)
738 {
739         assert(gob);
740         assert(image>=0);
741         assert(image<gob->num_images);
742         return gob->hs_x[image];
743 }
744
745
746 int pob_hs_y(int image, gob_t *gob)
747 {
748         assert(gob);
749         assert(image>=0);
750         assert(image<gob->num_images);
751         return gob->hs_y[image];
752 }
753
754
755 int read_pcx(unsigned char * handle, void *buf, int buf_len, char *pal)
756 {
757         unsigned char *buffer=buf;
758         short c1;
759         short a, b;
760         long ofs1;
761         if (buffer != 0) {
762                 handle += 128;
763                 ofs1 = 0;
764                 while (ofs1 < buf_len) {
765                         a = *(handle++);
766                         if ((a & 0xc0) == 0xc0) {
767                                 b = *(handle++);
768                                 a &= 0x3f;
769                                 for (c1 = 0; c1 < a && ofs1 < buf_len; c1++)
770                                         buffer[ofs1++] = (char) b;
771                         } else
772                                 buffer[ofs1++] = (char) a;
773                 }
774                 if (pal != 0) {
775                         handle++;
776                         for (c1 = 0; c1 < 768; c1++)
777                                 pal[c1] = *(handle++) /*fgetc(handle)*/ >> 2;
778                 }
779         }
780         return 0;
781 }
782
783
784 void register_background(char *pixels, char pal[768])
785 {
786         if (background) {
787                 free(background);
788                 background = NULL;
789         }
790         background_drawn = 0;
791         if (!pixels)
792                 return;
793         assert(pal);
794         if (scale_up) {
795                 background = malloc(screen_pitch*screen_height);
796                 assert(background);
797                 do_scale2x((unsigned char *)pixels, JNB_WIDTH, JNB_HEIGHT, (unsigned char *)background);
798         } else {
799                 background = malloc(JNB_WIDTH*JNB_HEIGHT);
800                 assert(background);
801                 memcpy(background, pixels, JNB_WIDTH*JNB_HEIGHT);
802         }
803 }
804
805 int register_gob(unsigned char *handle, gob_t *gob, int len)
806 {
807         unsigned char *gob_data;
808         int i;
809
810         gob_data = malloc(len);
811         memcpy(gob_data, handle, len);
812
813         gob->num_images = (short)((gob_data[0]) + (gob_data[1] << 8));
814
815         gob->width = malloc(gob->num_images*sizeof(int));
816         gob->height = malloc(gob->num_images*sizeof(int));
817         gob->hs_x = malloc(gob->num_images*sizeof(int));
818         gob->hs_y = malloc(gob->num_images*sizeof(int));
819         gob->data = malloc(gob->num_images*sizeof(void *));
820         gob->orig_data = malloc(gob->num_images*sizeof(void *));
821         for (i=0; i<gob->num_images; i++) {
822                 int image_size;
823                 int offset;
824
825                 offset = (gob_data[i*4+2]) + (gob_data[i*4+3] << 8) + (gob_data[i*4+4] << 16) + (gob_data[i*4+5] << 24);
826
827                 gob->width[i]  = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
828                 gob->height[i] = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
829                 gob->hs_x[i]   = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
830                 gob->hs_y[i]   = (short)((gob_data[offset]) + (gob_data[offset+1] << 8)); offset += 2;
831
832                 image_size = gob->width[i] * gob->height[i];
833                 gob->orig_data[i] = malloc(image_size);
834                 memcpy(gob->orig_data[i], &gob_data[offset], image_size);
835                 if (scale_up) {
836                         image_size = gob->width[i] * gob->height[i] * 4;
837                         gob->data[i] = malloc(image_size);
838                         do_scale2x((unsigned char *)gob->orig_data[i], gob->width[i], gob->height[i], (unsigned char *)gob->data[i]);
839                 } else {
840                         gob->data[i] = (unsigned short *)gob->orig_data[i];
841                 }
842         }
843         free(gob_data);
844         return 0;
845 }
846
847
848 void recalculate_gob(gob_t *gob, char pal[768])
849 {
850 }
851
852 void register_mask(void *pixels)
853 {
854         if (mask) {
855                 free(mask);
856                 mask = NULL;
857         }
858         assert(pixels);
859         if (scale_up) {
860                 mask = malloc(screen_pitch*screen_height);
861                 assert(mask);
862                 do_scale2x((unsigned char *)pixels, JNB_WIDTH, JNB_HEIGHT, (unsigned char *)mask);
863         } else {
864                 mask = malloc(JNB_WIDTH*JNB_HEIGHT);
865                 assert(mask);
866                 memcpy(mask, pixels, JNB_WIDTH*JNB_HEIGHT);
867         }
868 }