#include "stdafx.h" #include "SGameQjtvScene.h" #include "SGameSceneManager.h" #include #include "KUITextureManager.h" #include "KDeviceManager.h" #include "SGameMilesSoundMgr.h" #include "QJTVObj.h" #include #include "KViewport.h" #include "GameDefine.h" rp::SGameQjtvScene::SGameQjtvScene( SGameSceneManager& sceneMgr , SGameScene* parent , const char* sceneName , const char* jtvFile , const char* soundFile , const K3DVector& position , const KColor& bgColor , DWORD option , int fixedFps , bool registerSelf , KViewportObject* viewport , const K3DVector2& size ) : SGameScene ( sceneMgr, parent, sceneName ) , mQjtvFile ( jtvFile ) , mSoundFile ( soundFile ) , mQjtv ( 0 ) , mFrame ( 0 ) , mImageWidth ( 0 ) , mImageHeight ( 0 ) , mRefreshTime ( 0 ) , mBeginTime ( 0 ) , mPosition ( position ) , mBgColor ( bgColor ) , mOption ( option ) , mFixedFps ( fixedFps ) , mIsImageReady ( false ) , mIsPlaying ( true ) , mRegisterSelf ( registerSelf ) , mViewport ( viewport ) , mSize ( size ) { } rp::SGameQjtvScene::~SGameQjtvScene() { SAFE_DELETE( mQjtv ); } void rp::SGameQjtvScene::onEnter() { int ExpWidth, ExpHeight; KStream* TmlStream = KFileManager::Instance().CreateStreamFromResource( "QJTV.tml" ); if( TmlStream && TmlStream->IsValid() ) { TmlStream->Seek( 0, KStream::seekSet ); mQjtvTml.importTML( *TmlStream ); KStream* JtvStream = KFileManager::Instance().CreateStreamFromResource( mQjtvFile.c_str() ); if( JtvStream && JtvStream->IsValid() ) { // JtvStream는 mQjtv에서 삭제 된다. mQjtv = new QJTVObj; mQjtv->Load( &mQjtvTml, JtvStream ); if( mQjtv->GetFrameCount() > 0 ) { BYTE* Buffer( NULL ); mQjtv->GetFrame( 0, Buffer, mImageWidth, mImageHeight ); if( mOption & OPTION::FULL ) { ExpWidth = GAME_DEFINE::DEF_SIZE::SIZE_1024; ExpHeight = GAME_DEFINE::DEF_SIZE::SIZE_768; } else K3DRenderDevice::GetSquareSize( mImageWidth, mImageHeight, ExpWidth, ExpHeight ); if( KUITextureManager::GetHWType() == KUITextureManager::HW_SUPPORT ) { mRenderTarget = KDeviceManager::GetDeviceManager()->GetRenderDevice()->CreateTexture( ExpWidth, ExpHeight, KUSAGE_DYNAMIC, K3DFMT_A8R8G8B8, D3DPOOL_DEFAULT ); } else { //Intel Chip 계열에서 지원 안 되는 넘들이 있음. mRenderTarget = KDeviceManager::GetDeviceManager()->GetRenderDevice()->CreateTexture( ExpWidth, ExpHeight, K3DFMT_A8R8G8B8, D3DPOOL_MANAGED ); } } else { SAFE_DELETE( mQjtv ); } } else { std::string errmsg = "File not found - "; errmsg += mQjtvFile; MessageBox(NULL, errmsg.c_str(),"error", MB_OK); } KFileManager::Instance().DeleteStream( TmlStream ); } if( !mRenderTarget ) return; BYTE* TextureBuffer = 0; int Stride = 0; mRenderTarget->LockRect( 0, (void**)&TextureBuffer, Stride ); if( TextureBuffer == NULL ) { mRenderTarget = NULL; assert( 0 && "QJTV Lock Failed !!!" ); return; } unsigned int PixelCount = ExpHeight * ExpWidth; for( unsigned int i(0); i < PixelCount; i++ ) { KColor* Color = (KColor*)TextureBuffer; Color[ i ] = mBgColor; } mRenderTarget->Unlock(); mSprite = new KResSprite; mSprite->SetTexture( mRenderTarget, 0 ); K3DMatrixIdentity( mWorld ); if( mOption & SCREENCENTER ) mWorld.SetPosVector( K3DVector( (float)( GAME_DEFINE::DEF_SIZE::SIZE_1024 - mImageWidth ) / 2, (float)( GAME_DEFINE::DEF_SIZE::SIZE_768 - mImageHeight ) / 2, 0.1f ) ); else mWorld.SetPosVector( mPosition ); mSprite->SetTransform( mWorld ); if(mSize.x > 0) mSprite->SetSize( mSize.x, mSprite->GetSizeY() ); if(mSize.y > 0) mSprite->SetSize( mSprite->GetSizeX(), mSize.y ); mPrimitive.SetRes( mSprite ); //mPrimitive.SetTargetSize( mSize.x, mSize.y);//(float)ExpWidth, (float)ExpHeight ); mPrimitive.SetVisibility( 1.f ); //mPrimitive.SetMirror( false, true ); } void rp::SGameQjtvScene::onActivate() { mFrame = 0; mIsImageReady = false; mIsPlaying = true; mBeginTime = 0; if( !mSoundFile.empty() ) mSceneMgr.milesSoundMgr().ForcePlayMusic( mSoundFile.c_str() ); } void rp::SGameQjtvScene::onDeactivate() { mIsImageReady = false; mIsPlaying = false; } void rp::SGameQjtvScene::onLeave() { SAFE_DELETE( mQjtv ); mRenderTarget = 0; mSprite = 0; mPrimitive.SetRes( 0 ); } void rp::SGameQjtvScene::onTick() { /* float msFps = 1000.f / mFixedFps; if ( ( GetSafeTickCount() - mRefreshTime ) < msFps ) return; SGameScene::onTick(); if( _needToFillRenderTarget() ) { BYTE* Image( 0 ); int ImageWidth( 0 ), ImageHeight( 0 ); mQjtv->GetFrame( mFrame, Image, ImageWidth, ImageHeight ); if( Image ) mIsImageReady = _fillRenderTarget( mRenderTarget, Image, ImageWidth, ImageHeight ); // move frame mFrame++; if( mFrame >= mQjtv->GetFrameCount() ) { if( mOption & REPEAT ) mFrame = 0; else activate( false ); } } //mRefreshTime = GetSafeTickCount(); */ //프레임 스킵핑 적용 //2009-05-12:hunee SGameScene::onTick(); mRefreshTime = mSceneMgr.timer().getTime(); if( mBeginTime == 0 ) mBeginTime = mRefreshTime; // frame move if(mQjtv == NULL) return; float msFps = 1000.f / mFixedFps; // (msec/frame) DWORD msTotal = (DWORD)( (float)mQjtv->GetFrameCount() * msFps ); // (frame)*(msec/frame)=(msec) DWORD msDiff = mRefreshTime - mBeginTime; mFrame = (DWORD)( (float)msDiff / msTotal * mQjtv->GetFrameCount() ) + 1; if( _needToFillRenderTarget() ) { BYTE* Image( 0 ); int ImageWidth( 0 ), ImageHeight( 0 ); mQjtv->GetFrame( mFrame, Image, ImageWidth, ImageHeight ); if( Image ) mIsImageReady = _fillRenderTarget( mRenderTarget, Image, ImageWidth, ImageHeight ); if( mFrame >= mQjtv->GetFrameCount() ) { if( mOption & REPEAT ) { mBeginTime = mRefreshTime; mFrame = 0; } else { activate( false ); return; } } } updateVisibility(); mPrimitive.SetVisibility( getWorldVisibility() ); } void rp::SGameQjtvScene::onRender( KViewportObject* viewport ) { if( mIsImageReady && mRegisterSelf ) { if( mViewport ) mViewport->Register( &mPrimitive ); else viewport->Register( &mPrimitive ); } } void rp::SGameQjtvScene::play( bool play ) { mIsPlaying = play; } bool rp::SGameQjtvScene::_needToFillRenderTarget() const { return mQjtv && mRenderTarget && ( mIsPlaying || !mIsImageReady ); } bool rp::SGameQjtvScene::_fillRenderTarget( K3DTexture* texture, BYTE* image, int width, int height ) { int TexW = mRenderTarget->GetWidth(); int TexH = mRenderTarget->GetHeight(); unsigned int PosX = 0; unsigned int PosY = 0; if( mOption & OPTION::CENTER ) { PosX = TexW / 2 - width / 2; PosY = TexH / 2 - height / 2; } KRect Region( PosX, PosY, PosX + width, PosY + height ); char* Buffer = NULL; int Stride; texture->LockRect( &Region, (void**)&Buffer, Stride ); //위치 조정 if( Buffer ) { KColor* Color; for(int y = height - 1; y >= 0; y-- ) { Color = (KColor*)Buffer; for( int x = 0; x < width; x++ ) { KColor TempColor; unsigned int pos = ( y * width + x ) * 4; TempColor.b = image[ pos + 0 ]; TempColor.g = image[ pos + 1 ]; TempColor.r = image[ pos + 2 ]; if( mOption & OPTION::ALPHA ) TempColor.a = image[ pos + 3 ]; else TempColor.a = 255; Color[ x ] = TempColor; } Buffer += Stride; } texture->Unlock(); return true; } return false; }