gba-trycatch

changeset 15:b755fb002f17 tip

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 25 Jun 2014 17:02:48 +0300
parents c398d834d64a
children
files Makefile src/ggen.c src/mesh.c src/mesh.h src/polyfill.c src/polyfill.h src/x3d.c src/x3d.h
diffstat 8 files changed, 209 insertions(+), 74 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Mon Jun 23 10:33:24 2014 +0300
     1.2 +++ b/Makefile	Wed Jun 25 17:02:48 2014 +0300
     1.3 @@ -15,8 +15,8 @@
     1.4  OBJCOPY = $(ARCH)-objcopy
     1.5  EMU = vbam
     1.6  
     1.7 -#opt = -O3 -fomit-frame-pointer -mcpu=arm7tdmi -mtune=arm7tdmi
     1.8 -dbg = -g
     1.9 +opt = -O3 -fomit-frame-pointer -mcpu=arm7tdmi -mtune=arm7tdmi
    1.10 +#dbg = -g
    1.11  
    1.12  CFLAGS = $(opt) $(dbg) -pedantic -Wall -I../gbasys/src
    1.13  LDFLAGS = ../gbasys/libgbasys.a -lm
     2.1 --- a/src/ggen.c	Mon Jun 23 10:33:24 2014 +0300
     2.2 +++ b/src/ggen.c	Wed Jun 25 17:02:48 2014 +0300
     2.3 @@ -17,19 +17,25 @@
     2.4  		*cptr++ = b; \
     2.5  	} while(0)
     2.6  
     2.7 +#define TEXCOORD(u, v) \
     2.8 +	do { \
     2.9 +		*tptr++ = u; \
    2.10 +		*tptr++ = v; \
    2.11 +	} while(0)
    2.12 +
    2.13  int gen_box(struct mesh *m)
    2.14  {
    2.15  	int i;
    2.16 -	int num_faces = 12;
    2.17 -	int num_verts = num_faces * 3;
    2.18 +	int num_faces = 6;
    2.19 +	int num_verts = num_faces * 4;
    2.20  	int32_t v[8][3] = {
    2.21  		{-X1, -X1, -X1}, {X1, -X1, -X1}, {X1, -X1, X1}, {-X1, -X1, X1},
    2.22  		{-X1, X1, -X1}, {X1, X1, -X1}, {X1, X1, X1}, {-X1, X1, X1}
    2.23  	};
    2.24 -	int32_t *vptr, *cptr;
    2.25 +	int32_t *vptr, *cptr, *tptr;
    2.26  
    2.27  
    2.28 -	m->prim = X3D_TRIANGLES;
    2.29 +	m->prim = X3D_QUADS;
    2.30  	m->nverts = num_verts;
    2.31  	if(!(m->verts = malloc(num_verts * 3 * sizeof *m->verts))) {
    2.32  		return -1;
    2.33 @@ -41,71 +47,76 @@
    2.34  	}
    2.35  	cptr = m->colors;
    2.36  
    2.37 +	if(!(m->texcoords = malloc(num_verts * 2 * sizeof *m->texcoords))) {
    2.38 +		return -1;
    2.39 +	}
    2.40 +	tptr = m->texcoords;
    2.41 +
    2.42  	/* -Y */
    2.43  	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.44  	VERTEX(v[1][0], v[1][1], v[1][2]);
    2.45  	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.46 -	for(i=0; i<3; i++) COLOR(32768, 0, 32768);
    2.47 -
    2.48 -	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.49 -	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.50  	VERTEX(v[3][0], v[3][1], v[3][2]);
    2.51 -	for(i=0; i<3; i++) COLOR(65536, 0, 65536);
    2.52 +	TEXCOORD(65536, 0);
    2.53 +	TEXCOORD(0, 0);
    2.54 +	TEXCOORD(0, 65536);
    2.55 +	TEXCOORD(65536, 65536);
    2.56 +	for(i=0; i<4; i++) COLOR(65536, 0, 65536);
    2.57  
    2.58  	/* +Y */
    2.59 +	VERTEX(v[4][0], v[4][1], v[4][2]);
    2.60  	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.61  	VERTEX(v[6][0], v[6][1], v[6][2]);
    2.62  	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.63 -	for(i=0; i<3; i++) COLOR(0, 32768, 0);
    2.64 -
    2.65 -	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.66 -	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.67 -	VERTEX(v[4][0], v[4][1], v[4][2]);
    2.68 -	for(i=0; i<3; i++) COLOR(0, 65536, 0);
    2.69 +	TEXCOORD(0, 0);
    2.70 +	TEXCOORD(0, 65536);
    2.71 +	TEXCOORD(65536, 65536);
    2.72 +	TEXCOORD(65536, 0);
    2.73 +	for(i=0; i<4; i++) COLOR(0, 65536, 0);
    2.74  
    2.75  	/* -Z */
    2.76  	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.77  	VERTEX(v[4][0], v[4][1], v[4][2]);
    2.78  	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.79 -	for(i=0; i<3; i++) COLOR(32768, 32768, 0);
    2.80 -
    2.81 -	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.82 -	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.83  	VERTEX(v[1][0], v[1][1], v[1][2]);
    2.84 -	for(i=0; i<3; i++) COLOR(65536, 65536, 0);
    2.85 +	TEXCOORD(0, 0);
    2.86 +	TEXCOORD(0, 65536);
    2.87 +	TEXCOORD(65536, 65536);
    2.88 +	TEXCOORD(65536, 0);
    2.89 +	for(i=0; i<4; i++) COLOR(65536, 65536, 0);
    2.90  
    2.91  	/* +Z */
    2.92  	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.93  	VERTEX(v[6][0], v[6][1], v[6][2]);
    2.94  	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.95 -	for(i=0; i<3; i++) COLOR(0, 0, 32768);
    2.96 -
    2.97 -	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.98 -	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.99  	VERTEX(v[3][0], v[3][1], v[3][2]);
   2.100 -	for(i=0; i<3; i++) COLOR(0, 0, 65536);
   2.101 +	TEXCOORD(0, 0);
   2.102 +	TEXCOORD(0, 65536);
   2.103 +	TEXCOORD(65536, 65536);
   2.104 +	TEXCOORD(65536, 0);
   2.105 +	for(i=0; i<4; i++) COLOR(0, 0, 65536);
   2.106  
   2.107  	/* +X */
   2.108  	VERTEX(v[1][0], v[1][1], v[1][2]);
   2.109  	VERTEX(v[5][0], v[5][1], v[5][2]);
   2.110  	VERTEX(v[6][0], v[6][1], v[6][2]);
   2.111 -	for(i=0; i<3; i++) COLOR(32768, 0, 0);
   2.112 -
   2.113 -	VERTEX(v[1][0], v[1][1], v[1][2]);
   2.114 -	VERTEX(v[6][0], v[6][1], v[6][2]);
   2.115  	VERTEX(v[2][0], v[2][1], v[2][2]);
   2.116 -	for(i=0; i<3; i++) COLOR(65536, 0, 0);
   2.117 +	TEXCOORD(0, 0);
   2.118 +	TEXCOORD(0, 65536);
   2.119 +	TEXCOORD(65536, 65536);
   2.120 +	TEXCOORD(65536, 0);
   2.121 +	for(i=0; i<4; i++) COLOR(65536, 0, 0);
   2.122  
   2.123  	/* -X */
   2.124  	VERTEX(v[3][0], v[3][1], v[3][2]);
   2.125  	VERTEX(v[7][0], v[7][1], v[7][2]);
   2.126  	VERTEX(v[4][0], v[4][1], v[4][2]);
   2.127 -	for(i=0; i<3; i++) COLOR(0, 32768, 32768);
   2.128 -
   2.129 -	VERTEX(v[3][0], v[3][1], v[3][2]);
   2.130 -	VERTEX(v[4][0], v[4][1], v[4][2]);
   2.131  	VERTEX(v[0][0], v[0][1], v[0][2]);
   2.132 -	for(i=0; i<3; i++) COLOR(0, 65536, 65536);
   2.133 +	TEXCOORD(0, 0);
   2.134 +	TEXCOORD(0, 65536);
   2.135 +	TEXCOORD(65536, 65536);
   2.136 +	TEXCOORD(65536, 0);
   2.137 +	for(i=0; i<4; i++) COLOR(0, 65536, 65536);
   2.138  
   2.139  	return 0;
   2.140  }
     3.1 --- a/src/mesh.c	Mon Jun 23 10:33:24 2014 +0300
     3.2 +++ b/src/mesh.c	Wed Jun 25 17:02:48 2014 +0300
     3.3 @@ -7,6 +7,7 @@
     3.4  	m->prim = X3D_TRIANGLES;
     3.5  	m->verts = 0;
     3.6  	m->colors = 0;
     3.7 +	m->texcoords = 0;
     3.8  	m->nverts = 0;
     3.9  }
    3.10  
    3.11 @@ -14,6 +15,7 @@
    3.12  {
    3.13  	free(m->verts);
    3.14  	free(m->colors);
    3.15 +	free(m->texcoords);
    3.16  }
    3.17  
    3.18  void draw_mesh(struct mesh *m)
    3.19 @@ -22,9 +24,13 @@
    3.20  	if(m->colors) {
    3.21  		x3d_color_array(m->nverts, m->colors);
    3.22  	}
    3.23 +	if(m->texcoords) {
    3.24 +		x3d_texcoord_array(m->nverts, m->texcoords);
    3.25 +	}
    3.26  
    3.27  	x3d_draw(m->prim, m->nverts);
    3.28  
    3.29  	x3d_vertex_array(0, 0);
    3.30  	x3d_color_array(0, 0);
    3.31 +	x3d_texcoord_array(0, 0);
    3.32  }
     4.1 --- a/src/mesh.h	Mon Jun 23 10:33:24 2014 +0300
     4.2 +++ b/src/mesh.h	Wed Jun 25 17:02:48 2014 +0300
     4.3 @@ -9,6 +9,7 @@
     4.4  
     4.5  	int32_t *verts;
     4.6  	int32_t *colors;
     4.7 +	int32_t *texcoords;
     4.8  	int nverts;
     4.9  };
    4.10  
     5.1 --- a/src/polyfill.c	Mon Jun 23 10:33:24 2014 +0300
     5.2 +++ b/src/polyfill.c	Wed Jun 25 17:02:48 2014 +0300
     5.3 @@ -5,14 +5,18 @@
     5.4  #include "fixed.h"
     5.5  #include "gbasys.h"
     5.6  
     5.7 +/* TODO: constant interpolant optimization */
     5.8 +
     5.9  #define VNEXT(x, n)		(((x) + 1) % (n))
    5.10  #define VPREV(x, n)		((x) > 0 ? (x) - 1 : (n) - 1)
    5.11  
    5.12 -static void fill_scanline_pal(int y, int x0, int x1, uint8_t color);
    5.13 -static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color);
    5.14 +static void fill_scanline_pal(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1,
    5.15 +		int32_t v0, int32_t v1, uint8_t color);
    5.16 +static void fill_scanline_rgb(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1,
    5.17 +		int32_t v0, int32_t v1, uint16_t color);
    5.18  static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
    5.19  
    5.20 -void draw_poly(int num, const pvec3 *verts, uint16_t color)
    5.21 +void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color)
    5.22  {
    5.23  	int i, topidx = 0, botidx = 0;
    5.24  	int lidx[2] = {-1, -1}, ridx[2] = {-1, -1};
    5.25 @@ -22,6 +26,8 @@
    5.26  	int start, end;
    5.27  	pvec3 v0, v1;
    5.28  
    5.29 +	int32_t lu, lv, ru, rv, ldudy, ldvdy, rdudy, rdvdy;	/* texture interpolants */
    5.30 +
    5.31  	v0.x = verts[1].x - verts[0].x;
    5.32  	v0.y = verts[1].y - verts[0].y;
    5.33  
    5.34 @@ -63,6 +69,10 @@
    5.35  	}
    5.36  	lx = verts[lidx[0]].x;
    5.37  	ldxdy = x16div(verts[lidx[1]].x - lx, ldy);
    5.38 +	lu = tex[lidx[0]].x;
    5.39 +	ldudy = x16div(tex[lidx[1]].x - lu, ldy);
    5.40 +	lv = tex[lidx[0]].y;
    5.41 +	ldvdy = x16div(tex[lidx[1]].y - lv, ldy);
    5.42  
    5.43  	/* find starting right edge */
    5.44  	ridx[1] = VNEXT(ridx[0], num);
    5.45 @@ -80,6 +90,10 @@
    5.46  	}
    5.47  	rx = verts[ridx[0]].x;
    5.48  	rdxdy = x16div(verts[ridx[1]].x - rx, rdy);
    5.49 +	ru = tex[ridx[0]].x;
    5.50 +	rdudy = x16div(tex[ridx[1]].x - ru, rdy);
    5.51 +	rv = tex[ridx[0]].y;
    5.52 +	rdvdy = x16div(tex[ridx[1]].y - rv, rdy);
    5.53  
    5.54  	start = topy >> 16;
    5.55  	end = boty >> 16;
    5.56 @@ -88,7 +102,6 @@
    5.57  
    5.58  	y = topy;
    5.59  	for(i=start; i<=end; i++) {
    5.60 -		short x0, x1;
    5.61  
    5.62  		if(y >= verts[lidx[1]].y) {
    5.63  			lx = verts[lidx[1]].x;
    5.64 @@ -98,10 +111,18 @@
    5.65  			if(ldy < 0) {
    5.66  				break;
    5.67  			}
    5.68 +
    5.69 +			lu = tex[lidx[0]].x;
    5.70 +			lv = tex[lidx[0]].y;
    5.71 +
    5.72  			if(ldy) {
    5.73  				ldxdy = x16div(verts[lidx[1]].x - lx, ldy);
    5.74 +				ldudy = x16div(tex[lidx[1]].x - lu, ldy);
    5.75 +				ldvdy = x16div(tex[lidx[1]].y - lv, ldy);
    5.76  			} else {
    5.77  				ldxdy = verts[lidx[1]].x - lx;
    5.78 +				ldudy = tex[lidx[1]].x - lu;
    5.79 +				ldvdy = tex[lidx[1]].y - lv;
    5.80  			}
    5.81  		}
    5.82  		if(y >= verts[ridx[1]].y) {
    5.83 @@ -112,81 +133,145 @@
    5.84  			if(rdy < 0) {
    5.85  				break;
    5.86  			}
    5.87 +
    5.88 +			ru = tex[ridx[0]].x;
    5.89 +			rv = tex[ridx[0]].y;
    5.90 +
    5.91  			if(rdy) {
    5.92  				rdxdy = x16div(verts[ridx[1]].x - rx, rdy);
    5.93 +				rdudy = x16div(tex[ridx[1]].x - ru, rdy);
    5.94 +				rdvdy = x16div(tex[ridx[1]].y - rv, rdy);
    5.95  			} else {
    5.96  				rdxdy = verts[ridx[1]].x - rx;
    5.97 +				rdudy = tex[ridx[1]].x - ru;
    5.98 +				rdvdy = tex[ridx[1]].y - rv;
    5.99  			}
   5.100  		}
   5.101  
   5.102 -		x0 = lx >> 16;
   5.103 -		x1 = rx >> 16;
   5.104 -
   5.105 -		if(i >= 0) {// && x0 < x1) {
   5.106 +		if(i >= 0) {
   5.107  #ifdef PALMODE
   5.108 -			fill_scanline_pal(i, x0, x1, (uint8_t)color);
   5.109 +			fill_scanline_pal(i, lx, rx, lu, ru, lv, rv, (uint8_t)color);
   5.110  #else
   5.111 -			fill_scanline_rgb(i, x0, x1, color);
   5.112 +			fill_scanline_rgb(i, lx, rx, lu, ru, lv, rv, color);
   5.113  #endif
   5.114  		}
   5.115  
   5.116  		lx += ldxdy;
   5.117  		rx += rdxdy;
   5.118  		y += 65536;
   5.119 +
   5.120 +		lu += ldudy;
   5.121 +		lv += ldvdy;
   5.122 +		ru += rdudy;
   5.123 +		rv += rdvdy;
   5.124  	}
   5.125  }
   5.126  
   5.127  
   5.128 -static void fill_scanline_pal(int y, int x0, int x1, uint8_t color)
   5.129 +static void fill_scanline_pal(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1,
   5.130 +		int32_t v0, int32_t v1, uint8_t color)
   5.131  {
   5.132 -#if 1
   5.133 -	int i, num_pairs, num_pix = x1 - x0;
   5.134 -	uint16_t *pixels = (uint16_t*)back_buffer->pixels + (y * WIDTH + x0) / 2;
   5.135 +	int ix0, ix1;
   5.136 +	int32_t dx;
   5.137 +	int32_t u, v, dudx, dvdx;
   5.138 +
   5.139 +	int i, num_pairs, num_pix;
   5.140 +	uint16_t *pixels;
   5.141  	uint16_t colpair = (uint16_t)color | ((uint16_t)color << 8);
   5.142  
   5.143 -	if(x0 & 1) {
   5.144 +	if(x0 > x1) {
   5.145 +		int32_t tmp = x0;
   5.146 +		x0 = x1;
   5.147 +		x1 = tmp;
   5.148 +	}
   5.149 +
   5.150 +	dx = x1 - x0;
   5.151 +
   5.152 +	u = u0;
   5.153 +	v = v0;
   5.154 +	if(dx) {
   5.155 +		dudx = x16div(u1 - u0, dx);
   5.156 +		dvdx = x16div(v1 - v0, dx);
   5.157 +	} else {
   5.158 +		dudx = u1 - u0;
   5.159 +		dvdx = v1 - v0;
   5.160 +	}
   5.161 +
   5.162 +	ix0 = (x0 + 32768) >> 16;
   5.163 +	ix1 = (x1 + 32768) >> 16;
   5.164 +
   5.165 +	if(ix0 < 0) ix0 = 0;
   5.166 +	if(ix1 >= WIDTH - 1) ix1 = WIDTH - 1;
   5.167 +
   5.168 +	num_pix = ix1 - ix0;
   5.169 +	pixels = (uint16_t*)back_buffer->pixels + (y * WIDTH + ix0) / 2;
   5.170 +
   5.171 +	if(ix0 & 1) {
   5.172  		uint16_t pix = *pixels & 0xff;
   5.173  		*pixels++ = pix | ((uint16_t)color << 8);
   5.174  		--num_pix;
   5.175 +		u += dudx;
   5.176 +		v += dvdx;
   5.177  	}
   5.178  
   5.179  	num_pairs = (num_pix & 0xfffe) / 2;
   5.180  
   5.181  	for(i=0; i<num_pairs; i++) {
   5.182  		*pixels++ = colpair;
   5.183 +		u += dudx * 2;
   5.184 +		v += dvdx * 2;
   5.185  	}
   5.186  
   5.187  	if(num_pix & 1) {
   5.188  		uint16_t pix = *pixels & 0xff00;
   5.189  		*pixels = pix | color;
   5.190  	}
   5.191 -#else
   5.192 -	int i;
   5.193 -	uint8_t *pixels = (uint8_t*)back_buffer->pixels + y * WIDTH + x0;
   5.194 -
   5.195 -	for(i=x0; i<x1; i++) {
   5.196 -		*pixels++ = color;
   5.197 -	}
   5.198 -#endif
   5.199  }
   5.200  
   5.201 -static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color)
   5.202 +static void fill_scanline_rgb(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1,
   5.203 +		int32_t v0, int32_t v1, uint16_t color)
   5.204  {
   5.205 -	int i;
   5.206 +	int i, ix0, ix1;
   5.207  	uint16_t *pixels;
   5.208 +	int32_t dx;
   5.209 +	int32_t u, v, dudx, dvdx;
   5.210  
   5.211  	if(x0 > x1) {
   5.212 -		i = x0;
   5.213 +		int32_t tmp = x0;
   5.214  		x0 = x1;
   5.215 -		x1 = i;
   5.216 +		x1 = tmp;
   5.217  	}
   5.218  
   5.219 -	if(x0 < 0) x0 = 0;
   5.220 -	if(x1 >= WIDTH - 1) x1 = WIDTH - 1;
   5.221 +	dx = x1 - x0;
   5.222  
   5.223 -	pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0;
   5.224 -	for(i=x0; i<x1; i++) {
   5.225 -		*pixels++ = color;
   5.226 +	u = u0;
   5.227 +	v = v0;
   5.228 +	if(dx) {
   5.229 +		dudx = x16div(u1 - u0, dx);
   5.230 +		dvdx = x16div(v1 - v0, dx);
   5.231 +	} else {
   5.232 +		dudx = u1 - u0;
   5.233 +		dvdx = v1 - v0;
   5.234 +	}
   5.235 +
   5.236 +	ix0 = (x0 + 32768) >> 16;
   5.237 +	ix1 = (x1 + 32768) >> 16;
   5.238 +
   5.239 +	if(ix0 < 0) ix0 = 0;
   5.240 +	if(ix1 >= WIDTH - 1) ix1 = WIDTH - 1;
   5.241 +
   5.242 +	pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + ix0;
   5.243 +	for(i=ix0; i<ix1; i++) {
   5.244 +		/**pixels++ = color;*/
   5.245 +		int cr = u >> 8;
   5.246 +		int cg = v >> 8;
   5.247 +		if(cr > 255) cr = 255;
   5.248 +		if(cg > 255) cg = 255;
   5.249 +
   5.250 +		*pixels++ = RGB(cr, cg, 0);
   5.251 +
   5.252 +		u += dudx;
   5.253 +		v += dvdx;
   5.254  	}
   5.255  }
   5.256  
     6.1 --- a/src/polyfill.h	Mon Jun 23 10:33:24 2014 +0300
     6.2 +++ b/src/polyfill.h	Wed Jun 25 17:02:48 2014 +0300
     6.3 @@ -7,7 +7,11 @@
     6.4  	int32_t x, y, z;
     6.5  } pvec3;
     6.6  
     6.7 -void draw_poly(int num, const pvec3 *verts, uint16_t color);
     6.8 +typedef struct pvec2 {
     6.9 +	int32_t x, y;
    6.10 +} pvec2;
    6.11 +
    6.12 +void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color);
    6.13  
    6.14  void draw_point(const pvec3 *v, uint16_t color);
    6.15  
     7.1 --- a/src/x3d.c	Mon Jun 23 10:33:24 2014 +0300
     7.2 +++ b/src/x3d.c	Wed Jun 25 17:02:48 2014 +0300
     7.3 @@ -17,7 +17,8 @@
     7.4  	int32_t m[12];
     7.5  };
     7.6  
     7.7 -static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout);
     7.8 +static void proc_vertex(const int32_t *vin, const int32_t *cin, const int32_t *tin,
     7.9 +		pvec3 *vout, pvec3 *cout, pvec2 *tout);
    7.10  static int dump_frame(struct pixel_buffer *frame);
    7.11  
    7.12  
    7.13 @@ -39,8 +40,11 @@
    7.14  static unsigned short vertex_count;
    7.15  static const int32_t *color_array;
    7.16  static unsigned short color_count;
    7.17 +static const int32_t *texcoord_array;
    7.18 +static unsigned short texcoord_count;
    7.19  
    7.20  static int32_t im_color[3];
    7.21 +static int32_t im_texcoord[2];
    7.22  static uint8_t im_color_index;
    7.23  
    7.24  void x3d_projection(int fov, int32_t aspect, int32_t nearz, int32_t farz)
    7.25 @@ -163,11 +167,18 @@
    7.26  	color_count = count;
    7.27  }
    7.28  
    7.29 +void x3d_texcoord_array(int count, const int32_t *ptr)
    7.30 +{
    7.31 +	texcoord_array = ptr;
    7.32 +	texcoord_count = count;
    7.33 +}
    7.34 +
    7.35  int x3d_draw(int prim, int vnum)
    7.36  {
    7.37  	int i, j, pverts = prim;
    7.38  	const int32_t *vptr = vertex_array;
    7.39  	const int32_t *cptr = color_array;
    7.40 +	const int32_t *tptr = texcoord_array;
    7.41  #ifndef PALMODE
    7.42  	short cr, cg, cb;
    7.43  #endif
    7.44 @@ -185,14 +196,20 @@
    7.45  				__FUNCTION__, vnum, color_count);
    7.46  		vnum = color_count;
    7.47  	}
    7.48 +	if(texcoord_array && vnum > texcoord_count) {
    7.49 +		logmsg(LOG_DBG, "%s called with vnum=%d, but current texcoord array has %d elements\n",
    7.50 +				__FUNCTION__, vnum, texcoord_count);
    7.51 +		vnum = texcoord_count;
    7.52 +	}
    7.53  
    7.54  	for(i=0; i<vnum; i+=pverts) {
    7.55  		/* process vertices */
    7.56  		pvec3 vpos[4];
    7.57  		pvec3 col[4];
    7.58 +		pvec2 tex[4];
    7.59  
    7.60  		for(j=0; j<pverts; j++) {
    7.61 -			proc_vertex(vptr, cptr, vpos + j, col + j);
    7.62 +			proc_vertex(vptr, cptr, tptr, vpos + j, col + j, tex + j);
    7.63  
    7.64  			if(vpos[j].z <= proj_near) {
    7.65  				goto skip_prim;
    7.66 @@ -200,6 +217,7 @@
    7.67  
    7.68  			vptr += 3;
    7.69  			if(cptr) cptr += 3;
    7.70 +			if(tptr) tptr += 2;
    7.71  		}
    7.72  
    7.73  #ifdef PALMODE
    7.74 @@ -239,7 +257,7 @@
    7.75  
    7.76  		case X3D_TRIANGLES:
    7.77  		case X3D_QUADS:
    7.78 -			draw_poly(pverts, vpos, color);
    7.79 +			draw_poly(pverts, vpos, tex, color);
    7.80  			if(dbg_fill_dump) {
    7.81  				dump_frame(back_buffer);
    7.82  			}
    7.83 @@ -252,7 +270,8 @@
    7.84  	return 0;
    7.85  }
    7.86  
    7.87 -static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout)
    7.88 +static void proc_vertex(const int32_t *vin, const int32_t *cin, const int32_t *tin,
    7.89 +		pvec3 *vout, pvec3 *cout, pvec2 *tout)
    7.90  {
    7.91  	int i;
    7.92  	int32_t tvert[3];
    7.93 @@ -283,6 +302,14 @@
    7.94  		cout->y = im_color[1];
    7.95  		cout->z = im_color[2];
    7.96  	}
    7.97 +
    7.98 +	if(texcoord_array) {
    7.99 +		tout->x = tin[0];
   7.100 +		tout->y = tin[1];
   7.101 +	} else {
   7.102 +		tout->x = im_texcoord[0];
   7.103 +		tout->y = im_texcoord[1];
   7.104 +	}
   7.105  }
   7.106  
   7.107  void x3d_color_index(int cidx)
     8.1 --- a/src/x3d.h	Mon Jun 23 10:33:24 2014 +0300
     8.2 +++ b/src/x3d.h	Wed Jun 25 17:02:48 2014 +0300
     8.3 @@ -23,6 +23,7 @@
     8.4  
     8.5  void x3d_vertex_array(int count, const int32_t *ptr);
     8.6  void x3d_color_array(int count, const int32_t *ptr);
     8.7 +void x3d_texcoord_array(int count, const int32_t *ptr);
     8.8  
     8.9  int x3d_draw(int prim, int vnum);
    8.10  int x3d_draw_indexed(int prim, int count, uint16_t *ptr);