From 957873f3bb4ba8a1511c4efc9758c19466005dde Mon Sep 17 00:00:00 2001 From: James Brown Date: Sat, 10 Jun 2000 03:36:28 +0000 Subject: [PATCH] Half-Life BSP support, and fixed that idiotic WGL multitexture crash. I don't know and don't care if other targets are also screwed this way :) --- include/model.h | 1 + source/gl_draw.c | 2 +- source/gl_model.c | 32 ++- source/gl_rmisc.c | 2 +- source/gl_rsurf.c | 45 ++++ source/hl_bsp.c | 479 ++++++++++++++++++++++++++++++++++++++++++ source/hl_wad.c | 205 ++++++++++++++++++ source/makefile.winc | 29 ++- source/makefile.wingl | 31 ++- source/makefile.wins | 26 ++- source/vid_wgl.c | 8 +- 11 files changed, 827 insertions(+), 33 deletions(-) create mode 100644 source/hl_bsp.c create mode 100644 source/hl_wad.c diff --git a/include/model.h b/include/model.h index 4e50361..35b1922 100644 --- a/include/model.h +++ b/include/model.h @@ -98,6 +98,7 @@ typedef struct texture_s struct texture_s *anim_next; // in the animation sequence struct texture_s *alternate_anims; // bmodels in frmae 1 use these unsigned offsets[MIPLEVELS]; // four mip maps stored + int transparent; } texture_t; diff --git a/source/gl_draw.c b/source/gl_draw.c index 1d5d3aa..82934b2 100644 --- a/source/gl_draw.c +++ b/source/gl_draw.c @@ -1405,7 +1405,7 @@ void GL_SelectTexture (GLenum target) { if (!gl_mtexable) return; - qglSelectTexture (target + gl_mtex_enum); + qglSelectTexture(target+gl_mtex_enum); if (target == oldtarget) return; cnttextures[oldtarget] = currenttexture; diff --git a/source/gl_model.c b/source/gl_model.c index e1211db..4641ee1 100644 --- a/source/gl_model.c +++ b/source/gl_model.c @@ -80,8 +80,7 @@ byte mod_novis[MAX_MAP_LEAFS/8]; #define MAX_MOD_KNOWN 512 model_t mod_known[MAX_MOD_KNOWN]; -int mod_numknown; - +int mod_numknown, bspversion; unsigned *model_checksum; texture_t *r_notexture_mip; cvar_t *gl_subdivide_size; @@ -548,6 +547,9 @@ void Mod_LoadEntities (lump_t *l) } loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); + + if (bspversion > 29) + CL_ParseEntityLump(loadmodel->entities); } @@ -802,10 +804,12 @@ void Mod_LoadFaces (lump_t *l) for (i=0 ; istyles[i] = in->styles[i]; i = LittleLong(in->lightofs); - if (i == -1) - out->samples = NULL; - else - out->samples = loadmodel->lightdata + (i * 3); + if (i == -1) + out->samples = NULL; + else if (bspversion > 29) + out->samples = loadmodel->lightdata + i; + else + out->samples = loadmodel->lightdata + (i * 3); // set the drawing flags flag @@ -1172,9 +1176,11 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) header = (dheader_t *)buffer; i = LittleLong (header->version); - if (i != BSPVERSION) + if ((i != BSPVERSION) && (i != 30)) SV_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + bspversion = i; + // swap all the lumps mod_base = (byte *)header; @@ -1199,11 +1205,17 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) // load into heap + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); Mod_LoadEdges (&header->lumps[LUMP_EDGES]); Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); - Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); - Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + +// Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); +// Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + + HL_Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + HL_Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); Mod_LoadFaces (&header->lumps[LUMP_FACES]); @@ -1212,7 +1224,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); Mod_LoadNodes (&header->lumps[LUMP_NODES]); Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); - Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); Mod_MakeHull0 (); diff --git a/source/gl_rmisc.c b/source/gl_rmisc.c index fd852e6..1b289bb 100644 --- a/source/gl_rmisc.c +++ b/source/gl_rmisc.c @@ -243,7 +243,7 @@ void R_Init (void) r_speeds = Cvar_Get("r_speeds", "0", CVAR_NONE, "None"); r_netgraph = Cvar_Get("r_netgraph", "0", CVAR_NONE, "None"); - gl_clear = Cvar_Get("gl_clear", "0", CVAR_NONE, "None"); + gl_clear = Cvar_Get("gl_clear", "1", CVAR_NONE, "None"); gl_texsort = Cvar_Get("gl_texsort", "1", CVAR_NONE, "None"); if (gl_mtexable) diff --git a/source/gl_rsurf.c b/source/gl_rsurf.c index dafd486..ca64533 100644 --- a/source/gl_rsurf.c +++ b/source/gl_rsurf.c @@ -686,6 +686,46 @@ void R_BlendLightmaps (void) glDepthMask (1); // back to normal Z buffering } +// Ender: Half-Life BSP loading +void R_RenderBrushPolyTransparent (msurface_t *fa) +{ + texture_t *t; + byte *base; + int maps; + glRect_t *theRect; + int smax, tmax; + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GEQUAL, 0.05f); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + + c_brush_polys++; + + if (fa->flags & SURF_DRAWSKY) + { // warp texture, no lightmaps + EmitBothSkyLayers (fa); + return; + } + + t = R_TextureAnimation (fa->texinfo->texture); + GL_Bind (t->gl_texturenum); + + if (fa->flags & SURF_DRAWTURB) + { // warp texture, no lightmaps + EmitWaterPolys (fa); + return; + } + + if (fa->flags & SURF_UNDERWATER) + DrawGLWaterPoly (fa->polys); + else + DrawGLPoly (fa->polys); + + glDisable(GL_ALPHA_TEST); +} + + /* ================ R_RenderBrushPoly @@ -699,6 +739,11 @@ void R_RenderBrushPoly (msurface_t *fa) glRect_t *theRect; int smax, tmax; + if (fa->texinfo->texture->transparent) { + R_RenderBrushPolyTransparent(fa); + return; + } + c_brush_polys++; if (fa->flags & SURF_DRAWSKY) diff --git a/source/hl_bsp.c b/source/hl_bsp.c new file mode 100644 index 0000000..acef01a --- /dev/null +++ b/source/hl_bsp.c @@ -0,0 +1,479 @@ +// Halflife BSP Loading +// Hack #1: +// Use this LoadLighting instead of the existing one in gl_model.c +// Hack #2: +// Use this LoadTexture instead of the existing one in gl_model.c +// Hack #?: +// Add int lhcsum; to gltexture_t in gl_draw.c +// Hack #4: +// save bspversion in 'int bspversion;'. Allow 30. +// Hack #5: +// New hl_wad.c +// Hack #6: +// In gl_model.h, texture_s, add "int transparent;" +// Hack #7: +// LoadEntities: +// if (bspversion > 29) // hlbsp +// CL_ParseEntityLump(loadmodel->entities); +// +// Hack #8: +// Top of GL_RenderBrushPoly (gl_rsurf.c - and add the function :) +// if (fa->texinfo->texture->transparent) { +// R_RenderBrushPolyTransparent(fa); +// return; +// } +// +// Hack #9: (mod_loadfaces) +// if (i == -1) +// out->samples = NULL; +// else if (bspversion > 29) +// out->samples = loadmodel->lightdata + i; +// else +// out->samples = loadmodel->lightdata + (i * 3); +// + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include + +#include "bothdefs.h" // needed by: common.h, net.h, client.h +#include "qendian.h" +#include "msg.h" +#include "bspfile.h" // needed by: glquake.h +#include "vid.h" +#include "sys.h" +#include "zone.h" // needed by: client.h, gl_model.h +#include "mathlib.h" // needed by: protocol.h, render.h, client.h, + // modelgen.h, glmodel.h +#include "wad.h" +#include "draw.h" +#include "cvar.h" +#include "crc.h" +#include "net.h" // needed by: client.h +#include "protocol.h" // needed by: client.h +#include "cmd.h" +#include "sbar.h" +#include "render.h" // needed by: client.h, gl_model.h, glquake.h +#include "client.h" // need cls in this file +#include "model.h" // needed by: glquake.h +#include "console.h" +#include "glquake.h" +#include "quakefs.h" +#include "checksum.h" + + +int image_width; +int image_height; + +// From gl_draw.c +typedef struct +{ + int texnum; + char identifier[64]; + int width, height; + qboolean mipmap; + int lhcsum; +} gltexture_t; + +extern int bspversion; +extern model_t *loadmodel; +extern char loadname[32]; +extern byte *mod_base; +extern gltexture_t gltextures[]; +extern int numgltextures; + +int HL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha); + +typedef struct miptex_hls +{ + char name[16]; + unsigned width, height; + char junk[16]; +} miptex_hl; + +void HL_Mod_LoadLighting (lump_t *l) +{ + if (!l->filelen) + { + loadmodel->lightdata = NULL; + return; + } + + if (bspversion > 29) { // Load coloured lighting data + loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); + } else { // Expand white lighting data + byte *in, *out, d; + int i; + Con_DPrintf("Converting lightmap data\n"); + loadmodel->lightdata = Hunk_AllocName (l->filelen*3, loadname); + in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write + out = loadmodel->lightdata; + memcpy (in, mod_base + l->fileofs, l->filelen); + for (i = 0;i < l->filelen;i++) { + d = *in++; + *out++ = d; + *out++ = d; + *out++ = d; + } + } +} + +byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight) +{ + FILE *f; + char basename[128], name[128]; + byte *image_rgba; + COM_StripExtension(filename, basename); // strip the extension to allow TGA skins on Q2 models despite the .pcx in the skin name + sprintf (name, "%s.tga", basename); + COM_FOpenFile (name, &f); + if (f) + return LoadTGA (f, matchwidth, matchheight); + sprintf (name, "%s.pcx", basename); + COM_FOpenFile (name, &f); + if (f) + return LoadPCX (f, matchwidth, matchheight); + if (image_rgba = W_GetTexture(basename, matchwidth, matchheight)) + return image_rgba; + if (complain) + Con_Printf ("Couldn't load %s.tga or .pcx\n", filename); + return NULL; +} + +void HL_Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, max, altmax, freeimage, transparent, bytesperpixel; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + byte *data; + char imagename[32]; + + if (!l->filelen) + { + loadmodel->textures = NULL; + return; + } + + m = (dmiptexlump_t *)(mod_base + l->fileofs); + m->nummiptex = LittleLong (m->nummiptex); + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); + + for (i=0 ; inummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + + // LordHavoc: rewriting the map texture loader for GLQuake + tx = Hunk_AllocName (sizeof(texture_t), loadname ); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; joffsets[j] = 0; + + strcpy(imagename, "textures/"); + strcat(imagename, mt->name); + + freeimage = TRUE; + transparent = FALSE; + bytesperpixel = 4; + data = loadimagepixels(imagename, FALSE, tx->width, tx->height); + if (!data) // no external texture found + { + strcpy(imagename, mt->name); + data = loadimagepixels(imagename, FALSE, tx->width, tx->height); + if (!data) // no external texture found + { + freeimage = FALSE; + bytesperpixel = 1; + if (mt->offsets[0]) // texture included + data = (byte *)((int) mt + mt->offsets[0]); + else // no texture, and no external replacement texture was found + { + tx->width = tx->height = 16; + data = (byte *)((int) r_notexture_mip + r_notexture_mip->offsets[0]); + } + } + else + { + for (j = 0;j < image_width*image_height;j++) + if (data[j*4+3] < 255) + { + transparent = TRUE; + break; + } + } + } + else + { + for (j = 0;j < image_width*image_height;j++) + if (data[j*4+3] < 255) + { + transparent = TRUE; + break; + } + } + if (!strncmp(mt->name,"sky",3)) + { + tx->transparent = FALSE; +// R_InitSky (data, bytesperpixel); + R_InitSky (tx); + } + else + { + tx->transparent = transparent; + texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; + if (bytesperpixel == 1) + tx->gl_texturenum = GL_LoadTexture (tx->name, tx->width, tx->height, data, true, transparent); + else + tx->gl_texturenum = HL_LoadTexture (tx->name, tx->width, tx->height, data, true, transparent); + texture_mode = GL_LINEAR; + } + if (freeimage) + free(data); + } +// +// sequence the animations +// + for (i=0 ; inummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; jnummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; jname); + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; jname); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } +} + + +void CL_ParseEntityLump(char *entdata) +{ + char *data; + char key[128], value[1024]; + char wadname[128]; + int i, j, k; + + data = entdata; + if (!data) + return; + + data = COM_Parse(data); + + if (!data) + return; // valid exit + + if (com_token[0] != '{') + return; // error + + + while (1) + { + data = COM_Parse(data); + if (!data) + return; // error + if (com_token[0] == '}') + return; // since we're just parsing the first ent (worldspawn), exit + strcpy(key, com_token); + while (key[strlen(key)-1] == ' ') // remove trailing spaces + key[strlen(key)-1] = 0; + data = COM_Parse(data); + if (!data) + return; // error + strcpy(value, com_token); +// if (!strcmp("sky", key)) +// strcpy(skyname, value); +// else if (!strcmp("skyboxsize", key)) +// { +// r_skyboxsize.value = atof(value); +// if (r_skyboxsize.value < 64) +// r_skyboxsize.value = 64; +// } + + if (!strcmp("wad", key)) // for HalfLife maps + { + j = 0; + for (i = 0;i < 128;i++) + if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':') + break; + if (value[i]) + { + for (;i < 128;i++) + { + // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'... + if (value[i] == '\\' || value[i] == '/' || value[i] == ':') + j = i+1; + else if (value[i] == ';' || value[i] == 0) + { + k = value[i]; + value[i] = 0; + strcpy(wadname, "textures/"); + Con_DPrintf("Wad: %s\n", &value[j]); + strcat(wadname, &value[j]); + W_LoadTextureWadFile (wadname, FALSE); + j = i+1; + if (!k) + break; + } + } + } + } + } +} + +/* +================ +GL_LoadTexture +================ +*/ +int lhcsumtable2[256]; +int HL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha) +{ + qboolean noalpha; + int i, p, s, lhcsum; + gltexture_t *glt; + + // LordHavoc: do a checksum to confirm the data really is the same as previous + // occurances. well this isn't exactly a checksum, it's better than that but + // not following any standards. + lhcsum = 0; + s = width*height*4; + for (i = 0;i < 256;i++) lhcsumtable2[i] = i + 1; + for (i = 0;i < s;i++) lhcsum += (lhcsumtable2[data[i] & 255]++); + + // see if the texture is allready present + if (identifier[0]) + { + for (i=0, glt=gltextures ; iidentifier)) + { + // LordHavoc: everyone hates cache mismatchs, so I fixed it + if (lhcsum != glt->lhcsum || width != glt->width || height != glt->height) + { + Con_DPrintf("GL_LoadTexture: cache mismatch, replacing old texture\n"); + goto HL_LoadTexture_setup; // drop out with glt pointing to the texture to replace + } + return glt->texnum; + } + } + } + + glt = &gltextures[numgltextures]; + numgltextures++; + + strcpy (glt->identifier, identifier); + glt->texnum = texture_extension_number; + texture_extension_number++; +// LordHavoc: label to drop out of the loop into the setup code +HL_LoadTexture_setup: + glt->lhcsum = lhcsum; // LordHavoc: used to verify textures are identical + glt->width = width; + glt->height = height; + glt->mipmap = mipmap; + + GL_Bind(glt->texnum); + GL_Upload32 (data, width, height, mipmap, true); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + return glt->texnum; +} + diff --git a/source/hl_wad.c b/source/hl_wad.c new file mode 100644 index 0000000..12717a2 --- /dev/null +++ b/source/hl_wad.c @@ -0,0 +1,205 @@ +/* + hl_wad.c + + WAD loading support for WAD3 texture wads. By LordHavoc + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "sys.h" +#include "wad.h" +#include "quakefs.h" +#include "qendian.h" + + +#define TEXWAD_MAXIMAGES 8192 +typedef struct +{ + char name[16]; + FILE *file; + int position; +} texwadlump_t; +extern int image_width, image_height; +texwadlump_t texwadlump[TEXWAD_MAXIMAGES]; + +/* +==================== +W_LoadTextureWadFile +==================== +*/ +void W_LoadTextureWadFile (char *filename, int complain) +{ + lumpinfo_t *lumps, *lump_p; + wadinfo_t header; + unsigned i, j; + int infotableofs; + FILE *file; + int numlumps; + int temp; + + + COM_FOpenFile (filename, &file); + if (!file) + { + if (complain) + Con_Printf ("W_LoadTextureWadFile: couldn't find %s", filename); + return; + } + + if (fread(&header, sizeof(wadinfo_t), 1, file) != 1) + {Con_Printf ("W_LoadTextureWadFile: unable to read wad header");return;} + + if(header.identification[0] != 'W' + || header.identification[1] != 'A' + || header.identification[2] != 'D' + || header.identification[3] != '3') + {Con_Printf ("W_LoadTextureWadFile: Wad file %s doesn't have WAD3 id\n",filename);return;} + + numlumps = LittleLong(header.numlumps); + if (numlumps < 1 || numlumps > TEXWAD_MAXIMAGES) + {Con_Printf ("W_LoadTextureWadFile: invalid number of lumps (%i)\n", numlumps);return;} + infotableofs = LittleLong(header.infotableofs); + if (fseek(file, infotableofs, SEEK_SET)) + {Con_Printf ("W_LoadTextureWadFile: unable to seek to lump table");return;} + if (!(lumps = malloc(sizeof(lumpinfo_t)*numlumps))) + {Con_Printf ("W_LoadTextureWadFile: unable to allocate temporary memory for lump table");return;} + + if (fread(lumps, sizeof(lumpinfo_t), numlumps, file) != numlumps) + {Con_Printf ("W_LoadTextureWadFile: unable to read lump table");return;} + + for (i=0, lump_p = lumps ; iname, lump_p->name); + for (j = 0;j < TEXWAD_MAXIMAGES;j++) + { + if (texwadlump[j].name[0]) // occupied slot, check the name + { + if (!strcmp(lump_p->name, texwadlump[j].name)) // name match, replace old one + break; + } + else // empty slot + break; + } + if (j >= TEXWAD_MAXIMAGES) + break; // abort loading + W_CleanupName (lump_p->name, texwadlump[j].name); + texwadlump[j].file = file; + texwadlump[j].position = LittleLong(lump_p->filepos); + } + free(lumps); + // leaves the file open +} + +byte *W_GetTexture(char *name, int matchwidth, int matchheight) +{ + int i, c, datasize; + short colorcount; + FILE *file; + struct + { + char name[16]; + int width; + int height; + int ofs[4]; + } t; + byte pal[256][3], *indata, *outdata, *data; + for (i = 0;i < TEXWAD_MAXIMAGES;i++) + { + if (texwadlump[i].name[0]) + { + if (!strcmp(name, texwadlump[i].name)) // found it + { + file = texwadlump[i].file; + if (fseek(file, texwadlump[i].position, SEEK_SET)) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + if (fread(&t, sizeof(t), 1, file) != 1) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + image_width = LittleLong(t.width); + image_height = LittleLong(t.height); + if (matchwidth && image_width != matchwidth) + continue; + if (matchheight && image_height != matchheight) + continue; + if (image_width & 15 || image_height & 15) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + + // allocate space for expanded image, + // and load incoming image into upper area (overwritten as it expands) + if (!(data = outdata = malloc(image_width*image_height*4))) + {Con_Printf("W_GetTexture: out of memory");return false;} + indata = outdata + image_width*image_height*3; + datasize = image_width*image_height*85/64; + + // read the image data + if (fseek(file, texwadlump[i].position + sizeof(t), SEEK_SET)) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + if (fread(indata, 1, image_width*image_height, file) != image_width*image_height) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + + // read the number of colors used (always 256) + if (fseek(file, texwadlump[i].position + sizeof(t) + datasize, SEEK_SET)) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + if (fread(&colorcount, 2, 1, file) != 1) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + colorcount = LittleShort(colorcount); + + // sanity checking + if (colorcount < 0) colorcount = 0; + if (colorcount > 256) colorcount = 256; + + // read the palette + if (fread(&pal, 3, colorcount, file) != colorcount) + {Con_Printf("W_GetTexture: corrupt WAD3 file");return false;} + + // expand the image to 32bit RGBA + for (i = 0;i < image_width*image_height;i++) + { + c = *indata++; + if (c == 255) // transparent color + { + *outdata++ = 0; + *outdata++ = 0; + *outdata++ = 0; + *outdata++ = 0; + } + else + { + *outdata++ = pal[c][0]; + *outdata++ = pal[c][1]; + *outdata++ = pal[c][2]; + *outdata++ = 255; + } + } + return data; + } + } + else + break; + } + image_width = image_height = 0; + return NULL; +} diff --git a/source/makefile.winc b/source/makefile.winc index f9aded8..4c534d3 100644 --- a/source/makefile.winc +++ b/source/makefile.winc @@ -1,14 +1,14 @@ include # Microsoft VC6++ #!include # Use to compile with Intel's compiler -all:glclient.exe +all:client.exe INCPATH=E:\quakesrc\q1src\incs # Path to other includes (mgl, etc) MGLPATH=E:\quakesrc\q1src\libs # Path to other librarys (mgl) DXPATH=E:\quakesrc\q1src\libs # Path to other librarys (DirectX) LIBS=winmm.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib $(DXPATH)\dinput.lib $(DXPATH)\dxguid.lib $(MGLPATH)\mgllt.lib -NCFLAGS=/c /nologo /DWIN32 /D_WIN32 /I..\include /I..\include\win32\vc /I$(INCPATH) /MT /DHAVE_CONFIG_H +NCFLAGS=/c /nologo /DWIN32 /D_WIN32 /I..\include /I..\include\win32\vc /I$(INCPATH) /MT /DHAVE_CONFIG_H /Ox /I..\include\win32 COM_sources=\ net_chan.obj \ net_com.obj \ @@ -19,8 +19,22 @@ COM_sources=\ mathlib.obj \ cvar.obj \ crc.obj \ - common.obj \ + com.obj \ + qargs.obj \ + quakefs.obj \ + quakeio.obj \ + qendian.obj \ cmd.obj \ + link.obj \ + checksum.obj \ + info.obj \ + net_com.obj \ + msg.obj \ + sizebuf.obj \ + va.obj \ + fnmatch.obj \ + dirent.obj \ + buildnum.obj \ model.obj CL_SW_sources=\ @@ -53,6 +67,7 @@ CL_SW_sources=\ r_vars.obj \ r_view.obj \ screen.obj \ + sw_view.obj CL_sources=\ cl_cmd.obj \ @@ -76,10 +91,12 @@ CL_sources=\ nonintel.obj \ menu.obj \ keys.obj \ - console.obj + console.obj \ + cl_slist.obj \ + cl_trans.obj CL_platform=\ - vid_win.obj \ + vid_mgl.obj \ snd_win.obj \ in_win.obj \ sys_win.obj \ @@ -103,7 +120,7 @@ CL_asm=\ # r_drawa.asm \ # r_edgea.asm \ # r_varsa.asm \ - sys_wina.obj + sys_x86.obj # snd_mixa.asm \ # surf16.asm \ # surf8.asm diff --git a/source/makefile.wingl b/source/makefile.wingl index 028070a..e993276 100644 --- a/source/makefile.wingl +++ b/source/makefile.wingl @@ -1,4 +1,4 @@ -include # Microsoft VC6++ +!include # Microsoft VC6++ #!include # Use to compile with Intel's compiler all:glclient.exe @@ -8,7 +8,7 @@ MGLPATH=E:\quakesrc\q1src\libs # Path to other librarys (mgl) DXPATH=E:\quakesrc\q1src\libs # Path to other librarys (DirectX) LIBS=winmm.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib $(DXPATH)\dinput.lib $(DXPATH)\dxguid.lib $(MGLPATH)\mgllt.lib glu32.lib opengl32.lib -NCFLAGS=/c /nologo /DWIN32 /D_WIN32 /I..\include /I..\include\win32\vc /I$(INCPATH) /MT /DHAVE_CONFIG_H +NCFLAGS=/c /nologo /DWIN32 /D_WIN32 /I..\include /I..\include\win32\vc /I$(INCPATH) /MT /DHAVE_CONFIG_H -Ox /I..\include\win32 COM_sources=\ net_chan.obj \ @@ -20,10 +20,26 @@ COM_sources=\ mathlib.obj \ cvar.obj \ crc.obj \ - common.obj \ - cmd.obj + com.obj \ + qargs.obj \ + quakefs.obj \ + quakeio.obj \ + qendian.obj \ + cmd.obj \ + link.obj \ + checksum.obj \ + info.obj \ + net_com.obj \ + msg.obj \ + sizebuf.obj \ + va.obj \ + fnmatch.obj \ + dirent.obj \ + buildnum.obj \ CL_GL_sources=\ + hl_bsp.obj \ + hl_wad.obj \ r_view.obj \ gl_draw.obj \ gl_mesh.obj \ @@ -55,7 +71,6 @@ CL_sources=\ cl_pred.obj \ cl_tent.obj \ cl_cam.obj \ - model.obj \ wad.obj \ snd_dma.obj \ snd_mem.obj \ @@ -65,7 +80,7 @@ CL_sources=\ nonintel.obj \ menu.obj \ keys.obj \ - vc6fix.obj \ +# vc6fix.obj \ console.obj CL_platform=\ @@ -80,8 +95,8 @@ CL_asm=\ sys_x86.obj glclient.exe: $(COM_sources) $(CL_GL_sources) $(CL_sources) $(CL_platform) $(CL_asm) - $(link) /nologo /subsystem:windows /incremental:yes /machine:I386 -out:glclient.exe gl\*.obj $(LIBS) + $(link) /nologo /subsystem:windows /incremental:yes /machine:I386 -out:glclient.exe *.obj $(LIBS) .c.obj: - $(cc) $(NCFLAGS) $*.c /Fogl\$*.obj + $(cc) $(NCFLAGS) $*.c diff --git a/source/makefile.wins b/source/makefile.wins index f3185a2..eadb363 100644 --- a/source/makefile.wins +++ b/source/makefile.wins @@ -3,8 +3,12 @@ include all:server.exe -LIBS=winmm.lib wsock32.lib opengl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib libc.lib -NCFLAGS=/c /nologo /DWIN32 /D_WIN32 /I..\include /I..\include\win32\vc /MT /DHAVE_CONFIG_H +INCPATH=E:\quakesrc\q1src\incs # Path to other includes (mgl, etc) +MGLPATH=E:\quakesrc\q1src\libs # Path to other librarys (mgl) +DXPATH=E:\quakesrc\q1src\libs # Path to other librarys (DirectX) + +LIBS=winmm.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib $(DXPATH)\dinput.lib $(DXPATH)\dxguid.lib $(MGLPATH)\mgllt.lib +NCFLAGS=/c /nologo /DWIN32 /D_WIN32 /I..\include /I..\include\win32\vc /MT /DHAVE_CONFIG_H /I..\include\win32 /I$(INCPATH) /Zi COM_sources=\ net_chan.obj \ net_com.obj \ @@ -15,8 +19,22 @@ COM_sources=\ mathlib.obj \ cvar.obj \ crc.obj \ - common.obj \ + com.obj \ + qargs.obj \ + quakefs.obj \ + quakeio.obj \ + qendian.obj \ cmd.obj \ + link.obj \ + checksum.obj \ + info.obj \ + net_com.obj \ + msg.obj \ + sizebuf.obj \ + va.obj \ + fnmatch.obj \ + dirent.obj \ + buildnum.obj \ model.obj SV_sources=\ @@ -41,7 +59,7 @@ SV_sources=\ sv_cvar.obj server.exe: $(COM_sources) $(SV_sources) - $(link) /nologo /subsystem:console /incremental:yes /machine:I386 -out:server.exe *.obj $(LIBS) + $(link) /nologo /subsystem:console /incremental:yes /machine:I386 -out:server.exe *.obj $(LIBS) /debug .c.obj: $(cc) $(NCFLAGS) $*.c diff --git a/source/vid_wgl.c b/source/vid_wgl.c index e3f4255..c2d5192 100644 --- a/source/vid_wgl.c +++ b/source/vid_wgl.c @@ -152,6 +152,8 @@ typedef void (APIENTRY *lp3DFXFUNC) (int, int, int, int, int, const void*); lp3DFXFUNC glColorTableEXT; qboolean is8bit = false; qboolean isPermedia = false; +int gl_mtex_enum = TEXTURE0_SGIS; +qboolean gl_arb_mtex = false; qboolean gl_mtexable = false; //==================================== @@ -612,9 +614,9 @@ void CheckMultiTextureExtensions(void) { Con_Printf ("GL_ARB_multitexture\n"); qglMTexCoord2f = - (void *)wglGetProcAddress("glMTexCoord2fARB"); - qglSelectTexture = - (void *)wglGetProcAddress("glSelectTextureARB"); + (void *)wglGetProcAddress("glMultiTexCoord2fARB"); + qglSelectTexture = + (void *) wglGetProcAddress("glActiveTextureARB"); gl_mtex_enum = GL_TEXTURE0_ARB; gl_mtexable = true; gl_arb_mtex = true;