aboutsummaryrefslogtreecommitdiff
path: root/tr8as.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-05-04 22:55:50 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-05-04 22:55:50 +0100
commitbdbb811ac1a60920f87a5640f2f68e7f349fe2c0 (patch)
tree5cb0a043213f87f21136247fcb28810f3f304129 /tr8as.c
parent2fc29f20a343504780125aa2bed048cece79a37b (diff)
downloadtr8vm-bdbb811ac1a60920f87a5640f2f68e7f349fe2c0.tar.gz
tr8vm-bdbb811ac1a60920f87a5640f2f68e7f349fe2c0.zip
Include PNG images as data
Diffstat (limited to 'tr8as.c')
-rw-r--r--tr8as.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/tr8as.c b/tr8as.c
index 30beda6..c9bd816 100644
--- a/tr8as.c
+++ b/tr8as.c
@@ -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 },