Files
Leviathan/Client/Game/game/Main/Scene/SGameQjtvScene.cpp
T
2026-06-01 12:46:52 +02:00

326 lines
7.3 KiB
C++

#include "stdafx.h"
#include "SGameQjtvScene.h"
#include "SGameSceneManager.h"
#include <kfile/KFileManager.h>
#include "KUITextureManager.h"
#include "KDeviceManager.h"
#include "SGameMilesSoundMgr.h"
#include "QJTVObj.h"
#include <mmo/ArTime.h>
#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 <BackClear>!!!" );
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;
}