From: John Tsiombikas Date: Sun, 11 Sep 2022 23:54:02 +0000 (+0300) Subject: fixed clipping, emuprint for mgba, foo X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=gbajam22;a=commitdiff_plain;h=5e41feadc19dbc9cda954543cf2b2649ced835b4 fixed clipping, emuprint for mgba, foo --- diff --git a/Makefile b/Makefile index ce12325..4ac7b09 100644 --- 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 diff --git a/src/debug.c b/src/debug.c index e983ff6..9bdf5d1 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,4 +1,5 @@ #include +#include #include #include #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, ...) diff --git a/src/gamescr.c b/src/gamescr.c index 5a2347d..73566c3 100644 --- a/src/gamescr.c +++ b/src/gamescr.c @@ -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; inumvis; 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"))) diff --git a/src/level.c b/src/level.c index 0ae8d3e..d174ba6 100644 --- a/src/level.c +++ b/src/level.c @@ -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; } diff --git a/src/level.h b/src/level.h index 95ab9d9..ed32ce1 100644 --- a/src/level.h +++ b/src/level.h @@ -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_ */ diff --git a/src/player.c b/src/player.c index 1264857..d025799 100644 --- a/src/player.c +++ b/src/player.c @@ -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; } } diff --git a/src/player.h b/src/player.h index 6751691..33abfaf 100644 --- a/src/player.h +++ b/src/player.h @@ -3,9 +3,13 @@ #include +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); diff --git a/src/xgl.c b/src/xgl.c index 8f59d90..3efae76 100644 --- 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 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> 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); \