#include "stdafx.h" #include "SGameQJTV.h" #include #include "KRenderDeviceDX.h" #include "KViewport.h" #include #include "KUITextureManager.h" #include "GameDefine.h" #include "KTGA_IO.h" SGameQJTV::SGameQJTV( K3DRenderDeviceDX* pRenderDevice ) : m_pRenderDevice(pRenderDevice), m_CrrTime(0), m_StartTime(0), m_bPlay(false), m_bSuccessSetting(false) , m_nState(QJTV::OFF), m_OldFrameRenderTime(0), m_nStartFrame(0), m_TextureOption(0), m_TextureWidth(0), m_TextureHeight(0) , m_nCrrFrame(0), m_nCnt(0), m_fixFps(0), m_bRepeat(true), m_nFrameCnt(0), m_bSuccessCraeteTexture(false) { K3DMatrixIdentity( m_Matrix ); m_Matrix.SetPosVector( K3DVertex( 0, 0, 0.1f ) ); m_BackColor = KColor(0,0,0,0); Init(); } SGameQJTV::~SGameQJTV() { } void SGameQJTV::Init() { KStream * pStream = KFileManager::Instance().CreateStreamFromResource( "QJTV.tml" ); m_Meta.importTML( *pStream ); KFileManager::Instance().DeleteStream( pStream ); m_pResSprite = new KResSprite; } void SGameQJTV::SetQJTV( const char* pFileName, DWORD TextureOption/*0*/, int nStart/*0*/, int nCnt/*0*/, float fixFps/*25*/, KColor BackColor/*KColor(0,0,0,0)*/ ) { m_strFileName = pFileName; m_TextureOption = TextureOption; m_nStartFrame = nStart; m_nCnt = nCnt; m_fixFps = fixFps; LoadQJTV(nStart, nCnt, BackColor); } //동영상의 시작할 첫번째 파일의 위치, 총 프레임 수, 각 프레임의 랜더링걸 시간 bool SGameQJTV::LoadQJTV( int nStart/*0*/, int nCnt/*0*/, KColor BackColor/*KColor(0,0,0,0)*/ ) { //QJTVObj 안에서 KStream 삭제 된다 KStream* pStream = KFileManager::Instance().CreateStreamFromResource( m_strFileName.c_str() ); m_QJTV.Load( &m_Meta, pStream ); //파일로드 if( !CheckData(nStart, nCnt) ) //생성하고자 하는 옵션이 현재 로딩한 파일에 적합한지 검사 return false; BYTE* pBits(NULL); int nSrcWidth(0), nSrcHeight(0); m_QJTV.GetFrame( m_nStartFrame, pBits, nSrcWidth, nSrcHeight ); //첫번째 프레임의 택스처 정보 얻기 if( !CreateTexture(BackColor, nSrcWidth, nSrcHeight) ) //첫번째 프레임에 맞게 택스처 생성 return false; m_pResSprite->SetTransform(m_Matrix); m_pSpritePrimitive.SetRes( m_pResSprite ); //프리미티브에 리소스 연결 m_pSpritePrimitive.SetVisibility( 1.0f ); m_pSpritePrimitive.SetMirror( false, true ); m_bSuccessSetting = true; return true; } bool SGameQJTV::CheckData( int nStart/*0*/, int nCnt/*0*/ ) { m_nFrameCnt = m_QJTV.GetFrameCount(); if( m_nFrameCnt == 0 ) return false; if( m_nFrameCnt <= nStart ) return false; if( m_nFrameCnt < nStart+nCnt ) return false; return true; } bool SGameQJTV::CreateTexture(KColor BackColor, int& nSrcWidth, int& nSrcHeight ) { int nExpX(0) ,nExpY(0); if( m_TextureOption & QJTV::FULL ) //게임 해상도에 마춰서 택스처를 생성하겠다는 옵션 { KSize ScreenSize = m_pRenderDevice->GetScreenSize(); // nExpX = ScreenSize.width; nExpY = ScreenSize.height; nExpX = SIZE_1024; nExpY = SIZE_768; } if(nExpX==0 || nExpY==0) //아무런 옵션이 없던가 디폴트로 쎄팅 되있으니 택스처의 크기에 맞게 생성 K3DRenderDevice::GetSquareSize( nSrcWidth, nSrcHeight, nExpX, nExpY ); if( KUITextureManager::GetHWType() == KUITextureManager::HW_SUPPORT ) { m_pTexture = m_pRenderDevice->CreateTexture( nExpX, nExpY, KUSAGE_DYNAMIC, K3DFMT_A8R8G8B8, D3DPOOL_DEFAULT ); } else //Intel Chip 계열에서 지원 안 되는 넘들이 있음. { m_pTexture = m_pRenderDevice->CreateTexture( nExpX, nExpY, K3DFMT_A8R8G8B8, D3DPOOL_MANAGED ); } if( m_pTexture == NULL ) return false; else { BYTE* pTextureBuf(NULL); int nStride(0); m_pTexture->LockRect( NULL, (void**)&pTextureBuf, nStride ); if( pTextureBuf == NULL ) { m_pTexture = NULL; assert( 0 && "QJTV Lock Failed !!!" ); return false; } m_BackColor = BackColor; for( UINT i(0); i < (UINT)(nExpY*nExpX); i++ ) { KColor* pColor = ( KColor* )pTextureBuf; pColor[i] = BackColor; } m_pTexture->Unlock(); } nSrcWidth = nExpX; nSrcHeight = nExpY; m_pResSprite->SetTexture(m_pTexture, NULL); //택스처 리소스스프라이트에 쎄팅 m_pSpritePrimitive.SetTargetSize( nSrcWidth, nSrcHeight ); return true; } bool SGameQJTV::RefreshSeenTexture() { if( !m_bSuccessSetting || m_pTexture == NULL ) return false; int nTextureX(m_pTexture->GetWidth()), nTextureY(m_pTexture->GetHeight()); BYTE* pSrcBits(NULL); int nSrcWidth(0), nSrcHeight(0); m_QJTV.GetFrame( m_nCrrFrame, pSrcBits, nSrcWidth, nSrcHeight ); UINT StartX(0); UINT StartY(0); if( m_TextureOption & QJTV::CENTER ) { StartX = nTextureX/2-nSrcWidth/2; StartY = nTextureY/2-nSrcHeight/2; } BYTE* pTextureBuf(NULL); int nStride(0); KRect rcRock(StartX, StartY, StartX+nSrcWidth, StartY+nSrcHeight); m_pTexture->LockRect( &rcRock, (void**)&pTextureBuf, nStride ); if( pTextureBuf == NULL ) { m_pTexture = NULL; m_bSuccessCraeteTexture = false; assert( 0 && "QJTV Lock Failed!!!" ); return false; } KColor* pColor(NULL); for( UINT y(0); y < (UINT)nSrcHeight; y++ ) { pColor = (KColor*)pTextureBuf; for( UINT x(0); x < (UINT)nSrcWidth; ++x ) { KColor col; UINT Pos = (y*nSrcWidth +x)*4; col.b = pSrcBits[Pos+0]; col.g = pSrcBits[Pos+1]; col.r = pSrcBits[Pos+2]; if( m_TextureOption & QJTV::ALPHA ) col.a = pSrcBits[Pos+3]; else col.a = 255; //택스처에 있는 알파값을 사용하지 않는 경우 pColor[x] = col; } pTextureBuf += nStride; } m_pTexture->Unlock(); m_bSuccessCraeteTexture = true; return true; } bool SGameQJTV::SetScreenCenter() { if( m_pRenderDevice == NULL || m_pTexture == NULL ) return false; KSize ScreenSize = m_pRenderDevice->GetScreenSize(); int nTextureX(m_pTexture->GetWidth()), nTextureY(m_pTexture->GetHeight()); int StartX = ScreenSize.width/2-nTextureX/2; int StartY = ScreenSize.height/2-nTextureY/2; m_Matrix.SetPosVector( K3DVertex( StartX, StartY, 0.1f ) ); m_pResSprite->SetTransform(m_Matrix); return true; } void SGameQJTV::SetState( int nState ) { m_nState = nState; } void SGameQJTV::StartPlay() { m_bPlay = true; m_OldFrameRenderTime = m_StartTime = GetSafeTickCount(); m_nCrrFrame = m_nStartFrame; RefreshSeenTexture(); m_nState = QJTV::PLAY; } void SGameQJTV::Play() { bool bOver( m_nCrrFrame+1 > (int)m_QJTV.GetFrameCount() ); if( !m_bRepeat && bOver ) { m_nState = QJTV::END; return; } float msFps = 1000.f / m_fixFps; if ( m_CrrTime-m_OldFrameRenderTime > msFps ) { ++m_nCrrFrame; m_OldFrameRenderTime = GetSafeTickCount(); if(bOver && m_bRepeat) m_nCrrFrame = m_nStartFrame; if( m_bSuccessCraeteTexture && m_nFrameCnt <= 1 ) return; RefreshSeenTexture(); } } void SGameQJTV::OFF() { m_bPlay = false; m_nState = QJTV::OFF; } int SGameQJTV::Render( KViewportObject *viewport, bool bFront/*=true*/ ) { //OFF이거나 STOP일때는 render안건다... if( m_nState == QJTV::OFF ) return QJTV::OFF; // if( m_nState == QJTV::STOP ) return QJTV::STOP; viewport->Register( &m_pSpritePrimitive ); // viewport->Register( &m_pSpritePrimitive, bFront ); return m_nState; } int SGameQJTV::Proc( DWORD dwTime ) { m_CrrTime = dwTime; if( !m_bSuccessSetting || m_pTexture == NULL || m_nState == QJTV::OFF ) return SetOff(); switch(m_nState) { case QJTV::STARTPLAY: StartPlay(); break; case QJTV::PLAY: Play(); break; case QJTV::OFF: OFF(); break; } return m_nState; } int SGameQJTV::SetOff() { m_bPlay = false; m_nState = QJTV::OFF; return m_nState; } SGameMultiQJTV::SGameMultiQJTV( K3DRenderDeviceDX* pRenderDevice, int nWidth, int nHeight, KColor BackColor ) : m_pRenderDevice(pRenderDevice), m_nWidthSize(nWidth), m_nHeightSize(nHeight), m_pCrrQJTV(NULL) { K3DMatrixIdentity( m_Matrix ); m_Matrix.SetPosVector( K3DVertex( 0, 0, 0.1f ) ); m_BackColor = BackColor; Init(); } SGameMultiQJTV::~SGameMultiQJTV() { for( int i(0); i<(int)m_vecQJTV.size(); ++i ) { SAFE_DELETE(m_vecQJTV[i]); } m_vecQJTV.clear(); m_vecQJTV_FileName.clear(); } void SGameMultiQJTV::Init() { m_pResSprite = new KResSprite; CreateTexture(m_BackColor, m_nWidthSize, m_nHeightSize); m_pResSprite->SetTransform(m_Matrix); m_pSpritePrimitive.SetRes( m_pResSprite ); //프리미티브에 리소스 연결 m_pSpritePrimitive.SetVisibility( 1.0f ); m_pSpritePrimitive.SetMirror( false, true ); } bool SGameMultiQJTV::AddQJTV( const char* pFileName, DWORD TextureOption/*0*/, int nStart/*0*/, int nCnt/*0*/, float fixFps/*25*/ ) { //이미 add한 파일인지 체크... if( GetQJTVMovie(pFileName) ) return false; sQJTV* pQJTV = new sQJTV; if( pQJTV == NULL ) return false; KStream * pStream = KFileManager::Instance().CreateStreamFromResource( "QJTV.tml" ); pQJTV->m_Meta.importTML( *pStream ); KFileManager::Instance().DeleteStream( pStream ); SetQJTV( pQJTV, pFileName, TextureOption, nStart, nCnt, fixFps ); m_vecQJTV.push_back( pQJTV ); m_vecQJTV_FileName.push_back( pFileName ); return true; } bool SGameMultiQJTV::SetCrrMovie( const char* lpFileName ) { int nQJTVSize( m_vecQJTV.size() ); for( int i(0); i<(int)m_vecQJTV_FileName.size(); i++ ) { if( m_vecQJTV_FileName[i] == lpFileName && i >= 0 && i < nQJTVSize ) { m_pCrrQJTV = m_vecQJTV[i]; ClearTextureBuffer(); return true; } } return false; } void SGameMultiQJTV::ClearTextureBuffer() { BYTE* pTextureBuf(NULL); int nStride(0); m_pTexture->LockRect( NULL, (void**)&pTextureBuf, nStride ); if( pTextureBuf == NULL ) { m_pTexture = NULL; assert( 0 && "QJTV Lock Failed !!!" ); return; } for( UINT i(0); i < (UINT)(m_nWidthSize*m_nHeightSize); i++ ) { KColor* pColor = ( KColor* )pTextureBuf; pColor[i] = m_BackColor; } m_pTexture->Unlock(); } sQJTV* SGameMultiQJTV::GetQJTVMovie( const char* lpFileName ) { int nQJTVSize( m_vecQJTV.size() ); for( int i(0); i<(int)m_vecQJTV_FileName.size(); i++ ) { if( m_vecQJTV_FileName[i] == lpFileName && i > 0 && i < nQJTVSize ) { return m_vecQJTV[i]; } } return NULL; } void SGameMultiQJTV::SetQJTV( sQJTV* pQJTVSET, const char* pFileName, DWORD TextureOption/*0*/, int nStart/*0*/, int nCnt/*0*/, float fixFps/*25*/ ) { if( pQJTVSET == NULL ) return; pQJTVSET->m_strFileName = pFileName; pQJTVSET->m_TextureOption = TextureOption; pQJTVSET->m_nStartFrame = nStart; pQJTVSET->m_nCnt = nCnt; pQJTVSET->m_fixFps = fixFps; LoadQJTV(pQJTVSET, nStart, nCnt ); } //동영상의 시작할 첫번째 파일의 위치, 총 프레임 수, 각 프레임의 랜더링걸 시간 bool SGameMultiQJTV::LoadQJTV( sQJTV* pQJTVSET, int nStart/*0*/, int nCnt/*0*/ ) { if( pQJTVSET == NULL ) return false; //QJTVObj 안에서 KStream 삭제 된다 KStream* pStream = KFileManager::Instance().CreateStreamFromResource( pQJTVSET->m_strFileName.c_str() ); pQJTVSET->m_QJTV.Load( &pQJTVSET->m_Meta, pStream ); //파일로드 if( !CheckData(pQJTVSET, nStart, nCnt) ) //생성하고자 하는 옵션이 현재 로딩한 파일에 적합한지 검사 return false; pQJTVSET->m_bSuccessSetting = true; return true; } bool SGameMultiQJTV::CheckData( sQJTV* pQJTVSET, int nStart/*0*/, int nCnt/*0*/ ) { if( pQJTVSET == NULL ) return false; pQJTVSET->m_nFrameCnt = pQJTVSET->m_QJTV.GetFrameCount(); if( pQJTVSET->m_nFrameCnt == 0 ) return false; if( pQJTVSET->m_nFrameCnt <= nStart ) return false; if( pQJTVSET->m_nFrameCnt < nStart+nCnt ) return false; return true; } bool SGameMultiQJTV::CreateTexture( KColor BackColor, int& nSrcWidth, int& nSrcHeight ) { int nExpX(nSrcWidth) ,nExpY(nSrcHeight); // K3DRenderDevice::GetSquareSize( nSrcWidth, nSrcHeight, nExpX, nExpY ); //택스처의 크기에 맞게 생성 if( KUITextureManager::GetHWType() == KUITextureManager::HW_SUPPORT ) { m_pTexture = m_pRenderDevice->CreateTexture( nExpX, nExpY, KUSAGE_DYNAMIC, K3DFMT_A8R8G8B8, D3DPOOL_DEFAULT ); } else //Intel Chip 계열에서 지원 안 되는 넘들이 있음. { m_pTexture = m_pRenderDevice->CreateTexture( nExpX, nExpY, K3DFMT_A8R8G8B8, D3DPOOL_MANAGED ); } if( m_pTexture == NULL ) return false; else { BYTE* pTextureBuf(NULL); int nStride(0); m_pTexture->LockRect( NULL, (void**)&pTextureBuf, nStride ); if( pTextureBuf == NULL ) { m_pTexture = NULL; assert( 0 && "QJTV Lock Failed !!!" ); return false; } for( UINT i(0); i < (UINT)(nExpY*nExpX); i++ ) { KColor* pColor = ( KColor* )pTextureBuf; pColor[i] = m_BackColor; } m_pTexture->Unlock(); } nSrcWidth = nExpX; nSrcHeight = nExpY; m_pResSprite->SetTexture(m_pTexture, NULL); //택스처 리소스스프라이트에 쎄팅 m_pSpritePrimitive.SetTargetSize( nSrcWidth, nSrcHeight ); return true; } bool SGameMultiQJTV::RefreshSeenTexture( sQJTV* pQJTVSET ) { if( !pQJTVSET || !pQJTVSET->m_bSuccessSetting || m_pTexture == NULL ) return false; int nTextureX(m_pTexture->GetWidth()), nTextureY(m_pTexture->GetHeight()); BYTE* pSrcBits(NULL); int nSrcWidth(0), nSrcHeight(0); pQJTVSET->m_QJTV.GetFrame( pQJTVSET->m_nCrrFrame, pSrcBits, nSrcWidth, nSrcHeight ); UINT StartX(0); UINT StartY(0); if( pQJTVSET->m_TextureOption & QJTV::CENTER ) { StartX = nTextureX/2-nSrcWidth/2; StartY = nTextureY/2-nSrcHeight/2; } BYTE* pTextureBuf(NULL); int nStride(0); KRect rcRock(StartX, StartY, StartX+nSrcWidth, StartY+nSrcHeight); m_pTexture->LockRect( &rcRock, (void**)&pTextureBuf, nStride ); if( pTextureBuf == NULL ) { m_pTexture = NULL; pQJTVSET->m_bSuccessCraeteTexture = false; assert( 0 && "QJTV Lock Failed!!!" ); return false; } KColor* pColor(NULL); for( UINT y(0); y < (UINT)nSrcHeight; y++ ) { pColor = (KColor*)pTextureBuf; for( UINT x(0); x < (UINT)nSrcWidth; ++x ) { KColor col; UINT Pos = (y*nSrcWidth +x)*4; col.b = pSrcBits[Pos+0]; col.g = pSrcBits[Pos+1]; col.r = pSrcBits[Pos+2]; if( pQJTVSET->m_TextureOption & QJTV::ALPHA ) col.a = pSrcBits[Pos+3]; else col.a = 255; //택스처에 있는 알파값을 사용하지 않는 경우 pColor[x] = col; } pTextureBuf += nStride; } m_pTexture->Unlock(); pQJTVSET->m_bSuccessCraeteTexture = true; return true; } bool SGameMultiQJTV::SetScreenCenter() { if( m_pRenderDevice == NULL || m_pTexture == NULL ) return false; KSize ScreenSize = m_pRenderDevice->GetScreenSize(); int nTextureX(m_pTexture->GetWidth()), nTextureY(m_pTexture->GetHeight()); int StartX = ScreenSize.width/2-nTextureX/2; int StartY = ScreenSize.height/2-nTextureY/2; m_Matrix.SetPosVector( K3DVertex( StartX, StartY, 0.1f ) ); m_pResSprite->SetTransform(m_Matrix); return true; } void SGameMultiQJTV::SetState( int nState ) { if( m_pCrrQJTV ) m_pCrrQJTV->m_nState = nState; } void SGameMultiQJTV::StartPlay( sQJTV* pQJTVSET, bool bRefreshTexture ) { if( pQJTVSET == NULL ) return; pQJTVSET->m_bPlay = true; pQJTVSET->m_OldFrameRenderTime = pQJTVSET->m_StartTime = GetSafeTickCount(); pQJTVSET->m_nCrrFrame = pQJTVSET->m_nStartFrame; if( bRefreshTexture ) RefreshSeenTexture( pQJTVSET ); pQJTVSET->m_nState = QJTV::PLAY; } void SGameMultiQJTV::Play( sQJTV* pQJTVSET, bool bRefreshTexture ) { if( pQJTVSET == NULL ) return; bool bOver( pQJTVSET->m_nCrrFrame+1 > (int)pQJTVSET->m_QJTV.GetFrameCount() ); if( !pQJTVSET->m_bRepeat && bOver ) { pQJTVSET->m_nState = QJTV::END; return; } float msFps = 1000.f / pQJTVSET->m_fixFps; if ( pQJTVSET->m_CrrTime - pQJTVSET->m_OldFrameRenderTime > msFps ) { ++pQJTVSET->m_nCrrFrame; pQJTVSET->m_OldFrameRenderTime = GetSafeTickCount(); if(bOver && pQJTVSET->m_bRepeat) pQJTVSET->m_nCrrFrame = pQJTVSET->m_nStartFrame; if( pQJTVSET->m_bSuccessCraeteTexture && pQJTVSET->m_nFrameCnt <= 1 ) return; if( bRefreshTexture ) RefreshSeenTexture( pQJTVSET ); } } void SGameMultiQJTV::OFF( sQJTV* pQJTVSET ) { if( pQJTVSET == NULL ) return; pQJTVSET->m_bPlay = false; pQJTVSET->m_nState = QJTV::OFF; } int SGameMultiQJTV::Render( KViewportObject *viewport, bool bFront/*=true*/ ) { //OFF이거나 STOP일때는 render안건다... if( !m_pCrrQJTV || m_pCrrQJTV->m_nState == QJTV::OFF ) return QJTV::OFF; // if( m_nState == QJTV::STOP ) return QJTV::STOP; viewport->Register( &m_pSpritePrimitive ); // viewport->Register( &m_pSpritePrimitive, bFront ); return m_pCrrQJTV->m_nState; } void SGameMultiQJTV::Proc( DWORD dwTime ) { int nSize( m_vecQJTV.size() ); for( int i(0); im_CrrTime = dwTime; if( !m_vecQJTV[i]->m_bSuccessSetting || m_pTexture == NULL || m_vecQJTV[i]->m_nState == QJTV::OFF ) return; bool bUpdateTexture( m_vecQJTV[i] == m_pCrrQJTV ); switch(m_vecQJTV[i]->m_nState) { case QJTV::STARTPLAY: StartPlay( m_vecQJTV[i], bUpdateTexture ); break; case QJTV::PLAY: Play( m_vecQJTV[i], bUpdateTexture ); break; case QJTV::OFF: OFF( m_vecQJTV[i] ); break; } } } int SGameMultiQJTV::SetOff() { if( !m_pCrrQJTV ) return QJTV::OFF; m_pCrrQJTV->m_bPlay = false; m_pCrrQJTV->m_nState = QJTV::OFF; return m_pCrrQJTV->m_nState; }