2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 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 GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 // Leonardo Zide (leo@lokigames.com)
30 #include <glib/gi18n.h>
32 #if defined ( __linux__ ) || defined ( __APPLE__ )
34 #include <sys/types.h>
48 #define PREF_SECTION "Prefs"
49 #define INTERNAL_SECTION "Internals"
50 #define MOUSE_KEY "MouseButtons"
51 #define WINDOW_KEY "QE4StyleWindows"
52 #define LAYOUT_KEY "WindowLayout"
53 #define RUNQ2_KEY "RunQuake2Run"
54 #define TLOCK_KEY "TextureLock"
55 #define RLOCK_KEY "RotateLock"
56 #define LOADLAST_KEY "LoadLast"
57 #define LOADLASTMAP_KEY "LoadLastMap"
58 #define LASTPROJ_KEY "LastProject"
59 #define LASTPROJVER_KEY "LastProjectKey"
60 #define LASTMAP_KEY "LastMap"
61 #define FACE_KEY "NewFaceGrab"
62 #define BSP_KEY "InternalBSP"
63 #define RCLICK_KEY "NewRightClick"
64 #define VERTEX_KEY "NewVertex"
65 #define AUTOSAVE_KEY "Autosave"
66 #define AUTOSAVETIME_KEY "AutosaveMinutes"
67 #define PAK_KEY "UsePAK"
68 #define NEWAPPLY_KEY "ApplyDismissesSurface"
69 #define HACK_KEY "Gatewayescapehack"
70 #define TEXTURE_KEY "NewTextureWindowStuff"
71 #define TINYBRUSH_KEY "CleanTinyBrushes"
72 #define TINYSIZE_KEY "CleanTinyBrusheSize"
73 #define SNAPSHOT_KEY "Snapshots"
74 #define MOVESPEED_KEY "MoveSpeed"
75 #define ANGLESPEED_KEY "AngleSpeed"
76 #define SETGAME_KEY "UseSetGame"
77 #define CAMXYUPDATE_KEY "CamXYUpdate"
78 #define CAMDRAGMULTISELECT_KEY "CamDragMultiSelect"
79 #define CAMFREELOOK_KEY "CamFreeLook"
80 #define CAMINVERSEMOUSE_KEY "CamInverseMouse"
81 #define CAMDISCRETE_KEY "CamDiscrete"
82 #define LIGHTDRAW_KEY "NewLightStyle"
83 #define WHATGAME_KEY "WhichGame"
84 #define CUBICCLIP_KEY "CubicClipping"
85 #define CUBICSCALE_KEY "CubicScale"
86 #define ALTEDGE_KEY "ALTEdgeDrag"
87 #define FACECOLORS_KEY "FaceColors"
88 #define SNAPT_KEY "SnapT"
89 #define XZVIS_KEY "XZVIS"
90 #define YZVIS_KEY "YZVIS"
91 #define ZVIS_KEY "ZVIS"
92 #define SIZEPAINT_KEY "SizePainting"
93 #define DLLENTITIES_KEY "DLLEntities"
94 #define DETACHABLEMENUS_KEY "DetachableMenus"
95 #define PATCHTOOLBAR_KEY "PatchToolBar"
96 #define WIDETOOLBAR_KEY "WideToolBar"
97 #define PLUGINTOOLBAR_KEY "PluginToolBar"
98 #define NOCLAMP_KEY "NoClamp"
99 #define SNAP_KEY "Snap"
100 #define PREFAB_KEY "PrefabPath"
101 #define USERINI_KEY "UserINIPath"
102 #define ROTATION_KEY "Rotation"
103 #define BUGGYICD_KEY "BuggyICD"
104 #define CHASEMOUSE_KEY "ChaseMouse"
105 #define ENTITYSHOW_KEY "EntityShow"
106 #define TEXTURESCALE_KEY "TextureScale"
107 #define TEXTURESCROLLBAR_KEY "TextureScrollbar"
108 #define DISPLAYLISTS_KEY "UseDisplayLists"
109 #define ANTIALIASEDLINES_KEY "UseAntialiasedPointsAndLines" // Fishman - Add antialiazed points and lines support. 09/03/00
110 #define NORMALIZECOLORS_KEY "NormalizeColors"
111 #define SHADERS_KEY "UseShaders"
112 #define SWITCHCLIP_KEY "SwitchClipKey"
113 #define SELWHOLEENTS_KEY "SelectWholeEntitiesKey"
114 #define TEXTURESUBSET_KEY "UseTextureSubsetLoading"
115 #define TEXTUREQUALITY_KEY "TextureQuality"
116 #define SHOWSHADERS_KEY "ShowShaders"
117 #define SHADERTEST_KEY "ShaderTest"
118 #define GLLIGHTING_KEY "UseGLLighting"
119 #define LOADSHADERS_KEY "LoadShaders"
120 #define NOSTIPPLE_KEY "NoStipple"
121 #define UNDOLEVELS_KEY "UndoLevels"
122 #define VERTEXMODE_KEY "VertexSplit"
123 #define ENGINEPATH_KEY "EnginePath"
124 #define ENGINE_KEY "Engine"
125 #define LOGCONSOLE_KEY "LogConsole"
126 #define SELECTCURVES_KEY "SelectCurves"
127 #define SELECTMODELS_KEY "SelectModels"
128 #define SHADERLISTONLY_KEY "ShowShaderlistOnly"
129 #define WATCHBSP_KEY "WatchBSP"
130 #define LEAKSTOP_KEY "LeakStop"
131 #define DOSLEEP_KEY "SleepMode"
132 #define SUBDIVISIONS_KEY "Subdivisions"
133 #define DEFAULTTEXURESCALE_KEY "DefaultTextureScale"
134 #define CLIPCAULK_KEY "ClipCaulk"
135 #define PATCHSHOWBOUNDS_KEY "PatchShowBounds"
136 #define NATIVEGUI_KEY "NativeGUI"
137 #define STARTONPRIMMON_KEY "StartOnPrimMon"
138 #define NOSYSMENUPOPUPS_KEY "NoSysMenuPopups"
139 #define SNAPTTOGRID_KEY "SnapTToGrid"
140 #define FLOATINGZ_KEY "FloatingZ"
141 #define TARGETFIX_KEY "TargetFix"
142 #define GLPOINTWORKAROUND_KEY "GlPointWorkaround" // Gef: Workaround for broken Kyro * gl driver 25-aug-2001
143 #define WHEELINC_KEY "WheelMouseInc"
144 #define PATCHBBOXSEL_KEY "PatchBBoxSel"
145 #define LASTLIGHTINTENSITY_KEY "LastLightIntensity"
146 #define CUSTOMSHADEREDITOR_KEY "UseCustomShaderEditor"
147 #define CUSTOMSHADEREDITORCOMMAND_KEY "CustomShaderEditorCommand"
148 #define TEXTURECOMPRESSIONFORMAT_KEY "TextureCompressionFormat"
149 #define LIGHTRADIUS_KEY "LightRadiuses"
150 #define Q3MAP2TEX_KEY "Q3Map2Tex"
153 #define ATIHACK_KEY "ATIHack"
156 #ifdef NVIDIA_AERO_HACK
157 #define NVAEROHACK_KEY "NvidiaAeroHack"
161 #define ENTITYSPLIT1_KEY "EntitySplit1"
162 #define ENTITYSPLIT2_KEY "EntitySplit2"
163 #define POSITIONX_KEY "PositionX"
164 #define POSITIONY_KEY "PositionY"
165 #define ENTITYWND_KEY "EntityWnd"
166 #define MAPINFOWND_KEY "MapInfoDlg"
167 #define CAMWND_KEY "CamWnd"
168 #define ZWND_KEY "ZWnd"
169 #define XYWND_KEY "XYWnd"
170 #define XZWND_KEY "XZWnd"
171 #define YZWND_KEY "YZWnd"
172 #define PATCHWND_KEY "PatchWnd"
173 #define SURFACEWND_KEY "SurfaceWnd"
174 #define ENTITYINFOWND_KEY "EntityInfoDlg"
175 #define WIDTH_KEY "Width"
176 #define HEIGHT_KEY "Height"
177 #define ZWIDTH_KEY "ZWidth"
178 #define XYHEIGHT_KEY "XYHeight"
179 #define XYWIDTH_KEY "XYWidth"
180 #define CAMWIDTH_KEY "CamWidth"
181 #define CAMHEIGHT_KEY "CamHeight"
182 #define ZFLOATWIDTH_KEY "ZWidthFloating"
183 #define STATE_KEY "State"
186 #define COUNT_KEY "Count"
187 #define FILE_KEY "File"
190 #define SI_TEXMENU_KEY "SI_TexMenu"
191 #define SI_GAMMA_KEY "SI_Gamma"
192 #define SI_COLORS_KEY "SI_Colors"
193 #define SI_EXCLUDE_KEY "SI_Exclude"
194 #define SI_INCLUDE_KEY "SI_Include"
195 #define SI_SURFACE_TEXDEF_KEY "SI_SurfaceTexdef"
196 #define SI_PATCH_TEXDEF_KEY "SI_PatchTexdef"
197 #define SI_AXISCOLORS_KEY "SI_AxisColors"
198 #define SI_SHOWNAMES_KEY "SI_ShowNames"
199 #define SI_SHOWCOORDS_KEY "SI_ShowCoords"
200 #define SI_SHOWANGLES_KEY "SI_ShowAngles"
201 #define SI_SHOWOUTLINES_KEY "SI_ShowOutlines"
202 #define SI_SHOWAXIS_KEY "SI_ShowAxis"
203 #define SI_NOSELOUTLINES_KEY "SI_NoSelectedOutlines"
204 #define SI_OUTLINESTYLE_KEY "SI_OutLineStyle"
207 #define TD_SCALE1_KEY "_Scale1"
208 #define TD_SCALE2_KEY "_Scale2"
209 #define TD_SHIFT1_KEY "_Shift1"
210 #define TD_SHIFT2_KEY "_Shift2"
211 #define TD_ROTATE_KEY "_Rotate"
216 #define WATCHBSP_DEF 1
218 #define LOADLAST_DEF 1
220 #define SUBDIVISIONS_DEF 4
222 void WindowPosition_Parse( window_position_t& m_value, const CString& value ){
223 if ( sscanf( value.GetBuffer(), "%d %d %d %d", &m_value.x, &m_value.y, &m_value.w, &m_value.h ) != 4 ) {
224 m_value.x = m_value.y = m_value.w = m_value.h = -1;
228 void WindowPosition_Write( const window_position_t& m_value, CString& value ){
230 sprintf( buffer, "%d %d %d %d", m_value.x, m_value.y, m_value.w, m_value.h );
235 CXMLPropertyBag::CXMLPropertyBag() {
241 // generic preference functions
243 void CXMLPropertyBag::PushAssignment( const char *name, PrefTypes_t type, void *pV ){
244 list<CPrefAssignment>::iterator iAssign;
245 for ( iAssign = mPrefAssignments.begin(); iAssign != mPrefAssignments.end(); iAssign++ )
247 if ( ( *iAssign ).mName == name ) {
248 // we have it already, check anyway
249 if ( pV != ( *iAssign ).mVal ) {
250 Sys_FPrintf( SYS_ERR, "PushAssignment, '%s' has different mVal\n", name );
255 // ok, it's not in our list yet
256 mPrefAssignments.push_front( CPrefAssignment( name, type, pV ) );
259 xmlNodePtr CXMLPropertyBag::EpairForName( const char *name ){
260 xmlNodePtr ret = NULL;
262 xmlNodePtr pNode = mpDocNode->children;
263 while ( pNode != NULL )
265 if ( pNode->type == XML_ELEMENT_NODE ) {
266 xmlAttrPtr tmp_attr_ptr = xmlHasProp( pNode, (xmlChar *)"name" );
267 if ( tmp_attr_ptr != NULL && !strcmp( name, (char *)tmp_attr_ptr->children->content ) ) {
269 Sys_FPrintf( SYS_WRN, "WARNING: dupe property in CXMLPropertyBag::EpairForName '%s'\n", name );
281 void CXMLPropertyBag::GetPref( const char *name, Str *pV, const char *V ){
282 xmlNodePtr pNode = EpairForName( name );
284 if ( pNode->children && pNode->children->content ) {
285 *pV = pNode->children->content;
288 // means the pref exists, and that the value is ""
294 pNode = xmlNewChild( mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)V );
295 xmlSetProp( pNode, (xmlChar *)"name", (xmlChar *)name );
297 // push the pref assignment if needed
298 PushAssignment( name, PREF_STR, pV );
301 void CXMLPropertyBag::GetPref( const char *name, int *pV, int V ){
303 if ( ( pNode = EpairForName( name ) ) && pNode->children && pNode->children->content ) {
304 *pV = atoi( (char *)pNode->children->content );
309 sprintf( s, "%d", V );
310 pNode = xmlNewChild( mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s );
311 xmlSetProp( pNode, (xmlChar *)"name", (xmlChar *)name );
314 // push the pref assignment if needed
315 PushAssignment( name, PREF_INT, pV );
318 void CXMLPropertyBag::GetPref( const char *name, bool *pV, bool V ){
320 if ( ( pNode = EpairForName( name ) ) && pNode->children && pNode->children->content ) {
321 if ( !strcmp( (char *)pNode->children->content, "true" ) ) {
332 V ? strcpy( s, "true" ) : strcpy( s, "false" );
333 pNode = xmlNewChild( mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s );
334 xmlSetProp( pNode, (xmlChar *)"name", (xmlChar *)name );
337 // push the pref assignment
338 PushAssignment( name, PREF_BOOL, pV );
341 void CXMLPropertyBag::GetPref( const char *name, float *pV, float V ){
343 if ( ( pNode = EpairForName( name ) ) && pNode->children && pNode->children->content ) {
344 *pV = atof( (char *)pNode->children->content );
349 sprintf( s, "%f", V );
350 pNode = xmlNewChild( mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s );
351 xmlSetProp( pNode, (xmlChar *)"name", (xmlChar *)name );
354 // push the pref assignment if needed
355 PushAssignment( name, PREF_FLOAT, pV );
358 void CXMLPropertyBag::GetPref( const char *name, float* pV, float* V ){
360 if ( ( pNode = EpairForName( name ) ) && pNode->children && pNode->children->content ) {
361 sscanf( (char *)pNode->children->content, "%f %f %f", &pV[0], &pV[1], &pV[2] );
366 sprintf( s, "%f %f %f", V[0], V[1], V[2] );
367 pNode = xmlNewChild( mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s );
368 xmlSetProp( pNode, (xmlChar *)"name", (xmlChar *)name );
373 // push the pref assignment if needed
374 PushAssignment( name, PREF_VEC3, pV );
377 void CXMLPropertyBag::GetPref( const char *name, window_position_t* pV, window_position_t V ){
379 if ( ( pNode = EpairForName( name ) ) && pNode->children && pNode->children->content ) {
380 WindowPosition_Parse( *pV, CString( (xmlChar *)pNode->children->content ) );
385 WindowPosition_Write( V, str );
386 pNode = xmlNewChild( mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)str.GetBuffer() );
387 xmlSetProp( pNode, (xmlChar *)"name", (xmlChar *)name );
390 // push the pref assignment if needed
391 PushAssignment( name, PREF_WNDPOS, pV );
394 void CXMLPropertyBag::UpdatePrefTree(){
395 // read the assignments and update the tree
396 list<CPrefAssignment>::iterator iPref;
397 for ( iPref = mPrefAssignments.begin(); iPref != mPrefAssignments.end(); iPref++ )
399 CPrefAssignment *pPref = &( *iPref );
404 pNode = EpairForName( pPref->mName.GetBuffer() );
405 // we never expect that the node could not be found, because this is supposed to happen
406 // after the tree was built with GetPref calls, never on a blank tree
408 Sys_FPrintf( SYS_ERR, "Unexpected EpairForName '%s' not found in UpdatePrefTree\n", pPref->mName.GetBuffer() );
411 switch ( ( *iPref ).mType )
414 xmlNodeSetContent( pNode, (const xmlChar *)( (Str *)pPref->mVal )->GetBuffer() );
417 sprintf( s, "%d", *(int *)pPref->mVal );
418 xmlNodeSetContent( pNode, (xmlChar *)s );
421 sprintf( s, "%f", *(float *)pPref->mVal );
422 xmlNodeSetContent( pNode, (xmlChar *)s );
425 *(bool *)pPref->mVal ? strcpy( s, "true" ) : strcpy( s, "false" );
426 xmlNodeSetContent( pNode, (xmlChar *)s );
430 float* v = (float*)pPref->mVal;
431 sprintf( s, "%f %f %f", v[0], v[1], v[2] );
432 xmlNodeSetContent( pNode, (xmlChar *)s );
438 WindowPosition_Write( *(window_position_t*)pPref->mVal, str );
439 xmlNodeSetContent( pNode, (xmlChar*)str.GetBuffer() );
446 void CXMLPropertyBag::Clear(){
457 void CXMLPropertyBag::ReadXMLFile( const char* pFilename ){
458 mpDoc = xmlParseFile( pFilename );
462 mpDocNode = mpDoc->children;
463 xmlAttrPtr tmp_attr_ptr = xmlHasProp( mpDocNode, (xmlChar *)"version" );
464 if ( strcmp( (char *)mpDocNode->name, "qpref" ) ) {
465 Sys_FPrintf( SYS_ERR, "Unrecognized node '%s' in '%s'\n", mpDocNode->name, mpDoc->URL );
469 else if ( tmp_attr_ptr != NULL && strcmp( (char*)tmp_attr_ptr->children->content, "1" ) ) {
470 Sys_FPrintf( SYS_ERR, "Wrong version '%s' in <qpref> node for '%s'\n", (char*)tmp_attr_ptr->children->content, mpDoc->URL );
474 Sys_Printf( "Opened XML property file: '%s'\n", pFilename );
479 // no document, create one
480 mpDoc = xmlNewDoc( (xmlChar *)"1.0" );
481 mpDocNode = xmlNewDocNode( mpDoc, NULL, (xmlChar *)"qpref", NULL );
482 xmlDocSetRootElement( mpDoc, mpDocNode );
483 xmlSetProp( mpDocNode, (xmlChar *)"version", (xmlChar *)"1" );
484 Sys_Printf( "XML property file '%s' invalid/not found, creating blank properties tree\n", pFilename );
488 qboolean CXMLPropertyBag::WriteXMLFile( const char* pFilename ){
489 int res = xmlSaveFormatFile( pFilename, mpDoc, 1 );
495 Sys_Printf( "Wrote XML property file '%s'\n", pFilename );
499 // =============================================================================
500 // Widget callbacks for PrefsDlg
502 #if !defined( WIN32 )
503 // browse for custom editor executable
504 static void OnBtnBrowseEditor( GtkWidget *widget, gpointer data ){
505 PrefsDlg *dlg = (PrefsDlg*)data;
507 const char *filename = file_dialog( g_PrefsDlg.GetWidget(), TRUE, _( "Executable for Custom Editor" ) );
509 if ( filename != NULL ) {
510 dlg->m_strEditorCommand = filename;
511 dlg->UpdateData( FALSE );
516 static void OnBtnBrowseprefab( GtkWidget *widget, gpointer data ){
517 PrefsDlg *dlg = (PrefsDlg*)data;
518 char *path = dlg->m_strPrefabPath;
519 if ( strlen( path ) == 0 ) {
520 path = g_strGameToolsPath;
522 char *dir = dir_dialog( g_PrefsDlg.GetWidget(), _( "Set prefab path" ), path );
523 dlg->UpdateData( TRUE );
529 dlg->m_strPrefabPath = strPath;
530 dlg->UpdateData( FALSE );
535 static void OnBtnBrowseuserini( GtkWidget *widget, gpointer data ){
536 PrefsDlg *dlg = (PrefsDlg*)data;
537 char *path = dlg->m_strUserPath;
538 if ( strlen( path ) == 0 ) {
539 path = g_strGameToolsPath;
542 const char *filename = file_dialog( g_PrefsDlg.GetWidget(), TRUE, _( "Find INI file" ), path );
544 if ( filename != NULL ) {
545 dlg->UpdateData( TRUE );
546 dlg->m_strUserPath = filename;
547 dlg->UpdateData( FALSE );
551 static void OnButtonClean( GtkWidget *widget, gpointer data ){
552 // make sure this is what the user wants
553 if ( gtk_MessageBox( g_PrefsDlg.GetWidget(), _( "This will close Radiant and clean the corresponding registry entries.\n"
554 "Next time you start Radiant it will be good as new. Do you wish to continue?" ),
555 _( "Reset Registry" ), MB_YESNO ) == IDYES ) {
556 PrefsDlg *dlg = (PrefsDlg*)data;
557 dlg->EndModal( IDCANCEL );
559 g_qeglobals.disable_ini = true;
560 remove( dlg->m_inipath->str );
562 sprintf( buf, "%sSavedInfo.bin", dlg->m_rc_path->str );
564 HandleCommand( NULL, GINT_TO_POINTER( ID_FILE_EXIT ) );
569 // =============================================================================
572 // IMPORTANT NOTE: the values here don't matter very much
573 // the actual intialization if you start with an empty .ini is done when loading the prefs for the first time
574 // profile_load_int takes an argument to use if the value is not found
575 PrefsDlg::PrefsDlg (){
578 m_nView = MainFrame::eRegular;
580 m_bInternalBSP = FALSE;
581 m_bRightClick = FALSE;
585 m_bLoadLastMap = FALSE;
586 m_bTextureWindow = FALSE;
587 m_bSnapShots = FALSE;
589 m_bCleanTiny = FALSE;
590 m_bCamXYUpdate = TRUE;
591 m_bCamDragMultiSelect = FALSE;
592 m_bCamFreeLook = TRUE;
593 m_bCamFreeLookStrafe = FALSE;
594 m_bCamInverseMouse = FALSE;
595 m_bCamDiscrete = TRUE;
596 m_bNewLightDraw = FALSE;
597 m_strPrefabPath = "";
600 m_bFaceColors = FALSE;
604 m_bSizePaint = FALSE;
605 m_bDLLEntities = FALSE;
607 m_bDetachableMenus = FALSE; // Most win32 users will find detachable menus annoying
609 m_bDetachableMenus = TRUE; // Linux/Apple users are used to them...
611 m_bPatchToolbar = TRUE;
612 m_bWideToolbar = TRUE;
613 m_bPluginToolbar = TRUE;
618 m_bChaseMouse = FALSE;
619 m_bTextureScrollbar = TRUE;
620 m_bDisplayLists = TRUE;
621 m_bAntialiasedPointsAndLines = FALSE; // Fishman - Add antialiazed points and lines support. 09/03/00
622 m_bShowShaders = FALSE;
624 m_bNoStipple = FALSE;
625 m_bVertexSplit = FALSE;
626 m_bSelectCurves = TRUE;
627 m_bSelectModels = TRUE;
628 m_nEntityShowState = ENTITY_SKINNED_BOXED;
630 m_bSwitchClip = FALSE;
631 m_bSelectWholeEntities = TRUE;
632 m_nTextureQuality = 3;
633 m_bShowShaders = TRUE;
634 m_bGLLighting = FALSE;
637 m_bTexturesShaderlistOnly = FALSE;
638 // paths to ini files
648 m_bFloatingZ = FALSE;
649 m_bGlPtWorkaround = FALSE; // Gef: Kyro/GL_POINTS workaround 25-aug-2001
651 m_bNativeGUI = FALSE;
652 m_bStartOnPrimMon = FALSE;
654 m_global_rc_path = NULL;
656 m_bUseWin32Editor = TRUE;
658 // custom shader editor options
659 m_bUseCustomEditor = FALSE;
660 m_strEditorCommand = "";
662 m_nLightRadiuses = 1;
663 m_bQ3Map2Texturing = TRUE;
665 m_bGlATIHack = FALSE;
667 #ifdef NVIDIA_AERO_HACK
668 m_bGlNvidiaAeroHack = TRUE;
669 m_bGlNvidiaAeroHackPrevState = -1; // -1 is uninitialized, 0 is FALSE, 1 is TRUE
674 =========================================================
675 Games selection dialog
676 =========================================================
680 #define TOOLS_ATTRIBUTE "gametools_win32"
681 #define ENGINE_ATTRIBUTE "engine_win32"
682 #define ENGINEPATH_ATTRIBUTE "enginepath_win32"
683 #define MP_ENGINE_ATTRIBUTE "mp_engine_win32"
684 #elif defined( __linux__ ) || defined ( __FreeBSD__ )
685 #define TOOLS_ATTRIBUTE "gametools_linux"
686 #define ENGINE_ATTRIBUTE "engine_linux"
687 #define ENGINEPATH_ATTRIBUTE "enginepath_linux"
688 #define MP_ENGINE_ATTRIBUTE "mp_engine_linux"
689 #elif defined( __APPLE__ )
690 #define TOOLS_ATTRIBUTE "gametools_macos"
691 #define ENGINE_ATTRIBUTE "engine_macos"
692 #define ENGINEPATH_ATTRIBUTE "enginepath_macos"
693 #define MP_ENGINE_ATTRIBUTE "mp_engine_macos"
695 #error "unsupported platform"
698 CGameDescription::CGameDescription( xmlDocPtr pDoc, const Str &GameFile ){
701 // read the user-friendly game name
702 xmlNodePtr pNode = mpDoc->children;
704 while ( strcmp( (const char*)pNode->name, "game" ) && pNode != NULL ) pNode = pNode->next;
706 ///< \todo add the file name (this node and gametools should all be part of CGameDescription anyway)
707 Error( "Didn't find 'game' node in the game description file '%s'\n", pDoc->URL );
709 // on win32, game tools path can now be specified relative to the exe's cwd
710 prop = (char*)xmlGetProp( pNode, (xmlChar*)TOOLS_ATTRIBUTE );
711 if ( prop == NULL ) {
712 Error( "Didn't find '"TOOLS_ATTRIBUTE "' node in the game description file '%s'\n", pDoc->URL );
717 _fullpath( full, prop, PATH_MAX );
719 strncpy( full, prop, PATH_MAX );
723 for ( p = full; *p != '\0'; p++ ) {
727 mGameToolsPath = full;
728 if ( p != full && *( p - 1 ) != '/' ) {
729 mGameToolsPath += "/";
734 prop = (char*)xmlGetProp( pNode, (xmlChar*)"name" );
735 if ( prop == NULL ) {
736 Sys_FPrintf( SYS_WRN, "Warning, 'name' attribute not found in '%s'\n", pDoc->URL );
737 mGameName = pDoc->URL;
745 mGameFile = GameFile;
747 prop = (char*)xmlGetProp( pNode, (xmlChar*)"quake2" );
748 if ( prop == NULL ) {
758 // if this is set, the open maps dialoge will open the engine path not the
759 // home dir for map loading and saving
760 prop = (char*)xmlGetProp( pNode, (xmlChar*)"no_maps_in_home" );
761 if ( prop == NULL ) {
763 noMapsInHome = false;
771 prop = (char*)xmlGetProp( pNode, (xmlChar*)"basegame" );
772 if ( prop == NULL ) {
774 mBaseGame = "baseq3";
783 prop = (char*)xmlGetProp( pNode, (const xmlChar*)ENGINE_ATTRIBUTE );
784 if ( prop == NULL ) {
786 mEngine = "quake3.exe";
790 mEngine = "Quake3.app";
799 prop = (char*)xmlGetProp( pNode, (const xmlChar*)MP_ENGINE_ATTRIBUTE );
800 if ( prop == NULL ) {
802 mMultiplayerEngine = "quake3.exe";
804 mMultiplayerEngine = "quake3";
806 mMultiplayerEngine = "Quake3.app";
811 mMultiplayerEngine = prop;
816 // on win32, engine path can now be specified relative to the exe's cwd
817 prop = (char*)xmlGetProp( pNode, (const xmlChar *)ENGINEPATH_ATTRIBUTE );
818 if ( prop != NULL ) {
821 _fullpath( full, prop, PATH_MAX );
823 strncpy( full, prop, PATH_MAX );
827 // process seperators
828 for ( p = full; *p != '\0'; p++ ) {
834 if ( p != full && *( p - 1 ) != '/' ) {
840 // if engine path was not specified in the .game, it implies we can guess it from the gametools path
841 // on win32, and for most game package, the gametools are installed with the game
842 char aux_path[PATH_MAX]; // aux
843 strcpy( aux_path, mGameToolsPath.GetBuffer() );
844 if ( ( aux_path[ strlen( aux_path ) - 1 ] == '/' ) || ( aux_path[ strlen( aux_path ) - 1 ] == '\\' ) ) {
845 aux_path[strlen( aux_path ) - 1] = '\0'; // strip ending '/' if any
847 char up_path[PATH_MAX]; // up one level
848 ExtractFilePath( aux_path, up_path );
849 mEnginePath = up_path;
853 #if defined ( __linux__ ) || defined ( __APPLE__ )
855 prop = (char*)xmlGetProp( pNode, (const xmlChar *)"prefix" );
856 if ( prop != NULL ) {
857 mUserPathPrefix = prop;
861 mShaderPath = xmlGetProp( pNode, (const xmlChar *)"shaderpath" );
862 if ( !mShaderPath.GetLength() ) {
863 mShaderPath = "scripts/";
864 mShaderlist = "scripts/shaderlist.txt";
868 AddSlash( mShaderPath );
869 mShaderlist = mShaderPath;
870 mShaderlist += "shaderlist.txt";
872 xmlChar* default_scale = xmlGetProp( pNode, (const xmlChar *)"default_scale" );
873 if ( default_scale ) {
874 mTextureDefaultScale = atof( (const char *)default_scale );
875 xmlFree( default_scale );
878 mTextureDefaultScale = 0.5f;
880 xmlChar* eclass_singleload = xmlGetProp( pNode, (const xmlChar*)"eclass_singleload" );
881 if ( eclass_singleload ) {
882 mEClassSingleLoad = true;
883 xmlFree( eclass_singleload );
886 mEClassSingleLoad = false;
888 xmlChar* no_patch = xmlGetProp( pNode, (const xmlChar *)"no_patch" );
896 xmlChar* caulk_shader = xmlGetProp( pNode, (const xmlChar *)"caulk_shader" );
897 if ( caulk_shader ) {
898 mCaulkShader = caulk_shader;
899 xmlFree( caulk_shader );
902 mCaulkShader = "textures/common/caulk";
906 void CGameDescription::Dump(){
908 if ( CGameDialog::GetNetrun() ) {
909 Sys_Printf( "Running in network mode, prefs path set to '%s'\n", g_strTempPath.GetBuffer() );
912 Sys_Printf( "game name : '%s'\n", mGameName.GetBuffer() );
913 Sys_Printf( "game file : '%s'\n", mGameFile.GetBuffer() );
914 Sys_Printf( "game path : '%s'\n", mGameToolsPath.GetBuffer() );
915 Sys_Printf( "base game : '%s'\n", mBaseGame.GetBuffer() );
916 Sys_Printf( "engine path : '%s'\n", mEnginePath.GetBuffer() );
917 Sys_Printf( "engine : '%s'\n", mEngine.GetBuffer() );
918 Sys_Printf( "shaderlist : '%s'\n", mShaderlist.GetBuffer() );
919 Sys_Printf( "caulk shader: '%s'\n", mCaulkShader.GetBuffer() );
920 #if defined ( __linux__ ) || defined ( __APPLE__ )
921 Sys_Printf( "prefix : '%s'\n", mUserPathPrefix.GetBuffer() );
923 Sys_Printf( "default texture scale: %g\n", mTextureDefaultScale );
924 Sys_Printf( "single eclass load : %s\n", mEClassSingleLoad ? "Yes" : "No" );
925 Sys_Printf( "patches supported : %s\n", mNoPatch ? "No" : "Yes" );
928 CPrefAssignment& CPrefAssignment::operator =( const CPrefAssignment& ass ){
929 if ( &ass != this ) {
937 CPrefAssignment::CPrefAssignment( const CPrefAssignment& ass ){
941 void CGameDialog::LoadPrefs(){
942 // if we already have a document loaded, we will free and reload from file
943 if ( mGlobalPrefs.InUse() ) {
944 Sys_Printf( "Reloading global prefs from file\n" );
945 mGlobalPrefs.Clear();
948 // load global .pref file
949 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
950 strGlobalPref += "global.pref";
952 mGlobalPrefs.ReadXMLFile( strGlobalPref.GetBuffer() );
954 mGlobalPrefs.GetPref( "gamefile", &m_sGameFile, "" ); // NOTE: there's no default, user HAS to select something
955 mGlobalPrefs.GetPref( "autoload", &m_bAutoLoadGame, false );
956 mGlobalPrefs.GetPref( "log console", &m_bLogConsole, false );
957 // in a very particular post-.pid startup
958 // we may have the console turned on and want to keep it that way
959 // so we use a latching system
960 if ( m_bForceLogConsole ) {
961 m_bLogConsole = true;
962 Sys_Printf( "console logging has been latched on, saving prefs\n" );
964 m_bForceLogConsole = false;
967 // console logging: call Sys_LogConsole to check console logging status
968 // it is important that we would log console as early as possible to make it useful
971 if ( mGlobalPrefs.mbEmpty ) {
972 Sys_Printf( "Saving global.pref with default pref values\n" );
977 void CGameDialog::SavePrefs(){
978 // update the tree and save it
979 mGlobalPrefs.UpdatePrefTree();
981 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
982 strGlobalPref += "global.pref";
984 if ( !mGlobalPrefs.WriteXMLFile( strGlobalPref.GetBuffer() ) ) {
985 Sys_FPrintf( SYS_ERR, "Error occured while saving global prefs file '%s'\n", strGlobalPref.GetBuffer() );
989 void CGameDialog::DoGameInstall() {
990 // make sure console logging is on whenever we enter the installation loop
991 g_PrefsDlg.mGamesDialog.m_bLogConsole = true;
996 void CGameDialog::DoGameDialog() {
997 // allow looping the game selection dialog with calls to the game configure dialog in between
998 while ( m_bDoGameInstall ) {
1000 m_bDoGameInstall = false;
1002 if ( DoModal() == IDCANCEL ) {
1003 Error( "game selection dialog canceled, cannot continue" );
1007 if ( m_bDoGameInstall ) {
1010 // and we will loop to do another DoModal dialog
1014 // unhook so we can use in other places
1015 // we manually incref'ed it when creating, it won't be freed (destructor)
1016 gtk_container_remove( GTK_CONTAINER( mTopBox ), GetGlobalFrame() );
1018 // we save the prefs file
1022 GtkWidget* CGameDialog::GetGlobalFrame(){
1023 GtkWidget *vbox, *text, *combo, *check;
1025 if ( mFrame != NULL ) {
1029 mFrame = gtk_frame_new( NULL );
1030 gtk_container_set_border_width( GTK_CONTAINER( mFrame ), 5 );
1031 gtk_widget_show( mFrame );
1033 vbox = gtk_vbox_new( FALSE, 6 );
1034 gtk_widget_show( vbox );
1035 gtk_container_add( GTK_CONTAINER( mFrame ), vbox );
1036 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1038 text = gtk_label_new( _( "Select the game:" ) );
1039 gtk_widget_show( text );
1040 gtk_box_pack_start( GTK_BOX( vbox ), text, FALSE, FALSE, 0 );
1042 combo = gtk_combo_box_new_text();
1043 gtk_widget_show( combo );
1044 gtk_box_pack_start( GTK_BOX( vbox ), combo, FALSE, FALSE, 0 );
1045 AddDialogData( combo, &m_nComboSelect, DLG_COMBO_BOX_INT );
1046 mGameCombo = GTK_COMBO_BOX( combo );
1050 check = gtk_check_button_new_with_label( _( "Auto load selected game on startup" ) );
1051 gtk_widget_show( check );
1052 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1053 AddDialogData( check, &m_bAutoLoadGame, DLG_CHECK_BOOL );
1055 text = gtk_label_new( _( "(this frame is available in the prefs menu if you set auto-select)" ) );
1056 gtk_widget_show( text );
1057 gtk_box_pack_start( GTK_BOX( vbox ), text, FALSE, FALSE, 0 );
1060 check = gtk_check_button_new_with_label( _( "Networked install - per-user settings" ) );
1061 gtk_widget_show( check );
1062 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1063 AddDialogData( check, &m_bNetRun, DLG_CHECK_BOOL );
1066 check = gtk_check_button_new_with_label( _( "Log the console to radiant.log" ) );
1067 gtk_widget_show( check );
1068 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1069 AddDialogData( check, &m_bLogConsole, DLG_CHECK_BOOL );
1071 // incref it so we can pass it around
1072 gtk_widget_ref( GTK_WIDGET( mFrame ) );
1077 void CGameDialog::UpdateData( bool retrieve ) {
1079 // use m_sGameFile to set m_nComboSelect
1080 list<CGameDescription *>::iterator iGame;
1082 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ )
1084 if ( ( *iGame )->mGameFile == m_sGameFile ) {
1091 UpdateNetrun( false );
1094 Dialog::UpdateData( retrieve );
1096 // use m_nComboSelect to set m_sGameFile
1097 list<CGameDescription *>::iterator iGame = mGames.begin();
1099 for ( i = 0; i < m_nComboSelect; i++ )
1103 m_sGameFile = ( *iGame )->mGameFile;
1105 UpdateNetrun( true );
1110 void CGameDialog::SInstallCallback( GtkWidget *widget, gpointer data ) {
1111 CGameDialog *d = static_cast< CGameDialog* >( data );
1112 d->m_bDoGameInstall = true;
1116 void CGameDialog::BuildDialog() {
1117 GtkWidget *dlg, *vbox1, *button, *setup_button;
1120 gtk_window_set_title( GTK_WINDOW( dlg ), _( "Select Game" ) );
1122 vbox1 = gtk_vbox_new( FALSE, 0 );
1123 gtk_widget_show( vbox1 );
1124 gtk_container_add( GTK_CONTAINER( dlg ), vbox1 );
1126 gtk_container_add( GTK_CONTAINER( vbox1 ), GetGlobalFrame() );
1129 setup_button = gtk_button_new_with_label( _( "Configure more games" ) );
1130 gtk_widget_show( setup_button );
1131 gtk_box_pack_start( GTK_BOX( vbox1 ), setup_button, FALSE, FALSE, 0 );
1132 gtk_signal_connect( GTK_OBJECT( setup_button ), "clicked",
1133 GTK_SIGNAL_FUNC( SInstallCallback ), this );
1135 button = gtk_button_new_with_label( _( "OK" ) );
1136 gtk_widget_show( button );
1137 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
1138 AddModalButton( button, IDOK );
1140 button = gtk_button_new_with_label( _( "Cancel" ) );
1141 gtk_widget_show( button );
1142 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
1143 AddModalButton( button, IDCANCEL );
1145 gtk_widget_set_usize( button, 60, -2 );
1148 void CGameDialog::UpdateGameCombo() {
1149 // fill in with the game descriptions
1150 list<CGameDescription *>::iterator iGame;
1152 if ( mGameCombo == NULL ) {
1153 Sys_Printf( "mGameCombo == NULL\n" );
1157 // clear whatever is in - wtf no way to know how many text entries?
1158 // use set/get active to track
1159 gtk_combo_box_set_active( mGameCombo, 0 );
1160 while ( gtk_combo_box_get_active( mGameCombo ) == 0 ) {
1161 gtk_combo_box_remove_text( mGameCombo, 0 );
1162 gtk_combo_box_set_active( mGameCombo, 0 );
1165 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ ) {
1166 gtk_combo_box_append_text( mGameCombo, ( *iGame )->mGameName.GetBuffer() );
1168 gtk_combo_box_set_active( mGameCombo, 0 );
1171 void CGameDialog::ScanForGames(){
1175 CString strGamesPath = g_strAppPath.GetBuffer();
1176 strGamesPath += "games";
1177 const char *path = strGamesPath.GetBuffer();
1179 if ( !mGames.empty() ) {
1180 Sys_Printf( "Clearing game list\n" );
1181 list<CGameDescription*>::iterator iGame;
1182 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ ) {
1188 Sys_Printf( "Scanning for game description files: %s\n", path );
1192 do we put game description files below g_strAppPath, or in ~/.radiant
1193 i.e. read only or read/write?
1194 my guess .. readonly cause it's an install
1195 we will probably want to add ~/.radiant/<version>/games/ scanning on top of that for developers
1196 (if that's really needed)
1199 // FIXME need to catch the 'no game description' situation and exit with a clean error
1201 dir = g_dir_open( path, 0, NULL );
1203 if ( dir != NULL ) {
1206 const gchar* name = g_dir_read_name( dir );
1207 if ( name == NULL ) {
1211 dirlist = g_strdup( name );
1215 char *ext = strrchr( dirlist, '.' );
1216 if ( ( ext == NULL ) || ( strcmp( ext, ".game" ) != 0 ) ) {
1219 strPath.Format( "%s/%s", path, dirlist );
1220 Sys_Printf( "%s\n", strPath.GetBuffer() );
1222 xmlDocPtr pDoc = xmlParseFile( strPath.GetBuffer() );
1224 mGames.push_front( new CGameDescription( pDoc, dirlist ) );
1228 Sys_FPrintf( SYS_ERR, "XML parser failed on '%s'\n", strPath.GetBuffer() );
1236 // entries in the combo need to be updated
1240 CGameDescription* CGameDialog::GameDescriptionForComboItem(){
1241 list<CGameDescription *>::iterator iGame;
1243 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++,i++ ) {
1244 if ( i == m_nComboSelect ) {
1248 return NULL; // not found
1251 void CGameDialog::InitGlobalPrefPath(){
1252 GString *global_rc_path;
1253 // configure m_global_rc_path
1254 // this is the g_strTempPath, and it has already been mkdir'ed
1255 global_rc_path = g_string_new( g_strTempPath.GetBuffer() );
1256 g_PrefsDlg.m_global_rc_path = global_rc_path;
1259 void CGameDialog::Reset(){
1260 if ( !g_PrefsDlg.m_global_rc_path ) {
1261 InitGlobalPrefPath();
1263 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
1264 strGlobalPref += "global.pref";
1265 remove( strGlobalPref.GetBuffer() );
1268 void CGameDialog::Init(){
1269 InitGlobalPrefPath();
1271 if ( mGames.empty() ) {
1274 if ( mGames.empty() ) {
1275 Error( "No games setup, aborting\n" );
1279 if ( m_bAutoLoadGame ) {
1280 // search by .game name
1281 list<CGameDescription *>::iterator iGame;
1282 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ )
1284 if ( ( *iGame )->mGameFile == m_sGameFile ) {
1285 m_pCurrentGameDescription = ( *iGame );
1290 if ( !m_bAutoLoadGame || !m_pCurrentGameDescription ) {
1292 // use m_nComboSelect to identify the game to run as and set the globals
1293 m_pCurrentGameDescription = GameDescriptionForComboItem();
1294 if ( !m_pCurrentGameDescription ) {
1295 Error( "Lookup of game description object failed, can't continue\n" );
1298 g_pGameDescription = m_pCurrentGameDescription;
1300 g_strGameToolsPath = g_pGameDescription->mGameToolsPath;
1302 // NOTE TTimo: this is moved from QE_LoadProject in 1.2
1303 // (probably broken)
1304 // NOTE Hydra: was broken for win32, we don't use m_strHomeGame or m_strFSBasePath
1305 #if defined ( __linux__ ) || defined ( __APPLE__ )
1306 g_qeglobals.m_strHomeGame = g_get_home_dir();
1307 g_qeglobals.m_strHomeGame += "/";
1308 g_qeglobals.m_strHomeGame += m_pCurrentGameDescription->mUserPathPrefix.GetBuffer();
1309 g_qeglobals.m_strHomeGame += "/";
1311 g_qeglobals.m_strHomeGame = g_pGameDescription->mEnginePath.GetBuffer();
1314 g_pGameDescription->Dump();
1317 CGameDialog::~CGameDialog(){
1319 // NOTE I'm not too sure how reliable this is
1320 gtk_widget_unref( GTK_WIDGET( mFrame ) );
1322 // free all the game descriptions
1323 list<CGameDescription *>::iterator iGame;
1324 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ )
1331 void CGameDialog::AddPacksURL( Str &URL ){
1332 // add the URLs for the list of game packs installed
1333 // FIXME: this is kinda hardcoded for now..
1334 list<CGameDescription *>::iterator iGame;
1335 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ )
1337 if ( ( *iGame )->mGameFile == "q3.game" ) {
1338 URL += "&Games_dlup%5B%5D=1";
1340 else if ( ( *iGame )->mGameFile == "wolf.game" ) {
1341 URL += "&Games_dlup%5B%5D=2";
1343 // FIXME: double entry
1344 else if ( ( *iGame )->mGameFile == "wolf.game" ) {
1345 URL += "&Games_dlup%5B%5D=3";
1347 else if ( ( *iGame )->mGameFile == "jk2.game" ) {
1348 URL += "&Games_dlup%5B%5D=4";
1350 else if ( ( *iGame )->mGameFile == "stvef.game" ) {
1351 URL += "&Games_dlup%5B%5D=5";
1353 else if ( ( *iGame )->mGameFile == "sof2.game" ) {
1354 URL += "&Games_dlup%5B%5D=6";
1356 else if ( ( *iGame )->mGameFile == "ja.game" ) {
1357 URL += "&Games_dlup%5B%5D=7";
1364 #define NETRUN_FILENAME "netrun.conf"
1366 bool CGameDialog::m_bNetRun;
1368 void CGameDialog::UpdateNetrun( bool retrieve ){
1371 strNetrun = g_strAppPath; strNetrun += NETRUN_FILENAME;
1373 // now check if we are running from a network installation
1374 // use a dummy file as the flag
1375 f_netrun = fopen( strNetrun.GetBuffer(), "r" );
1387 f_netrun = fopen( strNetrun.GetBuffer(), "w" );
1389 Sys_FPrintf( SYS_ERR, "ERROR: Failed to create netrun file '%s'\n", strNetrun.GetBuffer() );
1395 Sys_Printf( "Created/Checked '%s'\n", strNetrun.GetBuffer() );
1400 if ( remove( strNetrun.GetBuffer() ) == -1 ) {
1401 if ( errno != ENOENT ) {
1402 Sys_FPrintf( SYS_ERR, "Failed to remove netrun file '%s'\n", strNetrun.GetBuffer() );
1408 Sys_Printf( "Netrun mode is disabled\n" );
1414 bool CGameDialog::GetNetrun(){
1422 very first prefs init deals with selecting the game and the game tools path
1423 then we can load .ini stuff
1425 using prefs / ini settings:
1429 look in g_strGameToolsPath for .ini
1432 look in ~/.radiant/<version>/gamename
1436 #define PREFS_LOCAL_FILENAME "local.pref"
1438 void PrefsDlg::Init(){
1439 mGamesDialog.Init();
1441 // m_global_rc_path has been set above, do m_rc_path with game specific stuff now
1442 // the win32 and linux versions have been unified for network mode
1444 if ( !CGameDialog::GetNetrun() ) {
1445 // legacy prefs settings, this goes where the game pack is installed
1446 m_rc_path = g_string_new( g_strGameToolsPath.GetBuffer() );
1447 m_inipath = g_string_new( m_rc_path->str );
1448 g_string_append( m_inipath, PREFS_LOCAL_FILENAME );
1452 // this is common to win32 and Linux init now
1453 m_rc_path = g_string_new( m_global_rc_path->str );
1456 g_string_append( m_rc_path, g_pGameDescription->mGameFile.GetBuffer() );
1457 g_string_append( m_rc_path, "/" );
1458 Q_mkdir( m_rc_path->str, 0775 );
1460 // then the ini file
1461 m_inipath = g_string_new( m_rc_path->str );
1462 g_string_append( m_inipath, PREFS_LOCAL_FILENAME );
1466 void PrefsDlg::UpdateData( bool retrieve ){
1467 // leo: the "changed" signal confuses the update function
1468 if ( m_pWidget == NULL ) {
1471 mGamesDialog.UpdateData( retrieve );
1472 Dialog::UpdateData( retrieve );
1476 #define PREFSHSPACE 5
1478 #define PREFSHSPACE 0
1481 static void UpdateSensitivity( GtkWidget *widget, gpointer data ){
1482 PrefsDlg *dlg = (PrefsDlg*)data;
1483 dlg->DoSensitivity();
1486 static void UpdateEditorSensitivity( GtkWidget *widget, gpointer data ){
1487 PrefsDlg *dlg = (PrefsDlg*)data;
1488 dlg->DoEditorSensitivity();
1491 // start new prefs dialog
1493 /*! Utility function for swapping notebook pages for tree list selections */
1494 void PrefsDlg::showPrefPage( int prefpage ){
1495 if ( gtk_notebook_get_current_page( GTK_NOTEBOOK( notebook ) ) != prefpage ) {
1496 gtk_notebook_set_page( GTK_NOTEBOOK( notebook ), prefpage );
1502 static void treeSelection( GtkTreeSelection* selection, gpointer data ){
1503 PrefsDlg *dlg = (PrefsDlg*)data;
1505 GtkTreeModel* model;
1506 GtkTreeIter selected;
1507 if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) {
1509 gtk_tree_model_get( model, &selected, 1, (gpointer*)&prefpage, -1 );
1510 dlg->showPrefPage( prefpage );
1514 void PrefsDlg::BuildDialog(){
1515 // Main Preferences dialog
1516 GtkWidget *dialog, *mainvbox, *hbox, *sc_win, *preflabel;
1518 // Widgets on notebook pages
1519 GtkWidget *check, *label, *scale, *hbox2, *combo,
1520 *table, *spin, *entry, *pixmap,
1521 *radio, *button, *pageframe, *vbox;
1523 GList *combo_list = (GList*)NULL;
1528 gtk_window_set_title( GTK_WINDOW( dialog ), _( "GtkRadiant Preferences" ) );
1529 gtk_widget_realize( dialog );
1531 mainvbox = gtk_vbox_new( FALSE, 5 );
1532 gtk_container_add( GTK_CONTAINER( dialog ), mainvbox );
1533 gtk_container_set_border_width( GTK_CONTAINER( mainvbox ), 5 );
1534 gtk_widget_show( mainvbox );
1536 hbox = gtk_hbox_new( FALSE, 5 );
1537 gtk_widget_show( hbox );
1538 gtk_box_pack_end( GTK_BOX( mainvbox ), hbox, FALSE, TRUE, 0 );
1540 button = gtk_button_new_with_label( _( "OK" ) );
1541 gtk_widget_show( button );
1542 gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
1543 gtk_widget_set_usize( button, 60, -2 );
1544 AddModalButton( button, IDOK );
1546 button = gtk_button_new_with_label( _( "Cancel" ) );
1547 gtk_widget_show( button );
1548 gtk_box_pack_end( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
1549 gtk_widget_set_usize( button, 60, -2 );
1550 AddModalButton( button, IDCANCEL );
1552 button = gtk_button_new_with_label( _( "Clean" ) );
1553 gtk_widget_show( button );
1554 gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( OnButtonClean ), this );
1555 gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
1556 gtk_widget_set_usize( button, 60, -2 );
1558 hbox = gtk_hbox_new( FALSE, 5 );
1559 gtk_box_pack_start( GTK_BOX( mainvbox ), hbox, TRUE, TRUE, 0 );
1560 gtk_widget_show( hbox );
1562 sc_win = gtk_scrolled_window_new( NULL, NULL );
1563 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( sc_win ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
1564 gtk_box_pack_start( GTK_BOX( hbox ), sc_win, FALSE, FALSE, 0 );
1565 gtk_widget_show( sc_win );
1567 // prefs pages notebook
1568 notebook = gtk_notebook_new();
1569 // hide the notebook tabs since its not supposed to look like a notebook
1570 gtk_notebook_set_show_tabs( GTK_NOTEBOOK( notebook ), FALSE );
1571 gtk_box_pack_start( GTK_BOX( hbox ), notebook, TRUE, TRUE, 0 );
1572 gtk_widget_show( notebook );
1574 gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( sc_win ), GTK_SHADOW_IN );
1577 GtkTreeStore* store = gtk_tree_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER );
1579 GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
1580 gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE );
1583 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1584 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( _( "Preferences" ), renderer, "text", 0, NULL );
1585 gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
1589 GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );
1590 g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( treeSelection ), this );
1593 gtk_widget_show( view );
1595 gtk_container_add( GTK_CONTAINER( sc_win ), view );
1598 /********************************************************************/
1599 /* Add preference tree options */
1600 /********************************************************************/
1603 gtk_tree_store_append( store, &group, NULL );
1604 gtk_tree_store_set( store, &group, 0, _( "Globals" ), 1, PTAB_FRONT, -1 );
1607 gtk_tree_store_append( store, &tab, &group );
1608 gtk_tree_store_set( store, &tab, 0, _( "Game settings" ), 1, (gpointer)PTAB_GAME_SETTINGS, -1 );
1614 gtk_tree_store_append( store, &group, NULL );
1615 gtk_tree_store_set( store, &group, 0, _( "Display" ), 1, PTAB_FRONT, -1 );
1618 gtk_tree_store_append( store, &tab, &group );
1619 gtk_tree_store_set( store, &tab, 0, _( "2D Display/Rendering" ), 1, (gpointer)PTAB_2D, -1 );
1623 gtk_tree_store_append( store, &tab, &group );
1624 gtk_tree_store_set( store, &tab, 0, _( "3D View" ), 1, (gpointer)PTAB_CAMERA, -1 );
1628 gtk_tree_store_append( store, &tab, &group );
1629 gtk_tree_store_set( store, &tab, 0, _( "Texture Settings" ), 1, (gpointer)PTAB_TEXTURE, -1 );
1635 gtk_tree_store_append( store, &group, NULL );
1636 gtk_tree_store_set( store, &group, 0, _( "Interface" ), 1, PTAB_FRONT, -1 );
1639 gtk_tree_store_append( store, &tab, &group );
1640 gtk_tree_store_set( store, &tab, 0, _( "Layout" ), 1, (gpointer)PTAB_LAYOUT, -1 );
1644 gtk_tree_store_append( store, &tab, &group );
1645 gtk_tree_store_set( store, &tab, 0, _( "Mouse" ), 1, (gpointer)PTAB_MOUSE, -1 );
1649 gtk_tree_store_append( store, &tab, &group );
1650 gtk_tree_store_set( store, &tab, 0, _( "Editing" ), 1, (gpointer)PTAB_EDITING, -1 );
1656 gtk_tree_store_append( store, &group, NULL );
1657 gtk_tree_store_set( store, &group, 0, _( "Other" ), 1, PTAB_FRONT, -1 );
1660 gtk_tree_store_append( store, &tab, &group );
1661 gtk_tree_store_set( store, &tab, 0, _( "Startup/Auto save" ), 1, (gpointer)PTAB_STARTUP, -1 );
1665 gtk_tree_store_append( store, &tab, &group );
1666 gtk_tree_store_set( store, &tab, 0, _( "Paths" ), 1, (gpointer)PTAB_PATHS, -1 );
1670 gtk_tree_store_append( store, &tab, &group );
1671 gtk_tree_store_set( store, &tab, 0, _( "Brush" ), 1, (gpointer)PTAB_BRUSH, -1 );
1675 gtk_tree_store_append( store, &tab, &group );
1676 gtk_tree_store_set( store, &tab, 0, _( "Misc" ), 1, (gpointer)PTAB_MISC, -1 );
1678 if ( !g_qeglobals.bBSPFrontendPlugin ) {
1680 gtk_tree_store_append( store, &tab, &group );
1681 gtk_tree_store_set( store, &tab, 0, _( "BSP Monitoring" ), 1, (gpointer)PTAB_BSPMONITOR, -1 );
1686 gtk_tree_view_expand_all( GTK_TREE_VIEW( view ) );
1688 g_object_unref( G_OBJECT( store ) );
1691 /**********************************************************************/
1692 /* build the prefs pages */
1693 /**********************************************************************/
1696 // todo : add something interesting here
1697 // NOTE TTimo: tip of the day? or a logo?
1698 preflabel = gtk_label_new( _( "Front Page" ) );
1699 gtk_widget_show( preflabel );
1700 pageframe = gtk_frame_new( NULL );
1701 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
1702 gtk_widget_show( pageframe );
1703 vbox = gtk_vbox_new( FALSE, 5 );
1704 gtk_widget_show( vbox );
1705 gtk_widget_set_usize( GTK_WIDGET( vbox ), 350, -2 );
1706 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1707 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
1709 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
1711 /******** global preferences group ****************************/
1712 preflabel = gtk_label_new( _( "Globals" ) );
1713 gtk_widget_show( preflabel );
1715 pageframe = mGamesDialog.GetGlobalFrame();
1716 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
1718 /******** 2D prefs group (xy views/rendering options) *********/
1719 preflabel = gtk_label_new( _( "2D Display" ) );
1720 gtk_widget_show( preflabel );
1721 pageframe = gtk_frame_new( _( "2D Display" ) );
1722 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
1723 gtk_widget_show( pageframe );
1724 vbox = gtk_vbox_new( FALSE, 5 );
1725 gtk_widget_show( vbox );
1726 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1727 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
1729 // OpenGL Display Lists
1730 check = gtk_check_button_new_with_label( _( "OpenGL Display Lists" ) );
1731 gtk_widget_show( check );
1732 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1733 AddDialogData( check, &m_bDisplayLists, DLG_CHECK_BOOL );
1735 // Antialiased points & lines
1736 // Fishman - Add antialiazed points and lines support. 09/03/00
1737 check = gtk_check_button_new_with_label( _( "OpenGL antialiased points and lines" ) );
1738 gtk_widget_show( check );
1739 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1740 AddDialogData( check, &m_bAntialiasedPointsAndLines, DLG_CHECK_BOOL );
1742 // Solid selection boxes
1743 check = gtk_check_button_new_with_label( _( "Solid selection boxes" ) );
1744 gtk_widget_show( check );
1745 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1746 AddDialogData( check, &m_bNoStipple, DLG_CHECK_BOOL );
1748 // Display size info
1749 check = gtk_check_button_new_with_label( _( "Display size info" ) );
1750 gtk_widget_show( check );
1751 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1752 AddDialogData( check, &m_bSizePaint, DLG_CHECK_BOOL );
1754 // Alternate vertex/edge handles
1755 // Gef: Kyro GL_POINT work around 25-aug-2001
1756 check = gtk_check_button_new_with_label( _( "Alternate vertex/edge handles" ) );
1757 gtk_widget_show( check );
1758 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1759 AddDialogData( check, &m_bGlPtWorkaround, DLG_CHECK_BOOL );
1761 g_list_free( combo_list );
1765 check = gtk_check_button_new_with_label( _( "ATI and Intel cards w/ buggy drivers (disappearing polygons)" ) );
1766 gtk_widget_show( check );
1767 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1768 AddDialogData( check, &m_bGlATIHack, DLG_CHECK_BOOL );
1771 #ifdef NVIDIA_AERO_HACK
1772 check = gtk_check_button_new_with_label( _( "NVIDIA/Aero bug - disable Windows composition" ) );
1773 gtk_widget_show( check );
1774 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1775 AddDialogData( check, &m_bGlNvidiaAeroHack, DLG_CHECK_BOOL );
1778 // Add the page to the notebook
1779 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
1781 /******** 3D Camera view group *********/
1782 preflabel = gtk_label_new( _( "3D View" ) );
1783 gtk_widget_show( preflabel );
1784 pageframe = gtk_frame_new( _( "3D View" ) );
1785 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
1786 gtk_widget_show( pageframe );
1787 vbox = gtk_vbox_new( FALSE, 5 );
1788 gtk_widget_show( vbox );
1789 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1790 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
1792 // Directional velocity (Movement Velocity)
1794 hbox2 = gtk_hbox_new( FALSE, 0 );
1795 gtk_widget_show( hbox2 );
1796 gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, FALSE, 0 );
1799 label = gtk_label_new( _( "Movement Velocity" ) );
1800 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
1801 gtk_widget_show( label );
1802 gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
1805 adj = gtk_adjustment_new( 100, 50, 300, 1, 10, 10 );
1806 AddDialogData( adj, &m_nMoveSpeed, DLG_ADJ_INT );
1809 scale = gtk_hscale_new( GTK_ADJUSTMENT( adj ) );
1810 gtk_widget_show( scale );
1811 gtk_box_pack_start( GTK_BOX( vbox ), scale, FALSE, TRUE, 2 );
1813 gtk_scale_set_draw_value( GTK_SCALE( scale ), TRUE );
1815 // Angular velocity (Rotational Velocity)
1817 hbox2 = gtk_hbox_new( FALSE, 0 );
1818 gtk_widget_show( hbox2 );
1819 gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, FALSE, 0 );
1822 label = gtk_label_new( _( "Rotational Velocity" ) );
1823 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
1824 gtk_widget_show( label );
1825 gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
1828 adj = gtk_adjustment_new( 3, 1, 180, 1, 10, 10 ); // value, low, high, step, page_step, page_size
1829 AddDialogData( adj, &m_nAngleSpeed, DLG_ADJ_INT );
1832 scale = gtk_hscale_new( GTK_ADJUSTMENT( adj ) );
1833 gtk_widget_show( scale );
1834 gtk_box_pack_start( GTK_BOX( vbox ), scale, FALSE, TRUE, 2 );
1835 gtk_scale_set_draw_value( GTK_SCALE( scale ), TRUE );
1837 // Text under the velocity sliders
1839 hbox2 = gtk_hbox_new( FALSE, 0 );
1840 gtk_widget_show( hbox2 );
1841 gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, FALSE, 0 );
1844 label = gtk_label_new( _( "slow" ) );
1845 gtk_widget_show( label );
1846 gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
1849 label = gtk_label_new( _( "fast" ) );
1850 gtk_widget_show( label );
1851 gtk_box_pack_end( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
1853 // Allow drag to select multiple faces/brushes
1855 table = gtk_table_new( 2, 1, FALSE );
1856 gtk_widget_show( table );
1857 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
1858 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1859 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1861 label = gtk_label_new( _( "Use paint-select in camera view:" ) );
1862 gtk_widget_show( label );
1863 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
1864 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
1865 (GtkAttachOptions) ( 0 ),
1866 (GtkAttachOptions) ( 0 ), 0, 0 );
1869 combo_list = g_list_append( combo_list, (void *)_( "No" ) );
1870 combo_list = g_list_append( combo_list, (void *)_( "Yes" ) );
1871 combo_list = g_list_append( combo_list, (void *)_( "Yes (Classic Key Setup)" ) );
1873 combo = gtk_combo_new();
1874 gtk_combo_set_popdown_strings( GTK_COMBO( combo ), combo_list );
1875 gtk_widget_show( combo );
1876 gtk_table_attach( GTK_TABLE( table ), combo, 1, 2, 0, 1,
1877 (GtkAttachOptions) ( GTK_FILL ),
1878 (GtkAttachOptions) ( 0 ), 0, 0 );
1879 gtk_entry_set_editable( GTK_ENTRY( GTK_COMBO( combo )->entry ), FALSE );
1880 AddDialogData( combo, &m_nCamDragMultiSelect, DLG_COMBO_INT );
1882 // Freelook in Camera view
1883 check = gtk_check_button_new_with_label( _( "Freelook in Camera view" ) );
1884 gtk_widget_show( check );
1885 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1886 gtk_label_set_justify( GTK_LABEL( GTK_BIN( check )->child ), GTK_JUSTIFY_LEFT );
1887 AddDialogData( check, &m_bCamFreeLook, DLG_CHECK_BOOL );
1889 // Freelook in Camera view w/ forward & back strafing instead of up and down looking
1890 check = gtk_check_button_new_with_label( _( "Freelook strafes Forward and Back" ) );
1891 gtk_widget_show( check );
1892 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1893 gtk_label_set_justify( GTK_LABEL( GTK_BIN( check )->child ), GTK_JUSTIFY_LEFT );
1894 AddDialogData( check, &m_bCamFreeLookStrafe, DLG_CHECK_BOOL );
1896 // Invert mouse in freelook
1897 check = gtk_check_button_new_with_label( _( "Invert mouse in freelook" ) );
1898 gtk_widget_show( check );
1899 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1900 gtk_label_set_justify( GTK_LABEL( GTK_BIN( check )->child ), GTK_JUSTIFY_LEFT );
1901 AddDialogData( check, &m_bCamInverseMouse, DLG_CHECK_BOOL );
1903 // Discrete movement
1904 check = gtk_check_button_new_with_label( _( "Discrete movement" ) );
1905 gtk_widget_show( check );
1906 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1907 gtk_label_set_justify( GTK_LABEL( GTK_BIN( check )->child ), GTK_JUSTIFY_LEFT );
1908 AddDialogData( check, &m_bCamDiscrete, DLG_CHECK_BOOL );
1910 // Update XY views on camera move
1911 check = gtk_check_button_new_with_label( _( "Update XY views on camera move" ) );
1912 gtk_widget_show( check );
1913 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1914 gtk_label_set_justify( GTK_LABEL( GTK_BIN( check )->child ), GTK_JUSTIFY_LEFT );
1915 AddDialogData( check, &m_bCamXYUpdate, DLG_CHECK_BOOL );
1917 // Add the page to the notebook
1918 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
1920 /******** Texture group *********/
1921 preflabel = gtk_label_new( _( "Textures" ) );
1922 gtk_widget_show( preflabel );
1923 pageframe = gtk_frame_new( _( "Textures" ) );
1924 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
1925 gtk_widget_show( pageframe );
1926 vbox = gtk_vbox_new( FALSE, 6 );
1927 gtk_widget_show( vbox );
1928 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1929 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
1931 // Texture quality slider
1933 label = gtk_label_new( _( "Texture quality" ) );
1934 gtk_widget_show( label );
1935 gtk_box_pack_start( GTK_BOX( vbox ), label, FALSE, FALSE, 0 );
1936 gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
1937 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
1940 adj = gtk_adjustment_new( 0, 0, 4, 1, 1, 1 );
1941 AddDialogData( adj, &m_nLatchedTextureQuality, DLG_ADJ_INT );
1944 scale = gtk_hscale_new( GTK_ADJUSTMENT( adj ) );
1945 gtk_widget_show( scale );
1946 gtk_box_pack_start( GTK_BOX( vbox ), scale, FALSE, FALSE, 0 );
1947 gtk_scale_set_draw_value( GTK_SCALE( scale ), FALSE );
1949 // text under the texture slider
1950 hbox2 = gtk_hbox_new( FALSE, 0 );
1951 gtk_widget_show( hbox2 );
1952 gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, FALSE, 0 );
1953 label = gtk_label_new( _( "low" ) );
1954 gtk_widget_show( label );
1955 gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
1956 label = gtk_label_new( _( "high" ) );
1957 gtk_widget_show( label );
1958 gtk_box_pack_end( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
1961 check = gtk_check_button_new_with_label( _( "Texture subsets" ) );
1962 gtk_widget_show( check );
1963 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1964 AddDialogData( check, &m_bTextureWindow, DLG_CHECK_BOOL );
1966 // texture scrollbar
1967 check = gtk_check_button_new_with_label( _( "Texture scrollbar" ) );
1968 gtk_widget_show( check );
1969 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1970 AddDialogData( check, &m_bTextureScrollbar, DLG_CHECK_BOOL );
1972 // texture increment matches grid
1973 check = gtk_check_button_new_with_label( _( "Tex increment matches grid" ) );
1974 gtk_widget_show( check );
1975 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1976 AddDialogData( check, &m_bSnapTToGrid, DLG_CHECK_BOOL );
1979 // Texture compression choice label
1981 table = gtk_table_new( 2, 1, FALSE );
1982 gtk_widget_show( table );
1983 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
1984 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1985 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1987 label = gtk_label_new( _( "Texture Compression (if available):" ) );
1988 gtk_widget_show( label );
1989 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
1990 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
1991 (GtkAttachOptions) ( 0 ),
1992 (GtkAttachOptions) ( 0 ), 0, 0 );
1993 gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
1995 // Texture compression choice label
1997 // NONE will always be in pos 0
1998 combo_list = g_list_append( combo_list, (void *)_( "None" ) );
2000 // if OpenGL compression is enabled it will always be
2002 if ( g_qeglobals.m_bOpenGLCompressionSupported ) {
2003 combo_list = g_list_append( combo_list, (void *)_( "OpenGL ARB" ) );
2006 // If S3 is enabled offer all 3 valid compression schemes in RGBA
2007 if ( g_qeglobals.m_bS3CompressionSupported ) {
2008 combo_list = g_list_append( combo_list, (void *)_( "S3TC DXT1" ) );
2009 combo_list = g_list_append( combo_list, (void *)_( "S3TC DXT3" ) );
2010 combo_list = g_list_append( combo_list, (void *)_( "S3TC DXT5" ) );
2013 combo = gtk_combo_new();
2014 gtk_combo_set_popdown_strings( GTK_COMBO( combo ), combo_list );
2015 gtk_widget_show( combo );
2016 gtk_table_attach( GTK_TABLE( table ), combo, 1, 2, 0, 1,
2017 (GtkAttachOptions) ( GTK_FILL ),
2018 (GtkAttachOptions) ( 0 ), 0, 0 );
2019 gtk_entry_set_editable( GTK_ENTRY( GTK_COMBO( combo )->entry ), FALSE );
2020 AddDialogData( combo, &m_nTextureCompressionFormat, DLG_COMBO_INT );
2021 g_list_free( combo_list );
2024 table = gtk_table_new( 2, 1, FALSE );
2025 gtk_widget_show( table );
2026 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2027 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2028 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2032 label = gtk_label_new( _( "Startup Shaders:" ) );
2033 gtk_widget_show( label );
2034 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
2035 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
2036 (GtkAttachOptions) ( 0 ),
2037 (GtkAttachOptions) ( 0 ), 0, 0 );
2038 gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
2042 combo_list = g_list_append( combo_list, (void *)_( "None" ) );
2043 if ( g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game" ) {
2044 combo_list = g_list_append( combo_list, (void *)_( "System" ) );
2046 else if ( g_pGameDescription->mGameFile == "sof2.game" ) {
2047 combo_list = g_list_append( combo_list, (void *)( "Tools" ) );
2050 combo_list = g_list_append( combo_list, (void *)_( "Common" ) );
2052 combo_list = g_list_append( combo_list, (void *)_( "All" ) );
2053 combo = gtk_combo_new();
2054 gtk_combo_set_popdown_strings( GTK_COMBO( combo ), combo_list );
2055 gtk_widget_show( combo );
2056 gtk_table_attach( GTK_TABLE( table ), combo, 1, 2, 0, 1,
2057 (GtkAttachOptions) ( GTK_FILL ),
2058 (GtkAttachOptions) ( 0 ), 0, 0 );
2059 gtk_entry_set_editable( GTK_ENTRY( GTK_COMBO( combo )->entry ), FALSE );
2060 AddDialogData( combo, &m_nLatchedShader, DLG_COMBO_INT );
2061 g_list_free( combo_list );
2063 // Add the page to the notebook
2064 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2066 /******** Layout group *********/
2067 preflabel = gtk_label_new( _( "Layout" ) );
2068 gtk_widget_show( preflabel );
2069 pageframe = gtk_frame_new( _( "Layout" ) );
2070 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2071 gtk_widget_show( pageframe );
2072 vbox = gtk_vbox_new( FALSE, 5 );
2073 gtk_widget_show( vbox );
2074 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2075 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2079 table = gtk_table_new( 2, 4, FALSE );
2080 gtk_widget_show( table );
2081 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2082 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2083 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2086 pixmap = new_pixmap( g_pParentWnd->m_pWidget, "window1.bmp" );
2087 gtk_widget_show( pixmap );
2088 gtk_table_attach( GTK_TABLE( table ), pixmap, 0, 1, 0, 1,
2089 (GtkAttachOptions) ( 0 ),
2090 (GtkAttachOptions) ( 0 ), 0, 0 );
2093 pixmap = new_pixmap( g_pParentWnd->m_pWidget, "window2.bmp" );
2094 gtk_widget_show( pixmap );
2095 gtk_table_attach( GTK_TABLE( table ), pixmap, 1, 2, 0, 1,
2096 (GtkAttachOptions) ( 0 ),
2097 (GtkAttachOptions) ( 0 ), 0, 0 );
2100 pixmap = new_pixmap( g_pParentWnd->m_pWidget, "window3.bmp" );
2101 gtk_widget_show( pixmap );
2102 gtk_table_attach( GTK_TABLE( table ), pixmap, 2, 3, 0, 1,
2103 (GtkAttachOptions) ( 0 ),
2104 (GtkAttachOptions) ( 0 ), 0, 0 );
2107 pixmap = new_pixmap( g_pParentWnd->m_pWidget, "window4.bmp" );
2108 gtk_widget_show( pixmap );
2109 gtk_table_attach( GTK_TABLE( table ), pixmap, 3, 4, 0, 1,
2110 (GtkAttachOptions) ( 0 ),
2111 (GtkAttachOptions) ( 0 ), 0, 0 );
2113 // view type 1 selector
2114 radio = gtk_radio_button_new( NULL );
2115 gtk_widget_show( radio );
2116 gtk_table_attach( GTK_TABLE( table ), radio, 0, 1, 1, 2,
2117 (GtkAttachOptions) ( 0 ),
2118 (GtkAttachOptions) ( 0 ), 0, 0 );
2120 // view type 2 selector
2121 radio = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON( radio ) );
2122 gtk_widget_show( radio );
2123 gtk_table_attach( GTK_TABLE( table ), radio, 1, 2, 1, 2,
2124 (GtkAttachOptions) ( 0 ),
2125 (GtkAttachOptions) ( 0 ), 0, 0 );
2127 // view type 3 selector
2128 radio = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON( radio ) );
2129 gtk_widget_show( radio );
2130 gtk_table_attach( GTK_TABLE( table ), radio, 2, 3, 1, 2,
2131 (GtkAttachOptions) ( 0 ),
2132 (GtkAttachOptions) ( 0 ), 0, 0 );
2134 // view type 4 selector
2135 radio = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON( radio ) );
2136 gtk_widget_show( radio );
2137 gtk_table_attach( GTK_TABLE( table ), radio, 3, 4, 1, 2,
2138 (GtkAttachOptions) ( 0 ),
2139 (GtkAttachOptions) ( 0 ), 0, 0 );
2140 AddDialogData( radio, &m_nLatchedView, DLG_RADIO_INT );
2142 // Floating Z window
2143 check = gtk_check_button_new_with_label( _( "Floating Z Window" ) );
2144 gtk_widget_show( check );
2145 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2146 AddDialogData( check, &m_bLatchedFloatingZ, DLG_CHECK_BOOL );
2148 // show menu tear-off seperators
2149 check = gtk_check_button_new_with_label( _( "Detachable Menus" ) );
2150 gtk_widget_show( check );
2151 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2152 AddDialogData( check, &m_bLatchedDetachableMenus, DLG_CHECK_BOOL );
2154 if ( !g_pGameDescription->mNoPatch ) {
2155 // show patch toolbar
2156 check = gtk_check_button_new_with_label( _( "Patch Toolbar" ) );
2157 gtk_widget_show( check );
2158 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2159 g_object_set_data( G_OBJECT( dialog ), "check_patchtoolbar", check ); // Allow to be disabled for Q1/Q2
2160 AddDialogData( check, &m_bLatchedPatchToolbar, DLG_CHECK_BOOL );
2164 check = gtk_check_button_new_with_label( _( "Wide Toolbar" ) );
2165 gtk_widget_show( check );
2166 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2167 AddDialogData( check, &m_bLatchedWideToolbar, DLG_CHECK_BOOL );
2169 // use plugin toolbar
2170 check = gtk_check_button_new_with_label( _( "Plugin Toolbar" ) );
2171 gtk_widget_show( check );
2172 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2173 AddDialogData( check, &m_bLatchedPluginToolbar, DLG_CHECK_BOOL );
2176 // win32 file dialog
2177 check = gtk_check_button_new_with_label( _( "Use win32 file dialog (hacky)" ) );
2178 gtk_widget_show( check );
2179 // gtk_container_add (GTK_CONTAINER (vbox), check);
2180 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2181 AddDialogData( check, &m_bNativeGUI, DLG_CHECK_BOOL );
2183 // position on primary monitor
2184 check = gtk_check_button_new_with_label( _( "Start on Primary Monitor" ) );
2185 gtk_widget_show( check );
2186 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2187 g_object_set_data( G_OBJECT( dialog ), "check_startonprimary", check );
2188 gtk_signal_connect( GTK_OBJECT( check ), "clicked", GTK_SIGNAL_FUNC( UpdateSensitivity ), this );
2189 AddDialogData( check, &m_bStartOnPrimMon, DLG_CHECK_BOOL );
2192 // Add the page to the notebook
2193 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2195 /******** Mouse group *********/
2196 preflabel = gtk_label_new( _( "Mouse" ) );
2197 gtk_widget_show( preflabel );
2198 pageframe = gtk_frame_new( _( "Mouse" ) );
2199 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2200 gtk_widget_show( pageframe );
2201 vbox = gtk_vbox_new( FALSE, 5 );
2202 gtk_widget_show( vbox );
2203 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2204 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2208 hbox2 = gtk_hbox_new( FALSE, 5 );
2209 gtk_widget_show( hbox2 );
2210 gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, FALSE, 0 );
2213 radio = gtk_radio_button_new_with_label( NULL, _( "2 button" ) );
2214 gtk_widget_show( radio );
2215 gtk_box_pack_start( GTK_BOX( hbox2 ), radio, FALSE, FALSE, 0 );
2218 radio = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radio ), _( "3 button" ) );
2219 gtk_widget_show( radio );
2220 gtk_box_pack_start( GTK_BOX( hbox2 ), radio, FALSE, FALSE, 0 );
2221 AddDialogData( radio, &m_nMouse, DLG_RADIO_INT );
2223 // right click to drop entity
2224 check = gtk_check_button_new_with_label( _( "Right click to drop entities" ) );
2225 gtk_widget_show( check );
2226 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2227 AddDialogData( check, &m_bRightClick, DLG_CHECK_BOOL );
2229 // Mouse chaser (and this does what?)
2230 check = gtk_check_button_new_with_label( _( "Mouse chaser" ) );
2231 gtk_widget_show( check );
2232 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2233 AddDialogData( check, &m_bChaseMouse, DLG_CHECK_BOOL );
2236 check = gtk_check_button_new_with_label( _( "ALT + multi-drag" ) );
2237 gtk_widget_show( check );
2238 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2239 AddDialogData( check, &m_bALTEdge, DLG_CHECK_BOOL );
2241 // Mouse wheel increments
2243 hbox2 = gtk_hbox_new( FALSE, 5 );
2244 gtk_widget_show( hbox2 );
2245 gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, FALSE, 0 );
2248 label = gtk_label_new( _( "Wheel Mouse inc:" ) );
2249 gtk_widget_show( label );
2250 gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
2253 entry = gtk_entry_new();
2254 gtk_widget_show( entry );
2255 gtk_widget_set_usize( entry, 40, -2 );
2256 gtk_box_pack_start( GTK_BOX( hbox2 ), entry, FALSE, FALSE, 0 );
2257 AddDialogData( entry, &m_nWheelInc, DLG_ENTRY_INT );
2259 // Add the page to the notebook
2260 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2262 /******** Editing group *********/
2263 preflabel = gtk_label_new( _( "Editing" ) );
2264 gtk_widget_show( preflabel );
2265 pageframe = gtk_frame_new( _( "Editing" ) );
2266 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2267 gtk_widget_show( pageframe );
2268 vbox = gtk_vbox_new( FALSE, 5 );
2269 gtk_widget_show( vbox );
2270 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2271 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2273 // Vertex editing splits faces
2274 check = gtk_check_button_new_with_label( _( "Vertex editing splits face" ) );
2275 gtk_widget_show( check );
2276 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2277 AddDialogData( check, &m_bVertexSplit, DLG_CHECK_BOOL );
2279 // Fix target/targetname collisions
2280 check = gtk_check_button_new_with_label( _( "Fix target/targetname collisions" ) );
2281 gtk_widget_show( check );
2282 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2283 AddDialogData( check, &m_bDoTargetFix, DLG_CHECK_BOOL );
2285 // Clipper tool uses caulk
2286 check = gtk_check_button_new_with_label( _( "Clipper tool uses caulk" ) );
2287 gtk_widget_show( check );
2288 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2289 AddDialogData( check, &m_bClipCaulk, DLG_CHECK_BOOL );
2291 // Don't clamp plane points
2292 check = gtk_check_button_new_with_label( _( "Don't clamp plane points" ) );
2293 gtk_widget_show( check );
2294 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2295 AddDialogData( check, &m_bNoClamp, DLG_CHECK_BOOL );
2298 check = gtk_check_button_new_with_label( _( "Snap to grid" ) );
2299 gtk_widget_show( check );
2300 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2301 AddDialogData( check, &m_bSnap, DLG_CHECK_BOOL );
2303 // Select patch by bounding box
2304 check = gtk_check_button_new_with_label( _( "Select patches by bounding box" ) );
2305 gtk_widget_show( check );
2306 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2307 AddDialogData( check, &m_bPatchBBoxSelect, DLG_CHECK_BOOL );
2309 // Rotation increment
2311 table = gtk_table_new( 2, 3, FALSE );
2312 gtk_widget_show( table );
2313 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2314 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2315 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2318 label = gtk_label_new( _( "Rotation increment:" ) );
2319 gtk_widget_show( label );
2320 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
2321 (GtkAttachOptions) ( 0 ),
2322 (GtkAttachOptions) ( 0 ), 0, 0 );
2325 entry = gtk_entry_new();
2326 gtk_widget_show( entry );
2327 gtk_widget_set_usize( entry, 60, -2 );
2328 gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1,
2329 (GtkAttachOptions) ( GTK_FILL ),
2330 (GtkAttachOptions) ( 0 ), 0, 0 );
2331 AddDialogData( entry, &m_nRotation, DLG_ENTRY_INT );
2335 label = gtk_label_new( _( "Undo Levels:" ) );
2336 gtk_widget_show( label );
2337 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
2338 (GtkAttachOptions) ( 0 ),
2339 (GtkAttachOptions) ( 0 ), 0, 0 );
2341 // spinner (allows undo levels to be set to zero)
2342 spin = gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 1, 0, 64, 1, 10, 10 ) ), 1, 0 );
2343 gtk_widget_show( spin );
2344 gtk_table_attach( GTK_TABLE( table ), spin, 1, 2, 1, 2,
2345 (GtkAttachOptions) ( GTK_FILL ),
2346 (GtkAttachOptions) ( 0 ), 0, 0 );
2347 gtk_widget_set_usize( spin, 60, -2 );
2348 AddDialogData( spin, &m_nUndoLevels, DLG_SPIN_INT );
2350 // Patch subdivisions
2352 label = gtk_label_new( _( "Patch subdivisions:" ) );
2353 gtk_widget_show( label );
2354 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3,
2355 (GtkAttachOptions) ( 0 ),
2356 (GtkAttachOptions) ( 0 ), 0, 0 );
2358 // entry (spinner perhaps? [2-16])
2359 entry = gtk_entry_new();
2360 gtk_widget_show( entry );
2361 gtk_widget_set_usize( entry, 60, -2 );
2362 gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 2, 3,
2363 (GtkAttachOptions) ( GTK_FILL ),
2364 (GtkAttachOptions) ( 0 ), 0, 0 );
2365 AddDialogData( entry, &m_nSubdivisions, DLG_ENTRY_INT );
2367 // Add the page to the notebook
2368 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2370 /******** Save/Load group *********/
2371 preflabel = gtk_label_new( _( "Startup/Auto save" ) );
2372 gtk_widget_show( preflabel );
2373 pageframe = gtk_frame_new( _( "Startup/Auto save" ) );
2374 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2375 gtk_widget_show( pageframe );
2376 vbox = gtk_vbox_new( FALSE, 5 );
2377 gtk_widget_show( vbox );
2378 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2379 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2382 check = gtk_check_button_new_with_label( _( "Snapshots" ) );
2383 gtk_widget_show( check );
2384 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2385 AddDialogData( check, &m_bSnapShots, DLG_CHECK_BOOL );
2387 // load last project on open
2388 check = gtk_check_button_new_with_label( _( "Load last project on open" ) );
2389 gtk_widget_show( check );
2390 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2391 AddDialogData( check, &m_bLoadLast, DLG_CHECK_BOOL );
2393 // load last map on open
2394 check = gtk_check_button_new_with_label( _( "Load last map on open" ) );
2395 gtk_widget_show( check );
2396 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2397 AddDialogData( check, &m_bLoadLastMap, DLG_CHECK_BOOL );
2401 hbox2 = gtk_hbox_new( FALSE, 5 );
2402 gtk_widget_show( hbox2 );
2403 gtk_box_pack_start( GTK_BOX( vbox ), hbox2, FALSE, FALSE, 0 );
2404 gtk_container_set_border_width( GTK_CONTAINER( hbox2 ), 0 );
2407 check = gtk_check_button_new_with_label( _( "Auto save every" ) );
2408 gtk_widget_show( check );
2409 gtk_box_pack_start( GTK_BOX( hbox2 ), check, FALSE, FALSE, 0 );
2410 AddDialogData( check, &m_bAutoSave, DLG_CHECK_BOOL );
2413 spin = gtk_spin_button_new( GTK_ADJUSTMENT( gtk_adjustment_new( 1, 1, 60, 1, 10, 10 ) ), 1, 0 );
2414 gtk_widget_show( spin );
2415 gtk_box_pack_start( GTK_BOX( hbox2 ), spin, FALSE, FALSE, 0 );
2416 gtk_widget_set_usize( spin, 60, -2 );
2417 AddDialogData( spin, &m_nAutoSave, DLG_SPIN_INT );
2420 label = gtk_label_new( _( "minutes" ) );
2421 gtk_widget_show( label );
2422 gtk_box_pack_start( GTK_BOX( hbox2 ), label, FALSE, FALSE, 0 );
2424 // Add the page to the notebook
2425 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2427 /******** Paths group *********/
2428 preflabel = gtk_label_new( _( "Paths" ) );
2429 gtk_widget_show( preflabel );
2430 pageframe = gtk_frame_new( _( "Paths" ) );
2431 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2432 gtk_widget_show( pageframe );
2433 vbox = gtk_vbox_new( FALSE, 5 );
2434 gtk_widget_show( vbox );
2435 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2436 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2440 table = gtk_table_new( 3, 3, FALSE );
2441 gtk_widget_show( table );
2442 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2443 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2444 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2447 label = gtk_label_new( _( "Prefab path:" ) );
2448 gtk_widget_show( label );
2449 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
2450 (GtkAttachOptions) ( 0 ),
2451 (GtkAttachOptions) ( 0 ), 0, 0 );
2452 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
2455 entry = gtk_entry_new();
2456 gtk_widget_show( entry );
2457 gtk_widget_set_usize( GTK_WIDGET( entry ), 240, -2 );
2458 gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1,
2459 (GtkAttachOptions) ( GTK_FILL ),
2460 (GtkAttachOptions) ( 0 ), 1, 0 );
2461 AddDialogData( entry, &m_strPrefabPath, DLG_ENTRY_TEXT );
2465 button = gtk_button_new_with_label( "..." );
2466 gtk_widget_show( button );
2467 gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( OnBtnBrowseprefab ), this );
2468 gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 0, 1,
2469 (GtkAttachOptions) ( 0 ),
2470 (GtkAttachOptions) ( 0 ), 0, 0 );
2475 label = gtk_label_new( _( "User INI path:" ) );
2476 gtk_widget_show( label );
2477 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
2478 (GtkAttachOptions) ( 0 ),
2479 (GtkAttachOptions) ( 0 ), 0, 0 );
2480 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
2482 // user ini path entry
2483 entry = gtk_entry_new();
2484 gtk_widget_show( entry );
2485 gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2,
2486 (GtkAttachOptions) ( GTK_FILL ),
2487 (GtkAttachOptions) ( 0 ), 1, 0 );
2488 AddDialogData( entry, &m_strUserPath, DLG_ENTRY_TEXT );
2490 // user ini browse button
2491 button = gtk_button_new_with_label( "..." );
2492 gtk_widget_show( button );
2493 gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( OnBtnBrowseuserini ), this );
2494 gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 1, 2,
2495 (GtkAttachOptions) ( 0 ),
2496 (GtkAttachOptions) ( 0 ), 0, 0 );
2498 // Add the page to the notebook
2499 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2501 /******** Brush group ********/
2502 preflabel = gtk_label_new( _( "Brush" ) );
2503 gtk_widget_show( preflabel );
2504 pageframe = gtk_frame_new( _( "Brush" ) );
2505 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2506 gtk_widget_show( pageframe );
2507 vbox = gtk_vbox_new( FALSE, 5 );
2508 gtk_widget_show( vbox );
2509 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2510 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2512 // default texture scale
2514 table = gtk_table_new( 2, 1, FALSE ); // I believe that the 2 and 1 are switched here, and this is
2515 // intentional to be consistent with other calls to gtk_table_new()
2516 // [that are probably also switched].
2517 gtk_widget_show( table );
2518 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2519 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2520 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2523 label = gtk_label_new( _( "Default texture scale:" ) );
2524 gtk_widget_show( label );
2525 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
2526 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
2527 (GtkAttachOptions) ( 0 ),
2528 (GtkAttachOptions) ( 0 ), 0, 0 );
2531 entry = gtk_entry_new();
2532 gtk_widget_show( entry );
2533 gtk_widget_set_usize( GTK_WIDGET( entry ), 60, -2 );
2534 gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1,
2535 (GtkAttachOptions) ( GTK_FILL ),
2536 (GtkAttachOptions) ( 0 ), 0, 0 );
2537 AddDialogData( entry, &m_fDefTextureScale, DLG_ENTRY_FLOAT );
2539 // Add the page to the notebook
2540 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2542 /******** Misc group *********/
2543 preflabel = gtk_label_new( _( "Misc" ) );
2544 gtk_widget_show( preflabel );
2545 pageframe = gtk_frame_new( _( "Misc" ) );
2546 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2547 gtk_widget_show( pageframe );
2548 vbox = gtk_vbox_new( FALSE, 5 );
2549 gtk_widget_show( vbox );
2550 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2551 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2554 check = gtk_check_button_new_with_label( _( "Light drawing" ) );
2555 gtk_widget_show( check );
2556 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2557 AddDialogData( check, &m_bNewLightDraw, DLG_CHECK_BOOL );
2561 table = gtk_table_new( 2, 1, FALSE );
2562 gtk_widget_show( table );
2563 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2564 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2565 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2567 label = gtk_label_new( _( "Light radiuses:" ) );
2568 gtk_widget_show( label );
2569 gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_LEFT );
2570 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
2571 (GtkAttachOptions) ( 0 ),
2572 (GtkAttachOptions) ( 0 ), 0, 0 );
2575 combo_list = g_list_append( combo_list, (void *)_( "Disabled" ) );
2576 combo_list = g_list_append( combo_list, (void *)_( "True Q3Map2 Style" ) );
2577 combo_list = g_list_append( combo_list, (void *)_( "Classic Style" ) );
2579 combo = gtk_combo_new();
2580 gtk_combo_set_popdown_strings( GTK_COMBO( combo ), combo_list );
2581 gtk_widget_show( combo );
2582 gtk_table_attach( GTK_TABLE( table ), combo, 1, 2, 0, 1,
2583 (GtkAttachOptions) ( GTK_FILL ),
2584 (GtkAttachOptions) ( 0 ), 0, 0 );
2585 gtk_entry_set_editable( GTK_ENTRY( GTK_COMBO( combo )->entry ), FALSE );
2586 AddDialogData( combo, &m_nLightRadiuses, DLG_COMBO_INT );
2589 check = gtk_check_button_new_with_label( _( "Use win32 file associations to open text files instead of builtin editor" ) );
2590 gtk_widget_show( check );
2591 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2592 AddDialogData( check, &g_PrefsDlg.m_bUseWin32Editor, DLG_CHECK_BOOL );
2594 // use custom shader editor
2595 check = gtk_check_button_new_with_label( _( "Use Custom Shader Editor" ) );
2596 gtk_widget_show( check );
2597 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2598 gtk_signal_connect( GTK_OBJECT( check ), "clicked", GTK_SIGNAL_FUNC( UpdateEditorSensitivity ), this );
2599 g_object_set_data( G_OBJECT( dialog ), "check_customeditor", check );
2600 AddDialogData( check, &g_PrefsDlg.m_bUseCustomEditor, DLG_CHECK_BOOL );
2602 // custom shader editor executable
2604 table = gtk_table_new( 3, 1, FALSE );
2605 gtk_widget_show( table );
2606 gtk_box_pack_start( GTK_BOX( vbox ), table, FALSE, TRUE, 0 );
2607 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
2608 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
2611 label = gtk_label_new( _( "Custom Editor Command" ) );
2612 gtk_widget_show( label );
2613 gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
2614 (GtkAttachOptions) ( 0 ),
2615 (GtkAttachOptions) ( 0 ), 0, 0 );
2616 gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
2617 g_object_set_data( G_OBJECT( dialog ), "label_customeditor", label );
2618 gtk_widget_set_sensitive( label, g_PrefsDlg.m_bUseCustomEditor );
2620 // custom editor command entry
2621 entry = gtk_entry_new();
2622 gtk_widget_show( entry );
2623 gtk_widget_set_usize( GTK_WIDGET( entry ), 240, -2 );
2624 gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1,
2625 (GtkAttachOptions) ( GTK_FILL ),
2626 (GtkAttachOptions) ( 0 ), 1, 0 );
2627 AddDialogData( entry, &m_strEditorCommand, DLG_ENTRY_TEXT );
2628 gtk_widget_set_sensitive( entry, g_PrefsDlg.m_bUseCustomEditor );
2629 g_object_set_data( G_OBJECT( dialog ), "entry_customeditor", entry );
2632 button = gtk_button_new_with_label( _( "..." ) );
2633 gtk_widget_show( button );
2634 gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( OnBtnBrowseEditor ), this );
2635 gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 0, 1,
2636 (GtkAttachOptions) ( 0 ),
2637 (GtkAttachOptions) ( 0 ), 0, 0 );
2638 g_object_set_data( G_OBJECT( dialog ), "button_customeditor", button );
2639 gtk_widget_set_sensitive( button, g_PrefsDlg.m_bUseCustomEditor );
2642 // Add the page to the notebook
2643 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2645 /******** BSP Monitoring group *********/
2646 // this is never displayed if the plugin isn't available
2647 preflabel = gtk_label_new( _( "BSP Monitoring" ) );
2648 gtk_widget_show( preflabel );
2649 pageframe = gtk_frame_new( _( "BSP Monitoring" ) );
2650 gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 5 );
2651 gtk_widget_show( pageframe );
2652 vbox = gtk_vbox_new( FALSE, 5 );
2653 gtk_widget_show( vbox );
2654 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
2655 gtk_container_add( GTK_CONTAINER( pageframe ), vbox );
2657 // Enable BSP process monitoring
2658 check = gtk_check_button_new_with_label( _( "Enable BSP process monitoring" ) );
2659 gtk_widget_show( check );
2660 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2661 g_object_set_data( G_OBJECT( dialog ), "check_monitorbsp", check );
2662 gtk_signal_connect( GTK_OBJECT( check ), "clicked", GTK_SIGNAL_FUNC( UpdateSensitivity ), this );
2663 AddDialogData( check, &g_PrefsDlg.m_bWatchBSP, DLG_CHECK_BOOL );
2666 check = gtk_check_button_new_with_label( _( "Stop compilation on leak" ) );
2667 gtk_widget_show( check );
2668 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2669 g_object_set_data( G_OBJECT( dialog ), "check_leakstop", check );
2670 AddDialogData( check, &g_PrefsDlg.m_bLeakStop, DLG_CHECK_BOOL );
2672 // engine after compile
2673 check = gtk_check_button_new_with_label( _( "Run engine after compile" ) );
2674 gtk_widget_show( check );
2675 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2676 g_object_set_data( G_OBJECT( dialog ), "check_runengine", check );
2677 gtk_signal_connect( GTK_OBJECT( check ), "clicked", GTK_SIGNAL_FUNC( UpdateSensitivity ), this );
2678 AddDialogData( check, &g_PrefsDlg.m_bRunQuake, DLG_CHECK_BOOL );
2680 // sleep mode when running engine
2681 check = gtk_check_button_new_with_label( _( "Activate sleep mode when running the engine" ) );
2682 gtk_widget_show( check );
2683 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2684 g_object_set_data( G_OBJECT( dialog ), "check_sleep", check );
2685 AddDialogData( check, &g_PrefsDlg.m_bDoSleep, DLG_CHECK_BOOL );
2687 // use q3map2's texture projection
2688 check = gtk_check_button_new_with_label( _( "Texturing compatible with q3map2" ) );
2689 gtk_widget_show( check );
2690 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
2691 g_object_set_data( G_OBJECT( dialog ), "check_q3map2", check );
2692 AddDialogData( check, &g_PrefsDlg.m_bQ3Map2Texturing, DLG_CHECK_BOOL );
2694 // Add the page to the notebook
2695 gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel );
2697 gtk_notebook_set_page( GTK_NOTEBOOK( notebook ), PTAB_FRONT );
2702 // end new prefs dialog
2704 void PrefsDlg::LoadTexdefPref( texdef_t* pTexdef, char* pName ){
2707 memset( pTexdef, 0, sizeof( texdef_t ) );
2709 sprintf( buffer, "%s%s", pName, TD_SCALE1_KEY );
2710 mLocalPrefs.GetPref( buffer, &pTexdef->scale[0], 0.5f );
2712 sprintf( buffer, "%s%s", pName, TD_SCALE2_KEY );
2713 mLocalPrefs.GetPref( buffer, &pTexdef->scale[1], 0.5f );
2715 sprintf( buffer, "%s%s", pName, TD_SHIFT1_KEY );
2716 mLocalPrefs.GetPref( buffer, &pTexdef->shift[0], 8.f );
2718 sprintf( buffer, "%s%s", pName, TD_SHIFT2_KEY );
2719 mLocalPrefs.GetPref( buffer, &pTexdef->shift[1], 8.f );
2721 sprintf( buffer, "%s%s", pName, TD_ROTATE_KEY );
2722 mLocalPrefs.GetPref( buffer, &pTexdef->rotate, 45 );
2725 void PrefsDlg::UpdateTextureCompression(){
2726 // if OpenGL is not ready yet, don't do anything
2727 if ( !g_qeglobals.m_bOpenGLReady ) {
2728 Sys_Printf( "OpenGL not ready - postpone texture compression capability check\n" );
2732 if ( g_qeglobals.bTextureCompressionSupported ) {
2733 if ( m_nTextureCompressionFormat >= 2 && !g_qeglobals.m_bS3CompressionSupported ) {
2734 Sys_Printf( "Inconsistant pref setting for texture compression (%d), rolling back\n", m_nTextureCompressionFormat );
2735 m_nTextureCompressionFormat = 1; // if this is not supported either, see below
2737 if ( m_nTextureCompressionFormat == 1 && !g_qeglobals.m_bOpenGLCompressionSupported ) {
2738 Sys_Printf( "Inconsistant pref setting for texture compression (GL_COMPRESSED_RGBA), rolling back\n" );
2739 m_nTextureCompressionFormat = 0;
2741 switch ( m_nTextureCompressionFormat )
2745 g_qeglobals.texture_components = GL_RGBA;
2746 Sys_Printf( "texture compression disabled by preferences settings\n" );
2751 g_qeglobals.texture_components = GL_COMPRESSED_RGBA;
2752 Sys_Printf( "OpenGL texture compression enabled\n" );
2757 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
2758 Sys_Printf( "S3TC DXT1 texture compression enabled\n" );
2763 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
2764 Sys_Printf( "S3TC DXT3 texture compression enabled\n" );
2769 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
2770 Sys_Printf( "S3TC DXT5 texture compression enabled\n" );
2777 Sys_Printf( "texture compression is not supported by your current graphic card/drivers\n" );
2778 g_qeglobals.texture_components = GL_RGBA;
2779 m_nTextureCompressionFormat = 0;
2784 void PrefsDlg::UpdateATIHack() {
2785 // if OpenGL is not ready yet, don't do anything
2786 if ( !g_qeglobals.m_bOpenGLReady ) {
2787 Sys_Printf( "OpenGL not ready - postpone ATI bug workaround setup\n" );
2791 if ( m_bGlATIHack ) {
2792 qglCullFace = &qglCullFace_ATIHack;
2793 qglDisable = &qglDisable_ATIHack;
2794 qglEnable = &qglEnable_ATIHack;
2795 qglPolygonMode = &qglPolygonMode_ATIHack;
2796 Sys_Printf( "ATI bug workaround enabled\n" );
2799 qglCullFace = qglCullFace_real;
2800 qglDisable = qglDisable_real;
2801 qglEnable = qglEnable_real;
2802 qglPolygonMode = qglPolygonMode_real;
2803 Sys_Printf( "ATI bug workaround disabled\n" );
2808 #ifdef NVIDIA_AERO_HACK
2809 void PrefsDlg::UpdateNvidiaAeroHack() {
2810 if ( m_bGlNvidiaAeroHack && m_bGlNvidiaAeroHackPrevState == 1 ) {
2813 if ( ( !m_bGlNvidiaAeroHack ) && m_bGlNvidiaAeroHackPrevState == 0 ) {
2816 if ( ( !m_bGlNvidiaAeroHack ) && m_bGlNvidiaAeroHackPrevState < 0 ) {
2817 // The hack state is uninitialized, meaning that this is the first call
2818 // to this function. I prefer not to explicitly enable composition because
2819 // the user may have set the application to disable it, and I don't want to
2820 // override that. Leave the state of composition as-is if the hack checkbox
2822 m_bGlNvidiaAeroHackPrevState = 0;
2825 HMODULE lib = LoadLibrary( "dwmapi.dll" );
2827 void ( WINAPI *qDwmEnableComposition )( bool bEnable ) =
2828 ( void (WINAPI *) ( bool bEnable ) )GetProcAddress( lib, "DwmEnableComposition" );
2829 if ( qDwmEnableComposition ) {
2830 if ( m_bGlNvidiaAeroHack ) {
2831 Sys_Printf( "Disabling Windows composition\n" );
2832 qDwmEnableComposition( 0 );
2833 m_bGlNvidiaAeroHackPrevState = 1;
2836 Sys_Printf( "Enabling Windows composition\n" );
2837 qDwmEnableComposition( 1 );
2838 m_bGlNvidiaAeroHackPrevState = 0;
2846 // TTimo: m_strEnginePath has a special status, if not found in registry we need to
2847 // initiliaze it for sure. It is not totally failsafe but we can use the same
2848 // code than in q3map, expecting to find some "quake" above us. If not, we prompt
2849 // for the engine executable path
2850 void PrefsDlg::LoadPrefs(){
2853 // first things first, load prefs from global prefs
2854 mGamesDialog.LoadPrefs();
2856 // if we already have a document loaded, we will free and reload from file
2857 if ( mLocalPrefs.InUse() ) {
2858 mLocalPrefs.Clear();
2861 // load local.pref file
2862 mLocalPrefs.ReadXMLFile( m_inipath->str );
2864 mLocalPrefs.GetPref( PATCHSHOWBOUNDS_KEY, &g_bPatchShowBounds, FALSE );
2865 mLocalPrefs.GetPref( MOUSE_KEY, &m_nMouse, MOUSE_DEF );
2866 m_nMouseButtons = m_nMouse ? 3 : 2;
2869 // if it's not found here, mainframe.cpp will take care of finding one
2870 mLocalPrefs.GetPref( LASTPROJ_KEY, &m_strLastProject, "" );
2871 mLocalPrefs.GetPref( LASTPROJVER_KEY, &m_nLastProjectVer, -1 );
2874 // NOTE TTimo: I'm not sure why this is in prefs
2875 // should probably be a project setting
2876 // and I'm not sure that we really have a way to set this reliably either
2878 strPrefab = g_qeglobals.m_strHomeGame.GetBuffer();
2879 strPrefab += g_pGameDescription->mBaseGame.GetBuffer();
2880 strPrefab += "/prefabs/";
2881 mLocalPrefs.GetPref( PREFAB_KEY, &m_strPrefabPath, strPrefab );
2883 mLocalPrefs.GetPref( LASTLIGHTINTENSITY_KEY, &m_iLastLightIntensity, 300 );
2884 mLocalPrefs.GetPref( TLOCK_KEY, &m_bTextureLock, TLOCK_DEF );
2885 mLocalPrefs.GetPref( RLOCK_KEY, &m_bRotateLock, TLOCK_DEF );
2886 mLocalPrefs.GetPref( LASTMAP_KEY, &m_strLastMap, "" );
2887 mLocalPrefs.GetPref( LOADLAST_KEY, &m_bLoadLast, LOADLAST_DEF );
2888 mLocalPrefs.GetPref( BSP_KEY, &m_bInternalBSP, FALSE );
2889 mLocalPrefs.GetPref( RCLICK_KEY, &m_bRightClick, TRUE );
2890 mLocalPrefs.GetPref( AUTOSAVE_KEY, &m_bAutoSave, TRUE );
2891 mLocalPrefs.GetPref( LOADLASTMAP_KEY, &m_bLoadLastMap, FALSE );
2892 mLocalPrefs.GetPref( TINYBRUSH_KEY, &m_bCleanTiny, FALSE );
2893 mLocalPrefs.GetPref( TINYSIZE_KEY, &m_fTinySize, 0.5f );
2894 mLocalPrefs.GetPref( AUTOSAVETIME_KEY, &m_nAutoSave, 5 );
2895 mLocalPrefs.GetPref( SNAPSHOT_KEY, &m_bSnapShots, FALSE );
2896 mLocalPrefs.GetPref( MOVESPEED_KEY, &m_nMoveSpeed, 100 );
2897 mLocalPrefs.GetPref( ANGLESPEED_KEY, &m_nAngleSpeed, 3 );
2898 mLocalPrefs.GetPref( SETGAME_KEY, &m_bSetGame, FALSE );
2899 mLocalPrefs.GetPref( CAMXYUPDATE_KEY, &m_bCamXYUpdate, TRUE );
2900 mLocalPrefs.GetPref( CAMDRAGMULTISELECT_KEY, &m_nCamDragMultiSelect, TRUE );
2901 mLocalPrefs.GetPref( CAMFREELOOK_KEY, &m_bCamFreeLook, TRUE );
2902 mLocalPrefs.GetPref( CAMINVERSEMOUSE_KEY, &m_bCamInverseMouse, FALSE );
2903 mLocalPrefs.GetPref( CAMDISCRETE_KEY, &m_bCamDiscrete, TRUE );
2904 mLocalPrefs.GetPref( LIGHTDRAW_KEY, &m_bNewLightDraw, TRUE );
2905 mLocalPrefs.GetPref( CUBICCLIP_KEY, &m_bCubicClipping, TRUE );
2906 mLocalPrefs.GetPref( CUBICSCALE_KEY, &m_nCubicScale, 13 );
2907 mLocalPrefs.GetPref( ALTEDGE_KEY, &m_bALTEdge, FALSE );
2908 mLocalPrefs.GetPref( FACECOLORS_KEY, &m_bFaceColors, FALSE );
2909 mLocalPrefs.GetPref( XZVIS_KEY, &m_bXZVis, FALSE );
2910 mLocalPrefs.GetPref( YZVIS_KEY, &m_bYZVis, FALSE );
2911 mLocalPrefs.GetPref( ZVIS_KEY, &m_bZVis, FALSE );
2912 mLocalPrefs.GetPref( SIZEPAINT_KEY, &m_bSizePaint, FALSE );
2913 mLocalPrefs.GetPref( DLLENTITIES_KEY, &m_bDLLEntities, FALSE );
2915 mLocalPrefs.GetPref( DETACHABLEMENUS_KEY, &m_bLatchedDetachableMenus, TRUE );
2916 m_bDetachableMenus = m_bLatchedDetachableMenus;
2918 if ( g_pGameDescription->mNoPatch ) {
2919 m_bPatchToolbar = false;
2923 mLocalPrefs.GetPref( PATCHTOOLBAR_KEY, &m_bLatchedPatchToolbar, TRUE );
2924 m_bPatchToolbar = m_bLatchedPatchToolbar;
2927 mLocalPrefs.GetPref( WIDETOOLBAR_KEY, &m_bLatchedWideToolbar, TRUE );
2928 m_bWideToolbar = m_bLatchedWideToolbar;
2930 mLocalPrefs.GetPref( PLUGINTOOLBAR_KEY, &m_bLatchedPluginToolbar, TRUE );
2931 m_bPluginToolbar = m_bLatchedPluginToolbar;
2933 mLocalPrefs.GetPref( WINDOW_KEY, (int*)&m_nLatchedView, WINDOW_DEF );
2934 m_nView = m_nLatchedView;
2936 mLocalPrefs.GetPref( FLOATINGZ_KEY, &m_bLatchedFloatingZ, FALSE );
2937 m_bFloatingZ = m_bLatchedFloatingZ;
2939 mLocalPrefs.GetPref( TEXTUREQUALITY_KEY, &m_nLatchedTextureQuality, 3 );
2940 m_nTextureQuality = m_nLatchedTextureQuality;
2942 mLocalPrefs.GetPref( LOADSHADERS_KEY, &m_nLatchedShader, 0 );
2943 m_nShader = m_nLatchedShader;
2945 mLocalPrefs.GetPref( NOCLAMP_KEY, &m_bNoClamp, FALSE );
2946 mLocalPrefs.GetPref( SNAP_KEY, &m_bSnap, TRUE );
2947 mLocalPrefs.GetPref( USERINI_KEY, &m_strUserPath, "" );
2948 mLocalPrefs.GetPref( ROTATION_KEY, &m_nRotation, 45 );
2949 mLocalPrefs.GetPref( CHASEMOUSE_KEY, &m_bChaseMouse, TRUE );
2950 mLocalPrefs.GetPref( ENTITYSHOW_KEY, &m_nEntityShowState, ENTITY_SKINNED_BOXED );
2952 // this will probably need to be 75 or 100 for Q1.
2953 mLocalPrefs.GetPref( TEXTURESCALE_KEY, &m_nTextureScale, 50 );
2955 // FIXME: Hydra - actually, this stuff is Q1,Q2 and HL specific.
2956 if ( ( g_pGameDescription->mGameFile == "hl.game" ) ) {
2957 // No BSP monitoring in the default compiler tools for Half-life (yet)
2958 mLocalPrefs.GetPref( WATCHBSP_KEY, &m_bWatchBSP, FALSE );
2960 // Texture subset on by default (HL specific really, because of halflife.wad's size)
2961 mLocalPrefs.GetPref( TEXTURE_KEY, &m_bTextureWindow, TRUE );
2963 else if ( g_pGameDescription->quake2 ) {
2964 // BSP monitoring is implemented in Quake2 and Heretic2 tools
2965 mLocalPrefs.GetPref( WATCHBSP_KEY, &m_bWatchBSP, TRUE );
2967 // Texture subset on by default (HL specific really, because of halflife.wad's size)
2968 mLocalPrefs.GetPref( TEXTURE_KEY, &m_bTextureWindow, TRUE );
2972 mLocalPrefs.GetPref( WATCHBSP_KEY, &m_bWatchBSP, WATCHBSP_DEF );
2973 mLocalPrefs.GetPref( TEXTURE_KEY, &m_bTextureWindow, FALSE );
2977 mLocalPrefs.GetPref( TEXTURESCROLLBAR_KEY, &m_bTextureScrollbar, TRUE );
2978 mLocalPrefs.GetPref( DISPLAYLISTS_KEY, &m_bDisplayLists, TRUE );
2979 mLocalPrefs.GetPref( ANTIALIASEDLINES_KEY, &m_bAntialiasedPointsAndLines, FALSE );
2980 mLocalPrefs.GetPref( SWITCHCLIP_KEY, &m_bSwitchClip, TRUE );
2981 mLocalPrefs.GetPref( SELWHOLEENTS_KEY, &m_bSelectWholeEntities, TRUE );
2982 mLocalPrefs.GetPref( SHOWSHADERS_KEY, &m_bShowShaders, TRUE );
2983 mLocalPrefs.GetPref( GLLIGHTING_KEY, &m_bGLLighting, FALSE );
2984 mLocalPrefs.GetPref( NOSTIPPLE_KEY, &m_bNoStipple, FALSE );
2985 mLocalPrefs.GetPref( UNDOLEVELS_KEY, &m_nUndoLevels, 30 );
2986 mLocalPrefs.GetPref( VERTEXMODE_KEY, &m_bVertexSplit, TRUE );
2987 mLocalPrefs.GetPref( RUNQ2_KEY, &m_bRunQuake, RUNQ2_DEF );
2988 mLocalPrefs.GetPref( LEAKSTOP_KEY, &m_bLeakStop, TRUE );
2989 mLocalPrefs.GetPref( DOSLEEP_KEY, &m_bDoSleep, FALSE );
2990 mLocalPrefs.GetPref( SELECTCURVES_KEY, &m_bSelectCurves, TRUE );
2991 mLocalPrefs.GetPref( SELECTMODELS_KEY, &m_bSelectModels, TRUE );
2992 mLocalPrefs.GetPref( SHADERLISTONLY_KEY, &m_bTexturesShaderlistOnly, FALSE );
2993 mLocalPrefs.GetPref( DEFAULTTEXURESCALE_KEY, &m_fDefTextureScale, g_pGameDescription->mTextureDefaultScale );
2994 mLocalPrefs.GetPref( SUBDIVISIONS_KEY, &m_nSubdivisions, SUBDIVISIONS_DEF );
2995 mLocalPrefs.GetPref( CLIPCAULK_KEY, &m_bClipCaulk, FALSE );
2996 mLocalPrefs.GetPref( SNAPTTOGRID_KEY, &m_bSnapTToGrid, FALSE );
2997 mLocalPrefs.GetPref( TARGETFIX_KEY, &m_bDoTargetFix, TRUE );
2998 mLocalPrefs.GetPref( WHEELINC_KEY, &m_nWheelInc, 64 );
2999 mLocalPrefs.GetPref( PATCHBBOXSEL_KEY, &m_bPatchBBoxSelect, FALSE );
3001 // Gef: Kyro GL_POINT workaround
3002 mLocalPrefs.GetPref( GLPOINTWORKAROUND_KEY, &m_bGlPtWorkaround, FALSE );
3004 // window positioning
3005 mLocalPrefs.GetPref( ENTITYSPLIT1_KEY, &mWindowInfo.nEntitySplit1, -1 );
3006 mLocalPrefs.GetPref( ENTITYSPLIT2_KEY, &mWindowInfo.nEntitySplit2, -1 );
3008 mLocalPrefs.GetPref( POSITIONX_KEY, &mWindowInfo.position.x, -1 );
3009 mLocalPrefs.GetPref( POSITIONY_KEY, &mWindowInfo.position.y, -1 );
3010 mLocalPrefs.GetPref( WIDTH_KEY, &mWindowInfo.position.w, -1 );
3011 mLocalPrefs.GetPref( HEIGHT_KEY, &mWindowInfo.position.h, 450 );
3013 const window_position_t default_window_pos = { 0, 0, 200, 200, };
3015 mLocalPrefs.GetPref( ENTITYWND_KEY, &mWindowInfo.posEntityWnd, default_window_pos );
3016 mLocalPrefs.GetPref( MAPINFOWND_KEY, &mWindowInfo.posMapInfoWnd, default_window_pos );
3017 mLocalPrefs.GetPref( CAMWND_KEY, &mWindowInfo.posCamWnd, default_window_pos );
3018 mLocalPrefs.GetPref( ZWND_KEY, &mWindowInfo.posZWnd, default_window_pos );
3019 mLocalPrefs.GetPref( XYWND_KEY, &mWindowInfo.posXYWnd, default_window_pos );
3020 mLocalPrefs.GetPref( YZWND_KEY, &mWindowInfo.posYZWnd, default_window_pos );
3021 mLocalPrefs.GetPref( XZWND_KEY, &mWindowInfo.posXZWnd, default_window_pos );
3022 mLocalPrefs.GetPref( PATCHWND_KEY, &mWindowInfo.posPatchWnd, default_window_pos );
3023 mLocalPrefs.GetPref( SURFACEWND_KEY, &mWindowInfo.posSurfaceWnd, default_window_pos );
3024 mLocalPrefs.GetPref( ENTITYINFOWND_KEY, &mWindowInfo.posEntityInfoWnd, default_window_pos );
3026 mLocalPrefs.GetPref( ZWIDTH_KEY, &mWindowInfo.nZWidth, 30 );
3027 mLocalPrefs.GetPref( XYHEIGHT_KEY, &mWindowInfo.nXYHeight, 300 );
3028 mLocalPrefs.GetPref( XYWIDTH_KEY, &mWindowInfo.nXYWidth, 300 );
3029 mLocalPrefs.GetPref( CAMWIDTH_KEY, &mWindowInfo.nCamWidth, 200 );
3030 mLocalPrefs.GetPref( CAMHEIGHT_KEY, &mWindowInfo.nCamHeight, 200 );
3031 mLocalPrefs.GetPref( ZFLOATWIDTH_KEY, &mWindowInfo.nZFloatWidth, 300 );
3033 mLocalPrefs.GetPref( STATE_KEY, &mWindowInfo.nState, SW_SHOW );
3037 mLocalPrefs.GetPref( COUNT_KEY, &m_nMRUCount, 0 );
3038 for ( i = 0; i < 4; i++ )
3041 sprintf( buf, "%s%d", FILE_KEY, i );
3042 mLocalPrefs.GetPref( buf, &m_strMRUFiles[i], "" );
3045 // some platform specific prefs
3047 mLocalPrefs.GetPref( NATIVEGUI_KEY, &m_bNativeGUI, TRUE );
3048 mLocalPrefs.GetPref( STARTONPRIMMON_KEY, &m_bStartOnPrimMon, FALSE );
3051 mLocalPrefs.GetPref( SI_TEXMENU_KEY, &g_qeglobals.d_savedinfo.iTexMenu, ID_VIEW_BILINEARMIPMAP );
3052 mLocalPrefs.GetPref( SI_GAMMA_KEY, &g_qeglobals.d_savedinfo.fGamma, 1.0f );
3053 mLocalPrefs.GetPref( SI_EXCLUDE_KEY, &g_qeglobals.d_savedinfo.exclude, 0 ); // nothing filtered by default
3054 mLocalPrefs.GetPref( SI_INCLUDE_KEY, &g_qeglobals.d_savedinfo.include, INCLUDE_NAMES | INCLUDE_COORDS | INCLUDE_ANGLES | INCLUDE_CAMERATINT );
3055 mLocalPrefs.GetPref( SI_SHOWNAMES_KEY, &g_qeglobals.d_savedinfo.show_names, FALSE );
3056 mLocalPrefs.GetPref( SI_SHOWCOORDS_KEY, &g_qeglobals.d_savedinfo.show_coordinates, TRUE );
3057 mLocalPrefs.GetPref( SI_SHOWANGLES_KEY, &g_qeglobals.d_savedinfo.show_angles, TRUE );
3058 mLocalPrefs.GetPref( SI_SHOWOUTLINES_KEY, &g_qeglobals.d_savedinfo.show_outline, FALSE );
3059 mLocalPrefs.GetPref( SI_SHOWAXIS_KEY, &g_qeglobals.d_savedinfo.show_axis, TRUE );
3060 mLocalPrefs.GetPref( SI_NOSELOUTLINES_KEY, &g_qeglobals.d_savedinfo.bNoSelectedOutlines, FALSE );
3062 mLocalPrefs.GetPref( SI_OUTLINESTYLE_KEY, &g_qeglobals.d_savedinfo.iSelectedOutlinesStyle, OUTLINE_ZBUF | OUTLINE_BSEL );
3064 LoadTexdefPref( &g_qeglobals.d_savedinfo.m_SIIncrement, SI_SURFACE_TEXDEF_KEY );
3065 LoadTexdefPref( &g_qeglobals.d_savedinfo.m_PIIncrement, SI_PATCH_TEXDEF_KEY );
3067 // text editor binding
3069 mLocalPrefs.GetPref( CUSTOMSHADEREDITOR_KEY, &m_bUseWin32Editor, TRUE );
3071 mLocalPrefs.GetPref( CUSTOMSHADEREDITOR_KEY, &m_bUseCustomEditor, FALSE );
3072 mLocalPrefs.GetPref( CUSTOMSHADEREDITORCOMMAND_KEY, &m_strEditorCommand, "" );
3076 vec3_t vDefaultAxisColours[3] = {
3082 for ( i = 0; i < 3; i++ ) {
3084 sprintf( buf, "%s%d", SI_AXISCOLORS_KEY, i );
3085 mLocalPrefs.GetPref( buf, g_qeglobals.d_savedinfo.AxisColors[i], vDefaultAxisColours[i] );
3088 vec3_t vDefaultColours[COLOR_LAST] = {
3089 {0.25f, 0.25f, 0.25f},
3091 {0.75f, 0.75f, 0.75f},
3093 {0.25f, 0.25f, 0.25f},
3106 for ( i = 0; i < COLOR_LAST; i++ ) {
3108 sprintf( buf, "%s%d", SI_COLORS_KEY, i );
3109 mLocalPrefs.GetPref( buf, g_qeglobals.d_savedinfo.colors[i], vDefaultColours[i] );
3112 mLocalPrefs.GetPref( TEXTURECOMPRESSIONFORMAT_KEY, &m_nTextureCompressionFormat, 1 );
3114 mLocalPrefs.GetPref( LIGHTRADIUS_KEY, &m_nLightRadiuses, TRUE );
3116 mLocalPrefs.GetPref( Q3MAP2TEX_KEY, &m_bQ3Map2Texturing, TRUE );
3119 mLocalPrefs.GetPref( ATIHACK_KEY, &m_bGlATIHack, FALSE );
3122 #ifdef NVIDIA_AERO_HACK
3123 mLocalPrefs.GetPref( NVAEROHACK_KEY, &m_bGlNvidiaAeroHack, TRUE );
3126 Undo_SetMaxSize( m_nUndoLevels ); // set it internally as well / FIXME: why not just have one global value?
3128 UpdateTextureCompression();
3134 #ifdef NVIDIA_AERO_HACK
3135 UpdateNvidiaAeroHack();
3138 if ( mLocalPrefs.mbEmpty ) {
3139 mLocalPrefs.mbEmpty = false;
3140 Sys_Printf( "Saving local.pref with default pref values\n" );
3145 void PrefsDlg::SavePrefs(){
3146 if ( g_qeglobals.disable_ini ) {
3151 Sys_Printf( "PrefsDlg::SavePrefs\n" );
3154 // this will take care of copying back from the dialog to the variables
3155 // NOTE: it may be overkill to call systematically before a SavePrefs, but it's safer
3156 // this will also cause an UpdateData for the mGamesDialog
3159 mGamesDialog.SavePrefs();
3161 // update the tree and save it
3162 mLocalPrefs.UpdatePrefTree();
3163 if ( !mLocalPrefs.WriteXMLFile( m_inipath->str ) ) {
3164 Sys_FPrintf( SYS_ERR, "Error occured while saving local prefs file '%s'\n", m_inipath->str );
3167 if ( m_nMouse == 0 ) {
3168 m_nMouseButtons = 2;
3171 m_nMouseButtons = 3;
3176 void PrefsDlg::PostModal( int code ){
3177 if ( code == IDOK ) {
3179 // make sure the logfile is ok
3184 #ifdef NVIDIA_AERO_HACK
3185 UpdateNvidiaAeroHack();
3187 if ( g_pParentWnd ) {
3188 g_pParentWnd->SetGridStatus();
3190 Sys_UpdateWindows( W_ALL );
3191 if ( m_nUndoLevels != 0 ) {
3192 Undo_SetMaxSize( m_nUndoLevels );
3197 void PrefsDlg::DoEditorSensitivity(){
3198 if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( m_pWidget ), "check_customeditor" ) ) ) ) {
3199 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "label_customeditor" ) ), TRUE );
3200 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "entry_customeditor" ) ), TRUE );
3201 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "button_customeditor" ) ), TRUE );
3205 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "label_customeditor" ) ), FALSE );
3206 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "entry_customeditor" ) ), FALSE );
3207 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "button_customeditor" ) ), FALSE );
3211 void PrefsDlg::DoSensitivity(){
3213 // first, look at the project file version ... will monitoring work?
3214 // project files now XML, guaranteed to be at least version 2
3215 if ( 0 ) { //IntForKey( g_qeglobals.d_project_entity, "version" ) < 2)
3218 Msg = "The current project file (";
3219 Msg += g_PrefsDlg.m_strLastProject;
3220 Msg += ") is not at least version 2.\nI need version 2 or above to setup BSP monitoring correctly.";
3221 gtk_MessageBox( m_pWidget, Msg.GetBuffer(), MB_OK );
3226 // go ahead, disable everybuddy
3227 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_leakstop" ) ), FALSE );
3228 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_monitorbsp" ) ), FALSE );
3229 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_runengine" ) ), FALSE );
3230 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_sleep" ) ), FALSE );
3237 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_leakstop" ) ), TRUE );
3238 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_monitorbsp" ) ), TRUE );
3239 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_runengine" ) ), TRUE );
3240 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_sleep" ) ), TRUE );
3242 if ( !gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( m_pWidget ), "check_monitorbsp" ) ) ) ) {
3243 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_leakstop" ) ), FALSE );
3244 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_runengine" ) ), FALSE );
3245 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_sleep" ) ), FALSE );
3247 else if ( !gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT( m_pWidget ), "check_runengine" ) ) ) ) {
3248 gtk_widget_set_sensitive( GTK_WIDGET( g_object_get_data( G_OBJECT( m_pWidget ), "check_sleep" ) ), FALSE );
3253 ============================================================
3255 ============================================================
3258 CGameInstall::CGameInstall() {
3259 memset( m_availGames, 0, sizeof( m_availGames ) );
3262 void CGameInstall::OnBtnBrowseEngine( GtkWidget *widget, gpointer data ) {
3263 Sys_Printf( "OnBtnBrowseEngine\n" );
3265 CGameInstall* i = static_cast<CGameInstall*>( data );
3266 char *dir = dir_dialog( i->m_pWidget, _( "Select game directory" ), NULL );
3268 i->UpdateData( TRUE );
3270 if ( dir != NULL ) {
3271 i->m_strEngine = dir;
3272 i->UpdateData( FALSE );
3277 void CGameInstall::OnGameSelectChanged( GtkWidget *widget, gpointer data ) {
3278 Sys_Printf( "OnGameSelectChanged\n" );
3280 CGameInstall* i = static_cast<CGameInstall*>( data );
3281 i->UpdateData( TRUE );
3282 i->m_strName = gtk_combo_box_get_active_text( GTK_COMBO_BOX( widget ) );
3283 i->UpdateData( FALSE );
3286 void CGameInstall::BuildDialog() {
3287 GtkWidget *dlg, *vbox1, *button, *text, *combo, *entry, *hbox;
3290 gtk_window_set_title( GTK_WINDOW( dlg ), _( "Configure games" ) );
3292 vbox1 = gtk_vbox_new( FALSE, 0 );
3293 gtk_widget_show( vbox1 );
3294 gtk_container_add( GTK_CONTAINER( dlg ), vbox1 );
3296 text = gtk_label_new( _( "Select the game to configure" ) );
3297 gtk_widget_show( text );
3298 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3300 combo = gtk_combo_box_new_text();
3301 gtk_widget_show( combo );
3302 gtk_box_pack_start( GTK_BOX( vbox1 ), combo, FALSE, FALSE, 0 );
3304 // GList *combo_list = NULL;
3306 while ( m_availGames[ iGame ] != GAME_NONE ) {
3307 switch ( m_availGames[ iGame ] ) {
3309 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Quake II" ) );
3312 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Quake III Arena and mods" ) );
3315 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Urban Terror (standalone)" ) );
3318 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "UFO: Alien Invasion" ) );
3321 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Quake2World" ) );
3324 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Warsow" ) );
3327 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Nexuiz" ) );
3329 case GAME_TREMULOUS:
3330 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Tremulous" ) );
3333 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Jedi Academy and mods" ) );
3336 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), _( "Reaction Quake 3" ) );
3341 AddDialogData( combo, &m_nComboSelect, DLG_COMBO_BOX_INT );
3342 gtk_signal_connect( GTK_OBJECT( combo ), "changed", G_CALLBACK( OnGameSelectChanged ), this );
3343 gtk_combo_box_set_active( GTK_COMBO_BOX( combo ), 0 ); // NOTE: will trigger signal
3345 text = gtk_label_new( _( "Name:" ) );
3346 gtk_widget_show( text );
3347 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3349 entry = gtk_entry_new();
3350 gtk_widget_show( entry );
3351 gtk_box_pack_start( GTK_BOX( vbox1 ), entry, FALSE, FALSE, 0 );
3352 AddDialogData( entry, &m_strName, DLG_ENTRY_TEXT );
3354 text = gtk_label_new( _( "Engine directory:" ) );
3355 gtk_widget_show( text );
3356 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3358 hbox = gtk_hbox_new( FALSE, 0 );
3359 gtk_widget_show( hbox );
3360 gtk_box_pack_start( GTK_BOX( vbox1 ), hbox, FALSE, FALSE, 0 );
3362 entry = gtk_entry_new();
3363 gtk_widget_show( entry );
3364 gtk_box_pack_start( GTK_BOX( hbox ), entry, FALSE, FALSE, 0 );
3365 AddDialogData( entry, &m_strEngine, DLG_ENTRY_TEXT );
3367 button = gtk_button_new_with_label( _( "..." ) );
3368 gtk_widget_show( button );
3369 gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( OnBtnBrowseEngine ), this );
3370 gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
3372 // this gets done in the project stuff atm
3374 text = gtk_label_new( _( "Mod subdirectory:" ) );
3375 gtk_widget_show( text );
3376 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3378 entry = gtk_entry_new();
3379 gtk_widget_show( entry );
3380 gtk_box_pack_start( GTK_BOX( vbox1 ), entry, FALSE, FALSE, 0 );
3381 AddDialogData( entry, &m_strMod, DLG_ENTRY_TEXT );
3384 button = gtk_button_new_with_label( _( "OK" ) );
3385 gtk_widget_show( button );
3386 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
3387 AddModalButton( button, IDOK );
3389 button = gtk_button_new_with_label( _( "Cancel" ) );
3390 gtk_widget_show( button );
3391 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
3392 AddModalButton( button, IDCANCEL );
3394 gtk_widget_set_usize( button, 60, -2 );
3397 void CGameInstall::Run() {
3399 if ( m_availGames[0] == GAME_NONE ) {
3402 if ( DoModal() == IDCANCEL ) {
3403 Sys_Printf( "game dialog cancelled\n" );
3406 Sys_Printf( "combo: %d name: %s engine: %s mod: %s\n", m_nComboSelect, m_strName.GetBuffer(), m_strEngine.GetBuffer(), m_strMod.GetBuffer() );
3408 // write out the game file
3409 Str gameFilePath = g_strAppPath.GetBuffer();
3410 gameFilePath += "games/";
3411 gameFilePath += m_strName.GetBuffer();
3412 gameFilePath += ".game";
3413 Sys_Printf( "game file: %s\n", gameFilePath.GetBuffer() );
3415 FILE * fg = fopen( gameFilePath.GetBuffer(), "w" );
3417 Error( "Failed to open %s for writing\n", gameFilePath.GetBuffer() );
3419 fprintf( fg, "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>\n<game\n" );
3420 fprintf( fg, " name=\"%s\"\n", m_strName.GetBuffer() );
3421 fprintf( fg, " "ENGINEPATH_ATTRIBUTE "=\"%s\"\n", m_strEngine.GetBuffer() );
3422 switch ( m_availGames[ m_nComboSelect ] ) {
3424 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/Quake2Pack/game\"\n", g_strAppPath.GetBuffer() );
3425 fprintf( fg, " prefix=\".quake2\"\n" );
3426 Str source = g_strAppPath.GetBuffer();
3427 source += "installs/";
3429 source += "/install/";
3430 Str dest = m_strEngine.GetBuffer();
3431 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3432 fprintf( fg, " basegame=\"baseq2\"\n" );
3436 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/Q3Pack/game\"\n", g_strAppPath.GetBuffer() );
3437 fprintf( fg, " prefix=\".q3a\"\n" );
3438 Str source = g_strAppPath.GetBuffer();
3439 source += "installs/";
3441 source += "/install/";
3442 Str dest = m_strEngine.GetBuffer();
3443 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3444 fprintf( fg, " basegame=\"baseq3\"\n" );
3448 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/UrTPack/game\"\n", g_strAppPath.GetBuffer() );
3449 fprintf( fg, " prefix=\".q3a\"\n" );
3450 Str source = g_strAppPath.GetBuffer();
3451 source += "installs/";
3453 source += "/install/";
3454 Str dest = m_strEngine.GetBuffer();
3455 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3456 fprintf( fg, " basegame=\"q3ut4\"\n" );
3460 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/UFOAIPack/game\"\n", g_strAppPath.GetBuffer() );
3461 fprintf( fg, " prefix=\".ufoai\"\n" );
3462 Str source = g_strAppPath.GetBuffer();
3463 source += "installs/";
3464 source += UFOAI_PACK;
3465 source += "/install/";
3466 Str dest = m_strEngine.GetBuffer();
3467 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3468 fprintf( fg, " basegame=\"base\"\n" );
3472 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/Q2WPack/game\"\n", g_strAppPath.GetBuffer() );
3473 fprintf( fg, " prefix=\".quake2world\"\n" );
3474 Str source = g_strAppPath.GetBuffer();
3475 source += "installs/";
3477 source += "/install/";
3478 Str dest = m_strEngine.GetBuffer();
3479 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3480 fprintf( fg, " basegame=\"default\"\n" );
3484 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/WarsowPack/game\"\n", g_strAppPath.GetBuffer() );
3485 fprintf( fg, " prefix=\".warsow\"\n" );
3486 Str source = g_strAppPath.GetBuffer();
3487 source += "installs/";
3488 source += WARSOW_PACK;
3489 source += "/install/";
3490 Str dest = m_strEngine.GetBuffer();
3491 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3492 fprintf( fg, " basegame=\"basewsw\"\n" );
3496 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/NexuizPack/game\"\n", g_strAppPath.GetBuffer() );
3497 fprintf( fg, " prefix=\".nexuiz\"\n" );
3498 Str source = g_strAppPath.GetBuffer();
3499 source += "installs/";
3500 source += NEXUIZ_PACK;
3501 source += "/install/";
3502 Str dest = m_strEngine.GetBuffer();
3503 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3504 fprintf( fg, " basegame=\"data\"\n" );
3507 case GAME_TREMULOUS: {
3508 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/TremulousPack/game\"\n", g_strAppPath.GetBuffer() );
3509 fprintf( fg, " prefix=\".tremulous\"\n" );
3510 Str source = g_strAppPath.GetBuffer();
3511 source += "installs/";
3512 source += TREMULOUS_PACK;
3513 source += "/install/";
3514 Str dest = m_strEngine.GetBuffer();
3515 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3516 fprintf( fg, " basegame=\"base\"\n" );
3520 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/JAPack/game\"\n", g_strAppPath.GetBuffer() );
3521 fprintf( fg, " prefix=\".ja\"\n" );
3522 Str source = g_strAppPath.GetBuffer();
3523 source += "installs/";
3525 source += "/install/";
3526 Str dest = m_strEngine.GetBuffer();
3527 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3528 fprintf( fg, " basegame=\"base\"\n" );
3531 case GAME_REACTION: {
3532 fprintf( fg, " "TOOLS_ATTRIBUTE "=\"%sinstalls/"REACTION_PACK "/game\"\n", g_strAppPath.GetBuffer() );
3533 fprintf( fg, " prefix=\".Reaction\"\n" );
3534 Str source = g_strAppPath.GetBuffer();
3535 source += "installs/";
3536 source += REACTION_PACK;
3537 source += "/install/";
3538 Str dest = m_strEngine.GetBuffer();
3539 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3540 fprintf( fg, " basegame=\"Boomstick\"\n" );
3541 fprintf( fg, " default_scale=\"0.5\"\n" ); // Superfluous because the default is already 0.5,
3542 // but demonstrates how to set the default texture scale
3543 // for a specific game.
3547 fprintf( fg, "/>\n" );
3553 CGameInstall::ScanGames
3554 scan for active games that can be installed, based on the presence
3557 void CGameInstall::ScanGames() {
3558 Str pakPaths = g_strAppPath.GetBuffer();
3560 const char *dirname;
3562 pakPaths += "installs/";
3563 FindFiles fileScan( pakPaths.GetBuffer() );
3564 while ( ( dirname = fileScan.NextFile() ) != NULL ) {
3565 if ( stricmp( dirname, Q3_PACK ) == 0 ) {
3566 m_availGames[ iGame++ ] = GAME_Q3;
3568 if ( stricmp( dirname, URT_PACK ) == 0 ) {
3569 m_availGames[ iGame++ ] = GAME_URT;
3571 if ( stricmp( dirname, UFOAI_PACK ) == 0 ) {
3572 m_availGames[ iGame++ ] = GAME_UFOAI;
3574 if ( stricmp( dirname, Q2W_PACK ) == 0 ) {
3575 m_availGames[ iGame++ ] = GAME_Q2W;
3577 if ( stricmp( dirname, WARSOW_PACK ) == 0 ) {
3578 m_availGames[ iGame++ ] = GAME_WARSOW;
3580 if ( stricmp( dirname, NEXUIZ_PACK ) == 0 ) {
3581 m_availGames[ iGame++ ] = GAME_NEXUIZ;
3583 if ( stricmp( dirname, Q2_PACK ) == 0 ) {
3584 m_availGames[ iGame++ ] = GAME_Q2;
3586 if ( stricmp( dirname, TREMULOUS_PACK ) == 0 ) {
3587 m_availGames[ iGame++ ] = GAME_TREMULOUS;
3589 if ( stricmp( dirname, JA_PACK ) == 0 ) {
3590 m_availGames[ iGame++ ] = GAME_JA;
3592 if ( stricmp( dirname, REACTION_PACK ) == 0 ) {
3593 m_availGames[ iGame++ ] = GAME_REACTION;
3596 Sys_Printf( "No installable games found in: %s\n",
3597 pakPaths.GetBuffer() );