qmesh.c 5.83 KB
/*
 *	Generate a mesh of quads
 */

#include <stdio.h>
#include <stdlib.h>
#include <gl/image.h>
#include "macros.h"

#define TRUE -1
#define FALSE 0

#define	XMIN	(-200)
#define	XMAX	200
#define	YMIN	(-200)
#define	YMAX	200

#define	TILE_MAXX	36
#define	TILE_MAXY	36

#define VTX_ELS 10 /* x, y, z, s, t, w, r, g, b, a */
#define VX 0
#define VY 1
#define VZ 2
#define VS 3
#define VT 4
#define VW 5
#define VR 6
#define VG 7
#define VB 8
#define VA 9

int dup_color = FALSE;
int dup_texture = FALSE;
char default_file[] = "six.t";
char *inputfile = default_file;

struct Vertex {
	float e[VTX_ELS];	
};

struct Vertex	vtx[4] = {
	{XMIN, YMIN, 0, 0, TC_FRAC_ONE, 1,		255, 0, 0, 255},
	{XMAX, YMIN, 0, TC_FRAC_ONE, TC_FRAC_ONE, 1,	255, 255, 0, 255},
	{XMIN, YMAX, 0, 0, 0, 1,			0, 255, 0, 255},
	{XMAX, YMAX, 0, TC_FRAC_ONE, 0, 1,		0, 0, 255, 255},
};

struct Box_st {
	int smin, tmin, smax, tmax;
	} ;

main(argc, argv)
int	argc;
char	**argv;
{
	int xstep = 1, ystep = 1;
	struct Vertex vx0, vx1, vx2, vx3;
	struct Vertex vy0, vy1, vy2, vy3;
	struct Box_st box_st;
	int	x, y;
	int	s, t;
	float	xdel, ydel;
	int	sdel, tdel;
	int i, j;

	int tex_w, tex_h;


while (--argc) {
        if ((*++argv)[0] == '-') {
        switch ((*argv)[1]) {
        case 'c':       dup_color = TRUE; break;
        case 't':       dup_texture = TRUE; break;
	case 'f':       argc--; argv++;
			inputfile = *argv;
			break;
	case 'x':       argc--; argv++;
                        sscanf( *argv, "%d", &xstep); break;
	case 'y':       argc--; argv++;
                        sscanf( *argv, "%d", &ystep); break;

       }}}

	get_texdim(inputfile, &tex_w, &tex_h);
	do_init();

	xdel = (XMAX-XMIN)/xstep;
	ydel = (YMAX-YMIN)/ystep;
	sdel = (float)tex_w/xstep;
	tdel = (float)tex_h/ystep;

	/* XXX 4/4/4/4 for now */
	/* load tile s,t + 1 for bilinear interpolation */
/*
	if ((sdel+1) > TILE_MAXX || (tdel+1) > TILE_MAXY) {
		fprintf(stderr, "texture tile does not fit\n");
		exit(0);
	}
*/
/* if duplicate texture, modify vertex texture to be 1 less than size */
if (dup_texture) {
	s = (int)((float)TC_FRAC_ONE*(tex_w-2)/(tex_w-1));
	t = (int)((float)TC_FRAC_ONE*(tex_h-2)/(tex_h-1));
	vtx[0].e[VS] = 0; vtx[0].e[VT] = t; 
	vtx[1].e[VS] = s; vtx[1].e[VT] = t; 
	vtx[2].e[VS] = 0; vtx[2].e[VT] = 0; 
	vtx[3].e[VS] = s; vtx[3].e[VT] = 0; 
		}

	vy0 = vtx[0];
	vy1 = vtx[1];
	for (y=1; y<=ystep; y++) {
		ydel = (float)y/ystep;
		lerp_vtx( &vtx[0], &vtx[2], ydel, &vy2);
		lerp_vtx( &vtx[1], &vtx[3], ydel, &vy3);
		vx0 = vy0;
		vx2 = vy2;
	for (x=1; x<=xstep; x++) {
		xdel = (float)x/xstep;
		lerp_vtx( &vy0, &vy1, xdel, &vx1);
		lerp_vtx( &vy2, &vy3, xdel, &vx3);
		if (dup_color) {
			copy_color( &vtx[0], &vx0);
			copy_color( &vtx[1], &vx1);
			copy_color( &vtx[2], &vx2);
			copy_color( &vtx[3], &vx3);
			}
		if (dup_texture) {
			copy_texture( &vtx[0], &vx0);
			copy_texture( &vtx[1], &vx1);
			copy_texture( &vtx[2], &vx2);
			copy_texture( &vtx[3], &vx3);
			}
		sortst(&box_st, &vx0, &vx1, &vx2, &vx3);
		do_tramload(&box_st, tex_w, tex_h);
		do_quad();
		do_vertex( &vx0);
		do_vertex( &vx1);
		do_vertex( &vx2);
		do_vertex( &vx3);
		vx0 = vx1;
		vx2 = vx3;
		}
		vy0 = vy2;
		vy1 = vy3;
		}
}

