From bdbb811ac1a60920f87a5640f2f68e7f349fe2c0 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Thu, 4 May 2023 22:55:50 +0100 Subject: Include PNG images as data --- tr8as.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'tr8as.c') diff --git a/tr8as.c b/tr8as.c index 30beda6..c9bd816 100644 --- a/tr8as.c +++ b/tr8as.c @@ -29,6 +29,10 @@ #include #include +#define STB_IMAGE_IMPLEMENTATION +#define STBI_ONLY_PNG +#include "stb_image.h" + #define MAX_LINE 1024 #define MAX_ID 0x40 #define MAX_LABELS 0x200 @@ -88,6 +92,27 @@ typedef struct uint8_t (*parse)(As *, char *); } InstParse; +/* used to map RGB values to palette index when including a PNG image */ +static uint8_t palette[16][3] = +{ + { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0xaa }, + { 0x00, 0xaa, 0x00 }, + { 0x00, 0xaa, 0xaa }, + { 0xaa, 0x00, 0x00 }, + { 0xaa, 0x00, 0xaa }, + { 0xaa, 0x55, 0x00 }, + { 0xaa, 0xaa, 0xaa }, + { 0x55, 0x55, 0x55 }, + { 0x55, 0x55, 0xff }, + { 0x55, 0xff, 0x55 }, + { 0x55, 0xff, 0xff }, + { 0xff, 0x55, 0x55 }, + { 0xff, 0x55, 0xff }, + { 0xff, 0xff, 0x55 }, + { 0xff, 0xff, 0xff }, +}; + static uint8_t error_l(const char *msg, Location *loc, const char *reason) { fprintf(stderr, "%s (%s:%d): %s\n", msg, loc->filename, loc->line, reason); @@ -431,6 +456,64 @@ static uint8_t parse_include(As *as, char *c) return 1; } +static uint8_t parse_incpng(As *as, char *c) +{ + /* XXX: may be support longer filenames */ + char word[MAX_ID + 1]; + uint8_t wlen; + + /* .incpng "filename" */ + + next_string(c, word, &wlen); + if (wlen == 0) + return error_l("Syntax error", &as->loc, "expected string"); + + if (strcasecmp(word + wlen - 4, ".png")) + return error_l("Invalid input", &as->loc, "expected PNG file"); + + int x, y, n; + uint8_t rc = 1; + + unsigned char *data = stbi_load(word, &x, &y, &n, 3); + if (!data) + return error_l("Invalid input", &as->loc, "expected PNG file"); + + if (x * y + as->addr > UINT16_MAX) + { + rc = error_l("Overflow in incpng", &as->loc, word); + goto exit_parseinc; + } + + /* TODO: mask */ + + uint16_t addr = as->addr; + uint8_t index; + + /* map RGB values to the palette indexes */ + for (int i = 0; i < x * y * 3; i += 3) + { + for (index = 0; index < 16; index++) + if (data[i] == palette[index][0] + && data[i + 1] == palette[index][1] + && data[i + 2] == palette[index][2]) + { + as->out[addr++] = index; + break; + } + if (index == 16) + addr++; + } + + as->addr = addr; + if (as->addr > as->size) + as->size = as->addr; + +exit_parseinc: + stbi_image_free(data); + + return rc; +} + static uint8_t parse_incbin(As *as, char *c) { /* XXX: may be support longer filenames */ @@ -1312,6 +1395,7 @@ static uint8_t parse_ld(As *as, char *c) static InstParse insts[] = { { ".include", parse_include }, + { ".incpng", parse_incpng }, { ".incbin", parse_incbin }, { ".org", parse_org }, { ".equ", parse_equ }, -- cgit v1.2.3