gba-x3dtest

changeset 8:fb0a0d6a8b52

sortof works
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 19 Jun 2014 05:53:46 +0300
parents 158d23956801
children b0ed38f13261
files src/fixed.h src/game.c src/game.h src/main.c src/main_sdl.c src/polyfill.c src/polyfill.h src/x3d.c src/x3d.h
diffstat 9 files changed, 240 insertions(+), 33 deletions(-) [+]
line diff
     1.1 --- a/src/fixed.h	Wed Jun 18 06:20:07 2014 +0300
     1.2 +++ b/src/fixed.h	Thu Jun 19 05:53:46 2014 +0300
     1.3 @@ -11,7 +11,8 @@
     1.4  
     1.5  #define x16mul(a, b)	(int32_t)(((int32_t)(a) >> 8) * ((int32_t)(b) >> 8))
     1.6  /*int32_t x16div(register int32_t num, register int32_t denom);*/
     1.7 -
     1.8  #define x16div(a, b)	(int32_t)(((int64_t)(a) << 16) / (b))
     1.9  
    1.10 +#define x16sq(x)		x16mul(x, x)
    1.11 +
    1.12  #endif	/* FIXED_H_ */
     2.1 --- a/src/game.c	Wed Jun 18 06:20:07 2014 +0300
     2.2 +++ b/src/game.c	Thu Jun 19 05:53:46 2014 +0300
     2.3 @@ -1,29 +1,46 @@
     2.4  #include "config.h"
     2.5  #include "game.h"
     2.6  #include "gbasys.h"
     2.7 -#include "polyfill.h"
     2.8 +#include "x3d.h"
     2.9 +#include "sincos.h"
    2.10 +#include "fixed.h"
    2.11  
    2.12  #define X16INT(x)	((x) << 16)
    2.13  
    2.14 -static const pvec3 poly[] = {
    2.15 -	{X16INT(80), X16INT(10), 0},
    2.16 -	{X16INT(140), X16INT(100), 0},
    2.17 -	{X16INT(40), X16INT(80), 0}
    2.18 +static const int32_t poly[] = {
    2.19 +	X16INT(80), X16INT(10), 0,
    2.20 +	X16INT(140), X16INT(100), 0,
    2.21 +	X16INT(40), X16INT(80), 0
    2.22  };
    2.23 +static const short vcount = sizeof poly / sizeof *poly / 3;
    2.24 +
    2.25 +int game_init(void)
    2.26 +{
    2.27 +	sincos_init();
    2.28 +
    2.29 +	return 0;
    2.30 +}
    2.31  
    2.32  void game_draw(void)
    2.33  {
    2.34 -	int i;
    2.35 +	unsigned long msec = get_millisec();
    2.36 +
    2.37  	clear_buffer(back_buffer, 0);
    2.38  
    2.39 -	draw_poly(3, poly, 0xffff);
    2.40 +	x3d_load_identity();
    2.41 +	x3d_translate(-itox16(WIDTH / 2), -itox16(HEIGHT / 2), 0);
    2.42 +	x3d_rotate((msec / 64) << 16, 0, 0, 65536);
    2.43 +	x3d_translate(itox16(WIDTH / 2), itox16(HEIGHT / 2), 0);
    2.44  
    2.45 -	for(i=0; i<sizeof poly / sizeof *poly; i++) {
    2.46 -		int x = poly[i].x >> 16;
    2.47 -		int y = poly[i].y >> 16;
    2.48 +	x3d_vertex_array(vcount, poly);
    2.49  
    2.50 -		((uint16_t*)back_buffer->pixels)[y * WIDTH + x] = RGB(0, 255, 0);
    2.51 -	}
    2.52 +	x3d_color(65536, 65536, 65536);
    2.53 +	x3d_draw_arrays(X3D_TRIANGLES, vcount);
    2.54 +
    2.55 +	x3d_color(0, 65536, 0);
    2.56 +	x3d_draw_arrays(X3D_POINTS, vcount);
    2.57 +
    2.58 +	x3d_vertex_array(0, 0);
    2.59  
    2.60  	flip();
    2.61  }
     3.1 --- a/src/game.h	Wed Jun 18 06:20:07 2014 +0300
     3.2 +++ b/src/game.h	Thu Jun 19 05:53:46 2014 +0300
     3.3 @@ -1,6 +1,7 @@
     3.4  #ifndef GAME_H_
     3.5  #define GAME_H_
     3.6  
     3.7 +int game_init(void);
     3.8  void game_draw(void);
     3.9  void game_keyb(int key, int pressed);
    3.10  
     4.1 --- a/src/main.c	Wed Jun 18 06:20:07 2014 +0300
     4.2 +++ b/src/main.c	Thu Jun 19 05:53:46 2014 +0300
     4.3 @@ -26,7 +26,9 @@
     4.4  	set_text_writebg(1);
     4.5  	logmsg(LOG_ALL, "please wait...\n");
     4.6  
     4.7 -	sincos_init();
     4.8 +	if(game_init() == -1) {
     4.9 +		return 1;
    4.10 +	}
    4.11  
    4.12  	for(;;) {
    4.13  		/* process events */
     5.1 --- a/src/main_sdl.c	Wed Jun 18 06:20:07 2014 +0300
     5.2 +++ b/src/main_sdl.c	Thu Jun 19 05:53:46 2014 +0300
     5.3 @@ -46,6 +46,11 @@
     5.4  
     5.5  	back_buffer = front_buffer = &bbuf;
     5.6  
     5.7 +	if(game_init() == -1) {
     5.8 +		SDL_Quit();
     5.9 +		return 1;
    5.10 +	}
    5.11 +
    5.12  	for(;;) {
    5.13  		SDL_Event ev;
    5.14  		uint16_t *dest, *src;
     6.1 --- a/src/polyfill.c	Wed Jun 18 06:20:07 2014 +0300
     6.2 +++ b/src/polyfill.c	Thu Jun 19 05:53:46 2014 +0300
     6.3 @@ -96,3 +96,17 @@
     6.4  		*pixels++ = color;
     6.5  	}
     6.6  }
     6.7 +
     6.8 +
     6.9 +void draw_point(const pvec3 *v, uint16_t color)
    6.10 +{
    6.11 +	int x = v->x >> 16;
    6.12 +	int y = v->y >> 16;
    6.13 +	uint16_t *pixels = (uint16_t*)back_buffer->pixels;
    6.14 +
    6.15 +	if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) {
    6.16 +		return;
    6.17 +	}
    6.18 +
    6.19 +	pixels[y * WIDTH + x] = color;
    6.20 +}
     7.1 --- a/src/polyfill.h	Wed Jun 18 06:20:07 2014 +0300
     7.2 +++ b/src/polyfill.h	Thu Jun 19 05:53:46 2014 +0300
     7.3 @@ -9,4 +9,6 @@
     7.4  
     7.5  void draw_poly(int num, const pvec3 *verts, uint16_t color);
     7.6  
     7.7 +void draw_point(const pvec3 *v, uint16_t color);
     7.8 +
     7.9  #endif	/* POLYFILL_H_ */
     8.1 --- a/src/x3d.c	Wed Jun 18 06:20:07 2014 +0300
     8.2 +++ b/src/x3d.c	Thu Jun 19 05:53:46 2014 +0300
     8.3 @@ -2,27 +2,37 @@
     8.4  #include "x3d.h"
     8.5  #include "fixed.h"
     8.6  #include "sincos.h"
     8.7 +#include "logger.h"
     8.8 +#include "polyfill.h"
     8.9 +#include "gbasys.h"
    8.10  
    8.11  #define MAT_STACK_SIZE	4
    8.12  
    8.13  struct matrix {
    8.14 -	int32_t m[3][4];
    8.15 +	int32_t m[12];
    8.16  };
    8.17  
    8.18 +static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout);
    8.19 +
    8.20 +
    8.21  static int32_t proj_fov = M_PI_X16;
    8.22  static int32_t proj_aspect = 65536;
    8.23  static int32_t proj_near = ftox16(0.5);
    8.24  static int32_t proj_far = 500 << 16;
    8.25  
    8.26 -static struct matrix identity = {
    8.27 -	{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}
    8.28 -};
    8.29 +#define ID_INIT {65536, 0, 0, 0, 0, 65536, 0, 0, 0, 0, 65536, 0}
    8.30 +
    8.31 +static struct matrix identity = { ID_INIT };
    8.32  
    8.33  static short mtop;
    8.34 -static struct matrix mstack[MAT_STACK_SIZE] = {
    8.35 -	{{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}},
    8.36 -	{{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}}
    8.37 -};
    8.38 +static struct matrix mstack[MAT_STACK_SIZE] = { {ID_INIT}, {ID_INIT} };
    8.39 +
    8.40 +static const int32_t *vertex_array;
    8.41 +static unsigned short vertex_count;
    8.42 +static const int32_t *color_array;
    8.43 +static unsigned short color_count;
    8.44 +
    8.45 +static int32_t im_color[3];
    8.46  
    8.47  void x3d_projection(int32_t fov, int32_t aspect, int32_t nearz, int32_t farz)
    8.48  {
    8.49 @@ -54,7 +64,7 @@
    8.50  
    8.51  void x3d_load_matrix(int32_t *m)
    8.52  {
    8.53 -	memcpy(mstack[mtop].m[0], m, sizeof *mstack);
    8.54 +	memcpy(mstack[mtop].m, m, sizeof *mstack);
    8.55  }
    8.56  
    8.57  
    8.58 @@ -64,21 +74,174 @@
    8.59  	int i, j;
    8.60  	struct matrix tmp;
    8.61  
    8.62 -	memcpy(tmp.m[0], mstack[mtop].m[0], sizeof tmp);
    8.63 +	memcpy(tmp.m, mstack[mtop].m, sizeof tmp);
    8.64  
    8.65  	for(i=0; i<3; i++) {
    8.66  		for(j=0; j<4; j++) {
    8.67 -			mstack[mtop].m[i][j] = x16mul(tmp.m[0][j], m[M(i, 0)]) +
    8.68 -				x16mul(tmp.m[1][j], m[M(i, 1)]) +
    8.69 -				x16mul(tmp.m[2][j], m[M(i, 2)]) +
    8.70 -				m[M(i, 3)];
    8.71 +			mstack[mtop].m[M(i, j)] =
    8.72 +				x16mul(tmp.m[M(0, j)], m[M(i, 0)]) +
    8.73 +				x16mul(tmp.m[M(1, j)], m[M(i, 1)]) +
    8.74 +				x16mul(tmp.m[M(2, j)], m[M(i, 2)]);
    8.75  		}
    8.76 +		mstack[mtop].m[M(i, 3)] += m[M(i, 3)];
    8.77  	}
    8.78  }
    8.79  
    8.80  void x3d_load_identity(void)
    8.81  {
    8.82 -	memcpy(mstack[mtop].m[0], identity.m[0], sizeof identity);
    8.83 +	memcpy(mstack[mtop].m, identity.m, sizeof identity);
    8.84  }
    8.85  
    8.86 -/* TODO cont... */
    8.87 +void x3d_translate(int32_t x, int32_t y, int32_t z)
    8.88 +{
    8.89 +	int32_t m[] = ID_INIT;
    8.90 +	m[3] = x;
    8.91 +	m[7] = y;
    8.92 +	m[11] = z;
    8.93 +
    8.94 +	x3d_mult_matrix(m);
    8.95 +}
    8.96 +
    8.97 +void x3d_rotate(int32_t deg, int32_t x, int32_t y, int32_t z)
    8.98 +{
    8.99 +	int32_t xform[] = ID_INIT;
   8.100 +
   8.101 +	int32_t angle = x16mul(M_PI_X16, deg) / 180;
   8.102 +	int32_t sina = sin_x16(angle);
   8.103 +	int32_t cosa = cos_x16(angle);
   8.104 +	int32_t one_minus_cosa = 65536 - cosa;
   8.105 +	int32_t nxsq = x16sq(x);
   8.106 +	int32_t nysq = x16sq(y);
   8.107 +	int32_t nzsq = x16sq(z);
   8.108 +
   8.109 +	xform[0] = nxsq + x16mul(65536 - nxsq, cosa);
   8.110 +	xform[4] = x16mul(x16mul(x, y), one_minus_cosa) - x16mul(z, sina);
   8.111 +	xform[8] = x16mul(x16mul(x, z), one_minus_cosa) + x16mul(y, sina);
   8.112 +	xform[1] = x16mul(x16mul(x, y), one_minus_cosa) + x16mul(z, sina);
   8.113 +	xform[5] = nysq + x16mul(65536 - nysq, cosa);
   8.114 +	xform[9] = x16mul(x16mul(y, z), one_minus_cosa) - x16mul(x, sina);
   8.115 +	xform[2] = x16mul(x16mul(x, z), one_minus_cosa) - x16mul(y, sina);
   8.116 +	xform[6] = x16mul(x16mul(y, z), one_minus_cosa) + x16mul(x, sina);
   8.117 +	xform[10] = nzsq + x16mul(65536 - nzsq, cosa);
   8.118 +
   8.119 +	x3d_mult_matrix(xform);
   8.120 +}
   8.121 +
   8.122 +void x3d_scale(int32_t x, int32_t y, int32_t z)
   8.123 +{
   8.124 +	int32_t m[] = ID_INIT;
   8.125 +
   8.126 +	m[0] = x;
   8.127 +	m[5] = y;
   8.128 +	m[10] = z;
   8.129 +
   8.130 +	x3d_mult_matrix(m);
   8.131 +}
   8.132 +
   8.133 +void x3d_vertex_array(int count, const int32_t *ptr)
   8.134 +{
   8.135 +	vertex_array = ptr;
   8.136 +	vertex_count = count;
   8.137 +}
   8.138 +
   8.139 +void x3d_color_array(int count, const int32_t *ptr)
   8.140 +{
   8.141 +	color_array = ptr;
   8.142 +	color_count = count;
   8.143 +}
   8.144 +
   8.145 +int x3d_draw_arrays(int prim, int vnum)
   8.146 +{
   8.147 +	int i, j, pverts = prim;
   8.148 +	const int32_t *vptr = vertex_array;
   8.149 +	const int32_t *cptr = color_array;
   8.150 +	short cr, cg, cb;
   8.151 +
   8.152 +	if(!vertex_array) return -1;
   8.153 +
   8.154 +	if(vnum > vertex_count) {
   8.155 +		logmsg(LOG_DBG, "%s called with vnum=%d, but current vertex array has %d vertices\n",
   8.156 +				__FUNCTION__, vnum, vertex_count);
   8.157 +		vnum = vertex_count;
   8.158 +	}
   8.159 +	if(color_array && vnum > color_count) {
   8.160 +		logmsg(LOG_DBG, "%s called with vnum=%d, but current color array has %d elements\n",
   8.161 +				__FUNCTION__, vnum, color_count);
   8.162 +		vnum = color_count;
   8.163 +	}
   8.164 +
   8.165 +	for(i=0; i<vnum; i+=pverts) {
   8.166 +		/* process vertices */
   8.167 +		pvec3 vpos[4];
   8.168 +		pvec3 col[4];
   8.169 +
   8.170 +		for(j=0; j<pverts; j++) {
   8.171 +			proc_vertex(vptr, cptr, vpos + j, col + j);
   8.172 +			vptr += 3;
   8.173 +			if(cptr) cptr += 3;
   8.174 +		}
   8.175 +
   8.176 +		cr = col[0].x >> 8;
   8.177 +		cg = col[0].y >> 8;
   8.178 +		cb = col[0].z >> 8;
   8.179 +
   8.180 +		if(cr > 255) cr = 255;
   8.181 +		if(cg > 255) cg = 255;
   8.182 +		if(cb > 255) cb = 255;
   8.183 +
   8.184 +		switch(pverts) {
   8.185 +		case X3D_POINTS:
   8.186 +			draw_point(vpos, RGB(cr, cg, cb));
   8.187 +			break;
   8.188 +
   8.189 +		case X3D_LINES:
   8.190 +			break;
   8.191 +
   8.192 +		case X3D_TRIANGLES:
   8.193 +		case X3D_QUADS:
   8.194 +			draw_poly(pverts, vpos, RGB(cr, cg, cb));
   8.195 +			break;
   8.196 +		}
   8.197 +	}
   8.198 +	return 0;
   8.199 +}
   8.200 +
   8.201 +static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout)
   8.202 +{
   8.203 +	int i;
   8.204 +	int32_t tvert[3];
   8.205 +	int32_t *mvmat = mstack[mtop].m;
   8.206 +
   8.207 +	/* transform vertex with current matrix */
   8.208 +	for(i=0; i<3; i++) {
   8.209 +		tvert[i] = x16mul(mvmat[0], vin[0]) +
   8.210 +			x16mul(mvmat[1], vin[1]) +
   8.211 +			x16mul(mvmat[2], vin[2]) +
   8.212 +			mvmat[3];
   8.213 +		mvmat += 4;
   8.214 +	}
   8.215 +
   8.216 +	vout->x = tvert[0];
   8.217 +	vout->y = tvert[1];
   8.218 +	vout->z = tvert[2];
   8.219 +	/*logmsg(LOG_DBG, "%s: (%g %g %g) -> (%g %g %g)\n", __FUNCTION__,
   8.220 +			x16tof(vin[0]), x16tof(vin[1]), x16tof(vin[2]),
   8.221 +			x16tof(vout->x), x16tof(vout->y), x16tof(vout->z));*/
   8.222 +
   8.223 +	if(color_array) {
   8.224 +		cout->x = cin[0];
   8.225 +		cout->y = cin[1];
   8.226 +		cout->z = cin[2];
   8.227 +	} else {
   8.228 +		cout->x = im_color[0];
   8.229 +		cout->y = im_color[1];
   8.230 +		cout->z = im_color[2];
   8.231 +	}
   8.232 +}
   8.233 +
   8.234 +void x3d_color(int32_t r, int32_t g, int32_t b)
   8.235 +{
   8.236 +	im_color[0] = r;
   8.237 +	im_color[1] = g;
   8.238 +	im_color[2] = b;
   8.239 +}
     9.1 --- a/src/x3d.h	Wed Jun 18 06:20:07 2014 +0300
     9.2 +++ b/src/x3d.h	Thu Jun 19 05:53:46 2014 +0300
     9.3 @@ -21,8 +21,10 @@
     9.4  void x3d_rotate(int32_t angle, int32_t x, int32_t y, int32_t z);
     9.5  void x3d_scale(int32_t x, int32_t y, int32_t z);
     9.6  
     9.7 -void x3d_vertex_array(int count, int32_t *ptr);
     9.8 -void x3d_color_array(int count, int32_t *ptr);
     9.9 -int x3d_draw_arrays(int prim);
    9.10 +void x3d_vertex_array(int count, const int32_t *ptr);
    9.11 +void x3d_color_array(int count, const int32_t *ptr);
    9.12 +int x3d_draw_arrays(int prim, int vnum);
    9.13 +
    9.14 +void x3d_color(int32_t r, int32_t g, int32_t b);
    9.15  
    9.16  #endif	/* X3D_H_ */