diff options
author | Eugene Sandulenko | 2010-07-29 19:53:02 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2010-10-12 21:38:20 +0000 |
commit | a683a420a9e43705c972b5e74d55e319729e1a81 (patch) | |
tree | bde6e4abd417bdfaec120aa951da9a19be36b654 /engines/sword25/kernel/kernel.cpp | |
parent | 7723d91c957d07205c51be32498d45cd0a78568f (diff) | |
download | scummvm-rg350-a683a420a9e43705c972b5e74d55e319729e1a81.tar.gz scummvm-rg350-a683a420a9e43705c972b5e74d55e319729e1a81.tar.bz2 scummvm-rg350-a683a420a9e43705c972b5e74d55e319729e1a81.zip |
SWORD25: Importing original sources
svn-id: r53171
Diffstat (limited to 'engines/sword25/kernel/kernel.cpp')
-rwxr-xr-x | engines/sword25/kernel/kernel.cpp | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/engines/sword25/kernel/kernel.cpp b/engines/sword25/kernel/kernel.cpp new file mode 100755 index 0000000000..e6d8ec2872 --- /dev/null +++ b/engines/sword25/kernel/kernel.cpp @@ -0,0 +1,412 @@ +// ----------------------------------------------------------------------------- +// This file is part of Broken Sword 2.5 +// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer +// +// Broken Sword 2.5 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. +// +// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------------------- + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include <windows.h> +#include <psapi.h> +#pragma comment(lib, "psapi.lib") + +#include <math.h> +#include <algorithm> + +#include "kernel.h" +#include "timer.h" +#include "service_ids.h" + +#include "gfx/graphicengine.h" +#include "sfx/soundengine.h" +#include "input/inputengine.h" +#include "package/packagemanager.h" +#include "script/script.h" +#include "fmv/movieplayer.h" +#include "persistenceservice.h" +#include "cpuinfo.h" + +#define BS_LOG_PREFIX "KERNEL" + +BS_Kernel * BS_Kernel::_Instance = 0; + +// Konstruktion / Destruktion +// -------------------------- +BS_Kernel::BS_Kernel() : + _pWindow(NULL), + _Running(false), + _pResourceManager(NULL), + _InitSuccess(false) +{ + // TODO: + // Messagebox ausgeben wenn nicht gelogged werden kann -> log.txt schreibgeschützt + BS_LOGLN("created."); + + // CPU-Daten in die Log-Datei schreiben + const BS_CPUInfo & CI = BS_CPUInfo::GetInstance(); + BS_LOGLN("CPU detected (vendor name: \"%s\", CPU name: \"%s\").", CI.GetVendorString().c_str(), CI.GetCPUName().c_str()); + BS_LOGLN("CPU features: %s%s%s%s%s.", + CI.IsMMXSupported() ? "MMX" : "", + CI.IsSSESupported() ? " SSE" : "", + CI.IsSSE2Supported() ? " SSE2" : "", + CI.Is3DNowSupported() ? " 3DNow!" : "", + CI.Is3DNowExtSupported() ? " 3DNow!Ext" : ""); + + // Sicherstellen, dass der Prozessor über MMX verfügt + if (!CI.IsMMXSupported()) + { + BS_LOG_ERRORLN("MMX support needed."); + return; + } + + // Feststellen, ob der Timer unterstützt wird. + if (!BS_Timer::IsTimerAvaliable()) + { + BS_LOG_ERRORLN("This machine doesn't support a performance counter."); + return; + } + + // Die BS_SERVICE_TABLE auslesen und kernelinterne Strukturen vorbereiten + for (unsigned int i = 0; i < BS_SERVICE_COUNT; i++) + { + // Ist die Superclass schon registriert? + Superclass* pCurSuperclass = NULL; + std::vector<Superclass*>::iterator Iter; + for (Iter = _SuperclassList.begin(); Iter != _SuperclassList.end(); ++Iter) + if ((*Iter)->GetIdentifier() == BS_SERVICE_TABLE[i].SuperclassIdentifier) + { + pCurSuperclass = *Iter; + break; + } + + // Falls die Superclass noch nicht registriert war, wird dies jetzt gemacht + if (!pCurSuperclass) + _SuperclassList.push_back(new Superclass(this, BS_SERVICE_TABLE[i].SuperclassIdentifier)); + } + + // Fensterobjekt erstellen + _pWindow = BS_Window::CreateBSWindow(0,0,0,0,false); + if (!_pWindow) + { + BS_LOG_ERRORLN("Failed to create the window."); + } + else + BS_LOGLN("Window created."); + + // Resource-Manager erstellen + _pResourceManager = new BS_ResourceManager(this); + + // Random-Number-Generator initialisieren + srand(GetMilliTicks()); + + // Die Skriptengine initialisieren + // Die Skriptengine muss bereits von Kernel und nicht vom Benutzer gestartet werden, damit der Kernel seine Funktionen bei seiner Erzeugung + // registrieren kann. + BS_ScriptEngine * pScript = static_cast<BS_ScriptEngine *>(NewService("script", "lua")); + if (!pScript || !pScript->Init()) + { + _InitSuccess = false; + return; + } + + // Scriptbindings des Kernels registrieren + if (!_RegisterScriptBindings()) + { + BS_LOG_ERRORLN("Script bindings could not be registered."); + _InitSuccess = false; + return; + } + BS_LOGLN("Script bindings registered."); + + _InitSuccess = true; +} + +BS_Kernel::~BS_Kernel() +{ + // Services in umgekehrter Reihenfolge der Erstellung endladen. + while (!_ServiceCreationOrder.empty()) + { + Superclass * superclass = GetSuperclassByIdentifier(_ServiceCreationOrder.top()); + if (superclass) superclass->DisconnectService(); + _ServiceCreationOrder.pop(); + } + + // Superclasslist leeren + while (_SuperclassList.size()) + { + delete _SuperclassList.back(); + _SuperclassList.pop_back(); + } + + // Fensterobjekt freigeben + delete _pWindow; + BS_LOGLN("Window destroyed."); + + // Resource-Manager freigeben + delete _pResourceManager; + + BS_LOGLN("destroyed."); +} + +// Service Methoden +// ---------------- +BS_Kernel::Superclass::Superclass (BS_Kernel* pKernel, const std::string& Identifier) : + _pKernel(pKernel), + _Identifier(Identifier), + _ServiceCount(0), + _ActiveService(NULL) +{ + for (unsigned int i = 0; i < BS_SERVICE_COUNT; i++) + if (BS_SERVICE_TABLE[i].SuperclassIdentifier == _Identifier) + _ServiceCount++; +} + +BS_Kernel::Superclass::~Superclass() +{ + DisconnectService(); +} + +std::string BS_Kernel::Superclass::GetServiceIdentifier(unsigned int Number) +{ + if (Number > _ServiceCount) return NULL; + + unsigned int CurServiceOrd = 0; + for (unsigned int i = 0; i < BS_SERVICE_COUNT; i++) + { + if (BS_SERVICE_TABLE[i].SuperclassIdentifier == _Identifier) + if (Number == CurServiceOrd) + return BS_SERVICE_TABLE[i].ServiceIdentifier; + else + CurServiceOrd++; + } + + return std::string(""); +} + +BS_Service* BS_Kernel::Superclass::NewService(const std::string& ServiceIdentifier) +{ + for (unsigned int i = 0; i < BS_SERVICE_COUNT; i++) + if (BS_SERVICE_TABLE[i].SuperclassIdentifier == _Identifier && + BS_SERVICE_TABLE[i].ServiceIdentifier == ServiceIdentifier) + { + BS_Service* NewService = BS_SERVICE_TABLE[i].CreateMethod(_pKernel); + + if (NewService) + { + DisconnectService(); + BS_LOGLN("Service '%s' created from superclass '%s'.", ServiceIdentifier.c_str(), _Identifier.c_str()); + _ActiveService = NewService; + _ActiveServiceName = BS_SERVICE_TABLE[i].ServiceIdentifier; + return _ActiveService; + } + else + { + BS_LOG_ERRORLN("Failed to create service '%s' from superclass '%s'.", ServiceIdentifier.c_str(), _Identifier.c_str()); + return NULL; + } + } + + BS_LOG_ERRORLN("Service '%s' is not avaliable from superclass '%s'.", ServiceIdentifier.c_str(), _Identifier.c_str()); + return NULL; +} + +bool BS_Kernel::Superclass::DisconnectService() +{ + if (_ActiveService) + { + delete _ActiveService; + _ActiveService = 0; + BS_LOGLN("Active service '%s' disconnected from superclass '%s'.", _ActiveServiceName.c_str(), _Identifier.c_str()); + return true; + } + + return false; +} + +BS_Kernel::Superclass* BS_Kernel::GetSuperclassByIdentifier(const std::string & Identifier) +{ + std::vector<Superclass*>::iterator Iter; + for (Iter = _SuperclassList.begin(); Iter != _SuperclassList.end(); ++Iter) + { + if ((*Iter)->GetIdentifier() == Identifier) + return *Iter; + } + + // BS_LOG_ERRORLN("Superclass '%s' does not exist.", Identifier.c_str()); + return NULL; +} + +unsigned int BS_Kernel::GetSuperclassCount() +{ + return _SuperclassList.size(); +} + +std::string BS_Kernel::GetSuperclassIdentifier(unsigned int Number) +{ + if (Number > _SuperclassList.size()) return NULL; + + unsigned int CurSuperclassOrd = 0; + std::vector<Superclass*>::iterator Iter; + for (Iter = _SuperclassList.begin(); Iter != _SuperclassList.end(); ++Iter) + { + if (CurSuperclassOrd == Number) + return ((*Iter)->GetIdentifier()); + + CurSuperclassOrd++; + } + + return std::string(""); +} + +unsigned int BS_Kernel::GetServiceCount(const std::string & SuperclassIdentifier) +{ + Superclass* pSuperclass; + if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return 0; + + return pSuperclass->GetServiceCount(); + +} + +std::string BS_Kernel::GetServiceIdentifier(const std::string & SuperclassIdentifier, unsigned int Number) +{ + Superclass* pSuperclass; + if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return NULL; + + return (pSuperclass->GetServiceIdentifier(Number)); +} + +BS_Service* BS_Kernel::NewService(const std::string& SuperclassIdentifier, const std::string& ServiceIdentifier) +{ + Superclass* pSuperclass; + if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return NULL; + + // Die Reihenfolge merken, in der Services erstellt werden, damit sie später in umgekehrter Reihenfolge entladen werden können. + _ServiceCreationOrder.push(SuperclassIdentifier); + + return pSuperclass->NewService(ServiceIdentifier); +} + +bool BS_Kernel::DisconnectService(const std::string& SuperclassIdentifier) +{ + Superclass* pSuperclass; + if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return false; + + return pSuperclass->DisconnectService(); +} + +BS_Service* BS_Kernel::GetService(const std::string& SuperclassIdentifier) +{ + Superclass* pSuperclass; + if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return NULL; + + return (pSuperclass->GetActiveService()); +} + +std::string BS_Kernel::GetActiveServiceIdentifier(const std::string& SuperclassIdentifier) +{ + Superclass * pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier); + if (!pSuperclass) return std::string(""); + + return (pSuperclass->GetActiveServiceName()); +} + +// ----------------------------------------------------------------------------- + +int BS_Kernel::GetRandomNumber(int Min, int Max) +{ + BS_ASSERT(Min <= Max); + unsigned int MaxInternal = (Min - Max + 1) < 0 ? - (Min - Max + 1) : (Min - Max + 1); + return (rand() % MaxInternal) + Min; +} + +// Timer Methoden +// -------------- +unsigned int BS_Kernel::GetMilliTicks() +{ + return BS_Timer::GetMilliTicks(); +} + +uint64_t BS_Kernel::GetMicroTicks() +{ + return BS_Timer::GetMicroTicks(); +} + +// Sonstige Methoden +// ----------------- + +size_t BS_Kernel::GetUsedMemory() +{ + PROCESS_MEMORY_COUNTERS pmc; + pmc.cb = sizeof(pmc); + if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) + { + return pmc.WorkingSetSize; + } + else + { + BS_LOG_ERRORLN("Call to GetProcessMemoryInfo() failed. Error code: %d", GetLastError()); + return 0; + } +} + +// ----------------------------------------------------------------------------- + +BS_GraphicEngine * BS_Kernel::GetGfx() +{ + return static_cast<BS_GraphicEngine *>(GetService("gfx")); +} + +// ----------------------------------------------------------------------------- + +BS_SoundEngine * BS_Kernel::GetSfx() +{ + return static_cast<BS_SoundEngine *>(GetService("sfx")); +} + +// ----------------------------------------------------------------------------- + +BS_InputEngine * BS_Kernel::GetInput() +{ + return static_cast<BS_InputEngine *>(GetService("input")); +} + +// ----------------------------------------------------------------------------- + +BS_PackageManager * BS_Kernel::GetPackage() +{ + return static_cast<BS_PackageManager *>(GetService("package")); +} + +// ----------------------------------------------------------------------------- + +BS_ScriptEngine * BS_Kernel::GetScript() +{ + return static_cast<BS_ScriptEngine *>(GetService("script")); +} + +// ----------------------------------------------------------------------------- + +BS_MoviePlayer * BS_Kernel::GetFMV() +{ + return static_cast<BS_MoviePlayer *>(GetService("fmv")); +} + +// ----------------------------------------------------------------------------- + +void BS_Kernel::Sleep(unsigned int Msecs) const +{ + ::Sleep(Msecs); +} |