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