Import the WIP CPC-Mode5 code from the sourcearchive

git-svn-id: svn://pulkomandy.tk/GrafX2/branches/cpcmode5@1718 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Adrien Destugues 2011-02-13 21:20:45 +00:00
parent b42bd0afad
commit 4e60f5ad74
18 changed files with 1031 additions and 154 deletions

View File

@ -152,9 +152,8 @@ else
RMDIR = rmdir
CP = cp
BIN = ../bin/grafx2
PLATFORMOBJ = $(OBJDIR)/haiku.o
COPT = -W -Wall -c -g `sdl-config --cflags` $(TTFCOPT) -I/boot/common/include
LOPT = `sdl-config --libs` -lSDL_image -lpng -ljpeg -lz $(TTFLOPT) -lfreetype -lbe
LOPT = `sdl-config --libs` -lSDL_image -lpng -ljpeg -lz $(TTFLOPT)
CC = gcc
OBJDIR = ../obj/haiku
ZIP = zip
@ -303,7 +302,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
@ -388,10 +387,6 @@ depend :
$(OBJDIR)/winres.o : gfx2.ico
echo "1 ICON \"gfx2.ico\"" | $(WINDRES) -o $(OBJDIR)/winres.o
# Compile the C++ file needed in Haiku to use the API
$(OBJDIR)/haiku.o : haiku.cpp
g++ -c haiku.cpp -o $(OBJDIR)/haiku.o
clean :
$(DELCOMMAND) $(OBJ)
$(DELCOMMAND) $(BIN)

View File

@ -125,14 +125,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 (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

@ -546,7 +546,7 @@ void Button_Colorize_mode(void)
switch(Colorize_current_mode)
{
case 0 :
Effect_function=Effect_interpolated_colorize;
Effect_function=Effect_layer_copy;
break;
case 1 :
Effect_function=Effect_additive_colorize;

View File

@ -37,7 +37,7 @@
#define BETA1 98 ///< Version number for gfx2.cfg (3/4)
#define BETA2 0 ///< Version number for gfx2.cfg (4/4)
#define MAX_VIDEO_MODES 100 ///< Maximum number of video modes Grafx2 can propose.
#define NB_SHORTCUTS 181 ///< Number of actions that can have a key combination associated to it.
#define NB_SHORTCUTS 183 ///< Number of actions that can have a key combination associated to it.
#define NB_ZOOM_FACTORS 15 ///< Number of zoom levels available in the magnifier.
#define MENU_WIDTH 254 ///< Width of the menu (not counting the palette)
#define MENU_HEIGHT 44 ///< Height of the menu.
@ -435,6 +435,8 @@ enum SPECIAL_ACTIONS
SPECIAL_LAYER7_TOGGLE,
SPECIAL_LAYER8_SELECT,
SPECIAL_LAYER8_TOGGLE,
SPECIAL_FORMAT_CHECKER,
SPECIAL_FORMAT_CHECKER_MENU,
NB_SPECIAL_SHORTCUTS ///< Number of special shortcuts
};

View File

@ -1084,6 +1084,10 @@ 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;
}
}
} // End of special keys

View File

@ -2853,6 +2853,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;
@ -2896,6 +2905,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;
@ -2909,9 +2922,48 @@ 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
byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
#ifndef NOLAYERS
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
@ -2923,13 +2975,15 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
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)
Pixel_preview(x,y,color);
#endif
}
#else
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color;
if (with_preview)
Pixel_preview(x,y,color);
#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

@ -31,8 +31,6 @@
#include <sys/mount.h>
#elif defined (__linux__)
#include <sys/vfs.h>
#elif defined(__HAIKU__)
#include "haiku.h"
#endif
#include "const.h"
@ -64,7 +62,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)
{
@ -672,8 +670,6 @@ void Button_Stats(void)
statfs(Main_current_directory,&disk_info);
mem_size=(qword) disk_info.f_bfree * (qword) disk_info.f_bsize;
}
#elif defined(__HAIKU__)
mem_size = haiku_get_free_space(Main_current_directory);
#else
// Free disk space is only for shows. Other platforms can display 0.
#warning "Missing code for your platform !!! Check and correct please :)"

View File

@ -312,6 +312,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

@ -1477,6 +1477,14 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
true,
SDLK_HOME|MOD_ALT, // Alt + Home
0},
{181,
"Format checker",
"Performs a format check on the",
"current image.",
"",
true,
0,
0},
};
word Ordering[NB_SHORTCUTS]=
@ -1662,4 +1670,6 @@ word Ordering[NB_SHORTCUTS]=
0x100+BUTTON_LAYER_UP,
0x100+BUTTON_LAYER_DOWN,
0x100+BUTTON_LAYER_MENU,
SPECIAL_FORMAT_CHECKER,
SPECIAL_FORMAT_CHECKER_MENU,
};

View File

@ -134,7 +134,7 @@ void Load_SDL_Image(T_IO_Context *);
// ENUM Name TestFunc LoadFunc SaveFunc PalOnly Comment Layers Ext Exts
T_Format File_formats[NB_KNOWN_FORMATS] = {
{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;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"},
{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__
@ -152,7 +152,7 @@ T_Format File_formats[NB_KNOWN_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_MISC,"misc.",NULL, NULL, NULL, 0, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"},
};
@ -430,8 +430,7 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
// On efface le commentaire précédent
Window_rectangle(45,70,32*8,8,MC_Light);
// Affichage du commentaire
if (Get_fileformat(format)->Comment)
Print_in_window(45,70,Main_comment,MC_Black,MC_Light);
Print_in_window(45,70,context->Comment,MC_Black,MC_Light);
// Calcul des données nécessaires à l'affichage de la preview:
if (ratio == PIXEL_WIDE &&

View File

@ -826,6 +826,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

@ -165,3 +165,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

@ -39,6 +39,7 @@
#include "sdlscreen.h"
#include "struct.h"
#include "windows.h"
#include "oldies.h"
//////////////////////////////////// PAL ////////////////////////////////////
//
@ -444,24 +445,24 @@ void Load_PKM(T_IO_Context * context)
// Trouver quels sont les octets de reconnaissance
void Find_recog(byte * recog1, byte * recog2)
{
dword Find_recon[256]; // Table d'utilisation de couleurs
dword color_usage[256]; // Table d'utilisation de couleurs
byte best; // Meilleure couleur pour recon (recon1 puis recon2)
dword NBest; // Nombre d'occurences de cette couleur
word index;
// On commence par compter l'utilisation de chaque couleurs
Count_used_colors(Find_recon);
Count_used_colors(color_usage);
// Ensuite recog1 devient celle la moins utilisée de celles-ci
*recog1=0;
best=1;
NBest=INT_MAX; // Une même couleur ne pourra jamais être utilisée 1M de fois.
for (index=1;index<=255;index++)
if (Find_recon[index]<NBest)
if (color_usage[index]<NBest)
{
best=index;
NBest=Find_recon[index];
NBest=color_usage[index];
}
*recog1=best;
@ -470,10 +471,10 @@ void Load_PKM(T_IO_Context * context)
best=0;
NBest=INT_MAX;
for (index=0;index<=255;index++)
if ( (Find_recon[index]<NBest) && (index!=*recog1) )
if ( (color_usage[index]<NBest) && (index!=*recog1) )
{
best=index;
NBest=Find_recon[index];
NBest=color_usage[index];
}
*recog2=best;
}
@ -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)
{
@ -1173,10 +1174,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);
@ -1185,7 +1186,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)
{
@ -2035,6 +2036,7 @@ void Save_NEO(T_IO_Context * context)
}
//////////////////////////////////// C64 ////////////////////////////////////
void Test_C64(T_IO_Context * context)
{
FILE* file;
@ -2050,14 +2052,15 @@ 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 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.
@ -2071,7 +2074,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;
@ -2079,8 +2082,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];
@ -2094,7 +2097,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;
@ -2102,9 +2105,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++)
{
@ -2120,16 +2123,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_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_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_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]={
@ -2150,118 +2250,194 @@ 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");
if (file)
{
File_error=0;
file_size = File_length_file(file);
File_error=0;
file_size = File_length_file(file);
switch (file_size)
// Check for known file sizes
switch (file_size)
{
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;
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 1000: // screen or color
hasLoadAddr=0;
loadFormat=F_screen;
break;
case 1002: // (screen or color) + loadaddr
hasLoadAddr=1;
loadFormat=F_screen;
break;
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;
}
if (context->Ratio == PIXEL_WIDE)
width=160;
// Write detailed format in comment
strcpy(context->Comment, c64_format_names[loadFormat]);
if (hasLoadAddr)
{
// get load address
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(context->Comment+strlen(context->Comment),", no addr");
}
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
if (file_size>9002)
width=160;
if (hasLoadAddr)
{
// get load address
Read_byte(file,&background);
Read_byte(file,&background);
sprintf(filename,"load at $%02x00",background);
}
else
{
sprintf(filename,"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
context->Width = width ;
context->Height = height;
context->Transparent_color=16;
Read_bytes(file,bitmap,8000);
if (file_size>8002)
Read_bytes(file,colors,1000);
else
if(loadFormat==F_fli)
{
for(i=0;i<1000;i++)
{
colors[i]=1;
}
Load_C64_fli(context,bitmap,screen_ram,color_ram,background);
}
if(width==160)
else
if(loadFormat==F_multi)
{
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;
@ -2290,17 +2466,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(char *); 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(char *); i++)
Window_dropdown_add_item(addr,i,address_label[i]);
@ -2337,10 +2513,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
{
@ -2374,7 +2550,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++)
{
@ -2416,7 +2592,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;
@ -2427,13 +2603,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;
@ -2483,9 +2659,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++)
{
@ -2529,10 +2705,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);
@ -2542,6 +2718,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];
@ -2551,12 +2776,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");
@ -2574,7 +2801,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);
}

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

@ -178,25 +178,47 @@ void Redraw_layered_image(void)
{
#ifndef NOLAYERS
// Re-construct the image with the visible layers
byte layer;
byte layer=0;
// First layer
for (layer=0; layer<Main_backups->Pages->Nb_layers; layer++)
if (Main_layers_visible & (1<<4))
{
if ((1<<layer) & Main_layers_visible)
// 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++)
{
// Copy it in Main_visible_image
memcpy(Main_visible_image.Image,
Main_backups->Pages->Image[layer],
Main_image_width*Main_image_height);
// Initialize the depth buffer
memset(Main_visible_image_depth_buffer.Image,
layer,
Main_image_width*Main_image_height);
// skip all other layers
layer++;
break;
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)
{
// Copy it in Main_visible_image
memcpy(Main_visible_image.Image,
Main_backups->Pages->Image[layer],
Main_image_width*Main_image_height);
// Initialize the depth buffer
memset(Main_visible_image_depth_buffer.Image,
layer,
Main_image_width*Main_image_height);
// skip all other layers
layer++;
break;
}
}
}
// subsequent layer(s)

View File

@ -323,11 +323,11 @@ typedef struct
byte Grid_XOR_color; ///< XOR value to apply for grid color.
} 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.
@ -350,11 +350,7 @@ typedef struct T_Page
byte Background_transparent; ///< Boolean, true if Layer 0 should have transparent pixels
byte Transparent_color; ///< Index of transparent color. 0 to 255.
byte Nb_layers; ///< Number of layers
#if __GNUC__ < 3
byte * Image[0];
#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;