#include <math.h>
#include "xgl.h"
#include "polyfill.h"
+#include "debug.h"
#define MAT_STACK_SIZE 4
static int vp[4];
static int32_t mat[MAT_STACK_SIZE][16];
static int mtop;
+static unsigned int opt;
+static int32_t ldir[3];
void xgl_init(void)
{
xgl_viewport(0, 0, 240, 160);
xgl_load_identity();
+
+ ldir[0] = ldir[1] = 0;
+ ldir[2] = -0x100;
+}
+
+void xgl_enable(unsigned int o)
+{
+ opt |= o;
+}
+
+void xgl_disable(unsigned int o)
+{
+ opt &= ~o;
}
void xgl_viewport(int x, int y, int w, int h)
out->z = XMUL(m[2], in->x) + XMUL(m[6], in->y) + XMUL(m[10], in->z) + m[14];
}
+static void xform_norm(struct xvertex *out, const struct xvertex *in, const int32_t *m)
+{
+ out->nx = XMUL(m[0], in->nx) + XMUL(m[4], in->ny) + XMUL(m[8], in->nz);
+ out->ny = XMUL(m[1], in->nx) + XMUL(m[5], in->ny) + XMUL(m[9], in->nz);
+ out->nz = XMUL(m[2], in->nx) + XMUL(m[6], in->ny) + XMUL(m[10], in->nz);
+}
+
/* d = 1.0 / tan(fov/2) */
-#define PROJ_D 2.0f
+#define PROJ_D 0x20000
void xgl_draw(int prim, const struct xvertex *varr, int vcount)
{
int i, cidx;
struct xvertex xv[4];
struct pvertex pv[4];
+ int32_t ndotl;
while(vcount >= prim) {
cidx = varr->cidx;
- for(i=0; i<prim; i++) {
+
+ xform(xv, varr, mat[mtop]);
+ xform_norm(xv, varr, mat[mtop]);
+
+ if(xv->nz > 0) {
+ /* backface */
+ varr += prim;
+ vcount -= prim;
+ continue;
+ }
+
+ if(opt & XGL_LIGHTING) {
+ ndotl = (xv->nx >> 8) * ldir[0] + (xv->ny >> 8) * ldir[1] + (xv->nz >> 8) * ldir[2];
+ if(ndotl < 0) ndotl = 0;
+ cidx = 128 + (ndotl >> 9);
+ if(cidx > 255) cidx = 255;
+ }
+
+ xv->x = (xv->x << 1) / (xv->z >> 8); /* assume aspect: ~2 */
+ xv->y = (xv->y << 2) / (xv->z >> 8); /* the shift is * PROJ_D */
+ /* projection result is 24.8 */
+ /* viewport */
+ pv->x = (((xv->x + 0x100) >> 1) * vp[2]) + (vp[0] << 8);
+ pv->y = (((0x100 - xv->y) >> 1) * vp[3]) + (vp[1] << 8);
+ varr++;
+
+ for(i=1; i<prim; i++) {
xform(xv + i, varr, mat[mtop]);
- varr++;
- xv[i].x = xv[i].x / (xv[i].z >> 8); /* assume aspect: ~2 */
- xv[i].y = (xv[i].y << 1) / (xv[i].z >> 8);
+ 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 */
/* projection result is 24.8 */
-
/* viewport */
pv[i].x = (((xv[i].x + 0x100) >> 1) * vp[2]) + (vp[0] << 8);
pv[i].y = (((0x100 - xv[i].y) >> 1) * vp[3]) + (vp[1] << 8);
+ varr++;
}
vcount -= prim;