converting to 16bpp
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 18 Oct 2022 21:21:09 +0000 (00:21 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 18 Oct 2022 21:21:09 +0000 (00:21 +0300)
Makefile
src/data.h
src/data.s
src/gamescr.c
src/voxscape.c
src/voxscape.h

index b7b0903..d3e2cfd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,8 @@ name = gbajam22
 elf = $(name).elf
 bin = $(name).gba
 
-data = data/color.raw data/color.pal data/height.raw
+#data = data/color.raw data/color.pal data/height.raw
+data = data/color.555 data/height.raw
 
 libs = libs/maxmod/libmm.a
 
@@ -69,6 +70,9 @@ tools/mmutil/mmutil:
 %.raw: %.png tools/pngdump/pngdump
        tools/pngdump/pngdump -o $@ -n $<
 
+%.555: %.png tools/pngdump/pngdump
+       tools/pngdump/pngdump -o $@ -555 $<
+
 %.pal: %.png tools/pngdump/pngdump
        tools/pngdump/pngdump -o $@ -c $<
 
index e3f3290..ce9a2e7 100644 (file)
@@ -9,8 +9,7 @@
 
 #define VOX_SZ 256
 
-extern unsigned char color_pixels[];
-extern unsigned char color_cmap[];
-extern unsigned char height_pixels[];
+extern uint16_t color_pixels[];
+extern uint8_t height_pixels[];
 
 #endif /* DATA_H_ */
index 7a6431d..e97ced3 100644 (file)
@@ -1,15 +1,11 @@
        .section .rodata
 
        .globl color_pixels
-       .globl color_cmap
        .globl height_pixels
 
        .align 1
 color_pixels:
-       .incbin "data/color.raw"
-       .align 1
-color_cmap:
-       .incbin "data/color.pal"
+       .incbin "data/color.555"
        .align 1
 height_pixels:
        .incbin "data/height.raw"
index e3ff340..2d283d8 100644 (file)
@@ -50,7 +50,7 @@ static int gamescr_start(void)
 {
        int i;
 
-       gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
+       gba_setmode(5, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
 
        vblperf_setcolor(0);
 
@@ -61,24 +61,6 @@ static int gamescr_start(void)
        }
        vox_proj(vox, 45, 2, VOX_SZ / 5);
 
-       /* setup color image palette */
-       for(i=0; i<192; i++) {
-               int r = color_cmap[i * 3];
-               int g = color_cmap[i * 3 + 1];
-               int b = color_cmap[i * 3 + 2];
-               gba_bgpal[i] = (((uint16_t)b << 7) & 0x7c00) | (((uint16_t)g << 2) & 0x3e0) | (((uint16_t)r >> 3) & 0x1f);
-       }
-
-       /* setup sky gradient palette */
-       for(i=0; i<64; i++) {
-               int t = (i << 8) / 64;
-               int r = (0xcc00 + (0x55 - 0xcc) * t) >> 8;
-               int g = (0x7700 + (0x88 - 0x77) * t) >> 8;
-               int b = (0xff00 + (0xcc - 0xff) * t) >> 8;
-               int cidx = COLOR_HORIZON + i;
-               gba_bgpal[cidx] = ((b << 7) & 0x7c00) | ((g << 2) & 0x3e0) | (r >> 3);
-       }
-
        nframes = 0;
        return 0;
 }
@@ -94,7 +76,7 @@ static void gamescr_frame(void)
        backbuf = ++nframes & 1;
        fb = (unsigned char*)vram[backbuf];
 
-       vox_framebuf(vox, 240, 160, fb, -1);
+       vox_framebuf(vox, 160, 128, fb, -1);
 
        update();
        draw();
index 60c2781..81ba215 100644 (file)
@@ -8,8 +8,8 @@
 #include "debug.h"
 
 /* hardcoded dimensions for the GBA */
-#define FBWIDTH                240
-#define FBHEIGHT       160
+#define FBWIDTH                160
+#define FBHEIGHT       128
 /* map size */
 #define XSZ                    256
 #define YSZ                    256
 #define XLERP(a, b, t, fp) \
        ((((a) << (fp)) + ((b) - (a)) * (t)) >> fp)
 
+static uint16_t lerp_rgb(int r0, int g0, int b0, int r1, int g1, int b1, int32_t t);
+
 enum {
        SLICELEN        = 1
 };
 
 struct voxscape {
        int xsz, ysz;
-       unsigned char *height;
-       unsigned char *color;
+       uint8_t *height;
+       uint16_t *color;
        int xshift, xmask, ymask;
 
        int hfilt, cfilt;
@@ -52,13 +54,15 @@ struct voxscape {
        int32_t *slicelen;
        int proj_dist;
 
+#if 0
        int zfog;       /* fog start Z (0: no fog) */
        uint8_t fogcolor;
+#endif
 
        unsigned int valid;
 };
 
-struct voxscape *vox_create(int xsz, int ysz, uint8_t *himg, uint8_t *cimg)
+struct voxscape *vox_create(int xsz, int ysz, uint8_t *himg, uint16_t *cimg)
 {
        struct voxscape *vox;
 
@@ -98,10 +102,10 @@ void vox_free(struct voxscape *vox)
        free(vox);
 }
 
-uint8_t *vox_texture(struct voxscape *vox, uint8_t *data)
+uint16_t *vox_texture(struct voxscape *vox, uint16_t *data)
 {
        if(data) {
-               memcpy(vox->color, data, vox->xsz * vox->ysz);
+               memcpy(vox->color, data, vox->xsz * vox->ysz * sizeof *vox->color);
        }
        return vox->color;
 }
@@ -114,11 +118,13 @@ uint8_t *vox_heightmap(struct voxscape *vox, uint8_t *data)
        return vox->height;
 }
 
+/*
 void vox_fog(struct voxscape *vox, int zstart, uint8_t color)
 {
        vox->zfog = zstart;
        vox->fogcolor = color;
 }
+*/
 
 #define H(x, y)        \
        vox->height[((((y) >> 16) & YMASK) << XSHIFT) + (((x) >> 16) & XMASK)]
@@ -176,7 +182,6 @@ int vox_color(struct voxscape *vox, int32_t x, int32_t y)
 }
 #endif /* !NO_LERP */
 
