]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/win_qe3.c
Merge branch 'master' into divVerent/farplanedist-sky-fix
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / win_qe3.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, 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 Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 #include "qe3.h"
24 #include "mru.h"
25
26 int     screen_width;
27 int     screen_height;
28 qboolean        have_quit;
29
30 int     update_bits;
31
32 HANDLE  bsp_process;
33
34 //===========================================
35
36 void Sys_SetTitle (char *text)
37 {
38         SetWindowText (g_qeglobals.d_hwndMain, text);
39 }
40
41 HCURSOR waitcursor;
42
43 void Sys_BeginWait (void)
44 {
45         waitcursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
46 }
47
48 void Sys_EndWait (void)
49 {
50         if (waitcursor)
51         {
52                 SetCursor (waitcursor);
53                 waitcursor = NULL;
54         }
55 }
56
57
58 void Sys_GetCursorPos (int *x, int *y)
59 {
60         POINT lpPoint;
61
62         GetCursorPos (&lpPoint);
63         *x = lpPoint.x;
64         *y = lpPoint.y;
65 }
66
67 void Sys_SetCursorPos (int x, int y)
68 {
69         SetCursorPos (x, y);
70 }
71
72 void Sys_UpdateWindows (int bits)
73 {
74 //      Sys_Printf("updating 0x%X\n", bits);
75         update_bits |= bits;
76 //update_bits = -1;
77 }
78
79
80 void Sys_Beep (void)
81 {
82         MessageBeep (MB_ICONASTERISK);
83 }
84
85 char    *TranslateString (char *buf)
86 {
87         static  char    buf2[32768];
88         int             i, l;
89         char    *out;
90
91         l = strlen(buf);
92         out = buf2;
93         for (i=0 ; i<l ; i++)
94         {
95                 if (buf[i] == '\n')
96                 {
97                         *out++ = '\r';
98                         *out++ = '\n';
99                 }
100                 else
101                         *out++ = buf[i];
102         }
103         *out++ = 0;
104
105         return buf2;
106 }
107
108 void Sys_ClearPrintf (void)
109 {
110         char    text[4];
111
112         text[0] = 0;
113
114         SendMessage (g_qeglobals.d_hwndEdit,
115                 WM_SETTEXT,
116                 0,
117                 (LPARAM)text);
118 }
119
120 void Sys_Printf (char *text, ...)
121 {
122         va_list argptr;
123         char    buf[32768];
124         char    *out;
125
126         va_start (argptr,text);
127         vsprintf (buf, text,argptr);
128         va_end (argptr);
129
130         out = TranslateString (buf);
131
132 #ifdef LATER
133         Sys_Status(out);
134 #else
135         SendMessage (g_qeglobals.d_hwndEdit,
136                 EM_REPLACESEL,
137                 0,
138                 (LPARAM)out);
139 #endif
140
141 }
142
143 double Sys_DoubleTime (void)
144 {
145         return clock()/ 1000.0;
146 }
147
148 void PrintPixels (HDC hDC)
149 {
150         int             i;
151         PIXELFORMATDESCRIPTOR p[64];
152
153         printf ("### flags color layer\n");
154         for (i=1 ; i<64 ; i++)
155         {
156                 if (!DescribePixelFormat ( hDC, i, sizeof(p[0]), &p[i]))
157                         break;
158                 printf ("%3i %5i %5i %5i\n", i,
159                         p[i].dwFlags,
160                         p[i].cColorBits,
161                         p[i].bReserved);
162         }
163         printf ("%i modes\n", i-1);
164 }
165
166
167
168 //==========================================================================
169
170 void QEW_StopGL( HWND hWnd, HGLRC hGLRC, HDC hDC )
171 {
172         wglMakeCurrent( NULL, NULL );
173         wglDeleteContext( hGLRC );
174         ReleaseDC( hWnd, hDC );
175 }
176
177 int QEW_SetupPixelFormat(HDC hDC, qboolean zbuffer )
178 {
179     static PIXELFORMATDESCRIPTOR pfd = {
180                 sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
181                 1,                                                              // version number
182                 PFD_DRAW_TO_WINDOW |                    // support window
183                 PFD_SUPPORT_OPENGL |                    // support OpenGL
184                 PFD_DOUBLEBUFFER,                               // double buffered
185                 PFD_TYPE_RGBA,                                  // RGBA type
186                 24,                                                             // 24-bit color depth
187                 0, 0, 0, 0, 0, 0,                               // color bits ignored
188                 0,                                                              // no alpha buffer
189                 0,                                                              // shift bit ignored
190                 0,                                                              // no accumulation buffer
191                 0, 0, 0, 0,                                             // accum bits ignored
192                 32,                                                         // depth bits
193                 0,                                                              // no stencil buffer
194                 0,                                                              // no auxiliary buffer
195                 PFD_MAIN_PLANE,                                 // main layer
196                 0,                                                              // reserved
197                 0, 0, 0                                                 // layer masks ignored
198     };
199     int pixelformat = 0;
200
201         zbuffer = true;
202         if ( !zbuffer )
203                 pfd.cDepthBits = 0;
204
205     if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 )
206         {
207                 printf("%d",GetLastError());
208         Error ("ChoosePixelFormat failed");
209         }
210
211     if (!SetPixelFormat(hDC, pixelformat, &pfd))
212         Error ("SetPixelFormat failed");
213
214         return pixelformat;
215 }
216
217 /*
218 =================
219 Error
220
221 For abnormal program terminations
222 =================
223 */
224 void Error (char *error, ...)
225 {
226         va_list argptr;
227         char    text[1024];
228         char    text2[1024];
229         int             err;
230
231         err = GetLastError ();
232
233         va_start (argptr,error);
234         vsprintf (text, error,argptr);
235         va_end (argptr);
236
237         sprintf (text2, "%s\nGetLastError() = %i", text, err);
238     MessageBox(g_qeglobals.d_hwndMain, text2, "Error", 0 /* MB_OK */ );
239
240         exit (1);
241 }
242
243 /*
244 ======================================================================
245
246 FILE DIALOGS
247
248 ======================================================================
249 */
250
251 qboolean ConfirmModified (void)
252 {
253         if (!modified)
254                 return true;
255
256         if (MessageBox (g_qeglobals.d_hwndMain, "This will lose changes to the map"
257                 , "warning", MB_OKCANCEL) == IDCANCEL)
258                 return false;
259         return true;
260 }
261
262 static OPENFILENAME ofn;       /* common dialog box structure   */
263 static char szDirName[MAX_PATH];    /* directory string              */
264 static char szFile[260];       /* filename string               */
265 static char szFileTitle[260];  /* file title string             */
266 static char szFilter[260] =     /* filter string                 */
267         "QuakeEd file (*.map)\0*.map\0\0";
268 static char szProjectFilter[260] =     /* filter string                 */
269         "QuakeEd project (*.qe4)\0*.qe4\0\0";
270 static char chReplace;         /* string separator for szFilter */
271 static int i, cbString;        /* integer count variables       */
272 static HANDLE hf;              /* file handle                   */
273
274 void OpenDialog (void)
275 {
276         /*
277          * Obtain the system directory name and
278          * store it in szDirName.
279          */
280
281         strcpy (szDirName, ValueForKey (g_qeglobals.d_project_entity, "basepath") );
282         strcat (szDirName, "\\maps");
283
284         /* Place the terminating null character in the szFile. */
285
286         szFile[0] = '\0';
287
288         /* Set the members of the OPENFILENAME structure. */
289
290         ofn.lStructSize = sizeof(OPENFILENAME);
291         ofn.hwndOwner = g_qeglobals.d_hwndCamera;
292         ofn.lpstrFilter = szFilter;
293         ofn.nFilterIndex = 1;
294         ofn.lpstrFile = szFile;
295         ofn.nMaxFile = sizeof(szFile);
296         ofn.lpstrFileTitle = szFileTitle;
297         ofn.nMaxFileTitle = sizeof(szFileTitle);
298         ofn.lpstrInitialDir = szDirName;
299         ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
300                 OFN_FILEMUSTEXIST;
301
302         /* Display the Open dialog box. */
303
304         if (!GetOpenFileName(&ofn))
305                 return; // canceled
306
307         // Add the file in MRU.
308         AddNewItem( g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
309
310         // Refresh the File menu.
311         PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0),
312                         ID_FILE_EXIT);
313
314         /* Open the file. */
315
316         Map_LoadFile (ofn.lpstrFile);
317 }
318
319 void ProjectDialog (void)
320 {
321         /*
322          * Obtain the system directory name and
323          * store it in szDirName.
324          */
325
326         strcpy (szDirName, ValueForKey(g_qeglobals.d_project_entity, "basepath") );
327         strcat (szDirName, "\\scripts");
328
329         /* Place the terminating null character in the szFile. */
330
331         szFile[0] = '\0';
332
333         /* Set the members of the OPENFILENAME structure. */
334
335         ofn.lStructSize = sizeof(OPENFILENAME);
336         ofn.hwndOwner = g_qeglobals.d_hwndCamera;
337         ofn.lpstrFilter = szProjectFilter;
338         ofn.nFilterIndex = 1;
339         ofn.lpstrFile = szFile;
340         ofn.nMaxFile = sizeof(szFile);
341         ofn.lpstrFileTitle = szFileTitle;
342         ofn.nMaxFileTitle = sizeof(szFileTitle);
343         ofn.lpstrInitialDir = szDirName;
344         ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
345                 OFN_FILEMUSTEXIST;
346
347         /* Display the Open dialog box. */
348
349         if (!GetOpenFileName(&ofn))
350                 return; // canceled
351
352         // Refresh the File menu.
353         PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0),
354                         ID_FILE_EXIT);
355
356         /* Open the file. */
357         if (!QE_LoadProject(ofn.lpstrFile))
358                 Error ("Couldn't load project file");
359 }
360
361
362 void SaveAsDialog (void)
363 {
364         strcpy (szDirName, ValueForKey (g_qeglobals.d_project_entity, "basepath") );
365         strcat (szDirName, "\\maps");
366
367         /* Place the terminating null character in the szFile. */
368
369         szFile[0] = '\0';
370
371         /* Set the members of the OPENFILENAME structure. */
372
373         ofn.lStructSize = sizeof(OPENFILENAME);
374         ofn.hwndOwner = g_qeglobals.d_hwndCamera;
375         ofn.lpstrFilter = szFilter;
376         ofn.nFilterIndex = 1;
377         ofn.lpstrFile = szFile;
378         ofn.nMaxFile = sizeof(szFile);
379         ofn.lpstrFileTitle = szFileTitle;
380         ofn.nMaxFileTitle = sizeof(szFileTitle);
381         ofn.lpstrInitialDir = szDirName;
382         ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
383                 OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT;
384
385         /* Display the Open dialog box. */
386
387         if (!GetSaveFileName(&ofn))
388                 return; // canceled
389
390         DefaultExtension (ofn.lpstrFile, ".map");
391         strcpy (currentmap, ofn.lpstrFile);
392
393         // Add the file in MRU.
394         AddNewItem(g_qeglobals.d_lpMruMenu, ofn.lpstrFile);
395
396         // Refresh the File menu.
397         PlaceMenuMRUItem(g_qeglobals.d_lpMruMenu,GetSubMenu(GetMenu(g_qeglobals.d_hwndMain),0),
398                         ID_FILE_EXIT);
399
400         Map_SaveFile (ofn.lpstrFile, false);    // ignore region
401 }
402
403 /*
404 =======================================================
405
406 Menu modifications
407
408 =======================================================
409 */
410
411 /*
412 ==================
413 FillBSPMenu
414
415 ==================
416 */
417 char    *bsp_commands[256];
418
419 void FillBSPMenu (void)
420 {
421         HMENU   hmenu;
422         epair_t *ep;
423         int             i;
424         static int count;
425
426         hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_BSP);
427
428         for (i=0 ; i<count ; i++)
429                 DeleteMenu (hmenu, CMD_BSPCOMMAND+i, MF_BYCOMMAND);
430         count = 0;
431
432         i = 0;
433         for (ep = g_qeglobals.d_project_entity->epairs ; ep ; ep=ep->next)
434         {
435                 if (ep->key[0] == 'b' && ep->key[1] == 's' && ep->key[2] == 'p')
436                 {
437                         bsp_commands[i] = ep->key;
438                         AppendMenu (hmenu, MF_ENABLED|MF_STRING,
439                         CMD_BSPCOMMAND+i, (LPCTSTR)ep->key);
440                         i++;
441                 }
442         }
443         count = i;
444 }
445
446 //==============================================
447
448 /*
449 ===============
450 CheckBspProcess
451
452 See if the BSP is done yet
453 ===============
454 */
455 void CheckBspProcess (void)
456 {
457         char    outputpath[1024];
458         char    temppath[512];
459         DWORD   exitcode;
460         char    *out;
461         BOOL    ret;
462
463         if (!bsp_process)
464                 return;
465
466         ret = GetExitCodeProcess (bsp_process, &exitcode);
467         if (!ret)
468                 Error ("GetExitCodeProcess failed");
469         if (exitcode == STILL_ACTIVE)
470                 return;
471
472         bsp_process = 0;
473
474         GetTempPath(512, temppath);
475         sprintf (outputpath, "%sjunk.txt", temppath);
476
477         LoadFile (outputpath, (void *)&out);
478         Sys_Printf ("%s", out);
479         Sys_Printf ("\ncompleted.\n");
480         free (out);
481         Sys_Beep ();
482
483         Pointfile_Check ();
484 }
485
486 extern int      cambuttonstate;
487
488 /*
489 ==================
490 WinMain
491
492 ==================
493 */
494 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance
495                                         ,LPSTR lpCmdLine, int nCmdShow)
496 {
497     MSG        msg;
498         double          time, oldtime, delta;
499         HACCEL          accelerators;
500
501         g_qeglobals.d_hInstance = hInstance;
502
503         InitCommonControls ();
504
505         screen_width = GetSystemMetrics (SM_CXFULLSCREEN);
506         screen_height = GetSystemMetrics (SM_CYFULLSCREEN);
507
508         // hack for broken NT 4.0 dual screen
509         if (screen_width > 2*screen_height)
510                 screen_width /= 2;
511
512         accelerators = LoadAccelerators (hInstance
513                 , MAKEINTRESOURCE(IDR_ACCELERATOR1));
514         if (!accelerators)
515                 Error ("LoadAccelerators failed");
516
517         Main_Create (hInstance);
518
519         WCam_Create (hInstance);
520         WXY_Create (hInstance);
521         WZ_Create (hInstance);
522         CreateEntityWindow(hInstance);
523
524         // the project file can be specified on the command line,
525         // or implicitly found in the scripts directory
526         if (lpCmdLine && strlen(lpCmdLine))
527         {
528                 ParseCommandLine (lpCmdLine);
529                 if (!QE_LoadProject(argv[1]))
530                         Error ("Couldn't load %s project file", argv[1]);
531         }
532         else if (!QE_LoadProject("scripts/quake.qe4"))
533                 Error ("Couldn't load scripts/quake.qe4 project file");
534
535         QE_Init ();
536
537         Sys_Printf ("Entering message loop\n");
538
539         oldtime = Sys_DoubleTime ();
540
541         while (!have_quit)
542         {
543                 Sys_EndWait ();         // remove wait cursor if active
544
545                 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
546                 {
547                         if (!TranslateAccelerator(g_qeglobals.d_hwndMain, accelerators, &msg) )
548                         {
549                         TranslateMessage (&msg);
550                         DispatchMessage (&msg);
551                         }
552                         if (msg.message == WM_QUIT)
553                                 have_quit = true;
554                 }
555
556
557                 CheckBspProcess ();
558
559                 time = Sys_DoubleTime ();
560                 delta = time - oldtime;
561                 oldtime = time;
562                 if (delta > 0.2)
563                         delta = 0.2;
564
565                 // run time dependant behavior
566                 Cam_MouseControl (delta);
567
568                 // update any windows now
569                 if (update_bits & W_CAMERA)
570                 {
571                         InvalidateRect(g_qeglobals.d_hwndCamera, NULL, false);
572                         UpdateWindow (g_qeglobals.d_hwndCamera);
573                 }
574                 if (update_bits & (W_Z | W_Z_OVERLAY) )
575                 {
576                         InvalidateRect(g_qeglobals.d_hwndZ, NULL, false);
577                         UpdateWindow (g_qeglobals.d_hwndZ);
578                 }
579
580                 if ( update_bits & W_TEXTURE )
581                 {
582                         InvalidateRect(g_qeglobals.d_hwndTexture, NULL, false);
583                         UpdateWindow (g_qeglobals.d_hwndEntity);
584                 }
585
586                 if (update_bits & (W_XY | W_XY_OVERLAY))
587                 {
588                         InvalidateRect(g_qeglobals.d_hwndXY, NULL, false);
589                         UpdateWindow (g_qeglobals.d_hwndXY);
590                 }
591
592                 update_bits = 0;
593
594                 if (!cambuttonstate && !have_quit)
595                 {       // if not driving in the camera view, block
596                         WaitMessage ();
597                 }
598
599         }
600
601     /* return success of application */
602     return TRUE;
603
604 }
605