#include "common.h" #include "templates.h" #include "General.h" #include "Streaming.h" #include "RwHelper.h" #include "TxdStore.h" CPool *CTxdStore::ms_pTxdPool; RwTexDictionary *CTxdStore::ms_pStoredTxd; void CTxdStore::Initialise(void) { if(ms_pTxdPool == nil) ms_pTxdPool = new CPool(TXDSTORESIZE); } void CTxdStore::Shutdown(void) { if(ms_pTxdPool) delete ms_pTxdPool; } void CTxdStore::GameShutdown(void) { int i; for(i = 0; i < TXDSTORESIZE; i++){ TxdDef *def = GetSlot(i); if(def && GetNumRefs(i) == 0) RemoveTxdSlot(i); } } int CTxdStore::AddTxdSlot(const char *name) { TxdDef *def = ms_pTxdPool->New(); assert(def); def->texDict = nil; def->refCount = 0; strcpy(def->name, name); return ms_pTxdPool->GetJustIndex(def); } void CTxdStore::RemoveTxdSlot(int slot) { TxdDef *def = GetSlot(slot); if(def->texDict) RwTexDictionaryDestroy(def->texDict); ms_pTxdPool->Delete(def); } int CTxdStore::FindTxdSlot(const char *name) { char *defname; int size = ms_pTxdPool->GetSize(); for(int i = 0; i < size; i++){ defname = GetTxdName(i); if(defname && !CGeneral::faststricmp(defname, name)) return i; } return -1; } char* CTxdStore::GetTxdName(int slot) { TxdDef *def = GetSlot(slot); return def ? def->name : nil; } void CTxdStore::PushCurrentTxd(void) { ms_pStoredTxd = RwTexDictionaryGetCurrent(); } void CTxdStore::PopCurrentTxd(void) { RwTexDictionarySetCurrent(ms_pStoredTxd); ms_pStoredTxd = nil; } void CTxdStore::SetCurrentTxd(int slot) { TxdDef *def = GetSlot(slot); if(def) RwTexDictionarySetCurrent(def->texDict); } void CTxdStore::Create(int slot) { GetSlot(slot)->texDict = RwTexDictionaryCreate(); } int CTxdStore::GetNumRefs(int slot) { return GetSlot(slot)->refCount; } void CTxdStore::AddRef(int slot) { GetSlot(slot)->refCount++; } void CTxdStore::RemoveRef(int slot) { if(--GetSlot(slot)->refCount <= 0) CStreaming::RemoveModel(slot + STREAM_OFFSET_TXD); } void CTxdStore::RemoveRefWithoutDelete(int slot) { GetSlot(slot)->refCount--; } #ifdef RW_GL3 rw::Raster* convertTexRaster(rw::Raster* ras) { rw::Image* img = ras->toImage(); // ras->destroy(); img->unindex(); ras = rw::Raster::createFromImage(img); img->destroy(); return ras; } void convertTxd(rw::TexDictionary* txd) { rw::Texture* tex; FORLIST(lnk, txd->textures) { tex = rw::Texture::fromDict(lnk); rw::Raster* ras = tex->raster; if (ras && ras->platform != rw::platform) { if (!(ras->platform == rw::PLATFORM_D3D8 && rw::platform == rw::PLATFORM_D3D9 || ras->platform == rw::PLATFORM_D3D9 && rw::platform == rw::PLATFORM_D3D8)) { tex->raster = convertTexRaster(ras); ras->destroy(); } } tex->setFilter(rw::Texture::LINEAR); } } #endif bool CTxdStore::LoadTxd(int slot, RwStream *stream) { TxdDef *def = GetSlot(slot); if(RwStreamFindChunk(stream, rwID_TEXDICTIONARY, nil, nil)){ def->texDict = RwTexDictionaryGtaStreamRead(stream); #ifdef RW_GL3 convertTxd(def->texDict); #endif return def->texDict != nil; } printf("Failed to load TXD\n"); return false; } bool CTxdStore::LoadTxd(int slot, const char *filename) { RwStream *stream; bool ret; ret = false; _rwD3D8TexDictionaryEnableRasterFormatConversion(true); do stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename); while(stream == nil); ret = LoadTxd(slot, stream); RwStreamClose(stream, nil); return ret; } bool CTxdStore::StartLoadTxd(int slot, RwStream *stream) { TxdDef *def = GetSlot(slot); if(RwStreamFindChunk(stream, rwID_TEXDICTIONARY, nil, nil)){ def->texDict = RwTexDictionaryGtaStreamRead1(stream); return def->texDict != nil; }else{ printf("Failed to load TXD\n"); return false; } } bool CTxdStore::FinishLoadTxd(int slot, RwStream *stream) { TxdDef *def = GetSlot(slot); def->texDict = RwTexDictionaryGtaStreamRead2(stream, def->texDict); return def->texDict != nil; } void CTxdStore::RemoveTxd(int slot) { TxdDef *def = GetSlot(slot); if(def->texDict) RwTexDictionaryDestroy(def->texDict); def->texDict = nil; }