2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
37 #include <process.h> // for _beginthreadex and _endthreadex
38 #include <ddeml.h> // for MSGF_DDEMGR
43 static char THIS_FILE[] = __FILE__;
46 idCVar radiant_entityMode( "radiant_entityMode", "0", CVAR_TOOL | CVAR_ARCHIVE, "" );
48 /////////////////////////////////////////////////////////////////////////////
51 BEGIN_MESSAGE_MAP(CRadiantApp, CWinApp)
52 //{{AFX_MSG_MAP(CRadiantApp)
53 ON_COMMAND(ID_HELP, OnHelp)
55 // Standard file based document commands
56 ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
57 ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
58 // Standard print setup command
59 ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
62 /////////////////////////////////////////////////////////////////////////////
63 // CRadiantApp construction
65 CRadiantApp::CRadiantApp()
67 // TODO: add construction code here,
68 // Place all significant initialization in InitInstance
71 /////////////////////////////////////////////////////////////////////////////
72 // The one and only CRadiantApp object
75 HINSTANCE g_DoomInstance = NULL;
76 bool g_editorAlive = false;
78 void RadiantPrint( const char *text ) {
79 if ( g_editorAlive && g_Inspectors ) {
80 if (g_Inspectors->consoleWnd.GetSafeHwnd()) {
81 g_Inspectors->consoleWnd.AddText( text );
86 void RadiantShutdown( void ) {
87 theApp.ExitInstance();
94 This is also called when you 'quit' in doom
97 void RadiantInit( void ) {
99 // make sure the renderer is initialized
100 if ( !renderSystem->IsOpenGLRunning() ) {
101 common->Printf( "no OpenGL running\n" );
105 g_editorAlive = true;
107 // allocate a renderWorld and a soundWorld
108 if ( g_qeglobals.rw == NULL ) {
109 g_qeglobals.rw = renderSystem->AllocRenderWorld();
110 g_qeglobals.rw->InitFromMap( NULL );
112 if ( g_qeglobals.sw == NULL ) {
113 g_qeglobals.sw = soundSystem->AllocSoundWorld( g_qeglobals.rw );
116 if ( g_DoomInstance ) {
117 if ( ::IsWindowVisible( win32.hWnd ) ) {
118 ::ShowWindow( win32.hWnd, SW_HIDE );
119 g_pParentWnd->ShowWindow( SW_SHOW );
120 g_pParentWnd->SetFocus();
123 Sys_GrabMouseCursor( false );
125 g_DoomInstance = win32.hInstance;
126 CWinApp* pApp = AfxGetApp();
127 CWinThread *pThread = AfxGetThread();
131 // App global initializations (rare)
132 pApp->InitApplication();
134 // Perform specific initializations
135 pThread->InitInstance();
138 //qwglMakeCurrent(0, 0);
139 qwglMakeCurrent(win32.hDC, win32.hGLRC);
141 // hide the doom window by default
142 ::ShowWindow( win32.hWnd, SW_HIDE );
147 extern void Map_VerifyCurrentMap(const char *map);
149 void RadiantSync( const char *mapName, const idVec3 &viewOrg, const idAngles &viewAngles ) {
150 if ( g_DoomInstance == NULL ) {
154 if ( g_DoomInstance ) {
156 osPath = fileSystem->RelativePathToOSPath( mapName );
157 Map_VerifyCurrentMap( osPath );
158 idAngles flip = viewAngles;
159 flip.pitch = -flip.pitch;
160 g_pParentWnd->GetCamera()->SetView( viewOrg, flip );
161 g_pParentWnd->SetFocus();
162 Sys_UpdateWindows( W_ALL );
163 g_pParentWnd->RoutineProcessing();
167 void RadiantRun( void ) {
168 static bool exceptionErr = false;
169 int show = ::IsWindowVisible(win32.hWnd);
172 if (!exceptionErr && !show) {
173 //qglPushAttrib(GL_ALL_ATTRIB_BITS);
177 //qwglMakeCurrent(0, 0);
178 qwglMakeCurrent(win32.hDC, win32.hGLRC);
181 catch( idException &ex ) {
182 ::MessageBox(NULL, ex.error, "Exception error", MB_OK);
187 /////////////////////////////////////////////////////////////////////////////
188 // CRadiantApp initialization
190 HINSTANCE g_hOpenGL32 = NULL;
191 HINSTANCE g_hOpenGL = NULL;
192 bool g_bBuildList = false;
194 BOOL CRadiantApp::InitInstance()
196 //g_hOpenGL32 = ::LoadLibrary("opengl32.dll");
197 // AfxEnableControlContainer();
199 // Standard initialization
200 // If you are not using these features and wish to reduce the size
201 // of your final executable, you should remove from the following
202 // the specific initialization routines you do not need.
203 //AfxEnableMemoryTracking(FALSE);
206 //Enable3dControls(); // Call this when using MFC in a shared DLL
208 //Enable3dControlsStatic(); // Call this when linking to MFC statically
211 // If there's a .INI file in the directory use it instead of registry
213 char RadiantPath[_MAX_PATH];
214 GetModuleFileName( NULL, RadiantPath, _MAX_PATH );
218 Finder.FindFile( RadiantPath );
219 Finder.FindNextFile();
221 CString Root = Finder.GetRoot();
223 CString IniPath = Root + "\\REGISTRY.INI";
224 // search for ini file
225 Finder.FindNextFile();
226 if (Finder.FindFile( IniPath ))
228 Finder.FindNextFile();
229 // use the .ini file instead of the registry
230 free((void*)m_pszProfileName);
231 m_pszProfileName=_tcsdup(_T(Finder.GetFilePath()));
232 // look for the registry key for void* buffers storage ( these can't go into .INI files )
241 sprintf( iBuf, "%d", i );
242 key = "Software\\Q3Radiant\\IniPrefs" + CString(iBuf);
243 // does this key exists ?
244 if ( RegOpenKeyEx( HKEY_CURRENT_USER, key, 0, KEY_ALL_ACCESS, &hkResult ) != ERROR_SUCCESS )
246 // this key doesn't exist, so it's the one we'll use
247 strcpy( g_qeglobals.use_ini_registry, key.GetBuffer(0) );
248 RegCreateKeyEx( HKEY_CURRENT_USER, key, 0, NULL,
249 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkResult, &dwDisp );
250 RegSetValueEx( hkResult, "RadiantName", 0, REG_SZ, reinterpret_cast<CONST BYTE *>(RadiantPath), strlen( RadiantPath )+1 );
251 RegCloseKey( hkResult );
256 char RadiantAux[ _MAX_PATH ];
257 unsigned long size = _MAX_PATH;
258 // the key exists, is it the one we are looking for ?
259 RegQueryValueEx( hkResult, "RadiantName", 0, &type, reinterpret_cast<BYTE *>(RadiantAux), &size );
260 RegCloseKey( hkResult );
261 if ( !strcmp( RadiantAux, RadiantPath ) )
264 strcpy( g_qeglobals.use_ini_registry, key.GetBuffer(0) );
270 g_qeglobals.use_ini = true;
274 // Change the registry key under which our settings are stored.
275 SetRegistryKey( EDITOR_REGISTRY_KEY );
276 g_qeglobals.use_ini = false;
279 LoadStdProfileSettings(); // Load standard INI file options (including MRU)
282 // Register the application's document templates. Document templates
283 // serve as the connection between documents, frame windows and views.
285 // CMultiDocTemplate* pDocTemplate;
286 // pDocTemplate = new CMultiDocTemplate(
288 // RUNTIME_CLASS(CRadiantDoc),
289 // RUNTIME_CLASS(CMainFrame), // custom MDI child frame
290 // RUNTIME_CLASS(CRadiantView));
291 // AddDocTemplate(pDocTemplate);
293 // create main MDI Frame window
295 g_PrefsDlg.LoadPrefs();
297 qglEnableClientState( GL_VERTEX_ARRAY );
299 CString strTemp = m_lpCmdLine;
301 if (strTemp.Find("builddefs") >= 0) {
305 CMainFrame* pMainFrame = new CMainFrame;
306 if (!pMainFrame->LoadFrame(IDR_MENU_QUAKE3)) {
310 if (pMainFrame->m_hAccelTable) {
311 ::DestroyAcceleratorTable(pMainFrame->m_hAccelTable);
314 pMainFrame->LoadAccelTable(MAKEINTRESOURCE(IDR_MINIACCEL));
316 m_pMainWnd = pMainFrame;
318 // The main window has been initialized, so show and update it.
319 pMainFrame->ShowWindow(m_nCmdShow);
320 pMainFrame->UpdateWindow();
325 /////////////////////////////////////////////////////////////////////////////
326 // CRadiantApp commands
328 int CRadiantApp::ExitInstance()
332 int ret = CWinApp::ExitInstance();
338 BOOL CRadiantApp::OnIdle(LONG lCount) {
340 g_pParentWnd->RoutineProcessing();
343 //return CWinApp::OnIdle(lCount);
346 void CRadiantApp::OnHelp()
348 ShellExecute(m_pMainWnd->GetSafeHwnd(), "open", "http://www.idDevNet.com", NULL, NULL, SW_SHOW);
351 int CRadiantApp::Run( void )
358 MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!!
360 MSG *msg = &m_msgCur;
363 // phase1: check to see if we can do idle work
364 while (bIdle && !::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE)) {
365 // call OnIdle while in bIdle state
366 if (!OnIdle(lIdleCount++)) {
367 bIdle = FALSE; // assume "no idle" state
371 // phase2: pump messages while available
373 // pump message, but quit on WM_QUIT
374 if (!PumpMessage()) {
375 return ExitInstance();
378 // reset "no idle" state after pumping "normal" message
379 if (IsIdleMessage(msg)) {
384 } while (::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE));
391 =============================================================
395 =============================================================
398 bool SaveRegistryInfo(const char *pszName, void *pvBuf, long lSize)
400 SetCvarBinary(pszName, pvBuf, lSize);
401 common->WriteFlaggedCVarsToFile( "editor.cfg", CVAR_TOOL, "sett" );
405 bool LoadRegistryInfo(const char *pszName, void *pvBuf, long *plSize)
407 return GetCvarBinary(pszName, pvBuf, *plSize);
410 bool SaveWindowState(HWND hWnd, const char *pszName)
413 GetWindowRect(hWnd, &rc);
414 if (hWnd != g_pParentWnd->GetSafeHwnd()) {
415 if (::GetParent(hWnd) != g_pParentWnd->GetSafeHwnd()) {
416 ::SetParent(hWnd, g_pParentWnd->GetSafeHwnd());
418 MapWindowPoints(NULL, g_pParentWnd->GetSafeHwnd(), (POINT *)&rc, 2);
420 return SaveRegistryInfo(pszName, &rc, sizeof(rc));
424 bool LoadWindowState(HWND hWnd, const char *pszName)
427 LONG lSize = sizeof(rc);
429 if (LoadRegistryInfo(pszName, &rc, &lSize))
435 if (rc.right < rc.left + 16)
436 rc.right = rc.left + 16;
437 if (rc.bottom < rc.top + 16)
438 rc.bottom = rc.top + 16;
440 MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE);
448 ===============================================================
452 ===============================================================
455 void Sys_UpdateStatusBar( void )
457 extern int g_numbrushes, g_numentities;
459 char numbrushbuffer[100] = "";
461 sprintf( numbrushbuffer, "Brushes: %d Entities: %d", g_numbrushes, g_numentities );
462 Sys_Status( numbrushbuffer, 2 );
465 void Sys_Status(const char *psz, int part )
468 common->Printf("%s", psz);
471 g_pParentWnd->SetStatusText(part, psz);