]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/preferences.h
fix and improve the game selection and game configuration dialogs - added dir dialog...
[xonotic/netradiant.git] / radiant / preferences.h
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #ifndef _PREFERENCES_H_
23 #define _PREFERENCES_H_
24
25 #include "dialog.h"
26 #include "gtkr_list.h"
27 //#include "profile.h"
28
29 #define MAX_TEXTURE_QUALITY 3
30
31 enum PrefTypes_t
32 {
33   PREF_STR,
34   PREF_INT,
35   PREF_BOOL,
36   PREF_FLOAT,
37   PREF_VEC3,
38   PREF_WNDPOS,
39 };
40
41 /*!
42 a preference assignment, name, type and pointer to value
43 we don't store the xmlNodePtr because the document itself can be thrown away upon any LoadPref
44 (see CGameDialog::UpdatePrefTree)
45 */
46 class CPrefAssignment
47 {
48 public:
49   Str mName;
50   PrefTypes_t mType;
51   void *mVal;
52
53   CPrefAssignment(char *name, PrefTypes_t Type, void *Val)
54   {
55     mName = name; mType = Type; mVal = Val;
56   }
57   CPrefAssignment() { mVal = NULL; }
58   CPrefAssignment(const CPrefAssignment& ass);
59   virtual ~CPrefAssignment() { }
60   virtual CPrefAssignment& operator =(const CPrefAssignment& ass);
61 };
62
63
64 /*!
65 generic preferences storage class, using xml files
66 */
67 class CXMLPropertyBag
68 {
69 private:
70   /*!
71   local prefs file
72   */
73   xmlDocPtr mpDoc;
74   xmlNodePtr mpDocNode;
75
76   /*!
77   prefs assignments (what pref name, what type, what variable)
78   */
79   list<CPrefAssignment> mPrefAssignments;
80
81   /*!
82   name of file to load/save as
83   */
84   Str mStrFilename;
85
86   /*!
87   store assignment in the property list if not already there
88   */
89   void PushAssignment(char *name, PrefTypes_t type, void *pV);
90
91   /*!
92   find the xmlnode relating to the epair name
93   */
94   xmlNodePtr EpairForName(const char *name);
95
96 public:
97   CXMLPropertyBag();
98   virtual ~CXMLPropertyBag() 
99   {
100     if (InUse())
101       Clear();
102   };
103
104   /*!
105   read a pref setting, if doesn't exist, will add it to the xml tree (using default value provided)
106   \arg name the name of the pref
107   \arg pV pointer to the value
108   \arg V default value
109   those functions will fill in the list of preferences assignments
110     (name, type and pointer to value)
111     this is used in UpdatePrefTree
112   */
113   void GetPref(char *name, Str *pV, char *V);
114   void GetPref(char *name, int *pV, int V);
115   void GetPref(char *name, bool *pV, bool V);
116   void GetPref(char *name, float *pV, float V);
117   void GetPref(char *name, float *pV, float* V);
118   void GetPref(char *name, window_position_t* pV, window_position_t V);
119
120   /*!
121   returns whether or not the property bag is already open
122   */
123   qboolean InUse() { return (mpDoc != NULL); };
124
125   /*!
126   unload the xml doc, and free the tree
127   */
128   void Clear();
129
130   /*|
131   read data from our XML file
132   */
133   void ReadXMLFile(const char* pFilename);
134
135   /*|
136   write out the property bag to an XML data file
137   return is success/fail
138   */
139   qboolean WriteXMLFile(const char* pFilename);
140
141   /*!
142   update the xml tree with data form the property list, usually in preparation for a write
143   */
144   void UpdatePrefTree();
145
146   /*!
147   did the file have any data or not?
148   */
149   qboolean mbEmpty;
150 };
151
152 /*!
153 holds information for a given game
154 I'm a bit unclear on that still
155 it holds game specific configuration stuff
156 such as base names, engine names, some game specific features to activate in the various modules
157 it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking
158 support for a new game)
159
160 what we do now is fully generate the information for this during the setup. We might want to
161 generate a piece that just says "the game pack is there", but put the rest of the config somwhere
162 else (i.e. not generated, copied over during setup .. for instance in the game tools directory)
163 */
164 class CGameDescription
165 {
166 public:
167   xmlDocPtr mpDoc; ///< the game description xml tree
168   Str mGameToolsPath; ///< the explicit path to the game-dependent modules
169   Str mGameName; ///< name of the game used in dialogs
170   Str mGameFile; ///< the .game file that describes this game
171   Str mBaseGame; ///< basegame directory
172   Str mEnginePath; ///< path to the engine
173   Str mEngine; ///< engine name
174 #if defined (__linux__) || defined (__APPLE__)
175   Str mUserPathPrefix; ///< prefix for ~/.q3a ~/.wolf init, only on *nix
176 #endif
177   Str mShaderPath; ///< the path in which to look for shaders
178   Str mShaderlist; ///< shaderlist file
179   float mTextureDefaultScale; ///< default scale (0.5 in q3, 1.0 in q1/q2, 0.25 in JK2 ..)
180   bool mEClassSingleLoad; ///< only load a single eclass definition file
181   bool mNoPatch; ///< this game doesn't support patch technology
182   Str mCaulkShader; ///< the shader to use for caulking
183   bool quake2; ///< set this to true to get quake2
184
185   CGameDescription() { mpDoc = NULL; }
186   /*!
187   \todo parse basic info from the node
188   user-friendly name of the game
189   essential parameters (such as the start dir)
190   */
191   CGameDescription(xmlDocPtr pDoc, const Str &GameFile);
192   virtual ~CGameDescription() { xmlFreeDoc(mpDoc); }
193
194   void Dump();
195 };
196
197 /*!
198 select games, copy editing assets and write out configuration files
199  */
200
201 #define Q3_PACK "Q3Pack"
202 #define URT_PACK "UrTPack"
203 #define UFOAI_PACK "UFOAIPack"
204 #define Q2W_PACK "Q2WPack"
205 #define WARSOW_PACK "WarsowPack"
206 #define NEXUIZ_PACK "NexuizPack"
207 #define Q2_PACK "Q2Pack"
208
209 class CGameInstall : public Dialog {
210 public:
211         CGameInstall();
212         void ScanGames();
213         void Run();
214         void BuildDialog();
215
216         static void OnBtnBrowseEngine( GtkWidget *widget, gpointer data );
217         static void OnGameSelectChanged( GtkWidget *widget, gpointer data );
218
219         enum gameType_e {
220                 GAME_NONE = 0,
221                 GAME_Q3 = 1,
222                 GAME_URT,
223                 GAME_UFOAI,
224                 GAME_Q2W,
225                 GAME_WARSOW,
226                 GAME_NEXUIZ,
227                 GAME_Q2,
228                 GAME_COUNT
229         };
230
231 protected:
232         Str             m_strName;
233         Str             m_strMod;
234         Str             m_strEngine;
235         int             m_nComboSelect;
236
237         // maps from m_nComboSelect to the games
238         int     m_availGames[GAME_COUNT];
239 };
240
241 /*!
242 standalone dialog for games selection, and more generally global settings
243 */
244 class CGameDialog : public Dialog
245 {
246   GtkWidget *mFrame; ///< this is built on-demand first time it's used
247   GtkWidget *mTopBox; ///< top level box used to store the dialog frame, must unhook after modal use
248
249   GtkComboBox   *mGameCombo;    // combo box holds the selection of available game
250
251   /*!
252   global prefs storage
253   */
254   CXMLPropertyBag mGlobalPrefs;
255
256 #ifdef _WIN32
257   /*!
258   run from a network share
259   this one is not being saved out in prefs, since we need to know before we load prefs
260   we use a dummy file NETRUN_FILENAME as flag
261   all done with static stuff
262   */
263   static bool m_bNetRun;
264 #endif
265
266   bool m_bDoGameInstall;
267
268   CGameInstall mGameInstall;
269
270 protected:
271   
272   int m_nComboSelect; ///< intermediate int value for combo in dialog box
273
274 public:
275
276   /*! 
277   those settings are saved in the global prefs file 
278   I'm too lazy to wrap behind protected access, not sure this needs to be public
279   NOTE: those are preference settings. if you change them it is likely that you would
280   have to restart the editor for them to take effect
281   */
282   /*@{*/
283   /*!
284   what game has been selected
285   this is the name of the .game file
286   */
287   Str m_sGameFile;
288   /*!
289   auto-load the game on startup
290   this is linked to auto-load checkbox
291   */
292   bool m_bAutoLoadGame;
293   /*!
294   log console to radiant.log
295   m_bForceLogConsole is an obscure forced latching situation
296   */
297   bool m_bLogConsole;
298   bool m_bForceLogConsole;
299   /*@}*/
300
301   /*!
302   points somewhere in mGames, set once at startup
303   */
304   CGameDescription *m_pCurrentGameDescription;
305
306   /*!
307   the list of game descriptions we scanned from the game/ dir
308   */
309   list<CGameDescription *> mGames;
310
311   CGameDialog() {
312           mFrame = NULL;
313           m_pCurrentGameDescription = NULL;
314           m_bLogConsole = false;
315           m_bForceLogConsole = false;
316           m_bDoGameInstall = true;      // go through DoModal at least once
317           mGameCombo = NULL;
318   }
319   virtual ~CGameDialog(); 
320
321   void AddPacksURL( Str &s );
322     
323   /*!
324   intialize the game dialog, called at CPrefsDlg::Init
325   will scan for games, load prefs, and do game selection dialog if needed
326   */
327   void Init();
328
329   /*!
330   reset the global settings by removing the file
331   */
332   void Reset();
333
334   /*!
335   run the dialog UI for the list of games 
336   */
337   void DoGameDialog();
338
339   /*!
340         call out to the game installation dialog
341   */
342   void DoGameInstall();
343
344   /*!
345   Dialog API
346   this is only called when the dialog is built at startup for main engine select
347   */
348   void BuildDialog();
349   void UpdateData( bool retrieve );
350
351   /*!
352   construction of the dialog frame
353   this is the part to be re-used in prefs dialog
354   for the standalone dialog, we include this in a modal box
355   for prefs, we hook the frame in the main notebook
356   build the frame on-demand (only once)
357   */
358   GtkWidget *GetGlobalFrame();
359
360   /*!
361   global preferences subsystem
362   XML-based this time, hopefully this will generalize to other prefs
363   LoadPrefs has hardcoded defaults
364   NOTE: it may not be strictly 'CGameDialog' to put the global prefs here
365     could have named the class differently I guess
366   */
367   /*@{*/
368   void LoadPrefs(); ///< load from file into variables
369   void SavePrefs(); ///< save pref variables to file
370   /*@}*/
371
372   /*!
373   read or set netrun (check file)
374   \param retrieve 
375     if false, will check if netrun file is present and will set m_bNetRun
376     if true, will create/erase the netrun file depending on m_bNetRun
377     NOTE: this is not backwards, 'retrieve' means 'retrieve from settings dialog' - in terms of UI
378   */
379   static void UpdateNetrun(bool retrieve);
380   /*!
381   get current netrun setting
382   */
383   static bool GetNetrun();
384
385 private:
386   /*!
387   scan for .game files, load them
388   */
389   void ScanForGames();
390
391   /*!
392   inits g_PrefsDlg.m_global_rc_path
393   */
394   void InitGlobalPrefPath();
395
396   /*!
397   uses m_nComboItem to find the right mGames
398   */
399   CGameDescription *GameDescriptionForComboItem();
400
401   /*!
402         callback for the game install button
403   */
404   static void SInstallCallback( GtkWidget *widget, gpointer data );
405
406   void UpdateGameCombo();
407 };
408
409 typedef struct {
410   int nEntitySplit1;
411   int nEntitySplit2;
412   
413   window_position_t position;
414
415   window_position_t posEntityWnd;
416   window_position_t posMapInfoWnd;
417   window_position_t posCamWnd;
418   window_position_t posZWnd;
419   window_position_t posXYWnd;
420   window_position_t posXZWnd;
421   window_position_t posYZWnd;
422   window_position_t posPatchWnd;
423   window_position_t posSurfaceWnd;
424   window_position_t posEntityInfoWnd;
425
426   int nXYHeight;
427   int nZWidth;
428   int nXYWidth;
429   int nCamWidth;
430   int nCamHeight;
431   int nZFloatWidth;
432   int nState;
433 } windowPosInfo_t;
434
435 class PrefsDlg : public Dialog
436 {
437   
438 public:
439   /*!
440   local prefs file
441   */
442   CXMLPropertyBag mLocalPrefs;
443
444   // will enable/disable stuff according to the situation
445   void DoSensitivity();
446   void PreModal() { DoSensitivity(); }
447   
448   // enable/disable custom editor entry
449   void DoEditorSensitivity();
450   
451   /*!
452   this holds global level preferences
453   */
454   CGameDialog mGamesDialog;
455 protected:
456   // warning about old project files
457   bool m_bWarn;
458   list<CGameDescription *> mGames;
459   
460 public:
461   // last light intensity used in the CLightPrompt dialog, stored in registry
462   int m_iLastLightIntensity;
463   // these mirror what goes in the combo box
464   // see PrefDlg::m_nShader, tells wether to load NONE / COMMON or ALL shaders at parsing stage
465   enum {SHADER_NONE = 0, SHADER_COMMON, SHADER_ALL};
466
467   // Gef: updated preferences dialog
468   /*! Preference notebook page numbers */
469   enum {PTAB_FRONT = 0, PTAB_GAME_SETTINGS, PTAB_2D, PTAB_CAMERA, PTAB_TEXTURE, PTAB_LAYOUT, PTAB_MOUSE,
470         PTAB_EDITING, PTAB_STARTUP, PTAB_PATHS, PTAB_MISC, PTAB_BSPMONITOR} pref_tabs;
471   
472   GtkWidget *notebook;
473        
474   void UpdateTextureCompression();
475
476 #ifdef ATIHACK_812
477   void UpdateATIHack();
478 #endif
479         
480   void LoadPrefs();
481   void SavePrefs();
482   void LoadTexdefPref(texdef_t* pTexdef, char* pName);
483
484   PrefsDlg ();
485   virtual ~PrefsDlg ()
486   {
487     g_string_free (m_rc_path, true );
488     g_string_free (m_inipath, true );
489   }
490
491   /*!
492   path for global settings
493   win32: g_strAppPath
494   linux: ~/.radiant/<version>/
495   */
496   GString *m_global_rc_path;
497
498   /*!
499   path to per-game settings
500   used for various game dependant storage
501   win32: g_strGameToolsPath
502   linux: ~/.radiant/<version>/<gamename>/
503   */
504   GString *m_rc_path;
505
506   /*!
507   holds per-game settings
508   m_rc_path+"local.pref"
509   \todo FIXME at some point this should become XML property bag code too
510   */
511   GString *m_inipath;
512
513   // initialize the above paths
514   void Init();
515
516 #if 0
517   // DEPRECATED: use engine path from the current game description instead
518         // path to the top-level installation
519         Str     m_strEnginePath;
520   // name of executable
521   // quake2 quake3 etc
522         Str     m_strEngine;
523   // we use this Str to store the full path to the engine: m_strEnginePath + m_strEngine
524   // it's not stored in the registry or anything, just ued for display in prefs
525   Str   m_strPrefsDlgEngine;
526 #endif
527
528   // Dialog Data
529   int   m_nMouse;
530   MainFrame::EViewStyle m_nView;
531   bool  m_bTextureLock;
532   bool  m_bLoadLast;
533         // path to the project loaded at startup
534         // if g_PrefsDlg can't find the information in the ini file
535         // it will try to guess and eventually ask the user
536   Str   m_strLastProject;  
537   /*!
538   version of last loaded project file
539   says -1 if there's no version loaded
540   if it's a manually constructed project file, will be 0
541   otherwise the actual 'version' epair
542   */
543   int   m_nLastProjectVer;
544   Str   m_strLastMap;
545   bool  m_bInternalBSP;
546   bool  m_bRightClick;
547   bool  m_bSetGame;
548   bool  m_bAutoSave;
549   bool  m_bLoadLastMap;
550   bool  m_bTextureWindow;
551   bool  m_bSnapShots;
552   float m_fTinySize;
553   bool  m_bCleanTiny;
554   bool  m_bCamXYUpdate;
555   int   m_nCamDragMultiSelect;
556   bool  m_bCamDragMultiSelect;
557   bool  m_bCamFreeLook;
558   bool  m_bCamFreeLookStrafe;
559   bool  m_bCamInverseMouse;
560   bool  m_bCamDiscrete;
561   bool  m_bNewLightDraw;
562   Str   m_strPrefabPath;
563   int   m_nWhatGame;
564   bool  m_bALTEdge;
565   bool  m_bFaceColors;
566   bool  m_bXZVis;
567   bool  m_bYZVis;
568   bool  m_bZVis;
569   bool  m_bSizePaint;
570   bool  m_bDLLEntities;
571   bool  m_bRotateLock;
572   bool  m_bDetachableMenus;
573   bool  m_bPatchToolbar;
574   bool  m_bWideToolbar;
575   bool  m_bPluginToolbar;
576   bool  m_bNoClamp;
577         //++timo this is most likely broken, I don't know what it's supposed to do
578   Str   m_strUserPath;
579   int   m_nRotation;
580   bool  m_bChaseMouse;
581   bool  m_bTextureScrollbar;
582   bool  m_bDisplayLists;
583   bool  m_bAntialiasedPointsAndLines; // Fishman - Add antialiazed points and lines support. 09/03/00
584   bool  m_bShowShaders;
585   int   m_nShader;
586   bool  m_bNoStipple;
587   int   m_nUndoLevels;
588   bool  m_bVertexSplit;
589
590   int   m_nMouseButtons;
591   int   m_nAngleSpeed;
592   int   m_nMoveSpeed;
593   int   m_nAutoSave;
594   bool  m_bCubicClipping;
595   int   m_nCubicScale;
596   bool  m_bSelectCurves;
597   bool  m_bSelectModels;
598   int   m_nEntityShowState;
599   int   m_nTextureScale;
600   bool  m_bNormalizeColors;
601   bool  m_bSwitchClip;
602   bool  m_bSelectWholeEntities;
603   int   m_nTextureQuality;
604   bool  m_bGLLighting;
605   bool  m_bTexturesShaderlistOnly;
606   int   m_nSubdivisions;
607   bool  m_bFloatingZ;
608   bool  m_bLatchedFloatingZ;
609   // Gef: Kyro GL_POINT workaround
610   bool  m_bGlPtWorkaround;
611
612   // how many menus in the texture thing before we split?
613   int   m_nTextureMenuSplit;
614
615   // watch the BSP process through network connections
616   // true: trigger the BSP steps one by one and monitor them through the network
617   // false: create a BAT / .sh file and execute it. don't bother monitoring it.
618   bool  m_bWatchBSP;
619   // do we stop the compilation process if we come accross a leak?
620   bool  m_bLeakStop;
621   // timeout when beginning a step (in seconds)
622   // if we don't get a connection quick enough we assume something failed and go back to idling
623   int   m_iTimeout;
624   bool  m_bRunQuake;
625   // store prefs setting for automatic sleep mode activation
626   bool  m_bDoSleep;
627   
628   bool m_bClipCaulk;
629
630   // make the texture increments match the grid changes
631   bool m_bSnapTToGrid;
632
633   // try to fix the target/targetname conflicts when importing a map (default true)
634   bool m_bDoTargetFix;
635
636   // the increment step we use against the wheel mouse
637   int m_nWheelInc;
638
639 #ifdef _WIN32
640   // use the file associations to open files instead of builtin Gtk editor
641   bool m_bUseWin32Editor;
642 #else
643   // custom shader editor
644   bool m_bUseCustomEditor;
645   Str  m_strEditorCommand;  // this is the command executed
646 #endif
647
648 #ifdef _WIN32
649   bool m_bNativeGUI;
650   bool m_bStartOnPrimMon;
651 #endif
652
653   bool m_bPatchBBoxSelect;
654
655   // RR2DO2: latched data, for settings that require a restart. We don't want to set
656   // these directly in case users set them under preferences and then continue working
657   // with the editor.
658   MainFrame::EViewStyle m_nLatchedView;
659   int m_nMRUCount;
660   Str m_strMRUFiles[4];
661
662   windowPosInfo_t mWindowInfo;
663
664   bool  m_bLatchedDetachableMenus;
665   bool  m_bLatchedPatchToolbar;
666   bool  m_bLatchedWideToolbar;
667   bool  m_bLatchedPluginToolbar;
668   int   m_nLatchedShader;
669   int   m_nLatchedTextureQuality;
670
671   // RIANT
672   // texture compression format
673   int m_nTextureCompressionFormat;
674
675   int m_nLightRadiuses;
676   
677   bool m_bQ3Map2Texturing;
678
679 #ifdef ATIHACK_812
680         bool m_bGlATIHack;
681 #endif
682
683   void UpdateData (bool retrieve);
684
685   /*! Utility function for swapping notebook pages for tree list selections */
686   void showPrefPage(int prefpage);
687
688 protected:
689   /*! Scan for game description files and build a list */
690   void ScanForGames();
691
692   /*! Dialog API */
693   void BuildDialog ();
694   void PostModal (int code);
695 };
696
697 #endif // _PREFERENCES_H_