porting voxscape to gba
authorJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 17 Oct 2022 19:19:13 +0000 (22:19 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 17 Oct 2022 19:19:13 +0000 (22:19 +0300)
Makefile.pc
src/gamescr.c
src/input.h
src/util.h
src/voxscape.c
src/voxscape.h
tools/lutgen.c

index 9770eda..208175a 100644 (file)
@@ -1,5 +1,5 @@
 src = $(wildcard src/*.c) $(wildcard src/pc/*.c)
-ssrc = data/lut.s
+ssrc = $(wildcard src/*.s) data/lut.s
 obj = $(src:.c=.o) $(ssrc:.s=.o)
 dep = $(src:.c=.d)
 bin = gbajam22
index 7981cb4..3adb5c8 100644 (file)
@@ -11,6 +11,8 @@
 #include "sprite.h"
 #include "debug.h"
 #include "level.h"
+#include "voxscape.h"
+#include "data.h"
 
 static int gamescr_start(void);
 static void gamescr_stop(void);
@@ -34,8 +36,8 @@ static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
 static int32_t pos[2], angle;
 static struct voxscape *vox;
 
-#define COLOR_HORIZON  0xcc77ff
-#define COLOR_ZENITH   0x5588cc
+#define COLOR_HORIZON  192
+#define COLOR_ZENITH   255
 
 
 
@@ -46,15 +48,37 @@ struct screen *init_game_screen(void)
 
 static int gamescr_start(void)
 {
+       int i;
+
        gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
 
        vblperf_setcolor(1);
 
-       if(!(vox = vox_create(512, 512))) {
+       pos[0] = pos[1] = 256 << 16;
+
+       if(!(vox = vox_create(512, 512, height_pixels, color_pixels))) {
                panic(get_pc(), "vox_create");
        }
        vox_proj(vox, 45, 1, 250);
 
+       /* 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] = ((r << 8) & 0x7c00) | ((g << 2) & 0x3e0) | (b >> 3);
+       }
+
+       /* setup sky gradient palette */
+       for(i=0; i<64; i++) {
+               int t = i << 8;
+               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] = ((r << 8) & 0x7c00) | ((g << 2) & 0x3e0) | (b >> 3);
+       }
+
        /*select_input(BN_DPAD | BN_LT | BN_RT);*/
 
        nframes = 0;
@@ -91,7 +115,7 @@ static void update(void)
        int32_t fwd[2], right[2];
        uint16_t input;
 
-       input = ~REG_KEYINPUT;
+       input = read_input();
 
        if(input & BN_LT) angle += TURN_SPEED;
        if(input & BN_RT) angle -= TURN_SPEED;
@@ -123,8 +147,10 @@ static void update(void)
 
 static void draw(void)
 {
+//     vox_begin(vox);
        vox_render(vox);
        vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
+       //vox_sky_solid(vox, COLOR_ZENITH);
 }
 
 #ifdef BUILD_GBA
index 3ed22a0..b7694c8 100644 (file)
@@ -21,4 +21,10 @@ enum {
 void select_input(uint16_t bmask);
 uint16_t get_input(void);
 
+#ifdef BUILD_GBA
+#define read_input()   (~REG_KEYINPUT)
+#else
+#define read_input()   get_input()
+#endif
+
 #endif /* INPUT_H_ */
index 3bbafbd..f719b17 100644 (file)
@@ -29,8 +29,14 @@ void present(int buf);               /* defined in src/pc/main.c */
 
 extern int16_t sinlut[];
 
-#define SIN(x) sinlut[(x) & 0xff]
-#define COS(x) sinlut[((x) + 64) & 0xff]
+#define SINLUT_BITS            8
+#define SINLUT_SIZE            (1 << SINLUT_BITS)
+
+#define SIN(angle) \
+       ((int32_t)sinlut[((angle) >> (16 - SINLUT_BITS)) & (SINLUT_SIZE - 1)] << 1)
+
+#define COS(angle) \
+       ((int32_t)sinlut[(((angle) >> (16 - SINLUT_BITS)) + (SINLUT_SIZE / 4)) & (SINLUT_SIZE - 1)] << 1)
 
 int iwram_brk(void *addr);
 void *iwram_sbrk(intptr_t delta);
index 2f2296e..462ed75 100644 (file)
@@ -5,7 +5,6 @@
 #include <math.h>
 #include <assert.h>
 #include "voxscape.h"
-#include "util.h"
 #include "debug.h"
 
 #define XLERP(a, b, t, fp) \
@@ -45,19 +44,15 @@ struct voxscape {
        unsigned int valid;
 };
 
-struct voxscape *vox_create(int xsz, int ysz)
+struct voxscape *vox_create(int xsz, int ysz, uint8_t *himg, uint8_t *cimg)
 {
        struct voxscape *vox;
 
        if(!(vox = calloc(1, sizeof *vox))) {
                return 0;
        }
-       if(!(vox->height = calloc(xsz * ysz, 1))) {
-               panic(get_pc(), "vox_create: failed to allocate %dx%d heightmap\n", xsz, ysz);
-       }
-       if(!(vox->color = calloc(xsz * ysz, 1))) {
-               panic(get_pc(), "vox_create: failed to allocate %dx%d color map\n", xsz, ysz);
-       }
+       vox->height = himg;
+       vox->color = cimg;
        vox->xsz = xsz;
        vox->ysz = ysz;
 
@@ -266,7 +261,7 @@ void vox_render_slice(struct voxscape *vox, int n)
                        color = vox_color(vox, x, y);
                        colstart = vox->fbheight - hval;
                        colheight = hval - vox->coltop[i];
-                       fbptr = vox->fb + colstart * vox->fbwidth + i;
+                       fbptr = vox->fb + colstart * vox->fbwidth / 2 + i / 2;
 
                        for(j=0; j<colheight; j++) {
                                *fbptr = color | ((uint16_t)color << 8);
@@ -315,7 +310,7 @@ void vox_sky_grad(struct voxscape *vox, uint8_t chor, uint8_t ctop)
 
        /* TODO double columns */
        for(i=0; i<vox->fbwidth/2; i++) {
-               fbptr = vox->fb + i;
+               fbptr = vox->fb + i / 2;
                colheight = vox->fbheight - vox->coltop[i];
                for(j=0; j<colheight; j++) {
                        *fbptr = grad[j] | ((uint16_t)grad[j] << 8);
index 56295ed..899ef86 100644 (file)
@@ -10,7 +10,7 @@ enum {
 
 struct voxscape;
 
-struct voxscape *vox_create(int xsz, int ysz);
+struct voxscape *vox_create(int xsz, int ysz, uint8_t *himg, uint8_t *cimg);
 void vox_free(struct voxscape *vox);
 
 /* data argument can be null */
index 70d7641..1dbb47a 100644 (file)
@@ -1,6 +1,9 @@
 #include <stdio.h>
 #include <math.h>
 
+#define SINLUT_SIZE            256
+#define SINLUT_SCALE   32767.0
+
 int main(void)
 {
        int i;
@@ -8,9 +11,10 @@ int main(void)
        puts("\t.data");
        puts("\t.globl sinlut");
        puts("sinlut:");
-       for(i=0; i<256; i++) {
-               float x = sin((float)i / 128.0f * M_PI);
-               printf("\t.short %d\n", (int)(x * 256.0f));
+       for(i=0; i<SINLUT_SIZE; i++) {
+               float t = (float)i / SINLUT_SIZE;
+               float theta = t * (M_PI * 2);
+               printf("\t.short %d\n", (int)(sin(theta) * SINLUT_SCALE));
        }
        return 0;
 }