summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorturret <turret@duck.com>2026-05-17 21:13:45 -0500
committerturret <turret@duck.com>2026-05-17 21:13:45 -0500
commit84c75e25183a8aed321bbbbc2ffcc5d21adbd92c (patch)
tree31b3903f433224bd1f8de6badc6c7fd09b48a786
parent397f95a3c09d2aa66a51aad1952975c924e6be0b (diff)
downloadgengine-sdk-84c75e25183a8aed321bbbbc2ffcc5d21adbd92c.tar.gz
gengine-sdk-84c75e25183a8aed321bbbbc2ffcc5d21adbd92c.tar.bz2
gengine-sdk-84c75e25183a8aed321bbbbc2ffcc5d21adbd92c.zip
mkmat: material compiler v0 (unstable do not use)HEADmaster
-rw-r--r--.gitignore3
-rw-r--r--Makefile5
-rw-r--r--arg.h49
-rw-r--r--mkmat.c136
4 files changed, 192 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index b6f8ad5..7c80bae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
gen_init_cpio
gen_init_cpio.o
+
+mkmat
+mkmat.o
diff --git a/Makefile b/Makefile
index 6435ad7..cf97b28 100644
--- a/Makefile
+++ b/Makefile
@@ -3,11 +3,14 @@ LDFLAGS = -no-pie -g
.PHONY: all clean
-all: gen_init_cpio
+all: gen_init_cpio mkmat
%.o: %.c
$(CC) -o $@ -c $<
+mkmat: mkmat.o
+ $(CC) -o $@ $^ $(LDFLAGS)
+
gen_init_cpio: gen_init_cpio.o
$(CC) -o $@ $^ $(LDFLAGS)
diff --git a/arg.h b/arg.h
new file mode 100644
index 0000000..e94e02b
--- /dev/null
+++ b/arg.h
@@ -0,0 +1,49 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][0] == '-'\
+ && argv[0][1];\
+ argc--, argv++) {\
+ char argc_;\
+ char **argv_;\
+ int brk_;\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ for (brk_ = 0, argv[0]++, argv_ = argv;\
+ argv[0][0] && !brk_;\
+ argv[0]++) {\
+ if (argv_ != argv)\
+ break;\
+ argc_ = argv[0][0];\
+ switch (argc_)
+
+#define ARGEND }\
+ }
+
+#define ARGC() argc_
+
+#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ ((x), abort(), (char *)0) :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ (char *)0 :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#endif
diff --git a/mkmat.c b/mkmat.c
new file mode 100644
index 0000000..452e0a7
--- /dev/null
+++ b/mkmat.c
@@ -0,0 +1,136 @@
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "arg.h"
+
+char *argv0;
+
+int execveat(int dirfd, const char *path,
+ char *const argv[],
+ char *const envp[],
+ int flags);
+
+void die(const char *fmt, ...)
+{
+ va_list ap;
+ int saved_errno;
+
+ saved_errno = errno;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':')
+ fprintf(stderr, " %s", strerror(saved_errno));
+ fputc('\n', stderr);
+
+ exit(1);
+}
+
+#define usage() die("Usage: %s [filename]", argv0)
+int main(int argc, char **argv)
+{
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND
+
+ if(argc < 1)
+ usage();
+
+ int cpwd = open(".", O_PATH | O_CLOEXEC);
+
+ int file = open(*argv, 0);
+ if(file < 0)
+ die("open file:");
+
+ char buf[1 << 8];
+ size_t linksize = readlink("/proc/self/exe", buf, 1 << 8);
+ if(linksize < 0)
+ die("readlink:");
+ buf[linksize] = '\0';
+ char *dname = dirname(buf);
+ chdir(dname);
+
+ int mkcpio = open("gen_init_cpio", O_CLOEXEC);
+ if(mkcpio < 0)
+ die("open gen_init_cpio:");
+
+ fchdir(cpwd);
+
+ char *argv0_dirname = strdup(*argv);
+ chdir(dirname(argv0_dirname));
+ free(argv0_dirname);
+
+ int cpiopipe[2];
+ if(pipe(cpiopipe) < 0)
+ die("pipe:");
+
+ int materialfd = memfd_create("material.mtl", 0);
+ if(materialfd < 0)
+ die("memfd_create:");
+
+ int stdout_kept = dup(STDOUT_FILENO);
+ dup2(cpiopipe[0], STDIN_FILENO);
+ dup2(cpiopipe[1], STDOUT_FILENO);
+ //dup2(STDOUT_FILENO, materialpipe[1]);
+ if(cpiopipe[0] != STDIN_FILENO)
+ close(cpiopipe[0]);
+ if(cpiopipe[1] != STDOUT_FILENO)
+ close(cpiopipe[1]);
+ /* all printf go to gen_init_cpio now */
+
+ printf("file material.mtl /proc/self/fd/%d 0644 0 0\n", materialfd);
+ size_t num_read = 1;
+ while(num_read > 0) {
+ buf[0] = '\0';
+ num_read = read(file, buf, (1 << 8) - 2);
+ lseek(file, -num_read, SEEK_CUR);
+ buf[num_read] = '\0';
+ *strchrnul(buf, '\n') = '\0';
+ lseek(file, strchrnul(buf, '\n') - buf + 1, SEEK_CUR);
+ if(strncmp(buf, "map_", 4) == 0 ||
+ strncmp(buf, "disp ", 5) == 0 ||
+ strncmp(buf, "bump ", 5) == 0) {
+ char *name = *argv;
+#define CASE(val) strncmp(buf, val, strlen(val)) == 0
+ if(CASE("map_Ka "))
+ name = "ambient";
+ else if(CASE("map_Kd "))
+ name = "diffuse";
+ else if(CASE("map_Ks "))
+ name = "specular";
+ else if(CASE("map_Ns "))
+ name = "specular_highlight";
+ else if(CASE("map_bump ") || CASE("bump"))
+ name = "bump";
+ else if(CASE("disp "))
+ name = "displacement";
+ else if(CASE("map_d "))
+ name = "alpha";
+
+ *strchrnul(buf, ' ') = '\0';
+ dprintf(materialfd, "%s %s\n", buf, name);
+
+ printf("file %s %s 0644 0 0\n", name, strchrnul(buf, ' ') + 1);
+ } else {
+ dprintf(materialfd, "%s\n", buf);
+ }
+ }
+ fflush(stdout);
+ dup2(stdout_kept, STDOUT_FILENO);
+ if(stdout_kept != STDOUT_FILENO)
+ close(stdout_kept);
+
+ execveat(mkcpio, "", (char*[]){"gen_init_cpio", "-", NULL}, NULL, AT_EMPTY_PATH);
+}