]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/preferences.cpp
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / radiant / preferences.cpp
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 //\r
23 // User preferences\r
24 //\r
25 // Leonardo Zide (leo@lokigames.com)\r
26 //\r
27 \r
28 #include "stdafx.h"\r
29 #include <glib.h>\r
30 #if defined (__linux__) || defined (__APPLE__)\r
31 #include <sys/stat.h>\r
32 #include <sys/types.h>\r
33 #include <fcntl.h>\r
34 #include <unistd.h>\r
35 #include <dirent.h>\r
36 #endif\r
37 #include "missing.h"\r
38 #include "gtkmisc.h"\r
39 \r
40 #ifdef _WIN32\r
41 #include <io.h>\r
42 #define X_OK 0\r
43 #include <sys/stat.h>\r
44 #endif\r
45 \r
46 #define PREF_SECTION            "Prefs"\r
47 #define INTERNAL_SECTION        "Internals"\r
48 #define MOUSE_KEY               "MouseButtons"\r
49 #define WINDOW_KEY              "QE4StyleWindows"\r
50 #define LAYOUT_KEY              "WindowLayout"\r
51 #define RUNQ2_KEY               "RunQuake2Run"\r
52 #define TLOCK_KEY               "TextureLock"\r
53 #define RLOCK_KEY               "RotateLock"\r
54 #define LOADLAST_KEY            "LoadLast"\r
55 #define LOADLASTMAP_KEY         "LoadLastMap"\r
56 #define LASTPROJ_KEY            "LastProject"\r
57 #define LASTPROJVER_KEY         "LastProjectKey"\r
58 #define LASTMAP_KEY             "LastMap"\r
59 #define FACE_KEY                "NewFaceGrab"\r
60 #define BSP_KEY                 "InternalBSP"\r
61 #define RCLICK_KEY              "NewRightClick"\r
62 #define VERTEX_KEY              "NewVertex"\r
63 #define AUTOSAVE_KEY            "Autosave"\r
64 #define AUTOSAVETIME_KEY        "AutosaveMinutes"\r
65 #define PAK_KEY                 "UsePAK"\r
66 #define NEWAPPLY_KEY            "ApplyDismissesSurface"\r
67 #define HACK_KEY                "Gatewayescapehack"\r
68 #define TEXTURE_KEY             "NewTextureWindowStuff"\r
69 #define TINYBRUSH_KEY           "CleanTinyBrushes"\r
70 #define TINYSIZE_KEY            "CleanTinyBrusheSize"\r
71 #define SNAPSHOT_KEY            "Snapshots"\r
72 #define MOVESPEED_KEY           "MoveSpeed"\r
73 #define ANGLESPEED_KEY          "AngleSpeed"\r
74 #define SETGAME_KEY             "UseSetGame"\r
75 #define CAMXYUPDATE_KEY         "CamXYUpdate"\r
76 #define CAMDRAGMULTISELECT_KEY  "CamDragMultiSelect"\r
77 #define CAMFREELOOK_KEY         "CamFreeLook"\r
78 #define CAMINVERSEMOUSE_KEY         "CamInverseMouse"\r
79 #define CAMDISCRETE_KEY         "CamDiscrete"\r
80 #define LIGHTDRAW_KEY           "NewLightStyle"\r
81 #define WHATGAME_KEY            "WhichGame"\r
82 #define CUBICCLIP_KEY           "CubicClipping"\r
83 #define CUBICSCALE_KEY          "CubicScale"\r
84 #define ALTEDGE_KEY             "ALTEdgeDrag"\r
85 #define FACECOLORS_KEY          "FaceColors"\r
86 #define SNAPT_KEY               "SnapT"\r
87 #define XZVIS_KEY               "XZVIS"\r
88 #define YZVIS_KEY               "YZVIS"\r
89 #define ZVIS_KEY                "ZVIS"\r
90 #define SIZEPAINT_KEY           "SizePainting"\r
91 #define DLLENTITIES_KEY         "DLLEntities"\r
92 #define DETACHABLEMENUS_KEY     "DetachableMenus"\r
93 #define PATCHTOOLBAR_KEY        "PatchToolBar"\r
94 #define WIDETOOLBAR_KEY         "WideToolBar"\r
95 #define PLUGINTOOLBAR_KEY "PluginToolBar"\r
96 #define NOCLAMP_KEY             "NoClamp"\r
97 #define PREFAB_KEY              "PrefabPath"\r
98 #define USERINI_KEY             "UserINIPath"\r
99 #define ROTATION_KEY            "Rotation"\r
100 #define BUGGYICD_KEY            "BuggyICD"\r
101 #define CHASEMOUSE_KEY          "ChaseMouse"\r
102 #define ENTITYSHOW_KEY          "EntityShow"\r
103 #define TEXTURESCALE_KEY        "TextureScale"\r
104 #define TEXTURESCROLLBAR_KEY    "TextureScrollbar"\r
105 #define DISPLAYLISTS_KEY        "UseDisplayLists"\r
106 #define ANTIALIASEDLINES_KEY    "UseAntialiasedPointsAndLines" // Fishman - Add antialiazed points and lines support. 09/03/00\r
107 #define NORMALIZECOLORS_KEY     "NormalizeColors"\r
108 #define SHADERS_KEY             "UseShaders"\r
109 #define SWITCHCLIP_KEY          "SwitchClipKey"\r
110 #define SELWHOLEENTS_KEY                    "SelectWholeEntitiesKey"\r
111 #define TEXTURESUBSET_KEY                 "UseTextureSubsetLoading"\r
112 #define TEXTUREQUALITY_KEY          "TextureQuality"\r
113 #define SHOWSHADERS_KEY               "ShowShaders"\r
114 #define SHADERTEST_KEY          "ShaderTest"\r
115 #define GLLIGHTING_KEY          "UseGLLighting"\r
116 #define LOADSHADERS_KEY         "LoadShaders"\r
117 #define NOSTIPPLE_KEY           "NoStipple"\r
118 #define UNDOLEVELS_KEY          "UndoLevels"\r
119 #define VERTEXMODE_KEY          "VertexSplit"\r
120 #define ENGINEPATH_KEY          "EnginePath"\r
121 #define ENGINE_KEY              "Engine"\r
122 #define LOGCONSOLE_KEY          "LogConsole"\r
123 #define SELECTCURVES_KEY        "SelectCurves"\r
124 #define SELECTMODELS_KEY        "SelectModels"\r
125 #define SHADERLISTONLY_KEY      "ShowShaderlistOnly"\r
126 #define WATCHBSP_KEY            "WatchBSP"\r
127 #define LEAKSTOP_KEY            "LeakStop"\r
128 #define DOSLEEP_KEY             "SleepMode"\r
129 #define SUBDIVISIONS_KEY        "Subdivisions"\r
130 #define CLIPCAULK_KEY           "ClipCaulk"\r
131 #define PATCHSHOWBOUNDS_KEY     "PatchShowBounds"\r
132 #define NATIVEGUI_KEY           "NativeGUI"\r
133 #define STARTONPRIMMON_KEY      "StartOnPrimMon"\r
134 #define NOSYSMENUPOPUPS_KEY     "NoSysMenuPopups"\r
135 #define SNAPTTOGRID_KEY         "SnapTToGrid"\r
136 #define FLOATINGZ_KEY           "FloatingZ"\r
137 #define TARGETFIX_KEY           "TargetFix"\r
138 #define GLPOINTWORKAROUND_KEY   "GlPointWorkaround"             // Gef: Workaround for broken Kyro * gl driver 25-aug-2001\r
139 #define WHEELINC_KEY            "WheelMouseInc"\r
140 #define PATCHBBOXSEL_KEY        "PatchBBoxSel"\r
141 #define LASTLIGHTINTENSITY_KEY  "LastLightIntensity"\r
142 #define CUSTOMSHADEREDITOR_KEY        "UseCustomShaderEditor"\r
143 #define CUSTOMSHADEREDITORCOMMAND_KEY "CustomShaderEditorCommand"\r
144 #define TEXTURECOMPRESSIONFORMAT_KEY "TextureCompressionFormat"\r
145 #define LIGHTRADIUS_KEY "LightRadiuses"\r
146 #define Q3MAP2TEX_KEY "Q3Map2Tex"\r
147 #define ATIHACK_KEY "ATIHack"\r
148 \r
149 // window stuff\r
150 #define ENTITYSPLIT1_KEY  "EntitySplit1"\r
151 #define ENTITYSPLIT2_KEY  "EntitySplit2"\r
152 #define POSITIONX_KEY     "PositionX"\r
153 #define POSITIONY_KEY     "PositionY"\r
154 #define ENTITYWND_KEY     "EntityWnd"\r
155 #define MAPINFOWND_KEY    "MapInfoDlg"\r
156 #define CAMWND_KEY        "CamWnd"\r
157 #define ZWND_KEY          "ZWnd"\r
158 #define XYWND_KEY         "XYWnd"\r
159 #define XZWND_KEY         "XZWnd"\r
160 #define YZWND_KEY         "YZWnd"\r
161 #define PATCHWND_KEY      "PatchWnd"\r
162 #define SURFACEWND_KEY    "SurfaceWnd"\r
163 #define ENTITYINFOWND_KEY "EntityInfoDlg"\r
164 #define WIDTH_KEY         "Width"\r
165 #define HEIGHT_KEY        "Height"\r
166 #define ZWIDTH_KEY        "ZWidth"\r
167 #define XYHEIGHT_KEY      "XYHeight"\r
168 #define XYWIDTH_KEY       "XYWidth"\r
169 #define CAMWIDTH_KEY      "CamWidth"\r
170 #define CAMHEIGHT_KEY     "CamHeight"\r
171 #define ZFLOATWIDTH_KEY   "ZWidthFloating"\r
172 #define STATE_KEY         "State"\r
173 \r
174 // menu stuff\r
175 #define COUNT_KEY         "Count"\r
176 #define FILE_KEY          "File"\r
177 \r
178 //saved info\r
179 #define SI_TEXMENU_KEY          "SI_TexMenu"\r
180 #define SI_GAMMA_KEY            "SI_Gamma"\r
181 #define SI_COLORS_KEY           "SI_Colors"\r
182 #define SI_EXCLUDE_KEY          "SI_Exclude"\r
183 #define SI_INCLUDE_KEY          "SI_Include"\r
184 #define SI_SURFACE_TEXDEF_KEY   "SI_SurfaceTexdef"\r
185 #define SI_PATCH_TEXDEF_KEY     "SI_PatchTexdef"\r
186 #define SI_AXISCOLORS_KEY       "SI_AxisColors"\r
187 #define SI_SHOWNAMES_KEY        "SI_ShowNames"\r
188 #define SI_SHOWCOORDS_KEY       "SI_ShowCoords"\r
189 #define SI_SHOWANGLES_KEY       "SI_ShowAngles"\r
190 #define SI_SHOWOUTLINES_KEY     "SI_ShowOutlines"\r
191 #define SI_SHOWAXIS_KEY         "SI_ShowAxis"\r
192 #define SI_NOSELOUTLINES_KEY    "SI_NoSelectedOutlines"\r
193 #define SI_OUTLINESTYLE_KEY "SI_OutLineStyle"\r
194 \r
195 //for texdefs\r
196 #define TD_SCALE1_KEY           "_Scale1"\r
197 #define TD_SCALE2_KEY           "_Scale2"\r
198 #define TD_SHIFT1_KEY           "_Shift1"\r
199 #define TD_SHIFT2_KEY           "_Shift2"\r
200 #define TD_ROTATE_KEY           "_Rotate"\r
201 \r
202 #define MOUSE_DEF 1\r
203 #define WINDOW_DEF 0\r
204 #define RUNQ2_DEF 0\r
205 #define WATCHBSP_DEF 1\r
206 #define TLOCK_DEF 1\r
207 #define LOADLAST_DEF 1\r
208 #define RUN_DEF 0\r
209 #define SUBDIVISIONS_DEF 4\r
210 \r
211 void WindowPosition_Parse(window_position_t& m_value, const CString& value)\r
212 {\r
213   if(sscanf(value.GetBuffer(), "%d %d %d %d", &m_value.x, &m_value.y, &m_value.w, &m_value.h) != 4)\r
214     m_value.x = m_value.y = m_value.w = m_value.h = -1;\r
215 }\r
216 \r
217 void WindowPosition_Write(const window_position_t& m_value, CString& value)\r
218 {\r
219   char buffer[64];\r
220   sprintf(buffer, "%d %d %d %d", m_value.x, m_value.y, m_value.w, m_value.h);\r
221   value = buffer;\r
222 }\r
223 \r
224 \r
225 CXMLPropertyBag::CXMLPropertyBag() {\r
226   mStrFilename = "";\r
227   mpDoc = NULL;\r
228   mbEmpty = false;\r
229 }\r
230 \r
231 // generic preference functions\r
232 \r
233 void CXMLPropertyBag::PushAssignment(char *name, PrefTypes_t type, void *pV)\r
234 {\r
235   list<CPrefAssignment>::iterator iAssign;\r
236   for(iAssign=mPrefAssignments.begin(); iAssign!=mPrefAssignments.end(); iAssign++)\r
237   {\r
238     if ((*iAssign).mName == name)\r
239     {\r
240       // we have it already, check anyway\r
241       if (pV != (*iAssign).mVal)\r
242       {\r
243         Sys_FPrintf(SYS_ERR, "PushAssignment, '%s' has different mVal\n", name);\r
244         return;\r
245       }\r
246     }\r
247   }\r
248   // ok, it's not in our list yet\r
249   mPrefAssignments.push_front(CPrefAssignment(name, type, pV));\r
250 }\r
251 \r
252 xmlNodePtr CXMLPropertyBag::EpairForName(const char *name)\r
253 {\r
254   xmlNodePtr ret = NULL;\r
255 \r
256   xmlNodePtr pNode = mpDocNode->children;\r
257   while (pNode != NULL)\r
258   {\r
259     if(pNode->type == XML_ELEMENT_NODE)\r
260     {\r
261       xmlAttrPtr tmp_attr_ptr = xmlHasProp(pNode, (xmlChar *)"name");\r
262       if (tmp_attr_ptr != NULL && !strcmp(name, (char *)tmp_attr_ptr->children->content))\r
263       {\r
264         if ( ret ) {\r
265           Sys_FPrintf( SYS_WRN, "WARNING: dupe property in CXMLPropertyBag::EpairForName '%s'\n", name );\r
266         } else {\r
267           ret = pNode;\r
268         }\r
269       }\r
270     }\r
271     pNode = pNode->next;\r
272   }\r
273   return ret;\r
274 }\r
275 \r
276 void CXMLPropertyBag::GetPref(char *name, Str *pV, char *V)\r
277 {\r
278   xmlNodePtr pNode = EpairForName( name );\r
279   if ( pNode )\r
280   {\r
281     if ( pNode->children && pNode->children->content ) {\r
282       *pV = pNode->children->content;\r
283     } else {\r
284       // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=427\r
285       // means the pref exists, and that the value is ""\r
286       *pV = "";\r
287     }\r
288   }\r
289   else\r
290   {\r
291     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)V);\r
292     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);\r
293   }\r
294   // push the pref assignment if needed\r
295   PushAssignment(name, PREF_STR, pV);\r
296 }\r
297 \r
298 void CXMLPropertyBag::GetPref(char *name, int *pV, int V)\r
299 {\r
300   xmlNodePtr pNode;  \r
301   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)\r
302   {\r
303     *pV = atoi((char *)pNode->children->content);\r
304   }\r
305   else\r
306   {\r
307     char s[10];\r
308     sprintf(s, "%d", V);\r
309     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);\r
310     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);\r
311     *pV=V;\r
312   }\r
313   // push the pref assignment if needed\r
314   PushAssignment(name, PREF_INT, pV); \r
315 }\r
316 \r
317 void CXMLPropertyBag::GetPref(char *name, bool *pV, bool V)\r
318 {\r
319   xmlNodePtr pNode;  \r
320   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)\r
321   {\r
322     if (!strcmp((char *)pNode->children->content, "true"))\r
323     {\r
324       *pV = true;\r
325     }\r
326     else\r
327     {\r
328       *pV = false;\r
329     }\r
330   }\r
331   else\r
332   {\r
333     char s[10];\r
334     V ? strcpy(s, "true") : strcpy(s, "false");\r
335     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);\r
336     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);\r
337     *pV=V;\r
338   }\r
339   // push the pref assignment\r
340   PushAssignment(name, PREF_BOOL, pV); \r
341 }\r
342 \r
343 void CXMLPropertyBag::GetPref(char *name, float *pV, float V)\r
344 {\r
345   xmlNodePtr pNode;  \r
346   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)\r
347   {\r
348     *pV = atof((char *)pNode->children->content);\r
349   }\r
350   else\r
351   {\r
352     char s[10];\r
353     sprintf(s, "%f", V);\r
354     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);\r
355     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);\r
356     *pV=V;\r
357   }\r
358   // push the pref assignment if needed\r
359   PushAssignment(name, PREF_FLOAT, pV); \r
360 }\r
361 \r
362 void CXMLPropertyBag::GetPref(char *name, float* pV, float* V)\r
363 {\r
364   xmlNodePtr pNode;  \r
365   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)\r
366   {\r
367     sscanf((char *)pNode->children->content, "%f %f %f", &pV[0], &pV[1], &pV[2]);\r
368   }\r
369   else\r
370   {\r
371     char s[128];\r
372     sprintf(s, "%f %f %f", V[0], V[1], V[2]);\r
373     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)s);\r
374     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);\r
375     pV[0] = V[0];\r
376     pV[1] = V[1];\r
377     pV[2] = V[2];\r
378   }\r
379   // push the pref assignment if needed\r
380   PushAssignment(name, PREF_VEC3, pV); \r
381 }\r
382 \r
383 void CXMLPropertyBag::GetPref(char *name, window_position_t* pV, window_position_t V)\r
384 {\r
385   xmlNodePtr pNode;  \r
386   if ((pNode = EpairForName(name)) && pNode->children && pNode->children->content)\r
387   {\r
388     WindowPosition_Parse(*pV, CString((xmlChar *)pNode->children->content));\r
389   }\r
390   else\r
391   {\r
392     CString str;\r
393     WindowPosition_Write(V, str);\r
394     pNode = xmlNewChild(mpDocNode, NULL, (xmlChar *)"epair", (xmlChar *)str.GetBuffer());\r
395     xmlSetProp(pNode, (xmlChar *)"name", (xmlChar *)name);\r
396     *pV = V;\r
397   }\r
398   // push the pref assignment if needed\r
399   PushAssignment(name, PREF_WNDPOS, pV); \r
400 }\r
401 \r
402 void CXMLPropertyBag::UpdatePrefTree()\r
403 {\r
404   // read the assignments and update the tree\r
405   list<CPrefAssignment>::iterator iPref;\r
406   for(iPref = mPrefAssignments.begin(); iPref != mPrefAssignments.end(); iPref++)\r
407   {\r
408     CPrefAssignment *pPref = &(*iPref);\r
409     // look for the node\r
410     xmlNodePtr pNode;\r
411     char s[64];\r
412 \r
413     pNode = EpairForName(pPref->mName.GetBuffer());\r
414     // we never expect that the node could not be found, because this is supposed to happen\r
415     // after the tree was built with GetPref calls, never on a blank tree\r
416     if (!pNode)\r
417     {\r
418       Sys_FPrintf(SYS_ERR, "Unexpected EpairForName '%s' not found in UpdatePrefTree\n", pPref->mName.GetBuffer());\r
419       return;\r
420     }\r
421     switch ((*iPref).mType)\r
422     {\r
423     case PREF_STR:\r
424       xmlNodeSetContent(pNode, (const xmlChar *)((Str *)pPref->mVal)->GetBuffer());\r
425       break;\r
426     case PREF_INT:\r
427       sprintf(s, "%d", *(int *)pPref->mVal);\r
428       xmlNodeSetContent(pNode, (xmlChar *)s);\r
429       break;\r
430     case PREF_FLOAT:\r
431       sprintf(s, "%f", *(float *)pPref->mVal);\r
432       xmlNodeSetContent(pNode, (xmlChar *)s);\r
433       break;\r
434     case PREF_BOOL:\r
435       *(bool *)pPref->mVal ? strcpy(s, "true") : strcpy(s, "false");\r
436       xmlNodeSetContent(pNode, (xmlChar *)s);\r
437       break;\r
438     case PREF_VEC3:\r
439       {\r
440         float* v = (float*)pPref->mVal;\r
441         sprintf(s, "%f %f %f", v[0], v[1], v[2]);\r
442         xmlNodeSetContent(pNode, (xmlChar *)s);\r
443       }\r
444       break;\r
445     case PREF_WNDPOS:\r
446       {\r
447         CString str;\r
448         WindowPosition_Write(*(window_position_t*)pPref->mVal, str);\r
449         xmlNodeSetContent(pNode, (xmlChar*)str.GetBuffer());\r
450       }\r
451       break;\r
452     }\r
453   }\r
454 }\r
455 \r
456 void CXMLPropertyBag::Clear()\r
457 {\r
458   if(!InUse())\r
459     return;\r
460 \r
461   xmlFreeDoc(mpDoc);\r
462   mpDoc = NULL;\r
463   mpDocNode = NULL;\r
464   mbEmpty = false;\r
465 }\r
466 \r
467 void CXMLPropertyBag::ReadXMLFile(const char* pFilename)\r
468 {\r
469   mpDoc = xmlParseFile(pFilename);\r
470 \r
471   // basic checks\r
472   if (mpDoc)\r
473   {\r
474     mpDocNode = mpDoc->children;\r
475     xmlAttrPtr tmp_attr_ptr = xmlHasProp(mpDocNode, (xmlChar *)"version");\r
476     if (strcmp((char *)mpDocNode->name, "qpref"))\r
477     {\r
478       Sys_FPrintf(SYS_ERR, "Unrecognized node '%s' in '%s'\n", mpDocNode->name, mpDoc->URL);\r
479       xmlFreeDoc(mpDoc);\r
480       mpDoc = NULL;\r
481     }\r
482     else if (tmp_attr_ptr != NULL && strcmp((char*)tmp_attr_ptr->children->content, "1"))\r
483     {\r
484       Sys_FPrintf(SYS_ERR, "Wrong version '%s' in <qpref> node for '%s'\n", (char*)tmp_attr_ptr->children->content, mpDoc->URL);\r
485       xmlFreeDoc(mpDoc);\r
486       mpDoc = NULL;\r
487     }    \r
488     Sys_Printf("Opened XML property file: '%s'\n", pFilename);\r
489   }\r
490 \r
491   if (!mpDoc)\r
492   {\r
493     mbEmpty = true;\r
494     // no document, create one\r
495     mpDoc = xmlNewDoc((xmlChar *)"1.0");\r
496     mpDocNode = xmlNewDocNode(mpDoc, NULL, (xmlChar *)"qpref", NULL);\r
497     xmlDocSetRootElement(mpDoc, mpDocNode);\r
498     xmlSetProp(mpDocNode, (xmlChar *)"version", (xmlChar *)"1");\r
499     Sys_Printf("XML property file '%s' invalid/not found, creating blank properties tree\n", pFilename);\r
500   }\r
501 }\r
502 \r
503 qboolean CXMLPropertyBag::WriteXMLFile(const char* pFilename)\r
504 {\r
505   int res = xmlSaveFormatFile(pFilename, mpDoc, 1);\r
506     \r
507   if(res == -1)\r
508     return false;\r
509 \r
510   Sys_Printf("Wrote XML property file '%s'\n", pFilename);\r
511   return true;\r
512 }\r
513 \r
514 // =============================================================================\r
515 // Widget callbacks for PrefsDlg\r
516 \r
517 #if !defined(WIN32)\r
518 // browse for custom editor executable\r
519 static void OnBtnBrowseEditor (GtkWidget *widget, gpointer data)\r
520 {\r
521   PrefsDlg *dlg = (PrefsDlg*)data;\r
522   \r
523   const char *filename = file_dialog(g_PrefsDlg.GetWidget(), TRUE, "Executable for Custom Editor");\r
524   \r
525   if(filename != NULL)\r
526   {\r
527     dlg->m_strEditorCommand = filename;\r
528     dlg->UpdateData(FALSE);\r
529   }\r
530 }\r
531 #endif\r
532 \r
533 static void OnBtnBrowseprefab (GtkWidget *widget, gpointer data)\r
534 {\r
535   PrefsDlg *dlg = (PrefsDlg*)data;\r
536   char *path = dlg->m_strPrefabPath;\r
537   if (strlen (path) == 0)\r
538     path = g_strGameToolsPath;\r
539   char *dir = dir_dialog (g_PrefsDlg.GetWidget (), "Set prefab path", path);\r
540   dlg->UpdateData(TRUE);\r
541 \r
542   if (dir != NULL)\r
543   {\r
544     CString strPath;\r
545     strPath = dir;\r
546     AddSlash(strPath);\r
547     dlg->m_strPrefabPath = strPath;\r
548     dlg->UpdateData(FALSE);\r
549     free (dir);\r
550   }\r
551 }\r
552 \r
553 static void OnBtnBrowseuserini (GtkWidget *widget, gpointer data)\r
554 {\r
555   PrefsDlg *dlg = (PrefsDlg*)data;\r
556   char *path = dlg->m_strUserPath;\r
557   if (strlen (path) == 0)\r
558     path = g_strGameToolsPath;\r
559   // TODO: INI filter?\r
560   const char *filename = file_dialog (g_PrefsDlg.GetWidget(), TRUE, "Find INI file", path);\r
561 \r
562   if (filename != NULL)\r
563   {\r
564     dlg->UpdateData(TRUE);\r
565     dlg->m_strUserPath = filename;\r
566     dlg->UpdateData(FALSE);\r
567   }\r
568 }\r
569 \r
570 static void OnButtonClean (GtkWidget *widget, gpointer data) \r
571 {\r
572   // make sure this is what the user wants\r
573   if (gtk_MessageBox (g_PrefsDlg.GetWidget (), "This will close Radiant and clean the corresponding registry entries.\n"\r
574                   "Next time you start Radiant it will be good as new. Do you wish to continue?",\r
575                   "Reset Registry", MB_YESNO) == IDYES)\r
576   {\r
577     PrefsDlg *dlg = (PrefsDlg*)data;\r
578     dlg->EndModal (IDCANCEL);\r
579 \r
580     g_qeglobals.disable_ini = true;\r
581     remove (dlg->m_inipath->str);\r
582     char buf[PATH_MAX];\r
583     sprintf(buf, "%sSavedInfo.bin", dlg->m_rc_path->str);\r
584     remove(buf);\r
585     HandleCommand (NULL, GINT_TO_POINTER (ID_FILE_EXIT));\r
586     _exit (0);\r
587   }\r
588 }\r
589 \r
590 // =============================================================================\r
591 // PrefsDlg class\r
592 \r
593 // IMPORTANT NOTE: the values here don't matter very much\r
594 // the actual intialization if you start with an empty .ini is done when loading the prefs for the first time\r
595 // profile_load_int takes an argument to use if the value is not found\r
596 PrefsDlg::PrefsDlg ()\r
597 {\r
598   m_bWarn = TRUE;\r
599   m_nMouse = 1;\r
600   m_nView = MainFrame::eRegular;\r
601   m_bLoadLast = FALSE;\r
602   m_bInternalBSP = FALSE;\r
603   m_bRightClick = FALSE;\r
604   m_bSetGame = FALSE;\r
605   m_bAutoSave = TRUE;\r
606   m_nAutoSave = 5;\r
607   m_bLoadLastMap = FALSE;\r
608   m_bTextureWindow = FALSE;\r
609   m_bSnapShots = FALSE;\r
610   m_fTinySize = 0.5;\r
611   m_bCleanTiny = FALSE;\r
612   m_bCamXYUpdate = TRUE;\r
613   m_bCamDragMultiSelect = FALSE;\r
614   m_bCamFreeLook = TRUE;\r
615   m_bCamFreeLookStrafe = FALSE;\r
616   m_bCamInverseMouse = FALSE;\r
617   m_bCamDiscrete = TRUE;\r
618   m_bNewLightDraw = FALSE;\r
619   m_strPrefabPath = "";\r
620   m_nWhatGame = 0;\r
621   m_bALTEdge = FALSE;\r
622   m_bFaceColors = FALSE;\r
623   m_bXZVis = FALSE;\r
624   m_bYZVis = FALSE;\r
625   m_bZVis = FALSE;\r
626   m_bSizePaint = FALSE;\r
627   m_bDLLEntities = FALSE;\r
628 #ifdef _WIN32\r
629   m_bDetachableMenus = FALSE;   // Most win32 users will find detachable menus annoying\r
630 #else\r
631   m_bDetachableMenus = TRUE;    // Linux/Apple users are used to them...\r
632 #endif\r
633   m_bPatchToolbar = TRUE;\r
634   m_bWideToolbar = TRUE;\r
635   m_bPluginToolbar = TRUE;\r
636   m_bNoClamp = FALSE;\r
637   m_strUserPath = "";\r
638   m_nRotation = 0;\r
639   m_bChaseMouse = FALSE;\r
640   m_bTextureScrollbar = TRUE;\r
641   m_bDisplayLists = TRUE;\r
642   m_bAntialiasedPointsAndLines = FALSE; // Fishman - Add antialiazed points and lines support. 09/03/00\r
643   m_bShowShaders = FALSE;\r
644   m_nShader = -1;\r
645   m_bNoStipple = FALSE;\r
646   m_bVertexSplit = FALSE;\r
647   m_bSelectCurves = TRUE;\r
648   m_bSelectModels = TRUE;\r
649   m_nEntityShowState = ENTITY_SKINNED_BOXED;\r
650   m_nTextureScale = 2;\r
651   m_bSwitchClip = FALSE;\r
652   m_bSelectWholeEntities = TRUE;\r
653   m_nTextureQuality = 3;\r
654   m_bShowShaders = TRUE;\r
655   m_bGLLighting = FALSE;\r
656   m_nShader = 0;\r
657   m_nUndoLevels = 30;\r
658   m_bTexturesShaderlistOnly = FALSE;\r
659   // paths to ini files\r
660   m_rc_path = NULL;\r
661   m_inipath = NULL;\r
662   m_bWatchBSP = TRUE;\r
663   m_bLeakStop = TRUE;\r
664   m_iTimeout = 15;\r
665   m_bRunQuake = TRUE;\r
666   m_bDoSleep = FALSE;\r
667   m_nSubdivisions = 4;\r
668   // not prefs\r
669   m_bFloatingZ = FALSE;\r
670   m_bGlPtWorkaround = FALSE;    // Gef: Kyro/GL_POINTS workaround 25-aug-2001\r
671 #ifdef _WIN32\r
672   m_bNativeGUI = FALSE;\r
673   m_bStartOnPrimMon = FALSE;\r
674 #endif\r
675   m_global_rc_path = NULL;\r
676 #ifdef _WIN32\r
677   m_bUseWin32Editor = TRUE;\r
678 #else\r
679   // custom shader editor options\r
680   m_bUseCustomEditor = FALSE;\r
681   m_strEditorCommand = "";\r
682 #endif\r
683   m_nLightRadiuses = 1;\r
684   m_bQ3Map2Texturing = TRUE;\r
685 #ifdef ATIHACK_812\r
686         m_bGlATIHack = FALSE;\r
687 #endif\r
688 }\r
689 \r
690 /*!\r
691 =========================================================\r
692 Games selection dialog\r
693 =========================================================\r
694 */\r
695 \r
696 CGameDescription::CGameDescription(xmlDocPtr pDoc, const Str &GameFile)\r
697 {\r
698   char *p, *prop;\r
699   mpDoc = pDoc;\r
700   // read the user-friendly game name \r
701   xmlNodePtr pNode = mpDoc->children;\r
702 \r
703   while (strcmp((const char*)pNode->name, "game") && pNode != NULL) pNode=pNode->next;\r
704   if (!pNode)\r
705   {\r
706     ///< \todo add the file name (this node and gametools should all be part of CGameDescription anyway)\r
707     Error("Didn't find 'game' node in the game description file '%s'\n", pDoc->URL);\r
708   }\r
709   // on win32, game tools path can now be specified relative to the exe's cwd\r
710   prop = (char*)xmlGetProp( pNode, (xmlChar*)"gametools" );\r
711   if ( prop == NULL ) {\r
712           Error( "Didn't find 'gametools' node in the game description file '%s'\n", pDoc->URL );\r
713   }\r
714   {\r
715         char full[PATH_MAX];\r
716 #ifdef _WIN32\r
717         _fullpath( full, prop, PATH_MAX );\r
718 #else\r
719     strncpy( full, prop, PATH_MAX );\r
720 #endif\r
721     xmlFree( prop );\r
722     prop = NULL;\r
723     for ( p = full; *p != '\0'; p++ ) {\r
724           if ( *p == '\\' ) {\r
725             *p = '/';\r
726           }\r
727           mGameToolsPath = full;\r
728           if ( p != full && *(p-1) != '/' ) {\r
729             mGameToolsPath += "/";\r
730           }\r
731     }\r
732   }\r
733 \r
734   prop = (char*)xmlGetProp(pNode, (xmlChar*)"name");\r
735   if (prop == NULL)\r
736   {\r
737     Sys_FPrintf(SYS_WRN, "Warning, 'name' attribute not found in '%s'\n", pDoc->URL);\r
738     mGameName = pDoc->URL;\r
739   }\r
740   else\r
741   {\r
742     mGameName = prop;\r
743     xmlFree(prop);\r
744   }\r
745 \r
746   mGameFile = GameFile;\r
747 \r
748   prop = (char*)xmlGetProp(pNode, (xmlChar*)"basegame");\r
749   if (prop == NULL)\r
750   {\r
751     // default\r
752     mBaseGame = "baseq3";\r
753   }\r
754   else\r
755   {\r
756     mBaseGame = prop;\r
757     xmlFree(prop);\r
758   }\r
759 \r
760   // on win32, engine path can now be specified relative to the exe's cwd\r
761   prop = (char*)xmlGetProp(pNode, (const xmlChar *)"enginepath");\r
762   if ( prop != NULL ) {\r
763     char full[PATH_MAX];\r
764 #ifdef _WIN32\r
765         _fullpath( full, prop, PATH_MAX );\r
766 #else\r
767         strncpy( full, prop, PATH_MAX );\r
768 #endif\r
769     xmlFree( prop );\r
770         prop = NULL;\r
771     // process seperators\r
772     for ( p = full; *p != '\0'; p++ ) {\r
773           if ( *p == '\\' ) {\r
774             *p = '/';\r
775           }\r
776         }\r
777     mEnginePath = full;\r
778         if ( p != full && *(p-1) != '/' ) {\r
779           mEnginePath += "/";\r
780         }\r
781   }\r
782   else\r
783   {\r
784     // if engine path was not specified in the .game, it implies we can guess it from the gametools path\r
785     // on win32, and for most game package, the gametools are installed with the game\r
786     char aux_path[PATH_MAX]; // aux\r
787     strcpy( aux_path, mGameToolsPath.GetBuffer() );\r
788         if ( ( aux_path[ strlen(aux_path)-1 ] == '/' ) || ( aux_path[ strlen(aux_path)-1 ] == '\\' ) ) {\r
789       aux_path[strlen(aux_path)-1] = '\0'; // strip ending '/' if any\r
790         }\r
791     char up_path[PATH_MAX]; // up one level\r
792     ExtractFilePath( aux_path, up_path );\r
793     mEnginePath = up_path;\r
794   }\r
795 \r
796   prop = (char*)xmlGetProp(pNode, (xmlChar*)"engine");\r
797   if (prop == NULL)\r
798   {\r
799 #ifdef _WIN32\r
800     mEngine = "quake3.exe";\r
801 #elif __linux__\r
802     mEngine = "quake3";\r
803 #elif __APPLE__\r
804     mEngine = "Quake3.app";\r
805 #endif\r
806   }\r
807   else\r
808   {\r
809     mEngine = prop;\r
810     xmlFree(prop);\r
811   }\r
812 \r
813 #if defined (__linux__) || defined (__APPLE__)\r
814   // *nix specific\r
815   prop = (char*)xmlGetProp(pNode, (const xmlChar *)"prefix");\r
816   if(prop != NULL)\r
817   {\r
818     mUserPathPrefix = prop;\r
819     xmlFree(prop);\r
820   }\r
821 #endif\r
822   mShaderPath = xmlGetProp(pNode, (const xmlChar *)"shaderpath");\r
823   if (!mShaderPath.GetLength())\r
824   {\r
825     mShaderPath = "scripts/";\r
826     mShaderlist = "scripts/shaderlist.txt";\r
827   }\r
828   else\r
829   {\r
830     AddSlash(mShaderPath);\r
831     mShaderlist = mShaderPath;\r
832     mShaderlist += "shaderlist.txt";\r
833   }\r
834   xmlChar* default_scale = xmlGetProp(pNode, (const xmlChar *)"default_scale");\r
835   if (default_scale)\r
836   {\r
837     mTextureDefaultScale = atof((const char *)default_scale);\r
838     xmlFree(default_scale);\r
839   }\r
840   else\r
841     mTextureDefaultScale = 0.5f;\r
842   xmlChar* eclass_singleload = xmlGetProp(pNode, (const xmlChar*)"eclass_singleload");\r
843   if (eclass_singleload)\r
844   {\r
845     mEClassSingleLoad = true;\r
846     xmlFree(eclass_singleload);\r
847   }\r
848   else\r
849     mEClassSingleLoad = false;\r
850   xmlChar* no_patch = xmlGetProp(pNode, (const xmlChar *)"no_patch");\r
851   if (no_patch)\r
852   {\r
853     mNoPatch = true;\r
854     xmlFree(no_patch);\r
855   }\r
856   else\r
857     mNoPatch = false;\r
858   xmlChar* caulk_shader = xmlGetProp(pNode, (const xmlChar *)"caulk_shader");\r
859   if (caulk_shader)\r
860   {\r
861     mCaulkShader = caulk_shader;\r
862     xmlFree(caulk_shader);\r
863   }\r
864   else\r
865     mCaulkShader = "textures/common/caulk";\r
866 }\r
867 \r
868 void CGameDescription::Dump()\r
869 {\r
870 #ifdef _WIN32\r
871   if (CGameDialog::GetNetrun())\r
872     Sys_Printf("Running in network mode, prefs path set to '%s'\n", g_strTempPath.GetBuffer());\r
873 #endif\r
874   Sys_Printf("game name            : '%s'\n", mGameName.GetBuffer());\r
875   Sys_Printf("game file            : '%s'\n", mGameFile.GetBuffer());\r
876   Sys_Printf("game path            : '%s'\n", mGameToolsPath.GetBuffer());\r
877   Sys_Printf("base game            : '%s'\n", mBaseGame.GetBuffer());\r
878   Sys_Printf("engine path          : '%s'\n", mEnginePath.GetBuffer());\r
879   Sys_Printf("engine               : '%s'\n", mEngine.GetBuffer());\r
880   Sys_Printf("shaderlist           : '%s'\n", mShaderlist.GetBuffer());\r
881   Sys_Printf("caulk shader: '%s'\n", mCaulkShader.GetBuffer());\r
882 #if defined (__linux__) || defined (__APPLE__)\r
883   Sys_Printf("prefix               : '%s'\n", mUserPathPrefix.GetBuffer());\r
884 #endif\r
885   Sys_Printf("default texture scale: %g\n", mTextureDefaultScale);\r
886   Sys_Printf("single eclass load   : %s\n", mEClassSingleLoad ? "Yes" : "No");\r
887   Sys_Printf("patches supported    : %s\n", mNoPatch ? "No" : "Yes");\r
888 }\r
889 \r
890 CPrefAssignment& CPrefAssignment::operator = (const CPrefAssignment& ass)\r
891 {\r
892   if (&ass != this)\r
893   {\r
894     mName = ass.mName;\r
895     mType = ass.mType;\r
896     mVal = ass.mVal;\r
897   }\r
898   return *this;\r
899 }\r
900 \r
901 CPrefAssignment::CPrefAssignment(const CPrefAssignment& ass)\r
902 {\r
903   *this = ass;\r
904 }\r
905 \r
906 void CGameDialog::LoadPrefs()\r
907 {\r
908   bool bEmpty = false;\r
909 \r
910   // if we already have a document loaded, we will free and reload from file\r
911   if (mGlobalPrefs.InUse())\r
912   {\r
913     Sys_Printf("Reloading global prefs from file\n");\r
914     mGlobalPrefs.Clear();\r
915   }\r
916 \r
917   // load global .pref file\r
918   CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;\r
919   strGlobalPref += "global.pref";\r
920 \r
921   mGlobalPrefs.ReadXMLFile(strGlobalPref.GetBuffer());\r
922 \r
923   mGlobalPrefs.GetPref("gamefile", &m_sGameFile, ""); // NOTE: there's no default, user HAS to select something\r
924   mGlobalPrefs.GetPref("autoload", &m_bAutoLoadGame, false);\r
925   mGlobalPrefs.GetPref("log console", &m_bLogConsole, false);\r
926   // in a very particular post-.pid startup\r
927   // we may have the console turned on and want to keep it that way\r
928   // so we use a latching system\r
929   if (m_bForceLogConsole)\r
930   {\r
931     m_bLogConsole = true;\r
932     Sys_Printf("console logging has been latched on, saving prefs\n");\r
933     SavePrefs();\r
934     m_bForceLogConsole = false;\r
935   }\r
936 \r
937   // console logging: call Sys_LogConsole to check console logging status\r
938   // it is important that we would log console as early as possible to make it useful\r
939   Sys_LogFile();\r
940 \r
941   if (mGlobalPrefs.mbEmpty)\r
942   {\r
943     Sys_Printf("Saving global.pref with default pref values\n");\r
944     SavePrefs();\r
945   }\r
946 }\r
947 \r
948 void CGameDialog::SavePrefs()\r
949 {\r
950   // update the tree and save it\r
951   mGlobalPrefs.UpdatePrefTree();\r
952   \r
953   CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;\r
954   strGlobalPref += "global.pref";\r
955   \r
956   if (!mGlobalPrefs.WriteXMLFile(strGlobalPref.GetBuffer()))\r
957     Sys_FPrintf(SYS_ERR, "Error occured while saving global prefs file '%s'\n", strGlobalPref.GetBuffer());\r
958 }\r
959 \r
960 void CGameDialog::DoGameDialog()\r
961 {\r
962   // show the UI\r
963   DoModal();\r
964 \r
965   // unhook so we can use in other places\r
966   // we manually incref'ed it when creating, it won't be freed (destructor)\r
967   gtk_container_remove (GTK_CONTAINER (mTopBox), GetGlobalFrame());\r
968 \r
969   // we save the prefs file\r
970   SavePrefs();\r
971 }\r
972 \r
973 GtkWidget* CGameDialog::GetGlobalFrame()\r
974 {\r
975   GtkWidget *vbox, *text, *combo, *check;\r
976 \r
977   if (mFrame)\r
978     return mFrame;\r
979 \r
980   mFrame = gtk_frame_new(NULL);\r
981   gtk_container_set_border_width(GTK_CONTAINER(mFrame), 5);\r
982   gtk_widget_show(mFrame);\r
983 \r
984   vbox = gtk_vbox_new (FALSE, 6);\r
985   gtk_widget_show (vbox);\r
986   gtk_container_add (GTK_CONTAINER (mFrame), vbox);\r
987   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);\r
988 \r
989   text = gtk_label_new("Select the game:");\r
990   gtk_widget_show(text);\r
991   gtk_box_pack_start (GTK_BOX(vbox), text, FALSE, FALSE, 0);\r
992 \r
993   combo = gtk_combo_new();\r
994   gtk_widget_show(combo);\r
995   gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);\r
996 \r
997   // fill in with the game descriptions\r
998   GList *combo_list = (GList*)NULL;\r
999   list<CGameDescription *>::iterator iGame;\r
1000   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)\r
1001   {\r
1002     combo_list = g_list_append (combo_list, (void *)(*iGame)->mGameName.GetBuffer());\r
1003   }\r
1004   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);\r
1005   g_list_free (combo_list);\r
1006 \r
1007   AddDialogData (combo, &m_nComboSelect, DLG_COMBO_INT);\r
1008 \r
1009   check = gtk_check_button_new_with_label("Auto load selected game on startup");\r
1010   gtk_widget_show(check);\r
1011   gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1012   AddDialogData (check, &m_bAutoLoadGame, DLG_CHECK_BOOL);\r
1013   \r
1014   text = gtk_label_new("(this frame is available in the prefs menu if you set auto-select)");\r
1015   gtk_widget_show(text);\r
1016   gtk_box_pack_start (GTK_BOX(vbox), text, FALSE, FALSE, 0);\r
1017 \r
1018 #ifdef _WIN32\r
1019   check = gtk_check_button_new_with_label("Networked install - per-user settings");\r
1020   gtk_widget_show(check);\r
1021   gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1022   AddDialogData (check, &m_bNetRun, DLG_CHECK_BOOL);\r
1023 #endif\r
1024 \r
1025   check = gtk_check_button_new_with_label("Log the console to radiant.log");\r
1026   gtk_widget_show(check);\r
1027   gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1028   AddDialogData (check, &m_bLogConsole, DLG_CHECK_BOOL);\r
1029 \r
1030   // incref it so we can pass it around\r
1031   gtk_widget_ref (GTK_WIDGET(mFrame));\r
1032 \r
1033   return mFrame;\r
1034 }\r
1035 \r
1036 void CGameDialog::UpdateData (bool retrieve)\r
1037 {\r
1038   if (!retrieve)\r
1039   {\r
1040     // use m_sGameFile to set m_nComboSelect\r
1041     list<CGameDescription *>::iterator iGame;\r
1042     int i = 0;\r
1043     for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)\r
1044     {\r
1045       if ((*iGame)->mGameFile == m_sGameFile)\r
1046       {\r
1047         m_nComboSelect = i;\r
1048         break;\r
1049       }\r
1050       i++;\r
1051     }\r
1052 #ifdef _WIN32\r
1053     UpdateNetrun(false);\r
1054 #endif\r
1055   }\r
1056   Dialog::UpdateData(retrieve);\r
1057   if (retrieve)\r
1058   {\r
1059     // use m_nComboSelect to set m_sGameFile\r
1060     list<CGameDescription *>::iterator iGame = mGames.begin();\r
1061     int i;\r
1062     for(i=0; i<m_nComboSelect; i++)\r
1063     {\r
1064       iGame++;\r
1065     }\r
1066     m_sGameFile = (*iGame)->mGameFile;\r
1067 #ifdef _WIN32\r
1068     UpdateNetrun(true);\r
1069 #endif\r
1070   }\r
1071 }\r
1072 \r
1073 void CGameDialog::BuildDialog()\r
1074 {\r
1075   GtkWidget *dlg, *vbox1, *button;\r
1076 \r
1077   dlg = m_pWidget;\r
1078   gtk_window_set_title (GTK_WINDOW (dlg), "Select Game");\r
1079 \r
1080   vbox1 = gtk_vbox_new (FALSE, 0);\r
1081   gtk_widget_show(vbox1);\r
1082   gtk_container_add (GTK_CONTAINER (dlg), vbox1);\r
1083 \r
1084   gtk_container_add (GTK_CONTAINER (vbox1), GetGlobalFrame());\r
1085   mTopBox = vbox1;\r
1086 \r
1087   button = gtk_button_new_with_label ("OK");\r
1088   gtk_widget_show (button);\r
1089   gtk_box_pack_start (GTK_BOX (vbox1), button, FALSE, FALSE, 0);\r
1090   AddModalButton(button, IDOK);\r
1091   gtk_widget_set_usize (button, 60, -2);\r
1092 }\r
1093 \r
1094 void CGameDialog::ScanForGames()\r
1095 {\r
1096   CString strPath;\r
1097   char *dirlist;\r
1098   GDir *dir;\r
1099   CString strGamesPath = g_strAppPath.GetBuffer();\r
1100   strGamesPath += "games";\r
1101   const char *path = strGamesPath.GetBuffer();\r
1102 \r
1103   Sys_Printf("Scanning for game description files: %s\n", path);\r
1104 \r
1105   /*!\r
1106   \todo FIXME LINUX:\r
1107   do we put game description files below g_strAppPath, or in ~/.radiant\r
1108   i.e. read only or read/write?\r
1109   my guess .. readonly cause it's an install\r
1110   we will probably want to add ~/.radiant/<version>/games/ scanning on top of that for developers\r
1111   (if that's really needed)\r
1112   */\r
1113 \r
1114   // FIXME need to catch the 'no game description' situation and exit with a clean error\r
1115 \r
1116   dir = g_dir_open(path, 0, NULL);\r
1117 \r
1118   if (dir != NULL)\r
1119   {\r
1120     while (1)\r
1121     {\r
1122       const gchar* name = g_dir_read_name(dir);\r
1123       if(name == NULL)\r
1124         break;\r
1125 \r
1126       dirlist = g_strdup(name);\r
1127 #ifdef _WIN32\r
1128       strlwr (dirlist);\r
1129 #endif\r
1130       char *ext = strrchr (dirlist, '.');\r
1131       if ((ext == NULL) || (strcmp (ext, ".game") != 0))\r
1132         continue;\r
1133       strPath.Format("%s/%s", path, dirlist);\r
1134       Sys_Printf("%s\n", strPath.GetBuffer());\r
1135       // got one, load it\r
1136       xmlDocPtr pDoc = xmlParseFile(strPath.GetBuffer());\r
1137       if (pDoc)\r
1138       {\r
1139         mGames.push_front(new CGameDescription(pDoc, dirlist));\r
1140       }\r
1141       else\r
1142       {\r
1143         Sys_FPrintf(SYS_ERR, "XML parser failed on '%s'\n", strPath.GetBuffer());\r
1144       }\r
1145 \r
1146       g_free(dirlist);\r
1147     }\r
1148     g_dir_close (dir);\r
1149   }\r
1150 }\r
1151 \r
1152 CGameDescription* CGameDialog::GameDescriptionForComboItem()\r
1153 {\r
1154   list<CGameDescription *>::iterator iGame;\r
1155   int i=0;\r
1156   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++,i++)\r
1157   {\r
1158     if (i == m_nComboSelect)\r
1159     {\r
1160       return (*iGame);\r
1161     }\r
1162   }\r
1163   return NULL; // not found\r
1164 }\r
1165 \r
1166 /*GString* CGameDialog::InitGlobalPrefPath()\r
1167 {\r
1168   GString* global_rc_path;\r
1169   // configure m_global_rc_path\r
1170 #if defined (__linux__) || defined (__APPLE__)\r
1171   global_rc_path = g_string_new (g_get_home_dir ());\r
1172 \r
1173   if (global_rc_path->str[global_rc_path->len-1] != '/')\r
1174     g_string_append (global_rc_path, "/");\r
1175 \r
1176   g_string_append (global_rc_path, ".radiant/");\r
1177   mkdir (global_rc_path->str, 0775);\r
1178   g_string_append (global_rc_path, RADIANT_VERSION);\r
1179   g_string_append (global_rc_path, "/");\r
1180   mkdir (global_rc_path->str, 0775);\r
1181 #elif WIN32\r
1182   global_rc_path = g_string_new (g_strAppPath.GetBuffer() );\r
1183 #else\r
1184 #error "WTF are you compiling under"\r
1185 #endif\r
1186   return global_rc_path;\r
1187 }*/\r
1188 \r
1189 void CGameDialog::InitGlobalPrefPath()\r
1190 {\r
1191   GString *global_rc_path;\r
1192   // configure m_global_rc_path\r
1193   // this is the g_strTempPath, and it has already been mkdir'ed\r
1194   global_rc_path = g_string_new(g_strTempPath.GetBuffer());\r
1195   g_PrefsDlg.m_global_rc_path = global_rc_path;\r
1196 }\r
1197 \r
1198 void CGameDialog::Reset()\r
1199 {\r
1200   if (!g_PrefsDlg.m_global_rc_path)\r
1201     InitGlobalPrefPath();\r
1202   CString strGlobalPref = g_PrefsDlg.m_global_rc_path->str;\r
1203   strGlobalPref += "global.pref";\r
1204   remove(strGlobalPref.GetBuffer());\r
1205 }\r
1206 \r
1207 void CGameDialog::Init()\r
1208 {\r
1209   InitGlobalPrefPath();\r
1210   ScanForGames();\r
1211   if (mGames.empty())\r
1212   {\r
1213     Error("Didn't find any valid game file descriptions, aborting\n");\r
1214   }\r
1215   LoadPrefs();\r
1216   if (m_bAutoLoadGame)\r
1217   {\r
1218     // search by .game name\r
1219     list<CGameDescription *>::iterator iGame;\r
1220     for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)\r
1221     {\r
1222       if ((*iGame)->mGameFile == m_sGameFile)\r
1223       {\r
1224         m_pCurrentGameDescription = (*iGame);\r
1225         break;\r
1226       }\r
1227     }\r
1228   }\r
1229   if (!m_bAutoLoadGame || !m_pCurrentGameDescription)\r
1230   {\r
1231     DoGameDialog();\r
1232     // use m_nComboSelect to identify the game to run as and set the globals\r
1233     m_pCurrentGameDescription = GameDescriptionForComboItem();\r
1234     if (!m_pCurrentGameDescription)\r
1235       Error("Lookup of game description object failed, can't continue\n");\r
1236   }\r
1237   g_pGameDescription = m_pCurrentGameDescription;\r
1238 \r
1239   g_strGameToolsPath = g_pGameDescription->mGameToolsPath;\r
1240 \r
1241         // NOTE TTimo: this is moved from QE_LoadProject in 1.2\r
1242         // (probably broken)\r
1243   // NOTE Hydra: was broken for win32, we don't use m_strHomeGame or m_strFSBasePath\r
1244 #if defined (__linux__) || defined (__APPLE__)\r
1245   g_qeglobals.m_strHomeGame = g_get_home_dir();\r
1246   g_qeglobals.m_strHomeGame += "/";\r
1247   g_qeglobals.m_strHomeGame += m_pCurrentGameDescription->mUserPathPrefix.GetBuffer();\r
1248   g_qeglobals.m_strHomeGame += "/";\r
1249 #else\r
1250   g_qeglobals.m_strHomeGame = g_pGameDescription->mEnginePath.GetBuffer();\r
1251 #endif\r
1252   \r
1253   g_pGameDescription->Dump();\r
1254 }\r
1255 \r
1256 CGameDialog::~CGameDialog()\r
1257 {\r
1258   if (mFrame)\r
1259   {\r
1260     // NOTE I'm not too sure how reliable this is\r
1261     gtk_widget_unref(GTK_WIDGET(mFrame));\r
1262   }\r
1263   // free all the game descriptions\r
1264   list<CGameDescription *>::iterator iGame;\r
1265   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)\r
1266   {\r
1267     delete (*iGame);\r
1268     *iGame = NULL;\r
1269   }\r
1270 }\r
1271 \r
1272 void CGameDialog::AddPacksURL(Str &URL)\r
1273 {\r
1274   // add the URLs for the list of game packs installed\r
1275   // FIXME: this is kinda hardcoded for now..\r
1276   list<CGameDescription *>::iterator iGame;\r
1277   for(iGame=mGames.begin(); iGame!=mGames.end(); iGame++)\r
1278   {  \r
1279     if ((*iGame)->mGameFile == "q3.game")      \r
1280       URL += "&Games_dlup%5B%5D=1";\r
1281     else if ((*iGame)->mGameFile == "wolf.game")\r
1282       URL += "&Games_dlup%5B%5D=2";\r
1283     else if ((*iGame)->mGameFile == "wolf.game")\r
1284       URL += "&Games_dlup%5B%5D=3";\r
1285     else if ((*iGame)->mGameFile == "jk2.game")\r
1286       URL += "&Games_dlup%5B%5D=4";\r
1287     else if ((*iGame)->mGameFile == "stvef.game")\r
1288       URL += "&Games_dlup%5B%5D=5";\r
1289     else if ((*iGame)->mGameFile == "sof2.game")\r
1290       URL += "&Games_dlup%5B%5D=6";\r
1291     else if ((*iGame)->mGameFile == "ja.game")\r
1292       URL += "&Games_dlup%5B%5D=7";\r
1293   }\r
1294 }\r
1295 \r
1296 #ifdef _WIN32\r
1297 \r
1298 #define NETRUN_FILENAME "netrun.conf"\r
1299 \r
1300 bool CGameDialog::m_bNetRun;\r
1301 \r
1302 void CGameDialog::UpdateNetrun(bool retrieve)\r
1303 {\r
1304   FILE *f_netrun;\r
1305   CString strNetrun;\r
1306   strNetrun = g_strAppPath; strNetrun += NETRUN_FILENAME;\r
1307   if (!retrieve)\r
1308   {\r
1309     // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=639\r
1310     // now check if we are running from a network installation\r
1311     // use a dummy file as the flag\r
1312     f_netrun = fopen(strNetrun.GetBuffer(), "r");\r
1313     if (f_netrun)\r
1314     {\r
1315       fclose(f_netrun);\r
1316       m_bNetRun = true;\r
1317     }\r
1318     else\r
1319       m_bNetRun = false;\r
1320   }\r
1321   else\r
1322   {\r
1323     if (m_bNetRun)\r
1324     {\r
1325       f_netrun = fopen(strNetrun.GetBuffer(), "w");\r
1326       if (!f_netrun)\r
1327       {\r
1328         Sys_FPrintf(SYS_ERR, "ERROR: Failed to create netrun file '%s'\n", strNetrun.GetBuffer());\r
1329         m_bNetRun = false;\r
1330       }\r
1331       else\r
1332       {\r
1333         fclose(f_netrun);\r
1334         Sys_Printf("Created/Checked '%s'\n", strNetrun.GetBuffer());\r
1335       }\r
1336     }\r
1337     else\r
1338     {\r
1339       if (remove(strNetrun.GetBuffer()) == -1)\r
1340       {\r
1341         if (errno != ENOENT)\r
1342           Sys_FPrintf(SYS_ERR, "Failed to remove netrun file '%s'\n", strNetrun.GetBuffer());\r
1343         m_bNetRun = true;\r
1344       }\r
1345       else\r
1346       {\r
1347         Sys_Printf("Netrun mode is disabled\n");\r
1348       }\r
1349     }\r
1350   }\r
1351 }\r
1352 \r
1353 bool CGameDialog::GetNetrun()\r
1354 {\r
1355   return m_bNetRun;\r
1356 }\r
1357 #endif\r
1358 \r
1359 /*\r
1360 ========\r
1361 \r
1362 very first prefs init deals with selecting the game and the game tools path\r
1363 then we can load .ini stuff\r
1364 \r
1365 using prefs / ini settings:\r
1366 those are per-game\r
1367 \r
1368 win32:\r
1369 look in g_strGameToolsPath for .ini\r
1370 \r
1371 linux:\r
1372 look in ~/.radiant/<version>/gamename\r
1373 ========\r
1374 */\r
1375 \r
1376 #define PREFS_LOCAL_FILENAME "local.pref"\r
1377 \r
1378 void PrefsDlg::Init()\r
1379 {\r
1380   mGamesDialog.Init();\r
1381 \r
1382   // m_global_rc_path has been set above, do m_rc_path with game specific stuff now\r
1383   // the win32 and linux versions have been unified for network mode\r
1384 #ifdef _WIN32\r
1385   if (!CGameDialog::GetNetrun())\r
1386   {\r
1387     // legacy prefs settings, this goes where the game pack is installed\r
1388     m_rc_path = g_string_new (g_strGameToolsPath.GetBuffer() );\r
1389     m_inipath = g_string_new (m_rc_path->str);\r
1390     g_string_append (m_inipath, PREFS_LOCAL_FILENAME);\r
1391     return;\r
1392   }\r
1393 #endif\r
1394   // this is common to win32 and Linux init now\r
1395   m_rc_path = g_string_new (m_global_rc_path->str);\r
1396   \r
1397   // game sub-dir\r
1398   g_string_append (m_rc_path, g_pGameDescription->mGameFile.GetBuffer());\r
1399   g_string_append (m_rc_path, "/");\r
1400   Q_mkdir (m_rc_path->str, 0775);\r
1401   \r
1402   // then the ini file\r
1403   m_inipath = g_string_new (m_rc_path->str);\r
1404   g_string_append (m_inipath, PREFS_LOCAL_FILENAME);\r
1405   \r
1406 }\r
1407 \r
1408 void PrefsDlg::UpdateData (bool retrieve)\r
1409 {\r
1410   // leo: the "changed" signal confuses the update function\r
1411   if (m_pWidget == NULL)\r
1412     return;\r
1413   mGamesDialog.UpdateData (retrieve);\r
1414   Dialog::UpdateData (retrieve);\r
1415 }\r
1416 \r
1417 #ifdef _WIN32\r
1418 #define PREFSHSPACE 5\r
1419 #else\r
1420 #define PREFSHSPACE 0\r
1421 #endif\r
1422 \r
1423 static void UpdateSensitivity( GtkWidget *widget, gpointer data )\r
1424 {\r
1425   PrefsDlg *dlg = (PrefsDlg*)data;\r
1426   dlg->DoSensitivity();\r
1427 }\r
1428 \r
1429 static void UpdateEditorSensitivity(GtkWidget *widget, gpointer data)\r
1430 {\r
1431   PrefsDlg *dlg = (PrefsDlg*)data;\r
1432   dlg->DoEditorSensitivity();\r
1433 }\r
1434 \r
1435 // start new prefs dialog\r
1436 \r
1437 /*! Utility function for swapping notebook pages for tree list selections */\r
1438 void PrefsDlg::showPrefPage(int prefpage)\r
1439 {\r
1440   if(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) != prefpage)\r
1441     gtk_notebook_set_page(GTK_NOTEBOOK(notebook), prefpage);\r
1442   \r
1443   return;\r
1444 }\r
1445 \r
1446 static void treeSelection(GtkTreeSelection* selection, gpointer data)\r
1447 {\r
1448   PrefsDlg *dlg = (PrefsDlg*)data;\r
1449 \r
1450   GtkTreeModel* model;\r
1451   GtkTreeIter selected;\r
1452   if(gtk_tree_selection_get_selected(selection, &model, &selected))\r
1453   {\r
1454     int prefpage;\r
1455     gtk_tree_model_get(model, &selected, 1, (gpointer*)&prefpage, -1);\r
1456     dlg->showPrefPage(prefpage);\r
1457   }\r
1458 }\r
1459 \r
1460 void PrefsDlg::BuildDialog ()\r
1461 {\r
1462   // Main Preferences dialog\r
1463   GtkWidget *dialog, *mainvbox, *hbox, *sc_win, *preflabel;\r
1464 \r
1465   // Widgets on notebook pages\r
1466   GtkWidget *check, *label, *scale, *hbox2, *combo,\r
1467             *table, *spin,  *entry, *pixmap,\r
1468             *radio, *button, *pageframe, *vbox;\r
1469   \r
1470   GList *combo_list = (GList*)NULL;\r
1471   \r
1472   GtkObject *adj;\r
1473     \r
1474   dialog = m_pWidget;\r
1475   gtk_window_set_title(GTK_WINDOW(dialog), "GtkRadiant Preferences");\r
1476   gtk_widget_realize(dialog);\r
1477     \r
1478   mainvbox = gtk_vbox_new(FALSE, 5);\r
1479   gtk_container_add(GTK_CONTAINER(dialog), mainvbox);\r
1480   gtk_container_set_border_width(GTK_CONTAINER(mainvbox), 5);\r
1481   gtk_widget_show(mainvbox);\r
1482   \r
1483   hbox = gtk_hbox_new(FALSE, 5);\r
1484   gtk_widget_show(hbox);\r
1485   gtk_box_pack_end(GTK_BOX(mainvbox), hbox, FALSE, TRUE, 0);\r
1486 \r
1487   button = gtk_button_new_with_label("OK");\r
1488   gtk_widget_show(button);\r
1489   gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);\r
1490   gtk_widget_set_usize(button, 60, -2);\r
1491   AddModalButton(button, IDOK);\r
1492 \r
1493   button = gtk_button_new_with_label("Cancel");\r
1494   gtk_widget_show(button);\r
1495   gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);\r
1496   gtk_widget_set_usize(button, 60, -2);\r
1497   AddModalButton (button, IDCANCEL);\r
1498 \r
1499   button = gtk_button_new_with_label ("Clean");\r
1500   gtk_widget_show(button);\r
1501   gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(OnButtonClean), this);\r
1502   gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);\r
1503   gtk_widget_set_usize (button, 60, -2);\r
1504   \r
1505   hbox = gtk_hbox_new(FALSE, 5);\r
1506   gtk_box_pack_start(GTK_BOX(mainvbox), hbox, TRUE, TRUE, 0);\r
1507   gtk_widget_show(hbox);\r
1508   \r
1509   sc_win = gtk_scrolled_window_new(NULL, NULL);\r
1510   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);\r
1511   gtk_box_pack_start(GTK_BOX(hbox), sc_win, FALSE, FALSE, 0);\r
1512   gtk_widget_show(sc_win);\r
1513 \r
1514   // prefs pages notebook\r
1515   notebook = gtk_notebook_new();\r
1516   // hide the notebook tabs since its not supposed to look like a notebook\r
1517   gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);\r
1518   gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 0);\r
1519   gtk_widget_show(notebook);\r
1520 \r
1521   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_win), GTK_SHADOW_IN);\r
1522 \r
1523   {\r
1524     GtkTreeStore* store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);\r
1525 \r
1526     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));\r
1527     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);\r
1528 \r
1529     {\r
1530       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();\r
1531       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Preferences", renderer, "text", 0, NULL);\r
1532       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);\r
1533     }\r
1534 \r
1535     {\r
1536       GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));\r
1537       g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(treeSelection), this);\r
1538     }\r
1539 \r
1540     gtk_widget_show(view);\r
1541 \r
1542     gtk_container_add(GTK_CONTAINER (sc_win), view);\r
1543 \r
1544     {\r
1545       /********************************************************************/\r
1546       /* Add preference tree options                                      */\r
1547       /********************************************************************/\r
1548       {\r
1549         GtkTreeIter group;\r
1550         gtk_tree_store_append(store, &group, NULL);\r
1551         gtk_tree_store_set(store, &group, 0, "Globals", 1, PTAB_FRONT, -1);\r
1552         {\r
1553           GtkTreeIter tab;\r
1554           gtk_tree_store_append(store, &tab, &group);\r
1555           gtk_tree_store_set(store, &tab, 0, "Game settings", 1, (gpointer)PTAB_GAME_SETTINGS, -1);\r
1556         }\r
1557       }\r
1558 \r
1559       {\r
1560         GtkTreeIter group;\r
1561         gtk_tree_store_append(store, &group, NULL);\r
1562         gtk_tree_store_set(store, &group, 0, "Display", 1, PTAB_FRONT, -1);\r
1563         {\r
1564           GtkTreeIter tab;\r
1565           gtk_tree_store_append(store, &tab, &group);\r
1566           gtk_tree_store_set(store, &tab, 0, "2D Display/Rendering", 1, (gpointer)PTAB_2D, -1);\r
1567         }\r
1568         {\r
1569           GtkTreeIter tab;\r
1570           gtk_tree_store_append(store, &tab, &group);\r
1571           gtk_tree_store_set(store, &tab, 0, "3D View", 1, (gpointer)PTAB_CAMERA, -1);\r
1572         }\r
1573         {\r
1574           GtkTreeIter tab;\r
1575           gtk_tree_store_append(store, &tab, &group);\r
1576           gtk_tree_store_set(store, &tab, 0, "Texture Settings", 1, (gpointer)PTAB_TEXTURE, -1);\r
1577         }\r
1578       }\r
1579   \r
1580       {\r
1581         GtkTreeIter group;\r
1582         gtk_tree_store_append(store, &group, NULL);\r
1583         gtk_tree_store_set(store, &group, 0, "Interface", 1, PTAB_FRONT, -1);\r
1584         {\r
1585           GtkTreeIter tab;\r
1586           gtk_tree_store_append(store, &tab, &group);\r
1587           gtk_tree_store_set(store, &tab, 0, "Layout", 1, (gpointer)PTAB_LAYOUT, -1);\r
1588         }\r
1589         {\r
1590           GtkTreeIter tab;\r
1591           gtk_tree_store_append(store, &tab, &group);\r
1592           gtk_tree_store_set(store, &tab, 0, "Mouse", 1, (gpointer)PTAB_MOUSE, -1);\r
1593         }\r
1594         {\r
1595           GtkTreeIter tab;\r
1596           gtk_tree_store_append(store, &tab, &group);\r
1597           gtk_tree_store_set(store, &tab, 0, "Editing", 1, (gpointer)PTAB_EDITING, -1);\r
1598         }\r
1599       }\r
1600   \r
1601       {\r
1602         GtkTreeIter group;\r
1603         gtk_tree_store_append(store, &group, NULL);\r
1604         gtk_tree_store_set(store, &group, 0, "Other", 1, PTAB_FRONT, -1);\r
1605         {\r
1606           GtkTreeIter tab;\r
1607           gtk_tree_store_append(store, &tab, &group);\r
1608           gtk_tree_store_set(store, &tab, 0, "Startup/Auto save", 1, (gpointer)PTAB_STARTUP, -1);\r
1609         }\r
1610         {\r
1611           GtkTreeIter tab;\r
1612           gtk_tree_store_append(store, &tab, &group);\r
1613           gtk_tree_store_set(store, &tab, 0, "Paths", 1, (gpointer)PTAB_PATHS, -1);\r
1614         }\r
1615         {\r
1616           GtkTreeIter tab;\r
1617           gtk_tree_store_append(store, &tab, &group);\r
1618           gtk_tree_store_set(store, &tab, 0, "Misc", 1, (gpointer)PTAB_MISC, -1);\r
1619         }\r
1620         if (!g_qeglobals.bBSPFrontendPlugin)\r
1621         {\r
1622           GtkTreeIter tab;\r
1623           gtk_tree_store_append(store, &tab, &group);\r
1624           gtk_tree_store_set(store, &tab, 0, "BSP Monitoring", 1, (gpointer)PTAB_BSPMONITOR, -1);\r
1625         }\r
1626       }\r
1627     }\r
1628 \r
1629     gtk_tree_view_expand_all(GTK_TREE_VIEW(view));\r
1630     \r
1631     g_object_unref(G_OBJECT(store));\r
1632   }\r
1633   \r
1634   /**********************************************************************/\r
1635   /* build the prefs pages                                              */\r
1636   /**********************************************************************/\r
1637   \r
1638   // Front page...\r
1639   // todo : add something interesting here\r
1640   // NOTE TTimo: tip of the day? or a logo?\r
1641   preflabel = gtk_label_new("Front Page");\r
1642   gtk_widget_show(preflabel);\r
1643   pageframe = gtk_frame_new(NULL);\r
1644   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
1645   gtk_widget_show(pageframe);\r
1646   vbox = gtk_vbox_new(FALSE, 5);\r
1647   gtk_widget_show(vbox);\r
1648   gtk_widget_set_usize(GTK_WIDGET(vbox), 350, -2);\r
1649   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
1650   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
1651   \r
1652   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
1653 \r
1654   /******** global preferences group ****************************/\r
1655   preflabel = gtk_label_new("Globals");\r
1656   gtk_widget_show(preflabel);\r
1657 \r
1658   pageframe = mGamesDialog.GetGlobalFrame();\r
1659   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
1660   \r
1661   /******** 2D prefs group (xy views/rendering options) *********/\r
1662   preflabel = gtk_label_new("2D Display");\r
1663   gtk_widget_show(preflabel);\r
1664   pageframe = gtk_frame_new("2D Display");\r
1665   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
1666   gtk_widget_show(pageframe);\r
1667   vbox = gtk_vbox_new(FALSE, 5);\r
1668   gtk_widget_show(vbox);\r
1669   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
1670   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
1671   \r
1672   // OpenGL Display Lists\r
1673   check = gtk_check_button_new_with_label("OpenGL Display Lists");\r
1674   gtk_widget_show(check);\r
1675   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1676   AddDialogData(check, &m_bDisplayLists, DLG_CHECK_BOOL);\r
1677   \r
1678   // Antialiased points & lines\r
1679   // Fishman - Add antialiazed points and lines support. 09/03/00\r
1680   check = gtk_check_button_new_with_label ("OpenGL antialiased points and lines");\r
1681   gtk_widget_show (check);\r
1682   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1683   AddDialogData (check, &m_bAntialiasedPointsAndLines, DLG_CHECK_BOOL);\r
1684   \r
1685   // Solid selection boxes\r
1686   check = gtk_check_button_new_with_label ("Solid selection boxes");\r
1687   gtk_widget_show (check);\r
1688   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1689   AddDialogData (check, &m_bNoStipple, DLG_CHECK_BOOL);\r
1690   \r
1691   // Display size info\r
1692   check = gtk_check_button_new_with_label ("Display size info");\r
1693   gtk_widget_show (check);\r
1694   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1695   AddDialogData (check, &m_bSizePaint, DLG_CHECK_BOOL);\r
1696 \r
1697   // Alternate vertex/edge handles\r
1698   // Gef: Kyro GL_POINT work around 25-aug-2001\r
1699   check = gtk_check_button_new_with_label ("Alternate vertex/edge handles");\r
1700   gtk_widget_show(check);\r
1701   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1702   AddDialogData(check, &m_bGlPtWorkaround, DLG_CHECK_BOOL);\r
1703 \r
1704   g_list_free (combo_list);\r
1705 \r
1706 #ifdef ATIHACK_812\r
1707         // ATI bugs\r
1708         // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=812\r
1709         check = gtk_check_button_new_with_label ("ATI cards with broken drivers - bug #802");\r
1710         gtk_widget_show(check);\r
1711         gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1712         AddDialogData(check, &m_bGlATIHack, DLG_CHECK_BOOL);\r
1713 #endif\r
1714   \r
1715   // Add the page to the notebook\r
1716   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
1717   \r
1718   /******** 3D Camera view group *********/\r
1719   preflabel = gtk_label_new("3D View");\r
1720   gtk_widget_show(preflabel);\r
1721   pageframe = gtk_frame_new("3D View");\r
1722   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
1723   gtk_widget_show(pageframe);\r
1724   vbox = gtk_vbox_new(FALSE, 5);\r
1725   gtk_widget_show(vbox);\r
1726   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
1727   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
1728 \r
1729   // Directional velocity (Movement Velocity)\r
1730   // label container\r
1731   hbox2 = gtk_hbox_new (FALSE, 0);\r
1732   gtk_widget_show (hbox2);\r
1733   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);\r
1734   \r
1735   // label\r
1736   label = gtk_label_new("Movement Velocity");\r
1737   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);\r
1738   gtk_widget_show(label);\r
1739   gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);\r
1740   \r
1741   // adjustment\r
1742   adj = gtk_adjustment_new(100, 50, 300, 1, 10, 10);\r
1743   AddDialogData(adj, &m_nMoveSpeed, DLG_ADJ_INT);\r
1744   \r
1745   // scale\r
1746   scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));\r
1747   gtk_widget_show(scale);\r
1748   gtk_box_pack_start(GTK_BOX (vbox), scale, FALSE, TRUE, 2);\r
1749   \r
1750   gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);\r
1751   \r
1752   // Angular velocity (Rotational Velocity)\r
1753   // label container\r
1754   hbox2 = gtk_hbox_new (FALSE, 0);\r
1755   gtk_widget_show (hbox2);\r
1756   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);\r
1757   \r
1758   // label\r
1759   label = gtk_label_new ("Rotational Velocity");\r
1760   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);\r
1761   gtk_widget_show (label);\r
1762   gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);\r
1763   \r
1764   // adjustment\r
1765   adj = gtk_adjustment_new (3, 1, 180, 1, 10, 10); // value, low, high, step, page_step, page_size\r
1766   AddDialogData (adj, &m_nAngleSpeed, DLG_ADJ_INT);\r
1767   \r
1768   // scale\r
1769   scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));\r
1770   gtk_widget_show (scale);\r
1771   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 2);\r
1772   gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);  \r
1773 \r
1774   // Text under the velocity sliders\r
1775   // container\r
1776   hbox2 = gtk_hbox_new (FALSE, 0);\r
1777   gtk_widget_show (hbox2);\r
1778   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);\r
1779   \r
1780   // label\r
1781   label = gtk_label_new ("slow");\r
1782   gtk_widget_show (label);\r
1783   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);\r
1784   \r
1785   // label\r
1786   label = gtk_label_new ("fast");\r
1787   gtk_widget_show (label);\r
1788   gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);\r
1789   \r
1790   // Allow drag to select multiple faces/brushes\r
1791   // container\r
1792   table = gtk_table_new(2, 1, FALSE);\r
1793   gtk_widget_show(table);\r
1794   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
1795   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
1796   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
1797 \r
1798   label = gtk_label_new ("Use paint-select in camera view:");\r
1799   gtk_widget_show (label);\r
1800   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);\r
1801   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,\r
1802                   (GtkAttachOptions) (0),\r
1803                   (GtkAttachOptions) (0), 0, 0);\r
1804 \r
1805   combo_list = NULL;\r
1806   combo_list = g_list_append (combo_list, (void *)"No");\r
1807   combo_list = g_list_append (combo_list, (void *)"Yes");\r
1808   combo_list = g_list_append (combo_list, (void *)"Yes (Classic Key Setup)");\r
1809 \r
1810   combo = gtk_combo_new ();\r
1811   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);\r
1812   gtk_widget_show (combo);\r
1813   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,\r
1814                   (GtkAttachOptions) (GTK_FILL),\r
1815                   (GtkAttachOptions) (0), 0, 0);\r
1816   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);\r
1817   AddDialogData (combo, &m_nCamDragMultiSelect, DLG_COMBO_INT);  \r
1818 \r
1819   // Freelook in Camera view\r
1820   check = gtk_check_button_new_with_label ("Freelook in Camera view");\r
1821   gtk_widget_show (check);\r
1822   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1823   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);\r
1824   AddDialogData (check, &m_bCamFreeLook, DLG_CHECK_BOOL);\r
1825 \r
1826   // Freelook in Camera view w/ forward & back strafing instead of up and down looking\r
1827   check = gtk_check_button_new_with_label ("Freelook strafes Forward and Back");\r
1828   gtk_widget_show (check);\r
1829   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1830   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);\r
1831   AddDialogData (check, &m_bCamFreeLookStrafe, DLG_CHECK_BOOL);\r
1832 \r
1833   // Invert mouse in freelook\r
1834   check = gtk_check_button_new_with_label ("Invert mouse in freelook");\r
1835   gtk_widget_show (check);\r
1836   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1837   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);\r
1838   AddDialogData (check, &m_bCamInverseMouse, DLG_CHECK_BOOL);\r
1839 \r
1840   // Discrete movement\r
1841   check = gtk_check_button_new_with_label ("Discrete movement");\r
1842   gtk_widget_show (check);\r
1843   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1844   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);\r
1845   AddDialogData (check, &m_bCamDiscrete, DLG_CHECK_BOOL);\r
1846 \r
1847   // Update XY views on camera move\r
1848   check = gtk_check_button_new_with_label ("Update XY views on camera move");\r
1849   gtk_widget_show (check);\r
1850   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1851   gtk_label_set_justify (GTK_LABEL (GTK_BIN (check)->child), GTK_JUSTIFY_LEFT);\r
1852   AddDialogData (check, &m_bCamXYUpdate, DLG_CHECK_BOOL);\r
1853 \r
1854   // Add the page to the notebook\r
1855   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
1856 \r
1857   /******** Texture group *********/\r
1858   preflabel = gtk_label_new("Textures");\r
1859   gtk_widget_show(preflabel);\r
1860   pageframe = gtk_frame_new("Textures");\r
1861   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
1862   gtk_widget_show(pageframe);\r
1863   vbox = gtk_vbox_new(FALSE, 6);\r
1864   gtk_widget_show(vbox);\r
1865   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
1866   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
1867   \r
1868   // Texture quality slider\r
1869   // label\r
1870   label = gtk_label_new ("Texture quality");\r
1871   gtk_widget_show (label);\r
1872   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);\r
1873   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);\r
1874   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);\r
1875   \r
1876   // adjustment\r
1877   adj = gtk_adjustment_new (0, 0, 4, 1, 1, 1);\r
1878   AddDialogData (adj, &m_nLatchedTextureQuality, DLG_ADJ_INT);\r
1879   \r
1880   // scale\r
1881   scale = gtk_hscale_new (GTK_ADJUSTMENT (adj));\r
1882   gtk_widget_show (scale);\r
1883   gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);\r
1884   gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);\r
1885 \r
1886   // text under the texture slider\r
1887   hbox2 = gtk_hbox_new (FALSE, 0);\r
1888   gtk_widget_show (hbox2);\r
1889   gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);\r
1890   label = gtk_label_new ("low");\r
1891   gtk_widget_show (label);\r
1892   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);\r
1893   label = gtk_label_new ("high");\r
1894   gtk_widget_show (label);\r
1895   gtk_box_pack_end (GTK_BOX (hbox2), label, FALSE, FALSE, 0);\r
1896 \r
1897   // texture subsets\r
1898   check = gtk_check_button_new_with_label ("Texture subsets");\r
1899   gtk_widget_show (check);\r
1900   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1901   AddDialogData (check, &m_bTextureWindow, DLG_CHECK_BOOL);\r
1902   \r
1903   // texture scrollbar\r
1904   check = gtk_check_button_new_with_label ("Texture scrollbar");\r
1905   gtk_widget_show (check);\r
1906   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
1907   AddDialogData (check, &m_bTextureScrollbar, DLG_CHECK_BOOL);\r
1908 \r
1909   // texture increment matches grid\r
1910   check = gtk_check_button_new_with_label ("Tex increment matches grid");\r
1911   gtk_widget_show (check);\r
1912   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
1913   AddDialogData (check, &m_bSnapTToGrid, DLG_CHECK_BOOL);\r
1914 \r
1915   // RIANT\r
1916   // Texture compression choice label\r
1917   // container\r
1918   table = gtk_table_new(2, 1, FALSE);\r
1919   gtk_widget_show(table);\r
1920   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
1921   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
1922   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
1923 \r
1924   label = gtk_label_new ("Texture Compression (if available):");\r
1925   gtk_widget_show (label);\r
1926   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);\r
1927   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,\r
1928                   (GtkAttachOptions) (0),\r
1929                   (GtkAttachOptions) (0), 0, 0);\r
1930   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);\r
1931 \r
1932   // Texture compression choice label\r
1933   combo_list = NULL;\r
1934   // NONE will always be in pos 0\r
1935   combo_list = g_list_append (combo_list, (void *)"None");\r
1936 \r
1937   // if OpenGL compression is enabled it will always be\r
1938   // in pos 1\r
1939   if (g_qeglobals.m_bOpenGLCompressionSupported)\r
1940   {\r
1941     combo_list = g_list_append (combo_list, (void *)"OpenGL ARB");\r
1942   }\r
1943 \r
1944   // If S3 is enabled offer all 3 valid compression schemes in RGBA\r
1945   if (g_qeglobals.m_bS3CompressionSupported)\r
1946   {\r
1947     combo_list = g_list_append (combo_list, (void *)"S3TC DXT1");\r
1948     combo_list = g_list_append (combo_list, (void *)"S3TC DXT3");\r
1949     combo_list = g_list_append (combo_list, (void *)"S3TC DXT5");\r
1950   }\r
1951 \r
1952   combo = gtk_combo_new ();\r
1953   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);\r
1954   gtk_widget_show (combo);\r
1955   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,\r
1956                   (GtkAttachOptions) (GTK_FILL),\r
1957                   (GtkAttachOptions) (0), 0, 0);\r
1958   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);\r
1959   AddDialogData (combo, &m_nTextureCompressionFormat, DLG_COMBO_INT);\r
1960   g_list_free (combo_list);\r
1961 \r
1962   // container\r
1963   table = gtk_table_new(2, 1, FALSE);\r
1964   gtk_widget_show(table);\r
1965   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
1966   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
1967   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
1968 \r
1969   // Startup shaders\r
1970   // label\r
1971   label = gtk_label_new ("Startup Shaders:");\r
1972   gtk_widget_show (label);\r
1973   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);\r
1974   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,\r
1975                   (GtkAttachOptions) (0),\r
1976                   (GtkAttachOptions) (0), 0, 0);\r
1977   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);\r
1978   \r
1979   // combo list\r
1980   combo_list = NULL;\r
1981   combo_list = g_list_append (combo_list, (void *)"None");\r
1982   if (g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game")\r
1983     combo_list = g_list_append (combo_list, (void *)"System");\r
1984   else if (g_pGameDescription->mGameFile == "sof2.game")\r
1985     combo_list = g_list_append (combo_list, (void *)"Tools");\r
1986   else\r
1987     combo_list = g_list_append (combo_list, (void *)"Common");\r
1988   combo_list = g_list_append (combo_list, (void *)"All");\r
1989   combo = gtk_combo_new ();\r
1990   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);\r
1991   gtk_widget_show (combo);\r
1992   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,\r
1993                   (GtkAttachOptions) (GTK_FILL),\r
1994                   (GtkAttachOptions) (0), 0, 0);\r
1995   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);\r
1996   AddDialogData (combo, &m_nLatchedShader, DLG_COMBO_INT);\r
1997   g_list_free (combo_list);\r
1998   \r
1999   // Add the page to the notebook\r
2000   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2001   \r
2002   /******** Layout group *********/\r
2003   preflabel = gtk_label_new("Layout");\r
2004   gtk_widget_show(preflabel);\r
2005   pageframe = gtk_frame_new("Layout");\r
2006   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
2007   gtk_widget_show(pageframe);\r
2008   vbox = gtk_vbox_new(FALSE, 5);\r
2009   gtk_widget_show(vbox);\r
2010   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
2011   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
2012 \r
2013   // View types\r
2014   // table\r
2015   table = gtk_table_new (2, 4, FALSE);\r
2016   gtk_widget_show (table);\r
2017   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
2018   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
2019   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
2020 \r
2021   // view type 1\r
2022   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window1.bmp");\r
2023   gtk_widget_show (pixmap);\r
2024   gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 0, 1,\r
2025                     (GtkAttachOptions) (0),\r
2026                     (GtkAttachOptions) (0), 0, 0);\r
2027 \r
2028   // view type 2\r
2029   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window2.bmp");\r
2030   gtk_widget_show (pixmap);\r
2031   gtk_table_attach (GTK_TABLE (table), pixmap, 1, 2, 0, 1,\r
2032                     (GtkAttachOptions) (0),\r
2033                     (GtkAttachOptions) (0), 0, 0);\r
2034 \r
2035   // view type 3\r
2036   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window3.bmp");\r
2037   gtk_widget_show (pixmap);\r
2038   gtk_table_attach (GTK_TABLE (table), pixmap, 2, 3, 0, 1,\r
2039                     (GtkAttachOptions) (0),\r
2040                     (GtkAttachOptions) (0), 0, 0);\r
2041 \r
2042   // view type 4\r
2043   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "window4.bmp");\r
2044   gtk_widget_show (pixmap);\r
2045   gtk_table_attach (GTK_TABLE (table), pixmap, 3, 4, 0, 1,\r
2046                     (GtkAttachOptions) (0),\r
2047                     (GtkAttachOptions) (0), 0, 0);\r
2048 \r
2049   // view type 1 selector\r
2050   radio = gtk_radio_button_new (NULL);\r
2051   gtk_widget_show (radio);\r
2052   gtk_table_attach (GTK_TABLE (table), radio, 0, 1, 1, 2,\r
2053                     (GtkAttachOptions) (0),\r
2054                     (GtkAttachOptions) (0), 0, 0);\r
2055 \r
2056   // view type 2 selector\r
2057   radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));\r
2058   gtk_widget_show (radio);\r
2059   gtk_table_attach (GTK_TABLE (table), radio, 1, 2, 1, 2,\r
2060                     (GtkAttachOptions) (0),\r
2061                     (GtkAttachOptions) (0), 0, 0);\r
2062 \r
2063   // view type 3 selector\r
2064   radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));\r
2065   gtk_widget_show (radio);\r
2066   gtk_table_attach (GTK_TABLE (table), radio, 2, 3, 1, 2,\r
2067                     (GtkAttachOptions) (0),\r
2068                     (GtkAttachOptions) (0), 0, 0);\r
2069 \r
2070   // view type 4 selector\r
2071   radio = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio));\r
2072   gtk_widget_show (radio);\r
2073   gtk_table_attach (GTK_TABLE (table), radio, 3, 4, 1, 2,\r
2074                     (GtkAttachOptions) (0),\r
2075                     (GtkAttachOptions) (0), 0, 0);\r
2076   AddDialogData (radio, &m_nLatchedView, DLG_RADIO_INT);\r
2077   \r
2078   // Floating Z window\r
2079   check = gtk_check_button_new_with_label ("Floating Z Window");\r
2080   gtk_widget_show (check);\r
2081   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2082   AddDialogData (check, &m_bLatchedFloatingZ, DLG_CHECK_BOOL);\r
2083   \r
2084   // show menu tear-off seperators\r
2085   check = gtk_check_button_new_with_label ("Detachable Menus");\r
2086   gtk_widget_show (check);\r
2087   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2088   AddDialogData (check, &m_bLatchedDetachableMenus, DLG_CHECK_BOOL);\r
2089 \r
2090   if (!g_pGameDescription->mNoPatch)\r
2091   {\r
2092     // show patch toolbar\r
2093     check = gtk_check_button_new_with_label ("Patch Toolbar");\r
2094     gtk_widget_show (check);\r
2095     gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2096     g_object_set_data (G_OBJECT (dialog), "check_patchtoolbar", check); // Allow to be disabled for Q1/Q2\r
2097     AddDialogData (check, &m_bLatchedPatchToolbar, DLG_CHECK_BOOL);\r
2098   }\r
2099 \r
2100   // use wide toolbar\r
2101   check = gtk_check_button_new_with_label ("Wide Toolbar");\r
2102   gtk_widget_show (check);\r
2103   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2104   AddDialogData (check, &m_bLatchedWideToolbar, DLG_CHECK_BOOL);\r
2105 \r
2106   // use plugin toolbar\r
2107   check = gtk_check_button_new_with_label ("Plugin Toolbar");\r
2108   gtk_widget_show (check);\r
2109   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2110   AddDialogData (check, &m_bLatchedPluginToolbar, DLG_CHECK_BOOL);\r
2111 \r
2112 #ifdef _WIN32\r
2113   // win32 file dialog\r
2114   check = gtk_check_button_new_with_label ("Use win32 file load dialog");\r
2115   gtk_widget_show (check);\r
2116   // gtk_container_add (GTK_CONTAINER (vbox), check);\r
2117   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2118   AddDialogData (check, &m_bNativeGUI, DLG_CHECK_BOOL);\r
2119 \r
2120   // position on primary monitor\r
2121   check = gtk_check_button_new_with_label ("Start on Primary Monitor");\r
2122   gtk_widget_show (check);\r
2123   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2124   g_object_set_data (G_OBJECT (dialog), "check_startonprimary", check);\r
2125   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );\r
2126   AddDialogData (check, &m_bStartOnPrimMon, DLG_CHECK_BOOL);\r
2127 #endif  \r
2128 \r
2129   // Add the page to the notebook\r
2130   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2131   \r
2132   /******** Mouse group *********/\r
2133   preflabel = gtk_label_new("Mouse");\r
2134   gtk_widget_show(preflabel);\r
2135   pageframe = gtk_frame_new("Mouse");\r
2136   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
2137   gtk_widget_show(pageframe);\r
2138   vbox = gtk_vbox_new(FALSE, 5);\r
2139   gtk_widget_show(vbox);\r
2140   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
2141   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
2142   \r
2143   // Buttons\r
2144   // container\r
2145   hbox2 = gtk_hbox_new (FALSE, 5);\r
2146   gtk_widget_show (hbox2);\r
2147   gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);\r
2148 \r
2149   // 2 button radio\r
2150   radio = gtk_radio_button_new_with_label (NULL, "2 button");\r
2151   gtk_widget_show (radio);\r
2152   gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);\r
2153 \r
2154   // 3 button radio\r
2155   radio = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio), "3 button");\r
2156   gtk_widget_show (radio);\r
2157   gtk_box_pack_start (GTK_BOX (hbox2), radio, FALSE, FALSE, 0);\r
2158   AddDialogData (radio, &m_nMouse, DLG_RADIO_INT);\r
2159 \r
2160   // right click to drop entity\r
2161   check = gtk_check_button_new_with_label ("Right click to drop entities");\r
2162   gtk_widget_show (check);\r
2163   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2164   AddDialogData (check, &m_bRightClick, DLG_CHECK_BOOL);\r
2165 \r
2166   // Mouse chaser (and this does what?)\r
2167   check = gtk_check_button_new_with_label ("Mouse chaser");\r
2168   gtk_widget_show (check);\r
2169   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2170   AddDialogData (check, &m_bChaseMouse, DLG_CHECK_BOOL);\r
2171 \r
2172   // Alt + multi-drag\r
2173   check = gtk_check_button_new_with_label ("ALT + multi-drag");\r
2174   gtk_widget_show (check);\r
2175   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2176   AddDialogData (check, &m_bALTEdge, DLG_CHECK_BOOL);\r
2177 \r
2178   // Mouse wheel increments\r
2179   // container\r
2180   hbox2 = gtk_hbox_new (FALSE, 5);\r
2181   gtk_widget_show (hbox2);\r
2182   gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);\r
2183   \r
2184   // label\r
2185   label = gtk_label_new ("Wheel Mouse inc:");\r
2186   gtk_widget_show (label);\r
2187   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);\r
2188   \r
2189   // entry\r
2190   entry = gtk_entry_new ();\r
2191   gtk_widget_show (entry);\r
2192   gtk_widget_set_usize (entry, 40, -2);\r
2193   gtk_box_pack_start (GTK_BOX (hbox2), entry, FALSE, FALSE, 0);\r
2194   AddDialogData (entry, &m_nWheelInc, DLG_ENTRY_INT);  \r
2195 \r
2196   // Add the page to the notebook\r
2197   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2198   \r
2199   /******** Editing group *********/\r
2200   preflabel = gtk_label_new("Editing");\r
2201   gtk_widget_show(preflabel);\r
2202   pageframe = gtk_frame_new("Editing");\r
2203   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
2204   gtk_widget_show(pageframe);\r
2205   vbox = gtk_vbox_new(FALSE, 5);\r
2206   gtk_widget_show(vbox);\r
2207   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
2208   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
2209   \r
2210   // Vertex editing splits faces\r
2211   check = gtk_check_button_new_with_label ("Vertex editing splits face");\r
2212   gtk_widget_show (check);\r
2213   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2214   AddDialogData (check, &m_bVertexSplit, DLG_CHECK_BOOL);\r
2215 \r
2216   // Fix target/targetname collisions\r
2217   check = gtk_check_button_new_with_label ("Fix target/targetname collisions");\r
2218   gtk_widget_show (check);\r
2219   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2220   AddDialogData (check, &m_bDoTargetFix, DLG_CHECK_BOOL);\r
2221   \r
2222   // Clipper tool uses caulk\r
2223   check = gtk_check_button_new_with_label ("Clipper tool uses caulk");\r
2224   gtk_widget_show (check);\r
2225   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2226   AddDialogData (check, &m_bClipCaulk, DLG_CHECK_BOOL);\r
2227 \r
2228   // Don't clamp plane points\r
2229   check = gtk_check_button_new_with_label ("Don't clamp plane points");\r
2230   gtk_widget_show (check);\r
2231   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);\r
2232   AddDialogData (check, &m_bNoClamp, DLG_CHECK_BOOL);\r
2233 \r
2234   // Select patch by bounding box\r
2235   check = gtk_check_button_new_with_label ("Select patches by bounding box");\r
2236   gtk_widget_show (check);\r
2237   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2238   AddDialogData (check, &m_bPatchBBoxSelect, DLG_CHECK_BOOL);  \r
2239   \r
2240   // Rotation increment\r
2241   // container\r
2242   table = gtk_table_new (2, 3, FALSE);\r
2243   gtk_widget_show (table);\r
2244   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
2245   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
2246   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
2247   \r
2248   // label\r
2249   label = gtk_label_new ("Rotation increment:");\r
2250   gtk_widget_show (label);\r
2251   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,\r
2252                    (GtkAttachOptions) (0),\r
2253                    (GtkAttachOptions) (0), 0, 0);\r
2254                    \r
2255   // entry\r
2256   entry = gtk_entry_new ();\r
2257   gtk_widget_show (entry);\r
2258   gtk_widget_set_usize (entry, 60, -2);\r
2259   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,\r
2260                    (GtkAttachOptions) (GTK_FILL),\r
2261                    (GtkAttachOptions) (0), 0, 0);\r
2262   AddDialogData (entry, &m_nRotation, DLG_ENTRY_INT);\r
2263   \r
2264   // Undo levels\r
2265   // label\r
2266   label = gtk_label_new ("Undo Levels:");\r
2267   gtk_widget_show (label);\r
2268   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,\r
2269                    (GtkAttachOptions) (0),\r
2270                    (GtkAttachOptions) (0), 0, 0);\r
2271                    \r
2272   // spinner (allows undo levels to be set to zero)\r
2273   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 0, 64, 1, 10, 10)), 1, 0); \r
2274   gtk_widget_show (spin);\r
2275   gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2,\r
2276                    (GtkAttachOptions) (GTK_FILL),\r
2277                    (GtkAttachOptions) (0), 0, 0);\r
2278   gtk_widget_set_usize (spin, 60, -2);\r
2279   AddDialogData (spin, &m_nUndoLevels, DLG_SPIN_INT);\r
2280 \r
2281   // Patch subdivisions\r
2282   // label\r
2283   label = gtk_label_new ("Patch subdivisions:");\r
2284   gtk_widget_show (label);\r
2285   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,\r
2286                    (GtkAttachOptions) (0),\r
2287                    (GtkAttachOptions) (0), 0, 0);\r
2288                    \r
2289   // entry (spinner perhaps? [2-16])\r
2290   entry = gtk_entry_new ();\r
2291   gtk_widget_show (entry);\r
2292   gtk_widget_set_usize (entry, 60, -2);\r
2293   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3,\r
2294                    (GtkAttachOptions) (GTK_FILL),\r
2295                    (GtkAttachOptions) (0), 0, 0);\r
2296   AddDialogData (entry, &m_nSubdivisions, DLG_ENTRY_INT);\r
2297 \r
2298   // Add the page to the notebook\r
2299   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2300   \r
2301   /******** Save/Load group *********/\r
2302   preflabel = gtk_label_new("Startup/Auto save");\r
2303   gtk_widget_show(preflabel);\r
2304   pageframe = gtk_frame_new("Startup/Auto save");\r
2305   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
2306   gtk_widget_show(pageframe);\r
2307   vbox = gtk_vbox_new(FALSE, 5);\r
2308   gtk_widget_show(vbox);\r
2309   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
2310   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
2311 \r
2312   // Snapshots\r
2313   check = gtk_check_button_new_with_label ("Snapshots");\r
2314   gtk_widget_show (check);\r
2315   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2316   AddDialogData (check, &m_bSnapShots, DLG_CHECK_BOOL);\r
2317   \r
2318   // load last project on open\r
2319   check = gtk_check_button_new_with_label ("Load last project on open");\r
2320   gtk_widget_show (check);\r
2321   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2322   AddDialogData (check, &m_bLoadLast, DLG_CHECK_BOOL);\r
2323 \r
2324   // load last map on open\r
2325   check = gtk_check_button_new_with_label ("Load last map on open");\r
2326   gtk_widget_show (check);\r
2327   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2328   AddDialogData (check, &m_bLoadLastMap, DLG_CHECK_BOOL);\r
2329 \r
2330   // Auto save..\r
2331   // container\r
2332   hbox2 = gtk_hbox_new (FALSE, 5);\r
2333   gtk_widget_show (hbox2);\r
2334   gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);\r
2335   gtk_container_set_border_width (GTK_CONTAINER (hbox2), 0);\r
2336   \r
2337   // label\r
2338   check = gtk_check_button_new_with_label ("Auto save every");\r
2339   gtk_widget_show (check);\r
2340   gtk_box_pack_start (GTK_BOX (hbox2), check, FALSE, FALSE, 0);\r
2341   AddDialogData (check, &m_bAutoSave, DLG_CHECK_BOOL);\r
2342   \r
2343   // spinner\r
2344   spin = gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 60, 1, 10, 10)), 1, 0);\r
2345   gtk_widget_show (spin);\r
2346   gtk_box_pack_start (GTK_BOX (hbox2), spin, FALSE, FALSE, 0);\r
2347   gtk_widget_set_usize (spin, 60, -2);\r
2348   AddDialogData (spin, &m_nAutoSave, DLG_SPIN_INT);\r
2349   \r
2350   // label\r
2351   label = gtk_label_new ("minutes");\r
2352   gtk_widget_show (label);\r
2353   gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);\r
2354   \r
2355   // Add the page to the notebook\r
2356   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2357   \r
2358   /******** Paths group *********/\r
2359   preflabel = gtk_label_new("Paths");\r
2360   gtk_widget_show(preflabel);\r
2361   pageframe = gtk_frame_new("Paths");\r
2362   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
2363   gtk_widget_show(pageframe);\r
2364   vbox = gtk_vbox_new(FALSE, 5);\r
2365   gtk_widget_show(vbox);\r
2366   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
2367   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
2368 \r
2369   // prefab path\r
2370   // table\r
2371   table = gtk_table_new (3, 3, FALSE);\r
2372   gtk_widget_show (table);\r
2373   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
2374   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
2375   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
2376   \r
2377   // label\r
2378   label = gtk_label_new ("Prefab path:");\r
2379   gtk_widget_show (label);\r
2380   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,\r
2381                    (GtkAttachOptions) (0),\r
2382                    (GtkAttachOptions) (0), 0, 0);\r
2383   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\r
2384   \r
2385   // path entry\r
2386   entry = gtk_entry_new ();\r
2387   gtk_widget_show (entry);\r
2388   gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);\r
2389   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,\r
2390                    (GtkAttachOptions) (GTK_FILL),\r
2391                    (GtkAttachOptions) (0), 1, 0);\r
2392   AddDialogData (entry, &m_strPrefabPath, DLG_ENTRY_TEXT);\r
2393 \r
2394   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=805\r
2395 #if 0  \r
2396   // browse button\r
2397   button = gtk_button_new_with_label ("...");\r
2398   gtk_widget_show (button);\r
2399   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseprefab), this);\r
2400   gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,\r
2401                    (GtkAttachOptions) (0),\r
2402                    (GtkAttachOptions) (0), 0, 0);\r
2403 #endif\r
2404 \r
2405   // User ini path\r
2406   // label\r
2407   label = gtk_label_new ("User INI path:");\r
2408   gtk_widget_show (label);\r
2409   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,\r
2410                    (GtkAttachOptions) (0),\r
2411                    (GtkAttachOptions) (0), 0, 0);\r
2412   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\r
2413   \r
2414   // user ini path entry\r
2415   entry = gtk_entry_new ();\r
2416   gtk_widget_show (entry);\r
2417   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,\r
2418                    (GtkAttachOptions) (GTK_FILL),\r
2419                    (GtkAttachOptions) (0), 1, 0);\r
2420   AddDialogData (entry, &m_strUserPath, DLG_ENTRY_TEXT);\r
2421   \r
2422   // user ini browse button\r
2423   button = gtk_button_new_with_label ("...");\r
2424   gtk_widget_show (button);\r
2425   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseuserini), this);\r
2426   gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,\r
2427                    (GtkAttachOptions) (0),\r
2428                    (GtkAttachOptions) (0), 0, 0);\r
2429 \r
2430   // Add the page to the notebook\r
2431   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2432   \r
2433   /******** Misc group *********/\r
2434   preflabel = gtk_label_new("Misc");\r
2435   gtk_widget_show(preflabel);\r
2436   pageframe = gtk_frame_new("Misc");\r
2437   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
2438   gtk_widget_show(pageframe);\r
2439   vbox = gtk_vbox_new(FALSE, 5);\r
2440   gtk_widget_show(vbox);\r
2441   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
2442   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
2443   \r
2444   // Light drawing\r
2445   check = gtk_check_button_new_with_label ("Light drawing");\r
2446   gtk_widget_show (check);\r
2447   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2448   AddDialogData (check, &m_bNewLightDraw, DLG_CHECK_BOOL);\r
2449 \r
2450   // Light radiuses\r
2451   // container\r
2452   table = gtk_table_new(2, 1, FALSE);\r
2453   gtk_widget_show(table);\r
2454   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
2455   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
2456   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
2457 \r
2458   label = gtk_label_new ("Light radiuses:");\r
2459   gtk_widget_show (label);\r
2460   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);\r
2461   gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,\r
2462                   (GtkAttachOptions) (0),\r
2463                   (GtkAttachOptions) (0), 0, 0);\r
2464 \r
2465   combo_list = NULL;\r
2466   combo_list = g_list_append (combo_list, (void *)"Disabled");\r
2467   combo_list = g_list_append (combo_list, (void *)"True Q3Map2 Style");\r
2468   combo_list = g_list_append (combo_list, (void *)"Classic Style");\r
2469 \r
2470   combo = gtk_combo_new ();\r
2471   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);\r
2472   gtk_widget_show (combo);\r
2473   gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 0, 1,\r
2474                   (GtkAttachOptions) (GTK_FILL),\r
2475                   (GtkAttachOptions) (0), 0, 0);\r
2476   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (combo)->entry), FALSE);\r
2477   AddDialogData (combo, &m_nLightRadiuses, DLG_COMBO_INT);\r
2478 \r
2479 #ifdef _WIN32\r
2480   check = gtk_check_button_new_with_label ("Use win32 file associations to open text files instead of builtin editor");\r
2481   gtk_widget_show(check);\r
2482   gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2483   AddDialogData (check, &g_PrefsDlg.m_bUseWin32Editor, DLG_CHECK_BOOL);\r
2484 #else\r
2485   // use custom shader editor\r
2486   check = gtk_check_button_new_with_label ("Use Custom Shader Editor");\r
2487   gtk_widget_show(check);\r
2488   gtk_box_pack_start(GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2489   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateEditorSensitivity), this);\r
2490   g_object_set_data (G_OBJECT(dialog), "check_customeditor", check);\r
2491   AddDialogData (check, &g_PrefsDlg.m_bUseCustomEditor, DLG_CHECK_BOOL);\r
2492   \r
2493   // custom shader editor executable\r
2494   // table\r
2495   table = gtk_table_new (3, 1, FALSE);\r
2496   gtk_widget_show (table);\r
2497   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
2498   gtk_table_set_row_spacings (GTK_TABLE (table), 5);\r
2499   gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
2500   \r
2501   // label\r
2502   label = gtk_label_new("Custom Editor Command");\r
2503   gtk_widget_show(label);\r
2504   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,\r
2505                    (GtkAttachOptions) (0),\r
2506                    (GtkAttachOptions) (0), 0, 0);\r
2507   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);\r
2508   g_object_set_data (G_OBJECT(dialog), "label_customeditor", label);\r
2509   gtk_widget_set_sensitive (label, g_PrefsDlg.m_bUseCustomEditor);\r
2510   \r
2511   // custom editor command entry\r
2512   entry = gtk_entry_new ();\r
2513   gtk_widget_show (entry);\r
2514   gtk_widget_set_usize(GTK_WIDGET(entry), 240, -2);\r
2515   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,\r
2516                    (GtkAttachOptions) (GTK_FILL),\r
2517                    (GtkAttachOptions) (0), 1, 0);\r
2518   AddDialogData (entry, &m_strEditorCommand, DLG_ENTRY_TEXT);\r
2519   gtk_widget_set_sensitive (entry, g_PrefsDlg.m_bUseCustomEditor);\r
2520   g_object_set_data (G_OBJECT(dialog), "entry_customeditor", entry);\r
2521   \r
2522   // browse button\r
2523   button = gtk_button_new_with_label ("...");\r
2524   gtk_widget_show (button);\r
2525   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (OnBtnBrowseEditor), this);\r
2526   gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,\r
2527                    (GtkAttachOptions) (0),\r
2528                    (GtkAttachOptions) (0), 0, 0);\r
2529   g_object_set_data (G_OBJECT(dialog), "button_customeditor", button);\r
2530   gtk_widget_set_sensitive (button, g_PrefsDlg.m_bUseCustomEditor);\r
2531 #endif\r
2532 \r
2533   // Add the page to the notebook\r
2534   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2535 \r
2536   /******** BSP Monitoring group *********/\r
2537   // this is never displayed if the plugin isn't available\r
2538   preflabel = gtk_label_new("BSP Monitoring");\r
2539   gtk_widget_show(preflabel);\r
2540   pageframe = gtk_frame_new("BSP Monitoring");\r
2541   gtk_container_set_border_width(GTK_CONTAINER(pageframe), 5);\r
2542   gtk_widget_show(pageframe);\r
2543   vbox = gtk_vbox_new(FALSE, 5);\r
2544   gtk_widget_show(vbox);\r
2545   gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);\r
2546   gtk_container_add(GTK_CONTAINER(pageframe), vbox);\r
2547 \r
2548   // Enable BSP process monitoring\r
2549   check = gtk_check_button_new_with_label ("Enable BSP process monitoring");\r
2550   gtk_widget_show (check);\r
2551   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2552   g_object_set_data (G_OBJECT (dialog), "check_monitorbsp", check);\r
2553   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );\r
2554   AddDialogData (check, &g_PrefsDlg.m_bWatchBSP, DLG_CHECK_BOOL);\r
2555 \r
2556   // Stop on leak\r
2557   check = gtk_check_button_new_with_label ("Stop compilation on leak");\r
2558   gtk_widget_show (check);\r
2559   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2560   g_object_set_data (G_OBJECT (dialog), "check_leakstop", check);\r
2561   AddDialogData (check, &g_PrefsDlg.m_bLeakStop, DLG_CHECK_BOOL);\r
2562 \r
2563   // engine after compile\r
2564   check = gtk_check_button_new_with_label ("Run engine after compile");\r
2565   gtk_widget_show (check);\r
2566   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2567   g_object_set_data (G_OBJECT (dialog), "check_runengine", check);\r
2568   gtk_signal_connect( GTK_OBJECT (check), "clicked", GTK_SIGNAL_FUNC(UpdateSensitivity), this );\r
2569   AddDialogData( check, &g_PrefsDlg.m_bRunQuake, DLG_CHECK_BOOL );  \r
2570   \r
2571   // sleep mode when running engine\r
2572   check = gtk_check_button_new_with_label ("Activate sleep mode when running the engine");\r
2573   gtk_widget_show (check);\r
2574   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2575   g_object_set_data (G_OBJECT (dialog), "check_sleep", check);\r
2576   AddDialogData( check, &g_PrefsDlg.m_bDoSleep, DLG_CHECK_BOOL );\r
2577   \r
2578   // use q3map2's texture projection\r
2579   check = gtk_check_button_new_with_label ("Texturing compatible with q3map2");\r
2580   gtk_widget_show (check);\r
2581   gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);\r
2582   g_object_set_data (G_OBJECT (dialog), "check_q3map2", check);\r
2583   AddDialogData( check, &g_PrefsDlg.m_bQ3Map2Texturing, DLG_CHECK_BOOL );\r
2584 \r
2585   // Add the page to the notebook\r
2586   gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel);\r
2587 \r
2588   gtk_notebook_set_page(GTK_NOTEBOOK(notebook), PTAB_FRONT);\r
2589 \r
2590   return;\r
2591 }\r
2592 \r
2593 // end new prefs dialog\r
2594 \r
2595 void PrefsDlg::LoadTexdefPref(texdef_t* pTexdef, char* pName)\r
2596 {\r
2597   char buffer[256];\r
2598 \r
2599   memset(pTexdef, 0, sizeof(texdef_t));\r
2600 \r
2601   sprintf(buffer, "%s%s", pName, TD_SCALE1_KEY);\r
2602   mLocalPrefs.GetPref(buffer, &pTexdef->scale[0],   0.5f);      \r
2603 \r
2604   sprintf(buffer, "%s%s", pName, TD_SCALE2_KEY);\r
2605   mLocalPrefs.GetPref(buffer, &pTexdef->scale[1],   0.5f);\r
2606 \r
2607   sprintf(buffer, "%s%s", pName, TD_SHIFT1_KEY);\r
2608   mLocalPrefs.GetPref(buffer, &pTexdef->shift[0],   8.f);\r
2609 \r
2610   sprintf(buffer, "%s%s", pName, TD_SHIFT2_KEY);\r
2611   mLocalPrefs.GetPref(buffer, &pTexdef->shift[1],   8.f);\r
2612 \r
2613   sprintf(buffer, "%s%s", pName, TD_ROTATE_KEY);\r
2614   mLocalPrefs.GetPref(buffer, &pTexdef->rotate,     45);\r
2615 }\r
2616 \r
2617 void PrefsDlg::UpdateTextureCompression()\r
2618 {\r
2619   // if OpenGL is not ready yet, don't do anything\r
2620   if (!g_qeglobals.m_bOpenGLReady) {\r
2621     Sys_Printf("OpenGL not ready - postpone texture compression capability check\n");\r
2622     return;\r
2623   }\r
2624   \r
2625   if (g_qeglobals.bTextureCompressionSupported)\r
2626   {\r
2627     if (m_nTextureCompressionFormat >= 2 && !g_qeglobals.m_bS3CompressionSupported)\r
2628     {\r
2629       Sys_Printf("Inconsistant pref setting for texture compression (%d), rolling back\n", m_nTextureCompressionFormat);\r
2630       m_nTextureCompressionFormat = 1; // if this is not supported either, see below\r
2631     }\r
2632     if (m_nTextureCompressionFormat == 1 && !g_qeglobals.m_bOpenGLCompressionSupported)\r
2633     {\r
2634       Sys_Printf("Inconsistant pref setting for texture compression (GL_COMPRESSED_RGBA), rolling back\n");\r
2635       m_nTextureCompressionFormat = 0;\r
2636     }\r
2637     switch (m_nTextureCompressionFormat)\r
2638     {\r
2639     case (0):\r
2640       {\r
2641         g_qeglobals.texture_components = GL_RGBA;\r
2642         Sys_Printf("texture compression disabled by preferences settings\n");\r
2643         break;\r
2644       }\r
2645     case (1):\r
2646       {\r
2647         g_qeglobals.texture_components = GL_COMPRESSED_RGBA;\r
2648         Sys_Printf("OpenGL texture compression enabled\n");\r
2649         break;\r
2650       }\r
2651     case (2):\r
2652       {\r
2653         g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;\r
2654         Sys_Printf("S3TC DXT1 texture compression enabled\n");\r
2655         break;\r
2656       }\r
2657     case (3):\r
2658       {\r
2659         g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;\r
2660         Sys_Printf("S3TC DXT3 texture compression enabled\n");\r
2661         break;\r
2662       }\r
2663     case (4):\r
2664       {\r
2665         g_qeglobals.texture_components = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;\r
2666         Sys_Printf("S3TC DXT5 texture compression enabled\n");\r
2667         break;\r
2668       }\r
2669     }\r
2670   }\r
2671   else\r
2672   {\r
2673     Sys_Printf("texture compression is not supported by your current graphic card/drivers\n");\r
2674     g_qeglobals.texture_components = GL_RGBA;\r
2675     m_nTextureCompressionFormat = 0;\r
2676   }\r
2677 }\r
2678 \r
2679 #ifdef ATIHACK_812\r
2680 void PrefsDlg::UpdateATIHack() {\r
2681   // if OpenGL is not ready yet, don't do anything\r
2682   if (!g_qeglobals.m_bOpenGLReady) {\r
2683     Sys_Printf("OpenGL not ready - postpone ATI bug workaround setup\n");\r
2684     return;\r
2685   }\r
2686 \r
2687   if (m_bGlATIHack) {\r
2688     qglCullFace = &qglCullFace_ATIHack;\r
2689     qglDisable = &qglDisable_ATIHack;\r
2690     qglEnable = &qglEnable_ATIHack;\r
2691     qglPolygonMode = &qglPolygonMode_ATIHack;\r
2692     Sys_Printf("ATI bug workaround enabled\n");\r
2693   } else {\r
2694     qglCullFace = qglCullFace_real;\r
2695     qglDisable = qglDisable_real;\r
2696     qglEnable = qglEnable_real;\r
2697     qglPolygonMode = qglPolygonMode_real;\r
2698     Sys_Printf("ATI bug workaround disabled\n");\r
2699   }\r
2700 }\r
2701 #endif\r
2702 \r
2703 // TTimo: m_strEnginePath has a special status, if not found in registry we need to \r
2704 // initiliaze it for sure. It is not totally failsafe but we can use the same\r
2705 // code than in q3map, expecting to find some "quake" above us. If not, we prompt\r
2706 // for the engine executable path\r
2707 void PrefsDlg::LoadPrefs ()\r
2708 {\r
2709   int i;\r
2710 \r
2711   // first things first, load prefs from global prefs\r
2712   mGamesDialog.LoadPrefs();\r
2713 \r
2714   // if we already have a document loaded, we will free and reload from file\r
2715   if (mLocalPrefs.InUse()) {\r
2716     mLocalPrefs.Clear();\r
2717   }\r
2718 \r
2719   // load local.pref file\r
2720   mLocalPrefs.ReadXMLFile(m_inipath->str);\r
2721 \r
2722   mLocalPrefs.GetPref(PATCHSHOWBOUNDS_KEY,  &g_bPatchShowBounds,  FALSE);\r
2723   mLocalPrefs.GetPref(MOUSE_KEY,            &m_nMouse,            MOUSE_DEF);\r
2724   m_nMouseButtons = m_nMouse ? 3 : 2;\r
2725   \r
2726         // project file\r
2727         // if it's not found here, mainframe.cpp will take care of finding one\r
2728   mLocalPrefs.GetPref(LASTPROJ_KEY, &m_strLastProject, "");\r
2729   mLocalPrefs.GetPref(LASTPROJVER_KEY, &m_nLastProjectVer, -1);\r
2730 \r
2731         // prefab path\r
2732   // NOTE TTimo: I'm not sure why this is in prefs\r
2733   // should probably be a project setting\r
2734   // and I'm not sure that we really have a way to set this reliably either\r
2735   CString strPrefab;\r
2736   strPrefab = g_qeglobals.m_strHomeGame.GetBuffer();\r
2737   strPrefab += g_pGameDescription->mBaseGame.GetBuffer();\r
2738   strPrefab += "/prefabs/";\r
2739   mLocalPrefs.GetPref(PREFAB_KEY, &m_strPrefabPath, strPrefab);\r
2740 \r
2741   mLocalPrefs.GetPref(LASTLIGHTINTENSITY_KEY, &m_iLastLightIntensity, 300);\r
2742   mLocalPrefs.GetPref(TLOCK_KEY,              &m_bTextureLock,        TLOCK_DEF);\r
2743   mLocalPrefs.GetPref(RLOCK_KEY,              &m_bRotateLock,         TLOCK_DEF);\r
2744   mLocalPrefs.GetPref(LASTMAP_KEY,            &m_strLastMap,          "");\r
2745   mLocalPrefs.GetPref(LOADLAST_KEY,           &m_bLoadLast,           LOADLAST_DEF);\r
2746   mLocalPrefs.GetPref(BSP_KEY,                &m_bInternalBSP,        FALSE);\r
2747   mLocalPrefs.GetPref(RCLICK_KEY,             &m_bRightClick,         TRUE);\r
2748   mLocalPrefs.GetPref(AUTOSAVE_KEY,           &m_bAutoSave,           TRUE);\r
2749   mLocalPrefs.GetPref(LOADLASTMAP_KEY,        &m_bLoadLastMap,        FALSE);\r
2750   mLocalPrefs.GetPref(TINYBRUSH_KEY,          &m_bCleanTiny,          FALSE);\r
2751   mLocalPrefs.GetPref(TINYSIZE_KEY,           &m_fTinySize,           0.5f);\r
2752   mLocalPrefs.GetPref(AUTOSAVETIME_KEY,       &m_nAutoSave,           5);\r
2753   mLocalPrefs.GetPref(SNAPSHOT_KEY,           &m_bSnapShots,          FALSE);\r
2754   mLocalPrefs.GetPref(MOVESPEED_KEY,          &m_nMoveSpeed,          100);\r
2755   mLocalPrefs.GetPref(ANGLESPEED_KEY,         &m_nAngleSpeed,         3);\r
2756   mLocalPrefs.GetPref(SETGAME_KEY,            &m_bSetGame,            FALSE);\r
2757   mLocalPrefs.GetPref(CAMXYUPDATE_KEY,        &m_bCamXYUpdate,        TRUE);\r
2758   mLocalPrefs.GetPref(CAMDRAGMULTISELECT_KEY, &m_nCamDragMultiSelect, TRUE);\r
2759   mLocalPrefs.GetPref(CAMFREELOOK_KEY,        &m_bCamFreeLook,        TRUE);\r
2760   mLocalPrefs.GetPref(CAMINVERSEMOUSE_KEY,    &m_bCamInverseMouse,    FALSE);\r
2761   mLocalPrefs.GetPref(CAMDISCRETE_KEY,        &m_bCamDiscrete,        TRUE);\r
2762   mLocalPrefs.GetPref(LIGHTDRAW_KEY,          &m_bNewLightDraw,       TRUE);\r
2763   mLocalPrefs.GetPref(CUBICCLIP_KEY,          &m_bCubicClipping,      TRUE);\r
2764   mLocalPrefs.GetPref(CUBICSCALE_KEY,         &m_nCubicScale,         13);\r
2765   mLocalPrefs.GetPref(ALTEDGE_KEY,            &m_bALTEdge,            FALSE);\r
2766   mLocalPrefs.GetPref(FACECOLORS_KEY,         &m_bFaceColors,         FALSE);\r
2767   mLocalPrefs.GetPref(XZVIS_KEY,              &m_bXZVis,              FALSE);\r
2768   mLocalPrefs.GetPref(YZVIS_KEY,              &m_bYZVis,              FALSE);\r
2769   mLocalPrefs.GetPref(ZVIS_KEY,               &m_bZVis,               FALSE);\r
2770   mLocalPrefs.GetPref(SIZEPAINT_KEY,          &m_bSizePaint,                  FALSE);\r
2771   mLocalPrefs.GetPref(DLLENTITIES_KEY,        &m_bDLLEntities,                FALSE);\r
2772 \r
2773   mLocalPrefs.GetPref(DETACHABLEMENUS_KEY,    &m_bLatchedDetachableMenus,            TRUE);\r
2774   m_bDetachableMenus = m_bLatchedDetachableMenus;\r
2775   \r
2776   if (g_pGameDescription->mNoPatch)\r
2777   {\r
2778     m_bPatchToolbar = false;\r
2779   }\r
2780   else\r
2781   {\r
2782     mLocalPrefs.GetPref(PATCHTOOLBAR_KEY,       &m_bLatchedPatchToolbar,               TRUE);\r
2783     m_bPatchToolbar = m_bLatchedPatchToolbar;\r
2784   }\r
2785 \r
2786   mLocalPrefs.GetPref(WIDETOOLBAR_KEY,        &m_bLatchedWideToolbar,                TRUE);\r
2787   m_bWideToolbar = m_bLatchedWideToolbar;\r
2788  \r
2789   mLocalPrefs.GetPref(PLUGINTOOLBAR_KEY, &m_bLatchedPluginToolbar, TRUE);\r
2790   m_bPluginToolbar = m_bLatchedPluginToolbar;\r
2791 \r
2792   mLocalPrefs.GetPref(WINDOW_KEY,             (int*)&m_nLatchedView,  WINDOW_DEF);\r
2793   m_nView = m_nLatchedView;\r
2794 \r
2795   mLocalPrefs.GetPref(FLOATINGZ_KEY,          &m_bLatchedFloatingZ,           FALSE);\r
2796   m_bFloatingZ = m_bLatchedFloatingZ;\r
2797 \r
2798   mLocalPrefs.GetPref(TEXTUREQUALITY_KEY,     &m_nLatchedTextureQuality,             3);\r
2799   m_nTextureQuality = m_nLatchedTextureQuality;\r
2800 \r
2801   mLocalPrefs.GetPref(LOADSHADERS_KEY,        &m_nLatchedShader,                     0);\r
2802   m_nShader = m_nLatchedShader;\r
2803 \r
2804   mLocalPrefs.GetPref(NOCLAMP_KEY,            &m_bNoClamp,                    FALSE);\r
2805   mLocalPrefs.GetPref(USERINI_KEY,            &m_strUserPath,                 "");\r
2806   mLocalPrefs.GetPref(ROTATION_KEY,           &m_nRotation,                   45);\r
2807   mLocalPrefs.GetPref(CHASEMOUSE_KEY,         &m_bChaseMouse,                 TRUE);\r
2808   mLocalPrefs.GetPref(ENTITYSHOW_KEY,         &m_nEntityShowState,            ENTITY_SKINNED_BOXED);\r
2809 \r
2810   // this will probably need to be 75 or 100 for Q1.\r
2811   mLocalPrefs.GetPref(TEXTURESCALE_KEY,       &m_nTextureScale,               50);\r
2812 \r
2813   // FIXME: Hydra - actually, this stuff is Q1,Q2 and HL specific.\r
2814   if ( (g_pGameDescription->mGameFile == "hl.game") )\r
2815   {\r
2816     // No BSP monitoring in the default compiler tools for Half-life (yet)\r
2817     mLocalPrefs.GetPref(WATCHBSP_KEY,           &m_bWatchBSP,                   FALSE);\r
2818 \r
2819     // Texture subset on by default (HL specific really, because of halflife.wad's size)\r
2820     mLocalPrefs.GetPref(TEXTURE_KEY,            &m_bTextureWindow,              TRUE);\r
2821   }\r
2822   else if ( ( g_pGameDescription->mGameFile == "q2.game" ) || ( g_pGameDescription->mGameFile == "heretic2.game" ) )\r
2823   {\r
2824     // BSP monitoring is implemented in Quake2 and Heretic2 tools\r
2825     mLocalPrefs.GetPref(WATCHBSP_KEY,           &m_bWatchBSP,                   TRUE);\r
2826 \r
2827     // Texture subset on by default (HL specific really, because of halflife.wad's size)\r
2828     mLocalPrefs.GetPref(TEXTURE_KEY,            &m_bTextureWindow,              TRUE);\r
2829   }\r
2830   else\r
2831   {\r
2832     mLocalPrefs.GetPref(WATCHBSP_KEY,           &m_bWatchBSP,                   WATCHBSP_DEF);\r
2833     mLocalPrefs.GetPref(TEXTURE_KEY,            &m_bTextureWindow,              FALSE);\r
2834   }\r
2835 \r
2836 \r
2837   mLocalPrefs.GetPref(TEXTURESCROLLBAR_KEY,   &m_bTextureScrollbar,           TRUE);\r
2838   mLocalPrefs.GetPref(DISPLAYLISTS_KEY,       &m_bDisplayLists,               TRUE);\r
2839   mLocalPrefs.GetPref(ANTIALIASEDLINES_KEY,   &m_bAntialiasedPointsAndLines,  FALSE);\r
2840   mLocalPrefs.GetPref(SWITCHCLIP_KEY,         &m_bSwitchClip,                 TRUE);\r
2841   mLocalPrefs.GetPref(SELWHOLEENTS_KEY,       &m_bSelectWholeEntities,        TRUE);\r
2842   mLocalPrefs.GetPref(SHOWSHADERS_KEY,        &m_bShowShaders,                TRUE);\r
2843   mLocalPrefs.GetPref(GLLIGHTING_KEY,         &m_bGLLighting,                 FALSE);\r
2844   mLocalPrefs.GetPref(NOSTIPPLE_KEY,          &m_bNoStipple,                  FALSE);\r
2845   mLocalPrefs.GetPref(UNDOLEVELS_KEY,         &m_nUndoLevels,                 30);\r
2846   mLocalPrefs.GetPref(VERTEXMODE_KEY,         &m_bVertexSplit,                TRUE);\r
2847   mLocalPrefs.GetPref(RUNQ2_KEY,              &m_bRunQuake,                   RUNQ2_DEF);\r
2848   mLocalPrefs.GetPref(LEAKSTOP_KEY,           &m_bLeakStop,                   TRUE);\r
2849   mLocalPrefs.GetPref(DOSLEEP_KEY,            &m_bDoSleep,                    FALSE);\r
2850   mLocalPrefs.GetPref(SELECTCURVES_KEY,       &m_bSelectCurves,               TRUE);\r
2851   mLocalPrefs.GetPref(SELECTMODELS_KEY,       &m_bSelectModels,               TRUE);\r
2852   mLocalPrefs.GetPref(SHADERLISTONLY_KEY,     &m_bTexturesShaderlistOnly,     FALSE);\r
2853   mLocalPrefs.GetPref(SUBDIVISIONS_KEY,       &m_nSubdivisions,               SUBDIVISIONS_DEF);\r
2854   mLocalPrefs.GetPref(CLIPCAULK_KEY,          &m_bClipCaulk,                  FALSE);\r
2855   mLocalPrefs.GetPref(SNAPTTOGRID_KEY,        &m_bSnapTToGrid,                FALSE);\r
2856   mLocalPrefs.GetPref(TARGETFIX_KEY,          &m_bDoTargetFix,                TRUE);\r
2857   mLocalPrefs.GetPref(WHEELINC_KEY,           &m_nWheelInc,                   64);\r
2858   mLocalPrefs.GetPref(PATCHBBOXSEL_KEY,       &m_bPatchBBoxSelect,            FALSE);\r
2859   \r
2860   // Gef: Kyro GL_POINT workaround\r
2861   mLocalPrefs.GetPref(GLPOINTWORKAROUND_KEY,  &m_bGlPtWorkaround,             FALSE);\r
2862 \r
2863   // window positioning\r
2864   mLocalPrefs.GetPref(ENTITYSPLIT1_KEY,       &mWindowInfo.nEntitySplit1,     -1);\r
2865   mLocalPrefs.GetPref(ENTITYSPLIT2_KEY,       &mWindowInfo.nEntitySplit2,     -1);\r
2866 \r
2867   mLocalPrefs.GetPref(POSITIONX_KEY,          &mWindowInfo.position.x,        -1);\r
2868   mLocalPrefs.GetPref(POSITIONY_KEY,          &mWindowInfo.position.y,        -1);\r
2869   mLocalPrefs.GetPref(WIDTH_KEY,              &mWindowInfo.position.w,        -1);\r
2870   mLocalPrefs.GetPref(HEIGHT_KEY,             &mWindowInfo.position.h,        450);\r
2871 \r
2872   const window_position_t default_window_pos = { 0, 0, 200, 200, };\r
2873 \r
2874   mLocalPrefs.GetPref(ENTITYWND_KEY,          &mWindowInfo.posEntityWnd,      default_window_pos);\r
2875   mLocalPrefs.GetPref(MAPINFOWND_KEY,         &mWindowInfo.posMapInfoWnd,     default_window_pos);\r
2876   mLocalPrefs.GetPref(CAMWND_KEY,             &mWindowInfo.posCamWnd,         default_window_pos);\r
2877   mLocalPrefs.GetPref(ZWND_KEY,               &mWindowInfo.posZWnd,           default_window_pos);\r
2878   mLocalPrefs.GetPref(XYWND_KEY,              &mWindowInfo.posXYWnd,          default_window_pos);\r
2879   mLocalPrefs.GetPref(YZWND_KEY,              &mWindowInfo.posYZWnd,          default_window_pos);\r
2880   mLocalPrefs.GetPref(XZWND_KEY,              &mWindowInfo.posXZWnd,          default_window_pos);\r
2881   mLocalPrefs.GetPref(PATCHWND_KEY,           &mWindowInfo.posPatchWnd,       default_window_pos);\r
2882   mLocalPrefs.GetPref(SURFACEWND_KEY,         &mWindowInfo.posSurfaceWnd,     default_window_pos);\r
2883   mLocalPrefs.GetPref(ENTITYINFOWND_KEY,      &mWindowInfo.posEntityInfoWnd,  default_window_pos);\r
2884 \r
2885   mLocalPrefs.GetPref(ZWIDTH_KEY,             &mWindowInfo.nZWidth,           30);\r
2886   mLocalPrefs.GetPref(XYHEIGHT_KEY,           &mWindowInfo.nXYHeight,         300);\r
2887   mLocalPrefs.GetPref(XYWIDTH_KEY,            &mWindowInfo.nXYWidth,          300);\r
2888   mLocalPrefs.GetPref(CAMWIDTH_KEY,           &mWindowInfo.nCamWidth,         200);\r
2889   mLocalPrefs.GetPref(CAMHEIGHT_KEY,          &mWindowInfo.nCamHeight,        200);\r
2890   mLocalPrefs.GetPref(ZFLOATWIDTH_KEY,        &mWindowInfo.nZFloatWidth,      300);\r
2891 #ifdef _WIN32\r
2892   mLocalPrefs.GetPref(STATE_KEY,              &mWindowInfo.nState,            SW_SHOW);\r
2893 #endif\r
2894 \r
2895   // menu stuff\r
2896   mLocalPrefs.GetPref(COUNT_KEY,              &m_nMRUCount,                   0);\r
2897   for(i = 0; i < 4; i++) \r
2898   {\r
2899     char buf[64];\r
2900     sprintf (buf, "%s%d", FILE_KEY, i);\r
2901     mLocalPrefs.GetPref(buf,                  &m_strMRUFiles[i],              "");    \r
2902   }\r
2903 \r
2904   // some platform specific prefs\r
2905 #ifdef _WIN32\r
2906   mLocalPrefs.GetPref(NATIVEGUI_KEY,          &m_bNativeGUI,                  TRUE);\r
2907   mLocalPrefs.GetPref(STARTONPRIMMON_KEY,     &m_bStartOnPrimMon,             FALSE);\r
2908 #endif\r
2909 \r
2910   mLocalPrefs.GetPref(SI_TEXMENU_KEY,         &g_qeglobals.d_savedinfo.iTexMenu,                ID_VIEW_BILINEARMIPMAP);\r
2911   mLocalPrefs.GetPref(SI_GAMMA_KEY,           &g_qeglobals.d_savedinfo.fGamma,                  1.0f);\r
2912   mLocalPrefs.GetPref(SI_EXCLUDE_KEY,         &g_qeglobals.d_savedinfo.exclude,                 0); // nothing filtered by default\r
2913   mLocalPrefs.GetPref(SI_INCLUDE_KEY,         &g_qeglobals.d_savedinfo.include,                 INCLUDE_NAMES | INCLUDE_COORDS | INCLUDE_ANGLES | INCLUDE_CAMERATINT);\r
2914   mLocalPrefs.GetPref(SI_SHOWNAMES_KEY,       &g_qeglobals.d_savedinfo.show_names,              FALSE);\r
2915   mLocalPrefs.GetPref(SI_SHOWCOORDS_KEY,      &g_qeglobals.d_savedinfo.show_coordinates,        TRUE);\r
2916   mLocalPrefs.GetPref(SI_SHOWANGLES_KEY,      &g_qeglobals.d_savedinfo.show_angles,             TRUE);\r
2917   mLocalPrefs.GetPref(SI_SHOWOUTLINES_KEY,    &g_qeglobals.d_savedinfo.show_outline,            FALSE);\r
2918   mLocalPrefs.GetPref(SI_SHOWAXIS_KEY,        &g_qeglobals.d_savedinfo.show_axis,               TRUE);\r
2919   mLocalPrefs.GetPref(SI_NOSELOUTLINES_KEY,   &g_qeglobals.d_savedinfo.bNoSelectedOutlines,     FALSE);\r
2920 \r
2921   mLocalPrefs.GetPref(SI_OUTLINESTYLE_KEY,   &g_qeglobals.d_savedinfo.iSelectedOutlinesStyle,  OUTLINE_ZBUF|OUTLINE_BSEL);\r
2922 \r
2923   LoadTexdefPref(&g_qeglobals.d_savedinfo.m_SIIncrement, SI_SURFACE_TEXDEF_KEY);\r
2924   LoadTexdefPref(&g_qeglobals.d_savedinfo.m_PIIncrement, SI_PATCH_TEXDEF_KEY);\r
2925 \r
2926   // text editor binding\r
2927 #ifdef _WIN32\r
2928   mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseWin32Editor, TRUE);\r
2929 #else\r
2930   mLocalPrefs.GetPref(CUSTOMSHADEREDITOR_KEY, &m_bUseCustomEditor, FALSE);\r
2931   mLocalPrefs.GetPref(CUSTOMSHADEREDITORCOMMAND_KEY, &m_strEditorCommand, "");\r
2932 #endif\r
2933 \r
2934 \r
2935   vec3_t vDefaultAxisColours[3] = {\r
2936     {0.f, 0.5f, 0.f},\r
2937     {0.f, 0.f, 1.f},\r
2938     {1.f, 0.f, 0.f},\r
2939   };\r
2940 \r
2941   for(i = 0; i < 3; i++) {\r
2942     char buf[64];\r
2943     sprintf(buf, "%s%d", SI_AXISCOLORS_KEY, i);\r
2944     mLocalPrefs.GetPref(buf,   g_qeglobals.d_savedinfo.AxisColors[i], vDefaultAxisColours[i]);\r
2945   }\r
2946 \r
2947   vec3_t vDefaultColours[COLOR_LAST] = {\r
2948     {0.25f, 0.25f,  0.25f},\r
2949     {1.f,   1.f,    1.f},\r
2950     {0.75f, 0.75f,  0.75f},\r
2951     {0.5f,  0.5f,   0.5f},\r
2952     {0.25f, 0.25f,  0.25f},\r
2953     {0.0f,  0.0f,   0.0f},\r
2954     {0.f,   0.f,    1.f},\r
2955     {0.f,   0.f,    0.f},\r
2956     {0.f,   0.f,    0.f},\r
2957     {1.f,   0.f,    0.f},\r
2958     {0.f,   0.f,    1.f},\r
2959     {0.5f,  0.f,    0.75f},\r
2960     {1.0f,  0.f,    0.f},\r
2961     {0.f,   0.f,    0.f},\r
2962     {0.f,   0.f,    0.f},\r
2963   };\r
2964 \r
2965   for(i = 0; i < COLOR_LAST; i++) {\r
2966     char buf[64];\r
2967     sprintf(buf, "%s%d", SI_COLORS_KEY, i);\r
2968     mLocalPrefs.GetPref(buf,   g_qeglobals.d_savedinfo.colors[i], vDefaultColours[i]);\r
2969   }\r
2970 \r
2971   mLocalPrefs.GetPref(TEXTURECOMPRESSIONFORMAT_KEY, &m_nTextureCompressionFormat, 1);\r
2972 \r
2973   mLocalPrefs.GetPref(LIGHTRADIUS_KEY, &m_nLightRadiuses, TRUE);\r
2974 \r
2975   mLocalPrefs.GetPref(Q3MAP2TEX_KEY, &m_bQ3Map2Texturing, TRUE);\r
2976 \r
2977 #ifdef ATIHACK_812\r
2978         mLocalPrefs.GetPref(ATIHACK_KEY, &m_bGlATIHack, FALSE);\r
2979 #endif\r
2980 \r
2981   Undo_SetMaxSize(m_nUndoLevels); // set it internally as well / FIXME: why not just have one global value?\r
2982 \r
2983   UpdateTextureCompression();\r
2984 \r
2985 #ifdef ATIHACK_812\r
2986   UpdateATIHack();\r
2987 #endif\r
2988 \r
2989   if (mLocalPrefs.mbEmpty)\r
2990   {\r
2991     mLocalPrefs.mbEmpty = false;\r
2992     Sys_Printf("Saving local.pref with default pref values\n");\r
2993     SavePrefs();\r
2994   }\r
2995 }\r
2996 \r
2997 void PrefsDlg::SavePrefs ()\r
2998 {\r
2999   if (g_qeglobals.disable_ini)\r
3000     return;\r
3001 \r
3002 #ifdef _DEBUG\r
3003   Sys_Printf("PrefsDlg::SavePrefs\n");\r
3004 #endif\r
3005 \r
3006   // this will take care of copying back from the dialog to the variables\r
3007   // NOTE: it may be overkill to call systematically before a SavePrefs, but it's safer\r
3008   // this will also cause an UpdateData for the mGamesDialog\r
3009   UpdateData(TRUE);\r
3010 \r
3011   mGamesDialog.SavePrefs();\r
3012 \r
3013   // update the tree and save it\r
3014   mLocalPrefs.UpdatePrefTree();\r
3015   if (!mLocalPrefs.WriteXMLFile(m_inipath->str))\r
3016     Sys_FPrintf(SYS_ERR, "Error occured while saving local prefs file '%s'\n", m_inipath->str);\r
3017 \r
3018   if (m_nMouse == 0)\r
3019     m_nMouseButtons = 2;\r
3020   else\r
3021     m_nMouseButtons = 3;\r
3022 \r
3023 }\r
3024 \r
3025 void PrefsDlg::PostModal (int code)\r
3026 {\r
3027   if (code == IDOK)\r
3028   {\r
3029     SavePrefs();\r
3030     // make sure the logfile is ok\r
3031     Sys_LogFile();\r
3032     #ifdef ATIHACK_812\r
3033       UpdateATIHack();\r
3034     #endif\r
3035     if (g_pParentWnd)\r
3036       g_pParentWnd->SetGridStatus();\r
3037     Sys_UpdateWindows(W_ALL);\r
3038     if (m_nUndoLevels != 0)\r
3039                 Undo_SetMaxSize(m_nUndoLevels);\r
3040   }\r
3041 }\r
3042 \r
3043 void PrefsDlg::DoEditorSensitivity()\r
3044 {\r
3045   if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data (G_OBJECT(m_pWidget), "check_customeditor"))))\r
3046   {\r
3047     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), TRUE);\r
3048     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), TRUE);\r
3049     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), TRUE);\r
3050   }\r
3051   else\r
3052   {\r
3053     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "label_customeditor")), FALSE);\r
3054     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "entry_customeditor")), FALSE);\r
3055     gtk_widget_set_sensitive(GTK_WIDGET(g_object_get_data (G_OBJECT(m_pWidget), "button_customeditor")), FALSE);\r
3056   }\r
3057 }\r
3058 \r
3059 void PrefsDlg::DoSensitivity()\r
3060 {\r
3061 #if 0\r
3062   // first, look at the project file version ... will monitoring work?\r
3063   // project files now XML, guaranteed to be at least version 2\r
3064   if (0)//IntForKey( g_qeglobals.d_project_entity, "version" ) < 2)\r
3065   {\r
3066     if (m_bWarn)\r
3067     {\r
3068       Str Msg;\r
3069       Msg = "The current project file (";\r
3070       Msg += g_PrefsDlg.m_strLastProject;\r
3071       Msg += ") is not at least version 2.\nI need version 2 or above to setup BSP monitoring correctly.";\r
3072       gtk_MessageBox(m_pWidget, Msg.GetBuffer(), MB_OK );\r
3073       \r
3074       m_bWarn = false;\r
3075     }\r
3076 \r
3077     // go ahead, disable everybuddy\r
3078     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );\r
3079     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), FALSE );\r
3080     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );\r
3081     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );\r
3082   }\r
3083   else\r
3084   {\r
3085 #endif\r
3086 //    m_bWarn = true;\r
3087 \r
3088     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), TRUE );\r
3089     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" )), TRUE );\r
3090     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), TRUE );\r
3091     gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), TRUE );\r
3092 \r
3093     if ( ! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_monitorbsp" ) ) ) )\r
3094     {\r
3095       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_leakstop" )), FALSE );\r
3096       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" )), FALSE );\r
3097       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );\r
3098     } else if (! gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_object_get_data( G_OBJECT(m_pWidget), "check_runengine" ) ) ) )\r
3099     {\r
3100       gtk_widget_set_sensitive( GTK_WIDGET(g_object_get_data( G_OBJECT(m_pWidget), "check_sleep" )), FALSE );\r
3101     }\r
3102 }\r