fixed clipping, emuprint for mgba, foo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 11 Sep 2022 23:54:02 +0000 (02:54 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 11 Sep 2022 23:54:02 +0000 (02:54 +0300)
Makefile
src/debug.c
src/gamescr.c
src/level.c
src/level.h
src/player.c
src/player.h
src/xgl.c

index ce12325..4ac7b09 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,9 @@ tools/pngdump/pngdump:
 tools/lutgen: tools/lutgen.c
        cc -o $@ $< -lm
 
+tools/vistab: tools/vistab.c
+       cc -o $@ $< -lm
+
 tools/mmutil/mmutil:
        $(MAKE) -C tools/mmutil
 
index e983ff6..9bdf5d1 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <string.h>
 #include <ctype.h>
 #include <stdarg.h>
 #include "gbaregs.h"
@@ -130,22 +131,40 @@ int dbg_drawstr(int x, int y, const char *fmt, ...)
 }
 
 #ifdef EMUBUILD
-__attribute__((target("arm")))
+#define REG_DBG_ENABLE REG16(0xfff780)
+#define REG_DBG_FLAGS  REG16(0xfff700)
+#define REG_DBG_STR            REG8(0xfff600)
+
+/*__attribute__((target("arm")))*/
 void emuprint(const char *fmt, ...)
 {
+       static int opened;
        char buf[128];
        va_list ap;
 
+       if(!opened) {
+               REG_DBG_ENABLE = 0xc0de;
+               if(REG_DBG_ENABLE != 0x1dea) {
+                       return;
+               }
+               opened = 1;
+       }
+
        va_start(ap, fmt);
        vsnprintf(buf, sizeof buf, fmt, ap);
        va_end(ap);
 
+       strcpy((char*)0x4fff600, buf);
+       REG_DBG_FLAGS = 0x104;  /* debug message */
+
+       /*
        asm volatile(
                "mov r0, %0\n\t"
                "swi 0xff0000\n\t" :
                : "r" (buf)
                : "r0"
        );
+       */
 }
 #else
 void emuprint(const char *fmt, ...)
index 5a2347d..73566c3 100644 (file)
@@ -53,14 +53,14 @@ void gamescr(void)
 
        REG_DISPCNT = 4 | DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1;
 
-       vblperf_setcolor(0xff);
+       vblperf_setcolor(1);
 
        lvl = init_level(testlvl);
 
        xgl_init();
 
        memset(&player, 0, sizeof player);
-       player.y = 0x60000;
+       player.phi = 0x100;
 
        select_input(BN_DPAD | BN_A | BN_B);
 
@@ -94,17 +94,30 @@ static void update(void)
 
        player_input(&player, bnstate);
 
-       upd_vis(lvl, player.x, player.y, player.theta);
+       upd_vis(lvl, &player);
 }
 
 static void draw(void)
 {
+       int i, x, y;
+       struct cell *cell;
+
        xgl_load_identity();
        xgl_rotate_x(player.phi);
        xgl_rotate_y(player.theta);
        xgl_translate(player.x, 0, player.y);
 
-       xgl_draw(XGL_QUADS, tm_floor, sizeof tm_floor / sizeof *tm_floor);
+       for(i=0; i<lvl->numvis; i++) {
+               cell = lvl->vis[i];
+
+               x = (int32_t)(cell->x - player.cx) << 17;
+               y = -(int32_t)(cell->y - player.cy) << 17;
+
+               xgl_push_matrix();
+               xgl_translate(x, 0, y);
+               xgl_draw(XGL_QUADS, tm_floor, sizeof tm_floor / sizeof *tm_floor);
+               xgl_pop_matrix();
+       }
 }
 
 __attribute__((noinline, target("arm"), section(".iwram")))
index 0ae8d3e..d174ba6 100644 (file)
@@ -1,6 +1,7 @@
 #include "util.h"
 #include "debug.h"
 #include "level.h"
+#include "player.h"
 
 struct level *init_level(const char *descstr)
 {
@@ -33,6 +34,8 @@ struct level *init_level(const char *descstr)
        lvl->width = ncols;
        lvl->xmask = ncols - 1;
        lvl->height = nrows;
+       lvl->orgx = lvl->width >> 1;
+       lvl->orgy = lvl->height >> 1;
        lvl->cells = calloc_nf(ncols * nrows, sizeof *lvl->cells);
        lvl->mobs = 0;
        lvl->items = 0;
@@ -75,28 +78,61 @@ void free_level(struct level *lvl)
        }
 }
 
