diff options
| author | turret <turret@duck.com> | 2026-05-17 21:13:45 -0500 |
|---|---|---|
| committer | turret <turret@duck.com> | 2026-05-17 21:13:45 -0500 |
| commit | 84c75e25183a8aed321bbbbc2ffcc5d21adbd92c (patch) | |
| tree | 31b3903f433224bd1f8de6badc6c7fd09b48a786 | |
| parent | 397f95a3c09d2aa66a51aad1952975c924e6be0b (diff) | |
| download | gengine-sdk-84c75e25183a8aed321bbbbc2ffcc5d21adbd92c.tar.gz gengine-sdk-84c75e25183a8aed321bbbbc2ffcc5d21adbd92c.tar.bz2 gengine-sdk-84c75e25183a8aed321bbbbc2ffcc5d21adbd92c.zip | |
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | arg.h | 49 | ||||
| -rw-r--r-- | mkmat.c | 136 |
4 files changed, 192 insertions, 1 deletions
@@ -1,2 +1,5 @@ gen_init_cpio gen_init_cpio.o + +mkmat +mkmat.o @@ -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) @@ -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 @@ -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); +} |
