]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/radiant/WIN_QE3.CPP
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / tools / radiant / WIN_QE3.CPP
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
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.
13
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.
18
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/>.
21
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.
23
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.
25
26 ===========================================================================
27 */
28
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "qe3.h"
33 #include "mru.h"
34
35 extern CEdit                            *g_pEdit;
36
37 int             screen_width;
38 int             screen_height;
39 bool    have_quit;
40
41 int             update_bits;
42
43 /*
44  =======================================================================================================================
45  =======================================================================================================================
46  */
47 void Sys_MarkMapModified(void) {
48         idStr title;
49
50         if (mapModified != 1) {
51                 mapModified = 1;        // mark the map as changed
52                 title = currentmap;
53                 title += " *";
54                 title.BackSlashesToSlashes();
55                 Sys_SetTitle(title);
56         }
57 }
58
59 /*
60  =======================================================================================================================
61  =======================================================================================================================
62  */
63 void Sys_SetTitle(const char *text) {
64         g_pParentWnd->SetWindowText(va("%s: %s",EDITOR_WINDOWTEXT, text));
65 }
66
67 /*
68  =======================================================================================================================
69  Wait Functions
70  =======================================================================================================================
71  */
72 HCURSOR waitcursor;
73
74 void Sys_BeginWait(void) {
75         waitcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
76 }
77
78 bool Sys_Waiting() {
79         return (waitcursor != NULL);
80 }
81
82 void Sys_EndWait(void) {
83         if (waitcursor) {
84                 SetCursor(waitcursor);
85                 waitcursor = NULL;
86         }
87 }
88
89 /*
90  =======================================================================================================================
91  =======================================================================================================================
92  */
93 void Sys_GetCursorPos(int *x, int *y) {
94         POINT   lpPoint;
95
96         GetCursorPos(&lpPoint);
97         *x = lpPoint.x;
98         *y = lpPoint.y;
99 }
100
101 /*
102  =======================================================================================================================
103  =======================================================================================================================
104  */
105 void Sys_SetCursorPos(int x, int y) {
106         SetCursorPos(x, y);
107 }
108
109 /*
110  =======================================================================================================================
111  =======================================================================================================================
112  */
113 void Sys_Beep(void) {
114         MessageBeep(MB_ICONASTERISK);
115 }
116
117 /*
118  =======================================================================================================================
119  =======================================================================================================================
120  */
121 char *TranslateString(char *buf) {
122         static char buf2[32768];
123         int                     i, l;
124         char            *out;
125
126         l = strlen(buf);
127         out = buf2;
128         for (i = 0; i < l; i++) {
129                 if (buf[i] == '\n') {
130                         *out++ = '\r';
131                         *out++ = '\n';
132                 }
133                 else {
134                         *out++ = buf[i];
135                 }
136         }
137
138         *out++ = 0;
139
140         return buf2;
141 }
142
143 /*
144  =======================================================================================================================
145  =======================================================================================================================
146  */
147 double Sys_DoubleTime(void) {
148         return clock() / 1000.0;
149 }
150
151 /*
152  =======================================================================================================================
153  =======================================================================================================================
154  */
155 void PrintPixels(HDC hDC) {
156         int                                             i;
157         PIXELFORMATDESCRIPTOR   p[64];
158
159         printf("### flags color layer\n");
160         for (i = 1; i < 64; i++) {
161                 if (!DescribePixelFormat(hDC, i, sizeof(p[0]), &p[i])) {
162                         break;
163                 }
164
165                 printf("%3i %5i %5i %5i\n", i, p[i].dwFlags, p[i].cColorBits, p[i].bReserved);
166         }
167
168         printf("%i modes\n", i - 1);
169 }
170
171 /*
172  =======================================================================================================================
173  =======================================================================================================================
174  */
175 int WINAPI QEW_SetupPixelFormat(HDC hDC, bool zbuffer)
176 {
177 #if 1
178
179         int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd);
180         if (pixelFormat > 0) {
181                 if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) {
182                         Error("SetPixelFormat failed.");
183                 }
184         }
185         else {
186                 Error("ChoosePixelFormat failed.");
187         }
188
189         return pixelFormat;
190 #else
191         static PIXELFORMATDESCRIPTOR    pfd = {
192                 sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
193                 1,                                              // version number
194                 PFD_DRAW_TO_WINDOW |    // support window
195                 PFD_SUPPORT_OPENGL |    // support OpenGL
196                 PFD_DOUBLEBUFFER,               // double buffered
197                 PFD_TYPE_RGBA,                  // RGBA type
198                 24,                                             // 24-bit color depth
199                 0,
200                 0,
201                 0,
202                 0,
203                 0,
204                 0,                                              // color bits ignored
205                 0,                                              // no alpha buffer
206                 0,                                              // shift bit ignored
207                 0,                                              // no accumulation buffer
208                 0,
209                 0,
210                 0,
211                 0,                                              // accum bits ignored
212                 32,                                             // depth bits
213                 0,                                              // no stencil buffer
214                 0,                                              // no auxiliary buffer
215                 PFD_MAIN_PLANE,                 // main layer
216                 0,                                              // reserved
217                 0,
218                 0,
219                 0                                               // layer masks ignored
220         };
221         int pixelformat = 0;
222
223         zbuffer = true;
224         if (!zbuffer) {
225                 pfd.cDepthBits = 0;
226         }
227
228         if ((pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0) {
229                 printf("%d", GetLastError());
230                 Error("ChoosePixelFormat failed");
231         }
232
233         if (!SetPixelFormat(hDC, pixelformat, &pfd)) {
234                 Error("SetPixelFormat failed");
235         }
236
237         return pixelformat;
238 #endif
239 }
240
241 /*
242  =======================================================================================================================
243     Error For abnormal program terminations
244  =======================================================================================================================
245  */
246 void Error(char *error, ...) {
247         va_list argptr;
248         char    text[1024];
249         char    text2[1024];
250         int             err;
251
252         err = GetLastError();
253
254         int i = qglGetError();
255
256         va_start(argptr, error);
257         vsprintf(text, error, argptr);
258         va_end(argptr);
259
260         sprintf
261         (
262                 text2,
263                 "%s\nGetLastError() = %i - %i\nAn unrecoverable error has occured. Would you like to edit Preferences before exiting Q3Radiant?",
264                 text,
265                 err,
266                 i
267         );
268
269         if (g_pParentWnd->MessageBox(text2, "Error", MB_YESNO) == IDYES) {
270                 g_PrefsDlg.LoadPrefs();
271                 g_PrefsDlg.DoModal();
272         }
273
274         common->FatalError( text );
275 }
276
277 /*
278  =======================================================================================================================
279  =======================================================================================================================
280  */
281 void Warning(char *error, ...) {
282         va_list argptr;
283         char    text[1024];
284         int             err;
285
286         err = GetLastError();
287
288         int i = qglGetError();
289
290         va_start(argptr, error);
291         vsprintf(text, error, argptr);
292         va_end(argptr);
293
294         common->Printf(text);
295 }
296
297 /*
298  =======================================================================================================================
299     FILE DIALOGS
300  =======================================================================================================================
301  */
302 bool ConfirmModified(void) {
303         if (!mapModified) {
304                 return true;
305         }
306
307         if (g_pParentWnd->MessageBox("This will lose changes to the map", "warning", MB_OKCANCEL) == IDCANCEL) {
308                 return false;
309         }
310
311         return true;
312 }
313
314 static OPENFILENAME ofn;        /* common dialog box structure */
315 static char                     szDirName[MAX_PATH];    /* directory string */
316 static char                     szFile[260];                    /* filename string */
317 static char                     szFileTitle[260];               /* file title string */
318 static char                     szFilter[260] =                 /* filter string */
319 "Map file (*.map, *.reg)\0*.map;*.reg\0";
320 static char                     szProjectFilter[260] =  /* filter string */
321 "Q3Radiant project (*.qe4, *.prj)\0*.qe4\0*.prj\0\0";
322 static char                     chReplace;                              /* string separator for szFilter */
323 static int                      i, cbString;                    /* integer count variables */
324 static HANDLE           hf;                                             /* file handle */
325
326 /*
327  =======================================================================================================================
328  =======================================================================================================================
329  */
330 void OpenDialog(void) {
331         /* Obtain the system directory name and store it in szDirName. */
332         strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "mapspath"));
333         if (strlen(szDirName) == 0) {
334                 strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath"));
335                 strcat(szDirName, "\\maps");
336         }
337
338         if (g_PrefsDlg.m_strMaps.GetLength() > 0) {
339                 strcat(szDirName, va("\\%s", g_PrefsDlg.m_strMaps));
340         }
341
342         /* Place the terminating null character in the szFile. */
343         szFile[0] = '\0';
344
345         /* Set the members of the OPENFILENAME structure. */
346         ofn.lStructSize = sizeof(OPENFILENAME);
347         ofn.hwndOwner = g_pParentWnd->GetSafeHwnd();
348         ofn.lpstrFilter = szFilter;
349         ofn.nFilterIndex = 1;
350         ofn.lpstrFile = szFile;
351         ofn.nMaxFile = sizeof(szFile);
352         ofn.lpstrFileTitle = szFileTitle;
353         ofn.nMaxFileTitle = sizeof(szFileTitle);
354         ofn.lpstrInitialDir = szDirName;
355         ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
356
357         /* Display the Open dialog box. */
358         if (!GetOpenFileName(&ofn)) {
359                 return; // canceled
360         }
361
362         // Add the file in MRU. FIXME
363         AddNewItem(g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
364
365         // Refresh the File menu. FIXME
366         PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu, GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), 0), ID_FILE_EXIT);
367
368         /* Open the file. */
369         Map_LoadFile(ofn.lpstrFile);
370
371         g_PrefsDlg.SavePrefs();
372
373 }
374
375 /*
376  =======================================================================================================================
377  =======================================================================================================================
378  */
379 void ProjectDialog(void) {
380         /* Obtain the system directory name and store it in szDirName. */
381         strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath"));
382
383         /* Place the terminating null character in the szFile. */
384         szFile[0] = '\0';
385
386         /* Set the members of the OPENFILENAME structure. */
387         ofn.lStructSize = sizeof(OPENFILENAME);
388         ofn.hwndOwner = g_pParentWnd->GetSafeHwnd();
389         ofn.lpstrFilter = szProjectFilter;
390         ofn.nFilterIndex = 1;
391         ofn.lpstrFile = szFile;
392         ofn.nMaxFile = sizeof(szFile);
393         ofn.lpstrFileTitle = szFileTitle;
394         ofn.nMaxFileTitle = sizeof(szFileTitle);
395         ofn.lpstrInitialDir = szDirName;
396         ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
397
398         /* Display the Open dialog box. */
399         if (!GetOpenFileName(&ofn)) {
400                 return; // canceled
401         }
402
403         // Refresh the File menu.
404         PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu, GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), 0), ID_FILE_EXIT);
405
406         /* Open the file. */
407         if (!QE_LoadProject(ofn.lpstrFile)) {
408                 Error("Couldn't load project file");
409         }
410 }
411
412 extern void AddSlash(CString &strPath);
413
414 /*
415  =======================================================================================================================
416  =======================================================================================================================
417  */
418 void SaveAsDialog(bool bRegion) {
419         strcpy(szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath"));
420
421         CString strPath = szDirName;
422         AddSlash(strPath);
423         strPath += "maps";
424         if (g_PrefsDlg.m_strMaps.GetLength() > 0) {
425                 strPath += va("\\%s", g_PrefsDlg.m_strMaps);
426         }
427
428         /* Place the terminating null character in the szFile. */
429         szFile[0] = '\0';
430
431         /* Set the members of the OPENFILENAME structure. */
432         ofn.lStructSize = sizeof(OPENFILENAME);
433         ofn.hwndOwner = g_pParentWnd->GetSafeHwnd();
434         ofn.lpstrFilter = szFilter;
435         ofn.nFilterIndex = 1;
436         ofn.lpstrFile = szFile;
437         ofn.nMaxFile = sizeof(szFile);
438         ofn.lpstrFileTitle = szFileTitle;
439         ofn.nMaxFileTitle = sizeof(szFileTitle);
440         ofn.lpstrInitialDir = strPath;
441         ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT;
442
443         /* Display the Open dialog box. */
444         if (!GetSaveFileName(&ofn)) {
445                 return; // canceled
446         }
447
448         if (bRegion) {
449                 DefaultExtension(ofn.lpstrFile, ".reg");
450         }
451         else {
452                 DefaultExtension(ofn.lpstrFile, ".map");
453         }
454
455         if (!bRegion) {
456                 strcpy(currentmap, ofn.lpstrFile);
457                 AddNewItem(g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
458                 PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu, GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), 0), ID_FILE_EXIT);
459         }
460
461         Map_SaveFile(ofn.lpstrFile, bRegion);   // ignore region
462 }
463
464 /*
465  * Menu modifications £
466  * FillBSPMenu
467  */
468 const char      *bsp_commands[256];
469
470 /*
471  =======================================================================================================================
472  =======================================================================================================================
473  */
474 void FillBSPMenu(void) {
475         HMENU           hmenu;
476         int                     i;
477         static int      count;
478
479         hmenu = GetSubMenu(GetMenu(g_pParentWnd->GetSafeHwnd()), MENU_BSP);
480
481         for (i = 0; i < count; i++) {
482                 DeleteMenu(hmenu, CMD_BSPCOMMAND + i, MF_BYCOMMAND);
483         }
484
485         i = 0;
486         count = g_qeglobals.d_project_entity->epairs.GetNumKeyVals();
487         for (int j = 0; j < count; j++) {
488                 if (g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[0] == 'b' && g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[1] == 's' && g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey()[2] == 'p') {
489                         bsp_commands[i] = g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey().c_str();
490                         AppendMenu(hmenu, MF_ENABLED | MF_STRING, CMD_BSPCOMMAND + i, (LPCTSTR) g_qeglobals.d_project_entity->epairs.GetKeyVal(j)->GetKey().c_str());
491                         i++;
492                 }
493         }
494
495         count = i;
496 }
497
498 /*
499  =======================================================================================================================
500  =======================================================================================================================
501  */
502 void AddSlash(CString &strPath) {
503         if (strPath.GetLength() > 0) {
504                 if (strPath.GetAt(strPath.GetLength() - 1) != '\\') {
505                         strPath += '\\';
506                 }
507         }
508 }