Support loading PPH files (Amstrad CPC).
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@2162 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
		
							parent
							
								
									0c7d17304a
								
							
						
					
					
						commit
						702f1835da
					
				@ -135,6 +135,7 @@ enum FILE_FORMATS
 | 
			
		||||
  FORMAT_GPL,
 | 
			
		||||
  FORMAT_SCR,
 | 
			
		||||
  FORMAT_CM5,
 | 
			
		||||
  FORMAT_PPH,
 | 
			
		||||
  FORMAT_XPM,
 | 
			
		||||
  FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -136,6 +136,11 @@ void Test_CM5(T_IO_Context *);
 | 
			
		||||
void Load_CM5(T_IO_Context *);
 | 
			
		||||
void Save_CM5(T_IO_Context *);
 | 
			
		||||
 | 
			
		||||
// -- PPH (Amstrad CPC)
 | 
			
		||||
void Test_PPH(T_IO_Context *);
 | 
			
		||||
void Load_PPH(T_IO_Context *);
 | 
			
		||||
void Save_PPH(T_IO_Context *);
 | 
			
		||||
 | 
			
		||||
// -- XPM (X PixMap)
 | 
			
		||||
// Loading is done through SDL_Image 
 | 
			
		||||
void Save_XPM(T_IO_Context*);
 | 
			
		||||
@ -153,7 +158,7 @@ void Load_SDL_Image(T_IO_Context *);
 | 
			
		||||
 | 
			
		||||
// ENUM     Name  TestFunc LoadFunc SaveFunc PalOnly Comment Layers Ext Exts  
 | 
			
		||||
