loadsave.c: Add functions to open file with alternate extension.
Used by CPC format which are in several files : PPH format uses PPH, ODD, EVE CM5 uses CM5 + GFX
This commit is contained in:
		
							parent
							
								
									fda4708756
								
							
						
					
					
						commit
						be824627ce
					
				@ -2321,6 +2321,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
 | 
				
			|||||||
        T_IO_Context preview_context;
 | 
					        T_IO_Context preview_context;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
        Init_context_preview(&preview_context, Selector_filename, Selector->Directory);
 | 
					        Init_context_preview(&preview_context, Selector_filename, Selector->Directory);
 | 
				
			||||||
 | 
					        preview_context.File_name_unicode = Selector_filename_unicode;
 | 
				
			||||||
        Hide_cursor();
 | 
					        Hide_cursor();
 | 
				
			||||||
        if (context->Type == CONTEXT_PALETTE)
 | 
					        if (context->Type == CONTEXT_PALETTE)
 | 
				
			||||||
          preview_context.Type = CONTEXT_PREVIEW_PALETTE;
 | 
					          preview_context.Type = CONTEXT_PREVIEW_PALETTE;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										128
									
								
								src/loadsave.c
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								src/loadsave.c
									
									
									
									
									
								
							@ -1787,6 +1787,38 @@ FILE * Open_file_write(T_IO_Context *context)
 | 
				
			|||||||
  return fopen(filename, "wb");
 | 
					  return fopen(filename, "wb");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  char *p;
 | 
				
			||||||
 | 
					  char filename[MAX_PATH_CHARACTERS]; // filename with full path
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
					  WCHAR filename_unicode[MAX_PATH_CHARACTERS];
 | 
				
			||||||
 | 
					  WCHAR * pw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (context->File_name_unicode != NULL)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Unicode_char_strlcpy((word *)filename_unicode, context->File_directory, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					    Unicode_char_strlcat((word *)filename_unicode, PATH_SEPARATOR, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					    Unicode_strlcat((word *)filename_unicode, context->File_name_unicode, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					    pw = wcschr(filename_unicode, (WCHAR)'.');
 | 
				
			||||||
 | 
					    if (pw != NULL)
 | 
				
			||||||
 | 
					      *pw = 0;
 | 
				
			||||||
 | 
					    Unicode_char_strlcat((word *)filename_unicode, ".", MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					    Unicode_char_strlcat((word *)filename_unicode, ext, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return _wfopen(filename_unicode, L"wb");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
				
			||||||
 | 
					  p = strrchr(filename, '.');
 | 
				
			||||||
 | 
					  if (p != NULL)
 | 
				
			||||||
 | 
					    *p = '\0';
 | 
				
			||||||
 | 
					  strcat(filename, ".");
 | 
				
			||||||
 | 
					  strcat(filename, ext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return fopen(filename, "wb");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
					/// For use by Load_XXX() and Test_XXX() functions
 | 
				
			||||||
FILE * Open_file_read(T_IO_Context *context)
 | 
					FILE * Open_file_read(T_IO_Context *context)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1797,6 +1829,102 @@ FILE * Open_file_read(T_IO_Context *context)
 | 
				
			|||||||
  return fopen(filename, "rb");
 | 
					  return fopen(filename, "rb");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct T_Find_alternate_ext_data
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  const char * ext;
 | 
				
			||||||
 | 
					  char basename[MAX_PATH_CHARACTERS];
 | 
				
			||||||
 | 
					  word basename_unicode[MAX_PATH_CHARACTERS];
 | 
				
			||||||
 | 
					  char foundname[MAX_PATH_CHARACTERS];
 | 
				
			||||||
 | 
					  word foundname_unicode[MAX_PATH_CHARACTERS];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void Look_for_alternate_ext(void * pdata, const char * filename, const word * filename_unicode, byte is_file, byte is_directory, byte is_hidden)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  size_t base_len;
 | 
				
			||||||
 | 
					  struct T_Find_alternate_ext_data * params = (struct T_Find_alternate_ext_data *)pdata;
 | 
				
			||||||
 | 
					  (void)is_hidden;
 | 
				
			||||||
 | 
					  (void)is_directory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!is_file)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (filename_unicode != NULL && params->basename_unicode[0] != 0)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    base_len = Unicode_strlen(params->basename_unicode);
 | 
				
			||||||
 | 
					    if (filename_unicode[base_len] != '.')
 | 
				
			||||||
 | 
					      return; // No match.
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      WCHAR temp_string[MAX_PATH_CHARACTERS];
 | 
				
			||||||
 | 
					      memcpy(temp_string, filename_unicode, base_len * sizeof(word));
 | 
				
			||||||
 | 
					      temp_string[base_len] = 0;
 | 
				
			||||||
 | 
					      if (_wcsicmp((const WCHAR *)params->basename_unicode, temp_string) != 0)
 | 
				
			||||||
 | 
					        return; // No match.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    if (memcmp(params->basename_unicode, filename_unicode, base_len * sizeof(word)) != 0)
 | 
				
			||||||
 | 
					      return; // No match.
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    if (Unicode_char_strcasecmp(filename_unicode + base_len + 1, params->ext) != 0)
 | 
				
			||||||
 | 
					      return; // No match.
 | 
				
			||||||
 | 
					    // it is a match !
 | 
				
			||||||
 | 
					    Unicode_strlcpy(params->foundname_unicode, filename_unicode, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					    strncpy(params->foundname, filename, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    base_len = strlen(params->basename);
 | 
				
			||||||
 | 
					    if (filename[base_len] != '.')
 | 
				
			||||||
 | 
					      return; // No match.
 | 
				
			||||||
 | 
					#if defined(WIN32)
 | 
				
			||||||
 | 
					    if (_memicmp(params->basename, filename, base_len) != 0)  // Not case sensitive
 | 
				
			||||||
 | 
					      return; // No match.
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    if (memcmp(params->basename, filename, base_len) != 0)
 | 
				
			||||||
 | 
					      return; // No match.
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    if (strcasecmp(filename + base_len + 1, params->ext) != 0)
 | 
				
			||||||
 | 
					      return; // No match.
 | 
				
			||||||
 | 
					    params->foundname_unicode[0] = 0;
 | 
				
			||||||
 | 
					    strncpy(params->foundname, filename, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  char * p;
 | 
				
			||||||
 | 
					  struct T_Find_alternate_ext_data params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  memset(¶ms, 0, sizeof(params));
 | 
				
			||||||
 | 
					  params.ext = ext;
 | 
				
			||||||
 | 
					  strncpy(params.basename, context->File_name, MAX_PATH_CHARACTERS);
 | 
				
			||||||
 | 
					  p = strrchr(params.basename, '.');
 | 
				
			||||||
 | 
					  if (p != NULL)
 | 
				
			||||||
 | 
					    *p = '\0';
 | 
				
			||||||
 | 
					  if (context->File_name_unicode != NULL)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    size_t i = Unicode_strlen(context->File_name_unicode);
 | 
				
			||||||
 | 
					    memcpy(params.basename_unicode, context->File_name_unicode, (i + 1) * sizeof(word));
 | 
				
			||||||
 | 
					    while (i-- > 0)
 | 
				
			||||||
 | 
					      if (params.basename_unicode[i] == (word)'.')
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        params.basename_unicode[i] = 0;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  For_each_directory_entry(context->File_directory, ¶ms, Look_for_alternate_ext);
 | 
				
			||||||
 | 
					  if (params.foundname[0] != '\0')
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    char filename[MAX_PATH_CHARACTERS]; // filename with full path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Get_full_filename(filename, params.foundname, context->File_directory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return fopen(filename, "rb");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// For use by Save_XXX() functions
 | 
					/// For use by Save_XXX() functions
 | 
				
			||||||
void Remove_file(T_IO_Context *context)
 | 
					void Remove_file(T_IO_Context *context)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -267,6 +267,13 @@ FILE * Open_file_write(T_IO_Context *context);
 | 
				
			|||||||
/// For use by Load_XXX() and Test_XXX() functions
 | 
					/// For use by Load_XXX() and Test_XXX() functions
 | 
				
			||||||
FILE * Open_file_read(T_IO_Context *context);
 | 
					FILE * Open_file_read(T_IO_Context *context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// For use by Load_XXX() and Test_XXX() functions
 | 
				
			||||||
 | 
					FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// For use by Save_XXX() functions
 | 
					/// For use by Save_XXX() functions
 | 
				
			||||||
void Remove_file(T_IO_Context *context);
 | 
					void Remove_file(T_IO_Context *context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// For use by Save_XXX() functions
 | 
				
			||||||
 | 
					FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -3217,15 +3217,12 @@ void Load_CM5(T_IO_Context* context)
 | 
				
			|||||||
  // Set palette to the CPC hardware colors 
 | 
					  // Set palette to the CPC hardware colors 
 | 
				
			||||||
  // Load the palette data to the 4 colorlayers
 | 
					  // Load the palette data to the 4 colorlayers
 | 
				
			||||||
  FILE *file;
 | 
					  FILE *file;
 | 
				
			||||||
  char filename[MAX_PATH_CHARACTERS];
 | 
					 | 
				
			||||||
  byte value = 0;
 | 
					  byte value = 0;
 | 
				
			||||||
  int mod=0;
 | 
					  int mod=0;
 | 
				
			||||||
  short line = 0;
 | 
					  short line = 0;
 | 
				
			||||||
  int tx, ty;
 | 
					  int tx, ty;
 | 
				
			||||||
  byte buffer[48*6/4];
 | 
					  byte buffer[48*6/4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!(file = Open_file_read(context)))
 | 
					  if (!(file = Open_file_read(context)))
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
      File_error = 1;
 | 
					      File_error = 1;
 | 
				
			||||||
@ -3330,22 +3327,11 @@ void Load_CM5(T_IO_Context* context)
 | 
				
			|||||||
  fclose(file);
 | 
					  fclose(file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Load the pixeldata to the 5th layer
 | 
					  // Load the pixeldata to the 5th layer
 | 
				
			||||||
 | 
					  file = Open_file_read_with_alternate_ext(context, "gfx");
 | 
				
			||||||
 | 
					  if (file == NULL)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
  	char* ext = filename + strlen(filename) - 3;
 | 
					    File_error = 1;
 | 
				
			||||||
	int idx = 8;
 | 
					    return;
 | 
				
			||||||
 	do {
 | 
					 | 
				
			||||||
		if (-- idx < 0)
 | 
					 | 
				
			||||||
  		{
 | 
					 | 
				
			||||||
    		File_error = 1;
 | 
					 | 
				
			||||||
    		return;
 | 
					 | 
				
			||||||
  		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ext[0] = (idx & 1) ? 'g':'G';
 | 
					 | 
				
			||||||
		ext[1] = (idx & 2) ? 'f':'F';
 | 
					 | 
				
			||||||
		ext[2] = (idx & 4) ? 'x':'X';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  		file = fopen(filename, "rb");
 | 
					 | 
				
			||||||
  	} while(file == NULL);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  Set_loading_layer(context, 4);
 | 
					  Set_loading_layer(context, 4);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@ -3368,12 +3354,9 @@ void Load_CM5(T_IO_Context* context)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Save_CM5(T_IO_Context* context)
 | 
					void Save_CM5(T_IO_Context* context)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  char filename[MAX_PATH_CHARACTERS];
 | 
					 | 
				
			||||||
  FILE* file;
 | 
					  FILE* file;
 | 
				
			||||||
  int tx, ty;
 | 
					  int tx, ty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
					 | 
				
			||||||
  // TODO: Check picture has 5 layers
 | 
					  // TODO: Check picture has 5 layers
 | 
				
			||||||
  // TODO: Check the constraints on the layers 
 | 
					  // TODO: Check the constraints on the layers 
 | 
				
			||||||
  // Layer 1 : 1 color Only
 | 
					  // Layer 1 : 1 color Only
 | 
				
			||||||
@ -3407,12 +3390,10 @@ void Save_CM5(T_IO_Context* context)
 | 
				
			|||||||
  fclose(file);
 | 
					  fclose(file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Now the pixeldata
 | 
					  // Now the pixeldata
 | 
				
			||||||
  filename[strlen(filename) - 3] = 0;
 | 
					  if (!(file = Open_file_write_with_alternate_ext(context, "gfx")))
 | 
				
			||||||
  strcat(filename,"gfx");
 | 
					 | 
				
			||||||
  if (!(file = fopen(filename, "wb")))
 | 
					 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
      File_error = 2;
 | 
					    File_error = 2;
 | 
				
			||||||
      return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  setvbuf(file, NULL, _IOFBF, 64*1024);
 | 
					  setvbuf(file, NULL, _IOFBF, 64*1024);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@ -3460,91 +3441,92 @@ void Save_CM5(T_IO_Context* context)
 | 
				
			|||||||
void Test_PPH(T_IO_Context * context)
 | 
					void Test_PPH(T_IO_Context * context)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  FILE *file;
 | 
					  FILE *file;
 | 
				
			||||||
  char buffer[MAX_PATH_CHARACTERS];
 | 
					  byte buffer[6];
 | 
				
			||||||
  long file_size;
 | 
					  long file_size;
 | 
				
			||||||
  int w;
 | 
					  int w;
 | 
				
			||||||
  int expected;
 | 
					  int expected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  File_error = 1;
 | 
					  File_error = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((file = Open_file_read(context)))
 | 
					  file = Open_file_read(context);
 | 
				
			||||||
  {
 | 
					  if (file == NULL)
 | 
				
			||||||
    // First check file size is large enough to hold the header
 | 
					    return;
 | 
				
			||||||
    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
 | 
					  // First check file size is large enough to hold the header
 | 
				
			||||||
    fread(buffer, 1, 6, file);
 | 
					  file_size = File_length_file(file);
 | 
				
			||||||
    if (buffer[0] > 5) {
 | 
					  if (file_size < 11) {
 | 
				
			||||||
        // Unknown mode
 | 
					    File_error = 1;
 | 
				
			||||||
        File_error = 2;
 | 
					    goto abort;
 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // File is large enough for the header, now check if the data makes some sense
 | 
				
			||||||
 | 
					  if (!Read_bytes(file, buffer, 6))
 | 
				
			||||||
 | 
					    goto abort;
 | 
				
			||||||
 | 
					  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:
 | 
				
			||||||
 | 
					      // Palette 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abort:
 | 
					abort:
 | 
				
			||||||
  fclose(file);
 | 
					  if (file != NULL)
 | 
				
			||||||
 | 
					    fclose(file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: check existence of .ODD/.EVE files with the same name
 | 
					  // TODO: check existence of .ODD/.EVE files with the same name
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -3564,7 +3546,6 @@ void Load_PPH(T_IO_Context* context)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  FILE *file;
 | 
					  FILE *file;
 | 
				
			||||||
  FILE *feven;
 | 
					  FILE *feven;
 | 
				
			||||||
  char filename[MAX_PATH_CHARACTERS];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Read in the header
 | 
					  // Read in the header
 | 
				
			||||||
  uint8_t mode;
 | 
					  uint8_t mode;
 | 
				
			||||||
@ -3574,7 +3555,6 @@ void Load_PPH(T_IO_Context* context)
 | 
				
			|||||||
  int i,j;
 | 
					  int i,j;
 | 
				
			||||||
  uint8_t a,b,c,d;
 | 
					  uint8_t a,b,c,d;
 | 
				
			||||||
  int file_size;
 | 
					  int file_size;
 | 
				
			||||||
  char* ext;
 | 
					 | 
				
			||||||
  uint8_t pl[16];
 | 
					  uint8_t pl[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static const T_Components CPCPAL[27] =
 | 
					  static const T_Components CPCPAL[27] =
 | 
				
			||||||
@ -3590,8 +3570,6 @@ void Load_PPH(T_IO_Context* context)
 | 
				
			|||||||
      { 0xF3, 0xF3, 0x0D }, { 0xF3, 0xF3, 0x6D }, { 0xFF, 0xF3, 0xF9 }
 | 
					      { 0xF3, 0xF3, 0x0D }, { 0xF3, 0xF3, 0x6D }, { 0xFF, 0xF3, 0xF9 }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!(file = Open_file_read(context)))
 | 
					  if (!(file = Open_file_read(context)))
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
      File_error = 1;
 | 
					      File_error = 1;
 | 
				
			||||||
@ -3713,18 +3691,19 @@ void Load_PPH(T_IO_Context* context)
 | 
				
			|||||||
  // Load the picture data
 | 
					  // Load the picture data
 | 
				
			||||||
  // There are two pages, each storing bytes in the CPC vram format but lines in
 | 
					  // There are two pages, each storing bytes in the CPC vram format but lines in
 | 
				
			||||||
  // linear order.
 | 
					  // linear order.
 | 
				
			||||||
  ext = filename + strlen(filename) - 3;  // TODO : make a function to load file with another extension !
 | 
					  file = Open_file_read_with_alternate_ext(context, "odd");
 | 
				
			||||||
  ext[0] = 'O';
 | 
					  if (file == NULL)
 | 
				
			||||||
  ext[1] = 'D';
 | 
					  {
 | 
				
			||||||
  ext[2] = 'D';
 | 
					    File_error = 3;
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
  file = fopen(filename, "rb");
 | 
					  }
 | 
				
			||||||
 | 
					  feven = Open_file_read_with_alternate_ext(context, "eve");
 | 
				
			||||||
  ext[0] = 'E';
 | 
					  if (feven == NULL)
 | 
				
			||||||
  ext[1] = 'V';
 | 
					  {
 | 
				
			||||||
  ext[2] = 'E';
 | 
					    File_error = 4;
 | 
				
			||||||
 | 
					    fclose(file);
 | 
				
			||||||
  feven = fopen(filename, "rb");
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  c = 0;
 | 
					  c = 0;
 | 
				
			||||||
  d = 0;
 | 
					  d = 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -87,6 +87,28 @@ int Unicode_char_strcmp(const word * s1, const char * s2)
 | 
				
			|||||||
  return (*s1 > *str2) ? 1 : -1;
 | 
					  return (*s1 > *str2) ? 1 : -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Compare an unicode string with a regular Latin1 string. Ignoring case
 | 
				
			||||||
 | 
					int Unicode_char_strcasecmp(const word * s1, const char * s2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  const byte * str2 = (const byte *)s2;
 | 
				
			||||||
 | 
					  unsigned int c1, c2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (;;)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    c1 = *s1++;
 | 
				
			||||||
 | 
					    c2 = *str2++;
 | 
				
			||||||
 | 
					    // first convert to lower case
 | 
				
			||||||
 | 
					    if ('a' <= c1 && c1 <= 'z')
 | 
				
			||||||
 | 
					        c1 -= ('a'-'A');
 | 
				
			||||||
 | 
					    if ('a' <= c2 && c2 <= 'z')
 | 
				
			||||||
 | 
					        c2 -= ('a'-'A');
 | 
				
			||||||
 | 
					    if (c1 != c2)
 | 
				
			||||||
 | 
					      return (c1 > c2) ? 1 : -1;
 | 
				
			||||||
 | 
					    if (c1 == 0)
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Copy a regular Latin1 string to an unicode string
 | 
					/// Copy a regular Latin1 string to an unicode string
 | 
				
			||||||
void Unicode_char_strlcpy(word * dst, const char * src, size_t len)
 | 
					void Unicode_char_strlcpy(word * dst, const char * src, size_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,9 @@ void Unicode_strlcat(word * dst, const word * src, size_t len);
 | 
				
			|||||||
/// Compare an unicode string with a regular Latin1 string
 | 
					/// Compare an unicode string with a regular Latin1 string
 | 
				
			||||||
int Unicode_char_strcmp(const word * s1, const char * s2);
 | 
					int Unicode_char_strcmp(const word * s1, const char * s2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Compare an unicode string with a regular Latin1 string. Ignoring case
 | 
				
			||||||
 | 
					int Unicode_char_strcasecmp(const word * s1, const char * s2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Copy a regular Latin1 string to an unicode string
 | 
					/// Copy a regular Latin1 string to an unicode string
 | 
				
			||||||
void Unicode_char_strlcpy(word * dst, const char * src, size_t len);
 | 
					void Unicode_char_strlcpy(word * dst, const char * src, size_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user