]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/guied/GEViewer.cpp
hello world
[icculus/iodoom3.git] / neo / tools / guied / GEViewer.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 "../../sys/win32/rc/guied_resource.h"
33 #include "../../renderer/tr_local.h"
34
35 #include "GEApp.h"
36 #include "GEViewer.h"
37
38 rvGEViewer::rvGEViewer ( )
39 {
40         mInterface = NULL;
41         mPaused    = true;
42         mTime      = 0;
43 }
44
45 bool rvGEViewer::Create ( HWND parent )
46 {
47         WNDCLASSEX      wndClass;                       
48         
49         // Make sure the alpha slider window class is registered
50         memset ( &wndClass, 0, sizeof(wndClass) );      
51         wndClass.cbSize                 = sizeof(WNDCLASSEX);
52         wndClass.lpszClassName  = "GUIED_VIEWER";               
53         wndClass.lpfnWndProc    = rvGEViewer::WndProc;
54         wndClass.hInstance              = gApp.GetInstance ( ); 
55         wndClass.style                  = CS_OWNDC|CS_BYTEALIGNWINDOW|CS_VREDRAW|CS_HREDRAW;
56         wndClass.hbrBackground  = (HBRUSH) (COLOR_3DFACE + 1); 
57         RegisterClassEx ( &wndClass );
58
59         mWnd = CreateWindowEx ( WS_EX_TOOLWINDOW, "GUIED_VIEWER", "GUI Viewer", 
60                                                         WS_SYSMENU|WS_THICKFRAME|WS_CAPTION|WS_POPUP|WS_OVERLAPPED|WS_BORDER|WS_CLIPSIBLINGS|WS_CHILD, 
61                                                         CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH/2, SCREEN_HEIGHT/2, 
62                                                         parent, NULL, gApp.GetInstance(), this );
63
64         gApp.GetOptions().GetWindowPlacement ( "viewer", mWnd );
65
66
67         ShowWindow ( mWnd, SW_SHOW );
68         UpdateWindow ( mWnd );                                                  
69
70         return true;
71 }
72
73 void rvGEViewer::Play ( void )
74 {
75         if ( !mPaused )
76         {
77                 return;
78         }
79
80         mLastTime = eventLoop->Milliseconds();
81         mPaused   = false;
82
83         TBBUTTONINFO tbinfo;
84         tbinfo.cbSize = sizeof(TBBUTTONINFO);
85         tbinfo.dwMask = TBIF_COMMAND|TBIF_IMAGE;
86         tbinfo.iImage = 1;
87         tbinfo.idCommand = ID_GUIED_VIEWER_PAUSE;
88         SendMessage ( mToolbar, TB_SETBUTTONINFO, ID_GUIED_VIEWER_PLAY, (LPARAM)&tbinfo );
89 }
90
91 void rvGEViewer::Pause ( void )
92 {
93         if ( mPaused )
94         {
95                 return;
96         }
97         
98         mPaused = true;
99
100         TBBUTTONINFO tbinfo;
101         tbinfo.cbSize = sizeof(TBBUTTONINFO);
102         tbinfo.dwMask = TBIF_COMMAND|TBIF_IMAGE;
103         tbinfo.iImage = 0;
104         tbinfo.idCommand = ID_GUIED_VIEWER_PLAY;
105         SendMessage ( mToolbar, TB_SETBUTTONINFO, ID_GUIED_VIEWER_PAUSE, (LPARAM)&tbinfo );
106 }
107
108
109 bool rvGEViewer::Destroy ( void )
110 {
111         gApp.GetOptions().SetWindowPlacement ( "viewer", mWnd );
112
113         DestroyWindow ( mWnd );
114         return true;
115 }
116
117 bool rvGEViewer::OpenFile ( const char* filename )
118 {
119         idStr tempfile;
120         idStr ospath;
121         
122         delete mInterface;
123         
124         tempfile = filename;
125         tempfile.StripPath ();
126         tempfile.StripFileExtension ( );
127         tempfile = va("guis/temp.guied", tempfile.c_str() );
128         ospath = fileSystem->RelativePathToOSPath ( tempfile, "fs_basepath" );
129
130         // Make sure the gui directory exists
131         idStr createDir = ospath;
132         createDir.StripFilename ( );
133         CreateDirectory ( createDir, NULL );
134
135         SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL );
136         DeleteFile ( ospath );
137         CopyFile ( filename, ospath, FALSE );
138         SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL );
139
140         mInterface = reinterpret_cast< idUserInterfaceLocal* >( uiManager->FindGui( tempfile, true, true ) );
141
142         mInterface->SetStateString( "guied_item_0", "guied 1" );
143         mInterface->SetStateString( "guied_item_1", "guied 2" );
144         mInterface->SetStateString( "guied_item_2", "guied 3" );
145
146         mTime = 0;
147
148         mInterface->Activate ( true, mTime );
149
150         DeleteFile ( ospath );
151
152         Play ( );
153         
154         return true;
155 }
156
157 /*
158 =======
159 MapKey
160
161 Map from windows to Doom keynums
162 =======
163 */
164 static int MapKey (int key)
165 {
166         int result;
167         int modified;
168         bool is_extended;
169
170         modified = ( key >> 16 ) & 255;
171
172         if ( modified > 127 )
173                 return 0;
174
175         if ( key & ( 1 << 24 ) ) {
176                 is_extended = true;
177         }
178         else {
179                 is_extended = false;
180         }
181
182         const unsigned char *scanToKey = Sys_GetScanTable();
183         result = scanToKey[modified];
184
185         // common->Printf( "Key: 0x%08x Modified: 0x%02x Extended: %s Result: 0x%02x\n", key, modified, (is_extended?"Y":"N"), result);
186
187         if ( is_extended ) {
188                 switch ( result )
189                 {
190                 case K_PAUSE:
191                         return K_KP_NUMLOCK;
192                 case 0x0D:
193                         return K_KP_ENTER;
194                 case 0x2F:
195                         return K_KP_SLASH;
196                 case 0xAF:
197                         return K_KP_PLUS;
198                 }
199         }
200         else {
201                 switch ( result )
202                 {
203                 case K_HOME:
204                         return K_KP_HOME;
205                 case K_UPARROW:
206                         return K_KP_UPARROW;
207                 case K_PGUP:
208                         return K_KP_PGUP;
209                 case K_LEFTARROW:
210                         return K_KP_LEFTARROW;
211                 case K_RIGHTARROW:
212                         return K_KP_RIGHTARROW;
213                 case K_END:
214                         return K_KP_END;
215                 case K_DOWNARROW:
216                         return K_KP_DOWNARROW;
217                 case K_PGDN:
218                         return K_KP_PGDN;
219                 case K_INS:
220                         return K_KP_INS;
221                 case K_DEL:
222                         return K_KP_DEL;
223                 }
224         }
225
226         return result;
227 }
228
229 LRESULT CALLBACK rvGEViewer::WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
230 {
231         rvGEViewer* viewer = (rvGEViewer*) GetWindowLong ( hwnd, GWL_USERDATA );
232         
233         switch ( msg )
234         {
235
236                 case WM_COMMAND:
237                         switch ( LOWORD(wParam) )
238                         {
239                                 case ID_GUIED_VIEWER_PLAY:
240                                         viewer->Play ( );
241                                         break;
242
243                                 case ID_GUIED_VIEWER_PAUSE:
244                                         viewer->Pause ( );
245                                         break;
246                         }
247                         break;
248         
249                 case WM_SIZE:
250                 {
251                         RECT rToolbar;
252                         SendMessage ( viewer->mToolbar, TB_AUTOSIZE, 0, 0 );
253                         GetWindowRect ( viewer->mToolbar, &rToolbar );
254                         viewer->mToolbarHeight = rToolbar.bottom - rToolbar.top;
255                         break;
256                 }
257         
258                 case WM_ACTIVATE:
259                         common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE );
260                         break;
261
262                 case WM_ERASEBKGND:
263                         return TRUE;
264                         
265                 case WM_PAINT:
266                         assert ( viewer );
267                         viewer->HandlePaint ( wParam, lParam );
268                         break;
269                 
270                 case WM_LBUTTONDOWN:
271                         if ( viewer->mInterface )
272                         {
273                                 sysEvent_t event;                       
274                                 bool       visuals;
275                                 ZeroMemory ( &event, sizeof(event) ) ;
276                                 event.evType = SE_KEY;
277                                 event.evValue = K_MOUSE1;               
278                                 event.evValue2 = true;  
279                                 viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals );
280                         }
281                         break;
282
283                 case WM_LBUTTONUP:
284                         if ( viewer->mInterface )
285                         {
286                                 sysEvent_t event;                       
287                                 bool       visuals;
288                                 ZeroMemory ( &event, sizeof(event) ) ;
289                                 event.evType = SE_KEY;
290                                 event.evValue = K_MOUSE1;               
291                                 event.evValue2 = false; 
292                                 viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals );
293                         }
294                         break;
295
296                 case WM_KEYDOWN:
297                         if ( viewer->mInterface )
298                         {
299                                 sysEvent_t event;                       
300                                 bool       visuals;
301                                 ZeroMemory ( &event, sizeof(event) ) ;
302                                 event.evType = SE_KEY;
303                                 event.evValue = MapKey( lParam );               
304                                 event.evValue2 = true;  
305                                 viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals );
306                         }
307                         break;
308
309                 case WM_SYSKEYUP:
310                 case WM_KEYUP:
311                         if ( viewer->mInterface )
312                         {
313                                 sysEvent_t event;                       
314                                 bool       visuals;
315                                 ZeroMemory ( &event, sizeof(event) ) ;
316                                 event.evType = SE_KEY;
317                                 event.evValue = MapKey( lParam );               
318                                 event.evValue2 = false; 
319                                 viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals );
320                         }
321                         break;
322
323                 case WM_CHAR:
324
325                         if ( wParam == VK_ESCAPE )
326                         {
327                                 SendMessage ( hwnd, WM_CLOSE, 0, 0 );
328                                 break;
329                         }
330
331                         if ( viewer->mInterface )
332                         {
333                                 sysEvent_t event;                       
334                                 bool       visuals;
335                                 ZeroMemory ( &event, sizeof(event) ) ;
336                                 event.evType = SE_CHAR;
337                                 event.evValue = wParam;         
338                                 event.evValue2 = false; 
339                                 viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals );
340                         }
341                         break;
342         
343                 case WM_MOUSEMOVE:
344                         if ( viewer->mInterface )
345                         {
346                                 float x = (float)(LOWORD(lParam)) / (float)viewer->mWindowWidth * SCREEN_WIDTH;
347                                 float y = (float)(HIWORD(lParam)) / (float)(viewer->mWindowHeight - viewer->mToolbarHeight) * SCREEN_HEIGHT;
348                                 sysEvent_t event;                       
349                                 bool       visuals;
350
351                                 ZeroMemory ( &event, sizeof(event) ) ;
352                                 event.evType = SE_MOUSE;
353                                 event.evValue = (int)x - viewer->mInterface->CursorX();
354                                 event.evValue2 = (int)y - viewer->mInterface->CursorY();
355                                 viewer->mInterface->HandleEvent ( &event, viewer->mTime, &visuals );
356                         }
357                         break;
358
359                 case WM_CLOSE:
360                         viewer->mInterface = NULL;
361                         gApp.CloseViewer ( );
362                         return 0;
363         
364                 case WM_CREATE:
365                 {
366                         CREATESTRUCT* cs = (CREATESTRUCT*) lParam;
367                         SetWindowLong ( hwnd, GWL_USERDATA, (LONG)cs->lpCreateParams );
368                                         
369                         viewer = (rvGEViewer*)cs->lpCreateParams;
370                         viewer->mWnd = hwnd;
371                         viewer->SetupPixelFormat ( );
372
373                         viewer->mToolbar = CreateWindowEx ( 0, TOOLBARCLASSNAME, "", CCS_BOTTOM|WS_CHILD|WS_VISIBLE,0,0,0,0, hwnd, (HMENU)IDR_GUIED_VIEWERTOOLBAR, gApp.GetInstance(), NULL );
374
375                     // Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility. 
376                         SendMessage( viewer->mToolbar, TB_BUTTONSTRUCTSIZE, ( WPARAM )sizeof( TBBUTTON ), 0 );
377                         
378                         SendMessage ( viewer->mToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(16,15) );
379                         
380                         SendMessage ( viewer->mToolbar, TB_SETSTYLE, 0, SendMessage ( viewer->mToolbar, TB_GETSTYLE, 0, 0 ) | TBSTYLE_FLAT );
381                         
382                         TBMETRICS tbmet;
383                         tbmet.cbSize = sizeof(TBMETRICS);
384                         SendMessage ( viewer->mToolbar, TB_GETMETRICS, 0, (LPARAM)&tbmet );
385                         tbmet.cyPad = 0;
386                         tbmet.cyBarPad = 0;
387                         SendMessage ( viewer->mToolbar, TB_SETMETRICS, 0, (LPARAM)&tbmet );
388
389                     // Add the bitmap containing button images to the toolbar. 
390                     TBADDBITMAP tbab; 
391                         tbab.hInst = win32.hInstance; 
392                         tbab.nID = IDR_GUIED_VIEWERTOOLBAR; 
393                         SendMessage( viewer->mToolbar, TB_ADDBITMAP, (WPARAM)4, (LPARAM) &tbab ); 
394
395                     TBBUTTON tbb[4]; 
396                         tbb[0].fsStyle = BTNS_SEP; 
397                         tbb[0].fsState = 0;
398
399                     tbb[1].idCommand = ID_GUIED_VIEWER_START;
400                         tbb[1].iBitmap = 2; 
401                         tbb[1].fsState = 0; 
402                         tbb[1].fsStyle = BTNS_BUTTON; 
403                         tbb[1].dwData = 0; 
404                         tbb[1].iString = -1; 
405
406                     tbb[2].idCommand = ID_GUIED_VIEWER_PAUSE;
407                         tbb[2].iBitmap = 1; 
408                         tbb[2].fsState = TBSTATE_ENABLED; 
409                         tbb[2].fsStyle = BTNS_BUTTON; 
410                         tbb[2].dwData = 0; 
411                         tbb[2].iString = -1; 
412
413                         tbb[3].fsStyle = BTNS_SEP; 
414                         tbb[3].fsState = 0;
415
416                         SendMessage( viewer->mToolbar, TB_ADDBUTTONS, (WPARAM)4, (LPARAM) &tbb ); 
417
418                         break;
419                 }
420                 
421                 case WM_SETCURSOR:
422                         SetCursor ( NULL );
423                         break;
424         }
425         
426         return DefWindowProc ( hwnd, msg, wParam, lParam );
427 }
428
429 LRESULT rvGEViewer::HandlePaint ( WPARAM wParam, LPARAM lParam )
430 {
431         HDC                     dc;
432         PAINTSTRUCT ps;
433
434         dc = BeginPaint ( mWnd, &ps );
435
436         Render ( dc );
437                 
438         EndPaint ( mWnd, &ps );
439         
440         return 1;
441 }
442
443 /*
444 ================
445 rvGEViewer::SetupPixelFormat
446
447 Setup the pixel format for the opengl context
448 ================
449 */
450 bool rvGEViewer::SetupPixelFormat ( void )
451 {
452         HDC      hDC    = GetDC ( mWnd );
453         bool result = true;
454
455         int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd);
456         if (pixelFormat > 0) 
457         {
458                 if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL) 
459                 {
460                         result = false;
461                 }
462         }
463         else 
464         {
465                 result = false;
466         }
467         
468         ReleaseDC ( mWnd, hDC );
469
470         return result;
471 }
472
473 void rvGEViewer::Render ( HDC dc )
474 {
475         int     frontEnd;
476         int     backEnd;
477         
478         // Switch GL contexts to our dc
479         if (!qwglMakeCurrent( dc, win32.hGLRC )) 
480         {
481                 common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError());
482                 common->Printf("Please restart Q3Radiant if the Map view is not working\n");
483             return;
484         }
485
486         if ( !mPaused )
487         {
488                 mTime += eventLoop->Milliseconds() - mLastTime;
489                 mLastTime = eventLoop->Milliseconds();
490         }       
491
492         RECT rClient;
493         RECT rToolbar;
494         GetClientRect ( mWnd, &rClient );
495         GetClientRect ( mToolbar, &rToolbar );
496         mWindowWidth = rClient.right - rClient.left;
497         mWindowHeight = rClient.bottom - rClient.top;
498
499         qglViewport(0, 0, mWindowWidth, mWindowHeight );
500         qglScissor(0, 0, mWindowWidth, mWindowHeight );
501         qglClearColor ( 0, 0, 0, 0 );
502
503         qglDisable(GL_DEPTH_TEST);
504         qglDisable(GL_CULL_FACE);
505         qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
506
507         // Render the workspace below
508         glMatrixMode(GL_PROJECTION);
509         glLoadIdentity();
510         qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1);
511         glMatrixMode(GL_MODELVIEW);
512         glLoadIdentity();
513
514         if ( mInterface )
515         {
516                 viewDef_t viewDef;
517                 memset ( &viewDef, 0, sizeof(viewDef) );
518                 tr.viewDef = &viewDef;
519                 viewDef.renderView.x = 0;
520                 viewDef.renderView.y = mToolbarHeight;
521                 viewDef.renderView.width = mWindowWidth;
522                 viewDef.renderView.height = mWindowHeight - mToolbarHeight;
523                 viewDef.scissor.x1 = 0;
524                 viewDef.scissor.y1 = 0; // (rToolbar.bottom-rToolbar.top);
525                 viewDef.scissor.x2 = mWindowWidth;
526                 viewDef.scissor.y2 = mWindowHeight;
527                 viewDef.isEditor = true;
528
529                 // Prepare the renderSystem view to draw the GUI in
530                 renderSystem->BeginFrame(mWindowWidth, mWindowHeight );
531                 
532                 // Draw the gui
533                 mInterface->Redraw ( mTime );
534                 
535                 // We are done using the renderSystem now
536                 renderSystem->EndFrame( &frontEnd, &backEnd );
537         }
538
539         qglFinish ( );
540         qwglSwapBuffers(dc);
541 }
542
543 void rvGEViewer::RunFrame ( void )
544 {
545         if ( !mPaused )
546         {
547                 HDC hDC = GetDC ( mWnd );               
548                 Render ( hDC );         
549                 ReleaseDC ( mWnd, hDC );
550         }
551 }