diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-05-04 22:55:50 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-05-04 22:55:50 +0100 |
commit | bdbb811ac1a60920f87a5640f2f68e7f349fe2c0 (patch) | |
tree | 5cb0a043213f87f21136247fcb28810f3f304129 /tr8as.c | |
parent | 2fc29f20a343504780125aa2bed048cece79a37b (diff) | |
download | tr8vm-bdbb811ac1a60920f87a5640f2f68e7f349fe2c0.tar.gz tr8vm-bdbb811ac1a60920f87a5640f2f68e7f349fe2c0.zip |
Include PNG images as data
Diffstat (limited to 'tr8as.c')
-rw-r--r-- | tr8as.c | 84 |
1 files changed, 84 insertions, 0 deletions
@@ -29,6 +29,10 @@ #include <strings.h> #include <ctype.h> +#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 }, |