-void upd_vis(struct level *lvl, int32_t px, int32_t py, int32_t angle)
+struct {int dx, dy;} visoffs[8][32] = {
+       /* dir 0 */
+       {{-2,-4}, {2,-4}, {-1,-4}, {1,-4}, {0,-4}, {-1,-3}, {1,-3}, {0,-3}, {-1,-2},
+        {1,-2}, {0,-2}, {0,-1}, {0,0}},
+       /* dir 1 */
+       {{4,-4}, {3,-4}, {4,-3}, {2,-4}, {4,-2}, {3,-3}, {2,-3}, {3,-2}, {1,-3},
+        {3,-1}, {2,-2}, {1,-2}, {2,-1}, {1,-1}, {0,0}},
+       /* dir 2 */
+       {{4,-2}, {4,2}, {4,-1}, {4,1}, {4,0}, {3,-1}, {3,1}, {3,0}, {2,-1}, {2,1},
+        {2,0}, {1,0}, {0,0}},
+       /* dir 3 */
+       {{4,4}, {4,3}, {3,4}, {4,2}, {2,4}, {3,3}, {3,2}, {2,3}, {3,1}, {1,3},
+        {2,2}, {2,1}, {1,2}, {1,1}, {0,0}},
+       /* dir 4 */
+       {{-2,4}, {2,4}, {-1,4}, {1,4}, {0,4}, {-1,3}, {1,3}, {0,3}, {-1,2}, {1,2},
+        {0,2}, {0,1}, {0,0}},
+       /* dir 5 */
+       {{-4,4}, {-4,3}, {-3,4}, {-4,2}, {-2,4}, {-3,3}, {-3,2}, {-2,3}, {-3,1},
+        {-1,3}, {-2,2}, {-2,1}, {-1,2}, {-1,1}, {0,0}},
+       /* dir 6 */
+       {{-4,-2}, {-4,2}, {-4,-1}, {-4,1}, {-4,0}, {-3,-1}, {-3,1}, {-3,0}, {-2,-1},
+        {-2,1}, {-2,0}, {-1,0}, {0,0}},
+       /* dir 7 */
+       {{-4,-4}, {-3,-4}, {-4,-3}, {-2,-4}, {-4,-2}, {-3,-3}, {-2,-3}, {-3,-2},
+        {-1,-3}, {-3,-1}, {-2,-2}, {-1,-2}, {-2,-1}, {-1,-1}, {0,0}}
+};
+
+void upd_vis(struct level *lvl, struct player *p)
 {
-       int cx, cy;
+       int dir, idx;
+       int x, y;
+       struct cell *cptr;
 
-       lvl->numvis = 0;
-
-       pos_to_cell(px, py, &cx, &cy);
+       pos_to_cell(lvl, p->x, p->y, &p->cx, &p->cy);
 
-       /* TODO: cont. */
+       lvl->numvis = 0;
+       idx = -1;
+       dir = 0;        /* TODO use p->theta */
+       do {
+               idx++;
+               x = p->cx + visoffs[dir][idx].dx;
+               y = p->cy + visoffs[dir][idx].dy;
+               cptr = lvl->cells + y * lvl->width + x;
+               lvl->vis[lvl->numvis++] = cptr;
+       } while(visoffs[dir][idx].dx | visoffs[dir][idx].dy);
 }
 
-void cell_to_pos(int cx, int cy, int32_t *px, int32_t *py)
+void cell_to_pos(struct level *lvl, int cx, int cy, int32_t *px, int32_t *py)
 {
-       *px = cx * CELL_SIZE - (CELL_SIZE >> 1);
-       *py = cy * CELL_SIZE - (CELL_SIZE >> 1);
+       *px = (cx - lvl->orgx) * CELL_SIZE;
+       *py = (cy - lvl->orgy) * CELL_SIZE;
 }
 
-void pos_to_cell(int32_t px, int32_t py, int *cx, int *cy)
+void pos_to_cell(struct level *lvl, int32_t px, int32_t py, int *cx, int *cy)
 {
-       _Static_assert((CELL_SIZE & ~0xff) == CELL_SIZE,
-                       "CELL_SIZE >> 8 in pos_to_cell will lose significant bits");
-
-       *cx = ((px + (CELL_SIZE >> 1)) << 8) / (CELL_SIZE >> 8);
-       *cy = ((py + (CELL_SIZE >> 1)) << 8) / (CELL_SIZE >> 8);
+       *cx = (px + (CELL_SIZE >> 1)) / CELL_SIZE + lvl->orgx;
+       *cy = (py + (CELL_SIZE >> 1)) / CELL_SIZE + lvl->orgy;
 }
index 95ab9d9..ed32ce1 100644 (file)
@@ -38,6 +38,7 @@ struct cell {
 
 struct level {
        int width, height;
+       int orgx, orgy;
        unsigned int xmask;
        struct cell *cells;
 
@@ -45,17 +46,18 @@ struct level {
        struct item *items;
 
        /* populated by calc_vis */
-       struct cell **vis;
+       struct cell *vis[128];
        int numvis;
 };
 
+struct player;
 
 struct level *init_level(const char *descstr);
 void free_level(struct level *lvl);
 
-void upd_vis(struct level *lvl, int32_t px, int32_t py, int32_t angle);
+void upd_vis(struct level *lvl, struct player *p);
 
-void cell_to_pos(int cx, int cy, int32_t *px, int32_t *py);
-void pos_to_cell(int32_t px, int32_t py, int *cx, int *cy);
+void cell_to_pos(struct level *lvl, int cx, int cy, int32_t *px, int32_t *py);
+void pos_to_cell(struct level *lvl, int32_t px, int32_t py, int *cx, int *cy);
 
 #endif /* LEVEL_H_ */
index 1264857..d025799 100644 (file)
@@ -21,9 +21,9 @@ void player_input(struct player *p, uint16_t bnstate)
                if(p->theta < X_2PI) p->theta += X_2PI;
        }
        if(bnstate & KEY_A) {
-               p->y += 0x1000;
+               p->y += 0x2000;
        }
        if(bnstate & KEY_B) {
-               p->y -= 0x1000;
+               p->y -= 0x2000;
        }
 }
