Merge the "CPC Mode 5" branch to trunk.
Note this alsoincludes the "oldies" branch. This has the following consequences : [C64] * Loading and saving of screen-only, and color-only C64 picture is removed * Loading and saving in FLI mode is now possible * FLI constraint checker : tries to convert your image to FLI format, and put all the areas where it couldn't find a solution in a separate layer for you to fixup * This is currently accessible only with a shortcut. Menu will come next. [Amstrad CPC] * Loading and saving of pictures in "Mode 5" is now possible. This custom format allows overscan mode 1 with rasters on 2 inks and split rasters on a 3rd one. * Mode 5 constraint enforcer : will ensure you can only draw pictures that are valid in mode 5. Each ink is seen as a layer. * This is accessible from a new button in the FX menu. [Generic] * Added patch as I saw it : platform that don't support reporting "free space" on disk will not display anything (instead of "0 bytesÃ" as before) * For other platforms, when the free space is 0, we now have a disk full message. The merge was not straight forward. I hope I didn't break too much things. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1810 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
commit
e875597964
@ -388,7 +388,7 @@ endif
|
||||
.PHONY : all debug release clean depend zip version force install uninstall
|
||||
|
||||
# This is the list of the objects we want to build. Dependancies are built by "make depend" automatically.
|
||||
OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o
|
||||
OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o $(OBJDIR)/oldies.o
|
||||
|
||||
SKIN_FILES = ../share/grafx2/skins/skin_classic.png ../share/grafx2/skins/skin_modern.png ../share/grafx2/skins/skin_DPaint.png ../share/grafx2/skins/font_Classic.png ../share/grafx2/skins/font_Fun.png ../share/grafx2/skins/font_Fairlight.png ../share/grafx2/skins/font_Melon.png ../share/grafx2/skins/font_DPaint.png ../share/grafx2/skins/skin_scenish.png ../share/grafx2/skins/font_Seen.png ../share/grafx2/skins/skin_Aurora.png
|
||||
|
||||
|
||||
109
src/brush.c
109
src/brush.c
@ -129,14 +129,119 @@ void Display_paintbrush(short x,short y,byte color,byte is_preview)
|
||||
byte temp_color; // color de la brosse en cours d'affichage
|
||||
int position;
|
||||
byte * temp;
|
||||
byte old_color;
|
||||
|
||||
if (is_preview==0 || Mouse_K==0) // pas de curseur si on est en preview et
|
||||
// en train de cliquer
|
||||
if (is_preview && Mouse_K) // pas de curseur si on est en preview et
|
||||
return; // en train de cliquer
|
||||
|
||||
if (Constraint_mode && Main_current_layer < 4)
|
||||
{
|
||||
if (is_preview)
|
||||
goto single_pixel;
|
||||
else
|
||||
{
|
||||
// Flood-fill the enclosing area
|
||||
if (x<Main_image_width && y<Main_image_height && x>= 0 && y >= 0
|
||||
&& (color=Effect_function(x,y,color)) != (old_color=Read_pixel_from_current_layer(x,y))
|
||||
&& (!((Stencil_mode) && (Stencil[old_color])))
|
||||
&& (!((Mask_mode) && (Mask_table[Read_pixel_from_spare_screen(x,y)])))
|
||||
)
|
||||
{
|
||||
short min_x,width,min_y,height;
|
||||
short xx,yy;
|
||||
|
||||
// determine area
|
||||
switch(Main_current_layer)
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
// Full layer
|
||||
min_x=0;
|
||||
min_y=0;
|
||||
width=Main_image_width;
|
||||
height=Main_image_height;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
// Line
|
||||
min_x=0;
|
||||
min_y=y;
|
||||
width=Main_image_width;
|
||||
height=1;
|
||||
break;
|
||||
case 3:
|
||||
// Segment
|
||||
min_x=x / 48 * 48;
|
||||
min_y=y;
|
||||
width=48;
|
||||
height=1;
|
||||
break;
|
||||
//case 4:
|
||||
// // 8x8
|
||||
// min_x=x / 8 * 8;
|
||||
// min_y=y / 8 * 8;
|
||||
// width=8;
|
||||
// height=8;
|
||||
// break;
|
||||
}
|
||||
// Clip the bottom edge.
|
||||
// (Necessary if image height is not a multiple)
|
||||
if (min_y+height>=Main_image_height)
|
||||
height=Main_image_height-min_y;
|
||||
// Clip the right edge.
|
||||
// (Necessary if image width is not a multiple)
|
||||
if (min_x+width>=Main_image_width)
|
||||
width=Main_image_width-min_x;
|
||||
|
||||
for (yy=min_y; yy<min_y+height; yy++)
|
||||
for (xx=min_x; xx<min_x+width; xx++)
|
||||
{
|
||||
Pixel_in_current_screen(xx,yy,color,0);
|
||||
}
|
||||
// Feedback
|
||||
// This part is greatly taken from Hide_paintbrush()
|
||||
Compute_clipped_dimensions(&min_x,&min_y,&width,&height);
|
||||
|
||||
if ( (width>0) && (height>0) )
|
||||
Clear_brush(min_x-Main_offset_X,
|
||||
min_y-Main_offset_Y,
|
||||
0,0,
|
||||
width,height,0,
|
||||
Main_image_width);
|
||||
|
||||
if (Main_magnifier_mode != 0)
|
||||
{
|
||||
Compute_clipped_dimensions_zoom(&min_x,&min_y,&width,&height);
|
||||
xx=min_x;
|
||||
yy=min_y;
|
||||
|
||||
if ( (width>0) && (height>0) )
|
||||
{
|
||||
// Corrections dues au Zoom:
|
||||
min_x=(min_x-Main_magnifier_offset_X)*Main_magnifier_factor;
|
||||
min_y=(min_y-Main_magnifier_offset_Y)*Main_magnifier_factor;
|
||||
height=min_y+(height*Main_magnifier_factor);
|
||||
if (height>Menu_Y)
|
||||
height=Menu_Y;
|
||||
|
||||
Clear_brush_scaled(Main_X_zoom+min_x,min_y,
|
||||
xx,yy,
|
||||
width,height,0,
|
||||
Main_image_width,
|
||||
Horizontal_line_buffer);
|
||||
}
|
||||
}
|
||||
// End of graphic feedback
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (Paintbrush_shape)
|
||||
{
|
||||
case PAINTBRUSH_SHAPE_NONE : // No paintbrush. for colorpicker for example
|
||||
break;
|
||||
case PAINTBRUSH_SHAPE_POINT : // !!! TOUJOURS EN PREVIEW !!!
|
||||
single_pixel:
|
||||
if ( (Paintbrush_X>=Limit_left)
|
||||
&& (Paintbrush_X<=Limit_right)
|
||||
&& (Paintbrush_Y>=Limit_top)
|
||||
|
||||
@ -4473,23 +4473,27 @@ void Display_effect_state(short x, short y, char * label, byte state)
|
||||
|
||||
Print_in_window(x,y,label,(state)?MC_White:MC_Black,MC_Light);
|
||||
if (state)
|
||||
Print_in_window(x+56,y,":ON ",MC_White,MC_Light);
|
||||
Window_select_normal_button(x-23, y-5, 16, 16);
|
||||
else
|
||||
Print_in_window(x+56,y,":OFF",MC_Black,MC_Light);
|
||||
Window_unselect_normal_button(x-23, y-5, 16, 16);
|
||||
}
|
||||
|
||||
#define C2 92
|
||||
|
||||
void Display_effect_states(void)
|
||||
{
|
||||
Display_effect_state( 30, 24,"Shade" ,Shade_mode);
|
||||
Display_effect_state( 30, 43,"Q-shade",Quick_shade_mode);
|
||||
Display_effect_state( 30, 62,"Transp.",Colorize_mode);
|
||||
Display_effect_state( 30, 81,"Smooth" ,Smooth_mode);
|
||||
Display_effect_state( 30,100,"Smear" ,Smear_mode);
|
||||
Display_effect_state(176, 24,"Stencil",Stencil_mode);
|
||||
Display_effect_state(176, 43,"Mask" ,Mask_mode);
|
||||
Display_effect_state(176, 62,"Sieve" ,Sieve_mode);
|
||||
Display_effect_state(176, 81,"Grid" ,Snap_mode);
|
||||
Display_effect_state(176,100,"Tiling" ,Tiling_mode);
|
||||
Display_effect_state( 30, 24, "Shade" ,Shade_mode);
|
||||
Display_effect_state( 30, 43, "Q-shade",Quick_shade_mode);
|
||||
Display_effect_state( 30, 62, "Transp.",Colorize_mode);
|
||||
Display_effect_state( 30, 81, "Smooth" ,Smooth_mode);
|
||||
Display_effect_state( 30,100, "Smear" ,Smear_mode);
|
||||
Display_effect_state(C2+23, 24, "Stencil",Stencil_mode);
|
||||
Display_effect_state(C2+23, 43, "Mask" ,Mask_mode);
|
||||
Display_effect_state(C2+23, 62, "Sieve" ,Sieve_mode);
|
||||
Display_effect_state(C2+23, 81, "Grid" ,Snap_mode);
|
||||
Display_effect_state(C2+23,100, "Tiling" ,Tiling_mode);
|
||||
|
||||
Display_effect_state(177+23,24, "8 bit" ,Constraint_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -4511,25 +4515,29 @@ void Button_Effects(void)
|
||||
Window_set_normal_button( 7, 57, 16,16,"",0,1,Config_Key[SPECIAL_COLORIZE_MODE][0]); // 3
|
||||
Window_set_normal_button( 7, 76, 16,16,"",0,1,Config_Key[SPECIAL_SMOOTH_MODE][0]); // 4
|
||||
Window_set_normal_button( 7, 95, 16,16,"",0,1,Config_Key[SPECIAL_SMEAR_MODE][0]); // 5
|
||||
Window_set_normal_button(153, 19, 16,16,"",0,1,Config_Key[SPECIAL_STENCIL_MODE][0]); // 6
|
||||
Window_set_normal_button(153, 38, 16,16,"",0,1,Config_Key[SPECIAL_MASK_MODE][0]); // 7
|
||||
Window_set_normal_button(153, 57, 16,16,"",0,1,Config_Key[SPECIAL_SIEVE_MODE][0]); // 8
|
||||
Window_set_normal_button(153, 76, 16,16,"",0,1,Config_Key[SPECIAL_GRID_MODE][0]); // 9
|
||||
Window_set_normal_button(153, 95, 16,16,"",0,1,Config_Key[SPECIAL_TILING_MODE][0]); // 10
|
||||
Window_set_normal_button(C2, 19, 16,16,"",0,1,Config_Key[SPECIAL_STENCIL_MODE][0]); // 6
|
||||
Window_set_normal_button(C2, 38, 16,16,"",0,1,Config_Key[SPECIAL_MASK_MODE][0]); // 7
|
||||
Window_set_normal_button(C2, 57, 16,16,"",0,1,Config_Key[SPECIAL_SIEVE_MODE][0]); // 8
|
||||
Window_set_normal_button(C2, 76, 16,16,"",0,1,Config_Key[SPECIAL_GRID_MODE][0]); // 9
|
||||
Window_set_normal_button(C2, 95, 16,16,"",0,1,Config_Key[SPECIAL_TILING_MODE][0]); // 10
|
||||
|
||||
Window_set_normal_button(195,131, 68,14,"Close",0,1,SDLK_RETURN); // 11
|
||||
Window_set_normal_button( 7,131, 68,14,"All off",0,1,SDLK_DELETE); // 12
|
||||
Window_set_normal_button( 83,131,104,14,"Feedback: ",1,1,SDLK_f); // 13
|
||||
|
||||
Window_set_normal_button(177, 19, 16,16,"",0,1,Config_Key[SPECIAL_FORMAT_CHECKER_MENU][0]); // 14
|
||||
|
||||
Display_feedback_state();
|
||||
Display_effect_sprite(0, 8,20);
|
||||
Display_effect_sprite(0, 8,39);
|
||||
Display_effect_sprite(1, 8,58);
|
||||
Display_effect_sprite(2, 8,77);
|
||||
Display_effect_sprite(8, 8,96);
|
||||
Display_effect_sprite(4,154,20);
|
||||
Display_effect_sprite(7,154,39);
|
||||
Display_effect_sprite(5,154,58);
|
||||
Display_effect_sprite(6,154,77);
|
||||
Display_effect_sprite(3,154,96);
|
||||
Display_effect_sprite(4,C2+1,20);
|
||||
Display_effect_sprite(7,C2+1,39);
|
||||
Display_effect_sprite(5,C2+1,58);
|
||||
Display_effect_sprite(6,C2+1,77);
|
||||
Display_effect_sprite(3,C2+1,96);
|
||||
Display_effect_states();
|
||||
|
||||
Print_in_window(12,117,"click: Left:Switch / Right:Edit",MC_Dark,MC_Light);
|
||||
@ -4666,7 +4674,7 @@ void Button_Effects(void)
|
||||
{
|
||||
Button_Stencil_mode();
|
||||
Hide_cursor();
|
||||
Display_effect_state(176,24,"Stencil",Stencil_mode);
|
||||
Display_effect_state(C2+23,24,"Stencil",Stencil_mode);
|
||||
Display_cursor();
|
||||
}
|
||||
else
|
||||
@ -4682,7 +4690,7 @@ void Button_Effects(void)
|
||||
{
|
||||
Button_Mask_mode();
|
||||
Hide_cursor();
|
||||
Display_effect_state(176,43,"Mask",Mask_mode);
|
||||
Display_effect_state(C2+23,43,"Mask",Mask_mode);
|
||||
Display_cursor();
|
||||
}
|
||||
else
|
||||
@ -4698,7 +4706,7 @@ void Button_Effects(void)
|
||||
{
|
||||
Button_Sieve_mode();
|
||||
Hide_cursor();
|
||||
Display_effect_state(176,62,"Sieve",Sieve_mode);
|
||||
Display_effect_state(C2+23,62,"Sieve",Sieve_mode);
|
||||
Display_cursor();
|
||||
}
|
||||
else
|
||||
@ -4714,7 +4722,7 @@ void Button_Effects(void)
|
||||
{
|
||||
Button_Snap_mode();
|
||||
Hide_cursor();
|
||||
Display_effect_state(176,81,"Grid",Snap_mode);
|
||||
Display_effect_state(C2+23,81,"Grid",Snap_mode);
|
||||
Display_cursor();
|
||||
}
|
||||
else
|
||||
@ -4757,6 +4765,22 @@ void Button_Effects(void)
|
||||
Display_feedback_state();
|
||||
Display_cursor();
|
||||
break;
|
||||
|
||||
|
||||
case 14: // Constraint checker/enforcer
|
||||
if (Window_attribute1==LEFT_SIDE)
|
||||
{
|
||||
Button_Constraint_mode();
|
||||
Hide_cursor();
|
||||
Display_effect_state(177+23,24, "8 bit" ,Constraint_mode);
|
||||
Display_cursor();
|
||||
} else {
|
||||
Close_window();
|
||||
Display_cursor();
|
||||
// Contraint checker/enforcer menu
|
||||
clicked_button = 11;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (clicked_button!=11);
|
||||
@ -4766,12 +4790,14 @@ void Button_Effects(void)
|
||||
else
|
||||
Hide_cursor();
|
||||
|
||||
if (!(Shade_mode||Quick_shade_mode||Colorize_mode||Smooth_mode||Tiling_mode||Smear_mode||Stencil_mode||Mask_mode||Sieve_mode||Snap_mode))
|
||||
if (!(Shade_mode||Quick_shade_mode||Colorize_mode||Smooth_mode||Tiling_mode||Smear_mode||Stencil_mode||Mask_mode||Sieve_mode||Snap_mode||Constraint_mode))
|
||||
Unselect_button(BUTTON_EFFECTS);
|
||||
|
||||
Display_cursor();
|
||||
}
|
||||
|
||||
#undef C2
|
||||
|
||||
// Callback to display a font name in the list
|
||||
void Draw_one_font_name(word x, word y, word index, byte highlighted)
|
||||
{
|
||||
|
||||
@ -438,6 +438,9 @@ void Button_Tiling_mode(void);
|
||||
*/
|
||||
void Button_Tiling_menu(void);
|
||||
|
||||
void Button_Constraint_mode(void);
|
||||
void Button_Constraint_menu(void);
|
||||
|
||||
/*!
|
||||
Callback for the command that turns off all drawaing effects.
|
||||
*/
|
||||
|
||||
@ -162,6 +162,19 @@ void Menu_tag_colors(char * window_title, byte * table, byte * mode, byte can_ca
|
||||
}
|
||||
|
||||
|
||||
// Constaint enforcer/checker ------------------------------------------------
|
||||
void Button_Constraint_mode(void)
|
||||
{
|
||||
Constraint_mode=!Constraint_mode;
|
||||
}
|
||||
|
||||
|
||||
void Button_Constraint_menu(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------- Stencil ----------------------------------
|
||||
void Button_Stencil_mode(void)
|
||||
{
|
||||
|
||||
@ -120,6 +120,7 @@ enum FILE_FORMATS
|
||||
FORMAT_KCF,
|
||||
FORMAT_PAL,
|
||||
FORMAT_SCR,
|
||||
FORMAT_CM5,
|
||||
FORMAT_XPM,
|
||||
FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image
|
||||
};
|
||||
@ -483,6 +484,10 @@ enum SPECIAL_ACTIONS
|
||||
SPECIAL_RUN_SCRIPT_9,
|
||||
SPECIAL_RUN_SCRIPT_10,
|
||||
SPECIAL_CYCLE_MODE,
|
||||
|
||||
SPECIAL_FORMAT_CHECKER,
|
||||
SPECIAL_FORMAT_CHECKER_MENU,
|
||||
|
||||
NB_SPECIAL_SHORTCUTS ///< Number of special shortcuts
|
||||
};
|
||||
|
||||
|
||||
@ -1292,6 +1292,11 @@ void Main_handler(void)
|
||||
Layer_activate((key_index-SPECIAL_LAYER1_TOGGLE)/2, RIGHT_SIDE);
|
||||
action++;
|
||||
break;
|
||||
case SPECIAL_FORMAT_CHECKER:
|
||||
C64_FLI_enforcer();
|
||||
action++;
|
||||
break;
|
||||
|
||||
case SPECIAL_REPEAT_SCRIPT:
|
||||
#ifdef __ENABLE_LUA__
|
||||
Repeat_script();
|
||||
|
||||
@ -2116,7 +2116,7 @@ void Load_GIF(T_IO_Context * context)
|
||||
// This a second layer/frame, or more.
|
||||
// Attempt to add a layer to current image
|
||||
current_layer++;
|
||||
Set_layer(context, current_layer);
|
||||
Set_loading_layer(context, current_layer);
|
||||
}
|
||||
number_LID++;
|
||||
|
||||
@ -2480,7 +2480,7 @@ void Save_GIF(T_IO_Context * context)
|
||||
GCE_block[3] |= 1; // Transparent color flag
|
||||
GCE_block[6] = context->Transparent_color;
|
||||
|
||||
Set_layer(context, current_layer);
|
||||
Set_saving_layer(context, current_layer);
|
||||
|
||||
if (current_layer == context->Nb_layers -1)
|
||||
{
|
||||
|
||||
@ -726,6 +726,9 @@ GFX2_GLOBAL byte Mask_mode;
|
||||
/// Array of booleans. True if the indexed color is protected by the mask.
|
||||
GFX2_GLOBAL byte Mask_table[256];
|
||||
|
||||
// -- Constraint enforcer
|
||||
GFX2_GLOBAL byte Constraint_mode;
|
||||
|
||||
// -- Magnifier data
|
||||
|
||||
#ifdef GLOBAL_VARIABLES
|
||||
|
||||
71
src/graph.c
71
src/graph.c
@ -2920,6 +2920,15 @@ byte Effect_smooth(word x,word y,__attribute__((unused)) byte color)
|
||||
// l'écran feedback car il s'agit de ne
|
||||
} // pas modifier l'écran courant.
|
||||
|
||||
byte Effect_layer_copy(word x,word y,byte color)
|
||||
{
|
||||
if (color<Main_backups->Pages->Nb_layers)
|
||||
{
|
||||
return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[color]);
|
||||
}
|
||||
return Read_pixel_from_feedback_screen(x,y);
|
||||
}
|
||||
|
||||
void Horizontal_grid_line(word x_pos,word y_pos,word width)
|
||||
{
|
||||
int x;
|
||||
@ -2963,6 +2972,10 @@ byte Read_pixel_from_current_screen (word x,word y)
|
||||
#ifndef NOLAYERS
|
||||
byte depth;
|
||||
byte color;
|
||||
|
||||
if (Main_current_layer==4)
|
||||
return *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width);
|
||||
|
||||
color = *(Main_screen+y*Main_image_width+x);
|
||||
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||
return color;
|
||||
@ -2977,6 +2990,8 @@ byte Read_pixel_from_current_screen (word x,word y)
|
||||
void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
|
||||
{
|
||||
#ifndef NOLAYERS
|
||||
if (!Constraint_mode)
|
||||
{
|
||||
byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
|
||||
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
|
||||
if ( depth <= Main_current_layer)
|
||||
@ -2990,6 +3005,61 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
|
||||
if (with_preview)
|
||||
Pixel_preview(x,y,color);
|
||||
}
|
||||
|
||||
}
|
||||
else if ( Main_current_layer == 4)
|
||||
{
|
||||
if (color<4)
|
||||
{
|
||||
// Paste in layer
|
||||
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
|
||||
// Paste in depth buffer
|
||||
*(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color;
|
||||
// Fetch pixel color from the target raster layer
|
||||
color=*(Main_backups->Pages->Image[color] + x+y*Main_image_width);
|
||||
// Draw that color on the visible image buffer
|
||||
*(x+y*Main_image_width+Main_screen)=color;
|
||||
|
||||
if (with_preview)
|
||||
Pixel_preview(x,y,color);
|
||||
}
|
||||
}
|
||||
else if (Main_current_layer<4 && (Main_layers_visible & (1<<4)))
|
||||
{
|
||||
byte depth;
|
||||
|
||||
// Paste in layer
|
||||
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
|
||||
// Search depth
|
||||
depth = *(Main_backups->Pages->Image[4] + x+y*Main_image_width);
|
||||
|
||||
if ( depth == Main_current_layer)
|
||||
{
|
||||
// Draw that color on the visible image buffer
|
||||
*(x+y*Main_image_width+Main_screen)=color;
|
||||
|
||||
if (with_preview)
|
||||
Pixel_preview(x,y,color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
byte depth;
|
||||
|
||||
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
|
||||
depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
|
||||
if ( depth <= Main_current_layer)
|
||||
{
|
||||
if (color == Main_backups->Pages->Transparent_color) // transparent color
|
||||
// fetch pixel color from the topmost visible layer
|
||||
color=*(Main_backups->Pages->Image[depth] + x+y*Main_image_width);
|
||||
|
||||
*(x+y*Main_image_width+Main_screen)=color;
|
||||
|
||||
if (with_preview)
|
||||
Pixel_preview(x,y,color);
|
||||
}
|
||||
}
|
||||
#else
|
||||
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color;
|
||||
if (with_preview)
|
||||
@ -2997,6 +3067,7 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Pixel_in_current_layer(word x,word y, byte color)
|
||||
{
|
||||
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color;
|
||||
|
||||
@ -38,6 +38,7 @@ byte Effect_shade(word x,word y,byte color);
|
||||
byte Effect_quick_shade(word x,word y,byte color);
|
||||
byte Effect_tiling(word x,word y,byte color);
|
||||
byte Effect_smooth(word x,word y,byte color);
|
||||
byte Effect_layer_copy(word x,word y,byte color);
|
||||
|
||||
void Display_foreback(void);
|
||||
|
||||
|
||||
27
src/help.c
27
src/help.c
@ -32,7 +32,7 @@
|
||||
#include <sys/mount.h>
|
||||
#elif defined (__linux__)
|
||||
#include <sys/vfs.h>
|
||||
#elif defined(__HAIKU__)
|
||||
#elif defined (__HAIKU__)
|
||||
#include "haiku.h"
|
||||
#elif defined (__MINT__)
|
||||
#include <mint/sysbind.h>
|
||||
@ -69,7 +69,7 @@ word * Shortcut(word shortcut_number)
|
||||
return &(Config_Key[shortcut_number & 0xFF][0]);
|
||||
}
|
||||
|
||||
// Nom de la touche actuallement assignée à un raccourci d'après son numéro
|
||||
// Nom de la touche actuallement assignée à un raccourci d'après son numéro
|
||||
// de type 0x100+BOUTON_* ou SPECIAL_*
|
||||
const char * Keyboard_shortcut_value(word shortcut_number)
|
||||
{
|
||||
@ -707,7 +707,7 @@ void Button_Stats(void)
|
||||
Print_in_window(146,35,TrueType_is_supported()?"TTF fonts":"no TTF fonts",STATS_DATA_COLOR,MC_Black);
|
||||
|
||||
#if defined (__MINT__)
|
||||
// Affichage de la mémoire restante
|
||||
// Display free TT/ST RAM
|
||||
Print_in_window(10,43,"Free memory: ",STATS_TITLE_COLOR,MC_Black);
|
||||
|
||||
freeRam=0;
|
||||
@ -751,7 +751,7 @@ void Button_Stats(void)
|
||||
Print_in_window(18,51,buffer,STATS_DATA_COLOR,MC_Black);
|
||||
|
||||
#else
|
||||
// Affichage de la mémoire restante
|
||||
// Display free RAM (generic)
|
||||
Print_in_window(10,51,"Free memory: ",STATS_TITLE_COLOR,MC_Black);
|
||||
|
||||
freeRam = Memory_free();
|
||||
@ -780,10 +780,6 @@ void Button_Stats(void)
|
||||
sprintf(buffer,"%ld (%lld Kb)",Stats_pages_number, Stats_pages_memory/1024);
|
||||
Print_in_window(162,59,buffer,STATS_DATA_COLOR,MC_Black);
|
||||
|
||||
// Affichage de l'espace disque libre
|
||||
sprintf(buffer,"Free space on %c:",Main_current_directory[0]);
|
||||
Print_in_window(10,67,buffer,STATS_TITLE_COLOR,MC_Black);
|
||||
|
||||
#if defined(__WIN32__)
|
||||
{
|
||||
ULARGE_INTEGER tailleU;
|
||||
@ -791,7 +787,6 @@ void Button_Stats(void)
|
||||
mem_size = tailleU.QuadPart;
|
||||
}
|
||||
#elif defined(__linux__) || defined(__macosx__) || defined(__FreeBSD__)
|
||||
// Note: under MacOSX, both macros are defined anyway.
|
||||
{
|
||||
struct statfs disk_info;
|
||||
statfs(Main_current_directory,&disk_info);
|
||||
@ -808,11 +803,19 @@ void Button_Stats(void)
|
||||
mem_size=drvInfo.b_free*drvInfo.b_clsiz*drvInfo.b_secsiz;
|
||||
|
||||
#else
|
||||
#define NODISKSPACESUPPORT
|
||||
// Free disk space is only for shows. Other platforms can display 0.
|
||||
#warning "Missing code for your platform !!! Check and correct please :)"
|
||||
mem_size=0;
|
||||
#endif
|
||||
|
||||
// Display free space
|
||||
if (mem_size != 0)
|
||||
{
|
||||
sprintf(buffer,"Free space on %c:",Main_current_directory[0]);
|
||||
Print_in_window(10,67,buffer,STATS_TITLE_COLOR,MC_Black);
|
||||
|
||||
|
||||
if(mem_size > (100ULL*1024*1024*1024))
|
||||
sprintf(buffer,"%u Gigabytes",(unsigned int)(mem_size/(1024*1024*1024)));
|
||||
else if(mem_size > (100*1024*1024))
|
||||
@ -822,6 +825,12 @@ void Button_Stats(void)
|
||||
else
|
||||
sprintf(buffer,"%u bytes",(unsigned int)mem_size);
|
||||
Print_in_window(146,67,buffer,STATS_DATA_COLOR,MC_Black);
|
||||
} else {
|
||||
#ifndef NODISKSPACESUPPORT
|
||||
Print_in_window(10,67,"Disk full!",STATS_TITLE_COLOR,MC_Black);
|
||||
#endif
|
||||
#undef NODISKSPACESUPPORT
|
||||
}
|
||||
|
||||
// Affichage des informations sur l'image
|
||||
Print_in_window(10,83,"Picture info.:",STATS_TITLE_COLOR,MC_Black);
|
||||
|
||||
@ -333,6 +333,12 @@ static const T_Help_table helptable_help[] =
|
||||
HELP_LINK (" 6 : %s", SPECIAL_LAYER6_TOGGLE)
|
||||
HELP_LINK (" 7 : %s", SPECIAL_LAYER7_TOGGLE)
|
||||
HELP_LINK (" 8 : %s", SPECIAL_LAYER8_TOGGLE)
|
||||
HELP_TEXT ("")
|
||||
HELP_LINK (" Format check : %s", SPECIAL_FORMAT_CHECKER)
|
||||
HELP_LINK (" Format check menu: %s", SPECIAL_FORMAT_CHECKER_MENU)
|
||||
HELP_TEXT ("")
|
||||
HELP_TEXT ("")
|
||||
HELP_TEXT ("")
|
||||
};
|
||||
static const T_Help_table helptable_credits[] =
|
||||
{
|
||||
|
||||
@ -1641,6 +1641,22 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
|
||||
true,
|
||||
SDLK_BACKQUOTE|MOD_CTRL, // Ctrl + `~
|
||||
0},
|
||||
{198,
|
||||
"Format checker",
|
||||
"Performs a format check on the",
|
||||
"current image.",
|
||||
"",
|
||||
true,
|
||||
0,
|
||||
0},
|
||||
{199,
|
||||
"Format checker menu",
|
||||
"Allows you to setup the checks",
|
||||
"performed by the format checker.",
|
||||
"",
|
||||
true,
|
||||
0,
|
||||
0},
|
||||
};
|
||||
|
||||
word Ordering[NB_SHORTCUTS]=
|
||||
@ -1843,4 +1859,6 @@ word Ordering[NB_SHORTCUTS]=
|
||||
SPECIAL_RUN_SCRIPT_9,
|
||||
SPECIAL_RUN_SCRIPT_10,
|
||||
SPECIAL_CYCLE_MODE,
|
||||
SPECIAL_FORMAT_CHECKER,
|
||||
SPECIAL_FORMAT_CHECKER_MENU,
|
||||
};
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
#endif
|
||||
#include <SDL.h>
|
||||
|
||||
#define NB_SHORTCUTS 198 ///< Number of actions that can have a key combination associated to it.
|
||||
#define NB_SHORTCUTS 200 ///< Number of actions that can have a key combination associated to it.
|
||||
|
||||
/*** Types definitions and structs ***/
|
||||
|
||||
|
||||
@ -125,6 +125,11 @@ void Save_C64(T_IO_Context *);
|
||||
// -- SCR (Amstrad CPC)
|
||||
void Save_SCR(T_IO_Context *);
|
||||
|
||||
// -- CM5 (Amstrad CPC)
|
||||
void Test_CM5(T_IO_Context *);
|
||||
void Load_CM5(T_IO_Context *);
|
||||
void Save_CM5(T_IO_Context *);
|
||||
|
||||
// -- XPM (X PixMap)
|
||||
// Loading is done through SDL_Image
|
||||
void Save_XPM(T_IO_Context*);
|
||||
@ -142,7 +147,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;lbm;ilbm;iff;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;kcf;pal;c64;koa;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"},
|
||||
{FORMAT_ALL_IMAGES, "(all)", NULL, NULL, NULL, 0, 0, 0, "", "gif;png;bmp;pcx;pkm;lbm;iff;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;kcf;pal;c64;koa;koala;fli;bml;cdu;prg;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;cm5"},
|
||||
{FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"},
|
||||
{FORMAT_GIF, " gif", Test_GIF, Load_GIF, Save_GIF, 0, 1, 1, "gif", "gif"},
|
||||
#ifndef __no_pnglib__
|
||||
@ -160,8 +165,9 @@ T_Format File_formats[] = {
|
||||
{FORMAT_NEO, " neo", Test_NEO, Load_NEO, Save_NEO, 0, 0, 0, "neo", "neo"},
|
||||
{FORMAT_KCF, " kcf", Test_KCF, Load_KCF, Save_KCF, 1, 0, 0, "kcf", "kcf"},
|
||||
{FORMAT_PAL, " pal", Test_PAL, Load_PAL, Save_PAL, 1, 0, 0, "pal", "pal"},
|
||||
{FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 0, 1, 0, "c64", "c64;koa"},
|
||||
{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_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"},
|
||||
};
|
||||
@ -427,7 +433,7 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
|
||||
context->Nb_layers=1;
|
||||
Main_current_layer=0;
|
||||
Main_layers_visible=1<<0;
|
||||
Set_layer(context,0);
|
||||
Set_loading_layer(context,0);
|
||||
|
||||
// Remove previous comment, unless we load just a palette
|
||||
if (! Get_fileformat(context->Format)->Palette_only)
|
||||
@ -1274,14 +1280,25 @@ void Init_context_surface(T_IO_Context * context, char *file_name, char *file_di
|
||||
|
||||
}
|
||||
/// Function to call when need to switch layers.
|
||||
void Set_layer(T_IO_Context *context, byte layer)
|
||||
void Set_saving_layer(T_IO_Context *context, byte layer)
|
||||
{
|
||||
context->Current_layer = layer;
|
||||
|
||||
if (context->Type == CONTEXT_MAIN_IMAGE)
|
||||
{
|
||||
context->Target_address=Main_backups->Pages->Image[layer];
|
||||
}
|
||||
}
|
||||
|
||||
/// Function to call when need to switch layers.
|
||||
void Set_loading_layer(T_IO_Context *context, byte layer)
|
||||
{
|
||||
context->Current_layer = layer;
|
||||
|
||||
if (context->Type == CONTEXT_MAIN_IMAGE)
|
||||
{
|
||||
// This awful thing is the part that happens on load
|
||||
while (layer > (context->Nb_layers-1))
|
||||
while (layer >= context->Nb_layers)
|
||||
{
|
||||
if (Add_layer(Main_backups, layer))
|
||||
{
|
||||
@ -1291,9 +1308,9 @@ void Set_layer(T_IO_Context *context, byte layer)
|
||||
break;
|
||||
}
|
||||
context->Nb_layers = Main_backups->Pages->Nb_layers;
|
||||
Main_current_layer = layer;
|
||||
Main_layers_visible = (2<<layer)-1;
|
||||
}
|
||||
Main_current_layer = layer;
|
||||
context->Target_address=Main_backups->Pages->Image[layer];
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +215,9 @@ void Set_pixel(T_IO_Context *context, short x, short y, byte c);
|
||||
/// Set the color of a 24bit pixel (on load)
|
||||
void Set_pixel_24b(T_IO_Context *context, short x, short y, byte r, byte g, byte b);
|
||||
/// Function to call when need to switch layers.
|
||||
void Set_layer(T_IO_Context *context, byte layer);
|
||||
void Set_loading_layer(T_IO_Context *context, byte layer);
|
||||
/// Function to call when need to switch layers.
|
||||
void Set_saving_layer(T_IO_Context *context, byte layer);
|
||||
|
||||
|
||||
// =================================================================
|
||||
|
||||
22
src/misc.c
22
src/misc.c
@ -853,6 +853,28 @@ double Fround(double n, unsigned d)
|
||||
return floor(n * exp + 0.5) / exp;
|
||||
}
|
||||
|
||||
/// Count number of bits in a word (16bit).
|
||||
/// Based on Wikipedia article for Hamming_weight, it's optimized
|
||||
/// for cases when zeroes are more frequent.
|
||||
int Popcount_word(word x)
|
||||
{
|
||||
word count;
|
||||
for (count=0; x; count++)
|
||||
x &= x-1;
|
||||
return count;
|
||||
}
|
||||
|
||||
/// Count number of bits in a dword (32bit).
|
||||
/// Based on Wikipedia article for Hamming_weight, it's optimized
|
||||
/// for cases when zeroes are more frequent.
|
||||
int Popcount_dword(dword x)
|
||||
{
|
||||
dword count;
|
||||
for (count=0; x; count++)
|
||||
x &= x-1;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
// Fonction retournant le libellé d'une mode (ex: " 320x200")
|
||||
char * Mode_label(int mode)
|
||||
|
||||
@ -168,3 +168,6 @@ int Max(int a,int b);
|
||||
|
||||
char* Mode_label(int mode);
|
||||
int Convert_videomode_arg(const char *argument);
|
||||
|
||||
int Popcount_word(word x);
|
||||
int Popcount_dword(dword x);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
Copyright 2009 Petter Lindquist
|
||||
Copyright 2008 Yves Rizoud
|
||||
Copyright 2008 Franck Charlet
|
||||
Copyright 2007 Adrien Destugues
|
||||
Copyright 2007-2011 Adrien Destugues
|
||||
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
|
||||
|
||||
Grafx2 is free software; you can redistribute it and/or
|
||||
@ -40,6 +40,7 @@
|
||||
#include "sdlscreen.h"
|
||||
#include "struct.h"
|
||||
#include "windows.h"
|
||||
#include "oldies.h"
|
||||
|
||||
//////////////////////////////////// PAL ////////////////////////////////////
|
||||
//
|
||||
@ -862,18 +863,18 @@ void Save_CEL(T_IO_Context * context)
|
||||
short x_pos;
|
||||
short y_pos;
|
||||
byte last_byte=0;
|
||||
dword Utilisation[256]; // Table d'utilisation de couleurs
|
||||
dword color_usage[256]; // Table d'utilisation de couleurs
|
||||
|
||||
|
||||
// On commence par compter l'utilisation de chaque couleurs
|
||||
Count_used_colors(Utilisation);
|
||||
Count_used_colors(color_usage);
|
||||
|
||||
File_error=0;
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
if ((file=fopen(filename,"wb")))
|
||||
{
|
||||
// On regarde si des couleurs >16 sont utilisées dans l'image
|
||||
for (x_pos=16;((x_pos<256) && (!Utilisation[x_pos]));x_pos++);
|
||||
for (x_pos=16;((x_pos<256) && (!color_usage[x_pos]));x_pos++);
|
||||
|
||||
if (x_pos==256)
|
||||
{
|
||||
@ -1180,10 +1181,10 @@ void Save_KCF(T_IO_Context * context)
|
||||
int pal_index;
|
||||
int color_index;
|
||||
int index;
|
||||
dword Utilisation[256]; // Table d'utilisation de couleurs
|
||||
dword color_usage[256]; // Table d'utilisation de couleurs
|
||||
|
||||
// On commence par compter l'utilisation de chaque couleurs
|
||||
Count_used_colors(Utilisation);
|
||||
Count_used_colors(color_usage);
|
||||
|
||||
File_error=0;
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
@ -1192,7 +1193,7 @@ void Save_KCF(T_IO_Context * context)
|
||||
// Sauvegarde de la palette
|
||||
|
||||
// On regarde si des couleurs >16 sont utilisées dans l'image
|
||||
for (index=16;((index<256) && (!Utilisation[index]));index++);
|
||||
for (index=16;((index<256) && (!color_usage[index]));index++);
|
||||
|
||||
if (index==256)
|
||||
{
|
||||
@ -2069,6 +2070,7 @@ void Save_NEO(T_IO_Context * context)
|
||||
}
|
||||
|
||||
//////////////////////////////////// C64 ////////////////////////////////////
|
||||
|
||||
void Test_C64(T_IO_Context * context)
|
||||
{
|
||||
FILE* file;
|
||||
@ -2084,14 +2086,17 @@ void Test_C64(T_IO_Context * context)
|
||||
file_size = File_length_file(file);
|
||||
switch (file_size)
|
||||
{
|
||||
case 1000: // screen or color
|
||||
case 1002: // (screen or color) + loadaddr
|
||||
// case 1000: // screen or color
|
||||
// case 1002: // (screen or color) + loadaddr
|
||||
case 8000: // raw bitmap
|
||||
case 8002: // raw bitmap with loadaddr
|
||||
case 9000: // bitmap + screen
|
||||
case 9002: // bitmap + screen + loadaddr
|
||||
case 9000: // bitmap + ScreenRAM
|
||||
case 9002: // bitmap + ScreenRAM + loadaddr
|
||||
case 10001: // multicolor
|
||||
case 10003: // multicolor + loadaddr
|
||||
case 17472: // FLI (BlackMail)
|
||||
case 17474: // FLI (BlackMail) + loadaddr
|
||||
case 10277: // multicolor CDU-Paint + loadaddr
|
||||
File_error = 0;
|
||||
break;
|
||||
default: // then we don't know for now.
|
||||
@ -2105,7 +2110,7 @@ void Test_C64(T_IO_Context * context)
|
||||
}
|
||||
}
|
||||
|
||||
void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *colors)
|
||||
void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *screen_ram)
|
||||
{
|
||||
int cx,cy,x,y,c[4],pixel,color;
|
||||
|
||||
@ -2113,8 +2118,8 @@ void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *colors)
|
||||
{
|
||||
for(cx=0; cx<40; cx++)
|
||||
{
|
||||
c[0]=colors[cy*40+cx]&15;
|
||||
c[1]=colors[cy*40+cx]>>4;
|
||||
c[0]=screen_ram[cy*40+cx]&15;
|
||||
c[1]=screen_ram[cy*40+cx]>>4;
|
||||
for(y=0; y<8; y++)
|
||||
{
|
||||
pixel=bitmap[cy*320+cx*8+y];
|
||||
@ -2128,7 +2133,7 @@ void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *colors)
|
||||
}
|
||||
}
|
||||
|
||||
void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *colors, byte *nybble, byte background)
|
||||
void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *screen_ram, byte *color_ram, byte background)
|
||||
{
|
||||
int cx,cy,x,y,c[4],pixel,color;
|
||||
c[0]=background&15;
|
||||
@ -2136,9 +2141,9 @@ void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *colors, byte *nyb
|
||||
{
|
||||
for(cx=0; cx<40; cx++)
|
||||
{
|
||||
c[1]=colors[cy*40+cx]>>4;
|
||||
c[2]=colors[cy*40+cx]&15;
|
||||
c[3]=nybble[cy*40+cx]&15;
|
||||
c[1]=screen_ram[cy*40+cx]>>4;
|
||||
c[2]=screen_ram[cy*40+cx]&15;
|
||||
c[3]=color_ram[cy*40+cx]&15;
|
||||
|
||||
for(y=0; y<8; y++)
|
||||
{
|
||||
@ -2154,16 +2159,113 @@ void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *colors, byte *nyb
|
||||
}
|
||||
}
|
||||
|
||||
void Load_C64_fli(T_IO_Context *context, byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
|
||||
{
|
||||
// Thanks to MagerValp for complement of specifications.
|
||||
//
|
||||
// background : length: 200 (+ padding 56)
|
||||
// These are the BG colors for lines 0-199 (top to bottom)
|
||||
// Low nybble: the color.
|
||||
// High nybble: garbage. ignore it.
|
||||
// color_ram : length: 1000 (+ padding 24)
|
||||
// Color RAM. Contains one color per 4x8 block.
|
||||
// There are 40x25 such blocks, arranged from top left to bottom
|
||||
// right, starting in right direction. For each block there is one byte.
|
||||
// Low nybble: the color.
|
||||
// High nybble: garbage. ignore it.
|
||||
// screen_ram : length: 8192
|
||||
// Screen RAMs. The s is important.
|
||||
// This is actually 8 blocks of 1000 bytes, each separated by a filler of
|
||||
// 24 bytes. Each byte contains data for a 4x1 pixel group, and a complete
|
||||
// block will contain 40x25 of them. 40 is from left to right, and 25 is from
|
||||
// top to bottom, spacing them 8 lines apart.
|
||||
// The second block start at y=1, the third block starts at y=2, etc...
|
||||
// Each byte contains 2 colors that *can* be used by the 4x1 pixel group:
|
||||
// Low nybble: Color 1
|
||||
// High nybble: Color 2
|
||||
//
|
||||
// bitmap : length: 8000
|
||||
// This is the final structure that refers to all others. It describes
|
||||
// 160x200 pixels linearly, from top left to bottom right, starting in
|
||||
// right direction. For each pixel, two bits say which color is displayed
|
||||
// (So 4 pixels are described by the same byte)
|
||||
// 00 Use the BG color of the current line (background[y])
|
||||
// 01 Use the Color 2 from the current 4x8 block of Screen RAM
|
||||
// ((screen_ram[y/8][x/4] & 0xF0) >> 8)
|
||||
// 10 Use the Color 1 from the current 4x8 block of Screen RAM
|
||||
// (screen_ram[y/8][x/4] & 0x0F)
|
||||
// 11 Use the color from Color RAM
|
||||
// (color_ram[y/8][x/4] & 0x0F)
|
||||
//
|
||||
|
||||
int cx,cy,x,y,c[4];
|
||||
|
||||
for(y=0; y<200; y++)
|
||||
{
|
||||
for(x=0; x<160; x++)
|
||||
{
|
||||
Set_pixel(context, x,y,background[y]);
|
||||
}
|
||||
}
|
||||
|
||||
Set_loading_layer(context, 1);
|
||||
for(cy=0; cy<25; cy++)
|
||||
{
|
||||
for(cx=0; cx<40; cx++)
|
||||
{
|
||||
c[3]=color_ram[cy*40+cx]&15;
|
||||
for(y=0; y<8; y++)
|
||||
{
|
||||
for(x=0; x<4; x++)
|
||||
{
|
||||
Set_pixel(context, cx*4+(3-x),cy*8+y,c[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set_loading_layer(context, 2);
|
||||
for(cy=0; cy<25; cy++)
|
||||
{
|
||||
for(cx=0; cx<40; cx++)
|
||||
{
|
||||
c[3]=color_ram[cy*40+cx]&15;
|
||||
for(y=0; y<8; y++)
|
||||
{
|
||||
int pixel=bitmap[cy*320+cx*8+y];
|
||||
|
||||
c[0]=background[cy*8+y]&15;
|
||||
c[1]=screen_ram[y*1024+cy*40+cx]>>4;
|
||||
c[2]=screen_ram[y*1024+cy*40+cx]&15;
|
||||
for(x=0; x<4; x++)
|
||||
{
|
||||
int color=c[(pixel&3)];
|
||||
pixel>>=2;
|
||||
Set_pixel(context, cx*4+(3-x),cy*8+y,color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Set_loading_layer(context, 3);
|
||||
for(y=0; y<200; y++)
|
||||
{
|
||||
for(x=0; x<160; x++)
|
||||
{
|
||||
Set_pixel(context, x,y,16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load_C64(T_IO_Context * context)
|
||||
{
|
||||
FILE* file;
|
||||
char filename[MAX_PATH_CHARACTERS];
|
||||
long file_size;
|
||||
int i;
|
||||
byte background,hasLoadAddr=0;
|
||||
byte hasLoadAddr=0;
|
||||
int loadFormat=0;
|
||||
enum c64_format {F_hires,F_multi,F_bitmap,F_screen,F_color};
|
||||
const char *c64_format_names[]={"hires","multicolor","bitmap","screen","color"};
|
||||
enum c64_format {F_hires,F_multi,F_bitmap,F_fli};
|
||||
const char *c64_format_names[]={"Hires","Multicolor","Bitmap","FLI"};
|
||||
|
||||
|
||||
// Palette from http://www.pepto.de/projects/colorvic/
|
||||
byte pal[48]={
|
||||
@ -2184,8 +2286,10 @@ void Load_C64(T_IO_Context * context)
|
||||
0x6C, 0x5E, 0xB5,
|
||||
0x95, 0x95, 0x95};
|
||||
|
||||
byte bitmap[8000],colors[1000],nybble[1000];
|
||||
byte *file_buffer;
|
||||
byte *bitmap, *screen_ram, *color_ram=NULL, *background=NULL; // Only pointers to existing data
|
||||
word width=320, height=200;
|
||||
static byte dummy_screen[1000];
|
||||
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
file = fopen(filename,"rb");
|
||||
@ -2195,107 +2299,181 @@ void Load_C64(T_IO_Context * context)
|
||||
File_error=0;
|
||||
file_size = File_length_file(file);
|
||||
|
||||
// Check for known file sizes
|
||||
switch (file_size)
|
||||
{
|
||||
case 1000: // screen or color
|
||||
hasLoadAddr=0;
|
||||
loadFormat=F_screen;
|
||||
case 8000: // raw bitmap
|
||||
case 8002: // raw bitmap with loadaddr
|
||||
case 9000: // bitmap + ScreenRAM
|
||||
case 9002: // bitmap + ScreenRAM + loadaddr
|
||||
case 10001: // multicolor
|
||||
case 10003: // multicolor + loadaddr
|
||||
case 10277: // multicolor CDU-Paint + loadaddr
|
||||
case 17472: // FLI (BlackMail)
|
||||
case 17474: // FLI (BlackMail) + loadaddr
|
||||
break;
|
||||
|
||||
case 1002: // (screen or color) + loadaddr
|
||||
hasLoadAddr=1;
|
||||
loadFormat=F_screen;
|
||||
break;
|
||||
default:
|
||||
File_error = 1;
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
// Load entire file in memory
|
||||
file_buffer=(byte *)malloc(file_size);
|
||||
if (!file_buffer)
|
||||
{
|
||||
File_error = 1;
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
if (!Read_bytes(file,file_buffer,file_size))
|
||||
{
|
||||
File_error = 1;
|
||||
free(file_buffer);
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
memset(dummy_screen,1,1000);
|
||||
|
||||
switch (file_size)
|
||||
{
|
||||
case 8000: // raw bitmap
|
||||
hasLoadAddr=0;
|
||||
loadFormat=F_bitmap;
|
||||
bitmap=file_buffer+0; // length: 8000
|
||||
screen_ram=dummy_screen;
|
||||
break;
|
||||
|
||||
case 8002: // raw bitmap with loadaddr
|
||||
hasLoadAddr=1;
|
||||
loadFormat=F_bitmap;
|
||||
bitmap=file_buffer+2; // length: 8000
|
||||
screen_ram=dummy_screen;
|
||||
break;
|
||||
|
||||
case 9000: // bitmap + screen
|
||||
case 9000: // bitmap + ScreenRAM
|
||||
hasLoadAddr=0;
|
||||
loadFormat=F_hires;
|
||||
bitmap=file_buffer+0; // length: 8000
|
||||
screen_ram=file_buffer+8000; // length: 1000
|
||||
break;
|
||||
|
||||
case 9002: // bitmap + screen + loadaddr
|
||||
case 9002: // bitmap + ScreenRAM + loadaddr
|
||||
hasLoadAddr=1;
|
||||
loadFormat=F_hires;
|
||||
bitmap=file_buffer+2; // length: 8000
|
||||
screen_ram=file_buffer+8002; // length: 1000
|
||||
break;
|
||||
|
||||
case 10001: // multicolor
|
||||
hasLoadAddr=0;
|
||||
loadFormat=F_multi;
|
||||
context->Ratio = PIXEL_WIDE;
|
||||
bitmap=file_buffer+0; // length: 8000
|
||||
screen_ram=file_buffer+8000; // length: 1000
|
||||
color_ram=file_buffer+9000; // length: 1000
|
||||
background=file_buffer+10000; // only 1
|
||||
break;
|
||||
|
||||
case 10003: // multicolor + loadaddr
|
||||
hasLoadAddr=1;
|
||||
loadFormat=F_multi;
|
||||
context->Ratio = PIXEL_WIDE;
|
||||
bitmap=file_buffer+2; // length: 8000
|
||||
screen_ram=file_buffer+8002; // length: 1000
|
||||
color_ram=file_buffer+9002; // length: 1000
|
||||
background=file_buffer+10002; // only 1
|
||||
break;
|
||||
|
||||
default: // then we don't know what it is.
|
||||
File_error = 1;
|
||||
case 10277: // multicolor CDU-Paint + loadaddr
|
||||
hasLoadAddr=1;
|
||||
loadFormat=F_multi;
|
||||
context->Ratio = PIXEL_WIDE;
|
||||
// 273 bytes of display routine
|
||||
bitmap=file_buffer+275; // length: 8000
|
||||
screen_ram=file_buffer+8275; // length: 1000
|
||||
color_ram=file_buffer+9275; // length: 1000
|
||||
background=file_buffer+10275; // only 1
|
||||
break;
|
||||
|
||||
case 17472: // FLI (BlackMail)
|
||||
hasLoadAddr=0;
|
||||
loadFormat=F_fli;
|
||||
context->Ratio = PIXEL_WIDE;
|
||||
background=file_buffer+0; // length: 200 (+ padding 56)
|
||||
color_ram=file_buffer+256; // length: 1000 (+ padding 24)
|
||||
screen_ram=file_buffer+1280; // length: 8192
|
||||
bitmap=file_buffer+9472; // length: 8000
|
||||
break;
|
||||
|
||||
case 17474: // FLI (BlackMail) + loadaddr
|
||||
hasLoadAddr=1;
|
||||
loadFormat=F_fli;
|
||||
context->Ratio = PIXEL_WIDE;
|
||||
background=file_buffer+2; // length: 200 (+ padding 56)
|
||||
color_ram=file_buffer+258; // length: 1000 (+ padding 24)
|
||||
screen_ram=file_buffer+1282; // length: 8192
|
||||
bitmap=file_buffer+9474; // length: 8000
|
||||
break;
|
||||
|
||||
default:
|
||||
File_error = 1;
|
||||
free(file_buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(context->Palette,pal,48); // this set the software palette for grafx2
|
||||
Palette_loaded(context); // Always call it if you change the palette
|
||||
|
||||
if (file_size>9002)
|
||||
if (context->Ratio == PIXEL_WIDE)
|
||||
width=160;
|
||||
|
||||
// Write detailed format in comment
|
||||
strcpy(context->Comment, c64_format_names[loadFormat]);
|
||||
if (hasLoadAddr)
|
||||
{
|
||||
// get load address
|
||||
Read_byte(file,&background);
|
||||
Read_byte(file,&background);
|
||||
sprintf(filename,"load at $%02x00",background);
|
||||
word load_addr;
|
||||
load_addr = file_buffer[0] | (file_buffer[1] << 8);
|
||||
sprintf(context->Comment+strlen(context->Comment),", load at $%04.4X",load_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(filename,"no addr");
|
||||
sprintf(context->Comment+strlen(context->Comment),", no addr");
|
||||
}
|
||||
|
||||
if(file_size>9002)
|
||||
{
|
||||
context->Ratio = PIXEL_WIDE;
|
||||
}
|
||||
sprintf(context->Comment,"C64 %s, %s",
|
||||
c64_format_names[loadFormat],filename);
|
||||
Pre_load(context, width, height, file_size, FORMAT_C64, context->Ratio,0); // Do this as soon as you can
|
||||
|
||||
memcpy(context->Palette,pal,48); // this set the software palette for grafx2
|
||||
// Transparent color "16" is a dark grey that is distinguishable
|
||||
// from black, but darker than normal colors.
|
||||
context->Palette[16].R=20;
|
||||
context->Palette[16].G=20;
|
||||
context->Palette[16].B=20;
|
||||
|
||||
Palette_loaded(context); // Always call it if you change the palette
|
||||
|
||||
context->Width = width ;
|
||||
context->Height = height;
|
||||
context->Transparent_color=16;
|
||||
|
||||
Read_bytes(file,bitmap,8000);
|
||||
|
||||
if (file_size>8002)
|
||||
Read_bytes(file,colors,1000);
|
||||
if(loadFormat==F_fli)
|
||||
{
|
||||
Load_C64_fli(context,bitmap,screen_ram,color_ram,background);
|
||||
}
|
||||
else
|
||||
if(loadFormat==F_multi)
|
||||
{
|
||||
for(i=0;i<1000;i++)
|
||||
{
|
||||
colors[i]=1;
|
||||
}
|
||||
}
|
||||
|
||||
if(width==160)
|
||||
{
|
||||
Read_bytes(file,nybble,1000);
|
||||
Read_byte(file,&background);
|
||||
Load_C64_multi(context,bitmap,colors,nybble,background);
|
||||
Load_C64_multi(context,bitmap,screen_ram,color_ram,*background);
|
||||
}
|
||||
else
|
||||
{
|
||||
Load_C64_hires(context,bitmap,colors);
|
||||
Load_C64_hires(context,bitmap,screen_ram);
|
||||
}
|
||||
|
||||
File_error = 0;
|
||||
fclose(file);
|
||||
|
||||
free(file_buffer);
|
||||
|
||||
}
|
||||
else
|
||||
File_error = 1;
|
||||
@ -2324,17 +2502,17 @@ int Save_C64_window(byte *saveWhat, byte *loadAddr)
|
||||
};
|
||||
|
||||
Open_window(200,120,"c64 settings");
|
||||
Window_set_normal_button(110,100,80,15,"Save",1,1,SDLK_RETURN);
|
||||
Window_set_normal_button(10,100,80,15,"Cancel",1,1,SDLK_ESCAPE);
|
||||
Window_set_normal_button(110,100,80,15,"Save",1,1,SDLK_RETURN); // 1
|
||||
Window_set_normal_button(10,100,80,15,"Cancel",1,1,SDLK_ESCAPE); // 2
|
||||
|
||||
Print_in_window(13,18,"Data:",MC_Dark,MC_Light);
|
||||
what=Window_set_dropdown_button(10,28,90,15,70,what_label[*saveWhat],1, 0, 1, LEFT_SIDE,0);
|
||||
what=Window_set_dropdown_button(10,28,90,15,70,what_label[*saveWhat],1, 0, 1, LEFT_SIDE,0); // 3
|
||||
Window_dropdown_clear_items(what);
|
||||
for (i=0; i<sizeof(what_label)/sizeof(what_label[0]); i++)
|
||||
Window_dropdown_add_item(what,i,what_label[i]);
|
||||
|
||||
Print_in_window(113,18,"Address:",MC_Dark,MC_Light);
|
||||
addr=Window_set_dropdown_button(110,28,70,15,70,address_label[*loadAddr/32],1, 0, 1, LEFT_SIDE,0);
|
||||
addr=Window_set_dropdown_button(110,28,70,15,70,address_label[*loadAddr/32],1, 0, 1, LEFT_SIDE,0); // 4
|
||||
Window_dropdown_clear_items(addr);
|
||||
for (i=0; i<sizeof(address_label)/sizeof(address_label[0]); i++)
|
||||
Window_dropdown_add_item(addr,i,address_label[i]);
|
||||
@ -2371,10 +2549,10 @@ int Save_C64_hires(T_IO_Context *context, char *filename, byte saveWhat, byte lo
|
||||
int cx,cy,x,y,c1,c2=0,i,pixel,bits,pos=0;
|
||||
word numcolors;
|
||||
dword cusage[256];
|
||||
byte colors[1000],bitmap[8000];
|
||||
byte screen_ram[1000],bitmap[8000];
|
||||
FILE *file;
|
||||
|
||||
for(x=0;x<1000;x++)colors[x]=1; // init colormem to black/white
|
||||
for(x=0;x<1000;x++)screen_ram[x]=1; // init colormem to black/white
|
||||
|
||||
for(cy=0; cy<25; cy++) // Character line, 25 lines
|
||||
{
|
||||
@ -2408,7 +2586,7 @@ int Save_C64_hires(T_IO_Context *context, char *filename, byte saveWhat, byte lo
|
||||
c1=i;
|
||||
}
|
||||
}
|
||||
colors[cx+cy*40]=(c2<<4)|c1;
|
||||
screen_ram[cx+cy*40]=(c2<<4)|c1;
|
||||
|
||||
for(y=0; y<8; y++)
|
||||
{
|
||||
@ -2450,7 +2628,7 @@ int Save_C64_hires(T_IO_Context *context, char *filename, byte saveWhat, byte lo
|
||||
if (saveWhat==0 || saveWhat==1)
|
||||
Write_bytes(file,bitmap,8000);
|
||||
if (saveWhat==0 || saveWhat==2)
|
||||
Write_bytes(file,colors,1000);
|
||||
Write_bytes(file,screen_ram,1000);
|
||||
|
||||
fclose(file);
|
||||
return 0;
|
||||
@ -2461,13 +2639,13 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
|
||||
/*
|
||||
BITS COLOR INFORMATION COMES FROM
|
||||
00 Background color #0 (screen color)
|
||||
01 Upper 4 bits of screen memory
|
||||
10 Lower 4 bits of screen memory
|
||||
11 Color nybble (nybble = 1/2 byte = 4 bits)
|
||||
01 Upper 4 bits of Screen RAM
|
||||
10 Lower 4 bits of Screen RAM
|
||||
11 Color RAM nybble (nybble = 1/2 byte = 4 bits)
|
||||
*/
|
||||
|
||||
int cx,cy,x,y,c[4]={0,0,0,0},color,lut[16],bits,pixel,pos=0;
|
||||
byte bitmap[8000],screen[1000],nybble[1000];
|
||||
byte bitmap[8000],screen_ram[1000],color_ram[1000];
|
||||
word numcolors,count;
|
||||
dword cusage[256];
|
||||
byte i,background=0;
|
||||
@ -2517,9 +2695,9 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
|
||||
}
|
||||
}
|
||||
}
|
||||
// add to screen and nybble
|
||||
screen[cx+cy*40]=c[1]<<4|c[2];
|
||||
nybble[cx+cy*40]=c[3];
|
||||
// add to screen_ram and color_ram
|
||||
screen_ram[cx+cy*40]=c[1]<<4|c[2];
|
||||
color_ram[cx+cy*40]=c[3];
|
||||
//printf("%x%x%x ",c[1],c[2],c[3]);
|
||||
for(y=0;y<8;y++)
|
||||
{
|
||||
@ -2563,10 +2741,10 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
|
||||
Write_bytes(file,bitmap,8000);
|
||||
|
||||
if (saveWhat==0 || saveWhat==2)
|
||||
Write_bytes(file,screen,1000);
|
||||
Write_bytes(file,screen_ram,1000);
|
||||
|
||||
if (saveWhat==0 || saveWhat==3)
|
||||
Write_bytes(file,nybble,1000);
|
||||
Write_bytes(file,color_ram,1000);
|
||||
|
||||
if (saveWhat==0)
|
||||
Write_byte(file,background);
|
||||
@ -2576,6 +2754,55 @@ int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte lo
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Save_C64_fli(char *filename, byte saveWhat, byte loadAddr)
|
||||
{
|
||||
|
||||
FILE *file;
|
||||
byte file_buffer[17474];
|
||||
|
||||
memset(file_buffer,0,sizeof(file_buffer));
|
||||
|
||||
if (C64_FLI(file_buffer+9474, file_buffer+1282, file_buffer+258, file_buffer+2))
|
||||
{
|
||||
File_error=1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
file = fopen(filename,"wb");
|
||||
|
||||
if(!file)
|
||||
{
|
||||
Warning_message("File open failed");
|
||||
File_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (loadAddr)
|
||||
{
|
||||
file_buffer[0]=0;
|
||||
file_buffer[1]=loadAddr;
|
||||
Write_bytes(file,file_buffer,2);
|
||||
}
|
||||
|
||||
if (saveWhat==0)
|
||||
Write_bytes(file,file_buffer+2,256);
|
||||
|
||||
if (saveWhat==0 || saveWhat==3)
|
||||
Write_bytes(file,file_buffer+258,1024);
|
||||
|
||||
if (saveWhat==0 || saveWhat==1)
|
||||
Write_bytes(file,file_buffer+1282,8192);
|
||||
|
||||
if (saveWhat==0 || saveWhat==2)
|
||||
Write_bytes(file,file_buffer+9474,8000);
|
||||
|
||||
|
||||
|
||||
fclose(file);
|
||||
//printf("\nbg:%d\n",background);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Save_C64(T_IO_Context * context)
|
||||
{
|
||||
char filename[MAX_PATH_CHARACTERS];
|
||||
@ -2585,12 +2812,14 @@ void Save_C64(T_IO_Context * context)
|
||||
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
|
||||
/*
|
||||
if (numcolors>16)
|
||||
{
|
||||
Warning_message("Error: Max 16 colors");
|
||||
File_error = 1;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
if (((context->Width!=320) && (context->Width!=160)) || context->Height!=200)
|
||||
{
|
||||
Warning_message("must be 320x200 or 160x200");
|
||||
@ -2608,7 +2837,7 @@ void Save_C64(T_IO_Context * context)
|
||||
if (context->Width==320)
|
||||
File_error = Save_C64_hires(context,filename,saveWhat,loadAddr);
|
||||
else
|
||||
File_error = Save_C64_multi(context,filename,saveWhat,loadAddr);
|
||||
File_error = Save_C64_fli(filename,saveWhat,loadAddr);
|
||||
}
|
||||
|
||||
|
||||
@ -2699,3 +2928,234 @@ void Save_SCR(T_IO_Context * context)
|
||||
|
||||
File_error = 0;
|
||||
}
|
||||
|
||||
// CM5 - Amstrad CPC "Mode 5" picture
|
||||
// This is a format designed by SyX. There is one .SCR file in the usual amstrad format,
|
||||
// and a .CM5 file with the palette, which varies over time.
|
||||
|
||||
void Test_CM5(T_IO_Context * context)
|
||||
{
|
||||
// check cm5 file size == 2049 bytes
|
||||
FILE *file;
|
||||
char filename[MAX_PATH_CHARACTERS];
|
||||
long file_size;
|
||||
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
|
||||
File_error = 1;
|
||||
|
||||
if ((file = fopen(filename, "rb")))
|
||||
{
|
||||
file_size = File_length_file(file);
|
||||
if (file_size == 2049)
|
||||
File_error = 0;
|
||||
}
|
||||
|
||||
// TODO: check existence of a .SCR file with the same name
|
||||
}
|
||||
|
||||
|
||||
void Load_CM5(T_IO_Context* context)
|
||||
{
|
||||
// Ensure "8bit" constraint mode is switched on
|
||||
// Set palette to the CPC hardware colors
|
||||
// Load the palette data to the 4 colorlayers
|
||||
FILE *file;
|
||||
char filename[MAX_PATH_CHARACTERS];
|
||||
byte value = 0;
|
||||
int mod;
|
||||
short line = 0;
|
||||
int tx, ty;
|
||||
byte buffer[48*6/4];
|
||||
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
|
||||
if (!(file = fopen(filename, "rb")))
|
||||
{
|
||||
File_error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
Pre_load(context, 48*6, 256, 2049, FORMAT_CM5, PIXEL_SIMPLE, 0);
|
||||
context->Width=48*6;
|
||||
context->Height=256;
|
||||
|
||||
// Setup the palette (amstrad hardware palette)
|
||||
context->Palette[0x54].R = 0; context->Palette[0x54].G = 2; context->Palette[0x54].B = 1;
|
||||
context->Palette[0x44].R = 0; context->Palette[0x44].G = 2; context->Palette[0x44].B = 0x6B;
|
||||
context->Palette[0x55].R = 0x0C; context->Palette[0x55].G = 2; context->Palette[0x55].B = 0xF4;
|
||||
context->Palette[0x5C].R = 0x6C; context->Palette[0x5C].G = 2; context->Palette[0x5C].B = 1;
|
||||
context->Palette[0x58].R = 0x69; context->Palette[0x58].G = 2; context->Palette[0x58].B = 0x68;
|
||||
context->Palette[0x5D].R = 0x6C; context->Palette[0x5D].G = 2; context->Palette[0x5D].B = 0xF2;
|
||||
context->Palette[0x4C].R = 0xF3; context->Palette[0x4C].G = 5; context->Palette[0x4C].B = 6;
|
||||
context->Palette[0x45].R = 0xF0; context->Palette[0x45].G = 2; context->Palette[0x45].B = 0x68;
|
||||
context->Palette[0x4D].R = 0xF3; context->Palette[0x4D].G = 2; context->Palette[0x4D].B = 0xF4;
|
||||
context->Palette[0x56].R = 2; context->Palette[0x56].G = 0x78; context->Palette[0x56].B = 1;
|
||||
context->Palette[0x46].R = 0; context->Palette[0x46].G = 0x78; context->Palette[0x46].B = 0x68;
|
||||
context->Palette[0x57].R = 0xC; context->Palette[0x57].G = 0x7B; context->Palette[0x57].B = 0xF4;
|
||||
context->Palette[0x5E].R = 0x6E; context->Palette[0x5E].G = 0x7B; context->Palette[0x5E].B = 1;
|
||||
context->Palette[0x40].R = 0x6E; context->Palette[0x40].G = 0x7D; context->Palette[0x40].B = 0x6B;
|
||||
context->Palette[0x5F].R = 0x6E; context->Palette[0x5F].G = 0x7B; context->Palette[0x5F].B = 0xF6;
|
||||
context->Palette[0x4E].R = 0xF3; context->Palette[0x4E].G = 0x7D; context->Palette[0x4E].B = 0xD;
|
||||
context->Palette[0x47].R = 0xF3; context->Palette[0x47].G = 0x7D; context->Palette[0x47].B = 0x6B;
|
||||
context->Palette[0x4F].R = 0xFA; context->Palette[0x4F].G = 0x80; context->Palette[0x4F].B = 0xF9;
|
||||
context->Palette[0x52].R = 2; context->Palette[0x52].G = 0xF0; context->Palette[0x52].B = 1;
|
||||
context->Palette[0x42].R = 0; context->Palette[0x42].G = 0xF3; context->Palette[0x42].B = 0x6B;
|
||||
context->Palette[0x53].R = 0xF; context->Palette[0x53].G = 0xF3; context->Palette[0x53].B = 0xF2;
|
||||
context->Palette[0x5A].R = 0x71; context->Palette[0x5A].G = 0xF5; context->Palette[0x5A].B = 4;
|
||||
context->Palette[0x59].R = 0x71; context->Palette[0x59].G = 0xF3; context->Palette[0x59].B = 0x6B;
|
||||
context->Palette[0x5B].R = 0x71; context->Palette[0x5B].G = 0xF3; context->Palette[0x5B].B = 0xF4;
|
||||
context->Palette[0x4A].R = 0xF3; context->Palette[0x4A].G = 0xF3; context->Palette[0x4A].B = 0xD;
|
||||
context->Palette[0x43].R = 0xF3; context->Palette[0x43].G = 0xF3; context->Palette[0x43].B = 0x6D;
|
||||
context->Palette[0x4B].R = 255; context->Palette[0x4B].G = 0xF3; context->Palette[0x4B].B = 0xF9;
|
||||
|
||||
Palette_loaded(context);
|
||||
|
||||
if (Constraint_mode != 1)
|
||||
Constraint_mode = 1;
|
||||
|
||||
if (Read_byte(file, &value)!=1)
|
||||
File_error = 2;
|
||||
|
||||
Set_loading_layer(context, 0);
|
||||
for(ty=0; ty<context->Height; ty++)
|
||||
for(tx=0; tx<context->Width; tx++)
|
||||
{
|
||||
Set_pixel(context, tx, ty, value);
|
||||
}
|
||||
// Fill layer with color we just read
|
||||
|
||||
while(Read_byte(file, &value) == 1)
|
||||
{
|
||||
switch(mod)
|
||||
{
|
||||
case 0:
|
||||
// This is color for layer 1
|
||||
Set_loading_layer(context, 1);
|
||||
for(tx=0; tx<context->Width; tx++)
|
||||
Set_pixel(context, tx, line, value);
|
||||
break;
|
||||
case 1:
|
||||
// This is color for layer 2
|
||||
Set_loading_layer(context, 2);
|
||||
for(tx=0; tx<context->Width; tx++)
|
||||
Set_pixel(context, tx, line, value);
|
||||
break;
|
||||
default:
|
||||
// This is color for a block in layer 4
|
||||
Set_loading_layer(context, 3);
|
||||
for(tx=(mod-2)*48; tx<(mod-1)*48; tx++)
|
||||
Set_pixel(context, tx, line, value);
|
||||
break;
|
||||
}
|
||||
mod = mod + 1;
|
||||
if (mod > 7)
|
||||
{
|
||||
mod = 0;
|
||||
line ++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
// Load the pixeldata to the 5th layer
|
||||
filename[strlen(filename) - 3] = 0;
|
||||
strcat(filename,"gfx");
|
||||
if (!(file = fopen(filename, "rb")))
|
||||
{
|
||||
File_error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
Set_loading_layer(context, 4);
|
||||
|
||||
for (ty = 0; ty < 256; ty++)
|
||||
{
|
||||
Read_bytes(file, buffer, 48*6/4);
|
||||
for (tx = 0; tx < 48*6; tx+=4)
|
||||
{
|
||||
Set_pixel(context, tx+0, ty, 3-(((buffer[tx/4]&0x80) >> 7) |((buffer[tx/4]&0x8)>>2)));
|
||||
Set_pixel(context, tx+1, ty, 3-(((buffer[tx/4]&0x40) >> 6) |((buffer[tx/4]&0x4)>>1)));
|
||||
Set_pixel(context, tx+2, ty, 3-(((buffer[tx/4]&0x20) >> 5) |((buffer[tx/4]&0x2)>>0)));
|
||||
Set_pixel(context, tx+3, ty, 3-(((buffer[tx/4]&0x10) >> 4) |((buffer[tx/4]&0x1)<<1)));
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Save_CM5(T_IO_Context* context)
|
||||
{
|
||||
char filename[MAX_PATH_CHARACTERS];
|
||||
FILE* file;
|
||||
int tx, ty;
|
||||
|
||||
|
||||
Get_full_filename(filename, context->File_name, context->File_directory);
|
||||
// TODO: Check picture has 5 layers
|
||||
// TODO: Check the constraints on the layers
|
||||
// Layer 1 : 1 color Only
|
||||
// Layer 2 and 3 : 1 color/line
|
||||
// Layer 4 : 1 color / 48x1 block
|
||||
// TODO: handle filesize
|
||||
|
||||
if (!(file = fopen(filename,"wb")))
|
||||
{
|
||||
File_error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Write layer 0
|
||||
Set_saving_layer(context, 0);
|
||||
Write_byte(file, Get_pixel(context, 0, 0));
|
||||
for(ty = 0; ty < 256; ty++)
|
||||
{
|
||||
Set_saving_layer(context, 1);
|
||||
Write_byte(file, Get_pixel(context, 0, ty));
|
||||
Set_saving_layer(context, 2);
|
||||
Write_byte(file, Get_pixel(context, 0, ty));
|
||||
Set_saving_layer(context, 3);
|
||||
for(tx = 0; tx < 6; tx++)
|
||||
{
|
||||
Write_byte(file, Get_pixel(context, tx*48, ty));
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
// Now the pixeldata
|
||||
filename[strlen(filename) - 3] = 0;
|
||||
strcat(filename,"gfx");
|
||||
if (!(file = fopen(filename, "wb")))
|
||||
{
|
||||
File_error = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
Set_saving_layer(context, 4);
|
||||
|
||||
for (ty = 0; ty < 256; ty++)
|
||||
{
|
||||
for (tx = 0; tx < 48*6; tx+=4)
|
||||
{
|
||||
byte code = 0;
|
||||
byte pixel;
|
||||
|
||||
pixel = 3-Get_pixel(context, tx+3, ty);
|
||||
code |= (pixel&2)>>1 | ((pixel & 1)<<4);
|
||||
pixel = 3-Get_pixel(context, tx+2, ty);
|
||||
code |= ((pixel&2)<<0) | ((pixel & 1)<<5);
|
||||
pixel = 3-Get_pixel(context, tx+1, ty);
|
||||
code |= ((pixel&2)<<1) | ((pixel & 1)<<6);
|
||||
pixel = 3-Get_pixel(context, tx, ty);
|
||||
code |= ((pixel&2)<<2) | ((pixel & 1)<<7);
|
||||
Write_byte(file, code);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
File_error = 0;
|
||||
|
||||
}
|
||||
|
||||
411
src/oldies.c
Normal file
411
src/oldies.c
Normal file
@ -0,0 +1,411 @@
|
||||
/* vim:expandtab:ts=2 sw=2:
|
||||
*/
|
||||
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
||||
|
||||
Copyright 2008 Yves Rizoud
|
||||
Copyright 2008 Franck Charlet
|
||||
Copyright 2007 Adrien Destugues
|
||||
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
|
||||
|
||||
Grafx2 is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; version 2
|
||||
of the License.
|
||||
|
||||
Grafx2 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Grafx2; if not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include <SDL.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "struct.h"
|
||||
#include "global.h"
|
||||
#include "errors.h"
|
||||
#include "misc.h"
|
||||
#include "palette.h"
|
||||
|
||||
void Pixel_in_layer(word x,word y, byte layer, byte color)
|
||||
{
|
||||
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer])=color;
|
||||
}
|
||||
|
||||
byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
|
||||
{
|
||||
word used_colors[200][40];
|
||||
word block_used_colors[25][40];
|
||||
word line_used_colors[200];
|
||||
byte used_colors_count[200][40];
|
||||
dword usage[16];
|
||||
word x,y,row,col;
|
||||
int i;
|
||||
byte line_color[200];
|
||||
byte block_color[25][40];
|
||||
word best_color_count;
|
||||
byte best_color;
|
||||
const byte no_color=16;
|
||||
|
||||
// Prerequisites
|
||||
if (Main_backups->Pages->Nb_layers < 3)
|
||||
return 1;
|
||||
if (Main_image_width != 160 || Main_image_height != 200)
|
||||
return 2;
|
||||
|
||||
memset(used_colors,0,200*40*sizeof(word));
|
||||
memset(block_used_colors,0,25*40*sizeof(word));
|
||||
memset(line_used_colors,0,200*sizeof(word));
|
||||
memset(used_colors_count,0,200*40*sizeof(byte));
|
||||
|
||||
// Initialize these as "unset"
|
||||
memset(line_color,no_color,200*sizeof(byte));
|
||||
memset(block_color,no_color,25*40*sizeof(byte));
|
||||
|
||||
// Examine all 4-pixel blocks to fill used_colors[][]
|
||||
for (row=0;row<200;row++)
|
||||
{
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
for (x=0;x<4;x++)
|
||||
{
|
||||
byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2]);
|
||||
used_colors[row][col] |= 1<<c;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get "mandatory colors" from layer 1
|
||||
for (row=0;row<200;row++)
|
||||
{
|
||||
byte c=*((row)*Main_image_width+0+Main_backups->Pages->Image[0]);
|
||||
if (c<16)
|
||||
{
|
||||
line_color[row]=c;
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
// Remove that color from the sets
|
||||
used_colors[row][col] &= ~(1<<c);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get "mandatory colors" from layer 2
|
||||
for (row=0;row<200;row+=8)
|
||||
{
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
byte c=*((row)*Main_image_width+(col*4)+Main_backups->Pages->Image[1]);
|
||||
if (c<16)
|
||||
{
|
||||
block_color[row/8][col]=c;
|
||||
// Remove that color from the sets
|
||||
for (y=0; y<8;y++)
|
||||
used_colors[row+y][col] &= ~(1<<c);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now count the "remaining colors".
|
||||
for (row=0;row<200;row++)
|
||||
{
|
||||
memset(usage,0,16*sizeof(dword));
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
used_colors_count[row][col]=Popcount_word(used_colors[row][col]);
|
||||
// Count which colors are used 3 times
|
||||
if (used_colors_count[row][col]==3)
|
||||
{
|
||||
for (i=0; i<16; i++)
|
||||
if (used_colors[row][col] & (1<<i))
|
||||
usage[i]+=1;
|
||||
}
|
||||
// Count which colors are used 4 times (important)
|
||||
else if (used_colors_count[row][col]==4)
|
||||
{
|
||||
for (i=0; i<16; i++)
|
||||
if (used_colors[row][col] & (1<<i))
|
||||
usage[i]+=2;
|
||||
}
|
||||
}
|
||||
// A complete line has been examined. Pick the color which has been tagged most, and set it as
|
||||
// the line color (unless it already was set.)
|
||||
if (line_color[row]==no_color)
|
||||
{
|
||||
best_color_count=0;
|
||||
best_color=no_color;
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
if (usage[i]>best_color_count)
|
||||
{
|
||||
best_color_count=usage[i];
|
||||
best_color=i;
|
||||
}
|
||||
}
|
||||
line_color[row]=best_color;
|
||||
|
||||
// Remove that color from the sets
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
if (used_colors[row][col] & (1<<best_color))
|
||||
{
|
||||
used_colors[row][col] &= ~(1<<best_color);
|
||||
// Update count
|
||||
used_colors_count[row][col]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now check all 4*8 blocks
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
for (row=0;row<200;row+=8)
|
||||
{
|
||||
// If there wasn't a preset color for this block
|
||||
if (block_color[row/8][col]==no_color)
|
||||
{
|
||||
word filter=0xFFFF;
|
||||
|
||||
// Count used colors
|
||||
memset(usage,0,16*sizeof(dword));
|
||||
for (y=0;y<8;y++)
|
||||
{
|
||||
if (used_colors_count[row+y][col]>2)
|
||||
{
|
||||
filter &= used_colors[row+y][col];
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
if (used_colors[row+y][col] & (1<<i))
|
||||
usage[i]+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filter != 0 && Popcount_word(filter) == 1)
|
||||
{
|
||||
// Only one color matched all needs: Use it.
|
||||
i=1;
|
||||
best_color=0;
|
||||
while (! (filter & i))
|
||||
{
|
||||
best_color++;
|
||||
i= i << 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filter==0)
|
||||
{
|
||||
// No color in common from multiple lines with 3+ colors...
|
||||
// Keep them all for the usage sort.
|
||||
filter=0xFFFF;
|
||||
}
|
||||
|
||||
// Pick the color which has been tagged most, and set it as
|
||||
// the block color
|
||||
best_color_count=0;
|
||||
best_color=no_color;
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
if (filter & (1<<i))
|
||||
{
|
||||
if (usage[i]>best_color_count)
|
||||
{
|
||||
best_color_count=usage[i];
|
||||
best_color=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
block_color[row/8][col]=best_color;
|
||||
|
||||
// Remove that color from the sets
|
||||
for (y=0;y<8;y++)
|
||||
{
|
||||
if (used_colors[row+y][col] & (1<<best_color))
|
||||
{
|
||||
used_colors[row+y][col] &= ~(1<<best_color);
|
||||
// Update count
|
||||
used_colors_count[row+y][col]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// At this point, the following arrays are filled:
|
||||
// - block_color[][]
|
||||
// - line_color[]
|
||||
// They contain either a color 0-16, or no_color if no color is mandatory.
|
||||
// It's now possible to scan the whole image and choose how to encode it.
|
||||
// TODO: Draw problematic places on layer 4, with one of the available colors
|
||||
/*
|
||||
if (bitmap!=NULL)
|
||||
{
|
||||
for (row=0;row<200;row++)
|
||||
{
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Output background
|
||||
if (background!=NULL)
|
||||
{
|
||||
for (row=0;row<200;row++)
|
||||
{
|
||||
if (line_color[row]==no_color)
|
||||
background[row]=0; // Unneeded line is black
|
||||
else
|
||||
background[row]=line_color[row];
|
||||
}
|
||||
}
|
||||
|
||||
// Output Color RAM
|
||||
if (color_ram!=NULL)
|
||||
{
|
||||
for (col=0;col<40;col++)
|
||||
{
|
||||
for (row=0;row<25;row++)
|
||||
{
|
||||
if (block_color[row][col]==no_color)
|
||||
color_ram[row*40+col]=0; // Unneeded block is black
|
||||
else
|
||||
color_ram[row*40+col]=block_color[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(row=0; row<25; row++)
|
||||
{
|
||||
for(col=0; col<40; col++)
|
||||
{
|
||||
for(y=0; y<8; y++)
|
||||
{
|
||||
byte c1, c2;
|
||||
|
||||
// Find 2 colors in used_colors[row*8+y][col]
|
||||
for (c1=0; c1<16 && !(used_colors[row*8+y][col] & (1<<c1)); c1++)
|
||||
;
|
||||
for (c2=c1+1; c2<16 && !(used_colors[row*8+y][col] & (1<<c2)); c2++)
|
||||
;
|
||||
if (c1>15)
|
||||
c1=16;
|
||||
if (c2>15)
|
||||
c2=16;
|
||||
|
||||
// Output Screen RAMs
|
||||
if (screen_ram!=NULL)
|
||||
screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4);
|
||||
|
||||
// Output bitmap
|
||||
if (bitmap!=NULL)
|
||||
{
|
||||
for(x=0; x<4; x++)
|
||||
{
|
||||
byte bits;
|
||||
byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2]);
|
||||
|
||||
if (c==line_color[row*8+y])
|
||||
// BG color
|
||||
bits=0;
|
||||
else if (c==block_color[row][col])
|
||||
// block color
|
||||
bits=3;
|
||||
else if (c==c1)
|
||||
// Color 1
|
||||
bits=2;
|
||||
else if (c==c2)
|
||||
// Color 2
|
||||
bits=1;
|
||||
else // problem
|
||||
bits=0;
|
||||
// clear target bits
|
||||
//bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2));
|
||||
// set them
|
||||
bitmap[row*320+col*8+y] |= bits<<((3-x)*2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//memset(background,3,200);
|
||||
//memset(color_ram,5,8000);
|
||||
//memset(screen_ram,(9<<4) | 7,8192);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
byte C64_FLI_enforcer(void)
|
||||
{
|
||||
byte background[200];
|
||||
byte bitmap[8000];
|
||||
byte screen_ram[8192];
|
||||
byte color_ram[1000];
|
||||
|
||||
int row, col, x, y;
|
||||
byte c[4];
|
||||
|
||||
// Checks
|
||||
if (Main_image_width != 160)
|
||||
return 1;
|
||||
if (Main_image_height != 200)
|
||||
return 1;
|
||||
if (Main_backups->Pages->Nb_layers != 4)
|
||||
return 2;
|
||||
|
||||
Backup_layers(1<<3);
|
||||
|
||||
memset(bitmap,0,8000);
|
||||
memset(background,0,200);
|
||||
memset(color_ram,0,1000);
|
||||
memset(screen_ram,0,8192);
|
||||
C64_FLI(bitmap, screen_ram, color_ram, background);
|
||||
|
||||
for(row=0; row<25; row++)
|
||||
{
|
||||
for(col=0; col<40; col++)
|
||||
{
|
||||
c[3]=color_ram[row*40+col]&15;
|
||||
for(y=0; y<8; y++)
|
||||
{
|
||||
int pixel=bitmap[row*320+col*8+y];
|
||||
|
||||
c[0]=background[row*8+y]&15;
|
||||
c[1]=screen_ram[y*1024+row*40+col]>>4;
|
||||
c[2]=screen_ram[y*1024+row*40+col]&15;
|
||||
for(x=0; x<4; x++)
|
||||
{
|
||||
int color=c[(pixel&3)];
|
||||
pixel>>=2;
|
||||
Pixel_in_layer(col*4+(3-x),row*8+y,3,color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End_of_modification();
|
||||
|
||||
// Visible feedback:
|
||||
|
||||
// If the "check" layer was visible, manually update the whole thing
|
||||
if (Main_layers_visible & (1<<3))
|
||||
{
|
||||
Hide_cursor();
|
||||
Redraw_layered_image();
|
||||
Display_all_screen();
|
||||
Display_layerbar();
|
||||
Display_cursor();
|
||||
}
|
||||
else
|
||||
// Otherwise, simply toggle the layer visiblity
|
||||
Layer_activate(3,RIGHT_SIDE);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
24
src/oldies.h
Normal file
24
src/oldies.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* vim:expandtab:ts=2 sw=2:
|
||||
*/
|
||||
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
||||
|
||||
Copyright 2008 Adrien Destugues
|
||||
|
||||
Grafx2 is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; version 2
|
||||
of the License.
|
||||
|
||||
Grafx2 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Grafx2; if not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background);
|
||||
|
||||
byte C64_FLI_enforcer(void);
|
||||
|
||||
24
src/pages.c
24
src/pages.c
@ -197,8 +197,29 @@ void Redraw_layered_image(void)
|
||||
{
|
||||
#ifndef NOLAYERS
|
||||
// Re-construct the image with the visible layers
|
||||
byte layer;
|
||||
byte layer=0;
|
||||
// First layer
|
||||
if (Constraint_mode && Main_layers_visible & (1<<4))
|
||||
{
|
||||
// The raster result layer is visible: start there
|
||||
// Copy it in Main_visible_image
|
||||
int i;
|
||||
for (i=0; i< Main_image_width*Main_image_height; i++)
|
||||
{
|
||||
layer = *(Main_backups->Pages->Image[4]+i);
|
||||
Main_visible_image.Image[i]=*(Main_backups->Pages->Image[layer]+i);
|
||||
}
|
||||
|
||||
// Copy it to the depth buffer
|
||||
memcpy(Main_visible_image_depth_buffer.Image,
|
||||
Main_backups->Pages->Image[4],
|
||||
Main_image_width*Main_image_height);
|
||||
|
||||
// Next
|
||||
layer= (1<<4)+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (layer=0; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
@ -218,6 +239,7 @@ void Redraw_layered_image(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// subsequent layer(s)
|
||||
for (; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
|
||||
10
src/struct.h
10
src/struct.h
@ -372,11 +372,11 @@ typedef struct
|
||||
byte Allow_multi_shortcuts; ///< Boolean, true if the same key combination can trigger multiple shortcuts.
|
||||
} T_Config;
|
||||
|
||||
// Structures utilisées pour les descriptions de pages et de liste de pages.
|
||||
// Lorsqu'on gérera les animations, il faudra aussi des listes de listes de
|
||||
// Structures utilisées pour les descriptions de pages et de liste de pages.
|
||||
// Lorsqu'on gèrera les animations, il faudra aussi des listes de listes de
|
||||
// pages.
|
||||
|
||||
// Ces structures sont manipulées à travers des fonctions de gestion du
|
||||
// Ces structures sont manipulées à travers des fonctions de gestion du
|
||||
// backup dans "graph.c".
|
||||
|
||||
/// This is the data for one step of Undo/Redo, for one image.
|
||||
@ -401,11 +401,11 @@ typedef struct T_Page
|
||||
byte Transparent_color; ///< Index of transparent color. 0 to 255.
|
||||
byte Nb_layers; ///< Number of layers
|
||||
#if __GNUC__ < 3
|
||||
byte * Image[0];
|
||||
// gcc2 doesn't suport [], but supports [0] which does the same thing.
|
||||
byte * Image[0]; ///< Pixel data for the (first layer of) image.
|
||||
#else
|
||||
byte * Image[]; ///< Pixel data for the (first layer of) image.
|
||||
#endif
|
||||
// Define as Image[0] if you have an old gcc which is not C99.
|
||||
// No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc.
|
||||
} T_Page;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user