home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / TexWnd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  76.8 KB  |  3,163 lines

  1. // TexWnd.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <assert.h>
  6. #include "Radiant.h"
  7. #include "TexWnd.h"
  8. #include "qe3.h"
  9. #include "io.h"
  10. #include "PrefsDlg.h"
  11. #include "shaderinfo.h"
  12. #include "pakstuff.h"
  13. #include "str.h"
  14. #include "PrefsDlg.h"
  15.  
  16. Str m_gStr;
  17.  
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23.  
  24. qtexture_t *Texture_ForNamePath(char* name, char* pFullPath);
  25. #define    TYP_MIPTEX    68
  26. static unsigned    tex_palette[256];
  27.  
  28. qtexture_t    *notexture = NULL;
  29. qtexture_t    *g_pluginTexture = NULL;
  30.  
  31. static qboolean    nomips = false;
  32.  
  33. #define    FONT_HEIGHT    10
  34.  
  35. HGLRC s_hglrcTexture = NULL;
  36. HDC     s_hdcTexture = NULL;
  37.  
  38. //int        texture_mode = GL_NEAREST;
  39. //int        texture_mode = GL_NEAREST_MIPMAP_NEAREST;
  40. //int        texture_mode = GL_NEAREST_MIPMAP_LINEAR;
  41. //int        texture_mode = GL_LINEAR;
  42. //int        texture_mode = GL_LINEAR_MIPMAP_NEAREST;
  43. int        texture_mode = GL_LINEAR_MIPMAP_LINEAR;
  44.  
  45. // this is the global counter for GL bind numbers
  46. int        texture_extension_number = 1;
  47. int g_nCurrentTextureMenuName;
  48.  
  49. int g_nTextureOffset = 0;
  50.  
  51. // current active texture directory.  if empty, show textures in use
  52. char        texture_directory[128];    // use if texture_showinuse is false
  53. qboolean    texture_showinuse;
  54.  
  55. bool g_bFilterEnabled = false;
  56. CString g_strFilter;
  57.  
  58. // texture layout functions
  59. qtexture_t    *current_texture = NULL;
  60. int            current_x, current_y, current_row;
  61.  
  62. int            texture_nummenus;
  63. #define        MAX_TEXTUREDIRS    128
  64. char        texture_menunames[MAX_TEXTUREDIRS][128];
  65.  
  66. qboolean    g_dontuse = true;        // set to true to load the texture but not flag as used
  67.  
  68. // void SelectTexture (int mx, int my, bool bShift = false);
  69. void SelectTexture (int mx, int my, bool bShift, bool bFitScale=false);
  70.  
  71. void    Texture_MouseDown (int x, int y, int buttons);
  72. void    Texture_MouseUp (int x, int y, int buttons);
  73. void    Texture_MouseMoved (int x, int y, int buttons);
  74.  
  75. CPtrArray g_lstShaders;
  76. CPtrArray g_lstSkinCache;
  77.  
  78. struct SkinInfo
  79. {
  80.   CString m_strName;
  81.   int m_nTextureBind;
  82.   SkinInfo(const char *pName, int n)
  83.   {
  84.     m_strName = pName;
  85.     m_nTextureBind = n;
  86.   };
  87.   SkinInfo(){};
  88. };
  89.  
  90. // checks wether a qtexture_t exists for a given name
  91. //++timo FIXME: is this really any use? redundant.
  92. bool ShaderQTextureExists(const char *pName)
  93. {
  94.   for (qtexture_t *q=g_qeglobals.d_qtextures ; q ; q=q->next)
  95.   {
  96.     if (!strcmp(q->name,  pName))
  97.     {
  98.       return true;
  99.     }
  100.   }
  101.   return false;
  102.  
  103. }
  104.  
  105. CShaderInfo* hasShader(const char *pName)
  106. {
  107.   int nSize = g_lstShaders.GetSize();
  108.   for (int i = 0; i < nSize; i++)
  109.   {
  110.     CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i));
  111.     if (pInfo != NULL)
  112.     {
  113.       if (pInfo->m_strName.CompareNoCase(pName) == 0)
  114.       {
  115.         return pInfo;
  116.       }
  117.     }
  118.   }
  119.   return NULL;
  120. }
  121.  
  122. // gets active texture extension
  123. // 
  124. // FIXME: fix this to be generic from project file
  125. //
  126. int GetTextureExtensionCount()
  127. {
  128.   return 2;
  129. }
  130.  
  131. const char* GetTextureExtension(int nIndex)
  132. {
  133.   if ( nIndex == 0)
  134.   {
  135.     _QERTextureInfo *pInfo = g_pParentWnd->GetPlugInMgr().GetTextureInfo();
  136.     const char *pTex = (pInfo != NULL) ? pInfo->m_TextureExtension : NULL;
  137.     return (pTex == NULL) ? (g_PrefsDlg.m_bHiColorTextures == FALSE) ? "wal" : "tga" : pTex;
  138.   }
  139.   // return jpg for 2nd extension
  140.   return "jpg";
  141. }
  142.  
  143. void SortTextures(void)
  144. {    
  145.     qtexture_t    *q, *qtemp, *qhead, *qcur, *qprev;
  146.  
  147.     // standard insertion sort
  148.     // Take the first texture from the list and
  149.     // add it to our new list
  150.     if ( g_qeglobals.d_qtextures == NULL)
  151.         return;    
  152.  
  153.     qhead = g_qeglobals.d_qtextures;
  154.     q = g_qeglobals.d_qtextures->next;
  155.     qhead->next = NULL;
  156.     
  157.     // while there are still things on the old
  158.     // list, keep adding them to the new list
  159.     while (q)
  160.     {
  161.         qtemp = q;
  162.         q = q->next;
  163.         
  164.         qprev = NULL;
  165.         qcur = qhead;
  166.  
  167.         while (qcur)
  168.         {
  169.             // Insert it here?
  170.             if (strcmp(qtemp->name, qcur->name) < 0)
  171.             {
  172.                 qtemp->next = qcur;
  173.                 if (qprev)
  174.                     qprev->next = qtemp;
  175.                 else
  176.                     qhead = qtemp;
  177.                 break;
  178.             }
  179.             
  180.             // Move on
  181.  
  182.             qprev = qcur;
  183.             qcur = qcur->next;
  184.  
  185.  
  186.             // is this one at the end?
  187.  
  188.             if (qcur == NULL)
  189.             {
  190.                 qprev->next = qtemp;
  191.                 qtemp->next = NULL;
  192.             }
  193.         }
  194.  
  195.  
  196.     }
  197.  
  198.     g_qeglobals.d_qtextures = qhead;
  199. }
  200.  
  201. /*
  202. ==============
  203. Texture_InitPalette
  204. ==============
  205. */
  206. void Texture_InitPalette (byte *pal)
  207. {
  208.     int        r,g,b,v;
  209.     int        i;
  210.     int        inf;
  211.     byte    gammatable[256];
  212.     float    gamma;
  213.  
  214.     gamma = g_qeglobals.d_savedinfo.fGamma;
  215.  
  216.     if (gamma == 1.0)
  217.     {
  218.         for (i=0 ; i<256 ; i++)
  219.             gammatable[i] = i;
  220.     }
  221.     else
  222.     {
  223.         for (i=0 ; i<256 ; i++)
  224.         {
  225.             inf = 255 * pow ( (i+0.5)/255.5 , gamma ) + 0.5;
  226.             if (inf < 0)
  227.                 inf = 0;
  228.             if (inf > 255)
  229.                 inf = 255;
  230.             gammatable[i] = inf;
  231.         }
  232.     }
  233.  
  234.     for (i=0 ; i<256 ; i++)
  235.     {
  236.           r = gammatable[pal[0]];
  237.           g = gammatable[pal[1]];
  238.           b = gammatable[pal[2]];
  239.           pal += 3;
  240.         
  241.           v = (r<<24) + (g<<16) + (b<<8) + 255;
  242.           v = BigLong (v);
  243.         
  244.           tex_palette[i] = v;
  245.     }
  246. }
  247.  
  248. void SetTexParameters (void)
  249. {
  250.     qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode );
  251.     
  252.     switch ( texture_mode )
  253.     {
  254.     case GL_NEAREST:
  255.     case GL_NEAREST_MIPMAP_NEAREST:
  256.     case GL_NEAREST_MIPMAP_LINEAR:
  257.         qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  258.         break;
  259.     case GL_LINEAR:
  260.     case GL_LINEAR_MIPMAP_NEAREST:
  261.     case GL_LINEAR_MIPMAP_LINEAR:
  262.         qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  263.         break;
  264.     }
  265. }
  266.  
  267. /*
  268. ============
  269. Texture_SetMode
  270. ============
  271. */
  272. void Texture_SetMode(int iMenu)
  273. {
  274.     int    i, iMode;
  275.     HMENU hMenu;
  276.     qboolean texturing = true;
  277.  
  278.     hMenu = GetMenu(g_qeglobals.d_hwndMain);
  279.  
  280.     switch(iMenu) {
  281.     case ID_VIEW_NEAREST:                    
  282.         iMode = GL_NEAREST;
  283.         break;
  284.     case ID_VIEW_NEARESTMIPMAP:
  285.         iMode = GL_NEAREST_MIPMAP_NEAREST;
  286.         break;
  287.     case ID_VIEW_LINEAR:
  288.         iMode = GL_NEAREST_MIPMAP_LINEAR;
  289.         break;
  290.     case ID_VIEW_BILINEAR:
  291.         iMode = GL_LINEAR;
  292.         break;
  293.     case ID_VIEW_BILINEARMIPMAP:
  294.         iMode = GL_LINEAR_MIPMAP_NEAREST;
  295.         break;
  296.     case ID_VIEW_TRILINEAR:
  297.         iMode = GL_LINEAR_MIPMAP_LINEAR;
  298.         break;
  299.  
  300.     case ID_TEXTURES_WIREFRAME:
  301.         iMode = 0;
  302.         texturing = false;
  303.         break;
  304.  
  305.     case ID_TEXTURES_FLATSHADE:
  306.         iMode = 0;
  307.         texturing = false;
  308.         break;
  309.  
  310.     }
  311.  
  312.     CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED);
  313.     CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
  314.     CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED);
  315.     CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
  316.     CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
  317.     CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
  318.     CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED);
  319.     CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED);
  320.  
  321.     CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED);
  322.  
  323.     g_qeglobals.d_savedinfo.iTexMenu = iMenu;
  324.     texture_mode = iMode;
  325.  
  326.   if (g_PrefsDlg.m_bSGIOpenGL)
  327.   {
  328.     if (s_hdcTexture && s_hglrcTexture)
  329.     {
  330.       //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
  331.       if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
  332.             Error ("wglMakeCurrent in LoadTexture failed");
  333.     }
  334.     else
  335.       return;
  336.   }
  337.  
  338.     if ( texturing )
  339.         SetTexParameters ();
  340.  
  341.     if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME)
  342.     {
  343.         g_pParentWnd->GetCamera()->Camera().draw_mode = cd_wire;
  344.         Map_BuildBrushData();
  345.         Sys_UpdateWindows (W_ALL);
  346.         return;
  347.  
  348.     } else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) {
  349.  
  350.         g_pParentWnd->GetCamera()->Camera().draw_mode = cd_solid;
  351.         Map_BuildBrushData();
  352.         Sys_UpdateWindows (W_ALL);
  353.         return;
  354.     }
  355.  
  356.     for (i=1 ; i<texture_extension_number ; i++)
  357.     {
  358.         qglBindTexture( GL_TEXTURE_2D, i );
  359.         SetTexParameters ();
  360.     }
  361.  
  362.     // select the default texture
  363.     qglBindTexture( GL_TEXTURE_2D, 0 );
  364.  
  365.     qglFinish();
  366.  
  367.     if (g_pParentWnd->GetCamera()->Camera().draw_mode != cd_texture)
  368.     {
  369.         g_pParentWnd->GetCamera()->Camera().draw_mode = cd_texture;
  370.         Map_BuildBrushData();
  371.     }
  372.  
  373.     Sys_UpdateWindows (W_ALL);
  374. }
  375.  
  376. /*
  377. ================
  378. R_MipMap
  379.  
  380. Operates in place, quartering the size of the texture
  381. ================
  382. */
  383. void R_MipMap (byte *in, int &width, int &height)
  384. {
  385.     int        i, j;
  386.     byte    *out;
  387.     int        row;
  388.     
  389.     row = width * 4;
  390.     width >>= 1;
  391.     height >>= 1;
  392.     out = in;
  393.     for (i=0 ; i<height ; i++, in+=row)
  394.     {
  395.         for (j=0 ; j<width ; j++, out+=4, in+=8)
  396.         {
  397.             out[0] = (in[0] + in[4] + in[row+0] + in[row+4])>>2;
  398.             out[1] = (in[1] + in[5] + in[row+1] + in[row+5])>>2;
  399.             out[2] = (in[2] + in[6] + in[row+2] + in[row+6])>>2;
  400.             out[3] = (in[3] + in[7] + in[row+3] + in[row+7])>>2;
  401.         }
  402.     }
  403. }
  404.  
  405. /*
  406. =================
  407. Texture_LoadTexture
  408. =================
  409. */
  410. //++timo NOTE: miptex_t is used only for .WAL format .. a bit outdated
  411. qtexture_t *Texture_LoadTexture (miptex_t *qtex)
  412. {
  413.   byte        *source;
  414.   unsigned    char *dest;
  415.   int            width, height, i, count;
  416.     int            total[3];
  417.   qtexture_t    *q;
  418.       
  419.   width = LittleLong(qtex->width);
  420.   height = LittleLong(qtex->height);
  421.  
  422.   q = (qtexture_t*)qmalloc(sizeof(*q));
  423.  
  424.   q->width = width;
  425.   q->height = height;
  426.  
  427.     q->flags = qtex->flags;
  428.     q->value = qtex->value;
  429.     q->contents = qtex->contents;
  430.  
  431.     dest = (unsigned char*)qmalloc (width*height*4);
  432.  
  433.   count = width*height;
  434.   source = (byte *)qtex + LittleLong(qtex->offsets[0]);
  435.  
  436.     // The dib is upside down so we want to copy it into 
  437.     // the buffer bottom up.
  438.  
  439.     total[0] = total[1] = total[2] = 0;
  440.   for (i=0 ; i<count ; i++)
  441.     {
  442.         dest[i] = tex_palette[source[i]];
  443.  
  444.         total[0] += ((byte *)(dest+i))[0];
  445.         total[1] += ((byte *)(dest+i))[1];
  446.         total[2] += ((byte *)(dest+i))[2];
  447.     }
  448.  
  449.     q->color[0] = (float)total[0]/(count*255);
  450.     q->color[1] = (float)total[1]/(count*255);
  451.     q->color[2] = (float)total[2]/(count*255);
  452.  
  453.   q->texture_number = texture_extension_number++;
  454.  
  455.   if (g_qeglobals.bSurfacePropertiesPlugin)
  456.   {
  457.       // Timo
  458.       // Surface properties plugins can store their own data in an IPluginQTexture
  459.       q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
  460.       GETPLUGINTEXDEF(q)->InitForMiptex( qtex );
  461.   }
  462.  
  463.   //++timo is the m_bSGIOpenGL parameter still taken into account?
  464.   if (g_PrefsDlg.m_bSGIOpenGL)
  465.   {
  466.     //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
  467.     if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
  468.           Error ("wglMakeCurrent in LoadTexture failed");
  469.   }
  470.  
  471.   qglBindTexture( GL_TEXTURE_2D, q->texture_number );
  472.  
  473.   //Handle3DfxTexturing(q, width, height, dest);
  474.  
  475.   SetTexParameters ();
  476.  
  477.   int nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality;
  478.   while (nCount-- > 0)
  479.   {
  480.     if (width > 16 && height > 16)
  481.     {
  482.       R_MipMap(dest, width, height);
  483.     }
  484.     else
  485.     {
  486.       break;
  487.     }
  488.   }
  489.  
  490.   if (g_PrefsDlg.m_bSGIOpenGL)
  491.   {
  492.       if (nomips)
  493.     {
  494.           qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
  495.     }
  496.       else
  497.           qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
  498.   }
  499.   else
  500.   {
  501.       if (nomips)
  502.           qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
  503.       else
  504.           qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
  505.   }
  506.  
  507.     free (dest);
  508.  
  509.     qglBindTexture( GL_TEXTURE_2D, 0 );
  510.  
  511.   return q;
  512. }
  513.  
  514.  
  515.  
  516.  
  517. /*
  518. =================
  519. Texture_LoadTexture
  520. =================
  521. */
  522. qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char* pPath, int nFlags, int nContents, int nValue )
  523. {
  524.   int i, j, inf;
  525.     byte    gammatable[256];
  526.     float fGamma = g_qeglobals.d_savedinfo.fGamma;
  527.  
  528.  
  529.   qtexture_t* q = (qtexture_t*)qmalloc(sizeof(*q));
  530.   q->width = nWidth;
  531.   q->height = nHeight;
  532.     q->flags = nFlags;
  533.     q->value = nValue;
  534.     q->contents = nContents;
  535.  
  536.   int nCount = nWidth * nHeight;
  537.   float total[3];
  538.   total[0] = total[1] = total[2] = 0.0f;
  539.  
  540.   //++timo FIXME: move gamma table initialization somewhere else!
  541.     if (fGamma == 1.0)
  542.     {
  543.         for (i=0 ; i<256 ; i++)
  544.             gammatable[i] = i;
  545.     }
  546.     else
  547.     {
  548.         for (i=0 ; i<256 ; i++)
  549.         {
  550.             inf = 255 * pow ( (i+0.5)/255.5 , fGamma ) + 0.5;
  551.             if (inf < 0)
  552.                 inf = 0;
  553.             if (inf > 255)
  554.                 inf = 255;
  555.             gammatable[i] = inf;
  556.         }
  557.     }
  558.  
  559.  
  560.   // all targas are stored internally as 32bit so rgba = 4 bytes
  561.   for (i = 0 ; i < (nCount * 4) ; i += 4)
  562.     {
  563.     for (j = 0; j < 3; j++)
  564.     {
  565.         total[j] += (pPixels+i)[j];
  566.       byte b = (pPixels+i)[j];
  567.       (pPixels+i)[j] = gammatable[b];
  568.               
  569.     }
  570.     }
  571.  
  572.     q->color[0] = total[0] / (nCount * 255);
  573.     q->color[1] = total[1] / (nCount * 255);
  574.     q->color[2] = total[2] / (nCount * 255);
  575.  
  576.  
  577.   q->texture_number = texture_extension_number++;
  578.  
  579.   if (g_qeglobals.bSurfacePropertiesPlugin)
  580.   {
  581.       // Timo
  582.       // Surface properties plugins can store their own data in an IPluginQTexture
  583.       q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
  584.       GETPLUGINTEXDEF(q)->SetDefaultTexdef();
  585.   }
  586.  
  587.   if (g_PrefsDlg.m_bSGIOpenGL)
  588.   {
  589.     //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
  590.     if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
  591.           Error ("wglMakeCurrent in LoadTexture failed");
  592.   }
  593.  
  594.   qglBindTexture( GL_TEXTURE_2D, q->texture_number );
  595.  
  596.   //Handle3DfxTexturing(q, width, height, dest);
  597.  
  598.   SetTexParameters();
  599.  
  600.   nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality;
  601.   while (nCount-- > 0)
  602.   {
  603.     if (nWidth > 16 && nHeight > 16)
  604.     {
  605.       R_MipMap(pPixels, nWidth, nHeight);
  606.     }
  607.     else
  608.     {
  609.       break;
  610.     }
  611.   }
  612.  
  613.   if (g_PrefsDlg.m_bSGIOpenGL)
  614.   {
  615.       if (nomips)
  616.     {
  617.           qglTexImage2D(GL_TEXTURE_2D, 0, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
  618.     }
  619.       else
  620.           qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
  621.   }
  622.   else
  623.   {
  624.       if (nomips)
  625.           qglTexImage2D(GL_TEXTURE_2D, 0, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
  626.       else
  627.           qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
  628.   }
  629.  
  630.     qglBindTexture( GL_TEXTURE_2D, 0 );
  631.  
  632.   return q;
  633. }
  634.  
  635.  
  636. qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char *pPath)
  637. {
  638.   CString strName;
  639.   CString strPath;
  640.   ExtractPath_and_Filename(pPath, strPath, strName);
  641.   AddSlash(strPath);
  642.   strPath += "textureinfo.ini";
  643.   strName.MakeLower();
  644.   StripExtension (strName.GetBuffer(0));
  645.   strName.ReleaseBuffer();
  646.   
  647.   int nFlags = GetPrivateProfileInt(strName, "Flags", 0, strPath);
  648.   int nValue = GetPrivateProfileInt(strName, "Value", 0, strPath);
  649.   int nContents = GetPrivateProfileInt(strName, "Contents", 0, strPath);
  650.   return Texture_LoadTGATexture(pPixels, nWidth, nHeight, pPath, nFlags, nValue, nContents);
  651. }
  652.  
  653.  
  654. void Texture_LoadFromPlugIn(LPVOID vp)
  655. {
  656.   g_pluginTexture = notexture;
  657.   _QERTextureLoad *pLoad = reinterpret_cast<_QERTextureLoad*>(vp);
  658.   if (pLoad != NULL)
  659.   {
  660.       qtexture_t    *q;
  661.     q = Texture_LoadTGATexture(pLoad->m_pRGBA, pLoad->m_nWidth, pLoad->m_nHeight, NULL, pLoad->m_nFlags, pLoad->m_nContents, pLoad->m_nValue);
  662.     if (q != NULL)
  663.     {
  664.         // to save duplicate code (since one always ends up getting forgotten and out of sync) this is now done later by caller
  665. //          strcpy (q->name, pLoad->m_pName);
  666. //          StripExtension (q->name);
  667. //          if (!g_dontuse)
  668. //            q->inuse = true;
  669. //        q->next = g_qeglobals.d_qtextures;
  670. //        g_qeglobals.d_qtextures = q;
  671.       g_pluginTexture = q;
  672.     }
  673.   }
  674. }
  675.  
  676.  
  677. /*
  678. ===============
  679. Texture_CreateSolid
  680.  
  681. Create a single pixel texture of the apropriate color
  682. ===============
  683. */
  684. qtexture_t *Texture_CreateSolid (const char *name)
  685. {
  686.     byte    data[4];
  687.     qtexture_t    *q;
  688.  
  689.   q = (qtexture_t*)qmalloc(sizeof(*q));
  690.  
  691.   if (g_qeglobals.bSurfacePropertiesPlugin)
  692.   {
  693.       // Timo
  694.       // Surface properties plugins can store their own data in an IPluginQTexture
  695.       q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
  696.       GETPLUGINTEXDEF(q)->SetDefaultTexdef();
  697.   }
  698.     
  699.     sscanf (name, "(%f %f %f)", &q->color[0], &q->color[1], &q->color[2]);
  700.  
  701.     data[0] = q->color[0]*255;
  702.     data[1] = q->color[1]*255;
  703.     data[2] = q->color[2]*255;
  704.     data[3] = 255;
  705.  
  706.     q->width = q->height = 1;
  707.     //q->width = q->height = 2;
  708.   q->texture_number = texture_extension_number++;
  709.     qglBindTexture( GL_TEXTURE_2D, q->texture_number );
  710.     SetTexParameters ();
  711.  
  712.   if (g_PrefsDlg.m_bSGIOpenGL)
  713.   {
  714.         qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  715.   }
  716.   else
  717.   {
  718.       if (nomips)
  719.           qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  720.       else
  721.           qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data);
  722.   }
  723.     qglBindTexture( GL_TEXTURE_2D, 0 );
  724.  
  725.     return q;
  726. }
  727.  
  728.  
  729. /*
  730. =================
  731. Texture_MakeDefault
  732. =================
  733. */
  734. qtexture_t* Texture_MakeDefault (void)
  735. {
  736.   qtexture_t    *q;
  737.   byte        data[4][4];
  738.  
  739.   if (g_PrefsDlg.m_bSGIOpenGL)
  740.   {
  741.     if (s_hdcTexture && s_hglrcTexture)
  742.     { 
  743.        //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
  744.        if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
  745.              Error ("wglMakeCurrent in LoadTexture failed");
  746.     }
  747.     else
  748.       return NULL;
  749.   }
  750.  
  751.   q = (qtexture_t*)qmalloc(sizeof(*q));
  752.   
  753.   strcpy (q->name, "notexture");
  754.   q->width = q->height = 64;
  755.   
  756.   memset (data, 0, sizeof(data));
  757.   data[0][2] = data[3][2] = 255;
  758.   
  759.   q->color[0] = 0;
  760.   q->color[1] = 0;
  761.   q->color[2] = 0.5;
  762.  
  763.   q->texture_number = texture_extension_number++;
  764.   qglBindTexture( GL_TEXTURE_2D, q->texture_number );
  765.   SetTexParameters ();
  766.  
  767.     if (nomips)
  768.         qglTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  769.     else
  770.         VERIFY(qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data) == 0);
  771.  
  772.   qglBindTexture( GL_TEXTURE_2D, 0 );
  773.   return q;
  774. }
  775.  
  776.  
  777. /*
  778. =================
  779. Texture_MakeNotexture
  780. =================
  781. */
  782. void Texture_MakeNotexture (void)
  783. {
  784.   notexture = Texture_MakeDefault();
  785.   // Timo
  786.   // Surface properties plugins can store their own data in an IPluginQTexture
  787.   if (g_qeglobals.bSurfacePropertiesPlugin)
  788.   {
  789.       notexture->pData = g_SurfaceTable.m_pfnQTextureAlloc( notexture );
  790.       GETPLUGINTEXDEF(notexture)->SetDefaultTexdef();
  791.   }
  792. }
  793.  
  794.  
  795. void DemandLoadShaderTexture(qtexture_t *q, CShaderInfo *pShader)
  796. {
  797.   char cWork[1024];
  798.   char cWork2[1024];
  799.   strcpy(cWork, (pShader->m_strTextureName.GetLength() > 0) ? pShader->m_strTextureName  : pShader->m_strName);
  800.   StripExtension(cWork);
  801.   // TTimo: if the shader has a m_fTransValue != 1.0f, ignore the alpha channel when loading the texture
  802.   // in some cases (common/weapclip) the 32bit .tga has an empty alpha channel,
  803.   // causing a display bug in the camera view (brush does not seemed drawn since alpha==0 for the texture)
  804.   // NOTE: the workaround is not perfect, the same texture may have been loaded earlier with it's alpha channel
  805.   q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, false);
  806.  
  807.   if (q == NULL || q == notexture) {
  808.     sprintf(cWork2, "%s/%s",ValueForKey(g_qeglobals.d_project_entity, "basepath"), cWork);
  809.     q = Texture_ForNamePath( cWork, cWork2);
  810.  
  811.     if (q == NULL || q == notexture) {
  812.       q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, true);
  813.     }
  814.   }
  815.  
  816.   if (q != NULL && q != notexture)
  817.   {
  818.     pShader->m_pQTexture = q;
  819.     strcpy(q->shadername, pShader->m_strShaderName);
  820.     q->bFromShader = true;
  821.     q->fTrans = pShader->m_fTransValue;
  822.     q->nShaderFlags = pShader->m_nFlags;
  823.     strcpy(q->name, pShader->m_strName );
  824.   }
  825.   else
  826.   {
  827.     Sys_Printf("Could not load shader editor image %s\n", cWork);
  828.   }
  829. }
  830.  
  831.  
  832. void LoadShader(char* pFilename, qtexture_t *q)
  833. {
  834.   char* pBuff = NULL;
  835.   CString strTexture;
  836.   int nSize = LoadFile(pFilename, reinterpret_cast<void**>(&pBuff));
  837.   if (nSize == -1)
  838.   {
  839.     nSize = PakLoadAnyFile(pFilename, reinterpret_cast<void**>(&pBuff));
  840.   }
  841.   if (nSize > 0)
  842.   {
  843.     StartTokenParsing(pBuff);
  844.     while (GetToken(true))
  845.     {
  846.       // first token should be the path + name.. (from base)
  847.       CShaderInfo *pShader = new CShaderInfo();
  848.       pShader->setName(token);
  849.       pShader->m_strShaderName = pFilename;
  850.       strTexture = token;
  851.       bool bGood = true;
  852.       float fTrans = 1.0;
  853.       GetToken(true);
  854.       if (strcmp(token, "{"))
  855.       {
  856.         bGood = false;
  857.         break;
  858.       }
  859.       else
  860.       {
  861.         // we need to read until we hit a balanced }
  862.         int nMatch = 1;
  863.         while (nMatch > 0 && GetToken(true))
  864.         {
  865.           if (strcmp(token, "{") == 0)
  866.           {
  867.             nMatch++;
  868.           }
  869.           else if (strcmp(token, "}") == 0)
  870.           {
  871.             nMatch--;
  872.           }
  873.           else if (strcmpi(token, "qer_nocarve") == 0)
  874.           {
  875.             pShader->m_nFlags |= QER_NOCARVE;
  876.           }
  877.           else if (strcmpi(token, "qer_trans") == 0)
  878.           {
  879.             if (GetToken(true))
  880.             {
  881.               fTrans = atof(token);
  882.             }
  883.             pShader->m_nFlags |= QER_TRANS;
  884.           }
  885.           else if (strcmpi(token, "qer_editorimage") == 0)
  886.           {
  887.             if (GetToken(true))
  888.             {
  889.               char* pTex = copystring(token);
  890.                   QE_ConvertDOSToUnixName( pTex, pTex );
  891.               CString str = pTex;
  892.               free (pTex);
  893.               FindReplace(str, "textures/", "");
  894.               FindReplace(str, ".tga", "");
  895.               int nPos = str.Find('/');
  896.               if (nPos == -1)
  897.               {
  898.                 nPos = str.Find('\\');
  899.               }
  900.               if (nPos >= 0)
  901.               {
  902.                 pShader->m_strTextureName = str;
  903.                                pShader->m_strTextureName.MakeLower();    //avoid problems with case
  904. /*
  905.                 else
  906.                 {
  907.                   CString strPath = str.Left(nPos+1);
  908.                   DeferredShaderLoad *deferred = new DeferredShaderLoad(str, pShader->m_strName, strPath); 
  909.                   g_lstDeferred.Add(deferred);
  910.                 }
  911. */
  912.               }
  913.             }
  914.           }
  915.           else if (strcmpi(token, "surfaceparm") == 0)
  916.           {
  917.             //--while (GetToken(false))
  918.             //--{
  919.             //--
  920.             //--}
  921.             if (GetToken(true))
  922.             {
  923.               // next token should be a surface parm
  924.               //--if (strcmpi(token, "trans") == 0)
  925.               //--{
  926.               //--  fTrans = 0.33;
  927.               //--}
  928.               if (strcmpi(token, "fog") == 0)
  929.               {
  930.                 if (fTrans == 1.0) // has not been explicitly set by qer_trans
  931.                 {
  932.                   fTrans = 0.35;
  933.                 }
  934.               }
  935.             }
  936.           }
  937.         }
  938.         if (nMatch != 0)
  939.         {
  940.           bGood = false;
  941.           break;
  942.         }
  943.       }
  944.       //--if (bGood && q)
  945.       if (bGood)
  946.       {
  947.         pShader->m_fTransValue = fTrans;
  948.         g_lstShaders.Add(pShader);
  949.  
  950.         int n = g_PrefsDlg.m_nShader;
  951.         if (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_ALL || (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_COMMON && strstr(pShader->m_strName, "common" )))
  952.         {
  953. // new 
  954.           if (pShader->m_strTextureName.GetLength() > 0)
  955.           {
  956.             if (!ShaderQTextureExists(pShader->m_strName))
  957.             {
  958.               DemandLoadShaderTexture(q, pShader);
  959.             }
  960.           }
  961.         }
  962. // end new 
  963.         //--q->bFromShader = true;
  964.         //--q->fTrans = fTrans;
  965.  
  966.         //--// good texture here
  967.         //--//Sys_Printf("Test load texture %s\n", strTexture);
  968.         //--// FIXME.. this is a load of crap
  969.         //--strcpy(dirstring, strTexture);
  970.         //--QE_ConvertDOSToUnixName(dirstring, dirstring);
  971.         //--strTexture = dirstring;
  972.         //--FindReplace(strTexture, "textures/", "");
  973.             //--qtexture_t *q = Texture_ForName (strTexture.GetBuffer(0));
  974.         //--if (q != NULL)
  975.         //--{
  976.         //--  q->bFromShader = true;
  977.         //--  q->fTrans = fTrans;
  978.         //--}
  979.       }
  980.       else
  981.       {
  982.         Sys_Printf("Error parsing shader at texture %s\n", strTexture);
  983.       }
  984.  
  985.     }
  986.     free (pBuff);
  987.   }
  988.   else
  989.   {
  990.     Sys_Printf("Unabled to read shader %s\n", pFilename);
  991.   }
  992. }
  993.  
  994.  
  995. extern bool DoesFileExist(const char* pBuff, long& lSize);
  996. CShaderInfo* SetNameShaderInfo(qtexture_t* q, const char* pPath, const char* pName)
  997. {
  998.   CShaderInfo *pInfo = hasShader(pName);
  999.   if (pInfo)
  1000.   {
  1001.     strcpy(q->shadername, pInfo->m_strShaderName);
  1002.     q->bFromShader = true;
  1003.     q->fTrans = pInfo->m_fTransValue;
  1004.     q->nShaderFlags = pInfo->m_nFlags;
  1005.   }
  1006.   else
  1007.   {
  1008.     q->shadername[0] = 0;
  1009.   }
  1010.   strncpy (q->name, pName, sizeof(q->name) - 1);
  1011.     StripExtension (q->name);
  1012.   return pInfo;
  1013. }
  1014.  
  1015. void ReplaceQTexture(qtexture_t *pOld, qtexture_t *pNew, brush_t *pList)
  1016. {
  1017.  
  1018.   for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next)
  1019.     {
  1020.     if (pBrush->patchBrush)
  1021.     {
  1022.       Patch_ReplaceQTexture(pBrush, pOld, pNew);
  1023.     }
  1024.  
  1025.     for (face_t* pFace = pBrush->brush_faces; pFace; pFace = pFace->next)
  1026.     {
  1027.       if (pFace->d_texture == pOld)
  1028.       {
  1029.         pFace->d_texture = pNew;
  1030.       }
  1031.     }
  1032.     //Brush_Build(pBrush);
  1033.     }
  1034.  
  1035. }
  1036.  
  1037.  
  1038. void Texture_Remove(qtexture_t *q)
  1039. {
  1040.   qtexture_t* pTex = g_qeglobals.d_qtextures->next;
  1041.   if (q == g_qeglobals.d_qtextures)   // it is the head
  1042.   {
  1043.     g_qeglobals.d_qtextures->next = q->next->next;
  1044.     g_qeglobals.d_qtextures = q->next;
  1045.   }
  1046.   else
  1047.   {
  1048.     qtexture_t* pLast = g_qeglobals.d_qtextures;
  1049.     while (pTex != NULL && pTex != g_qeglobals.d_qtextures)
  1050.     {
  1051.       if (pTex == q)
  1052.       {
  1053.         pLast->next = q->next;
  1054.         break;
  1055.       }
  1056.       pLast = pTex;
  1057.       pTex = pTex->next;
  1058.     }
  1059.   }
  1060.   qglDeleteTextures(1, reinterpret_cast<const unsigned int*>(&q->texture_number));
  1061.  
  1062.   if (g_qeglobals.bSurfacePropertiesPlugin)
  1063.   {
  1064.       // Timo
  1065.       // Surface properties plugin
  1066. #ifdef _DEBUG
  1067.       if ( !q->pData )
  1068.           Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
  1069. #endif
  1070.       if ( q->pData )
  1071.           GETPLUGINTEXDEF(q)->DecRef();
  1072.   }
  1073.  
  1074.   free(q);
  1075.  
  1076. }
  1077.  
  1078. /*
  1079. =================
  1080. Texture_MakeNoShadertexture
  1081.  
  1082. Make a default black/red check pattern texture
  1083. =================
  1084. */
  1085. qtexture_t * Texture_MakeNoshadertexture( const char *name )
  1086. {
  1087.     qtexture_t    *q;
  1088.     byte        data[4][4];
  1089.  
  1090.     notexture = q = (qtexture_t*)qmalloc(sizeof(*q));
  1091.     q->width = q->height = 64;
  1092.     q->fTrans = 1;
  1093.  
  1094.     q = (qtexture_t*)qmalloc(sizeof(*q));
  1095.   strcpy (q->name, name);
  1096.  
  1097.     q->width = q->height = 64;
  1098.     q->fTrans = 1;
  1099.  
  1100.     memset (data, 0, sizeof(data));
  1101.     data[0][0] = data[3][0] = 255;
  1102.  
  1103.     q->color[0] = 0;
  1104.     q->color[1] = 0;
  1105.     q->color[2] = 0.5;
  1106.  
  1107.     q->texture_number = texture_extension_number++;
  1108.     qglBindTexture( GL_TEXTURE_2D, q->texture_number );
  1109.     SetTexParameters ();
  1110.  
  1111.     if (nomips)
  1112.         qglTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  1113.     else
  1114.         VERIFY(qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data) == 0);
  1115.  
  1116.     qglBindTexture( GL_TEXTURE_2D, 0 );
  1117.  
  1118.     return q;
  1119. }
  1120.  
  1121.  
  1122.  
  1123. /*
  1124. ===============
  1125. Texture_ForName
  1126. ===============
  1127. */
  1128. //bReload is set to true when called from DemandLoadShaderTexture because it should never re-use
  1129. //an already loaded texture
  1130. qtexture_t *Texture_ForName (const char *name, bool bReplace, bool bShader, bool bNoAlpha, bool bReload, bool makeShader)
  1131. {
  1132.   byte    *lump;
  1133.     qtexture_t    *q = NULL;
  1134.     char    filename[1024];
  1135.     
  1136.   if (name == NULL || strlen(name) == 0)
  1137.         return notexture;
  1138.     
  1139.     qtexture_t *pRemove = NULL;
  1140.     
  1141.     if (!bReload)
  1142.     {
  1143.         for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
  1144.         {
  1145.             if (!strcmp(name,  q->name))
  1146.             {
  1147.                 if (bReplace)
  1148.                 {
  1149.                     pRemove = q;
  1150.                     //Texture_Remove(q);
  1151.                     break;
  1152.                 }
  1153.                 else
  1154.                 {
  1155. #ifdef _DEBUG
  1156.                     // if the texture is already in memory, then the bNoAlpha flag doesn't have any influence
  1157.                     if (bNoAlpha)
  1158.                         Sys_Printf("WARNING: bNoAlpha flag on an already loaded texture\n");
  1159. #endif
  1160.                     if (!g_dontuse)
  1161.                     {
  1162.                         q->inuse = true;
  1163.                     }
  1164.                     return q;
  1165.                 }
  1166.             }
  1167.         }
  1168.     }
  1169.  
  1170.   // did not find it in the standard list
  1171.   // skip entity names (
  1172.   if (!bShader && name[0] != '(')
  1173.   {
  1174.     CShaderInfo* pShader = hasShader(name);
  1175.     if (pShader)
  1176.     {
  1177.       if (pShader->m_pQTexture == NULL)
  1178.       {
  1179.         DemandLoadShaderTexture(q, pShader);
  1180.       }
  1181.       q = pShader->m_pQTexture;
  1182.       //Sys_Printf ("used Shader %s.\n", pShader->m_strName);
  1183.     }
  1184.     if ( q != NULL)
  1185.     {
  1186.       return q;
  1187.     }
  1188.   }
  1189.  
  1190.     
  1191.     if (name[0] == '(')
  1192.     {
  1193.         q = Texture_CreateSolid (name);
  1194.         strncpy (q->name, name, sizeof(q->name)-1);
  1195.     }
  1196.     else
  1197.     {
  1198.         // FIXME: this is a mess.. need to move consolidate stuff
  1199.         // down to a single routine.. 
  1200.         // 
  1201.         // if plugins have a texture loader
  1202.         // {
  1203.         //   
  1204.         // }
  1205.         // else
  1206.         // 
  1207.         if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL)
  1208.         {
  1209.             // rad: 12/19/98
  1210.             // if the plugin is not a wad style then we need to treat it normally
  1211.             // otherwise return without trying to explicitly load the texture
  1212.             // as it should have been loaded by the wad style plugin at init time
  1213.             CString strTex = GetTextureExtension(0);
  1214.             sprintf (filename, "%s\\%s.%s", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name, strTex);
  1215.             if (!g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle)
  1216.       {   
  1217.                 g_pParentWnd->GetPlugInMgr().LoadTexture(filename);        
  1218.                 if (g_pluginTexture)
  1219.                     q = g_pluginTexture;
  1220.             }
  1221.             else
  1222.             {
  1223.                 return notexture;
  1224.                 // wadstyle.. if we get here then we do not have it
  1225.             }
  1226.         }
  1227.         else
  1228.       // we need to try several formats here, or would it be better if we are given a complete name
  1229.             if (g_PrefsDlg.m_bHiColorTextures == TRUE)
  1230.             {
  1231.             char cWork[1024];
  1232.               sprintf (filename, "%s/%s.tga", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name);
  1233.             QE_ConvertDOSToUnixName( cWork, filename );
  1234.             strcpy(filename, cWork);
  1235.                 Sys_Printf ("Loading %s...", name);
  1236.                 unsigned char* pPixels = NULL;
  1237.                 int nWidth;
  1238.                 int nHeight;
  1239.                 LoadImage(filename, &pPixels, &nWidth, &nHeight);
  1240.         if (pPixels == NULL)
  1241.         {
  1242.           // try jpg
  1243.           // blatant assumption of .tga should be fine since we sprintf'd it above
  1244.           int nLen = strlen(filename);
  1245.           filename[nLen-3] = 'j';
  1246.           filename[nLen-2] = 'p';
  1247.           filename[nLen-1] = 'g';
  1248.                   LoadImage(filename, &pPixels, &nWidth, &nHeight);
  1249.         }
  1250.                 if (pPixels)
  1251.                 {
  1252.                     // if we were asked to ignore alpha channel, do it now (.TGA is the only supported file type with alpha channel)
  1253.                     //if (bNoAlpha)
  1254.                     if (TRUE)
  1255.                     {
  1256.                         unsigned char* iPix = pPixels;
  1257.                         int nCount = nWidth * nHeight;
  1258.                         for(iPix=pPixels+3; iPix-pPixels < nCount*4; iPix+=4)
  1259.                             *iPix = 255;
  1260.                     }
  1261.           // we'll be binding the GL texture now
  1262.           // need to check we are using a right GL context
  1263.           // with GL plugins that have their own window, the GL context may be the plugin's, in which case loading textures will bug
  1264.             HDC currentHDC = qwglGetCurrentDC();
  1265.             HGLRC currentHGLRC = qwglGetCurrentContext();
  1266.           //++timo FIXME: this may duplicate with qtexture_t* WINAPI QERApp_Texture_ForName (const char *name)
  1267.           //++timo FIXME: we need a list of lawfull GL contexts or something?
  1268.           // I'd rather always use the same GL context for binding...
  1269.           if (currentHDC != g_qeglobals.d_hdcBase || currentHGLRC != g_qeglobals.d_hglrcBase)
  1270.               qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase );
  1271.                     q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0);
  1272.           //++timo I don't set back the GL context .. I don't know how safe it is
  1273.           //qwglMakeCurrent( currentHDC, currentHGLRC );
  1274.         //++timo storing the filename .. will be removed by shader code cleanup
  1275.         // this is dirty, and we sure miss some places were we should fill the filename info
  1276.         strcpy( q->filename, name );
  1277.                     SetNameShaderInfo(q, filename, name);
  1278.                     Sys_Printf ("done.\n", name);
  1279.                     free(pPixels);
  1280.                 }
  1281.             }
  1282.             else
  1283.             {
  1284.                 // load the file
  1285.                 sprintf (filename, "%s/%s.wal", ValueForKey (g_qeglobals.d_project_entity, "texturepath"),    name);
  1286.                 Sys_Printf ("Loading %s...", name);
  1287.                 if (LoadFile (filename, (void**)&lump) == -1)
  1288.                 {
  1289.                     sprintf (filename, "%s.wal", name);
  1290.                     Sys_Printf("failed.. trying pak0.pak..");
  1291.                     if(!PakLoadFile(filename, (void**)&lump))
  1292.                     {
  1293.                         Sys_Printf (" load failed!\n");
  1294.                         return notexture;
  1295.                     }
  1296.                 }
  1297.                 Sys_Printf("successful.\n");
  1298.                 q = Texture_LoadTexture ((miptex_t *)lump);
  1299.                 free (lump);
  1300.                 strncpy (q->name, name, sizeof(q->name)-1);
  1301.                 StripExtension (q->name);
  1302.             }
  1303.             
  1304.              if (g_PrefsDlg.m_bSGIOpenGL)
  1305.             {
  1306.                 if(!q)
  1307.                     return notexture;
  1308.             }
  1309.             
  1310.     }// name[0] != '('
  1311.     
  1312.     if(!q)    // safety
  1313.   {
  1314.     if (bShader && !makeShader) {
  1315.       return q;
  1316.     }
  1317.   
  1318.     if (bShader)
  1319.     {
  1320.       q = Texture_MakeNoshadertexture( name );
  1321.         Sys_Printf("failed, using default shader\n");
  1322.     }
  1323.     else
  1324.     {
  1325.       q = Texture_MakeDefault();
  1326.         Sys_Printf("failed, using default\n");
  1327.     }
  1328.   }
  1329.     
  1330.   strncpy (q->name, name, sizeof(q->name)-1);
  1331.   if (name[0] != '(')
  1332.   {
  1333.     StripExtension (q->name);
  1334.   }
  1335.  
  1336.     if (!g_dontuse)
  1337.         q->inuse = true;
  1338.     q->next = g_qeglobals.d_qtextures;
  1339.     g_qeglobals.d_qtextures = q;
  1340.     
  1341.     if (pRemove != NULL)
  1342.     {
  1343.         ReplaceQTexture(pRemove, q, &active_brushes);
  1344.         ReplaceQTexture(pRemove, q, &filtered_brushes);
  1345.         Texture_Remove(pRemove);
  1346.     }
  1347.     
  1348.     return q;
  1349. }
  1350.  
  1351. /*
  1352. ===============
  1353. Texture_ForNamePath
  1354. ===============
  1355. */
  1356. qtexture_t *Texture_ForNamePath(char* name, char* pFullPath)
  1357. {
  1358.   byte    *lump;
  1359.     qtexture_t    *q;
  1360.     char    filename[1024];
  1361.  
  1362.   if (strlen(name) == 0)
  1363.     return notexture;
  1364.  
  1365.     for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
  1366.   {
  1367.       if (!strcmp(name,  q->name))
  1368.         {
  1369.             if (!g_dontuse)
  1370.                 q->inuse = true;
  1371.             return q;
  1372.         }
  1373.   }
  1374.  
  1375.     if (name[0] == '(')
  1376.     {
  1377.         q = Texture_CreateSolid (name);
  1378.         strncpy (q->name, name, sizeof(q->name)-1);
  1379.     }
  1380.     else
  1381.     {
  1382.         // load the file
  1383.     if (g_PrefsDlg.m_bHiColorTextures == TRUE)
  1384.     {
  1385.       char cWork[1024];
  1386.       if (strstr(pFullPath, ".tga") == NULL) {
  1387.         sprintf(filename, "%s%s", pFullPath, ".tga");
  1388.       } else {
  1389.         strcpy(filename, pFullPath);
  1390.       }
  1391.           QE_ConvertDOSToUnixName( cWork, filename );
  1392.         strcpy(filename, cWork);
  1393.           Sys_Printf ("Loading %s...", name);
  1394.       unsigned char* pPixels = NULL;
  1395.       int nWidth;
  1396.       int nHeight;
  1397.       LoadImage(filename, &pPixels, &nWidth, &nHeight);
  1398.       if (!pPixels)
  1399.       {
  1400.         // try jpg
  1401.         // blatant assumption of .tga should be fine since we sprintf'd it above
  1402.         int nLen = strlen(filename);
  1403.         filename[nLen-3] = 'j';
  1404.         filename[nLen-2] = 'p';
  1405.         filename[nLen-1] = 'g';
  1406.                 LoadImage(filename, &pPixels, &nWidth, &nHeight);
  1407.       }
  1408.       if (pPixels)
  1409.       {
  1410.         q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0);
  1411.         //++timo storing the filename .. will be removed by shader code cleanup
  1412.         // this is dirty, and we sure miss some places were we should fill the filename info
  1413.         // NOTE: we store relative path, need to extract it
  1414.         strcpy( q->filename, name );
  1415.  
  1416.       }
  1417.       else
  1418.       {
  1419.         return notexture;
  1420.       }
  1421.       free(pPixels);
  1422.     }
  1423.     else
  1424.     {
  1425.       sprintf(filename, "%s%s", pFullPath, ".wal");
  1426.           Sys_Printf ("Loading %s...", name);
  1427.           if (LoadFile (filename, (void**)&lump) == -1)
  1428.       {
  1429.               Sys_Printf (" load failed!\n");
  1430.               return notexture;
  1431.       }
  1432.       Sys_Printf("successful.\n");
  1433.           q = Texture_LoadTexture ((miptex_t *)lump);
  1434.           free (lump);
  1435.     }
  1436.     if (g_PrefsDlg.m_bSGIOpenGL)
  1437.     {
  1438.           if(!q)
  1439.               return notexture;
  1440.     }
  1441.         strncpy (q->name, name, sizeof(q->name)-1);
  1442.         StripExtension (q->name);
  1443.     }
  1444.  
  1445.     if (!g_dontuse)
  1446.         q->inuse = true;
  1447.     q->next = g_qeglobals.d_qtextures;
  1448.     g_qeglobals.d_qtextures = q;
  1449.  
  1450.   return q;
  1451. }
  1452.  
  1453.  
  1454.  
  1455. /*
  1456. ==================
  1457. FillTextureMenu
  1458.  
  1459. ==================
  1460. */
  1461. void FillTextureMenu (CStringArray* pArray)
  1462. {
  1463.     HMENU    hmenu;
  1464.     int        i;
  1465.     struct _finddata_t fileinfo;
  1466.     int        handle;
  1467.     char    dirstring[1024];
  1468.     char    *path;
  1469.     DIRLIST    *list = NULL, *temp;
  1470.  
  1471.   if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL)
  1472.   {
  1473.     if (g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle)
  1474.       return;
  1475.   }
  1476.  
  1477.     hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_TEXTURE);
  1478.  
  1479.     // delete everything
  1480.     for (i=0 ; i<texture_nummenus ; i++)
  1481.         DeleteMenu (hmenu, CMD_TEXTUREWAD+i, MF_BYCOMMAND);
  1482.  
  1483.   texture_nummenus = 0;
  1484.  
  1485.     // add everything
  1486.   if (g_qeglobals.d_project_entity)
  1487.   {
  1488.     //--if (g_PrefsDlg.m_bUseShaders)
  1489.     //--{
  1490.       //--  path = ValueForKey (g_qeglobals.d_project_entity, "basepath");
  1491.       //--  sprintf (dirstring, "%s/scripts/*.shader", path);
  1492.     //--
  1493.     //--}
  1494.     //--else
  1495.     //--{
  1496.         path = ValueForKey (g_qeglobals.d_project_entity, "texturepath");
  1497.         sprintf (dirstring, "%s/*.*", path);
  1498.     //--}
  1499.  
  1500.       handle = _findfirst (dirstring, &fileinfo);
  1501.       if (handle != -1)
  1502.     {
  1503.         do
  1504.         {
  1505.         //--if (g_PrefsDlg.m_bUseShaders)
  1506.         //--{
  1507.             //--  if ((fileinfo.attrib & _A_SUBDIR))
  1508.         //--    continue;
  1509.         //--}
  1510.         //--else
  1511.         //--{
  1512.               if (!(fileinfo.attrib & _A_SUBDIR))
  1513.                 continue;
  1514.               if (fileinfo.name[0] == '.')
  1515.                 continue;
  1516.         //--}
  1517.         // add this directory to the menu
  1518.           AddToDirListAlphabetized(&list, fileinfo.name, FROMDISK);
  1519.         } while (_findnext( handle, &fileinfo ) != -1);
  1520.  
  1521.         _findclose (handle);
  1522.     }
  1523.  
  1524.     //--if (!g_PrefsDlg.m_bUseShaders)
  1525.     //--{
  1526.       GetPackTextureDirs(&list);
  1527.     //--}
  1528.  
  1529.       for(temp = list; temp; temp = temp->next)
  1530.       {
  1531.           AppendMenu (hmenu, MF_ENABLED|MF_STRING, CMD_TEXTUREWAD+texture_nummenus, (LPCTSTR)temp->dirname);
  1532.           strcpy (texture_menunames[texture_nummenus], temp->dirname);
  1533.       //--if (!g_PrefsDlg.m_bUseShaders)
  1534.       //--{
  1535.             strcat (texture_menunames[texture_nummenus], "/");
  1536.       //--}
  1537.       if (pArray)
  1538.         pArray->Add(temp->dirname);
  1539.           if (++texture_nummenus == MAX_TEXTUREDIRS)
  1540.            break;
  1541.       }
  1542.  
  1543.       ClearDirList(&list);
  1544.   }
  1545.  
  1546.  
  1547. }
  1548.  
  1549.  
  1550. /*
  1551. ==================
  1552. Texture_ClearInuse
  1553.  
  1554. A new map is being loaded, so clear inuse markers
  1555. ==================
  1556. */
  1557. void Texture_ClearInuse (void)
  1558. {
  1559.     qtexture_t    *q;
  1560.  
  1561.     for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
  1562.     {
  1563.         q->inuse = false;
  1564.     }
  1565. }
  1566.  
  1567.  
  1568.  
  1569.  
  1570. void LoadShadersFromDir(const char *pPath)
  1571. {
  1572.   int nSize = g_lstShaders.GetSize();
  1573.   for (int i = 0; i < nSize; i++)
  1574.   {
  1575.     CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i));
  1576.     if (pInfo != NULL)
  1577.     {
  1578.       if (strstr(pInfo->m_strName, pPath) && pInfo->m_pQTexture == NULL && strstr(pInfo->m_strName, "models/player") == NULL)
  1579.       {
  1580.         qtexture_t *q = NULL;
  1581.         DemandLoadShaderTexture(q, pInfo);
  1582.       }
  1583.     }
  1584.   }
  1585. }
  1586.  
  1587.  
  1588. /*
  1589. ==============
  1590. Texture_ShowDirectory
  1591. ==============
  1592. */
  1593. void    Texture_ShowDirectory (int menunum, bool bLinked)
  1594. {
  1595.     struct _finddata_t fileinfo;
  1596.     int        handle;
  1597.     char    name[1024];
  1598.     char    dirstring[1024];
  1599.     char    linkstring[1024];
  1600.     FILELIST            *list = NULL, *temp;
  1601.   CString strTemp;
  1602.  
  1603.   //Texture_Flush(false);
  1604.     //Select_Deselect();
  1605.     Texture_ClearInuse();
  1606.     texture_showinuse = false;
  1607.     strcpy (texture_directory, texture_menunames[menunum-CMD_TEXTUREWAD]);
  1608.  
  1609.   if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL)
  1610.   {
  1611.     if (g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle)
  1612.       return;
  1613.   }
  1614.  
  1615.   // new
  1616. /*
  1617.   if (!g_PrefsDlg.m_bShaderTest)
  1618.   {
  1619.     g_dontuse = true;    // needed because this next piece of code calls Texture_ForName() internally! -slc
  1620.     LoadDeferred(texture_directory);
  1621.     g_dontuse = false;
  1622.   }
  1623. */
  1624.   if (g_PrefsDlg.m_bHiColorTextures == FALSE)
  1625.   {
  1626.   }
  1627.  
  1628.     g_qeglobals.d_texturewin.originy = 0;
  1629.  
  1630.   //--if (g_PrefsDlg.m_bUseShaders)
  1631.   //--{
  1632.   //--  sprintf (dirstring, "%s/scripts/%s", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_directory);
  1633.     //--  Sys_Printf("loading textures from shader %s\n", dirstring);
  1634.   //--  LoadShader(dirstring);
  1635.   //--}
  1636.   //--else
  1637.   //--{
  1638.       Sys_Status("Loading textures\n", 0);
  1639.  
  1640.       // load all image files
  1641.                                           
  1642.     sprintf (linkstring, "%s/textures/%stextureinfo.ini", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_menunames[menunum-CMD_TEXTUREWAD]);
  1643.  
  1644.     for (int nExt = 0; nExt < GetTextureExtensionCount(); nExt++)
  1645.     {
  1646.       sprintf (dirstring, "%s/textures/%s*.%s", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt));
  1647.       Sys_Printf ("Scanning %s\n", dirstring);
  1648.         handle = _findfirst (dirstring, &fileinfo);
  1649.  
  1650.       if (handle == -1)
  1651.       {
  1652.         sprintf(dirstring, "%s/%s*.%s", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt));
  1653.         handle = _findfirst (dirstring, &fileinfo);
  1654.       }
  1655.       if (handle != -1)
  1656.         {
  1657.             do
  1658.             {
  1659.                 sprintf (name, "%s%s", texture_directory, fileinfo.name);
  1660.                 AddToFileListAlphabetized(&list, name, FROMDISK, 0, false);
  1661.             } while (_findnext( handle, &fileinfo ) != -1);
  1662.             _findclose (handle);
  1663.         }
  1664.         else
  1665.         {
  1666.           sprintf (dirstring, "%s*.%s", texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt));
  1667.             GetPackFileList(&list, dirstring);
  1668.         }
  1669.     }
  1670.  
  1671.       g_dontuse = true;
  1672.       for(temp = list; temp; temp = temp->next)
  1673.       {
  1674.           if(temp->offset == -1)
  1675.               sprintf(name, "%s", temp->filename);
  1676.           else
  1677.               sprintf(name, "%s%s", texture_menunames[menunum-CMD_TEXTUREWAD], temp->filename);
  1678.           StripExtension (name);
  1679.       strTemp = name;
  1680.       strTemp.MakeLower();
  1681.       if ( strTemp.Find(".specular") >= 0 ||
  1682.            strTemp.Find(".glow") >= 0 ||
  1683.            strTemp.Find(".bump") >= 0 ||
  1684.            strTemp.Find(".diffuse") >= 0 ||
  1685.            strTemp.Find(".blend") >= 0 ||
  1686.            strTemp.Find(".alpha") >= 0
  1687.          )
  1688.         continue;
  1689.       else
  1690.       {
  1691.             Texture_ForName (name, true);
  1692.       }
  1693.       }
  1694.  
  1695.       ClearFileList(&list);
  1696.   //--}
  1697.  
  1698.  
  1699.     g_dontuse = false;
  1700.  
  1701.   if (!bLinked)
  1702.   {
  1703.  
  1704.     for (int k = 0; k < 10; k++)
  1705.     {
  1706.       sprintf(name, "Path%d", k);
  1707.       if (GetPrivateProfileString("Include", name, "", dirstring, 1024, linkstring) > 0)
  1708.       {
  1709.         Texture_ShowDirectory(dirstring, true);
  1710.       }
  1711.     }
  1712.  
  1713.     LoadShadersFromDir(texture_directory);
  1714.  
  1715.     SortTextures();
  1716.       
  1717.     sprintf (name, "Textures: %s", texture_directory);
  1718.       SetWindowText(g_qeglobals.d_hwndEntity, name);
  1719.  
  1720.       // select the first texture in the list
  1721.       if (!g_qeglobals.d_texturewin.texdef.name[0])
  1722.           SelectTexture (16, g_qeglobals.d_texturewin.height -16, false);
  1723.   }
  1724. }
  1725.  
  1726.  
  1727. // this can be combined with the above, but per usual i am in a hurry
  1728. //
  1729. void    Texture_ShowDirectory (char* pPath, bool bLinked)
  1730. {
  1731.     struct _finddata_t fileinfo;
  1732.     int        handle;
  1733.     char    name[1024];
  1734.     char    dirstring[1024];
  1735.     char    linkstring[1024];
  1736.     FILELIST            *list = NULL, *temp;
  1737.  
  1738.   //Texture_Flush(false);
  1739.  
  1740.     texture_showinuse = false;
  1741.     Texture_ClearInuse();
  1742.     strcpy (texture_directory, pPath);
  1743.  
  1744.   if (g_PrefsDlg.m_bHiColorTextures == FALSE)
  1745.   {
  1746.   }
  1747.  
  1748.     g_qeglobals.d_texturewin.originy = 0;
  1749.     Sys_Status("loading all textures\n", 0);
  1750.  
  1751.     // load all .wal files
  1752.   for (int nExt = 0; nExt < GetTextureExtensionCount(); nExt++)
  1753.   {
  1754.     sprintf(dirstring, "%s*.%s", pPath,GetTextureExtension(nExt));
  1755.                                           
  1756.       Sys_Printf ("Scanning %s\n", dirstring);
  1757.  
  1758.       handle = _findfirst (dirstring, &fileinfo);
  1759.  
  1760.     if (handle != -1)
  1761.       {
  1762.           do
  1763.           {
  1764.               sprintf (name, "%s%s", texture_directory, fileinfo.name);
  1765.               AddToFileListAlphabetized(&list, name, FROMDISK, 0, false);
  1766.           } while (_findnext( handle, &fileinfo ) != -1);
  1767.           _findclose (handle);
  1768.       }
  1769.       else
  1770.       {
  1771.           //sprintf (dirstring, "%s*.wal", texture_menunames[menunum-CMD_TEXTUREWAD]);
  1772.           //if(!GetPackFileList(&list, dirstring))
  1773.               return;
  1774.       }
  1775.   }
  1776.  
  1777.     g_dontuse = true;
  1778.     for(temp = list; temp; temp = temp->next)
  1779.     {
  1780.         if(temp->offset == -1)
  1781.             sprintf(name, "%s", temp->filename);
  1782.         else
  1783.           sprintf(name, "%s%s", pPath, temp->filename);
  1784.         StripExtension (name);
  1785.  
  1786.     int nLen = strlen(name)-1;
  1787.     ASSERT(nLen > 0);
  1788.     while (name[nLen] != '\\')
  1789.       nLen--;
  1790.     // found first one
  1791.     nLen--;
  1792.     ASSERT(nLen > 0);
  1793.     while (name[nLen] != '\\')
  1794.       nLen--;
  1795.     ASSERT(nLen >= 0);
  1796.     QE_ConvertDOSToUnixName(name, name);
  1797.     Texture_ForName(&name[nLen+1]);
  1798.  
  1799.     }
  1800.  
  1801.     ClearFileList(&list);
  1802.  
  1803.     g_dontuse = false;
  1804.  
  1805.   SortTextures();
  1806.  
  1807.   if (!bLinked)
  1808.   {
  1809.  
  1810.     for (int k = 0; k < 10; k++)
  1811.     {
  1812.       sprintf(name, "Path%d", k);
  1813.       if (GetPrivateProfileString("Include", name, "", dirstring, 1024, linkstring) > 0)
  1814.       {
  1815.         Texture_ShowDirectory(dirstring, true);
  1816.       }
  1817.     }
  1818.  
  1819.  
  1820.       sprintf (name, "Textures: %s", texture_directory);
  1821.       SetWindowText(g_qeglobals.d_hwndEntity, name);
  1822.  
  1823.       // select the first texture in the list
  1824.       if (!g_qeglobals.d_texturewin.texdef.name[0])
  1825.           SelectTexture (16, g_qeglobals.d_texturewin.height -16 ,false);
  1826.   }
  1827. }
  1828.  
  1829.  
  1830.  
  1831. void Texture_ResetPosition()
  1832. {
  1833.   SelectTexture (16, g_qeglobals.d_texturewin.height -16 ,false);
  1834.   g_qeglobals.d_texturewin.originy = 0;
  1835. }
  1836.  
  1837.  
  1838.  
  1839. /*
  1840. ==================
  1841. Texture_SetInuse
  1842.  
  1843. ==================
  1844. */
  1845. void Texture_SetInuse (void)
  1846. {
  1847.     qtexture_t    *q;
  1848.  
  1849.     for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
  1850.   {
  1851.         q->inuse = true;
  1852.     }
  1853. }
  1854.  
  1855.  
  1856. /*
  1857. ==============
  1858. Texture_ShowAll
  1859. ==============
  1860. */
  1861. void    Texture_ShowAll()
  1862. {
  1863.   Texture_SetInuse();
  1864.     Sys_Printf("Showing all textures...\n");
  1865.     Sys_UpdateWindows (W_TEXTURE);
  1866. }
  1867.  
  1868. /*
  1869. ==============
  1870. Texture_ShowInuse
  1871. ==============
  1872. */
  1873. void    Texture_ShowInuse (void)
  1874. {
  1875.     face_t    *f;
  1876.     brush_t    *b;
  1877.     char    name[1024];
  1878.  
  1879.     texture_showinuse = true;
  1880.     g_dontuse = false;
  1881.  
  1882.     g_qeglobals.d_texturewin.originy = 0;    
  1883.  
  1884.     Texture_ClearInuse();
  1885.     Sys_Status("Selecting active textures\n", 0);
  1886.  
  1887.     for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next)
  1888.   {
  1889.     if (b->patchBrush)
  1890.     {
  1891.       Texture_ForName(b->pPatch->d_texture->name);
  1892.     }
  1893.     else
  1894.     {
  1895.           for (f=b->brush_faces ; f ; f=f->next)
  1896.       {
  1897.               Texture_ForName (f->texdef.name);
  1898.       }
  1899.     }
  1900.   }
  1901.  
  1902.     for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next)
  1903.   {
  1904.     if (b->patchBrush)
  1905.     {
  1906.       Texture_ForName(b->pPatch->d_texture->name);
  1907.     }
  1908.     else
  1909.     {
  1910.           for (f=b->brush_faces ; f ; f=f->next)
  1911.       {
  1912.               Texture_ForName (f->texdef.name);
  1913.       }
  1914.     }
  1915.   }
  1916.  
  1917.     SortTextures();
  1918.     //SetInspectorMode(W_TEXTURE);
  1919.     Sys_UpdateWindows (W_TEXTURE);
  1920.  
  1921.     sprintf (name, "Textures: in use");
  1922.     SetWindowText(g_qeglobals.d_hwndEntity, name);
  1923.  
  1924.     // select the first texture in the list
  1925.     if (!g_qeglobals.d_texturewin.texdef.name[0])
  1926.   {
  1927.         SelectTexture (16, g_qeglobals.d_texturewin.height -16, false);
  1928.   }
  1929. }
  1930.  
  1931. /*
  1932. ============================================================================
  1933.  
  1934. TEXTURE LAYOUT
  1935.  
  1936. ============================================================================
  1937. */
  1938.  
  1939. void Texture_StartPos (void)
  1940. {
  1941.     current_texture = g_qeglobals.d_qtextures;
  1942.     current_x = 8;
  1943.     current_y = -8;
  1944.     current_row = 0;
  1945. }
  1946.  
  1947. qtexture_t *Texture_NextPos (int *x, int *y)
  1948. {
  1949.     qtexture_t    *q;
  1950.  
  1951.     while (1)
  1952.     {
  1953.         q = current_texture;
  1954.         if (!q)
  1955.             return q;
  1956.         current_texture = current_texture->next;
  1957.         if (q->name[0] == '(')    // fake color texture
  1958.             continue;
  1959.  
  1960.     if (g_bFilterEnabled)
  1961.     {
  1962.       CString strName = q->name;
  1963.       int nPos = strName.Find('\\');
  1964.       if (nPos == -1)
  1965.         nPos = strName.Find('/');
  1966.       if (nPos >= 0)
  1967.         strName = strName.Right(strName.GetLength() - nPos - 1);
  1968.       if (strnicmp(g_strFilter.GetBuffer(0), strName, g_strFilter.GetLength()) == 0)
  1969.         break;
  1970.       else
  1971.         continue;
  1972.     }
  1973.  
  1974.     if (q->bFromShader && g_PrefsDlg.m_bShowShaders == FALSE)
  1975.     {
  1976.       continue;
  1977.     }
  1978.  
  1979.         if (q->inuse)
  1980.             break;            // always show in use
  1981.     
  1982.     if (!texture_showinuse && !strnicmp (q->name, texture_directory, strlen(texture_directory)))
  1983.             break;
  1984.         continue;
  1985.     }
  1986.  
  1987.   int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width;
  1988.   int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height;
  1989.     if (current_x + nWidth > g_qeglobals.d_texturewin.width-8 && current_row)
  1990.     {    // go to the next row unless the texture is the first on the row
  1991.         current_x = 8;
  1992.         current_y -= current_row + FONT_HEIGHT + 4;
  1993.         current_row = 0;
  1994.     }
  1995.  
  1996.     *x = current_x;
  1997.     *y = current_y;
  1998.  
  1999.     // Is our texture larger than the row? If so, grow the 
  2000.     // row height to match it
  2001.  
  2002.     if (current_row < nHeight)
  2003.           current_row = nHeight;
  2004.  
  2005.     // never go less than 64, or the names get all crunched up
  2006.     current_x += nWidth < 64 ? 64 : nWidth;
  2007.     current_x += 8;
  2008.  
  2009.     return q;
  2010. }
  2011.  
  2012. /*
  2013. ============================================================================
  2014.  
  2015.   MOUSE ACTIONS
  2016.  
  2017. ============================================================================
  2018. */
  2019.  
  2020. static    int    textures_cursorx, textures_cursory;
  2021.  
  2022.  
  2023. /*
  2024. ============
  2025. Texture_SetTexture
  2026.  
  2027. brushprimit_texdef must be understood as a qtexture_t with width=2 height=2 ( the default one )
  2028. ============
  2029. */
  2030. void Texture_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, IPluginTexdef *pTexdef, bool bSetSelection )
  2031. {
  2032.     qtexture_t    *q;
  2033.     int            x,y;
  2034.  
  2035.     if (texdef->name[0] == '(')
  2036.     {
  2037.         Sys_Status("Can't select an entity texture\n", 0);
  2038.         return;
  2039.     }
  2040.     g_qeglobals.d_texturewin.texdef = *texdef;
  2041.     g_qeglobals.d_texturewin.texdef.flags &= ~SURF_KEEP;
  2042.     g_qeglobals.d_texturewin.texdef.contents &= ~CONTENTS_KEEP;
  2043.     // store the texture coordinates for new brush primitive mode
  2044.     // be sure that all the callers are using the default 2x2 texture
  2045.     if (g_qeglobals.m_bBrushPrimitMode)
  2046.     {
  2047.         g_qeglobals.d_texturewin.brushprimit_texdef = *brushprimit_texdef;
  2048.     }
  2049.     // surface properties plugin
  2050.     if (g_qeglobals.bSurfacePropertiesPlugin)
  2051.     {
  2052.         if (g_qeglobals.d_texturewin.pTexdef)
  2053.         {
  2054.             // decrement reference count
  2055.             static_cast<IPluginTexdef *>(g_qeglobals.d_texturewin.pTexdef)->DecRef();
  2056.             g_qeglobals.d_texturewin.pTexdef = NULL;
  2057.         }
  2058.         if (pTexdef)
  2059.         {
  2060.             g_qeglobals.d_texturewin.pTexdef = pTexdef->Copy();
  2061.         }
  2062.     }
  2063.  
  2064.     Sys_UpdateWindows (W_TEXTURE);
  2065.  
  2066.   g_dlgFind.updateTextures(texdef->name);
  2067.  
  2068.   if (!g_dlgFind.isOpen() && bSetSelection)
  2069.   {
  2070.     Select_SetTexture(texdef,brushprimit_texdef,bFitScale);
  2071.   }
  2072.  
  2073.  
  2074.     //plugins: send a message telling that the selected texture may have changed
  2075.     DispatchRadiantMsg( RADIANT_TEXTURE );
  2076.  
  2077.     // scroll origin so the texture is completely on screen
  2078.     Texture_StartPos ();
  2079.     while (1)
  2080.     {
  2081.         q = Texture_NextPos (&x, &y);
  2082.         if (!q)
  2083.             break;
  2084.  
  2085.     int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width;
  2086.     int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height;
  2087.         if (!strcmpi(texdef->name, q->name))
  2088.         {
  2089.             if (y > g_qeglobals.d_texturewin.originy)
  2090.             {
  2091.                 g_qeglobals.d_texturewin.originy = y;
  2092.                 Sys_UpdateWindows (W_TEXTURE);
  2093.                 return;
  2094.             }
  2095.  
  2096.             if (y-nHeight-2*FONT_HEIGHT < g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height)
  2097.             {
  2098.                 g_qeglobals.d_texturewin.originy = y-nHeight-2*FONT_HEIGHT+g_qeglobals.d_texturewin.height;
  2099.                 Sys_UpdateWindows (W_TEXTURE);
  2100.                 return;
  2101.             }
  2102.  
  2103.             return;
  2104.         }
  2105.     }
  2106. }
  2107.  
  2108.  
  2109. HWND FindEditWindow()
  2110. {
  2111.   HWND hwnd = FindWindow("TEditPadForm", NULL);
  2112.   HWND hwndEdit = NULL;
  2113.   if (hwnd != NULL)
  2114.   {
  2115.     HWND hwndTab = FindWindowEx(hwnd, NULL, "TTabControl", NULL);
  2116.     if (hwndTab != NULL)
  2117.     {
  2118.       hwndEdit = FindWindowEx(hwndTab, NULL, "TRicherEdit", NULL);
  2119.     }
  2120.   }
  2121.   return hwndEdit;
  2122. }
  2123.  
  2124. void Delay(float fSeconds)
  2125. {
  2126.   DWORD dw = ::GetTickCount();
  2127.   DWORD dwTil = dw + (fSeconds * 1000);
  2128.   while (::GetTickCount() < dwTil)
  2129.   {
  2130.     MSG msg;
  2131.     if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 
  2132.     { 
  2133.       TranslateMessage(&msg);
  2134.       DispatchMessage(&msg);
  2135.     }
  2136.   }
  2137. }
  2138.  
  2139.  
  2140. void ViewShader(const char *pFile, const char *pName)
  2141. {
  2142.   CString str;
  2143.   char* pBuff = NULL;
  2144.   int nSize = LoadFile(pFile, reinterpret_cast<void**>(&pBuff));
  2145.   if (nSize == -1)
  2146.   {
  2147.     nSize = PakLoadAnyFile(pFile, reinterpret_cast<void**>(&pBuff));
  2148.   }
  2149.   if (nSize > 0)
  2150.   {
  2151.     str = pBuff;
  2152.   }
  2153.   int nStart = 0; 
  2154.   if (str.GetLength() > 0)
  2155.   {
  2156.     CString strFind = pName;
  2157.     CString strLook = str;
  2158.     strLook.MakeLower();
  2159.     strFind.MakeLower();
  2160.     int n = strLook.Find(strFind);
  2161.     if (n >= 0)
  2162.     {
  2163.       nStart = n;
  2164.     }
  2165.   }
  2166.  
  2167.   CString s= "editpad ";
  2168.   s += pFile;
  2169.   WinExec(s, SW_SHOWNORMAL);
  2170.  
  2171.   Delay(1.5);
  2172.  
  2173.   HWND hwndEdit = FindEditWindow();
  2174.  
  2175.   if (hwndEdit != NULL)
  2176.   {
  2177.     PostMessage(hwndEdit, EM_SETSEL, nStart, nStart);
  2178.   }
  2179.   else
  2180.   {
  2181.     Sys_Printf("Unable to load shader editor.\n");
  2182.   }
  2183.  
  2184.  
  2185. }
  2186.  
  2187. /*
  2188. ==============
  2189. SelectTexture
  2190.  
  2191.   By mouse click
  2192. ==============
  2193. */
  2194. void SelectTexture (int mx, int my, bool bShift, bool bFitScale)
  2195. {
  2196.     int        x, y;
  2197.     qtexture_t    *q;
  2198.     texdef_t    tex;
  2199.     brushprimit_texdef_t brushprimit_tex;
  2200.  
  2201.     my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height;
  2202.     
  2203.     Texture_StartPos ();
  2204.     while (1)
  2205.     {
  2206.         q = Texture_NextPos (&x, &y);
  2207.         if (!q)
  2208.             break;
  2209.         int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width;
  2210.         int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height;
  2211.         if (mx > x && mx - x < nWidth
  2212.             && my < y && y - my < nHeight + FONT_HEIGHT)
  2213.         {
  2214.             if (bShift)
  2215.             {
  2216.                 if (g_PrefsDlg.m_bHiColorTextures && q->shadername[0] != 0)
  2217.                 {
  2218.                     //CString s = "notepad ";
  2219.                     //s += q->shadername;
  2220.                     //WinExec(s, SW_SHOWNORMAL);    
  2221.     
  2222.                     ViewShader(q->shadername, q->name);                
  2223.  
  2224.                 }
  2225.             }
  2226.             memset (&tex, 0, sizeof(tex));
  2227.             memset (&brushprimit_tex, 0, sizeof(brushprimit_tex));
  2228.             if (g_qeglobals.m_bBrushPrimitMode)
  2229.             {
  2230.                 // brushprimit fitted to a 2x2 texture
  2231.                 brushprimit_tex.coords[0][0] = 1.0f;
  2232.                 brushprimit_tex.coords[1][1] = 1.0f;
  2233.             }
  2234.             else
  2235.             {
  2236.                 tex.scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
  2237.                 tex.scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
  2238.             }
  2239.             tex.flags = q->flags;
  2240.             tex.value = q->value;
  2241.             tex.contents = q->contents;
  2242.             //strcpy (tex.name, q->name);
  2243.             tex.SetName(q->name);
  2244.             Texture_SetTexture ( &tex, &brushprimit_tex, bFitScale, GETPLUGINTEXDEF(q));
  2245.             CString strTex;
  2246.             CString strName = q->name;
  2247.             //int nPos = strName.Find('\\');
  2248.             //if (nPos == -1)
  2249.             //  nPos = strName.Find('/');
  2250.             //if (nPos >= 0)
  2251.             //  strName = strName.Right(strName.GetLength() - nPos - 1);
  2252.             strTex.Format("%s W: %i H: %i", strName.GetBuffer(0), q->width, q->height);
  2253.             g_pParentWnd->SetStatusText(3, strTex);
  2254.             return;
  2255.         }
  2256.     }
  2257.  
  2258.     Sys_Status("Did not select a texture\n", 0);
  2259. }
  2260.  
  2261. /*
  2262. ==============
  2263. Texture_MouseDown
  2264. ==============
  2265. */
  2266. void Texture_MouseDown (int x, int y, int buttons)
  2267. {
  2268.     Sys_GetCursorPos (&textures_cursorx, &textures_cursory);
  2269.  
  2270.     // lbutton = select texture
  2271.     if (buttons == MK_LBUTTON || buttons == (MK_LBUTTON | MK_SHIFT) || buttons == (MK_LBUTTON | MK_CONTROL))
  2272.     {
  2273.     SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y, buttons & MK_SHIFT, buttons & MK_CONTROL);
  2274.     UpdateSurfaceDialog();
  2275.     UpdatePatchInspector();
  2276.     }
  2277. }
  2278.  
  2279. /*
  2280. ==============
  2281. Texture_MouseUp
  2282. ==============
  2283. */
  2284. void Texture_MouseUp (int x, int y, int buttons)
  2285. {
  2286. }
  2287.  
  2288. /*
  2289. ==============
  2290. Texture_MouseMoved
  2291. ==============
  2292. */
  2293. void Texture_MouseMoved (int x, int y, int buttons)
  2294. {
  2295.     int scale = 1;
  2296.  
  2297.     if ( buttons & MK_SHIFT )
  2298.         scale = 4;
  2299.  
  2300.     // rbutton = drag texture origin
  2301.     if (buttons & MK_RBUTTON)
  2302.     {
  2303.         Sys_GetCursorPos (&x, &y);
  2304.         if ( y != textures_cursory)
  2305.         {
  2306.             g_qeglobals.d_texturewin.originy += ( y-textures_cursory) * scale;
  2307.             if (g_qeglobals.d_texturewin.originy > 0)
  2308.                 g_qeglobals.d_texturewin.originy = 0;
  2309.             Sys_SetCursorPos (textures_cursorx, textures_cursory);
  2310.       CWnd *pWnd = CWnd::FromHandle(g_qeglobals.d_hwndTexture);
  2311.       if (g_PrefsDlg.m_bTextureScrollbar && pWnd != NULL)
  2312.       {
  2313.         pWnd->SetScrollPos(SB_VERT, abs(g_qeglobals.d_texturewin.originy));
  2314.       }
  2315.           InvalidateRect(g_qeglobals.d_hwndTexture, NULL, false);
  2316.           UpdateWindow (g_qeglobals.d_hwndTexture);
  2317.         }
  2318.         return;
  2319.     }
  2320. }
  2321.  
  2322.  
  2323. /*
  2324. ============================================================================
  2325.  
  2326. DRAWING
  2327.  
  2328. ============================================================================
  2329. */
  2330.  
  2331. int imax(int iFloor, int i) { if (i>iFloor) return iFloor; return i; }
  2332. HFONT ghFont = NULL;
  2333.  
  2334. /*
  2335. ============
  2336. Texture_Draw2
  2337. ============
  2338. */
  2339. void Texture_Draw2 (int width, int height)
  2340. {
  2341.     qtexture_t    *q;
  2342.     int            x, y;
  2343.     char        *name;
  2344.  
  2345.     qglClearColor (
  2346.         g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0],
  2347.         g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1],
  2348.         g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2],
  2349.         0);
  2350.     qglViewport (0,0,width,height);
  2351.     qglMatrixMode(GL_PROJECTION);
  2352.     qglLoadIdentity ();
  2353.  
  2354.     qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  2355.     qglDisable (GL_DEPTH_TEST);
  2356.     qglDisable(GL_BLEND);
  2357.     qglOrtho (0, width, g_qeglobals.d_texturewin.originy-height, g_qeglobals.d_texturewin.originy, -100, 100);
  2358.     qglEnable (GL_TEXTURE_2D);
  2359.  
  2360.     qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  2361.     g_qeglobals.d_texturewin.width = width;
  2362.     g_qeglobals.d_texturewin.height = height;
  2363.     Texture_StartPos ();
  2364.  
  2365.     while (1)
  2366.     {
  2367.         q = Texture_NextPos (&x, &y);
  2368.         if (!q)
  2369.             break;
  2370.  
  2371.     int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width;
  2372.     int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height;
  2373.         // Is this texture visible?
  2374.         if ( (y-nHeight-FONT_HEIGHT < g_qeglobals.d_texturewin.originy)
  2375.             && (y > g_qeglobals.d_texturewin.originy - height) )
  2376.         {
  2377.  
  2378.             // if in use, draw a background
  2379.             if ((q->inuse && !texture_showinuse) || q->bFromShader)
  2380.             {
  2381.                 qglLineWidth (1);
  2382.  
  2383.         if (q->bFromShader)
  2384.         {
  2385.                   qglColor3f (1,1,1);
  2386.         }
  2387.         else
  2388.         {
  2389.                   qglColor3f (0.5,1,0.5);
  2390.         }
  2391.                 qglDisable (GL_TEXTURE_2D);
  2392.  
  2393.                 qglBegin (GL_LINE_LOOP);
  2394.                 qglVertex2f (x-1,y+1-FONT_HEIGHT);
  2395.                 qglVertex2f (x-1,y-nHeight-1-FONT_HEIGHT);
  2396.                 qglVertex2f (x+1+nWidth,y-nHeight-1-FONT_HEIGHT);
  2397.                 qglVertex2f (x+1+nWidth,y+1-FONT_HEIGHT);
  2398.                 qglEnd ();
  2399.  
  2400.                 qglEnable (GL_TEXTURE_2D);
  2401.             }
  2402.  
  2403.             // Draw the texture
  2404.       float fScale = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? ((float)g_PrefsDlg.m_nTextureScale / 100) : 1.0;
  2405.  
  2406.             qglBindTexture( GL_TEXTURE_2D, q->texture_number );
  2407.       QE_CheckOpenGLForErrors();
  2408.             qglColor3f (1,1,1);
  2409.             qglBegin (GL_QUADS);
  2410.             qglTexCoord2f (0,0);
  2411.             qglVertex2f (x,y-FONT_HEIGHT);
  2412.             qglTexCoord2f (1,0);
  2413.             qglVertex2f (x+nWidth,y-FONT_HEIGHT);
  2414.             qglTexCoord2f (1,1);
  2415.             qglVertex2f (x+nWidth,y-FONT_HEIGHT-nHeight);
  2416.             qglTexCoord2f (0,1);
  2417.             qglVertex2f (x,y-FONT_HEIGHT-nHeight);
  2418.             qglEnd ();
  2419.  
  2420.             // draw the selection border
  2421.             if (!strcmpi(g_qeglobals.d_texturewin.texdef.name, q->name))
  2422.             {
  2423.                 qglLineWidth (3);
  2424.                 qglColor3f (1,0,0);
  2425.                 qglDisable (GL_TEXTURE_2D);
  2426.  
  2427.                 qglBegin (GL_LINE_LOOP);
  2428.                 qglVertex2f (x-4,y-FONT_HEIGHT+4);
  2429.                 qglVertex2f (x-4,y-FONT_HEIGHT-nHeight-4);
  2430.                 qglVertex2f (x+4+nWidth,y-FONT_HEIGHT-nHeight-4);
  2431.                 qglVertex2f (x+4+nWidth,y-FONT_HEIGHT+4);
  2432.                 qglEnd ();
  2433.  
  2434.                 qglEnable (GL_TEXTURE_2D);
  2435.                 qglLineWidth (1);
  2436.             }
  2437.  
  2438.             // draw the texture name
  2439.         qglColor3f (0,0,0);
  2440.             
  2441.       qglRasterPos2f (x, y-FONT_HEIGHT+2);
  2442.  
  2443.             // don't draw the directory name
  2444.             for (name = q->name ; *name && *name != '/' && *name != '\\' ; name++)
  2445.                 ;
  2446.             if (!*name)
  2447.                 name = q->name;
  2448.             else
  2449.                 name++;
  2450.  
  2451.       if (g_PrefsDlg.m_bHiColorTextures && q->shadername[0] != 0)
  2452.       {
  2453.         // slow as shit
  2454.         CString s = "[";
  2455.         s += name;
  2456.         s += "]";
  2457.               qglCallLists (s.GetLength(), GL_UNSIGNED_BYTE, s.GetBuffer(0));
  2458.       }
  2459.       else
  2460.       {
  2461.               qglCallLists (strlen(name), GL_UNSIGNED_BYTE, name);
  2462.       }
  2463.         }
  2464.     }
  2465.  
  2466.     g_qeglobals.d_texturewin.m_nTotalHeight = abs(y) + 100;
  2467.     // reset the current texture
  2468.     qglBindTexture( GL_TEXTURE_2D, 0 );
  2469.     qglFinish();
  2470. }
  2471.  
  2472.  
  2473. void Texture_Init (bool bHardInit)
  2474. {
  2475.     char    name[1024];
  2476.     byte    *pal = NULL;
  2477.  
  2478.   if (g_PrefsDlg.m_bHiColorTextures == FALSE)
  2479.   {
  2480.       // load the palette
  2481.       sprintf (name, "%s/pics/colormap.pcx", ValueForKey (g_qeglobals.d_project_entity, "basepath"));
  2482.  
  2483.       Load256Image (name, NULL, &pal, NULL, NULL);
  2484.       if (!pal)
  2485.     {
  2486.       // before dropping out, try to load it from the QERadiant directory
  2487.       CString strFile = g_strAppPath;
  2488.       AddSlash(strFile);
  2489.       strFile += "colormap.pcx";
  2490.         Load256Image (strFile.GetBuffer(0), NULL, &pal, NULL, NULL);
  2491.         if (!pal)
  2492.             Sys_Printf ("Couldn't load %s or %s", name, strFile);
  2493.     }
  2494.     else
  2495.     {
  2496.         Texture_InitPalette (pal);
  2497.         free (pal);
  2498.     }
  2499.   }
  2500.  
  2501.     // create the fallback texture
  2502.  
  2503.   if (bHardInit)
  2504.   {
  2505.       Texture_MakeNotexture();
  2506.       g_qeglobals.d_qtextures = NULL;
  2507.   }
  2508.   LoadShaders();
  2509.  
  2510. }
  2511.  
  2512. void Texture_FlushUnused()
  2513. {
  2514.   CWaitCursor cursor;
  2515.   Texture_ShowInuse();
  2516.   if (g_qeglobals.d_qtextures)
  2517.   {
  2518.       qtexture_t* pTex = g_qeglobals.d_qtextures->next;
  2519.     qtexture_t *pPrev = g_qeglobals.d_qtextures;
  2520.     while (pTex != NULL && pTex != g_qeglobals.d_qtextures)
  2521.     {
  2522.       qtexture_t* pNextTex = pTex->next;
  2523.         if (g_qeglobals.bSurfacePropertiesPlugin)
  2524.         {
  2525.             // Timo
  2526.             // Surface properties plugin
  2527. #ifdef _DEBUG
  2528.             if ( !pTex->pData )
  2529.                 Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
  2530. #endif
  2531.             if ( pTex->pData && pTex->inuse )
  2532.                 GETPLUGINTEXDEF(pTex)->DecRef();
  2533.         }
  2534.  
  2535.       if (!pTex->inuse)
  2536.       {
  2537.         unsigned int nTexture = pTex->texture_number;
  2538.         qglDeleteTextures(1, &nTexture);
  2539.         pPrev->next = pNextTex;
  2540.           free(pTex);
  2541.       }
  2542.       else
  2543.       {
  2544.         pPrev = pTex;
  2545.       }
  2546.       pTex = pNextTex;
  2547.     }
  2548.   }
  2549. }
  2550.  
  2551. void Texture_Cleanup(CStringList *pList)
  2552. {
  2553.   if (g_qeglobals.d_qtextures)
  2554.   {
  2555.       qtexture_t* pTex = g_qeglobals.d_qtextures->next;
  2556.     while (pTex != NULL && pTex != g_qeglobals.d_qtextures)
  2557.     {
  2558.       qtexture_t* pNextTex = pTex->next;
  2559.       if (pList)
  2560.       {
  2561.         if (pTex->name[0] != '(')
  2562.         {
  2563.           pList->AddTail(pTex->name);
  2564.         }
  2565.       }
  2566.  
  2567.         if (g_qeglobals.bSurfacePropertiesPlugin)
  2568.         {
  2569.             // Timo
  2570.             // Surface properties plugin
  2571. #ifdef _DEBUG
  2572.             if ( !pTex->pData )
  2573.                 Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
  2574. #endif
  2575.             if ( pTex->pData )
  2576.                 GETPLUGINTEXDEF(pTex)->DecRef();
  2577.         }
  2578.         free(pTex);
  2579.       pTex = pNextTex;
  2580.     }
  2581.   }
  2582.  
  2583.   int nSize = g_lstSkinCache.GetSize();
  2584.   for (int i = 0; i < nSize; i++)
  2585.   {
  2586.     SkinInfo *pInfo = reinterpret_cast<SkinInfo*>(g_lstSkinCache.GetAt(i));
  2587.     delete pInfo;
  2588.   }
  2589.  
  2590. }
  2591.  
  2592. /*
  2593. ==================
  2594. Texture_Flush
  2595. ==================
  2596. */
  2597. void Texture_Flush (bool bReload)
  2598. {
  2599.   if (!ConfirmModified())
  2600.     return;
  2601.  
  2602.   Map_New ();
  2603.  
  2604.   CWaitCursor cursor;
  2605.   CStringList strList;
  2606.   Texture_Init(false);
  2607.   Texture_Cleanup(&strList);
  2608.  
  2609.   GLuint* pGln = new GLuint[texture_extension_number-1];
  2610.   qglGenTextures(texture_extension_number-1, pGln);
  2611.   QE_CheckOpenGLForErrors();
  2612.   qglDeleteTextures(texture_extension_number-1, pGln);
  2613.   QE_CheckOpenGLForErrors();
  2614.   delete []pGln;
  2615.   texture_extension_number = 1;
  2616.     g_qeglobals.d_qtextures = NULL;
  2617.  
  2618.   if (bReload)
  2619.   {
  2620.     POSITION pos = strList.GetHeadPosition();
  2621.     while (pos)
  2622.     {
  2623.       CString strTex = strList.GetNext(pos);
  2624.           Texture_ForName (strTex.GetBuffer(0));
  2625.     }
  2626.   }
  2627.  
  2628. }
  2629.  
  2630.  
  2631.  
  2632. /////////////////////////////////////////////////////////////////////////////
  2633. // CTexWnd
  2634. IMPLEMENT_DYNCREATE(CTexWnd, CWnd);
  2635.  
  2636. CTexWnd::CTexWnd()
  2637. {
  2638.   m_bNeedRange = true;
  2639. }
  2640.  
  2641. CTexWnd::~CTexWnd()
  2642. {
  2643. }
  2644.  
  2645.  
  2646. BEGIN_MESSAGE_MAP(CTexWnd, CWnd)
  2647.     //{{AFX_MSG_MAP(CTexWnd)
  2648.     ON_WM_CREATE()
  2649.     ON_WM_SIZE()
  2650.     ON_WM_PARENTNOTIFY()
  2651.     ON_WM_TIMER()
  2652.     ON_WM_KEYDOWN()
  2653.     ON_WM_KEYUP()
  2654.     ON_WM_PAINT()
  2655.     ON_WM_VSCROLL()
  2656.     ON_COMMAND(ID_TEXTURES_FLUSH, OnTexturesFlush)
  2657.   ON_BN_CLICKED(1200, OnShaderClick)
  2658.     //}}AFX_MSG_MAP
  2659. END_MESSAGE_MAP()
  2660.  
  2661.  
  2662. /////////////////////////////////////////////////////////////////////////////
  2663. // CTexWnd message handlers
  2664.  
  2665. /*
  2666. ============
  2667. WTexWndProc
  2668. ============
  2669. */
  2670. LONG WINAPI TexWndProc (
  2671.     HWND    hWnd,
  2672.     UINT    uMsg,
  2673.     WPARAM  wParam,
  2674.     LPARAM  lParam)
  2675. {
  2676.     int        xPos, yPos;
  2677.     RECT    rect;
  2678.  
  2679.     GetClientRect(hWnd, &rect);
  2680.  
  2681.     switch (uMsg)
  2682.     {
  2683.     case WM_CREATE:
  2684.     s_hdcTexture = GetDC(hWnd);
  2685.         QEW_SetupPixelFormat(s_hdcTexture, false);
  2686.  
  2687.         if ( ( s_hglrcTexture = qwglCreateContext( s_hdcTexture ) ) == 0 )
  2688.             Error( "wglCreateContext in WTex_WndProc failed" );
  2689.  
  2690.         if (!qwglShareLists( g_qeglobals.d_hglrcBase, s_hglrcTexture ) )
  2691.             Error( "wglShareLists in WTex_WndProc failed" );
  2692.  
  2693.     if (!qwglMakeCurrent( s_hdcTexture, s_hglrcTexture ))
  2694.           Error ("wglMakeCurrent in WTex_WndProc failed");
  2695.  
  2696.       g_qeglobals.d_hwndTexture = hWnd;
  2697.         return 0;
  2698.  
  2699.     case WM_DESTROY:
  2700.         //wglMakeCurrent( NULL, NULL );
  2701.         //wglDeleteContext( s_hglrcTexture );
  2702.          ReleaseDC( hWnd, s_hdcTexture );
  2703.         return 0;
  2704. #if 0
  2705.     case WM_PAINT:
  2706.         { 
  2707.             PAINTSTRUCT    ps;
  2708.  
  2709.             BeginPaint(hWnd, &ps);
  2710.  
  2711.         if ( !qwglMakeCurrent( s_hdcTexture, s_hglrcTexture ) )
  2712.         //if ( !wglMakeCurrent( ps.hdc, s_hglrcTexture ) )
  2713.         {
  2714.           Sys_Printf("ERROR: wglMakeCurrent failed..\n ");
  2715.           Sys_Printf("Please restart Q3Radiant if the Texture view is not working\n");
  2716.         }
  2717.         else
  2718.         {
  2719.                 Texture_Draw2 (rect.right-rect.left, rect.bottom-rect.top - g_nTextureOffset);
  2720.                 qwglSwapBuffers(s_hdcTexture);
  2721.           TRACE("Texture Paint\n");
  2722.         }
  2723.             EndPaint(hWnd, &ps);
  2724.         }
  2725.         return 0;
  2726. #endif
  2727.     case WM_MBUTTONDOWN:
  2728.     case WM_RBUTTONDOWN:
  2729.     case WM_LBUTTONDOWN:
  2730.         SetCapture( g_qeglobals.d_hwndTexture );
  2731.         xPos = (short)LOWORD(lParam);  // horizontal position of cursor 
  2732.         yPos = (short)HIWORD(lParam);  // vertical position of cursor 
  2733.         
  2734.         Texture_MouseDown (xPos, yPos - g_nTextureOffset, wParam);
  2735.         return 0;
  2736.  
  2737.     case WM_MBUTTONUP:
  2738.     case WM_RBUTTONUP:
  2739.     case WM_LBUTTONUP:
  2740.         xPos = (short)LOWORD(lParam);  // horizontal position of cursor 
  2741.         yPos = (short)HIWORD(lParam);  // vertical position of cursor 
  2742.         
  2743.         Texture_MouseUp (xPos, yPos - g_nTextureOffset, wParam);
  2744.         if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
  2745.             ReleaseCapture ();
  2746.         return 0;
  2747.  
  2748.     case WM_MOUSEMOVE:
  2749.         xPos = (short)LOWORD(lParam);  // horizontal position of cursor 
  2750.         yPos = (short)HIWORD(lParam);  // vertical position of cursor 
  2751.         
  2752.         Texture_MouseMoved (xPos, yPos - g_nTextureOffset, wParam);
  2753.         return 0;
  2754.     }
  2755.  
  2756.     return DefWindowProc (hWnd, uMsg, wParam, lParam);
  2757. }
  2758.  
  2759.  
  2760.  
  2761. BOOL CTexWnd::PreCreateWindow(CREATESTRUCT& cs) 
  2762. {
  2763.   WNDCLASS wc;
  2764.   HINSTANCE hInstance = AfxGetInstanceHandle();
  2765.   if (::GetClassInfo(hInstance, TEXTURE_WINDOW_CLASS, &wc) == FALSE)
  2766.   {
  2767.     // Register a new class
  2768.       memset (&wc, 0, sizeof(wc));
  2769.     wc.style         = CS_NOCLOSE | CS_OWNDC;
  2770.     wc.lpszClassName = TEXTURE_WINDOW_CLASS;
  2771.     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
  2772.     wc.lpfnWndProc = TexWndProc;
  2773.     if (AfxRegisterClass(&wc) == FALSE)
  2774.       Error ("CZWnd RegisterClass: failed");
  2775.   }
  2776.  
  2777.   cs.lpszClass = TEXTURE_WINDOW_CLASS;
  2778.   cs.lpszName = "TEX";
  2779.   if (cs.style != QE3_CHILDSTYLE && cs.style != QE3_STYLE)
  2780.     cs.style = QE3_SPLITTER_STYLE;
  2781.  
  2782.     return CWnd::PreCreateWindow(cs);
  2783. }
  2784.  
  2785. int CTexWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  2786. {
  2787.     if (CWnd::OnCreate(lpCreateStruct) == -1)
  2788.         return -1;
  2789.  
  2790.   CRect rctEdit(8, 5, 20, 20);
  2791.   g_nTextureOffset = 0;
  2792.  
  2793. /*
  2794.   if (g_PrefsDlg.m_bShaderTest)
  2795.   {
  2796.     m_wndShaders.Create("Show Shaders", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, rctEdit, this, 1200);
  2797.     m_wndShaders.ModifyStyleEx(0, WS_EX_CLIENTEDGE, 0);
  2798.     m_wndShaders.SetCheck(g_PrefsDlg.m_bShowShaders);
  2799.     g_nTextureOffset = 25;
  2800.   }
  2801. */
  2802.   rctEdit.SetRect(8, g_nTextureOffset, 20, 20);
  2803.   m_wndFilter.Create(WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT, rctEdit, this, 1201);
  2804.   m_wndFilter.ModifyStyleEx(0, WS_EX_CLIENTEDGE, 0);
  2805.   m_wndFilter.SetTexWnd(this);
  2806.  
  2807.   g_nTextureOffset += 25;
  2808.   if (!g_PrefsDlg.m_bTextureWindow)
  2809.   {
  2810.     m_wndFilter.ShowWindow(SW_HIDE);
  2811.     g_nTextureOffset -= 25;
  2812.   }
  2813.  
  2814.   ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar);
  2815.   m_bNeedRange = true;
  2816.  
  2817.     return 0;
  2818. }
  2819.  
  2820. void CTexWnd::OnSize(UINT nType, int cx, int cy) 
  2821. {
  2822.     CWnd::OnSize(nType, cx, cy);
  2823.   CRect rctClient;
  2824.   GetClientRect(rctClient);
  2825. /*
  2826.   if (g_PrefsDlg.m_bShaderTest && m_wndShaders.GetSafeHwnd())
  2827.   {
  2828.     m_wndShaders.SetWindowPos(NULL, rctClient.left + 8, rctClient.top + 5, rctClient.right - 16, 20, 0);
  2829.   }
  2830. */
  2831.   m_wndFilter.SetWindowPos(NULL, rctClient.left + 8, rctClient.top + 25, rctClient.right - 16, 20, 0);
  2832.   m_bNeedRange = true;
  2833. }
  2834.  
  2835. void CTexWnd::OnShaderClick()
  2836. {
  2837.   g_PrefsDlg.m_bShowShaders = (m_wndShaders.GetCheck() != 0);
  2838.   g_PrefsDlg.SavePrefs();
  2839.     RedrawWindow();
  2840. }
  2841.  
  2842. void CTexWnd::OnParentNotify(UINT message, LPARAM lParam) 
  2843. {
  2844.     CWnd::OnParentNotify(message, lParam);
  2845. }
  2846.  
  2847. int g_nLastLen = 0;
  2848. int g_nTimerHandle = -1;
  2849. char g_cLastChar;
  2850.  
  2851. void CTexWnd::UpdateFilter(const char* pFilter)
  2852. {
  2853.   if (g_nTimerHandle > 0)
  2854.     KillTimer(1);
  2855.   g_bFilterEnabled = false;
  2856.   if (pFilter)
  2857.   {
  2858.     g_strFilter = pFilter;
  2859.     if (g_strFilter.GetLength() > 0)
  2860.     {
  2861.       g_bFilterEnabled = true;
  2862.       if (g_pParentWnd->CurrentStyle() == QR_QE4 || g_pParentWnd->CurrentStyle() == QR_4WAY)
  2863.       {
  2864.         if (g_strFilter.GetLength() > g_nLastLen)
  2865.         {
  2866.           g_cLastChar = toupper(g_strFilter.GetAt(g_strFilter.GetLength()-1));
  2867.           if (g_cLastChar == 'N' || g_cLastChar == 'O') // one of the other popups
  2868.           {
  2869.             g_nTimerHandle = SetTimer(1, 800, NULL);   // half second timer
  2870.           }
  2871.         }
  2872.       }
  2873.     }
  2874.     g_nLastLen = g_strFilter.GetLength();
  2875.       SortTextures();
  2876.   }
  2877.   Sys_UpdateWindows (W_TEXTURE);
  2878. }
  2879.  
  2880. void CTexWnd::UpdatePrefs()
  2881. {
  2882.   if (!g_PrefsDlg.m_bTextureWindow)
  2883.   {
  2884.     m_wndFilter.ShowWindow(SW_HIDE);
  2885.     g_nTextureOffset = 0;
  2886.   }
  2887.   else
  2888.   {
  2889.     m_wndFilter.ShowWindow(SW_SHOW);
  2890.     g_nTextureOffset = 25;
  2891.   }
  2892.   ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar);
  2893.   m_bNeedRange = true;
  2894.   Invalidate();
  2895.   UpdateWindow();
  2896. }
  2897.  
  2898. void CTexWnd::FocusEdit()
  2899. {
  2900.   if (m_wndFilter.IsWindowVisible())
  2901.     m_wndFilter.SetFocus();
  2902. }
  2903.  
  2904. void CTexWnd::OnTimer(UINT nIDEvent) 
  2905. {
  2906.   KillTimer(1);
  2907.   g_nLastLen = 0;
  2908.   g_nTimerHandle = -1;
  2909.   ::SetFocus(g_qeglobals.d_hwndEntity);
  2910.   ::PostMessage(g_qeglobals.d_hwndEntity, WM_CHAR, g_cLastChar, 0);
  2911. }
  2912.  
  2913. void CTexWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  2914. {
  2915.   g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
  2916.     //CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  2917. }
  2918.  
  2919. void CTexWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  2920. {
  2921.   g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false);
  2922. }
  2923.  
  2924. void CTexWnd::OnPaint() 
  2925. {
  2926.     CPaintDC dc(this); // device context for painting
  2927.   CRect rctClient;
  2928.   GetClientRect(rctClient);
  2929.   int nOld = g_qeglobals.d_texturewin.m_nTotalHeight;
  2930.   if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
  2931.   //if ( !qwglMakeCurrent(dc.m_hDC, s_hglrcTexture ) )
  2932.   {
  2933.     Sys_Printf("ERROR: wglMakeCurrent failed..\n ");
  2934.     Sys_Printf("Please restart Q3Radiant if the Texture view is not working\n");
  2935.   }
  2936.   else
  2937.   {
  2938.     Texture_Draw2 (rctClient.right-rctClient.left, rctClient.bottom-rctClient.top - g_nTextureOffset);
  2939.         qwglSwapBuffers(s_hdcTexture);
  2940.     TRACE("Texture Paint\n");
  2941.   }
  2942.   if (g_PrefsDlg.m_bTextureScrollbar && (m_bNeedRange || g_qeglobals.d_texturewin.m_nTotalHeight != nOld))
  2943.   {
  2944.     m_bNeedRange = false;
  2945.     SetScrollRange(SB_VERT, 0, g_qeglobals.d_texturewin.m_nTotalHeight, TRUE);
  2946.   }
  2947. }
  2948.  
  2949. void CTexWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  2950. {
  2951.     CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
  2952.  
  2953.   int n = GetScrollPos(SB_VERT);;
  2954.   switch (nSBCode)
  2955.   {
  2956.     case SB_LINEUP :
  2957.     {
  2958.       n = (n - 15 >  0) ? n - 15 : 0; 
  2959.       break;
  2960.     }
  2961.     case SB_LINEDOWN :
  2962.     {
  2963.       n = (n + 15 < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + 15 : n; 
  2964.       break;
  2965.     }
  2966.     case SB_PAGEUP :
  2967.     {
  2968.       n = (n - g_qeglobals.d_texturewin.height >  0) ? n - g_qeglobals.d_texturewin.height : 0; 
  2969.       break;
  2970.     }
  2971.     case SB_PAGEDOWN :
  2972.     {
  2973.       n = (n + g_qeglobals.d_texturewin.height < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + g_qeglobals.d_texturewin.height : n; 
  2974.       break;
  2975.     }
  2976.     case SB_THUMBPOSITION :
  2977.     {
  2978.       n = nPos;
  2979.       break;
  2980.     }
  2981.     case SB_THUMBTRACK :
  2982.     {
  2983.       n = nPos;
  2984.       break;
  2985.     }
  2986.   }
  2987.   SetScrollPos(SB_VERT, n);
  2988.     g_qeglobals.d_texturewin.originy = -((int)n);
  2989.   Invalidate();
  2990.   UpdateWindow();
  2991.   //Sys_UpdateWindows(W_TEXTURE);
  2992. }
  2993.  
  2994. /*
  2995. 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
  2996. */
  2997.  
  2998. void CTexWnd::OnTexturesFlush() 
  2999. {
  3000.     // TODO: Add your command handler code here
  3001.     
  3002. }
  3003.  
  3004. void LoadShaders()
  3005. {
  3006.     char    dirstring[1024];
  3007.     char    *path;
  3008.     //struct _finddata_t fileinfo;
  3009.     //int        handle;
  3010.   path = ValueForKey (g_qeglobals.d_project_entity, "basepath");
  3011.   sprintf (dirstring, "%s/scripts/shaderlist.txt", path);
  3012.   char *pBuff = NULL;
  3013.   
  3014.   int nLen = LoadFile(dirstring, reinterpret_cast<void**>(&pBuff));
  3015.   if (nLen == -1)
  3016.   {
  3017.     nLen = PakLoadAnyFile(dirstring, reinterpret_cast<void**>(&pBuff));
  3018.   }
  3019.   if (nLen > 0)
  3020.   {
  3021.     CStringList lst;
  3022.     StartTokenParsing(pBuff);
  3023.     nLen = 0;
  3024.     while (GetToken(true))
  3025.     {
  3026.       // each token should be a shader filename
  3027.       sprintf(dirstring, "%s/scripts/%s.shader", path, token);
  3028.       lst.AddTail(dirstring);
  3029.       nLen++;
  3030.     }
  3031.     POSITION pos = lst.GetHeadPosition();
  3032.     while (pos != NULL)
  3033.     {
  3034.       LoadShader(lst.GetAt(pos).GetBuffer(0), NULL);
  3035.       lst.GetNext(pos);
  3036.     }
  3037.     free(pBuff);
  3038.   }
  3039.   else
  3040.   {
  3041.     Sys_Printf("Unable to load shaderlist.txt, shaders not loaded!");
  3042.   }
  3043.  
  3044. /*
  3045.   handle = _findfirst (dirstring, &fileinfo);
  3046.   if (handle != -1)
  3047.   {
  3048.     do
  3049.     {
  3050.       if ((fileinfo.attrib & _A_SUBDIR))
  3051.         continue;
  3052.       sprintf(dirstring, "%s/scripts/%s", path, fileinfo.name);
  3053.       LoadShader(dirstring, NULL);
  3054.       } while (_findnext( handle, &fileinfo ) != -1);
  3055.  
  3056.       _findclose (handle);
  3057.   }
  3058. */
  3059. }
  3060.  
  3061. void FreeShaders()
  3062. {
  3063.   int nSize = g_lstShaders.GetSize();
  3064.   for (int i = 0; i < nSize; i++)
  3065.   {
  3066.     CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i));
  3067.     delete pInfo;
  3068.   }
  3069.  
  3070.   g_lstShaders.RemoveAll();
  3071. }
  3072.  
  3073. void ReloadShaders()
  3074. {
  3075.   FreeShaders();
  3076.   LoadShaders();
  3077.   qtexture_t* pTex = g_qeglobals.d_qtextures;
  3078.   while (pTex != NULL)
  3079.   {
  3080.     SetNameShaderInfo(pTex, NULL, pTex->name);
  3081.     pTex = pTex->next;
  3082.   }
  3083.  
  3084. }
  3085.  
  3086. int WINAPI Texture_LoadSkin(char *pName, int *pnWidth, int *pnHeight)
  3087. {
  3088.   byte *pic = NULL;
  3089.   byte *pic32 = NULL;
  3090.   int nTex = -1;
  3091.  
  3092.   strlwr(pName);
  3093.   QE_ConvertDOSToUnixName(pName, pName);
  3094.  
  3095.   int nSize = g_lstSkinCache.GetSize();
  3096.   for (int i = 0; i < nSize; i++)
  3097.   {
  3098.     SkinInfo *pInfo = reinterpret_cast<SkinInfo*>(g_lstSkinCache.GetAt(i));
  3099.     if (pInfo)
  3100.     {
  3101.       if (stricmp(pName, pInfo->m_strName) == 0)
  3102.       {
  3103.         return pInfo->m_nTextureBind;
  3104.       }
  3105.     }
  3106.   }
  3107.  
  3108.   LoadImage( pName, &pic32, pnWidth, pnHeight);
  3109.   if (pic32 != NULL)
  3110.   {
  3111.  
  3112.     nTex = texture_extension_number++;
  3113.     if (g_PrefsDlg.m_bSGIOpenGL)
  3114.     {
  3115.       //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
  3116.       if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
  3117.             Error ("wglMakeCurrent in LoadTexture failed");
  3118.     }
  3119.  
  3120.     qglBindTexture( GL_TEXTURE_2D, nTex);
  3121.     SetTexParameters ();
  3122.  
  3123.       int nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality;
  3124.       while (nCount-- > 0)
  3125.       {
  3126.         if (*pnWidth > 16 && *pnHeight > 16)
  3127.         {
  3128.           R_MipMap(pic32, *pnWidth, *pnHeight);
  3129.         }
  3130.         else
  3131.         {
  3132.           break;
  3133.         }
  3134.       }
  3135.  
  3136.     if (g_PrefsDlg.m_bSGIOpenGL)
  3137.     {
  3138.         if (nomips)
  3139.       {
  3140.             qglTexImage2D(GL_TEXTURE_2D, 0, 3, *pnWidth, *pnHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pic32);
  3141.       }
  3142.         else
  3143.             qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, *pnWidth, *pnHeight,GL_RGBA, GL_UNSIGNED_BYTE, pic32);
  3144.     }
  3145.     else
  3146.     {
  3147.         if (nomips)
  3148.             qglTexImage2D(GL_TEXTURE_2D, 0, 3, *pnWidth, *pnHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pic32);
  3149.         else
  3150.             qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, *pnWidth, *pnHeight,GL_RGBA, GL_UNSIGNED_BYTE, pic32);
  3151.     }
  3152.       free (pic32);
  3153.       qglBindTexture( GL_TEXTURE_2D, 0 );
  3154.   }
  3155.  
  3156.   SkinInfo *pInfo = new SkinInfo(pName, nTex);
  3157.   g_lstSkinCache.Add(pInfo);
  3158.  
  3159.   return nTex;
  3160. }
  3161.  
  3162.  
  3163.