From 1c2ab9aa99108174ee3795d0fd973da3858498f4 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Sat, 14 Aug 2010 19:03:55 +0000 Subject: [PATCH] ILBM format : Cycling color ranges are loaded (unused so far) git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1572 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/buttons.c | 2 + src/fileformats.c | 124 +++++++++++++++++++++++++++++++++++++--------- src/loadsave.c | 11 +++- src/loadsave.h | 11 ++++ src/main.c | 35 +++++++++++-- 5 files changed, 155 insertions(+), 28 deletions(-) diff --git a/src/buttons.c b/src/buttons.c index c8fa5cfc..7a967f88 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -2422,6 +2422,8 @@ void Draw_button_gradient_style(short x_pos,short y_pos,int technique) void Load_gradient_data(int index) { + if (Gradient_array[index].Start>Gradient_array[index].End) + Error(0); Gradient_lower_bound =Gradient_array[index].Start; Gradient_upper_bound =Gradient_array[index].End; Gradient_is_inverted =Gradient_array[index].Inverse; diff --git a/src/fileformats.c b/src/fileformats.c index c8d8a402..06e95e5f 100644 --- a/src/fileformats.c +++ b/src/fileformats.c @@ -388,28 +388,42 @@ void Test_LBM(T_IO_Context * context) } } - // ------------------------- Attendre une section ------------------------- - byte Wait_for(byte * expected_section) - { - // Valeur retournée: 1=Section trouvée, 0=Section non trouvée (erreur) - dword Taille_section; - byte section_read[4]; +// Inspired by Allegro: storing a 4-character identifier as a 32bit litteral +#define ID4(a,b,c,d) ((((a)&255)<<24) | (((b)&255)<<16) | (((c)&255)<<8) | (((d)&255))) +/// Skips the current section in an ILBM file. +/// This function should be called while the file pointer is right +/// after the 4-character code that identifies the section. +int LBM_Skip_section(void) +{ + dword size; + + if (!Read_dword_be(LBM_file,&size)) + return 0; + if (size&1) + size++; + if (fseek(LBM_file,size,SEEK_CUR)) + return 0; + return 1; +} + +// ------------------------- Attendre une section ------------------------- +byte LBM_Wait_for(byte * expected_section) +{ + // Valeur retournée: 1=Section trouvée, 0=Section non trouvée (erreur) + byte section_read[4]; + + if (! Read_bytes(LBM_file,section_read,4)) + return 0; + while (memcmp(section_read,expected_section,4)) // Sect. pas encore trouvée + { + if (!LBM_Skip_section()) + return 0; if (! Read_bytes(LBM_file,section_read,4)) return 0; - while (memcmp(section_read,expected_section,4)) // Sect. pas encore trouvée - { - if (!Read_dword_be(LBM_file,&Taille_section)) - return 0; - if (Taille_section&1) - Taille_section++; - if (fseek(LBM_file,Taille_section,SEEK_CUR)) - return 0; - if (! Read_bytes(LBM_file,section_read,4)) - return 0; - } - return 1; } + return 1; +} // Les images ILBM sont stockés en bitplanes donc on doit trifouiller les bits pour // en faire du chunky @@ -522,7 +536,7 @@ void Load_LBM(T_IO_Context * context) byte temp_byte; short b256; dword nb_colors; - dword image_size; + dword section_size; short x_pos; short y_pos; short counter; @@ -544,7 +558,7 @@ void Load_LBM(T_IO_Context * context) Read_bytes(LBM_file,section,4); Read_dword_be(LBM_file,&dummy); Read_bytes(LBM_file,format,4); - if (!Wait_for((byte *)"BMHD")) + if (!LBM_Wait_for((byte *)"BMHD")) File_error=1; Read_dword_be(LBM_file,&dummy); @@ -564,7 +578,7 @@ void Load_LBM(T_IO_Context * context) && (Read_word_be(LBM_file,&header.Y_screen)) && header.Width && header.Height) { - if ( (header.BitPlanes) && (Wait_for((byte *)"CMAP")) ) + if ( (header.BitPlanes) && (LBM_Wait_for((byte *)"CMAP")) ) { Read_dword_be(LBM_file,&nb_colors); nb_colors/=3; @@ -616,10 +630,72 @@ void Load_LBM(T_IO_Context * context) if (nb_colors&1) if (Read_byte(LBM_file,&temp_byte)) File_error=2; - - if ( (Wait_for((byte *)"BODY")) && (!File_error) ) + + // Keep reading sections until we find the body + while (1) { - Read_dword_be(LBM_file,&image_size); + if (! Read_bytes(LBM_file,section,4)) + { + File_error=2; + break; + } + // Found body : stop searching + if (!memcmp(section,"BODY",4)) + break; + else if (!memcmp(section,"CRNG",4)) + { + // Handle CRNG + + // The content of a CRNG is as follows: + word padding; + word rate; + word flags; + byte min_col; + byte max_col; + // + + if ( (Read_dword_be(LBM_file,§ion_size)) + && (Read_word_be(LBM_file,&padding)) + && (Read_word_be(LBM_file,&rate)) + && (Read_word_be(LBM_file,&flags)) + && (Read_byte(LBM_file,&min_col)) + && (Read_byte(LBM_file,&max_col))) + { + if (section_size == 8 && (flags & 1) && min_col != max_col) + { + // Valid cycling range + if (max_colCycle_range[context->Color_cycles].Start=min_col; + context->Cycle_range[context->Color_cycles].End=max_col; + context->Cycle_range[context->Color_cycles].Inverse=(flags&2)?1:0; + context->Cycle_range[context->Color_cycles].Speed=rate/78; + + context->Color_cycles++; + } + } + else + { + File_error=2; + break; + } + } + else + { + // ignore any number of unknown sections + if (!LBM_Skip_section()) + { + File_error=2; + break; + } + } + + } + + if ( !File_error ) + { + Read_dword_be(LBM_file,§ion_size); //swab((char *)&header.Width ,(char *)&context->Width,2); //swab((char *)&header.Height,(char *)&context->Height,2); context->Width = header.Width; diff --git a/src/loadsave.c b/src/loadsave.c index 3aacd162..02727b66 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -606,7 +606,7 @@ void Load_image(T_IO_Context *context) { unsigned int index; // index de balayage des formats T_Format *format = &(File_formats[2]); // Format du fichier à charger - + int i; // On place par défaut File_error à vrai au cas où on ne sache pas // charger le format du fichier: @@ -774,6 +774,15 @@ void Load_image(T_IO_Context *context) Main_image_width=1; if (Main_image_height<1) Main_image_height=1; + + // Color cyling ranges: + for (i=0; iColor_cycles; i++) + { + Gradient_array[i].Start=context->Cycle_range[i].Start; + Gradient_array[i].End=context->Cycle_range[i].End; + Gradient_array[i].Inverse=context->Cycle_range[i].Inverse; + } + } } else if (File_error!=1) diff --git a/src/loadsave.h b/src/loadsave.h index f82383b9..4108af67 100644 --- a/src/loadsave.h +++ b/src/loadsave.h @@ -37,6 +37,14 @@ enum CONTEXT_TYPE { CONTEXT_SURFACE, }; +/// Data for a cycling color series. Heavily cloned from T_Gradient_array. +typedef struct +{ + byte Start; ///< First color + byte End; ///< Last color + byte Inverse; ///< Boolean, true if the gradient goes in descending order + byte Speed; ///< Frequency of cycling, from 1 (slow) to 64 (fast) +} T_Color_cycle; typedef struct { @@ -71,6 +79,9 @@ typedef struct /// Original file directory, stored in GIF file char * Original_file_directory; + byte Color_cycles; + T_Color_cycle Cycle_range[16]; + /// Internal: during load, marks which layer is being loaded. short Current_layer; diff --git a/src/main.c b/src/main.c index 9484d320..92d87c4f 100644 --- a/src/main.c +++ b/src/main.c @@ -88,13 +88,42 @@ int test_colorcycling(void* useless) { - byte r = 0; - while(1) { + static byte offset[16]; // static forces init at 0 + int i, color; + static SDL_Color PaletteSDL[256]; + + while(!Quitting) + { SDL_Delay(50); - Set_color(0,++r,0,0); + // Init palette + for(color=0;color<256;color++) + { + PaletteSDL[color].r=Main_palette[color].R; + PaletteSDL[color].g=Main_palette[color].G; + PaletteSDL[color].b=Main_palette[color].B; + } + for (i=0; i<16; i++) + { + byte len; + + len=Gradient_array[i].End-Gradient_array[i].Start+1; + if (len) + { + for(color=Gradient_array[i].Start;color<=Gradient_array[i].End;color++) + { + PaletteSDL[color].r=Main_palette[Gradient_array[i].Start+((color-Gradient_array[i].Start+offset[i])%len)].R; + PaletteSDL[color].g=Main_palette[Gradient_array[i].Start+((color-Gradient_array[i].Start+offset[i])%len)].G; + PaletteSDL[color].b=Main_palette[Gradient_array[i].Start+((color-Gradient_array[i].Start+offset[i])%len)].B; + } + offset[i]= (offset[i]+len-1)%len; + } + } + SDL_SetPalette(Screen_SDL, SDL_PHYSPAL | SDL_LOGPAL, PaletteSDL,0,256); } + return 0; } + //--- Affichage de la syntaxe, et de la liste des modes vidéos disponibles --- void Display_syntax(void) {