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

141 lines
3.1 KiB
C++

#include "QJTVObj.h"
#include <il/il.h>
#include <compress/XZip.h>
// QJTVObj
QJTVObj::QJTVObj()
{
m_pStream = NULL;
m_pMapper = NULL;
m_nCurWidth = 0;
m_nCurHeight = 0;
m_pBits = NULL;
m_pFrameArray = NULL;
ilInit();
ilEnable( IL_ORIGIN_SET );
ilOriginFunc( IL_ORIGIN_LOWER_LEFT );
ilEnable( IL_FORMAT_SET );
ilSetInteger( IL_FORMAT_MODE, IL_BGRA );
ilEnable( IL_FILE_OVERWRITE );
}
QJTVObj::~QJTVObj()
{
Clear();
}
void QJTVObj::Clear()
{
SAFE_DELETE( m_pMapper );
SAFE_DELETE( m_pStream );
m_vFrames.clear();
m_nCurWidth = 0;
m_nCurHeight = 0;
ClearBits();
}
void QJTVObj::ClearBits()
{
SAFE_DELETE( m_pBits );
}
void QJTVObj::AllocBits()
{
if( m_nCurWidth == 0 || m_nCurHeight == 0 )
return;
m_pBits = new BYTE[ m_nCurWidth * m_nCurHeight * 4 ];
}
void QJTVObj::Load( const trf::MetaData* pMeta, KStream* pStream )
{
Clear();
m_pStream = pStream;
_DetailLoad( pMeta, m_pStream );
}
void QJTVObj::Load( const trf::MetaData* pMeta, const char* szFile )
{
Clear();
m_pStream = new KFileStream( szFile );
_DetailLoad( pMeta, m_pStream );
}
void QJTVObj::_DetailLoad( const trf::MetaData* pMeta, KStream* pStream )
{
m_pMapper = new trf::Mapper( pMeta, pStream->GetMappedPtr( 0 ), ( int ) pStream->GetLength() );
trf::MDictPtr pRoot = m_pMapper->root();
for( int i = 0; i < pRoot->count(); i++ )
{
trf::MTemplatePtr pHeader = pRoot->getTemplateAt( i );
const char* szName = pHeader->className();
if( strcmp( szName, "nx3_jtv_header" ) == 0 )
{
trf::MDictPtr pData = pHeader->getDictBy( "data" );
m_pFrameArray = pData->getTemplateArrayBy( "frame_array" );
int numFrames = m_pFrameArray->count();
m_vFrames.reserve( numFrames );
for( int j = 0; j < numFrames; j++ )
{
trf::MTemplatePtr pFrame = m_pFrameArray->getTemplateAt( j );
trf::MDictPtr pFrameData = pFrame->getDictBy( "data" );
m_vFrames.push_back( pFrameData->getDWordBy( "frame" ) );
}
}
}
}
void QJTVObj::GetFrame( int nFrame, BYTE*& pBits, int& nWidth, int& nHeight )
{
int nFrameIndex = -1;
if( !m_vFrames.empty() )
{
nFrameIndex = std::lower_bound( m_vFrames.begin(), m_vFrames.end(), nFrame ) - m_vFrames.begin();
if( nFrameIndex == ( int ) m_vFrames.size() )
nFrameIndex--;
}
if( nFrameIndex < 0 )
return;
trf::MTemplatePtr pFrame = m_pFrameArray->getTemplateAt( nFrameIndex );
trf::MDictPtr pFrameData = pFrame->getDictBy( "data" );
int nFrameWidth = pFrameData->getDWordBy( "width" );
int nFrameHeight = pFrameData->getDWordBy( "height" );
trf::MArrayPtr pFrameBits = pFrameData->getArrayBy( "bits" );;
const BYTE* pSrcBits = pFrameBits->getByteArray();
int nSrcSize = pFrameBits->count();
int nOrgSize = XZip::GetOriginalSize( pSrcBits, nSrcSize );
if( nOrgSize != nFrameWidth * nFrameHeight * 4 )
{
assert( 0 );
return;
}
if( m_nCurWidth * m_nCurHeight < nFrameWidth * nFrameHeight )
{
m_nCurWidth = nFrameWidth;
m_nCurHeight = nFrameHeight;
ClearBits();
AllocBits();
}
if( !XZip::Uncompress( pSrcBits, nSrcSize, m_pBits, m_nCurWidth * m_nCurHeight * 4 ) )
return;
pBits = m_pBits;
nWidth = m_nCurWidth;
nHeight = m_nCurHeight;
}