Add support for loading the C64 pixcen .GPX format
Pixcen is a C64 picture editor under MS Windows : http://hammarberg.github.io/pixcen/
This commit is contained in:
parent
653593ba66
commit
682e1a77ad
@ -141,6 +141,7 @@ enum FILE_FORMATS
|
|||||||
FORMAT_CEL, ///< Atari ST Cyber Paint Cell
|
FORMAT_CEL, ///< Atari ST Cyber Paint Cell
|
||||||
FORMAT_NEO, ///< Atari ST NeoChrome
|
FORMAT_NEO, ///< Atari ST NeoChrome
|
||||||
FORMAT_C64, ///< Several C64 formats : Koala, FLI, BML, etc.
|
FORMAT_C64, ///< Several C64 formats : Koala, FLI, BML, etc.
|
||||||
|
FORMAT_GPX, ///< pixcen C64 format : .gpx
|
||||||
FORMAT_KCF, ///< KiSS Color File
|
FORMAT_KCF, ///< KiSS Color File
|
||||||
FORMAT_PAL, ///< raw 6bit palette or Jasc Paint Shop Pro palette
|
FORMAT_PAL, ///< raw 6bit palette or Jasc Paint Shop Pro palette
|
||||||
FORMAT_GPL, ///< Gimp palette
|
FORMAT_GPL, ///< Gimp palette
|
||||||
|
|||||||
@ -111,6 +111,10 @@ void Test_C64(T_IO_Context *, FILE *);
|
|||||||
void Load_C64(T_IO_Context *);
|
void Load_C64(T_IO_Context *);
|
||||||
void Save_C64(T_IO_Context *);
|
void Save_C64(T_IO_Context *);
|
||||||
|
|
||||||
|
// -- GPX (pixcen C64)
|
||||||
|
void Test_GPX(T_IO_Context *, FILE *);
|
||||||
|
void Load_GPX(T_IO_Context *);
|
||||||
|
|
||||||
// -- SCR (Amstrad CPC)
|
// -- SCR (Amstrad CPC)
|
||||||
void Test_SCR(T_IO_Context *, FILE *);
|
void Test_SCR(T_IO_Context *, FILE *);
|
||||||
void Load_SCR(T_IO_Context *);
|
void Load_SCR(T_IO_Context *);
|
||||||
|
|||||||
@ -115,6 +115,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;cel;"
|
"gif;png;bmp;2bp;pcx;pkm;iff;lbm;ilbm;sham;ham;ham6;ham8;acbm;pic;anim;img;sci;scq;scf;scn;sco;cel;"
|
||||||
"pi1;pc1;pi2;pc2;pi3;pc3;neo;"
|
"pi1;pc1;pi2;pc2;pi3;pc3;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;"
|
||||||
|
"gpx;"
|
||||||
"cpc;scr;win;"
|
"cpc;scr;win;"
|
||||||
"hgr;dhgr;"
|
"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"},
|
||||||
@ -141,6 +142,7 @@ const T_Format File_formats[] = {
|
|||||||
{FORMAT_GPL, " gpl", Test_GPL, Load_GPL, Save_GPL, 1, 0, 0, "gpl", "gpl"},
|
{FORMAT_GPL, " gpl", Test_GPL, Load_GPL, Save_GPL, 1, 0, 0, "gpl", "gpl"},
|
||||||
{FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 0, 1, 1, "c64",
|
{FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 0, 1, 1, "c64",
|
||||||
"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"},
|
||||||
|
{FORMAT_GPX, " gpx", Test_GPX, Load_GPX, NULL, 0, 0, 0, "gpx", "gpx"},
|
||||||
{FORMAT_SCR, " cpc", Test_SCR, Load_SCR, Save_SCR, 0, 0, 0, "scr", "cpc;scr;win"},
|
{FORMAT_SCR, " cpc", Test_SCR, Load_SCR, Save_SCR, 0, 0, 0, "scr", "cpc;scr;win"},
|
||||||
{FORMAT_CM5, " cm5", Test_CM5, Load_CM5, Save_CM5, 0, 0, 1, "cm5", "cm5"},
|
{FORMAT_CM5, " cm5", Test_CM5, Load_CM5, Save_CM5, 0, 0, 1, "cm5", "cm5"},
|
||||||
{FORMAT_PPH, " pph", Test_PPH, Load_PPH, Save_PPH, 0, 0, 1, "pph", "pph"},
|
{FORMAT_PPH, " pph", Test_PPH, Load_PPH, Save_PPH, 0, 0, 1, "pph", "pph"},
|
||||||
|
|||||||
@ -38,6 +38,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
@ -4034,6 +4036,184 @@ void Save_C64(T_IO_Context * context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////// pixcen *.GPX ///////////////////////////
|
||||||
|
void Test_GPX(T_IO_Context * context, FILE * file)
|
||||||
|
{
|
||||||
|
byte header[2];
|
||||||
|
(void)context;
|
||||||
|
|
||||||
|
// check for a Zlib compressed stream
|
||||||
|
File_error = 1;
|
||||||
|
if (!Read_bytes(file, header, 2))
|
||||||
|
return;
|
||||||
|
if ((header[0] & 0x0f) != 8)
|
||||||
|
return;
|
||||||
|
if (((header[0] << 8) + header[1]) % 31)
|
||||||
|
return;
|
||||||
|
File_error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Load_GPX(T_IO_Context * context)
|
||||||
|
{
|
||||||
|
FILE * file;
|
||||||
|
unsigned long file_size;
|
||||||
|
byte * buffer;
|
||||||
|
|
||||||
|
File_error = 1;
|
||||||
|
file = Open_file_read(context);
|
||||||
|
if (file == NULL)
|
||||||
|
return;
|
||||||
|
file_size = File_length_file(file);
|
||||||
|
buffer = malloc(file_size);
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
GFX2_Log(GFX2_ERROR, "Failed to allocate %lu bytes.\n", file_size);
|
||||||
|
fclose(file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Read_bytes(file, buffer, file_size))
|
||||||
|
{
|
||||||
|
byte * gpx = NULL;
|
||||||
|
unsigned long gpx_size = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
free(gpx);
|
||||||
|
gpx_size += 65536;
|
||||||
|
gpx = malloc(gpx_size);
|
||||||
|
if (gpx == NULL)
|
||||||
|
{
|
||||||
|
GFX2_Log(GFX2_ERROR, "Failed to allocate %lu bytes\n", gpx_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
r = uncompress(gpx, &gpx_size, buffer, file_size);
|
||||||
|
if (r != Z_BUF_ERROR && r != Z_OK)
|
||||||
|
GFX2_Log(GFX2_ERROR, "uncompress() failed with error %d: %s\n", r, zError(r));
|
||||||
|
}
|
||||||
|
while (r == Z_BUF_ERROR); // there was not enough room in the output buffer
|
||||||
|
if (r == Z_OK)
|
||||||
|
{
|
||||||
|
byte * p;
|
||||||
|
dword version, mode;
|
||||||
|
/*
|
||||||
|
mode :
|
||||||
|
0 BITMAP,
|
||||||
|
1 MC_BITMAP,
|
||||||
|
2 SPRITE,
|
||||||
|
3 MC_SPRITE,
|
||||||
|
4 CHAR,
|
||||||
|
5 MC_CHAR,
|
||||||
|
6 UNUSED1,
|
||||||
|
7 UNUSED2,
|
||||||
|
8 UNRESTRICTED,
|
||||||
|
9 W_UNRESTRICTED
|
||||||
|
*/
|
||||||
|
GFX2_Log(GFX2_DEBUG, "inflated %lu bytes to %lu\n", file_size, gpx_size);
|
||||||
|
#define READU32LE(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
|
||||||
|
version = READU32LE(gpx);
|
||||||
|
mode = READU32LE(gpx+4);
|
||||||
|
GFX2_Log(GFX2_DEBUG, "gpx version %u mode %u\n", version, mode);
|
||||||
|
snprintf(context->Comment, COMMENT_SIZE, "pixcen file version %u mode %u", version, mode);
|
||||||
|
if (version >= 4)
|
||||||
|
{
|
||||||
|
dword count;
|
||||||
|
const char * key;
|
||||||
|
word value[256];
|
||||||
|
int xsize = -1;
|
||||||
|
int ysize = -1;
|
||||||
|
int mapsize = -1;
|
||||||
|
int screensize = -1;
|
||||||
|
int colorsize = -1;
|
||||||
|
int backbuffers = -1;
|
||||||
|
|
||||||
|
count = READU32LE(gpx+8);
|
||||||
|
p = gpx + 12;
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int int_value = 0;
|
||||||
|
|
||||||
|
key = (const char *)p;
|
||||||
|
while (*p++);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
value[i] = p[0] + (p[1] << 8);
|
||||||
|
p += 2;
|
||||||
|
if (value[i] == 0)
|
||||||
|
break;
|
||||||
|
int_value = int_value * 10 + (value[i] - '0');
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
GFX2_Log(GFX2_DEBUG, "%s=%d\n", key, int_value);
|
||||||
|
if (0 == strcmp(key, "xsize"))
|
||||||
|
xsize = int_value;
|
||||||
|
else if (0 == strcmp(key, "ysize"))
|
||||||
|
ysize = int_value;
|
||||||
|
else if (0 == strcmp(key, "mapsize"))
|
||||||
|
mapsize = int_value;
|
||||||
|
else if (0 == strcmp(key, "screensize"))
|
||||||
|
screensize = int_value;
|
||||||
|
else if (0 == strcmp(key, "colorsize"))
|
||||||
|
colorsize = int_value;
|
||||||
|
else if (0 == strcmp(key, "backbuffers"))
|
||||||
|
backbuffers = int_value;
|
||||||
|
}
|
||||||
|
//buffersize = 64 + (64 + mapsize + screensize + colorsize) * backbuffers;
|
||||||
|
p += 64; // 64 empty bytes ?
|
||||||
|
File_error = 0;
|
||||||
|
if (mode & 1)
|
||||||
|
context->Ratio = PIXEL_WIDE;
|
||||||
|
else
|
||||||
|
context->Ratio = PIXEL_SIMPLE;
|
||||||
|
Pre_load(context, xsize, ysize, file_size, FORMAT_GPX, context->Ratio, 4); // Do this as soon as you can
|
||||||
|
if (Config.Clear_palette)
|
||||||
|
memset(context->Palette,0, sizeof(T_Palette));
|
||||||
|
C64_set_palette(context->Palette);
|
||||||
|
context->Transparent_color=16;
|
||||||
|
|
||||||
|
//foreach backbuffer
|
||||||
|
if (backbuffers >= 1)
|
||||||
|
{
|
||||||
|
byte border, background;
|
||||||
|
//byte ext0, ext1, ext2;
|
||||||
|
byte * bitmap, * color, * screen;
|
||||||
|
|
||||||
|
//GFX2_LogHexDump(GFX2_DEBUG, "GPX ", p, 0, 64);
|
||||||
|
p += 47; // Extra bytes
|
||||||
|
//crippled = p;
|
||||||
|
p += 6;
|
||||||
|
//lock = p;
|
||||||
|
p += 6;
|
||||||
|
border = *p++;
|
||||||
|
background = *p++;
|
||||||
|
/*ext0 = *p++;
|
||||||
|
ext1 = *p++;
|
||||||
|
ext2 = *p++;*/
|
||||||
|
p += 3;
|
||||||
|
bitmap = p;
|
||||||
|
p += mapsize;
|
||||||
|
color = p;
|
||||||
|
p += colorsize;
|
||||||
|
screen = p;
|
||||||
|
p += screensize;
|
||||||
|
|
||||||
|
(void)border;
|
||||||
|
Load_C64_multi(context, bitmap, screen, color, background);
|
||||||
|
Set_image_mode(context, (mode & 1) ? IMAGE_MODE_C64MULTI : IMAGE_MODE_C64HIRES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GFX2_Log(GFX2_ERROR, "GPX file version %d unsupported\n", version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(gpx);
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for SCR file (Amstrad CPC)
|
* Test for SCR file (Amstrad CPC)
|
||||||
*
|
*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user