584 lines
14 KiB
C++
584 lines
14 KiB
C++
#include "stdafx.h"
|
|
#include "SGameCutScene.h"
|
|
#include "SGameSceneManager.h"
|
|
#include "SGameMilesSoundMgr.h"
|
|
#include "KResourceManager.h"
|
|
#include "KViewport.h"
|
|
#include "TinyXML.h"
|
|
#include <mmo/ArTime.h>
|
|
|
|
#include <kfile/KFileManager.h>
|
|
#include "SStringDB.h"
|
|
|
|
using namespace rp;
|
|
|
|
|
|
|
|
SGameCutScene::Image::Image( SGameSceneManager& sceneMgr, const char* szName, const char* szFileName )
|
|
: Primitive( szName )
|
|
{
|
|
NX3LoadPack loadpack;
|
|
loadpack.Init();
|
|
mTexture = sceneMgr.textureMgr().GetTexture( szFileName, &loadpack, true, 0 );
|
|
assert( mTexture && "image scene's texture was not loaded!!" );
|
|
if( mTexture == 0 )
|
|
return;
|
|
|
|
K3DMatrix worldMatrix;
|
|
K3DMatrixIdentity( worldMatrix );
|
|
worldMatrix.SetPosVector( K3DVector( 0, 0, 0 ) );
|
|
|
|
mSprite = new KResSprite();
|
|
mSprite->SetTexture( mTexture, NULL );
|
|
mSprite->SetTransform( worldMatrix );
|
|
mPrimitive.SetRes( mSprite );
|
|
}
|
|
|
|
SGameCutScene::Image::~Image()
|
|
{
|
|
mPrimitive.SetRes( 0 );
|
|
}
|
|
|
|
SGameCutScene::Text::Text( const char* szName, const char* szText, int nWidth, int nHeight )
|
|
: Primitive( szName ), mText( szText ), m_pText( NULL )
|
|
{
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
SDEBUGLOG("SGameCutScene::Text::Text - begin");
|
|
SDEBUGLOG("SGameCutScene::Text::Text %s, %s, %d, %d",szName,szText,nWidth,nHeight);
|
|
#ifdef _COUNTRY_ME_
|
|
m_pText = new KTextLayout2( nWidth, nHeight );
|
|
#else
|
|
m_pText = new KTextPhrase( nWidth, nHeight );
|
|
#endif
|
|
SDEBUGLOG("SGameCutScene::Text::Text - KTextPhrase()");
|
|
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
m_pText->AddString( szText );
|
|
|
|
SDEBUGLOG("SGameCutScene::Text::Text - end");
|
|
}
|
|
|
|
|
|
SGameCutScene::Text::Text( const char* szName, const int nTextID, int nWidth, int nHeight )
|
|
: Primitive( szName ), m_pText( NULL )
|
|
{
|
|
mText = GetStringDB().GetString( nTextID );
|
|
#ifdef _COUNTRY_ME_
|
|
m_pText = new KTextLayout2( nWidth, nHeight );
|
|
#else
|
|
m_pText = new KTextPhrase( nWidth, nHeight );
|
|
#endif
|
|
m_pText->AddString( mText.c_str() );
|
|
}
|
|
|
|
|
|
|
|
SGameCutScene::Text::~Text()
|
|
{
|
|
SAFE_DELETE( m_pText );
|
|
}
|
|
|
|
|
|
void SGameCutScene::Image::SetPosition( int nX, int nY )
|
|
{
|
|
mPrimitive.SetPosition( nX, nY, 0 );
|
|
}
|
|
|
|
void SGameCutScene::Image::SetVisibility( float fVis )
|
|
{
|
|
mPrimitive.SetVisibility( fVis );
|
|
}
|
|
|
|
void SGameCutScene::Image::SetScale( float fW, float fH )
|
|
{
|
|
mPrimitive.SetTargetSize( fW * mSprite->GetSizeX(), fH * mSprite->GetSizeY() );
|
|
}
|
|
|
|
void SGameCutScene::Image::SetSize( float fW, float fH )
|
|
{
|
|
mPrimitive.SetTargetSize( fW, fH );
|
|
}
|
|
|
|
void SGameCutScene::Image::Render( KViewportObject* viewport )
|
|
{
|
|
viewport->Register( &mPrimitive );
|
|
}
|
|
|
|
|
|
void SGameCutScene::Text::SetPosition( int nX, int nY )
|
|
{
|
|
m_pText->SetPosition( nX, nY, 0 );
|
|
}
|
|
|
|
void SGameCutScene::Text::SetVisibility( float fVis )
|
|
{
|
|
m_pText->SetVisibility( fVis );
|
|
}
|
|
|
|
void SGameCutScene::Text::SetScale( float fW, float fH )
|
|
{
|
|
}
|
|
|
|
void SGameCutScene::Text::SetSize( float fW, float fH )
|
|
{
|
|
}
|
|
|
|
|
|
void SGameCutScene::Text::Render( KViewportObject* viewport )
|
|
{
|
|
m_pText->Render( viewport, true );
|
|
}
|
|
|
|
|
|
|
|
SGameCutScene::animation::animation( const char* szName )
|
|
: mObjName( szName )
|
|
{}
|
|
|
|
SGameCutScene::animation::~animation()
|
|
{
|
|
for ( ilistAttr itor = mAttrs.begin(); itor != mAttrs.end(); ++itor )
|
|
delete *itor;
|
|
mAttrs.clear();
|
|
}
|
|
|
|
void SGameCutScene::attr_pos::Apply( DWORD dwTime, SGameCutScene::attr_snapshot& attr )
|
|
{
|
|
if ( IsInTime( dwTime ) )
|
|
{
|
|
if ( dwEndTime == 0xFFFFFFFF )
|
|
{
|
|
attr.nX = nSX;
|
|
attr.nY = nSY;
|
|
}
|
|
else
|
|
{
|
|
float fD1 = ( dwEndTime - dwTime );
|
|
float fD2 = ( dwTime - dwStartTime );
|
|
|
|
attr.nX = ( nSX * fD1 + nEX * fD2 ) / (dwEndTime - dwStartTime);
|
|
attr.nY = ( nSY * fD1 + nEY * fD2 ) / (dwEndTime - dwStartTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SGameCutScene::attr_scale::Apply( DWORD dwTime, SGameCutScene::attr_snapshot& attr )
|
|
{
|
|
if ( IsInTime( dwTime ) )
|
|
{
|
|
if ( dwEndTime == 0xFFFFFFFF )
|
|
{
|
|
attr.fW = fSW;
|
|
attr.fH = fSH;
|
|
}
|
|
else
|
|
{
|
|
float fD1 = ( dwEndTime - dwTime );
|
|
float fD2 = ( dwTime - dwStartTime );
|
|
|
|
attr.fW = ( fSW * fD1 + fEW * fD2 ) / (dwEndTime - dwStartTime);
|
|
attr.fH = ( fSH * fD1 + fEH * fD2 ) / (dwEndTime - dwStartTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SGameCutScene::attr_vis::Apply( DWORD dwTime, SGameCutScene::attr_snapshot& attr )
|
|
{
|
|
if ( IsInTime( dwTime ) )
|
|
{
|
|
if ( dwEndTime == 0xFFFFFFFF )
|
|
{
|
|
attr.fV = fSVis;
|
|
}
|
|
else
|
|
{
|
|
float fD1 = ( dwEndTime - dwTime );
|
|
float fD2 = ( dwTime - dwStartTime );
|
|
|
|
attr.fV = ( fSVis * fD1 + fEVis * fD2 ) / (dwEndTime - dwStartTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
SGameCutScene::attr_snapshot SGameCutScene::animation::GetAttrAt( DWORD dwTime )
|
|
{
|
|
attr_snapshot attr;
|
|
|
|
for ( ilistAttr itor = mAttrs.begin(); itor != mAttrs.end(); ++itor )
|
|
(*itor)->Apply( dwTime, attr );
|
|
return attr;
|
|
}
|
|
|
|
bool SGameCutScene::animation::IsVisibleAt( DWORD dwTime )
|
|
{
|
|
for ( ilistAttr itor = mAttrs.begin(); itor != mAttrs.end(); ++itor )
|
|
{
|
|
if ( (*itor)->IsInTime( dwTime ) )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool SGameCutScene::animation::IsEnd( DWORD dwTime )
|
|
{
|
|
DWORD dwMaxEndTime = 0;
|
|
|
|
for ( ilistAttr itor = mAttrs.begin(); itor != mAttrs.end(); ++itor )
|
|
{
|
|
if ( (*itor)->dwEndTime != 0xFFFFFFFF )
|
|
dwMaxEndTime = std::max( (*itor)->dwEndTime, dwMaxEndTime );
|
|
}
|
|
return dwTime >= dwMaxEndTime;
|
|
}
|
|
|
|
SGameCutScene::SGameCutScene(
|
|
SGameSceneManager& sceneMgr
|
|
, SGameScene* parent
|
|
, const char* sceneName
|
|
, const char* sceneFile
|
|
, const K3DVector& position
|
|
, const K3DVector2& size )
|
|
: SGameScene( sceneMgr, parent, sceneName )
|
|
, mSceneFile( sceneFile )
|
|
, mStartTime( 0 )
|
|
, mLastTime( 0 )
|
|
, mPosition( position )
|
|
, mSize( size )
|
|
{
|
|
}
|
|
|
|
SGameCutScene::~SGameCutScene()
|
|
{
|
|
onLeave();
|
|
}
|
|
|
|
void SGameCutScene::onEnter()
|
|
{
|
|
// pack파일에서 .xml 파일을 추출한다.
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
std::string strFile = KFileManager::Instance().CreateTemporaryFileFromResourceWithLocale( mSceneFile.c_str() );
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
|
|
TiXmlDocument doc( strFile.c_str() );
|
|
bool bSuc = doc.LoadFile();
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
|
|
// 추출한 pack파일을 삭제한다.
|
|
KFileManager::Instance().DeleteTemporaryFile( mSceneFile.c_str() );
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
|
|
if ( bSuc )
|
|
{
|
|
TiXmlElement* pBGM = doc.FirstChildElement( "bgm" );
|
|
if ( pBGM )
|
|
m_strBGMFileName = pBGM->Attribute( "filename" );
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
|
|
TiXmlNode* pObjRoot = doc.FirstChild( "objects" );
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
|
|
if ( pObjRoot )
|
|
{
|
|
TiXmlElement* pObj = pObjRoot->FirstChildElement();
|
|
while ( pObj)
|
|
{
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
|
|
if ( strcmp( pObj->Value(), "image" ) == 0 )
|
|
{
|
|
SDEBUGLOG("%s ",pObj->Value() );
|
|
|
|
Image* pImage = new Image( getSceneManager(), pObj->Attribute( "name" ), pObj->Attribute( "file" ) );
|
|
// 2010.06.03 - prodongi
|
|
if (!pImage->mSprite)
|
|
continue;
|
|
|
|
// CutScene 내부 좌표계는 0,0 ~ 1024,768 을 기준임으로 실제 화면 사이즈에 맞게 조절 해 준다. 2006.06.04 sfreer
|
|
int nWidth = pImage->mSprite->GetSizeX();
|
|
int nHeight = pImage->mSprite->GetSizeY();
|
|
|
|
if(mSize.x > 0)
|
|
nWidth = nWidth * mSize.x / 1024;
|
|
|
|
if(mSize.y > 0)
|
|
nHeight = nHeight * mSize.y / 768;
|
|
|
|
pImage->SetSize(nWidth, nHeight);
|
|
|
|
mPrimitives.insert( mapPrimitive::value_type( pObj->Attribute( "name" ), pImage ) );
|
|
mImagelist.push_back( pImage );
|
|
}
|
|
else if ( strcmp( pObj->Value(), "string" ) == 0 )
|
|
{
|
|
|
|
int nWidth, nHeight;
|
|
|
|
pObj->Attribute( "width", &nWidth );
|
|
pObj->Attribute( "height", &nHeight );
|
|
|
|
SDEBUGLOG("%s %d %d",pObj->Value(),nWidth, nHeight);
|
|
|
|
// CutScene 내부 좌표계는 0,0 ~ 1024,768 을 기준임으로 실제 화면 사이즈에 맞게 조절 해 준다. 2006.06.04 sfreer
|
|
if(mSize.x > 0)
|
|
nWidth = nWidth * mSize.x / 1024;
|
|
|
|
if(mSize.y > 0)
|
|
nHeight = nHeight * mSize.y / 768;
|
|
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
Text* pText = new Text( pObj->Attribute( "name" ), pObj->Attribute( "text" ), nWidth, nHeight ); //[MEMORY_LEAK] 2012. 3. 5 - marine 맵 clear 시 메모리 해제 되고 있음.
|
|
auto ret = mPrimitives.insert( mapPrimitive::value_type( pObj->Attribute( "name" ), pText ) );
|
|
if( ret.second == false )
|
|
{
|
|
delete pText;
|
|
}
|
|
}
|
|
else if ( strcmp( pObj->Value(), "stringid" ) == 0 )
|
|
{
|
|
int nWidth, nHeight;
|
|
int nTextID;
|
|
|
|
pObj->Attribute( "width", &nWidth );
|
|
pObj->Attribute( "height", &nHeight );
|
|
pObj->Attribute( "textid", &nTextID );
|
|
|
|
SDEBUGLOG("%s %d %d %d",pObj->Value(),nWidth, nHeight, nTextID);
|
|
|
|
// CutScene 내부 좌표계는 0,0 ~ 1024,768 을 기준임으로 실제 화면 사이즈에 맞게 조절 해 준다. 2006.06.04 sfreer
|
|
if(mSize.x > 0)
|
|
nWidth = nWidth * mSize.x / 1024;
|
|
|
|
if(mSize.y > 0)
|
|
nHeight = nHeight * mSize.y / 768;
|
|
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
Text* pText = new Text( pObj->Attribute( "name" ), nTextID, nWidth, nHeight );
|
|
auto ret = mPrimitives.insert( mapPrimitive::value_type( pObj->Attribute( "name" ), pText ) );
|
|
if( ret.second == false )
|
|
{
|
|
delete pText;
|
|
}
|
|
|
|
}
|
|
pObj = pObj->NextSiblingElement();
|
|
}
|
|
}
|
|
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
|
|
TiXmlElement* pAniRoot = doc.FirstChildElement( "animation" );
|
|
while ( pAniRoot )
|
|
{
|
|
animation* pAnimation = new animation( pAniRoot->Attribute( "object" ) );
|
|
|
|
TiXmlElement* pAttr = pAniRoot->FirstChildElement();
|
|
while ( pAttr )
|
|
{
|
|
DWORD dwStartTime, dwEndTime;
|
|
|
|
pAttr->Attribute( "stime", (int *)&dwStartTime );
|
|
if ( pAttr->Attribute( "etime", (int *)&dwEndTime ) == NULL )
|
|
dwEndTime = 0xFFFFFFFF;
|
|
|
|
if ( strcmp( pAttr->Value(), "position" ) == 0 )
|
|
{
|
|
int nSX, nSY, nEX, nEY;
|
|
pAttr->Attribute( "sx", &nSX );
|
|
pAttr->Attribute( "sy", &nSY );
|
|
pAttr->Attribute( "ex", &nEX );
|
|
pAttr->Attribute( "ey", &nEY );
|
|
|
|
// CutScene 내부 좌표계는 0,0 ~ 1024,768 을 기준임으로 실제 화면 사이즈에 맞게 조절 해 준다. 2006.06.04 sfreer
|
|
if(mSize.x > 0)
|
|
{
|
|
nSX = (nSX * mSize.x / 1024);// + mPosition.x;
|
|
nEX = (nEX * mSize.x / 1024);// + mPosition.x;
|
|
}
|
|
|
|
if(mSize.y > 0)
|
|
{
|
|
nSY = (nSY * mSize.y / 768);// + mPosition.y;
|
|
nEY = (nEY * mSize.y / 768);// + mPosition.y;
|
|
}
|
|
|
|
nSX = nSX + mPosition.x;
|
|
nEX = nEX + mPosition.x;
|
|
nSY = nSY + mPosition.y;
|
|
nEY = nEY + mPosition.y;
|
|
|
|
attr_pos* pPos = new attr_pos( dwStartTime, nSX, nSY, dwEndTime, nEX, nEY );
|
|
pAnimation->mAttrs.push_back( pPos );
|
|
}
|
|
else if ( strcmp( pAttr->Value(), "scale" ) == 0 )
|
|
{
|
|
double dSW, dSH, dEW, dEH;
|
|
pAttr->Attribute( "sw", &dSW );
|
|
pAttr->Attribute( "sh", &dSH );
|
|
pAttr->Attribute( "ew", &dEW );
|
|
pAttr->Attribute( "eh", &dEH );
|
|
|
|
attr_scale* pScale = new attr_scale( dwStartTime, dSW, dSH, dwEndTime, dEW, dEH );
|
|
pAnimation->mAttrs.push_back( pScale );
|
|
}
|
|
else if ( strcmp( pAttr->Value(), "visibility" ) == 0 )
|
|
{
|
|
double dSV, dEV;
|
|
pAttr->Attribute( "sv", &dSV );
|
|
pAttr->Attribute( "ev", &dEV );
|
|
attr_vis* pVis = new attr_vis( dwStartTime, dSV, dwEndTime, dEV );
|
|
pAnimation->mAttrs.push_back( pVis );
|
|
}
|
|
pAttr = pAttr->NextSiblingElement();
|
|
}
|
|
mAnimations.push_back( pAnimation );
|
|
|
|
pAniRoot = pAniRoot->NextSiblingElement( "animation" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::string errmsg = "xml scene's was not loaded - ";
|
|
errmsg += mSceneFile;
|
|
MessageBox(NULL, errmsg.c_str(),"error", MB_OK);
|
|
}
|
|
|
|
//_ASSERTE( _CrtCheckMemory( ) );
|
|
}
|
|
|
|
|
|
void SGameCutScene::onLeave()
|
|
{
|
|
//mImagelist.push_back( pImage );
|
|
|
|
for ( imapPrimitive itor = mPrimitives.begin(); itor != mPrimitives.end(); ++itor )
|
|
{
|
|
bool enabledel = true;
|
|
|
|
for( std::list<Image *>::iterator itt = mImagelist.begin() ; itt != mImagelist.end(); ++itt)
|
|
{
|
|
if( (*itt) == itor->second )
|
|
{
|
|
enabledel = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(enabledel)
|
|
delete itor->second;
|
|
}
|
|
mPrimitives.clear();
|
|
|
|
for( std::list<Image *>::iterator itt = mImagelist.begin() ; itt != mImagelist.end(); ++itt)
|
|
delete (*itt);
|
|
mImagelist.clear();
|
|
|
|
|
|
for ( ilistAnimation itor = mAnimations.begin(); itor != mAnimations.end(); ++itor )
|
|
delete *itor;
|
|
mAnimations.clear();
|
|
}
|
|
|
|
void SGameCutScene::onActivate()
|
|
{
|
|
// mStartTime = mLastTime = mSceneMgr.timer().getTime();
|
|
mStartTime = GetSafeTickCount();
|
|
mLastTime = 0;
|
|
_oprint( "\n\n\nFrame Start Time = %d\n\n\n\n", mStartTime );
|
|
|
|
//mSceneMgr.milesSoundMgr().StopBgm();
|
|
mSceneMgr.milesSoundMgr().StopMusic();
|
|
|
|
//mSceneMgr.milesSoundMgr().ForcePlayMusic( m_strBGMFileName.c_str() );
|
|
mSceneMgr.milesSoundMgr().SwapPlayBGM( m_strBGMFileName.c_str(), 100, 1000, 1000, false );
|
|
|
|
}
|
|
|
|
void SGameCutScene::onDeactivate()
|
|
{
|
|
SGameScene::onDeactivate();
|
|
}
|
|
|
|
void SGameCutScene::onTick()
|
|
{
|
|
SGameScene::onTick();
|
|
//_oprint( "LastTime = %d ", mLastTime );
|
|
|
|
if(mLastTime == 0)
|
|
mLastTime = GetSafeTickCount();//mSceneMgr.timer().getTime();
|
|
|
|
DWORD ScreeningTimeDiff = /*mSceneMgr.timer().getTime()*/GetSafeTickCount() - mLastTime;
|
|
|
|
//_oprint( "Frame Diff Time = %d ", ScreeningTimeDiff );
|
|
|
|
bool bAllEnd = true;
|
|
DWORD dwFrame = (mLastTime - mStartTime) * 30 / 1000;
|
|
|
|
|
|
animation* pAni;
|
|
for ( ilistAnimation itor = mAnimations.begin(); itor != mAnimations.end(); ++itor )
|
|
{
|
|
pAni = *itor;
|
|
|
|
if ( !pAni->IsEnd( dwFrame ) )
|
|
bAllEnd = false;
|
|
|
|
if ( pAni->IsVisibleAt( dwFrame ) )
|
|
{
|
|
imapPrimitive itObj;
|
|
|
|
itObj = mPrimitives.find( pAni->mObjName );
|
|
if ( itObj != mPrimitives.end() )
|
|
{
|
|
|
|
Primitive* pPrim = itObj->second;
|
|
|
|
attr_snapshot attr = pAni->GetAttrAt( dwFrame );
|
|
|
|
/*
|
|
pPrim->SetPosition( attr.nX, attr.nY);
|
|
pPrim->SetVisibility( attr.fV );
|
|
*/
|
|
|
|
//_oprint( "Frame : %d, Vis = %x, nX = %d, nY = %d \n", dwFrame, attr.fV );
|
|
}
|
|
}
|
|
}
|
|
if (bAllEnd )
|
|
activate( false );
|
|
mLastTime += ScreeningTimeDiff;
|
|
}
|
|
|
|
|
|
void SGameCutScene::onRender( KViewportObject* viewport )
|
|
{
|
|
if(mLastTime == 0)
|
|
return;
|
|
|
|
animation* pAni;
|
|
DWORD dwFrame = (mLastTime - mStartTime) * 30 / 1000;
|
|
for ( ilistAnimation itor = mAnimations.begin(); itor != mAnimations.end(); ++itor )
|
|
{
|
|
pAni = *itor;
|
|
|
|
if ( pAni->IsVisibleAt( dwFrame ) )
|
|
{
|
|
imapPrimitive itObj;
|
|
|
|
itObj = mPrimitives.find( pAni->mObjName );
|
|
if ( itObj != mPrimitives.end() )
|
|
{
|
|
Primitive* pPrim = itObj->second;
|
|
|
|
//좌표값, 투명도 갱신이 제대로 이루어져있지 않아 onTick 에서 여기로 임시로 옮겨옴. 2009.07.10 sfreer
|
|
attr_snapshot attr = pAni->GetAttrAt( dwFrame );
|
|
pPrim->SetPosition( attr.nX, attr.nY);
|
|
pPrim->SetVisibility( attr.fV );
|
|
|
|
pPrim->Render( viewport );
|
|
}
|
|
}
|
|
}
|
|
} |