// TexWnd.cpp : implementation file // #include "stdafx.h" #include #include "Radiant.h" #include "TexWnd.h" #include "qe3.h" #include "io.h" #include "inc.h" #include "PrefsDlg.h" #include "shaderinfo.h" #include "oddbits.h" #include "..\libs\pakstuff.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define TYP_MIPTEX 68 static unsigned tex_palette[256]; qtexture_t *notexture = NULL; qtexture_t *g_pluginTexture = NULL; static qboolean nomips = false; #define FONT_HEIGHT 10 HGLRC s_hglrcTexture = NULL; HDC s_hdcTexture = NULL; //int texture_mode = GL_NEAREST; //int texture_mode = GL_NEAREST_MIPMAP_NEAREST; //int texture_mode = GL_NEAREST_MIPMAP_LINEAR; //int texture_mode = GL_LINEAR; //int texture_mode = GL_LINEAR_MIPMAP_NEAREST; int texture_mode = GL_LINEAR_MIPMAP_LINEAR; int texture_extension_number = 1; int g_nCurrentTextureMenuName; int g_nTextureOffset = 0; // current active texture directory. if empty, show textures in use char texture_directory[128]; // use if texture_showinuse is false qboolean texture_showinuse; bool g_bFilterEnabled = false; CString g_strFilter; // texture layout functions qtexture_t *current_texture = NULL; int current_x, current_y, current_row; int texture_nummenus; #define MAX_TEXTUREDIRS 128 char texture_menunames[MAX_TEXTUREDIRS][128]; qboolean g_dontuse = true; // set to true to load the texture but not flag as used void SelectTexture (int mx, int my, bool bShift, bool bFitScale = false, bool bNoSystemTextureOverwrite = false); void Texture_MouseDown (int x, int y, int buttons); void Texture_MouseUp (int x, int y, int buttons); void Texture_MouseMoved (int x, int y, int buttons); CPtrArray g_lstShaders; CPtrArray g_lstDeferred; struct DeferredShaderLoad { CString m_strImage; CString m_strShader; CString m_strPath; DeferredShaderLoad(const char *pImage, const char *pShader, const char *pPath) { m_strImage = pImage; m_strShader = pShader; m_strPath = pPath; m_strPath.MakeLower(); } }; void loadDeferredByName(const char *pName) { } bool DeferredExists(const char *pName) { for (qtexture_t *q=g_qeglobals.d_qtextures ; q ; q=q->next) { if (!strcmp(q->name, pName)) { return true; } } return false; } bool ShaderQTextureExists(const char *pName) { for (qtexture_t *q=g_qeglobals.d_qtextures ; q ; q=q->next) { if (!strcmp(q->name, pName)) { return true; } } return false; } void LoadDeferred(const char *pPath) { int nSize = g_lstDeferred.GetSize(); for (int i = 0; i < nSize; i++) { DeferredShaderLoad *p = reinterpret_cast(g_lstDeferred.ElementAt(i)); if (p != NULL) { if (p->m_strPath.CompareNoCase(pPath) == 0) { if (DeferredExists(p->m_strShader) == false) { qtexture_t *q = Texture_ForName(p->m_strImage.GetBuffer(0)); if (q != NULL) { strcpy(q->name, p->m_strShader); } } } } } } CShaderInfo* hasShader(const char *pName) { int nSize = g_lstShaders.GetSize(); for (int i = 0; i < nSize; i++) { CShaderInfo *pInfo = reinterpret_cast(g_lstShaders.ElementAt(i)); if (pInfo != NULL) { if (pInfo->m_strName.CompareNoCase(pName) == 0) { return pInfo; } } } return NULL; } /* struct ShaderInfo { ShaderInfo(){ }; ~ShaderInfo() { }; CString m_strName; CStringList m_strEditorParams; CStringList m_strSurfaceParams; }; */ // gets active texture extension // // FIXME: fix this to be generic from project file // int GetTextureExtensionCount() { return 2; } const char* GetTextureExtension(int nIndex) { if ( nIndex == 0) { _QERTextureInfo *pInfo = g_pParentWnd->GetPlugInMgr().GetTextureInfo(); const char *pTex = (pInfo != NULL) ? pInfo->m_TextureExtension : NULL; return (pTex == NULL) ? (g_PrefsDlg.m_bHiColorTextures == FALSE) ? "wal" : "tga" : pTex; } // return jpg for 2nd extension return "jpg"; } /* ================= CheckTexturePrefix Check the texture name for a prefix, if it exists, do nothing if it does not exist, append it ================= */ void CheckTexturePrefix (char *texname) { char string[128]; char *temp; // if the texture directory prefix is not in the texture name (i.e. imported file), add it if (!strstr (texname, texture_menunames[g_nCurrentTextureMenuName])) { // if the texture name has an asterisk in it, remove it. if (texname[0] == '*') { temp = texname + 1; strcpy (texname, temp); } sprintf (string, "%s%s", texture_menunames[g_nCurrentTextureMenuName], texname); temp = _strlwr (string); strcpy (texname, temp); } } //===================================================== void SortTextures(void) { qtexture_t *q, *qtemp, *qhead, *qcur, *qprev; // standard insertion sort // Take the first texture from the list and // add it to our new list if ( g_qeglobals.d_qtextures == NULL) return; qhead = g_qeglobals.d_qtextures; q = g_qeglobals.d_qtextures->next; qhead->next = NULL; // while there are still things on the old // list, keep adding them to the new list while (q) { qtemp = q; q = q->next; qprev = NULL; qcur = qhead; while (qcur) { // Insert it here? if (strcmp(qtemp->name, qcur->name) < 0) { qtemp->next = qcur; if (qprev) qprev->next = qtemp; else qhead = qtemp; break; } // Move on qprev = qcur; qcur = qcur->next; // is this one at the end? if (qcur == NULL) { qprev->next = qtemp; qtemp->next = NULL; } } } g_qeglobals.d_qtextures = qhead; } //===================================================== /* ============== Texture_InitPalette ============== */ void Texture_InitPalette (byte *pal) { int r,g,b,v; int i; int inf; byte gammatable[256]; float gamma; gamma = g_qeglobals.d_savedinfo.fGamma; if (gamma == 1.0) { for (i=0 ; i<256 ; i++) gammatable[i] = i; } else { for (i=0 ; i<256 ; i++) { inf = 255 * pow ( (i+0.5)/255.5 , gamma ) + 0.5; if (inf < 0) inf = 0; if (inf > 255) inf = 255; gammatable[i] = inf; } } for (i=0 ; i<256 ; i++) { r = gammatable[pal[0]]; g = gammatable[pal[1]]; b = gammatable[pal[2]]; pal += 3; v = (r<<24) + (g<<16) + (b<<8) + 255; v = BigLong (v); tex_palette[i] = v; } } void SetTexParameters (void) { qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode ); switch ( texture_mode ) { case GL_NEAREST: case GL_NEAREST_MIPMAP_NEAREST: case GL_NEAREST_MIPMAP_LINEAR: qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); break; case GL_LINEAR: case GL_LINEAR_MIPMAP_NEAREST: case GL_LINEAR_MIPMAP_LINEAR: qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); break; } } /* ============ Texture_SetMode ============ */ void Texture_SetMode(int iMenu) { int i, iMode; HMENU hMenu; qboolean texturing = true; hMenu = GetMenu(g_qeglobals.d_hwndMain); switch(iMenu) { case ID_VIEW_NEAREST: iMode = GL_NEAREST; break; case ID_VIEW_NEARESTMIPMAP: iMode = GL_NEAREST_MIPMAP_NEAREST; break; case ID_VIEW_LINEAR: iMode = GL_NEAREST_MIPMAP_LINEAR; break; case ID_VIEW_BILINEAR: iMode = GL_LINEAR; break; case ID_VIEW_BILINEARMIPMAP: iMode = GL_LINEAR_MIPMAP_NEAREST; break; case ID_VIEW_TRILINEAR: iMode = GL_LINEAR_MIPMAP_LINEAR; break; case ID_TEXTURES_WIREFRAME: iMode = 0; texturing = false; break; case ID_TEXTURES_FLATSHADE: iMode = 0; texturing = false; break; } CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED); CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED); g_qeglobals.d_savedinfo.iTexMenu = iMenu; texture_mode = iMode; if (g_PrefsDlg.m_bSGIOpenGL) { if (s_hdcTexture && s_hglrcTexture) { //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) Error ("wglMakeCurrent in LoadTexture failed"); } else return; } if ( texturing ) SetTexParameters (); if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME) { g_pParentWnd->GetCamera()->Camera().draw_mode = cd_wire; Map_BuildBrushData(); Sys_UpdateWindows (W_ALL); return; } else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) { g_pParentWnd->GetCamera()->Camera().draw_mode = cd_solid; Map_BuildBrushData(); Sys_UpdateWindows (W_ALL); return; } for (i=1 ; iGetCamera()->Camera().draw_mode != cd_texture) { g_pParentWnd->GetCamera()->Camera().draw_mode = cd_texture; Map_BuildBrushData(); } Sys_UpdateWindows (W_ALL); } /* ================ R_MipMap Operates in place, quartering the size of the texture ================ */ void R_MipMap (byte *in, int &width, int &height) { int i, j; byte *out; int row; row = width * 4; width >>= 1; height >>= 1; out = in; for (i=0 ; i>2; out[1] = (in[1] + in[5] + in[row+1] + in[row+5])>>2; out[2] = (in[2] + in[6] + in[row+2] + in[row+6])>>2; out[3] = (in[3] + in[7] + in[row+3] + in[row+7])>>2; } } } /* ================= Texture_LoadTexture ================= */ //extern void Handle3DfxTexturing(qtexture_t* q, int nWidth, int nHeight, unsigned* pDest); qtexture_t *Texture_LoadTexture (miptex_t *qtex) { byte *source; unsigned char *dest; int width, height, i, count; int total[3]; qtexture_t *q; width = LittleLong(qtex->width); height = LittleLong(qtex->height); //if (g_PrefsDlg.m_bSGIOpenGL) //{ // if (width == 320) // return NULL; //} q = (qtexture_t*)qmalloc(sizeof(*q)); q->width = width; q->height = height; q->flags = qtex->flags; q->value = qtex->value; q->contents = qtex->contents; dest = (unsigned char*)qmalloc (width*height*4); count = width*height; source = (byte *)qtex + LittleLong(qtex->offsets[0]); // The dib is upside down so we want to copy it into // the buffer bottom up. total[0] = total[1] = total[2] = 0; for (i=0 ; icolor[0] = (float)total[0]/(count*255); q->color[1] = (float)total[1]/(count*255); q->color[2] = (float)total[2]/(count*255); q->texture_number = texture_extension_number++; if (g_PrefsDlg.m_bSGIOpenGL) { //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) Error ("wglMakeCurrent in LoadTexture failed"); } qglBindTexture( GL_TEXTURE_2D, q->texture_number ); //Handle3DfxTexturing(q, width, height, dest); SetTexParameters (); int nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality; while (nCount-- > 0) { if (width > 16 && height > 16) { R_MipMap(dest, width, height); } else { break; } } if (g_PrefsDlg.m_bSGIOpenGL) { if (nomips) { qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest); } else qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest); } else { if (nomips) qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest); else qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest); } free (dest); qglBindTexture( GL_TEXTURE_2D, 0 ); return q; } /* ================= Texture_LoadTexture ================= */ //extern void Handle3DfxTexturing(qtexture_t* q, int nWidth, int nHeight, unsigned* pDest); // (the TGA part of this function name appears to be irrelevant, the only criteria is that the pixels supplied are // 32bpp, and in a normal sequential memory buffer...) // qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char* pPath, int nFlags, int nContents, int nValue ) { int i, j, inf; byte gammatable[256]; float fGamma = g_qeglobals.d_savedinfo.fGamma; qtexture_t* q = (qtexture_t*)qmalloc(sizeof(*q)); q->width = nWidth; q->height = nHeight; q->flags = nFlags; q->value = nValue; q->contents = nContents; int nCount = nWidth * nHeight; float total[3]; total[0] = total[1] = total[2] = 0.0f; if (fGamma == 1.0) { for (i=0 ; i<256 ; i++) gammatable[i] = i; } else { for (i=0 ; i<256 ; i++) { inf = 255 * pow ( (i+0.5)/255.5 , fGamma ) + 0.5; if (inf < 0) inf = 0; if (inf > 255) inf = 255; gammatable[i] = inf; } } // all targas are stored internally as 32bit so rgba = 4 bytes for (i = 0 ; i < (nCount * 4) ; i += 4) { for (j = 0; j < 3; j++) { total[j] += (pPixels+i)[j]; byte b = (pPixels+i)[j]; (pPixels+i)[j] = gammatable[b]; } } q->color[0] = total[0] / (nCount * 255); q->color[1] = total[1] / (nCount * 255); q->color[2] = total[2] / (nCount * 255); q->texture_number = texture_extension_number++; if (g_PrefsDlg.m_bSGIOpenGL) { //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) Error ("wglMakeCurrent in LoadTexture failed"); } qglBindTexture( GL_TEXTURE_2D, q->texture_number ); //Handle3DfxTexturing(q, width, height, dest); SetTexParameters(); nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality; while (nCount-- > 0) { if (nWidth > 16 && nHeight > 16) { R_MipMap(pPixels, nWidth, nHeight); } else { break; } } if (g_PrefsDlg.m_bSGIOpenGL) { if (nomips) { qglTexImage2D(GL_TEXTURE_2D, 0, 3, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels); } else qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels); } else { if (nomips) qglTexImage2D(GL_TEXTURE_2D, 0, 3, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels); else qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels); } qglBindTexture( GL_TEXTURE_2D, 0 ); return q; } qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char *pPath) { CString strName; CString strPath; ExtractPath_and_Filename(pPath, strPath, strName); AddSlash(strPath); strPath += "textureinfo.ini"; strName.MakeLower(); StripExtension (strName.GetBuffer(0)); strName.ReleaseBuffer(); int nFlags = GetPrivateProfileInt(strName, "Flags", 0, strPath); int nValue = GetPrivateProfileInt(strName, "Value", 0, strPath); int nContents = GetPrivateProfileInt(strName, "Contents", 0, strPath); return Texture_LoadTGATexture(pPixels, nWidth, nHeight, pPath, nFlags, nValue, nContents); } void Texture_LoadFromPlugIn(LPVOID vp) { _QERTextureLoad *pLoad = reinterpret_cast<_QERTextureLoad*>(vp); if (pLoad != NULL) { qtexture_t *q; q = Texture_LoadTGATexture(pLoad->m_pRGBA, pLoad->m_nWidth, pLoad->m_nHeight, NULL, pLoad->m_nFlags, pLoad->m_nContents, pLoad->m_nValue); if (q != NULL) { // to save duplicate code (since one always ends up getting forgotten and out of sync) this is now done later by caller // strcpy (q->name, pLoad->m_pName); // StripExtension (q->name); // if (!g_dontuse) // q->inuse = true; // q->next = g_qeglobals.d_qtextures; // g_qeglobals.d_qtextures = q; g_pluginTexture = q; } } } /* =============== Texture_CreateSolid Create a single pixel texture of the apropriate color =============== */ qtexture_t *Texture_CreateSolid (const char *name) { byte data[4]; qtexture_t *q; q = (qtexture_t*)qmalloc(sizeof(*q)); sscanf (name, "(%f %f %f)", &q->color[0], &q->color[1], &q->color[2]); data[0] = q->color[0]*255; data[1] = q->color[1]*255; data[2] = q->color[2]*255; data[3] = 255; q->width = q->height = 1; //q->width = q->height = 2; q->texture_number = texture_extension_number++; qglBindTexture( GL_TEXTURE_2D, q->texture_number ); SetTexParameters (); if (g_PrefsDlg.m_bSGIOpenGL) { qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } else { if (nomips) qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); else qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data); } qglBindTexture( GL_TEXTURE_2D, 0 ); return q; } /* ================= Texture_MakeNotexture ================= */ void Texture_MakeNotexture (void) { qtexture_t *q; byte data[4][4]; if (g_PrefsDlg.m_bSGIOpenGL) { if (s_hdcTexture && s_hglrcTexture) { //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) Error ("wglMakeCurrent in LoadTexture failed"); } else return; } notexture = q = (qtexture_t*)qmalloc(sizeof(*q)); strcpy (q->name, "notexture"); q->width = q->height = 64; memset (data, 0, sizeof(data)); data[0][2] = data[3][2] = 255; q->color[0] = 0; q->color[1] = 0; q->color[2] = 0.5; q->texture_number = texture_extension_number++; qglBindTexture( GL_TEXTURE_2D, q->texture_number ); SetTexParameters (); if (nomips) qglTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); else VERIFY(qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data) == 0); qglBindTexture( GL_TEXTURE_2D, 0 ); } qtexture_t *Texture_MakePlaceHolder(void) { qtexture_t *q; byte data[4][4]; if (g_PrefsDlg.m_bSGIOpenGL) { if (s_hdcTexture && s_hglrcTexture) { //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) Error ("wglMakeCurrent in Texture_MakePlaceHolder failed"); } else return NULL; } q = (qtexture_t*)qmalloc(sizeof(*q)); strcpy (q->name, "placeholder"); // overwritten on return q->width = q->height = 64; q->bPlaceHolder = true; memset (data, 0, sizeof(data)); data[0][1] = data[3][1] = 255; // green and black squares q->color[0] = 0; q->color[1] = 0; q->color[2] = 0.5; q->texture_number = texture_extension_number++; qglBindTexture( GL_TEXTURE_2D, q->texture_number ); SetTexParameters (); if (nomips) qglTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); else VERIFY(qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data) == 0); qglBindTexture( GL_TEXTURE_2D, 0 ); return q; } void LoadShader(const char* pFilename, qtexture_t *q) { char* pBuff = NULL; CString strTexture; int nSize = LoadFile(pFilename, reinterpret_cast(&pBuff)); if (nSize == -1) { nSize = PakLoadAnyFile(pFilename, reinterpret_cast(&pBuff)); } if (nSize > 0) { StartTokenParsing(pBuff); while (GetToken(true)) { // first token should be the path + name.. (from base) CShaderInfo *pShader = new CShaderInfo(); pShader->setName(token); pShader->m_strShaderName = pFilename; strTexture = token; bool bGood = true; float fTrans = 1.0; GetToken(true); if (strcmp(token, "{")) { bGood = false; break; } else { // we need to read until we hit a balanced } int nMatch = 1; while (nMatch > 0 && GetToken(true)) { if (strcmp(token, "{") == 0) { nMatch++; } else if (strcmp(token, "}") == 0) { nMatch--; } else if (strcmpi(token, "qer_nocarve") == 0) { pShader->m_nFlags |= QER_NOCARVE; } else if (strcmpi(token, "qer_trans") == 0) { if (GetToken(true)) { fTrans = atof(token); } pShader->m_nFlags |= QER_TRANS; } else if (strcmpi(token, "qer_editorimage") == 0) { if (GetToken(true)) { char* pTex = copystring(token); QE_ConvertDOSToUnixName( pTex, pTex ); CString str = pTex; free (pTex); FindReplace(str, "textures/", ""); FindReplace(str, ".tga", ""); int nPos = str.Find('/'); if (nPos == -1) { nPos = str.Find('\\'); } if (nPos >= 0) { if (g_PrefsDlg.m_bShaderTest) { pShader->m_strTextureName = str; pShader->m_strTextureName.MakeLower(); //avoid problems with case } else { CString strPath = str.Left(nPos+1); DeferredShaderLoad *deferred = new DeferredShaderLoad(str, pShader->m_strName, strPath); g_lstDeferred.Add(deferred); } } } } else if (strcmpi(token, "surfaceparm") == 0) { //--while (GetToken(false)) //--{ //-- //--} if (GetToken(true)) { // next token should be a surface parm //--if (strcmpi(token, "trans") == 0) //--{ //-- fTrans = 0.33; //--} if (strcmpi(token, "fog") == 0) { if (fTrans == 1.0) // has not been explicitly set by qer_trans { fTrans = 0.35; } } } } } if (nMatch != 0) { bGood = false; break; } } //--if (bGood && q) if (bGood) { pShader->m_fTransValue = fTrans; g_lstShaders.Add(pShader); if (g_PrefsDlg.m_bShaderTest) { // new if (pShader->m_strTextureName.GetLength() > 0) { if (!ShaderQTextureExists(pShader->m_strName)) { q = Texture_ForName ( pShader->m_strTextureName.GetBuffer(0), true, // bool bForArchitecture NULL, // const char *psBasePath eReplace_NO, // eReplace_t eReplace true // bool bPlaceHolderLoad ); if (q != NULL) { strcpy(q->shadername, pShader->m_strShaderName); q->bFromShader = true; q->fTrans = pShader->m_fTransValue; q->nShaderFlags = pShader->m_nFlags; strcpy(q->name, pShader->m_strName); } } } } // end new //--q->bFromShader = true; //--q->fTrans = fTrans; //--// good texture here //--//Sys_Printf("Test load texture %s\n", strTexture); //--// FIXME.. this is a load of crap //--strcpy(dirstring, strTexture); //--QE_ConvertDOSToUnixName(dirstring, dirstring); //--strTexture = dirstring; //--FindReplace(strTexture, "textures/", ""); //--qtexture_t *q = Texture_ForName (strTexture.GetBuffer(0)); //--if (q != NULL) //--{ //-- q->bFromShader = true; //-- q->fTrans = fTrans; //--} } else { Sys_Printf("Error parsing shader at texture %s\n", strTexture); } } free (pBuff); } else { Sys_Printf("Unabled to read shader %s\n", pFilename); } } extern bool DoesFileExist(const char* pBuff, long& lSize); void SetNameShaderInfo(qtexture_t* q, const char* pPath, const char* pName) { CShaderInfo *pInfo = hasShader(pName); if (pInfo) { strcpy(q->shadername, pInfo->m_strShaderName); q->bFromShader = true; q->fTrans = pInfo->m_fTransValue; q->nShaderFlags = pInfo->m_nFlags; } else { q->shadername[0] = 0; } strncpy (q->name, pName, sizeof(q->name) - 1); StripExtension (q->name); } void ReplaceQTexture(qtexture_t *pOld, qtexture_t *pNew) { brush_t* pList = &active_brushes; for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next) { if (pBrush->patchBrush) { Patch_ReplaceQTexture(pBrush, pOld, pNew); } for (face_t* pFace = pBrush->brush_faces; pFace; pFace = pFace->next) { if (pFace->d_texture == pOld) { pFace->d_texture = pNew; } } //Brush_Build(pBrush); } } void Texture_Remove(qtexture_t *q) { qtexture_t* pTex = g_qeglobals.d_qtextures->next; if (q == g_qeglobals.d_qtextures) // it is the head { g_qeglobals.d_qtextures->next = q->next->next; g_qeglobals.d_qtextures = q->next; } else { qtexture_t* pLast = g_qeglobals.d_qtextures; while (pTex != NULL && pTex != g_qeglobals.d_qtextures) { if (pTex == q) { pLast->next = q->next; break; } pLast = pTex; pTex = pTex->next; } } qglDeleteTextures(1, reinterpret_cast(&q->texture_number)); free(q); } bool GetFileTime(LPCSTR psFileName, FILETIME &ft) { bool bSuccess = false; HANDLE hFile = CreateFile( psFileName, // LPCTSTR lpFileName, // pointer to name of the file GENERIC_READ, // DWORD dwDesiredAccess, // access (read-write) mode FILE_SHARE_READ, // DWORD dwShareMode, // share mode NULL, // LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes OPEN_EXISTING, // DWORD dwCreationDisposition, // how to create FILE_FLAG_SEQUENTIAL_SCAN,// DWORD dwFlagsAndAttributes, // file attributes NULL // HANDLE hTemplateFile // handle to file with attributes to ); if (hFile != INVALID_HANDLE_VALUE) { if (GetFileTime(hFile, // handle to file NULL, // LPFILETIME lpCreationTime NULL, // LPFILETIME lpLastAccessTime &ft // LPFILETIME lpLastWriteTime ) ) { bSuccess = true; } CloseHandle(hFile); } return bSuccess; } bool CurrentFileOutOfDate(FILETIME &ftCurrent, FILETIME &ftProposed) { LONG l = CompareFileTime( &ftCurrent, &ftProposed ); return (l<0); } static qtexture_t *Texture_ForName_Actual (const char *name, const char *psBasePath /* may be NULL */, qtexture_t *pRemove, bool bPlaceHolderLoad) { byte *lump; qtexture_t *q; char filename[1024]; if (bPlaceHolderLoad) { Sys_Printf ("Placeholding %s...", name); q = Texture_MakePlaceHolder(); if (q == NULL) { Sys_Printf ("ERROR in SGI code!\n"); return notexture; // only happens if Errorbox pops up using SGI OpenGL, so who cares? } SetNameShaderInfo(q, filename, name); Sys_Printf ("ok\n"); } else { if (name[0] == '(') { q = Texture_CreateSolid (name); strncpy (q->name, name, sizeof(q->name)-1); } else { // FIXME: this is a mess.. need to move consolidate stuff // down to a single routine.. // // if plugins have a texture loader // { // // } // else // if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL) { // rad: 12/19/98 // if the plugin is not a wad style then we need to treat it normally // otherwise return without trying to explicitly load the texture // as it should have been loaded by the wad style plugin at init time CString strTex = GetTextureExtension(0); sprintf (filename, "%s\\%s.%s", (psBasePath?psBasePath:ValueForKey (g_qeglobals.d_project_entity, "texturepath")), name, strTex); if (!g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle) { g_pParentWnd->GetPlugInMgr().LoadTexture(filename); q = g_pluginTexture; } else { return notexture; // wadstyle.. if we get here then we do not have it } } else { if (g_PrefsDlg.m_bHiColorTextures == TRUE) { sprintf (filename, "%s/%s.tga", (psBasePath?psBasePath:ValueForKey (g_qeglobals.d_project_entity, "texturepath")), name); if (strchr(/*file*/name,' ')) // only check 'name', not 'filename' since we don't care about the "q:\quake" part (which CAN have spaces) { ErrorBox( va("Dammit!\n\nThe texture name \"%s\" has a space in it\n\nFix this now!!!",name)); } else { Sys_Printf ("Loading %s...", name); unsigned char* pPixels = NULL; int nWidth; int nHeight; LoadTGA(filename, &pPixels, &nWidth, &nHeight); if (pPixels) { q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0); SetNameShaderInfo(q, filename, name); Sys_Printf ("done.\n", name); free(pPixels); } else { Sys_Printf ("failed. Trying Shader..."); //=========== findmeste2 CShaderInfo *pInfo = hasShader(name); if (pInfo) { sprintf (filename, "%s/%s.tga", (psBasePath?psBasePath:ValueForKey (g_qeglobals.d_project_entity, "texturepath")), pInfo->m_strTextureName); LoadTGA(filename, &pPixels, &nWidth, &nHeight); } if (pPixels) { q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0); SetNameShaderInfo(q, filename, name); free(pPixels); Sys_Printf (" success, shader: \"%s\"\n", q->shadername); } else { Sys_Printf (" failed. Using default. !! !! !!\n"); q = notexture; SetNameShaderInfo(q, filename, name); Texture_MakeNotexture(); } } } } else { // load the file sprintf (filename, "%s/%s.wal", (psBasePath?psBasePath:ValueForKey (g_qeglobals.d_project_entity, "texturepath")), name); Sys_Printf ("Loading %s...", name); if (LoadFile (filename, (void**)&lump) == -1) { sprintf (filename, "%s.wal", name); Sys_Printf("failed.. trying pak0.pak.."); if(!PakLoadFile(filename, (void**)&lump)) { Sys_Printf (" load failed!\n"); return notexture; } } Sys_Printf("successful.\n"); q = Texture_LoadTexture ((miptex_t *)lump); free (lump); strncpy (q->name, name, sizeof(q->name)-1); StripExtension (q->name); } } if(!q) return notexture; strncpy (q->name, name, sizeof(q->name)-1); StripExtension (q->name); }// name[0] != '(' } if(!q) // safety return notexture; if (!g_dontuse) q->inuse = true; q->next = g_qeglobals.d_qtextures; g_qeglobals.d_qtextures = q; if (pRemove != NULL) { Sys_Printf ("** Replacing %s with %s **\n", pRemove->name, q->name); ReplaceQTexture(pRemove, q); Texture_Remove(pRemove); } return q; } extern char gsFoundFilename[MAX_PATH]; extern FILETIME gtFileTime; extern bool gbFileTimeValid; //bool GetFileTime(LPCSTR psFileName, FILETIME &ft); qtexture_t *Texture_ForName(const char *name, bool bForArchitecture /* = true */, const char *psBasePath /* = NULL */, eReplace_t eReplace /* = eReplace_NO */, bool bPlaceHolderLoad /* = false */ ) { qtexture_t *q; #ifdef QUAKE3 // this is really dirty, I'm going to write back into a constant char array (which is part of a CString buffer) // purely because I know that changing the case won't overrun any internal buffers... :-) // char *__p = const_cast (name); strlwr(__p); #endif if (strlen(name) == 0) return notexture; qtexture_t *pRemove = NULL; for (q=g_qeglobals.d_qtextures ; q ; q=q->next) { if (!stricmp(name, q->name)) { if (bPlaceHolderLoad) // don't worry about this until we try and load it seriously, this is just establishing the name slot { return q; } else { if (q->bPlaceHolder) { eReplace = eReplace_YES; // neat, huh? } } switch ( eReplace ) { case eReplace_NO: if (!g_dontuse) q->inuse = true; q->bForArchitecture = bForArchitecture; return q; case eReplace_YES: pRemove = q; //Texture_Remove(q); break; case eReplace_TIMESTAMP: if (q->sFTName[0]) { FILETIME ftDiskVersion; if (GetFileTime(q->sFTName, ftDiskVersion)) { if (!CurrentFileOutOfDate(q->ft, ftDiskVersion)) { if (!g_dontuse) q->inuse = true; q->bForArchitecture = bForArchitecture; return q; } } } pRemove = q; break; } break; } } gbFileTimeValid = false; q = Texture_ForName_Actual(name, psBasePath, pRemove, bPlaceHolderLoad); if (gbFileTimeValid && gsFoundFilename[0]) { q->ft = gtFileTime; strcpy(q->sFTName,gsFoundFilename); } else { q->sFTName[0] = '\0'; } q->bForArchitecture = bForArchitecture; return q; } /* =============== Texture_ForName =============== */ /* // appears not to be used now qtexture_t *Texture_ForNamePath(char* name, char* pFullPath) { byte *lump; qtexture_t *q; char filename[1024]; if (strlen(name) == 0) return notexture; for (q=g_qeglobals.d_qtextures ; q ; q=q->next) { if (!strcmp(name, q->name)) { if (!g_dontuse) q->inuse = true; return q; } } if (name[0] == '(') { q = Texture_CreateSolid (name); strncpy (q->name, name, sizeof(q->name)-1); } else { // load the file if (g_PrefsDlg.m_bHiColorTextures == TRUE) { sprintf(filename, "%s%s", pFullPath, ".tga"); Sys_Printf ("Loading %s...", name); unsigned char* pPixels = NULL; int nWidth; int nHeight; LoadTGA(filename, &pPixels, &nWidth, &nHeight); if (pPixels) { q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0); } else { return notexture; } free(pPixels); } else { sprintf(filename, "%s%s", pFullPath, ".wal"); Sys_Printf ("Loading %s...", name); if (LoadFile (filename, (void**)&lump) == -1) { Sys_Printf (" load failed!\n"); return notexture; } Sys_Printf("successful.\n"); q = Texture_LoadTexture ((miptex_t *)lump); free (lump); } if (g_PrefsDlg.m_bSGIOpenGL) { if(!q) return notexture; } strncpy (q->name, name, sizeof(q->name)-1); StripExtension (q->name); } if (!g_dontuse) q->inuse = true; q->next = g_qeglobals.d_qtextures; g_qeglobals.d_qtextures = q; return q; } */ /* ================== FillTextureMenu ================== */ void FillTextureMenu (CStringArray* pArray) { HMENU hmenu; int i; struct _finddata_t fileinfo; int handle; char dirstring[1024]; char *path; DIRLIST *list = NULL, *temp; if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL) { if (g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle) return; } hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_TEXTURE); // delete everything for (i=0 ; inext) { AppendMenu (hmenu, MF_ENABLED|MF_STRING, CMD_TEXTUREWAD+texture_nummenus, (LPCTSTR)temp->dirname); strcpy (texture_menunames[texture_nummenus], temp->dirname); //--if (!g_PrefsDlg.m_bUseShaders) //--{ strcat (texture_menunames[texture_nummenus], "/"); //--} if (pArray) pArray->Add(temp->dirname); if (++texture_nummenus == MAX_TEXTUREDIRS) break; } ClearDirList(&list); } } /* ================== Texture_ClearInuse A new map is being loaded, so clear inuse markers ================== */ void Texture_ClearInuse (void) { qtexture_t *q; for (q=g_qeglobals.d_qtextures ; q ; q=q->next) { q->inuse = false; } } /* ============== Texture_LoadPalette ============== */ void Texture_LoadPalette (char *palette) { char name[1024]; byte *pal; // added for daikatana Texture_ClearInuse (); //load the palette sprintf (name, "%s/textures/%scolormap.bmp", // added for daikatana ValueForKey(g_qeglobals.d_project_entity, "basepath"), palette);// added for daikatana Load256Image (name, NULL, &pal, NULL, NULL); // added for daikatana if (!pal) // added for daikatana Error ("Couldn't load %s", name); // added for daikatana Texture_InitPalette (pal); // added for daikatana free (pal); // added for daikatana // create the fallback texture // added for daikatana Texture_MakeNotexture (); // added for daikatana } /* ============== Texture_LoadPalette ============== */ void Texture_LoadPaletteExplicit(char *palette) { char name[1024]; byte *pal; // added for daikatana Texture_ClearInuse (); //load the palette sprintf (name, "%s%s",palette,"colormap.bmp"); Load256Image (name, NULL, &pal, NULL, NULL); // added for daikatana if (!pal) // added for daikatana Error ("Couldn't load %s", name); // added for daikatana Texture_InitPalette (pal); // added for daikatana free (pal); // added for daikatana // create the fallback texture // added for daikatana Texture_MakeNotexture (); // added for daikatana } /* ============== Texture_ShowDirectory ============== */ void Texture_ShowDirectory (int menunum, bool bLinked) { struct _finddata_t fileinfo; int handle; char name[1024]; char dirstring[1024]; char linkstring[1024]; FILELIST *list = NULL, *temp; CString strTemp; //Texture_Flush(false); Select_Deselect(); texture_showinuse = false; strcpy (texture_directory, texture_menunames[menunum-CMD_TEXTUREWAD]); if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL) { if (g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle) return; } // new if (!g_PrefsDlg.m_bShaderTest) { g_dontuse = true; // needed because this next piece of code calls Texture_ForName() internally! -slc LoadDeferred(texture_directory); g_dontuse = false; } if (g_PrefsDlg.m_bHiColorTextures == FALSE) { } g_qeglobals.d_texturewin.originy = 0; //--if (g_PrefsDlg.m_bUseShaders) //--{ //-- sprintf (dirstring, "%s/scripts/%s", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_directory); //-- Sys_Printf("loading textures from shader %s\n", dirstring); //-- LoadShader(dirstring); //--} //--else //--{ Sys_Status("Loading textures\n", 0); // load all image files sprintf (linkstring, "%s/textures/%stextureinfo.ini", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_menunames[menunum-CMD_TEXTUREWAD]); for (int nExt = 0; nExt < GetTextureExtensionCount(); nExt++) { sprintf (dirstring, "%s/textures/%s*.%s", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt)); Sys_Printf ("Scanning %s\n", dirstring); handle = _findfirst (dirstring, &fileinfo); if (handle == -1) { sprintf(dirstring, "%s/%s*.%s", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt)); handle = _findfirst (dirstring, &fileinfo); } if (handle != -1) { do { sprintf (name, "%s%s", texture_directory, fileinfo.name); AddToFileListAlphabetized(&list, name, FROMDISK, 0, false); } while (_findnext( handle, &fileinfo ) != -1); _findclose (handle); } else {//if you don't put textures/ in here, it will also return other crap like, menu/common/*.tga sprintf (dirstring, "textures/%s*.%s", texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt)); if(!GetPackFileList(&list, dirstring)) { // return; } } } g_dontuse = true; for(temp = list; temp; temp = temp->next) { if(temp->offset == -1) sprintf(name, "%s", temp->filename); else sprintf(name, "%s%s", texture_menunames[menunum-CMD_TEXTUREWAD], temp->filename); StripExtension (name); strTemp = name; strTemp.MakeLower(); if ( strTemp.Find(".specular") >= 0 || strTemp.Find(".glow") >= 0 || strTemp.Find(".bump") >= 0 || strTemp.Find(".diffuse") >= 0 || strTemp.Find(".blend") >= 0 || strTemp.Find(".alpha") >= 0 ) continue; else { //if pref do replacing //Texture_ForName (name, true); //else Texture_ForName (name, true, NULL, eReplace_TIMESTAMP); // any architecture placeholder textures still need loading?... // bool bPlaceHoldersStillExist = false; for (qtexture_t *q=g_qeglobals.d_qtextures ; q ; q=q->next) { if (q->bForArchitecture && q->bPlaceHolder) { bPlaceHoldersStillExist = true; break; } } if (bPlaceHoldersStillExist) { // new bit, because of placeholder loading, we should also force-load any other shaders that use this // texture... CString strTextureName(name); CShaderInfo *pParentShader = hasShader(name); if (pParentShader && !pParentShader->m_strTextureName.IsEmpty()) { strTextureName = pParentShader->m_strTextureName; } // find all other shaders that also use this texture and load them as well... // int nSize = g_lstShaders.GetSize(); for (int i = 0; i < nSize; i++) { CShaderInfo *pInfo = reinterpret_cast(g_lstShaders.ElementAt(i)); if (pInfo != NULL && pInfo != pParentShader) { // does this shader same the same actual texture as the one we've just loaded?... // if (pInfo->m_strTextureName.CompareNoCase(strTextureName) == 0) { // yep, so ensure this one is loaded as well... // Texture_ForName(pInfo->m_strName, true, NULL, eReplace_TIMESTAMP); } } } } } } ClearFileList(&list); //--} g_dontuse = false; if (!bLinked) { for (int k = 0; k < 10; k++) { sprintf(name, "Path%d", k); if (GetPrivateProfileString("Include", name, "", dirstring, 1024, linkstring) > 0) { Texture_ShowDirectory(dirstring, true); } } SortTextures(); sprintf (name, "Textures: %s", texture_directory); SetWindowText(g_qeglobals.d_hwndEntity, name); // select the first texture in the list if (!g_qeglobals.d_texturewin.texdef.name[0]) SelectTexture (16, g_qeglobals.d_texturewin.height -16, false); } Sys_Printf ("Done\n", dirstring); } // this can be combined with the above, but per usual i am in a hurry // void Texture_ShowDirectory (char* pPath, bool bLinked) { struct _finddata_t fileinfo; int handle; char name[1024]; char dirstring[1024]; char linkstring[1024]; FILELIST *list = NULL, *temp; //Texture_Flush(false); texture_showinuse = false; strcpy (texture_directory, pPath); if (g_PrefsDlg.m_bHiColorTextures == FALSE) { } g_qeglobals.d_texturewin.originy = 0; Sys_Status("loading all textures\n", 0); // load all .wal files for (int nExt = 0; nExt < GetTextureExtensionCount(); nExt++) { sprintf(dirstring, "%s*.%s", pPath,GetTextureExtension(nExt)); Sys_Printf ("Scanning %s\n", dirstring); handle = _findfirst (dirstring, &fileinfo); if (handle != -1) { do { sprintf (name, "%s%s", texture_directory, fileinfo.name); AddToFileListAlphabetized(&list, name, FROMDISK, 0, false); } while (_findnext( handle, &fileinfo ) != -1); _findclose (handle); } else { //sprintf (dirstring, "%s*.wal", texture_menunames[menunum-CMD_TEXTUREWAD]); //if(!GetPackFileList(&list, dirstring)) // return; } } g_dontuse = true; for(temp = list; temp; temp = temp->next) { if(temp->offset == -1) sprintf(name, "%s", temp->filename); else sprintf(name, "%s%s", pPath, temp->filename); StripExtension (name); int nLen = strlen(name)-1; ASSERT(nLen > 0); while (name[nLen] != '\\') nLen--; // found first one nLen--; ASSERT(nLen > 0); while (name[nLen] != '\\') nLen--; ASSERT(nLen >= 0); QE_ConvertDOSToUnixName(name, name); Texture_ForName(&name[nLen+1]); } ClearFileList(&list); g_dontuse = false; if (!bLinked) { for (int k = 0; k < 10; k++) { sprintf(name, "Path%d", k); if (GetPrivateProfileString("Include", name, "", dirstring, 1024, linkstring) > 0) { Texture_ShowDirectory(dirstring, true); } } SortTextures(); sprintf (name, "Textures: %s", texture_directory); SetWindowText(g_qeglobals.d_hwndEntity, name); // select the first texture in the list if (!g_qeglobals.d_texturewin.texdef.name[0]) SelectTexture (16, g_qeglobals.d_texturewin.height -16, false); } } void Texture_ResetPosition() { SelectTexture (16, g_qeglobals.d_texturewin.height -16, false); g_qeglobals.d_texturewin.originy = 0; } /* ============== Texture_ShowInuse ============== */ void Texture_ShowInuse (void) { face_t *f; brush_t *b; char name[1024]; texture_showinuse = true; g_dontuse = false; g_qeglobals.d_texturewin.originy = 0; Texture_ClearInuse(); Sys_Status("Selecting active textures\n", 0); for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next) { const char *p = Patch_FromBrush_GetTextureName(b); if (strlen(p)) Texture_ForName (p); for (f=b->brush_faces ; f ; f=f->next) Texture_ForName (f->texdef.name); } for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next) { const char *p = Patch_FromBrush_GetTextureName(b); if (strlen(p)) Texture_ForName (p); for (f=b->brush_faces ; f ; f=f->next) Texture_ForName (f->texdef.name); } SortTextures(); //SetInspectorMode(W_TEXTURE); Sys_UpdateWindows (W_TEXTURE); sprintf (name, "Textures: in use"); SetWindowText(g_qeglobals.d_hwndEntity, name); // select the first texture in the list if (!g_qeglobals.d_texturewin.texdef.name[0]) { SelectTexture (16, g_qeglobals.d_texturewin.height -16, false); } } /* ============================================================================ TEXTURE LAYOUT ============================================================================ */ void Texture_StartPos (void) { current_texture = g_qeglobals.d_qtextures; current_x = 8; current_y = -8; current_row = 0; } qtexture_t *Texture_NextPos (int *x, int *y) { qtexture_t *q; while (1) { q = current_texture; if (!q) return q; current_texture = current_texture->next; if (q->name[0] == '(') // fake color texture continue; if (!q->bForArchitecture) continue; if (g_bFilterEnabled) { CString strName = q->name; int nPos = strName.Find('\\'); if (nPos == -1) nPos = strName.Find('/'); if (nPos >= 0) strName = strName.Right(strName.GetLength() - nPos - 1); if (strnicmp(g_strFilter.GetBuffer(0), strName, g_strFilter.GetLength()) == 0) break; else continue; } if (q->bFromShader && g_PrefsDlg.m_bShowShaders == FALSE) { continue; } if (q->inuse) break; // always show in use if (!texture_showinuse && !strnicmp (q->name, texture_directory, strlen(texture_directory))) break; continue; } int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; if (current_x + nWidth > g_qeglobals.d_texturewin.width-8 && current_row) { // go to the next row unless the texture is the first on the row current_x = 8; current_y -= current_row + FONT_HEIGHT + 4; current_row = 0; } *x = current_x; *y = current_y; // Is our texture larger than the row? If so, grow the // row height to match it if (current_row < nHeight) current_row = nHeight; // never go less than 64, or the names get all crunched up current_x += nWidth < 64 ? 64 : nWidth; current_x += 8; return q; } /* ============================================================================ MOUSE ACTIONS ============================================================================ */ static int textures_cursorx, textures_cursory; /* ============ Texture_SetTexture ============ */ void Texture_SetTexture (texdef_t *texdef, bool bFitScale/*=false*/, bool bNoSystemTextureOverwrite/*=false*/) { qtexture_t *q; int x,y; if (texdef->name[0] == '(') { Sys_Status("Can't select an entity texture\n", 0); return; } g_qeglobals.d_texturewin.texdef = *texdef; g_qeglobals.d_texturewin.texdef.flags &= ~SURF_KEEP; g_qeglobals.d_texturewin.texdef.contents &= ~CONTENTS_KEEP; Sys_UpdateWindows (W_TEXTURE); g_dlgFind.updateTextures(texdef->name); if (!g_dlgFind.isOpen())// && bSetSelection) { Select_SetTexture(texdef, bFitScale, bNoSystemTextureOverwrite); } // scroll origin so the texture is completely on screen Texture_StartPos (); while (1) { q = Texture_NextPos (&x, &y); if (!q) break; int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; if (!strcmpi(texdef->name, q->name)) { if (y > g_qeglobals.d_texturewin.originy) { g_qeglobals.d_texturewin.originy = y; Sys_UpdateWindows (W_TEXTURE); return; } if (y-nHeight-2*FONT_HEIGHT < g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height) { g_qeglobals.d_texturewin.originy = y-nHeight-2*FONT_HEIGHT+g_qeglobals.d_texturewin.height; Sys_UpdateWindows (W_TEXTURE); return; } return; } } } /* ============== SelectTexture By mouse click ============== */ void SelectTexture (int mx, int my, bool bShift, bool bFitScale/*=false*/, bool bNoSystemTextureOverwrite/*=false*/) { int x, y; qtexture_t *q, *pPrev = NULL; texdef_t tex; my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height; Texture_StartPos (); for (;;pPrev = q) { q = Texture_NextPos (&x, &y); if (!q) break; int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; if (mx > x && mx - x < nWidth && my < y && y - my < nHeight + FONT_HEIGHT) { if (q->bPlaceHolder) { CWaitCursor wait; // this next bit will change the order of the link list by inserting us at the front, so we need to // restore the list order for niceness... // qtexture_t *pNext = q->next; q = Texture_ForName(q->name, true, NULL, eReplace_YES, false); // q is now different (new malloc, linked to list start) // // move new q ptr back to old position in list... // if (pPrev) { assert(g_qeglobals.d_qtextures == q); g_qeglobals.d_qtextures = q->next; pPrev->next = q; q->next = pNext; } else { // was at the head now, was at the head before, ergo nothing to do... } Sys_UpdateWindows( W_TEXTURE); return; } if (bShift) { if (g_PrefsDlg.m_bHiColorTextures && q->shadername[0] != 0) { CString s = "notepad "; s += q->shadername; WinExec(s, SW_SHOWNORMAL); } } memset (&tex, 0, sizeof(tex)); tex.scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? fTEXTURE_SCALE : 1; tex.scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? fTEXTURE_SCALE : 1; tex.flags = q->flags; tex.value = q->value; tex.contents = q->contents; strcpy (tex.name, q->name); Texture_SetTexture (&tex, bFitScale,bNoSystemTextureOverwrite); CString strTex; CString strName = q->name; //int nPos = strName.Find('\\'); //if (nPos == -1) // nPos = strName.Find('/'); //if (nPos >= 0) // strName = strName.Right(strName.GetLength() - nPos - 1); strTex.Format("%s W: %i H: %i", strName.GetBuffer(0), q->width, q->height); g_pParentWnd->SetStatusText(3, strTex); return; } } Sys_Status("Did not select a texture\n", 0); } /* ============== Texture_MouseDown ============== */ void Texture_MouseDown (int x, int y, int buttons) { Sys_GetCursorPos (&textures_cursorx, &textures_cursory); // lbutton = select texture if (buttons == MK_LBUTTON || buttons == (MK_LBUTTON | MK_SHIFT) || buttons == (MK_LBUTTON | MK_CONTROL) || buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) { // I now distinguish shift and ctrl from shift&ctrl... // bool bShift = (buttons & MK_SHIFT) && !(buttons & MK_CONTROL); bool bFitScale = (buttons & MK_CONTROL) && !(buttons & MK_SHIFT); bool bNoSystemTextureOverwrite = (buttons & MK_CONTROL) && (buttons & MK_SHIFT); SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y, bShift, bFitScale, bNoSystemTextureOverwrite); UpdateSurfaceDialog(); UpdatePatchInspector(); } } /* ============== Texture_MouseUp ============== */ void Texture_MouseUp (int x, int y, int buttons) { } /* ============== Texture_MouseMoved ============== */ void Texture_MouseMoved (int x, int y, int buttons) { int scale = 1; if ( buttons & MK_SHIFT ) scale = 4; // rbutton = drag texture origin if (buttons & MK_RBUTTON) { Sys_GetCursorPos (&x, &y); if ( y != textures_cursory) { g_qeglobals.d_texturewin.originy += ( y-textures_cursory) * scale; if (g_qeglobals.d_texturewin.originy > 0) g_qeglobals.d_texturewin.originy = 0; Sys_SetCursorPos (textures_cursorx, textures_cursory); CWnd *pWnd = CWnd::FromHandle(g_qeglobals.d_hwndTexture); if (g_PrefsDlg.m_bTextureScrollbar && pWnd != NULL) { pWnd->SetScrollPos(SB_VERT, abs(g_qeglobals.d_texturewin.originy)); } InvalidateRect(g_qeglobals.d_hwndTexture, NULL, false); UpdateWindow (g_qeglobals.d_hwndTexture); } return; } } /* ============================================================================ DRAWING ============================================================================ */ int imax(int iFloor, int i) { if (i>iFloor) return iFloor; return i; } HFONT ghFont = NULL; /* ============ Texture_Draw2 ============ */ void Texture_Draw2 (int width, int height) { qtexture_t *q; int x, y; char *name; qglClearColor ( g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0], g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1], g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2], 0); qglViewport (0,0,width,height); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); qglDisable (GL_DEPTH_TEST); qglDisable(GL_BLEND); qglOrtho (0, width, g_qeglobals.d_texturewin.originy-height, g_qeglobals.d_texturewin.originy, -100, 100); qglEnable (GL_TEXTURE_2D); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); g_qeglobals.d_texturewin.width = width; g_qeglobals.d_texturewin.height = height; Texture_StartPos (); while (1) { q = Texture_NextPos (&x, &y); if (!q) break; int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; // Is this texture visible? if ( (y-nHeight-FONT_HEIGHT < g_qeglobals.d_texturewin.originy) && (y > g_qeglobals.d_texturewin.originy - height) ) { // if in use, draw a background if ((q->inuse && !texture_showinuse) || q->bFromShader) { qglLineWidth (1); if (q->bFromShader) { qglColor3f (1,1,1); } else { qglColor3f (0.5,1,0.5); } qglDisable (GL_TEXTURE_2D); qglBegin (GL_LINE_LOOP); qglVertex2f (x-1,y+1-FONT_HEIGHT); qglVertex2f (x-1,y-nHeight-1-FONT_HEIGHT); qglVertex2f (x+1+nWidth,y-nHeight-1-FONT_HEIGHT); qglVertex2f (x+1+nWidth,y+1-FONT_HEIGHT); qglEnd (); qglEnable (GL_TEXTURE_2D); } // Draw the texture float fScale = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? ((float)g_PrefsDlg.m_nTextureScale / 100) : 1.0; qglBindTexture( GL_TEXTURE_2D, q->texture_number ); QE_CheckOpenGLForErrors(); qglColor3f (1,1,1); qglBegin (GL_QUADS); qglTexCoord2f (0,0); qglVertex2f (x,y-FONT_HEIGHT); qglTexCoord2f (1,0); qglVertex2f (x+nWidth,y-FONT_HEIGHT); qglTexCoord2f (1,1); qglVertex2f (x+nWidth,y-FONT_HEIGHT-nHeight); qglTexCoord2f (0,1); qglVertex2f (x,y-FONT_HEIGHT-nHeight); qglEnd (); // draw the selection border if (!strcmpi(g_qeglobals.d_texturewin.texdef.name, q->name)) { qglLineWidth (3); qglColor3f (1,0,0); qglDisable (GL_TEXTURE_2D); qglBegin (GL_LINE_LOOP); qglVertex2f (x-4,y-FONT_HEIGHT+4); qglVertex2f (x-4,y-FONT_HEIGHT-nHeight-4); qglVertex2f (x+4+nWidth,y-FONT_HEIGHT-nHeight-4); qglVertex2f (x+4+nWidth,y-FONT_HEIGHT+4); qglEnd (); qglEnable (GL_TEXTURE_2D); qglLineWidth (1); } // draw the texture name qglColor3f (0,0,0); qglRasterPos2f (x, y-FONT_HEIGHT+2); // don't draw the directory name for (name = q->name ; *name && *name != '/' && *name != '\\' ; name++) ; if (!*name) name = q->name; else name++; if (g_PrefsDlg.m_bHiColorTextures && q->shadername[0] != 0) { // slow as shit CString s = "["; s += name; s += "]"; qglCallLists (s.GetLength(), GL_UNSIGNED_BYTE, s.GetBuffer(0)); } else { qglCallLists (strlen(name), GL_UNSIGNED_BYTE, name); } } } g_qeglobals.d_texturewin.m_nTotalHeight = abs(y) + 100; // reset the current texture qglBindTexture( GL_TEXTURE_2D, 0 ); qglFinish(); } #if 0 void Texture_LoadColorMap() { char name[1024]; byte *pal; // load the palette sprintf (name, "%s/pics/colormap.pcx", ValueForKey (g_qeglobals.d_project_entity, "basepath")); Load256Image (name, NULL, &pal, NULL, NULL); if (!pal) { // before dropping out, try to load it from the QERadiant directory CString strFile = g_strAppPath; AddSlash(strFile); strFile += "colormap.pcx"; Load256Image (strFile.GetBuffer(0), NULL, &pal, NULL, NULL); if (!pal) Error ("Couldn't load %s or %s", name, strFile); } else { Texture_InitPalette (pal); free (pal); } } // //================== //Texture_Init //================== // void Texture_Init (bool bHardInit) { Texture_LoadColorMap(); // create the fallback texture Texture_MakeNotexture (); g_qeglobals.d_qtextures = NULL; } #else void Texture_Init (bool bHardInit) { char name[1024]; byte *pal; if (g_PrefsDlg.m_bHiColorTextures == FALSE) { // load the palette sprintf (name, "%s/pics/colormap.pcx", ValueForKey (g_qeglobals.d_project_entity, "basepath")); Load256Image (name, NULL, &pal, NULL, NULL); if (!pal) { // before dropping out, try to load it from the QERadiant directory CString strFile = g_strAppPath; AddSlash(strFile); strFile += "colormap.pcx"; Load256Image (strFile.GetBuffer(0), NULL, &pal, NULL, NULL); if (!pal) Error ("Couldn't load %s or %s", name, strFile); } Texture_InitPalette (pal); free (pal); } // create the fallback texture if (bHardInit) { Texture_MakeNotexture(); g_qeglobals.d_qtextures = NULL; } LoadShaders(); } #endif /* ================== Texture_Flush ================== */ void Texture_Flush (bool bReload) { if (!ConfirmModified()) return; Map_New (); CWaitCursor cursor; CStringList strList; Texture_Init(false); if (g_qeglobals.d_qtextures) { qtexture_t* pTex = g_qeglobals.d_qtextures->next; while (pTex != NULL && pTex != g_qeglobals.d_qtextures) { qtexture_t* pNextTex = pTex->next; if (bReload) { if (pTex->name[0] != '(') { strList.AddTail(pTex->name); } } free(pTex); pTex = pNextTex; } } GLuint* pGln = new GLuint[texture_extension_number-1]; qglGenTextures(texture_extension_number-1, pGln); QE_CheckOpenGLForErrors(); qglDeleteTextures(texture_extension_number-1, pGln); QE_CheckOpenGLForErrors(); delete []pGln; texture_extension_number = 1; g_qeglobals.d_qtextures = NULL; if (bReload) { POSITION pos = strList.GetHeadPosition(); while (pos) { CString strTex = strList.GetNext(pos); Texture_ForName (strTex.GetBuffer(0)); } } } ///////////////////////////////////////////////////////////////////////////// // CTexWnd IMPLEMENT_DYNCREATE(CTexWnd, CWnd); CTexWnd::CTexWnd() { m_bNeedRange = true; } CTexWnd::~CTexWnd() { } BEGIN_MESSAGE_MAP(CTexWnd, CWnd) //{{AFX_MSG_MAP(CTexWnd) ON_WM_CREATE() ON_WM_SIZE() ON_WM_PARENTNOTIFY() ON_WM_TIMER() ON_WM_KEYDOWN() ON_WM_KEYUP() ON_WM_PAINT() ON_WM_VSCROLL() ON_COMMAND(ID_TEXTURES_FLUSH, OnTexturesFlush) ON_BN_CLICKED(1200, OnShaderClick) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTexWnd message handlers /* ============ WTexWndProc ============ */ LONG WINAPI TexWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int xPos, yPos; RECT rect; GetClientRect(hWnd, &rect); switch (uMsg) { case WM_CREATE: s_hdcTexture = GetDC(hWnd); QEW_SetupPixelFormat(s_hdcTexture, false); if ( ( s_hglrcTexture = qwglCreateContext( s_hdcTexture ) ) == 0 ) Error( "wglCreateContext in WTex_WndProc failed" ); if (!qwglShareLists( g_qeglobals.d_hglrcBase, s_hglrcTexture ) ) Error( "wglShareLists in WTex_WndProc failed" ); if (!qwglMakeCurrent( s_hdcTexture, s_hglrcTexture )) Error ("wglMakeCurrent in WTex_WndProc failed"); g_qeglobals.d_hwndTexture = hWnd; return 0; case WM_DESTROY: //wglMakeCurrent( NULL, NULL ); //wglDeleteContext( s_hglrcTexture ); ReleaseDC( hWnd, s_hdcTexture ); return 0; #if 0 case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hWnd, &ps); if ( !qwglMakeCurrent( s_hdcTexture, s_hglrcTexture ) ) //if ( !wglMakeCurrent( ps.hdc, s_hglrcTexture ) ) { Sys_Printf("ERROR: wglMakeCurrent failed..\n "); Sys_Printf("Please restart QERadiant if the Texture view is not working\n"); } else { Texture_Draw2 (rect.right-rect.left, rect.bottom-rect.top - g_nTextureOffset); qwglSwapBuffers(s_hdcTexture); // TRACE("Texture Paint\n"); } EndPaint(hWnd, &ps); } return 0; #endif case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: case WM_LBUTTONDOWN: SetCapture( g_qeglobals.d_hwndTexture ); xPos = (short)LOWORD(lParam); // horizontal position of cursor yPos = (short)HIWORD(lParam); // vertical position of cursor Texture_MouseDown (xPos, yPos - g_nTextureOffset, wParam); return 0; case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_LBUTTONUP: xPos = (short)LOWORD(lParam); // horizontal position of cursor yPos = (short)HIWORD(lParam); // vertical position of cursor Texture_MouseUp (xPos, yPos - g_nTextureOffset, wParam); if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) ReleaseCapture (); return 0; case WM_MOUSEMOVE: xPos = (short)LOWORD(lParam); // horizontal position of cursor yPos = (short)HIWORD(lParam); // vertical position of cursor Texture_MouseMoved (xPos, yPos - g_nTextureOffset, wParam); return 0; } return DefWindowProc (hWnd, uMsg, wParam, lParam); } BOOL CTexWnd::PreCreateWindow(CREATESTRUCT& cs) { WNDCLASS wc; HINSTANCE hInstance = AfxGetInstanceHandle(); if (::GetClassInfo(hInstance, TEXTURE_WINDOW_CLASS, &wc) == FALSE) { // Register a new class memset (&wc, 0, sizeof(wc)); wc.style = CS_NOCLOSE | CS_OWNDC; wc.lpszClassName = TEXTURE_WINDOW_CLASS; wc.hCursor = LoadCursor (NULL,IDC_ARROW); wc.lpfnWndProc = TexWndProc; if (AfxRegisterClass(&wc) == FALSE) Error ("CZWnd RegisterClass: failed"); } cs.lpszClass = TEXTURE_WINDOW_CLASS; cs.lpszName = "TEX"; if (cs.style != QE3_CHILDSTYLE && cs.style != QE3_STYLE) cs.style = QE3_SPLITTER_STYLE; return CWnd::PreCreateWindow(cs); } int CTexWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; CRect rctEdit(8, 5, 20, 20); g_nTextureOffset = 0; if (g_PrefsDlg.m_bShaderTest) { m_wndShaders.Create("Show Shaders", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, rctEdit, this, 1200); m_wndShaders.ModifyStyleEx(0, WS_EX_CLIENTEDGE, 0); m_wndShaders.SetCheck(g_PrefsDlg.m_bShowShaders); g_nTextureOffset = 25; } rctEdit.SetRect(8, g_nTextureOffset, 20, 20); m_wndFilter.Create(WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT, rctEdit, this, 1201); m_wndFilter.ModifyStyleEx(0, WS_EX_CLIENTEDGE, 0); m_wndFilter.SetTexWnd(this); g_nTextureOffset += 25; if (!g_PrefsDlg.m_bTextureWindow) { m_wndFilter.ShowWindow(SW_HIDE); g_nTextureOffset -= 25; } ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar); m_bNeedRange = true; return 0; } void CTexWnd::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); CRect rctClient; GetClientRect(rctClient); if (g_PrefsDlg.m_bShaderTest) { m_wndShaders.SetWindowPos(NULL, rctClient.left + 8, rctClient.top + 5, rctClient.right - 16, 20, 0); } m_wndFilter.SetWindowPos(NULL, rctClient.left + 8, rctClient.top + 25, rctClient.right - 16, 20, 0); m_bNeedRange = true; } void CTexWnd::OnShaderClick() { g_PrefsDlg.m_bShowShaders = (m_wndShaders.GetCheck() != 0); g_PrefsDlg.SavePrefs(); RedrawWindow(); } void CTexWnd::OnParentNotify(UINT message, LPARAM lParam) { CWnd::OnParentNotify(message, lParam); } int g_nLastLen = 0; int g_nTimerHandle = -1; char g_cLastChar; void CTexWnd::UpdateFilter(const char* pFilter) { if (g_nTimerHandle > 0) KillTimer(1); g_bFilterEnabled = false; if (pFilter) { g_strFilter = pFilter; if (g_strFilter.GetLength() > 0) { g_bFilterEnabled = true; if (g_pParentWnd->CurrentStyle() == QR_QE4 || g_pParentWnd->CurrentStyle() == QR_4WAY) { if (g_strFilter.GetLength() > g_nLastLen) { g_cLastChar = toupper(g_strFilter.GetAt(g_strFilter.GetLength()-1)); if (g_cLastChar == 'N' || g_cLastChar == 'O') // one of the other popups { g_nTimerHandle = SetTimer(1, 800, NULL); // half second timer } } } } g_nLastLen = g_strFilter.GetLength(); SortTextures(); } Sys_UpdateWindows (W_TEXTURE); } void CTexWnd::UpdatePrefs() { if (!g_PrefsDlg.m_bTextureWindow) { m_wndFilter.ShowWindow(SW_HIDE); g_nTextureOffset = 0; } else { m_wndFilter.ShowWindow(SW_SHOW); g_nTextureOffset = 25; } ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar); m_bNeedRange = true; Invalidate(); UpdateWindow(); } void CTexWnd::FocusEdit() { if (m_wndFilter.IsWindowVisible()) m_wndFilter.SetFocus(); } void CTexWnd::OnTimer(UINT nIDEvent) { KillTimer(1); g_nLastLen = 0; g_nTimerHandle = -1; ::SetFocus(g_qeglobals.d_hwndEntity); ::PostMessage(g_qeglobals.d_hwndEntity, WM_CHAR, g_cLastChar, 0); } void CTexWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); //CWnd::OnKeyDown(nChar, nRepCnt, nFlags); } void CTexWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); } void CTexWnd::OnPaint() { CPaintDC dc(this); // device context for painting CRect rctClient; GetClientRect(rctClient); int nOld = g_qeglobals.d_texturewin.m_nTotalHeight; if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) //if ( !qwglMakeCurrent(dc.m_hDC, s_hglrcTexture ) ) { Sys_Printf("ERROR: wglMakeCurrent failed..\n "); Sys_Printf("Please restart QERadiant if the Texture view is not working\n"); } else { Texture_Draw2 (rctClient.right-rctClient.left, rctClient.bottom-rctClient.top - g_nTextureOffset); qwglSwapBuffers(s_hdcTexture); // TRACE("Texture Paint\n"); } if (g_PrefsDlg.m_bTextureScrollbar && (m_bNeedRange || g_qeglobals.d_texturewin.m_nTotalHeight != nOld)) { m_bNeedRange = false; SetScrollRange(SB_VERT, 0, g_qeglobals.d_texturewin.m_nTotalHeight, TRUE); } } void CTexWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { CWnd::OnVScroll(nSBCode, nPos, pScrollBar); int n = GetScrollPos(SB_VERT);; switch (nSBCode) { case SB_LINEUP : { n = (n - 15 > 0) ? n - 15 : 0; break; } case SB_LINEDOWN : { n = (n + 15 < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + 15 : n; break; } case SB_PAGEUP : { n = (n - g_qeglobals.d_texturewin.height > 0) ? n - g_qeglobals.d_texturewin.height : 0; break; } case SB_PAGEDOWN : { n = (n + g_qeglobals.d_texturewin.height < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + g_qeglobals.d_texturewin.height : n; break; } case SB_THUMBPOSITION : { n = nPos; break; } case SB_THUMBTRACK : { n = nPos; break; } } SetScrollPos(SB_VERT, n); g_qeglobals.d_texturewin.originy = -((int)n); Invalidate(); UpdateWindow(); //Sys_UpdateWindows(W_TEXTURE); } /* and are the caps new caps? anything done with older stuff will be fubar'd.. which brings up the point if you ever naturalize a cap, you cannot force it back to cap texturing.. i will add that too */ void CTexWnd::OnTexturesFlush() { // TODO: Add your command handler code here } void LoadShaders() { char dirstring[1024]; char *path; struct _finddata_t fileinfo; int handle; path = ValueForKey (g_qeglobals.d_project_entity, "basepath"); sprintf (dirstring, "%s/shaders/*.shader", path); /* sprintf (dirstring, "%s/shaders/shaderlist.txt", path); char *pBuff = NULL; int nLen = LoadFile(dirstring, reinterpret_cast(&pBuff)); if (nLen == -1) { nLen = PakLoadAnyFile(dirstring, reinterpret_cast(&pBuff)); } if (nLen > 0) { CStringList lst; StartTokenParsing(pBuff); nLen = 0; while (GetToken(true)) { // each token should be a shader filename sprintf(dirstring, "%s/shaders/%s.shader", path, token); lst.AddTail(dirstring); nLen++; } POSITION pos = lst.GetHeadPosition(); while (pos != NULL) { LoadShader(lst.GetAt(pos).GetBuffer(0), NULL); lst.GetNext(pos); } free(pBuff); } else { Sys_Printf("Unable to load shaderlist.txt, shaders not loaded!"); } */ handle = _findfirst (dirstring, &fileinfo); if (handle != -1) { do { if ((fileinfo.attrib & _A_SUBDIR)) continue; sprintf(dirstring, "%s/shaders/%s", path, fileinfo.name); LoadShader(dirstring, NULL); } while (_findnext( handle, &fileinfo ) != -1); _findclose (handle); } } void FreeShaders() { int nSize = g_lstShaders.GetSize(); for (int i = 0; i < nSize; i++) { CShaderInfo *pInfo = reinterpret_cast(g_lstShaders.ElementAt(i)); delete pInfo; } nSize = g_lstDeferred.GetSize(); for (i = 0; i < nSize; i++) { DeferredShaderLoad *p = reinterpret_cast(g_lstDeferred.ElementAt(i)); delete p; } g_lstShaders.RemoveAll(); g_lstDeferred.RemoveAll(); } void ReloadShaders() { FreeShaders(); LoadShaders(); qtexture_t* pTex = g_qeglobals.d_qtextures; while (pTex != NULL) { SetNameShaderInfo(pTex, NULL, pTex->name); pTex = pTex->next; } } int Texture_LoadSkin(char *pName, int *pnWidth, int *pnHeight, const char *psBasePath) { #if 1 qtexture_t *pTex = Texture_ForName(Filename_WithoutExt(pName), false, psBasePath); *pnWidth = pTex->width; *pnHeight= pTex->height; return pTex->texture_number; #else byte *pic = NULL; byte *pic32 = NULL; byte *pal; int nTex = -1; if (strstr(pName, ".pcx") != NULL) { LoadPCX(pName, &pic, &pal, pnWidth, pnHeight); int c = (*pnWidth) * (*pnHeight); pic32 = reinterpret_cast(qmalloc(4 * c )); byte* out = pic32; for (int i = 0 ; i < c ; i++) { int p = pic[i]; out[0] = pal[p*3]; out[1] = pal[p*3 + 1]; out[2] = pal[p*3 + 2]; out[3] = 255; out += 4; } free(pic); free(pal); } else if (strstr(pName, ".tga") != NULL) { unsigned char* pPixels = NULL; LoadTGA(pName, &pPixels, pnWidth, pnHeight); if (pPixels) { pic32 = reinterpret_cast(pPixels); } } if (pic32 != NULL) { nTex = texture_extension_number++; if (g_PrefsDlg.m_bSGIOpenGL) { //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) Error ("wglMakeCurrent in LoadTexture failed"); } qglBindTexture( GL_TEXTURE_2D, nTex); SetTexParameters (); int nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality; while (nCount-- > 0) { if (*pnWidth > 16 && *pnHeight > 16) { R_MipMap(pic32, *pnWidth, *pnHeight); } else { break; } } if (g_PrefsDlg.m_bSGIOpenGL) { if (nomips) { qglTexImage2D(GL_TEXTURE_2D, 0, 3, *pnWidth, *pnHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pic32); } else qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, *pnWidth, *pnHeight,GL_RGBA, GL_UNSIGNED_BYTE, pic32); } else { if (nomips) qglTexImage2D(GL_TEXTURE_2D, 0, 3, *pnWidth, *pnHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pic32); else qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, *pnWidth, *pnHeight,GL_RGBA, GL_UNSIGNED_BYTE, pic32); } free (pic32); qglBindTexture( GL_TEXTURE_2D, 0 ); } return nTex; #endif }