⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resfile.cpp

📁 一个3D的保龄球的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
* ============================================================================
*  Name     : CResFile from ResFile.cpp
*  Part of  : Game
*  Created  : 2003-06-16 by Qiu Wei Min
*  Implementation notes:
*  Modified : 2003-09-03 by Zheng Jie Sheng
*      To decompress from zlib compressed package. Using old packing tool. 
		Modified : 2004-10-04 by Wang Zhendong
*      To decompress from lzma compressed package. Using new packing tool. 
*  Version  :
*  Copyright: Gameloft S.A.
*
* ============================================================================
*/

// INCLUDE FILES
#include <AEE.h> 
#include <AEEfile.h> 
#include <AEEStdLib.h>
#include "simplememory.h"
#include "resfile.h"

#include "gfx.h"

//#include "game.h"

// ================= MEMBER FUNCTIONS =======================
// Base
//const int Sign8_cos[] = {0, 1, 1, 1, 0, -1, -1, -1};
//const int Sign8_sin[] = {-1, -1, 0, 1, 1, 1, 0, -1};

CResFile::CResFile(CEngine *pEngine)
{
	m_pEngine = pEngine;
	m_nEntry = 0;
	m_handle = NULL;	
	CSimpleMemory::Fill((void*)&m_f, 0, sizeof(FileIO));
	/*
	m_pZlib  = NULL;
	m_pZlib = new CZLibBrew();
	SYS_ASSERT(NULL != m_pZlib);
	if(m_pZlib)
	{
		
	}
	*/
}

CResFile::~CResFile()
{
	if(m_handle)
	{
		IFILE_Release((IFile*)m_handle);
		m_handle = NULL;
	}
	/*
	if(m_pZlib)
	{
		delete m_pZlib;
		m_pZlib = NULL;
	}
	*/
}

bool CResFile::Open(const char *fn)
{
	int iRet = 0;
	long nPak; //number of pakage entry

  m_handle = IFILEMGR_OpenFile ((IFileMgr*) m_pEngine->pFileMgr ,fn, _OFM_READ);
	SYS_ASSERT(NULL != m_handle);
	if(NULL ==m_handle)
		return false;
	m_f.isPaked = (char)(m_handle !=NULL);
	
	int size;
	iRet = IFILE_Read(m_handle, &nPak, sizeof(nPak)); 
	if(iRet != sizeof(nPak))
	{
		return false;
	}
	m_nEntry = (int)nPak;
	SYS_ASSERT(nPak >= 0 && nPak <=64000); //max file number on brew.
	size = sizeof(struct Pak ) + nPak *sizeof(struct PakEntry);


	m_f.pak = (struct Pak*)m_pEngine->GetMem()->GlobalMalloc(size);
	SYS_ASSERT(NULL != m_f.pak);
	if(NULL == m_f.pak)
		return false;
	IFILE_Seek(m_handle,_SEEK_START,0);
	IFILE_Read(m_handle, m_f.pak, size);

	return true;
}

void* CResFile::FindRecord(const char *name)
{
	unsigned long h = ComputeHash(name);
	int i;
	struct PakEntry *p;
	for(i=0, p=m_f.pak->aPak; i<m_f.pak->nPak; i++, p++){
		if(p->nameHash == h)
			return	p;//(void*)i;
	}
	SYS_ASSERT(0);//open failed
	return NULL;
}

unsigned long CResFile::ComputeHash(const char *s)
{
	unsigned long h=0;
	const char *p;
	for(p = s; *p ; p ++) 
		h = ( h << 5 ) - h + *p;
  return h;
}

void* CResFile::ReadToStack(void *hRecord)
{
	int len = GetDecompressedSize(hRecord);
	if(len>=0)
	{
		void* p = m_pEngine->GetMem()->StackMalloc(len);
		if(NULL != p)
		{
			if(Read(hRecord, p, len))
				return p;
			m_pEngine->GetMem()->StackFree(p);
		}
	}
	return NULL;
}

int CResFile::LoadFileToStack(const char *fName, void **pData)
{
	*pData = NULL;
	void *h = FindRecord(fName);
	SYS_ASSERT(NULL != h);
	if(NULL == h)
		return -1;
	void *p = ReadToStack(h);
	if(p)
	{
		int size = GetDecompressedSize(h);
		if(size >= 0)
		{
			*pData = p;
			return size;// read to stack ok
		}
		m_pEngine->GetMem()->StackFree(NULL);
	}
	return -1;
}

