From: John Tsiombikas Date: Mon, 8 Aug 2022 03:33:16 +0000 (+0300) Subject: foo X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=gbajam22;a=commitdiff_plain;h=ff8e2d7dab918d2e303f941fad00dee6bb80544e foo --- diff --git a/src/gamescr.c b/src/gamescr.c index 3b15a4a..dcceb20 100644 --- a/src/gamescr.c +++ b/src/gamescr.c @@ -6,6 +6,7 @@ #include "util.h" #include "intr.h" #include "input.h" +#include "player.h" #include "sprite.h" #include "debug.h" #include "level.h" @@ -33,43 +34,18 @@ static const char *testlvl = "#### ###\n" "########\n"; -static struct xvertex cube[] __attribute__((section(".rodata"))) = { - /* front */ - {-0x10000, -0x10000, -0x10000, 0, 0, -0x10000, 255}, - {0x10000, -0x10000, -0x10000, 0, 0, -0x10000, 255}, - {0x10000, 0x10000, -0x10000, 0, 0, -0x10000, 255}, - {-0x10000, 0x10000, -0x10000, 0, 0, -0x10000, 255}, - /* right */ - {0x10000, -0x10000, -0x10000, 0x10000, 0, 0, 128}, - {0x10000, -0x10000, 0x10000, 0x10000, 0, 0, 128}, - {0x10000, 0x10000, 0x10000, 0x10000, 0, 0, 128}, - {0x10000, 0x10000, -0x10000, 0x10000, 0, 0, 128}, - /* back */ - {0x10000, -0x10000, 0x10000, 0, 0, 0x10000, 200}, - {-0x10000, -0x10000, 0x10000, 0, 0, 0x10000, 200}, - {-0x10000, 0x10000, 0x10000, 0, 0, 0x10000, 200}, - {0x10000, 0x10000, 0x10000, 0, 0, 0x10000, 200}, - /* left */ - {-0x10000, -0x10000, 0x10000, -0x10000, 0, 0, 192}, - {-0x10000, -0x10000, -0x10000, -0x10000, 0, 0, 192}, - {-0x10000, 0x10000, -0x10000, -0x10000, 0, 0, 192}, - {-0x10000, 0x10000, 0x10000, -0x10000, 0, 0, 192}, - /* top */ - {-0x10000, 0x10000, -0x10000, 0, 0x10000, 0, 150}, - {0x10000, 0x10000, -0x10000, 0, 0x10000, 0, 150}, - {0x10000, 0x10000, 0x10000, 0, 0x10000, 0, 150}, - {-0x10000, 0x10000, 0x10000, 0, 0x10000, 0, 150}, - /* bottom */ - {0x10000, -0x10000, -0x10000, 0, -0x10000, 0, 210}, - {-0x10000, -0x10000, -0x10000, 0, -0x10000, 0, 210}, - {-0x10000, -0x10000, 0x10000, 0, -0x10000, 0, 210}, - {0x10000, -0x10000, 0x10000, 0, -0x10000, 0, 210} +static struct xvertex tm_floor[] __attribute__((section(".rodata"))) = { + {0x10000, -0x10000, 0x10000, 0, 0x10000, 0, 210}, + {-0x10000, -0x10000, 0x10000, 0, 0x10000, 0, 210}, + {-0x10000, -0x10000, -0x10000, 0, 0x10000, 0, 210}, + {0x10000, -0x10000, -0x10000, 0, 0x10000, 0, 210} }; static struct level *lvl; -static int32_t cam_theta, cam_phi; +static struct player player; + void gamescr(void) { @@ -83,7 +59,10 @@ void gamescr(void) xgl_init(); - select_input(BN_DPAD); + memset(&player, 0, sizeof player); + player.y = 0x60000; + + select_input(BN_DPAD | BN_A | BN_B); mask(INTR_VBLANK); screen_vblank = vblank; @@ -113,33 +92,17 @@ static void update(void) bnstate = get_input(); - if(bnstate & KEY_UP) { - cam_phi += 0x2000; - if(cam_phi > X_HPI) cam_phi = X_HPI; - } - if(bnstate & KEY_DOWN) { - cam_phi -= 0x2000; - if(cam_phi < -X_HPI) cam_phi = -X_HPI; - } - if(bnstate & KEY_LEFT) { - cam_theta += 0x2000; - if(cam_theta > X_2PI) cam_theta -= X_2PI; - } - if(bnstate & KEY_RIGHT) { - cam_theta -= 0x2000; - if(cam_theta < X_2PI) cam_theta += X_2PI; - } + player_input(&player, bnstate); } static void draw(void) { xgl_load_identity(); - //xgl_translate(0, -0x50000, 0); - xgl_translate(0, 0, 0x80000); - xgl_rotate_x(cam_phi); - xgl_rotate_y(cam_theta); + xgl_rotate_x(player.phi); + xgl_rotate_y(player.theta); + xgl_translate(player.x, 0, player.y); - xgl_draw(XGL_QUADS, cube, sizeof cube / sizeof *cube); + xgl_draw(XGL_QUADS, tm_floor, sizeof tm_floor / sizeof *tm_floor); } __attribute__((noinline, target("arm"), section(".iwram"))) diff --git a/src/player.c b/src/player.c new file mode 100644 index 0000000..62c9813 --- /dev/null +++ b/src/player.c @@ -0,0 +1,29 @@ +#include "player.h" +#include "gbaregs.h" +#include "xgl.h" + +void player_input(struct player *p, uint16_t bnstate) +{ + if(bnstate & KEY_UP) { + p->phi += 0x2000; + if(p->phi > X_HPI) p->phi = X_HPI; + } + if(bnstate & KEY_DOWN) { + p->phi -= 0x2000; + if(p->phi < -X_HPI) p->phi = -X_HPI; + } + if(bnstate & KEY_LEFT) { + p->theta += 0x2000; + if(p->theta > X_2PI) p->theta -= X_2PI; + } + if(bnstate & KEY_RIGHT) { + p->theta -= 0x2000; + if(p->theta < X_2PI) p->theta += X_2PI; + } + if(bnstate & KEY_A) { + p->y += 0x1000; + } + if(bnstate & KEY_B) { + p->y -= 0x1000; + } +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..6751691 --- /dev/null +++ b/src/player.h @@ -0,0 +1,13 @@ +#ifndef PLAYER_H_ +#define PLAYER_H_ + +#include + +struct player { + int32_t x, y; + int32_t theta, phi; +}; + +void player_input(struct player *p, uint16_t bnstate); + +#endif /* PLAYER_H_ */ diff --git a/src/polyfill.c b/src/polyfill.c index 18294f5..5b70987 100644 --- a/src/polyfill.c +++ b/src/polyfill.c @@ -1,6 +1,6 @@ /* -blender for the Gameboy Advance -Copyright (C) 2021 John Tsiombikas +gbajam22 entry for the Gameboy Advance +Copyright (C) 2022 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/polyfill.h b/src/polyfill.h index 88166cf..1afce36 100644 --- a/src/polyfill.h +++ b/src/polyfill.h @@ -1,6 +1,6 @@ /* -blender for the Gameboy Advance -Copyright (C) 2021 John Tsiombikas +gbajam22 entry for the Gameboy Advance +Copyright (C) 2022 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/xgl.c b/src/xgl.c index deccdea..48db220 100644 --- a/src/xgl.c +++ b/src/xgl.c @@ -1,6 +1,6 @@ /* -blender for the Gameboy Advance -Copyright (C) 2021 John Tsiombikas +gbajam22 entry for the Gameboy Advance +Copyright (C) 2022 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -190,6 +190,8 @@ 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 0x10000 void xgl_draw(int prim, const struct xvertex *varr, int vcount) { @@ -204,47 +206,45 @@ void xgl_draw(int prim, const struct xvertex *varr, int vcount) } while(vcount >= prim) { - cidx = varr->cidx; + cidx = 0xff;//varr->cidx; xform(xv, varr, mat[mtop]); xform_norm(xv, varr, mat[mtop]); - if(xv->nz > 0) { - /* backface */ - varr += prim; - vcount -= prim; - continue; - } + /* 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]; 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 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 */ - /* projection result is 24.8 */ + /* transform result is 24.8 */ + } + + /* clip against near plane */ + + + for(i=0; i> 1) * vp[2]) + (vp[0] << 8); pv[i].y = (((0x100 - xv[i].y) >> 1) * vp[3]) + (vp[1] << 8); - varr++; } - vcount -= prim; polyfill_flat(pv, prim, cidx); +skip_poly: + varr += prim; + vcount -= prim; } } @@ -284,7 +284,7 @@ static void draw_ptlines(int prim, const struct xvertex *varr, int vcount) #ifndef ALT_LCLIP clip_line((int*)&xv[0].x, (int*)&xv[0].y, (int*)&xv[1].x, (int*)&xv[1].y, vp[0], vp[1], vp[2] - 1, vp[3] - 1); #endif - draw_line(xv[0].x, xv[0].y, xv[1].x, xv[1].y, varr[-2].cidx); + draw_line(xv[0].x, xv[0].y, xv[1].x, xv[1].y, 0xff); } } @@ -292,3 +292,83 @@ void xgl_xyzzy(void) { mat[mtop][12] = mat[mtop][13] = 0; } + +#define ISECT_NEAR(v0, v1) ((((v0)->z - NEAR_Z) << 8) / (((v0)->z - (v1)->z) >> 8)) + +#define LERP_VATTR(res, v0, v1, t) \ + do { \ + (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); \ + (res)->tx = (v0)->tx + (((v1)->tx - (v0)->tx) >> 8) * (t); \ + (res)->ty = (v0)->ty + (((v1)->ty - (v0)->ty) >> 8) * (t); \ + (res)->lit = (v0)->lit + (((v1)->lit - (v0)->lit) >> 8) * (t); \ + } while(0) + +static int clip_edge_near(struct xvertex *poly, int *vnumptr, struct xvertex *v0, struct xvertex *v1) +{ + int vnum = *vnumptr; + int in0, in1; + int32_t t; + struct xvertex *vptr; + + in0 = v0->z >= NEAR_Z ? 1 : 0; + in1 = v1->z >= NEAR_Z ? 1 : 0; + + if(in0) { + /* start inside */ + if(in1) { + /* all inside */ + poly[vnum++] = *v1; /* append v1 */ + *vnumptr = vnum; + return 1; + } else { + /* going out */ + vptr = poly + vnum; + t = ISECT_NEAR(v0, v1); /* 24:8 */ + LERP_VATTR(vptr, v0, v1, t); + ++vnum; /* append new vertex on the intersection point */ + } + } else { + /* start outside */ + if(in1) { + /* going in */ + vptr = poly + vnum; + t = ISECT_NEAR(v0, v1); + LERP_VATTR(vptr, v0, v1, t); + ++vnum; /* append new vertex ... */ + /* then append v1 */ + poly[vnum++] = *v1; + } else { + /* all outside */ + return -1; + } + } + + *vnumptr = vnum; + return 0; +} + +/* special case near-plane clipper */ +int xgl_clip_near(struct xvertex *vout, int *voutnum, struct xvertex *vin, int vnum) +{ + int i, nextidx, res; + int edges_clipped = 0; + + *voutnum = 0; + + for(i=0; i= vnum) nextidx = 0; + res = clip_edge_near(vout, voutnum, vin + i, vin + nextidx); + if(res == 0) { + ++edges_clipped; + } + } + + if(*voutnum <= 0) return -1; + return edges_clipped > 0 ? 0 : 1; +} diff --git a/src/xgl.h b/src/xgl.h index eba42b5..9a2308b 100644 --- a/src/xgl.h +++ b/src/xgl.h @@ -1,6 +1,6 @@ /* -blender for the Gameboy Advance -Copyright (C) 2021 John Tsiombikas +gbajam22 entry for the Gameboy Advance +Copyright (C) 2022 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,7 +37,8 @@ enum { struct xvertex { int32_t x, y, z; int32_t nx, ny, nz; - unsigned char cidx; + int32_t tx, ty; + int32_t lit; }; void xgl_init(void);