From 12315f4d0e0ae993805f141f64cb8c73c5297311 Mon Sep 17 00:00:00 2001 From: Hans Lambermont Date: Sat, 12 Oct 2002 11:37:38 +0000 Subject: Initial revision --- .../GamePlayer/ghost/GPG_Application.cpp | 607 +++++++++++++++++++++ 1 file changed, 607 insertions(+) create mode 100644 source/gameengine/GamePlayer/ghost/GPG_Application.cpp (limited to 'source/gameengine/GamePlayer/ghost/GPG_Application.cpp') diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp new file mode 100644 index 00000000000..07ed803b205 --- /dev/null +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -0,0 +1,607 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * GHOST Blender Player application implementation file. + */ + +#ifdef WIN32 + #pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#endif + +#include "GPG_Application.h" + +#include +#include + +/********************************** + * Begin Blender include block + **********************************/ +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus +#include "BLI_blenlib.h" +#include "BLO_readfile.h" +#ifdef __cplusplus +} +#endif // __cplusplus +/********************************** + * End Blender include block + **********************************/ + + +#include "SYS_System.h" +#include "KX_KetsjiEngine.h" + +// include files needed by "KX_BlenderSceneConverter.h" +#include "GEN_Map.h" +#include "SCA_IActuator.h" +#include "RAS_MeshObject.h" +#include "RAS_OpenGLRasterizer.h" +#include "KX_PythonInit.h" +#include "KX_PyConstraintBinding.h" + +#include "KX_BlenderSceneConverter.h" +#include "NG_LoopBackNetworkDeviceInterface.h" +#include "SND_DeviceManager.h" + +#include "GPC_MouseDevice.h" +#include "GPC_RenderTools.h" +#include "GPG_Canvas.h" +#include "GPG_KeyboardDevice.h" +#include "GPG_System.h" + +#include "STR_String.h" + +#include "GHOST_ISystem.h" +#include "GHOST_IEvent.h" +#include "GHOST_IEventConsumer.h" +#include "GHOST_IWindow.h" +#include "GHOST_Rect.h" + + +static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time); + +static GHOST_ISystem* fSystem = 0; +static const int kTimerFreq = 10; + +GPG_Application::GPG_Application(GHOST_ISystem* system, struct Main *maggie, STR_String startSceneName) + : m_maggie(maggie), m_startSceneName(startSceneName), m_exitRequested(0), + m_system(system), m_mainWindow(0), m_frameTimer(0), m_cursor(GHOST_kStandardCursorFirstCursor), + m_mouse(0), m_keyboard(0), m_rasterizer(0), m_canvas(0), m_rendertools(0), m_kxsystem(0), m_networkdevice(0), m_audiodevice(0), m_sceneconverter(0), + m_engineInitialized(0), m_engineRunning(0), m_ketsjiengine(0) +{ + fSystem = system; +} + + + +GPG_Application::~GPG_Application(void) +{ + exitEngine(); + fSystem->disposeWindow(m_mainWindow); +} + + + +bool GPG_Application::SetGameEngineData(struct Main *maggie, STR_String startSceneName) +{ + bool result = false; + + if (maggie != NULL && startSceneName != "") + { + m_maggie = maggie; + m_startSceneName = startSceneName; + result = true; + } + + return result; +} + + + +bool GPG_Application::startWindow(STR_String& title, + int windowLeft, + int windowTop, + int windowWidth, + int windowHeight, + const bool stereoVisual, + const int stereoMode) +{ + bool success; + // Create the main window + //STR_String title ("Blender Player - GHOST"); + m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, stereoVisual); + if (!m_mainWindow) { + printf("error: could not create main window\n"); + exit(-1); + } + + /* Check the size of the client rectangle of the window and resize the window + * so that the client rectangle has the size requested. + */ + m_mainWindow->setClientSize(windowWidth, windowHeight); + + success = initEngine(m_mainWindow, stereoMode); + if (success) { + success = startEngine(); + } + return success; +} + + + +bool GPG_Application::startFullScreen( + int width, + int height, + int bpp,int frequency, + const bool stereoVisual, + const int stereoMode) +{ + bool success; + // Create the main window + GHOST_DisplaySetting setting; + setting.xPixels = width; + setting.yPixels = height; + setting.bpp = bpp; + setting.frequency = frequency; + + fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual); + + success = initEngine(m_mainWindow, stereoMode); + if (success) { + success = startEngine(); + } + return success; +} + + + +bool GPG_Application::StartGameEngine(int stereoMode) +{ + bool success = initEngine(m_mainWindow, stereoMode); + + if (success) + success = startEngine(); + + return success; +} + + + +void GPG_Application::StopGameEngine() +{ + exitEngine(); +} + + + +bool GPG_Application::processEvent(GHOST_IEvent* event) +{ + bool handled = true; + + switch (event->getType()) + { + case GHOST_kEventUnknown: + break; + + case GHOST_kEventButtonDown: + handled = handleButton(event, true); + break; + + case GHOST_kEventButtonUp: + handled = handleButton(event, false); + break; + + case GHOST_kEventCursorMove: + handled = handleCursorMove(event); + break; + + case GHOST_kEventKeyDown: + handleKey(event, true); + break; + + case GHOST_kEventKeyUp: + handleKey(event, false); + break; + + + case GHOST_kEventWindowClose: + m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; + break; + + case GHOST_kEventWindowActivate: + handled = false; + break; + case GHOST_kEventWindowDeactivate: + handled = false; + break; + + case GHOST_kEventWindowUpdate: + { + GHOST_IWindow* window = event->getWindow(); + if (!m_system->validWindow(window)) break; + // Update the state of the game engine + if (m_kxsystem && !m_exitRequested) + { + // Proceed to next frame + window->activateDrawingContext(); + + // first check if we want to exit + m_exitRequested = m_ketsjiengine->GetExitCode(); + + // kick the engine + m_ketsjiengine->NextFrame(); + + // render the frame + m_ketsjiengine->Render(); + } + m_exitString = m_ketsjiengine->GetExitString(); + } + break; + + case GHOST_kEventWindowSize: + { + GHOST_IWindow* window = event->getWindow(); + if (!m_system->validWindow(window)) break; + if (m_canvas) { + GHOST_Rect bnds; + window->getClientBounds(bnds); + m_canvas->Resize(bnds.getWidth(), bnds.getHeight()); + } + } + break; + + default: + handled = false; + break; + } + return handled; +} + + + +int GPG_Application::getExitRequested(void) +{ + return m_exitRequested; +} + + + +const STR_String& GPG_Application::getExitString(void) +{ + return m_exitString; +} + + + +bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) +{ + if (!m_engineInitialized) + { + // get and set the preferences + SYS_SystemHandle syshandle = SYS_GetSystem(); + if (syshandle) + { + // SYS_WriteCommandLineInt(syshandle, "fixedtime", 0); + SYS_WriteCommandLineInt(syshandle, "vertexarrays",1); + //bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0); + //bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0); + //bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0); + + // create the canvas, rasterizer and rendertools + m_canvas = new GPG_Canvas(window); + if (m_canvas) + { + m_canvas->Init(); + m_rendertools = new GPC_RenderTools(); + if (m_rendertools) + { + m_rasterizer = new RAS_OpenGLRasterizer(m_canvas); + m_rasterizer->SetStereoMode(stereoMode); + if (m_rasterizer) + { + // create the inputdevices + m_keyboard = new GPG_KeyboardDevice(); + if (m_keyboard) + { + m_mouse = new GPC_MouseDevice(); + if (m_mouse) + { + // create a networkdevice + m_networkdevice = new NG_LoopBackNetworkDeviceInterface(); + if (m_networkdevice) + { + // get an audiodevice + SND_DeviceManager::Subscribe(); + m_audiodevice = SND_DeviceManager::Instance(); + if (m_audiodevice) + { + m_audiodevice->UseCD(); + // create a ketsjisystem (only needed for timing and stuff) + m_kxsystem = new GPG_System (m_system); + if (m_kxsystem) + { + // create the ketsjiengine + m_ketsjiengine = new KX_KetsjiEngine(m_kxsystem); + + // set the devices + m_ketsjiengine->SetKeyboardDevice(m_keyboard); + m_ketsjiengine->SetMouseDevice(m_mouse); + m_ketsjiengine->SetNetworkDevice(m_networkdevice); + m_ketsjiengine->SetCanvas(m_canvas); + m_ketsjiengine->SetRenderTools(m_rendertools); + m_ketsjiengine->SetRasterizer(m_rasterizer); + m_ketsjiengine->SetNetworkDevice(m_networkdevice); + m_ketsjiengine->SetAudioDevice(m_audiodevice); + + m_ketsjiengine->SetUseFixedTime(false); + //m_ketsjiengine->SetTimingDisplay(frameRate, profile, properties); + + m_engineInitialized = true; + } + } + } + } + } + } + } + } + } + } + + return m_engineInitialized; +} + + + +bool GPG_Application::startEngine(void) +{ + if (m_engineRunning) { + return false; + } + + // Temporary hack to disable banner display for NaN approved content. + /* + m_canvas->SetBannerDisplayEnabled(true); + Camera* cam; + cam = (Camera*)G.scene->camera->data; + if (cam) { + if (((cam->flag) & 48)==48) { + m_canvas->SetBannerDisplayEnabled(false); + } + } + else { + showError(CString("Camera data invalid.")); + return false; + } + */ + + // create a scene converter, create and convert the stratingscene + m_sceneconverter = new KX_BlenderSceneConverter(m_maggie, m_ketsjiengine); + if (m_sceneconverter) + { + STR_String startscenename = m_startSceneName.Ptr(); + m_ketsjiengine->SetSceneConverter(m_sceneconverter); + + // if (always_use_expand_framing) + // sceneconverter->SetAlwaysUseExpandFraming(true); + + + KX_Scene* startscene = new KX_Scene(m_keyboard, + m_mouse, + m_networkdevice, + m_audiodevice, + startscenename); + + // some python things + PyObject* m_dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest); + m_ketsjiengine->SetPythonDictionary(m_dictionaryobject); + initRasterizer(m_rasterizer, m_canvas); + initGameLogic(startscene); + initGameKeys(); + initPythonConstraintBinding(); + + m_sceneconverter->ConvertScene( + startscenename, + startscene, + m_dictionaryobject, + m_keyboard, + m_rendertools, + m_canvas); + m_ketsjiengine->AddScene(startscene); + + // Create a timer that is used to kick the engine + if (!m_frameTimer) { + m_frameTimer = m_system->installTimer(0, kTimerFreq, frameTimerProc, m_mainWindow); + } + m_rasterizer->Init(); + m_ketsjiengine->StartEngine(); + m_engineRunning = true; + + } + + if (!m_engineRunning) + { + stopEngine(); + } + + return m_engineRunning; +} + + +void GPG_Application::stopEngine() +{ + // when exiting the mainloop + exitGamePythonScripting(); + m_ketsjiengine->StopEngine(); + m_networkdevice->Disconnect(); + + if (m_sceneconverter) { + delete m_sceneconverter; + m_sceneconverter = 0; + } + if (m_system && m_frameTimer) { + m_system->removeTimer(m_frameTimer); + m_frameTimer = 0; + } + m_engineRunning = false; +} + + +void GPG_Application::exitEngine() +{ + if (m_ketsjiengine) + { + stopEngine(); + delete m_ketsjiengine; + m_ketsjiengine = 0; + } + if (m_kxsystem) + { + delete m_kxsystem; + m_kxsystem = 0; + } + if (m_audiodevice) + { + SND_DeviceManager::Unsubscribe(); + m_audiodevice = 0; + } + if (m_networkdevice) + { + delete m_networkdevice; + m_networkdevice = 0; + } + if (m_mouse) + { + delete m_mouse; + m_mouse = 0; + } + if (m_keyboard) + { + delete m_keyboard; + m_keyboard = 0; + } + if (m_rasterizer) + { + delete m_rasterizer; + m_rasterizer = 0; + } + if (m_rendertools) + { + delete m_rendertools; + m_rendertools = 0; + } + if (m_canvas) + { + delete m_canvas; + m_canvas = 0; + } + + m_exitRequested = 0; + m_engineInitialized = false; +} + + +bool GPG_Application::handleButton(GHOST_IEvent* event, bool isDown) +{ + bool handled = false; + assert(event); + if (m_mouse) + { + GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); + GHOST_TEventButtonData* buttonData = static_cast(eventData); + GPC_MouseDevice::TButtonId button; + switch (buttonData->button) + { + case GHOST_kButtonMaskMiddle: + button = GPC_MouseDevice::buttonMiddle; + break; + case GHOST_kButtonMaskRight: + button = GPC_MouseDevice::buttonRight; + break; + case GHOST_kButtonMaskLeft: + default: + button = GPC_MouseDevice::buttonLeft; + break; + } + m_mouse->ConvertButtonEvent(button, isDown); + handled = true; + } + return handled; +} + + +bool GPG_Application::handleCursorMove(GHOST_IEvent* event) +{ + bool handled = false; + assert(event); + if (m_mouse && m_mainWindow) + { + GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); + GHOST_TEventCursorData* cursorData = static_cast(eventData); + GHOST_TInt32 x, y; + m_mainWindow->screenToClient(cursorData->x, cursorData->y, x, y); + m_mouse->ConvertMoveEvent(x, y); + handled = true; + } + return handled; +} + + +bool GPG_Application::handleKey(GHOST_IEvent* event, bool isDown) +{ + bool handled = false; + assert(event); + if (m_keyboard) + { + GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData(); + GHOST_TEventKeyData* keyData = static_cast(eventData); + if (fSystem->getFullScreen()) { + if (keyData->key == GHOST_kKeyEsc) { + m_exitRequested = KX_EXIT_REQUEST_OUTSIDE; + } + } + m_keyboard->ConvertEvent(keyData->key, isDown); + handled = true; + } + return handled; +} + + + +static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time) +{ + GHOST_IWindow* window = (GHOST_IWindow*)task->getUserData(); + if (fSystem->validWindow(window)) { + window->invalidate(); + } +} -- cgit v1.2.3