do_init()
{
	printf("WINDOW\t\t640 480 0x7fff\n\n");
	printf("LD_TEXTURE\t%s\tRGBA4444\n\n", inputfile);
	printf("FRUSTUM\n");
	printf("-0.128 0.128 -0.096 0.096 1.0 32000.0\n\n");
	printf("LD_MATRIX\n");
	printf("1 1 1\n0 0 0\n0 0 -2000\n\n");
	printf("MARK\n");
	printf("CLEAR\t\t0x404040\n");
}

do_quad()
{
	printf("QUAD\n");
}

do_vertex( v)
struct Vertex *v;
{
int i;
	for (i=0; i<VTX_ELS; i++) printf("%d ", (int)v->e[i]);
	printf("0.0 0.0 1.0");
	printf("\n");
}

do_tramload(box, w, h)
struct Box_st *box;
int	w;
int	h;
{
	int	ps, pt;
	int	ds, dt;

/* truncate min and round up max for bilinear */
        ps = tc_image( box->smin, (w-1));
        pt = tc_image( box->tmin, (h-1));
        ds = tc_image( box->smax, (w-1))  + TI_FRAC_MASK;
        dt = tc_image( box->tmax, (h-1))  + TI_FRAC_MASK;
	ps = ps >> TI_FRAC_SHFT;
	pt = pt >> TI_FRAC_SHFT;
	ds = ds >> TI_FRAC_SHFT;
	dt = dt >> TI_FRAC_SHFT;
/* size is +1 for coord subtract */
	ds = ds + 2;
	dt = dt + 2;
	if (ds > w) ds  = w;
	if (dt > h) dt  = h;
	ds -= ps;
	dt -= pt;

/* specify the tile+1, padding will occur during the load */

	printf("LD_TRAM\t%s %d %d %d %d %d\n",
		inputfile, ps, pt, ds, dt, 0);
}

sortst(struct Box_st *box,
	struct Vertex *st0, struct Vertex *st1,
	struct Vertex *st2, struct Vertex *st3)
{
	box->smin = box->smax = st0->e[VS];
	box->smin = (st1->e[VS] < box->smin) ? st1->e[VS] : box->smin;
	box->smax = (st1->e[VS] > box->smax) ? st1->e[VS] : box->smax;
	box->smin = (st2->e[VS] < box->smin) ? st2->e[VS] : box->smin;
	box->smax = (st2->e[VS] > box->smax) ? st2->e[VS] : box->smax;
	box->smin = (st3->e[VS] < box->smin) ? st3->e[VS] : box->smin;
	box->smax = (st3->e[VS] > box->smax) ? st3->e[VS] : box->smax;
	box->tmin = box->tmax = st0->e[VT];
	box->tmin = (st1->e[VT] < box->tmin) ? st1->e[VT] : box->tmin;
	box->tmax = (st1->e[VT] > box->tmax) ? st1->e[VT] : box->tmax;
	box->tmin = (st2->e[VT] < box->tmin) ? st2->e[VT] : box->tmin;
	box->tmax = (st2->e[VT] > box->tmax) ? st2->e[VT] : box->tmax;
	box->tmin = (st3->e[VT] < box->tmin) ? st3->e[VT] : box->tmin;
	box->tmax = (st3->e[VT] > box->tmax) ? st3->e[VT] : box->tmax;

}

get_texdim(char *file, int *w, int *h)
{
	IMAGE	*img;

	if ((img = iopen(file, "r")) == (IMAGE *)NULL) {
		fprintf(stderr, "can't open texture file %s\n", file);
		exit(EXIT_FAILURE);
	}

	*w = img->xsize;
	*h = img->ysize;
}

lerp_vtx( vn, vf, a, vo)
struct Vertex *vn, *vf, *vo;
float a;
{
int i;
for (i=0; i<VTX_ELS; i++) vo->e[i] = vn->e[i] + (vf->e[i] - vn->e[i]) * a;
}
copy_color( vi, vo)
struct Vertex *vi, *vo;
{
	vo->e[VR] = vi->e[VR];
	vo->e[VG] = vi->e[VG];
	vo->e[VB] = vi->e[VB];
	vo->e[VA] = vi->e[VA];
	}
copy_texture( vi, vo)
struct Vertex *vi, *vo;
{
	vo->e[VS] = vi->e[VS];
	vo->e[VT] = vi->e[VT];
	vo->e[VW] = vi->e[VW];
	}