# HG changeset patch # User John Tsiombikas # Date 1403146426 -10800 # Node ID fb0a0d6a8b5271c28e58f7a4918bf95f444ff26f # Parent 158d23956801a53e30137b03a586aa7e27711acd sortof works diff -r 158d23956801 -r fb0a0d6a8b52 src/fixed.h --- a/src/fixed.h Wed Jun 18 06:20:07 2014 +0300 +++ b/src/fixed.h Thu Jun 19 05:53:46 2014 +0300 @@ -11,7 +11,8 @@ #define x16mul(a, b) (int32_t)(((int32_t)(a) >> 8) * ((int32_t)(b) >> 8)) /*int32_t x16div(register int32_t num, register int32_t denom);*/ - #define x16div(a, b) (int32_t)(((int64_t)(a) << 16) / (b)) +#define x16sq(x) x16mul(x, x) + #endif /* FIXED_H_ */ diff -r 158d23956801 -r fb0a0d6a8b52 src/game.c --- a/src/game.c Wed Jun 18 06:20:07 2014 +0300 +++ b/src/game.c Thu Jun 19 05:53:46 2014 +0300 @@ -1,29 +1,46 @@ #include "config.h" #include "game.h" #include "gbasys.h" -#include "polyfill.h" +#include "x3d.h" +#include "sincos.h" +#include "fixed.h" #define X16INT(x) ((x) << 16) -static const pvec3 poly[] = { - {X16INT(80), X16INT(10), 0}, - {X16INT(140), X16INT(100), 0}, - {X16INT(40), X16INT(80), 0} +static const int32_t poly[] = { + X16INT(80), X16INT(10), 0, + X16INT(140), X16INT(100), 0, + X16INT(40), X16INT(80), 0 }; +static const short vcount = sizeof poly / sizeof *poly / 3; + +int game_init(void) +{ + sincos_init(); + + return 0; +} void game_draw(void) { - int i; + unsigned long msec = get_millisec(); + clear_buffer(back_buffer, 0); - draw_poly(3, poly, 0xffff); + x3d_load_identity(); + x3d_translate(-itox16(WIDTH / 2), -itox16(HEIGHT / 2), 0); + x3d_rotate((msec / 64) << 16, 0, 0, 65536); + x3d_translate(itox16(WIDTH / 2), itox16(HEIGHT / 2), 0); - for(i=0; i> 16; - int y = poly[i].y >> 16; + x3d_vertex_array(vcount, poly); - ((uint16_t*)back_buffer->pixels)[y * WIDTH + x] = RGB(0, 255, 0); - } + x3d_color(65536, 65536, 65536); + x3d_draw_arrays(X3D_TRIANGLES, vcount); + + x3d_color(0, 65536, 0); + x3d_draw_arrays(X3D_POINTS, vcount); + + x3d_vertex_array(0, 0); flip(); } diff -r 158d23956801 -r fb0a0d6a8b52 src/game.h --- a/src/game.h Wed Jun 18 06:20:07 2014 +0300 +++ b/src/game.h Thu Jun 19 05:53:46 2014 +0300 @@ -1,6 +1,7 @@ #ifndef GAME_H_ #define GAME_H_ +int game_init(void); void game_draw(void); void game_keyb(int key, int pressed); diff -r 158d23956801 -r fb0a0d6a8b52 src/main.c --- a/src/main.c Wed Jun 18 06:20:07 2014 +0300 +++ b/src/main.c Thu Jun 19 05:53:46 2014 +0300 @@ -26,7 +26,9 @@ set_text_writebg(1); logmsg(LOG_ALL, "please wait...\n"); - sincos_init(); + if(game_init() == -1) { + return 1; + } for(;;) { /* process events */ diff -r 158d23956801 -r fb0a0d6a8b52 src/main_sdl.c --- a/src/main_sdl.c Wed Jun 18 06:20:07 2014 +0300 +++ b/src/main_sdl.c Thu Jun 19 05:53:46 2014 +0300 @@ -46,6 +46,11 @@ back_buffer = front_buffer = &bbuf; + if(game_init() == -1) { + SDL_Quit(); + return 1; + } + for(;;) { SDL_Event ev; uint16_t *dest, *src; diff -r 158d23956801 -r fb0a0d6a8b52 src/polyfill.c --- a/src/polyfill.c Wed Jun 18 06:20:07 2014 +0300 +++ b/src/polyfill.c Thu Jun 19 05:53:46 2014 +0300 @@ -96,3 +96,17 @@ *pixels++ = color; } } + + +void draw_point(const pvec3 *v, uint16_t color) +{ + int x = v->x >> 16; + int y = v->y >> 16; + uint16_t *pixels = (uint16_t*)back_buffer->pixels; + + if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) { + return; + } + + pixels[y * WIDTH + x] = color; +} diff -r 158d23956801 -r fb0a0d6a8b52 src/polyfill.h --- a/src/polyfill.h Wed Jun 18 06:20:07 2014 +0300 +++ b/src/polyfill.h Thu Jun 19 05:53:46 2014 +0300 @@ -9,4 +9,6 @@ void draw_poly(int num, const pvec3 *verts, uint16_t color); +void draw_point(const pvec3 *v, uint16_t color); + #endif /* POLYFILL_H_ */ diff -r 158d23956801 -r fb0a0d6a8b52 src/x3d.c --- a/src/x3d.c Wed Jun 18 06:20:07 2014 +0300 +++ b/src/x3d.c Thu Jun 19 05:53:46 2014 +0300 @@ -2,27 +2,37 @@ #include "x3d.h" #include "fixed.h" #include "sincos.h" +#include "logger.h" +#include "polyfill.h" +#include "gbasys.h" #define MAT_STACK_SIZE 4 struct matrix { - int32_t m[3][4]; + int32_t m[12]; }; +static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout); + + static int32_t proj_fov = M_PI_X16; static int32_t proj_aspect = 65536; static int32_t proj_near = ftox16(0.5); static int32_t proj_far = 500 << 16; -static struct matrix identity = { - {{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}} -}; +#define ID_INIT {65536, 0, 0, 0, 0, 65536, 0, 0, 0, 0, 65536, 0} + +static struct matrix identity = { ID_INIT }; static short mtop; -static struct matrix mstack[MAT_STACK_SIZE] = { - {{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}}, - {{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}} -}; +static struct matrix mstack[MAT_STACK_SIZE] = { {ID_INIT}, {ID_INIT} }; + +static const int32_t *vertex_array; +static unsigned short vertex_count; +static const int32_t *color_array; +static unsigned short color_count; + +static int32_t im_color[3]; void x3d_projection(int32_t fov, int32_t aspect, int32_t nearz, int32_t farz) { @@ -54,7 +64,7 @@ void x3d_load_matrix(int32_t *m) { - memcpy(mstack[mtop].m[0], m, sizeof *mstack); + memcpy(mstack[mtop].m, m, sizeof *mstack); } @@ -64,21 +74,174 @@ int i, j; struct matrix tmp; - memcpy(tmp.m[0], mstack[mtop].m[0], sizeof tmp); + memcpy(tmp.m, mstack[mtop].m, sizeof tmp); for(i=0; i<3; i++) { for(j=0; j<4; j++) { - mstack[mtop].m[i][j] = x16mul(tmp.m[0][j], m[M(i, 0)]) + - x16mul(tmp.m[1][j], m[M(i, 1)]) + - x16mul(tmp.m[2][j], m[M(i, 2)]) + - m[M(i, 3)]; + mstack[mtop].m[M(i, j)] = + x16mul(tmp.m[M(0, j)], m[M(i, 0)]) + + x16mul(tmp.m[M(1, j)], m[M(i, 1)]) + + x16mul(tmp.m[M(2, j)], m[M(i, 2)]); } + mstack[mtop].m[M(i, 3)] += m[M(i, 3)]; } } void x3d_load_identity(void) { - memcpy(mstack[mtop].m[0], identity.m[0], sizeof identity); + memcpy(mstack[mtop].m, identity.m, sizeof identity); } -/* TODO cont... */ +void x3d_translate(int32_t x, int32_t y, int32_t z) +{ + int32_t m[] = ID_INIT; + m[3] = x; + m[7] = y; + m[11] = z; + + x3d_mult_matrix(m); +} + +void x3d_rotate(int32_t deg, int32_t x, int32_t y, int32_t z) +{ + int32_t xform[] = ID_INIT; + + int32_t angle = x16mul(M_PI_X16, deg) / 180; + int32_t sina = sin_x16(angle); + int32_t cosa = cos_x16(angle); + int32_t one_minus_cosa = 65536 - cosa; + int32_t nxsq = x16sq(x); + int32_t nysq = x16sq(y); + int32_t nzsq = x16sq(z); + + xform[0] = nxsq + x16mul(65536 - nxsq, cosa); + xform[4] = x16mul(x16mul(x, y), one_minus_cosa) - x16mul(z, sina); + xform[8] = x16mul(x16mul(x, z), one_minus_cosa) + x16mul(y, sina); + xform[1] = x16mul(x16mul(x, y), one_minus_cosa) + x16mul(z, sina); + xform[5] = nysq + x16mul(65536 - nysq, cosa); + xform[9] = x16mul(x16mul(y, z), one_minus_cosa) - x16mul(x, sina); + xform[2] = x16mul(x16mul(x, z), one_minus_cosa) - x16mul(y, sina); + xform[6] = x16mul(x16mul(y, z), one_minus_cosa) + x16mul(x, sina); + xform[10] = nzsq + x16mul(65536 - nzsq, cosa); + + x3d_mult_matrix(xform); +} + +void x3d_scale(int32_t x, int32_t y, int32_t z) +{ + int32_t m[] = ID_INIT; + + m[0] = x; + m[5] = y; + m[10] = z; + + x3d_mult_matrix(m); +} + +void x3d_vertex_array(int count, const int32_t *ptr) +{ + vertex_array = ptr; + vertex_count = count; +} + +void x3d_color_array(int count, const int32_t *ptr) +{ + color_array = ptr; + color_count = count; +} + +int x3d_draw_arrays(int prim, int vnum) +{ + int i, j, pverts = prim; + const int32_t *vptr = vertex_array; + const int32_t *cptr = color_array; + short cr, cg, cb; + + if(!vertex_array) return -1; + + if(vnum > vertex_count) { + logmsg(LOG_DBG, "%s called with vnum=%d, but current vertex array has %d vertices\n", + __FUNCTION__, vnum, vertex_count); + vnum = vertex_count; + } + if(color_array && vnum > color_count) { + logmsg(LOG_DBG, "%s called with vnum=%d, but current color array has %d elements\n", + __FUNCTION__, vnum, color_count); + vnum = color_count; + } + + for(i=0; i> 8; + cg = col[0].y >> 8; + cb = col[0].z >> 8; + + if(cr > 255) cr = 255; + if(cg > 255) cg = 255; + if(cb > 255) cb = 255; + + switch(pverts) { + case X3D_POINTS: + draw_point(vpos, RGB(cr, cg, cb)); + break; + + case X3D_LINES: + break; + + case X3D_TRIANGLES: + case X3D_QUADS: + draw_poly(pverts, vpos, RGB(cr, cg, cb)); + break; + } + } + return 0; +} + +static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout) +{ + int i; + int32_t tvert[3]; + int32_t *mvmat = mstack[mtop].m; + + /* transform vertex with current matrix */ + for(i=0; i<3; i++) { + tvert[i] = x16mul(mvmat[0], vin[0]) + + x16mul(mvmat[1], vin[1]) + + x16mul(mvmat[2], vin[2]) + + mvmat[3]; + mvmat += 4; + } + + vout->x = tvert[0]; + vout->y = tvert[1]; + vout->z = tvert[2]; + /*logmsg(LOG_DBG, "%s: (%g %g %g) -> (%g %g %g)\n", __FUNCTION__, + x16tof(vin[0]), x16tof(vin[1]), x16tof(vin[2]), + x16tof(vout->x), x16tof(vout->y), x16tof(vout->z));*/ + + if(color_array) { + cout->x = cin[0]; + cout->y = cin[1]; + cout->z = cin[2]; + } else { + cout->x = im_color[0]; + cout->y = im_color[1]; + cout->z = im_color[2]; + } +} + +void x3d_color(int32_t r, int32_t g, int32_t b) +{ + im_color[0] = r; + im_color[1] = g; + im_color[2] = b; +} diff -r 158d23956801 -r fb0a0d6a8b52 src/x3d.h --- a/src/x3d.h Wed Jun 18 06:20:07 2014 +0300 +++ b/src/x3d.h Thu Jun 19 05:53:46 2014 +0300 @@ -21,8 +21,10 @@ void x3d_rotate(int32_t angle, int32_t x, int32_t y, int32_t z); void x3d_scale(int32_t x, int32_t y, int32_t z); -void x3d_vertex_array(int count, int32_t *ptr); -void x3d_color_array(int count, int32_t *ptr); -int x3d_draw_arrays(int prim); +void x3d_vertex_array(int count, const int32_t *ptr); +void x3d_color_array(int count, const int32_t *ptr); +int x3d_draw_arrays(int prim, int vnum); + +void x3d_color(int32_t r, int32_t g, int32_t b); #endif /* X3D_H_ */