Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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