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"
32 #include "../../sys/win32/rc/guied_resource.h"
33 #include "../../renderer/tr_local.h"
38 rvGEViewer::rvGEViewer ( )
45 bool rvGEViewer::Create ( HWND parent )
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 );
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 );
64 gApp.GetOptions().GetWindowPlacement ( "viewer", mWnd );
67 ShowWindow ( mWnd, SW_SHOW );
68 UpdateWindow ( mWnd );
73 void rvGEViewer::Play ( void )
80 mLastTime = eventLoop->Milliseconds();
84 tbinfo.cbSize = sizeof(TBBUTTONINFO);
85 tbinfo.dwMask = TBIF_COMMAND|TBIF_IMAGE;
87 tbinfo.idCommand = ID_GUIED_VIEWER_PAUSE;
88 SendMessage ( mToolbar, TB_SETBUTTONINFO, ID_GUIED_VIEWER_PLAY, (LPARAM)&tbinfo );
91 void rvGEViewer::Pause ( void )
101 tbinfo.cbSize = sizeof(TBBUTTONINFO);
102 tbinfo.dwMask = TBIF_COMMAND|TBIF_IMAGE;
104 tbinfo.idCommand = ID_GUIED_VIEWER_PLAY;
105 SendMessage ( mToolbar, TB_SETBUTTONINFO, ID_GUIED_VIEWER_PAUSE, (LPARAM)&tbinfo );
109 bool rvGEViewer::Destroy ( void )
111 gApp.GetOptions().SetWindowPlacement ( "viewer", mWnd );
113 DestroyWindow ( mWnd );
117 bool rvGEViewer::OpenFile ( const char* filename )
125 tempfile.StripPath ();
126 tempfile.StripFileExtension ( );
127 tempfile = va("guis/temp.guied", tempfile.c_str() );
128 ospath = fileSystem->RelativePathToOSPath ( tempfile, "fs_basepath" );
130 // Make sure the gui directory exists
131 idStr createDir = ospath;
132 createDir.StripFilename ( );
133 CreateDirectory ( createDir, NULL );
135 SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL );
136 DeleteFile ( ospath );
137 CopyFile ( filename, ospath, FALSE );
138 SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL );
140 mInterface = reinterpret_cast< idUserInterfaceLocal* >( uiManager->FindGui( tempfile, true, true ) );
142 mInterface->SetStateString( "guied_item_0", "guied 1" );
143 mInterface->SetStateString( "guied_item_1", "guied 2" );
144 mInterface->SetStateString( "guied_item_2", "guied 3" );
148 mInterface->Activate ( true, mTime );
150 DeleteFile ( ospath );
161 Map from windows to Doom keynums
164 static int MapKey (int key)
170 modified = ( key >> 16 ) & 255;
172 if ( modified > 127 )
175 if ( key & ( 1 << 24 ) ) {
182 const unsigned char *scanToKey = Sys_GetScanTable();
183 result = scanToKey[modified];
185 // common->Printf( "Key: 0x%08x Modified: 0x%02x Extended: %s Result: 0x%02x\n", key, modified, (is_extended?"Y":"N"), result);
210 return K_KP_LEFTARROW;
212 return K_KP_RIGHTARROW;
216 return K_KP_DOWNARROW;
229 LRESULT CALLBACK rvGEViewer::WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
231 rvGEViewer* viewer = (rvGEViewer*) GetWindowLong ( hwnd, GWL_USERDATA );
237 switch ( LOWORD(wParam) )
239 case ID_GUIED_VIEWER_PLAY:
243 case ID_GUIED_VIEWER_PAUSE:
252 SendMessage ( viewer->mToolbar, TB_AUTOSIZE, 0, 0 );
253 GetWindowRect ( viewer->mToolbar, &rToolbar );
254 viewer->mToolbarHeight = rToolbar.bottom - rToolbar.top;
259 common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE );
267 viewer->HandlePaint ( wParam, lParam );
271 if ( viewer->mInterface )
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 );
284 if ( viewer->mInterface )
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 );
297 if ( viewer->mInterface )
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 );
311 if ( viewer->mInterface )
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 );
325 if ( wParam == VK_ESCAPE )
327 SendMessage ( hwnd, WM_CLOSE, 0, 0 );
331 if ( viewer->mInterface )
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 );
344 if ( viewer->mInterface )
346 float x = (float)(LOWORD(lParam)) / (float)viewer->mWindowWidth * SCREEN_WIDTH;
347 float y = (float)(HIWORD(lParam)) / (float)(viewer->mWindowHeight - viewer->mToolbarHeight) * SCREEN_HEIGHT;
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 );
360 viewer->mInterface = NULL;
361 gApp.CloseViewer ( );
366 CREATESTRUCT* cs = (CREATESTRUCT*) lParam;
367 SetWindowLong ( hwnd, GWL_USERDATA, (LONG)cs->lpCreateParams );
369 viewer = (rvGEViewer*)cs->lpCreateParams;
371 viewer->SetupPixelFormat ( );
373 viewer->mToolbar = CreateWindowEx ( 0, TOOLBARCLASSNAME, "", CCS_BOTTOM|WS_CHILD|WS_VISIBLE,0,0,0,0, hwnd, (HMENU)IDR_GUIED_VIEWERTOOLBAR, gApp.GetInstance(), NULL );
375 // Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility.
376 SendMessage( viewer->mToolbar, TB_BUTTONSTRUCTSIZE, ( WPARAM )sizeof( TBBUTTON ), 0 );
378 SendMessage ( viewer->mToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(16,15) );
380 SendMessage ( viewer->mToolbar, TB_SETSTYLE, 0, SendMessage ( viewer->mToolbar, TB_GETSTYLE, 0, 0 ) | TBSTYLE_FLAT );
383 tbmet.cbSize = sizeof(TBMETRICS);
384 SendMessage ( viewer->mToolbar, TB_GETMETRICS, 0, (LPARAM)&tbmet );
387 SendMessage ( viewer->mToolbar, TB_SETMETRICS, 0, (LPARAM)&tbmet );
389 // Add the bitmap containing button images to the toolbar.
391 tbab.hInst = win32.hInstance;
392 tbab.nID = IDR_GUIED_VIEWERTOOLBAR;
393 SendMessage( viewer->mToolbar, TB_ADDBITMAP, (WPARAM)4, (LPARAM) &tbab );
396 tbb[0].fsStyle = BTNS_SEP;
399 tbb[1].idCommand = ID_GUIED_VIEWER_START;
402 tbb[1].fsStyle = BTNS_BUTTON;
406 tbb[2].idCommand = ID_GUIED_VIEWER_PAUSE;
408 tbb[2].fsState = TBSTATE_ENABLED;
409 tbb[2].fsStyle = BTNS_BUTTON;
413 tbb[3].fsStyle = BTNS_SEP;
416 SendMessage( viewer->mToolbar, TB_ADDBUTTONS, (WPARAM)4, (LPARAM) &tbb );
426 return DefWindowProc ( hwnd, msg, wParam, lParam );
429 LRESULT rvGEViewer::HandlePaint ( WPARAM wParam, LPARAM lParam )
434 dc = BeginPaint ( mWnd, &ps );
438 EndPaint ( mWnd, &ps );
445 rvGEViewer::SetupPixelFormat
447 Setup the pixel format for the opengl context
450 bool rvGEViewer::SetupPixelFormat ( void )
452 HDC hDC = GetDC ( mWnd );
455 int pixelFormat = ChoosePixelFormat(hDC, &win32.pfd);
458 if (SetPixelFormat(hDC, pixelFormat, &win32.pfd) == NULL)
468 ReleaseDC ( mWnd, hDC );
473 void rvGEViewer::Render ( HDC dc )
478 // Switch GL contexts to our dc
479 if (!qwglMakeCurrent( dc, win32.hGLRC ))
481 common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError());
482 common->Printf("Please restart Q3Radiant if the Map view is not working\n");
488 mTime += eventLoop->Milliseconds() - mLastTime;
489 mLastTime = eventLoop->Milliseconds();
494 GetClientRect ( mWnd, &rClient );
495 GetClientRect ( mToolbar, &rToolbar );
496 mWindowWidth = rClient.right - rClient.left;
497 mWindowHeight = rClient.bottom - rClient.top;
499 qglViewport(0, 0, mWindowWidth, mWindowHeight );
500 qglScissor(0, 0, mWindowWidth, mWindowHeight );
501 qglClearColor ( 0, 0, 0, 0 );
503 qglDisable(GL_DEPTH_TEST);
504 qglDisable(GL_CULL_FACE);
505 qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
507 // Render the workspace below
508 glMatrixMode(GL_PROJECTION);
510 qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1);
511 glMatrixMode(GL_MODELVIEW);
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;
529 // Prepare the renderSystem view to draw the GUI in
530 renderSystem->BeginFrame(mWindowWidth, mWindowHeight );
533 mInterface->Redraw ( mTime );
535 // We are done using the renderSystem now
536 renderSystem->EndFrame( &frontEnd, &backEnd );
543 void rvGEViewer::RunFrame ( void )
547 HDC hDC = GetDC ( mWnd );
549 ReleaseDC ( mWnd, hDC );