#include "util.h"
#include "debug.h"
#include "level.h"
+#include "player.h"
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;
}
}
-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;
}
}
}
+/* 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)
/* 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)
{
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];
}
*/
- 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);
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); \