#include "stdafx.h" #include "SGameCutScene.h" #include "SGameSceneManager.h" #include "SGameMilesSoundMgr.h" #include "KResourceManager.h" #include "KViewport.h" #include "TinyXML.h" #include #include #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::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::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 ); } } } }