// Size after compression
int CResFile::GetRecordSize(void *hRecord)
{
	PakEntry *p = (PakEntry*)hRecord;
	SYS_ASSERT(p != NULL);
	if(NULL == p)
		return -1;
	return p->len;
}

// Size before compression
int CResFile::GetDecompressedSize(void *hRecord)
{
	int iRet = -1;
	PakEntry *p = (PakEntry*)hRecord;
	if(SUCCESS != IFILE_Seek((IFile*)m_handle, _SEEK_START, (p->start<<2)))
	{
		return -1;
	}

	unsigned char properties[5] ;
	int ii,outSize;	
	IFILE_Read((IFile*)m_handle,properties,5);
	outSize = 0;
	for (ii = 0; ii < 4; ii++)
	{
		unsigned char b;
		IFILE_Read((IFile*)m_handle,&b,1);
			
		outSize += (unsigned int)(b) << (ii * 8);
	}

	if (outSize == 0xFFFFFFFF)
	{
		//DBGPRINTF("outSize:%d",outSize);
		return NULL;
	}
	
	for (ii = 0; ii < 4; ii++)
	{
		unsigned char b;
		IFILE_Read((IFile*)m_handle,&b,1);
			
		if (b != 0)
		{
			//DBGPRINTF("\n too long file");
			return -1;
		}
	}
	return outSize;
}


bool CResFile::Read(void *hRecord, void *pBuf, int len, int ofs)
{
	struct PakEntry *p = (struct PakEntry*)hRecord;
	
	
	if(len == -1) 
		return false;		
	int iCompressedSize = GetRecordSize(hRecord);
	SYS_ASSERT( iCompressedSize >= 0);
	if(iCompressedSize < 0)
		return false;
	
	if(SUCCESS != IFILE_Seek((IFile*)m_handle, _SEEK_START, (p->start<<2)+ ofs))
	{
		return false;
	}
	unsigned int length;
	unsigned int compressedSize, outSize, outSizeProcessed, lzmaInternalSize;
	void *inStream,  *lzmaInternalData;
	unsigned char properties[5];
	unsigned char prop0;
	int ii;
	int lc, lp, pb;
	int res;
	long crc = 0;	
	length = iCompressedSize;
	IFILE_Read((IFile*)m_handle,properties,5);
	outSize = 0;
	for (ii = 0; ii < 4; ii++)
	{
		unsigned char b;
		IFILE_Read((IFile*)m_handle,&b,1);
		
		outSize += (unsigned int)(b) << (ii * 8);
	}
	
	if (outSize == 0xFFFFFFFF)
	{
		//DBGPRINTF("outSize:%d",outSize);
		return NULL;
	}
	
	for (ii = 0; ii < 4; ii++)
	{
		unsigned char b;
		IFILE_Read((IFile*)m_handle,&b,1);
		
		if (b != 0)
		{
			//DBGPRINTF("\n too long file");
			return false;
		}
	}
	
	compressedSize = length - 13;		
	inStream = m_pEngine->GetMem()->StackMalloc(compressedSize);
	if (inStream == NULL)
	{
		//DBGPRINTF("can't allocate1");
		return false;
	}
	IFILE_Read((IFile*)m_handle,inStream,compressedSize);		
				
	prop0 = properties[0];
	if (prop0 >= (9*5*5))
	{
		//DBGPRINTF("Properties error");
		return NULL;
	}
	for (pb = 0; prop0 >= (9 * 5); 
	pb++, prop0 -= (9 * 5));
	for (lp = 0; prop0 >= 9; 
	lp++, prop0 -= 9);
	lc = prop0;
	
	lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(unsigned short);	
	
	lzmaInternalData = m_pEngine->GetMem()->StackMalloc(lzmaInternalSize);
	if ( lzmaInternalData == 0)
	{
		//DBGPRINTF("can't allocate2");
		return NULL;
	}
	res = LzmaDecode((unsigned char *)lzmaInternalData, lzmaInternalSize,
		lc, lp, pb,           
#ifdef _LZMA_IN_CB
		&bo.InCallback,
#else
		(unsigned char *)inStream, compressedSize,
#endif
		(unsigned char *)pBuf, len, &outSizeProcessed,NULL);
	m_pEngine->GetMem()->StackFree(lzmaInternalData);
	m_pEngine->GetMem()->StackFree(inStream);
	if(res == 0)
		return true;
	else
		return false;
}

