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)
31 #if defined (__linux__) || defined (__APPLE__)
33 #include <sys/types.h>
47 #define PREF_SECTION "Prefs"
48 #define INTERNAL_SECTION "Internals"
49 #define MOUSE_KEY "MouseButtons"
50 #define WINDOW_KEY "QE4StyleWindows"
51 #define LAYOUT_KEY "WindowLayout"
52 #define RUNQ2_KEY "RunQuake2Run"
53 #define TLOCK_KEY "TextureLock"
54 #define RLOCK_KEY "RotateLock"
55 #define LOADLAST_KEY "LoadLast"
56 #define LOADLASTMAP_KEY "LoadLastMap"
57 #define LASTPROJ_KEY "LastProject"
58 #define LASTPROJVER_KEY "LastProjectKey"
59 #define LASTMAP_KEY "LastMap"
60 #define FACE_KEY "NewFaceGrab"
61 #define BSP_KEY "InternalBSP"
62 #define RCLICK_KEY "NewRightClick"
63 #define VERTEX_KEY "NewVertex"
64 #define AUTOSAVE_KEY "Autosave"
65 #define AUTOSAVETIME_KEY "AutosaveMinutes"
66 #define PAK_KEY "UsePAK"
67 #define NEWAPPLY_KEY "ApplyDismissesSurface"
68 #define HACK_KEY "Gatewayescapehack"
69 #define TEXTURE_KEY "NewTextureWindowStuff"
70 #define TINYBRUSH_KEY "CleanTinyBrushes"
71 #define TINYSIZE_KEY "CleanTinyBrusheSize"
72 #define SNAPSHOT_KEY "Snapshots"
73 #define MOVESPEED_KEY "MoveSpeed"
74 #define ANGLESPEED_KEY "AngleSpeed"
75 #define SETGAME_KEY "UseSetGame"
76 #define CAMXYUPDATE_KEY "CamXYUpdate"
77 #define CAMDRAGMULTISELECT_KEY "CamDragMultiSelect"
78 #define CAMFREELOOK_KEY "CamFreeLook"
79 #define CAMINVERSEMOUSE_KEY "CamInverseMouse"
80 #define CAMDISCRETE_KEY "CamDiscrete"
81 #define LIGHTDRAW_KEY "NewLightStyle"
82 #define WHATGAME_KEY "WhichGame"
83 #define CUBICCLIP_KEY "CubicClipping"
84 #define CUBICSCALE_KEY "CubicScale"
85 #define ALTEDGE_KEY "ALTEdgeDrag"
86 #define FACECOLORS_KEY "FaceColors"
87 #define SNAPT_KEY "SnapT"
88 #define XZVIS_KEY "XZVIS"
89 #define YZVIS_KEY "YZVIS"
90 #define ZVIS_KEY "ZVIS"
91 #define SIZEPAINT_KEY "SizePainting"
92 #define DLLENTITIES_KEY "DLLEntities"
93 #define DETACHABLEMENUS_KEY "DetachableMenus"
94 #define PATCHTOOLBAR_KEY "PatchToolBar"
95 #define WIDETOOLBAR_KEY "WideToolBar"
96 #define PLUGINTOOLBAR_KEY "PluginToolBar"
97 #define NOCLAMP_KEY "NoClamp"
98 #define PREFAB_KEY "PrefabPath"
99 #define USERINI_KEY "UserINIPath"
100 #define ROTATION_KEY "Rotation"
101 #define BUGGYICD_KEY "BuggyICD"
102 #define CHASEMOUSE_KEY "ChaseMouse"
103 #define ENTITYSHOW_KEY "EntityShow"
104 #define TEXTURESCALE_KEY "TextureScale"
105 #define TEXTURESCROLLBAR_KEY "TextureScrollbar"
106 #define DISPLAYLISTS_KEY "UseDisplayLists"
107 #define ANTIALIASEDLINES_KEY "UseAntialiasedPointsAndLines" // Fishman - Add antialiazed points and lines support. 09/03/00
108 #define NORMALIZECOLORS_KEY "NormalizeColors"
109 #define SHADERS_KEY "UseShaders"
110 #define SWITCHCLIP_KEY "SwitchClipKey"
111 #define SELWHOLEENTS_KEY "SelectWholeEntitiesKey"
112 #define TEXTURESUBSET_KEY "UseTextureSubsetLoading"
113 #define TEXTUREQUALITY_KEY "TextureQuality"
114 #define SHOWSHADERS_KEY "ShowShaders"
115 #define SHADERTEST_KEY "ShaderTest"
116 #define GLLIGHTING_KEY "UseGLLighting"
117 #define LOADSHADERS_KEY "LoadShaders"
118 #define NOSTIPPLE_KEY "NoStipple"
119 #define UNDOLEVELS_KEY "UndoLevels"
120 #define VERTEXMODE_KEY "VertexSplit"
121 #define ENGINEPATH_KEY "EnginePath"
122 #define ENGINE_KEY "Engine"
123 #define LOGCONSOLE_KEY "LogConsole"
124 #define SELECTCURVES_KEY "SelectCurves"
125 #define SELECTMODELS_KEY "SelectModels"
126 #define SHADERLISTONLY_KEY "ShowShaderlistOnly"
127 #define WATCHBSP_KEY "WatchBSP"
128 #define LEAKSTOP_KEY "LeakStop"
129 #define DOSLEEP_KEY "SleepMode"
130 #define SUBDIVISIONS_KEY "Subdivisions"
131 #define CLIPCAULK_KEY "ClipCaulk"
132 #define PATCHSHOWBOUNDS_KEY "PatchShowBounds"
133 #define NATIVEGUI_KEY "NativeGUI"
134 #define STARTONPRIMMON_KEY "StartOnPrimMon"
135 #define NOSYSMENUPOPUPS_KEY "NoSysMenuPopups"
136 #define SNAPTTOGRID_KEY "SnapTToGrid"
137 #define FLOATINGZ_KEY "FloatingZ"
138 #define TARGETFIX_KEY "TargetFix"
139 #define GLPOINTWORKAROUND_KEY "GlPointWorkaround" // Gef: Workaround for broken Kyro * gl driver 25-aug-2001
140 #define WHEELINC_KEY "WheelMouseInc"
141 #define PATCHBBOXSEL_KEY "PatchBBoxSel"
142 #define LASTLIGHTINTENSITY_KEY "LastLightIntensity"
143 #define CUSTOMSHADEREDITOR_KEY "UseCustomShaderEditor"
144 #define CUSTOMSHADEREDITORCOMMAND_KEY "CustomShaderEditorCommand"
145 #define TEXTURECOMPRESSIONFORMAT_KEY "TextureCompressionFormat"
146 #define LIGHTRADIUS_KEY "LightRadiuses"
147 #define Q3MAP2TEX_KEY "Q3Map2Tex"
148 #define ATIHACK_KEY "ATIHack"
151 #define ENTITYSPLIT1_KEY "EntitySplit1"
152 #define ENTITYSPLIT2_KEY "EntitySplit2"
153 #define POSITIONX_KEY "PositionX"
154 #define POSITIONY_KEY "PositionY"
155 #define ENTITYWND_KEY "EntityWnd"
156 #define MAPINFOWND_KEY "MapInfoDlg"
157 #define CAMWND_KEY "CamWnd"
158 #define ZWND_KEY "ZWnd"
159 #define XYWND_KEY "XYWnd"
160 #define XZWND_KEY "XZWnd"
161 #define YZWND_KEY "YZWnd"
162 #define PATCHWND_KEY "PatchWnd"
163 #define SURFACEWND_KEY "SurfaceWnd"
164 #define ENTITYINFOWND_KEY "EntityInfoDlg"
165 #define WIDTH_KEY "Width"
166 #define HEIGHT_KEY "Height"
167 #define ZWIDTH_KEY "ZWidth"
168 #define XYHEIGHT_KEY "XYHeight"
169 #define XYWIDTH_KEY "XYWidth"
170 #define CAMWIDTH_KEY "CamWidth"
171 #define CAMHEIGHT_KEY "CamHeight"
172 #define ZFLOATWIDTH_KEY "ZWidthFloating"
173 #define STATE_KEY "State"
176 #define COUNT_KEY "Count"
177 #define FILE_KEY "File"
180 #define SI_TEXMENU_KEY "SI_TexMenu"
181 #define SI_GAMMA_KEY "SI_Gamma"
182 #define SI_COLORS_KEY "SI_Colors"
183 #define SI_EXCLUDE_KEY "SI_Exclude"
184 #define SI_INCLUDE_KEY "SI_Include"
185 #define SI_SURFACE_TEXDEF_KEY "SI_SurfaceTexdef"
186 #define SI_PATCH_TEXDEF_KEY "SI_PatchTexdef"
187 #define SI_AXISCOLORS_KEY "SI_AxisColors"
188 #define SI_SHOWNAMES_KEY "SI_ShowNames"
189 #define SI_SHOWCOORDS_KEY "SI_ShowCoords"
190 #define SI_SHOWANGLES_KEY "SI_ShowAngles"
191 #define SI_SHOWOUTLINES_KEY "SI_ShowOutlines"
192 #define SI_SHOWAXIS_KEY "SI_ShowAxis"
193 #define SI_NOSELOUTLINES_KEY "SI_NoSelectedOutlines"
194 #define SI_OUTLINESTYLE_KEY "SI_OutLineStyle"
197 #define TD_SCALE1_KEY "_Scale1"
198 #define TD_SCALE2_KEY "_Scale2"
199 #define TD_SHIFT1_KEY "_Shift1"
200 #define TD_SHIFT2_KEY "_Shift2"
201 #define TD_ROTATE_KEY "_Rotate"
206 #define WATCHBSP_DEF 1
208 #define LOADLAST_DEF 1
210 #define SUBDIVISIONS_DEF 4
212 void WindowPosition_Parse(window_position_t& m_value, const CString& value)
214 if(sscanf(value.GetBuffer(), "%d %d %d %d", &m_value.x, &m_value.y, &m_value.w, &m_value.h) != 4)
215 m_value.x = m_value.y = m_value.w = m_value.h = -1;
218 void WindowPosition_Write(const window_position_t& m_value, CString& value)
221 sprintf(buffer, "%d %d %d %d", m_value.x, m_value.y, m_value.w, m_value.h);
226 CXMLPropertyBag::CXMLPropertyBag() {
232 // generic preference functions
234 void CXMLPropertyBag::PushAssignment(char *name, PrefTypes_t type, void *pV)
236 list<CPrefAssignment>::iterator iAssign;
237 for(iAssign=mPrefAssignments.begin(); iAssign!=mPrefAssignments.end(); iAssign++)
239 if ((*iAssign).mName == name)
241 // we have it already, check anyway
242 if (pV != (*iAssign).mVal)
244 Sys_FPrintf(SYS_ERR, "PushAssignment, '%s' has different mVal\n", name);
249 // ok, it's not in our list yet
250 mPrefAssignments.push_front(CPrefAssignment(name, type, pV));
253 xmlNodePtr CXMLPropertyBag::EpairForName(const char *name)
255 xmlNodePtr ret = NULL;
257 xmlNodePtr pNode = mpDocNode->children;
258 while (pNode != NULL)
260 if(pNode->type == XML_ELEMENT_NODE)
262 xmlAttrPtr tmp_attr_ptr = xmlHasProp(pNode, (xmlChar *)"name");
263 if (tmp_attr_ptr != NULL && !strcmp(name, (char *)tmp_attr_ptr->children->content))
266 Sys_FPrintf( SYS_WRN, "WARNING: dupe property in CXMLPropertyBag::EpairForName '%s'\n", name );
277 void CXMLPropertyBag::GetPref(char *name, Str *pV, char *V)
279 xmlNodePtr pNode = EpairForName( name );
282 if ( pNode->children && pNode->children->content ) {
283 *pV = pNode->children->content;
285 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=427
286 // means the pref exists, and that the value is ""
292 pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)V);
293 xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
295 // push the pref assignment if needed
296 PushAssignment(name, PREF_STR, pV);
299 void CXMLPropertyBag::GetPref(char *name, int *pV, int V)
302 if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
304 *pV = atoi((char *)pNode->children->content);
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(char *name, bool *pV, bool V)
321 if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
323 if (!strcmp((char *)pNode->children->content, "true"))
335 V ? strcpy(s, "true") : strcpy(s, "false");
336 pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);
337 xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
340 // push the pref assignment
341 PushAssignment(name, PREF_BOOL, pV);
344 void CXMLPropertyBag::GetPref(char *name, float *pV, float V)
347 if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
349 *pV = atof((char *)pNode->children->content);
355 pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);
356 xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
359 // push the pref assignment if needed
360 PushAssignment(name, PREF_FLOAT, pV);
363 void CXMLPropertyBag::GetPref(char *name, float* pV, float* V)
366 if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
368 sscanf((char *)pNode->children->content, "%f %f %f", &pV[0], &pV[1], &pV[2]);
373 sprintf(s, "%f %f %f", V[0], V[1], V[2]);
374 pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);
375 xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
380 // push the pref assignment if needed
381 PushAssignment(name, PREF_VEC3, pV);
384 void CXMLPropertyBag::GetPref(char *name, window_position_t* pV, window_position_t V)
387 if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)
389 WindowPosition_Parse(*pV, CString((xmlChar *)pNode->children->content));
394 WindowPosition_Write(V, str);
395 pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)str.GetBuffer());
396 xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);
399 // push the pref assignment if needed
400 PushAssignment(name, PREF_WNDPOS, pV);
403 void CXMLPropertyBag::UpdatePrefTree()
405 // read the assignments and update the tree
406 list<CPrefAssignment>::iterator iPref;
407 for(iPref = mPrefAssignments.begin(); iPref != mPrefAssignments.end(); iPref++)
409 CPrefAssignment *pPref = &(*iPref);
414 pNode = EpairForName(pPref->mName.GetBuffer());
415 // we never expect that the node could not be found, because this is supposed to happen
416 // after the tree was built with GetPref calls, never on a blank tree
419 Sys_FPrintf(SYS_ERR, "Unexpected EpairForName '%s' not found in UpdatePrefTree\n", pPref->mName.GetBuffer());
422 switch ((*iPref).mType)
425 xmlNodeSetContent(pNode, (const xmlChar *)((Str *)pPref->mVal)->GetBuffer());
428 sprintf(s, "%d", *(int *)pPref->mVal);
429 xmlNodeSetContent(pNode, (xmlChar *)s);
432 sprintf(s, "%f", *(float *)pPref->mVal);
433 xmlNodeSetContent(pNode, (xmlChar *)s);
436 *(bool *)pPref->mVal ? strcpy(s, "true") : strcpy(s, "false");
437 xmlNodeSetContent(pNode, (xmlChar *)s);
441 float* v = (float*)pPref->mVal;
442 sprintf(s, "%f %f %f", v[0], v[1], v[2]);
443 xmlNodeSetContent(pNode, (xmlChar *)s);
449 WindowPosition_Write(*(window_position_t*)pPref->mVal, str);
450 xmlNodeSetContent(pNode, (xmlChar*)str.GetBuffer());
457 void CXMLPropertyBag::Clear()
468 void CXMLPropertyBag::ReadXMLFile(const char* pFilename)
470 mpDoc = xmlParseFile(pFilename);
475 mpDocNode = mpDoc->children;
476 xmlAttrPtr tmp_attr_ptr = xmlHasProp(mpDocNode, (xmlChar *)"version");
477 if (strcmp((char *)mpDocNode->name, "qpref"))
479 Sys_FPrintf(SYS_ERR, "Unrecognized node '%s' in '%s'\n", mpDocNode->name, mpDoc->URL);
483 else if (tmp_attr_ptr != NULL && strcmp((char*)tmp_attr_ptr->children->content, "1"))
485 Sys_FPrintf(SYS_ERR, "Wrong version '%s' in <qpref> node for '%s'\n", (char*)tmp_attr_ptr->children->content, mpDoc->URL);
489 Sys_Printf("Opened XML property file: '%s'\n", pFilename);
495 // no document, create one
496 mpDoc = xmlNewDoc((xmlChar *)"1.0");
497 mpDocNode = xmlNewDocNode(mpDoc, NULL, (xmlChar *)"qpref", NULL);
498 xmlDocSetRootElement(mpDoc, mpDocNode);
499 xmlSetProp(mpDocNode, (xmlChar *)"version", (xmlChar *)"1");
500 Sys_Printf("XML property file '%s' invalid/not found, creating blank properties tree\n", pFilename);
504 qboolean CXMLPropertyBag::WriteXMLFile(const char* pFilename)
506 int res = xmlSaveFormatFile(pFilename, mpDoc, 1);
511 Sys_Printf("Wrote XML property file '%s'\n", pFilename);
515 // =============================================================================
516 // Widget callbacks for PrefsDlg
519 // browse for custom editor executable
520 static void OnBtnBrowseEditor (GtkWidget *widget, gpointer data)
522 PrefsDlg *dlg = (PrefsDlg*)data;
524 const char *filename = file_dialog(g_PrefsDlg.GetWidget(), TRUE, "Executable for Custom Editor");
528 dlg->m_strEditorCommand = filename;
529 dlg->UpdateData(FALSE);
534 static void OnBtnBrowseprefab (GtkWidget *widget, gpointer data)
536 PrefsDlg *dlg = (PrefsDlg*)data;
537 char *path = dlg->m_strPrefabPath;
538 if (strlen (path) == 0)
539 path = g_strGameToolsPath;
540 char *dir = dir_dialog (g_PrefsDlg.GetWidget (), "Set prefab path", path);
541 dlg->UpdateData(TRUE);
548 dlg->m_strPrefabPath = strPath;
549 dlg->UpdateData(FALSE);
554 static void OnBtnBrowseuserini (GtkWidget *widget, gpointer data)
556 PrefsDlg *dlg = (PrefsDlg*)data;
557 char *path = dlg->m_strUserPath;
558 if (strlen (path) == 0)
559 path = g_strGameToolsPath;
561 const char *filename = file_dialog (g_PrefsDlg.GetWidget(), TRUE, "Find INI file", path);
563 if (filename != NULL)
565 dlg->UpdateData(TRUE);
566 dlg->m_strUserPath = filename;
567 dlg->UpdateData(FALSE);
571 static void OnButtonClean (GtkWidget *widget, gpointer data)
573 // make sure this is what the user wants
574 if (gtk_MessageBox (g_PrefsDlg.GetWidget (), "This will close Radiant and clean the corresponding registry entries.\n"
575 "Next time you start Radiant it will be good as new. Do you wish to continue?",
576 "Reset Registry", MB_YESNO) == IDYES)
578 PrefsDlg *dlg = (PrefsDlg*)data;
579 dlg->EndModal (IDCANCEL);
581 g_qeglobals.disable_ini = true;
582 remove (dlg->m_inipath->str);
584 sprintf(buf, "%sSavedInfo.bin", dlg->m_rc_path->str);
586 HandleCommand (NULL, GINT_TO_POINTER (ID_FILE_EXIT));
591 // =============================================================================
594 // IMPORTANT NOTE: the values here don't matter very much
595 // the actual intialization if you start with an empty .ini is done when loading the prefs for the first time
596 // profile_load_int takes an argument to use if the value is not found
597 PrefsDlg::PrefsDlg ()
601 m_nView = MainFrame::eRegular;
603 m_bInternalBSP = FALSE;
604 m_bRightClick = FALSE;
608 m_bLoadLastMap = FALSE;
609 m_bTextureWindow = FALSE;
610 m_bSnapShots = FALSE;
612 m_bCleanTiny = FALSE;
613 m_bCamXYUpdate = TRUE;
614 m_bCamDragMultiSelect = FALSE;
615 m_bCamFreeLook = TRUE;
616 m_bCamFreeLookStrafe = FALSE;
617 m_bCamInverseMouse = FALSE;
618 m_bCamDiscrete = TRUE;
619 m_bNewLightDraw = FALSE;
620 m_strPrefabPath = "";
623 m_bFaceColors = FALSE;
627 m_bSizePaint = FALSE;
628 m_bDLLEntities = FALSE;
630 m_bDetachableMenus = FALSE; // Most win32 users will find detachable menus annoying
632 m_bDetachableMenus = TRUE; // Linux/Apple users are used to them...
634 m_bPatchToolbar = TRUE;
635 m_bWideToolbar = TRUE;
636 m_bPluginToolbar = TRUE;
640 m_bChaseMouse = FALSE;
641 m_bTextureScrollbar = TRUE;
642 m_bDisplayLists = TRUE;
643 m_bAntialiasedPointsAndLines = FALSE; // Fishman - Add antialiazed points and lines support. 09/03/00
644 m_bShowShaders = FALSE;
646 m_bNoStipple = FALSE;
647 m_bVertexSplit = FALSE;
648 m_bSelectCurves = TRUE;
649 m_bSelectModels = TRUE;
650 m_nEntityShowState = ENTITY_SKINNED_BOXED;
652 m_bSwitchClip = FALSE;
653 m_bSelectWholeEntities = TRUE;
654 m_nTextureQuality = 3;
655 m_bShowShaders = TRUE;
656 m_bGLLighting = FALSE;
659 m_bTexturesShaderlistOnly = FALSE;
660 // paths to ini files
670 m_bFloatingZ = FALSE;
671 m_bGlPtWorkaround = FALSE; // Gef: Kyro/GL_POINTS workaround 25-aug-2001
673 m_bNativeGUI = FALSE;
674 m_bStartOnPrimMon = FALSE;
676 m_global_rc_path = NULL;
678 m_bUseWin32Editor = TRUE;
680 // custom shader editor options
681 m_bUseCustomEditor = FALSE;
682 m_strEditorCommand = "";
684 m_nLightRadiuses = 1;
685 m_bQ3Map2Texturing = TRUE;
687 m_bGlATIHack = FALSE;
692 =========================================================
693 Games selection dialog
694 =========================================================
697 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;
707 ///< \todo add the file name (this node and gametools should all be part of CGameDescription anyway)
708 Error("Didn't find 'game' node in the game description file '%s'\n", pDoc->URL);
710 // on win32, game tools path can now be specified relative to the exe's cwd
711 prop = (char*)xmlGetProp( pNode, (xmlChar*)"gametools" );
712 if ( prop == NULL ) {
713 Error( "Didn't find 'gametools' node in the game description file '%s'\n", pDoc->URL );
718 _fullpath( full, prop, PATH_MAX );
720 strncpy( full, prop, PATH_MAX );
724 for ( p = full; *p != '\0'; p++ ) {
728 mGameToolsPath = full;
729 if ( p != full && *(p-1) != '/' ) {
730 mGameToolsPath += "/";
735 prop = (char*)xmlGetProp(pNode, (xmlChar*)"name");
738 Sys_FPrintf(SYS_WRN, "Warning, 'name' attribute not found in '%s'\n", pDoc->URL);
739 mGameName = pDoc->URL;
747 mGameFile = GameFile;
749 prop = (char*)xmlGetProp(pNode, (xmlChar*)"quake2");
761 prop = (char*)xmlGetProp(pNode, (xmlChar*)"basegame");
765 mBaseGame = "baseq3";
773 // on win32, engine path can now be specified relative to the exe's cwd
774 prop = (char*)xmlGetProp(pNode, (const xmlChar *)"enginepath");
775 if ( prop != NULL ) {
778 _fullpath( full, prop, PATH_MAX );
780 strncpy( full, prop, PATH_MAX );
784 // process seperators
785 for ( p = full; *p != '\0'; p++ ) {
791 if ( p != full && *(p-1) != '/' ) {
797 // if engine path was not specified in the .game, it implies we can guess it from the gametools path
798 // on win32, and for most game package, the gametools are installed with the game
799 char aux_path[PATH_MAX]; // aux
800 strcpy( aux_path, mGameToolsPath.GetBuffer() );
801 if ( ( aux_path[ strlen(aux_path)-1 ] == '/' ) || ( aux_path[ strlen(aux_path)-1 ] == '\\' ) ) {
802 aux_path[strlen(aux_path)-1] = '\0'; // strip ending '/' if any
804 char up_path[PATH_MAX]; // up one level
805 ExtractFilePath( aux_path, up_path );
806 mEnginePath = up_path;
809 prop = (char*)xmlGetProp(pNode, (xmlChar*)"engine");
813 mEngine = "quake3.exe";
817 mEngine = "Quake3.app";
826 #if defined (__linux__) || defined (__APPLE__)
828 prop = (char*)xmlGetProp(pNode, (const xmlChar *)"prefix");
831 mUserPathPrefix = prop;
835 mShaderPath = xmlGetProp(pNode, (const xmlChar *)"shaderpath");
836 if (!mShaderPath.GetLength())
838 mShaderPath = "scripts/";
839 mShaderlist = "scripts/shaderlist.txt";
843 AddSlash(mShaderPath);
844 mShaderlist = mShaderPath;
845 mShaderlist += "shaderlist.txt";
847 xmlChar* default_scale = xmlGetProp(pNode, (const xmlChar *)"default_scale");
850 mTextureDefaultScale = atof((const char *)default_scale);
851 xmlFree(default_scale);
854 mTextureDefaultScale = 0.5f;
855 xmlChar* eclass_singleload = xmlGetProp(pNode, (const xmlChar*)"eclass_singleload");
856 if (eclass_singleload)
858 mEClassSingleLoad = true;
859 xmlFree(eclass_singleload);
862 mEClassSingleLoad = false;
863 xmlChar* no_patch = xmlGetProp(pNode, (const xmlChar *)"no_patch");
871 xmlChar* caulk_shader = xmlGetProp(pNode, (const xmlChar *)"caulk_shader");
874 mCaulkShader = caulk_shader;
875 xmlFree(caulk_shader);
878 mCaulkShader = "textures/common/caulk";
881 void CGameDescription::Dump()
884 if (CGameDialog::GetNetrun())
885 Sys_Printf("Running in network mode, prefs path set to '%s'\n", g_strTempPath.GetBuffer());
887 Sys_Printf("game name : '%s'\n", mGameName.GetBuffer());
888 Sys_Printf("game file : '%s'\n", mGameFile.GetBuffer());
889 Sys_Printf("game path : '%s'\n", mGameToolsPath.GetBuffer());
890 Sys_Printf("base game : '%s'\n", mBaseGame.GetBuffer());
891 Sys_Printf("engine path : '%s'\n", mEnginePath.GetBuffer());
892 Sys_Printf("engine : '%s'\n", mEngine.GetBuffer());
893 Sys_Printf("shaderlist : '%s'\n", mShaderlist.GetBuffer());
894 Sys_Printf("caulk shader: '%s'\n", mCaulkShader.GetBuffer());
895 #if defined (__linux__) || defined (__APPLE__)
896 Sys_Printf("prefix : '%s'\n", mUserPathPrefix.GetBuffer());
898 Sys_Printf("default texture scale: %g\n", mTextureDefaultScale);
899 Sys_Printf("single eclass load : %s\n", mEClassSingleLoad ? "Yes" : "No");
900 Sys_Printf("patches supported : %s\n", mNoPatch ? "No" : "Yes");
903 CPrefAssignment& CPrefAssignment::operator = (const CPrefAssignment& ass)
914 CPrefAssignment::CPrefAssignment(const CPrefAssignment& ass)
919 void CGameDialog::LoadPrefs()
923 // if we already have a document loaded, we will free and reload from file
924 if (mGlobalPrefs.InUse())
926 Sys_Printf("Reloading global prefs from file\n");
927 mGlobalPrefs.Clear();
930 // load global .pref file
931 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
932 strGlobalPref += "global.pref";
934 mGlobalPrefs.ReadXMLFile(strGlobalPref.GetBuffer());
936 mGlobalPrefs.GetPref("gamefile", &m_sGameFile, ""); // NOTE: there's no default, user HAS to select something
937 mGlobalPrefs.GetPref("autoload", &m_bAutoLoadGame, false);
938 mGlobalPrefs.GetPref("log console", &m_bLogConsole, false);
939 // in a very particular post-.pid startup
940 // we may have the console turned on and want to keep it that way
941 // so we use a latching system
942 if (m_bForceLogConsole)
944 m_bLogConsole = true;
945 Sys_Printf("console logging has been latched on, saving prefs\n");
947 m_bForceLogConsole = false;
950 // console logging: call Sys_LogConsole to check console logging status
951 // it is important that we would log console as early as possible to make it useful
954 if (mGlobalPrefs.mbEmpty)
956 Sys_Printf("Saving global.pref with default pref values\n");
961 void CGameDialog::SavePrefs()
963 // update the tree and save it
964 mGlobalPrefs.UpdatePrefTree();
966 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
967 strGlobalPref += "global.pref";
969 if ( !mGlobalPrefs.WriteXMLFile( strGlobalPref.GetBuffer() ) ) {
970 Sys_FPrintf(SYS_ERR, "Error occured while saving global prefs file '%s'\n", strGlobalPref.GetBuffer());
974 void CGameDialog::DoGameInstall() {
975 // make sure console logging is on whenever we enter the installation loop
976 g_PrefsDlg.mGamesDialog.m_bLogConsole = true;
981 void CGameDialog::DoGameDialog() {
982 // allow looping the game selection dialog with calls to the game configure dialog in between
983 while ( m_bDoGameInstall ) {
985 m_bDoGameInstall = false;
987 if ( DoModal() == IDCANCEL ) {
988 Error( "game selection dialog canceled, cannot continue" );
992 if ( m_bDoGameInstall ) {
995 // and we will loop to do another DoModal dialog
999 // unhook so we can use in other places
1000 // we manually incref'ed it when creating, it won't be freed (destructor)
1001 gtk_container_remove( GTK_CONTAINER( mTopBox ), GetGlobalFrame() );
1003 // we save the prefs file
1007 GtkWidget* CGameDialog::GetGlobalFrame()
1009 GtkWidget *vbox, *text, *combo, *check;
1011 if ( mFrame != NULL ) {
1015 mFrame = gtk_frame_new( NULL );
1016 gtk_container_set_border_width( GTK_CONTAINER( mFrame ), 5 );
1017 gtk_widget_show( mFrame );
1019 vbox = gtk_vbox_new( FALSE, 6 );
1020 gtk_widget_show( vbox );
1021 gtk_container_add( GTK_CONTAINER( mFrame ), vbox );
1022 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1024 text = gtk_label_new( "Select the game:" );
1025 gtk_widget_show( text );
1026 gtk_box_pack_start( GTK_BOX( vbox ), text, FALSE, FALSE, 0 );
1028 combo = gtk_combo_box_new_text();
1029 gtk_widget_show( combo );
1030 gtk_box_pack_start( GTK_BOX( vbox ), combo, FALSE, FALSE, 0 );
1031 AddDialogData( combo, &m_nComboSelect, DLG_COMBO_BOX_INT );
1032 mGameCombo = GTK_COMBO_BOX( combo );
1036 check = gtk_check_button_new_with_label( "Auto load selected game on startup" );
1037 gtk_widget_show(check);
1038 gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);
1039 AddDialogData (check, &m_bAutoLoadGame, DLG_CHECK_BOOL);
1041 text = gtk_label_new("(this frame is available in the prefs menu if you set auto-select)");
1042 gtk_widget_show(text);
1043 gtk_box_pack_start (GTK_BOX(vbox), text, FALSE, FALSE, 0);
1046 check = gtk_check_button_new_with_label( "Networked install - per-user settings" );
1047 gtk_widget_show( check );
1048 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1049 AddDialogData( check, &m_bNetRun, DLG_CHECK_BOOL );
1052 check = gtk_check_button_new_with_label( "Log the console to radiant.log" );
1053 gtk_widget_show( check );
1054 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1055 AddDialogData( check, &m_bLogConsole, DLG_CHECK_BOOL );
1057 // incref it so we can pass it around
1058 gtk_widget_ref( GTK_WIDGET( mFrame ) );
1063 void CGameDialog::UpdateData( bool retrieve ) {
1066 // use m_sGameFile to set m_nComboSelect
1067 list<CGameDescription *>::iterator iGame;
1069 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1071 if ((*iGame)->mGameFile == m_sGameFile)
1079 UpdateNetrun(false);
1082 Dialog::UpdateData(retrieve);
1085 // use m_nComboSelect to set m_sGameFile
1086 list<CGameDescription *>::iterator iGame = mGames.begin();
1088 for(i=0; i<m_nComboSelect; i++)
1092 m_sGameFile = (*iGame)->mGameFile;
1099 void CGameDialog::SInstallCallback( GtkWidget *widget, gpointer data ) {
1100 CGameDialog *d = static_cast< CGameDialog* >( data );
1101 d->m_bDoGameInstall = true;
1105 void CGameDialog::BuildDialog() {
1106 GtkWidget *dlg, *vbox1, *button, *setup_button;
1109 gtk_window_set_title( GTK_WINDOW( dlg ), "Select Game" );
1111 vbox1 = gtk_vbox_new( FALSE, 0 );
1112 gtk_widget_show( vbox1 );
1113 gtk_container_add( GTK_CONTAINER( dlg ), vbox1 );
1115 gtk_container_add( GTK_CONTAINER( vbox1 ), GetGlobalFrame() );
1118 setup_button = gtk_button_new_with_label( "Configure more games" );
1119 gtk_widget_show( setup_button );
1120 gtk_box_pack_start( GTK_BOX( vbox1 ), setup_button, FALSE, FALSE, 0 );
1121 gtk_signal_connect( GTK_OBJECT( setup_button ), "clicked",
1122 GTK_SIGNAL_FUNC( SInstallCallback ), this );
1124 button = gtk_button_new_with_label( "OK" );
1125 gtk_widget_show( button );
1126 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
1127 AddModalButton( button, IDOK );
1129 button = gtk_button_new_with_label( "Cancel" );
1130 gtk_widget_show( button );
1131 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
1132 AddModalButton( button, IDCANCEL );
1134 gtk_widget_set_usize( button, 60, -2 );
1137 void CGameDialog::UpdateGameCombo() {
1138 // fill in with the game descriptions
1139 list<CGameDescription *>::iterator iGame;
1141 if ( mGameCombo == NULL ) {
1142 Sys_Printf( "mGameCombo == NULL\n" );
1146 // clear whatever is in - wtf no way to know how many text entries?
1147 // use set/get active to track
1148 gtk_combo_box_set_active( mGameCombo, 0 );
1149 while ( gtk_combo_box_get_active( mGameCombo ) == 0 ) {
1150 gtk_combo_box_remove_text( mGameCombo, 0 );
1151 gtk_combo_box_set_active( mGameCombo, 0 );
1154 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ ) {
1155 gtk_combo_box_append_text( mGameCombo, (*iGame)->mGameName.GetBuffer() );
1157 gtk_combo_box_set_active( mGameCombo, 0 );
1160 void CGameDialog::ScanForGames()
1165 CString strGamesPath = g_strAppPath.GetBuffer();
1166 strGamesPath += "games";
1167 const char *path = strGamesPath.GetBuffer();
1169 if ( !mGames.empty() ) {
1170 Sys_Printf( "Clearing game list\n" );
1171 list<CGameDescription*>::iterator iGame;
1172 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ ) {
1178 Sys_Printf( "Scanning for game description files: %s\n", path );
1182 do we put game description files below g_strAppPath, or in ~/.radiant
1183 i.e. read only or read/write?
1184 my guess .. readonly cause it's an install
1185 we will probably want to add ~/.radiant/<version>/games/ scanning on top of that for developers
1186 (if that's really needed)
1189 // FIXME need to catch the 'no game description' situation and exit with a clean error
1191 dir = g_dir_open(path, 0, NULL);
1197 const gchar* name = g_dir_read_name(dir);
1201 dirlist = g_strdup(name);
1205 char *ext = strrchr (dirlist, '.');
1206 if ((ext == NULL) || (strcmp (ext, ".game") != 0))
1208 strPath.Format("%s/%s", path, dirlist);
1209 Sys_Printf("%s\n", strPath.GetBuffer());
1211 xmlDocPtr pDoc = xmlParseFile(strPath.GetBuffer());
1214 mGames.push_front( new CGameDescription( pDoc, dirlist ) );
1218 Sys_FPrintf(SYS_ERR, "XML parser failed on '%s'\n", strPath.GetBuffer());
1226 // entries in the combo need to be updated
1230 CGameDescription* CGameDialog::GameDescriptionForComboItem()
1232 list<CGameDescription *>::iterator iGame;
1234 for( iGame = mGames.begin(); iGame != mGames.end(); iGame++,i++ ) {
1235 if ( i == m_nComboSelect ) {
1239 return NULL; // not found
1242 void CGameDialog::InitGlobalPrefPath()
1244 GString *global_rc_path;
1245 // configure m_global_rc_path
1246 // this is the g_strTempPath, and it has already been mkdir'ed
1247 global_rc_path = g_string_new(g_strTempPath.GetBuffer());
1248 g_PrefsDlg.m_global_rc_path = global_rc_path;
1251 void CGameDialog::Reset()
1253 if (!g_PrefsDlg.m_global_rc_path)
1254 InitGlobalPrefPath();
1255 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
1256 strGlobalPref += "global.pref";
1257 remove(strGlobalPref.GetBuffer());
1260 void CGameDialog::Init()
1262 InitGlobalPrefPath();
1264 if ( mGames.empty() ) {
1267 if ( mGames.empty() ) {
1268 Error( "No games setup, aborting\n" );
1272 if ( m_bAutoLoadGame ) {
1273 // search by .game name
1274 list<CGameDescription *>::iterator iGame;
1275 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1277 if ((*iGame)->mGameFile == m_sGameFile)
1279 m_pCurrentGameDescription = (*iGame);
1284 if ( !m_bAutoLoadGame || !m_pCurrentGameDescription ) {
1286 // use m_nComboSelect to identify the game to run as and set the globals
1287 m_pCurrentGameDescription = GameDescriptionForComboItem();
1288 if ( !m_pCurrentGameDescription ) {
1289 Error("Lookup of game description object failed, can't continue\n");
1292 g_pGameDescription = m_pCurrentGameDescription;
1294 g_strGameToolsPath = g_pGameDescription->mGameToolsPath;
1296 // NOTE TTimo: this is moved from QE_LoadProject in 1.2
1297 // (probably broken)
1298 // NOTE Hydra: was broken for win32, we don't use m_strHomeGame or m_strFSBasePath
1299 #if defined (__linux__) || defined (__APPLE__)
1300 g_qeglobals.m_strHomeGame = g_get_home_dir();
1301 g_qeglobals.m_strHomeGame += "/";
1302 g_qeglobals.m_strHomeGame += m_pCurrentGameDescription->mUserPathPrefix.GetBuffer();
1303 g_qeglobals.m_strHomeGame += "/";
1305 g_qeglobals.m_strHomeGame = g_pGameDescription->mEnginePath.GetBuffer();
1308 g_pGameDescription->Dump();
1311 CGameDialog::~CGameDialog()
1315 // NOTE I'm not too sure how reliable this is
1316 gtk_widget_unref(GTK_WIDGET(mFrame));
1318 // free all the game descriptions
1319 list<CGameDescription *>::iterator iGame;
1320 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1327 void CGameDialog::AddPacksURL(Str &URL)
1329 // add the URLs for the list of game packs installed
1330 // FIXME: this is kinda hardcoded for now..
1331 list<CGameDescription *>::iterator iGame;
1332 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1334 if ((*iGame)->mGameFile == "q3.game")
1335 URL += "&Games_dlup%5B%5D=1";
1336 else if ((*iGame)->mGameFile == "wolf.game")
1337 URL += "&Games_dlup%5B%5D=2";
1338 else if ((*iGame)->mGameFile == "wolf.game")
1339 URL += "&Games_dlup%5B%5D=3";
1340 else if ((*iGame)->mGameFile == "jk2.game")
1341 URL += "&Games_dlup%5B%5D=4";
1342 else if ((*iGame)->mGameFile == "stvef.game")
1343 URL += "&Games_dlup%5B%5D=5";
1344 else if ((*iGame)->mGameFile == "sof2.game")
1345 URL += "&Games_dlup%5B%5D=6";
1346 else if ((*iGame)->mGameFile == "ja.game")
1347 URL += "&Games_dlup%5B%5D=7";
1353 #define NETRUN_FILENAME "netrun.conf"
1355 bool CGameDialog::m_bNetRun;
1357 void CGameDialog::UpdateNetrun(bool retrieve)
1361 strNetrun = g_strAppPath; strNetrun += NETRUN_FILENAME;
1364 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=639
1365 // now check if we are running from a network installation
1366 // use a dummy file as the flag
1367 f_netrun = fopen(strNetrun.GetBuffer(), "r");
1380 f_netrun = fopen(strNetrun.GetBuffer(), "w");
1383 Sys_FPrintf(SYS_ERR, "ERROR: Failed to create netrun file '%s'\n", strNetrun.GetBuffer());
1389 Sys_Printf("Created/Checked '%s'\n", strNetrun.GetBuffer());
1394 if (remove(strNetrun.GetBuffer()) == -1)
1396 if (errno != ENOENT)
1397 Sys_FPrintf(SYS_ERR, "Failed to remove netrun file '%s'\n", strNetrun.GetBuffer());
1402 Sys_Printf("Netrun mode is disabled\n");
1408 bool CGameDialog::GetNetrun()
1417 very first prefs init deals with selecting the game and the game tools path
1418 then we can load .ini stuff
1420 using prefs / ini settings:
1424 look in g_strGameToolsPath for .ini
1427 look in ~/.radiant/<version>/gamename
1431 #define PREFS_LOCAL_FILENAME "local.pref"
1433 void PrefsDlg::Init()
1435 mGamesDialog.Init();
1437 // m_global_rc_path has been set above, do m_rc_path with game specific stuff now
1438 // the win32 and linux versions have been unified for network mode
1440 if (!CGameDialog::GetNetrun())
1442 // legacy prefs settings, this goes where the game pack is installed
1443 m_rc_path = g_string_new (g_strGameToolsPath.GetBuffer() );
1444 m_inipath = g_string_new (m_rc_path->str);
1445 g_string_append (m_inipath, PREFS_LOCAL_FILENAME);
1449 // this is common to win32 and Linux init now
1450 m_rc_path = g_string_new (m_global_rc_path->str);
1453 g_string_append (m_rc_path, g_pGameDescription->mGameFile.GetBuffer());
1454 g_string_append (m_rc_path, "/");
1455 Q_mkdir (m_rc_path->str, 0775);
1457 // then the ini file
1458 m_inipath = g_string_new (m_rc_path->str);
1459 g_string_append (m_inipath, PREFS_LOCAL_FILENAME);
1463 void PrefsDlg::UpdateData (bool retrieve)
1465 // leo: the "changed" signal confuses the update function
1466 if (m_pWidget == NULL)
1468 mGamesDialog.UpdateData (retrieve);
1469 Dialog::UpdateData (retrieve);
1473 #define PREFSHSPACE 5
1475 #define PREFSHSPACE 0
1478 static void UpdateSensitivity( GtkWidget *widget, gpointer data )
1480 PrefsDlg *dlg = (PrefsDlg*)data;
1481 dlg->DoSensitivity();
1484 static void UpdateEditorSensitivity(GtkWidget *widget, gpointer data)
1486 PrefsDlg *dlg = (PrefsDlg*)data;
1487 dlg->DoEditorSensitivity();
1490 // start new prefs dialog
1492 /*! Utility function for swapping notebook pages for tree list selections */
1493 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);
1501 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))
1510 gtk_tree_model_get(model, &selected, 1, (gpointer*)&prefpage, -1);
1511 dlg->showPrefPage(prefpage);
1515 void PrefsDlg::BuildDialog ()
1517 // Main Preferences dialog
1518 GtkWidget *dialog, *mainvbox, *hbox, *sc_win, *preflabel;
1520 // Widgets on notebook pages
1521 GtkWidget *check, *label, *scale, *hbox2, *combo,
1522 *table, *spin, *entry, *pixmap,
1523 *radio, *button, *pageframe, *vbox;
1525 GList *combo_list = (GList*)NULL;
1530 gtk_window_set_title(GTK_WINDOW(dialog), "GtkRadiant Preferences");
1531 gtk_widget_realize(dialog);
1533 mainvbox = gtk_vbox_new(FALSE, 5);
1534 gtk_container_add(GTK_CONTAINER(dialog), mainvbox);
1535 gtk_container_set_border_width(GTK_CONTAINER(mainvbox), 5);
1536 gtk_widget_show(mainvbox);
1538 hbox = gtk_hbox_new(FALSE, 5);
1539 gtk_widget_show(hbox);
1540 gtk_box_pack_end(GTK_BOX(mainvbox), hbox, FALSE, TRUE, 0);
1542 button = gtk_button_new_with_label("OK");
1543 gtk_widget_show(button);
1544 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1545 gtk_widget_set_usize(button, 60, -2);
1546 AddModalButton(button, IDOK);
1548 button = gtk_button_new_with_label("Cancel");
1549 gtk_widget_show(button);
1550 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1551 gtk_widget_set_usize(button, 60, -2);
1552 AddModalButton(button, IDCANCEL);
1554 button = gtk_button_new_with_label ("Clean");
1555 gtk_widget_show(button);
1556 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(OnButtonClean), this);
1557 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1558 gtk_widget_set_usize (button, 60, -2);
1560 hbox = gtk_hbox_new(FALSE, 5);
1561 gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 0);
1562 gtk_widget_show(hbox);
1564 sc_win = gtk_scrolled_window_new(NULL, NULL);
1565 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1566 gtk_box_pack_start(GTK_BOX(hbox), sc_win, FALSE, FALSE, 0);
1567 gtk_widget_show(sc_win);
1569 // prefs pages notebook
1570 notebook = gtk_notebook_new();
1571 // hide the notebook tabs since its not supposed to look like a notebook
1572 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
1573 gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 0);
1574 gtk_widget_show(notebook);
1576 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_win), GTK_SHADOW_IN);
1579 GtkTreeStore* store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
1581 GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1582 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1585 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1586 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Preferences", renderer, "text", 0, NULL);
1587 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1591 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1592 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(treeSelection), this);
1595 gtk_widget_show(view);
1597 gtk_container_add(GTK_CONTAINER (sc_win), view);
1600 /********************************************************************/
1601 /* Add preference tree options */
1602 /********************************************************************/
1605 gtk_tree_store_append(store, &group, NULL);
1606 gtk_tree_store_set(store, &group, 0, "Globals", 1, PTAB_FRONT, -1);
1609 gtk_tree_store_append(store, &tab, &group);
1610 gtk_tree_store_set(store, &tab, 0, "Game settings", 1, (gpointer)PTAB_GAME_SETTINGS, -1);
1616 gtk_tree_store_append(store, &group, NULL);
1617 gtk_tree_store_set(store, &group, 0, "Display", 1, PTAB_FRONT, -1);
1620 gtk_tree_store_append(store, &tab, &group);
1621 gtk_tree_store_set(store, &tab, 0, "2D Display/Rendering", 1, (gpointer)PTAB_2D, -1);
1625 gtk_tree_store_append(store, &tab, &group);
1626 gtk_tree_store_set(store, &tab, 0, "3D View", 1, (gpointer)PTAB_CAMERA, -1);
1630 gtk_tree_store_append(store, &tab, &group);
1631 gtk_tree_store_set(store, &tab, 0, "Texture Settings", 1, (gpointer)PTAB_TEXTURE, -1);
1637 gtk_tree_store_append(store, &group, NULL);
1638 gtk_tree_store_set(store, &group, 0, "Interface", 1, PTAB_FRONT, -1);
1641 gtk_tree_store_append(store, &tab, &group);
1642 gtk_tree_store_set(store, &tab, 0, "Layout", 1, (gpointer)PTAB_LAYOUT, -1);
1646 gtk_tree_store_append(store, &tab, &group);
1647 gtk_tree_store_set(store, &tab, 0, "Mouse", 1, (gpointer)PTAB_MOUSE, -1);
1651 gtk_tree_store_append(store, &tab, &group);
1652 gtk_tree_store_set(store, &tab, 0, "Editing", 1, (gpointer)PTAB_EDITING, -1);
1658 gtk_tree_store_append(store, &group, NULL);
1659 gtk_tree_store_set(store, &group, 0, "Other", 1, PTAB_FRONT, -1);
1662 gtk_tree_store_append(store, &tab, &group);
1663 gtk_tree_store_set(store, &tab, 0, "Startup/Auto save", 1, (gpointer)PTAB_STARTUP, -1);
1667 gtk_tree_store_append(store, &tab, &group);
1668 gtk_tree_store_set(store, &tab, 0, "Paths", 1, (gpointer)PTAB_PATHS, -1);
1672 gtk_tree_store_append(store, &tab, &group);
1673 gtk_tree_store_set(store, &tab, 0, "Misc", 1, (gpointer)PTAB_MISC, -1);
1675 if (!g_qeglobals.bBSPFrontendPlugin)
1678 gtk_tree_store_append(store, &tab, &group);
1679 gtk_tree_store_set(store, &tab, 0, "BSP Monitoring", 1, (gpointer)PTAB_BSPMONITOR, -1);
1684 gtk_tree_view_expand_all(GTK_TREE_VIEW(view));
1686 g_object_unref(G_OBJECT(store));
1689 /**********************************************************************/
1690 /* build the prefs pages */
1691 /**********************************************************************/
1694 // todo : add something interesting here
1695 // NOTE TTimo: tip of the day? or a logo?
1696 preflabel = gtk_label_new("Front Page");
1697 gtk_widget_show(preflabel);
1698 pageframe = gtk_frame_new(NULL);
1699 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1700 gtk_widget_show(pageframe);
1701 vbox = gtk_vbox_new(FALSE, 5);
1702 gtk_widget_show(vbox);
1703 gtk_widget_set_usize(GTK_WIDGET(vbox), 350, -2);
1704 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1705 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1707 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1709 /******** global preferences group ****************************/
1710 preflabel = gtk_label_new("Globals");
1711 gtk_widget_show(preflabel);
1713 pageframe = mGamesDialog.GetGlobalFrame();
1714 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1716 /******** 2D prefs group (xy views/rendering options) *********/
1717 preflabel = gtk_label_new("2D Display");
1718 gtk_widget_show(preflabel);
1719 pageframe = gtk_frame_new("2D Display");
1720 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1721 gtk_widget_show(pageframe);
1722 vbox = gtk_vbox_new(FALSE, 5);
1723 gtk_widget_show(vbox);
1724 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1725 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1727 // OpenGL Display Lists
1728 check = gtk_check_button_new_with_label("OpenGL Display Lists");
1729 gtk_widget_show(check);
1730 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1731 AddDialogData(check, &m_bDisplayLists, DLG_CHECK_BOOL);
1733 // Antialiased points & lines
1734 // Fishman - Add antialiazed points and lines support. 09/03/00
1735 check = gtk_check_button_new_with_label ("OpenGL antialiased points and lines");
1736 gtk_widget_show (check);
1737 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1738 AddDialogData (check, &m_bAntialiasedPointsAndLines, DLG_CHECK_BOOL);
1740 // Solid selection boxes
1741 check = gtk_check_button_new_with_label ("Solid selection boxes");
1742 gtk_widget_show (check);
1743 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1744 AddDialogData (check, &m_bNoStipple, DLG_CHECK_BOOL);
1746 // Display size info
1747 check = gtk_check_button_new_with_label ("Display size info");
1748 gtk_widget_show (check);
1749 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1750 AddDialogData (check, &m_bSizePaint, DLG_CHECK_BOOL);
1752 // Alternate vertex/edge handles
1753 // Gef: Kyro GL_POINT work around 25-aug-2001
1754 check = gtk_check_button_new_with_label ("Alternate vertex/edge handles");
1755 gtk_widget_show(check);
1756 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1757 AddDialogData(check, &m_bGlPtWorkaround, DLG_CHECK_BOOL);
1759 g_list_free (combo_list);
1763 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=812
1764 check = gtk_check_button_new_with_label ("ATI cards with broken drivers - bug #802");
1765 gtk_widget_show(check);
1766 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1767 AddDialogData(check, &m_bGlATIHack, DLG_CHECK_BOOL);
1770 // Add the page to the notebook
1771 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1773 /******** 3D Camera view group *********/
1774 preflabel = gtk_label_new("3D View");
1775 gtk_widget_show(preflabel);
1776 pageframe = gtk_frame_new("3D View");
1777 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1778 gtk_widget_show(pageframe);
1779 vbox = gtk_vbox_new(FALSE, 5);
1780 gtk_widget_show(vbox);
1781 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1782 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1784 // Directional velocity (Movement Velocity)
1786 hbox2 = gtk_hbox_new (FALSE, 0);
1787 gtk_widget_show (hbox2);
1788 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1791 label = gtk_label_new("Movement Velocity");
1792 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1793 gtk_widget_show(label);
1794 gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1797 adj = gtk_adjustment_new(100, 50, 300, 1, 10, 10);
1798 AddDialogData(adj, &m_nMoveSpeed, DLG_ADJ_INT);
1801 scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));
1802 gtk_widget_show(scale);
1803 gtk_box_pack_start(GTK_BOX (vbox), scale, FALSE, TRUE, 2);
1805 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
1807 // Angular velocity (Rotational Velocity)
1809 hbox2 = gtk_hbox_new (FALSE, 0);
1810 gtk_widget_show (hbox2);
1811 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1814 label = gtk_label_new ("Rotational Velocity");
1815 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1816 gtk_widget_show (label);
1817 gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1820 adj = gtk_adjustment_new (3, 1, 180, 1, 10, 10); // value, low, high, step, page_step, page_size
1821 AddDialogData (adj, &m_nAngleSpeed, DLG_ADJ_INT);
1824 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1825 gtk_widget_show (scale);
1826 gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 2);
1827 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
1829 // Text under the velocity sliders
1831 hbox2 = gtk_hbox_new (FALSE, 0);
1832 gtk_widget_show (hbox2);
1833 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1836 label = gtk_label_new ("slow");
1837 gtk_widget_show (label);
1838 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1841 label = gtk_label_new ("fast");
1842 gtk_widget_show (label);
1843 gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1845 // Allow drag to select multiple faces/brushes
1847 table = gtk_table_new(2, 1, FALSE);
1848 gtk_widget_show(table);
1849 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1850 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1851 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1853 label = gtk_label_new ("Use paint-select in camera view:");
1854 gtk_widget_show (label);
1855 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1856 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
1857 (GtkAttachOptions) (0),
1858 (GtkAttachOptions) (0), 0, 0);
1861 combo_list = g_list_append (combo_list, (void *)"No");
1862 combo_list = g_list_append (combo_list, (void *)"Yes");
1863 combo_list = g_list_append (combo_list, (void *)"Yes (Classic Key Setup)");
1865 combo = gtk_combo_new ();
1866 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
1867 gtk_widget_show (combo);
1868 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
1869 (GtkAttachOptions) (GTK_FILL),
1870 (GtkAttachOptions) (0), 0, 0);
1871 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
1872 AddDialogData (combo, &m_nCamDragMultiSelect, DLG_COMBO_INT);
1874 // Freelook in Camera view
1875 check = gtk_check_button_new_with_label ("Freelook in Camera view");
1876 gtk_widget_show (check);
1877 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1878 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1879 AddDialogData (check, &m_bCamFreeLook, DLG_CHECK_BOOL);
1881 // Freelook in Camera view w/ forward & back strafing instead of up and down looking
1882 check = gtk_check_button_new_with_label ("Freelook strafes Forward and Back");
1883 gtk_widget_show (check);
1884 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1885 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1886 AddDialogData (check, &m_bCamFreeLookStrafe, DLG_CHECK_BOOL);
1888 // Invert mouse in freelook
1889 check = gtk_check_button_new_with_label ("Invert mouse in freelook");
1890 gtk_widget_show (check);
1891 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1892 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1893 AddDialogData (check, &m_bCamInverseMouse, DLG_CHECK_BOOL);
1895 // Discrete movement
1896 check = gtk_check_button_new_with_label ("Discrete movement");
1897 gtk_widget_show (check);
1898 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1899 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1900 AddDialogData (check, &m_bCamDiscrete, DLG_CHECK_BOOL);
1902 // Update XY views on camera move
1903 check = gtk_check_button_new_with_label ("Update XY views on camera move");
1904 gtk_widget_show (check);
1905 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1906 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1907 AddDialogData (check, &m_bCamXYUpdate, DLG_CHECK_BOOL);
1909 // Add the page to the notebook
1910 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1912 /******** Texture group *********/
1913 preflabel = gtk_label_new("Textures");
1914 gtk_widget_show(preflabel);
1915 pageframe = gtk_frame_new("Textures");
1916 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1917 gtk_widget_show(pageframe);
1918 vbox = gtk_vbox_new(FALSE, 6);
1919 gtk_widget_show(vbox);
1920 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1921 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1923 // Texture quality slider
1925 label = gtk_label_new ("Texture quality");
1926 gtk_widget_show (label);
1927 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
1928 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1929 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1932 adj = gtk_adjustment_new (0, 0, 4, 1, 1, 1);
1933 AddDialogData (adj, &m_nLatchedTextureQuality, DLG_ADJ_INT);
1936 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1937 gtk_widget_show (scale);
1938 gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
1939 gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
1941 // text under the texture slider
1942 hbox2 = gtk_hbox_new (FALSE, 0);
1943 gtk_widget_show (hbox2);
1944 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1945 label = gtk_label_new ("low");
1946 gtk_widget_show (label);
1947 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1948 label = gtk_label_new ("high");
1949 gtk_widget_show (label);
1950 gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1953 check = gtk_check_button_new_with_label ("Texture subsets");
1954 gtk_widget_show (check);
1955 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1956 AddDialogData (check, &m_bTextureWindow, DLG_CHECK_BOOL);
1958 // texture scrollbar
1959 check = gtk_check_button_new_with_label ("Texture scrollbar");
1960 gtk_widget_show (check);
1961 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1962 AddDialogData (check, &m_bTextureScrollbar, DLG_CHECK_BOOL);
1964 // texture increment matches grid
1965 check = gtk_check_button_new_with_label ("Tex increment matches grid");
1966 gtk_widget_show (check);
1967 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1968 AddDialogData (check, &m_bSnapTToGrid, DLG_CHECK_BOOL);
1971 // Texture compression choice label
1973 table = gtk_table_new(2, 1, FALSE);
1974 gtk_widget_show(table);
1975 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1976 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1977 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1979 label = gtk_label_new ("Texture Compression (if available):");
1980 gtk_widget_show (label);
1981 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1982 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
1983 (GtkAttachOptions) (0),
1984 (GtkAttachOptions) (0), 0, 0);
1985 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1987 // Texture compression choice label
1989 // NONE will always be in pos 0
1990 combo_list = g_list_append (combo_list, (void *)"None");
1992 // if OpenGL compression is enabled it will always be
1994 if (g_qeglobals.m_bOpenGLCompressionSupported)
1996 combo_list = g_list_append (combo_list, (void *)"OpenGL ARB");
1999 // If S3 is enabled offer all 3 valid compression schemes in RGBA
2000 if (g_qeglobals.m_bS3CompressionSupported)
2002 combo_list = g_list_append (combo_list, (void *)"S3TC DXT1");
2003 combo_list = g_list_append (combo_list, (void *)"S3TC DXT3");
2004 combo_list = g_list_append (combo_list, (void *)"S3TC DXT5");
2007 combo = gtk_combo_new ();
2008 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2009 gtk_widget_show (combo);
2010 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
2011 (GtkAttachOptions) (GTK_FILL),
2012 (GtkAttachOptions) (0), 0, 0);
2013 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
2014 AddDialogData (combo, &m_nTextureCompressionFormat, DLG_COMBO_INT);
2015 g_list_free (combo_list);
2018 table = gtk_table_new(2, 1, FALSE);
2019 gtk_widget_show(table);
2020 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2021 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2022 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2026 label = gtk_label_new ("Startup Shaders:");
2027 gtk_widget_show (label);
2028 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
2029 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
2030 (GtkAttachOptions) (0),
2031 (GtkAttachOptions) (0), 0, 0);
2032 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2036 combo_list = g_list_append (combo_list, (void *)"None");
2037 if (g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game")
2038 combo_list = g_list_append (combo_list, (void *)"System");
2039 else if (g_pGameDescription->mGameFile == "sof2.game")
2040 combo_list = g_list_append (combo_list, (void *)"Tools");
2042 combo_list = g_list_append (combo_list, (void *)"Common");
2043 combo_list = g_list_append (combo_list, (void *)"All");
2044 combo = gtk_combo_new ();
2045 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2046 gtk_widget_show (combo);
2047 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
2048 (GtkAttachOptions) (GTK_FILL),
2049 (GtkAttachOptions) (0), 0, 0);
2050 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
2051 AddDialogData (combo, &m_nLatchedShader, DLG_COMBO_INT);
2052 g_list_free (combo_list);
2054 // Add the page to the notebook
2055 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2057 /******** Layout group *********/
2058 preflabel = gtk_label_new("Layout");
2059 gtk_widget_show(preflabel);
2060 pageframe = gtk_frame_new("Layout");
2061 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2062 gtk_widget_show(pageframe);
2063 vbox = gtk_vbox_new(FALSE, 5);
2064 gtk_widget_show(vbox);
2065 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2066 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2070 table = gtk_table_new (2, 4, FALSE);
2071 gtk_widget_show (table);
2072 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2073 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2074 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2077 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window1.bmp");
2078 gtk_widget_show (pixmap);
2079 gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 0, 1,
2080 (GtkAttachOptions) (0),
2081 (GtkAttachOptions) (0), 0, 0);
2084 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window2.bmp");
2085 gtk_widget_show (pixmap);
2086 gtk_table_attach (GTK_TABLE (table), pixmap, 1, 2, 0, 1,
2087 (GtkAttachOptions) (0),
2088 (GtkAttachOptions) (0), 0, 0);
2091 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window3.bmp");
2092 gtk_widget_show (pixmap);
2093 gtk_table_attach (GTK_TABLE (table), pixmap, 2, 3, 0, 1,
2094 (GtkAttachOptions) (0),
2095 (GtkAttachOptions) (0), 0, 0);
2098 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window4.bmp");
2099 gtk_widget_show (pixmap);
2100 gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 0, 1,
2101 (GtkAttachOptions) (0),
2102 (GtkAttachOptions) (0), 0, 0);
2104 // view type 1 selector
2105 radio = gtk_radio_button_new (NULL);
2106 gtk_widget_show (radio);
2107 gtk_table_attach (GTK_TABLE (table), radio, 0, 1, 1, 2,
2108 (GtkAttachOptions) (0),
2109 (GtkAttachOptions) (0), 0, 0);
2111 // view type 2 selector
2112 radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2113 gtk_widget_show (radio);
2114 gtk_table_attach (GTK_TABLE (table), radio, 1, 2, 1, 2,
2115 (GtkAttachOptions) (0),
2116 (GtkAttachOptions) (0), 0, 0);
2118 // view type 3 selector
2119 radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2120 gtk_widget_show (radio);
2121 gtk_table_attach (GTK_TABLE (table), radio, 2, 3, 1, 2,
2122 (GtkAttachOptions) (0),
2123 (GtkAttachOptions) (0), 0, 0);
2125 // view type 4 selector
2126 radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2127 gtk_widget_show (radio);
2128 gtk_table_attach (GTK_TABLE (table), radio, 3, 4, 1, 2,
2129 (GtkAttachOptions) (0),
2130 (GtkAttachOptions) (0), 0, 0);
2131 AddDialogData (radio, &m_nLatchedView, DLG_RADIO_INT);
2133 // Floating Z window
2134 check = gtk_check_button_new_with_label ("Floating Z Window");
2135 gtk_widget_show (check);
2136 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2137 AddDialogData (check, &m_bLatchedFloatingZ, DLG_CHECK_BOOL);
2139 // show menu tear-off seperators
2140 check = gtk_check_button_new_with_label ("Detachable Menus");
2141 gtk_widget_show (check);
2142 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2143 AddDialogData (check, &m_bLatchedDetachableMenus, DLG_CHECK_BOOL);
2145 if (!g_pGameDescription->mNoPatch)
2147 // show patch toolbar
2148 check = gtk_check_button_new_with_label ("Patch Toolbar");
2149 gtk_widget_show (check);
2150 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2151 g_object_set_data (G_OBJECT (dialog), "check_patchtoolbar", check); // Allow to be disabled for Q1/Q2
2152 AddDialogData (check, &m_bLatchedPatchToolbar, DLG_CHECK_BOOL);
2156 check = gtk_check_button_new_with_label ("Wide Toolbar");
2157 gtk_widget_show (check);
2158 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2159 AddDialogData (check, &m_bLatchedWideToolbar, DLG_CHECK_BOOL);
2161 // use plugin toolbar
2162 check = gtk_check_button_new_with_label ("Plugin Toolbar");
2163 gtk_widget_show (check);
2164 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2165 AddDialogData (check, &m_bLatchedPluginToolbar, DLG_CHECK_BOOL);
2168 // win32 file dialog
2169 check = gtk_check_button_new_with_label ("Use win32 file load dialog");
2170 gtk_widget_show (check);
2171 // gtk_container_add (GTK_CONTAINER (vbox), check);
2172 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2173 AddDialogData (check, &m_bNativeGUI, DLG_CHECK_BOOL);
2175 // position on primary monitor
2176 check = gtk_check_button_new_with_label ("Start on Primary Monitor");
2177 gtk_widget_show (check);
2178 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2179 g_object_set_data (G_OBJECT (dialog), "check_startonprimary", check);
2180 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2181 AddDialogData (check, &m_bStartOnPrimMon, DLG_CHECK_BOOL);
2184 // Add the page to the notebook
2185 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2187 /******** Mouse group *********/
2188 preflabel = gtk_label_new("Mouse");
2189 gtk_widget_show(preflabel);
2190 pageframe = gtk_frame_new("Mouse");
2191 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2192 gtk_widget_show(pageframe);
2193 vbox = gtk_vbox_new(FALSE, 5);
2194 gtk_widget_show(vbox);
2195 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2196 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2200 hbox2 = gtk_hbox_new (FALSE, 5);
2201 gtk_widget_show (hbox2);
2202 gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2205 radio = gtk_radio_button_new_with_label (NULL, "2 button");
2206 gtk_widget_show (radio);
2207 gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);
2210 radio = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio), "3 button");
2211 gtk_widget_show (radio);
2212 gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);
2213 AddDialogData (radio, &m_nMouse, DLG_RADIO_INT);
2215 // right click to drop entity
2216 check = gtk_check_button_new_with_label ("Right click to drop entities");
2217 gtk_widget_show (check);
2218 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2219 AddDialogData (check, &m_bRightClick, DLG_CHECK_BOOL);
2221 // Mouse chaser (and this does what?)
2222 check = gtk_check_button_new_with_label ("Mouse chaser");
2223 gtk_widget_show (check);
2224 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2225 AddDialogData (check, &m_bChaseMouse, DLG_CHECK_BOOL);
2228 check = gtk_check_button_new_with_label ("ALT + multi-drag");
2229 gtk_widget_show (check);
2230 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2231 AddDialogData (check, &m_bALTEdge, DLG_CHECK_BOOL);
2233 // Mouse wheel increments
2235 hbox2 = gtk_hbox_new (FALSE, 5);
2236 gtk_widget_show (hbox2);
2237 gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2240 label = gtk_label_new ("Wheel Mouse inc:");
2241 gtk_widget_show (label);
2242 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
2245 entry = gtk_entry_new ();
2246 gtk_widget_show (entry);
2247 gtk_widget_set_usize (entry, 40, -2);
2248 gtk_box_pack_start (GTK_BOX (hbox2), entry, FALSE, FALSE, 0);
2249 AddDialogData (entry, &m_nWheelInc, DLG_ENTRY_INT);
2251 // Add the page to the notebook
2252 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2254 /******** Editing group *********/
2255 preflabel = gtk_label_new("Editing");
2256 gtk_widget_show(preflabel);
2257 pageframe = gtk_frame_new("Editing");
2258 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2259 gtk_widget_show(pageframe);
2260 vbox = gtk_vbox_new(FALSE, 5);
2261 gtk_widget_show(vbox);
2262 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2263 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2265 // Vertex editing splits faces
2266 check = gtk_check_button_new_with_label ("Vertex editing splits face");
2267 gtk_widget_show (check);
2268 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2269 AddDialogData (check, &m_bVertexSplit, DLG_CHECK_BOOL);
2271 // Fix target/targetname collisions
2272 check = gtk_check_button_new_with_label ("Fix target/targetname collisions");
2273 gtk_widget_show (check);
2274 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2275 AddDialogData (check, &m_bDoTargetFix, DLG_CHECK_BOOL);
2277 // Clipper tool uses caulk
2278 check = gtk_check_button_new_with_label ("Clipper tool uses caulk");
2279 gtk_widget_show (check);
2280 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2281 AddDialogData (check, &m_bClipCaulk, DLG_CHECK_BOOL);
2283 // Don't clamp plane points
2284 check = gtk_check_button_new_with_label ("Don't clamp plane points");
2285 gtk_widget_show (check);
2286 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2287 AddDialogData (check, &m_bNoClamp, DLG_CHECK_BOOL);
2289 // Select patch by bounding box
2290 check = gtk_check_button_new_with_label ("Select patches by bounding box");
2291 gtk_widget_show (check);
2292 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2293 AddDialogData (check, &m_bPatchBBoxSelect, DLG_CHECK_BOOL);
2295 // Rotation increment
2297 table = gtk_table_new (2, 3, FALSE);
2298 gtk_widget_show (table);
2299 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2300 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2301 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2304 label = gtk_label_new ("Rotation increment:");
2305 gtk_widget_show (label);
2306 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2307 (GtkAttachOptions) (0),
2308 (GtkAttachOptions) (0), 0, 0);
2311 entry = gtk_entry_new ();
2312 gtk_widget_show (entry);
2313 gtk_widget_set_usize (entry, 60, -2);
2314 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2315 (GtkAttachOptions) (GTK_FILL),
2316 (GtkAttachOptions) (0), 0, 0);
2317 AddDialogData (entry, &m_nRotation, DLG_ENTRY_INT);
2321 label = gtk_label_new ("Undo Levels:");
2322 gtk_widget_show (label);
2323 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2324 (GtkAttachOptions) (0),
2325 (GtkAttachOptions) (0), 0, 0);
2327 // spinner (allows undo levels to be set to zero)
2328 spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 0, 64, 1, 10, 10)), 1, 0);
2329 gtk_widget_show (spin);
2330 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,
2331 (GtkAttachOptions) (GTK_FILL),
2332 (GtkAttachOptions) (0), 0, 0);
2333 gtk_widget_set_usize (spin, 60, -2);
2334 AddDialogData (spin, &m_nUndoLevels, DLG_SPIN_INT);
2336 // Patch subdivisions
2338 label = gtk_label_new ("Patch subdivisions:");
2339 gtk_widget_show (label);
2340 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
2341 (GtkAttachOptions) (0),
2342 (GtkAttachOptions) (0), 0, 0);
2344 // entry (spinner perhaps? [2-16])
2345 entry = gtk_entry_new ();
2346 gtk_widget_show (entry);
2347 gtk_widget_set_usize (entry, 60, -2);
2348 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3,
2349 (GtkAttachOptions) (GTK_FILL),
2350 (GtkAttachOptions) (0), 0, 0);
2351 AddDialogData (entry, &m_nSubdivisions, DLG_ENTRY_INT);
2353 // Add the page to the notebook
2354 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2356 /******** Save/Load group *********/
2357 preflabel = gtk_label_new("Startup/Auto save");
2358 gtk_widget_show(preflabel);
2359 pageframe = gtk_frame_new("Startup/Auto save");
2360 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2361 gtk_widget_show(pageframe);
2362 vbox = gtk_vbox_new(FALSE, 5);
2363 gtk_widget_show(vbox);
2364 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2365 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2368 check = gtk_check_button_new_with_label ("Snapshots");
2369 gtk_widget_show (check);
2370 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2371 AddDialogData (check, &m_bSnapShots, DLG_CHECK_BOOL);
2373 // load last project on open
2374 check = gtk_check_button_new_with_label ("Load last project on open");
2375 gtk_widget_show (check);
2376 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2377 AddDialogData (check, &m_bLoadLast, DLG_CHECK_BOOL);
2379 // load last map on open
2380 check = gtk_check_button_new_with_label ("Load last map on open");
2381 gtk_widget_show (check);
2382 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2383 AddDialogData (check, &m_bLoadLastMap, DLG_CHECK_BOOL);
2387 hbox2 = gtk_hbox_new (FALSE, 5);
2388 gtk_widget_show (hbox2);
2389 gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2390 gtk_container_set_border_width (GTK_CONTAINER (hbox2), 0);
2393 check = gtk_check_button_new_with_label ("Auto save every");
2394 gtk_widget_show (check);
2395 gtk_box_pack_start (GTK_BOX (hbox2), check, FALSE, FALSE, 0);
2396 AddDialogData (check, &m_bAutoSave, DLG_CHECK_BOOL);
2399 spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 60, 1, 10, 10)), 1, 0);
2400 gtk_widget_show (spin);
2401 gtk_box_pack_start (GTK_BOX (hbox2), spin, FALSE, FALSE, 0);
2402 gtk_widget_set_usize (spin, 60, -2);
2403 AddDialogData (spin, &m_nAutoSave, DLG_SPIN_INT);
2406 label = gtk_label_new ("minutes");
2407 gtk_widget_show (label);
2408 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
2410 // Add the page to the notebook
2411 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2413 /******** Paths group *********/
2414 preflabel = gtk_label_new("Paths");
2415 gtk_widget_show(preflabel);
2416 pageframe = gtk_frame_new("Paths");
2417 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2418 gtk_widget_show(pageframe);
2419 vbox = gtk_vbox_new(FALSE, 5);
2420 gtk_widget_show(vbox);
2421 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2422 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2426 table = gtk_table_new (3, 3, FALSE);
2427 gtk_widget_show (table);
2428 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2429 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2430 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2433 label = gtk_label_new ("Prefab path:");
2434 gtk_widget_show (label);
2435 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2436 (GtkAttachOptions) (0),
2437 (GtkAttachOptions) (0), 0, 0);
2438 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2441 entry = gtk_entry_new ();
2442 gtk_widget_show (entry);
2443 gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);
2444 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2445 (GtkAttachOptions) (GTK_FILL),
2446 (GtkAttachOptions) (0), 1, 0);
2447 AddDialogData (entry, &m_strPrefabPath, DLG_ENTRY_TEXT);
2449 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=805
2452 button = gtk_button_new_with_label ("...");
2453 gtk_widget_show (button);
2454 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseprefab), this);
2455 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
2456 (GtkAttachOptions) (0),
2457 (GtkAttachOptions) (0), 0, 0);
2462 label = gtk_label_new ("User INI path:");
2463 gtk_widget_show (label);
2464 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2465 (GtkAttachOptions) (0),
2466 (GtkAttachOptions) (0), 0, 0);
2467 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2469 // user ini path entry
2470 entry = gtk_entry_new ();
2471 gtk_widget_show (entry);
2472 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
2473 (GtkAttachOptions) (GTK_FILL),
2474 (GtkAttachOptions) (0), 1, 0);
2475 AddDialogData (entry, &m_strUserPath, DLG_ENTRY_TEXT);
2477 // user ini browse button
2478 button = gtk_button_new_with_label ("...");
2479 gtk_widget_show (button);
2480 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseuserini), this);
2481 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,
2482 (GtkAttachOptions) (0),
2483 (GtkAttachOptions) (0), 0, 0);
2485 // Add the page to the notebook
2486 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2488 /******** Misc group *********/
2489 preflabel = gtk_label_new("Misc");
2490 gtk_widget_show(preflabel);
2491 pageframe = gtk_frame_new("Misc");
2492 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2493 gtk_widget_show(pageframe);
2494 vbox = gtk_vbox_new(FALSE, 5);
2495 gtk_widget_show(vbox);
2496 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2497 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2500 check = gtk_check_button_new_with_label ("Light drawing");
2501 gtk_widget_show (check);
2502 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2503 AddDialogData (check, &m_bNewLightDraw, DLG_CHECK_BOOL);
2507 table = gtk_table_new(2, 1, FALSE);
2508 gtk_widget_show(table);
2509 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2510 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2511 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2513 label = gtk_label_new ("Light radiuses:");
2514 gtk_widget_show (label);
2515 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2516 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
2517 (GtkAttachOptions) (0),
2518 (GtkAttachOptions) (0), 0, 0);
2521 combo_list = g_list_append (combo_list, (void *)"Disabled");
2522 combo_list = g_list_append (combo_list, (void *)"True Q3Map2 Style");
2523 combo_list = g_list_append (combo_list, (void *)"Classic Style");
2525 combo = gtk_combo_new ();
2526 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2527 gtk_widget_show (combo);
2528 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
2529 (GtkAttachOptions) (GTK_FILL),
2530 (GtkAttachOptions) (0), 0, 0);
2531 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
2532 AddDialogData (combo, &m_nLightRadiuses, DLG_COMBO_INT);
2535 check = gtk_check_button_new_with_label ("Use win32 file associations to open text files instead of builtin editor");
2536 gtk_widget_show(check);
2537 gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);
2538 AddDialogData (check, &g_PrefsDlg.m_bUseWin32Editor, DLG_CHECK_BOOL);
2540 // use custom shader editor
2541 check = gtk_check_button_new_with_label ("Use Custom Shader Editor");
2542 gtk_widget_show(check);
2543 gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);
2544 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateEditorSensitivity), this);
2545 g_object_set_data (G_OBJECT(dialog), "check_customeditor", check);
2546 AddDialogData (check, &g_PrefsDlg.m_bUseCustomEditor, DLG_CHECK_BOOL);
2548 // custom shader editor executable
2550 table = gtk_table_new (3, 1, FALSE);
2551 gtk_widget_show (table);
2552 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2553 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2554 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2557 label = gtk_label_new("Custom Editor Command");
2558 gtk_widget_show(label);
2559 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2560 (GtkAttachOptions) (0),
2561 (GtkAttachOptions) (0), 0, 0);
2562 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2563 g_object_set_data (G_OBJECT(dialog), "label_customeditor", label);
2564 gtk_widget_set_sensitive (label, g_PrefsDlg.m_bUseCustomEditor);
2566 // custom editor command entry
2567 entry = gtk_entry_new ();
2568 gtk_widget_show (entry);
2569 gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);
2570 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2571 (GtkAttachOptions) (GTK_FILL),
2572 (GtkAttachOptions) (0), 1, 0);
2573 AddDialogData (entry, &m_strEditorCommand, DLG_ENTRY_TEXT);
2574 gtk_widget_set_sensitive (entry, g_PrefsDlg.m_bUseCustomEditor);
2575 g_object_set_data (G_OBJECT(dialog), "entry_customeditor", entry);
2578 button = gtk_button_new_with_label ("...");
2579 gtk_widget_show (button);
2580 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseEditor), this);
2581 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
2582 (GtkAttachOptions) (0),
2583 (GtkAttachOptions) (0), 0, 0);
2584 g_object_set_data (G_OBJECT(dialog), "button_customeditor", button);
2585 gtk_widget_set_sensitive (button, g_PrefsDlg.m_bUseCustomEditor);
2588 // Add the page to the notebook
2589 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2591 /******** BSP Monitoring group *********/
2592 // this is never displayed if the plugin isn't available
2593 preflabel = gtk_label_new("BSP Monitoring");
2594 gtk_widget_show(preflabel);
2595 pageframe = gtk_frame_new("BSP Monitoring");
2596 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2597 gtk_widget_show(pageframe);
2598 vbox = gtk_vbox_new(FALSE, 5);
2599 gtk_widget_show(vbox);
2600 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2601 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2603 // Enable BSP process monitoring
2604 check = gtk_check_button_new_with_label ("Enable BSP process monitoring");
2605 gtk_widget_show (check);
2606 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2607 g_object_set_data (G_OBJECT (dialog), "check_monitorbsp", check);
2608 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2609 AddDialogData (check, &g_PrefsDlg.m_bWatchBSP, DLG_CHECK_BOOL);
2612 check = gtk_check_button_new_with_label ("Stop compilation on leak");
2613 gtk_widget_show (check);
2614 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2615 g_object_set_data (G_OBJECT (dialog), "check_leakstop", check);
2616 AddDialogData (check, &g_PrefsDlg.m_bLeakStop, DLG_CHECK_BOOL);
2618 // engine after compile
2619 check = gtk_check_button_new_with_label ("Run engine after compile");
2620 gtk_widget_show (check);
2621 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2622 g_object_set_data (G_OBJECT (dialog), "check_runengine", check);
2623 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2624 AddDialogData( check, &g_PrefsDlg.m_bRunQuake, DLG_CHECK_BOOL );
2626 // sleep mode when running engine
2627 check = gtk_check_button_new_with_label ("Activate sleep mode when running the engine");
2628 gtk_widget_show (check);
2629 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2630 g_object_set_data (G_OBJECT (dialog), "check_sleep", check);
2631 AddDialogData( check, &g_PrefsDlg.m_bDoSleep, DLG_CHECK_BOOL );
2633 // use q3map2's texture projection
2634 check = gtk_check_button_new_with_label ("Texturing compatible with q3map2");
2635 gtk_widget_show (check);
2636 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2637 g_object_set_data (G_OBJECT (dialog), "check_q3map2", check);
2638 AddDialogData( check, &g_PrefsDlg.m_bQ3Map2Texturing, DLG_CHECK_BOOL );
2640 // Add the page to the notebook
2641 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2643 gtk_notebook_set_page(GTK_NOTEBOOK(notebook), PTAB_FRONT);
2648 // end new prefs dialog
2650 void PrefsDlg::LoadTexdefPref(texdef_t* pTexdef, char* pName)
2654 memset(pTexdef, 0, sizeof(texdef_t));
2656 sprintf(buffer, "%s%s", pName, TD_SCALE1_KEY);
2657 mLocalPrefs.GetPref(buffer, &pTexdef->scale[0], 0.5f);
2659 sprintf(buffer, "%s%s", pName, TD_SCALE2_KEY);
2660 mLocalPrefs.GetPref(buffer, &pTexdef->scale[1], 0.5f);
2662 sprintf(buffer, "%s%s", pName, TD_SHIFT1_KEY);
2663 mLocalPrefs.GetPref(buffer, &pTexdef->shift[0], 8.f);
2665 sprintf(buffer, "%s%s", pName, TD_SHIFT2_KEY);
2666 mLocalPrefs.GetPref(buffer, &pTexdef->shift[1], 8.f);
2668 sprintf(buffer, "%s%s", pName, TD_ROTATE_KEY);
2669 mLocalPrefs.GetPref(buffer, &pTexdef->rotate, 45);
2672 void PrefsDlg::UpdateTextureCompression()
2674 // if OpenGL is not ready yet, don't do anything
2675 if (!g_qeglobals.m_bOpenGLReady) {
2676 Sys_Printf("OpenGL not ready - postpone texture compression capability check\n");
2680 if (g_qeglobals.bTextureCompressionSupported)
2682 if (m_nTextureCompressionFormat >= 2 && !g_qeglobals.m_bS3CompressionSupported)
2684 Sys_Printf("Inconsistant pref setting for texture compression (%d), rolling back\n", m_nTextureCompressionFormat);
2685 m_nTextureCompressionFormat = 1; // if this is not supported either, see below
2687 if (m_nTextureCompressionFormat == 1 && !g_qeglobals.m_bOpenGLCompressionSupported)
2689 Sys_Printf("Inconsistant pref setting for texture compression (GL_COMPRESSED_RGBA), rolling back\n");
2690 m_nTextureCompressionFormat = 0;
2692 switch (m_nTextureCompressionFormat)
2696 g_qeglobals.texture_components = GL_RGBA;
2697 Sys_Printf("texture compression disabled by preferences settings\n");
2702 g_qeglobals.texture_components = GL_COMPRESSED_RGBA;
2703 Sys_Printf("OpenGL texture compression enabled\n");
2708 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
2709 Sys_Printf("S3TC DXT1 texture compression enabled\n");
2714 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
2715 Sys_Printf("S3TC DXT3 texture compression enabled\n");
2720 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
2721 Sys_Printf("S3TC DXT5 texture compression enabled\n");
2728 Sys_Printf("texture compression is not supported by your current graphic card/drivers\n");
2729 g_qeglobals.texture_components = GL_RGBA;
2730 m_nTextureCompressionFormat = 0;
2735 void PrefsDlg::UpdateATIHack() {
2736 // if OpenGL is not ready yet, don't do anything
2737 if (!g_qeglobals.m_bOpenGLReady) {
2738 Sys_Printf("OpenGL not ready - postpone ATI bug workaround setup\n");
2743 qglCullFace = &qglCullFace_ATIHack;
2744 qglDisable = &qglDisable_ATIHack;
2745 qglEnable = &qglEnable_ATIHack;
2746 qglPolygonMode = &qglPolygonMode_ATIHack;
2747 Sys_Printf("ATI bug workaround enabled\n");
2749 qglCullFace = qglCullFace_real;
2750 qglDisable = qglDisable_real;
2751 qglEnable = qglEnable_real;
2752 qglPolygonMode = qglPolygonMode_real;
2753 Sys_Printf("ATI bug workaround disabled\n");
2758 // TTimo: m_strEnginePath has a special status, if not found in registry we need to
2759 // initiliaze it for sure. It is not totally failsafe but we can use the same
2760 // code than in q3map, expecting to find some "quake" above us. If not, we prompt
2761 // for the engine executable path
2762 void PrefsDlg::LoadPrefs ()
2766 // first things first, load prefs from global prefs
2767 mGamesDialog.LoadPrefs();
2769 // if we already have a document loaded, we will free and reload from file
2770 if (mLocalPrefs.InUse()) {
2771 mLocalPrefs.Clear();
2774 // load local.pref file
2775 mLocalPrefs.ReadXMLFile(m_inipath->str);
2777 mLocalPrefs.GetPref(PATCHSHOWBOUNDS_KEY, &g_bPatchShowBounds, FALSE);
2778 mLocalPrefs.GetPref(MOUSE_KEY, &m_nMouse, MOUSE_DEF);
2779 m_nMouseButtons = m_nMouse ? 3 : 2;
2782 // if it's not found here, mainframe.cpp will take care of finding one
2783 mLocalPrefs.GetPref(LASTPROJ_KEY, &m_strLastProject, "");
2784 mLocalPrefs.GetPref(LASTPROJVER_KEY, &m_nLastProjectVer, -1);
2787 // NOTE TTimo: I'm not sure why this is in prefs
2788 // should probably be a project setting
2789 // and I'm not sure that we really have a way to set this reliably either
2791 strPrefab = g_qeglobals.m_strHomeGame.GetBuffer();
2792 strPrefab += g_pGameDescription->mBaseGame.GetBuffer();
2793 strPrefab += "/prefabs/";
2794 mLocalPrefs.GetPref(PREFAB_KEY, &m_strPrefabPath, strPrefab);
2796 mLocalPrefs.GetPref(LASTLIGHTINTENSITY_KEY, &m_iLastLightIntensity, 300);
2797 mLocalPrefs.GetPref(TLOCK_KEY, &m_bTextureLock, TLOCK_DEF);
2798 mLocalPrefs.GetPref(RLOCK_KEY, &m_bRotateLock, TLOCK_DEF);
2799 mLocalPrefs.GetPref(LASTMAP_KEY, &m_strLastMap, "");
2800 mLocalPrefs.GetPref(LOADLAST_KEY, &m_bLoadLast, LOADLAST_DEF);
2801 mLocalPrefs.GetPref(BSP_KEY, &m_bInternalBSP, FALSE);
2802 mLocalPrefs.GetPref(RCLICK_KEY, &m_bRightClick, TRUE);
2803 mLocalPrefs.GetPref(AUTOSAVE_KEY, &m_bAutoSave, TRUE);
2804 mLocalPrefs.GetPref(LOADLASTMAP_KEY, &m_bLoadLastMap, FALSE);
2805 mLocalPrefs.GetPref(TINYBRUSH_KEY, &m_bCleanTiny, FALSE);
2806 mLocalPrefs.GetPref(TINYSIZE_KEY, &m_fTinySize, 0.5f);
2807 mLocalPrefs.GetPref(AUTOSAVETIME_KEY, &m_nAutoSave, 5);
2808 mLocalPrefs.GetPref(SNAPSHOT_KEY, &m_bSnapShots, FALSE);
2809 mLocalPrefs.GetPref(MOVESPEED_KEY, &m_nMoveSpeed, 100);
2810 mLocalPrefs.GetPref(ANGLESPEED_KEY, &m_nAngleSpeed, 3);
2811 mLocalPrefs.GetPref(SETGAME_KEY, &m_bSetGame, FALSE);
2812 mLocalPrefs.GetPref(CAMXYUPDATE_KEY, &m_bCamXYUpdate, TRUE);
2813 mLocalPrefs.GetPref(CAMDRAGMULTISELECT_KEY, &m_nCamDragMultiSelect, TRUE);
2814 mLocalPrefs.GetPref(CAMFREELOOK_KEY, &m_bCamFreeLook, TRUE);
2815 mLocalPrefs.GetPref(CAMINVERSEMOUSE_KEY, &m_bCamInverseMouse, FALSE);
2816 mLocalPrefs.GetPref(CAMDISCRETE_KEY, &m_bCamDiscrete, TRUE);
2817 mLocalPrefs.GetPref(LIGHTDRAW_KEY, &m_bNewLightDraw, TRUE);
2818 mLocalPrefs.GetPref(CUBICCLIP_KEY, &m_bCubicClipping, TRUE);
2819 mLocalPrefs.GetPref(CUBICSCALE_KEY, &m_nCubicScale, 13);
2820 mLocalPrefs.GetPref(ALTEDGE_KEY, &m_bALTEdge, FALSE);
2821 mLocalPrefs.GetPref(FACECOLORS_KEY, &m_bFaceColors, FALSE);
2822 mLocalPrefs.GetPref(XZVIS_KEY, &m_bXZVis, FALSE);
2823 mLocalPrefs.GetPref(YZVIS_KEY, &m_bYZVis, FALSE);
2824 mLocalPrefs.GetPref(ZVIS_KEY, &m_bZVis, FALSE);
2825 mLocalPrefs.GetPref(SIZEPAINT_KEY, &m_bSizePaint, FALSE);
2826 mLocalPrefs.GetPref(DLLENTITIES_KEY, &m_bDLLEntities, FALSE);
2828 mLocalPrefs.GetPref(DETACHABLEMENUS_KEY, &m_bLatchedDetachableMenus, TRUE);
2829 m_bDetachableMenus = m_bLatchedDetachableMenus;
2831 if (g_pGameDescription->mNoPatch)
2833 m_bPatchToolbar = false;
2837 mLocalPrefs.GetPref(PATCHTOOLBAR_KEY, &m_bLatchedPatchToolbar, TRUE);
2838 m_bPatchToolbar = m_bLatchedPatchToolbar;
2841 mLocalPrefs.GetPref(WIDETOOLBAR_KEY, &m_bLatchedWideToolbar, TRUE);
2842 m_bWideToolbar = m_bLatchedWideToolbar;
2844 mLocalPrefs.GetPref(PLUGINTOOLBAR_KEY, &m_bLatchedPluginToolbar, TRUE);
2845 m_bPluginToolbar = m_bLatchedPluginToolbar;
2847 mLocalPrefs.GetPref(WINDOW_KEY, (int*)&m_nLatchedView, WINDOW_DEF);
2848 m_nView = m_nLatchedView;
2850 mLocalPrefs.GetPref(FLOATINGZ_KEY, &m_bLatchedFloatingZ, FALSE);
2851 m_bFloatingZ = m_bLatchedFloatingZ;
2853 mLocalPrefs.GetPref(TEXTUREQUALITY_KEY, &m_nLatchedTextureQuality, 3);
2854 m_nTextureQuality = m_nLatchedTextureQuality;
2856 mLocalPrefs.GetPref(LOADSHADERS_KEY, &m_nLatchedShader, 0);
2857 m_nShader = m_nLatchedShader;
2859 mLocalPrefs.GetPref(NOCLAMP_KEY, &m_bNoClamp, FALSE);
2860 mLocalPrefs.GetPref(USERINI_KEY, &m_strUserPath, "");
2861 mLocalPrefs.GetPref(ROTATION_KEY, &m_nRotation, 45);
2862 mLocalPrefs.GetPref(CHASEMOUSE_KEY, &m_bChaseMouse, TRUE);
2863 mLocalPrefs.GetPref(ENTITYSHOW_KEY, &m_nEntityShowState, ENTITY_SKINNED_BOXED);
2865 // this will probably need to be 75 or 100 for Q1.
2866 mLocalPrefs.GetPref(TEXTURESCALE_KEY, &m_nTextureScale, 50);
2868 // FIXME: Hydra - actually, this stuff is Q1,Q2 and HL specific.
2869 if ( (g_pGameDescription->mGameFile == "hl.game") )
2871 // No BSP monitoring in the default compiler tools for Half-life (yet)
2872 mLocalPrefs.GetPref(WATCHBSP_KEY, &m_bWatchBSP, FALSE);
2874 // Texture subset on by default (HL specific really, because of halflife.wad's size)
2875 mLocalPrefs.GetPref(TEXTURE_KEY, &m_bTextureWindow, TRUE);
2877 else if ( ( g_pGameDescription->mGameFile == "q2.game" ) || ( g_pGameDescription->mGameFile == "heretic2.game" ) )
2879 // BSP monitoring is implemented in Quake2 and Heretic2 tools
2880 mLocalPrefs.GetPref(WATCHBSP_KEY, &m_bWatchBSP, TRUE);
2882 // Texture subset on by default (HL specific really, because of halflife.wad's size)
2883 mLocalPrefs.GetPref(TEXTURE_KEY, &m_bTextureWindow, TRUE);
2887 mLocalPrefs.GetPref(WATCHBSP_KEY, &m_bWatchBSP, WATCHBSP_DEF);
2888 mLocalPrefs.GetPref(TEXTURE_KEY, &m_bTextureWindow, FALSE);
2892 mLocalPrefs.GetPref(TEXTURESCROLLBAR_KEY, &m_bTextureScrollbar, TRUE);
2893 mLocalPrefs.GetPref(DISPLAYLISTS_KEY, &m_bDisplayLists, TRUE);
2894 mLocalPrefs.GetPref(ANTIALIASEDLINES_KEY, &m_bAntialiasedPointsAndLines, FALSE);
2895 mLocalPrefs.GetPref(SWITCHCLIP_KEY, &m_bSwitchClip, TRUE);
2896 mLocalPrefs.GetPref(SELWHOLEENTS_KEY, &m_bSelectWholeEntities, TRUE);
2897 mLocalPrefs.GetPref(SHOWSHADERS_KEY, &m_bShowShaders, TRUE);
2898 mLocalPrefs.GetPref(GLLIGHTING_KEY, &m_bGLLighting, FALSE);
2899 mLocalPrefs.GetPref(NOSTIPPLE_KEY, &m_bNoStipple, FALSE);
2900 mLocalPrefs.GetPref(UNDOLEVELS_KEY, &m_nUndoLevels, 30);
2901 mLocalPrefs.GetPref(VERTEXMODE_KEY, &m_bVertexSplit, TRUE);
2902 mLocalPrefs.GetPref(RUNQ2_KEY, &m_bRunQuake, RUNQ2_DEF);
2903 mLocalPrefs.GetPref(LEAKSTOP_KEY, &m_bLeakStop, TRUE);
2904 mLocalPrefs.GetPref(DOSLEEP_KEY, &m_bDoSleep, FALSE);
2905 mLocalPrefs.GetPref(SELECTCURVES_KEY, &m_bSelectCurves, TRUE);
2906 mLocalPrefs.GetPref(SELECTMODELS_KEY, &m_bSelectModels, TRUE);
2907 mLocalPrefs.GetPref(SHADERLISTONLY_KEY, &m_bTexturesShaderlistOnly, FALSE);
2908 mLocalPrefs.GetPref(SUBDIVISIONS_KEY, &m_nSubdivisions, SUBDIVISIONS_DEF);
2909 mLocalPrefs.GetPref(CLIPCAULK_KEY, &m_bClipCaulk, FALSE);
2910 mLocalPrefs.GetPref(SNAPTTOGRID_KEY, &m_bSnapTToGrid, FALSE);
2911 mLocalPrefs.GetPref(TARGETFIX_KEY, &m_bDoTargetFix, TRUE);
2912 mLocalPrefs.GetPref(WHEELINC_KEY, &m_nWheelInc, 64);
2913 mLocalPrefs.GetPref(PATCHBBOXSEL_KEY, &m_bPatchBBoxSelect, FALSE);
2915 // Gef: Kyro GL_POINT workaround
2916 mLocalPrefs.GetPref(GLPOINTWORKAROUND_KEY, &m_bGlPtWorkaround, FALSE);
2918 // window positioning
2919 mLocalPrefs.GetPref(ENTITYSPLIT1_KEY, &mWindowInfo.nEntitySplit1, -1);
2920 mLocalPrefs.GetPref(ENTITYSPLIT2_KEY, &mWindowInfo.nEntitySplit2, -1);
2922 mLocalPrefs.GetPref(POSITIONX_KEY, &mWindowInfo.position.x, -1);
2923 mLocalPrefs.GetPref(POSITIONY_KEY, &mWindowInfo.position.y, -1);
2924 mLocalPrefs.GetPref(WIDTH_KEY, &mWindowInfo.position.w, -1);
2925 mLocalPrefs.GetPref(HEIGHT_KEY, &mWindowInfo.position.h, 450);
2927 const window_position_t default_window_pos = { 0, 0, 200, 200, };
2929 mLocalPrefs.GetPref(ENTITYWND_KEY, &mWindowInfo.posEntityWnd, default_window_pos);
2930 mLocalPrefs.GetPref(MAPINFOWND_KEY, &mWindowInfo.posMapInfoWnd, default_window_pos);
2931 mLocalPrefs.GetPref(CAMWND_KEY, &mWindowInfo.posCamWnd, default_window_pos);
2932 mLocalPrefs.GetPref(ZWND_KEY, &mWindowInfo.posZWnd, default_window_pos);
2933 mLocalPrefs.GetPref(XYWND_KEY, &mWindowInfo.posXYWnd, default_window_pos);
2934 mLocalPrefs.GetPref(YZWND_KEY, &mWindowInfo.posYZWnd, default_window_pos);
2935 mLocalPrefs.GetPref(XZWND_KEY, &mWindowInfo.posXZWnd, default_window_pos);
2936 mLocalPrefs.GetPref(PATCHWND_KEY, &mWindowInfo.posPatchWnd, default_window_pos);
2937 mLocalPrefs.GetPref(SURFACEWND_KEY, &mWindowInfo.posSurfaceWnd, default_window_pos);
2938 mLocalPrefs.GetPref(ENTITYINFOWND_KEY, &mWindowInfo.posEntityInfoWnd, default_window_pos);
2940 mLocalPrefs.GetPref(ZWIDTH_KEY, &mWindowInfo.nZWidth, 30);
2941 mLocalPrefs.GetPref(XYHEIGHT_KEY, &mWindowInfo.nXYHeight, 300);
2942 mLocalPrefs.GetPref(XYWIDTH_KEY, &mWindowInfo.nXYWidth, 300);
2943 mLocalPrefs.GetPref(CAMWIDTH_KEY, &mWindowInfo.nCamWidth, 200);
2944 mLocalPrefs.GetPref(CAMHEIGHT_KEY, &mWindowInfo.nCamHeight, 200);
2945 mLocalPrefs.GetPref(ZFLOATWIDTH_KEY, &mWindowInfo.nZFloatWidth, 300);
2947 mLocalPrefs.GetPref(STATE_KEY, &mWindowInfo.nState, SW_SHOW);
2951 mLocalPrefs.GetPref(COUNT_KEY, &m_nMRUCount, 0);
2952 for(i = 0; i < 4; i++)
2955 sprintf (buf, "%s%d", FILE_KEY, i);
2956 mLocalPrefs.GetPref(buf, &m_strMRUFiles[i], "");
2959 // some platform specific prefs
2961 mLocalPrefs.GetPref(NATIVEGUI_KEY, &m_bNativeGUI, TRUE);
2962 mLocalPrefs.GetPref(STARTONPRIMMON_KEY, &m_bStartOnPrimMon, FALSE);
2965 mLocalPrefs.GetPref(SI_TEXMENU_KEY, &g_qeglobals.d_savedinfo.iTexMenu, ID_VIEW_BILINEARMIPMAP);
2966 mLocalPrefs.GetPref(SI_GAMMA_KEY, &g_qeglobals.d_savedinfo.fGamma, 1.0f);
2967 mLocalPrefs.GetPref(SI_EXCLUDE_KEY, &g_qeglobals.d_savedinfo.exclude, 0); // nothing filtered by default
2968 mLocalPrefs.GetPref(SI_INCLUDE_KEY, &g_qeglobals.d_savedinfo.include, INCLUDE_NAMES | INCLUDE_COORDS | INCLUDE_ANGLES | INCLUDE_CAMERATINT);
2969 mLocalPrefs.GetPref(SI_SHOWNAMES_KEY, &g_qeglobals.d_savedinfo.show_names, FALSE);
2970 mLocalPrefs.GetPref(SI_SHOWCOORDS_KEY, &g_qeglobals.d_savedinfo.show_coordinates, TRUE);
2971 mLocalPrefs.GetPref(SI_SHOWANGLES_KEY, &g_qeglobals.d_savedinfo.show_angles, TRUE);
2972 mLocalPrefs.GetPref(SI_SHOWOUTLINES_KEY, &g_qeglobals.d_savedinfo.show_outline, FALSE);
2973 mLocalPrefs.GetPref(SI_SHOWAXIS_KEY, &g_qeglobals.d_savedinfo.show_axis, TRUE);
2974 mLocalPrefs.GetPref(SI_NOSELOUTLINES_KEY, &g_qeglobals.d_savedinfo.bNoSelectedOutlines, FALSE);
2976 mLocalPrefs.GetPref(SI_OUTLINESTYLE_KEY, &g_qeglobals.d_savedinfo.iSelectedOutlinesStyle, OUTLINE_ZBUF|OUTLINE_BSEL);
2978 LoadTexdefPref(&g_qeglobals.d_savedinfo.m_SIIncrement, SI_SURFACE_TEXDEF_KEY);
2979 LoadTexdefPref(&g_qeglobals.d_savedinfo.m_PIIncrement, SI_PATCH_TEXDEF_KEY);
2981 // text editor binding
2983 mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseWin32Editor, TRUE);
2985 mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseCustomEditor, FALSE);
2986 mLocalPrefs.GetPref(CUSTOMSHADEREDITORCOMMAND_KEY, &m_strEditorCommand, "");
2990 vec3_t vDefaultAxisColours[3] = {
2996 for(i = 0; i < 3; i++) {
2998 sprintf(buf, "%s%d", SI_AXISCOLORS_KEY, i);
2999 mLocalPrefs.GetPref(buf, g_qeglobals.d_savedinfo.AxisColors[i], vDefaultAxisColours[i]);
3002 vec3_t vDefaultColours[COLOR_LAST] = {
3003 {0.25f, 0.25f, 0.25f},
3005 {0.75f, 0.75f, 0.75f},
3007 {0.25f, 0.25f, 0.25f},
3020 for(i = 0; i < COLOR_LAST; i++) {
3022 sprintf(buf, "%s%d", SI_COLORS_KEY, i);
3023 mLocalPrefs.GetPref(buf, g_qeglobals.d_savedinfo.colors[i], vDefaultColours[i]);
3026 mLocalPrefs.GetPref(TEXTURECOMPRESSIONFORMAT_KEY, &m_nTextureCompressionFormat, 1);
3028 mLocalPrefs.GetPref(LIGHTRADIUS_KEY, &m_nLightRadiuses, TRUE);
3030 mLocalPrefs.GetPref(Q3MAP2TEX_KEY, &m_bQ3Map2Texturing, TRUE);
3033 mLocalPrefs.GetPref(ATIHACK_KEY, &m_bGlATIHack, FALSE);
3036 Undo_SetMaxSize(m_nUndoLevels); // set it internally as well / FIXME: why not just have one global value?
3038 UpdateTextureCompression();
3044 if (mLocalPrefs.mbEmpty)
3046 mLocalPrefs.mbEmpty = false;
3047 Sys_Printf("Saving local.pref with default pref values\n");
3052 void PrefsDlg::SavePrefs ()
3054 if (g_qeglobals.disable_ini)
3058 Sys_Printf("PrefsDlg::SavePrefs\n");
3061 // this will take care of copying back from the dialog to the variables
3062 // NOTE: it may be overkill to call systematically before a SavePrefs, but it's safer
3063 // this will also cause an UpdateData for the mGamesDialog
3066 mGamesDialog.SavePrefs();
3068 // update the tree and save it
3069 mLocalPrefs.UpdatePrefTree();
3070 if (!mLocalPrefs.WriteXMLFile(m_inipath->str))
3071 Sys_FPrintf(SYS_ERR, "Error occured while saving local prefs file '%s'\n", m_inipath->str);
3073 if ( m_nMouse == 0 ) {
3074 m_nMouseButtons = 2;
3076 m_nMouseButtons = 3;
3081 void PrefsDlg::PostModal (int code)
3086 // make sure the logfile is ok
3092 g_pParentWnd->SetGridStatus();
3093 Sys_UpdateWindows(W_ALL);
3094 if (m_nUndoLevels != 0)
3095 Undo_SetMaxSize(m_nUndoLevels);
3099 void PrefsDlg::DoEditorSensitivity()
3101 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data (G_OBJECT(m_pWidget), "check_customeditor"))))
3103 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), TRUE);
3104 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), TRUE);
3105 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), TRUE);
3109 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), FALSE);
3110 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), FALSE);
3111 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), FALSE);
3115 void PrefsDlg::DoSensitivity()
3118 // first, look at the project file version ... will monitoring work?
3119 // project files now XML, guaranteed to be at least version 2
3120 if (0)//IntForKey( g_qeglobals.d_project_entity, "version" ) < 2)
3125 Msg = "The current project file (";
3126 Msg += g_PrefsDlg.m_strLastProject;
3127 Msg += ") is not at least version 2.\nI need version 2 or above to setup BSP monitoring correctly.";
3128 gtk_MessageBox(m_pWidget, Msg.GetBuffer(), MB_OK );
3133 // go ahead, disable everybuddy
3134 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );
3135 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), FALSE );
3136 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );
3137 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3144 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), TRUE );
3145 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), TRUE );
3146 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), TRUE );
3147 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), TRUE );
3149 if ( ! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" ) ) ) )
3151 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );
3152 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );
3153 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3154 } else if (! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" ) ) ) )
3156 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3161 ============================================================
3163 ============================================================
3166 CGameInstall::CGameInstall() {
3167 memset( m_availGames, 0, sizeof( m_availGames ) );
3170 static void CGameInstall::OnBtnBrowseEngine( GtkWidget *widget, gpointer data ) {
3171 Sys_Printf( "OnBtnBrowseEngine\n" );
3173 CGameInstall* i = static_cast<CGameInstall*>( data );
3174 char *dir = dir_dialog( widget, "Select game directory", NULL );
3176 i->UpdateData( TRUE );
3178 if ( dir != NULL ) {
3179 i->m_strEngine = dir;
3180 i->UpdateData( FALSE );
3185 static void CGameInstall::OnGameSelectChanged( GtkWidget *widget, gpointer data ) {
3186 Sys_Printf( "OnGameSelectChanged\n" );
3188 CGameInstall* i = static_cast<CGameInstall*>( data );
3189 i->UpdateData( TRUE );
3190 i->m_strName = gtk_combo_box_get_active_text( GTK_COMBO_BOX( widget ) );
3191 i->UpdateData( FALSE );
3194 void CGameInstall::BuildDialog() {
3195 GtkWidget *dlg, *vbox1, *button, *text, *combo, *entry, *hbox;
3198 gtk_window_set_title( GTK_WINDOW( dlg ), "Configure games" );
3200 vbox1 = gtk_vbox_new( FALSE, 0 );
3201 gtk_widget_show( vbox1 );
3202 gtk_container_add( GTK_CONTAINER( dlg ), vbox1 );
3204 text = gtk_label_new( "Select the game to configure" );
3205 gtk_widget_show( text );
3206 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3208 combo = gtk_combo_box_new_text();
3209 gtk_widget_show( combo );
3210 gtk_box_pack_start( GTK_BOX( vbox1 ), combo, FALSE, FALSE, 0 );
3212 // GList *combo_list = NULL;
3214 while ( m_availGames[ iGame ] != GAME_NONE ) {
3215 switch ( m_availGames[ iGame ] ) {
3217 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Quake II" );
3220 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Quake III Arena and mods" );
3223 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Urban Terror (standalone)" );
3226 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "UFO: Alien Invasion" );
3229 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Quake2World" );
3232 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Warsow" );
3235 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Nexuiz" );
3240 AddDialogData( combo, &m_nComboSelect, DLG_COMBO_BOX_INT );
3241 gtk_signal_connect( GTK_OBJECT( combo ), "changed", G_CALLBACK( OnGameSelectChanged ), this );
3242 gtk_combo_box_set_active( GTK_COMBO_BOX( combo ), 0 ); // NOTE: will trigger signal
3244 text = gtk_label_new( "Name:" );
3245 gtk_widget_show( text );
3246 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3248 entry = gtk_entry_new();
3249 gtk_widget_show( entry );
3250 gtk_box_pack_start( GTK_BOX( vbox1 ), entry, FALSE, FALSE, 0 );
3251 AddDialogData( entry, &m_strName, DLG_ENTRY_TEXT );
3253 text = gtk_label_new( "Engine directory:" );
3254 gtk_widget_show( text );
3255 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3257 hbox = gtk_hbox_new( FALSE, 0 );
3258 gtk_widget_show( hbox );
3259 gtk_box_pack_start( GTK_BOX( vbox1 ), hbox, FALSE, FALSE, 0 );
3261 entry = gtk_entry_new();
3262 gtk_widget_show( entry );
3263 gtk_box_pack_start( GTK_BOX( hbox ), entry, FALSE, FALSE, 0 );
3264 AddDialogData( entry, &m_strEngine, DLG_ENTRY_TEXT );
3266 button = gtk_button_new_with_label ("...");
3267 gtk_widget_show( button );
3268 gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( OnBtnBrowseEngine ), this );
3269 gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
3271 // this gets done in the project stuff atm
3273 text = gtk_label_new( "Mod subdirectory:" );
3274 gtk_widget_show( text );
3275 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3277 entry = gtk_entry_new();
3278 gtk_widget_show( entry );
3279 gtk_box_pack_start( GTK_BOX( vbox1 ), entry, FALSE, FALSE, 0 );
3280 AddDialogData( entry, &m_strMod, DLG_ENTRY_TEXT );
3283 button = gtk_button_new_with_label( "OK" );
3284 gtk_widget_show( button );
3285 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
3286 AddModalButton( button, IDOK );
3288 button = gtk_button_new_with_label( "Cancel" );
3289 gtk_widget_show( button );
3290 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
3291 AddModalButton( button, IDCANCEL );
3293 gtk_widget_set_usize( button, 60, -2 );
3296 void CGameInstall::Run() {
3298 if ( DoModal() == IDCANCEL ) {
3299 Sys_Printf( "game dialog cancelled\n" );
3302 Sys_Printf( "combo: %d name: %s engine: %s mod: %s\n", m_nComboSelect, m_strName.GetBuffer(), m_strEngine.GetBuffer(), m_strMod.GetBuffer() );
3304 // write out the game file
3305 Str gameFilePath = g_strAppPath.GetBuffer();
3306 gameFilePath += "games/";
3307 gameFilePath += m_strName.GetBuffer();
3308 gameFilePath += ".game";
3309 Sys_Printf( "game file: %s\n", gameFilePath.GetBuffer() );
3311 FILE *fg = fopen( gameFilePath.GetBuffer(), "w" );
3313 Error( "Failed to open %s for writing\n", gameFilePath.GetBuffer() );
3315 fprintf( fg, "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>\n<game\n" );
3316 fprintf( fg, " name=\"%s\"\n", m_strName.GetBuffer() );
3317 fprintf( fg, " enginepath=\"%s\"\n", m_strEngine.GetBuffer() );
3318 switch ( m_availGames[ m_nComboSelect ] ) {
3320 fprintf( fg, " gametools=\"%sinstalls/Quake2Pack/game\"\n", g_strAppPath.GetBuffer() );
3321 fprintf( fg, " prefix=\".quake2\"\n" );
3322 Str source = g_strAppPath.GetBuffer();
3323 source += "installs/";
3325 source += "/install/";
3326 Str dest = m_strEngine.GetBuffer();
3327 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3328 fprintf( fg, " basegame=\"baseq2\"\n" );
3332 fprintf( fg, " gametools=\"%sinstalls/Q3Pack/game\"\n", g_strAppPath.GetBuffer() );
3333 fprintf( fg, " prefix=\".q3a\"\n" );
3334 Str source = g_strAppPath.GetBuffer();
3335 source += "installs/";
3337 source += "/install/";
3338 Str dest = m_strEngine.GetBuffer();
3339 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3340 fprintf( fg, " basegame=\"baseq3\"\n" );
3344 fprintf( fg, " gametools=\"%sinstalls/UrTPack/game\"\n", g_strAppPath.GetBuffer() );
3345 fprintf( fg, " prefix=\".q3a\"\n" );
3346 Str source = g_strAppPath.GetBuffer();
3347 source += "installs/";
3349 source += "/install/";
3350 Str dest = m_strEngine.GetBuffer();
3351 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3352 fprintf( fg, " basegame=\"q3ut4\"\n" );
3356 fprintf( fg, " gametools=\"%sinstalls/UFOAIPack/game\"\n", g_strAppPath.GetBuffer() );
3357 fprintf( fg, " prefix=\".ufoai\"\n" );
3358 Str source = g_strAppPath.GetBuffer();
3359 source += "installs/";
3360 source += UFOAI_PACK;
3361 source += "/install/";
3362 Str dest = m_strEngine.GetBuffer();
3363 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3364 fprintf( fg, " basegame=\"base\"\n" );
3368 fprintf( fg, " gametools=\"%sinstalls/Q2WPack/game\"\n", g_strAppPath.GetBuffer() );
3369 fprintf( fg, " prefix=\".quake2world\"\n" );
3370 Str source = g_strAppPath.GetBuffer();
3371 source += "installs/";
3373 source += "/install/";
3374 Str dest = m_strEngine.GetBuffer();
3375 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3376 fprintf( fg, " basegame=\"default\"\n" );
3380 fprintf( fg, " gametools=\"%installs/WarsowPack/game\"\n", g_strAppPath.GetBuffer() );
3381 fprintf( fg, " prefix=\".warsow\"\n" );
3382 Str source = g_strAppPath.GetBuffer();
3383 source += "installs/";
3384 source += WARSOW_PACK;
3385 source += "/install/";
3386 Str dest = m_strEngine.GetBuffer();
3387 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3388 fprintf( fg, " basegame=\"basewsw\"\n" );
3392 fprintf( fg, " gametools=\"%sinstalls/NexuizPack/game\"\n", g_strAppPath.GetBuffer() );
3393 fprintf( fg, " prefix=\".nexuiz\"\n" );
3394 Str source = g_strAppPath.GetBuffer();
3395 source += "installs/";
3396 source += NEXUIZ_PACK;
3397 source += "/install/";
3398 Str dest = m_strEngine.GetBuffer();
3399 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3400 fprintf( fg, " basegame=\"data\"\n" );
3404 fprintf( fg, "/>\n" );
3410 CGameInstall::ScanGames
3411 scan for active games that can be installed, based on the presence
3414 void CGameInstall::ScanGames() {
3415 Str pakPaths = g_strAppPath.GetBuffer();
3417 const char *dirname;
3419 pakPaths += "installs/";
3420 FindFiles fileScan( pakPaths.GetBuffer() );
3421 while ( ( dirname = fileScan.NextFile() ) != NULL ) {
3422 if ( stricmp( dirname, Q3_PACK ) == 0 ) {
3423 m_availGames[ iGame++ ] = GAME_Q3;
3425 if ( stricmp( dirname, URT_PACK ) == 0 ) {
3426 m_availGames[ iGame++ ] = GAME_URT;
3428 if ( stricmp( dirname, UFOAI_PACK ) == 0 ) {
3429 m_availGames[ iGame++ ] = GAME_UFOAI;
3431 if ( stricmp( dirname, Q2W_PACK ) == 0 ) {
3432 m_availGames[ iGame++ ] = GAME_Q2W;
3434 if ( stricmp( dirname, WARSOW_PACK ) == 0 ) {
3435 m_availGames[ iGame++ ] = GAME_WARSOW;
3437 if ( stricmp( dirname, NEXUIZ_PACK ) == 0 ) {
3438 m_availGames[ iGame++ ] = GAME_NEXUIZ;
3440 if ( stricmp( dirname, Q2_PACK ) == 0 ) {
3441 m_availGames[ iGame++ ] = GAME_Q2;