-
 void vox_filter(struct voxscape *vox, int hfilt, int cfilt)
 {
        vox->hfilt = hfilt;
@@ -247,7 +252,7 @@ void vox_begin(struct voxscape *vox)
 {
        int i;
 
-       memset(vox->fb, 0, FBWIDTH * FBHEIGHT);
+       memset(vox->fb, 0, FBWIDTH * FBHEIGHT * 2);
        memset(vox->coltop, 0, FBWIDTH * sizeof *vox->coltop);
 
        if(!(vox->valid & SLICELEN)) {
@@ -264,7 +269,7 @@ void vox_render_slice(struct voxscape *vox, int n)
 {
        int i, j, hval, last_hval, colstart, colheight, col, z, offs, last_offs = -1;
        int32_t x, y, len, xstep, ystep;
-       uint8_t color, last_col;
+       uint16_t color, last_col;
        uint16_t *fbptr;
 
        z = vox->znear + n;
@@ -276,8 +281,7 @@ void vox_render_slice(struct voxscape *vox, int n)
        x = vox->x - SIN(vox->angle) * z - xstep * (FBWIDTH / 2);
        y = vox->y + COS(vox->angle) * z - ystep * (FBWIDTH / 2);
 
-       for(i=1; i<FBWIDTH / 2; i++) {
-               col = i * 2;
+       for(i=1; i<FBWIDTH; i++) {
                offs = (((y >> 16) & YMASK) << XSHIFT) + ((x >> 16) & XMASK);
                if(offs == last_offs) {
                        hval = last_hval;
@@ -291,44 +295,16 @@ void vox_render_slice(struct voxscape *vox, int n)
                        last_hval = hval;
                        last_col = color;
                }
-               if(hval > vox->coltop[col]) {
+               if(hval > vox->coltop[i]) {
                        colstart = FBHEIGHT - hval;
-                       colheight = hval - vox->coltop[col];
-                       fbptr = vox->fb + colstart * (FBWIDTH / 2) + i;
+                       colheight = hval - vox->coltop[i];
+                       fbptr = vox->fb + colstart * FBWIDTH + i;
 
                        for(j=0; j<colheight; j++) {
-                               *fbptr |= color;
-                               fbptr += FBWIDTH / 2;
+                               *fbptr = color;
+                               fbptr += FBWIDTH;
                        }
-                       vox->coltop[col] = hval;
-               }
-               x += xstep;
-               y += ystep;
-
-               col++;
-               offs = (((y >> 16) & YMASK) << XSHIFT) + ((x >> 16) & XMASK);
-               if(offs == last_offs) {
-                       hval = last_hval;
-                       color = last_col;
-               } else {
-                       hval = vox->height[offs] - vox->vheight;
-                       hval = hval * HSCALE / (vox->znear + n) + vox->horizon;
-                       if(hval > FBHEIGHT) hval = FBHEIGHT;
-                       color = vox->color[offs];
-                       last_offs = offs;
-                       last_hval = hval;
-                       last_col = color;
-               }
-               if(hval > vox->coltop[col]) {
-                       colstart = FBHEIGHT - hval;
-                       colheight = hval - vox->coltop[col];
-                       fbptr = vox->fb + colstart * (FBWIDTH / 2) + i;
-
-                       for(j=0; j<colheight; j++) {
-                               *fbptr |= ((uint16_t)color << 8);
-                               fbptr += FBWIDTH / 2;
-                       }
-                       vox->coltop[col] = hval;
+                       vox->coltop[i] = hval;
                }
                x += xstep;
                y += ystep;
@@ -336,72 +312,59 @@ void vox_render_slice(struct voxscape *vox, int n)
 }
 
 ARM_IWRAM
-void vox_sky_solid(struct voxscape *vox, uint8_t color)
+void vox_sky_solid(struct voxscape *vox, uint16_t color)
 {
-       int i, j, colh0, colh1, colhboth;
+       int i, j, colheight;
        uint16_t *fbptr;
 
-       for(i=1; i<FBWIDTH / 2; i++) {
+       for(i=1; i<FBWIDTH; i++) {
                fbptr = vox->fb + i;
-               colh0 = FBHEIGHT - vox->coltop[i << 1];
-               colh1 = FBHEIGHT - vox->coltop[(i << 1) + 1];
-               colhboth = colh0 < colh1 ? colh0 : colh1;
+               colheight = FBHEIGHT - vox->coltop[i];
 
-               for(j=0; j<colhboth; j++) {
-                       *fbptr = color | ((uint16_t)color << 8);
+               for(j=0; j<colheight; j++) {
+                       *fbptr = color;
                        fbptr += FBWIDTH / 2;
                }
-
-               if(colh0 > colh1) {
-                       for(j=colhboth; j<colh0; j++) {
-                               *fbptr |= color;
-                               fbptr += FBWIDTH / 2;
-                       }
-               } else {
-                       for(j=colhboth; j<colh1; j++) {
-                               *fbptr |= (uint16_t)color << 8;
-                               fbptr += FBWIDTH / 2;
-                       }
-               }
        }
 }
 
-void vox_sky_grad(struct voxscape *vox, uint8_t chor, uint8_t ctop)
+void vox_sky_grad(struct voxscape *vox, uint16_t chor, uint16_t ctop)
 {
-       int i, j, colh0, colh1, colhboth, t;
+       int i, j, colheight, t;
+       int r0, g0, b0, r1, g1, b1;
        int d = FBHEIGHT - vox->horizon;
-       uint8_t grad[FBHEIGHT];
-       uint16_t *fbptr;
+       uint16_t grad[FBHEIGHT], *fbptr;
+
+       r0 = ctop & 0x1f;
+       g0 = (ctop >> 5) & 0x1f;
+       b0 = (ctop >> 10) & 0x1f;
+       r1 = chor & 0x1f;
+       g1 = (chor >> 5) & 0x1f;
+       b1 = (chor >> 10) & 0x1f;
 
        for(i=0; i<d; i++) {
                t = (i << 16) / d;
-               grad[i] = XLERP(ctop, chor, t, 16);
+               grad[i] = lerp_rgb(r0, g0, b0, r1, g1, b1, t);
        }
-       for(i=d; i<FBHEIGHT; i++) {
+       for(i=d; i<vox->fbheight; i++) {
                grad[i] = chor;
        }
 
-       for(i=1; i<FBWIDTH / 2; i++) {
+       for(i=0; i<vox->fbwidth; i++) {
                fbptr = vox->fb + i;
-               colh0 = FBHEIGHT - vox->coltop[i << 1];
-               colh1 = FBHEIGHT - vox->coltop[(i << 1) + 1];
-               colhboth = colh0 < colh1 ? colh0 : colh1;
-
-               for(j=0; j<colhboth; j++) {
-                       *fbptr = grad[j] | ((uint16_t)grad[j] << 8);
-                       fbptr += FBWIDTH / 2;
-               }
-
-               if(colh0 > colh1) {
-                       for(j=colhboth; j<colh0; j++) {
-                               *fbptr |= grad[j];
-                               fbptr += FBWIDTH / 2;
-                       }
-               } else {
-                       for(j=colhboth; j<colh1; j++) {
-                               *fbptr |= (uint16_t)grad[j] << 8;
-                               fbptr += FBWIDTH / 2;
-                       }
+               colheight = vox->fbheight - vox->coltop[i];
+               for(j=0; j<colheight; j++) {
+                       *fbptr = grad[j];
+                       fbptr += vox->fbwidth;
                }
        }
 }
+
+static uint16_t lerp_rgb(int r0, int g0, int b0, int r1, int g1, int b1, int32_t t)
+{
+       int r = XLERP(r0, r1, t, 16);
+       int g = XLERP(g0, g1, t, 16);
+       int b = XLERP(b0, b1, t, 16);
+       return r | (g << 5) | (b << 10);
+}
+
index 899ef86..465a11a 100644 (file)
@@ -10,14 +10,14 @@ enum {
 
 struct voxscape;
 
-struct voxscape *vox_create(int xsz, int ysz, uint8_t *himg, uint8_t *cimg);
+struct voxscape *vox_create(int xsz, int ysz, uint8_t *himg, uint16_t *cimg);
 void vox_free(struct voxscape *vox);
 
 /* data argument can be null */
-uint8_t *vox_texture(struct voxscape *vox, uint8_t *data);
+uint16_t *vox_texture(struct voxscape *vox, uint16_t *data);
 uint8_t *vox_heightmap(struct voxscape *vox, uint8_t *data);
 
-void vox_fog(struct voxscape *vox, int zstart, uint8_t color);
+/*void vox_fog(struct voxscape *vox, int zstart, uint16_t color);*/
 int vox_height(struct voxscape *vox, int32_t x, int32_t y);
 
 void vox_filter(struct voxscape *vox, int hfilt, int cfilt);
@@ -32,7 +32,7 @@ void vox_render(struct voxscape *vox);
 void vox_begin(struct voxscape *vox);
 void vox_render_slice(struct voxscape *vox, int n);
 
-void vox_sky_solid(struct voxscape *vox, uint8_t color);
-void vox_sky_grad(struct voxscape *vox, uint8_t chor, uint8_t ctop);
+void vox_sky_solid(struct voxscape *vox, uint16_t color);
+void vox_sky_grad(struct voxscape *vox, uint16_t chor, uint16_t ctop);
 
 #endif /* VOXSCAPE_H_ */