#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)

#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5


Byte CResFile::RangeDecoderReadByte(CRangeDecoder *rd)
{
  if (rd->Buffer == rd->BufferLim)
  {
    #ifdef _LZMA_IN_CB
    UInt32 size;
    rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
    rd->BufferLim = rd->Buffer + size;
    if (size == 0)
    #endif
    {
      rd->ExtraBytes = 1;
      return 0xFF;
    }
  }
  return (*rd->Buffer++);
}

/* #define ReadByte (*rd->Buffer++) */
#define ReadByte (RangeDecoderReadByte(rd))

void CResFile::RangeDecoderInit(CRangeDecoder *rd,
  #ifdef _LZMA_IN_CB
    ILzmaInCallback *inCallback
  #else
    Byte *stream, UInt32 bufferSize
  #endif
    )
{
  int i;
  #ifdef _LZMA_IN_CB
  rd->InCallback = inCallback;
  rd->Buffer = rd->BufferLim = 0;
  #else
  rd->Buffer = stream;
  rd->BufferLim = stream + bufferSize;
  #endif
  rd->ExtraBytes = 0;
  rd->Code = 0;
  rd->Range = (0xFFFFFFFF);
  for(i = 0; i < 5; i++)
    rd->Code = (rd->Code << 8) | ReadByte;
}

#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;        
#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }

UInt32 CResFile::RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
{
  RC_INIT_VAR
  UInt32 result = 0;
  int i;
  for (i = numTotalBits; i > 0; i--)
  {
    /* UInt32 t; */
    range >>= 1;

    result <<= 1;
    if (code >= range)
    {
      code -= range;
      result |= 1;
    }
    /*
    t = (code - range) >> 31;
    t &= 1;
    code -= range & (t - 1);
    result = (result + result) | (1 - t);
    */
    RC_NORMALIZE
  }
  RC_FLUSH_VAR
  return result;
}

int CResFile::RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
{
  UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
  if (rd->Code < bound)
  {
    rd->Range = bound;
    *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
    if (rd->Range < kTopValue)
    {
      rd->Code = (rd->Code << 8) | ReadByte;
      rd->Range <<= 8;
    }
    return 0;
  }
  else
  {
    rd->Range -= bound;
    rd->Code -= bound;
    *prob -= (*prob) >> kNumMoveBits;
    if (rd->Range < kTopValue)
    {
      rd->Code = (rd->Code << 8) | ReadByte;
      rd->Range <<= 8;
    }
    return 1;
  }
}

#define RC_GET_BIT2(prob, mi, A0, A1) \
  UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
  if (code < bound) \
    { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
  else \
    { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
  RC_NORMALIZE

#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)               

int CResFile::RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
{
  int mi = 1;
  int i;
  #ifdef _LZMA_LOC_OPT
  RC_INIT_VAR
  #endif
  for(i = numLevels; i > 0; i--)
  {
    #ifdef _LZMA_LOC_OPT
    CProb *prob = probs + mi;
    RC_GET_BIT(prob, mi)
    #else
    mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
    #endif
  }
  #ifdef _LZMA_LOC_OPT
  RC_FLUSH_VAR
  #endif
  return mi - (1 << numLevels);
}

int CResFile::RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
{
  int mi = 1;
  int i;
  int symbol = 0;
  #ifdef _LZMA_LOC_OPT
  RC_INIT_VAR
  #endif
  for(i = 0; i < numLevels; i++)
  {
    #ifdef _LZMA_LOC_OPT
    CProb *prob = probs + mi;
    RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
    #else
    int bit = RangeDecoderBitDecode(probs + mi, rd);
    mi = mi + mi + bit;
    symbol |= (bit << i);
    #endif
  }
  #ifdef _LZMA_LOC_OPT
  RC_FLUSH_VAR
  #endif
  return symbol;
}

Byte CResFile::LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
{ 
  int symbol = 1;
  #ifdef _LZMA_LOC_OPT
  RC_INIT_VAR
  #endif
  do
  {
    #ifdef _LZMA_LOC_OPT
    CProb *prob = probs + symbol;
    RC_GET_BIT(prob, symbol)
    #else
    symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
    #endif
  }
  while (symbol < 0x100);
  #ifdef _LZMA_LOC_OPT
  RC_FLUSH_VAR
  #endif
  return symbol;
}

Byte CResFile::LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
{ 
  int symbol = 1;
  #ifdef _LZMA_LOC_OPT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -