Apple II HGR & DHGR Load/Save

This commit is contained in:
Thomas Bernard 2018-12-01 17:39:27 +01:00 committed by Adrien Destugues
parent f38b335b80
commit 1bffaacead
6 changed files with 310 additions and 0 deletions

View File

@ -148,6 +148,7 @@ enum FILE_FORMATS
FORMAT_INFO, ///< Amiga OS icons FORMAT_INFO, ///< Amiga OS icons
FORMAT_FLI, ///< Autodesk Animator FLI/FLC FORMAT_FLI, ///< Autodesk Animator FLI/FLC
FORMAT_MOTO, ///< Thomson MO/TO computers pictures FORMAT_MOTO, ///< Thomson MO/TO computers pictures
FORMAT_HGR, ///< Apple II HGR and DHGR
FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image
}; };

View File

@ -155,5 +155,10 @@ void Test_MOTO(T_IO_Context *, FILE *);
void Load_MOTO(T_IO_Context *); void Load_MOTO(T_IO_Context *);
void Save_MOTO(T_IO_Context *); void Save_MOTO(T_IO_Context *);
// -- Apple II HGR and DHGR pictures ----------------------------------------
void Test_HGR(T_IO_Context *, FILE *);
void Load_HGR(T_IO_Context *);
void Save_HGR(T_IO_Context *);
/// @} /// @}
#endif #endif

View File

@ -91,6 +91,7 @@ const T_Format File_formats[] = {
"gif;png;bmp;2bp;pcx;pkm;iff;lbm;ilbm;sham;ham;ham6;ham8;acbm;pic;anim;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;" "gif;png;bmp;2bp;pcx;pkm;iff;lbm;ilbm;sham;ham;ham6;ham8;acbm;pic;anim;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;"
"c64;p64;a64;pi;rp;aas;art;dd;iph;ipt;hpc;ocp;koa;koala;fli;bml;cdu;prg;pmg;rpm;" "c64;p64;a64;pi;rp;aas;art;dd;iph;ipt;hpc;ocp;koa;koala;fli;bml;cdu;prg;pmg;rpm;"
"cpc;scr;win;" "cpc;scr;win;"
"hgr;dhgr;"
"tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;cm5;pph;info;flc;bin;map"}, "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;cm5;pph;info;flc;bin;map"},
{FORMAT_ALL_PALETTES, "(pal)", NULL, NULL, NULL, 1, 0, 0, "", "kcf;pal;gpl"}, {FORMAT_ALL_PALETTES, "(pal)", NULL, NULL, NULL, 1, 0, 0, "", "kcf;pal;gpl"},
{FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"}, {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"},
@ -123,6 +124,7 @@ const T_Format File_formats[] = {
{FORMAT_INFO," info",Test_INFO,Load_INFO,NULL, 0, 0, 0, "info", "info"}, {FORMAT_INFO," info",Test_INFO,Load_INFO,NULL, 0, 0, 0, "info", "info"},
{FORMAT_FLI, " flc", Test_FLI, Load_FLI, NULL, 0, 0, 0, "flc", "flc;fli;dat"}, {FORMAT_FLI, " flc", Test_FLI, Load_FLI, NULL, 0, 0, 0, "flc", "flc;fli;dat"},
{FORMAT_MOTO," moto",Test_MOTO,Load_MOTO,Save_MOTO,0, 1, 0, "bin", "bin;map"}, {FORMAT_MOTO," moto",Test_MOTO,Load_MOTO,Save_MOTO,0, 1, 0, "bin", "bin;map"},
{FORMAT_HGR, " hgr", Test_HGR, Load_HGR, Save_HGR, 0, 0, 1, "hgr", "hgr;dhgr;bin"},
{FORMAT_MISC,"misc.",NULL, NULL, NULL, 0, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff"}, {FORMAT_MISC,"misc.",NULL, NULL, NULL, 0, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff"},
}; };

View File

@ -6671,3 +6671,240 @@ error:
fclose(file); fclose(file);
File_error = 1; File_error = 1;
} }
/////////////////////////////// Apple II Files //////////////////////////////
/**
* Test for an Apple II HGR or DHGR raw file
*/
void Test_HGR(T_IO_Context * context, FILE * file)
{
long file_size;
(void)context;
File_error = 1;
file_size = File_length_file(file);
if (file_size == 8192) // HGR
File_error = 0;
else if(file_size == 16384) // DHGR
File_error = 0;
}
/**
* Load HGR (280x192) or DHGR (560x192) Apple II pictures
*
* Creates 2 layers :
* 1. Monochrome
* 2. Color
*/
void Load_HGR(T_IO_Context * context)
{
unsigned long file_size;
FILE * file;
byte * vram[2];
int bank;
int x, y;
int is_dhgr = 0;
file = Open_file_read(context);
if (file == NULL)
{
File_error = 1;
return;
}
file_size = File_length_file(file);
if (file_size == 16384)
is_dhgr = 1;
vram[0] = malloc(8192);
Read_bytes(file, vram[0], 8192);
if (is_dhgr)
{
vram[1] = malloc(8192);
Read_bytes(file, vram[1], 8192);
}
else
vram[1] = NULL;
fclose(file);
if (Config.Clear_palette)
memset(context->Palette,0,sizeof(T_Palette));
if (is_dhgr)
{
DHGR_set_palette(context->Palette);
Pre_load(context, 560, 192, file_size, FORMAT_HGR, PIXEL_TALL, 4);
}
else
{
HGR_set_palette(context->Palette);
Pre_load(context, 280, 192, file_size, FORMAT_HGR, PIXEL_SIMPLE, 2);
}
for (y = 0; y < 192; y++)
{
byte palette = 0, color = 0;
byte previous_palette = 0; // palette for the previous pixel pair
int column, i;
int offset = ((y & 7) << 10) + ((y & 070) << 4) + ((y >> 6) * 40);
x = 0;
for (column = 0; column < 40; column++)
for (bank = 0; bank <= is_dhgr; bank++)
{
byte b = vram[bank][offset+column];
if (!is_dhgr)
palette = (b & 0x80) ? 4 : 0;
else
palette = (b & 0x80) ? 0 : 16;
for (i = 0; i < 7; i++)
{
if (context->Type == CONTEXT_MAIN_IMAGE)
{
// monochrome
Set_loading_layer(context, 0);
Set_pixel(context, x, y, ((b & 1) * (is_dhgr ? 15 : 3)) + palette);
Set_loading_layer(context, 1);
}
// color
color = (color << 1) | (b & 1);
if (is_dhgr)
{
if ((x & 3) == 0)
previous_palette = palette; // what is important is the value when the 1st bit was read...
/// emulate "chat mauve" DHGR mixed mode.
/// see http://boutillon.free.fr/Underground/Anim_Et_Graph/Extasie_Chat_Mauve_Reloaded/Extasie_Chat_Mauve_Reloaded.html
if (previous_palette) // BW
Set_pixel(context, x, y, ((b & 1) * 15) + palette);
else if ((x & 3) == 3)
{
Set_pixel(context, x - 3, y, (color & 15) + palette);
Set_pixel(context, x - 2, y, (color & 15) + palette);
Set_pixel(context, x - 1, y, (color & 15) + palette);
Set_pixel(context, x, y, (color & 15) + palette);
}
}
else
{
if (x & 1)
{
if ((color & 6) == 6) // 2 bits to 1 => force White
{
Set_pixel(context, x - 2, y, 3 + previous_palette);
Set_pixel(context, x - 1, y, 3 + palette);
}
else
Set_pixel(context, x - 1, y, (color & 3) + palette);
Set_pixel(context, x, y, (color & 3) + palette);
previous_palette = palette;
}
}
b >>= 1;
x++;
}
}
}
// show hidden data in HOLES
for (y = 0; y < 64; y++)
for (bank = 0; bank < 1; bank++)
{
byte b = 0;
for (x = 0; x < 8; x++)
b |= vram[bank][x + (y << 7) + 120];
if (b != 0)
GFX2_LogHexDump(GFX2_DEBUG, bank ? "AUX " : "MAIN", vram[bank], (y << 7) + 120, 8);
}
free(vram[0]);
free(vram[1]);
File_error = 0;
}
/**
* Save HGR (280x192) or DHGR (560x192) Apple II pictures
*
* The data saved is the "monochrome" data from layer 1
*/
void Save_HGR(T_IO_Context * context)
{
FILE * file;
byte * vram[2];
int bank;
int x, y;
int is_dhgr = 0;
File_error = 1;
if (context->Height != 192 || (context->Width != 280 && context->Width != 560))
{
Warning_message("Picture must be 280x192 (HGR) or 560x192 (DHGR)");
return;
}
if (context->Width == 560)
is_dhgr = 1;
file = Open_file_write(context);
if (file == NULL)
return;
vram[0] = calloc(8192, 1);
if (vram[0] == NULL)
{
fclose(file);
return;
}
if (is_dhgr)
{
vram[1] = calloc(8192, 1);
if (vram[1] == NULL)
{
free(vram[0]);
fclose(file);
return;
}
}
else
vram[1] = NULL;
Set_saving_layer(context, 0); // "monochrome" layer
for (y = 0; y < 192; y++)
{
int i, column = 0;
int offset = ((y & 7) << 10) + ((y & 070) << 4) + ((y >> 6) * 40);
x = 0;
bank = 0;
while (x < context->Width)
{
byte b;
if (is_dhgr)
b = (Get_pixel(context, x, y) & 16) ? 0 : 0x80;
else
b = (Get_pixel(context, x, y) & 4) ? 0x80 : 0;
for (i = 0; i < 7; i++)
{
b = b | ((Get_pixel(context, x++, y) & 1) << i);
}
vram[bank][offset + column] = b;
if (is_dhgr)
{
if (++bank > 1)
{
bank = 0;
column++;
}
}
else
column++;
}
}
if (Write_bytes(file, vram[0], 8192))
{
if (is_dhgr)
{
if (Write_bytes(file, vram[1], 8192))
File_error = 0;
}
else
File_error = 0;
}
free(vram[0]);
free(vram[1]);
fclose(file);
}

View File

@ -2,6 +2,7 @@
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2018 Thomas Bernard
Copyright 2008 Yves Rizoud Copyright 2008 Yves Rizoud
Copyright 2008 Franck Charlet Copyright 2008 Franck Charlet
Copyright 2007 Adrien Destugues Copyright 2007 Adrien Destugues
@ -748,3 +749,48 @@ void MOTO_set_TO7_palette(T_Components * palette)
palette[17].G = 127; palette[17].G = 127;
palette[17].B = 127; palette[17].B = 127;
} }
void HGR_set_palette(T_Components * palette)
{
static const T_Components hgr_palette[] = {
{ 0, 0, 0 }, // black
{ 0, 255, 0 }, // green
{ 255, 0, 255 }, // purple
{ 255, 255, 255 }, // white
{ 0, 0, 0 }, // black
{ 255, 80, 0 }, // orange
{ 0, 175, 255 }, // blue
{ 255, 255, 255 } // white
};
memcpy(palette, hgr_palette, sizeof(hgr_palette));
}
void DHGR_set_palette(T_Components * palette)
{
// Color Palette from the JACE emulator
static const T_Components dhgr_palette[] = {
{0,0,0}, /* 0 black */
{177,0,93}, /* 1 red */
{94,86,0}, /* 8 brown */
{255,86,0}, /* 9 orange */
{0,127,34}, /* 4 dk green */
{127,127,127},/* 5 gray */
{44,213,0}, /* 12 lt green */
{222,213,0}, /* 13 yellow */
{32,41,255}, /* 2 dk blue */
{210,41,255}, /* 3 purple */
{127,127,127},/* 10 grey */
{255,127,220},/* 11 pink */
{0,168,255}, /* 6 med blue */
{160,168,255},/* 7 lt blue */
{77,255,161}, /* 14 aqua */
{255,255,255} /* 15 white */
};
memcpy(palette, dhgr_palette, sizeof(dhgr_palette));
palette[16].R = 0;
palette[16].G = 0;
palette[16].B = 0;
palette[31].R = 255;
palette[31].G = 255;
palette[31].B = 255;
}

View File

@ -2,6 +2,7 @@
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2018 Thomas Bernard
Copyright 2008 Adrien Destugues Copyright 2008 Adrien Destugues
Grafx2 is free software; you can redistribute it and/or Grafx2 is free software; you can redistribute it and/or
@ -224,3 +225,21 @@ void MOTO_set_MO5_palette(T_Components * palette);
void MOTO_set_TO7_palette(T_Components * palette); void MOTO_set_TO7_palette(T_Components * palette);
/** @}*/ /** @}*/
/** @defgroup apple2 Apple II
*
* HGR and DHGR modes
* @{
*/
/**
* Set the 6 color Apple II HGR palette
*/
void HGR_set_palette(T_Components * palette);
/**
* Set the 16 color Apple II DHGR palette
*/
void DHGR_set_palette(T_Components * palette);
/** @}*/