heretic2-sdk/Toolkit/Programming/Tools/qe4/textures.c
1998-11-24 00:00:00 +00:00

2018 lines
No EOL
46 KiB
C

#include "qe3.h"
#include "io.h"
#define TYP_MIPTEX 68
static unsigned tex_palette[256];
static qtexture_t *notexture;
static qboolean nomips;
#define FONT_HEIGHT 10
static HGLRC s_hglrcTexture;
static HDC s_hdcTexture;
//int texture_mode = GL_NEAREST;
//int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
//int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
//int texture_mode = GL_LINEAR;
//int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
int texture_extension_number = 1;
// current active texture directory. if empty, show textures in use
char texture_directory[32]; // use if texture_showinuse is false
qboolean texture_showinuse;
// texture layout functions
qtexture_t *current_texture;
int current_x, current_y, current_row;
int texture_nummenus;
#define MAX_TEXTUREDIRS 100
char texture_menunames[MAX_TEXTUREDIRS][64];
qboolean g_dontuse; // set to true to load the texture but not flag as used
void SelectTexture (int mx, int my);
void Texture_MouseDown (int x, int y, int buttons);
void Texture_MouseUp (int x, int y, int buttons);
void Texture_MouseMoved (int x, int y, int buttons);
//=====================================================
void SortTextures(void)
{
qtexture_t *q, *qtemp, *qhead, *qcur, *qprev;
// standard insertion sort
// Take the first texture from the list and
// add it to our new list
if ( g_qeglobals.d_qtextures == NULL)
return;
qhead = g_qeglobals.d_qtextures;
q = g_qeglobals.d_qtextures->next;
qhead->next = NULL;
// while there are still things on the old
// list, keep adding them to the new list
while (q)
{
qtemp = q;
q = q->next;
qprev = NULL;
qcur = qhead;
while (qcur)
{
// Insert it here?
if (strcmp(qtemp->name, qcur->name) < 0)
{
qtemp->next = qcur;
if (qprev)
qprev->next = qtemp;
else
qhead = qtemp;
break;
}
// Move on
qprev = qcur;
qcur = qcur->next;
// is this one at the end?
if (qcur == NULL)
{
qprev->next = qtemp;
qtemp->next = NULL;
}
}
}
g_qeglobals.d_qtextures = qhead;
}
/*
============================================================================
SCROLLBAR UPDATE AND RESPONSE
============================================================================
*/
void Texture_SetScrollRange (void)
{
qtexture_t *q, *curtex;
int done;
int curx, cury, currow;
//start at the top
curtex = g_qeglobals.d_qtextures;
curx = 8;
cury = -12 - FONT_HEIGHT;
currow = 0;
//go thru all the textures and figure out how tall the whole list is
done = false;
while (curtex)
{
while (1)
{
q = curtex;
if (!q)
done = true;
else
{
curtex = curtex->next;
if (q->name[0] == '(') // fake color texture
continue;
if (q->inuse)
break; // allways show in use
if (!texture_showinuse && strncmp (q->name, texture_directory, strlen(texture_directory)))
continue;
}
break;
}
if (!done)
{
if (curx + q->width > g_qeglobals.d_texturewin.width-8 && currow)
{ // go to the next row unless the texture is the first on the row
curx = 8;
cury -= currow + FONT_HEIGHT + 4;
currow = 0;
}
// Is our texture larger than the row? If so, grow the
// row height to match it
if (currow < q->height)
currow = q->height;
// never go less than 64, or the names get all crunched up
curx += q->width < 64 ? 64 : q->width;
curx += 8;
}
}
g_qeglobals.d_texturewin.scrollheight = -cury + currow - g_qeglobals.d_texturewin.height;
SetScrollRange(g_qeglobals.d_hwndTexture, SB_VERT, 0,
g_qeglobals.d_texturewin.scrollheight, true);
}
void Texture_SetScrollPos (void)
{
SetScrollPos(g_qeglobals.d_hwndTexture, SB_VERT, -g_qeglobals.d_texturewin.originy, true);
}
void Texture_ScrollLine (int ydown)
{
g_qeglobals.d_texturewin.originy += ydown;
if (g_qeglobals.d_texturewin.originy > 0)
{
g_qeglobals.d_texturewin.originy = 0;
}
if (g_qeglobals.d_texturewin.originy < -g_qeglobals.d_texturewin.scrollheight)
{
g_qeglobals.d_texturewin.originy = -g_qeglobals.d_texturewin.scrollheight;
}
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
}
void Texture_ScrollRow (int ydown)//warning: i only plan on making this work for values of 1 & -1 --ss
{
qtexture_t *q, *curtex;
int done;
int curx, cury, currow, lastrow;
//start at the top
curtex = g_qeglobals.d_qtextures;
curx = 8;
cury = 0;//to make the textures above top row not peek down at top of window, set this to -8 initially
//(it's set to 0 to let you go to very top of window with scrollbar arrows)
currow = 0;
//go thru all the textures until we find the row we want to scroll past
done = false;
lastrow = 0;
while (curtex && !done)
{
while (1)
{
q = curtex;
if (!q)
done = true;
else
{
curtex = curtex->next;
if (q->name[0] == '(') // fake color texture
continue;
if (q->inuse)
break; // allways show in use
if (!texture_showinuse && strncmp (q->name, texture_directory, strlen(texture_directory)))
continue;
}
break;
}
if (!done)
{
if (curx + q->width > g_qeglobals.d_texturewin.width-8 && currow)
{ // go to the next row unless the texture is the first on the row
curx = 8;
if ((ydown > 0) && lastrow)//want to scroll down--set origin to cury + the last row
{
if (cury > g_qeglobals.d_texturewin.originy)
g_qeglobals.d_texturewin.originy = cury;
else
g_qeglobals.d_texturewin.originy = cury+lastrow+FONT_HEIGHT+4;
done = true;
}
else if ((ydown < 0)&&lastrow)//want to scroll up--set origin to cury
{
if (cury < g_qeglobals.d_texturewin.originy)
g_qeglobals.d_texturewin.originy = cury;
else
g_qeglobals.d_texturewin.originy = cury-currow-FONT_HEIGHT-4;
done = true;
}
else
{
cury -= currow + FONT_HEIGHT + 4;
// Is this texture visible?
if ( (cury-q->height-FONT_HEIGHT < g_qeglobals.d_texturewin.originy)
&& (cury > g_qeglobals.d_texturewin.originy - g_qeglobals.d_texturewin.height) )
{
lastrow = currow;
}
}
if (!done)
{
currow = 0;
}
}
// Is our texture larger than the row? If so, grow the
// row height to match it
if (currow < q->height)
currow = q->height;
// never go less than 64, or the names get all crunched up
curx += q->width < 64 ? 64 : q->width;
curx += 8;
}
}
if (g_qeglobals.d_texturewin.originy > 0)
g_qeglobals.d_texturewin.originy = 0;
if (g_qeglobals.d_texturewin.originy < -g_qeglobals.d_texturewin.scrollheight)
g_qeglobals.d_texturewin.originy = -g_qeglobals.d_texturewin.scrollheight;
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
}
void Texture_ScrollPage (int ydown)//warning: i only plan on making this work for values of 1 & -1 --ss
{
qtexture_t *q, *curtex;
int done;
int curx, cury, currow, lastrow, curscroll;
int pagedone, hasscrolled, totalscrolled;
pagedone = false;
hasscrolled = false;
totalscrolled = 0;
if (!g_qeglobals.d_qtextures)
return; //JFM: stop the madness
while ((!pagedone) || (!hasscrolled))
{
//start at the top
curtex = g_qeglobals.d_qtextures;
curx = 8;
cury = 0;//to make the textures above top row not peek down at top of window, set this to -8 initially
//(it's set to 0 to let you go to very top of window with scrollbar arrows)
currow = 0;
//go thru all the textures until we find the row we want to scroll past
done = false;
lastrow = 0;
while (curtex && !done)
{
while (1)
{
q = curtex;
if (!q)
{
pagedone = true;
hasscrolled = true;
done = true;
}
else
{
curtex = curtex->next;
if (q->name[0] == '(') // fake color texture
continue;
if (q->inuse)
break; // allways show in use
if (!texture_showinuse && strncmp (q->name, texture_directory, strlen(texture_directory)))
continue;
}
break;
}
if (!done)
{
if (curx + q->width > g_qeglobals.d_texturewin.width-8 && currow)
{ // go to the next row unless the texture is the first on the row
curx = 8;
if ((ydown > 0) && lastrow)//want to scroll down--set origin to cury + the last row
{
if (cury > g_qeglobals.d_texturewin.originy)
{
curscroll = cury - g_qeglobals.d_texturewin.originy;
}
else
{
curscroll = cury + lastrow + FONT_HEIGHT + 4 - g_qeglobals.d_texturewin.originy;
}
if ((hasscrolled)&&(totalscrolled + curscroll > g_qeglobals.d_texturewin.height))
{//hey, if i scroll any more, all prev. lines will go totally off the screen, so stop
pagedone = true;
}
else
{//can still safely scroll some more, so do it
g_qeglobals.d_texturewin.originy += curscroll;
totalscrolled += curscroll;
if (g_qeglobals.d_texturewin.originy > -5)//oop, that was the last one
{
pagedone = true;
}
}
hasscrolled = true;
done = true;
}
else if ((ydown < 0)&&lastrow)//want to scroll up--set origin to cury
{
if (cury < g_qeglobals.d_texturewin.originy)
{
curscroll = g_qeglobals.d_texturewin.originy - cury;
}
else
{
curscroll = /*g_qeglobals.d_texturewin.originy - cury +*/ lastrow + FONT_HEIGHT + 4;
}
if ((hasscrolled)&&((totalscrolled + curscroll) > g_qeglobals.d_texturewin.height))
{//hey, if i scroll any more, all prev. lines will go totally off the screen, so stop
pagedone = true;
}
else
{//can still safely scroll some more, so do it
g_qeglobals.d_texturewin.originy -= curscroll;
totalscrolled += curscroll;
if (g_qeglobals.d_texturewin.originy < -g_qeglobals.d_texturewin.scrollheight+5)//oop, that was the last one
// -g_qeglobals.d_texturewin.scrollheight+5 caused the program to crash... ^^ this is a temp. hack fix
{
pagedone = true;
}
}
hasscrolled = true;
done = true;
}
/* {
pagedone = true;
hasscrolled = true;
if (cury < g_qeglobals.d_texturewin.originy)
{
g_qeglobals.d_texturewin.originy = cury;
}
else
{
g_qeglobals.d_texturewin.originy = cury-currow-FONT_HEIGHT-4;
}
done = true;
}
*/ else
{
cury -= currow + FONT_HEIGHT + 4;
// Is this texture visible?
if ( (cury-q->height-FONT_HEIGHT < g_qeglobals.d_texturewin.originy)
&& (cury > g_qeglobals.d_texturewin.originy - g_qeglobals.d_texturewin.height) )
{
lastrow = currow;
}
}
if (!done)
{
currow = 0;
}
}
// Is our texture larger than the row? If so, grow the
// row height to match it
if (currow < q->height)
{
currow = q->height;
}
// never go less than 64, or the names get all crunched up
curx += q->width < 64 ? 64 : q->width;
curx += 8;
}
}
if (g_qeglobals.d_texturewin.originy > 0)
g_qeglobals.d_texturewin.originy = 0;
if (g_qeglobals.d_texturewin.originy < -g_qeglobals.d_texturewin.scrollheight)
g_qeglobals.d_texturewin.originy = -g_qeglobals.d_texturewin.scrollheight;
}
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
}
void Texture_ScrollTo (int pos)
{
g_qeglobals.d_texturewin.originy = pos;
if (g_qeglobals.d_texturewin.originy > 0)
g_qeglobals.d_texturewin.originy = 0;
if (g_qeglobals.d_texturewin.originy < -g_qeglobals.d_texturewin.scrollheight)
g_qeglobals.d_texturewin.originy = -g_qeglobals.d_texturewin.scrollheight;
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
}
//=====================================================
/*
==============
Texture_InitPalette
==============
*/
void Texture_InitPalette (byte *pal)
{
int r,g,b,v;
int i;
int inf;
byte gammatable[256];
float gamma;
gamma = g_qeglobals.d_savedinfo.fGamma;
if (gamma == 1.0)
{
for (i=0 ; i<256 ; i++)
gammatable[i] = i;
}
else
{
for (i=0 ; i<256 ; i++)
{
inf = 255 * pow ( (i+0.5)/255.5 , gamma ) + 0.5;
if (inf < 0)
inf = 0;
if (inf > 255)
inf = 255;
gammatable[i] = inf;
}
}
for (i=0 ; i<256 ; i++)
{
r = gammatable[pal[0]];
g = gammatable[pal[1]];
b = gammatable[pal[2]];
pal += 3;
v = (r<<24) + (g<<16) + (b<<8) + 255;
v = BigLong (v);
tex_palette[i] = v;
}
}
void SetTexParameters (void)
{
switch ( texture_mode )
{
case GL_NEAREST:
case GL_NEAREST_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
break;
case GL_LINEAR:
case GL_LINEAR_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_LINEAR:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
break;
}
}
/*
============
Texture_SetMode
============
*/
void Texture_SetMode(int iMenu)
{
int i, iMode;
HMENU hMenu;
qboolean texturing = true;
hMenu = GetMenu(g_qeglobals.d_hwndMain);
switch(iMenu) {
case ID_VIEW_NEAREST:
iMode = GL_NEAREST;
break;
case ID_VIEW_NEARESTMIPMAP:
iMode = GL_NEAREST_MIPMAP_NEAREST;
break;
case ID_VIEW_LINEAR:
iMode = GL_NEAREST_MIPMAP_LINEAR;
break;
case ID_VIEW_BILINEAR:
iMode = GL_LINEAR;
break;
case ID_VIEW_BILINEARMIPMAP:
iMode = GL_LINEAR_MIPMAP_NEAREST;
break;
case ID_VIEW_TRILINEAR:
iMode = GL_LINEAR_MIPMAP_LINEAR;
break;
case ID_TEXTURES_WIREFRAME:
iMode = 0;
texturing = false;
break;
case ID_TEXTURES_FLATSHADE:
iMode = 0;
texturing = false;
break;
}
CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED);
g_qeglobals.d_savedinfo.iTexMenu = iMenu;
texture_mode = iMode;
if ( texturing )
SetTexParameters ();
if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME)
{
camera.draw_mode = cd_wire;
Map_BuildBrushData(false);
Sys_UpdateWindows (W_ALL);
return;
} else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) {
camera.draw_mode = cd_solid;
Map_BuildBrushData(false);
Sys_UpdateWindows (W_ALL);
return;
}
for (i=1 ; i<texture_extension_number ; i++)
{
glBindTexture( GL_TEXTURE_2D, i );
SetTexParameters ();
}
// select the default texture
glBindTexture( GL_TEXTURE_2D, 0 );
glFinish();
if (camera.draw_mode != cd_texture)
{
camera.draw_mode = cd_texture;
Map_BuildBrushData(false);
}
Sys_UpdateWindows (W_ALL);
}
/*
=================
Texture_LoadTexture
=================
*/
qtexture_t *Texture_LoadTexture (miptex_t *qtex)
{
byte *source;
unsigned *dest;
int width, height, i, count;
int total[3];
qtexture_t *q;
q = qmalloc(sizeof(*q));
width = LittleLong(qtex->width[0]);
height = LittleLong(qtex->height[0]);
q->width = width;
q->height = height;
q->flags = qtex->flags;
q->value = qtex->value;
q->contents = qtex->contents;
q->scale_x = 1.0;
q->scale_y = 1.0;
dest = qmalloc (width*height*4);
count = width*height;
source = (byte *)qtex + LittleLong(qtex->offsets[0]);
// The dib is upside down so we want to copy it into
// the buffer bottom up.
total[0] = total[1] = total[2] = 0;
for (i=0 ; i<count ; i++)
{
dest[i] = qtex->palette[source[i]].b;
dest[i] <<= 8;
dest[i] += qtex->palette[source[i]].g;
dest[i] <<= 8;
dest[i] += qtex->palette[source[i]].r;
total[0] += ((byte *)(dest+i))[0];
total[1] += ((byte *)(dest+i))[1];
total[2] += ((byte *)(dest+i))[2];
}
q->color[0] = (float)total[0]/(count*255);
q->color[1] = (float)total[1]/(count*255);
q->color[2] = (float)total[2]/(count*255);
q->texture_number = texture_extension_number++;
glBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
if (nomips)
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
free (dest);
glBindTexture( GL_TEXTURE_2D, 0 );
return q;
}
/*
=================
Texture_LoadTexture
=================
*/
qtexture_t *Texture_LoadTexture32 (miptex32_t *qtex)
{
unsigned *source;
unsigned *dest;
int width, height, i, count;
int total[3];
qtexture_t *q;
if (qtex->version != MIP32_VERSION)
{
return NULL;
}
q = qmalloc(sizeof(*q));
width = LittleLong(qtex->width[0]);
height = LittleLong(qtex->height[0]);
q->width = width;
q->height = height;
q->flags = qtex->flags;
q->value = qtex->value;
q->contents = qtex->contents;
q->scale_x = qtex->scale_x;
q->scale_y = qtex->scale_y;
dest = qmalloc (width*height*4);
count = width*height;
source = (unsigned *)((byte *)qtex + LittleLong(qtex->offsets[0]));
// The dib is upside down so we want to copy it into
// the buffer bottom up.
total[0] = total[1] = total[2] = 0;
for (i=0 ; i<count ; i++)
{
dest[i] = source[i];
total[0] += ((byte *)(dest+i))[0];
total[1] += ((byte *)(dest+i))[1];
total[2] += ((byte *)(dest+i))[2];
}
q->color[0] = (float)total[0]/(count*255);
q->color[1] = (float)total[1]/(count*255);
q->color[2] = (float)total[2]/(count*255);
q->texture_number = texture_extension_number++;
glBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
if (nomips)
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
free (dest);
glBindTexture( GL_TEXTURE_2D, 0 );
return q;
}
/*
===============
Texture_CreateSolid
Create a single pixel texture of the apropriate color
===============
*/
qtexture_t *Texture_CreateSolid (char *name)
{
byte data[4];
qtexture_t *q;
q = qmalloc(sizeof(*q));
sscanf (name, "(%f %f %f)", &q->color[0], &q->color[1], &q->color[2]);
data[0] = q->color[0]*255;
data[1] = q->color[1]*255;
data[2] = q->color[2]*255;
data[3] = 255;
q->width = q->height = 1;
q->texture_number = texture_extension_number++;
glBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
q->scale_x = 1.0;
q->scale_y = 1.0;
if (nomips)
glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture( GL_TEXTURE_2D, 0 );
return q;
}
/*
=================
Texture_MakeNotexture
=================
*/
void Texture_MakeNotexture (void)
{
qtexture_t *q;
byte data[4][4];
notexture = q = qmalloc(sizeof(*q));
strcpy (q->name, "notexture");
q->width = q->height = 64;
memset (data, 0, sizeof(data));
data[0][2] = data[3][2] = 255;
q->color[0] = 0;
q->color[1] = 0;
q->color[2] = 0.5;
q->scale_x = 1.0;
q->scale_y = 1.0;
q->texture_number = texture_extension_number++;
glBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
if (nomips)
glTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture( GL_TEXTURE_2D, 0 );
}
/*
===============
Texture_ForName
===============
*/
qtexture_t *Texture_ForName (char *name)
{
byte *lump;
qtexture_t *q = NULL;
char filename[1024];
//return notexture;
for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
{
if (!strcmp(name, q->name))
{
if (!g_dontuse)
q->inuse = true;
return q;
}
}
if (name[0] == '(')
{
q = Texture_CreateSolid (name);
strncpy (q->name, name, sizeof(q->name)-1);
}
else
{
// load the file
sprintf (filename, "%s/%s.m32",
ValueForKey (g_qeglobals.d_project_entity, "texturepath"),
name);
if (TryLoadFile (filename, &lump) == -1)
{
sprintf (filename, "%s/%s.m8",
ValueForKey (g_qeglobals.d_project_entity, "texturepath"),
name);
if (TryLoadFile (filename, &lump) == -1)
{
Sys_Printf (" load failed for %s!\n", name);
return notexture;
}
Sys_Printf ("Loading %s\n", name);
q = Texture_LoadTexture ((miptex_t *)lump);
}
else
{
Sys_Printf ("Loading %s\n", name);
q = Texture_LoadTexture32 ((miptex32_t *)lump);
}
free (lump);
if (!q)
{
return q;
}
strncpy (q->name, name, sizeof(q->name)-1);
StripExtension (q->name);
}
if (!g_dontuse)
q->inuse = true;
q->next = g_qeglobals.d_qtextures;
g_qeglobals.d_qtextures = q;
return q;
}
/*
==================
FillTextureMenu
==================
*/
void FillTextureMenu (void)
{
HMENU hmenu;
int i;
struct _finddata_t fileinfo;
int handle;
char dirstring[1024];
char *path;
hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_TEXTURE);
// delete everything
for (i=0 ; i<texture_nummenus ; i++)
DeleteMenu (hmenu, CMD_TEXTUREWAD+i, MF_BYCOMMAND);
// add everything
path = ValueForKey (g_qeglobals.d_project_entity, "texturepath");
sprintf (dirstring, "%s/*.*", path);
handle = _findfirst (dirstring, &fileinfo);
if (handle == -1)
return;
do
{
if (!(fileinfo.attrib & _A_SUBDIR))
continue;
if (fileinfo.name[0] == '.')
continue;
// add this directory to the menu
AppendMenu (hmenu, MF_ENABLED|MF_STRING,
CMD_TEXTUREWAD+texture_nummenus, (LPCTSTR)fileinfo.name);
strcpy (texture_menunames[texture_nummenus], fileinfo.name);
strcat (texture_menunames[texture_nummenus], "/");
if (++texture_nummenus == MAX_TEXTUREDIRS)
break;
} while (_findnext( handle, &fileinfo ) != -1);
_findclose (handle);
}
/*
==================
Texture_ClearInuse
A new map is being loaded, so clear inuse markers
==================
*/
void Texture_ClearInuse (void)
{
qtexture_t *q;
for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
{
q->inuse = false;
}
}
/*
==============
Texture_ShowDirectory
==============
*/
void Texture_ShowDirectory (int menunum)
{
struct _finddata_t fileinfo;
int handle;
char name[1024];
char dirstring[1024];
texture_showinuse = false;
strcpy (texture_directory, texture_menunames[menunum-CMD_TEXTUREWAD]);
g_qeglobals.d_texturewin.originy = 0;
Sys_Status("loading all textures\n", 0);
// load all .wal files
sprintf (dirstring, "%s/textures/%s*.m*",
ValueForKey (g_qeglobals.d_project_entity, "basepath"),
texture_menunames[menunum-CMD_TEXTUREWAD]);
Sys_Printf ("Scanning %s\n", dirstring);
handle = _findfirst (dirstring, &fileinfo);
if (handle == -1)
return;
g_dontuse = true;
do
{
sprintf (name, "%s%s", texture_directory, fileinfo.name);
StripExtension (name);
Texture_ForName (name);
} while (_findnext( handle, &fileinfo ) != -1);
g_dontuse = false;
_findclose (handle);
SortTextures();
SetInspectorMode(W_TEXTURE);
Sys_UpdateWindows(W_TEXTURE);
Texture_SetScrollRange();
Texture_SetScrollPos();
sprintf (name, "Textures: %s", texture_directory);
SetWindowText(g_qeglobals.d_hwndEntity, name);
// select the first texture in the list
if (!g_qeglobals.d_texturewin.texdef.name[0])
SelectTexture (16, g_qeglobals.d_texturewin.height -16);
}
/*
==============
Texture_ShowInuse
==============
*/
void Texture_ShowInuse (void)
{
char name[1024];
face_t *f;
brush_t *b;
texture_showinuse = true;
g_qeglobals.d_texturewin.originy = 0;
Sys_Status("Selecting active textures\n", 0);
Texture_ClearInuse ();
for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next)
for (f=b->brush_faces ; f ; f=f->next)
Texture_ForName (f->texdef.name);
for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next)
for (f=b->brush_faces ; f ; f=f->next)
Texture_ForName (f->texdef.name);
SortTextures();
SetInspectorMode(W_TEXTURE);
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
sprintf (name, "Textures: in use");
SetWindowText(g_qeglobals.d_hwndEntity, name);
// select the first texture in the list
if (!g_qeglobals.d_texturewin.texdef.name[0])
SelectTexture (16, g_qeglobals.d_texturewin.height -16);
}
/*
===============
Texture_ListInUse
===============
*/
void Texture_ListInUse(void)
{
brush_t* b;
face_t* f;
texlist_t* texturelist; // the first texture name in the list
texlist_t* thistexture; // texture currently read in
texlist_t* curTexture; // texture in the list that we're working with
texlist_t* prevTexture; // texture prior to curTexture
texturelist = NULL;
SetInspectorMode(W_CONSOLE);
Sys_ClearPrintf();
Sys_Printf ("Textures in use:\n");
for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next)
{
for (f=b->brush_faces ; f ; f=f->next)
{
if (f->texdef.name[0] != '(') // we only want texture names, not entities
{
thistexture = malloc( sizeof(texlist_t));
if (thistexture == NULL)
{
Error("Not enough memory");
return;
}
thistexture->uses = 0;
thistexture->name[0] = '\0';
thistexture->prev = NULL;
thistexture->next = NULL;
strcpy(thistexture->name, f->texdef.name);
if (texturelist == NULL)
{
thistexture->uses++;
texturelist = thistexture; //put first member on list
}
else
{
curTexture = texturelist; // grab the list
prevTexture = curTexture->prev;
while (1)
{
if (curTexture->name == NULL) // end of list
{
thistexture->uses++;
thistexture->prev = prevTexture; // add texture on
prevTexture->next = thistexture;
break;
}
if (strcmp(thistexture->name,curTexture->name) == 0) // texture already on list
{
curTexture->uses++;
free (thistexture);
break;
}
if (strcmp(thistexture->name,curTexture->name) < 0) // texture belongs ahead of this one
{
if (prevTexture == NULL) // texture goes at front of list
{
thistexture->uses++;
thistexture->next = curTexture;
curTexture->prev = thistexture;
texturelist = thistexture; // list now starts here
}
else
{
thistexture->uses++;
thistexture->prev = curTexture->prev;
thistexture->next = curTexture;
curTexture->prev = thistexture;
prevTexture->next = thistexture;
}
break;
}
prevTexture = curTexture;
curTexture = curTexture->next; // advance to next texture in list
}
}
} // texture name
} // face
} // brush
for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next)
{
for (f=b->brush_faces ; f ; f=f->next)
{
if (f->texdef.name[0] != '(') // we only want texture names, not entities
{
thistexture = malloc( sizeof(texlist_t));
if (thistexture == NULL)
{
Error("Not enough memory");
return;
}
thistexture->uses = 0;
thistexture->name[0] = '\0';
thistexture->prev = NULL;
thistexture->next = NULL;
strcpy(thistexture->name, f->texdef.name);
if (texturelist == NULL)
{
thistexture->uses++;
texturelist = thistexture; //put first member on list
}
else
{
curTexture = texturelist; // grab the list
prevTexture = curTexture->prev;
while (1)
{
if (curTexture->name == NULL) // end of list
{
thistexture->uses++;
thistexture->prev = prevTexture; // add texture on
prevTexture->next = thistexture;
break;
}
if (strcmp(thistexture->name,curTexture->name) == 0) // texture already on list
{
curTexture->uses++;
free (thistexture);
break;
}
if (strcmp(thistexture->name,curTexture->name) < 0) // texture belongs ahead of this one
{
if (prevTexture == NULL) // texture goes at front of list
{
thistexture->uses++;
thistexture->next = curTexture;
curTexture->prev = thistexture;
texturelist = thistexture; // list now starts here
}
else
{
thistexture->uses++;
thistexture->prev = curTexture->prev;
thistexture->next = curTexture;
curTexture->prev = thistexture;
prevTexture->next = thistexture;
}
break;
}
prevTexture = curTexture;
curTexture = curTexture->next; // advance to next texture in list
}
}
} // texture name
} // face
} // brush
for (curTexture = texturelist; curTexture; curTexture=curTexture->next)
{
Sys_Printf("%s, Used on %d faces\n",curTexture->name, curTexture->uses);
}
while (texturelist != NULL)
{
curTexture = texturelist;
texturelist = curTexture->next;
free (curTexture);
}
}
/*
==============
Texture_Replace
==============
*/
// Start with world_enitity
void Texture_Replace(char *from, char *to, int replaceAll)
{
brush_t *b, *startBrush;
face_t *f, *startFace;
qtexture_t *curTex;
int foundTex = 0;
int i;
curTex = g_qeglobals.d_qtextures;
while(curTex && !foundTex)
{
if(!strcmpi(to, curTex->name))
{ // found it...
foundTex = 1;
}
else
{
curTex = curTex->next;
}
}
if(!foundTex)
{ // looks like the texture entered was invalid
return;
}
if(replaceAll)
{
b = world_entity->brushes.onext;
}
else
{
b = selected_brushes.next;
}
startBrush = b;
while(b != NULL)
{
// Search through the face linked list
f = b->brush_faces;
startFace = f;
while(f != NULL)
{
// check the stuff
if (!strcmpi(from, f->texdef.name))
{
// replace the things
memset (&f->texdef, 0, sizeof(f->texdef));
f->texdef.scale[0] = curTex->scale_x;
f->texdef.scale[1] = curTex->scale_y;
f->texdef.flags = curTex->flags;
f->texdef.value = curTex->value;
f->texdef.contents = curTex->contents;
f->texdef.lighting[0] = 1.0;
f->texdef.lighting[1] = 1.0;
f->texdef.lighting[2] = 1.0;
f->texdef.lighting[3] = 1.0;
strcpy (f->texdef.name, curTex->name);
}
f = f->next;
if(f == startFace)
{
f = NULL;
}
}
if(replaceAll)
{
b = b->onext;
}
else
{
b = b->next;
}
if(b == startBrush)
{
b = NULL; // hit the end of the circular list
}
}
// This is really pretty hacky. This ensures that the camera view is properly updated....
// Otherwise the textures don't get update (?)
if(camera.draw_mode == cd_texture)
{
camera.draw_mode = cd_solid;
Map_BuildBrushData(false);
Sys_UpdateWindows (W_ALL);
for (i=1 ; i<texture_extension_number ; i++)
{
glBindTexture( GL_TEXTURE_2D, i );
SetTexParameters ();
}
// select the default texture
glBindTexture( GL_TEXTURE_2D, 0 );
glFinish();
if (camera.draw_mode != cd_texture)
{
camera.draw_mode = cd_texture;
Map_BuildBrushData(false);
}
Sys_UpdateWindows (W_ALL);
}
}
/*
============================================================================
TEXTURE LAYOUT
============================================================================
*/
void Texture_StartPos (void)
{
current_texture = g_qeglobals.d_qtextures;
current_x = 8;
current_y = -8;
current_row = 0;
}
qtexture_t *Texture_NextPos (int *x, int *y)
{
qtexture_t *q;
while (1)
{
q = current_texture;
if (!q)
return q;
current_texture = current_texture->next;
if (q->name[0] == '(') // fake color texture
continue;
if (q->inuse)
break; // allways show in use
if (!texture_showinuse && strncmp (q->name, texture_directory, strlen(texture_directory)))
continue;
break;
}
if (current_x + q->width > g_qeglobals.d_texturewin.width-8 && current_row)
{ // go to the next row unless the texture is the first on the row
current_x = 8;
current_y -= current_row + FONT_HEIGHT + 4;
current_row = 0;
}
*x = current_x;
*y = current_y;
// Is our texture larger than the row? If so, grow the
// row height to match it
if (current_row < q->height)
current_row = q->height;
// never go less than 64, or the names get all crunched up
current_x += q->width < 64 ? 64 : q->width;
current_x += 8;
return q;
}
/*
============================================================================
MOUSE ACTIONS
============================================================================
*/
static int textures_cursorx, textures_cursory;
/*
============
Texture_SetTexture
============
*/
void Texture_SetTexture (texdef_t *texdef)
{
qtexture_t *q;
int x,y;
char sz[256];
if (texdef->name[0] == '(')
{
Sys_Status("Can't select an entity texture\n", 0);
return;
}
g_qeglobals.d_texturewin.prevTexDef = g_qeglobals.d_texturewin.texdef;
g_qeglobals.d_texturewin.texdef = *texdef;
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
sprintf(sz, "Selected texture: %s\n", texdef->name);
Sys_Status(sz, 0);
Select_SetTexture(texdef);
// scroll origin so the texture is completely on screen
Texture_StartPos ();
while (1)
{
q = Texture_NextPos (&x, &y);
if (!q)
break;
if (!strcmpi(texdef->name, q->name))
{
if (y > g_qeglobals.d_texturewin.originy)
{
g_qeglobals.d_texturewin.originy = y;
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
return;
}
if (y-q->height-2*FONT_HEIGHT < g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height)
{
g_qeglobals.d_texturewin.originy = y-q->height-2*FONT_HEIGHT+g_qeglobals.d_texturewin.height;
Sys_UpdateWindows (W_TEXTURE);
Texture_SetScrollPos();
return;
}
return;
}
}
}
/*
==============
SelectTexture
By mouse click
==============
*/
void SelectTexture (int mx, int my)
{
int x, y;
qtexture_t *q;
texdef_t tex;
my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height;
Texture_StartPos ();
while (1)
{
q = Texture_NextPos (&x, &y);
if (!q)
break;
if (mx > x && mx - x < q->width
&& my < y && y - my < q->height + FONT_HEIGHT)
{
memset (&tex, 0, sizeof(tex));
tex.scale[0] = q->scale_x;
tex.scale[1] = q->scale_y;
tex.flags = q->flags;
tex.value = q->value;
tex.contents = q->contents;
strcpy (tex.name, q->name);
Texture_SetTexture (&tex);
return;
}
}
Sys_Status("Did not select a texture\n", 0);
}
/*
==============
Texture_MouseDown
==============
*/
void Texture_MouseDown (int x, int y, int buttons)
{
Sys_GetCursorPos (&textures_cursorx, &textures_cursory);
// lbutton = select texture
if (buttons == MK_LBUTTON )
{
SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y);
return;
}
}
/*
==============
Texture_MouseUp
==============
*/
void Texture_MouseUp (int x, int y, int buttons)
{
}
/*
==============
Texture_MouseMoved
==============
*/
void Texture_MouseMoved (int x, int y, int buttons)
{
int scale = 1;
if ( buttons & MK_SHIFT )
scale = 4;
// rbutton = drag texture origin
if (buttons & MK_RBUTTON)
{
Sys_GetCursorPos (&x, &y);
if ( y != textures_cursory)
{
Texture_ScrollLine(( y-textures_cursory) * scale);
Sys_SetCursorPos (textures_cursorx, textures_cursory);
}
return;
}
}
/*
============================================================================
DRAWING
============================================================================
*/
int imax(int iFloor, int i) { if (i>iFloor) return iFloor; return i; }
HFONT ghFont = NULL;
/*
============
Texture_Draw2
============
*/
void Texture_Draw2 (int width, int height)
{
qtexture_t *q;
int x, y;
char *name;
glClearColor (
g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0],
g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1],
g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2],
0);
glViewport (0,0,width,height);
glClear (GL_COLOR_BUFFER_BIT);
glDisable (GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, width, g_qeglobals.d_texturewin.originy-height, g_qeglobals.d_texturewin.originy, -100, 100);
glEnable (GL_TEXTURE_2D);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
g_qeglobals.d_texturewin.width = width;
g_qeglobals.d_texturewin.height = height;
Texture_StartPos ();
while (1)
{
q = Texture_NextPos (&x, &y);
if (!q)
break;
// Is this texture visible?
if ( (y-q->height-FONT_HEIGHT < g_qeglobals.d_texturewin.originy)
&& (y > g_qeglobals.d_texturewin.originy - height) )
{
// if in use, draw a background
if (q->inuse && !texture_showinuse)
{
glLineWidth (1);
glColor3f (0.5,1,0.5);
glDisable (GL_TEXTURE_2D);
glBegin (GL_LINE_LOOP);
glVertex2f (x-1,y+1-FONT_HEIGHT);
glVertex2f (x-1,y-q->height-1-FONT_HEIGHT);
glVertex2f (x+1+q->width,y-q->height-1-FONT_HEIGHT);
glVertex2f (x+1+q->width,y+1-FONT_HEIGHT);
glEnd ();
glEnable (GL_TEXTURE_2D);
}
// Draw the texture
glColor3f (1,1,1);
glBindTexture( GL_TEXTURE_2D, q->texture_number );
glBegin (GL_QUADS);
glTexCoord2f (0,0);
glVertex2f (x,y-FONT_HEIGHT);
glTexCoord2f (1,0);
glVertex2f (x+q->width,y-FONT_HEIGHT);
glTexCoord2f (1,1);
glVertex2f (x+q->width,y-FONT_HEIGHT-q->height);
glTexCoord2f (0,1);
glVertex2f (x,y-FONT_HEIGHT-q->height);
glEnd ();
// draw the selection border
if (!strcmpi(g_qeglobals.d_texturewin.texdef.name, q->name))
{
glLineWidth (3);
glColor3f (1,0,0);
glDisable (GL_TEXTURE_2D);
glBegin (GL_LINE_LOOP);
glVertex2f (x-4,y-FONT_HEIGHT+4);
glVertex2f (x-4,y-FONT_HEIGHT-q->height-4);
glVertex2f (x+4+q->width,y-FONT_HEIGHT-q->height-4);
glVertex2f (x+4+q->width,y-FONT_HEIGHT+4);
glEnd ();
glEnable (GL_TEXTURE_2D);
glLineWidth (1);
}
// draw the texture name
glColor3f (0,0,0);
glRasterPos2f (x, y-FONT_HEIGHT+2);
// don't draw the directory name
for (name = q->name ; *name && *name != '/' && *name != '\\' ; name++)
;
if (!*name)
name = q->name;
else
name++;
glCallLists (strlen(name), GL_UNSIGNED_BYTE, name);
}
}
// reset the current texture
glBindTexture( GL_TEXTURE_2D, 0 );
glFinish();
}
/*
============
WTexWndProc
============
*/
LONG WINAPI WTex_WndProc (
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
int xPos, yPos;
RECT rect;
GetClientRect(hWnd, &rect);
switch (uMsg)
{
case WM_CREATE:
s_hdcTexture = GetDC(hWnd);
QEW_SetupPixelFormat(s_hdcTexture, false);
if ( ( s_hglrcTexture = wglCreateContext( s_hdcTexture ) ) == 0 )
Error( "wglCreateContext in WTex_WndProc failed" );
if (!wglMakeCurrent( s_hdcTexture, s_hglrcTexture ))
Error ("wglMakeCurrent in WTex_WndProc failed");
if (!wglShareLists( g_qeglobals.d_hglrcBase, s_hglrcTexture ) )
Error( "wglShareLists in WTex_WndProc failed" );
return 0;
case WM_DESTROY:
wglMakeCurrent( NULL, NULL );
wglDeleteContext( s_hglrcTexture );
ReleaseDC( hWnd, s_hdcTexture );
return 0;
case WM_PAINT:
{
// PAINTSTRUCT ps;
// BeginPaint(hWnd, &ps);
if ( !wglMakeCurrent( s_hdcTexture, s_hglrcTexture ) )
Error ("wglMakeCurrent failed");
Texture_Draw2 (rect.right-rect.left, rect.bottom-rect.top);
SwapBuffers(s_hdcTexture);
// EndPaint(hWnd, &ps);
ValidateRect(hWnd, NULL);
}
return 0;
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN:
SetCapture( g_qeglobals.d_hwndTexture );
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
Texture_MouseDown (xPos, yPos, wParam);
return 0;
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONUP:
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
Texture_MouseUp (xPos, yPos, wParam);
if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
ReleaseCapture ();
return 0;
case WM_MOUSEMOVE:
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
Texture_MouseMoved (xPos, yPos, wParam);
return 0;
case WM_SIZE:
//i'm not worried about messing this up, since i'll get a paint message soon anyhow
g_qeglobals.d_texturewin.width = rect.right-rect.left;
g_qeglobals.d_texturewin.height = rect.bottom-rect.top;
Texture_SetScrollRange();//this is inefficient way of updating scrollbar?
return 0;
case WM_VSCROLL:
switch(LOWORD(wParam))
{
case SB_LINEUP:
Texture_ScrollRow(1);
break;
case SB_LINEDOWN:
Texture_ScrollRow(-1);
break;
case SB_PAGEUP:
Texture_ScrollPage(1);
break;
case SB_PAGEDOWN:
Texture_ScrollPage(-1);
break;
case SB_THUMBTRACK:
Texture_ScrollTo (-HIWORD(wParam));
break;
case SB_THUMBPOSITION:
Texture_ScrollTo (-HIWORD(wParam));
break;
default:
break;
}
return 0;
case WM_LBUTTONDBLCLK:
PostMessage (g_qeglobals.d_hwndMain, WM_COMMAND, ID_TEXTURES_INSPECTOR, 0);
return 0;
case WM_MOUSEWHEEL:
// Sys_Printf ("got a wheel!\n");
/* gcWheelDelta -= (short) HIWORD(wParam);
if (abs(gcWheelDelta) >=
WHEEL_DELTA && gucWheelScrollLines > 0)
{
texturewin.originy += gucWheelScrollLines*(gcWheelDelta / WHEEL_DELTA);
if (texturewin.originy > 0)
texturewin.originy = 0;
Sys_UpdateWindows (W_TEXTURE);
}
break;
*/
Texture_ScrollRow(HIWORD(wParam) / WHEEL_DELTA);
return 0;
default:
if (uMsg == g_qeglobals.uMSH_MOUSEWHEEL)
{
Texture_ScrollRow(*(int *)&wParam / WHEEL_DELTA);
return 0;
}
break;
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
/*
==================
CreateTextureWindow
We need to create a seperate window for the textures
in the inspector window, because we can't share
gl and gdi drawing in a single window
==================
*/
#define TEXTURE_WINDOW_CLASS "QTEX"
extern BOOL CALLBACK TexModifyProc (
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
HWND CreateTextureWindow (void)
{
WNDCLASS wc;
HWND hwnd;
/* Register the camera class */
memset (&wc, 0, sizeof(wc));
wc.style = CS_OWNDC|CS_DBLCLKS;
wc.lpfnWndProc = (WNDPROC)WTex_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_qeglobals.d_hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = TEXTURE_WINDOW_CLASS;
if (!RegisterClass (&wc) )
Error ("WCam_Register: failed");
hwnd = CreateWindow (TEXTURE_WINDOW_CLASS ,
"Texture View",
WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL,
20,
20,
64,
64, // size
g_qeglobals.d_hwndEntity, // parent window
0, // no menu
g_qeglobals.d_hInstance,
0);
if (!hwnd)
Error ("Couldn't create texturewindow");
g_qeglobals.d_hwndTexModDlg = CreateDialog(g_qeglobals.d_hInstance, MAKEINTRESOURCE(IDD_TEXMODIFY),
g_qeglobals.d_hwndEntity, (DLGPROC)TexModifyProc);
return hwnd;
}
/*
==================
Texture_Flush
==================
*/
void Texture_Flush (void)
{
}
/*
==================
Texture_Init
==================
*/
void Texture_Init (void)
{
// char name[1024];
// byte *pal;
// load the palette
// sprintf (name, "%s/pics/colormap.pcx",
// ValueForKey (g_qeglobals.d_project_entity, "basepath"));
// Load256Image (name, NULL, &pal, NULL, NULL);
// if (!pal)
// Error ("Couldn't load %s", name);
// Texture_InitPalette (pal);
// free (pal);
// create the fallback texture
Texture_MakeNotexture ();
g_qeglobals.d_qtextures = NULL;
}
/*
==================
Texture_DefaultMaterial
==================
*/
void Texture_DefaultMaterial(void)
{
qtexture_t *curTex;
brush_t *b, *startBrush;
face_t *f, *startFace;
b = world_entity->brushes.onext;
startBrush = b;
while (b != NULL)
{
f = b->brush_faces;
startFace = f;
while (f != NULL)
{
curTex = g_qeglobals.d_qtextures;
while(curTex)
{
if (!strcmpi(curTex->name, f->texdef.name))
{
f->texdef.flags = ((f->texdef.flags & 0x00FFFFFF) | (curTex->flags & 0x0FF000000));
break;
}
curTex = curTex->next;
}
f = f->next;
if (f == startFace)
{
f = NULL;
}
}
b = b->onext;
if (b == startBrush)
{
b = NULL;
}
}
}