curved tunnel
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 18 Apr 2021 03:28:37 +0000 (06:28 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 18 Apr 2021 03:28:37 +0000 (06:28 +0300)
src/gamescr.c
tools/tungen.c

index 70991e8..30ae380 100644 (file)
@@ -52,12 +52,13 @@ void gamescr(void)
 __attribute__((noinline, target("arm"), section(".iwram")))
 static void draw_tunnel(void)
 {
-       int i, j, tx, ty, angle, depth, zoffs;
+       int i, j, tx, ty, angle, depth, zoffs, uoffs;
        uint16_t pptop, ppbot;
        uint16_t *top, *bot;
        uint32_t tun, *tunptr;
 
        zoffs = nframes;
+       uoffs = 0;
 
        top = vram[backbuf];
        bot = vram[backbuf] + 159 * 240 / 2;
@@ -71,18 +72,18 @@ static void draw_tunnel(void)
 
                        angle = tun & 0xff;
                        depth = (tun >> 8) & 0xff;
-                       tx = ((angle >> 1) + zoffs) & 0x1f;
+                       tx = ((angle >> 1) + uoffs) & 0x1f;
                        ty = ((depth >> 1) + zoffs) & 0x1f;
                        pptop = tex[(ty << 5) + tx];
-                       tx = ((angle >> 1) - zoffs) & 0x1f;
+                       tx = ((angle >> 1) - uoffs) & 0x1f;
                        ppbot = tex[(ty << 5) + tx];
 
                        angle = (tun >> 16) & 0xff;
                        depth = (tun >> 24) & 0xff;
-                       tx = ((angle >> 1) + zoffs) & 0x1f;
+                       tx = ((angle >> 1) + uoffs) & 0x1f;
                        ty = ((depth >> 1) + zoffs) & 0x1f;
                        pptop |= (uint16_t)tex[(ty << 5) + tx] << 8;
-                       tx = ((angle >> 1) - zoffs) & 0x1f;
+                       tx = ((angle >> 1) - uoffs) & 0x1f;
                        ppbot |= (uint16_t)tex[(ty << 5) + tx] << 8;
 
                        *top++ = pptop;
index 8122c95..4148b26 100644 (file)
@@ -3,11 +3,16 @@
 #include <stdint.h>
 #include <math.h>
 
+struct vec2 {
+       float x, y;
+};
+
 int main(int argc, char **argv)
 {
-       int i, j, xsz = 240, ysz = 160, texsz = 128;
+       int i, j, imgrad, xsz = 240, ysz = 160, texsz = 128;
        struct vec2 *tunbuf, *tun;
-       float aspect;
+       float aspect, prev_r;
+       struct vec2 *buf, *ptr;
 
        for(i=1; i<argc; i++) {
                if(argv[i][0] == '-') {
@@ -36,6 +41,39 @@ invalopt:    fprintf(stderr, "invalid argument: %s\n", argv[i]);
                }
        }
 
+       if(!(buf = malloc(xsz * ysz * sizeof *buf))) {
+               perror("failed to allocate buffer");
+               return 1;
+       }
+       imgrad = sqrt(xsz * xsz + ysz * ysz);
+
+#define UDIV   2048
+#define VDIV   32768
+       prev_r = 0.0f;
+       for(i=0; i<VDIV; i++) {
+               float v = (float)(VDIV - i) / (float)VDIV;
+               float r = 4.0 / v + 16;
+               float z = v * 400.0f;
+
+               /* don't bother drawing rings < 1 pixel apart */
+               if(fabs(r - prev_r) < 0.05) continue;
+
+               for(j=0; j<UDIV; j++) {
+                       float u = (float)j / (float)(UDIV - 1);
+                       float theta = 2.0f * u * M_PI;
+
+                       int x = (int)(cos(theta) * r - z) + xsz / 2;
+                       int y = (int)(sin(theta) * r) + ysz / 2;
+
+                       if(x >= 0 && x < xsz && y >= 0 && y < ysz) {
+                               ptr = buf + y * xsz + x;
+                               ptr->x = u;
+                               ptr->y = v * 8;
+                       }
+               }
+               prev_r = r;
+       }
+
        FILE *fp = fopen("tun_preview.ppm", "wb");
        if(fp) {
                fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
@@ -43,32 +81,24 @@ invalopt:   fprintf(stderr, "invalid argument: %s\n", argv[i]);
 
        aspect = (float)xsz / (float)ysz;
 
-       tun = tunbuf;
+       ptr = buf;
        for(i=0; i<ysz; i++) {
-               float y = 2.0f * (float)i / (float)(ysz - 1) - 1.0f;
                for(j=0; j<xsz; j++) {
-                       float x = (2.0f * (float)j / (float)(xsz - 1) - 1.0f) * aspect;
-
-                       float r = sqrt(x * x + y * y);
-                       float theta = atan2(y, x);
+                       float u = ptr->x;
+                       float v = ptr->y;
+                       int r = (int)(u * 8.0 * 255.0f) & 0xff;
+                       int b = (int)(v * 8.0 * 255.0f) & 0xff;
 
-                       float u = 0.5f * theta / M_PI + 0.5f;
-                       float v = 0.8f / r;
+                       ptr++;
 
-                       /*
-                       uint32_t out = ((uint32_t)(u * 65535.0f) & 0xffff) |
-                               (((uint32_t)(v * 65535.0f) & 0xffff) << 16);
-                       */
                        uint16_t out = ((uint16_t)(u * 255.0f) & 0xff) |
                                (((uint16_t)(v * 255.0f) & 0xff) << 8);
                        fwrite(&out, sizeof out, 1, stdout);
 
                        if(fp) {
-                               int cr = (int)(u * 2048.0f) & 0xff;
-                               int cb = (int)(r * 2048.0f) & 0xff;
-                               fputc(cr, fp);
+                               fputc(r, fp);
                                fputc(0, fp);
-                               fputc(cb, fp);
+                               fputc(b, fp);
                        }
                }
        }