Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TGA support and GPL palette export #94

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
26 changes: 26 additions & 0 deletions src/Demo/Graphics/GPLPalette.ZC
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
U0 PaletteExportGPL(U8* name="Palette", CBGR24 *pal=NULL) {
I64 i;
U8 *filename;
CDoc *out = DocNew;
if (!pal)
{
pal = MAlloc(sizeof(CBGR24) * COLORS_NUM);
GrPaletteGet(pal);
}

filename = ExtDefault(name, "gpl");
StrCopy(out->filename.name, filename);
Free(filename);

out->flags |= DOCF_PLAIN_TEXT | DOCF_NO_CURSOR;

DocPrint(out, "GIMP Palette\nName: %s\nColumns: 16\n", name);

for(i = 0; i < COLORS_NUM; i++)
DocPrint(out, "%d %d %d Zeal%d\n", pal[i].r, pal[i].g, pal[i].b, i);

Free(pal);

DocWrite(out);
DocDel(out);
}
2 changes: 1 addition & 1 deletion src/Demo/Graphics/ScreenCapture.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ U0 Main()
{
"Capture screen...\n";
PressAKey;
GRScreenCaptureWrite("~/DemoScreenShot");
GRScreenCaptureWrite("~/DemoScreenShot", FALSE);
xslendix marked this conversation as resolved.
Show resolved Hide resolved
"View captured screen...\n";
PressAKey;
GRScreenCaptureRead("~/DemoScreenShot");
Expand Down
55 changes: 15 additions & 40 deletions src/System/Gr/GrDC.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,21 @@ public I64 DCColorChange(CDC *dc, I64 src_color, I64 dst_color=TRANSPARENT)
return res;
}

public I64 DCColorMax(CDC *dc, U8 max=COLORS_NUM, U8 newcolor=BLACK)
{//Keep only colors below or at maximum
I64 i, res = 0;
U8 *dst;

dst = dc->body;
i = dc->width_internal * dc->height;
while (i--)
{
if (*dst > max) *dst = newcolor;
dst++;
}
return res;
}

public U8 *DCSave(CDC *dc, I64 *_size=NULL, I64 dcsf_flags=NONE)
{//Stores device context to mem, perhaps, with compression.
U8 *res, *ptr, *body;
Expand Down Expand Up @@ -395,46 +410,6 @@ public CDC *DCLoad(U8 *src, I64 *_size=NULL, CTask *task=NULL)
return res;
}

#help_index "Graphics/GR Files"
#help_file "::/Doc/GRFiles"
#help_index "Graphics/Device Contexts;Graphics/GR Files"

#define GR_FILE_MAX (offset(CDC.end) - offset(CDC.start) + COLORS_NUM * sizeof(CBGR24) + GR_WIDTH * GR_HEIGHT)

public I64 GRWrite(U8 *filename, CDC *dc, I64 dcsf_flags=NONE)
{//ZealOS GR File.
I64 size;
U8 *st = ExtDefault(filename, "GR"), *src = DCSave(dc, &size, dcsf_flags);
FileWrite(st, src, size);
Free(st);
Free(src);

return size;
}

public CDC *GRRead(U8 *filename, CTask *task=NULL)
{//ZealOS GR File.
CDC *dc = NULL;
U8 *st = ExtDefault(filename, "GR"), *src = FileRead(st);
if (src)
dc = DCLoad(src,, task);
Free(src);
Free(st);

return dc;
}

#help_index "Graphics/Sprite;Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
public U0 DocGR(CDoc *doc=NULL, U8 *filename)
{//Put a GR file into a document as asprite.
CDC *dc = GRRead(filename);
CSprite *elems = DC2Sprite(dc);

DocSprite(doc, elems);
Free(elems);
DCDel(dc);
}

