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:
Adrien Destugues 2011-06-19 20:15:22 +00:00
commit e875597964
24 changed files with 1401 additions and 175 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)
{

View File

@ -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.
*/

View File

@ -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)
{

View File

@ -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
};

View File

@ -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();

View File

@ -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)
{

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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[] =
{

View File

@ -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,
};

View File

@ -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 ***/

View File

@ -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];
}
}

View File

@ -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);
// =================================================================

View File

@ -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)

View File

@ -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);

View File

@ -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
View 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
View 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);

View File

@ -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++)
{

View File

@ -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;