From 3c0df895f115943fc4e37deb2b6fbfb2953f9196 Mon Sep 17 00:00:00 2001 From: aap Date: Sat, 19 Sep 2015 19:28:23 +0200 Subject: [PATCH] fixed bug with texture allocation --- librw.vcxproj | 1 + src/clump.cpp | 12 +- src/d3d.cpp | 69 +++++++--- src/d3d8.cpp | 15 +-- src/geometry.cpp | 9 ++ src/gtaplg.cpp | 7 +- src/image.cpp | 45 +++---- src/plugins.cpp | 25 ++-- src/ps2.cpp | 7 +- src/rwbase.cpp | 2 - src/rwbase.h | 4 +- src/rwd3d.h | 20 +-- src/rwobjects.h | 10 ++ src/rwps2.h | 7 +- src/rwxbox.h | 115 +++++++++++++++-- src/xbox.cpp | 214 +++++++++----------------------- tools/insttest/insttest.cpp | 17 ++- tools/insttest/insttest.vcxproj | 4 + tools/txdwrite/txdwrite.cpp | 70 ++++++++++- 19 files changed, 380 insertions(+), 273 deletions(-) diff --git a/librw.vcxproj b/librw.vcxproj index 7ec59e6..b023989 100644 --- a/librw.vcxproj +++ b/librw.vcxproj @@ -77,6 +77,7 @@ Disabled true _USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebug true diff --git a/src/clump.cpp b/src/clump.cpp index 7d9f695..9016a84 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -524,7 +524,7 @@ Atomic::getPipeline(void) { return this->pipeline ? this->pipeline : - defaultPipelines[platformIdx[platform]]; + defaultPipelines[platform]; } void @@ -533,15 +533,15 @@ Atomic::init(void) ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL); for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) defaultPipelines[i] = defpipe; - defaultPipelines[platformIdx[PLATFORM_PS2]] = + defaultPipelines[PLATFORM_PS2] = ps2::makeDefaultPipeline(); - defaultPipelines[platformIdx[PLATFORM_OGL]] = + defaultPipelines[PLATFORM_OGL] = gl::makeDefaultPipeline(); - defaultPipelines[platformIdx[PLATFORM_XBOX]] = + defaultPipelines[PLATFORM_XBOX] = xbox::makeDefaultPipeline(); - defaultPipelines[platformIdx[PLATFORM_D3D8]] = + defaultPipelines[PLATFORM_D3D8] = d3d8::makeDefaultPipeline(); - defaultPipelines[platformIdx[PLATFORM_D3D9]] = + defaultPipelines[PLATFORM_D3D9] = d3d9::makeDefaultPipeline(); } diff --git a/src/d3d.cpp b/src/d3d.cpp index ff9d5ce..45792e3 100644 --- a/src/d3d.cpp +++ b/src/d3d.cpp @@ -340,7 +340,7 @@ deleteObject(void *object) int32 nativeRasterOffset; void -makeNativeRaster(Raster *raster) +D3dRaster::create(Raster *raster) { static uint32 formatMap[] = { 0, @@ -366,46 +366,42 @@ makeNativeRaster(Raster *raster) 0, 0, 0, 0, 0, 0 }; - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); if(raster->flags & 0x80) return; uint32 format; if(raster->format & (Raster::PAL4 | Raster::PAL8)){ format = D3DFMT_P8; - ras->palette = new uint8[4*256]; + this->palette = new uint8[4*256]; }else format = formatMap[(raster->format >> 8) & 0xF]; - ras->format = 0; - ras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF]; + this->format = 0; + this->hasAlpha = alphaMap[(raster->format >> 8) & 0xF]; int32 levels = Raster::calculateNumLevels(raster->width, raster->height); - ras->texture = createTexture(raster->width, raster->width, - raster->format & Raster::MIPMAP ? levels : 1, - format); + this->texture = createTexture(raster->width, raster->height, + raster->format & Raster::MIPMAP ? levels : 1, + format); } uint8* -lockRaster(Raster *raster, int32 level) +D3dRaster::lock(Raster *raster, int32 level) { - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - return lockTexture(ras->texture, level); + return lockTexture(this->texture, level); } void -unlockRaster(Raster *raster, int32 level) +D3dRaster::unlock(Raster *raster, int32 level) { - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - unlockTexture(ras->texture, level); + unlockTexture(this->texture, level); } int32 -getNumLevels(Raster *raster) +D3dRaster::getNumLevels(Raster *raster) { - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); #ifdef RW_D3D9 - IDirect3DTexture9 *tex = (IDirect3DTexture9*)ras->texture; + IDirect3DTexture9 *tex = (IDirect3DTexture9*)this->texture; return tex->GetLevelCount(); #else - RasterLevels *levels = (RasterLevels*)ras->texture; + RasterLevels *levels = (RasterLevels*)this->texture; return levels->numlevels; #endif } @@ -425,11 +421,46 @@ getLevelSize(Raster *raster, int32 level) #endif } +void +allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha) +{ + static uint32 dxtMap[] = { + 0x31545844, // DXT1 + 0x32545844, // DXT2 + 0x33545844, // DXT3 + 0x34545844, // DXT4 + 0x35545844, // DXT5 + }; + D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); + ras->format = dxtMap[dxt-1]; + ras->hasAlpha = hasAlpha; + ras->texture = createTexture(raster->width, raster->height, + raster->format & Raster::MIPMAP ? numLevels : 1, + ras->format); + raster->flags &= ~0x80; +} + +void +setPalette(Raster *raster, void *palette, int32 size) +{ + D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); + memcpy(ras->palette, palette, 4*size); +} + +void +setTexels(Raster *raster, void *texels, int32 level) +{ + D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); + uint8 *dst = raster->lock(level); + memcpy(dst, texels, getLevelSize(raster, level)); + raster->unlock(level); +} static void* createNativeRaster(void *object, int32 offset, int32) { D3dRaster *raster = PLUGINOFFSET(D3dRaster, object, offset); + new (raster) D3dRaster; raster->texture = NULL; raster->palette = NULL; raster->format = 0; @@ -463,6 +494,8 @@ registerNativeRaster(void) createNativeRaster, destroyNativeRaster, copyNativeRaster); + Raster::nativeOffsets[PLATFORM_D3D8] = nativeRasterOffset; + Raster::nativeOffsets[PLATFORM_D3D9] = nativeRasterOffset; } } diff --git a/src/d3d8.cpp b/src/d3d8.cpp index ba5c510..5e6b696 100644 --- a/src/d3d8.cpp +++ b/src/d3d8.cpp @@ -385,13 +385,6 @@ makeMatFXPipeline(void) Texture* readNativeTexture(Stream *stream) { - static uint32 dxtMap[] = { - 0x31545844, // DXT1 - 0x32545844, // DXT2 - 0x33545844, // DXT3 - 0x34545844, // DXT4 - 0x35545844, // DXT5 - }; assert(findChunk(stream, ID_STRUCT, NULL, NULL)); assert(stream->readU32() == PLATFORM_D3D8); Texture *tex = new Texture; @@ -415,13 +408,7 @@ readNativeTexture(Stream *stream) D3dRaster *ras; if(compression){ raster = new Raster(width, height, depth, format | type | 0x80, PLATFORM_D3D8); - ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - ras->format = dxtMap[compression-1]; - ras->hasAlpha = hasAlpha; - ras->texture = createTexture(raster->width, raster->width, - raster->format & Raster::MIPMAP ? numLevels : 1, - ras->format); - raster->flags &= ~0x80; + allocateDXT(raster, compression, numLevels, hasAlpha); }else raster = new Raster(width, height, depth, format | type, PLATFORM_D3D8); diff --git a/src/geometry.cpp b/src/geometry.cpp index 4d635d3..598d41d 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -304,6 +304,11 @@ Geometry::generateTriangles(void) this->numTriangles = 0; Mesh *m = header->mesh; for(uint32 i = 0; i < header->numMeshes; i++){ + if(m->numIndices < 3){ + // shouldn't happen but it does + m++; + continue; + } if(header->flags == 1){ // tristrip for(uint32 j = 0; j < m->numIndices-2; j++){ if(!isDegenerate(&m->indices[j])) @@ -320,6 +325,10 @@ Geometry::generateTriangles(void) uint16 *f = this->triangles; m = header->mesh; for(uint32 i = 0; i < header->numMeshes; i++){ + if(m->numIndices < 3){ + m++; + continue; + } int32 matid = findPointer((void*)m->material, (void**)this->materialList, this->numMaterials); diff --git a/src/gtaplg.cpp b/src/gtaplg.cpp index eed108a..30e8be1 100644 --- a/src/gtaplg.cpp +++ b/src/gtaplg.cpp @@ -10,6 +10,7 @@ #include "rwpipeline.h" #include "rwobjects.h" #include "rwps2.h" +#include "rwd3d.h" #include "rwxbox.h" #include "gtaplg.h" @@ -21,7 +22,11 @@ void attachPlugins(void) { rw::ps2::registerPDSPlugin(); + rw::ps2::registerNativeRaster(); + rw::xbox::registerNativeRaster(); + rw::d3d::registerNativeRaster(); + rw::registerMeshPlugin(); rw::registerNativeDataPlugin(); rw::registerAtomicRightsPlugin(); @@ -36,7 +41,7 @@ attachPlugins(void) gta::registerExtraNormalsPlugin(); gta::registerExtraVertColorPlugin(); gta::registerEnvSpecPlugin(); - gta::registerBreakableModelPlugin(); +// gta::registerBreakableModelPlugin(); gta::registerCollisionPlugin(); gta::register2dEffectPlugin(); gta::registerPipelinePlugin(); diff --git a/src/image.cpp b/src/image.cpp index 4571696..9944428 100755 --- a/src/image.cpp +++ b/src/image.cpp @@ -532,6 +532,8 @@ writeTGA(Image *image, const char *filename) // Raster // +int32 Raster::nativeOffsets[NUM_PLATFORMS]; + Raster::Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform) { this->platform = platform ? platform : rw::platform; @@ -543,11 +545,11 @@ Raster::Raster(int32 width, int32 height, int32 depth, int32 format, int32 platf this->depth = depth; this->texels = this->palette = NULL; this->constructPlugins(); - if(this->platform == PLATFORM_D3D8 || - this->platform == PLATFORM_D3D9) - d3d::makeNativeRaster(this); - if(this->platform == PLATFORM_XBOX) - xbox::makeNativeRaster(this); + + int32 offset = nativeOffsets[this->platform]; + assert(offset != 0 && "unimplemented raster platform"); + NativeRaster *nr = PLUGINOFFSET(NativeRaster, this, offset); + nr->create(this); } Raster::~Raster(void) @@ -560,37 +562,28 @@ Raster::~Raster(void) uint8* Raster::lock(int32 level) { - if(this->platform == PLATFORM_D3D8 || - this->platform == PLATFORM_D3D9) - return d3d::lockRaster(this, level); - if(this->platform == PLATFORM_XBOX) - return xbox::lockRaster(this, level); - assert(0 && "unsupported raster platform"); - return NULL; + int32 offset = nativeOffsets[this->platform]; + assert(offset != 0 && "unimplemented raster platform"); + NativeRaster *nr = PLUGINOFFSET(NativeRaster, this, offset); + return nr->lock(this, level); } void Raster::unlock(int32 level) { - if(this->platform == PLATFORM_D3D8 || - this->platform == PLATFORM_D3D9) - d3d::unlockRaster(this, level); - else if(this->platform == PLATFORM_XBOX) - xbox::unlockRaster(this, level); - else - assert(0 && "unsupported raster platform"); + int32 offset = nativeOffsets[this->platform]; + assert(offset != 0 && "unimplemented raster platform"); + NativeRaster *nr = PLUGINOFFSET(NativeRaster, this, offset); + nr->unlock(this, level); } int32 Raster::getNumLevels(void) { - if(this->platform == PLATFORM_D3D8 || - this->platform == PLATFORM_D3D9) - return d3d::getNumLevels(this); - if(this->platform == PLATFORM_XBOX) - return xbox::getNumLevels(this); - assert(0 && "unsupported raster platform"); - return 1; + int32 offset = nativeOffsets[this->platform]; + assert(offset != 0 && "unimplemented raster platform"); + NativeRaster *nr = PLUGINOFFSET(NativeRaster, this, offset); + return nr->getNumLevels(this); } int32 diff --git a/src/plugins.cpp b/src/plugins.cpp index 966a9f2..288b19a 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -303,6 +303,7 @@ MeshHeader::allocateIndices(void) for(uint32 i = 0; i < this->numMeshes; i++){ mesh->indices = p; p += mesh->numIndices; + mesh++; } } @@ -597,7 +598,7 @@ getSizeSkin(void *object, int32 offset, int32) static void skinRights(void *object, int32, int32, uint32) { - ((Atomic*)object)->pipeline = skinGlobals.pipelines[platformIdx[rw::platform]]; + ((Atomic*)object)->pipeline = skinGlobals.pipelines[rw::platform]; } void @@ -608,15 +609,15 @@ registerSkinPlugin(void) defpipe->pluginData = 1; for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) skinGlobals.pipelines[i] = defpipe; - skinGlobals.pipelines[platformIdx[PLATFORM_PS2]] = + skinGlobals.pipelines[PLATFORM_PS2] = ps2::makeSkinPipeline(); - skinGlobals.pipelines[platformIdx[PLATFORM_OGL]] = + skinGlobals.pipelines[PLATFORM_OGL] = gl::makeSkinPipeline(); - skinGlobals.pipelines[platformIdx[PLATFORM_XBOX]] = + skinGlobals.pipelines[PLATFORM_XBOX] = xbox::makeSkinPipeline(); - skinGlobals.pipelines[platformIdx[PLATFORM_D3D8]] = + skinGlobals.pipelines[PLATFORM_D3D8] = d3d8::makeSkinPipeline(); - skinGlobals.pipelines[platformIdx[PLATFORM_D3D9]] = + skinGlobals.pipelines[PLATFORM_D3D9] = d3d9::makeSkinPipeline(); skinGlobals.offset = Geometry::registerPlugin(sizeof(Skin*), ID_SKIN, @@ -733,7 +734,7 @@ readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32) *PLUGINOFFSET(int32, object, offset) = flag; if(flag) ((Atomic*)object)->pipeline = - matFXGlobals.pipelines[platformIdx[rw::platform]]; + matFXGlobals.pipelines[rw::platform]; } static void @@ -1022,15 +1023,15 @@ registerMatFXPlugin(void) defpipe->pluginData = 0; for(uint i = 0; i < nelem(matFXGlobals.pipelines); i++) matFXGlobals.pipelines[i] = defpipe; - matFXGlobals.pipelines[platformIdx[PLATFORM_PS2]] = + matFXGlobals.pipelines[PLATFORM_PS2] = ps2::makeMatFXPipeline(); - matFXGlobals.pipelines[platformIdx[PLATFORM_OGL]] = + matFXGlobals.pipelines[PLATFORM_OGL] = gl::makeMatFXPipeline(); - matFXGlobals.pipelines[platformIdx[PLATFORM_XBOX]] = + matFXGlobals.pipelines[PLATFORM_XBOX] = xbox::makeMatFXPipeline(); - matFXGlobals.pipelines[platformIdx[PLATFORM_D3D8]] = + matFXGlobals.pipelines[PLATFORM_D3D8] = d3d8::makeMatFXPipeline(); - matFXGlobals.pipelines[platformIdx[PLATFORM_D3D9]] = + matFXGlobals.pipelines[PLATFORM_D3D9] = d3d9::makeMatFXPipeline(); matFXGlobals.atomicOffset = diff --git a/src/ps2.cpp b/src/ps2.cpp index 79418ab..1901ad7 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -1114,15 +1114,11 @@ sizedebug(InstanceData *inst) int32 nativeRasterOffset; -struct Ps2Raster -{ - int32 mipmap; -}; - static void* createNativeRaster(void *object, int32 offset, int32) { Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset); + new (raster) Ps2Raster; raster->mipmap = 0xFC0; return object; } @@ -1176,6 +1172,7 @@ registerNativeRaster(void) createNativeRaster, destroyNativeRaster, copyNativeRaster); + Raster::nativeOffsets[PLATFORM_PS2] = nativeRasterOffset; Texture::registerPlugin(0, ID_SKYMIPMAP, NULL, NULL, NULL); Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap); } diff --git a/src/rwbase.cpp b/src/rwbase.cpp index 1988076..f95c4dd 100644 --- a/src/rwbase.cpp +++ b/src/rwbase.cpp @@ -12,8 +12,6 @@ using namespace std; namespace rw { -int platformIdx[10] = { 0, -1, 1, -1, 2, 3, -1, -1, 4, 5 }; - int version = 0x36003; int build = 0xFFFF; #ifdef RW_PS2 diff --git a/src/rwbase.h b/src/rwbase.h index a4cfbb1..e5b87e2 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -105,11 +105,9 @@ enum Platform // SOFTRAS PLATFORM_D3D8 = 8, PLATFORM_D3D9 = 9, - NUM_PLATFORMS = 6 + NUM_PLATFORMS }; -extern int platformIdx[10]; - enum PluginID { // Core diff --git a/src/rwd3d.h b/src/rwd3d.h index 95b8035..4cf4a3a 100644 --- a/src/rwd3d.h +++ b/src/rwd3d.h @@ -70,22 +70,26 @@ uint8 *lockTexture(void *texture, int32 level); void unlockTexture(void *texture, int32 level); void deleteObject(void *object); -// Native Raster +// Native Texture and Raster -void makeNativeRaster(Raster *raster); -uint8 *lockRaster(Raster *raster, int32 level); -void unlockRaster(Raster *raster, int32 level); -int32 getNumLevels(Raster *raster); -int32 getLevelSize(Raster *raster, int32 level); - -struct D3dRaster +struct D3dRaster : NativeRaster { void *texture; void *palette; uint32 format; bool32 hasAlpha; + + virtual void create(Raster *raster); + virtual uint8 *lock(Raster *raster, int32 level); + virtual void unlock(Raster *raster, int32 level); + virtual int32 getNumLevels(Raster *raster); }; +int32 getLevelSize(Raster *raster, int32 level); +void allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha); +void setPalette(Raster *raster, void *palette, int32 size); +void setTexels(Raster *raster, void *texels, int32 level); + extern int32 nativeRasterOffset; void registerNativeRaster(void); diff --git a/src/rwobjects.h b/src/rwobjects.h index 3a0a683..9e571c4 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -118,6 +118,8 @@ struct Raster : PluginBase uint8 *texels; uint8 *palette; + static int32 nativeOffsets[NUM_PLATFORMS]; + Raster(int32 width, int32 height, int32 depth, int32 format, int32 platform = 0); ~Raster(void); @@ -146,6 +148,14 @@ struct Raster : PluginBase }; }; +struct NativeRaster +{ + virtual void create(Raster *raster) { assert (0 && "unimplemented"); }; + virtual uint8 *lock(Raster *raster, int32 level) { assert (0 && "unimplemented"); return NULL; }; + virtual void unlock(Raster *raster, int32 level) { assert (0 && "unimplemented"); }; + virtual int32 getNumLevels(Raster *raster) { assert (0 && "unimplemented"); return 0; }; +}; + // TODO: link into texdict struct Texture : PluginBase { diff --git a/src/rwps2.h b/src/rwps2.h index c1f86a3..211ef8c 100644 --- a/src/rwps2.h +++ b/src/rwps2.h @@ -116,7 +116,12 @@ void registerADCPlugin(void); void registerPDSPlugin(void); -// Raster +// Native Texture and Raster + +struct Ps2Raster : NativeRaster +{ + int32 mipmap; +}; extern int32 nativeRasterOffset; void registerNativeRaster(void); diff --git a/src/rwxbox.h b/src/rwxbox.h index f6b2d43..d0b1774 100644 --- a/src/rwxbox.h +++ b/src/rwxbox.h @@ -68,28 +68,119 @@ void registerVertexFormatPlugin(void); // Native Texture and Raster -void makeNativeRaster(Raster *raster); -uint8 *lockRaster(Raster *raster, int32 level); -void unlockRaster(Raster *raster, int32 level); -int32 getNumLevels(Raster *raster); -int32 getLevelSize(Raster *raster, int32 level); - -Texture *readNativeTexture(Stream *stream); -void writeNativeTexture(Texture *tex, Stream *stream); -uint32 getSizeNativeTexture(Texture *tex); - -struct XboxRaster +struct XboxRaster : NativeRaster { void *texture; void *palette; uint32 format; bool32 hasAlpha; bool32 unknownFlag; -// int32 compression; + + virtual void create(Raster *raster); + virtual uint8 *lock(Raster *raster, int32 level); + virtual void unlock(Raster *raster, int32 level); + virtual int32 getNumLevels(Raster *raster); }; +int32 getLevelSize(Raster *raster, int32 level); + extern int32 nativeRasterOffset; void registerNativeRaster(void); +Texture *readNativeTexture(Stream *stream); +void writeNativeTexture(Texture *tex, Stream *stream); +uint32 getSizeNativeTexture(Texture *tex); + +enum { + D3DFMT_UNKNOWN = 0xFFFFFFFF, + + /* Swizzled formats */ + + D3DFMT_A8R8G8B8 = 0x00000006, + D3DFMT_X8R8G8B8 = 0x00000007, + D3DFMT_R5G6B5 = 0x00000005, + D3DFMT_R6G5B5 = 0x00000027, + D3DFMT_X1R5G5B5 = 0x00000003, + D3DFMT_A1R5G5B5 = 0x00000002, + D3DFMT_A4R4G4B4 = 0x00000004, + D3DFMT_A8 = 0x00000019, + D3DFMT_A8B8G8R8 = 0x0000003A, + D3DFMT_B8G8R8A8 = 0x0000003B, + D3DFMT_R4G4B4A4 = 0x00000039, + D3DFMT_R5G5B5A1 = 0x00000038, + D3DFMT_R8G8B8A8 = 0x0000003C, + D3DFMT_R8B8 = 0x00000029, + D3DFMT_G8B8 = 0x00000028, + + D3DFMT_P8 = 0x0000000B, + + D3DFMT_L8 = 0x00000000, + D3DFMT_A8L8 = 0x0000001A, + D3DFMT_AL8 = 0x00000001, + D3DFMT_L16 = 0x00000032, + + D3DFMT_V8U8 = 0x00000028, + D3DFMT_L6V5U5 = 0x00000027, + D3DFMT_X8L8V8U8 = 0x00000007, + D3DFMT_Q8W8V8U8 = 0x0000003A, + D3DFMT_V16U16 = 0x00000033, + + D3DFMT_D16_LOCKABLE = 0x0000002C, + D3DFMT_D16 = 0x0000002C, + D3DFMT_D24S8 = 0x0000002A, + D3DFMT_F16 = 0x0000002D, + D3DFMT_F24S8 = 0x0000002B, + + /* YUV formats */ + + D3DFMT_YUY2 = 0x00000024, + D3DFMT_UYVY = 0x00000025, + + /* Compressed formats */ + + D3DFMT_DXT1 = 0x0000000C, + D3DFMT_DXT2 = 0x0000000E, + D3DFMT_DXT3 = 0x0000000E, + D3DFMT_DXT4 = 0x0000000F, + D3DFMT_DXT5 = 0x0000000F, + + /* Linear formats */ + + D3DFMT_LIN_A1R5G5B5 = 0x00000010, + D3DFMT_LIN_A4R4G4B4 = 0x0000001D, + D3DFMT_LIN_A8 = 0x0000001F, + D3DFMT_LIN_A8B8G8R8 = 0x0000003F, + D3DFMT_LIN_A8R8G8B8 = 0x00000012, + D3DFMT_LIN_B8G8R8A8 = 0x00000040, + D3DFMT_LIN_G8B8 = 0x00000017, + D3DFMT_LIN_R4G4B4A4 = 0x0000003E, + D3DFMT_LIN_R5G5B5A1 = 0x0000003D, + D3DFMT_LIN_R5G6B5 = 0x00000011, + D3DFMT_LIN_R6G5B5 = 0x00000037, + D3DFMT_LIN_R8B8 = 0x00000016, + D3DFMT_LIN_R8G8B8A8 = 0x00000041, + D3DFMT_LIN_X1R5G5B5 = 0x0000001C, + D3DFMT_LIN_X8R8G8B8 = 0x0000001E, + + D3DFMT_LIN_A8L8 = 0x00000020, + D3DFMT_LIN_AL8 = 0x0000001B, + D3DFMT_LIN_L16 = 0x00000035, + D3DFMT_LIN_L8 = 0x00000013, + + D3DFMT_LIN_V16U16 = 0x00000036, + D3DFMT_LIN_V8U8 = 0x00000017, + D3DFMT_LIN_L6V5U5 = 0x00000037, + D3DFMT_LIN_X8L8V8U8 = 0x0000001E, + D3DFMT_LIN_Q8W8V8U8 = 0x00000012, + + D3DFMT_LIN_D24S8 = 0x0000002E, + D3DFMT_LIN_F24S8 = 0x0000002F, + D3DFMT_LIN_D16 = 0x00000030, + D3DFMT_LIN_F16 = 0x00000031, + + D3DFMT_VERTEXDATA = 100, + D3DFMT_INDEX16 = 101, +}; + } } diff --git a/src/xbox.cpp b/src/xbox.cpp index 345dc52..010cfa0 100644 --- a/src/xbox.cpp +++ b/src/xbox.cpp @@ -16,97 +16,6 @@ using namespace std; namespace rw { namespace xbox { -enum { - D3DFMT_UNKNOWN = 0xFFFFFFFF, - - /* Swizzled formats */ - - D3DFMT_A8R8G8B8 = 0x00000006, - D3DFMT_X8R8G8B8 = 0x00000007, - D3DFMT_R5G6B5 = 0x00000005, - D3DFMT_R6G5B5 = 0x00000027, - D3DFMT_X1R5G5B5 = 0x00000003, - D3DFMT_A1R5G5B5 = 0x00000002, - D3DFMT_A4R4G4B4 = 0x00000004, - D3DFMT_A8 = 0x00000019, - D3DFMT_A8B8G8R8 = 0x0000003A, - D3DFMT_B8G8R8A8 = 0x0000003B, - D3DFMT_R4G4B4A4 = 0x00000039, - D3DFMT_R5G5B5A1 = 0x00000038, - D3DFMT_R8G8B8A8 = 0x0000003C, - D3DFMT_R8B8 = 0x00000029, - D3DFMT_G8B8 = 0x00000028, - - D3DFMT_P8 = 0x0000000B, - - D3DFMT_L8 = 0x00000000, - D3DFMT_A8L8 = 0x0000001A, - D3DFMT_AL8 = 0x00000001, - D3DFMT_L16 = 0x00000032, - - D3DFMT_V8U8 = 0x00000028, - D3DFMT_L6V5U5 = 0x00000027, - D3DFMT_X8L8V8U8 = 0x00000007, - D3DFMT_Q8W8V8U8 = 0x0000003A, - D3DFMT_V16U16 = 0x00000033, - - D3DFMT_D16_LOCKABLE = 0x0000002C, - D3DFMT_D16 = 0x0000002C, - D3DFMT_D24S8 = 0x0000002A, - D3DFMT_F16 = 0x0000002D, - D3DFMT_F24S8 = 0x0000002B, - - /* YUV formats */ - - D3DFMT_YUY2 = 0x00000024, - D3DFMT_UYVY = 0x00000025, - - /* Compressed formats */ - - D3DFMT_DXT1 = 0x0000000C, - D3DFMT_DXT2 = 0x0000000E, - D3DFMT_DXT3 = 0x0000000E, - D3DFMT_DXT4 = 0x0000000F, - D3DFMT_DXT5 = 0x0000000F, - - /* Linear formats */ - - D3DFMT_LIN_A1R5G5B5 = 0x00000010, - D3DFMT_LIN_A4R4G4B4 = 0x0000001D, - D3DFMT_LIN_A8 = 0x0000001F, - D3DFMT_LIN_A8B8G8R8 = 0x0000003F, - D3DFMT_LIN_A8R8G8B8 = 0x00000012, - D3DFMT_LIN_B8G8R8A8 = 0x00000040, - D3DFMT_LIN_G8B8 = 0x00000017, - D3DFMT_LIN_R4G4B4A4 = 0x0000003E, - D3DFMT_LIN_R5G5B5A1 = 0x0000003D, - D3DFMT_LIN_R5G6B5 = 0x00000011, - D3DFMT_LIN_R6G5B5 = 0x00000037, - D3DFMT_LIN_R8B8 = 0x00000016, - D3DFMT_LIN_R8G8B8A8 = 0x00000041, - D3DFMT_LIN_X1R5G5B5 = 0x0000001C, - D3DFMT_LIN_X8R8G8B8 = 0x0000001E, - - D3DFMT_LIN_A8L8 = 0x00000020, - D3DFMT_LIN_AL8 = 0x0000001B, - D3DFMT_LIN_L16 = 0x00000035, - D3DFMT_LIN_L8 = 0x00000013, - - D3DFMT_LIN_V16U16 = 0x00000036, - D3DFMT_LIN_V8U8 = 0x00000017, - D3DFMT_LIN_L6V5U5 = 0x00000037, - D3DFMT_LIN_X8L8V8U8 = 0x0000001E, - D3DFMT_LIN_Q8W8V8U8 = 0x00000012, - - D3DFMT_LIN_D24S8 = 0x0000002E, - D3DFMT_LIN_F24S8 = 0x0000002F, - D3DFMT_LIN_D16 = 0x00000030, - D3DFMT_LIN_F16 = 0x00000031, - - D3DFMT_VERTEXDATA = 100, - D3DFMT_INDEX16 = 101, -}; - void* destroyNativeData(void *object, int32, int32) { @@ -716,6 +625,8 @@ registerVertexFormatPlugin(void) // Native Texture and Raster +int32 nativeRasterOffset; + static uint32 calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format) { @@ -799,10 +710,7 @@ calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format) } } - -int32 nativeRasterOffset; - -void* +static void* createTexture(int32 width, int32 height, int32 numlevels, uint32 format) { int32 w = width; @@ -838,7 +746,7 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format) } void -makeNativeRaster(Raster *raster) +XboxRaster::create(Raster *raster) { static uint32 formatMap[] = { D3DFMT_UNKNOWN, @@ -870,41 +778,38 @@ makeNativeRaster(Raster *raster) 0, 0, 0, 0, 0, 0 }; - XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); if(raster->flags & 0x80) return; uint32 format; if(raster->format & (Raster::PAL4 | Raster::PAL8)){ format = D3DFMT_P8; - ras->palette = new uint8[4*256]; + this->palette = new uint8[4*256]; }else format = formatMap[(raster->format >> 8) & 0xF]; - ras->format = 0; - ras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF]; + this->format = 0; + this->hasAlpha = alphaMap[(raster->format >> 8) & 0xF]; int32 levels = Raster::calculateNumLevels(raster->width, raster->height); - ras->texture = createTexture(raster->width, raster->width, - raster->format & Raster::MIPMAP ? levels : 1, - format); + this->texture = createTexture(raster->width, raster->height, + raster->format & Raster::MIPMAP ? levels : 1, + format); } uint8* -lockRaster(Raster *raster, int32 level) +XboxRaster::lock(Raster *raster, int32 level) { - XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); - RasterLevels *levels = (RasterLevels*)ras->texture; + RasterLevels *levels = (RasterLevels*)this->texture; return levels->levels[level].data; } void -unlockRaster(Raster *raster, int32 level) +XboxRaster::unlock(Raster *raster, int32 level) { } int32 -getNumLevels(Raster *raster) +XboxRaster::getNumLevels(Raster *raster) { - XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); - RasterLevels *levels = (RasterLevels*)ras->texture; + RasterLevels *levels = (RasterLevels*)this->texture; return levels->numlevels; } @@ -916,6 +821,49 @@ getLevelSize(Raster *raster, int32 level) return levels->levels[level].size; } +static void* +createNativeRaster(void *object, int32 offset, int32) +{ + XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset); + new (raster) XboxRaster; + raster->texture = NULL; + raster->palette = NULL; + raster->format = 0; + raster->hasAlpha = 0; + raster->unknownFlag = 0; + return object; +} + +static void* +destroyNativeRaster(void *object, int32 offset, int32) +{ + // TODO: + return object; +} + +static void* +copyNativeRaster(void *dst, void *, int32 offset, int32) +{ + XboxRaster *raster = PLUGINOFFSET(XboxRaster, dst, offset); + raster->texture = NULL; + raster->palette = NULL; + raster->format = 0; + raster->hasAlpha = 0; + raster->unknownFlag = 0; + return dst; +} + +void +registerNativeRaster(void) +{ + nativeRasterOffset = Raster::registerPlugin(sizeof(XboxRaster), + 0x12340000 | PLATFORM_XBOX, + createNativeRaster, + destroyNativeRaster, + copyNativeRaster); + Raster::nativeOffsets[PLATFORM_XBOX] = nativeRasterOffset; +} + Texture* readNativeTexture(Stream *stream) { @@ -949,7 +897,7 @@ readNativeTexture(Stream *stream) XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); ras->format = compression; ras->hasAlpha = hasAlpha; - ras->texture = createTexture(raster->width, raster->width, + ras->texture = createTexture(raster->width, raster->height, raster->format & Raster::MIPMAP ? numLevels : 1, ras->format); raster->flags &= ~0x80; @@ -1035,49 +983,5 @@ getSizeNativeTexture(Texture *tex) return size; } -static void* -createNativeRaster(void *object, int32 offset, int32) -{ - XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset); - raster->texture = NULL; - raster->palette = NULL; - raster->format = 0; - raster->hasAlpha = 0; - raster->unknownFlag = 0; -// raster->compression = 0; - return object; -} - -static void* -destroyNativeRaster(void *object, int32 offset, int32) -{ - // TODO: - return object; -} - -static void* -copyNativeRaster(void *dst, void *, int32 offset, int32) -{ - XboxRaster *raster = PLUGINOFFSET(XboxRaster, dst, offset); - raster->texture = NULL; - raster->palette = NULL; - raster->format = 0; - raster->hasAlpha = 0; - raster->unknownFlag = 0; -// raster->compression = 0; - return dst; -} - -void -registerNativeRaster(void) -{ - nativeRasterOffset = Raster::registerPlugin(sizeof(XboxRaster), - 0x12340000 | PLATFORM_XBOX, - createNativeRaster, - destroyNativeRaster, - copyNativeRaster); -} - - } } diff --git a/tools/insttest/insttest.cpp b/tools/insttest/insttest.cpp index 7f54f73..933d86f 100644 --- a/tools/insttest/insttest.cpp +++ b/tools/insttest/insttest.cpp @@ -15,10 +15,10 @@ main(int argc, char *argv[]) { gta::attachPlugins(); -// rw::version = 0x33002; - rw::platform = rw::PLATFORM_PS2; + rw::version = 0x34003; +// rw::platform = rw::PLATFORM_PS2; // rw::platform = rw::PLATFORM_OGL; -// rw::platform = rw::PLATFORM_XBOX; + rw::platform = rw::PLATFORM_XBOX; // rw::platform = rw::PLATFORM_D3D8; // rw::platform = rw::PLATFORM_D3D9; @@ -32,7 +32,7 @@ main(int argc, char *argv[]) if(strcmp(argv[arg], "-u") == 0){ uninstance++; - arg++; + arg++; if(argc < 3){ printf("usage: %s [-u] in.dff\n", argv[0]); return 0; @@ -82,6 +82,9 @@ main(int argc, char *argv[]) p->instance(a); } + if(uninstance) + rw::platform = rw::PLATFORM_D3D8; + data = new rw::uint8[1024*1024]; rw::StreamMemory out; out.open(data, 0, 1024*1024); @@ -89,7 +92,11 @@ main(int argc, char *argv[]) currentUVAnimDictionary->streamWrite(&out); c->streamWrite(&out); - FILE *cf = fopen("out.dff", "wb"); + FILE *cf; + if(arg+1 < argc) + cf = fopen(argv[arg+1], "wb"); + else + cf = fopen("out.dff", "wb"); assert(cf != NULL); fwrite(data, out.getLength(), 1, cf); fclose(cf); diff --git a/tools/insttest/insttest.vcxproj b/tools/insttest/insttest.vcxproj index 11826d3..597be6f 100644 --- a/tools/insttest/insttest.vcxproj +++ b/tools/insttest/insttest.vcxproj @@ -81,11 +81,15 @@ Disabled true _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebug true librw.lib;%(AdditionalDependencies) + + copy /y "$(TargetPath)" "C:\Users\aap\bin\" + diff --git a/tools/txdwrite/txdwrite.cpp b/tools/txdwrite/txdwrite.cpp index b8a7354..1cd0479 100644 --- a/tools/txdwrite/txdwrite.cpp +++ b/tools/txdwrite/txdwrite.cpp @@ -10,15 +10,67 @@ using namespace std; using namespace rw; +Raster* +xboxToD3d8(Raster *raster) +{ + using namespace xbox; + + Raster *newras; + if(raster->platform != PLATFORM_XBOX) + return raster; + XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); + + int32 numLevels = raster->getNumLevels(); + + int32 format = raster->format; +// format &= ~Raster::MIPMAP; + if(ras->format){ + newras = new Raster(raster->width, raster->height, raster->depth, + format | raster->type | 0x80, PLATFORM_D3D8); + int32 dxt = 0; + switch(ras->format){ + case D3DFMT_DXT1: + dxt = 1; + break; + case D3DFMT_DXT3: + dxt = 3; + break; + case D3DFMT_DXT5: + dxt = 5; + break; + } + d3d::allocateDXT(newras, dxt, numLevels, ras->hasAlpha); + }else{ + printf("swizzled!\n"); + newras = new Raster(raster->width, raster->height, raster->depth, + format | raster->type, PLATFORM_D3D8); + } + + if(raster->format & Raster::PAL4) + d3d::setPalette(newras, ras->palette, 32); + else if(raster->format & Raster::PAL8) + d3d::setPalette(newras, ras->palette, 256); + + uint8 *data; + for(int32 i = 0; i < numLevels; i++){ + if(i >= newras->getNumLevels()) + break; + data = raster->lock(i); + d3d::setTexels(newras, data, i); + raster->unlock(i); + } + + delete raster; + return newras; +} + int main(int argc, char *argv[]) { gta::attachPlugins(); - rw::ps2::registerNativeRaster(); - rw::xbox::registerNativeRaster(); - rw::d3d::registerNativeRaster(); // rw::version = 0x33002; + rw::version = 0x32000; // rw::platform = rw::PLATFORM_PS2; // rw::platform = rw::PLATFORM_OGL; // rw::platform = rw::PLATFORM_XBOX; @@ -32,7 +84,7 @@ main(int argc, char *argv[]) rw::StreamFile in; if(in.open(argv[1], "rb") == NULL){ - printf("couldn't open file\n"); + printf("couldn't open file %s\n", argv[1]); return 1; } rw::findChunk(&in, rw::ID_TEXDICTIONARY, NULL, NULL); @@ -42,8 +94,16 @@ main(int argc, char *argv[]) in.close(); rw::currentTexDictionary = txd; +// for(Texture *tex = txd->first; tex; tex = tex->next) +// tex->raster = xboxToD3d8(tex->raster); + for(Texture *tex = txd->first; tex; tex = tex->next) + tex->filterAddressing = (tex->filterAddressing&~0xF) | 0x2; + rw::StreamFile out; - out.open("out.txd", "wb"); + if(argc > 2) + out.open(argv[2], "wb"); + else + out.open("out.txd", "wb"); txd->streamWrite(&out); out.close();