2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
5 This file is part of Quake 2 Tools source code.
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
27 static unsigned tex_palette[256];
29 static qtexture_t *notexture;
31 static qboolean nomips;
33 #define FONT_HEIGHT 10
35 static HGLRC s_hglrcTexture;
36 static HDC s_hdcTexture;
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;
45 int texture_extension_number = 1;
47 // current active texture directory. if empty, show textures in use
48 char texture_directory[32]; // use if texture_showinuse is false
49 qboolean texture_showinuse;
51 // texture layout functions
52 qtexture_t *current_texture;
53 int current_x, current_y, current_row;
56 #define MAX_TEXTUREDIRS 100
57 char texture_menunames[MAX_TEXTUREDIRS][64];
59 qboolean g_dontuse; // set to true to load the texture but not flag as used
61 void SelectTexture (int mx, int my);
63 void Texture_MouseDown (int x, int y, int buttons);
64 void Texture_MouseUp (int x, int y, int buttons);
65 void Texture_MouseMoved (int x, int y, int buttons);
67 //=====================================================
69 void SortTextures(void)
71 qtexture_t *q, *qtemp, *qhead, *qcur, *qprev;
73 // standard insertion sort
74 // Take the first texture from the list and
75 // add it to our new list
76 if ( g_qeglobals.d_qtextures == NULL)
79 qhead = g_qeglobals.d_qtextures;
80 q = g_qeglobals.d_qtextures->next;
83 // while there are still things on the old
84 // list, keep adding them to the new list
96 if (strcmp(qtemp->name, qcur->name) < 0)
112 // is this one at the end?
124 g_qeglobals.d_qtextures = qhead;
127 //=====================================================
135 void Texture_InitPalette (byte *pal)
140 byte gammatable[256];
143 gamma = g_qeglobals.d_savedinfo.fGamma;
147 for (i=0 ; i<256 ; i++)
152 for (i=0 ; i<256 ; i++)
154 inf = 255 * pow ( (i+0.5)/255.5 , gamma ) + 0.5;
163 for (i=0 ; i<256 ; i++)
165 r = gammatable[pal[0]];
166 g = gammatable[pal[1]];
167 b = gammatable[pal[2]];
170 v = (r<<24) + (g<<16) + (b<<8) + 255;
177 void SetTexParameters (void)
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode );
181 switch ( texture_mode )
184 case GL_NEAREST_MIPMAP_NEAREST:
185 case GL_NEAREST_MIPMAP_LINEAR:
186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
189 case GL_LINEAR_MIPMAP_NEAREST:
190 case GL_LINEAR_MIPMAP_LINEAR:
191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
201 void Texture_SetMode(int iMenu)
205 qboolean texturing = true;
207 hMenu = GetMenu(g_qeglobals.d_hwndMain);
210 case ID_VIEW_NEAREST:
213 case ID_VIEW_NEARESTMIPMAP:
214 iMode = GL_NEAREST_MIPMAP_NEAREST;
217 iMode = GL_NEAREST_MIPMAP_LINEAR;
219 case ID_VIEW_BILINEAR:
222 case ID_VIEW_BILINEARMIPMAP:
223 iMode = GL_LINEAR_MIPMAP_NEAREST;
225 case ID_VIEW_TRILINEAR:
226 iMode = GL_LINEAR_MIPMAP_LINEAR;
229 case ID_TEXTURES_WIREFRAME:
234 case ID_TEXTURES_FLATSHADE:
241 CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED);
242 CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
243 CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED);
244 CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
245 CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
246 CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
247 CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED);
248 CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED);
250 CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED);
252 g_qeglobals.d_savedinfo.iTexMenu = iMenu;
253 texture_mode = iMode;
257 if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME)
259 camera.draw_mode = cd_wire;
260 Map_BuildBrushData();
261 Sys_UpdateWindows (W_ALL);
264 } else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) {
266 camera.draw_mode = cd_solid;
267 Map_BuildBrushData();
268 Sys_UpdateWindows (W_ALL);
272 for (i=1 ; i<texture_extension_number ; i++)
274 glBindTexture( GL_TEXTURE_2D, i );
278 // select the default texture
279 glBindTexture( GL_TEXTURE_2D, 0 );
283 if (camera.draw_mode != cd_texture)
285 camera.draw_mode = cd_texture;
286 Map_BuildBrushData();
289 Sys_UpdateWindows (W_ALL);
298 qtexture_t *Texture_LoadTexture (miptex_t *qtex)
302 int width, height, i, count;
306 q = qmalloc(sizeof(*q));
307 width = LittleLong(qtex->width);
308 height = LittleLong(qtex->height);
313 q->flags = qtex->flags;
314 q->value = qtex->value;
315 q->contents = qtex->contents;
317 dest = qmalloc (width*height*4);
319 count = width*height;
320 source = (byte *)qtex + LittleLong(qtex->offsets[0]);
322 // The dib is upside down so we want to copy it into
323 // the buffer bottom up.
325 total[0] = total[1] = total[2] = 0;
326 for (i=0 ; i<count ; i++)
328 dest[i] = tex_palette[source[i]];
330 total[0] += ((byte *)(dest+i))[0];
331 total[1] += ((byte *)(dest+i))[1];
332 total[2] += ((byte *)(dest+i))[2];
335 q->color[0] = (float)total[0]/(count*255);
336 q->color[1] = (float)total[1]/(count*255);
337 q->color[2] = (float)total[2]/(count*255);
339 q->texture_number = texture_extension_number++;
341 glBindTexture( GL_TEXTURE_2D, q->texture_number );
345 glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
347 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
351 glBindTexture( GL_TEXTURE_2D, 0 );
360 Create a single pixel texture of the apropriate color
363 qtexture_t *Texture_CreateSolid (char *name)
368 q = qmalloc(sizeof(*q));
370 sscanf (name, "(%f %f %f)", &q->color[0], &q->color[1], &q->color[2]);
372 data[0] = q->color[0]*255;
373 data[1] = q->color[1]*255;
374 data[2] = q->color[2]*255;
377 q->width = q->height = 1;
378 q->texture_number = texture_extension_number++;
379 glBindTexture( GL_TEXTURE_2D, q->texture_number );
383 glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
385 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data);
387 glBindTexture( GL_TEXTURE_2D, 0 );
395 Texture_MakeNotexture
398 void Texture_MakeNotexture (void)
403 notexture = q = qmalloc(sizeof(*q));
404 strcpy (q->name, "notexture");
405 q->width = q->height = 64;
407 memset (data, 0, sizeof(data));
408 data[0][2] = data[3][2] = 255;
414 q->texture_number = texture_extension_number++;
415 glBindTexture( GL_TEXTURE_2D, q->texture_number );
419 glTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
421 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data);
423 glBindTexture( GL_TEXTURE_2D, 0 );
433 qtexture_t *Texture_ForName (char *name)
440 for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
442 if (!strcmp(name, q->name))
452 q = Texture_CreateSolid (name);
453 strncpy (q->name, name, sizeof(q->name)-1);
458 sprintf (filename, "%s/%s.wal",
459 ValueForKey (g_qeglobals.d_project_entity, "texturepath"),
461 Sys_Printf ("Loading %s\n", name);
462 if (LoadFile (filename, &lump) == -1)
464 Sys_Printf (" load failed!\n");
467 q = Texture_LoadTexture ((miptex_t *)lump);
469 strncpy (q->name, name, sizeof(q->name)-1);
470 StripExtension (q->name);
475 q->next = g_qeglobals.d_qtextures;
476 g_qeglobals.d_qtextures = q;
487 void FillTextureMenu (void)
491 struct _finddata_t fileinfo;
493 char dirstring[1024];
496 hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_TEXTURE);
499 for (i=0 ; i<texture_nummenus ; i++)
500 DeleteMenu (hmenu, CMD_TEXTUREWAD+i, MF_BYCOMMAND);
503 path = ValueForKey (g_qeglobals.d_project_entity, "texturepath");
505 sprintf (dirstring, "%s/*.*", path);
507 handle = _findfirst (dirstring, &fileinfo);
513 if (!(fileinfo.attrib & _A_SUBDIR))
515 if (fileinfo.name[0] == '.')
517 // add this directory to the menu
518 AppendMenu (hmenu, MF_ENABLED|MF_STRING,
519 CMD_TEXTUREWAD+texture_nummenus, (LPCTSTR)fileinfo.name);
520 strcpy (texture_menunames[texture_nummenus], fileinfo.name);
521 strcat (texture_menunames[texture_nummenus], "/");
522 if (++texture_nummenus == MAX_TEXTUREDIRS)
524 } while (_findnext( handle, &fileinfo ) != -1);
534 A new map is being loaded, so clear inuse markers
537 void Texture_ClearInuse (void)
541 for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
551 Texture_ShowDirectory
554 void Texture_ShowDirectory (int menunum)
556 struct _finddata_t fileinfo;
559 char dirstring[1024];
561 texture_showinuse = false;
562 strcpy (texture_directory, texture_menunames[menunum-CMD_TEXTUREWAD]);
564 g_qeglobals.d_texturewin.originy = 0;
565 Sys_Status("loading all textures\n", 0);
567 // load all .wal files
568 sprintf (dirstring, "%s/textures/%s*.wal",
569 ValueForKey (g_qeglobals.d_project_entity, "basepath"),
570 texture_menunames[menunum-CMD_TEXTUREWAD]);
572 Sys_Printf ("Scanning %s\n", dirstring);
574 handle = _findfirst (dirstring, &fileinfo);
581 sprintf (name, "%s%s", texture_directory, fileinfo.name);
582 StripExtension (name);
583 Texture_ForName (name);
584 } while (_findnext( handle, &fileinfo ) != -1);
590 SetInspectorMode(W_TEXTURE);
591 Sys_UpdateWindows(W_TEXTURE);
593 sprintf (name, "Textures: %s", texture_directory);
594 SetWindowText(g_qeglobals.d_hwndEntity, name);
596 // select the first texture in the list
597 if (!g_qeglobals.d_texturewin.texdef.name[0])
598 SelectTexture (16, g_qeglobals.d_texturewin.height -16);
606 void Texture_ShowInuse (void)
612 texture_showinuse = true;
614 g_qeglobals.d_texturewin.originy = 0;
615 Sys_Status("Selecting active textures\n", 0);
616 Texture_ClearInuse ();
618 for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next)
619 for (f=b->brush_faces ; f ; f=f->next)
620 Texture_ForName (f->texdef.name);
622 for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next)
623 for (f=b->brush_faces ; f ; f=f->next)
624 Texture_ForName (f->texdef.name);
627 SetInspectorMode(W_TEXTURE);
628 Sys_UpdateWindows (W_TEXTURE);
630 sprintf (name, "Textures: in use");
631 SetWindowText(g_qeglobals.d_hwndEntity, name);
633 // select the first texture in the list
634 if (!g_qeglobals.d_texturewin.texdef.name[0])
635 SelectTexture (16, g_qeglobals.d_texturewin.height -16);
639 ============================================================================
643 ============================================================================
646 void Texture_StartPos (void)
648 current_texture = g_qeglobals.d_qtextures;
654 qtexture_t *Texture_NextPos (int *x, int *y)
663 current_texture = current_texture->next;
664 if (q->name[0] == '(') // fake color texture
667 break; // allways show in use
668 if (!texture_showinuse && strncmp (q->name, texture_directory, strlen(texture_directory)))
673 if (current_x + q->width > g_qeglobals.d_texturewin.width-8 && current_row)
674 { // go to the next row unless the texture is the first on the row
676 current_y -= current_row + FONT_HEIGHT + 4;
683 // Is our texture larger than the row? If so, grow the
684 // row height to match it
686 if (current_row < q->height)
687 current_row = q->height;
689 // never go less than 64, or the names get all crunched up
690 current_x += q->width < 64 ? 64 : q->width;
697 ============================================================================
701 ============================================================================
704 static int textures_cursorx, textures_cursory;
713 void Texture_SetTexture (texdef_t *texdef)
719 if (texdef->name[0] == '(')
721 Sys_Status("Can't select an entity texture\n", 0);
724 g_qeglobals.d_texturewin.texdef = *texdef;
726 Sys_UpdateWindows (W_TEXTURE);
727 sprintf(sz, "Selected texture: %s\n", texdef->name);
729 Select_SetTexture(texdef);
731 // scroll origin so the texture is completely on screen
735 q = Texture_NextPos (&x, &y);
738 if (!strcmpi(texdef->name, q->name))
740 if (y > g_qeglobals.d_texturewin.originy)
742 g_qeglobals.d_texturewin.originy = y;
743 Sys_UpdateWindows (W_TEXTURE);
747 if (y-q->height-2*FONT_HEIGHT < g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height)
749 g_qeglobals.d_texturewin.originy = y-q->height-2*FONT_HEIGHT+g_qeglobals.d_texturewin.height;
750 Sys_UpdateWindows (W_TEXTURE);
767 void SelectTexture (int mx, int my)
773 my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height;
778 q = Texture_NextPos (&x, &y);
781 if (mx > x && mx - x < q->width
782 && my < y && y - my < q->height + FONT_HEIGHT)
784 memset (&tex, 0, sizeof(tex));
787 tex.flags = q->flags;
788 tex.value = q->value;
789 tex.contents = q->contents;
790 strcpy (tex.name, q->name);
791 Texture_SetTexture (&tex);
796 Sys_Status("Did not select a texture\n", 0);
804 void Texture_MouseDown (int x, int y, int buttons)
806 Sys_GetCursorPos (&textures_cursorx, &textures_cursory);
808 // lbutton = select texture
809 if (buttons == MK_LBUTTON )
811 SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y);
822 void Texture_MouseUp (int x, int y, int buttons)
831 void Texture_MouseMoved (int x, int y, int buttons)
835 if ( buttons & MK_SHIFT )
838 // rbutton = drag texture origin
839 if (buttons & MK_RBUTTON)
841 Sys_GetCursorPos (&x, &y);
842 if ( y != textures_cursory)
844 g_qeglobals.d_texturewin.originy += ( y-textures_cursory) * scale;
845 if (g_qeglobals.d_texturewin.originy > 0)
846 g_qeglobals.d_texturewin.originy = 0;
847 Sys_SetCursorPos (textures_cursorx, textures_cursory);
848 Sys_UpdateWindows (W_TEXTURE);
856 ============================================================================
860 ============================================================================
863 int imax(int iFloor, int i) { if (i>iFloor) return iFloor; return i; }
871 void Texture_Draw2 (int width, int height)
878 g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0],
879 g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1],
880 g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2],
882 glViewport (0,0,width,height);
883 glClear (GL_COLOR_BUFFER_BIT);
884 glDisable (GL_DEPTH_TEST);
885 glMatrixMode(GL_PROJECTION);
887 glOrtho (0, width, g_qeglobals.d_texturewin.originy-height, g_qeglobals.d_texturewin.originy, -100, 100);
888 glEnable (GL_TEXTURE_2D);
890 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
891 g_qeglobals.d_texturewin.width = width;
892 g_qeglobals.d_texturewin.height = height;
897 q = Texture_NextPos (&x, &y);
901 // Is this texture visible?
902 if ( (y-q->height-FONT_HEIGHT < g_qeglobals.d_texturewin.originy)
903 && (y > g_qeglobals.d_texturewin.originy - height) )
906 // if in use, draw a background
907 if (q->inuse && !texture_showinuse)
910 glColor3f (0.5,1,0.5);
911 glDisable (GL_TEXTURE_2D);
913 glBegin (GL_LINE_LOOP);
914 glVertex2f (x-1,y+1-FONT_HEIGHT);
915 glVertex2f (x-1,y-q->height-1-FONT_HEIGHT);
916 glVertex2f (x+1+q->width,y-q->height-1-FONT_HEIGHT);
917 glVertex2f (x+1+q->width,y+1-FONT_HEIGHT);
920 glEnable (GL_TEXTURE_2D);
925 glBindTexture( GL_TEXTURE_2D, q->texture_number );
928 glVertex2f (x,y-FONT_HEIGHT);
930 glVertex2f (x+q->width,y-FONT_HEIGHT);
932 glVertex2f (x+q->width,y-FONT_HEIGHT-q->height);
934 glVertex2f (x,y-FONT_HEIGHT-q->height);
937 // draw the selection border
938 if (!strcmpi(g_qeglobals.d_texturewin.texdef.name, q->name))
942 glDisable (GL_TEXTURE_2D);
944 glBegin (GL_LINE_LOOP);
945 glVertex2f (x-4,y-FONT_HEIGHT+4);
946 glVertex2f (x-4,y-FONT_HEIGHT-q->height-4);
947 glVertex2f (x+4+q->width,y-FONT_HEIGHT-q->height-4);
948 glVertex2f (x+4+q->width,y-FONT_HEIGHT+4);
951 glEnable (GL_TEXTURE_2D);
955 // draw the texture name
957 glRasterPos2f (x, y-FONT_HEIGHT+2);
959 // don't draw the directory name
960 for (name = q->name ; *name && *name != '/' && *name != '\\' ; name++)
966 glCallLists (strlen(name), GL_UNSIGNED_BYTE, name);
970 // reset the current texture
971 glBindTexture( GL_TEXTURE_2D, 0 );
980 LONG WINAPI WTex_WndProc (
989 GetClientRect(hWnd, &rect);
994 s_hdcTexture = GetDC(hWnd);
995 QEW_SetupPixelFormat(s_hdcTexture, false);
997 if ( ( s_hglrcTexture = wglCreateContext( s_hdcTexture ) ) == 0 )
998 Error( "wglCreateContext in WTex_WndProc failed" );
1000 if (!wglMakeCurrent( s_hdcTexture, s_hglrcTexture ))
1001 Error ("wglMakeCurrent in WTex_WndProc failed");
1003 if (!wglShareLists( g_qeglobals.d_hglrcBase, s_hglrcTexture ) )
1004 Error( "wglShareLists in WTex_WndProc failed" );
1009 wglMakeCurrent( NULL, NULL );
1010 wglDeleteContext( s_hglrcTexture );
1011 ReleaseDC( hWnd, s_hdcTexture );
1018 BeginPaint(hWnd, &ps);
1020 if ( !wglMakeCurrent( s_hdcTexture, s_hglrcTexture ) )
1021 Error ("wglMakeCurrent failed");
1022 Texture_Draw2 (rect.right-rect.left, rect.bottom-rect.top);
1023 SwapBuffers(s_hdcTexture);
1025 EndPaint(hWnd, &ps);
1029 case WM_MBUTTONDOWN:
1030 case WM_RBUTTONDOWN:
1031 case WM_LBUTTONDOWN:
1032 SetCapture( g_qeglobals.d_hwndTexture );
1033 xPos = (short)LOWORD(lParam); // horizontal position of cursor
1034 yPos = (short)HIWORD(lParam); // vertical position of cursor
1036 Texture_MouseDown (xPos, yPos, wParam);
1042 xPos = (short)LOWORD(lParam); // horizontal position of cursor
1043 yPos = (short)HIWORD(lParam); // vertical position of cursor
1045 Texture_MouseUp (xPos, yPos, wParam);
1046 if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
1051 xPos = (short)LOWORD(lParam); // horizontal position of cursor
1052 yPos = (short)HIWORD(lParam); // vertical position of cursor
1054 Texture_MouseMoved (xPos, yPos, wParam);
1058 return DefWindowProc (hWnd, uMsg, wParam, lParam);
1067 We need to create a seperate window for the textures
1068 in the inspector window, because we can't share
1069 gl and gdi drawing in a single window
1072 #define TEXTURE_WINDOW_CLASS "QTEX"
1073 HWND CreateTextureWindow (void)
1078 /* Register the camera class */
1079 memset (&wc, 0, sizeof(wc));
1082 wc.lpfnWndProc = (WNDPROC)WTex_WndProc;
1085 wc.hInstance = g_qeglobals.d_hInstance;
1087 wc.hCursor = LoadCursor (NULL,IDC_ARROW);
1088 wc.hbrBackground = NULL;
1089 wc.lpszMenuName = 0;
1090 wc.lpszClassName = TEXTURE_WINDOW_CLASS;
1092 if (!RegisterClass (&wc) )
1093 Error ("WCam_Register: failed");
1095 hwnd = CreateWindow (TEXTURE_WINDOW_CLASS ,
1097 WS_BORDER|WS_CHILD|WS_VISIBLE,
1103 g_qeglobals.d_hwndEntity, // parent window
1105 g_qeglobals.d_hInstance,
1108 Error ("Couldn't create texturewindow");
1118 void Texture_Flush (void)
1128 void Texture_Init (void)
1134 sprintf (name, "%s/pics/colormap.pcx",
1135 ValueForKey (g_qeglobals.d_project_entity, "basepath"));
1136 Load256Image (name, NULL, &pal, NULL, NULL);
1138 Error ("Couldn't load %s", name);
1139 Texture_InitPalette (pal);
1142 // create the fallback texture
1143 Texture_MakeNotexture ();
1145 g_qeglobals.d_qtextures = NULL;