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(const 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(const char *name, Str *pV, const 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(const 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(const 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(const 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(const 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(const 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()
921 // if we already have a document loaded, we will free and reload from file
922 if (mGlobalPrefs.InUse())
924 Sys_Printf("Reloading global prefs from file\n");
925 mGlobalPrefs.Clear();
928 // load global .pref file
929 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
930 strGlobalPref += "global.pref";
932 mGlobalPrefs.ReadXMLFile(strGlobalPref.GetBuffer());
934 mGlobalPrefs.GetPref("gamefile", &m_sGameFile, ""); // NOTE: there's no default, user HAS to select something
935 mGlobalPrefs.GetPref("autoload", &m_bAutoLoadGame, false);
936 mGlobalPrefs.GetPref("log console", &m_bLogConsole, false);
937 // in a very particular post-.pid startup
938 // we may have the console turned on and want to keep it that way
939 // so we use a latching system
940 if (m_bForceLogConsole)
942 m_bLogConsole = true;
943 Sys_Printf("console logging has been latched on, saving prefs\n");
945 m_bForceLogConsole = false;
948 // console logging: call Sys_LogConsole to check console logging status
949 // it is important that we would log console as early as possible to make it useful
952 if (mGlobalPrefs.mbEmpty)
954 Sys_Printf("Saving global.pref with default pref values\n");
959 void CGameDialog::SavePrefs()
961 // update the tree and save it
962 mGlobalPrefs.UpdatePrefTree();
964 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
965 strGlobalPref += "global.pref";
967 if ( !mGlobalPrefs.WriteXMLFile( strGlobalPref.GetBuffer() ) ) {
968 Sys_FPrintf(SYS_ERR, "Error occured while saving global prefs file '%s'\n", strGlobalPref.GetBuffer());
972 void CGameDialog::DoGameInstall() {
973 // make sure console logging is on whenever we enter the installation loop
974 g_PrefsDlg.mGamesDialog.m_bLogConsole = true;
979 void CGameDialog::DoGameDialog() {
980 // allow looping the game selection dialog with calls to the game configure dialog in between
981 while ( m_bDoGameInstall ) {
983 m_bDoGameInstall = false;
985 if ( DoModal() == IDCANCEL ) {
986 Error( "game selection dialog canceled, cannot continue" );
990 if ( m_bDoGameInstall ) {
993 // and we will loop to do another DoModal dialog
997 // unhook so we can use in other places
998 // we manually incref'ed it when creating, it won't be freed (destructor)
999 gtk_container_remove( GTK_CONTAINER( mTopBox ), GetGlobalFrame() );
1001 // we save the prefs file
1005 GtkWidget* CGameDialog::GetGlobalFrame()
1007 GtkWidget *vbox, *text, *combo, *check;
1009 if ( mFrame != NULL ) {
1013 mFrame = gtk_frame_new( NULL );
1014 gtk_container_set_border_width( GTK_CONTAINER( mFrame ), 5 );
1015 gtk_widget_show( mFrame );
1017 vbox = gtk_vbox_new( FALSE, 6 );
1018 gtk_widget_show( vbox );
1019 gtk_container_add( GTK_CONTAINER( mFrame ), vbox );
1020 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1022 text = gtk_label_new( "Select the game:" );
1023 gtk_widget_show( text );
1024 gtk_box_pack_start( GTK_BOX( vbox ), text, FALSE, FALSE, 0 );
1026 combo = gtk_combo_box_new_text();
1027 gtk_widget_show( combo );
1028 gtk_box_pack_start( GTK_BOX( vbox ), combo, FALSE, FALSE, 0 );
1029 AddDialogData( combo, &m_nComboSelect, DLG_COMBO_BOX_INT );
1030 mGameCombo = GTK_COMBO_BOX( combo );
1034 check = gtk_check_button_new_with_label( "Auto load selected game on startup" );
1035 gtk_widget_show(check);
1036 gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);
1037 AddDialogData (check, &m_bAutoLoadGame, DLG_CHECK_BOOL);
1039 text = gtk_label_new("(this frame is available in the prefs menu if you set auto-select)");
1040 gtk_widget_show(text);
1041 gtk_box_pack_start (GTK_BOX(vbox), text, FALSE, FALSE, 0);
1044 check = gtk_check_button_new_with_label( "Networked install - per-user settings" );
1045 gtk_widget_show( check );
1046 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1047 AddDialogData( check, &m_bNetRun, DLG_CHECK_BOOL );
1050 check = gtk_check_button_new_with_label( "Log the console to radiant.log" );
1051 gtk_widget_show( check );
1052 gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
1053 AddDialogData( check, &m_bLogConsole, DLG_CHECK_BOOL );
1055 // incref it so we can pass it around
1056 gtk_widget_ref( GTK_WIDGET( mFrame ) );
1061 void CGameDialog::UpdateData( bool retrieve ) {
1064 // use m_sGameFile to set m_nComboSelect
1065 list<CGameDescription *>::iterator iGame;
1067 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1069 if ((*iGame)->mGameFile == m_sGameFile)
1077 UpdateNetrun(false);
1080 Dialog::UpdateData(retrieve);
1083 // use m_nComboSelect to set m_sGameFile
1084 list<CGameDescription *>::iterator iGame = mGames.begin();
1086 for(i=0; i<m_nComboSelect; i++)
1090 m_sGameFile = (*iGame)->mGameFile;
1097 void CGameDialog::SInstallCallback( GtkWidget *widget, gpointer data ) {
1098 CGameDialog *d = static_cast< CGameDialog* >( data );
1099 d->m_bDoGameInstall = true;
1103 void CGameDialog::BuildDialog() {
1104 GtkWidget *dlg, *vbox1, *button, *setup_button;
1107 gtk_window_set_title( GTK_WINDOW( dlg ), "Select Game" );
1109 vbox1 = gtk_vbox_new( FALSE, 0 );
1110 gtk_widget_show( vbox1 );
1111 gtk_container_add( GTK_CONTAINER( dlg ), vbox1 );
1113 gtk_container_add( GTK_CONTAINER( vbox1 ), GetGlobalFrame() );
1116 setup_button = gtk_button_new_with_label( "Configure more games" );
1117 gtk_widget_show( setup_button );
1118 gtk_box_pack_start( GTK_BOX( vbox1 ), setup_button, FALSE, FALSE, 0 );
1119 gtk_signal_connect( GTK_OBJECT( setup_button ), "clicked",
1120 GTK_SIGNAL_FUNC( SInstallCallback ), this );
1122 button = gtk_button_new_with_label( "OK" );
1123 gtk_widget_show( button );
1124 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
1125 AddModalButton( button, IDOK );
1127 button = gtk_button_new_with_label( "Cancel" );
1128 gtk_widget_show( button );
1129 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
1130 AddModalButton( button, IDCANCEL );
1132 gtk_widget_set_usize( button, 60, -2 );
1135 void CGameDialog::UpdateGameCombo() {
1136 // fill in with the game descriptions
1137 list<CGameDescription *>::iterator iGame;
1139 if ( mGameCombo == NULL ) {
1140 Sys_Printf( "mGameCombo == NULL\n" );
1144 // clear whatever is in - wtf no way to know how many text entries?
1145 // use set/get active to track
1146 gtk_combo_box_set_active( mGameCombo, 0 );
1147 while ( gtk_combo_box_get_active( mGameCombo ) == 0 ) {
1148 gtk_combo_box_remove_text( mGameCombo, 0 );
1149 gtk_combo_box_set_active( mGameCombo, 0 );
1152 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ ) {
1153 gtk_combo_box_append_text( mGameCombo, (*iGame)->mGameName.GetBuffer() );
1155 gtk_combo_box_set_active( mGameCombo, 0 );
1158 void CGameDialog::ScanForGames()
1163 CString strGamesPath = g_strAppPath.GetBuffer();
1164 strGamesPath += "games";
1165 const char *path = strGamesPath.GetBuffer();
1167 if ( !mGames.empty() ) {
1168 Sys_Printf( "Clearing game list\n" );
1169 list<CGameDescription*>::iterator iGame;
1170 for ( iGame = mGames.begin(); iGame != mGames.end(); iGame++ ) {
1176 Sys_Printf( "Scanning for game description files: %s\n", path );
1180 do we put game description files below g_strAppPath, or in ~/.radiant
1181 i.e. read only or read/write?
1182 my guess .. readonly cause it's an install
1183 we will probably want to add ~/.radiant/<version>/games/ scanning on top of that for developers
1184 (if that's really needed)
1187 // FIXME need to catch the 'no game description' situation and exit with a clean error
1189 dir = g_dir_open(path, 0, NULL);
1195 const gchar* name = g_dir_read_name(dir);
1199 dirlist = g_strdup(name);
1203 char *ext = strrchr (dirlist, '.');
1204 if ((ext == NULL) || (strcmp (ext, ".game") != 0))
1206 strPath.Format("%s/%s", path, dirlist);
1207 Sys_Printf("%s\n", strPath.GetBuffer());
1209 xmlDocPtr pDoc = xmlParseFile(strPath.GetBuffer());
1212 mGames.push_front( new CGameDescription( pDoc, dirlist ) );
1216 Sys_FPrintf(SYS_ERR, "XML parser failed on '%s'\n", strPath.GetBuffer());
1224 // entries in the combo need to be updated
1228 CGameDescription* CGameDialog::GameDescriptionForComboItem()
1230 list<CGameDescription *>::iterator iGame;
1232 for( iGame = mGames.begin(); iGame != mGames.end(); iGame++,i++ ) {
1233 if ( i == m_nComboSelect ) {
1237 return NULL; // not found
1240 void CGameDialog::InitGlobalPrefPath()
1242 GString *global_rc_path;
1243 // configure m_global_rc_path
1244 // this is the g_strTempPath, and it has already been mkdir'ed
1245 global_rc_path = g_string_new(g_strTempPath.GetBuffer());
1246 g_PrefsDlg.m_global_rc_path = global_rc_path;
1249 void CGameDialog::Reset()
1251 if (!g_PrefsDlg.m_global_rc_path)
1252 InitGlobalPrefPath();
1253 CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;
1254 strGlobalPref += "global.pref";
1255 remove(strGlobalPref.GetBuffer());
1258 void CGameDialog::Init()
1260 InitGlobalPrefPath();
1262 if ( mGames.empty() ) {
1265 if ( mGames.empty() ) {
1266 Error( "No games setup, aborting\n" );
1270 if ( m_bAutoLoadGame ) {
1271 // search by .game name
1272 list<CGameDescription *>::iterator iGame;
1273 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1275 if ((*iGame)->mGameFile == m_sGameFile)
1277 m_pCurrentGameDescription = (*iGame);
1282 if ( !m_bAutoLoadGame || !m_pCurrentGameDescription ) {
1284 // use m_nComboSelect to identify the game to run as and set the globals
1285 m_pCurrentGameDescription = GameDescriptionForComboItem();
1286 if ( !m_pCurrentGameDescription ) {
1287 Error("Lookup of game description object failed, can't continue\n");
1290 g_pGameDescription = m_pCurrentGameDescription;
1292 g_strGameToolsPath = g_pGameDescription->mGameToolsPath;
1294 // NOTE TTimo: this is moved from QE_LoadProject in 1.2
1295 // (probably broken)
1296 // NOTE Hydra: was broken for win32, we don't use m_strHomeGame or m_strFSBasePath
1297 #if defined (__linux__) || defined (__APPLE__)
1298 g_qeglobals.m_strHomeGame = g_get_home_dir();
1299 g_qeglobals.m_strHomeGame += "/";
1300 g_qeglobals.m_strHomeGame += m_pCurrentGameDescription->mUserPathPrefix.GetBuffer();
1301 g_qeglobals.m_strHomeGame += "/";
1303 g_qeglobals.m_strHomeGame = g_pGameDescription->mEnginePath.GetBuffer();
1306 g_pGameDescription->Dump();
1309 CGameDialog::~CGameDialog()
1313 // NOTE I'm not too sure how reliable this is
1314 gtk_widget_unref(GTK_WIDGET(mFrame));
1316 // free all the game descriptions
1317 list<CGameDescription *>::iterator iGame;
1318 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1325 void CGameDialog::AddPacksURL(Str &URL)
1327 // add the URLs for the list of game packs installed
1328 // FIXME: this is kinda hardcoded for now..
1329 list<CGameDescription *>::iterator iGame;
1330 for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)
1332 if ((*iGame)->mGameFile == "q3.game")
1333 URL += "&Games_dlup%5B%5D=1";
1334 else if ((*iGame)->mGameFile == "wolf.game")
1335 URL += "&Games_dlup%5B%5D=2";
1336 else if ((*iGame)->mGameFile == "wolf.game")
1337 URL += "&Games_dlup%5B%5D=3";
1338 else if ((*iGame)->mGameFile == "jk2.game")
1339 URL += "&Games_dlup%5B%5D=4";
1340 else if ((*iGame)->mGameFile == "stvef.game")
1341 URL += "&Games_dlup%5B%5D=5";
1342 else if ((*iGame)->mGameFile == "sof2.game")
1343 URL += "&Games_dlup%5B%5D=6";
1344 else if ((*iGame)->mGameFile == "ja.game")
1345 URL += "&Games_dlup%5B%5D=7";
1351 #define NETRUN_FILENAME "netrun.conf"
1353 bool CGameDialog::m_bNetRun;
1355 void CGameDialog::UpdateNetrun(bool retrieve)
1359 strNetrun = g_strAppPath; strNetrun += NETRUN_FILENAME;
1362 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=639
1363 // now check if we are running from a network installation
1364 // use a dummy file as the flag
1365 f_netrun = fopen(strNetrun.GetBuffer(), "r");
1378 f_netrun = fopen(strNetrun.GetBuffer(), "w");
1381 Sys_FPrintf(SYS_ERR, "ERROR: Failed to create netrun file '%s'\n", strNetrun.GetBuffer());
1387 Sys_Printf("Created/Checked '%s'\n", strNetrun.GetBuffer());
1392 if (remove(strNetrun.GetBuffer()) == -1)
1394 if (errno != ENOENT)
1395 Sys_FPrintf(SYS_ERR, "Failed to remove netrun file '%s'\n", strNetrun.GetBuffer());
1400 Sys_Printf("Netrun mode is disabled\n");
1406 bool CGameDialog::GetNetrun()
1415 very first prefs init deals with selecting the game and the game tools path
1416 then we can load .ini stuff
1418 using prefs / ini settings:
1422 look in g_strGameToolsPath for .ini
1425 look in ~/.radiant/<version>/gamename
1429 #define PREFS_LOCAL_FILENAME "local.pref"
1431 void PrefsDlg::Init()
1433 mGamesDialog.Init();
1435 // m_global_rc_path has been set above, do m_rc_path with game specific stuff now
1436 // the win32 and linux versions have been unified for network mode
1438 if (!CGameDialog::GetNetrun())
1440 // legacy prefs settings, this goes where the game pack is installed
1441 m_rc_path = g_string_new (g_strGameToolsPath.GetBuffer() );
1442 m_inipath = g_string_new (m_rc_path->str);
1443 g_string_append (m_inipath, PREFS_LOCAL_FILENAME);
1447 // this is common to win32 and Linux init now
1448 m_rc_path = g_string_new (m_global_rc_path->str);
1451 g_string_append (m_rc_path, g_pGameDescription->mGameFile.GetBuffer());
1452 g_string_append (m_rc_path, "/");
1453 Q_mkdir (m_rc_path->str, 0775);
1455 // then the ini file
1456 m_inipath = g_string_new (m_rc_path->str);
1457 g_string_append (m_inipath, PREFS_LOCAL_FILENAME);
1461 void PrefsDlg::UpdateData (bool retrieve)
1463 // leo: the "changed" signal confuses the update function
1464 if (m_pWidget == NULL)
1466 mGamesDialog.UpdateData (retrieve);
1467 Dialog::UpdateData (retrieve);
1471 #define PREFSHSPACE 5
1473 #define PREFSHSPACE 0
1476 static void UpdateSensitivity( GtkWidget *widget, gpointer data )
1478 PrefsDlg *dlg = (PrefsDlg*)data;
1479 dlg->DoSensitivity();
1482 static void UpdateEditorSensitivity(GtkWidget *widget, gpointer data)
1484 PrefsDlg *dlg = (PrefsDlg*)data;
1485 dlg->DoEditorSensitivity();
1488 // start new prefs dialog
1490 /*! Utility function for swapping notebook pages for tree list selections */
1491 void PrefsDlg::showPrefPage(int prefpage)
1493 if(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) != prefpage)
1494 gtk_notebook_set_page(GTK_NOTEBOOK(notebook), prefpage);
1499 static void treeSelection(GtkTreeSelection* selection, gpointer data)
1501 PrefsDlg *dlg = (PrefsDlg*)data;
1503 GtkTreeModel* model;
1504 GtkTreeIter selected;
1505 if(gtk_tree_selection_get_selected(selection, &model, &selected))
1508 gtk_tree_model_get(model, &selected, 1, (gpointer*)&prefpage, -1);
1509 dlg->showPrefPage(prefpage);
1513 void PrefsDlg::BuildDialog ()
1515 // Main Preferences dialog
1516 GtkWidget *dialog, *mainvbox, *hbox, *sc_win, *preflabel;
1518 // Widgets on notebook pages
1519 GtkWidget *check, *label, *scale, *hbox2, *combo,
1520 *table, *spin, *entry, *pixmap,
1521 *radio, *button, *pageframe, *vbox;
1523 GList *combo_list = (GList*)NULL;
1528 gtk_window_set_title(GTK_WINDOW(dialog), "GtkRadiant Preferences");
1529 gtk_widget_realize(dialog);
1531 mainvbox = gtk_vbox_new(FALSE, 5);
1532 gtk_container_add(GTK_CONTAINER(dialog), mainvbox);
1533 gtk_container_set_border_width(GTK_CONTAINER(mainvbox), 5);
1534 gtk_widget_show(mainvbox);
1536 hbox = gtk_hbox_new(FALSE, 5);
1537 gtk_widget_show(hbox);
1538 gtk_box_pack_end(GTK_BOX(mainvbox), hbox, FALSE, TRUE, 0);
1540 button = gtk_button_new_with_label("OK");
1541 gtk_widget_show(button);
1542 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1543 gtk_widget_set_usize(button, 60, -2);
1544 AddModalButton(button, IDOK);
1546 button = gtk_button_new_with_label("Cancel");
1547 gtk_widget_show(button);
1548 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1549 gtk_widget_set_usize(button, 60, -2);
1550 AddModalButton(button, IDCANCEL);
1552 button = gtk_button_new_with_label ("Clean");
1553 gtk_widget_show(button);
1554 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(OnButtonClean), this);
1555 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1556 gtk_widget_set_usize (button, 60, -2);
1558 hbox = gtk_hbox_new(FALSE, 5);
1559 gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 0);
1560 gtk_widget_show(hbox);
1562 sc_win = gtk_scrolled_window_new(NULL, NULL);
1563 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1564 gtk_box_pack_start(GTK_BOX(hbox), sc_win, FALSE, FALSE, 0);
1565 gtk_widget_show(sc_win);
1567 // prefs pages notebook
1568 notebook = gtk_notebook_new();
1569 // hide the notebook tabs since its not supposed to look like a notebook
1570 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
1571 gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 0);
1572 gtk_widget_show(notebook);
1574 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_win), GTK_SHADOW_IN);
1577 GtkTreeStore* store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
1579 GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1580 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1583 GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1584 GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Preferences", renderer, "text", 0, NULL);
1585 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1589 GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1590 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(treeSelection), this);
1593 gtk_widget_show(view);
1595 gtk_container_add(GTK_CONTAINER (sc_win), view);
1598 /********************************************************************/
1599 /* Add preference tree options */
1600 /********************************************************************/
1603 gtk_tree_store_append(store, &group, NULL);
1604 gtk_tree_store_set(store, &group, 0, "Globals", 1, PTAB_FRONT, -1);
1607 gtk_tree_store_append(store, &tab, &group);
1608 gtk_tree_store_set(store, &tab, 0, "Game settings", 1, (gpointer)PTAB_GAME_SETTINGS, -1);
1614 gtk_tree_store_append(store, &group, NULL);
1615 gtk_tree_store_set(store, &group, 0, "Display", 1, PTAB_FRONT, -1);
1618 gtk_tree_store_append(store, &tab, &group);
1619 gtk_tree_store_set(store, &tab, 0, "2D Display/Rendering", 1, (gpointer)PTAB_2D, -1);
1623 gtk_tree_store_append(store, &tab, &group);
1624 gtk_tree_store_set(store, &tab, 0, "3D View", 1, (gpointer)PTAB_CAMERA, -1);
1628 gtk_tree_store_append(store, &tab, &group);
1629 gtk_tree_store_set(store, &tab, 0, "Texture Settings", 1, (gpointer)PTAB_TEXTURE, -1);
1635 gtk_tree_store_append(store, &group, NULL);
1636 gtk_tree_store_set(store, &group, 0, "Interface", 1, PTAB_FRONT, -1);
1639 gtk_tree_store_append(store, &tab, &group);
1640 gtk_tree_store_set(store, &tab, 0, "Layout", 1, (gpointer)PTAB_LAYOUT, -1);
1644 gtk_tree_store_append(store, &tab, &group);
1645 gtk_tree_store_set(store, &tab, 0, "Mouse", 1, (gpointer)PTAB_MOUSE, -1);
1649 gtk_tree_store_append(store, &tab, &group);
1650 gtk_tree_store_set(store, &tab, 0, "Editing", 1, (gpointer)PTAB_EDITING, -1);
1656 gtk_tree_store_append(store, &group, NULL);
1657 gtk_tree_store_set(store, &group, 0, "Other", 1, PTAB_FRONT, -1);
1660 gtk_tree_store_append(store, &tab, &group);
1661 gtk_tree_store_set(store, &tab, 0, "Startup/Auto save", 1, (gpointer)PTAB_STARTUP, -1);
1665 gtk_tree_store_append(store, &tab, &group);
1666 gtk_tree_store_set(store, &tab, 0, "Paths", 1, (gpointer)PTAB_PATHS, -1);
1670 gtk_tree_store_append(store, &tab, &group);
1671 gtk_tree_store_set(store, &tab, 0, "Misc", 1, (gpointer)PTAB_MISC, -1);
1673 if (!g_qeglobals.bBSPFrontendPlugin)
1676 gtk_tree_store_append(store, &tab, &group);
1677 gtk_tree_store_set(store, &tab, 0, "BSP Monitoring", 1, (gpointer)PTAB_BSPMONITOR, -1);
1682 gtk_tree_view_expand_all(GTK_TREE_VIEW(view));
1684 g_object_unref(G_OBJECT(store));
1687 /**********************************************************************/
1688 /* build the prefs pages */
1689 /**********************************************************************/
1692 // todo : add something interesting here
1693 // NOTE TTimo: tip of the day? or a logo?
1694 preflabel = gtk_label_new("Front Page");
1695 gtk_widget_show(preflabel);
1696 pageframe = gtk_frame_new(NULL);
1697 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1698 gtk_widget_show(pageframe);
1699 vbox = gtk_vbox_new(FALSE, 5);
1700 gtk_widget_show(vbox);
1701 gtk_widget_set_usize(GTK_WIDGET(vbox), 350, -2);
1702 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1703 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1705 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1707 /******** global preferences group ****************************/
1708 preflabel = gtk_label_new("Globals");
1709 gtk_widget_show(preflabel);
1711 pageframe = mGamesDialog.GetGlobalFrame();
1712 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1714 /******** 2D prefs group (xy views/rendering options) *********/
1715 preflabel = gtk_label_new("2D Display");
1716 gtk_widget_show(preflabel);
1717 pageframe = gtk_frame_new("2D Display");
1718 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1719 gtk_widget_show(pageframe);
1720 vbox = gtk_vbox_new(FALSE, 5);
1721 gtk_widget_show(vbox);
1722 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1723 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1725 // OpenGL Display Lists
1726 check = gtk_check_button_new_with_label("OpenGL Display Lists");
1727 gtk_widget_show(check);
1728 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1729 AddDialogData(check, &m_bDisplayLists, DLG_CHECK_BOOL);
1731 // Antialiased points & lines
1732 // Fishman - Add antialiazed points and lines support. 09/03/00
1733 check = gtk_check_button_new_with_label ("OpenGL antialiased points and lines");
1734 gtk_widget_show (check);
1735 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1736 AddDialogData (check, &m_bAntialiasedPointsAndLines, DLG_CHECK_BOOL);
1738 // Solid selection boxes
1739 check = gtk_check_button_new_with_label ("Solid selection boxes");
1740 gtk_widget_show (check);
1741 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1742 AddDialogData (check, &m_bNoStipple, DLG_CHECK_BOOL);
1744 // Display size info
1745 check = gtk_check_button_new_with_label ("Display size info");
1746 gtk_widget_show (check);
1747 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1748 AddDialogData (check, &m_bSizePaint, DLG_CHECK_BOOL);
1750 // Alternate vertex/edge handles
1751 // Gef: Kyro GL_POINT work around 25-aug-2001
1752 check = gtk_check_button_new_with_label ("Alternate vertex/edge handles");
1753 gtk_widget_show(check);
1754 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1755 AddDialogData(check, &m_bGlPtWorkaround, DLG_CHECK_BOOL);
1757 g_list_free (combo_list);
1761 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=812
1762 check = gtk_check_button_new_with_label ("ATI cards with broken drivers - bug #802");
1763 gtk_widget_show(check);
1764 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1765 AddDialogData(check, &m_bGlATIHack, DLG_CHECK_BOOL);
1768 // Add the page to the notebook
1769 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1771 /******** 3D Camera view group *********/
1772 preflabel = gtk_label_new("3D View");
1773 gtk_widget_show(preflabel);
1774 pageframe = gtk_frame_new("3D View");
1775 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1776 gtk_widget_show(pageframe);
1777 vbox = gtk_vbox_new(FALSE, 5);
1778 gtk_widget_show(vbox);
1779 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1780 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1782 // Directional velocity (Movement Velocity)
1784 hbox2 = gtk_hbox_new (FALSE, 0);
1785 gtk_widget_show (hbox2);
1786 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1789 label = gtk_label_new("Movement Velocity");
1790 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1791 gtk_widget_show(label);
1792 gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1795 adj = gtk_adjustment_new(100, 50, 300, 1, 10, 10);
1796 AddDialogData(adj, &m_nMoveSpeed, DLG_ADJ_INT);
1799 scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));
1800 gtk_widget_show(scale);
1801 gtk_box_pack_start(GTK_BOX (vbox), scale, FALSE, TRUE, 2);
1803 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
1805 // Angular velocity (Rotational Velocity)
1807 hbox2 = gtk_hbox_new (FALSE, 0);
1808 gtk_widget_show (hbox2);
1809 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1812 label = gtk_label_new ("Rotational Velocity");
1813 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1814 gtk_widget_show (label);
1815 gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
1818 adj = gtk_adjustment_new (3, 1, 180, 1, 10, 10); // value, low, high, step, page_step, page_size
1819 AddDialogData (adj, &m_nAngleSpeed, DLG_ADJ_INT);
1822 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1823 gtk_widget_show (scale);
1824 gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 2);
1825 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
1827 // Text under the velocity sliders
1829 hbox2 = gtk_hbox_new (FALSE, 0);
1830 gtk_widget_show (hbox2);
1831 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1834 label = gtk_label_new ("slow");
1835 gtk_widget_show (label);
1836 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1839 label = gtk_label_new ("fast");
1840 gtk_widget_show (label);
1841 gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1843 // Allow drag to select multiple faces/brushes
1845 table = gtk_table_new(2, 1, FALSE);
1846 gtk_widget_show(table);
1847 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1848 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1849 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1851 label = gtk_label_new ("Use paint-select in camera view:");
1852 gtk_widget_show (label);
1853 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1854 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
1855 (GtkAttachOptions) (0),
1856 (GtkAttachOptions) (0), 0, 0);
1859 combo_list = g_list_append (combo_list, (void *)"No");
1860 combo_list = g_list_append (combo_list, (void *)"Yes");
1861 combo_list = g_list_append (combo_list, (void *)"Yes (Classic Key Setup)");
1863 combo = gtk_combo_new ();
1864 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
1865 gtk_widget_show (combo);
1866 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
1867 (GtkAttachOptions) (GTK_FILL),
1868 (GtkAttachOptions) (0), 0, 0);
1869 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
1870 AddDialogData (combo, &m_nCamDragMultiSelect, DLG_COMBO_INT);
1872 // Freelook in Camera view
1873 check = gtk_check_button_new_with_label ("Freelook in Camera view");
1874 gtk_widget_show (check);
1875 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1876 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1877 AddDialogData (check, &m_bCamFreeLook, DLG_CHECK_BOOL);
1879 // Freelook in Camera view w/ forward & back strafing instead of up and down looking
1880 check = gtk_check_button_new_with_label ("Freelook strafes Forward and Back");
1881 gtk_widget_show (check);
1882 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1883 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1884 AddDialogData (check, &m_bCamFreeLookStrafe, DLG_CHECK_BOOL);
1886 // Invert mouse in freelook
1887 check = gtk_check_button_new_with_label ("Invert mouse in freelook");
1888 gtk_widget_show (check);
1889 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1890 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1891 AddDialogData (check, &m_bCamInverseMouse, DLG_CHECK_BOOL);
1893 // Discrete movement
1894 check = gtk_check_button_new_with_label ("Discrete movement");
1895 gtk_widget_show (check);
1896 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1897 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1898 AddDialogData (check, &m_bCamDiscrete, DLG_CHECK_BOOL);
1900 // Update XY views on camera move
1901 check = gtk_check_button_new_with_label ("Update XY views on camera move");
1902 gtk_widget_show (check);
1903 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1904 gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);
1905 AddDialogData (check, &m_bCamXYUpdate, DLG_CHECK_BOOL);
1907 // Add the page to the notebook
1908 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
1910 /******** Texture group *********/
1911 preflabel = gtk_label_new("Textures");
1912 gtk_widget_show(preflabel);
1913 pageframe = gtk_frame_new("Textures");
1914 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
1915 gtk_widget_show(pageframe);
1916 vbox = gtk_vbox_new(FALSE, 6);
1917 gtk_widget_show(vbox);
1918 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1919 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
1921 // Texture quality slider
1923 label = gtk_label_new ("Texture quality");
1924 gtk_widget_show (label);
1925 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
1926 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1927 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1930 adj = gtk_adjustment_new (0, 0, 4, 1, 1, 1);
1931 AddDialogData (adj, &m_nLatchedTextureQuality, DLG_ADJ_INT);
1934 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
1935 gtk_widget_show (scale);
1936 gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
1937 gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
1939 // text under the texture slider
1940 hbox2 = gtk_hbox_new (FALSE, 0);
1941 gtk_widget_show (hbox2);
1942 gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
1943 label = gtk_label_new ("low");
1944 gtk_widget_show (label);
1945 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1946 label = gtk_label_new ("high");
1947 gtk_widget_show (label);
1948 gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
1951 check = gtk_check_button_new_with_label ("Texture subsets");
1952 gtk_widget_show (check);
1953 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1954 AddDialogData (check, &m_bTextureWindow, DLG_CHECK_BOOL);
1956 // texture scrollbar
1957 check = gtk_check_button_new_with_label ("Texture scrollbar");
1958 gtk_widget_show (check);
1959 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
1960 AddDialogData (check, &m_bTextureScrollbar, DLG_CHECK_BOOL);
1962 // texture increment matches grid
1963 check = gtk_check_button_new_with_label ("Tex increment matches grid");
1964 gtk_widget_show (check);
1965 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
1966 AddDialogData (check, &m_bSnapTToGrid, DLG_CHECK_BOOL);
1969 // Texture compression choice label
1971 table = gtk_table_new(2, 1, FALSE);
1972 gtk_widget_show(table);
1973 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
1974 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1975 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1977 label = gtk_label_new ("Texture Compression (if available):");
1978 gtk_widget_show (label);
1979 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1980 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
1981 (GtkAttachOptions) (0),
1982 (GtkAttachOptions) (0), 0, 0);
1983 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1985 // Texture compression choice label
1987 // NONE will always be in pos 0
1988 combo_list = g_list_append (combo_list, (void *)"None");
1990 // if OpenGL compression is enabled it will always be
1992 if (g_qeglobals.m_bOpenGLCompressionSupported)
1994 combo_list = g_list_append (combo_list, (void *)"OpenGL ARB");
1997 // If S3 is enabled offer all 3 valid compression schemes in RGBA
1998 if (g_qeglobals.m_bS3CompressionSupported)
2000 combo_list = g_list_append (combo_list, (void *)"S3TC DXT1");
2001 combo_list = g_list_append (combo_list, (void *)"S3TC DXT3");
2002 combo_list = g_list_append (combo_list, (void *)"S3TC DXT5");
2005 combo = gtk_combo_new ();
2006 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2007 gtk_widget_show (combo);
2008 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
2009 (GtkAttachOptions) (GTK_FILL),
2010 (GtkAttachOptions) (0), 0, 0);
2011 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
2012 AddDialogData (combo, &m_nTextureCompressionFormat, DLG_COMBO_INT);
2013 g_list_free (combo_list);
2016 table = gtk_table_new(2, 1, FALSE);
2017 gtk_widget_show(table);
2018 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2019 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2020 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2024 label = gtk_label_new ("Startup Shaders:");
2025 gtk_widget_show (label);
2026 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
2027 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
2028 (GtkAttachOptions) (0),
2029 (GtkAttachOptions) (0), 0, 0);
2030 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2034 combo_list = g_list_append (combo_list, (void *)"None");
2035 if (g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game")
2036 combo_list = g_list_append (combo_list, (void *)"System");
2037 else if (g_pGameDescription->mGameFile == "sof2.game")
2038 combo_list = g_list_append (combo_list, (void *)"Tools");
2040 combo_list = g_list_append (combo_list, (void *)"Common");
2041 combo_list = g_list_append (combo_list, (void *)"All");
2042 combo = gtk_combo_new ();
2043 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2044 gtk_widget_show (combo);
2045 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
2046 (GtkAttachOptions) (GTK_FILL),
2047 (GtkAttachOptions) (0), 0, 0);
2048 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
2049 AddDialogData (combo, &m_nLatchedShader, DLG_COMBO_INT);
2050 g_list_free (combo_list);
2052 // Add the page to the notebook
2053 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2055 /******** Layout group *********/
2056 preflabel = gtk_label_new("Layout");
2057 gtk_widget_show(preflabel);
2058 pageframe = gtk_frame_new("Layout");
2059 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2060 gtk_widget_show(pageframe);
2061 vbox = gtk_vbox_new(FALSE, 5);
2062 gtk_widget_show(vbox);
2063 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2064 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2068 table = gtk_table_new (2, 4, FALSE);
2069 gtk_widget_show (table);
2070 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2071 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2072 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2075 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window1.bmp");
2076 gtk_widget_show (pixmap);
2077 gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 0, 1,
2078 (GtkAttachOptions) (0),
2079 (GtkAttachOptions) (0), 0, 0);
2082 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window2.bmp");
2083 gtk_widget_show (pixmap);
2084 gtk_table_attach (GTK_TABLE (table), pixmap, 1, 2, 0, 1,
2085 (GtkAttachOptions) (0),
2086 (GtkAttachOptions) (0), 0, 0);
2089 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window3.bmp");
2090 gtk_widget_show (pixmap);
2091 gtk_table_attach (GTK_TABLE (table), pixmap, 2, 3, 0, 1,
2092 (GtkAttachOptions) (0),
2093 (GtkAttachOptions) (0), 0, 0);
2096 pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window4.bmp");
2097 gtk_widget_show (pixmap);
2098 gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 0, 1,
2099 (GtkAttachOptions) (0),
2100 (GtkAttachOptions) (0), 0, 0);
2102 // view type 1 selector
2103 radio = gtk_radio_button_new (NULL);
2104 gtk_widget_show (radio);
2105 gtk_table_attach (GTK_TABLE (table), radio, 0, 1, 1, 2,
2106 (GtkAttachOptions) (0),
2107 (GtkAttachOptions) (0), 0, 0);
2109 // view type 2 selector
2110 radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2111 gtk_widget_show (radio);
2112 gtk_table_attach (GTK_TABLE (table), radio, 1, 2, 1, 2,
2113 (GtkAttachOptions) (0),
2114 (GtkAttachOptions) (0), 0, 0);
2116 // view type 3 selector
2117 radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2118 gtk_widget_show (radio);
2119 gtk_table_attach (GTK_TABLE (table), radio, 2, 3, 1, 2,
2120 (GtkAttachOptions) (0),
2121 (GtkAttachOptions) (0), 0, 0);
2123 // view type 4 selector
2124 radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));
2125 gtk_widget_show (radio);
2126 gtk_table_attach (GTK_TABLE (table), radio, 3, 4, 1, 2,
2127 (GtkAttachOptions) (0),
2128 (GtkAttachOptions) (0), 0, 0);
2129 AddDialogData (radio, &m_nLatchedView, DLG_RADIO_INT);
2131 // Floating Z window
2132 check = gtk_check_button_new_with_label ("Floating Z Window");
2133 gtk_widget_show (check);
2134 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2135 AddDialogData (check, &m_bLatchedFloatingZ, DLG_CHECK_BOOL);
2137 // show menu tear-off seperators
2138 check = gtk_check_button_new_with_label ("Detachable Menus");
2139 gtk_widget_show (check);
2140 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2141 AddDialogData (check, &m_bLatchedDetachableMenus, DLG_CHECK_BOOL);
2143 if (!g_pGameDescription->mNoPatch)
2145 // show patch toolbar
2146 check = gtk_check_button_new_with_label ("Patch Toolbar");
2147 gtk_widget_show (check);
2148 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2149 g_object_set_data (G_OBJECT (dialog), "check_patchtoolbar", check); // Allow to be disabled for Q1/Q2
2150 AddDialogData (check, &m_bLatchedPatchToolbar, DLG_CHECK_BOOL);
2154 check = gtk_check_button_new_with_label ("Wide Toolbar");
2155 gtk_widget_show (check);
2156 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2157 AddDialogData (check, &m_bLatchedWideToolbar, DLG_CHECK_BOOL);
2159 // use plugin toolbar
2160 check = gtk_check_button_new_with_label ("Plugin Toolbar");
2161 gtk_widget_show (check);
2162 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2163 AddDialogData (check, &m_bLatchedPluginToolbar, DLG_CHECK_BOOL);
2166 // win32 file dialog
2167 check = gtk_check_button_new_with_label ("Use win32 file load dialog");
2168 gtk_widget_show (check);
2169 // gtk_container_add (GTK_CONTAINER (vbox), check);
2170 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2171 AddDialogData (check, &m_bNativeGUI, DLG_CHECK_BOOL);
2173 // position on primary monitor
2174 check = gtk_check_button_new_with_label ("Start on Primary Monitor");
2175 gtk_widget_show (check);
2176 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2177 g_object_set_data (G_OBJECT (dialog), "check_startonprimary", check);
2178 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2179 AddDialogData (check, &m_bStartOnPrimMon, DLG_CHECK_BOOL);
2182 // Add the page to the notebook
2183 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2185 /******** Mouse group *********/
2186 preflabel = gtk_label_new("Mouse");
2187 gtk_widget_show(preflabel);
2188 pageframe = gtk_frame_new("Mouse");
2189 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2190 gtk_widget_show(pageframe);
2191 vbox = gtk_vbox_new(FALSE, 5);
2192 gtk_widget_show(vbox);
2193 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2194 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2198 hbox2 = gtk_hbox_new (FALSE, 5);
2199 gtk_widget_show (hbox2);
2200 gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2203 radio = gtk_radio_button_new_with_label (NULL, "2 button");
2204 gtk_widget_show (radio);
2205 gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);
2208 radio = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio), "3 button");
2209 gtk_widget_show (radio);
2210 gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);
2211 AddDialogData (radio, &m_nMouse, DLG_RADIO_INT);
2213 // right click to drop entity
2214 check = gtk_check_button_new_with_label ("Right click to drop entities");
2215 gtk_widget_show (check);
2216 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2217 AddDialogData (check, &m_bRightClick, DLG_CHECK_BOOL);
2219 // Mouse chaser (and this does what?)
2220 check = gtk_check_button_new_with_label ("Mouse chaser");
2221 gtk_widget_show (check);
2222 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2223 AddDialogData (check, &m_bChaseMouse, DLG_CHECK_BOOL);
2226 check = gtk_check_button_new_with_label ("ALT + multi-drag");
2227 gtk_widget_show (check);
2228 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2229 AddDialogData (check, &m_bALTEdge, DLG_CHECK_BOOL);
2231 // Mouse wheel increments
2233 hbox2 = gtk_hbox_new (FALSE, 5);
2234 gtk_widget_show (hbox2);
2235 gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2238 label = gtk_label_new ("Wheel Mouse inc:");
2239 gtk_widget_show (label);
2240 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
2243 entry = gtk_entry_new ();
2244 gtk_widget_show (entry);
2245 gtk_widget_set_usize (entry, 40, -2);
2246 gtk_box_pack_start (GTK_BOX (hbox2), entry, FALSE, FALSE, 0);
2247 AddDialogData (entry, &m_nWheelInc, DLG_ENTRY_INT);
2249 // Add the page to the notebook
2250 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2252 /******** Editing group *********/
2253 preflabel = gtk_label_new("Editing");
2254 gtk_widget_show(preflabel);
2255 pageframe = gtk_frame_new("Editing");
2256 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2257 gtk_widget_show(pageframe);
2258 vbox = gtk_vbox_new(FALSE, 5);
2259 gtk_widget_show(vbox);
2260 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2261 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2263 // Vertex editing splits faces
2264 check = gtk_check_button_new_with_label ("Vertex editing splits face");
2265 gtk_widget_show (check);
2266 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2267 AddDialogData (check, &m_bVertexSplit, DLG_CHECK_BOOL);
2269 // Fix target/targetname collisions
2270 check = gtk_check_button_new_with_label ("Fix target/targetname collisions");
2271 gtk_widget_show (check);
2272 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2273 AddDialogData (check, &m_bDoTargetFix, DLG_CHECK_BOOL);
2275 // Clipper tool uses caulk
2276 check = gtk_check_button_new_with_label ("Clipper tool uses caulk");
2277 gtk_widget_show (check);
2278 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2279 AddDialogData (check, &m_bClipCaulk, DLG_CHECK_BOOL);
2281 // Don't clamp plane points
2282 check = gtk_check_button_new_with_label ("Don't clamp plane points");
2283 gtk_widget_show (check);
2284 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
2285 AddDialogData (check, &m_bNoClamp, DLG_CHECK_BOOL);
2287 // Select patch by bounding box
2288 check = gtk_check_button_new_with_label ("Select patches by bounding box");
2289 gtk_widget_show (check);
2290 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2291 AddDialogData (check, &m_bPatchBBoxSelect, DLG_CHECK_BOOL);
2293 // Rotation increment
2295 table = gtk_table_new (2, 3, FALSE);
2296 gtk_widget_show (table);
2297 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2298 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2299 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2302 label = gtk_label_new ("Rotation increment:");
2303 gtk_widget_show (label);
2304 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2305 (GtkAttachOptions) (0),
2306 (GtkAttachOptions) (0), 0, 0);
2309 entry = gtk_entry_new ();
2310 gtk_widget_show (entry);
2311 gtk_widget_set_usize (entry, 60, -2);
2312 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2313 (GtkAttachOptions) (GTK_FILL),
2314 (GtkAttachOptions) (0), 0, 0);
2315 AddDialogData (entry, &m_nRotation, DLG_ENTRY_INT);
2319 label = gtk_label_new ("Undo Levels:");
2320 gtk_widget_show (label);
2321 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2322 (GtkAttachOptions) (0),
2323 (GtkAttachOptions) (0), 0, 0);
2325 // spinner (allows undo levels to be set to zero)
2326 spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 0, 64, 1, 10, 10)), 1, 0);
2327 gtk_widget_show (spin);
2328 gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,
2329 (GtkAttachOptions) (GTK_FILL),
2330 (GtkAttachOptions) (0), 0, 0);
2331 gtk_widget_set_usize (spin, 60, -2);
2332 AddDialogData (spin, &m_nUndoLevels, DLG_SPIN_INT);
2334 // Patch subdivisions
2336 label = gtk_label_new ("Patch subdivisions:");
2337 gtk_widget_show (label);
2338 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
2339 (GtkAttachOptions) (0),
2340 (GtkAttachOptions) (0), 0, 0);
2342 // entry (spinner perhaps? [2-16])
2343 entry = gtk_entry_new ();
2344 gtk_widget_show (entry);
2345 gtk_widget_set_usize (entry, 60, -2);
2346 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3,
2347 (GtkAttachOptions) (GTK_FILL),
2348 (GtkAttachOptions) (0), 0, 0);
2349 AddDialogData (entry, &m_nSubdivisions, DLG_ENTRY_INT);
2351 // Add the page to the notebook
2352 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2354 /******** Save/Load group *********/
2355 preflabel = gtk_label_new("Startup/Auto save");
2356 gtk_widget_show(preflabel);
2357 pageframe = gtk_frame_new("Startup/Auto save");
2358 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2359 gtk_widget_show(pageframe);
2360 vbox = gtk_vbox_new(FALSE, 5);
2361 gtk_widget_show(vbox);
2362 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2363 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2366 check = gtk_check_button_new_with_label ("Snapshots");
2367 gtk_widget_show (check);
2368 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2369 AddDialogData (check, &m_bSnapShots, DLG_CHECK_BOOL);
2371 // load last project on open
2372 check = gtk_check_button_new_with_label ("Load last project on open");
2373 gtk_widget_show (check);
2374 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2375 AddDialogData (check, &m_bLoadLast, DLG_CHECK_BOOL);
2377 // load last map on open
2378 check = gtk_check_button_new_with_label ("Load last map on open");
2379 gtk_widget_show (check);
2380 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2381 AddDialogData (check, &m_bLoadLastMap, DLG_CHECK_BOOL);
2385 hbox2 = gtk_hbox_new (FALSE, 5);
2386 gtk_widget_show (hbox2);
2387 gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);
2388 gtk_container_set_border_width (GTK_CONTAINER (hbox2), 0);
2391 check = gtk_check_button_new_with_label ("Auto save every");
2392 gtk_widget_show (check);
2393 gtk_box_pack_start (GTK_BOX (hbox2), check, FALSE, FALSE, 0);
2394 AddDialogData (check, &m_bAutoSave, DLG_CHECK_BOOL);
2397 spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 60, 1, 10, 10)), 1, 0);
2398 gtk_widget_show (spin);
2399 gtk_box_pack_start (GTK_BOX (hbox2), spin, FALSE, FALSE, 0);
2400 gtk_widget_set_usize (spin, 60, -2);
2401 AddDialogData (spin, &m_nAutoSave, DLG_SPIN_INT);
2404 label = gtk_label_new ("minutes");
2405 gtk_widget_show (label);
2406 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
2408 // Add the page to the notebook
2409 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2411 /******** Paths group *********/
2412 preflabel = gtk_label_new("Paths");
2413 gtk_widget_show(preflabel);
2414 pageframe = gtk_frame_new("Paths");
2415 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2416 gtk_widget_show(pageframe);
2417 vbox = gtk_vbox_new(FALSE, 5);
2418 gtk_widget_show(vbox);
2419 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2420 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2424 table = gtk_table_new (3, 3, FALSE);
2425 gtk_widget_show (table);
2426 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2427 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2428 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2431 label = gtk_label_new ("Prefab path:");
2432 gtk_widget_show (label);
2433 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2434 (GtkAttachOptions) (0),
2435 (GtkAttachOptions) (0), 0, 0);
2436 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2439 entry = gtk_entry_new ();
2440 gtk_widget_show (entry);
2441 gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);
2442 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2443 (GtkAttachOptions) (GTK_FILL),
2444 (GtkAttachOptions) (0), 1, 0);
2445 AddDialogData (entry, &m_strPrefabPath, DLG_ENTRY_TEXT);
2447 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=805
2450 button = gtk_button_new_with_label ("...");
2451 gtk_widget_show (button);
2452 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseprefab), this);
2453 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
2454 (GtkAttachOptions) (0),
2455 (GtkAttachOptions) (0), 0, 0);
2460 label = gtk_label_new ("User INI path:");
2461 gtk_widget_show (label);
2462 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2463 (GtkAttachOptions) (0),
2464 (GtkAttachOptions) (0), 0, 0);
2465 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2467 // user ini path entry
2468 entry = gtk_entry_new ();
2469 gtk_widget_show (entry);
2470 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
2471 (GtkAttachOptions) (GTK_FILL),
2472 (GtkAttachOptions) (0), 1, 0);
2473 AddDialogData (entry, &m_strUserPath, DLG_ENTRY_TEXT);
2475 // user ini browse button
2476 button = gtk_button_new_with_label ("...");
2477 gtk_widget_show (button);
2478 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseuserini), this);
2479 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,
2480 (GtkAttachOptions) (0),
2481 (GtkAttachOptions) (0), 0, 0);
2483 // Add the page to the notebook
2484 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2486 /******** Misc group *********/
2487 preflabel = gtk_label_new("Misc");
2488 gtk_widget_show(preflabel);
2489 pageframe = gtk_frame_new("Misc");
2490 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2491 gtk_widget_show(pageframe);
2492 vbox = gtk_vbox_new(FALSE, 5);
2493 gtk_widget_show(vbox);
2494 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2495 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2498 check = gtk_check_button_new_with_label ("Light drawing");
2499 gtk_widget_show (check);
2500 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2501 AddDialogData (check, &m_bNewLightDraw, DLG_CHECK_BOOL);
2505 table = gtk_table_new(2, 1, FALSE);
2506 gtk_widget_show(table);
2507 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2508 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2509 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2511 label = gtk_label_new ("Light radiuses:");
2512 gtk_widget_show (label);
2513 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2514 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
2515 (GtkAttachOptions) (0),
2516 (GtkAttachOptions) (0), 0, 0);
2519 combo_list = g_list_append (combo_list, (void *)"Disabled");
2520 combo_list = g_list_append (combo_list, (void *)"True Q3Map2 Style");
2521 combo_list = g_list_append (combo_list, (void *)"Classic Style");
2523 combo = gtk_combo_new ();
2524 gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2525 gtk_widget_show (combo);
2526 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,
2527 (GtkAttachOptions) (GTK_FILL),
2528 (GtkAttachOptions) (0), 0, 0);
2529 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);
2530 AddDialogData (combo, &m_nLightRadiuses, DLG_COMBO_INT);
2533 check = gtk_check_button_new_with_label ("Use win32 file associations to open text files instead of builtin editor");
2534 gtk_widget_show(check);
2535 gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);
2536 AddDialogData (check, &g_PrefsDlg.m_bUseWin32Editor, DLG_CHECK_BOOL);
2538 // use custom shader editor
2539 check = gtk_check_button_new_with_label ("Use Custom Shader Editor");
2540 gtk_widget_show(check);
2541 gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);
2542 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateEditorSensitivity), this);
2543 g_object_set_data (G_OBJECT(dialog), "check_customeditor", check);
2544 AddDialogData (check, &g_PrefsDlg.m_bUseCustomEditor, DLG_CHECK_BOOL);
2546 // custom shader editor executable
2548 table = gtk_table_new (3, 1, FALSE);
2549 gtk_widget_show (table);
2550 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
2551 gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2552 gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2555 label = gtk_label_new("Custom Editor Command");
2556 gtk_widget_show(label);
2557 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2558 (GtkAttachOptions) (0),
2559 (GtkAttachOptions) (0), 0, 0);
2560 gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2561 g_object_set_data (G_OBJECT(dialog), "label_customeditor", label);
2562 gtk_widget_set_sensitive (label, g_PrefsDlg.m_bUseCustomEditor);
2564 // custom editor command entry
2565 entry = gtk_entry_new ();
2566 gtk_widget_show (entry);
2567 gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);
2568 gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
2569 (GtkAttachOptions) (GTK_FILL),
2570 (GtkAttachOptions) (0), 1, 0);
2571 AddDialogData (entry, &m_strEditorCommand, DLG_ENTRY_TEXT);
2572 gtk_widget_set_sensitive (entry, g_PrefsDlg.m_bUseCustomEditor);
2573 g_object_set_data (G_OBJECT(dialog), "entry_customeditor", entry);
2576 button = gtk_button_new_with_label ("...");
2577 gtk_widget_show (button);
2578 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseEditor), this);
2579 gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,
2580 (GtkAttachOptions) (0),
2581 (GtkAttachOptions) (0), 0, 0);
2582 g_object_set_data (G_OBJECT(dialog), "button_customeditor", button);
2583 gtk_widget_set_sensitive (button, g_PrefsDlg.m_bUseCustomEditor);
2586 // Add the page to the notebook
2587 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2589 /******** BSP Monitoring group *********/
2590 // this is never displayed if the plugin isn't available
2591 preflabel = gtk_label_new("BSP Monitoring");
2592 gtk_widget_show(preflabel);
2593 pageframe = gtk_frame_new("BSP Monitoring");
2594 gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);
2595 gtk_widget_show(pageframe);
2596 vbox = gtk_vbox_new(FALSE, 5);
2597 gtk_widget_show(vbox);
2598 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2599 gtk_container_add(GTK_CONTAINER(pageframe), vbox);
2601 // Enable BSP process monitoring
2602 check = gtk_check_button_new_with_label ("Enable BSP process monitoring");
2603 gtk_widget_show (check);
2604 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2605 g_object_set_data (G_OBJECT (dialog), "check_monitorbsp", check);
2606 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2607 AddDialogData (check, &g_PrefsDlg.m_bWatchBSP, DLG_CHECK_BOOL);
2610 check = gtk_check_button_new_with_label ("Stop compilation on leak");
2611 gtk_widget_show (check);
2612 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2613 g_object_set_data (G_OBJECT (dialog), "check_leakstop", check);
2614 AddDialogData (check, &g_PrefsDlg.m_bLeakStop, DLG_CHECK_BOOL);
2616 // engine after compile
2617 check = gtk_check_button_new_with_label ("Run engine after compile");
2618 gtk_widget_show (check);
2619 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2620 g_object_set_data (G_OBJECT (dialog), "check_runengine", check);
2621 gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );
2622 AddDialogData( check, &g_PrefsDlg.m_bRunQuake, DLG_CHECK_BOOL );
2624 // sleep mode when running engine
2625 check = gtk_check_button_new_with_label ("Activate sleep mode when running the engine");
2626 gtk_widget_show (check);
2627 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2628 g_object_set_data (G_OBJECT (dialog), "check_sleep", check);
2629 AddDialogData( check, &g_PrefsDlg.m_bDoSleep, DLG_CHECK_BOOL );
2631 // use q3map2's texture projection
2632 check = gtk_check_button_new_with_label ("Texturing compatible with q3map2");
2633 gtk_widget_show (check);
2634 gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
2635 g_object_set_data (G_OBJECT (dialog), "check_q3map2", check);
2636 AddDialogData( check, &g_PrefsDlg.m_bQ3Map2Texturing, DLG_CHECK_BOOL );
2638 // Add the page to the notebook
2639 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);
2641 gtk_notebook_set_page(GTK_NOTEBOOK(notebook), PTAB_FRONT);
2646 // end new prefs dialog
2648 void PrefsDlg::LoadTexdefPref(texdef_t* pTexdef, char* pName)
2652 memset(pTexdef, 0, sizeof(texdef_t));
2654 sprintf(buffer, "%s%s", pName, TD_SCALE1_KEY);
2655 mLocalPrefs.GetPref(buffer, &pTexdef->scale[0], 0.5f);
2657 sprintf(buffer, "%s%s", pName, TD_SCALE2_KEY);
2658 mLocalPrefs.GetPref(buffer, &pTexdef->scale[1], 0.5f);
2660 sprintf(buffer, "%s%s", pName, TD_SHIFT1_KEY);
2661 mLocalPrefs.GetPref(buffer, &pTexdef->shift[0], 8.f);
2663 sprintf(buffer, "%s%s", pName, TD_SHIFT2_KEY);
2664 mLocalPrefs.GetPref(buffer, &pTexdef->shift[1], 8.f);
2666 sprintf(buffer, "%s%s", pName, TD_ROTATE_KEY);
2667 mLocalPrefs.GetPref(buffer, &pTexdef->rotate, 45);
2670 void PrefsDlg::UpdateTextureCompression()
2672 // if OpenGL is not ready yet, don't do anything
2673 if (!g_qeglobals.m_bOpenGLReady) {
2674 Sys_Printf("OpenGL not ready - postpone texture compression capability check\n");
2678 if (g_qeglobals.bTextureCompressionSupported)
2680 if (m_nTextureCompressionFormat >= 2 && !g_qeglobals.m_bS3CompressionSupported)
2682 Sys_Printf("Inconsistant pref setting for texture compression (%d), rolling back\n", m_nTextureCompressionFormat);
2683 m_nTextureCompressionFormat = 1; // if this is not supported either, see below
2685 if (m_nTextureCompressionFormat == 1 && !g_qeglobals.m_bOpenGLCompressionSupported)
2687 Sys_Printf("Inconsistant pref setting for texture compression (GL_COMPRESSED_RGBA), rolling back\n");
2688 m_nTextureCompressionFormat = 0;
2690 switch (m_nTextureCompressionFormat)
2694 g_qeglobals.texture_components = GL_RGBA;
2695 Sys_Printf("texture compression disabled by preferences settings\n");
2700 g_qeglobals.texture_components = GL_COMPRESSED_RGBA;
2701 Sys_Printf("OpenGL texture compression enabled\n");
2706 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
2707 Sys_Printf("S3TC DXT1 texture compression enabled\n");
2712 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
2713 Sys_Printf("S3TC DXT3 texture compression enabled\n");
2718 g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
2719 Sys_Printf("S3TC DXT5 texture compression enabled\n");
2726 Sys_Printf("texture compression is not supported by your current graphic card/drivers\n");
2727 g_qeglobals.texture_components = GL_RGBA;
2728 m_nTextureCompressionFormat = 0;
2733 void PrefsDlg::UpdateATIHack() {
2734 // if OpenGL is not ready yet, don't do anything
2735 if (!g_qeglobals.m_bOpenGLReady) {
2736 Sys_Printf("OpenGL not ready - postpone ATI bug workaround setup\n");
2741 qglCullFace = &qglCullFace_ATIHack;
2742 qglDisable = &qglDisable_ATIHack;
2743 qglEnable = &qglEnable_ATIHack;
2744 qglPolygonMode = &qglPolygonMode_ATIHack;
2745 Sys_Printf("ATI bug workaround enabled\n");
2747 qglCullFace = qglCullFace_real;
2748 qglDisable = qglDisable_real;
2749 qglEnable = qglEnable_real;
2750 qglPolygonMode = qglPolygonMode_real;
2751 Sys_Printf("ATI bug workaround disabled\n");
2756 // TTimo: m_strEnginePath has a special status, if not found in registry we need to
2757 // initiliaze it for sure. It is not totally failsafe but we can use the same
2758 // code than in q3map, expecting to find some "quake" above us. If not, we prompt
2759 // for the engine executable path
2760 void PrefsDlg::LoadPrefs ()
2764 // first things first, load prefs from global prefs
2765 mGamesDialog.LoadPrefs();
2767 // if we already have a document loaded, we will free and reload from file
2768 if (mLocalPrefs.InUse()) {
2769 mLocalPrefs.Clear();
2772 // load local.pref file
2773 mLocalPrefs.ReadXMLFile(m_inipath->str);
2775 mLocalPrefs.GetPref(PATCHSHOWBOUNDS_KEY, &g_bPatchShowBounds, FALSE);
2776 mLocalPrefs.GetPref(MOUSE_KEY, &m_nMouse, MOUSE_DEF);
2777 m_nMouseButtons = m_nMouse ? 3 : 2;
2780 // if it's not found here, mainframe.cpp will take care of finding one
2781 mLocalPrefs.GetPref(LASTPROJ_KEY, &m_strLastProject, "");
2782 mLocalPrefs.GetPref(LASTPROJVER_KEY, &m_nLastProjectVer, -1);
2785 // NOTE TTimo: I'm not sure why this is in prefs
2786 // should probably be a project setting
2787 // and I'm not sure that we really have a way to set this reliably either
2789 strPrefab = g_qeglobals.m_strHomeGame.GetBuffer();
2790 strPrefab += g_pGameDescription->mBaseGame.GetBuffer();
2791 strPrefab += "/prefabs/";
2792 mLocalPrefs.GetPref(PREFAB_KEY, &m_strPrefabPath, strPrefab);
2794 mLocalPrefs.GetPref(LASTLIGHTINTENSITY_KEY, &m_iLastLightIntensity, 300);
2795 mLocalPrefs.GetPref(TLOCK_KEY, &m_bTextureLock, TLOCK_DEF);
2796 mLocalPrefs.GetPref(RLOCK_KEY, &m_bRotateLock, TLOCK_DEF);
2797 mLocalPrefs.GetPref(LASTMAP_KEY, &m_strLastMap, "");
2798 mLocalPrefs.GetPref(LOADLAST_KEY, &m_bLoadLast, LOADLAST_DEF);
2799 mLocalPrefs.GetPref(BSP_KEY, &m_bInternalBSP, FALSE);
2800 mLocalPrefs.GetPref(RCLICK_KEY, &m_bRightClick, TRUE);
2801 mLocalPrefs.GetPref(AUTOSAVE_KEY, &m_bAutoSave, TRUE);
2802 mLocalPrefs.GetPref(LOADLASTMAP_KEY, &m_bLoadLastMap, FALSE);
2803 mLocalPrefs.GetPref(TINYBRUSH_KEY, &m_bCleanTiny, FALSE);
2804 mLocalPrefs.GetPref(TINYSIZE_KEY, &m_fTinySize, 0.5f);
2805 mLocalPrefs.GetPref(AUTOSAVETIME_KEY, &m_nAutoSave, 5);
2806 mLocalPrefs.GetPref(SNAPSHOT_KEY, &m_bSnapShots, FALSE);
2807 mLocalPrefs.GetPref(MOVESPEED_KEY, &m_nMoveSpeed, 100);
2808 mLocalPrefs.GetPref(ANGLESPEED_KEY, &m_nAngleSpeed, 3);
2809 mLocalPrefs.GetPref(SETGAME_KEY, &m_bSetGame, FALSE);
2810 mLocalPrefs.GetPref(CAMXYUPDATE_KEY, &m_bCamXYUpdate, TRUE);
2811 mLocalPrefs.GetPref(CAMDRAGMULTISELECT_KEY, &m_nCamDragMultiSelect, TRUE);
2812 mLocalPrefs.GetPref(CAMFREELOOK_KEY, &m_bCamFreeLook, TRUE);
2813 mLocalPrefs.GetPref(CAMINVERSEMOUSE_KEY, &m_bCamInverseMouse, FALSE);
2814 mLocalPrefs.GetPref(CAMDISCRETE_KEY, &m_bCamDiscrete, TRUE);
2815 mLocalPrefs.GetPref(LIGHTDRAW_KEY, &m_bNewLightDraw, TRUE);
2816 mLocalPrefs.GetPref(CUBICCLIP_KEY, &m_bCubicClipping, TRUE);
2817 mLocalPrefs.GetPref(CUBICSCALE_KEY, &m_nCubicScale, 13);
2818 mLocalPrefs.GetPref(ALTEDGE_KEY, &m_bALTEdge, FALSE);
2819 mLocalPrefs.GetPref(FACECOLORS_KEY, &m_bFaceColors, FALSE);
2820 mLocalPrefs.GetPref(XZVIS_KEY, &m_bXZVis, FALSE);
2821 mLocalPrefs.GetPref(YZVIS_KEY, &m_bYZVis, FALSE);
2822 mLocalPrefs.GetPref(ZVIS_KEY, &m_bZVis, FALSE);
2823 mLocalPrefs.GetPref(SIZEPAINT_KEY, &m_bSizePaint, FALSE);
2824 mLocalPrefs.GetPref(DLLENTITIES_KEY, &m_bDLLEntities, FALSE);
2826 mLocalPrefs.GetPref(DETACHABLEMENUS_KEY, &m_bLatchedDetachableMenus, TRUE);
2827 m_bDetachableMenus = m_bLatchedDetachableMenus;
2829 if (g_pGameDescription->mNoPatch)
2831 m_bPatchToolbar = false;
2835 mLocalPrefs.GetPref(PATCHTOOLBAR_KEY, &m_bLatchedPatchToolbar, TRUE);
2836 m_bPatchToolbar = m_bLatchedPatchToolbar;
2839 mLocalPrefs.GetPref(WIDETOOLBAR_KEY, &m_bLatchedWideToolbar, TRUE);
2840 m_bWideToolbar = m_bLatchedWideToolbar;
2842 mLocalPrefs.GetPref(PLUGINTOOLBAR_KEY, &m_bLatchedPluginToolbar, TRUE);
2843 m_bPluginToolbar = m_bLatchedPluginToolbar;
2845 mLocalPrefs.GetPref(WINDOW_KEY, (int*)&m_nLatchedView, WINDOW_DEF);
2846 m_nView = m_nLatchedView;
2848 mLocalPrefs.GetPref(FLOATINGZ_KEY, &m_bLatchedFloatingZ, FALSE);
2849 m_bFloatingZ = m_bLatchedFloatingZ;
2851 mLocalPrefs.GetPref(TEXTUREQUALITY_KEY, &m_nLatchedTextureQuality, 3);
2852 m_nTextureQuality = m_nLatchedTextureQuality;
2854 mLocalPrefs.GetPref(LOADSHADERS_KEY, &m_nLatchedShader, 0);
2855 m_nShader = m_nLatchedShader;
2857 mLocalPrefs.GetPref(NOCLAMP_KEY, &m_bNoClamp, FALSE);
2858 mLocalPrefs.GetPref(USERINI_KEY, &m_strUserPath, "");
2859 mLocalPrefs.GetPref(ROTATION_KEY, &m_nRotation, 45);
2860 mLocalPrefs.GetPref(CHASEMOUSE_KEY, &m_bChaseMouse, TRUE);
2861 mLocalPrefs.GetPref(ENTITYSHOW_KEY, &m_nEntityShowState, ENTITY_SKINNED_BOXED);
2863 // this will probably need to be 75 or 100 for Q1.
2864 mLocalPrefs.GetPref(TEXTURESCALE_KEY, &m_nTextureScale, 50);
2866 // FIXME: Hydra - actually, this stuff is Q1,Q2 and HL specific.
2867 if ( (g_pGameDescription->mGameFile == "hl.game") )
2869 // No BSP monitoring in the default compiler tools for Half-life (yet)
2870 mLocalPrefs.GetPref(WATCHBSP_KEY, &m_bWatchBSP, FALSE);
2872 // Texture subset on by default (HL specific really, because of halflife.wad's size)
2873 mLocalPrefs.GetPref(TEXTURE_KEY, &m_bTextureWindow, TRUE);
2875 else if ( ( g_pGameDescription->mGameFile == "q2.game" ) || ( g_pGameDescription->mGameFile == "heretic2.game" ) )
2877 // BSP monitoring is implemented in Quake2 and Heretic2 tools
2878 mLocalPrefs.GetPref(WATCHBSP_KEY, &m_bWatchBSP, TRUE);
2880 // Texture subset on by default (HL specific really, because of halflife.wad's size)
2881 mLocalPrefs.GetPref(TEXTURE_KEY, &m_bTextureWindow, TRUE);
2885 mLocalPrefs.GetPref(WATCHBSP_KEY, &m_bWatchBSP, WATCHBSP_DEF);
2886 mLocalPrefs.GetPref(TEXTURE_KEY, &m_bTextureWindow, FALSE);
2890 mLocalPrefs.GetPref(TEXTURESCROLLBAR_KEY, &m_bTextureScrollbar, TRUE);
2891 mLocalPrefs.GetPref(DISPLAYLISTS_KEY, &m_bDisplayLists, TRUE);
2892 mLocalPrefs.GetPref(ANTIALIASEDLINES_KEY, &m_bAntialiasedPointsAndLines, FALSE);
2893 mLocalPrefs.GetPref(SWITCHCLIP_KEY, &m_bSwitchClip, TRUE);
2894 mLocalPrefs.GetPref(SELWHOLEENTS_KEY, &m_bSelectWholeEntities, TRUE);
2895 mLocalPrefs.GetPref(SHOWSHADERS_KEY, &m_bShowShaders, TRUE);
2896 mLocalPrefs.GetPref(GLLIGHTING_KEY, &m_bGLLighting, FALSE);
2897 mLocalPrefs.GetPref(NOSTIPPLE_KEY, &m_bNoStipple, FALSE);
2898 mLocalPrefs.GetPref(UNDOLEVELS_KEY, &m_nUndoLevels, 30);
2899 mLocalPrefs.GetPref(VERTEXMODE_KEY, &m_bVertexSplit, TRUE);
2900 mLocalPrefs.GetPref(RUNQ2_KEY, &m_bRunQuake, RUNQ2_DEF);
2901 mLocalPrefs.GetPref(LEAKSTOP_KEY, &m_bLeakStop, TRUE);
2902 mLocalPrefs.GetPref(DOSLEEP_KEY, &m_bDoSleep, FALSE);
2903 mLocalPrefs.GetPref(SELECTCURVES_KEY, &m_bSelectCurves, TRUE);
2904 mLocalPrefs.GetPref(SELECTMODELS_KEY, &m_bSelectModels, TRUE);
2905 mLocalPrefs.GetPref(SHADERLISTONLY_KEY, &m_bTexturesShaderlistOnly, FALSE);
2906 mLocalPrefs.GetPref(SUBDIVISIONS_KEY, &m_nSubdivisions, SUBDIVISIONS_DEF);
2907 mLocalPrefs.GetPref(CLIPCAULK_KEY, &m_bClipCaulk, FALSE);
2908 mLocalPrefs.GetPref(SNAPTTOGRID_KEY, &m_bSnapTToGrid, FALSE);
2909 mLocalPrefs.GetPref(TARGETFIX_KEY, &m_bDoTargetFix, TRUE);
2910 mLocalPrefs.GetPref(WHEELINC_KEY, &m_nWheelInc, 64);
2911 mLocalPrefs.GetPref(PATCHBBOXSEL_KEY, &m_bPatchBBoxSelect, FALSE);
2913 // Gef: Kyro GL_POINT workaround
2914 mLocalPrefs.GetPref(GLPOINTWORKAROUND_KEY, &m_bGlPtWorkaround, FALSE);
2916 // window positioning
2917 mLocalPrefs.GetPref(ENTITYSPLIT1_KEY, &mWindowInfo.nEntitySplit1, -1);
2918 mLocalPrefs.GetPref(ENTITYSPLIT2_KEY, &mWindowInfo.nEntitySplit2, -1);
2920 mLocalPrefs.GetPref(POSITIONX_KEY, &mWindowInfo.position.x, -1);
2921 mLocalPrefs.GetPref(POSITIONY_KEY, &mWindowInfo.position.y, -1);
2922 mLocalPrefs.GetPref(WIDTH_KEY, &mWindowInfo.position.w, -1);
2923 mLocalPrefs.GetPref(HEIGHT_KEY, &mWindowInfo.position.h, 450);
2925 const window_position_t default_window_pos = { 0, 0, 200, 200, };
2927 mLocalPrefs.GetPref(ENTITYWND_KEY, &mWindowInfo.posEntityWnd, default_window_pos);
2928 mLocalPrefs.GetPref(MAPINFOWND_KEY, &mWindowInfo.posMapInfoWnd, default_window_pos);
2929 mLocalPrefs.GetPref(CAMWND_KEY, &mWindowInfo.posCamWnd, default_window_pos);
2930 mLocalPrefs.GetPref(ZWND_KEY, &mWindowInfo.posZWnd, default_window_pos);
2931 mLocalPrefs.GetPref(XYWND_KEY, &mWindowInfo.posXYWnd, default_window_pos);
2932 mLocalPrefs.GetPref(YZWND_KEY, &mWindowInfo.posYZWnd, default_window_pos);
2933 mLocalPrefs.GetPref(XZWND_KEY, &mWindowInfo.posXZWnd, default_window_pos);
2934 mLocalPrefs.GetPref(PATCHWND_KEY, &mWindowInfo.posPatchWnd, default_window_pos);
2935 mLocalPrefs.GetPref(SURFACEWND_KEY, &mWindowInfo.posSurfaceWnd, default_window_pos);
2936 mLocalPrefs.GetPref(ENTITYINFOWND_KEY, &mWindowInfo.posEntityInfoWnd, default_window_pos);
2938 mLocalPrefs.GetPref(ZWIDTH_KEY, &mWindowInfo.nZWidth, 30);
2939 mLocalPrefs.GetPref(XYHEIGHT_KEY, &mWindowInfo.nXYHeight, 300);
2940 mLocalPrefs.GetPref(XYWIDTH_KEY, &mWindowInfo.nXYWidth, 300);
2941 mLocalPrefs.GetPref(CAMWIDTH_KEY, &mWindowInfo.nCamWidth, 200);
2942 mLocalPrefs.GetPref(CAMHEIGHT_KEY, &mWindowInfo.nCamHeight, 200);
2943 mLocalPrefs.GetPref(ZFLOATWIDTH_KEY, &mWindowInfo.nZFloatWidth, 300);
2945 mLocalPrefs.GetPref(STATE_KEY, &mWindowInfo.nState, SW_SHOW);
2949 mLocalPrefs.GetPref(COUNT_KEY, &m_nMRUCount, 0);
2950 for(i = 0; i < 4; i++)
2953 sprintf (buf, "%s%d", FILE_KEY, i);
2954 mLocalPrefs.GetPref(buf, &m_strMRUFiles[i], "");
2957 // some platform specific prefs
2959 mLocalPrefs.GetPref(NATIVEGUI_KEY, &m_bNativeGUI, TRUE);
2960 mLocalPrefs.GetPref(STARTONPRIMMON_KEY, &m_bStartOnPrimMon, FALSE);
2963 mLocalPrefs.GetPref(SI_TEXMENU_KEY, &g_qeglobals.d_savedinfo.iTexMenu, ID_VIEW_BILINEARMIPMAP);
2964 mLocalPrefs.GetPref(SI_GAMMA_KEY, &g_qeglobals.d_savedinfo.fGamma, 1.0f);
2965 mLocalPrefs.GetPref(SI_EXCLUDE_KEY, &g_qeglobals.d_savedinfo.exclude, 0); // nothing filtered by default
2966 mLocalPrefs.GetPref(SI_INCLUDE_KEY, &g_qeglobals.d_savedinfo.include, INCLUDE_NAMES | INCLUDE_COORDS | INCLUDE_ANGLES | INCLUDE_CAMERATINT);
2967 mLocalPrefs.GetPref(SI_SHOWNAMES_KEY, &g_qeglobals.d_savedinfo.show_names, FALSE);
2968 mLocalPrefs.GetPref(SI_SHOWCOORDS_KEY, &g_qeglobals.d_savedinfo.show_coordinates, TRUE);
2969 mLocalPrefs.GetPref(SI_SHOWANGLES_KEY, &g_qeglobals.d_savedinfo.show_angles, TRUE);
2970 mLocalPrefs.GetPref(SI_SHOWOUTLINES_KEY, &g_qeglobals.d_savedinfo.show_outline, FALSE);
2971 mLocalPrefs.GetPref(SI_SHOWAXIS_KEY, &g_qeglobals.d_savedinfo.show_axis, TRUE);
2972 mLocalPrefs.GetPref(SI_NOSELOUTLINES_KEY, &g_qeglobals.d_savedinfo.bNoSelectedOutlines, FALSE);
2974 mLocalPrefs.GetPref(SI_OUTLINESTYLE_KEY, &g_qeglobals.d_savedinfo.iSelectedOutlinesStyle, OUTLINE_ZBUF|OUTLINE_BSEL);
2976 LoadTexdefPref(&g_qeglobals.d_savedinfo.m_SIIncrement, SI_SURFACE_TEXDEF_KEY);
2977 LoadTexdefPref(&g_qeglobals.d_savedinfo.m_PIIncrement, SI_PATCH_TEXDEF_KEY);
2979 // text editor binding
2981 mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseWin32Editor, TRUE);
2983 mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseCustomEditor, FALSE);
2984 mLocalPrefs.GetPref(CUSTOMSHADEREDITORCOMMAND_KEY, &m_strEditorCommand, "");
2988 vec3_t vDefaultAxisColours[3] = {
2994 for(i = 0; i < 3; i++) {
2996 sprintf(buf, "%s%d", SI_AXISCOLORS_KEY, i);
2997 mLocalPrefs.GetPref(buf, g_qeglobals.d_savedinfo.AxisColors[i], vDefaultAxisColours[i]);
3000 vec3_t vDefaultColours[COLOR_LAST] = {
3001 {0.25f, 0.25f, 0.25f},
3003 {0.75f, 0.75f, 0.75f},
3005 {0.25f, 0.25f, 0.25f},
3018 for(i = 0; i < COLOR_LAST; i++) {
3020 sprintf(buf, "%s%d", SI_COLORS_KEY, i);
3021 mLocalPrefs.GetPref(buf, g_qeglobals.d_savedinfo.colors[i], vDefaultColours[i]);
3024 mLocalPrefs.GetPref(TEXTURECOMPRESSIONFORMAT_KEY, &m_nTextureCompressionFormat, 1);
3026 mLocalPrefs.GetPref(LIGHTRADIUS_KEY, &m_nLightRadiuses, TRUE);
3028 mLocalPrefs.GetPref(Q3MAP2TEX_KEY, &m_bQ3Map2Texturing, TRUE);
3031 mLocalPrefs.GetPref(ATIHACK_KEY, &m_bGlATIHack, FALSE);
3034 Undo_SetMaxSize(m_nUndoLevels); // set it internally as well / FIXME: why not just have one global value?
3036 UpdateTextureCompression();
3042 if (mLocalPrefs.mbEmpty)
3044 mLocalPrefs.mbEmpty = false;
3045 Sys_Printf("Saving local.pref with default pref values\n");
3050 void PrefsDlg::SavePrefs ()
3052 if (g_qeglobals.disable_ini)
3056 Sys_Printf("PrefsDlg::SavePrefs\n");
3059 // this will take care of copying back from the dialog to the variables
3060 // NOTE: it may be overkill to call systematically before a SavePrefs, but it's safer
3061 // this will also cause an UpdateData for the mGamesDialog
3064 mGamesDialog.SavePrefs();
3066 // update the tree and save it
3067 mLocalPrefs.UpdatePrefTree();
3068 if (!mLocalPrefs.WriteXMLFile(m_inipath->str))
3069 Sys_FPrintf(SYS_ERR, "Error occured while saving local prefs file '%s'\n", m_inipath->str);
3071 if ( m_nMouse == 0 ) {
3072 m_nMouseButtons = 2;
3074 m_nMouseButtons = 3;
3079 void PrefsDlg::PostModal (int code)
3084 // make sure the logfile is ok
3090 g_pParentWnd->SetGridStatus();
3091 Sys_UpdateWindows(W_ALL);
3092 if (m_nUndoLevels != 0)
3093 Undo_SetMaxSize(m_nUndoLevels);
3097 void PrefsDlg::DoEditorSensitivity()
3099 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data (G_OBJECT(m_pWidget), "check_customeditor"))))
3101 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), TRUE);
3102 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), TRUE);
3103 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), TRUE);
3107 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), FALSE);
3108 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), FALSE);
3109 gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), FALSE);
3113 void PrefsDlg::DoSensitivity()
3116 // first, look at the project file version ... will monitoring work?
3117 // project files now XML, guaranteed to be at least version 2
3118 if (0)//IntForKey( g_qeglobals.d_project_entity, "version" ) < 2)
3123 Msg = "The current project file (";
3124 Msg += g_PrefsDlg.m_strLastProject;
3125 Msg += ") is not at least version 2.\nI need version 2 or above to setup BSP monitoring correctly.";
3126 gtk_MessageBox(m_pWidget, Msg.GetBuffer(), MB_OK );
3131 // go ahead, disable everybuddy
3132 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );
3133 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), FALSE );
3134 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );
3135 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3142 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), TRUE );
3143 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), TRUE );
3144 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), TRUE );
3145 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), TRUE );
3147 if ( ! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" ) ) ) )
3149 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );
3150 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );
3151 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3152 } else if (! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" ) ) ) )
3154 gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );
3159 ============================================================
3161 ============================================================
3164 CGameInstall::CGameInstall() {
3165 memset( m_availGames, 0, sizeof( m_availGames ) );
3168 void CGameInstall::OnBtnBrowseEngine( GtkWidget *widget, gpointer data ) {
3169 Sys_Printf( "OnBtnBrowseEngine\n" );
3171 CGameInstall* i = static_cast<CGameInstall*>( data );
3172 char *dir = dir_dialog( widget, "Select game directory", NULL );
3174 i->UpdateData( TRUE );
3176 if ( dir != NULL ) {
3177 i->m_strEngine = dir;
3178 i->UpdateData( FALSE );
3183 void CGameInstall::OnGameSelectChanged( GtkWidget *widget, gpointer data ) {
3184 Sys_Printf( "OnGameSelectChanged\n" );
3186 CGameInstall* i = static_cast<CGameInstall*>( data );
3187 i->UpdateData( TRUE );
3188 i->m_strName = gtk_combo_box_get_active_text( GTK_COMBO_BOX( widget ) );
3189 i->UpdateData( FALSE );
3192 void CGameInstall::BuildDialog() {
3193 GtkWidget *dlg, *vbox1, *button, *text, *combo, *entry, *hbox;
3196 gtk_window_set_title( GTK_WINDOW( dlg ), "Configure games" );
3198 vbox1 = gtk_vbox_new( FALSE, 0 );
3199 gtk_widget_show( vbox1 );
3200 gtk_container_add( GTK_CONTAINER( dlg ), vbox1 );
3202 text = gtk_label_new( "Select the game to configure" );
3203 gtk_widget_show( text );
3204 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3206 combo = gtk_combo_box_new_text();
3207 gtk_widget_show( combo );
3208 gtk_box_pack_start( GTK_BOX( vbox1 ), combo, FALSE, FALSE, 0 );
3210 // GList *combo_list = NULL;
3212 while ( m_availGames[ iGame ] != GAME_NONE ) {
3213 switch ( m_availGames[ iGame ] ) {
3215 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Quake II" );
3218 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Quake III Arena and mods" );
3221 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Urban Terror (standalone)" );
3224 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "UFO: Alien Invasion" );
3227 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Quake2World" );
3230 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Warsow" );
3233 gtk_combo_box_append_text( GTK_COMBO_BOX( combo ), "Nexuiz" );
3238 AddDialogData( combo, &m_nComboSelect, DLG_COMBO_BOX_INT );
3239 gtk_signal_connect( GTK_OBJECT( combo ), "changed", G_CALLBACK( OnGameSelectChanged ), this );
3240 gtk_combo_box_set_active( GTK_COMBO_BOX( combo ), 0 ); // NOTE: will trigger signal
3242 text = gtk_label_new( "Name:" );
3243 gtk_widget_show( text );
3244 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3246 entry = gtk_entry_new();
3247 gtk_widget_show( entry );
3248 gtk_box_pack_start( GTK_BOX( vbox1 ), entry, FALSE, FALSE, 0 );
3249 AddDialogData( entry, &m_strName, DLG_ENTRY_TEXT );
3251 text = gtk_label_new( "Engine directory:" );
3252 gtk_widget_show( text );
3253 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3255 hbox = gtk_hbox_new( FALSE, 0 );
3256 gtk_widget_show( hbox );
3257 gtk_box_pack_start( GTK_BOX( vbox1 ), hbox, FALSE, FALSE, 0 );
3259 entry = gtk_entry_new();
3260 gtk_widget_show( entry );
3261 gtk_box_pack_start( GTK_BOX( hbox ), entry, FALSE, FALSE, 0 );
3262 AddDialogData( entry, &m_strEngine, DLG_ENTRY_TEXT );
3264 button = gtk_button_new_with_label ("...");
3265 gtk_widget_show( button );
3266 gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( OnBtnBrowseEngine ), this );
3267 gtk_box_pack_start( GTK_BOX( hbox ), button, FALSE, FALSE, 0 );
3269 // this gets done in the project stuff atm
3271 text = gtk_label_new( "Mod subdirectory:" );
3272 gtk_widget_show( text );
3273 gtk_box_pack_start( GTK_BOX( vbox1 ), text, FALSE, FALSE, 0 );
3275 entry = gtk_entry_new();
3276 gtk_widget_show( entry );
3277 gtk_box_pack_start( GTK_BOX( vbox1 ), entry, FALSE, FALSE, 0 );
3278 AddDialogData( entry, &m_strMod, DLG_ENTRY_TEXT );
3281 button = gtk_button_new_with_label( "OK" );
3282 gtk_widget_show( button );
3283 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
3284 AddModalButton( button, IDOK );
3286 button = gtk_button_new_with_label( "Cancel" );
3287 gtk_widget_show( button );
3288 gtk_box_pack_start( GTK_BOX( vbox1 ), button, FALSE, FALSE, 0 );
3289 AddModalButton( button, IDCANCEL );
3291 gtk_widget_set_usize( button, 60, -2 );
3294 void CGameInstall::Run() {
3296 if ( DoModal() == IDCANCEL ) {
3297 Sys_Printf( "game dialog cancelled\n" );
3300 Sys_Printf( "combo: %d name: %s engine: %s mod: %s\n", m_nComboSelect, m_strName.GetBuffer(), m_strEngine.GetBuffer(), m_strMod.GetBuffer() );
3302 // write out the game file
3303 Str gameFilePath = g_strAppPath.GetBuffer();
3304 gameFilePath += "games/";
3305 gameFilePath += m_strName.GetBuffer();
3306 gameFilePath += ".game";
3307 Sys_Printf( "game file: %s\n", gameFilePath.GetBuffer() );
3309 FILE *fg = fopen( gameFilePath.GetBuffer(), "w" );
3311 Error( "Failed to open %s for writing\n", gameFilePath.GetBuffer() );
3313 fprintf( fg, "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"yes\"?>\n<game\n" );
3314 fprintf( fg, " name=\"%s\"\n", m_strName.GetBuffer() );
3315 fprintf( fg, " enginepath=\"%s\"\n", m_strEngine.GetBuffer() );
3316 switch ( m_availGames[ m_nComboSelect ] ) {
3318 fprintf( fg, " gametools=\"%sinstalls/Quake2Pack/game\"\n", g_strAppPath.GetBuffer() );
3319 fprintf( fg, " prefix=\".quake2\"\n" );
3320 Str source = g_strAppPath.GetBuffer();
3321 source += "installs/";
3323 source += "/install/";
3324 Str dest = m_strEngine.GetBuffer();
3325 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3326 fprintf( fg, " basegame=\"baseq2\"\n" );
3330 fprintf( fg, " gametools=\"%sinstalls/Q3Pack/game\"\n", g_strAppPath.GetBuffer() );
3331 fprintf( fg, " prefix=\".q3a\"\n" );
3332 Str source = g_strAppPath.GetBuffer();
3333 source += "installs/";
3335 source += "/install/";
3336 Str dest = m_strEngine.GetBuffer();
3337 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3338 fprintf( fg, " basegame=\"baseq3\"\n" );
3342 fprintf( fg, " gametools=\"%sinstalls/UrTPack/game\"\n", g_strAppPath.GetBuffer() );
3343 fprintf( fg, " prefix=\".q3a\"\n" );
3344 Str source = g_strAppPath.GetBuffer();
3345 source += "installs/";
3347 source += "/install/";
3348 Str dest = m_strEngine.GetBuffer();
3349 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3350 fprintf( fg, " basegame=\"q3ut4\"\n" );
3354 fprintf( fg, " gametools=\"%sinstalls/UFOAIPack/game\"\n", g_strAppPath.GetBuffer() );
3355 fprintf( fg, " prefix=\".ufoai\"\n" );
3356 Str source = g_strAppPath.GetBuffer();
3357 source += "installs/";
3358 source += UFOAI_PACK;
3359 source += "/install/";
3360 Str dest = m_strEngine.GetBuffer();
3361 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3362 fprintf( fg, " basegame=\"base\"\n" );
3366 fprintf( fg, " gametools=\"%sinstalls/Q2WPack/game\"\n", g_strAppPath.GetBuffer() );
3367 fprintf( fg, " prefix=\".quake2world\"\n" );
3368 Str source = g_strAppPath.GetBuffer();
3369 source += "installs/";
3371 source += "/install/";
3372 Str dest = m_strEngine.GetBuffer();
3373 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3374 fprintf( fg, " basegame=\"default\"\n" );
3378 fprintf( fg, " gametools=\"%sinstalls/WarsowPack/game\"\n", g_strAppPath.GetBuffer() );
3379 fprintf( fg, " prefix=\".warsow\"\n" );
3380 Str source = g_strAppPath.GetBuffer();
3381 source += "installs/";
3382 source += WARSOW_PACK;
3383 source += "/install/";
3384 Str dest = m_strEngine.GetBuffer();
3385 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3386 fprintf( fg, " basegame=\"basewsw\"\n" );
3390 fprintf( fg, " gametools=\"%sinstalls/NexuizPack/game\"\n", g_strAppPath.GetBuffer() );
3391 fprintf( fg, " prefix=\".nexuiz\"\n" );
3392 Str source = g_strAppPath.GetBuffer();
3393 source += "installs/";
3394 source += NEXUIZ_PACK;
3395 source += "/install/";
3396 Str dest = m_strEngine.GetBuffer();
3397 CopyTree( source.GetBuffer(), dest.GetBuffer() );
3398 fprintf( fg, " basegame=\"data\"\n" );
3402 fprintf( fg, "/>\n" );
3408 CGameInstall::ScanGames
3409 scan for active games that can be installed, based on the presence
3412 void CGameInstall::ScanGames() {
3413 Str pakPaths = g_strAppPath.GetBuffer();
3415 const char *dirname;
3417 pakPaths += "installs/";
3418 FindFiles fileScan( pakPaths.GetBuffer() );
3419 while ( ( dirname = fileScan.NextFile() ) != NULL ) {
3420 if ( stricmp( dirname, Q3_PACK ) == 0 ) {
3421 m_availGames[ iGame++ ] = GAME_Q3;
3423 if ( stricmp( dirname, URT_PACK ) == 0 ) {
3424 m_availGames[ iGame++ ] = GAME_URT;
3426 if ( stricmp( dirname, UFOAI_PACK ) == 0 ) {
3427 m_availGames[ iGame++ ] = GAME_UFOAI;
3429 if ( stricmp( dirname, Q2W_PACK ) == 0 ) {
3430 m_availGames[ iGame++ ] = GAME_Q2W;
3432 if ( stricmp( dirname, WARSOW_PACK ) == 0 ) {
3433 m_availGames[ iGame++ ] = GAME_WARSOW;
3435 if ( stricmp( dirname, NEXUIZ_PACK ) == 0 ) {
3436 m_availGames[ iGame++ ] = GAME_NEXUIZ;
3438 if ( stricmp( dirname, Q2_PACK ) == 0 ) {
3439 m_availGames[ iGame++ ] = GAME_Q2;