Read Packed CPC files from ConvImgCPC
This commit is contained in:
		
							parent
							
								
									2669ba9b06
								
							
						
					
					
						commit
						095ad1a1ec
					
				
							
								
								
									
										189
									
								
								src/cpcformats.c
									
									
									
									
									
								
							
							
						
						
									
										189
									
								
								src/cpcformats.c
									
									
									
									
									
								
							@ -118,6 +118,25 @@ void Test_SCR(T_IO_Context * context, FILE * file)
 | 
				
			|||||||
      File_error = 0;
 | 
					      File_error = 0;
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else if (loading_address == 0xc000 || loading_address == 0x0200)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      byte buffer[4];
 | 
				
			||||||
 | 
					      fseek(file, 128, SEEK_SET); // right after AMSDOS header
 | 
				
			||||||
 | 
					      Read_bytes(file, buffer, 4);
 | 
				
			||||||
 | 
					      // ConvImgCPC "LZW" packed pictures. Signatures :
 | 
				
			||||||
 | 
					      // PKSL -> 320x200 STD
 | 
				
			||||||
 | 
					      // PKS3 -> 320x200 Mode 3
 | 
				
			||||||
 | 
					      // PKSP -> 320x200 PLUS
 | 
				
			||||||
 | 
					      // PKVL -> Overscan STD
 | 
				
			||||||
 | 
					      // PKVP -> Overscan PLUS
 | 
				
			||||||
 | 
					      if (buffer[0] == 'P' && buffer[1] == 'K'
 | 
				
			||||||
 | 
					          && (buffer[2] == 'S' || buffer[2] == 'V')
 | 
				
			||||||
 | 
					          && (buffer[3] == 'L' || buffer[3] == 'P'))
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        File_error = 0;
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    file_size = File_length_file(file);
 | 
					    file_size = File_length_file(file);
 | 
				
			||||||
