Loading of Apple II GS files
This commit is contained in:
parent
fa90c61d02
commit
39ee4d1eae
@ -82,6 +82,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\2gsformats.c" />
|
||||||
<ClCompile Include="..\..\src\6502.c">
|
<ClCompile Include="..\..\src\6502.c">
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CPU_6502_STATIC;CPU_6502_USE_LOCAL_HEADER;CPU_6502_DEPENDENCIES_H="6502types.h";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CPU_6502_STATIC;CPU_6502_USE_LOCAL_HEADER;CPU_6502_DEPENDENCIES_H="6502types.h";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CPU_6502_STATIC;CPU_6502_USE_LOCAL_HEADER;CPU_6502_DEPENDENCIES_H="6502types.h";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CPU_6502_STATIC;CPU_6502_USE_LOCAL_HEADER;CPU_6502_DEPENDENCIES_H="6502types.h";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
|||||||
@ -234,6 +234,9 @@
|
|||||||
<ClCompile Include="..\..\src\osdep.c">
|
<ClCompile Include="..\..\src\osdep.c">
|
||||||
<Filter>Fichiers sources</Filter>
|
<Filter>Fichiers sources</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\2gsformats.c">
|
||||||
|
<Filter>Fichiers sources</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\brush.h">
|
<ClInclude Include="..\..\src\brush.h">
|
||||||
|
|||||||
302
src/2gsformats.c
Normal file
302
src/2gsformats.c
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
/* vim:expandtab:ts=2 sw=2:
|
||||||
|
*/
|
||||||
|
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
||||||
|
|
||||||
|
Copyright owned by various GrafX2 authors, see COPYRIGHT.txt for details.
|
||||||
|
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
///@file 2gsformats.c
|
||||||
|
/// Formats for the Apple II GS
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "global.h"
|
||||||
|
#include "fileformats.h"
|
||||||
|
#include "loadsavefuncs.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "gfx2mem.h"
|
||||||
|
#include "gfx2log.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an Apple 2 GS picture file
|
||||||
|
*/
|
||||||
|
void Test_2GS(T_IO_Context * context, FILE * file)
|
||||||
|
{
|
||||||
|
unsigned long file_size;
|
||||||
|
dword chunksize;
|
||||||
|
byte header[5];
|
||||||
|
|
||||||
|
(void)context;
|
||||||
|
File_error = 1;
|
||||||
|
file_size = File_length_file(file);
|
||||||
|
if (!Read_dword_le(file, &chunksize))
|
||||||
|
return;
|
||||||
|
if (!Read_bytes(file, header, sizeof(header)))
|
||||||
|
return;
|
||||||
|
if (0 != memcmp(header, "\x04MAIN", 5))
|
||||||
|
return;
|
||||||
|
if (file_size < chunksize)
|
||||||
|
return;
|
||||||
|
File_error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a 16 entry Apple II GS palette from file
|
||||||
|
*/
|
||||||
|
static int Load_2GS_Palette(T_Components * palette, FILE * file)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
word palentry;
|
||||||
|
if (!Read_word_le(file, &palentry))
|
||||||
|
return 0;
|
||||||
|
palette[i].R = ((palentry >> 8) & 0x0f) * 0x11;
|
||||||
|
palette[i].G = ((palentry >> 4) & 0x0f) * 0x11;
|
||||||
|
palette[i].B = (palentry & 0x0f) * 0x11;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define COMPONENTS(x) linepal[x].R, linepal[x].G, linepal[x].B
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the (2 or 4) pixels for the byte.
|
||||||
|
*/
|
||||||
|
#define WRITE2GS_PIXELS \
|
||||||
|
if (multipalcount > 0) \
|
||||||
|
{ \
|
||||||
|
if (linemode & 0x80) \
|
||||||
|
{ \
|
||||||
|
Set_pixel_24b(context, x++, y, COMPONENTS(8 + (pixel >> 6))); \
|
||||||
|
Set_pixel_24b(context, x++, y, COMPONENTS(12 + ((pixel >> 4) & 3))); \
|
||||||
|
Set_pixel_24b(context, x++, y, COMPONENTS((pixel >> 2) & 3)); \
|
||||||
|
Set_pixel_24b(context, x++, y, COMPONENTS(4 + (pixel & 3))); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
Set_pixel_24b(context, x++, y, COMPONENTS(pixel >> 4)); \
|
||||||
|
Set_pixel_24b(context, x++, y, COMPONENTS(pixel & 15)); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
if (linemode & 0x80) \
|
||||||
|
{ \
|
||||||
|
Set_pixel(context, x++, y, (linemode << 4) | 8 | (pixel >> 6)); \
|
||||||
|
Set_pixel(context, x++, y, (linemode << 4) | 12 | ((pixel >> 4) & 3)); \
|
||||||
|
Set_pixel(context, x++, y, (linemode << 4) | ((pixel >> 2) & 3)); \
|
||||||
|
Set_pixel(context, x++, y, (linemode << 4) | 4 | (pixel & 3)); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
Set_pixel(context, x++, y, (linemode << 4) | (pixel >> 4)); \
|
||||||
|
Set_pixel(context, x++, y, (linemode << 4) | (pixel & 15)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
void Load_2GS(T_IO_Context * context)
|
||||||
|
{
|
||||||
|
FILE * file;
|
||||||
|
unsigned long file_size;
|
||||||
|
dword chunksize;
|
||||||
|
byte header[5];
|
||||||
|
word mode;
|
||||||
|
word width;
|
||||||
|
word height;
|
||||||
|
word palcount;
|
||||||
|
word palindex;
|
||||||
|
long lineoffset;
|
||||||
|
long dataoffset;
|
||||||
|
word y;
|
||||||
|
byte bpp = 2;
|
||||||
|
word multipalcount = 0;
|
||||||
|
long multipaloffset = -1;
|
||||||
|
long offset;
|
||||||
|
|
||||||
|
File_error = 1;
|
||||||
|
file = Open_file_read(context);
|
||||||
|
if (file == NULL)
|
||||||
|
return;
|
||||||
|
file_size = File_length_file(file);
|
||||||
|
if (!Read_dword_le(file, &chunksize))
|
||||||
|
return;
|
||||||
|
if (!Read_bytes(file, header, sizeof(header)))
|
||||||
|
goto error;
|
||||||
|
if (0 != memcmp(header, "\x04MAIN", 5))
|
||||||
|
goto error;
|
||||||
|
if (!Read_word_le(file, &mode) || !Read_word_le(file, &width) || !Read_word_le(file, &palcount))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (Config.Clear_palette)
|
||||||
|
memset(context->Palette, 0, sizeof(T_Palette));
|
||||||
|
for (palindex = 0; palindex < palcount; palindex++)
|
||||||
|
{
|
||||||
|
if (!Load_2GS_Palette(context->Palette + (palindex * 16), file))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!Read_word_le(file, &height))
|
||||||
|
goto error;
|
||||||
|
lineoffset = ftell(file);
|
||||||
|
dataoffset = lineoffset + 4 * (long)height;
|
||||||
|
GFX2_Log(GFX2_DEBUG, " mode %02x %ux%u %u palettes\n", mode, (unsigned)width, (unsigned)height, (unsigned)palcount);
|
||||||
|
|
||||||
|
// read other chunks before decoding the picture
|
||||||
|
GFX2_Log(GFX2_DEBUG, "file_size : %06lx, chunksize : %06lx, current offset : %06lx\n", file_size, chunksize, dataoffset);
|
||||||
|
offset = chunksize;
|
||||||
|
while (offset < (long)file_size)
|
||||||
|
{
|
||||||
|
char * p;
|
||||||
|
byte c;
|
||||||
|
fseek(file, offset, SEEK_SET);
|
||||||
|
if (!Read_dword_le(file, &chunksize) || !Read_byte(file, &c))
|
||||||
|
goto error;
|
||||||
|
p = GFX2_malloc(c + 1);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
fread(p, 1, c, file);
|
||||||
|
p[c] = '\0';
|
||||||
|
GFX2_Log(GFX2_DEBUG, "%06lx: %04x %s\n", offset, chunksize, p);
|
||||||
|
if (c == 4 && 0 == memcmp(p, "NOTE", 4))
|
||||||
|
{
|
||||||
|
word len;
|
||||||
|
if (Read_word_le(file, &len))
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
p = GFX2_malloc(len + 1);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
fread(p, 1, len, file);
|
||||||
|
p[len] = '\0';
|
||||||
|
GFX2_Log(GFX2_DEBUG, "%s\n", p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 12 && 0 == memcmp(p, "SuperConvert", 12))
|
||||||
|
{
|
||||||
|
dword len = chunksize - 4 - 13;
|
||||||
|
free(p);
|
||||||
|
p = GFX2_malloc(len);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
fread(p, 1, len, file);
|
||||||
|
GFX2_LogHexDump(GFX2_DEBUG, "", p, 0 /*offset + 4 + 13*/, (long)len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 8 && 0 == memcmp(p, "MULTIPAL", 8))
|
||||||
|
{
|
||||||
|
if (Read_word_le(file, &multipalcount))
|
||||||
|
{
|
||||||
|
// all palettes are there...
|
||||||
|
multipaloffset = ftell(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
offset += chunksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multipalcount > 0)
|
||||||
|
{
|
||||||
|
bpp = 12;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((1 << bpp) < ((mode & 0x80) ? 4 : 16) * palcount)
|
||||||
|
bpp++;
|
||||||
|
}
|
||||||
|
File_error = 0;
|
||||||
|
Pre_load(context, width, height, file_size, FORMAT_2GS, (mode & 0x80) ? PIXEL_TALL : PIXEL_SIMPLE, bpp);
|
||||||
|
if (File_error)
|
||||||
|
goto error;
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
word linebytes;
|
||||||
|
byte linemode;
|
||||||
|
word x;
|
||||||
|
T_Components linepal[16];
|
||||||
|
if (multipalcount > y)
|
||||||
|
{
|
||||||
|
fseek(file, multipaloffset + 32 * y, SEEK_SET);
|
||||||
|
if (!Load_2GS_Palette(linepal, file))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
fseek(file, lineoffset, SEEK_SET);
|
||||||
|
if (!Read_word_le(file, &linebytes) || !Read_byte(file, &linemode))
|
||||||
|
goto error;
|
||||||
|
//GFX2_Log(GFX2_DEBUG, "Line #%03u mode/pal=%02x %u bytes\n", (unsigned)y, linemode, (unsigned)linebytes);
|
||||||
|
lineoffset += 4;
|
||||||
|
fseek(file, dataoffset, SEEK_SET);
|
||||||
|
if (multipalcount > 0)
|
||||||
|
{
|
||||||
|
linemode = 0;
|
||||||
|
}
|
||||||
|
for (x = 0; x < width; )
|
||||||
|
{
|
||||||
|
byte code, pixel;
|
||||||
|
unsigned count;
|
||||||
|
if (!Read_byte(file, &code))
|
||||||
|
goto error;
|
||||||
|
count = (code & 0x3f) + 1;
|
||||||
|
switch (code >> 6)
|
||||||
|
{
|
||||||
|
case 0: // unpacked
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
if (!Read_byte(file, &pixel))
|
||||||
|
goto error;
|
||||||
|
WRITE2GS_PIXELS
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // byte packed x 4
|
||||||
|
count <<= 2;
|
||||||
|
case 1: // byte packed
|
||||||
|
if (!Read_byte(file, &pixel))
|
||||||
|
goto error;
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
WRITE2GS_PIXELS
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // dword packed
|
||||||
|
{
|
||||||
|
byte pixels[4];
|
||||||
|
if (!Read_bytes(file, pixels, 4))
|
||||||
|
goto error;
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
pixel = pixels[i];
|
||||||
|
WRITE2GS_PIXELS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataoffset += linebytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
File_error = 1;
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
@ -819,6 +819,7 @@ OBJS = main.o init.o graph.o $(APIOBJ) misc.o osdep.o special.o \
|
|||||||
loadsave.o loadsavefuncs.o \
|
loadsave.o loadsavefuncs.o \
|
||||||
pngformat.o motoformats.o stformats.o c64formats.o cpcformats.o \
|
pngformat.o motoformats.o stformats.o c64formats.o cpcformats.o \
|
||||||
ifformat.o msxformats.o packbits.o giformat.o \
|
ifformat.o msxformats.o packbits.o giformat.o \
|
||||||
|
2gsformats.o \
|
||||||
fileformats.o miscfileformats.o libraw2crtc.o \
|
fileformats.o miscfileformats.o libraw2crtc.o \
|
||||||
brush_ops.o buttons_effects.o layers.o \
|
brush_ops.o buttons_effects.o layers.o \
|
||||||
oldies.o tiles.o colorred.o unicode.o gfx2surface.o \
|
oldies.o tiles.o colorred.o unicode.o gfx2surface.o \
|
||||||
|
|||||||
@ -136,6 +136,7 @@ enum FILE_FORMATS
|
|||||||
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_HGR, ///< Apple II HGR and DHGR
|
||||||
|
FORMAT_2GS, ///< Apple II GS format
|
||||||
FORMAT_TIFF, ///< Tagged Image File Format
|
FORMAT_TIFF, ///< Tagged Image File Format
|
||||||
FORMAT_GRB, ///< HP-48 Grob
|
FORMAT_GRB, ///< HP-48 Grob
|
||||||
FORMAT_MSX, ///< MSX formats
|
FORMAT_MSX, ///< MSX formats
|
||||||
|
|||||||
@ -207,5 +207,10 @@ void Test_MSX(T_IO_Context *, FILE *);
|
|||||||
void Load_MSX(T_IO_Context *);
|
void Load_MSX(T_IO_Context *);
|
||||||
void Save_MSX(T_IO_Context *);
|
void Save_MSX(T_IO_Context *);
|
||||||
|
|
||||||
|
// -- Apple II GS -----------------------------------------------------------
|
||||||
|
void Test_2GS(T_IO_Context *, FILE *);
|
||||||
|
void Load_2GS(T_IO_Context *);
|
||||||
|
void Save_2GS(T_IO_Context *);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -114,6 +114,7 @@ const T_Format File_formats[] = {
|
|||||||
"gpx;"
|
"gpx;"
|
||||||
"cpc;scr;win;pph;cm5;go1;sgx;"
|
"cpc;scr;win;pph;cm5;go1;sgx;"
|
||||||
"hgr;dhgr;"
|
"hgr;dhgr;"
|
||||||
|
"shr;gs;iigs;32k;"
|
||||||
"grb;grob;"
|
"grb;grob;"
|
||||||
"sc2;"
|
"sc2;"
|
||||||
"tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;info;flc;bin;map"},
|
"tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;info;flc;bin;map"},
|
||||||
@ -156,6 +157,7 @@ const T_Format File_formats[] = {
|
|||||||
{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_MSX, " msx", Test_MSX, Load_MSX, Save_MSX, 0, 0, 0, "sc2", "sc2"},
|
{FORMAT_MSX, " msx", Test_MSX, Load_MSX, Save_MSX, 0, 0, 0, "sc2", "sc2"},
|
||||||
{FORMAT_HGR, " hgr", Test_HGR, Load_HGR, Save_HGR, 0, 0, 1, "hgr", "hgr;dhgr;bin"},
|
{FORMAT_HGR, " hgr", Test_HGR, Load_HGR, Save_HGR, 0, 0, 1, "hgr", "hgr;dhgr;bin"},
|
||||||
|
{FORMAT_2GS, " 2gs", Test_2GS, Load_2GS, NULL, 0, 0, 0, "shr", "shr;gs;iigs;32k"},
|
||||||
#ifndef __no_tifflib__
|
#ifndef __no_tifflib__
|
||||||
{FORMAT_TIFF," tiff",Test_TIFF,Load_TIFF,Save_TIFF,0, 1, 1, "tif", "tif;tiff"},
|
{FORMAT_TIFF," tiff",Test_TIFF,Load_TIFF,Save_TIFF,0, 1, 1, "tif", "tif;tiff"},
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user