#help_index "Graphics/Device Contexts;Graphics/Screen"
public CDC *DCScreenCapture(Bool include_zoom=TRUE, CTask *task=NULL)
{//Capture screen to a device context.
Expand Down
169 changes: 169 additions & 0 deletions src/System/Gr/GrFile.ZC
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#help_index "Graphics/GR Files"
#help_file "::/Doc/GRFiles"
#help_index "Graphics/Device Contexts;Graphics/GR Files"

#define GR_FILE_MAX (offset(CDC.end) - offset(CDC.start) + COLORS_NUM * sizeof(CBGR24) + GR_WIDTH * GR_HEIGHT)

public I64 GRWrite(U8 *filename, CDC *dc, I64 dcsf_flags=NONE)
{//ZealOS GR File.
I64 size;
U8 *st = ExtDefault(filename, "GR"), *src = DCSave(dc, &size, dcsf_flags);
FileWrite(st, src, size);
Free(st);
Free(src);

return size;
}

public CDC *GRRead(U8 *filename, CTask *task=NULL)
{//ZealOS GR File.
CDC *dc = NULL;
U8 *st = ExtDefault(filename, "GR"), *src = FileRead(st);
if (src)
dc = DCLoad(src,, task);
Free(src);
Free(st);

return dc;
}

#help_index "Graphics/Sprite;Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
public U0 DocGR(CDoc *doc=NULL, U8 *filename)
{//Put a GR file into a document as asprite.
CDC *dc = GRRead(filename);
CSprite *elems = DC2Sprite(dc);

DocSprite(doc, elems);
Free(elems);
DCDel(dc);
}

public class TGAFile
{
U0 start;
U8 id_size,
map_type,
image_type;
U16 color_map_origin,
color_map_length;
U8 color_map_bpp;
U16 x_origin,
y_origin,
width,
height;
U8 bpp,
flags;
U0 end;
U8 *id;
CBGR24 *palette;
U8 *body;
};

public I64 TGAWrite(U8 *filename, CDC *dc)
{//Truevision TGA File.
CDC *dc_copy = DCCopy(dc);
I64 i, size = offset(TGAFile.end) + sizeof(CBGR24) * COLORS_NUM >> 2 * 3 + dc_copy->width * dc_copy->height;
TGAFile *tga = CAlloc(size);
U8 *palette = tga(U8 *) + offset(TGAFile.end);
U8 *body = tga(U8 *) + offset(TGAFile.end) + sizeof(CBGR24) * COLORS_NUM >> 2 * 3;

tga->map_type = 1;
tga->image_type = 1; //uncompressed color-mapped
tga->color_map_origin = 0;
tga->color_map_length = COLORS_NUM;
tga->color_map_bpp = 24;
tga->x_origin = 0;
tga->y_origin = dc_copy->height;
tga->width = dc_copy->width;
tga->height = dc_copy->height;
tga->bpp = 8;
tga->flags = 0x20; //origin in top-left
if (!(dc_copy->flags & DCF_PALETTE))
{
GrPaletteGet(dc_copy->palette);
}

GrPaletteUnpad(palette, dc_copy->palette);
DCColorMax(dc_copy);

if (dc_copy->width_internal == dc_copy->width)
{
MemCopy(body, dc_copy->body, dc_copy->width_internal * dc_copy->height);
}
else
{
for (i = 0; i < dc_copy->height; i++)
MemCopy(body + i * dc_copy->width, dc_copy->body + i * dc_copy->width_internal, dc_copy->width);
}

DCDel(dc_copy);

U8 *str = ExtDefault(filename, "TGA");

FileWrite(str, tga, size);

Free(tga);
Free(str);

return size;
}

public CDC *TGARead(U8 *filename, Bool palette=TRUE, CTask *task=NULL)
{//Truevision TGA File.
I64 i;
CDC *dc = NULL;
U8 *st = ExtDefault(filename, "TGA"), *src = FileRead(st);
TGAFile *tga = CAlloc(sizeof(TGAFile));

if (src)
{
MemCopy(tga, src, offset(TGAFile.end));
if(tga->image_type != 1) goto exit;
if(tga->map_type != 1) goto exit;
if(tga->color_map_origin != 0) goto exit;
if(tga->color_map_bpp != 24/* && tga->color_map_bpp != 32*/) goto exit;
if(tga->color_map_length > COLORS_NUM) goto exit;
if(tga->x_origin != 0) goto exit;
if(tga->y_origin != tga->height) goto exit; //TODO: Support y_origin == 0
if(tga->bpp != 8) goto exit;
if(tga->flags != 0x20) goto exit; //TODO: Support y_origin == 0

//TGA ID string doesn't store any useful information
//if(tga->id_size) tga->id = src + offset(TGAFile.end);

tga->palette = CAlloc(sizeof(CBGR24) * COLORS_NUM);
GrPalettePad(tga->palette, src + offset(TGAFile.end) + tga->id_size, tga->color_map_length);
/*
32 bpp palette read. Should work in theory but not widely supported.
MemCopy(tga->palette, src + offset(TGAFile.end) + tga->id_size, sizeof(CBGR24) * tga->color_map_length);
*/

tga->body = src + offset(TGAFile.end) + tga->id_size + sizeof(CBGR24) >> 2 * tga->color_map_bpp >> 3 * tga->color_map_length;

dc = DCNew(tga->width, tga->height, task);
if (palette)
{
dc->flags |= DCF_PALETTE;
MemCopy(dc->palette, tga->palette, sizeof(CBGR24) * COLORS_NUM);
}

if (tga->width == dc->width_internal)
{
MemCopy(dc->body, tga->body, dc->width_internal * dc->height);
}
else
{
for (i = 0; i < tga->height; i++)
MemCopy(dc->body + i * dc->width_internal, tga->body + i * tga->width, tga->width);
}

}

exit:
Free(src);
Free(st);
Free(tga->palette);
Free(tga);

return dc;
}
23 changes: 23 additions & 0 deletions src/System/Gr/GrPalette.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,29 @@ public U0 GrPaletteSet(CBGR24 *bgr24)
MemCopy(&gr_palette, bgr24, sizeof(CBGR24) * COLORS_NUM);
}

U0 GrPaletteUnpad(U8 *dst, CBGR24 *src, U64 count=COLORS_NUM)
{//Remove extra byte from 24-bit palette.
I64 i, j = 0;
for (i = 0; i < sizeof(CBGR24) * count; i++)
{
if ((i + 1) % 4 == 0) i++;
dst[j] = src(U8 *)[i];
j++;
}
}

U0 GrPalettePad(CBGR24 *dst, U8 *src, U64 count=COLORS_NUM)
{//Add extra byte back to 24-bit palette
I64 i;
for (i = 0; i < count; i++)
{
dst[i].b = src[i * 3];
dst[i].g = src[i * 3 + 1];
dst[i].r = src[i * 3 + 2];
dst[i].pad = 0;
}
}

//********************************************************************************
public CBGR24 gr32_palette_std[COLORS_NUM] = {
0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
Expand Down
1 change: 1 addition & 0 deletions src/System/Gr/MakeGr.ZC
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Cd(__DIR__);;
#include "GrAsm"
#include "GrPalette"
#include "GrDC"
#include "GrFile"
y4my4my4m marked this conversation as resolved.
Show resolved Hide resolved
#include "GrInitB"
#include "GrMath"
#include "GrScreen"
Expand Down