floor tool
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 28 Jan 2024 16:27:36 +0000 (18:27 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 28 Jan 2024 16:27:36 +0000 (18:27 +0200)
.gitignore
tools/floor/Makefile [new file with mode: 0644]
tools/floor/floor.c [new file with mode: 0644]

index 09004c7..170e017 100644 (file)
@@ -7,6 +7,7 @@
 *.z80
 tools/pngdump/pngdump
 tools/json2tmap/json2tmap
+tools/floor/floor
 core
 disasm
 .cache/
diff --git a/tools/floor/Makefile b/tools/floor/Makefile
new file mode 100644 (file)
index 0000000..3c2877a
--- /dev/null
@@ -0,0 +1,12 @@
+obj = floor.o
+bin = floor
+
+CFLAGS = -pedantic -Wall -g
+LDFLAGS = -limago -lm
+
+$(bin): $(obj)
+       $(CC) -o $@ $(obj) $(LDFLAGS)
+
+.PHONY: clean
+clean:
+       rm -f $(obj) $(bin)
diff --git a/tools/floor/floor.c b/tools/floor/floor.c
new file mode 100644 (file)
index 0000000..4db2d22
--- /dev/null
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <imago2.h>
+
+void scale_line(uint32_t *dst, uint32_t *src, float scale, int xsz);
+
+int main(int argc, char **argv)
+{
+       uint32_t *img, *newimg, *src, *dst;
+       float scale, y, z;
+       int i, scanline, xsz, ysz;
+
+       if(!argv[1] || !argv[2]) {
+               fprintf(stderr, "usage: %s <srcfile> <dstfile>\n", argv[0]);
+               return 1;
+       }
+
+       if(!(img = img_load_pixels(argv[1], &xsz, &ysz, IMG_FMT_RGBA32))) {
+               fprintf(stderr, "failed to open: %s\n", argv[1]);
+               return 1;
+       }
+
+       if(!(newimg = calloc(1, xsz * ysz * 4))) {
+               perror("malloc failed");
+               return 1;
+       }
+
+       dst = newimg;
+       for(i=0; i<ysz; i++) {
+               y = (float)(i + 1) / (float)ysz;
+               z = 20.0f / y;
+               scale = (float)i / (2.0f * (float)ysz) + 0.5f;
+               scanline = ysz - 1 - (int)(z * ysz / 25.0f) % ysz;
+               src = img + scanline * xsz;
+               scale_line(dst, src, scale, xsz);
+               dst += xsz;
+       }
+
+       if(img_save_pixels(argv[2], newimg, xsz, ysz, IMG_FMT_RGBA32) == -1) {
+               fprintf(stderr, "failed to save: %s\n", argv[2]);
+               return 1;
+       }
+       return 0;
+}
+
+void scale_line(uint32_t *dst, uint32_t *src, float scale, int xsz)
+{
+       int i, idx, newsz;
+       float sx, dx;
+
+       newsz = xsz * scale;
+       dx = 1.0 / scale;
+       sx = xsz - (xsz - newsz) / (2.0f * scale);
+
+       for(i=0; i<xsz; i++) {
+               idx = (int)sx;
+               *dst++ = src[idx % xsz];
+               sx += dx;
+       }
+}