T_Format File_formats[] = {
 | 
			
		||||
  {FORMAT_ALL_IMAGES, "(all)", NULL, NULL, NULL, 0, 0, 0, "", "gif;png;bmp;pcx;pkm;iff;lbm;ilbm;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;c64;koa;koala;fli;bml;cdu;prg;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;cm5"},
 | 
			
		||||
  {FORMAT_ALL_IMAGES, "(all)", NULL, NULL, NULL, 0, 0, 0, "", "gif;png;bmp;pcx;pkm;iff;lbm;ilbm;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;c64;koa;koala;fli;bml;cdu;prg;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;cm5;pph"},
 | 
			
		||||
  {FORMAT_ALL_PALETTES, "(all)", NULL, NULL, NULL, 1, 0, 0, "", "kcf;pal;gpl"},
 | 
			
		||||
  {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"},
 | 
			
		||||
  {FORMAT_GIF, " gif", Test_GIF, Load_GIF, Save_GIF, 0, 1, 1, "gif", "gif"},
 | 
			
		||||
@ -177,6 +182,7 @@ T_Format File_formats[] = {
 | 
			
		||||
  {FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 0, 1, 0, "c64", "c64;koa;koala;fli;bml;cdu;prg"},
 | 
			
		||||
  {FORMAT_SCR, " cpc", NULL,     NULL,     Save_SCR, 0, 0, 0, "cpc", "cpc;scr"},
 | 
			
		||||
  {FORMAT_CM5, " cm5", Test_CM5, Load_CM5, Save_CM5, 0, 0, 1, "cm5", "cm5"},
 | 
			
		||||
  {FORMAT_PPH, " pph", Test_PPH, Load_PPH, Save_PPH, 0, 0, 1, "pph", "pph"},
 | 
			
		||||
  {FORMAT_XPM, " xpm", NULL,     NULL,     Save_XPM, 0, 0, 0, "xpm", "xpm"},
 | 
			
		||||
  {FORMAT_MISC,"misc.",NULL,     NULL,     NULL,     0, 0, 0, "",    "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -2916,11 +2916,11 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    int cx,cy,x,y,c[4]={0,0,0,0},color,lut[16],bits,pixel,pos=0;
 | 
			
		||||
	int cand,n,used;
 | 
			
		||||
	word cols, candidates = 0, invalids = 0;
 | 
			
		||||
    int cand,n,used;
 | 
			
		||||
    word cols, candidates = 0, invalids = 0;
 | 
			
		||||
 | 
			
		||||
	// FIXME allocating this on the stack is not a good idea. On some platforms
 | 
			
		||||
	// the stack has a rather small size...
 | 
			
		||||
    // FIXME allocating this on the stack is not a good idea. On some platforms
 | 
			
		||||
    // the stack has a rather small size...
 | 
			
		||||
    byte bitmap[8000],screen_ram[1000],color_ram[1000];
 | 
			
		||||
 | 
			
		||||
    word numcolors,count;
 | 
			
		||||
@ -2932,66 +2932,66 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
 | 
			
		||||
 | 
			
		||||
    count=0;
 | 
			
		||||
 | 
			
		||||
	// Detect the ackground color the image should be using. It's the one that's
 | 
			
		||||
	// used on all tiles having 4 colors.
 | 
			
		||||
	for(y=0;y<200;y=y+8)
 | 
			
		||||
	{
 | 
			
		||||
		for (x = 0; x<160; x=x+4)
 | 
			
		||||
		{
 | 
			
		||||
			cols = 0;
 | 
			
		||||
    // Detect the ackground color the image should be using. It's the one that's
 | 
			
		||||
    // used on all tiles having 4 colors.
 | 
			
		||||
    for(y=0;y<200;y=y+8)
 | 
			
		||||
    {
 | 
			
		||||
        for (x = 0; x<160; x=x+4)
 | 
			
		||||
        {
 | 
			
		||||
            cols = 0;
 | 
			
		||||
 | 
			
		||||
			// Compute the usage count of each color in the tile
 | 
			
		||||
			for (cy=0;cy<8;cy++)
 | 
			
		||||
			for (cx=0;cx<4;cx++)
 | 
			
		||||
			{
 | 
			
		||||
				pixel=Get_pixel(context, x+cx,y+cy);
 | 
			
		||||
				cols |= (1 << pixel);
 | 
			
		||||
			}
 | 
			
		||||
            // Compute the usage count of each color in the tile
 | 
			
		||||
            for (cy=0;cy<8;cy++)
 | 
			
		||||
            for (cx=0;cx<4;cx++)
 | 
			
		||||
            {
 | 
			
		||||
                pixel=Get_pixel(context, x+cx,y+cy);
 | 
			
		||||
                cols |= (1 << pixel);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
			cand = 0;
 | 
			
		||||
			used = 0;
 | 
			
		||||
			// Count the number of used colors in the tile
 | 
			
		||||
			for (n = 0; n<16; n++)
 | 
			
		||||
			{
 | 
			
		||||
				if (cols & (1 << pixel))
 | 
			
		||||
					used++;
 | 
			
		||||
			}
 | 
			
		||||
            cand = 0;
 | 
			
		||||
            used = 0;
 | 
			
		||||
            // Count the number of used colors in the tile
 | 
			
		||||
            for (n = 0; n<16; n++)
 | 
			
		||||
            {
 | 
			
		||||
                if (cols & (1 << pixel))
 | 
			
		||||
                    used++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
			if (used>3)
 | 
			
		||||
			{
 | 
			
		||||
				// This is a tile that uses the background color (and 3 others)
 | 
			
		||||
            if (used>3)
 | 
			
		||||
            {
 | 
			
		||||
                // This is a tile that uses the background color (and 3 others)
 | 
			
		||||
 | 
			
		||||
				// Try to guess which color is most likely the background one
 | 
			
		||||
				for (n = 0; n<16; n++)
 | 
			
		||||
				{
 | 
			
		||||
					if ((cols & (1 << n)) && !((candidates | invalids) & (1 << n))) {
 | 
			
		||||
						// This color was not used in any other tile yet,
 | 
			
		||||
						// but it could be the background one.
 | 
			
		||||
						candidates |= 1 << n;
 | 
			
		||||
					}
 | 
			
		||||
                // Try to guess which color is most likely the background one
 | 
			
		||||
                for (n = 0; n<16; n++)
 | 
			
		||||
                {
 | 
			
		||||
                    if ((cols & (1 << n)) && !((candidates | invalids) & (1 << n))) {
 | 
			
		||||
                        // This color was not used in any other tile yet,
 | 
			
		||||
                        // but it could be the background one.
 | 
			
		||||
                        candidates |= 1 << n;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
					if ((cols & 1 << n) == 0 ) {
 | 
			
		||||
						// This color isn't used at all in this tile:
 | 
			
		||||
						// Can't be the global 
 | 
			
		||||
						invalids |= 1 << n;
 | 
			
		||||
					}
 | 
			
		||||
                    if ((cols & 1 << n) == 0 ) {
 | 
			
		||||
                        // This color isn't used at all in this tile:
 | 
			
		||||
                        // Can't be the global 
 | 
			
		||||
                        invalids |= 1 << n;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
					if (candidates & (1 << n)) {
 | 
			
		||||
						// We have a candidate, mark it as such
 | 
			
		||||
						cand++;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
                    if (candidates & (1 << n)) {
 | 
			
		||||
                        // We have a candidate, mark it as such
 | 
			
		||||
                        cand++;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
				// After checking the constraints for this tile, do we have
 | 
			
		||||
				// candidate background colors left ?
 | 
			
		||||
				if (cand==0)
 | 
			
		||||
				{
 | 
			
		||||
					Warning_message("No possible global background color found");
 | 
			
		||||
					return 1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
                // After checking the constraints for this tile, do we have
 | 
			
		||||
                // candidate background colors left ?
 | 
			
		||||
                if (cand==0)
 | 
			
		||||
                {
 | 
			
		||||
                    Warning_message("No possible global background color found");
 | 
			
		||||
                    return 1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	// Now just pick the first valid candidate
 | 
			
		||||
	for (n = 0; n<16; n++)
 | 
			
		||||
@ -3302,6 +3302,8 @@ void Test_CM5(T_IO_Context * context)
 | 
			
		||||
      File_error = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fclose(file);
 | 
			
		||||
 | 
			
		||||
  // TODO: check existence of a .SCR file with the same name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3439,8 +3441,6 @@ void Load_CM5(T_IO_Context* context)
 | 
			
		||||
		ext[1] = (idx & 2) ? 'f':'F';
 | 
			
		||||
		ext[2] = (idx & 4) ? 'x':'X';
 | 
			
		||||
 | 
			
		||||
		printf("trying to load %s...\n", filename);
 | 
			
		||||
 | 
			
		||||
  		file = fopen(filename, "rb");
 | 
			
		||||
  	} while(file == NULL);
 | 
			
		||||
  }
 | 
			
		||||
@ -3538,3 +3538,364 @@ void Save_CM5(T_IO_Context* context)
 | 
			
		||||
  File_error = 0;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Amstrad CPC 'PPH' for Perfect Pix.
 | 
			
		||||
// This is a format designed by Rhino.
 | 
			
		||||
// There are 3 modes:
 | 
			
		||||
// - Mode 'R': 1:1 pixels, 16 colors from the CPC 27 color palette.
 | 
			
		||||
//   (this is implemented on CPC as two pictures with wide pixels, the "odd" one
 | 
			
		||||
//   being shifted half a pixel to the right), and flipping)
 | 
			
		||||
// - Mode 'B0': wide pixels, up to 126 out of 378 colors.
 | 
			
		||||
//   (this is implemented as two pictures with wide pixels, sharing the same 16
 | 
			
		||||
//   color palette, and flipping)
 | 
			
		||||
// - Mode 'B1': 1:1 pixels, 1 fixed color, up to 34 palettes of 9 colors
 | 
			
		||||
//   (actually 4 colors + flipping)
 | 
			
		||||
//
 | 
			
		||||
// - The standard CPC formats can also be encapsulated into a PPH file.
 | 
			
		||||
*/
 | 
			
		||||
void Test_PPH(T_IO_Context * context)
 | 
			
		||||
{
 | 
			
		||||
  FILE *file;
 | 
			
		||||
  unsigned char buffer[MAX_PATH_CHARACTERS];
 | 
			
		||||
  long file_size;
 | 
			
		||||
  int w;
 | 
			
		||||
  int expected;
 | 
			
		||||
 | 
			
		||||
  Get_full_filename(buffer, context->File_name, context->File_directory);
 | 
			
		||||
 | 
			
		||||
  File_error = 1;
 | 
			
		||||
 | 
			
		||||
  if ((file = fopen(buffer, "rb")))
 | 
			
		||||
  {
 | 
			
		||||
    // First check file size is large enough to hold the header
 | 
			
		||||
    file_size = File_length_file(file);
 | 
			
		||||
    if (file_size < 11) {
 | 
			
		||||
      File_error = 1;
 | 
			
		||||
      goto abort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // File is large enough for the header, now check if the data makes some sense
 | 
			
		||||
    fread(buffer, 1, 6, file);
 | 
			
		||||
    if (buffer[0] > 5) {
 | 
			
		||||
        // Unknown mode
 | 
			
		||||
        File_error = 2;
 | 
			
		||||
        goto abort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    w = buffer[1] | (buffer[2] << 8);
 | 
			
		||||
    if (w < 2 || w > 384) {
 | 
			
		||||
        // Invalid width
 | 
			
		||||
        File_error = 3;
 | 
			
		||||
        goto abort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    w = buffer[3] | (buffer[4] << 8);
 | 
			
		||||
    if (w < 1 || w > 272) {
 | 
			
		||||
        // Invalid height
 | 
			
		||||
        File_error = 4;
 | 
			
		||||
        goto abort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (buffer[5] < 1 || buffer[5] > 28)
 | 
			
		||||
    {
 | 
			
		||||
        // Invalid palettes count
 | 
			
		||||
        File_error = 5;
 | 
			
		||||
        goto abort;
 | 
			
		||||
    }
 | 
			
		||||
    expected = 6; // Size of header
 | 
			
		||||
    switch(buffer[0])
 | 
			
		||||
    {
 | 
			
		||||
        case 0:
 | 
			
		||||
        case 3:
 | 
			
		||||
        case 4:
 | 
			
		||||
            // Palette size should be 16 bytes, only 1 palette.
 | 
			
		||||
            if (buffer[5] != 1) {
 | 
			
		||||
                File_error = 7;
 | 
			
		||||
                goto abort;
 | 
			
		||||
            }
 | 
			
		||||
            expected += 16;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 1:
 | 
			
		||||
        case 5:
 | 
			
		||||
            expected += buffer[5] * 5 - 1;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 2:
 | 
			
		||||
            // Palete size should be 2 bytes
 | 
			
		||||
            if (buffer[5] != 1) {
 | 
			
		||||
                File_error = 7;
 | 
			
		||||
                goto abort;
 | 
			
		||||
            }
 | 
			
		||||
            expected += 2;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (file_size != expected)
 | 
			
		||||
    {
 | 
			
		||||
        File_error = 6;
 | 
			
		||||
        goto abort;
 | 
			
		||||
    }
 | 
			
		||||
    File_error = 0;
 | 
			
		||||
  } else {
 | 
			
		||||
    File_error = 8;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
abort:
 | 
			
		||||
  fclose(file);
 | 
			
		||||
 | 
			
		||||
  // TODO: check existence of .ODD/.EVE files with the same name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Load_PPH(T_IO_Context* context)
 | 
			
		||||
{
 | 
			
		||||
  FILE *file;
 | 
			
		||||
  FILE *feven;
 | 
			
		||||
  char filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
 | 
			
		||||
  // Read in the header
 | 
			
		||||
  uint8_t mode;
 | 
			
		||||
  uint16_t width;
 | 
			
		||||
  uint16_t height;
 | 
			
		||||
  uint8_t npal;
 | 
			
		||||
  int i,j;
 | 
			
		||||
  uint8_t a,b,c,d;
 | 
			
		||||
  int file_size;
 | 
			
		||||
  char* ext;
 | 
			
		||||
  uint8_t pl[16];
 | 
			
		||||
 | 
			
		||||
  static const T_Components CPCPAL[27] =
 | 
			
		||||
  {
 | 
			
		||||
      { 0x00, 0x02, 0x01 }, { 0x00, 0x02, 0x6B }, { 0x0C, 0x02, 0xF4 },
 | 
			
		||||
      { 0x6C, 0x02, 0x01 }, { 0x69, 0x02, 0x68 }, { 0x6C, 0x02, 0xF2 },
 | 
			
		||||
      { 0xF3, 0x05, 0x06 }, { 0xF0, 0x02, 0x68 }, { 0xF3, 0x02, 0xF4 },
 | 
			
		||||
      { 0x02, 0x78, 0x01 }, { 0x00, 0x78, 0x68 }, { 0x0C, 0x7B, 0xF4 },
 | 
			
		||||
      { 0x6E, 0x7B, 0x01 }, { 0x6E, 0x7D, 0x6B }, { 0x6E, 0x7B, 0xF6 },
 | 
			
		||||
      { 0xF3, 0x7D, 0x0D }, { 0xF3, 0x7D, 0x6B }, { 0xFA, 0x80, 0xF9 },
 | 
			
		||||
      { 0x02, 0xF0, 0x01 }, { 0x00, 0xF3, 0x6B }, { 0x0F, 0xF3, 0xF2 },
 | 
			
		||||
      { 0x71, 0xF5, 0x04 }, { 0x71, 0xF3, 0x6B }, { 0x71, 0xF3, 0xF4 },
 | 
			
		||||
      { 0xF3, 0xF3, 0x0D }, { 0xF3, 0xF3, 0x6D }, { 0xFF, 0xF3, 0xF9 }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
			
		||||
 | 
			
		||||
  if (!(file = fopen(filename, "rb")))
 | 
			
		||||
  {
 | 
			
		||||
      File_error = 1;
 | 
			
		||||
      return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  file_size=File_length_file(file);
 | 
			
		||||
 | 
			
		||||
  Read_byte(file, &mode);
 | 
			
		||||
  Read_word_le(file, &width);
 | 
			
		||||
  Read_word_le(file, &height);
 | 
			
		||||
  Read_byte(file, &npal);
 | 
			
		||||
 | 
			
		||||
  if (npal > 16)
 | 
			
		||||
      npal = 16;
 | 
			
		||||
 | 
			
		||||
  // Switch to the proper aspect ratio
 | 
			
		||||
  switch (mode)
 | 
			
		||||
  {
 | 
			
		||||
      case 0:
 | 
			
		||||
      case 4:
 | 
			
		||||
        context->Ratio = PIXEL_WIDE;
 | 
			
		||||
        width /= 2;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case 2:
 | 
			
		||||
        context->Ratio = PIXEL_TALL;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case 1:
 | 
			
		||||
      case 5:
 | 
			
		||||
      case 3:
 | 
			
		||||
        context->Ratio = PIXEL_SIMPLE;
 | 
			
		||||
        break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Pre_load(context, width, height, file_size, FORMAT_PPH, context->Ratio, 0);
 | 
			
		||||
 | 
			
		||||
  context->Width = width;
 | 
			
		||||
  context->Height = height;
 | 
			
		||||
 | 
			
		||||
  // First of all, detect the mode
 | 
			
		||||
  // 0, 1, 2 > Load as with SCR files?
 | 
			
		||||
  // R(3)    > Load as single layer, square pixels, 16 colors
 | 
			
		||||
  // B0(4)   > Load as single layer, wide pixels, expand palette with colorcycling
 | 
			
		||||
  // B1(5)   > Load as ???
 | 
			
		||||
  //           Maybe special mode similar to mode5, with 2 layers + auto-flicker?
 | 
			
		||||
 | 
			
		||||
  switch (mode)
 | 
			
		||||
  {
 | 
			
		||||
      case 0:
 | 
			
		||||
      case 3: // R
 | 
			
		||||
          // 16-color palette
 | 
			
		||||
          for (i = 0; i < 16; i++)
 | 
			
		||||
          {
 | 
			
		||||
              uint8_t color;
 | 
			
		||||
              Read_byte(file, &color);
 | 
			
		||||
              context->Palette[i] = CPCPAL[color];
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
      case 1:
 | 
			
		||||
      case 5: // B1
 | 
			
		||||
      {
 | 
			
		||||
          // Single or multiple 4-color palettes
 | 
			
		||||
          uint8_t base[4];
 | 
			
		||||
          for (j = 0; j < npal; j++)
 | 
			
		||||
          {
 | 
			
		||||
            for (i = 0; i < 4; i++)
 | 
			
		||||
            {
 | 
			
		||||
              Read_byte(file,&base[i]);
 | 
			
		||||
            }
 | 
			
		||||
            for (i = 0; i < 16; i++)
 | 
			
		||||
            {
 | 
			
		||||
              context->Palette[i + 16*j].R
 | 
			
		||||
                  = (CPCPAL[base[i & 3]].R + CPCPAL[base[i >> 2]].R) / 2;
 | 
			
		||||
              context->Palette[i + 16*j].G
 | 
			
		||||
                  = (CPCPAL[base[i & 3]].G + CPCPAL[base[i >> 2]].G) / 2;
 | 
			
		||||
              context->Palette[i + 16*j].B
 | 
			
		||||
                  = (CPCPAL[base[i & 3]].B + CPCPAL[base[i >> 2]].B) / 2;
 | 
			
		||||
            }
 | 
			
		||||
            // TODO this byte marks where this palette stops being used and the
 | 
			
		||||
            // next starts. We must handle this!
 | 
			
		||||
            Read_byte(file,&pl[j]);
 | 
			
		||||
          }
 | 
			
		||||
          pl[npal - 1] = 255;
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      case 2:
 | 
			
		||||
          // Single 2-color palette
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
      case 4: // B0
 | 
			
		||||
      {
 | 
			
		||||
          // Single 16-color palette + flipping, need to expand palette and
 | 
			
		||||
          // setup colorcycling ranges.
 | 
			
		||||
          uint8_t base[16];
 | 
			
		||||
          for (i = 0; i < 16; i++)
 | 
			
		||||
          {
 | 
			
		||||
              Read_byte(file,&base[i]);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          for (i = 0; i < 256; i++)
 | 
			
		||||
          {
 | 
			
		||||
              context->Palette[i].R
 | 
			
		||||
                  = (CPCPAL[base[i & 15]].R + CPCPAL[base[i >> 4]].R) / 2;
 | 
			
		||||
              context->Palette[i].G
 | 
			
		||||
                  = (CPCPAL[base[i & 15]].G + CPCPAL[base[i >> 4]].G) / 2;
 | 
			
		||||
              context->Palette[i].B
 | 
			
		||||
                  = (CPCPAL[base[i & 15]].B + CPCPAL[base[i >> 4]].B) / 2;
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fclose(file);
 | 
			
		||||
 | 
			
		||||
  // Load the picture data
 | 
			
		||||
  // There are two pages, each storing bytes in the CPC vram format but lines in
 | 
			
		||||
  // linear order.
 | 
			
		||||
  ext = filename + strlen(filename) - 3;
 | 
			
		||||
  ext[0] = 'O';
 | 
			
		||||
  ext[1] = 'D';
 | 
			
		||||
  ext[2] = 'D';
 | 
			
		||||
 | 
			
		||||
  file = fopen(filename, "rb");
 | 
			
		||||
 | 
			
		||||
  ext[0] = 'E';
 | 
			
		||||
  ext[1] = 'V';
 | 
			
		||||
  ext[2] = 'E';
 | 
			
		||||
 | 
			
		||||
  feven = fopen(filename, "rb");
 | 
			
		||||
 | 
			
		||||
  c = 0;
 | 
			
		||||
  d = 0;
 | 
			
		||||
 | 
			
		||||
  for (j = 0; j < height; j++)
 | 
			
		||||
  {
 | 
			
		||||
      for (i = 0; i < width;)
 | 
			
		||||
      {
 | 
			
		||||
          uint8_t even, odd;
 | 
			
		||||
          Read_byte(feven, &even);
 | 
			
		||||
          Read_byte(file, &odd);
 | 
			
		||||
 | 
			
		||||
          switch (mode)
 | 
			
		||||
          {
 | 
			
		||||
              case 4:
 | 
			
		||||
                a = ((even & 0x02) << 2) | ((even & 0x08) >> 2)
 | 
			
		||||
                  | ((even & 0x20) >> 3) | ((even & 0x80) >> 7);
 | 
			
		||||
                a <<= 4;
 | 
			
		||||
                a |= ((odd & 0x02) << 2) | (( odd & 0x08) >> 2)
 | 
			
		||||
                  | (( odd & 0x20) >> 3) | (( odd & 0x80) >> 7);
 | 
			
		||||
 | 
			
		||||
                b = ((even & 0x01) << 3) | ((even & 0x04) >> 1)
 | 
			
		||||
                  | ((even & 0x10) >> 2) | ((even & 0x40) >> 6);
 | 
			
		||||
                b <<= 4;
 | 
			
		||||
                b |= ((odd & 0x01) << 3) | (( odd & 0x04) >> 1)
 | 
			
		||||
                  | (( odd & 0x10) >> 2) | (( odd & 0x40) >> 6);
 | 
			
		||||
 | 
			
		||||
                Set_pixel(context, i++, j, a);
 | 
			
		||||
                Set_pixel(context, i++, j, b);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
              case 3:
 | 
			
		||||
                a = ((even & 0x02) << 2) | ((even & 0x08) >> 2)
 | 
			
		||||
                  | ((even & 0x20) >> 3) | ((even & 0x80) >> 7);
 | 
			
		||||
                b = (( odd & 0x02) << 2) | (( odd & 0x08) >> 2)
 | 
			
		||||
                  | (( odd & 0x20) >> 3) | (( odd & 0x80) >> 7);
 | 
			
		||||
                c = ((even & 0x01) << 3) | ((even & 0x04) >> 1)
 | 
			
		||||
                  | ((even & 0x10) >> 2) | ((even & 0x40) >> 6);
 | 
			
		||||
                d = (( odd & 0x01) << 3) | (( odd & 0x04) >> 1)
 | 
			
		||||
                  | (( odd & 0x10) >> 2) | (( odd & 0x40) >> 6);
 | 
			
		||||
                Set_pixel(context, i++, j, j & 1 ? b : a);
 | 
			
		||||
                Set_pixel(context, i++, j, j & 1 ? a : b);
 | 
			
		||||
                Set_pixel(context, i++, j, j & 1 ? d : c);
 | 
			
		||||
                Set_pixel(context, i++, j, j & 1 ? c : d);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
              case 5:
 | 
			
		||||
                if (d > pl[c])
 | 
			
		||||
                {
 | 
			
		||||
                    d = 0;
 | 
			
		||||
                    c++;
 | 
			
		||||
                }
 | 
			
		||||
                a = ((even & 0x80) >> 6) | ((even & 0x08) >> 3);
 | 
			
		||||
                b = (( odd & 0x80) >> 6) | (( odd & 0x08) >> 3);
 | 
			
		||||
                Set_pixel(context, i++, j, a + (b << 2) + c * 16);
 | 
			
		||||
                a = ((even & 0x40) >> 5) | ((even & 0x04) >> 2);
 | 
			
		||||
                b = (( odd & 0x40) >> 5) | (( odd & 0x04) >> 2);
 | 
			
		||||
                Set_pixel(context, i++, j, a + (b << 2) + c * 16);
 | 
			
		||||
                a = ((even & 0x20) >> 4) | ((even & 0x02) >> 1);
 | 
			
		||||
                b = (( odd & 0x20) >> 4) | (( odd & 0x02) >> 1);
 | 
			
		||||
                Set_pixel(context, i++, j, a + (b << 2) + c * 16);
 | 
			
		||||
                a = ((even & 0x10) >> 3) | ((even & 0x01) >> 0);
 | 
			
		||||
                b = (( odd & 0x10) >> 3) | (( odd & 0x01) >> 0);
 | 
			
		||||
                Set_pixel(context, i++, j, a + (b << 2) + c * 16);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
              default:
 | 
			
		||||
                File_error = 2;
 | 
			
		||||
                return;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
      d++;
 | 
			
		||||
  }
 | 
			
		||||
  fclose(file);
 | 
			
		||||
  fclose(feven);
 | 
			
		||||
 | 
			
		||||
  File_error = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Save_PPH(T_IO_Context* context)
 | 
			
		||||
{
 | 
			
		||||
    // TODO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -136,7 +136,10 @@ void Set_data_directory(const char * program_dir, char * data_dir)
 | 
			
		||||
  // Haiku provides us with an API to find it.
 | 
			
		||||
  #elif defined(__HAIKU__)
 | 
			
		||||
    if (find_path(Set_data_directory, B_FIND_PATH_DATA_DIRECTORY, "grafx2/", data_dir, PATH_MAX) != B_OK)
 | 
			
		||||
      strcat(data_dir,"../data/grafx2/");
 | 
			
		||||
    {
 | 
			
		||||
      // If the program is not installed, find_path will fail. Try from local dir then.
 | 
			
		||||
      strcat(data_dir,"../share/grafx2/");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  // All other targets, program is in a "bin" subdirectory
 | 
			
		||||
  #else
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user