aboutsummaryrefslogtreecommitdiffstats
path: root/q3radiant/TexWnd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'q3radiant/TexWnd.cpp')
-rwxr-xr-xq3radiant/TexWnd.cpp3186
1 files changed, 3186 insertions, 0 deletions
diff --git a/q3radiant/TexWnd.cpp b/q3radiant/TexWnd.cpp
new file mode 100755
index 0000000..471ba0e
--- /dev/null
+++ b/q3radiant/TexWnd.cpp
@@ -0,0 +1,3186 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+
+This file is part of Quake III Arena source code.
+
+Quake III Arena source code 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.
+
+Quake III Arena source code 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 Foobar; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+// TexWnd.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include <assert.h>
+#include "Radiant.h"
+#include "TexWnd.h"
+#include "qe3.h"
+#include "io.h"
+#include "PrefsDlg.h"
+#include "shaderinfo.h"
+#include "pakstuff.h"
+#include "str.h"
+#include "PrefsDlg.h"
+
+Str m_gStr;
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+qtexture_t *Texture_ForNamePath(char* name, char* pFullPath);
+#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;
+
+// this is the global counter for GL bind numbers
+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 = false);
+void SelectTexture (int mx, int my, bool bShift, bool bFitScale=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_lstSkinCache;
+
+struct SkinInfo
+{
+ CString m_strName;
+ int m_nTextureBind;
+ SkinInfo(const char *pName, int n)
+ {
+ m_strName = pName;
+ m_nTextureBind = n;
+ };
+ SkinInfo(){};
+};
+
+// checks wether a qtexture_t exists for a given name
+//++timo FIXME: is this really any use? redundant.
+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;
+
+}
+
+CShaderInfo* hasShader(const char *pName)
+{
+ int nSize = g_lstShaders.GetSize();
+ for (int i = 0; i < nSize; i++)
+ {
+ CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i));
+ if (pInfo != NULL)
+ {
+ if (pInfo->m_strName.CompareNoCase(pName) == 0)
+ {
+ return pInfo;
+ }
+ }
+ }
+ return NULL;
+}
+
+// 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";
+}
+
+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 ( (float)( (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 ; i<texture_extension_number ; i++)
+ {
+ qglBindTexture( GL_TEXTURE_2D, i );
+ SetTexParameters ();
+ }
+
+ // select the default texture
+ qglBindTexture( GL_TEXTURE_2D, 0 );
+
+ qglFinish();
+
+ if (g_pParentWnd->GetCamera()->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<height ; i++, in+=row)
+ {
+ for (j=0 ; j<width ; j++, out+=4, in+=8)
+ {
+ out[0] = (in[0] + in[4] + in[row+0] + in[row+4])>>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
+=================
+*/
+//++timo NOTE: miptex_t is used only for .WAL format .. a bit outdated
+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);
+
+ 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 ; i<count ; i++)
+ {
+ dest[i] = tex_palette[source[i]];
+
+ total[0] += ((byte *)(dest+i))[0];
+ total[1] += ((byte *)(dest+i))[1];
+ total[2] += ((byte *)(dest+i))[2];
+ }
+
+ q->color[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_qeglobals.bSurfacePropertiesPlugin)
+ {
+ // Timo
+ // Surface properties plugins can store their own data in an IPluginQTexture
+ q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
+ GETPLUGINTEXDEF(q)->InitForMiptex( qtex );
+ }
+
+ //++timo is the m_bSGIOpenGL parameter still taken into account?
+ 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
+=================
+*/
+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;
+
+ //++timo FIXME: move gamma table initialization somewhere else!
+ if (fGamma == 1.0)
+ {
+ for (i=0 ; i<256 ; i++)
+ gammatable[i] = i;
+ }
+ else
+ {
+ for (i=0 ; i<256 ; i++)
+ {
+ inf = 255 * pow ( (float)( (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_qeglobals.bSurfacePropertiesPlugin)
+ {
+ // Timo
+ // Surface properties plugins can store their own data in an IPluginQTexture
+ q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
+ GETPLUGINTEXDEF(q)->SetDefaultTexdef();
+ }
+
+ 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, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
+ }
+ else
+ qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
+ }
+ else
+ {
+ if (nomips)
+ qglTexImage2D(GL_TEXTURE_2D, 0, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
+ else
+ qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, 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)
+{
+ g_pluginTexture = notexture;
+ _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));
+
+ if (g_qeglobals.bSurfacePropertiesPlugin)
+ {
+ // Timo
+ // Surface properties plugins can store their own data in an IPluginQTexture
+ q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
+ GETPLUGINTEXDEF(q)->SetDefaultTexdef();
+ }
+
+ 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_MakeDefault
+=================
+*/
+qtexture_t* Texture_MakeDefault (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 NULL;
+ }
+
+ 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 );
+ return q;
+}
+
+
+/*
+=================
+Texture_MakeNotexture
+=================
+*/
+void Texture_MakeNotexture (void)
+{
+ notexture = Texture_MakeDefault();
+ // Timo
+ // Surface properties plugins can store their own data in an IPluginQTexture
+ if (g_qeglobals.bSurfacePropertiesPlugin)
+ {
+ notexture->pData = g_SurfaceTable.m_pfnQTextureAlloc( notexture );
+ GETPLUGINTEXDEF(notexture)->SetDefaultTexdef();
+ }
+}
+
+
+void DemandLoadShaderTexture(qtexture_t *q, CShaderInfo *pShader)
+{
+ char cWork[1024];
+ char cWork2[1024];
+ strcpy(cWork, (pShader->m_strTextureName.GetLength() > 0) ? pShader->m_strTextureName : pShader->m_strName);
+ StripExtension(cWork);
+ // TTimo: if the shader has a m_fTransValue != 1.0f, ignore the alpha channel when loading the texture
+ // in some cases (common/weapclip) the 32bit .tga has an empty alpha channel,
+ // causing a display bug in the camera view (brush does not seemed drawn since alpha==0 for the texture)
+ // NOTE: the workaround is not perfect, the same texture may have been loaded earlier with it's alpha channel
+ q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, false);
+
+ if (q == NULL || q == notexture) {
+ sprintf(cWork2, "%s/%s",ValueForKey(g_qeglobals.d_project_entity, "basepath"), cWork);
+ q = Texture_ForNamePath( cWork, cWork2);
+
+ if (q == NULL || q == notexture) {
+ q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, true);
+ }
+ }
+
+ if (q != NULL && q != notexture)
+ {
+ pShader->m_pQTexture = q;
+ 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 );
+ }
+ else
+ {
+ Sys_Printf("Could not load shader editor image %s\n", cWork);
+ }
+}
+
+
+void LoadShader(char* pFilename, qtexture_t *q)
+{
+ char* pBuff = NULL;
+ CString strTexture;
+ int nSize = LoadFile(pFilename, reinterpret_cast<void**>(&pBuff));
+ if (nSize == -1)
+ {
+ nSize = PakLoadAnyFile(pFilename, reinterpret_cast<void**>(&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)
+ {
+ 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);
+
+ int n = g_PrefsDlg.m_nShader;
+ if (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_ALL || (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_COMMON && strstr(pShader->m_strName, "common" )))
+ {
+// new
+ if (pShader->m_strTextureName.GetLength() > 0)
+ {
+ if (!ShaderQTextureExists(pShader->m_strName))
+ {
+ DemandLoadShaderTexture(q, pShader);
+ }
+ }
+ }
+// 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);
+CShaderInfo* 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);
+ return pInfo;
+}
+
+void ReplaceQTexture(qtexture_t *pOld, qtexture_t *pNew, brush_t *pList)
+{
+ for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next)
+ {
+ if (pBrush->patchBrush)
+ {
+ Patch_ReplaceQTexture(pBrush, pOld, pNew);
+ }
+ if (pBrush->terrainBrush)
+ {
+ Terrain_ReplaceQTexture(pBrush->pTerrain, 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<const unsigned int*>(&q->texture_number));
+
+ if (g_qeglobals.bSurfacePropertiesPlugin)
+ {
+ // Timo
+ // Surface properties plugin
+#ifdef _DEBUG
+ if ( !q->pData )
+ Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
+#endif
+ if ( q->pData )
+ GETPLUGINTEXDEF(q)->DecRef();
+ }
+
+ free(q);
+
+}
+
+/*
+=================
+Texture_MakeNoShadertexture
+
+Make a default black/red check pattern texture
+=================
+*/
+qtexture_t * Texture_MakeNoshadertexture( const char *name )
+{
+ qtexture_t *q;
+ byte data[4][4];
+
+ notexture = q = (qtexture_t*)qmalloc(sizeof(*q));
+ q->width = q->height = 64;
+ q->fTrans = 1;
+
+ q = (qtexture_t*)qmalloc(sizeof(*q));
+ strcpy (q->name, name);
+
+ q->width = q->height = 64;
+ q->fTrans = 1;
+
+ memset (data, 0, sizeof(data));
+ data[0][0] = data[3][0] = 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 );
+
+ return q;
+}
+
+
+
+/*
+===============
+Texture_ForName
+===============
+*/
+//bReload is set to true when called from DemandLoadShaderTexture because it should never re-use
+//an already loaded texture
+qtexture_t *Texture_ForName (const char *name, bool bReplace, bool bShader, bool bNoAlpha, bool bReload, bool makeShader)
+{
+ byte *lump;
+ qtexture_t *q = NULL;
+ char filename[1024];
+
+ if (name == NULL || strlen(name) == 0)
+ return notexture;
+
+ qtexture_t *pRemove = NULL;
+
+ if (!bReload)
+ {
+ for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
+ {
+ if (!strcmp(name, q->name))
+ {
+ if (bReplace)
+ {
+ pRemove = q;
+ //Texture_Remove(q);
+ break;
+ }
+ else
+ {
+#ifdef _DEBUG
+ // if the texture is already in memory, then the bNoAlpha flag doesn't have any influence
+ if (bNoAlpha)
+ Sys_Printf("WARNING: bNoAlpha flag on an already loaded texture\n");
+#endif
+ if (!g_dontuse)
+ {
+ q->inuse = true;
+ }
+ return q;
+ }
+ }
+ }
+ }
+
+ // did not find it in the standard list
+ // skip entity names (
+ if (!bShader && name[0] != '(')
+ {
+ CShaderInfo* pShader = hasShader(name);
+ if (pShader)
+ {
+ if (pShader->m_pQTexture == NULL)
+ {
+ DemandLoadShaderTexture(q, pShader);
+ }
+ q = pShader->m_pQTexture;
+ //Sys_Printf ("used Shader %s.\n", pShader->m_strName);
+ }
+ if ( q != NULL)
+ {
+ return q;
+ }
+ }
+
+
+ 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", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name, strTex);
+ if (!g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle)
+ {
+ g_pParentWnd->GetPlugInMgr().LoadTexture(filename);
+ if (g_pluginTexture)
+ q = g_pluginTexture;
+ }
+ else
+ {
+ return notexture;
+ // wadstyle.. if we get here then we do not have it
+ }
+ }
+ else
+ // we need to try several formats here, or would it be better if we are given a complete name
+ if (g_PrefsDlg.m_bHiColorTextures == TRUE)
+ {
+ char cWork[1024];
+ sprintf (filename, "%s/%s.tga", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name);
+ QE_ConvertDOSToUnixName( cWork, filename );
+ strcpy(filename, cWork);
+ Sys_Printf ("Loading %s...", name);
+ unsigned char* pPixels = NULL;
+ int nWidth;
+ int nHeight;
+ LoadImage(filename, &pPixels, &nWidth, &nHeight);
+ if (pPixels == NULL)
+ {
+ // try jpg
+ // blatant assumption of .tga should be fine since we sprintf'd it above
+ int nLen = strlen(filename);
+ filename[nLen-3] = 'j';
+ filename[nLen-2] = 'p';
+ filename[nLen-1] = 'g';
+ LoadImage(filename, &pPixels, &nWidth, &nHeight);
+ }
+ if (pPixels)
+ {
+ // if we were asked to ignore alpha channel, do it now (.TGA is the only supported file type with alpha channel)
+ //if (bNoAlpha)
+ if (TRUE)
+ {
+ unsigned char* iPix = pPixels;
+ int nCount = nWidth * nHeight;
+ for(iPix=pPixels+3; iPix-pPixels < nCount*4; iPix+=4)
+ *iPix = 255;
+ }
+ // we'll be binding the GL texture now
+ // need to check we are using a right GL context
+ // with GL plugins that have their own window, the GL context may be the plugin's, in which case loading textures will bug
+ HDC currentHDC = qwglGetCurrentDC();
+ HGLRC currentHGLRC = qwglGetCurrentContext();
+ //++timo FIXME: this may duplicate with qtexture_t* WINAPI QERApp_Texture_ForName (const char *name)
+ //++timo FIXME: we need a list of lawfull GL contexts or something?
+ // I'd rather always use the same GL context for binding...
+ if (currentHDC != g_qeglobals.d_hdcBase || currentHGLRC != g_qeglobals.d_hglrcBase)
+ qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase );
+ q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0);
+ //++timo I don't set back the GL context .. I don't know how safe it is
+ //qwglMakeCurrent( currentHDC, currentHGLRC );
+ //++timo storing the filename .. will be removed by shader code cleanup
+ // this is dirty, and we sure miss some places were we should fill the filename info
+ strcpy( q->filename, name );
+ SetNameShaderInfo(q, filename, name);
+ Sys_Printf ("done.\n", name);
+ free(pPixels);
+ }
+ }
+ else
+ {
+ // load the file
+ sprintf (filename, "%s/%s.wal", 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 (g_PrefsDlg.m_bSGIOpenGL)
+ {
+ if(!q)
+ return notexture;
+ }
+
+ }// name[0] != '('
+
+ if(!q) // safety
+ {
+ if (bShader && !makeShader) {
+ return q;
+ }
+
+ if (bShader)
+ {
+ q = Texture_MakeNoshadertexture( name );
+ Sys_Printf("failed, using default shader\n");
+ }
+ else
+ {
+ q = Texture_MakeDefault();
+ Sys_Printf("failed, using default\n");
+ }
+ }
+
+ strncpy (q->name, name, sizeof(q->name)-1);
+ if (name[0] != '(')
+ {
+ StripExtension (q->name);
+ }
+
+ if (!g_dontuse)
+ q->inuse = true;
+ q->next = g_qeglobals.d_qtextures;
+ g_qeglobals.d_qtextures = q;
+
+ if (pRemove != NULL)
+ {
+ ReplaceQTexture(pRemove, q, &active_brushes);
+ ReplaceQTexture(pRemove, q, &filtered_brushes);
+ Texture_Remove(pRemove);
+ }
+
+ return q;
+}
+
+/*
+===============
+Texture_ForNamePath
+===============
+*/
+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)
+ {
+ char cWork[1024];
+ if (strstr(pFullPath, ".tga") == NULL) {
+ sprintf(filename, "%s%s", pFullPath, ".tga");
+ } else {
+ strcpy(filename, pFullPath);
+ }
+ QE_ConvertDOSToUnixName( cWork, filename );
+ strcpy(filename, cWork);
+ Sys_Printf ("Loading %s...", name);
+ unsigned char* pPixels = NULL;
+ int nWidth;
+ int nHeight;
+ LoadImage(filename, &pPixels, &nWidth, &nHeight);
+ if (!pPixels)
+ {
+ // try jpg
+ // blatant assumption of .tga should be fine since we sprintf'd it above
+ int nLen = strlen(filename);
+ filename[nLen-3] = 'j';
+ filename[nLen-2] = 'p';
+ filename[nLen-1] = 'g';
+ LoadImage(filename, &pPixels, &nWidth, &nHeight);
+ }
+ if (pPixels)
+ {
+ q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0);
+ //++timo storing the filename .. will be removed by shader code cleanup
+ // this is dirty, and we sure miss some places were we should fill the filename info
+ // NOTE: we store relative path, need to extract it
+ strcpy( q->filename, name );
+
+ }
+ 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 ; i<texture_nummenus ; i++)
+ DeleteMenu (hmenu, CMD_TEXTUREWAD+i, MF_BYCOMMAND);
+
+ texture_nummenus = 0;
+
+ // add everything
+ if (g_qeglobals.d_project_entity)
+ {
+ //--if (g_PrefsDlg.m_bUseShaders)
+ //--{
+ //-- path = ValueForKey (g_qeglobals.d_project_entity, "basepath");
+ //-- sprintf (dirstring, "%s/scripts/*.shader", path);
+ //--
+ //--}
+ //--else
+ //--{
+ path = ValueForKey (g_qeglobals.d_project_entity, "texturepath");
+ sprintf (dirstring, "%s/*.*", path);
+ //--}
+
+ handle = _findfirst (dirstring, &fileinfo);
+ if (handle != -1)
+ {
+ do
+ {
+ //--if (g_PrefsDlg.m_bUseShaders)
+ //--{
+ //-- if ((fileinfo.attrib & _A_SUBDIR))
+ //-- continue;
+ //--}
+ //--else
+ //--{
+ if (!(fileinfo.attrib & _A_SUBDIR))
+ continue;
+ if (fileinfo.name[0] == '.')
+ continue;
+ //--}
+ // add this directory to the menu
+ AddToDirListAlphabetized(&list, fileinfo.name, FROMDISK);
+ } while (_findnext( handle, &fileinfo ) != -1);
+
+ _findclose (handle);
+ }
+
+ //--if (!g_PrefsDlg.m_bUseShaders)
+ //--{
+ GetPackTextureDirs(&list);
+ //--}
+
+ for(temp = list; temp; temp = temp->next)
+ {
+ 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;
+ }
+}
+
+
+
+
+void LoadShadersFromDir(const char *pPath)
+{
+ int nSize = g_lstShaders.GetSize();
+ for (int i = 0; i < nSize; i++)
+ {
+ CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i));
+ if (pInfo != NULL)
+ {
+ if (strstr(pInfo->m_strName, pPath) && pInfo->m_pQTexture == NULL && strstr(pInfo->m_strName, "models/player") == NULL)
+ {
+ qtexture_t *q = NULL;
+ DemandLoadShaderTexture(q, pInfo);
+ }
+ }
+ }
+}
+
+
+/*
+==============
+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_ClearInuse();
+ 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
+ {
+ sprintf (dirstring, "%s*.%s", texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt));
+ GetPackFileList(&list, dirstring);
+ }
+ }
+
+ 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
+ {
+ Texture_ForName (name, true);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ LoadShadersFromDir(texture_directory);
+
+ 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);
+ }
+}
+
+
+// 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;
+ Texture_ClearInuse();
+ 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;
+
+ SortTextures();
+
+ 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);
+ }
+ }
+
+
+ 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_SetInuse
+
+==================
+*/
+void Texture_SetInuse (void)
+{
+ qtexture_t *q;
+
+ for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
+ {
+ q->inuse = true;
+ }
+}
+
+
+/*
+==============
+Texture_ShowAll
+==============
+*/
+void Texture_ShowAll()
+{
+ Texture_SetInuse();
+ Sys_Printf("Showing all textures...\n");
+ Sys_UpdateWindows (W_TEXTURE);
+}
+
+/*
+==============
+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)
+ {
+ if (b->patchBrush)
+ {
+ Texture_ForName(b->pPatch->d_texture->name);
+ }
+ else
+ {
+ 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)
+ {
+ if (b->patchBrush)
+ {
+ Texture_ForName(b->pPatch->d_texture->name);
+ }
+ else
+ {
+ 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 (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
+
+brushprimit_texdef must be understood as a qtexture_t with width=2 height=2 ( the default one )
+============
+*/
+void Texture_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, IPluginTexdef *pTexdef, bool bSetSelection )
+{
+ 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;
+ // store the texture coordinates for new brush primitive mode
+ // be sure that all the callers are using the default 2x2 texture
+ if (g_qeglobals.m_bBrushPrimitMode)
+ {
+ g_qeglobals.d_texturewin.brushprimit_texdef = *brushprimit_texdef;
+ }
+ // surface properties plugin
+ if (g_qeglobals.bSurfacePropertiesPlugin)
+ {
+ if (g_qeglobals.d_texturewin.pTexdef)
+ {
+ // decrement reference count
+ static_cast<IPluginTexdef *>(g_qeglobals.d_texturewin.pTexdef)->DecRef();
+ g_qeglobals.d_texturewin.pTexdef = NULL;
+ }
+ if (pTexdef)
+ {
+ g_qeglobals.d_texturewin.pTexdef = pTexdef->Copy();
+ }
+ }
+
+ Sys_UpdateWindows (W_TEXTURE);
+
+ g_dlgFind.updateTextures(texdef->name);
+
+ if (!g_dlgFind.isOpen() && bSetSelection)
+ {
+ Select_SetTexture(texdef,brushprimit_texdef,bFitScale);
+ }
+
+
+ //plugins: send a message telling that the selected texture may have changed
+ DispatchRadiantMsg( RADIANT_TEXTURE );
+
+ // 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;
+ }
+ }
+}
+
+
+HWND FindEditWindow()
+{
+ HWND hwnd = FindWindow("TEditPadForm", NULL);
+ HWND hwndEdit = NULL;
+ if (hwnd != NULL)
+ {
+ HWND hwndTab = FindWindowEx(hwnd, NULL, "TTabControl", NULL);
+ if (hwndTab != NULL)
+ {
+ hwndEdit = FindWindowEx(hwndTab, NULL, "TRicherEdit", NULL);
+ }
+ }
+ return hwndEdit;
+}
+
+void Delay(float fSeconds)
+{
+ DWORD dw = ::GetTickCount();
+ DWORD dwTil = dw + (fSeconds * 1000);
+ while (::GetTickCount() < dwTil)
+ {
+ MSG msg;
+ if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+}
+
+
+void ViewShader(const char *pFile, const char *pName)
+{
+ CString str;
+ char* pBuff = NULL;
+ int nSize = LoadFile(pFile, reinterpret_cast<void**>(&pBuff));
+ if (nSize == -1)
+ {
+ nSize = PakLoadAnyFile(pFile, reinterpret_cast<void**>(&pBuff));
+ }
+ if (nSize > 0)
+ {
+ str = pBuff;
+ }
+ int nStart = 0;
+ if (str.GetLength() > 0)
+ {
+ CString strFind = pName;
+ CString strLook = str;
+ strLook.MakeLower();
+ strFind.MakeLower();
+ int n = strLook.Find(strFind);
+ if (n >= 0)
+ {
+ nStart = n;
+ }
+ }
+
+ CString s= "editpad ";
+ s += pFile;
+ WinExec(s, SW_SHOWNORMAL);
+
+ Delay(1.5);
+
+ HWND hwndEdit = FindEditWindow();
+
+ if (hwndEdit != NULL)
+ {
+ PostMessage(hwndEdit, EM_SETSEL, nStart, nStart);
+ }
+ else
+ {
+ Sys_Printf("Unable to load shader editor.\n");
+ }
+
+
+}
+
+/*
+==============
+SelectTexture
+
+ By mouse click
+==============
+*/
+void SelectTexture (int mx, int my, bool bShift, bool bFitScale)
+{
+ int x, y;
+ qtexture_t *q;
+ texdef_t tex;
+ brushprimit_texdef_t brushprimit_tex;
+
+ my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.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;
+ if (mx > x && mx - x < nWidth
+ && my < y && y - my < nHeight + FONT_HEIGHT)
+ {
+ if (bShift)
+ {
+ if (g_PrefsDlg.m_bHiColorTextures && q->shadername[0] != 0)
+ {
+ //CString s = "notepad ";
+ //s += q->shadername;
+ //WinExec(s, SW_SHOWNORMAL);
+
+ ViewShader(q->shadername, q->name);
+
+ }
+ }
+ memset (&tex, 0, sizeof(tex));
+ memset (&brushprimit_tex, 0, sizeof(brushprimit_tex));
+ if (g_qeglobals.m_bBrushPrimitMode)
+ {
+ // brushprimit fitted to a 2x2 texture
+ brushprimit_tex.coords[0][0] = 1.0f;
+ brushprimit_tex.coords[1][1] = 1.0f;
+ }
+ else
+ {
+ tex.scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
+ tex.scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
+ }
+ tex.flags = q->flags;
+ tex.value = q->value;
+ tex.contents = q->contents;
+ //strcpy (tex.name, q->name);
+ tex.SetName(q->name);
+ Texture_SetTexture ( &tex, &brushprimit_tex, bFitScale, GETPLUGINTEXDEF(q));
+ 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))
+ {
+ SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y, buttons & MK_SHIFT, buttons & MK_CONTROL);
+ 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();
+}
+
+
+void Texture_Init (bool bHardInit)
+{
+ char name[1024];
+ byte *pal = NULL;
+
+ 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)
+ Sys_Printf ("Couldn't load %s or %s", name, strFile);
+ }
+ else
+ {
+ Texture_InitPalette (pal);
+ free (pal);
+ }
+ }
+
+ // create the fallback texture
+
+ if (bHardInit)
+ {
+ Texture_MakeNotexture();
+ g_qeglobals.d_qtextures = NULL;
+ }
+ LoadShaders();
+
+}
+
+void Texture_FlushUnused()
+{
+ CWaitCursor cursor;
+ Texture_ShowInuse();
+ if (g_qeglobals.d_qtextures)
+ {
+ qtexture_t* pTex = g_qeglobals.d_qtextures->next;
+ qtexture_t *pPrev = g_qeglobals.d_qtextures;
+ while (pTex != NULL && pTex != g_qeglobals.d_qtextures)
+ {
+ qtexture_t* pNextTex = pTex->next;
+ if (g_qeglobals.bSurfacePropertiesPlugin)
+ {
+ // Timo
+ // Surface properties plugin
+#ifdef _DEBUG
+ if ( !pTex->pData )
+ Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
+#endif
+ if ( pTex->pData && pTex->inuse )
+ GETPLUGINTEXDEF(pTex)->DecRef();
+ }
+
+ if (!pTex->inuse)
+ {
+ unsigned int nTexture = pTex->texture_number;
+ qglDeleteTextures(1, &nTexture);
+ pPrev->next = pNextTex;
+ free(pTex);
+ }
+ else
+ {
+ pPrev = pTex;
+ }
+ pTex = pNextTex;
+ }
+ }
+}
+
+void Texture_Cleanup(CStringList *pList)
+{
+ 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 (pList)
+ {
+ if (pTex->name[0] != '(')
+ {
+ pList->AddTail(pTex->name);
+ }
+ }
+
+ if (g_qeglobals.bSurfacePropertiesPlugin)
+ {
+ // Timo
+ // Surface properties plugin
+#ifdef _DEBUG
+ if ( !pTex->pData )
+ Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
+#endif
+ if ( pTex->pData )
+ GETPLUGINTEXDEF(pTex)->DecRef();
+ }
+ free(pTex);
+ pTex = pNextTex;
+ }
+ }
+
+ int nSize = g_lstSkinCache.GetSize();
+ for (int i = 0; i < nSize; i++)
+ {
+ SkinInfo *pInfo = reinterpret_cast<SkinInfo*>(g_lstSkinCache.GetAt(i));
+ delete pInfo;
+ }
+
+}
+
+/*
+==================
+Texture_Flush
+==================
+*/
+void Texture_Flush (bool bReload)
+{
+ if (!ConfirmModified())
+ return;
+
+ Map_New ();
+
+ CWaitCursor cursor;
+ CStringList strList;
+ Texture_Init(false);
+ Texture_Cleanup(&strList);
+
+ 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 Q3Radiant 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.GetSafeHwnd())
+ {
+ 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 Q3Radiant 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/scripts/shaderlist.txt", path);
+ char *pBuff = NULL;
+
+ int nLen = LoadFile(dirstring, reinterpret_cast<void**>(&pBuff));
+ if (nLen == -1)
+ {
+ nLen = PakLoadAnyFile(dirstring, reinterpret_cast<void**>(&pBuff));
+ }
+ if (nLen > 0)
+ {
+ CStringList lst;
+ StartTokenParsing(pBuff);
+ nLen = 0;
+ while (GetToken(true))
+ {
+ // each token should be a shader filename
+ sprintf(dirstring, "%s/scripts/%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/scripts/%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<CShaderInfo*>(g_lstShaders.ElementAt(i));
+ delete pInfo;
+ }
+
+ g_lstShaders.RemoveAll();
+}
+
+void ReloadShaders()
+{
+ FreeShaders();
+ LoadShaders();
+ qtexture_t* pTex = g_qeglobals.d_qtextures;
+ while (pTex != NULL)
+ {
+ SetNameShaderInfo(pTex, NULL, pTex->name);
+ pTex = pTex->next;
+ }
+
+}
+
+int WINAPI Texture_LoadSkin(char *pName, int *pnWidth, int *pnHeight)
+{
+ byte *pic = NULL;
+ byte *pic32 = NULL;
+ int nTex = -1;
+
+ strlwr(pName);
+ QE_ConvertDOSToUnixName(pName, pName);
+
+ int nSize = g_lstSkinCache.GetSize();
+ for (int i = 0; i < nSize; i++)
+ {
+ SkinInfo *pInfo = reinterpret_cast<SkinInfo*>(g_lstSkinCache.GetAt(i));
+ if (pInfo)
+ {
+ if (stricmp(pName, pInfo->m_strName) == 0)
+ {
+ return pInfo->m_nTextureBind;
+ }
+ }
+ }
+
+ LoadImage( pName, &pic32, pnWidth, pnHeight);
+ 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 );
+ }
+
+ SkinInfo *pInfo = new SkinInfo(pName, nTex);
+ g_lstSkinCache.Add(pInfo);
+
+ return nTex;
+}
+
+