]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/win_main.c
Merge branch 'master' into divVerent/farplanedist-sky-fix
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / win_main.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
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.
11
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.
16
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 ===========================================================================
21 */
22
23 #include "qe3.h"
24 #include <process.h>
25 #include "mru.h"
26 #include "entityw.h"
27
28 static HWND      s_hwndToolbar;
29
30 BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize);
31 BOOL LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize);
32
33 static HWND CreateMyStatusWindow(HINSTANCE hInst);
34 static HWND CreateToolBar(HINSTANCE hinst);
35
36 extern int WXY_Print( void );
37
38 /*
39 ==============================================================================
40
41   MENU
42
43 ==============================================================================
44 */
45
46 void OpenDialog (void);
47 void SaveAsDialog (void);
48 qboolean ConfirmModified (void);
49 void  Select_Ungroup (void);
50
51 void QE_ExpandBspString (char *bspaction, char *out, char *mapname)
52 {
53         char    *in;
54         char    src[1024];
55         char    rsh[1024];
56         char    base[256];
57
58         ExtractFileName (mapname, base);
59         sprintf (src, "%s/maps/%s", ValueForKey(g_qeglobals.d_project_entity, "remotebasepath"), base);
60         strcpy (rsh, ValueForKey(g_qeglobals.d_project_entity, "rshcmd"));
61
62         in = ValueForKey( g_qeglobals.d_project_entity, bspaction );
63         while (*in)
64         {
65                 if (in[0] == '!')
66                 {
67                         strcpy (out, rsh);
68                         out += strlen(rsh);
69                         in++;
70                         continue;
71                 }
72                 if (in[0] == '$')
73                 {
74                         strcpy (out, src);
75                         out += strlen(src);
76                         in++;
77                         continue;
78                 }
79                 if (in[0] == '@')
80                 {
81                         *out++ = '"';
82                         in++;
83                         continue;
84                 }
85                 *out++ = *in++;
86         }
87         *out = 0;
88 }
89
90
91
92 void RunBsp (char *command)
93 {
94         char    sys[1024];
95         char    batpath[1024];
96         char    outputpath[1024];
97         char    temppath[512];
98         char    name[1024];
99         FILE    *hFile;
100         BOOL    ret;
101         PROCESS_INFORMATION ProcessInformation;
102         STARTUPINFO     startupinfo;
103
104         SetInspectorMode (W_CONSOLE);
105
106         if (bsp_process)
107         {
108                 Sys_Printf ("BSP is still going...\n");
109                 return;
110         }
111
112         GetTempPath(512, temppath);
113         sprintf (outputpath, "%sjunk.txt", temppath);
114
115         strcpy (name, currentmap);
116         if (region_active)
117         {
118                 Map_SaveFile (name, false);
119                 StripExtension (name);
120                 strcat (name, ".reg");
121         }
122
123         Map_SaveFile (name, region_active);
124
125
126         QE_ExpandBspString (command, sys, name);
127
128         Sys_ClearPrintf ();
129         Sys_Printf ("======================================\nRunning bsp command...\n");
130         Sys_Printf ("\n%s\n", sys);
131
132         //
133         // write qe3bsp.bat
134         //
135         sprintf (batpath, "%sqe3bsp.bat", temppath);
136         hFile = fopen(batpath, "w");
137         if (!hFile)
138                 Error ("Can't write to %s", batpath);
139         fprintf (hFile, sys);
140         fclose (hFile);
141
142         //
143         // write qe3bsp2.bat
144         //
145         sprintf (batpath, "%sqe3bsp2.bat", temppath);
146         hFile = fopen(batpath, "w");
147         if (!hFile)
148                 Error ("Can't write to %s", batpath);
149         fprintf (hFile, "%sqe3bsp.bat > %s", temppath, outputpath);
150         fclose (hFile);
151
152         Pointfile_Delete ();
153
154         GetStartupInfo (&startupinfo);
155
156         ret = CreateProcess(
157     batpath,            // pointer to name of executable module
158     NULL,                       // pointer to command line string
159     NULL,                       // pointer to process security attributes
160     NULL,                       // pointer to thread security attributes
161     FALSE,                      // handle inheritance flag
162     0 /*DETACHED_PROCESS*/,             // creation flags
163     NULL,                       // pointer to new environment block
164     NULL,                       // pointer to current directory name
165     &startupinfo,       // pointer to STARTUPINFO
166     &ProcessInformation         // pointer to PROCESS_INFORMATION
167    );
168
169         if (!ret)
170                 Error ("CreateProcess failed");
171
172         bsp_process = ProcessInformation.hProcess;
173
174         Sleep (100);    // give the new process a chance to open it's window
175
176         BringWindowToTop( g_qeglobals.d_hwndMain );     // pop us back on top
177         SetFocus (g_qeglobals.d_hwndCamera);
178 }
179
180 /*
181 =============
182 DoColor
183
184 =============
185 */
186 qboolean DoColor(int iIndex)
187 {
188         CHOOSECOLOR     cc;
189         static COLORREF custom[16];
190
191         cc.lStructSize = sizeof(cc);
192         cc.hwndOwner = g_qeglobals.d_hwndMain;
193         cc.hInstance = g_qeglobals.d_hInstance;
194         cc.rgbResult =
195                 (int)(g_qeglobals.d_savedinfo.colors[iIndex][0]*255) +
196                 (((int)(g_qeglobals.d_savedinfo.colors[iIndex][1]*255))<<8) +
197                 (((int)(g_qeglobals.d_savedinfo.colors[iIndex][2]*255))<<16);
198     cc.lpCustColors = custom;
199     cc.Flags = CC_FULLOPEN|CC_RGBINIT;
200     //cc.lCustData;
201     //cc.lpfnHook;
202     //cc.lpTemplateName
203
204         if (!ChooseColor(&cc))
205                 return false;
206
207         g_qeglobals.d_savedinfo.colors[iIndex][0] = (cc.rgbResult&255)/255.0;
208         g_qeglobals.d_savedinfo.colors[iIndex][1] = ((cc.rgbResult>>8)&255)/255.0;
209         g_qeglobals.d_savedinfo.colors[iIndex][2] = ((cc.rgbResult>>16)&255)/255.0;
210
211         /*
212         ** scale colors so that at least one component is at 1.0F
213         ** if this is meant to select an entity color
214         */
215         if ( iIndex == COLOR_ENTITY )
216         {
217                 float largest = 0.0F;
218
219                 if ( g_qeglobals.d_savedinfo.colors[iIndex][0] > largest )
220                         largest = g_qeglobals.d_savedinfo.colors[iIndex][0];
221                 if ( g_qeglobals.d_savedinfo.colors[iIndex][1] > largest )
222                         largest = g_qeglobals.d_savedinfo.colors[iIndex][1];
223                 if ( g_qeglobals.d_savedinfo.colors[iIndex][2] > largest )
224                         largest = g_qeglobals.d_savedinfo.colors[iIndex][2];
225
226                 if ( largest == 0.0F )
227                 {
228                         g_qeglobals.d_savedinfo.colors[iIndex][0] = 1.0F;
229                         g_qeglobals.d_savedinfo.colors[iIndex][1] = 1.0F;
230                         g_qeglobals.d_savedinfo.colors[iIndex][2] = 1.0F;
231                 }
232                 else
233                 {
234                         float scaler = 1.0F / largest;
235
236                         g_qeglobals.d_savedinfo.colors[iIndex][0] *= scaler;
237                         g_qeglobals.d_savedinfo.colors[iIndex][1] *= scaler;
238                         g_qeglobals.d_savedinfo.colors[iIndex][2] *= scaler;
239                 }
240         }
241
242         Sys_UpdateWindows (W_ALL);
243
244         return true;
245 }
246
247
248 /* Copied from MSDN */
249
250 BOOL DoMru(HWND hWnd,WORD wId)
251 {
252         char szFileName[128];
253         OFSTRUCT of;
254         BOOL fExist;
255
256         GetMenuItem(g_qeglobals.d_lpMruMenu, wId, TRUE, szFileName, sizeof(szFileName));
257
258         // Test if the file exists.
259
260         fExist = OpenFile(szFileName ,&of,OF_EXIST) != HFILE_ERROR;
261
262         if (fExist) {
263
264                 // Place the file on the top of MRU.
265                 AddNewItem(g_qeglobals.d_lpMruMenu,(LPSTR)szFileName);
266
267                 // Now perform opening this file !!!
268                 Map_LoadFile (szFileName);
269         }
270         else
271                 // Remove the file on MRU.
272                 DelMenuItem(g_qeglobals.d_lpMruMenu,wId,TRUE);
273
274         // Refresh the File menu.
275         PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(hWnd),0),
276                         ID_FILE_EXIT);
277
278         return fExist;
279 }
280
281
282 /* handle all WM_COMMAND messages here */
283 LONG WINAPI CommandHandler (
284     HWND    hWnd,
285     WPARAM  wParam,
286     LPARAM  lParam)
287 {
288         HMENU hMenu;
289
290     switch (LOWORD(wParam))
291     {
292 //
293 // file menu
294 //
295         case ID_FILE_EXIT:
296             /* exit application */
297                         if (!ConfirmModified())
298                                 return TRUE;
299
300             PostMessage (hWnd, WM_CLOSE, 0, 0L);
301                         break;
302
303                 case ID_FILE_OPEN:
304                         if (!ConfirmModified())
305                                 return TRUE;
306                         OpenDialog ();
307                         break;
308
309                 case ID_FILE_NEW:
310                         if (!ConfirmModified())
311                                 return TRUE;
312                         Map_New ();
313                         break;
314                 case ID_FILE_SAVE:
315                         if (!strcmp(currentmap, "unnamed.map"))
316                                 SaveAsDialog ();
317                         else
318                                 Map_SaveFile (currentmap, false);       // ignore region
319                         break;
320                 case ID_FILE_SAVEAS:
321                         SaveAsDialog ();
322                         break;
323
324                 case ID_FILE_LOADPROJECT:
325                         if (!ConfirmModified())
326                                 return TRUE;
327                         ProjectDialog ();
328                         break;
329
330                 case ID_FILE_POINTFILE:
331                         if (g_qeglobals.d_pointfile_display_list)
332                                 Pointfile_Clear ();
333                         else
334                                 Pointfile_Check ();
335                         break;
336
337 //
338 // view menu
339 //
340                 case ID_VIEW_ENTITY:
341                         SetInspectorMode(W_ENTITY);
342                         break;
343                 case ID_VIEW_CONSOLE:
344                         SetInspectorMode(W_CONSOLE);
345                         break;
346                 case ID_VIEW_TEXTURE:
347                         SetInspectorMode(W_TEXTURE);
348                         break;
349
350                 case ID_VIEW_100:
351                         g_qeglobals.d_xy.scale = 1;
352                         Sys_UpdateWindows (W_XY|W_XY_OVERLAY);
353                         break;
354                 case ID_VIEW_ZOOMIN:
355                         g_qeglobals.d_xy.scale *= 5.0/4;
356                         if (g_qeglobals.d_xy.scale > 16)
357                                 g_qeglobals.d_xy.scale = 16;
358                         Sys_UpdateWindows (W_XY|W_XY_OVERLAY);
359                         break;
360                 case ID_VIEW_ZOOMOUT:
361                         g_qeglobals.d_xy.scale *= 4.0/5;
362                         if (g_qeglobals.d_xy.scale < 0.1)
363                                 g_qeglobals.d_xy.scale = 0.1;
364                         Sys_UpdateWindows (W_XY|W_XY_OVERLAY);
365                         break;
366
367                 case ID_VIEW_Z100:
368                         z.scale = 1;
369                         Sys_UpdateWindows (W_Z|W_Z_OVERLAY);
370                         break;
371                 case ID_VIEW_ZZOOMIN:
372                         z.scale *= 5.0/4;
373                         if (z.scale > 4)
374                                 z.scale = 4;
375                         Sys_UpdateWindows (W_Z|W_Z_OVERLAY);
376                         break;
377                 case ID_VIEW_ZZOOMOUT:
378                         z.scale *= 4.0/5;
379                         if (z.scale < 0.125)
380                                 z.scale = 0.125;
381                         Sys_UpdateWindows (W_Z|W_Z_OVERLAY);
382                         break;
383
384                 case ID_VIEW_CENTER:
385                         camera.angles[ROLL] = camera.angles[PITCH] = 0;
386                         camera.angles[YAW] = 22.5 *
387                                 floor( (camera.angles[YAW]+11)/22.5 );
388                         Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
389                         break;
390
391                 case ID_VIEW_UPFLOOR:
392                         Cam_ChangeFloor (true);
393                         break;
394                 case ID_VIEW_DOWNFLOOR:
395                         Cam_ChangeFloor (false);
396                         break;
397
398                 case ID_VIEW_SHOWNAMES:
399                         g_qeglobals.d_savedinfo.show_names = !g_qeglobals.d_savedinfo.show_names;
400                         CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWNAMES, MF_BYCOMMAND | (g_qeglobals.d_savedinfo.show_names ? MF_CHECKED : MF_UNCHECKED)  );
401                         Map_BuildBrushData();
402                         Sys_UpdateWindows (W_XY);
403                         break;
404
405                 case ID_VIEW_SHOWCOORDINATES:
406                         g_qeglobals.d_savedinfo.show_coordinates ^= 1;
407                         CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWCOORDINATES, MF_BYCOMMAND | (g_qeglobals.d_savedinfo.show_coordinates ? MF_CHECKED : MF_UNCHECKED)  );
408                         Sys_UpdateWindows (W_XY);
409                         break;
410
411                 case ID_VIEW_SHOWBLOCKS:
412                         g_qeglobals.show_blocks ^= 1;
413                         CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWBLOCKS, MF_BYCOMMAND | (g_qeglobals.show_blocks ? MF_CHECKED : MF_UNCHECKED)  );
414                         Sys_UpdateWindows (W_XY);
415                         break;
416
417                 case ID_VIEW_SHOWLIGHTS:
418                         if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_LIGHTS ) & EXCLUDE_LIGHTS )
419                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_UNCHECKED );
420                         else
421                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_CHECKED );
422                         Sys_UpdateWindows (W_XY|W_CAMERA);
423                         break;
424
425                 case ID_VIEW_SHOWPATH:
426                         if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_PATHS ) & EXCLUDE_PATHS )
427                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED );
428                         else
429                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_CHECKED );
430                         Sys_UpdateWindows (W_XY|W_CAMERA);
431                         break;
432
433                 case ID_VIEW_SHOWENT:
434                         if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_ENT ) & EXCLUDE_ENT )
435                                 CheckMenuItem( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWENT, MF_BYCOMMAND | MF_UNCHECKED);
436                         else
437                                 CheckMenuItem( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWENT, MF_BYCOMMAND | MF_CHECKED);
438                         Sys_UpdateWindows (W_XY|W_CAMERA);
439                         break;
440
441                 case ID_VIEW_SHOWWATER:
442                         if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_WATER ) & EXCLUDE_WATER )
443                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_UNCHECKED );
444                         else
445                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_CHECKED );
446                         Sys_UpdateWindows (W_XY|W_CAMERA);
447                         break;
448
449                 case ID_VIEW_SHOWCLIP:
450                         if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CLIP ) & EXCLUDE_CLIP )
451                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_UNCHECKED );
452                         else
453                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_CHECKED );
454                         Sys_UpdateWindows (W_XY|W_CAMERA);
455                         break;
456
457                 case ID_VIEW_SHOWDETAIL:
458                         if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_DETAIL ) & EXCLUDE_DETAIL )
459                         {
460                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWDETAIL, MF_BYCOMMAND | MF_UNCHECKED );
461                                 SetWindowText (g_qeglobals.d_hwndCamera, "Camera View (DETAIL EXCLUDED)");
462                         }
463                         else
464                         {
465                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWDETAIL, MF_BYCOMMAND | MF_CHECKED );
466                                 SetWindowText (g_qeglobals.d_hwndCamera, "Camera View");
467                         }
468                         Sys_UpdateWindows (W_XY|W_CAMERA);
469                         break;
470
471                 case ID_VIEW_SHOWWORLD:
472                         if ( ( g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_WORLD ) & EXCLUDE_WORLD )
473                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_UNCHECKED );
474                         else
475                                 CheckMenuItem ( GetMenu(g_qeglobals.d_hwndMain), ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_CHECKED );
476                         Sys_UpdateWindows (W_XY|W_CAMERA);
477                         break;
478
479
480 //
481 // grid menu
482 //
483                 case ID_GRID_1:
484                 case ID_GRID_2:
485                 case ID_GRID_4:
486                 case ID_GRID_8:
487                 case ID_GRID_16:
488                 case ID_GRID_32:
489                 case ID_GRID_64:
490                 {
491                         hMenu = GetMenu(hWnd);
492
493                         CheckMenuItem(hMenu, ID_GRID_1, MF_BYCOMMAND | MF_UNCHECKED);
494                         CheckMenuItem(hMenu, ID_GRID_2, MF_BYCOMMAND | MF_UNCHECKED);
495                         CheckMenuItem(hMenu, ID_GRID_4, MF_BYCOMMAND | MF_UNCHECKED);
496                         CheckMenuItem(hMenu, ID_GRID_8, MF_BYCOMMAND | MF_UNCHECKED);
497                         CheckMenuItem(hMenu, ID_GRID_16, MF_BYCOMMAND | MF_UNCHECKED);
498                         CheckMenuItem(hMenu, ID_GRID_32, MF_BYCOMMAND | MF_UNCHECKED);
499                         CheckMenuItem(hMenu, ID_GRID_64, MF_BYCOMMAND | MF_UNCHECKED);
500
501                         switch (LOWORD(wParam))
502                         {
503                                 case ID_GRID_1: g_qeglobals.d_gridsize = 0; break;
504                                 case ID_GRID_2: g_qeglobals.d_gridsize = 1; break;
505                                 case ID_GRID_4: g_qeglobals.d_gridsize = 2; break;
506                                 case ID_GRID_8: g_qeglobals.d_gridsize = 3; break;
507                                 case ID_GRID_16: g_qeglobals.d_gridsize = 4; break;
508                                 case ID_GRID_32: g_qeglobals.d_gridsize = 5; break;
509                                 case ID_GRID_64: g_qeglobals.d_gridsize = 6; break;
510                         }
511                         g_qeglobals.d_gridsize = 1 << g_qeglobals.d_gridsize;
512
513                         CheckMenuItem(hMenu, LOWORD(wParam), MF_BYCOMMAND | MF_CHECKED);
514                         Sys_UpdateWindows (W_XY|W_Z);
515                         break;
516                 }
517
518 //
519 // texture menu
520 //
521                 case ID_VIEW_NEAREST:
522                 case ID_VIEW_NEARESTMIPMAP:
523                 case ID_VIEW_LINEAR:
524                 case ID_VIEW_BILINEAR:
525                 case ID_VIEW_BILINEARMIPMAP:
526                 case ID_VIEW_TRILINEAR:
527                 case ID_TEXTURES_WIREFRAME:
528                 case ID_TEXTURES_FLATSHADE:
529                         Texture_SetMode (LOWORD(wParam));
530                         break;
531
532                 case ID_TEXTURES_SHOWINUSE:
533                         Sys_BeginWait ();
534                         Texture_ShowInuse ();
535                         SetInspectorMode(W_TEXTURE);
536                         break;
537
538                 case ID_TEXTURES_INSPECTOR:
539                         DoSurface ();
540                         break;
541
542                 case CMD_TEXTUREWAD:
543                 case CMD_TEXTUREWAD+1:
544                 case CMD_TEXTUREWAD+2:
545                 case CMD_TEXTUREWAD+3:
546                 case CMD_TEXTUREWAD+4:
547                 case CMD_TEXTUREWAD+5:
548                 case CMD_TEXTUREWAD+6:
549                 case CMD_TEXTUREWAD+7:
550                 case CMD_TEXTUREWAD+8:
551                 case CMD_TEXTUREWAD+9:
552                 case CMD_TEXTUREWAD+10:
553                 case CMD_TEXTUREWAD+11:
554                 case CMD_TEXTUREWAD+12:
555                 case CMD_TEXTUREWAD+13:
556                 case CMD_TEXTUREWAD+14:
557                 case CMD_TEXTUREWAD+15:
558                 case CMD_TEXTUREWAD+16:
559                 case CMD_TEXTUREWAD+17:
560                 case CMD_TEXTUREWAD+18:
561                 case CMD_TEXTUREWAD+19:
562                 case CMD_TEXTUREWAD+20:
563                 case CMD_TEXTUREWAD+21:
564                 case CMD_TEXTUREWAD+22:
565                 case CMD_TEXTUREWAD+23:
566                 case CMD_TEXTUREWAD+24:
567                 case CMD_TEXTUREWAD+25:
568                 case CMD_TEXTUREWAD+26:
569                 case CMD_TEXTUREWAD+27:
570                 case CMD_TEXTUREWAD+28:
571                 case CMD_TEXTUREWAD+29:
572                 case CMD_TEXTUREWAD+30:
573                 case CMD_TEXTUREWAD+31:
574                         Sys_BeginWait ();
575                         Texture_ShowDirectory (LOWORD(wParam));
576                         SetInspectorMode(W_TEXTURE);
577                         break;
578
579 //
580 // bsp menu
581 //
582                 case CMD_BSPCOMMAND:
583                 case CMD_BSPCOMMAND+1:
584                 case CMD_BSPCOMMAND+2:
585                 case CMD_BSPCOMMAND+3:
586                 case CMD_BSPCOMMAND+4:
587                 case CMD_BSPCOMMAND+5:
588                 case CMD_BSPCOMMAND+6:
589                 case CMD_BSPCOMMAND+7:
590                 case CMD_BSPCOMMAND+8:
591                 case CMD_BSPCOMMAND+9:
592                 case CMD_BSPCOMMAND+10:
593                 case CMD_BSPCOMMAND+11:
594                 case CMD_BSPCOMMAND+12:
595                 case CMD_BSPCOMMAND+13:
596                 case CMD_BSPCOMMAND+14:
597                 case CMD_BSPCOMMAND+15:
598                 case CMD_BSPCOMMAND+16:
599                 case CMD_BSPCOMMAND+17:
600                 case CMD_BSPCOMMAND+18:
601                 case CMD_BSPCOMMAND+19:
602                 case CMD_BSPCOMMAND+20:
603                 case CMD_BSPCOMMAND+21:
604                 case CMD_BSPCOMMAND+22:
605                 case CMD_BSPCOMMAND+23:
606                 case CMD_BSPCOMMAND+24:
607                 case CMD_BSPCOMMAND+25:
608                 case CMD_BSPCOMMAND+26:
609                 case CMD_BSPCOMMAND+27:
610                 case CMD_BSPCOMMAND+28:
611                 case CMD_BSPCOMMAND+29:
612                 case CMD_BSPCOMMAND+30:
613                 case CMD_BSPCOMMAND+31:
614                         {
615                                 extern  char    *bsp_commands[256];
616
617                                 RunBsp (bsp_commands[LOWORD(wParam-CMD_BSPCOMMAND)]);
618                         }
619                         break;
620
621 //
622 // misc menu
623 //
624                 case ID_MISC_BENCHMARK:
625                         SendMessage ( g_qeglobals.d_hwndCamera,
626                         WM_USER+267,    0, 0);
627                         break;
628
629                 case ID_TEXTUREBK:
630                         DoColor(COLOR_TEXTUREBACK);
631                         Sys_UpdateWindows (W_ALL);
632                         break;
633
634                 case ID_MISC_SELECTENTITYCOLOR:
635                         {
636                                 extern int inspector_mode;
637
638                                 if ( ( inspector_mode == W_ENTITY ) && DoColor(COLOR_ENTITY) == true )
639                                 {
640                                         extern void AddProp( void );
641
642                                         char buffer[100];
643
644                                         sprintf( buffer, "%f %f %f", g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][0],
645                                                 g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][1],
646                                                 g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][2] );
647
648                                         SetWindowText( hwndEnt[EntValueField], buffer );
649                                         SetWindowText( hwndEnt[EntKeyField], "_color" );
650                                         AddProp();
651                                 }
652                                 Sys_UpdateWindows( W_ALL );
653                         }
654                         break;
655
656                 case ID_MISC_PRINTXY:
657                         WXY_Print();
658                         break;
659
660                 case ID_COLORS_XYBK:
661                         DoColor(COLOR_GRIDBACK);
662                         Sys_UpdateWindows (W_ALL);
663                         break;
664
665                 case ID_COLORS_MAJOR:
666                         DoColor(COLOR_GRIDMAJOR);
667                         Sys_UpdateWindows (W_ALL);
668                         break;
669
670                 case ID_COLORS_MINOR:
671                         DoColor(COLOR_GRIDMINOR);
672                         Sys_UpdateWindows (W_ALL);
673                         break;
674
675                 case ID_MISC_GAMMA:
676                         DoGamma();
677                         break;
678
679                 case ID_MISC_FINDBRUSH:
680                         DoFind();
681                         break;
682
683                 case ID_MISC_NEXTLEAKSPOT:
684                         Pointfile_Next();
685                         break;
686                 case ID_MISC_PREVIOUSLEAKSPOT:
687                         Pointfile_Prev();
688                         break;
689
690 //
691 // brush menu
692 //
693                 case ID_BRUSH_3SIDED:
694                         Brush_MakeSided (3);
695                         break;
696                 case ID_BRUSH_4SIDED:
697                         Brush_MakeSided (4);
698                         break;
699                 case ID_BRUSH_5SIDED:
700                         Brush_MakeSided (5);
701                         break;
702                 case ID_BRUSH_6SIDED:
703                         Brush_MakeSided (6);
704                         break;
705                 case ID_BRUSH_7SIDED:
706                         Brush_MakeSided (7);
707                         break;
708                 case ID_BRUSH_8SIDED:
709                         Brush_MakeSided (8);
710                         break;
711                 case ID_BRUSH_9SIDED:
712                         Brush_MakeSided (9);
713                         break;
714                 case ID_BRUSH_ARBITRARYSIDED:
715                         DoSides ();
716                         break;
717
718 //
719 // select menu
720 //
721                 case ID_BRUSH_FLIPX:
722                         Select_FlipAxis (0);
723                         break;
724                 case ID_BRUSH_FLIPY:
725                         Select_FlipAxis (1);
726                         break;
727                 case ID_BRUSH_FLIPZ:
728                         Select_FlipAxis (2);
729                         break;
730                 case ID_BRUSH_ROTATEX:
731                         Select_RotateAxis (0, 90);
732                         break;
733                 case ID_BRUSH_ROTATEY:
734                         Select_RotateAxis (1, 90);
735                         break;
736                 case ID_BRUSH_ROTATEZ:
737                         Select_RotateAxis (2, 90);
738                         break;
739
740                 case ID_SELECTION_ARBITRARYROTATION:
741                         DoRotate ();
742                         break;
743
744                 case ID_SELECTION_UNGROUPENTITY:
745                         Select_Ungroup ();
746                         break;
747
748                 case ID_SELECTION_CONNECT:
749                         ConnectEntities ();
750                         break;
751
752                 case ID_SELECTION_DRAGVERTECIES:
753                         if (g_qeglobals.d_select_mode == sel_vertex)
754                         {
755                                 g_qeglobals.d_select_mode = sel_brush;
756                                 Sys_UpdateWindows (W_ALL);
757                         }
758                         else
759                         {
760                                 SetupVertexSelection ();
761                                 if (g_qeglobals.d_numpoints)
762                                         g_qeglobals.d_select_mode = sel_vertex;
763                         }
764                         break;
765                 case ID_SELECTION_DRAGEDGES:
766                         if (g_qeglobals.d_select_mode == sel_edge)
767                         {
768                                 g_qeglobals.d_select_mode = sel_brush;
769                                 Sys_UpdateWindows (W_ALL);
770                         }
771                         else
772                         {
773                                 SetupVertexSelection ();
774                                 if (g_qeglobals.d_numpoints)
775                                         g_qeglobals.d_select_mode = sel_edge;
776                         }
777                         break;
778
779                 case ID_SELECTION_SELECTPARTIALTALL:
780                         Select_PartialTall ();
781                         break;
782                 case ID_SELECTION_SELECTCOMPLETETALL:
783                         Select_CompleteTall ();
784                         break;
785                 case ID_SELECTION_SELECTTOUCHING:
786                         Select_Touching ();
787                         break;
788                 case ID_SELECTION_SELECTINSIDE:
789                         Select_Inside ();
790                         break;
791                 case ID_SELECTION_CSGSUBTRACT:
792                         CSG_Subtract ();
793                         break;
794                 case ID_SELECTION_MAKEHOLLOW:
795                         CSG_MakeHollow ();
796                         break;
797
798                 case ID_SELECTION_CLONE:
799                         Select_Clone ();
800                         break;
801                 case ID_SELECTION_DELETE:
802                         Select_Delete ();
803                         break;
804                 case ID_SELECTION_DESELECT:
805                         Select_Deselect ();
806                         break;
807
808                 case ID_SELECTION_MAKE_DETAIL:
809                         Select_MakeDetail ();
810                         break;
811                 case ID_SELECTION_MAKE_STRUCTURAL:
812                         Select_MakeStructural ();
813                         break;
814
815
816 //
817 // region menu
818 //
819                 case ID_REGION_OFF:
820                         Map_RegionOff ();
821                         break;
822                 case ID_REGION_SETXY:
823                         Map_RegionXY ();
824                         break;
825                 case ID_REGION_SETTALLBRUSH:
826                         Map_RegionTallBrush ();
827                         break;
828                 case ID_REGION_SETBRUSH:
829                         Map_RegionBrush ();
830                         break;
831                 case ID_REGION_SETSELECTION:
832                         Map_RegionSelectedBrushes ();
833                         break;
834
835                 case IDMRU+1:
836                 case IDMRU+2:
837                 case IDMRU+3:
838                 case IDMRU+4:
839                 case IDMRU+5:
840                 case IDMRU+6:
841                 case IDMRU+7:
842                 case IDMRU+8:
843                 case IDMRU+9:
844                         DoMru(hWnd,LOWORD(wParam));
845                         break;
846
847 //
848 // help menu
849 //
850
851                 case ID_HELP_ABOUT:
852                         DoAbout();
853                         break;
854
855                 default:
856             return FALSE;
857     }
858
859     return TRUE;
860 }
861
862 /*
863 ============
864 WMAIN_WndProc
865 ============
866 */
867 LONG WINAPI WMAIN_WndProc (
868     HWND    hWnd,
869     UINT    uMsg,
870     WPARAM  wParam,
871     LPARAM  lParam)
872 {
873     LONG    lRet = 1;
874     RECT        rect;
875         HDC             maindc;
876
877     GetClientRect(hWnd, &rect);
878
879     switch (uMsg)
880     {
881         case WM_TIMER:
882                 QE_CountBrushesAndUpdateStatusBar();
883                 QE_CheckAutoSave();
884                 return 0;
885
886         case WM_DESTROY:
887                 SaveMruInReg(g_qeglobals.d_lpMruMenu,"Software\\id\\QuakeEd4\\MRU");
888                 DeleteMruMenu(g_qeglobals.d_lpMruMenu);
889                 PostQuitMessage(0);
890                 KillTimer( hWnd, QE_TIMER0 );
891                 return 0;
892
893         case WM_CREATE:
894         maindc = GetDC(hWnd);
895 //          QEW_SetupPixelFormat(maindc, false);
896                 g_qeglobals.d_lpMruMenu = CreateMruMenuDefault();
897                 LoadMruInReg(g_qeglobals.d_lpMruMenu,"Software\\id\\QuakeEd4\\MRU");
898
899                 // Refresh the File menu.
900                 PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(hWnd),0),
901                                 ID_FILE_EXIT);
902
903                 return 0;
904
905         case WM_SIZE:
906                 // resize the status window
907                 MoveWindow( g_qeglobals.d_hwndStatus, -100, 100, 10, 10, true);
908                 return 0;
909
910         case WM_KEYDOWN:
911                 return QE_KeyDown (wParam);
912
913         case WM_CLOSE:
914         /* call destroy window to cleanup and go away */
915                 SaveWindowState(g_qeglobals.d_hwndXY, "xywindow");
916                 SaveWindowState(g_qeglobals.d_hwndCamera, "camerawindow");
917                 SaveWindowState(g_qeglobals.d_hwndZ, "zwindow");
918                 SaveWindowState(g_qeglobals.d_hwndEntity, "EntityWindow");
919                 SaveWindowState(g_qeglobals.d_hwndMain, "mainwindow");
920
921                 // FIXME: is this right?
922                 SaveRegistryInfo("SavedInfo", &g_qeglobals.d_savedinfo, sizeof(g_qeglobals.d_savedinfo));
923         DestroyWindow (hWnd);
924                 return 0;
925
926     case WM_COMMAND:
927                 return CommandHandler (hWnd, wParam, lParam);
928                 return 0;
929     }
930
931     return DefWindowProc (hWnd, uMsg, wParam, lParam);
932 }
933
934
935
936
937 /*
938 ==============
939 Main_Create
940 ==============
941 */
942 void Main_Create (HINSTANCE hInstance)
943 {
944     WNDCLASS   wc;
945         int                i;
946         HMENU      hMenu;
947
948     /* Register the camera class */
949         memset (&wc, 0, sizeof(wc));
950
951     wc.style         = 0;
952     wc.lpfnWndProc   = (WNDPROC)WMAIN_WndProc;
953     wc.cbClsExtra    = 0;
954     wc.cbWndExtra    = 0;
955     wc.hInstance     = hInstance;
956     wc.hIcon         = 0;
957     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
958     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
959     wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
960     wc.lpszClassName = "QUAKE_MAIN";
961
962     if (!RegisterClass (&wc) )
963         Error ("WCam_Register: failed");
964
965
966         g_qeglobals.d_hwndMain = CreateWindow ("QUAKE_MAIN" ,
967                 "QuakeEd 3",
968                 WS_OVERLAPPEDWINDOW |
969                 WS_CLIPSIBLINGS |
970                 WS_CLIPCHILDREN,
971                 0,0,screen_width,screen_height+GetSystemMetrics(SM_CYSIZE),     // size
972                 0,
973                 0,              // no menu
974                 hInstance,
975                 NULL);
976         if (!g_qeglobals.d_hwndMain)
977                 Error ("Couldn't create main window");
978
979         /* create a timer so that we can count brushes */
980         SetTimer( g_qeglobals.d_hwndMain,
981                           QE_TIMER0,
982                           1000,
983                       NULL );
984
985         LoadWindowState(g_qeglobals.d_hwndMain, "mainwindow");
986
987         s_hwndToolbar = CreateToolBar(hInstance);
988
989         g_qeglobals.d_hwndStatus = CreateMyStatusWindow(hInstance);
990
991         //
992         // load misc info from registry
993         //
994         i = sizeof(g_qeglobals.d_savedinfo);
995         LoadRegistryInfo("SavedInfo", &g_qeglobals.d_savedinfo, &i);
996
997         if (g_qeglobals.d_savedinfo.iSize != sizeof(g_qeglobals.d_savedinfo))
998         {
999                 // fill in new defaults
1000
1001                 g_qeglobals.d_savedinfo.iSize = sizeof(g_qeglobals.d_savedinfo);
1002                 g_qeglobals.d_savedinfo.fGamma = 1.0;
1003                 g_qeglobals.d_savedinfo.iTexMenu = ID_VIEW_NEAREST;
1004
1005                 g_qeglobals.d_savedinfo.exclude = 0;
1006                 g_qeglobals.d_savedinfo.show_coordinates = true;
1007                 g_qeglobals.d_savedinfo.show_names       = true;
1008
1009                 for (i=0 ; i<3 ; i++)
1010                 {
1011                         g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25;
1012                         g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0;
1013                         g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.75;
1014                         g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5;
1015                         g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25;
1016                 }
1017         }
1018
1019         if ( ( hMenu = GetMenu( g_qeglobals.d_hwndMain ) ) != 0 )
1020         {
1021                 /*
1022                 ** by default all of these are checked because that's how they're defined in the menu editor
1023                 */
1024                 if ( !g_qeglobals.d_savedinfo.show_names )
1025                         CheckMenuItem( hMenu, ID_VIEW_SHOWNAMES, MF_BYCOMMAND | MF_UNCHECKED );
1026                 if ( !g_qeglobals.d_savedinfo.show_coordinates )
1027                         CheckMenuItem( hMenu, ID_VIEW_SHOWCOORDINATES, MF_BYCOMMAND | MF_UNCHECKED );
1028
1029                 if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS )
1030                         CheckMenuItem( hMenu, ID_VIEW_SHOWLIGHTS, MF_BYCOMMAND | MF_UNCHECKED );
1031                 if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT )
1032                         CheckMenuItem( hMenu, ID_VIEW_ENTITY, MF_BYCOMMAND | MF_UNCHECKED );
1033                 if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS )
1034                         CheckMenuItem( hMenu, ID_VIEW_SHOWPATH, MF_BYCOMMAND | MF_UNCHECKED );
1035                 if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_WATER )
1036                         CheckMenuItem( hMenu, ID_VIEW_SHOWWATER, MF_BYCOMMAND | MF_UNCHECKED );
1037                 if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD )
1038                         CheckMenuItem( hMenu, ID_VIEW_SHOWWORLD, MF_BYCOMMAND | MF_UNCHECKED );
1039                 if ( g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP )
1040                         CheckMenuItem( hMenu, ID_VIEW_SHOWCLIP, MF_BYCOMMAND | MF_UNCHECKED );
1041         }
1042
1043         ShowWindow (g_qeglobals.d_hwndMain, SW_SHOWDEFAULT);
1044 }
1045
1046
1047 /*
1048 =============================================================
1049
1050 REGISTRY INFO
1051
1052 =============================================================
1053 */
1054
1055 BOOL SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize)
1056 {
1057         LONG lres;
1058         DWORD dwDisp;
1059         HKEY  hKeyId;
1060
1061         lres = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\id\\QuakeEd4", 0, NULL,
1062                         REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyId, &dwDisp);
1063
1064         if (lres != ERROR_SUCCESS)
1065                 return FALSE;
1066
1067         lres = RegSetValueEx(hKeyId, pszName, 0, REG_BINARY, pvBuf, lSize);
1068
1069         RegCloseKey(hKeyId);
1070
1071         if (lres != ERROR_SUCCESS)
1072                 return FALSE;
1073
1074         return TRUE;
1075 }
1076
1077 BOOL LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize)
1078 {
1079         HKEY  hKey;
1080         long lres, lType, lSize;
1081
1082         if (plSize == NULL)
1083                 plSize = &lSize;
1084
1085         lres = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\id\\QuakeEd4", 0, KEY_READ, &hKey);
1086
1087         if (lres != ERROR_SUCCESS)
1088                 return FALSE;
1089
1090         lres = RegQueryValueEx(hKey, pszName, NULL, &lType, pvBuf, plSize);
1091
1092         RegCloseKey(hKey);
1093
1094         if (lres != ERROR_SUCCESS)
1095                 return FALSE;
1096
1097         return TRUE;
1098 }
1099
1100 BOOL SaveWindowState(HWND hWnd, const char *pszName)
1101 {
1102         RECT rc;
1103
1104         GetWindowRect(hWnd, &rc);
1105         if (hWnd != g_qeglobals.d_hwndMain)
1106                 MapWindowPoints(NULL, g_qeglobals.d_hwndMain, (POINT *)&rc, 2);
1107         return SaveRegistryInfo(pszName, &rc, sizeof(rc));
1108 }
1109
1110
1111 BOOL LoadWindowState(HWND hWnd, const char *pszName)
1112 {
1113         RECT rc;
1114         LONG lSize = sizeof(rc);
1115
1116         if (LoadRegistryInfo(pszName, &rc, &lSize))
1117         {
1118                 if (rc.left < 0)
1119                         rc.left = 0;
1120                 if (rc.top < 0)
1121                         rc.top = 0;
1122                 if (rc.right < rc.left + 16)
1123                         rc.right = rc.left + 16;
1124                 if (rc.bottom < rc.top + 16)
1125                         rc.bottom = rc.top + 16;
1126
1127                 MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left,
1128                                 rc.bottom - rc.top, FALSE);
1129                 return TRUE;
1130         }
1131
1132         return FALSE;
1133 }
1134
1135 /*
1136 ===============================================================
1137
1138   STATUS WINDOW
1139
1140 ===============================================================
1141 */
1142
1143 void Sys_UpdateStatusBar( void )
1144 {
1145         extern int   g_numbrushes, g_numentities;
1146
1147         char numbrushbuffer[100]="";
1148
1149         sprintf( numbrushbuffer, "Brushes: %d Entities: %d", g_numbrushes, g_numentities );
1150
1151         Sys_Status( numbrushbuffer, 2 );
1152 }
1153
1154 void Sys_Status(const char *psz, int part )
1155 {
1156         SendMessage(g_qeglobals.d_hwndStatus, SB_SETTEXT, part, (LPARAM)psz);
1157 }
1158
1159 static HWND CreateMyStatusWindow(HINSTANCE hInst)
1160 {
1161         HWND hWnd;
1162         int partsize[3] = { 300, 1100, -1 };
1163
1164         hWnd = CreateWindowEx( WS_EX_TOPMOST, // no extended styles
1165             STATUSCLASSNAME,                 // status bar
1166             "",                              // no text
1167             WS_CHILD | WS_BORDER | WS_VISIBLE,  // styles
1168             -100, -100, 10, 10,              // x, y, cx, cy
1169             g_qeglobals.d_hwndMain,          // parent window
1170             (HMENU)100,                      // window ID
1171             hInst,                           // instance
1172             NULL);                                                       // window data
1173
1174         SendMessage( hWnd, SB_SETPARTS, 3, ( long ) partsize );
1175
1176         return hWnd;
1177 }
1178
1179 //==============================================================
1180
1181 #define NUMBUTTONS 15
1182 HWND CreateToolBar(HINSTANCE hinst)
1183 {
1184     HWND hwndTB;
1185     TBADDBITMAP tbab;
1186     TBBUTTON tbb[NUMBUTTONS];
1187
1188      // Ensure that the common control DLL is loaded.
1189
1190     InitCommonControls();
1191
1192     // Create a toolbar that the user can customize and that has a
1193     // tooltip associated with it.
1194
1195     hwndTB = CreateWindowEx(0, TOOLBARCLASSNAME, (LPSTR) NULL,
1196         WS_CHILD | TBSTYLE_TOOLTIPS | CCS_ADJUSTABLE | WS_BORDER,
1197         0, 0, 0, 0, g_qeglobals.d_hwndMain, (HMENU) IDR_TOOLBAR1, hinst, NULL);
1198
1199     // Send the TB_BUTTONSTRUCTSIZE message, which is required for
1200     // backward compatibility.
1201
1202     SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
1203
1204     // Add the bitmap containing button images to the toolbar.
1205
1206     tbab.hInst = hinst;
1207     tbab.nID   = IDR_TOOLBAR1;
1208     SendMessage(hwndTB, TB_ADDBITMAP, (WPARAM)NUMBUTTONS, (WPARAM) &tbab);
1209
1210     // Fill the TBBUTTON array with button information, and add the
1211     // buttons to the toolbar.
1212
1213     tbb[0].iBitmap = 0;
1214     tbb[0].idCommand = ID_BRUSH_FLIPX;
1215     tbb[0].fsState = TBSTATE_ENABLED;
1216     tbb[0].fsStyle = TBSTYLE_BUTTON;
1217     tbb[0].dwData = 0;
1218     tbb[0].iString = 0;
1219
1220     tbb[1].iBitmap = 2;
1221     tbb[1].idCommand = ID_BRUSH_FLIPY;
1222     tbb[1].fsState = TBSTATE_ENABLED;
1223     tbb[1].fsStyle = TBSTYLE_BUTTON;
1224     tbb[1].dwData = 0;
1225     tbb[1].iString = 0;
1226
1227     tbb[2].iBitmap = 4;
1228     tbb[2].idCommand = ID_BRUSH_FLIPZ;
1229     tbb[2].fsState = TBSTATE_ENABLED;
1230     tbb[2].fsStyle = TBSTYLE_BUTTON;
1231     tbb[2].dwData = 0;
1232     tbb[2].iString = 0;
1233
1234     tbb[3].iBitmap = 1;
1235     tbb[3].idCommand = ID_BRUSH_ROTATEX;
1236     tbb[3].fsState = TBSTATE_ENABLED;
1237     tbb[3].fsStyle = TBSTYLE_BUTTON;
1238     tbb[3].dwData = 0;
1239     tbb[3].iString = 0;
1240
1241     tbb[4].iBitmap = 3;
1242     tbb[4].idCommand = ID_BRUSH_ROTATEY;
1243     tbb[4].fsState = TBSTATE_ENABLED;
1244     tbb[4].fsStyle = TBSTYLE_BUTTON;
1245     tbb[4].dwData = 0;
1246     tbb[4].iString = 0;
1247
1248     tbb[5].iBitmap = 5;
1249     tbb[5].idCommand = ID_BRUSH_ROTATEZ;
1250     tbb[5].fsState = TBSTATE_ENABLED;
1251     tbb[5].fsStyle = TBSTYLE_BUTTON;
1252     tbb[5].dwData = 0;
1253     tbb[5].iString = 0;
1254
1255     tbb[6].iBitmap = 6;
1256     tbb[6].idCommand = ID_SELECTION_SELECTCOMPLETETALL;
1257     tbb[6].fsState = TBSTATE_ENABLED;
1258     tbb[6].fsStyle = TBSTYLE_BUTTON;
1259     tbb[6].dwData = 0;
1260     tbb[6].iString = 0;
1261
1262     tbb[7].iBitmap = 7;
1263     tbb[7].idCommand = ID_SELECTION_SELECTTOUCHING;
1264     tbb[7].fsState = TBSTATE_ENABLED;
1265     tbb[7].fsStyle = TBSTYLE_BUTTON;
1266     tbb[7].dwData = 0;
1267     tbb[7].iString = 0;
1268
1269     tbb[8].iBitmap = 8;
1270     tbb[8].idCommand = ID_SELECTION_SELECTPARTIALTALL;
1271     tbb[8].fsState = TBSTATE_ENABLED;
1272     tbb[8].fsStyle = TBSTYLE_BUTTON;
1273     tbb[8].dwData = 0;
1274     tbb[8].iString = 0;
1275
1276
1277     tbb[9].iBitmap = 9;
1278     tbb[9].idCommand = ID_SELECTION_SELECTINSIDE;
1279     tbb[9].fsState = TBSTATE_ENABLED;
1280     tbb[9].fsStyle = TBSTYLE_BUTTON;
1281     tbb[9].dwData = 0;
1282     tbb[9].iString = 0;
1283
1284     tbb[10].iBitmap = 10;
1285     tbb[10].idCommand = ID_SELECTION_CSGSUBTRACT;
1286     tbb[10].fsState = TBSTATE_ENABLED;
1287     tbb[10].fsStyle = TBSTYLE_BUTTON;
1288     tbb[10].dwData = 0;
1289     tbb[10].iString = 0;
1290
1291
1292     tbb[11].iBitmap = 11;
1293     tbb[11].idCommand = ID_SELECTION_MAKEHOLLOW;
1294     tbb[11].fsState = TBSTATE_ENABLED;
1295     tbb[11].fsStyle = TBSTYLE_BUTTON;
1296     tbb[11].dwData = 0;
1297     tbb[11].iString = 0;
1298
1299     tbb[12].iBitmap = 12;
1300     tbb[12].idCommand = ID_TEXTURES_WIREFRAME;
1301     tbb[12].fsState = TBSTATE_ENABLED;
1302     tbb[12].fsStyle = TBSTYLE_BUTTON;
1303     tbb[12].dwData = 0;
1304     tbb[12].iString = 0;
1305
1306     tbb[13].iBitmap = 13;
1307     tbb[13].idCommand = ID_TEXTURES_FLATSHADE;
1308     tbb[13].fsState = TBSTATE_ENABLED;
1309     tbb[13].fsStyle = TBSTYLE_BUTTON;
1310     tbb[13].dwData = 0;
1311     tbb[13].iString = 0;
1312
1313     tbb[14].iBitmap = 14;
1314     tbb[14].idCommand = ID_VIEW_TRILINEAR;
1315     tbb[14].fsState = TBSTATE_ENABLED;
1316     tbb[14].fsStyle = TBSTYLE_BUTTON;
1317     tbb[14].dwData = 0;
1318     tbb[14].iString = 0;
1319
1320     SendMessage(hwndTB, TB_ADDBUTTONS, (WPARAM)NUMBUTTONS,
1321         (LPARAM) (LPTBBUTTON) &tbb);
1322
1323     ShowWindow(hwndTB, SW_SHOW);
1324
1325     return hwndTB;
1326 }
1327