Support for saving SymbOS .SGX graphics files
This commit is contained in:
parent
713fd9ff71
commit
9ed89cc860
125
src/cpcformats.c
125
src/cpcformats.c
@ -30,9 +30,14 @@
|
|||||||
#include "loadsavefuncs.h"
|
#include "loadsavefuncs.h"
|
||||||
#include "libraw2crtc.h"
|
#include "libraw2crtc.h"
|
||||||
#include "oldies.h"
|
#include "oldies.h"
|
||||||
|
#include "windows.h"
|
||||||
|
#include "misc.h"
|
||||||
#include "gfx2mem.h"
|
#include "gfx2mem.h"
|
||||||
#include "gfx2log.h"
|
#include "gfx2log.h"
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
|
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
@ -275,6 +280,126 @@ void Load_SGX(T_IO_Context * context)
|
|||||||
fclose(data.file);
|
fclose(data.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write SGX file format as specified here :
|
||||||
|
* http://www.cpcwiki.eu/index.php/Format:SGX_(SymbOS_graphic_files)
|
||||||
|
*
|
||||||
|
* We are using only simple chunks for 4 colors pictures.
|
||||||
|
* Chunk dimentions are limited to the ones of simple chunks (252x255),
|
||||||
|
* we could go up to 508x65535 with extended chunks.
|
||||||
|
*
|
||||||
|
* @return 0 for error
|
||||||
|
*/
|
||||||
|
static int Save_SGX_Sub(T_IO_Context * context, FILE * file, word n_colors)
|
||||||
|
{
|
||||||
|
word posy = 0;
|
||||||
|
|
||||||
|
while (posy < context->Height)
|
||||||
|
{
|
||||||
|
word posx = 0;
|
||||||
|
word height = MIN(context->Height - posy, 255);
|
||||||
|
if (posy != 0)
|
||||||
|
{
|
||||||
|
// Write Line Feed
|
||||||
|
if (!Write_byte(file, 255)
|
||||||
|
|| !Write_byte(file, 255) || !Write_byte(file, 255))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (posx < context->Width)
|
||||||
|
{
|
||||||
|
word width = MIN(context->Width - posx, 252);
|
||||||
|
GFX2_Log(GFX2_DEBUG, "Save_SGX : (%hu,%hu) %hux%hu %huc\n",
|
||||||
|
posx, posy, width, height, n_colors);
|
||||||
|
if (n_colors == 4)
|
||||||
|
{
|
||||||
|
word y;
|
||||||
|
byte byte_width = (width + 3) >> 2;
|
||||||
|
if (!Write_byte(file, byte_width)
|
||||||
|
|| !Write_byte(file, (byte)width) || !Write_byte(file, (byte)height))
|
||||||
|
return 0;
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
byte i;
|
||||||
|
word x;
|
||||||
|
for (i = 0, x = 0; i < byte_width; i++)
|
||||||
|
{
|
||||||
|
byte b = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
byte c = Get_pixel(context, posx + x++, posy + y);
|
||||||
|
b <<= 1;
|
||||||
|
b |= (c & 1) << 4;
|
||||||
|
b |= (c & 2) >> 1;
|
||||||
|
} while (x & 3);
|
||||||
|
if (!Write_byte(file, b))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
word y;
|
||||||
|
word byte_width = (width + 1) >> 1;
|
||||||
|
if (!Write_byte(file, 64) || !Write_byte(file, 5)
|
||||||
|
|| !Write_word_le(file, byte_width) || !Write_word_le(file, width) || !Write_word_le(file, height))
|
||||||
|
return 0;
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
word i, x;
|
||||||
|
for (i = 0, x = 0; i < byte_width; i++)
|
||||||
|
{
|
||||||
|
byte b = Get_pixel(context, posx + x++, posy + y) << 4;
|
||||||
|
b |= Get_pixel(context, posx + x++, posy + y) & 0x0f;
|
||||||
|
if (!Write_byte(file, b))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
posx += width;
|
||||||
|
}
|
||||||
|
posy += height;
|
||||||
|
}
|
||||||
|
// Write EOF marker
|
||||||
|
for (posy = 0; posy < 3; posy++)
|
||||||
|
Write_byte(file, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Save_SGX(T_IO_Context * context)
|
||||||
|
{
|
||||||
|
FILE * file;
|
||||||
|
dword color_usage[256];
|
||||||
|
word n_colors;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
File_error = 1;
|
||||||
|
n_colors = Count_used_colors(color_usage);
|
||||||
|
for (i = 16; i < 256; i++)
|
||||||
|
{
|
||||||
|
if (color_usage[i] != 0)
|
||||||
|
{
|
||||||
|
Warning_message("SGX format is limited to 16 colors");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 4 colors mode if sufficient, otherwise 16 colors
|
||||||
|
n_colors = 4;
|
||||||
|
for (i = 4; i < 16; i++)
|
||||||
|
{
|
||||||
|
if (color_usage[i] != 0)
|
||||||
|
{
|
||||||
|
n_colors = 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file = Open_file_write(context);
|
||||||
|
if (file == NULL)
|
||||||
|
return;
|
||||||
|
if (Save_SGX_Sub(context, file, n_colors))
|
||||||
|
File_error = 0;
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for SCR file (Amstrad CPC)
|
* Test for SCR file (Amstrad CPC)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -151,6 +151,7 @@ void Save_GOS(T_IO_Context *);
|
|||||||
// -- SGX (SymbOS)
|
// -- SGX (SymbOS)
|
||||||
void Test_SGX(T_IO_Context *, FILE *);
|
void Test_SGX(T_IO_Context *, FILE *);
|
||||||
void Load_SGX(T_IO_Context *);
|
void Load_SGX(T_IO_Context *);
|
||||||
|
void Save_SGX(T_IO_Context *);
|
||||||
|
|
||||||
// -- XPM (X PixMap)
|
// -- XPM (X PixMap)
|
||||||
// Loading is done through SDL_Image
|
// Loading is done through SDL_Image
|
||||||
|
|||||||
@ -148,7 +148,7 @@ const T_Format File_formats[] = {
|
|||||||
{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"},
|
||||||
{FORMAT_GOS, " go1", Test_GOS, Load_GOS, Save_GOS, 0, 0, 0, "go1", "go1"},
|
{FORMAT_GOS, " go1", Test_GOS, Load_GOS, Save_GOS, 0, 0, 0, "go1", "go1"},
|
||||||
{FORMAT_SGX, " sgx", Test_SGX, Load_SGX, NULL, 0, 0, 1, "sgx", "sgx"},
|
{FORMAT_SGX, " sgx", Test_SGX, Load_SGX, Save_SGX, 0, 0, 1, "sgx", "sgx"},
|
||||||
{FORMAT_XPM, " xpm", NULL, NULL, Save_XPM, 0, 0, 0, "xpm", "xpm"},
|
{FORMAT_XPM, " xpm", NULL, NULL, Save_XPM, 0, 0, 0, "xpm", "xpm"},
|
||||||
{FORMAT_ICO, " ico", Test_ICO, Load_ICO, Save_ICO, 0, 0, 0, "ico", "ico;ic2;cur"},
|
{FORMAT_ICO, " ico", Test_ICO, Load_ICO, Save_ICO, 0, 0, 0, "ico", "ico;ic2;cur"},
|
||||||
{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"},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user