From 93c370a115018efcd9cadedbb5a9885220176c4c Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 8 Nov 2022 01:39:22 +0200 Subject: [PATCH] porting back some changes from the GBA version --- src/main.c | 22 +++++++++++++--------- src/voxscape.c | 26 +++++++++++++++++++------- src/voxscape.h | 6 +++--- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/main.c b/src/main.c index daa03bf..bbe64fd 100644 --- a/src/main.c +++ b/src/main.c @@ -37,7 +37,8 @@ int mouse_x, mouse_y, mwarp, mbstate[3]; int hfilt = VOX_LINEAR, cfilt = VOX_LINEAR; unsigned int input; -int32_t pos[2], angle; +int32_t pos[2], theta, phi; +int horizon; struct voxscape *vox; @@ -80,8 +81,8 @@ int init(void) if(!(vox = vox_open("data/height.png", "data/color.png"))) { return -1; } - vox_framebuf(vox, FB_W, FB_H, fb, -1); - vox_proj(vox, 45, 1, 300); + vox_framebuf(vox, FB_W, FB_H, fb); + vox_proj(vox, 140, 45, 1, 300); vox_fog(vox, 260, COLOR_HORIZON); vox_filter(vox, hfilt, cfilt); @@ -101,11 +102,11 @@ void update(void) { int32_t fwd[2], right[2]; - if(input & INP_LTURN) angle += TURN_SPEED; - if(input & INP_RTURN) angle -= TURN_SPEED; + if(input & INP_LTURN) theta += TURN_SPEED; + if(input & INP_RTURN) theta -= TURN_SPEED; - fwd[0] = -SIN(angle); - fwd[1] = COS(angle); + fwd[0] = -SIN(theta); + fwd[1] = COS(theta); right[0] = fwd[1]; right[1] = -fwd[0]; @@ -126,7 +127,7 @@ void update(void) pos[1] -= right[1]; } - vox_view(vox, pos[0], pos[1], -30, angle); + vox_view(vox, pos[0], pos[1], -30, theta, phi); } void display(void) @@ -263,6 +264,9 @@ void motion(int x, int y) if(!(dx | dy)) return; if(mbstate[0]) { - angle -= dx << 6; + theta -= dx << 6; + phi += dy << 8; + if(phi < -0x18000) phi = -0x18000; + if(phi > 0x18000) phi = 0x18000; } } diff --git a/src/voxscape.c b/src/voxscape.c index 54c0b10..c10b170 100644 --- a/src/voxscape.c +++ b/src/voxscape.c @@ -27,6 +27,8 @@ struct voxscape { int hfilt, cfilt; + int hscale; + /* framebuffer */ uint32_t *fb; int fbwidth, fbheight; @@ -41,7 +43,7 @@ struct voxscape { int fov, znear, zfar; int nslices; int32_t *slicelen; - int proj_dist; + int *projlut; int zfog; /* fog start Z (0: no fog) */ int fogcolor[3]; @@ -80,7 +82,7 @@ struct voxscape *vox_create(int xsz, int ysz) } vox->vheight = 80; - vox->proj_dist = 4; /* TODO */ + vox->hscale = 140; return vox; } @@ -205,7 +207,7 @@ void vox_filter(struct voxscape *vox, int hfilt, int cfilt) vox->cfilt = cfilt; } -void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb, int horizon) +void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb) { if(xres != vox->fbwidth) { free(vox->coltop); @@ -217,10 +219,9 @@ void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb, int ho vox->fb = fb; vox->fbwidth = xres; vox->fbheight = yres; - vox->horizon = horizon >= 0 ? horizon : vox->fbheight / 2; } -void vox_view(struct voxscape *vox, int32_t x, int32_t y, int h, int32_t angle) +void vox_view(struct voxscape *vox, int32_t x, int32_t y, int h, int32_t angle, int32_t vangle) { if(h < 0) { h = vox_height(vox, x, y) - h; @@ -231,14 +232,17 @@ void vox_view(struct voxscape *vox, int32_t x, int32_t y, int h, int32_t angle) vox->vheight = h; vox->angle = angle; + vox->horizon = (vox->fbheight * ((vangle + 0x10000) >> 1)) >> 16; + vox->valid &= ~SLICELEN; } -void vox_proj(struct voxscape *vox, int fov, int znear, int zfar) +void vox_proj(struct voxscape *vox, int hscale, int fov, int znear, int zfar) { vox->fov = fov; vox->znear = znear; vox->zfar = zfar; + vox->hscale = hscale; vox->nslices = vox->zfar - vox->znear; free(vox->slicelen); @@ -246,6 +250,12 @@ void vox_proj(struct voxscape *vox, int fov, int znear, int zfar) fprintf(stderr, "vox_proj: failed to allocate slice length table (%d)\n", vox->nslices); return; } + free(vox->projlut); + if(!(vox->projlut = malloc(vox->nslices * sizeof *vox->projlut))) { + fprintf(stderr, "vox_proj: failed to allocate projection table (%d)\n", vox->nslices); + free(vox->slicelen); + return; + } vox->valid &= ~SLICELEN; } @@ -276,6 +286,7 @@ void vox_begin(struct voxscape *vox) float theta = (float)vox->fov * M_PI / 360.0f; /* half angle */ for(i=0; inslices; i++) { vox->slicelen[i] = (int32_t)((vox->znear + i) * tan(theta) * 4.0f * 65536.0f); + vox->projlut[i] = (vox->hscale << 8) / (vox->znear + i); } vox->valid |= SLICELEN; } @@ -304,7 +315,7 @@ void vox_render_slice(struct voxscape *vox, int n) y = vox->y + COS(vox->angle) * z - ystep * (vox->fbwidth >> 1); for(i=0; ifbwidth; i++) { hval = vox_height(vox, x, y) - vox->vheight; - hval = hval * 160 / (vox->znear + n) + vox->horizon; + hval = ((hval * vox->projlut[n]) >> 8) + vox->horizon; if(hval > vox->fbheight) hval = vox->fbheight; if(hval > vox->coltop[i]) { color = vox_color(vox, x, y); @@ -360,6 +371,7 @@ void vox_sky_grad(struct voxscape *vox, uint32_t chor, uint32_t ctop) r1 = chor & 0xff; for(i=0; i= vox->fbheight) break; t = (i << 16) / d; grad[i] = lerp_rgb(r0, g0, b0, r1, g1, b1, t); } diff --git a/src/voxscape.h b/src/voxscape.h index 0602831..98d9bf3 100644 --- a/src/voxscape.h +++ b/src/voxscape.h @@ -22,10 +22,10 @@ int vox_height(struct voxscape *vox, int32_t x, int32_t y); void vox_filter(struct voxscape *vox, int hfilt, int cfilt); -void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb, int horizon); +void vox_framebuf(struct voxscape *vox, int xres, int yres, uint32_t *fb); /* negative height for auto at -h above terrain */ -void vox_view(struct voxscape *vox, int32_t x, int32_t y, int h, int32_t angle); -void vox_proj(struct voxscape *vox, int fov, int znear, int zfar); +void vox_view(struct voxscape *vox, int32_t x, int32_t y, int h, int32_t angle, int32_t vangle); +void vox_proj(struct voxscape *vox, int hscale, int fov, int znear, int zfar); void vox_render(struct voxscape *vox); -- 1.7.10.4