index 6751691..33abfaf 100644 (file)
@@ -3,9 +3,13 @@
 
 #include <stdint.h>
 
+struct cell;
+
 struct player {
        int32_t x, y;
        int32_t theta, phi;
+       int cx, cy;
+       struct cell *cell;
 };
 
 void player_input(struct player *p, uint16_t bnstate);
index 8f59d90..3efae76 100644 (file)
--- a/src/xgl.c
+++ b/src/xgl.c
@@ -116,6 +116,7 @@ void xgl_mult_matrix(const int32_t *m2)
        }
 }
 
+/* XXX TODO XXX */
 #define XSIN(x)                (int32_t)(sin(x / 65536.0f) * 65536.0f)
 #define XCOS(x)                (int32_t)(cos(x / 65536.0f) * 65536.0f)
 
@@ -191,7 +192,7 @@ static void xform_norm(struct xvertex *out, const struct xvertex *in, const int3
 /* d = 1.0 / tan(fov/2) */
 #define PROJ_D 0x20000
 /* near Z = 0.5 */
-#define NEAR_Z 0x40000
+#define NEAR_Z 0x18000
 
 void xgl_draw(int prim, const struct xvertex *varr, int vcount)
 {
@@ -211,9 +212,6 @@ void xgl_draw(int prim, const struct xvertex *varr, int vcount)
                xform(xv, varr, mat[mtop]);
                xform_norm(xv, varr, mat[mtop]);
 
-               /* backfacing check */
-               if(xv->nz > 0) goto skip_poly;
-
                /*
                if(opt & XGL_LIGHTING) {
                        ndotl = (xv->nx >> 8) * ldir[0] + (xv->ny >> 8) * ldir[1] + (xv->nz >> 8) * ldir[2];
@@ -223,19 +221,18 @@ void xgl_draw(int prim, const struct xvertex *varr, int vcount)
                }
                */
 
-               for(i=0; i<prim; i++) {
-                       if(i > 0) {
-                               xform(xv + i, varr + i, mat[mtop]);
-                       }
-                       xv[i].x = (xv[i].x << 1) / (xv[i].z >> 8);      /* assume aspect: ~2 */
-                       xv[i].y = (xv[i].y << 2) / (xv[i].z >> 8);      /* the shift is * PROJ_D */
-                       /* transform result is 24.8 */
+               /* transform the rest of the vertices to view space */
+               for(i=1; i<prim; i++) {
+                       xform(xv + i, varr + i, mat[mtop]);
                }
 
                /* clip against near plane */
                xgl_clip_near(xvclip, &clipnum, xv, prim);
 
                for(i=0; i<clipnum; i++) {
+                       xvclip[i].x = (xvclip[i].x << 1) / (xvclip[i].z >> 8);  /* assume aspect: ~2 */
+                       xvclip[i].y = (xvclip[i].y << 2) / (xvclip[i].z >> 8);  /* the shift is * PROJ_D */
+                       /* transform result is 24.8 */
                        /* viewport */
                        pv[i].x = (((xvclip[i].x + 0x100) >> 1) * vp[2]) + (vp[0] << 8);
                        pv[i].y = (((0x100 - xvclip[i].y) >> 1) * vp[3]) + (vp[1] << 8);
@@ -293,14 +290,13 @@ void xgl_xyzzy(void)
        mat[mtop][12] = mat[mtop][13] = 0;
 }
 
-/* 24.8 */
 #define ISECT_NEAR(v0, v1)     ((((v0)->z - NEAR_Z) << 8) / ((v0)->z - (v1)->z))
 
 #define LERP_VATTR(res, v0, v1, t) \
        do { \
-               (res)->x = (v0)->x + (((v1)->x - (v0)->x) * (t) >> 8);  \
-               (res)->y = (v0)->y + (((v1)->y - (v0)->y) * (t) >> 8);  \
-               (res)->z = (v0)->z + (((v1)->z - (v0)->nx) >> 8) * (t); \
+               (res)->x = (v0)->x + (((v1)->x - (v0)->x) >> 8) * (t);  \
+               (res)->y = (v0)->y + (((v1)->y - (v0)->y) >> 8) * (t);  \
+               (res)->z = (v0)->z + (((v1)->z - (v0)->z) >> 8) * (t);  \
                (res)->nx = (v0)->nx + (((v1)->nx - (v0)->nx) >> 8) * (t);      \
                (res)->ny = (v0)->ny + (((v1)->ny - (v0)->ny) >> 8) * (t);      \
                (res)->nz = (v0)->nz + (((v1)->nz - (v0)->nz) >> 8) * (t);      \