123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849 |
- #ifdef SYSTEM_WIN32
- #pragma warning(disable:4996)
- #endif
- #include "csg.h"
- #define MAXWADNAME 16
- #define MAX_TEXFILES 128
- // FindMiptex
- // TEX_InitFromWad
- // FindTexture
- // LoadLump
- // AddAnimatingTextures
- typedef struct
- {
- char identification[4]; // should be WAD2/WAD3
- int numlumps;
- int infotableofs;
- } wadinfo_t;
- typedef struct
- {
- int filepos;
- int disksize;
- int size; // uncompressed
- char type;
- char compression;
- char pad1, pad2;
- char name[MAXWADNAME]; // must be null terminated
- int iTexFile; // index of the wad this texture is located in
- } lumpinfo_t;
- std::deque< std::string > g_WadInclude;
- std::map< int, bool > s_WadIncludeMap;
- static int nummiptex = 0;
- static lumpinfo_t miptex[MAX_MAP_TEXTURES];
- static int nTexLumps = 0;
- static lumpinfo_t* lumpinfo = NULL;
- static int nTexFiles = 0;
- static FILE* texfiles[MAX_TEXFILES];
- // fix for 64 bit machines
- #if SIZEOF_CHARP == 8
- static char* texmap64[MAX_MAP_BRUSHES];
- static int tex_max64=0;
- static inline int texmap64_store(char *texname)
- {
- int curr_tex;
- ThreadLock();
- if (tex_max64 >= MAX_MAP_BRUSHES) // no assert?
- {
- printf("MAX_MAP_BRUSHES exceeded!\n");
- exit(-1);
- }
- curr_tex = tex_max64;
- texmap64[tex_max64] = texname;
- tex_max64++;
- ThreadUnlock();
- return curr_tex;
- }
- static inline char* texmap64_retrieve( int index)
- {
- if(index > tex_max64)
- {
- printf("retrieving bogus texture index %d\n", index);
- exit(-1);
- }
- return texmap64[index];
- }
- #else // SIZEOF_CHARP != 8, almost certainly 4
- #define texmap64_store( A ) ( (int) A)
- #define texmap64_retrieve( A ) ( (char*) A)
- #endif // SIZEOF_CHARP
- // =====================================================================================
- // CleanupName
- // =====================================================================================
- static void CleanupName(const char* const in, char* out)
- {
- int i;
- for (i = 0; i < MAXWADNAME; i++)
- {
- if (!in[i])
- {
- break;
- }
- out[i] = toupper(in[i]);
- }
- for (; i < MAXWADNAME; i++)
- {
- out[i] = 0;
- }
- }
- // =====================================================================================
- // lump_sorters
- // =====================================================================================
- static int CDECL lump_sorter_by_wad_and_name(const void* lump1, const void* lump2)
- {
- lumpinfo_t* plump1 = (lumpinfo_t*)lump1;
- lumpinfo_t* plump2 = (lumpinfo_t*)lump2;
- if (plump1->iTexFile == plump2->iTexFile)
- {
- return strcmp(plump1->name, plump2->name);
- }
- else
- {
- return plump1->iTexFile - plump2->iTexFile;
- }
- }
- static int CDECL lump_sorter_by_name(const void* lump1, const void* lump2)
- {
- lumpinfo_t* plump1 = (lumpinfo_t*)lump1;
- lumpinfo_t* plump2 = (lumpinfo_t*)lump2;
- return strcmp(plump1->name, plump2->name);
- }
- // =====================================================================================
- // FindMiptex
- // Find and allocate a texture into the lump data
- // =====================================================================================
- static int FindMiptex(const char* const name)
- {
- int i;
- ThreadLock();
- for (i = 0; i < nummiptex; i++)
- {
- if (!strcmp(name, miptex[i].name))
- {
- ThreadUnlock();
- return i;
- }
- }
- hlassume(nummiptex < MAX_MAP_TEXTURES, assume_MAX_MAP_TEXTURES);
- safe_strncpy(miptex[i].name, name, MAXWADNAME);
- nummiptex++;
- ThreadUnlock();
- return i;
- }
- // =====================================================================================
- // TEX_InitFromWad
- // =====================================================================================
- bool TEX_InitFromWad()
- {
- int i, j;
- wadinfo_t wadinfo;
- char szTmpWad[1024]; // arbitrary, but needs to be large.
- char* pszWadFile;
- const char* pszWadroot;
- wadpath_t* currentwad;
- Log("\n\nChecking Wadfiles (max. expected texture size is %i bytes):\n\n", MAX_TEXTURE_SIZE); //SILENCER //Indentation and blank lines make it much easier to view
- szTmpWad[0] = 0;
- pszWadroot = getenv("WADROOT");
- #ifdef HLCSG_AUTOWAD
- autowad_UpdateUsedWads();
- #endif
- // for eachwadpath
- for (i = 0; i < g_iNumWadPaths; i++)
- {
- FILE* texfile; // temporary used in this loop
- bool bExcludeThisWad = false;
- currentwad = g_pWadPaths[i];
- pszWadFile = currentwad->path;
- #ifdef HLCSG_AUTOWAD
- #ifdef _DEBUG
- Log("[dbg] Attempting to parse wad: '%s'\n", pszWadFile);
- #endif
- if (g_bWadAutoDetect && !currentwad->usedtextures)
- continue;
- #ifdef _DEBUG
- Log("[dbg] Parsing wad\n");
- #endif
- #endif
- texfiles[nTexFiles] = fopen(pszWadFile, "rb");
- #ifdef SYSTEM_WIN32
- if (!texfiles[nTexFiles])
- {
- // cant find it, maybe this wad file has a hard code drive
- if (pszWadFile[1] == ':')
- {
- pszWadFile += 2; // skip past the drive
- texfiles[nTexFiles] = fopen(pszWadFile, "rb");
- }
- }
- #endif
- if (!texfiles[nTexFiles] && pszWadroot)
- {
- char szTmp[_MAX_PATH];
- char szFile[_MAX_PATH];
- char szSubdir[_MAX_PATH];
- ExtractFile(pszWadFile, szFile);
- ExtractFilePath(pszWadFile, szTmp);
- ExtractFile(szTmp, szSubdir);
- // szSubdir will have a trailing separator
- safe_snprintf(szTmp, _MAX_PATH, "%s" SYSTEM_SLASH_STR "%s%s", pszWadroot, szSubdir, szFile);
- texfiles[nTexFiles] = fopen(szTmp, "rb");
- #ifdef SYSTEM_POSIX
- if (!texfiles[nTexFiles])
- {
- // if we cant find it, Convert to lower case and try again
- strlwr(szTmp);
- texfiles[nTexFiles] = fopen(szTmp, "rb");
- }
- #endif
- }
- if (!texfiles[nTexFiles])
- {
- // still cant find it, error out
- Log(" "); //SILENCER //Indentation and blank lines make it much easier to view
- Fatal(assume_COULD_NOT_FIND_WAD, "Could not open wad file %s", pszWadFile);
- continue;
- }
- // look and see if we're supposed to include the textures from this WAD in the bsp.
- WadInclude_i it;
- for (it = g_WadInclude.begin(); it != g_WadInclude.end(); it++)
- {
- if (stristr(pszWadFile, it->c_str()))
- {
- //SILENCER //Indentation and blank lines make it much easier to view
- Log(" Including Wadfile: %s:\n", pszWadFile);
- bExcludeThisWad = true; // wadincluding this one
- s_WadIncludeMap[nTexFiles] = true;
- break;
- }
- }
- if (!bExcludeThisWad)
- {
- //SILENCER //Indentation and blank lines make it much easier to view
- Log(" Using Wadfile: %s:\n", pszWadFile);
- safe_snprintf(szTmpWad, 1024, "%s%s;", szTmpWad, pszWadFile);
- }
- // temp assignment to make things cleaner:
- texfile = texfiles[nTexFiles];
- // read in this wadfiles information
- SafeRead(texfile, &wadinfo, sizeof(wadinfo));
- // make sure its a valid format
- if (strncmp(wadinfo.identification, "WAD2", 4) && strncmp(wadinfo.identification, "WAD3", 4))
- {
- Log(" "); //SILENCER //Indentation and blank lines make it much easier to view
- Error("%s isn't a Wadfile!", pszWadFile);
- }
- wadinfo.numlumps = LittleLong(wadinfo.numlumps);
- wadinfo.infotableofs = LittleLong(wadinfo.infotableofs);
- // read in lump
- if (fseek(texfile, wadinfo.infotableofs, SEEK_SET)) {
- Log(" "); //SILENCER //Indentation and blank lines make it much easier to view
- Warning("fseek to %d in wadfile %s failed", wadinfo.infotableofs, pszWadFile);
- }
- // memalloc for this lump
- lumpinfo = (lumpinfo_t*)realloc(lumpinfo, (nTexLumps + wadinfo.numlumps) * sizeof(lumpinfo_t));
- // for each texlump
- for (j = 0; j < wadinfo.numlumps; j++, nTexLumps++)
- {
- SafeRead(texfile, &lumpinfo[nTexLumps], (sizeof(lumpinfo_t) - sizeof(int)) ); // iTexFile is NOT read from file
- if (!TerminatedString(lumpinfo[nTexLumps].name, MAXWADNAME))
- {
- lumpinfo[nTexLumps].name[MAXWADNAME - 1] = 0;
- Log(" "); //SILENCER //Indentation and blank lines make it much easier to view
- Warning("Unterminated texture name : wad[%s] texture[%d] name[%s]\n", pszWadFile, nTexLumps, lumpinfo[nTexLumps].name);
- }
- CleanupName(lumpinfo[nTexLumps].name, lumpinfo[nTexLumps].name);
- lumpinfo[nTexLumps].filepos = LittleLong(lumpinfo[nTexLumps].filepos);
- lumpinfo[nTexLumps].disksize = LittleLong(lumpinfo[nTexLumps].disksize);
- lumpinfo[nTexLumps].iTexFile = nTexFiles;
- if (lumpinfo[nTexLumps].disksize > MAX_TEXTURE_SIZE)
- {
- Log(" "); //SILENCER //Indentation and blank lines make it much easier to view
- Warning("Larger than expected texture (%d bytes): '%s'",
- lumpinfo[nTexLumps].disksize, lumpinfo[nTexLumps].name);
- }
- }
- // AJM: this feature is dependant on autowad. :(
- // CONSIDER: making it standard?
- #ifdef HLCSG_AUTOWAD
- {
- double percused = ((float)(currentwad->usedtextures) / (float)(g_numUsedTextures)) * 100;
- //SILENCER //Indentation and blank lines make it much easier to view:
- Log(" Contains %i used texture%s, %2.2f percent of map. (%d textures in wad)\n\n",
- currentwad->usedtextures, currentwad->usedtextures == 1 ? "" : "s", percused, wadinfo.numlumps);
- }
- #endif
- nTexFiles++;
- hlassume(nTexFiles < MAX_TEXFILES, assume_MAX_TEXFILES);
- }
- //Log("num of used textures: %i\n", g_numUsedTextures);
- // AJM: Tommy suggested i add this warning message in, and it certainly doesnt
- // hurt to be cautious. Especially one of the possible side effects he mentioned was svc_bad
- if (nTexFiles > 8)
- {
- Warning("More than 8 wadfiles are in use. (%i)\n"
- "This may be harmless, and if no strange side effects are occurring, then\n"
- "it can safely be ignored. However, if your map starts exhibiting strange\n"
- "or obscure errors, consider this as suspect. One of the possible side\n"
- "effects is getting an svc_bad error, by which a client drops from the game."
- , nTexFiles); //SILENCER: Added the note about possible svc_bad to the warning message.
- }
- // sort texlumps in memory by name
- qsort((void*)lumpinfo, (size_t) nTexLumps, sizeof(lumpinfo[0]), lump_sorter_by_name);
- SetKeyValue(&g_entities[0], "wad", szTmpWad);
- Log("\n");
- CheckFatal();
- return true;
- }
- // =====================================================================================
- // FindTexture
- // =====================================================================================
- lumpinfo_t* FindTexture(const lumpinfo_t* const source)
- {
- //Log("** PnFNFUNC: FindTexture\n");
- lumpinfo_t* found = NULL;
- found = (lumpinfo_t*)bsearch(source, (void*)lumpinfo, (size_t) nTexLumps, sizeof(lumpinfo[0]), lump_sorter_by_name);
- if (!found)
- {
- Warning("::FindTexture() texture %s not found!", source->name);
- if (!strcmp(source->name, "NULL"))
- {
- Log("Are you sure you included zhlt.wad in your wadpath list?\n");
- }
- }
- return found;
- }
- // =====================================================================================
- // TestIncludeTextureNamed
- // check to see if this texture should never be included -- should fix problematic
- // sky behavior.
- //
- // TODO : fix any texture used by this code so that it is always contained in a
- // non-included wad or throw warning and include anyway
- // =====================================================================================
- bool TestIncludeTextureNamed(const char* const name)
- {
- bool shouldInclude = true;
- /* switch(name[0])
- {
- case 'a': case 'A':
- if(!stricmp(name,"AAATRIGGER"))
- { shouldInclude = false; }
- break;
- case 'c': case 'C':
- if(!stricmp(name,"CLIP"))
- { shouldInclude = false; }
- break;
- case 'h': case 'H':
- if(!stricmp(name,"HINT"))
- { shouldInclude = false; }
- break;
- // case 'n': case 'N':
- // if(!stricmp(name,"NULL"))
- // { shouldInclude = false; }
- // break;
- case 'o': case 'O':
- if(!stricmp(name,"ORIGIN"))
- { shouldInclude = false; }
- break;
- case 's': case 'S':
- if(!stricmp(name,"SKY") || !stricmp(name,"SKIP"))
- { shouldInclude = false; }
- break;
- }
- */
- if(!shouldInclude)
- { Warning("Overriding inclusion of common texture: %s",name); }
- return shouldInclude;
- }
- // =====================================================================================
- // LoadLump
- // =====================================================================================
- int LoadLump(const lumpinfo_t* const source, byte* dest, int* texsize)
- {
- //Log("** PnFNFUNC: LoadLump\n");
- *texsize = 0;
- if (source->filepos)
- {
- if (fseek(texfiles[source->iTexFile], source->filepos, SEEK_SET)) {
- Log(" "); //SILENCER //Indentation and blank lines make it much easier to view
- Warning("fseek to %d failed\n", source->filepos);
- }
- *texsize = source->disksize;
- bool wadinclude = false;
- std::map< int, bool >::iterator it;
- it = s_WadIncludeMap.find(source->iTexFile);
- if (it != s_WadIncludeMap.end())
- {
- wadinclude = it->second;
- }
- // Should we just load the texture header w/o the palette & bitmap?
- if ((g_wadtextures && !wadinclude) || !TestIncludeTextureNamed(source->name))
- {
- // Just read the miptex header and zero out the data offsets.
- // We will load the entire texture from the WAD at engine runtime
- int i;
- miptex_t* miptex = (miptex_t*)dest;
- SafeRead(texfiles[source->iTexFile], dest, sizeof(miptex_t));
- for (i = 0; i < MIPLEVELS; i++)
- miptex->offsets[i] = 0;
- return sizeof(miptex_t);
- }
- else
- {
- Developer(DEVELOPER_LEVEL_MESSAGE,"Including texture %s\n",source->name);
- // Load the entire texture here so the BSP contains the texture
- SafeRead(texfiles[source->iTexFile], dest, source->disksize);
- return source->disksize;
- }
- }
-
- Log(" "); //SILENCER //Indentation and blank lines make it much easier to view
- Warning("::LoadLump() texture %s not found!", source->name);
- return 0;
- }
- // =====================================================================================
- // AddAnimatingTextures
- // =====================================================================================
- void AddAnimatingTextures()
- {
- int base;
- int i, j, k;
- char name[MAXWADNAME];
- base = nummiptex;
- for (i = 0; i < base; i++)
- {
- if ((miptex[i].name[0] != '+') && (miptex[i].name[0] != '-'))
- {
- continue;
- }
- safe_strncpy(name, miptex[i].name, MAXWADNAME);
- for (j = 0; j < 20; j++)
- {
- if (j < 10)
- {
- name[1] = '0' + j;
- }
- else
- {
- name[1] = 'A' + j - 10; // alternate animation
- }
- // see if this name exists in the wadfile
- for (k = 0; k < nTexLumps; k++)
- {
- if (!strcmp(name, lumpinfo[k].name))
- {
- FindMiptex(name); // add to the miptex list
- break;
- }
- }
- }
- }
- if (nummiptex - base)
- {
- Log("Added %i additional animating textures.\n\n", nummiptex - base);
- }
- }
- // =====================================================================================
- // GetWadPath
- // AJM: this sub is obsolete
- // =====================================================================================
- char* GetWadPath()
- {
- const char* path = ValueForKey(&g_entities[0], "_wad");
- if (!path || !path[0])
- {
- path = ValueForKey(&g_entities[0], "wad");
- if (!path || !path[0])
- {
- Warning("no wadfile specified");
- return strdup("");
- }
- }
- return strdup(path);
- }
- // =====================================================================================
- // WriteMiptex
- // =====================================================================================
- void WriteMiptex()
- {
- int len, texsize, totaltexsize = 0;
- byte* data;
- dmiptexlump_t* l;
- double start, end;
- g_texdatasize = 0;
- start = I_FloatTime();
- {
- if (!TEX_InitFromWad())
- return;
- AddAnimatingTextures();
- }
- end = I_FloatTime();
- Verbose("TEX_InitFromWad & AddAnimatingTextures elapsed time = %ldms\n", (long)(end - start));
- start = I_FloatTime();
- {
- int i;
- for (i = 0; i < nummiptex; i++)
- {
- lumpinfo_t* found;
- found = FindTexture(miptex + i);
- if (found)
- {
- miptex[i] = *found;
- }
- else
- {
- miptex[i].iTexFile = miptex[i].filepos = miptex[i].disksize = 0;
- }
- }
- }
- end = I_FloatTime();
- Verbose("FindTextures elapsed time = %ldms\n", (long)(end - start));
- start = I_FloatTime();
- {
- int i;
- texinfo_t* tx = g_texinfo;
- // Sort them FIRST by wadfile and THEN by name for most efficient loading in the engine.
- qsort((void*)miptex, (size_t) nummiptex, sizeof(miptex[0]), lump_sorter_by_wad_and_name);
- // Sleazy Hack 104 Pt 2 - After sorting the miptex array, reset the texinfos to point to the right miptexs
- for (i = 0; i < g_numtexinfo; i++, tx++)
- {
- char* miptex_name = texmap64_retrieve(tx->miptex);
- tx->miptex = FindMiptex(miptex_name);
- // Free up the originally strdup()'ed miptex_name
- free(miptex_name);
- }
- }
- end = I_FloatTime();
- Verbose("qsort(miptex) elapsed time = %ldms\n", (long)(end - start));
- start = I_FloatTime();
- {
- int i;
- // Now setup to get the miptex data (or just the headers if using -wadtextures) from the wadfile
- l = (dmiptexlump_t*)g_dtexdata;
- data = (byte*) & l->dataofs[nummiptex];
- l->nummiptex = nummiptex;
- for (i = 0; i < nummiptex; i++)
- {
- l->dataofs[i] = data - (byte*) l;
- len = LoadLump(miptex + i, data, &texsize);
- if (!len)
- {
- l->dataofs[i] = -1; // didn't find the texture
- }
- else
- {
- totaltexsize += texsize;
- hlassume(totaltexsize < g_max_map_miptex, assume_MAX_MAP_MIPTEX);
- }
- data += len;
- }
- g_texdatasize = data - g_dtexdata;
- }
- end = I_FloatTime();
- Log("Texture usage is at %1.2f MB (of %1.2f MB max)\n", (float)totaltexsize / (1024 * 1024),
- (float)g_max_map_miptex / (1024 * 1024));
- Verbose("LoadLump() elapsed time = %ldms\n", (long)(end - start));
- }
- //==========================================================================
- // =====================================================================================
- // TexinfoForBrushTexture
- // =====================================================================================
- int TexinfoForBrushTexture(const plane_t* const plane, brush_texture_t* bt, const vec3_t origin)
- {
- vec3_t vecs[2];
- int sv, tv;
- vec_t ang, sinv, cosv;
- vec_t ns, nt;
- texinfo_t tx;
- texinfo_t* tc;
- int i, j, k;
- memset(&tx, 0, sizeof(tx));
- if(!strncmp(bt->name,"BEVEL",5))
- {
- tx.flags |= TEX_BEVEL;
- safe_strncpy(bt->name,"NULL",5);
- }
- tx.miptex = FindMiptex(bt->name);
- // Note: FindMiptex() still needs to be called here to add it to the global miptex array
- // Very Sleazy Hack 104 - since the tx.miptex index will be bogus after we sort the miptex array later
- // Put the string name of the miptex in this "index" until after we are done sorting it in WriteMiptex().
- tx.miptex = texmap64_store(strdup(bt->name));
- // set the special flag
- if (bt->name[0] == '*'
- || !strncasecmp(bt->name, "sky", 3)
- // =====================================================================================
- //Cpt_Andrew - Env_Sky Check
- // =====================================================================================
- || !strncasecmp(bt->name, "env_sky", 5)
- // =====================================================================================
- || !strncasecmp(bt->name, "clip", 4)
- || !strncasecmp(bt->name, "origin", 6)
- #ifdef ZHLT_NULLTEX // AJM
- || !strncasecmp(bt->name, "null", 4)
- #endif
- || !strncasecmp(bt->name, "aaatrigger", 10)
- )
- {
- tx.flags |= TEX_SPECIAL;
- }
- if (bt->txcommand)
- {
- memcpy(tx.vecs, bt->vects.quark.vects, sizeof(tx.vecs));
- if (origin[0] || origin[1] || origin[2])
- {
- tx.vecs[0][3] += DotProduct(origin, tx.vecs[0]);
- tx.vecs[1][3] += DotProduct(origin, tx.vecs[1]);
- }
- }
- else
- {
- if (g_nMapFileVersion < 220)
- {
- TextureAxisFromPlane(plane, vecs[0], vecs[1]);
- }
- if (!bt->vects.valve.scale[0])
- {
- bt->vects.valve.scale[0] = 1;
- }
- if (!bt->vects.valve.scale[1])
- {
- bt->vects.valve.scale[1] = 1;
- }
- if (g_nMapFileVersion < 220)
- {
- // rotate axis
- if (bt->vects.valve.rotate == 0)
- {
- sinv = 0;
- cosv = 1;
- }
- else if (bt->vects.valve.rotate == 90)
- {
- sinv = 1;
- cosv = 0;
- }
- else if (bt->vects.valve.rotate == 180)
- {
- sinv = 0;
- cosv = -1;
- }
- else if (bt->vects.valve.rotate == 270)
- {
- sinv = -1;
- cosv = 0;
- }
- else
- {
- ang = bt->vects.valve.rotate / 180 * Q_PI;
- sinv = sin(ang);
- cosv = cos(ang);
- }
- if (vecs[0][0])
- {
- sv = 0;
- }
- else if (vecs[0][1])
- {
- sv = 1;
- }
- else
- {
- sv = 2;
- }
- if (vecs[1][0])
- {
- tv = 0;
- }
- else if (vecs[1][1])
- {
- tv = 1;
- }
- else
- {
- tv = 2;
- }
- for (i = 0; i < 2; i++)
- {
- ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
- nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
- vecs[i][sv] = ns;
- vecs[i][tv] = nt;
- }
- for (i = 0; i < 2; i++)
- {
- for (j = 0; j < 3; j++)
- {
- tx.vecs[i][j] = vecs[i][j] / bt->vects.valve.scale[i];
- }
- }
- }
- else
- {
- vec_t scale;
- scale = 1 / bt->vects.valve.scale[0];
- VectorScale(bt->vects.valve.UAxis, scale, tx.vecs[0]);
- scale = 1 / bt->vects.valve.scale[1];
- VectorScale(bt->vects.valve.VAxis, scale, tx.vecs[1]);
- }
- tx.vecs[0][3] = bt->vects.valve.shift[0] + DotProduct(origin, tx.vecs[0]);
- tx.vecs[1][3] = bt->vects.valve.shift[1] + DotProduct(origin, tx.vecs[1]);
- }
- //
- // find the g_texinfo
- //
- ThreadLock();
- tc = g_texinfo;
- for (i = 0; i < g_numtexinfo; i++, tc++)
- {
- // Sleazy hack 104, Pt 3 - Use strcmp on names to avoid dups
- if (strcmp(texmap64_retrieve((tc->miptex)), texmap64_retrieve((tx.miptex))) != 0)
- {
- continue;
- }
- if (tc->flags != tx.flags)
- {
- continue;
- }
- for (j = 0; j < 2; j++)
- {
- for (k = 0; k < 4; k++)
- {
- if (tc->vecs[j][k] != tx.vecs[j][k])
- {
- goto skip;
- }
- }
- }
- ThreadUnlock();
- return i;
- skip:;
- }
- hlassume(g_numtexinfo < MAX_MAP_TEXINFO, assume_MAX_MAP_TEXINFO);
- *tc = tx;
- g_numtexinfo++;
- ThreadUnlock();
- return i;
- }
|