a little easier to read

This commit is contained in:
Bill Currie 2004-02-05 23:46:21 +00:00
parent 3764497143
commit 3f91157b26

View file

@ -18,7 +18,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "config.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -36,6 +36,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "QF/sys.h" #include "QF/sys.h"
#include "QF/zone.h" #include "QF/zone.h"
#include "compat.h"
#define PROGNAME "bsp2img" #define PROGNAME "bsp2img"
#define V_MAJOR 0 #define V_MAJOR 0
#define V_MINOR 0 #define V_MINOR 0
@ -50,6 +52,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define Y point[1] #define Y point[1]
#define Z point[2] #define Z point[2]
#define SUB(a,b,c) ((c).X = (a).X - (b).X, \
(c).Y = (a).Y - (b).Y, \
(c).Z = (a).Z - (b).Z)
#define DOT(a,b) ((a).X * (b).X + (a).Y * (b).Y + (a).Z * (b).Z)
#define CROSS(a,b,c) ((c).X = (a).Y * (b).Z - (a).Z * (b).Y, \
(c).Y = (a).Z * (b).X - (a).X * (b).Z, \
(c).Z = (a).X * (b).Y - (a).Y * (b).X)
/* /*
Thanks fly to Id for a hackable game! :) Thanks fly to Id for a hackable game! :)
*/ */
@ -95,6 +105,8 @@ typedef struct {
long height; long height;
} image_t; } image_t;
struct options_t options;
static void static void
show_help (void) show_help (void)
{ {
@ -126,7 +138,7 @@ show_help (void)
} }
static void static void
plotpoint (image_t * image, long xco, long yco, unsigned int color) plotpoint (image_t *image, long xco, long yco, unsigned int color)
{ {
unsigned int bigcol = 0; unsigned int bigcol = 0;
@ -135,12 +147,9 @@ plotpoint (image_t * image, long xco, long yco, unsigned int color)
bigcol = (unsigned int) image->image[yco * image->width + xco]; bigcol = (unsigned int) image->image[yco * image->width + xco];
bigcol = bigcol + color; bigcol += color;
if (bigcol < 0) bigcol = bound (0, bigcol, 255);
bigcol = 0;
if (bigcol > 255)
bigcol = 255;
image->image[yco * image->width + xco] = (eightbit) bigcol; image->image[yco * image->width + xco] = (eightbit) bigcol;
@ -478,14 +487,32 @@ show_options (struct options_t *opt)
return; return;
} }
int static image_t *
main (int argc, char *argv[]) create_image (long width, long height)
{
long size;
image_t *image;
image = malloc (sizeof (image_t));
image->width = width;
image->height = height;
size = sizeof (eightbit) * width * height;
if (!(image->image = malloc (size))) {
fprintf (stderr, "Error allocating image buffer %ldx%ld.\n",
width, height);
exit (2);
}
printf ("Allocated buffer %ldx%ld for image.\n", width, height);
memset (image->image, 0, size);
return image;
}
static image_t *
render_map (bsp_t *bsp)
{ {
QFile *bspfile = NULL;
QFile *outfile = NULL;
long i = 0, j = 0, k = 0, x = 0; long i = 0, j = 0, k = 0, x = 0;
dvertex_t *vertexlist; dvertex_t *vertexlist, *vert1, *vert2;
dedge_t *edgelist; dedge_t *edgelist;
dface_t *facelist; dface_t *facelist;
int *ledges; int *ledges;
@ -501,31 +528,8 @@ main (int argc, char *argv[])
long Z_Xdir = 1, Z_Ydir = -1; long Z_Xdir = 1, Z_Ydir = -1;
image_t *image; image_t *image;
struct options_t options;
int drawcol; int drawcol;
bsp_t *bsp;
/* Enough args? */
if (argc < 3) {
show_help ();
return 1;
}
/* Setup options */
def_options (&options);
get_options (&options, argc, argv);
show_options (&options);
bspfile = Qopen (options.bspf_name, "rbz");
if (bspfile == NULL) {
fprintf (stderr, "Error opening bsp file %s.\n", options.bspf_name);
return 1;
}
bsp = LoadBSPFile (bspfile, Qfilesize (bspfile));
Qclose (bspfile);
vertexlist = bsp->vertexes; vertexlist = bsp->vertexes;
edgelist = bsp->edges; edgelist = bsp->edges;
facelist = bsp->faces; facelist = bsp->faces;
@ -539,7 +543,7 @@ main (int argc, char *argv[])
if (edge_extra == NULL) { if (edge_extra == NULL) {
fprintf (stderr, "Error allocating %ld bytes for extra edge info.", fprintf (stderr, "Error allocating %ld bytes for extra edge info.",
(long) sizeof (struct edge_extra_t) * bsp->numedges); (long) sizeof (struct edge_extra_t) * bsp->numedges);
return 2; exit (2);
} }
/* initialize the array */ /* initialize the array */
for (i = 0; i < bsp->numedges; i++) { for (i = 0; i < bsp->numedges; i++) {
@ -562,74 +566,46 @@ main (int argc, char *argv[])
vect.Z = 0.0; vect.Z = 0.0;
while (vect.X == 0.0 && vect.Y == 0.0 && vect.Z == 0.0 while (vect.X == 0.0 && vect.Y == 0.0 && vect.Z == 0.0
&& k < (facelist[i].numedges + j)) { && k < (facelist[i].numedges + j)) {
dedge_t *e1, *e2;
/* If the first 2 are parallel edges, go with the next one */ /* If the first 2 are parallel edges, go with the next one */
k++; k++;
e1 = &edgelist[abs (ledges[j])];
e2 = &edgelist[abs (ledges[k])];
if (ledges[j] > 0) { if (ledges[j] > 0) {
v0.X = v0.X = vertexlist[e1->v[0]].X - vertexlist[e1->v[1]].X;
vertexlist[edgelist[abs ((int) ledges[j])].v[0]].X - v0.Y = vertexlist[e1->v[0]].Y - vertexlist[e1->v[1]].Y;
vertexlist[edgelist[abs ((int) ledges[j])].v[1]].X; v0.Z = vertexlist[e1->v[0]].Z - vertexlist[e1->v[1]].Z;
v0.Y =
vertexlist[edgelist[abs ((int) ledges[j])].v[0]].Y -
vertexlist[edgelist[abs ((int) ledges[j])].v[1]].Y;
v0.Z =
vertexlist[edgelist[abs ((int) ledges[j])].v[0]].Z -
vertexlist[edgelist[abs ((int) ledges[j])].v[1]].Z;
v1.X = v1.X = vertexlist[e2->v[0]].X - vertexlist[e2->v[1]].X;
vertexlist[edgelist[abs ((int) ledges[k])].v[0]].X - v1.Y = vertexlist[e2->v[0]].Y - vertexlist[e2->v[1]].Y;
vertexlist[edgelist[abs ((int) ledges[k])].v[1]].X; v1.Z = vertexlist[e2->v[0]].Z - vertexlist[e2->v[1]].Z;
v1.Y =
vertexlist[edgelist[abs ((int) ledges[k])].v[0]].Y -
vertexlist[edgelist[abs ((int) ledges[k])].v[1]].Y;
v1.Z =
vertexlist[edgelist[abs ((int) ledges[k])].v[0]].Z -
vertexlist[edgelist[abs ((int) ledges[k])].v[1]].Z;
} else { } else {
/* negative index, therefore walk in reverse order */ /* negative index, therefore walk in reverse order */
v0.X = v0.X = vertexlist[e1->v[1]].X - vertexlist[e1->v[0]].X;
vertexlist[edgelist[abs ((int) ledges[j])].v[1]].X - v0.Y = vertexlist[e1->v[1]].Y - vertexlist[e1->v[0]].Y;
vertexlist[edgelist[abs ((int) ledges[j])].v[0]].X; v0.Z = vertexlist[e1->v[1]].Z - vertexlist[e1->v[0]].Z;
v0.Y =
vertexlist[edgelist[abs ((int) ledges[j])].v[1]].Y -
vertexlist[edgelist[abs ((int) ledges[j])].v[0]].Y;
v0.Z =
vertexlist[edgelist[abs ((int) ledges[j])].v[1]].Z -
vertexlist[edgelist[abs ((int) ledges[j])].v[0]].Z;
v1.X = v1.X = vertexlist[e2->v[1]].X - vertexlist[e2->v[0]].X;
vertexlist[edgelist[abs ((int) ledges[k])].v[1]].X - v1.Y = vertexlist[e2->v[1]].Y - vertexlist[e2->v[0]].Y;
vertexlist[edgelist[abs ((int) ledges[k])].v[0]].X; v1.Z = vertexlist[e2->v[1]].Z - vertexlist[e2->v[0]].Z;
v1.Y =
vertexlist[edgelist[abs ((int) ledges[k])].v[1]].Y -
vertexlist[edgelist[abs ((int) ledges[k])].v[0]].Y;
v1.Z =
vertexlist[edgelist[abs ((int) ledges[k])].v[1]].Z -
vertexlist[edgelist[abs ((int) ledges[k])].v[0]].Z;
} }
/* cross product */ /* cross product */
vect.X = (v0.Y * v1.Z) - (v0.Z * v1.Y); CROSS (v0, v1, vect);
vect.Y = (v0.Z * v1.X) - (v0.X * v1.Z);
vect.Z = (v0.X * v1.Y) - (v0.Y * v1.X);
/* Okay, it's not the REAL area, but i'm lazy, and since a lot /* Okay, it's not the REAL area, but i'm lazy, and since a lot
of mapmakers use rectangles anyways... */ of mapmakers use rectangles anyways... */
area = (int) (sqrt (v0.X * v0.X + v0.Y * v0.Y + v0.Z * v0.Z) * area = sqrt (DOT (v0, v0)) * sqrt (DOT (v1, v1));
sqrt (v1.X * v1.X + v1.Y * v1.Y + v1.Z * v1.Z));
} /* while */ } /* while */
/* reduce cross product to a unit vector */ /* reduce cross product to a unit vector */
tempf = tempf = sqrt (DOT (vect, vect));
(float)
sqrt ((double)
(vect.X * vect.X + vect.Y * vect.Y + vect.Z * vect.Z));
if (tempf > 0.0) { if (tempf > 0.0) {
vect.X = vect.X / tempf; vect.X = vect.X / tempf;
vect.Y = vect.Y / tempf; vect.Y = vect.Y / tempf;
vect.Z = vect.Z / tempf; vect.Z = vect.Z / tempf;
} /* if tempf */ } else {
else {
vect.X = 0.0; vect.X = 0.0;
vect.Y = 0.0; vect.Y = 0.0;
vect.Z = 0.0; vect.Z = 0.0;
@ -637,24 +613,18 @@ main (int argc, char *argv[])
/* Now go put ref in all edges... */ /* Now go put ref in all edges... */
for (j = 0; j < facelist[i].numedges; j++) { for (j = 0; j < facelist[i].numedges; j++) {
edge_extra_t *e;
k = j + facelist[i].firstedge; k = j + facelist[i].firstedge;
x = edge_extra[abs ((int) ledges[k])].num_face_ref; e = &edge_extra[abs (ledges[k])];
if (edge_extra[abs ((int) ledges[k])].num_face_ref < x = e->num_face_ref;
MAX_REF_FACES) { if (e->num_face_ref < MAX_REF_FACES) {
x++; x++;
edge_extra[abs ((int) ledges[k])].num_face_ref = x; e->num_face_ref = x;
edge_extra[abs ((int) ledges[k])].ref_faces[x - 1] = i; e->ref_faces[x - 1] = i;
edge_extra[abs ((int) ledges[k])].ref_faces_normal[x - e->ref_faces_normal[x - 1].X = vect.X;
1].X = e->ref_faces_normal[x - 1].Y = vect.Y;
vect.X; e->ref_faces_normal[x - 1].Z = vect.Z;
edge_extra[abs ((int) ledges[k])].ref_faces_normal[x - e->ref_faces_area[x - 1] = area;
1].Y =
vect.Y;
edge_extra[abs ((int) ledges[k])].ref_faces_normal[x -
1].Z =
vect.Z;
edge_extra[abs ((int) ledges[k])].ref_faces_area[x - 1] =
area;
} }
} /* for */ } /* for */
@ -725,20 +695,14 @@ main (int argc, char *argv[])
minZ = vertexlist[i].Z; minZ = vertexlist[i].Z;
maxZ = vertexlist[i].Z; maxZ = vertexlist[i].Z;
} else { } else {
if (vertexlist[i].X < minX) minX = min (vertexlist[i].X, minX);
minX = vertexlist[i].X; maxX = max (vertexlist[i].X, maxX);
if (vertexlist[i].X > maxX)
maxX = vertexlist[i].X;
if (vertexlist[i].Y < minY) minY = min (vertexlist[i].Y, minY);
minY = vertexlist[i].Y; maxY = max (vertexlist[i].Y, maxY);
if (vertexlist[i].Y > maxY)
maxY = vertexlist[i].Y;
if (vertexlist[i].Z < minZ) minZ = min (vertexlist[i].Z, minZ);
minZ = vertexlist[i].Z; maxZ = max (vertexlist[i].Z, maxZ);
if (vertexlist[i].Z > maxZ)
maxZ = vertexlist[i].Z;
} }
} }
if (options.z_pad == -1) if (options.z_pad == -1)
@ -752,24 +716,16 @@ main (int argc, char *argv[])
(maxZ - minZ), midZ); (maxZ - minZ), midZ);
/* image array */ /* image array */
image = malloc (sizeof (image_t)); {
image->width = long width, height;
(long) ((maxX - minX) / options.scaledown) + (options.image_pad * 2) +
(options.z_pad * 2); width = (maxX - minX) / options.scaledown;
image->height = width += (options.image_pad + options.z_pad) * 2;
(long) ((maxY - minY) / options.scaledown) + (options.image_pad * 2) +
(options.z_pad * 2); height = (maxY - minY) / options.scaledown;
if (! height += (options.image_pad + options.z_pad) * 2;
(image->image =
malloc (sizeof (eightbit) * image->width * image->height))) { image = create_image (width, height);
fprintf (stderr, "Error allocating image buffer %ldx%ld.\n",
image->width, image->height);
return 0;
} else {
printf ("Allocated buffer %ldx%ld for image.\n", image->width,
image->height);
memset (image->image, 0,
sizeof (eightbit) * image->width * image->height);
} }
/* Zoffset calculations */ /* Zoffset calculations */
@ -779,43 +735,39 @@ main (int argc, char *argv[])
Z_Ydir = 1; Z_Ydir = 1;
break; break;
case 1: default: /* unknown */
Z_Xdir = 1; /* up & right */ case 1: /* up & right */
Z_Xdir = 1;
Z_Ydir = -1; Z_Ydir = -1;
break; break;
case 2: case 2: /* right */
Z_Xdir = 1; /* right */ Z_Xdir = 1;
Z_Ydir = 0; Z_Ydir = 0;
break; break;
case 3: case 3: /* down & right */
Z_Xdir = 1; /* down & right */ Z_Xdir = 1;
Z_Ydir = 1; Z_Ydir = 1;
break; break;
case 4: case 4: /* down */
Z_Xdir = 0; /* down */ Z_Xdir = 0;
Z_Ydir = 1; Z_Ydir = 1;
break; break;
case 5: case 5: /* down & left */
Z_Xdir = -1; /* down & left */ Z_Xdir = -1;
Z_Ydir = 1; Z_Ydir = 1;
break; break;
case 6: case 6: /* left */
Z_Xdir = -1; /* left */ Z_Xdir = -1;
Z_Ydir = 0; Z_Ydir = 0;
break; break;
case 7: case 7: /* up & left */
Z_Xdir = -1; /* up & left */ Z_Xdir = -1;
Z_Ydir = -1;
break;
default:
Z_Xdir = 1; /* unknown - go with case 1 */
Z_Ydir = -1; Z_Ydir = -1;
break; break;
} }
@ -836,15 +788,9 @@ main (int argc, char *argv[])
tempf = 1.0; tempf = 1.0;
/* dot products of all referenced faces */ /* dot products of all referenced faces */
for (j = 0; j < edge_extra[i].num_face_ref - 1; j = j + 2) { for (j = 0; j < edge_extra[i].num_face_ref - 1; j = j + 2) {
/* dot product */
tempf = tempf =
tempf * (edge_extra[i].ref_faces_normal[j].X * tempf * (DOT (edge_extra[i].ref_faces_normal[j],
edge_extra[i].ref_faces_normal[j + 1].X + edge_extra[i].ref_faces_normal[j + 1]));
edge_extra[i].ref_faces_normal[j].Y *
edge_extra[i].ref_faces_normal[j + 1].Y +
edge_extra[i].ref_faces_normal[j].Z *
edge_extra[i].ref_faces_normal[j + 1].Z);
/* What is the smallest area this edge references? */ /* What is the smallest area this edge references? */
if (usearea > edge_extra[i].ref_faces_area[j]) if (usearea > edge_extra[i].ref_faces_area[j])
@ -859,44 +805,23 @@ main (int argc, char *argv[])
tempf = 0.0; tempf = 0.0;
} }
if ((abs (tempf) < options.flat_threshold) && vert1 = &vertexlist[edgelist[i].v[0]];
(usearea > options.area_threshold) && vert2 = &vertexlist[edgelist[i].v[1]];
(sqrt SUB (*vert1, *vert2, vect);
((vertexlist[edgelist[i].v[0]].X - if (abs (tempf) < options.flat_threshold
vertexlist[edgelist[i].v[1]].X) * && usearea > options.area_threshold
(vertexlist[edgelist[i].v[0]].X - && sqrt (DOT (vect, vect)) > options.linelen_threshold) {
vertexlist[edgelist[i].v[1]].X) + float offs0, offs1;
(vertexlist[edgelist[i].v[0]].Y - Zoffset0 = (options.z_pad * (vert1->Z - midZ) / (maxZ - minZ));
vertexlist[edgelist[i].v[1]].Y) * Zoffset1 = (options.z_pad * (vert2->Z - midZ) / (maxZ - minZ));
(vertexlist[edgelist[i].v[0]].Y -
vertexlist[edgelist[i].v[1]].Y) +
(vertexlist[edgelist[i].v[0]].Z -
vertexlist[edgelist[i].v[1]].Z) *
(vertexlist[edgelist[i].v[0]].Z -
vertexlist[edgelist[i].v[1]].Z)) >
options.linelen_threshold)) {
Zoffset0 =
(long) (options.z_pad *
(vertexlist[edgelist[i].v[0]].Z - midZ) / (maxZ -
minZ));
Zoffset1 =
(long) (options.z_pad *
(vertexlist[edgelist[i].v[1]].Z - midZ) / (maxZ -
minZ));
bresline (image, offs0 = options.image_pad + options.z_pad + (Zoffset0 * Z_Xdir);
(long) ((vertexlist[edgelist[i].v[0]].X - offs1 = options.image_pad + options.z_pad + (Zoffset1 * Z_Xdir);
minX) / options.scaledown + options.image_pad +
options.z_pad + (float) (Zoffset0 * Z_Xdir)), bresline (image, (vert1->X - minX) / options.scaledown + offs0,
(long) ((vertexlist[edgelist[i].v[0]].Y - (vert1->Y - minY) / options.scaledown + offs0,
minY) / options.scaledown + options.image_pad + (vert2->X - minX) / options.scaledown + offs1,
options.z_pad + (float) (Zoffset0 * Z_Ydir)), (vert2->Y - minY) / options.scaledown + offs1,
(long) ((vertexlist[edgelist[i].v[1]].X -
minX) / options.scaledown + options.image_pad +
options.z_pad + (float) (Zoffset1 * Z_Xdir)),
(long) ((vertexlist[edgelist[i].v[1]].Y -
minY) / options.scaledown + options.image_pad +
options.z_pad + (float) (Zoffset1 * Z_Ydir)),
drawcol); drawcol);
} else { } else {
k++; k++;
@ -942,6 +867,40 @@ main (int argc, char *argv[])
} }
} }
} }
if (options.edgeremove) {
free (edge_extra);
}
return image;
}
int
main (int argc, char *argv[])
{
QFile *bspfile;
QFile *outfile;
bsp_t *bsp;
image_t *image;
/* Enough args? */
if (argc < 3) {
show_help ();
return 1;
}
/* Setup options */
def_options (&options);
get_options (&options, argc, argv);
show_options (&options);
bspfile = Qopen (options.bspf_name, "rbz");
if (bspfile == NULL) {
fprintf (stderr, "Error opening bsp file %s.\n", options.bspf_name);
return 1;
}
bsp = LoadBSPFile (bspfile, Qfilesize (bspfile));
Qclose (bspfile);
image = render_map (bsp);
/* Write image */ /* Write image */
@ -984,21 +943,6 @@ main (int argc, char *argv[])
free (image->image); free (image->image);
free (image); free (image);
if (options.edgeremove) {
free (edge_extra);
}
if (options.write_raw) {
printf ("\nIf you want to:\n"
" convert -verbose -colors 256 -size %ldx%ld gray:%s map.jpg\n"
"(this is using ImageMagick's convert)\n",
image->width, image->height, options.outf_name);
} else {
printf ("\nIf you want to:\n"
" convert -verbose -colors 256 pcx:%s map.jpg\n"
"(this is using ImageMagick's convert)\n",
options.outf_name);
}
return 0; return 0;
} }