Blender  V2.59
GPG_Application.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: GPG_Application.cpp 37865 2011-06-27 14:34:58Z blendix $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  * GHOST Blender Player application implementation file.
00029  */
00030 
00036 #ifdef WIN32
00037         #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
00038         #include <windows.h>
00039 #endif
00040 
00041 #include "GL/glew.h"
00042 #include "GPU_extensions.h"
00043 
00044 #include "GPG_Application.h"
00045 
00046 #include <iostream>
00047 #include <MT_assert.h>
00048 #include <stdlib.h>
00049 
00050 /**********************************
00051  * Begin Blender include block
00052  **********************************/
00053 #ifdef __cplusplus
00054 extern "C"
00055 {
00056 #endif  // __cplusplus
00057 #include "BLI_blenlib.h"
00058 #include "BLO_readfile.h"
00059 #include "BKE_global.h"
00060 #include "BKE_main.h"
00061 #include "BKE_sound.h"
00062 #include "IMB_imbuf.h"
00063 #include "DNA_scene_types.h"
00064 #ifdef __cplusplus
00065 }
00066 #endif // __cplusplus
00067 /**********************************
00068  * End Blender include block
00069  **********************************/
00070 
00071 
00072 #include "BL_System.h"
00073 #include "KX_KetsjiEngine.h"
00074 
00075 // include files needed by "KX_BlenderSceneConverter.h"
00076 #include "CTR_Map.h"
00077 #include "SCA_IActuator.h"
00078 #include "RAS_MeshObject.h"
00079 #include "RAS_OpenGLRasterizer.h"
00080 #include "RAS_VAOpenGLRasterizer.h"
00081 #include "RAS_ListRasterizer.h"
00082 #include "RAS_GLExtensionManager.h"
00083 #include "KX_PythonInit.h"
00084 #include "KX_PyConstraintBinding.h"
00085 #include "BL_Material.h" // MAXTEX
00086 
00087 #include "KX_BlenderSceneConverter.h"
00088 #include "NG_LoopBackNetworkDeviceInterface.h"
00089 
00090 #include "GPC_MouseDevice.h"
00091 #include "GPC_RenderTools.h"
00092 #include "GPG_Canvas.h" 
00093 #include "GPG_KeyboardDevice.h"
00094 #include "GPG_System.h"
00095 
00096 #include "STR_String.h"
00097 
00098 #include "GHOST_ISystem.h"
00099 #include "GHOST_IEvent.h"
00100 #include "GHOST_IEventConsumer.h"
00101 #include "GHOST_IWindow.h"
00102 #include "GHOST_Rect.h"
00103 
00104 static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
00105 
00106 static GHOST_ISystem* fSystem = 0;
00107 static const int kTimerFreq = 10;
00108 
00109 GPG_Application::GPG_Application(GHOST_ISystem* system)
00110         : m_startSceneName(""), 
00111           m_startScene(0),
00112           m_maggie(0),
00113           m_exitRequested(0),
00114           m_system(system), 
00115           m_mainWindow(0), 
00116           m_frameTimer(0), 
00117           m_cursor(GHOST_kStandardCursorFirstCursor),
00118           m_engineInitialized(0), 
00119           m_engineRunning(0), 
00120           m_isEmbedded(false),
00121           m_ketsjiengine(0),
00122           m_kxsystem(0), 
00123           m_keyboard(0), 
00124           m_mouse(0), 
00125           m_canvas(0), 
00126           m_rendertools(0), 
00127           m_rasterizer(0), 
00128           m_sceneconverter(0),
00129           m_networkdevice(0),
00130           m_blendermat(0),
00131           m_blenderglslmat(0),
00132           m_pyGlobalDictString(0),
00133           m_pyGlobalDictString_Length(0)
00134 {
00135         fSystem = system;
00136 }
00137 
00138 
00139 
00140 GPG_Application::~GPG_Application(void)
00141 {
00142     if(m_pyGlobalDictString) {
00143                 delete [] m_pyGlobalDictString;
00144                 m_pyGlobalDictString = 0;
00145                 m_pyGlobalDictString_Length = 0;
00146         }
00147 
00148         exitEngine();
00149         fSystem->disposeWindow(m_mainWindow);
00150 }
00151 
00152 
00153 
00154 bool GPG_Application::SetGameEngineData(struct Main* maggie, Scene *scene, int argc, char **argv)
00155 {
00156         bool result = false;
00157 
00158         if (maggie != NULL && scene != NULL)
00159         {
00160 // XXX          G.scene = scene;
00161                 m_maggie = maggie;
00162                 m_startSceneName = scene->id.name+2;
00163                 m_startScene = scene;
00164                 result = true;
00165         }
00166         
00167         /* Python needs these */
00168         m_argc= argc;
00169         m_argv= argv;
00170 
00171         return result;
00172 }
00173 
00174 
00175 #ifdef WIN32
00176 #define SCR_SAVE_MOUSE_MOVE_THRESHOLD 15
00177 
00178 static HWND found_ghost_window_hwnd;
00179 static GHOST_IWindow* ghost_window_to_find;
00180 static WNDPROC ghost_wnd_proc;
00181 static POINT scr_save_mouse_pos;
00182 
00183 static LRESULT CALLBACK screenSaverWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00184 {
00185         BOOL close = FALSE;
00186         switch (uMsg)
00187         {
00188                 case WM_MOUSEMOVE:
00189                 { 
00190                         POINT pt; 
00191                         GetCursorPos(&pt);
00192                         LONG dx = scr_save_mouse_pos.x - pt.x;
00193                         LONG dy = scr_save_mouse_pos.y - pt.y;
00194                         if (abs(dx) > SCR_SAVE_MOUSE_MOVE_THRESHOLD
00195                             || abs(dy) > SCR_SAVE_MOUSE_MOVE_THRESHOLD)
00196                         {
00197                                 close = TRUE;
00198                         }
00199                         scr_save_mouse_pos = pt;
00200                         break;
00201                 }
00202                 case WM_LBUTTONDOWN: 
00203                 case WM_MBUTTONDOWN: 
00204                 case WM_RBUTTONDOWN: 
00205                 case WM_KEYDOWN:
00206                         close = TRUE;
00207         }
00208         if (close)
00209                 PostMessage(hwnd,WM_CLOSE,0,0);
00210         return CallWindowProc(ghost_wnd_proc, hwnd, uMsg, wParam, lParam);
00211 }
00212 
00213 BOOL CALLBACK findGhostWindowHWNDProc(HWND hwnd, LPARAM lParam)
00214 {
00215         GHOST_IWindow *p = (GHOST_IWindow*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
00216         BOOL ret = TRUE;
00217         if (p == ghost_window_to_find)
00218         {
00219                 found_ghost_window_hwnd = hwnd;
00220                 ret = FALSE;
00221         }
00222         return ret;
00223 }
00224 
00225 static HWND findGhostWindowHWND(GHOST_IWindow* window)
00226 {
00227         found_ghost_window_hwnd = NULL;
00228         ghost_window_to_find = window;
00229         EnumWindows(findGhostWindowHWNDProc, NULL);
00230         return found_ghost_window_hwnd;
00231 }
00232 
00233 bool GPG_Application::startScreenSaverPreview(
00234         HWND parentWindow,
00235         const bool stereoVisual,
00236         const int stereoMode,
00237         const GHOST_TUns16 samples)
00238 {
00239         bool success = false;
00240 
00241         RECT rc;
00242         if (GetWindowRect(parentWindow, &rc))
00243         {
00244                 int windowWidth = rc.right - rc.left;
00245                 int windowHeight = rc.bottom - rc.top;
00246                 STR_String title = "";
00247                                                         
00248                 m_mainWindow = fSystem->createWindow(title, 0, 0, windowWidth, windowHeight, GHOST_kWindowStateMinimized,
00249                         GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples);
00250                 if (!m_mainWindow) {
00251                         printf("error: could not create main window\n");
00252                         exit(-1);
00253                 }
00254 
00255                 HWND ghost_hwnd = findGhostWindowHWND(m_mainWindow);
00256                 if (!ghost_hwnd) {
00257                         printf("error: could find main window\n");
00258                         exit(-1);
00259                 }
00260 
00261                 SetParent(ghost_hwnd, parentWindow);
00262                 LONG style = GetWindowLong(ghost_hwnd, GWL_STYLE);
00263                 LONG exstyle = GetWindowLong(ghost_hwnd, GWL_EXSTYLE);
00264 
00265                 RECT adjrc = { 0, 0, windowWidth, windowHeight };
00266                 AdjustWindowRectEx(&adjrc, style, FALSE, exstyle);
00267 
00268                 style = (style & (~(WS_POPUP|WS_OVERLAPPEDWINDOW|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_TILEDWINDOW ))) | WS_CHILD;
00269                 SetWindowLong(ghost_hwnd, GWL_STYLE, style);
00270                 SetWindowPos(ghost_hwnd, NULL, adjrc.left, adjrc.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
00271 
00272                 /* Check the size of the client rectangle of the window and resize the window
00273                  * so that the client rectangle has the size requested.
00274                  */
00275                 m_mainWindow->setClientSize(windowWidth, windowHeight);
00276 
00277                 success = initEngine(m_mainWindow, stereoMode);
00278                 if (success) {
00279                         success = startEngine();
00280                 }
00281 
00282         }
00283         return success;
00284 }
00285 
00286 bool GPG_Application::startScreenSaverFullScreen(
00287                 int width,
00288                 int height,
00289                 int bpp,int frequency,
00290                 const bool stereoVisual,
00291                 const int stereoMode,
00292                 const GHOST_TUns16 samples)
00293 {
00294         bool ret = startFullScreen(width, height, bpp, frequency, stereoVisual, stereoMode, samples);
00295         if (ret)
00296         {
00297                 HWND ghost_hwnd = findGhostWindowHWND(m_mainWindow);
00298                 if (ghost_hwnd != NULL)
00299                 {
00300                         GetCursorPos(&scr_save_mouse_pos);
00301                         ghost_wnd_proc = (WNDPROC) GetWindowLongPtr(ghost_hwnd, GWLP_WNDPROC);
00302                         SetWindowLongPtr(ghost_hwnd,GWLP_WNDPROC, (uintptr_t) screenSaverWindowProc);
00303                 }
00304         }
00305         return ret;
00306 }
00307 
00308 #endif
00309 
00310 bool GPG_Application::startWindow(STR_String& title,
00311         int windowLeft,
00312         int windowTop,
00313         int windowWidth,
00314         int windowHeight,
00315         const bool stereoVisual,
00316         const int stereoMode,
00317         const GHOST_TUns16 samples)
00318 {
00319         bool success;
00320         // Create the main window
00321         //STR_String title ("Blender Player - GHOST");
00322         m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal,
00323                 GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples);
00324         if (!m_mainWindow) {
00325                 printf("error: could not create main window\n");
00326                 exit(-1);
00327         }
00328 
00329         /* Check the size of the client rectangle of the window and resize the window
00330          * so that the client rectangle has the size requested.
00331          */
00332         m_mainWindow->setClientSize(windowWidth, windowHeight);
00333         m_mainWindow->setCursorVisibility(false);
00334 
00335         success = initEngine(m_mainWindow, stereoMode);
00336         if (success) {
00337                 success = startEngine();
00338         }
00339         return success;
00340 }
00341 
00342 bool GPG_Application::startEmbeddedWindow(STR_String& title,
00343         const GHOST_TEmbedderWindowID parentWindow, 
00344         const bool stereoVisual, 
00345         const int stereoMode,
00346         const GHOST_TUns16 samples) {
00347         GHOST_TWindowState state = GHOST_kWindowStateNormal;
00348         if (parentWindow != 0)
00349                 state = GHOST_kWindowStateEmbedded;
00350         m_mainWindow = fSystem->createWindow(title, 0, 0, 0, 0, state,
00351                 GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples, parentWindow);
00352 
00353         if (!m_mainWindow) {
00354                 printf("error: could not create main window\n");
00355                 exit(-1);
00356         }
00357         m_isEmbedded = true;
00358 
00359         bool success = initEngine(m_mainWindow, stereoMode);
00360         if (success) {
00361                 success = startEngine();
00362         }
00363         return success;
00364 }
00365 
00366 
00367 bool GPG_Application::startFullScreen(
00368                 int width,
00369                 int height,
00370                 int bpp,int frequency,
00371                 const bool stereoVisual,
00372                 const int stereoMode,
00373                 const GHOST_TUns16 samples)
00374 {
00375         bool success;
00376         // Create the main window
00377         GHOST_DisplaySetting setting;
00378         setting.xPixels = width;
00379         setting.yPixels = height;
00380         setting.bpp = bpp;
00381         setting.frequency = frequency;
00382 
00383         fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual);
00384         m_mainWindow->setCursorVisibility(false);
00385         m_mainWindow->setState(GHOST_kWindowStateFullScreen);
00386 
00387         success = initEngine(m_mainWindow, stereoMode);
00388         if (success) {
00389                 success = startEngine();
00390         }
00391         return success;
00392 }
00393 
00394 
00395 
00396 
00397 bool GPG_Application::StartGameEngine(int stereoMode)
00398 {
00399         bool success = initEngine(m_mainWindow, stereoMode);
00400         
00401         if (success)
00402                 success = startEngine();
00403 
00404         return success;
00405 }
00406 
00407 
00408 
00409 void GPG_Application::StopGameEngine()
00410 {
00411         exitEngine();
00412 }
00413 
00414 
00415 
00416 bool GPG_Application::processEvent(GHOST_IEvent* event)
00417 {
00418         bool handled = true;
00419 
00420         switch (event->getType())
00421         {
00422                 case GHOST_kEventUnknown:
00423                         break;
00424 
00425                 case GHOST_kEventButtonDown:
00426                         handled = handleButton(event, true);
00427                         break;
00428 
00429                 case GHOST_kEventButtonUp:
00430                         handled = handleButton(event, false);
00431                         break;
00432                         
00433                 case GHOST_kEventWheel:
00434                         handled = handleWheel(event);
00435                         break;
00436 
00437                 case GHOST_kEventCursorMove:
00438                         handled = handleCursorMove(event);
00439                         break;
00440 
00441                 case GHOST_kEventKeyDown:
00442                         handleKey(event, true);
00443                         break;
00444 
00445                 case GHOST_kEventKeyUp:
00446                         handleKey(event, false);
00447                         break;
00448 
00449 
00450                 case GHOST_kEventWindowClose:
00451                 case GHOST_kEventQuit:
00452                         m_exitRequested = KX_EXIT_REQUEST_OUTSIDE;
00453                         break;
00454 
00455                 case GHOST_kEventWindowActivate:
00456                         handled = false;
00457                         break;
00458                 case GHOST_kEventWindowDeactivate:
00459                         handled = false;
00460                         break;
00461 
00462                 case GHOST_kEventWindowUpdate:
00463                         {
00464                                 GHOST_IWindow* window = event->getWindow();
00465                                 if (!m_system->validWindow(window)) break;
00466                                 // Update the state of the game engine
00467                                 if (m_kxsystem && !m_exitRequested)
00468                                 {
00469                                         // Proceed to next frame
00470                                         window->activateDrawingContext();
00471 
00472                                         // first check if we want to exit
00473                                         m_exitRequested = m_ketsjiengine->GetExitCode();
00474                                         
00475                                         // kick the engine
00476                                         bool renderFrame = m_ketsjiengine->NextFrame();
00477                                         if (renderFrame)
00478                                         {
00479                                                 // render the frame
00480                                                 m_ketsjiengine->Render();
00481                                         }
00482                                 }
00483                                 m_exitString = m_ketsjiengine->GetExitString();
00484                         }
00485                         break;
00486                 
00487                 case GHOST_kEventWindowSize:
00488                         {
00489                         GHOST_IWindow* window = event->getWindow();
00490                         if (!m_system->validWindow(window)) break;
00491                         if (m_canvas) {
00492                                 GHOST_Rect bnds;
00493                                 window->getClientBounds(bnds);
00494                                 m_canvas->Resize(bnds.getWidth(), bnds.getHeight());
00495                         }
00496                         }
00497                         break;
00498                 
00499                 default:
00500                         handled = false;
00501                         break;
00502         }
00503         return handled;
00504 }
00505 
00506 
00507 
00508 int GPG_Application::getExitRequested(void)
00509 {
00510         return m_exitRequested;
00511 }
00512 
00513 
00514 
00515 const STR_String& GPG_Application::getExitString(void)
00516 {
00517         return m_exitString;
00518 }
00519 
00520 
00521 
00522 bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
00523 {
00524         if (!m_engineInitialized)
00525         {
00526                 GPU_extensions_init();
00527                 bgl::InitExtensions(true);
00528 
00529                 // get and set the preferences
00530                 SYS_SystemHandle syshandle = SYS_GetSystem();
00531                 if (!syshandle)
00532                         return false;
00533                 
00534                 // SYS_WriteCommandLineInt(syshandle, "fixedtime", 0);
00535                 // SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);                
00536                 GameData *gm= &m_startScene->gm;
00537                 bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
00538                 bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
00539                 bool fixedFr = (gm->flag & GAME_ENABLE_ALL_FRAMES);
00540 
00541                 bool showPhysics = (gm->flag & GAME_SHOW_PHYSICS);
00542                 SYS_WriteCommandLineInt(syshandle, "show_physics", showPhysics);
00543 
00544                 bool fixed_framerate= (SYS_GetCommandLineInt(syshandle, "fixed_framerate", fixedFr) != 0);
00545                 bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
00546                 bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", gm->flag & GAME_DISPLAY_LISTS) != 0);
00547                 bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 1) != 0);
00548 
00549                 if(GLEW_ARB_multitexture && GLEW_VERSION_1_1)
00550                         m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 1) != 0);
00551 
00552                 if(GPU_glsl_support())
00553                         m_blenderglslmat = (SYS_GetCommandLineInt(syshandle, "blender_glsl_material", 1) != 0);
00554                 else if(gm->matmode == GAME_MAT_GLSL)
00555                         m_blendermat = false;
00556 
00557                 // create the canvas, rasterizer and rendertools
00558                 m_canvas = new GPG_Canvas(window);
00559                 if (!m_canvas)
00560                         return false;
00561                                 
00562                 m_canvas->Init();
00563                 if (gm->flag & GAME_SHOW_MOUSE)
00564                         m_canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);                             
00565 
00566                 m_rendertools = new GPC_RenderTools();
00567                 if (!m_rendertools)
00568                         goto initFailed;
00569                 
00570                 if(useLists) {
00571                         if(GLEW_VERSION_1_1)
00572                                 m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
00573                         else
00574                                 m_rasterizer = new RAS_ListRasterizer(m_canvas);
00575                 }
00576                 else if (GLEW_VERSION_1_1)
00577                         m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
00578                 else
00579                         m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);
00580 
00581                 /* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
00582                 m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
00583                 m_rasterizer->SetEyeSeparation(m_startScene->gm.eyeseparation);
00584                 
00585                 if (!m_rasterizer)
00586                         goto initFailed;
00587                                                 
00588                 // create the inputdevices
00589                 m_keyboard = new GPG_KeyboardDevice();
00590                 if (!m_keyboard)
00591                         goto initFailed;
00592                         
00593                 m_mouse = new GPC_MouseDevice();
00594                 if (!m_mouse)
00595                         goto initFailed;
00596                         
00597                 // create a networkdevice
00598                 m_networkdevice = new NG_LoopBackNetworkDeviceInterface();
00599                 if (!m_networkdevice)
00600                         goto initFailed;
00601                         
00602                 sound_init(m_maggie);
00603 
00604                 // create a ketsjisystem (only needed for timing and stuff)
00605                 m_kxsystem = new GPG_System (m_system);
00606                 if (!m_kxsystem)
00607                         goto initFailed;
00608                 
00609                 // create the ketsjiengine
00610                 m_ketsjiengine = new KX_KetsjiEngine(m_kxsystem);
00611                 
00612                 // set the devices
00613                 m_ketsjiengine->SetKeyboardDevice(m_keyboard);
00614                 m_ketsjiengine->SetMouseDevice(m_mouse);
00615                 m_ketsjiengine->SetNetworkDevice(m_networkdevice);
00616                 m_ketsjiengine->SetCanvas(m_canvas);
00617                 m_ketsjiengine->SetRenderTools(m_rendertools);
00618                 m_ketsjiengine->SetRasterizer(m_rasterizer);
00619                 m_ketsjiengine->SetNetworkDevice(m_networkdevice);
00620 
00621                 m_ketsjiengine->SetTimingDisplay(frameRate, false, false);
00622 #ifdef WITH_PYTHON
00623                 CValue::SetDeprecationWarnings(nodepwarnings);
00624 #else
00625                 (void)nodepwarnings;
00626 #endif
00627 
00628                 m_ketsjiengine->SetUseFixedTime(fixed_framerate);
00629                 m_ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
00630 
00631                 m_engineInitialized = true;
00632         }
00633 
00634         return m_engineInitialized;
00635 initFailed:
00636         sound_exit();
00637         delete m_kxsystem;
00638         delete m_networkdevice;
00639         delete m_mouse;
00640         delete m_keyboard;
00641         delete m_rasterizer;
00642         delete m_rendertools;
00643         delete m_canvas;
00644         m_canvas = NULL;
00645         m_rendertools = NULL;
00646         m_rasterizer = NULL;
00647         m_keyboard = NULL;
00648         m_mouse = NULL;
00649         m_networkdevice = NULL;
00650         m_kxsystem = NULL;
00651         return false;
00652 }
00653 
00654 
00655 
00656 bool GPG_Application::startEngine(void)
00657 {
00658         if (m_engineRunning) {
00659                 return false;
00660         }
00661         
00662         // Temporary hack to disable banner display for NaN approved content.
00663         /*
00664         m_canvas->SetBannerDisplayEnabled(true);        
00665         Camera* cam;
00666         cam = (Camera*)scene->camera->data;
00667         if (cam) {
00668         if (((cam->flag) & 48)==48) {
00669         m_canvas->SetBannerDisplayEnabled(false);
00670         }
00671         }
00672         else {
00673         showError(CString("Camera data invalid."));
00674         return false;
00675         }
00676         */
00677         
00678         // create a scene converter, create and convert the stratingscene
00679         m_sceneconverter = new KX_BlenderSceneConverter(m_maggie, m_ketsjiengine);
00680         if (m_sceneconverter)
00681         {
00682                 STR_String startscenename = m_startSceneName.Ptr();
00683                 m_ketsjiengine->SetSceneConverter(m_sceneconverter);
00684 
00685                 //      if (always_use_expand_framing)
00686                 //              sceneconverter->SetAlwaysUseExpandFraming(true);
00687                 if(m_blendermat && (m_startScene->gm.matmode != GAME_MAT_TEXFACE))
00688                         m_sceneconverter->SetMaterials(true);
00689                 if(m_blenderglslmat && (m_startScene->gm.matmode == GAME_MAT_GLSL))
00690                         m_sceneconverter->SetGLSLMaterials(true);
00691 
00692                 KX_Scene* startscene = new KX_Scene(m_keyboard,
00693                         m_mouse,
00694                         m_networkdevice,
00695                         startscenename,
00696                         m_startScene,
00697                         m_canvas);
00698                 
00699 #ifdef WITH_PYTHON
00700                         // some python things
00701                         PyObject *gameLogic, *gameLogic_keys;
00702                         setupGamePython(m_ketsjiengine, startscene, m_maggie, NULL, &gameLogic, &gameLogic_keys, m_argc, m_argv);
00703 #endif // WITH_PYTHON
00704 
00705                 //initialize Dome Settings
00706                 if(m_startScene->gm.stereoflag == STEREO_DOME)
00707                         m_ketsjiengine->InitDome(m_startScene->gm.dome.res, m_startScene->gm.dome.mode, m_startScene->gm.dome.angle, m_startScene->gm.dome.resbuf, m_startScene->gm.dome.tilt, m_startScene->gm.dome.warptext);
00708 
00709 #ifdef WITH_PYTHON
00710                 // Set the GameLogic.globalDict from marshal'd data, so we can
00711                 // load new blend files and keep data in GameLogic.globalDict
00712                 loadGamePythonConfig(m_pyGlobalDictString, m_pyGlobalDictString_Length);
00713 #endif          
00714                 m_sceneconverter->ConvertScene(
00715                         startscene,
00716                         m_rendertools,
00717                         m_canvas);
00718                 m_ketsjiengine->AddScene(startscene);
00719                 
00720                 // Create a timer that is used to kick the engine
00721                 if (!m_frameTimer) {
00722                         m_frameTimer = m_system->installTimer(0, kTimerFreq, frameTimerProc, m_mainWindow);
00723                 }
00724                 m_rasterizer->Init();
00725                 m_ketsjiengine->StartEngine(true);
00726                 m_engineRunning = true;
00727                 
00728                 // Set the animation playback rate for ipo's and actions
00729                 // the framerate below should patch with FPS macro defined in blendef.h
00730                 // Could be in StartEngine set the framerate, we need the scene to do this
00731                 Scene *scene= startscene->GetBlenderScene(); // needed for macro
00732                 m_ketsjiengine->SetAnimFrameRate(FPS);
00733         }
00734         
00735         if (!m_engineRunning)
00736         {
00737                 stopEngine();
00738         }
00739         
00740         return m_engineRunning;
00741 }
00742 
00743 
00744 void GPG_Application::stopEngine()
00745 {
00746 #ifdef WITH_PYTHON
00747         // GameLogic.globalDict gets converted into a buffer, and sorted in
00748         // m_pyGlobalDictString so we can restore after python has stopped
00749         // and started between .blend file loads.
00750         if(m_pyGlobalDictString) {
00751                 delete [] m_pyGlobalDictString;
00752                 m_pyGlobalDictString = 0;
00753         }
00754 
00755         m_pyGlobalDictString_Length = saveGamePythonConfig(&m_pyGlobalDictString);
00756         
00757         // when exiting the mainloop
00758         exitGamePythonScripting();
00759 #endif
00760         
00761         m_ketsjiengine->StopEngine();
00762         m_networkdevice->Disconnect();
00763 
00764         if (m_sceneconverter) {
00765                 delete m_sceneconverter;
00766                 m_sceneconverter = 0;
00767         }
00768         if (m_system && m_frameTimer) {
00769                 m_system->removeTimer(m_frameTimer);
00770                 m_frameTimer = 0;
00771         }
00772         m_engineRunning = false;
00773 }
00774 
00775 
00776 void GPG_Application::exitEngine()
00777 {
00778         sound_exit();
00779         if (m_ketsjiengine)
00780         {
00781                 stopEngine();
00782                 delete m_ketsjiengine;
00783                 m_ketsjiengine = 0;
00784         }
00785         if (m_kxsystem)
00786         {
00787                 delete m_kxsystem;
00788                 m_kxsystem = 0;
00789         }
00790         if (m_networkdevice)
00791         {
00792                 delete m_networkdevice;
00793                 m_networkdevice = 0;
00794         }
00795         if (m_mouse)
00796         {
00797                 delete m_mouse;
00798                 m_mouse = 0;
00799         }
00800         if (m_keyboard)
00801         {
00802                 delete m_keyboard;
00803                 m_keyboard = 0;
00804         }
00805         if (m_rasterizer)
00806         {
00807                 delete m_rasterizer;
00808                 m_rasterizer = 0;
00809         }
00810         if (m_rendertools)
00811         {
00812                 delete m_rendertools;
00813                 m_rendertools = 0;
00814         }
00815         if (m_canvas)
00816         {
00817                 delete m_canvas;
00818                 m_canvas = 0;
00819         }
00820 
00821         GPU_extensions_exit();
00822 
00823         m_exitRequested = 0;
00824         m_engineInitialized = false;
00825 }
00826 
00827 bool GPG_Application::handleWheel(GHOST_IEvent* event)
00828 {
00829         bool handled = false;
00830         MT_assert(event);
00831         if (m_mouse) 
00832         {
00833                 GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
00834                 GHOST_TEventWheelData* wheelData = static_cast<GHOST_TEventWheelData*>(eventData);
00835                 GPC_MouseDevice::TButtonId button;
00836                 if (wheelData->z > 0)
00837                         button = GPC_MouseDevice::buttonWheelUp;
00838                 else
00839                         button = GPC_MouseDevice::buttonWheelDown;
00840                 m_mouse->ConvertButtonEvent(button, true);
00841                 handled = true;
00842         }
00843         return handled;
00844 }
00845 
00846 bool GPG_Application::handleButton(GHOST_IEvent* event, bool isDown)
00847 {
00848         bool handled = false;
00849         MT_assert(event);
00850         if (m_mouse) 
00851         {
00852                 GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
00853                 GHOST_TEventButtonData* buttonData = static_cast<GHOST_TEventButtonData*>(eventData);
00854                 GPC_MouseDevice::TButtonId button;
00855                 switch (buttonData->button)
00856                 {
00857                 case GHOST_kButtonMaskMiddle:
00858                         button = GPC_MouseDevice::buttonMiddle;
00859                         break;
00860                 case GHOST_kButtonMaskRight:
00861                         button = GPC_MouseDevice::buttonRight;
00862                         break;
00863                 case GHOST_kButtonMaskLeft:
00864                 default:
00865                         button = GPC_MouseDevice::buttonLeft;
00866                         break;
00867                 }
00868                 m_mouse->ConvertButtonEvent(button, isDown);
00869                 handled = true;
00870         }
00871         return handled;
00872 }
00873 
00874 
00875 bool GPG_Application::handleCursorMove(GHOST_IEvent* event)
00876 {
00877         bool handled = false;
00878         MT_assert(event);
00879         if (m_mouse && m_mainWindow)
00880         {
00881                 GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
00882                 GHOST_TEventCursorData* cursorData = static_cast<GHOST_TEventCursorData*>(eventData);
00883                 GHOST_TInt32 x, y;
00884                 m_mainWindow->screenToClient(cursorData->x, cursorData->y, x, y);
00885                 m_mouse->ConvertMoveEvent(x, y);
00886                 handled = true;
00887         }
00888         return handled;
00889 }
00890 
00891 
00892 bool GPG_Application::handleKey(GHOST_IEvent* event, bool isDown)
00893 {
00894         bool handled = false;
00895         MT_assert(event);
00896         if (m_keyboard)
00897         {
00898                 GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
00899                 GHOST_TEventKeyData* keyData = static_cast<GHOST_TEventKeyData*>(eventData);
00900                 //no need for this test
00901                 //if (fSystem->getFullScreen()) {
00902                         if (keyData->key == GHOST_kKeyEsc && !m_keyboard->m_hookesc && !m_isEmbedded) {
00903                                 m_exitRequested = KX_EXIT_REQUEST_OUTSIDE;
00904                         }
00905                 //}
00906                 m_keyboard->ConvertEvent(keyData->key, isDown);
00907                 handled = true;
00908         }
00909         return handled;
00910 }
00911 
00912 
00913 
00914 static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time)
00915 {
00916         GHOST_IWindow* window = (GHOST_IWindow*)task->getUserData();
00917         if (fSystem->validWindow(window)) {
00918                 window->invalidate();
00919         }
00920 }