3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
5 * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
7 * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
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.
13 * This file is part of Jump'n'Bump.
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.
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.
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
31 #include "SDL_endian.h"
34 #include "jumpnbump32.xpm"
36 #include "jumpnbump128.xpm"
38 #include "jumpnbump64.xpm"
43 int screen_height=256;
46 int bytes_per_pixel=1;
47 int dirty_block_shift=4;
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];
60 static SDL_Surface *load_xpm_from_array(char **xpm)
62 #define NEXT_TOKEN { \
63 while ((*p != ' ') && (*p != '\t')) p++; \
64 while ((*p == ' ') || (*p == '\t')) p++; }
97 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
101 SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
109 SDL_FreeSurface(surface);
115 pal[color] = strtoul(++p, NULL, 16) | 0xff000000;
126 pixels = (int *)&((char *)surface->pixels)[y++ * surface->pitch];
132 SDL_FreeSurface(surface);
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);
148 void *get_vgaptr(int page, int x, int y)
150 assert(drawing_enable==1);
152 return (unsigned char *)screen_buffer[page] + (y*screen_pitch)+(x*bytes_per_pixel);
156 void set_scaling(int scale)
164 screen_pitch=screen_width*bytes_per_pixel;
171 screen_pitch=screen_width*bytes_per_pixel;
175 void open_screen(void)
181 lval = SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
183 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
191 flags = SDL_SWSURFACE;
193 flags |= SDL_FULLSCREEN;
194 jnb_surface = SDL_SetVideoMode(screen_width, screen_height, bpp, flags);
197 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
206 SDL_WM_SetCaption("Jump n Bump","");
208 icon=load_xpm_from_array(jumpnbump_xpm);
210 printf("Couldn't load icon\n");
212 SDL_WM_SetIcon(icon,NULL);
217 memset(current_pal, 0, sizeof(current_pal));
218 memset(dirty_blocks, 0, sizeof(dirty_blocks));
220 screen_buffer[0]=malloc(screen_width*screen_height*bytes_per_pixel);
221 screen_buffer[1]=malloc(screen_width*screen_height*bytes_per_pixel);
224 dirty_blocks[0]=malloc(sizeof(int)*25*16+1000);
225 dirty_blocks[1]=malloc(sizeof(int)*25*16+1000);
238 if (SDL_WM_ToggleFullScreen(jnb_surface))
243 void wait_vrt(int mix)
249 void clear_page(int page, int color)
253 assert(drawing_enable==1);
255 for (i=0; i<(25*16); i++)
256 dirty_blocks[page][i] = 1;
258 if (bytes_per_pixel==1) {
259 unsigned char *buf = get_vgaptr(page, 0, 0);
261 for (i=0; i<screen_height; i++)
262 for (j=0; j<screen_width; j++)
264 } else if (bytes_per_pixel==2) {
265 unsigned short *buf = get_vgaptr(page, 0, 0);
267 for (i=0; i<screen_height; i++)
268 for (j=0; j<screen_width; j++)
271 unsigned int *buf = get_vgaptr(page, 0, 0);
273 for (i=0; i<screen_height; i++)
274 for (j=0; j<screen_width; j++)
280 void clear_lines(int page, int y, int count, int color)
284 assert(drawing_enable==1);
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++)
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++)
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++)
316 count = ((y+count)>>dirty_block_shift) - (y>>dirty_block_shift) + 1;
317 y >>= dirty_block_shift;
318 for (i=0; i<count; i++)
320 dirty_blocks[page][(y+i)*25+j] = 1;
324 int get_color(int color, char pal[768])
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));
332 int get_pixel(int page, int x, int y)
334 assert(drawing_enable==1);
341 assert(x<screen_width);
342 assert(y<screen_height);
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);
349 return *(unsigned int *)get_vgaptr(page, x, y);
353 void set_pixel(int page, int x, int y, int color)
355 assert(drawing_enable==1);
362 assert(x<screen_width);
363 assert(y<screen_height);
365 dirty_blocks[page][(y>>dirty_block_shift)*25+(x>>dirty_block_shift)] = 1;
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;
372 *(unsigned int *)get_vgaptr(page, x, y) = color;
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;
383 int Init_2xSaI (unsigned int BitFormat)
385 if (BitFormat == 565)
387 colorMask = (0xF7DEF7DE);
388 lowPixelMask = (0x08210821);
389 qcolorMask = (0xE79CE79C);
390 qlowpixelMask = (0x18631863);
391 redblueMask = (0xF81F);
394 else if (BitFormat == 555)
396 colorMask = (0x7BDE7BDE);
397 lowPixelMask = (0x04210421);
398 qcolorMask = (0x739C739C);
399 qlowpixelMask = (0x0C630C63);
400 redblueMask = (0x7C1F);
409 Init_2xSaIMMX (BitFormat);
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])
420 #define GET_COLOR(x) (pal[(x)])
423 unsigned char *src_line;
424 unsigned char *dst_line[2];
428 dst_line[1] = dst + dst_pitch;
429 for (y=0; y<height; y++) {
430 for (x=0; x<width; x++) {
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);
438 color = *(((unsigned int*)src_line) + x);
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);
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;
452 src_line += src_pitch;
454 if (y < height - 1) {
455 dst_line[0] += dst_pitch * 2;
456 dst_line[1] += dst_pitch * 2;
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])
466 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
468 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
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)
473 #define GET_COLOR(x) (pal[(x)])
475 unsigned char *src_line[4];
476 unsigned char *dst_line[2];
478 unsigned long color[16];
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);
485 /* Point to the first 3 lines. */
488 src_line[2] = src + src_pitch;
489 src_line[3] = src + (src_pitch * 2);
492 dst_line[1] = dst + dst_pitch;
496 if (src_bytes_per_pixel == 1) {
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));
502 color[8] = GET_COLOR(*sbp); color[9] = color[8]; color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
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) {
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);
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);
525 for (y = 0; y < height; y++) {
527 /* Todo: x = width - 2, x = width - 1 */
529 for (x = 0; x < width; x++) {
530 unsigned long product1a, product1b, product2a, product2b;
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 //--------------------------------------
542 if (color[9] == color[6] && color[5] != color[10]) {
543 product2b = color[9];
544 product1b = product2b;
546 else if (color[5] == color[10] && color[9] != color[6]) {
547 product2b = color[5];
548 product1b = product2b;
550 else if (color[5] == color[10] && color[9] == color[6]) {
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]);
559 product1b = color[6];
561 product1b = color[5];
563 product1b = INTERPOLATE(color[5], color[6]);
565 product2b = product1b;
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]);
574 product2b = INTERPOLATE(color[9], color[10]);
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]);
581 product1b = INTERPOLATE(color[5], color[6]);
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]);
589 product2a = color[9];
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]);
596 product1a = color[5];
598 if (dst_bytes_per_pixel == 2) {
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);
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;
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];
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);
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);
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];
645 src_line[3] = src_line[2];
647 src_line[3] = src_line[2] + src_pitch;
649 /* Then shift the color matrix up */
650 if (src_bytes_per_pixel == 1) {
653 color[0] = GET_COLOR(*sbp); color[1] = color[0]; color[2] = GET_COLOR(*(sbp + 1)); color[3] = GET_COLOR(*(sbp + 2));
655 color[4] = GET_COLOR(*sbp); color[5] = color[4]; color[6] = GET_COLOR(*(sbp + 1)); color[7] = GET_COLOR(*(sbp + 2));
657 color[8] = GET_COLOR(*sbp); color[9] = color[8]; color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
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) {
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);
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);
682 if (y < height - 1) {
683 dst_line[0] += dst_pitch * 2;
684 dst_line[1] += dst_pitch * 2;
690 void flippage(int page)
696 assert(drawing_enable==0);
698 SDL_LockSurface(jnb_surface);
699 if (!jnb_surface->pixels) {
701 for (x=0; x<(25*16); x++) {
702 dirty_blocks[0][x] = 1;
703 dirty_blocks[1][x] = 1;
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);
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++) {
722 while ( (test_x<25) && (dirty_blocks[page][(y>>dirty_block_shift)*25+test_x]) ) {
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);
734 memset(&dirty_blocks[page], 0, sizeof(int)*25*16);
736 SDL_UnlockSurface(jnb_surface);
737 SDL_Flip(jnb_surface);
741 void draw_begin(void)
743 assert(drawing_enable==0);
746 if (background_drawn == 0) {
748 put_block(0, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
749 put_block(1, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
754 background_drawn = 1;
761 assert(drawing_enable==1);
767 void setpalette(int index, int count, char *palette)
769 SDL_Color colors[256];
772 assert(drawing_enable==0);
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);
781 SDL_SetColors(jnb_surface, &colors[index], index, count);
785 void fillpalette(int red, int green, int blue)
787 SDL_Color colors[256];
790 assert(drawing_enable==0);
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);
799 SDL_SetColors(jnb_surface, colors, 0, 256);
803 void get_block(int page, int x, int y, int width, int height, void *buffer)
805 unsigned char *buffer_ptr, *vga_ptr;
808 assert(drawing_enable==1);
821 if (y + height >= screen_height)
822 height = screen_height - y;
823 if (x + width >= screen_width)
824 width = screen_width - x;
830 vga_ptr = get_vgaptr(page, x, y);
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;
841 void put_block(int page, int x, int y, int width, int height, void *buffer)
844 unsigned char *vga_ptr, *buffer_ptr;
846 assert(drawing_enable==1);
859 if (y + height >= screen_height)
860 height = screen_height - y;
861 if (x + width >= screen_width)
862 width = screen_width - x;
868 vga_ptr = get_vgaptr(page, x, y);
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;
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;
880 for (h=0; h<height; h++)
881 dirty_blocks[page][(y+h)*25+(x+width)] = 1;
885 void put_text(int page, int x, int y, char *text, int align)
893 assert(drawing_enable==1);
895 if (text == NULL || strlen(text) == 0)
897 if (font_gobs.num_images == 0)
902 while (text[c1] != 0) {
909 if (t1 >= 33 && t1 <= 34)
912 else if (t1 >= 39 && t1 <= 41)
915 else if (t1 >= 44 && t1 <= 59)
918 else if (t1 >= 64 && t1 <= 90)
921 else if (t1 >= 97 && t1 <= 122)
947 width += pob_width(image, &font_gobs) + 1;
958 cur_x = x - width / 2;
961 cur_x = 0; /* this should cause error? -Chuck */
966 while (text[c1] != 0) {
973 if (t1 >= 33 && t1 <= 34)
976 else if (t1 >= 39 && t1 <= 41)
979 else if (t1 >= 44 && t1 <= 59)
982 else if (t1 >= 64 && t1 <= 90)
985 else if (t1 >= 97 && t1 <= 122)
1000 else if (t1 == 0x8f)
1003 else if (t1 == 0x94)
1006 else if (t1 == 0x99)
1011 put_pob(page, cur_x, y, image, &font_gobs, 1, mask_pic);
1012 cur_x += pob_width(image, &font_gobs) + 1;
1017 void put_pob(int page, int x, int y, int image, gob_t *gob, int use_mask, void *mask_pic)
1022 int draw_width, draw_height;
1025 assert(drawing_enable==1);
1028 assert(image<gob->num_images);
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;
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];
1044 if ((x + width) <= 0 || x >= screen_width)
1046 if ((y + height) <= 0 || y >= screen_height)
1056 if ((x + width) > screen_width)
1057 draw_width -= x + width - screen_width;
1063 if ((y + height) > screen_height)
1064 draw_height -= y + height - screen_height;
1067 if (bytes_per_pixel==1) {
1068 unsigned char *vga_ptr;
1069 unsigned char *pob_ptr;
1070 unsigned char *mask_ptr;
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++) {
1078 if (use_mask == 0 || (use_mask == 1 && colour == 0)) {
1088 pob_ptr += width - c2;
1089 vga_ptr += (screen_width - c2);
1090 mask_ptr += (screen_width - c2);
1092 } else if (bytes_per_pixel==2) {
1093 unsigned short *vga_ptr;
1094 unsigned short *pob_ptr;
1095 unsigned short *mask_ptr;
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++) {
1103 if (use_mask == 0 || (use_mask == 1 && colour == 0)) {
1113 pob_ptr += width - c2;
1114 vga_ptr += (screen_width - c2);
1115 mask_ptr += (screen_width - c2);
1118 unsigned int *vga_ptr;
1119 unsigned int *pob_ptr;
1120 unsigned int *mask_ptr;
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++) {
1128 if (use_mask == 0 || (use_mask == 1 && colour == 0)) {
1138 pob_ptr += width - c2;
1139 vga_ptr += (screen_width - c2);
1140 mask_ptr += (screen_width - c2);
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;
1153 int pob_width(int image, gob_t *gob)
1157 assert(image<gob->num_images);
1158 return gob->width[image];
1162 int pob_height(int image, gob_t *gob)
1166 assert(image<gob->num_images);
1167 return gob->height[image];
1171 int pob_hs_x(int image, gob_t *gob)
1175 assert(image<gob->num_images);
1176 return gob->hs_x[image];
1180 int pob_hs_y(int image, gob_t *gob)
1184 assert(image<gob->num_images);
1185 return gob->hs_y[image];
1189 int read_pcx(unsigned char * handle, void *buf, int buf_len, char *pal)
1191 unsigned char *buffer=buf;
1198 while (ofs1 < buf_len) {
1200 if ((a & 0xc0) == 0xc0) {
1203 for (c1 = 0; c1 < a && ofs1 < buf_len; c1++)
1204 buffer[ofs1++] = (char) b;
1206 buffer[ofs1++] = (char) a;
1210 for (c1 = 0; c1 < 768; c1++)
1211 pal[c1] = *(handle++) /*fgetc(handle)*/ >> 2;
1218 void register_background(char *pixels, char pal[768])
1224 background_drawn = 0;
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);
1237 Super2xSaI((unsigned char *)pixels, JNB_WIDTH, 1, (unsigned char *)background, screen_pitch, bytes_per_pixel, JNB_WIDTH, JNB_HEIGHT, int_pal);
1239 background = malloc(JNB_WIDTH*JNB_HEIGHT);
1241 memcpy(background, pixels, JNB_WIDTH*JNB_HEIGHT);
1245 int register_gob(unsigned char *handle, gob_t *gob, int len)
1247 unsigned char *gob_data;
1250 gob_data = malloc(len);
1251 memcpy(gob_data, handle, len);
1253 gob->num_images = (short)((gob_data[0]) + (gob_data[1] << 8));
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++) {
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);
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;
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);
1276 image_size = gob->width[i] * gob->height[i] * 4 * bytes_per_pixel;
1277 gob->data[i] = malloc(image_size);
1279 gob->data[i] = (unsigned short *)gob->orig_data[i];
1287 void recalculate_gob(gob_t *gob, char pal[768])
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);
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);
1309 void register_mask(void *pixels)
1321 for (i=1; i<256; i++)
1322 int_pal[i] = 0xffffffff;
1323 mask = malloc(screen_pitch*screen_height);
1326 Scale2x(pixels, JNB_WIDTH, 1, (unsigned char *)mask, screen_pitch, bytes_per_pixel, JNB_WIDTH, JNB_HEIGHT, int_pal);
1328 mask = malloc(JNB_WIDTH*JNB_HEIGHT);
1330 memcpy(mask, pixels, JNB_WIDTH*JNB_HEIGHT);