1206 lines
34 KiB
C++
1206 lines
34 KiB
C++
/******************************************************************************
|
|
File : CustomPlayer.cpp
|
|
|
|
Description: This file contains the CCustomPlayer class which
|
|
is the "interface" with the Virtools SDK. All other files are Windows/MFC
|
|
specific code.
|
|
|
|
Virtools SDK
|
|
Copyright (c) Virtools 2005, All Rights Reserved.
|
|
******************************************************************************/
|
|
|
|
#include "CPStdAfx.h"
|
|
#include "CustomPlayer.h"
|
|
#include "CustomPlayerDefines.h"
|
|
|
|
#if defined(CUSTOM_PLAYER_STATIC)
|
|
// include file used for the static configuration
|
|
#include "CustomPlayerStaticLibs.h"
|
|
#include "CustomPlayerRegisterDlls.h"
|
|
#endif
|
|
|
|
extern CCustomPlayerApp theApp;
|
|
extern CCustomPlayer* thePlayer;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CCustomPlayer: PUBLIC STATIC METHODS
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CCustomPlayer&
|
|
CCustomPlayer::Instance()
|
|
{
|
|
if (thePlayer==0) {
|
|
thePlayer = new CCustomPlayer();
|
|
}
|
|
return *thePlayer;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CCustomPlayer: PUBLIC METHODS
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CCustomPlayer::~CCustomPlayer()
|
|
{
|
|
// here we stop/release/clear the Virtools Engine
|
|
|
|
try {
|
|
if (!m_CKContext) {
|
|
return;
|
|
}
|
|
|
|
// clear the CK context
|
|
m_CKContext->Reset();
|
|
m_CKContext->ClearAll();
|
|
|
|
// destroy the render engine
|
|
if (m_RenderManager && m_RenderContext) {
|
|
m_RenderManager->DestroyRenderContext(m_RenderContext);
|
|
}
|
|
m_RenderContext = NULL;
|
|
|
|
// close the ck context
|
|
CKCloseContext(m_CKContext);
|
|
|
|
m_CKContext = NULL;
|
|
|
|
// shutdown all
|
|
CKShutdown();
|
|
|
|
m_CKContext = NULL;
|
|
} catch(...) {
|
|
}
|
|
}
|
|
|
|
BOOL CCustomPlayer::ChangeResolution()
|
|
{
|
|
if (!m_RenderContext)
|
|
return FALSE;
|
|
|
|
if (m_RenderContext->IsFullScreen()) {
|
|
// we are in fullscreen mode
|
|
if (_GetFullScreenResolution()) {
|
|
// the resolution has changed
|
|
|
|
// pause the player
|
|
m_CKContext->Pause();
|
|
// and stop fullscreen
|
|
m_RenderContext->StopFullScreen();
|
|
|
|
// return to fullscreen with the new resolution
|
|
m_RenderContext->GoFullScreen(m_FullscreenWidth,m_FullscreenHeight,m_FullscreenBpp,m_Driver);
|
|
|
|
VxDriverDesc* Check_API_Desc = m_RenderManager->GetRenderDriverDescription(m_Driver);
|
|
//we have to resize the mainwin to allow correct picking (only in DX)
|
|
if (Check_API_Desc->Caps2D.Family==CKRST_DIRECTX && m_RenderContext->IsFullScreen()) {
|
|
//store current size
|
|
GetWindowRect(m_MainWindow,&m_MainWindowRect);
|
|
|
|
//Resize the window
|
|
::SetWindowPos(m_MainWindow,HWND_TOPMOST,0,0,m_FullscreenWidth,m_FullscreenHeight,NULL);
|
|
|
|
//Prevent the window from beeing resized
|
|
LONG st = GetWindowLong(m_MainWindow,GWL_STYLE);
|
|
st&=~WS_THICKFRAME;
|
|
st&=~WS_SIZEBOX;
|
|
SetWindowLong(m_MainWindow,GWL_STYLE,st);
|
|
}
|
|
// everything is ok to restart the player
|
|
m_CKContext->Play();
|
|
}
|
|
} else {
|
|
// we are in windowed mode
|
|
if (_GetWindowedResolution()) {
|
|
// the resolution has changed
|
|
|
|
//allow the window to be resized
|
|
LONG st = GetWindowLong(m_MainWindow,GWL_STYLE);
|
|
st|=WS_THICKFRAME;
|
|
st&=~WS_SIZEBOX;
|
|
SetWindowLong(m_MainWindow,GWL_STYLE,st);
|
|
|
|
//reposition the window
|
|
m_MainWindowRect.left = (GetSystemMetrics(SM_CXSCREEN)-m_WindowedWidth)/2;
|
|
m_MainWindowRect.right = m_WindowedWidth+m_MainWindowRect.left;
|
|
m_MainWindowRect.top = (GetSystemMetrics(SM_CYSCREEN)-m_WindowedHeight)/2;
|
|
m_MainWindowRect.bottom = m_WindowedHeight+m_MainWindowRect.top;
|
|
BOOL ret = AdjustWindowRect(&m_MainWindowRect,WS_OVERLAPPEDWINDOW & ~(WS_SYSMENU|WS_SIZEBOX|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX),FALSE);
|
|
::SetWindowPos(m_MainWindow,0,m_MainWindowRect.left,m_MainWindowRect.top,m_MainWindowRect.right - m_MainWindowRect.left,m_MainWindowRect.bottom - m_MainWindowRect.top,NULL);
|
|
|
|
// and set the position of the render window in the main window
|
|
::SetWindowPos(m_RenderWindow,NULL,0,0,m_WindowedWidth,m_WindowedHeight,SWP_NOMOVE|SWP_NOZORDER);
|
|
m_RenderContext->Resize(0,0,m_WindowedWidth,m_WindowedHeight);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CCustomPlayer::ClipMouse(BOOL iEnable)
|
|
{
|
|
// manage the mouse clipping
|
|
|
|
if(iEnable==FALSE) {
|
|
// disable the clipping
|
|
return ClipCursor(NULL);
|
|
}
|
|
|
|
if (!m_RenderContext) {
|
|
return FALSE;
|
|
}
|
|
|
|
// retrieve the render window rectangle
|
|
VxRect r;
|
|
m_RenderContext->GetWindowRect(r,TRUE);
|
|
|
|
RECT rect;
|
|
rect.top = (LONG)r.top;
|
|
rect.left = (LONG)r.left;
|
|
rect.bottom = (LONG)r.bottom;
|
|
rect.right = (LONG)r.right;
|
|
|
|
// to clip the mouse in it.
|
|
return ClipCursor(&rect);
|
|
}
|
|
|
|
BOOL CCustomPlayer::InitPlayer(HWND iMainWindow, HWND iRenderWindow, int iConfig, const void* iData,int iDataSize)
|
|
{
|
|
// keep a reference on the main/render window
|
|
m_MainWindow = iMainWindow;
|
|
m_RenderWindow = iRenderWindow;
|
|
|
|
// start the Virtools Engine
|
|
CKStartUp();
|
|
|
|
// retrieve the plugin manager ...
|
|
CKPluginManager* pluginManager = CKGetPluginManager();
|
|
|
|
// ... to intialize plugins ...
|
|
if (!_InitPlugins(*pluginManager)) {
|
|
MessageBox(NULL,UNABLE_TO_INIT_PLUGINS,INIT_ERROR,MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// ... and the render engine.
|
|
int renderEngine = _InitRenderEngines(*pluginManager);
|
|
if (renderEngine==-1) {
|
|
MessageBox(NULL,UNABLE_TO_LOAD_RENDERENGINE,INIT_ERROR,MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// now create the CK context
|
|
CKERROR res = CKCreateContext(&m_CKContext,m_MainWindow,0);
|
|
if (res!=CK_OK) {
|
|
MessageBox(NULL,UNABLE_TO_INIT_CK,INIT_ERROR,MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// retrieve the main managers which will be used by the player
|
|
m_MessageManager = m_CKContext->GetMessageManager();
|
|
m_RenderManager = m_CKContext->GetRenderManager();
|
|
m_TimeManager = m_CKContext->GetTimeManager();
|
|
m_AttributeManager = m_CKContext->GetAttributeManager();
|
|
m_InputManager = (CKInputManager*)m_CKContext->GetManagerByGuid(INPUT_MANAGER_GUID);
|
|
if (!m_MessageManager || !m_RenderManager || !m_TimeManager || !m_AttributeManager || !m_InputManager) {
|
|
MessageBox(NULL,UNABLE_TO_INIT_MANAGERS,INIT_ERROR,MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// initialize the display driver using the player configuration (resolution, rasterizer, ...)
|
|
if (!_InitDriver()) {
|
|
MessageBox(NULL,UNABLE_TO_INIT_DRIVER,INIT_ERROR,MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// create the render context
|
|
if (iConfig&eAutoFullscreen) {
|
|
// in fullscreen we specify the rendering size using a rectangle (CKRECT)
|
|
CKRECT rect;
|
|
rect.left = 0;
|
|
rect.top = 0;
|
|
rect.right = m_FullscreenWidth;
|
|
rect.bottom = m_FullscreenHeight;
|
|
|
|
// create the render context
|
|
m_RenderContext = m_RenderManager->CreateRenderContext(m_RenderWindow,m_Driver,&rect,TRUE,m_FullscreenBpp);
|
|
|
|
// set the position of the render window
|
|
::SetWindowPos(m_RenderWindow,NULL,0,0,m_FullscreenWidth,m_FullscreenHeight,SWP_NOMOVE|SWP_NOZORDER);
|
|
|
|
// resize the render context
|
|
if (m_RenderContext) {
|
|
m_RenderContext->Resize(0,0,m_FullscreenWidth,m_FullscreenHeight);
|
|
}
|
|
} else {
|
|
// set the position of the render window
|
|
::SetWindowPos(m_RenderWindow,NULL,0,0,m_WindowedWidth,m_WindowedHeight,SWP_NOMOVE|SWP_NOZORDER);
|
|
|
|
// create the render context
|
|
m_RenderContext = m_RenderManager->CreateRenderContext(m_RenderWindow,m_Driver,0,FALSE);
|
|
|
|
// resize the render context
|
|
if (m_RenderContext) {
|
|
m_RenderContext->Resize(0,0,m_WindowedWidth,m_WindowedHeight);
|
|
}
|
|
}
|
|
|
|
if (!m_RenderContext) {
|
|
MessageBox(NULL,UNABLE_TO_CREATE_RENDERCONTEXT,INIT_ERROR,MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// now load the compostion
|
|
if (iDataSize) { // if iDataSize is not null it means the composition is already in memory
|
|
if (_Load(iData,iDataSize)!=CK_OK) {
|
|
MessageBox(NULL,"Unable to load composition from memory.","Initialisation Error",MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
} else if (_Load((const char*)iData)!=CK_OK) { // else we load it from a file (iData contains the filename)
|
|
MessageBox(NULL,"Unable to load composition from file.","Initialisation Error",MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// cleare the render view
|
|
m_RenderContext->Clear();
|
|
m_RenderContext->BackToFront();
|
|
m_RenderContext->Clear();
|
|
|
|
// finialize the loading
|
|
if (!_FinishLoad()) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CCustomPlayer::OnActivateApp(BOOL iActivate)
|
|
{
|
|
// if
|
|
// - the application is being activated (iActivate == TRUE)
|
|
// - the render context is in fullscreen
|
|
// - and the player is not already switching fullscreen (m_EatDisplayChange == FALSE)
|
|
if (iActivate==TRUE && m_RenderContext && m_RenderContext->IsFullScreen() && !m_EatDisplayChange) {
|
|
// we switch fullscreen because the application is deactivated
|
|
//SwitchFullscreen();
|
|
_FullScreen();
|
|
}
|
|
}
|
|
|
|
void CCustomPlayer::OnFocusChange(BOOL iFocus)
|
|
{
|
|
// here we manage the focus change
|
|
|
|
if (!m_CKContext) {
|
|
return;
|
|
}
|
|
|
|
///////////////////////
|
|
// First, check minimize/restore
|
|
///////////////////////
|
|
|
|
if ( (m_State==ePlaying) && IsIconic(m_MainWindow) ) { // we must pause process
|
|
// the application is minimized
|
|
m_State = eMinimized;
|
|
// so we pause the player
|
|
m_CKContext->Pause();
|
|
return;
|
|
}
|
|
|
|
if ( (m_State==eMinimized) && !IsIconic(m_MainWindow) ) { // we must restart process
|
|
// the application is no longer minimized
|
|
m_State = ePlaying;
|
|
// so we restart the player
|
|
m_CKContext->Play();
|
|
return;
|
|
}
|
|
|
|
///////////////////////
|
|
// then check focus lost behavior
|
|
///////////////////////
|
|
|
|
CKDWORD pauseMode = m_CKContext->GetFocusLostBehavior();
|
|
|
|
if(m_State==ePlaying || m_State==eFocusLost) {
|
|
switch (pauseMode)
|
|
{
|
|
// if the composition is configured to pause
|
|
// the input manager when the focus is lost
|
|
// note: for a stand alone player
|
|
// CK_FOCUSLOST_PAUSEINPUT_MAIN and CK_FOCUSLOST_PAUSEINPUT_PLAYER
|
|
// is the same thing. there is a difference only for the webplayer
|
|
case CK_FOCUSLOST_PAUSEINPUT_MAIN:
|
|
case CK_FOCUSLOST_PAUSEINPUT_PLAYER:
|
|
case CK_FOCUSLOST_PAUSEINPUT_WHENOUT:
|
|
// we pause/unpause it depending on the focus
|
|
m_InputManager->Pause(!iFocus);
|
|
break;
|
|
|
|
// if the composition is configured to pause
|
|
// the player (pause all) when the focus is lost
|
|
case CK_FOCUSLOST_PAUSEALL:
|
|
if (!iFocus) {
|
|
// focus lost
|
|
m_State = eFocusLost;
|
|
// pause the player
|
|
m_CKContext->Pause();
|
|
} else {
|
|
// else
|
|
m_State = ePlaying;
|
|
// play
|
|
m_CKContext->Play();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CCustomPlayer::OnMouseClick(int iMessage)
|
|
{
|
|
// here we manage the mouse click
|
|
|
|
if (!m_RenderContext) {
|
|
return;
|
|
}
|
|
|
|
// retrieve the cursor position
|
|
POINT pt;
|
|
GetCursorPos(&pt);
|
|
ScreenToClient(m_RenderWindow,&pt);
|
|
|
|
// convert the windows message to the virtools message
|
|
int msg = (iMessage==WM_LBUTTONDOWN)?m_MsgClick:m_MsgDoubleClick;
|
|
|
|
// retrieve information about object "under" the mouse
|
|
VxIntersectionDesc desc;
|
|
CKObject* obj = m_RenderContext->Pick(pt.x,pt.y,&desc);
|
|
if(obj && CKIsChildClassOf(obj,CKCID_BEOBJECT)) {
|
|
// send a message to the beobject
|
|
m_MessageManager->SendMessageSingle(msg,(CKBeObject*)obj);
|
|
}
|
|
|
|
if (desc.Sprite) {
|
|
// send a message to the sprite
|
|
m_MessageManager->SendMessageSingle(msg,(CKBeObject *)desc.Sprite);
|
|
}
|
|
}
|
|
|
|
void CCustomPlayer::OnPaint()
|
|
{
|
|
if (!m_RenderContext || m_RenderContext->IsFullScreen()) {
|
|
return;
|
|
}
|
|
// in windowed mode call render when WM_PAINT
|
|
m_RenderContext->Render();
|
|
}
|
|
|
|
LRESULT CCustomPlayer::OnSysKeyDownMainWindow(int iConfig, int iKey)
|
|
{
|
|
// Manage system key (ALT + KEY)
|
|
// system keys can be disable using eDisableKeys
|
|
|
|
switch(iKey)
|
|
{
|
|
case VK_RETURN:
|
|
if (!(iConfig&eDisableKeys)) {
|
|
// ALT + ENTER -> SwitchFullscreen
|
|
SwitchFullscreen();
|
|
}
|
|
break;
|
|
|
|
case VK_F4:
|
|
if (!(iConfig&eDisableKeys)) {
|
|
// ALT + F4 -> Quit the application
|
|
PostQuitMessage(0);
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void CCustomPlayer::Pause()
|
|
{
|
|
// mark the play as paused
|
|
m_State = ePlaused;
|
|
// pause
|
|
m_CKContext->Pause();
|
|
}
|
|
|
|
void CCustomPlayer::Play()
|
|
{
|
|
// mark the player as playing
|
|
m_State = ePlaying;
|
|
// play
|
|
m_CKContext->Play();
|
|
}
|
|
|
|
BOOL
|
|
CCustomPlayer::Process(int iConfig)
|
|
{
|
|
// just to be sure we check the player is ready and playing
|
|
if (!m_CKContext || !m_CKContext->IsPlaying()) {
|
|
Sleep(10);
|
|
return TRUE;
|
|
}
|
|
|
|
float beforeRender = 0;
|
|
float beforeProcess = 0;
|
|
// retrieve the time to wait in milliseconds to perfom a rendering or a process loop
|
|
// so that the time manager limits are respected.
|
|
m_TimeManager->GetTimeToWaitForLimits(beforeRender,beforeProcess);
|
|
|
|
if (beforeProcess<=0) {
|
|
// ok to process
|
|
m_TimeManager->ResetChronos(FALSE,TRUE);
|
|
m_CKContext->Process();
|
|
}
|
|
|
|
if (beforeRender<=0) {
|
|
// ok to render
|
|
m_TimeManager->ResetChronos(TRUE,FALSE);
|
|
m_RenderContext->Render();
|
|
}
|
|
|
|
// now we check if the composition has not change the state of a "control" attribute
|
|
|
|
// quit has been set
|
|
if (m_Level->HasAttribute(m_QuitAttType)) {
|
|
// we remove it (so it is not "here" the next frame)
|
|
m_Level->RemoveAttribute(m_QuitAttType);
|
|
// and return FALSE to quit
|
|
return FALSE;
|
|
}
|
|
|
|
// switch fullscreen has been set
|
|
if (m_Level->HasAttribute(m_SwitchFullscreenAttType)) {
|
|
// we remove it (so it is not "here" the next frame)
|
|
m_Level->RemoveAttribute(m_SwitchFullscreenAttType);
|
|
// and switch fullscreen (ie goes from fullscreen to windowed
|
|
// or to windowed from fullscreen)
|
|
SwitchFullscreen();
|
|
}
|
|
|
|
// switch resolution has been set
|
|
if (m_Level->HasAttribute(m_SwitchResolutionAttType)) {
|
|
// we remove it (so it is not "here" the next frame)
|
|
m_Level->RemoveAttribute(m_SwitchResolutionAttType);
|
|
// and we change the resolution
|
|
ChangeResolution();
|
|
}
|
|
|
|
// switch resolution has been set
|
|
if (m_Level->HasAttribute(m_SwitchMouseClippingAttType)) {
|
|
// we remove it (so it is not "here" the next frame)
|
|
m_Level->RemoveAttribute(m_SwitchMouseClippingAttType);
|
|
m_MouseClipped = !m_MouseClipped;
|
|
ClipMouse(m_MouseClipped);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
CCustomPlayer::Reset()
|
|
{
|
|
// mark the player as playing
|
|
m_State = ePlaying;
|
|
// reset
|
|
m_CKContext->Reset();
|
|
// and play
|
|
m_CKContext->Play();
|
|
}
|
|
|
|
BOOL
|
|
CCustomPlayer::SwitchFullscreen()
|
|
{
|
|
if (!m_RenderContext || !m_FullscreenEnabled) {
|
|
return FALSE;
|
|
}
|
|
|
|
// mark eat display change to true
|
|
// so we cannot switch the display during this function.
|
|
m_EatDisplayChange = TRUE;
|
|
|
|
if (m_RenderContext->IsFullScreen()) {
|
|
// siwtch to windowed mode
|
|
_Windowed();
|
|
|
|
/*// retrieve the windowed resolution from the attributes
|
|
_GetWindowedResolution();
|
|
// we pause the player
|
|
m_CKContext->Pause();
|
|
// stop the fullscreen
|
|
m_RenderContext->StopFullScreen();
|
|
|
|
//restore the main window size (only in DirectX rasterizer->m_MainWindowRect.bottom not modified)
|
|
if (m_MainWindowRect.bottom!=0 && !m_RenderContext->IsFullScreen()) {
|
|
//allow the window to be resized
|
|
LONG st = GetWindowLong(m_MainWindow,GWL_STYLE);
|
|
st|=WS_THICKFRAME;
|
|
st&=~WS_SIZEBOX;
|
|
SetWindowLong(m_MainWindow,GWL_STYLE,st);
|
|
}
|
|
|
|
//reposition the window
|
|
m_MainWindowRect.left = (GetSystemMetrics(SM_CXSCREEN)-m_WindowedWidth)/2;
|
|
m_MainWindowRect.right = m_WindowedWidth+m_MainWindowRect.left;
|
|
m_MainWindowRect.top = (GetSystemMetrics(SM_CYSCREEN)-m_WindowedHeight)/2;
|
|
m_MainWindowRect.bottom = m_WindowedHeight+m_MainWindowRect.top;
|
|
BOOL ret = AdjustWindowRect(&m_MainWindowRect,WS_OVERLAPPEDWINDOW & ~(WS_SYSMENU|WS_SIZEBOX|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX),FALSE);
|
|
::SetWindowPos(m_MainWindow,HWND_NOTOPMOST,m_MainWindowRect.left,m_MainWindowRect.top,m_MainWindowRect.right - m_MainWindowRect.left,m_MainWindowRect.bottom - m_MainWindowRect.top,NULL);
|
|
|
|
// now we can show the main widnwos
|
|
ShowWindow(m_MainWindow,SW_SHOW);
|
|
SetFocus(m_MainWindow);
|
|
|
|
// and set the position of the render window in the main window
|
|
::SetWindowPos(m_RenderWindow,NULL,0,0,m_WindowedWidth,m_WindowedHeight,SWP_NOMOVE|SWP_NOZORDER);
|
|
|
|
// and give the focus to the render window
|
|
SetFocus(m_RenderWindow);
|
|
|
|
// everything is ok to restart the player
|
|
m_CKContext->Play();*/
|
|
} else {
|
|
// switch to fullscreen mode
|
|
_FullScreen();
|
|
|
|
/*// retrieve the fullscreen resolution from the attributes
|
|
_GetFullScreenResolution();
|
|
// we pause the player
|
|
m_CKContext->Pause();
|
|
// and go fullscreen
|
|
m_RenderContext->GoFullScreen(m_FullscreenWidth,m_FullscreenHeight,m_FullscreenBpp,m_Driver);
|
|
|
|
// everything is ok to restart the player
|
|
m_CKContext->Play();
|
|
|
|
VxDriverDesc* Check_API_Desc = m_RenderManager->GetRenderDriverDescription(m_Driver);
|
|
//we have to resize the mainwin to allow correct picking (only in DX)
|
|
if (Check_API_Desc->Caps2D.Family==CKRST_DIRECTX && m_RenderContext->IsFullScreen()) {
|
|
//store current size
|
|
GetWindowRect(m_MainWindow,&m_MainWindowRect);
|
|
|
|
//Resize the window
|
|
::SetWindowPos(m_MainWindow,HWND_TOPMOST,0,0,m_FullscreenWidth,m_FullscreenHeight,NULL);
|
|
|
|
//Prevent the window from beeing resized
|
|
LONG st = GetWindowLong(m_MainWindow,GWL_STYLE);
|
|
st&=~WS_THICKFRAME;
|
|
st&=~WS_SIZEBOX;
|
|
SetWindowLong(m_MainWindow,GWL_STYLE,st);
|
|
}*/
|
|
}
|
|
|
|
// mark eat display change to false
|
|
// as we have finished
|
|
m_EatDisplayChange = FALSE;
|
|
|
|
ClipMouse(m_MouseClipped);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PRIVATE
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
CCustomPlayer::CCustomPlayer()
|
|
: m_State(eInitial), m_MainWindow(0),m_RenderWindow(0),
|
|
m_CKContext(0),m_RenderContext(0),
|
|
m_MessageManager(0),m_RenderManager(0),m_TimeManager(0),
|
|
m_AttributeManager(0),m_InputManager(0),
|
|
m_Level(0),m_QuitAttType(-1),m_SwitchResolutionAttType(-1),m_SwitchMouseClippingAttType(-1),
|
|
m_WindowedResolutionAttType(-1),m_FullscreenResolutionAttType(-1),m_FullscreenBppAttType(-1),
|
|
m_MsgClick(0),m_MsgDoubleClick(0),
|
|
m_RasterizerFamily(CKRST_DIRECTX),m_RasterizerFlags(CKRST_SPECIFICCAPS_HARDWARE|CKRST_SPECIFICCAPS_DX9),
|
|
m_WindowedWidth(640),m_WindowedHeight(480),
|
|
m_MinWindowedWidth(400),m_MinWindowedHeight(300),
|
|
m_FullscreenWidth(640),m_FullscreenHeight(480),m_FullscreenBpp(32),
|
|
m_Driver(-1),m_FullscreenEnabled(FALSE),
|
|
m_EatDisplayChange(FALSE),m_MouseClipped(FALSE)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
BOOL CCustomPlayer::_CheckDriver(VxDriverDesc* iDesc, int iFlags)
|
|
{
|
|
// check the rasterizer family
|
|
if (iFlags & eFamily) {
|
|
if (iDesc->Caps2D.Family!=m_RasterizerFamily) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// test directx version
|
|
if ( (iDesc->Caps2D.Family==CKRST_DIRECTX) && (iFlags & eDirectXVersion) ) {
|
|
if ((iDesc->Caps3D.CKRasterizerSpecificCaps&0x00000f00UL)!=(m_RasterizerFlags&0x00000f00UL)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// test hardware/software
|
|
if (iFlags & eSoftware) {
|
|
if (((int)iDesc->Caps3D.CKRasterizerSpecificCaps&CKRST_SPECIFICCAPS_SOFTWARE)!=(m_RasterizerFlags&CKRST_SPECIFICCAPS_SOFTWARE)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CCustomPlayer::_CheckFullscreenDisplayMode(BOOL iDoBest)
|
|
{
|
|
VxDriverDesc* desc = m_RenderManager->GetRenderDriverDescription(m_Driver);
|
|
|
|
// try to find the correct fullscreen display mode
|
|
for (VxDisplayMode* displayMode=desc->DisplayModes.Begin();displayMode!=desc->DisplayModes.End();displayMode++) {
|
|
if (displayMode->Width==m_FullscreenWidth &&
|
|
displayMode->Height==m_FullscreenHeight &&
|
|
displayMode->Bpp==m_FullscreenBpp) {
|
|
m_FullscreenEnabled = TRUE;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (!iDoBest) {
|
|
return FALSE;
|
|
}
|
|
|
|
// we did not find a display mode
|
|
// try 640x480x32
|
|
m_FullscreenWidth = 640;
|
|
m_FullscreenHeight = 480;
|
|
m_FullscreenBpp = 32;
|
|
|
|
for (VxDisplayMode* displayMode=desc->DisplayModes.Begin();displayMode!=desc->DisplayModes.End();displayMode++) {
|
|
if (displayMode->Width==m_FullscreenWidth &&
|
|
displayMode->Height==m_FullscreenHeight &&
|
|
displayMode->Bpp==m_FullscreenBpp) {
|
|
m_FullscreenEnabled = TRUE;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// we did not find a display mode
|
|
// try 640x480x16
|
|
m_FullscreenBpp = 16;
|
|
|
|
for (VxDisplayMode* displayMode=desc->DisplayModes.Begin();displayMode!=desc->DisplayModes.End();displayMode++) {
|
|
if (displayMode->Width==m_FullscreenWidth &&
|
|
displayMode->Height==m_FullscreenHeight &&
|
|
displayMode->Bpp==m_FullscreenBpp) {
|
|
m_FullscreenEnabled = TRUE;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
m_FullscreenEnabled = FALSE;
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CCustomPlayer::_FinishLoad()
|
|
{
|
|
// retrieve the level
|
|
m_Level = m_CKContext->GetCurrentLevel();
|
|
if (!m_Level) {
|
|
MessageBox(NULL,CANNOT_FIND_LEVEL,INIT_ERROR,MB_OK|MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
// Add the render context to the level
|
|
m_Level->AddRenderContext(m_RenderContext,TRUE);
|
|
|
|
// Take the first camera we found and attach the viewpoint to it.
|
|
// (in case it is not set by the composition later)
|
|
const XObjectPointerArray cams = m_CKContext->GetObjectListByType(CKCID_CAMERA,TRUE);
|
|
if(cams.Size()) {
|
|
m_RenderContext->AttachViewpointToCamera((CKCamera*)cams[0]);
|
|
}
|
|
|
|
// Hide curves ?
|
|
int curveCount = m_CKContext->GetObjectsCountByClassID(CKCID_CURVE);
|
|
CK_ID* curve_ids = m_CKContext->GetObjectsListByClassID(CKCID_CURVE);
|
|
for (int i=0;i<curveCount;++i) {
|
|
CKMesh* mesh = ((CKCurve*)m_CKContext->GetObject(curve_ids[i]))->GetCurrentMesh();
|
|
if(mesh)
|
|
mesh->Show(CKHIDE);
|
|
}
|
|
|
|
// retrieve custom player attributes
|
|
// from an exemple about using this attributes see sample.cmo which is delivered with this player sample
|
|
// simply set the "Quit" attribute to quit the application
|
|
m_QuitAttType = m_AttributeManager->GetAttributeTypeByName("Quit");
|
|
// simply set the "Switch Fullscreen" attribute to make the player switch between fullscreen and windowed mode
|
|
m_SwitchFullscreenAttType = m_AttributeManager->GetAttributeTypeByName("Switch Fullscreen");
|
|
// simply set the "Switch Resolution" attribute to make the player change its resolution according
|
|
// to the "Windowed Resolution" or "Fullscreen Resolution" (depending on the current mode)
|
|
m_SwitchResolutionAttType = m_AttributeManager->GetAttributeTypeByName("Switch Resolution");
|
|
// simply set the "Switch Mouse Clipping" attribute to make the player clip/unclip the mouse to the render window
|
|
m_SwitchMouseClippingAttType = m_AttributeManager->GetAttributeTypeByName("Switch Mouse Clipping");
|
|
// the windowed resolution
|
|
m_WindowedResolutionAttType = m_AttributeManager->GetAttributeTypeByName("Windowed Resolution");
|
|
// the fullscreen resolution
|
|
m_FullscreenResolutionAttType = m_AttributeManager->GetAttributeTypeByName("Fullscreen Resolution");
|
|
// the fullscreen bpp
|
|
m_FullscreenBppAttType = m_AttributeManager->GetAttributeTypeByName("Fullscreen Bpp");
|
|
|
|
// remove attributes (quit,switch fullscreen and switch resolution) if present
|
|
if (m_Level->HasAttribute(m_QuitAttType)) {
|
|
m_Level->RemoveAttribute(m_QuitAttType);
|
|
}
|
|
if (m_Level->HasAttribute(m_SwitchFullscreenAttType)) {
|
|
m_Level->RemoveAttribute(m_SwitchFullscreenAttType);
|
|
}
|
|
if (m_Level->HasAttribute(m_SwitchResolutionAttType)) {
|
|
m_Level->RemoveAttribute(m_SwitchResolutionAttType);
|
|
}
|
|
if (m_Level->HasAttribute(m_SwitchMouseClippingAttType)) {
|
|
m_Level->RemoveAttribute(m_SwitchMouseClippingAttType);
|
|
}
|
|
|
|
// set the attributes so it match the current player configuration
|
|
_SetResolutions();
|
|
|
|
// set a fake last cmo loaded
|
|
// we build a filename using the exe full filename
|
|
// remplacing exe by vmo.
|
|
{
|
|
char path[MAX_PATH];
|
|
if (::GetModuleFileName(0,path,MAX_PATH)) {
|
|
char drive[MAX_PATH];
|
|
char dir[MAX_PATH];
|
|
char filename[MAX_PATH];
|
|
char ext[MAX_PATH];
|
|
_splitpath(path,drive,dir,filename,ext);
|
|
_makepath(path,drive,dir,filename,"vmo");
|
|
m_CKContext->SetLastCmoLoaded(path);
|
|
|
|
}
|
|
}
|
|
|
|
// we launch the default scene
|
|
m_Level->LaunchScene(NULL);
|
|
|
|
// ReRegister OnClick Message in case it changed
|
|
m_MsgClick = m_MessageManager->AddMessageType("OnClick");
|
|
m_MsgDoubleClick = m_MessageManager->AddMessageType("OnDblClick");
|
|
|
|
// render the first frame
|
|
m_RenderContext->Render();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CCustomPlayer::_GetFullScreenResolution()
|
|
{
|
|
// retrieve the fullscreen resolution from attribute
|
|
|
|
// retrieve the attribute (resolution width and height)
|
|
CKParameterOut* paramRes = m_Level->GetAttributeParameter(m_FullscreenResolutionAttType);
|
|
if (!paramRes) {
|
|
return FALSE;
|
|
}
|
|
|
|
// save old values
|
|
int oldWidth = m_FullscreenWidth;
|
|
int oldHeight = m_FullscreenHeight;
|
|
int oldBpp = m_FullscreenBpp;
|
|
|
|
// retrieve the attribute (bpp)
|
|
CKParameterOut* paramBpp = m_Level->GetAttributeParameter(m_FullscreenBppAttType);
|
|
if (paramBpp) {
|
|
paramBpp->GetValue(&m_FullscreenBpp);
|
|
}
|
|
|
|
Vx2DVector res(m_FullscreenWidth,m_FullscreenHeight);
|
|
paramRes->GetValue(&res);
|
|
m_FullscreenWidth = (int)res.x;
|
|
m_FullscreenHeight = (int)res.y;
|
|
|
|
// check the resolution is compatible with the fullscreen mode
|
|
if (!_CheckFullscreenDisplayMode(FALSE)) {
|
|
// else ...
|
|
m_FullscreenWidth = oldWidth;
|
|
m_FullscreenHeight = oldHeight;
|
|
m_FullscreenBpp = oldBpp;
|
|
// ... reset attributes with old values
|
|
_SetResolutions();
|
|
}
|
|
|
|
// returns TRUE if at least one value has changed
|
|
return (m_FullscreenWidth!=oldWidth || m_FullscreenHeight!=oldHeight || m_FullscreenBpp!=oldBpp);
|
|
}
|
|
|
|
BOOL CCustomPlayer::_GetWindowedResolution()
|
|
{
|
|
// retrieve the windowed resolution from attribute
|
|
|
|
// retrieve the attribute (resolution width and height)
|
|
CKParameterOut* pout = m_Level->GetAttributeParameter(m_WindowedResolutionAttType);
|
|
if (!pout) {
|
|
return FALSE;
|
|
}
|
|
|
|
// save old values
|
|
int oldWidth = m_WindowedWidth;
|
|
int oldHeight = m_WindowedHeight;
|
|
|
|
Vx2DVector res(m_WindowedWidth,m_WindowedHeight);
|
|
pout->GetValue(&res);
|
|
m_WindowedWidth = (int)res.x;
|
|
m_WindowedHeight = (int)res.y;
|
|
|
|
// returns TRUE if at least one value has changed
|
|
return (m_WindowedWidth!=oldWidth || m_WindowedHeight!=oldHeight);
|
|
}
|
|
|
|
BOOL CCustomPlayer::_Windowed()
|
|
{
|
|
// retrieve the windowed resolution from the attributes
|
|
_GetWindowedResolution();
|
|
// we pause the player
|
|
m_CKContext->Pause();
|
|
// stop the fullscreen
|
|
m_RenderContext->StopFullScreen();
|
|
|
|
m_RenderContext->Resize(0,0,m_WindowedWidth,m_WindowedHeight);
|
|
|
|
//restore the main window size (only in DirectX rasterizer->m_MainWindowRect.bottom not modified)
|
|
if (m_MainWindowRect.bottom!=0 && !m_RenderContext->IsFullScreen()) {
|
|
//allow the window to be resized
|
|
LONG st = GetWindowLong(m_MainWindow,GWL_STYLE);
|
|
st|=WS_THICKFRAME;
|
|
st&=~WS_SIZEBOX;
|
|
SetWindowLong(m_MainWindow,GWL_STYLE,st);
|
|
}
|
|
|
|
//reposition the window
|
|
m_MainWindowRect.left = (GetSystemMetrics(SM_CXSCREEN)-m_WindowedWidth)/2;
|
|
m_MainWindowRect.right = m_WindowedWidth+m_MainWindowRect.left;
|
|
m_MainWindowRect.top = (GetSystemMetrics(SM_CYSCREEN)-m_WindowedHeight)/2;
|
|
m_MainWindowRect.bottom = m_WindowedHeight+m_MainWindowRect.top;
|
|
BOOL ret = AdjustWindowRect(&m_MainWindowRect,WS_OVERLAPPEDWINDOW & ~(WS_SYSMENU|WS_SIZEBOX|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX),FALSE);
|
|
::SetWindowPos(m_MainWindow,HWND_NOTOPMOST,m_MainWindowRect.left,m_MainWindowRect.top,m_MainWindowRect.right - m_MainWindowRect.left,m_MainWindowRect.bottom - m_MainWindowRect.top,NULL);
|
|
|
|
// now we can show the main widnwos
|
|
ShowWindow(m_MainWindow,SW_SHOW);
|
|
SetFocus(m_MainWindow);
|
|
|
|
// and set the position of the render window in the main window
|
|
::SetWindowPos(m_RenderWindow,NULL,0,0,m_WindowedWidth,m_WindowedHeight,SWP_NOMOVE|SWP_NOZORDER);
|
|
|
|
// and give the focus to the render window
|
|
SetFocus(m_RenderWindow);
|
|
|
|
// everything is ok to restart the player
|
|
m_CKContext->Play();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CCustomPlayer::_FullScreen()
|
|
{
|
|
// retrieve the fullscreen resolution from the attributes
|
|
_GetFullScreenResolution();
|
|
// we pause the player
|
|
m_CKContext->Pause();
|
|
// and go fullscreen
|
|
|
|
ShowWindow(m_MainWindow,SW_HIDE);
|
|
//ShowWindow(m_RenderWindow,SW_SHOW);
|
|
|
|
m_RenderContext->StopFullScreen();
|
|
m_RenderContext->GoFullScreen(m_FullscreenWidth,m_FullscreenHeight,m_FullscreenBpp,m_Driver);
|
|
|
|
// everything is ok to restart the player
|
|
m_CKContext->Play();
|
|
|
|
VxDriverDesc* Check_API_Desc = m_RenderManager->GetRenderDriverDescription(m_Driver);
|
|
//we have to resize the mainwin to allow correct picking (only in DX)
|
|
if (Check_API_Desc->Caps2D.Family==CKRST_DIRECTX && m_RenderContext->IsFullScreen()) {
|
|
//store current size
|
|
GetWindowRect(m_MainWindow,&m_MainWindowRect);
|
|
|
|
//Resize the window
|
|
::SetWindowPos(m_MainWindow,HWND_TOPMOST,0,0,m_FullscreenWidth,m_FullscreenHeight,NULL);
|
|
|
|
//Prevent the window from beeing resized
|
|
LONG st = GetWindowLong(m_MainWindow,GWL_STYLE);
|
|
st&=~WS_THICKFRAME;
|
|
st&=~WS_SIZEBOX;
|
|
SetWindowLong(m_MainWindow,GWL_STYLE,st);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CCustomPlayer::_InitDriver()
|
|
{
|
|
int count = m_RenderManager->GetRenderDriverCount();
|
|
int i = 0;
|
|
|
|
// first, we try to get exactly what is required
|
|
int checkFlags = eFamily | eDirectXVersion | eSoftware;
|
|
for (i=0;i<count;++i) {
|
|
VxDriverDesc* desc = m_RenderManager->GetRenderDriverDescription(i);
|
|
if (!desc) {
|
|
continue;
|
|
}
|
|
|
|
if (_CheckDriver(desc,checkFlags)) {
|
|
m_Driver = i;
|
|
_CheckFullscreenDisplayMode(TRUE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (m_RasterizerFamily == CKRST_OPENGL) {
|
|
return FALSE;
|
|
}
|
|
|
|
// if we did not find a driver,
|
|
// we only check family and software flags
|
|
checkFlags &= ~eDirectXVersion;
|
|
for (i=0;i<count;++i) {
|
|
VxDriverDesc* desc = m_RenderManager->GetRenderDriverDescription(i);
|
|
if (!desc) {
|
|
continue;
|
|
}
|
|
|
|
if (_CheckDriver(desc,checkFlags)) {
|
|
m_Driver = i;
|
|
_CheckFullscreenDisplayMode(TRUE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CCustomPlayer::_InitPlugins(CKPluginManager& iPluginManager)
|
|
{
|
|
#if !defined(CUSTOM_PLAYER_STATIC)
|
|
// if the player is not static
|
|
|
|
char szPath[_MAX_PATH];
|
|
char PluginPath[_MAX_PATH];
|
|
char RenderPath[_MAX_PATH];
|
|
char BehaviorPath[_MAX_PATH];
|
|
char ManagerPath[_MAX_PATH];
|
|
|
|
VxGetModuleFileName(NULL,szPath,_MAX_PATH);
|
|
CKPathSplitter ps(szPath);
|
|
sprintf(PluginPath,"%s%s%s",ps.GetDrive(),ps.GetDir(),"Plugins");
|
|
sprintf(RenderPath,"%s%s%s",ps.GetDrive(),ps.GetDir(),"RenderEngines");
|
|
sprintf(ManagerPath,"%s%s%s",ps.GetDrive(),ps.GetDir(),"Managers");
|
|
sprintf(BehaviorPath,"%s%s%s",ps.GetDrive(),ps.GetDir(),"BuildingBlocks");
|
|
|
|
// we initialize plugins by parsing directories
|
|
iPluginManager.ParsePlugins(RenderPath);
|
|
iPluginManager.ParsePlugins(ManagerPath);
|
|
iPluginManager.ParsePlugins(BehaviorPath);
|
|
iPluginManager.ParsePlugins(PluginPath);
|
|
#else
|
|
// else if the player is static
|
|
// we initialize plugins by manually register them
|
|
// for an exemple look at CustomPlayerRegisterDlls.h
|
|
CustomPlayerRegisterRenderEngine(iPluginManager);
|
|
CustomPlayerRegisterReaders(iPluginManager);
|
|
CustomPlayerRegisterManagers(iPluginManager);
|
|
CustomPlayerRegisterBehaviors(iPluginManager);
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CCustomPlayer::_InitRenderEngines(CKPluginManager& iPluginManager)
|
|
{
|
|
// here we look for the render engine (ck2_3d)
|
|
int count = iPluginManager.GetPluginCount(CKPLUGIN_RENDERENGINE_DLL);
|
|
for (int i=0;i<count;i++) {
|
|
CKPluginEntry* desc = iPluginManager.GetPluginInfo(CKPLUGIN_RENDERENGINE_DLL,i);
|
|
CKPluginDll* dll = iPluginManager.GetPluginDllInfo(desc->m_PluginDllIndex);
|
|
#if !defined(CUSTOM_PLAYER_STATIC)
|
|
XDWORD pos = dll->m_DllFileName.RFind(DIRECTORY_SEP_CHAR);
|
|
if (pos==XString::NOTFOUND)
|
|
continue;
|
|
XString str = dll->m_DllFileName.Substring(pos+1);
|
|
if (strnicmp(str.CStr(),"ck2_3d",strlen("ck2_3d"))==0)
|
|
return i;
|
|
#else
|
|
if (dll->m_DllFileName.ICompare("ck2_3d")==0)
|
|
return i;
|
|
#endif
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
CKERROR CCustomPlayer::_Load(const char* str)
|
|
{
|
|
// the composition from a file
|
|
|
|
// validate the filename
|
|
if(!str || !(*str) || strlen(str)<=0) {
|
|
return FALSE;
|
|
}
|
|
|
|
// here we decompose the loading from a file to manage the missing guids case
|
|
|
|
// create a ckfile
|
|
CKFile *f = m_CKContext->CreateCKFile();
|
|
XString resolvedfile = str;
|
|
// resolve the filename using the pathmanager
|
|
{
|
|
CKPathManager *pm = m_CKContext->GetPathManager();
|
|
if(pm) {
|
|
pm->ResolveFileName(resolvedfile,0);
|
|
}
|
|
}
|
|
|
|
// open the file
|
|
DWORD res = CKERR_INVALIDFILE;
|
|
res = f->OpenFile(resolvedfile.Str(),(CK_LOAD_FLAGS) (CK_LOAD_DEFAULT | CK_LOAD_CHECKDEPENDENCIES));
|
|
if (res!=CK_OK) {
|
|
// something failed
|
|
if (res==CKERR_PLUGINSMISSING) {
|
|
// log the missing guids
|
|
_MissingGuids(f,resolvedfile.CStr());
|
|
}
|
|
//m_CKContext->DeleteCKFile(f);
|
|
//return res;
|
|
}
|
|
|
|
CKPathSplitter ps(resolvedfile.Str());
|
|
CKPathMaker mp(ps.GetDrive(),ps.GetDir(),NULL,NULL);
|
|
if(strcmp(mp.GetFileName(),CKGetStartPath())){
|
|
CKPathManager *pm = m_CKContext->GetPathManager();
|
|
XString XStr = XString(mp.GetFileName());
|
|
pm->AddPath(BITMAP_PATH_IDX,XStr);
|
|
XStr = XString(mp.GetFileName());
|
|
pm->AddPath(DATA_PATH_IDX,XStr);
|
|
XStr = XString(mp.GetFileName());
|
|
pm->AddPath(SOUND_PATH_IDX,XStr);
|
|
}
|
|
|
|
CKObjectArray *array = CreateCKObjectArray();
|
|
res = f->LoadFileData(array);
|
|
if(res != CK_OK) {
|
|
m_CKContext->DeleteCKFile(f);
|
|
DeleteCKObjectArray(array);
|
|
return res;
|
|
}
|
|
|
|
m_CKContext->DeleteCKFile(f);
|
|
|
|
DeleteCKObjectArray(array);
|
|
return CK_OK;
|
|
}
|
|
|
|
CKERROR CCustomPlayer::_Load(const void* iMemoryBuffer,int iBufferSize)
|
|
{
|
|
CKFile *f = m_CKContext->CreateCKFile();
|
|
|
|
DWORD res = CKERR_INVALIDFILE;
|
|
res = f->OpenMemory((void*)iMemoryBuffer,iBufferSize,(CK_LOAD_FLAGS) (CK_LOAD_DEFAULT | CK_LOAD_CHECKDEPENDENCIES));
|
|
if (res!=CK_OK) {
|
|
if (res==CKERR_PLUGINSMISSING) {
|
|
_MissingGuids(f,0);
|
|
}
|
|
//m_CKContext->DeleteCKFile(f);
|
|
//return res;
|
|
}
|
|
|
|
CKObjectArray *array = CreateCKObjectArray();
|
|
res = f->LoadFileData(array);
|
|
if(res != CK_OK) {
|
|
m_CKContext->DeleteCKFile(f);
|
|
return res;
|
|
}
|
|
|
|
m_CKContext->DeleteCKFile(f);
|
|
|
|
DeleteCKObjectArray(array);
|
|
return CK_OK;
|
|
}
|
|
|
|
void CCustomPlayer::_MissingGuids(CKFile* iFile, const char* iResolvedFile)
|
|
{
|
|
// here we manage the error CKERR_PLUGINSMISSING when loading a composition failed
|
|
|
|
// create missing guids log filename
|
|
char fp[_MAX_PATH];
|
|
{
|
|
GetTempPath(_MAX_PATH,fp);
|
|
char drive[_MAX_DRIVE];
|
|
char dir[_MAX_DIR];
|
|
char fname[_MAX_FNAME];
|
|
char ext[_MAX_EXT];
|
|
|
|
_splitpath(fp,drive,dir,fname,ext);
|
|
_makepath(fp,drive,dir,MISSINGUIDS_LOG,NULL);
|
|
}
|
|
|
|
// retrieve the list of missing plugins/guids
|
|
XClassArray<CKFilePluginDependencies> *p = iFile->GetMissingPlugins();
|
|
CKFilePluginDependencies*it = p->Begin();
|
|
|
|
FILE *logf = NULL;
|
|
char str[64];
|
|
for(CKFilePluginDependencies* it=p->Begin();it!=p->End();it++) {
|
|
int count = (*it).m_Guids.Size();
|
|
for(int i=0;i<count;i++) {
|
|
if (!((*it).ValidGuids[i])) {
|
|
if(!logf) {
|
|
logf = fopen(fp,"wt");
|
|
if (!logf) {
|
|
return;
|
|
}
|
|
if (iResolvedFile) {
|
|
fprintf(logf,"File Name : %s\nMissing GUIDS:\n",iResolvedFile);
|
|
}
|
|
}
|
|
|
|
sprintf(str,"%x,%x\n",(*it).m_Guids[i].d1,(*it).m_Guids[i].d2);
|
|
fprintf(logf,"%s",str);
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(logf);
|
|
}
|
|
|
|
void CCustomPlayer::_SetResolutions()
|
|
{
|
|
// retrieve the windowed attribute
|
|
CKParameterOut* pout = m_Level->GetAttributeParameter(m_WindowedResolutionAttType);
|
|
if (pout) {
|
|
Vx2DVector res(m_WindowedWidth,m_WindowedHeight);
|
|
// set it
|
|
pout->SetValue(&res);
|
|
}
|
|
|
|
// retrieve the fullscreen attribute
|
|
pout = m_Level->GetAttributeParameter(m_FullscreenResolutionAttType);
|
|
if (pout) {
|
|
Vx2DVector res(m_FullscreenWidth,m_FullscreenHeight);
|
|
// set it
|
|
pout->SetValue(&res);
|
|
}
|
|
|
|
// retrieve the fullscreen bpp attribute
|
|
pout = m_Level->GetAttributeParameter(m_FullscreenBppAttType);
|
|
if (pout) {
|
|
// set it
|
|
pout->SetValue(&m_FullscreenBpp);
|
|
}
|
|
}
|