@ -167,6 +186,104 @@ void Test_SCR(T_IO_Context * context, FILE * file)
 | 
				
			|||||||
  fclose(pal_file);
 | 
					  fclose(pal_file);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Unpack LZ streams from CPCconvImg v0.x (Demoniak/iMPACT!)
 | 
				
			||||||
 | 
					 * @param dst destination buffer
 | 
				
			||||||
 | 
					 * @param file input
 | 
				
			||||||
 | 
					 * @return unpacked length or -1 for error
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int Depack_CPC_LZW(byte * dst, FILE * file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int bitcount = 0;
 | 
				
			||||||
 | 
					  byte control_byte = 0;
 | 
				
			||||||
 | 
					  int count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (;;)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (bitcount == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (!Read_byte(file, &control_byte))
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					      bitcount = 8;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(control_byte & 1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (!Read_byte(file, &dst[count++]))
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      byte code, code2;
 | 
				
			||||||
 | 
					      word delta;
 | 
				
			||||||
 | 
					      word len;
 | 
				
			||||||
 | 
					      if (!Read_byte(file, &code))
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					      if (code == 0)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        return count; // EOF
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (code & 0x80)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // 1LLL DDDD DDDD DDDD
 | 
				
			||||||
 | 
					        if (!Read_byte(file, &code2))
 | 
				
			||||||
 | 
					          return -1;
 | 
				
			||||||
 | 
					        len = 3 + ((code >> 4) & 7);
 | 
				
			||||||
 | 
					        delta = ((word)(code & 15) << 8) + (word)code2 + 1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else if (code & 0x40)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // 01DD DDDD
 | 
				
			||||||
 | 
					        len = 2;
 | 
				
			||||||
 | 
					        delta = (code & 0x3f) + 1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else if (code & 0x20)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // 001L LLLL DDDD DDDD
 | 
				
			||||||
 | 
					        len = 2 + (code & 31);
 | 
				
			||||||
 | 
					        if (!Read_byte(file, &code2))
 | 
				
			||||||
 | 
					          return -1;
 | 
				
			||||||
 | 
					        delta = (word)code2 + 1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else if (code & 0x10)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // 0001 DDDD DDDD DDDD LLLL LLLL
 | 
				
			||||||
 | 
					        if (!Read_byte(file, &code2))
 | 
				
			||||||
 | 
					          return -1;
 | 
				
			||||||
 | 
					        delta = ((word)(code & 15) << 8) + (word)code2 + 1;
 | 
				
			||||||
 | 
					        if (!Read_byte(file, &code2))
 | 
				
			||||||
 | 
					          return -1;
 | 
				
			||||||
 | 
					        len = (word)code2 + 1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else if (code == 0x0f)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // 0000 1111 LDLD LDLD
 | 
				
			||||||
 | 
					        if (!Read_byte(file, &code2))
 | 
				
			||||||
 | 
					          return -1;
 | 
				
			||||||
 | 
					        delta = len = (word)code2 + 1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else if (code > 1)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // 0000 LDLD   1 < len = delta < 15
 | 
				
			||||||
 | 
					        delta = len = (word)code;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        // 0000 0001
 | 
				
			||||||
 | 
					        delta = len = 256;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      while (len--)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        dst[count] = dst[count - delta];
 | 
				
			||||||
 | 
					        count++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    bitcount--;
 | 
				
			||||||
 | 
					    control_byte >>= 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Load Advanced OCP Art Studio files (Amstrad CPC)
 | 
					 * Load Advanced OCP Art Studio files (Amstrad CPC)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -215,6 +332,7 @@ void Load_SCR(T_IO_Context * context)
 | 
				
			|||||||
  byte sig[3];
 | 
					  byte sig[3];
 | 
				
			||||||
  word block_length;
 | 
					  word block_length;
 | 
				
			||||||
  word win_width, win_height;
 | 
					  word win_width, win_height;
 | 
				
			||||||
 | 
					  int linear = 0;
 | 
				
			||||||
  int is_win = 0;
 | 
					  int is_win = 0;
 | 
				
			||||||
  int columns = 80;
 | 
					  int columns = 80;
 | 
				
			||||||
  int cpc_plus = 0;
 | 
					  int cpc_plus = 0;
 | 
				
			||||||
@ -280,7 +398,72 @@ void Load_SCR(T_IO_Context * context)
 | 
				
			|||||||
  cpc_ram = GFX2_malloc(64*1024);
 | 
					  cpc_ram = GFX2_malloc(64*1024);
 | 
				
			||||||
  memset(cpc_ram, 0, 64*1024);
 | 
					  memset(cpc_ram, 0, 64*1024);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (0 != memcmp(sig, "MJH", 3) || block_length > 16384)
 | 
					  if (0 == memcmp(sig, "PKV", 3))
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // PKVL / PKVP => Overscan
 | 
				
			||||||
 | 
					    fseek(file, 4, SEEK_CUR);
 | 
				
			||||||
 | 
					    i = Depack_CPC_LZW(cpc_ram + load_address, file);
 | 
				
			||||||
 | 
					    if (i < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      File_error = 1;
 | 
				
			||||||
 | 
					      fclose(file);
 | 
				
			||||||
 | 
					      free(cpc_ram);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    GFX2_Log(GFX2_DEBUG, "%c%c%c%c count=%d\n", sig[0], sig[1], sig[2], block_length & 255, i);
 | 
				
			||||||
 | 
					    cpc_plus = (block_length & 255) == 'P';
 | 
				
			||||||
 | 
					    if (cpc_plus)
 | 
				
			||||||
 | 
					      cpc_plus_pal = cpc_ram + 0x801;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      int j;
 | 
				
			||||||
 | 
					      for (j = 0; j < 16; j++)
 | 
				
			||||||
 | 
					        pal_data[12*j] = CPC_Firmware_to_Hardware_color(cpc_ram[0x801 + j]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    context->Comment[COMMENT_SIZE-2] = ' ';
 | 
				
			||||||
 | 
					    context->Comment[COMMENT_SIZE-1] = 'P';
 | 
				
			||||||
 | 
					    context->Comment[COMMENT_SIZE] = '\0';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (0 == memcmp(sig, "PKS", 3))
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // PKSL = CPC "old"
 | 
				
			||||||
 | 
					    // PKSP = CPC +
 | 
				
			||||||
 | 
					    fseek(file, 4 + 1, SEEK_CUR);
 | 
				
			||||||
 | 
					    cpc_plus = (block_length & 255) == 'P';
 | 
				
			||||||
 | 
					    if (!Read_bytes(file, cpc_ram, cpc_plus ? 32 : 16))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      File_error = 1;
 | 
				
			||||||
 | 
					      fclose(file);
 | 
				
			||||||
 | 
					      free(cpc_ram);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!cpc_plus)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      for (i = 0; i < 16; i++)
 | 
				
			||||||
 | 
					        pal_data[12*i] = CPC_Firmware_to_Hardware_color(cpc_ram[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      cpc_plus_pal = cpc_ram;
 | 
				
			||||||
 | 
					    i = Depack_CPC_LZW(cpc_ram + load_address, file);
 | 
				
			||||||
 | 
					    if (i < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      File_error = 1;
 | 
				
			||||||
 | 
					      fclose(file);
 | 
				
			||||||
 | 
					      free(cpc_ram);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    mode = block_length >> 8;
 | 
				
			||||||
 | 
					    GFX2_Log(GFX2_DEBUG, "%c%c%c%c mode %d count=%d\n", sig[0], sig[1], sig[2], block_length & 255, mode, i);
 | 
				
			||||||
 | 
					    linear = 1;
 | 
				
			||||||
 | 
					    display_start = load_address;
 | 
				
			||||||
 | 
					    i = 0;
 | 
				
			||||||
 | 
					    height = 200;
 | 
				
			||||||
 | 
					    columns = 80;
 | 
				
			||||||
 | 
					    context->Comment[COMMENT_SIZE-2] = ' ';
 | 
				
			||||||
 | 
					    context->Comment[COMMENT_SIZE-1] = 'P';
 | 
				
			||||||
 | 
					    context->Comment[COMMENT_SIZE] = '\0';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (0 != memcmp(sig, "MJH", 3) || block_length > 16384)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // raw data
 | 
					    // raw data
 | 
				
			||||||
    Read_bytes(file, cpc_ram + load_address, file_size);
 | 
					    Read_bytes(file, cpc_ram + load_address, file_size);
 | 
				
			||||||
@ -601,7 +784,7 @@ void Load_SCR(T_IO_Context * context)
 | 
				
			|||||||
  File_error = 0;
 | 
					  File_error = 0;
 | 
				
			||||||
  Pre_load(context, width, height, real_file_size, FORMAT_SCR, ratio, bpp);
 | 
					  Pre_load(context, width, height, real_file_size, FORMAT_SCR, ratio, bpp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!is_win)
 | 
					  if (!is_win && !linear)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // Standard resolution files have the 200 lines stored in block
 | 
					    // Standard resolution files have the 200 lines stored in block
 | 
				
			||||||
    // of 25 lines of 80 bytes = 2000 bytes every 2048 bytes.
 | 
					    // of 25 lines of 80 bytes = 2000 bytes every 2048 bytes.
 | 
				
			||||||
@ -645,6 +828,8 @@ void Load_SCR(T_IO_Context * context)
 | 
				
			|||||||
      byte pixels;
 | 
					      byte pixels;
 | 
				
			||||||
      if (is_win)
 | 
					      if (is_win)
 | 
				
			||||||
        addr = display_start + y * columns + i;
 | 
					        addr = display_start + y * columns + i;
 | 
				
			||||||
 | 
					      else if (linear)
 | 
				
			||||||
 | 
					        addr = display_start + y + i * height;
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        addr = display_start + ((y >> 3) * columns) + i;
 | 
					        addr = display_start + ((y >> 3) * columns) + i;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user