From ee96da332f451750abe23d023fe3fef42b6032a3 Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 17 Sep 2015 10:44:07 +0200 Subject: [PATCH] added palette support --- src/d3d.cpp | 8 ++++++-- src/d3d8.cpp | 18 ++++++++++++++++-- src/image.cpp | 15 ++++++++++++--- src/rwobjects.h | 2 +- src/xbox.cpp | 24 ++++++++++++++++++++---- tools/d3d9/d3dInit.cpp | 3 ++- tools/txdwrite/txdwrite.cpp | 5 +++-- 7 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/d3d.cpp b/src/d3d.cpp index 3b26093..ff9d5ce 100644 --- a/src/d3d.cpp +++ b/src/d3d.cpp @@ -369,14 +369,18 @@ makeNativeRaster(Raster *raster) D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); if(raster->flags & 0x80) return; - uint32 format = formatMap[(raster->format >> 8) & 0xF]; + uint32 format; + if(raster->format & (Raster::PAL4 | Raster::PAL8)){ + format = D3DFMT_P8; + ras->palette = new uint8[4*256]; + }else + format = formatMap[(raster->format >> 8) & 0xF]; ras->format = 0; ras->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); - assert((raster->flags & (Raster::PAL4 | Raster::PAL8)) == 0); } uint8* diff --git a/src/d3d8.cpp b/src/d3d8.cpp index 92d9cc9..ba5c510 100644 --- a/src/d3d8.cpp +++ b/src/d3d8.cpp @@ -424,11 +424,16 @@ readNativeTexture(Stream *stream) raster->flags &= ~0x80; }else raster = new Raster(width, height, depth, format | type, PLATFORM_D3D8); + + ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); tex->raster = raster; // TODO: check if format supported and convert if necessary - if(raster->format & (Raster::PAL4 | Raster::PAL8)) - assert(0 && "don't support palettes"); + + if(raster->format & Raster::PAL4) + stream->read(ras->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->read(ras->palette, 4*256); uint32 size; uint8 *data; @@ -491,6 +496,11 @@ writeNativeTexture(Texture *tex, Stream *stream) } stream->writeU8(compression); + if(raster->format & Raster::PAL4) + stream->write(ras->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->write(ras->palette, 4*256); + uint32 size; uint8 *data; for(int32 i = 0; i < numLevels; i++){ @@ -508,6 +518,10 @@ getSizeNativeTexture(Texture *tex) { uint32 size = 12 + 72 + 16; int32 levels = tex->raster->getNumLevels(); + if(tex->raster->format & Raster::PAL4) + size += 4*32; + else if(tex->raster->format & Raster::PAL8) + size += 4*256; for(int32 i = 0; i < levels; i++) size += 4 + getLevelSize(tex->raster, i); size += 12 + tex->streamGetPluginSize(); diff --git a/src/image.cpp b/src/image.cpp index 44a5888..4571696 100755 --- a/src/image.cpp +++ b/src/image.cpp @@ -208,10 +208,19 @@ Texture::streamGetSize(void) Texture* Texture::streamReadNative(Stream *stream) { - if(rw::platform == PLATFORM_D3D8) + assert(findChunk(stream, ID_STRUCT, NULL, NULL)); + uint32 platform = stream->readU32(); + stream->seek(-16); + if(platform == PLATFORM_D3D8) return d3d8::readNativeTexture(stream); - if(rw::platform == PLATFORM_XBOX) + if(platform == PLATFORM_XBOX) return xbox::readNativeTexture(stream); + +// if(rw::platform == PLATFORM_D3D8) +// return d3d8::readNativeTexture(stream); +// if(rw::platform == PLATFORM_XBOX) +// return xbox::readNativeTexture(stream); + assert(0 && "unsupported platform"); return NULL; } @@ -533,12 +542,12 @@ Raster::Raster(int32 width, int32 height, int32 depth, int32 format, int32 platf this->height = height; 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); - this->constructPlugins(); } Raster::~Raster(void) diff --git a/src/rwobjects.h b/src/rwobjects.h index 41f3e59..3a0a683 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -429,7 +429,7 @@ private: void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf); }; -struct TexDictionary : PluginBase +struct TexDictionary : PluginBase { Texture *first; diff --git a/src/xbox.cpp b/src/xbox.cpp index 2aba5a9..345dc52 100644 --- a/src/xbox.cpp +++ b/src/xbox.cpp @@ -873,14 +873,18 @@ makeNativeRaster(Raster *raster) XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); if(raster->flags & 0x80) return; - uint32 format = formatMap[(raster->format >> 8) & 0xF]; + uint32 format; + if(raster->format & (Raster::PAL4 | Raster::PAL8)){ + format = D3DFMT_P8; + ras->palette = new uint8[4*256]; + }else + format = formatMap[(raster->format >> 8) & 0xF]; ras->format = 0; ras->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); - assert((raster->flags & (Raster::PAL4 | Raster::PAL8)) == 0); } uint8* @@ -951,10 +955,13 @@ readNativeTexture(Stream *stream) raster->flags &= ~0x80; }else raster = new Raster(width, height, depth, format | type, PLATFORM_XBOX); + XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); tex->raster = raster; - if(raster->format & (Raster::PAL4 | Raster::PAL8)) - assert(0 && "don't support palettes"); + if(raster->format & Raster::PAL4) + stream->read(ras->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->read(ras->palette, 4*256); // exploit the fact that mipmaps are allocated consecutively uint8 *data = raster->lock(0); @@ -999,6 +1006,11 @@ writeNativeTexture(Texture *tex, Stream *stream) totalSize = (totalSize+3)&~3; stream->writeI32(totalSize); + if(raster->format & Raster::PAL4) + stream->write(ras->palette, 4*32); + else if(raster->format & Raster::PAL8) + stream->write(ras->palette, 4*256); + // exploit the fact that mipmaps are allocated consecutively uint8 *data = raster->lock(0); stream->write(data, totalSize); @@ -1015,6 +1027,10 @@ getSizeNativeTexture(Texture *tex) for(int32 i = 0; i < levels; i++) size += getLevelSize(tex->raster, i); size = (size+3)&~3; + if(tex->raster->format & Raster::PAL4) + size += 4*32; + else if(tex->raster->format & Raster::PAL8) + size += 4*256; size += 12 + tex->streamGetPluginSize(); return size; } diff --git a/tools/d3d9/d3dInit.cpp b/tools/d3d9/d3dInit.cpp index 5944b92..1fb75f4 100644 --- a/tools/d3d9/d3dInit.cpp +++ b/tools/d3d9/d3dInit.cpp @@ -188,7 +188,7 @@ initrw(void) rw::platform = rw::PLATFORM_D3D8; rw::d3d::device = Device; - if(0){ + if(1){ char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.txd"; rw::StreamFile in; if(in.open(filename, "rb") == NULL){ @@ -209,6 +209,7 @@ initrw(void) } char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\admiral.dff"; +// char *filename = "D:\\rockstargames\\pc\\gta3\\models\\gta3_archive\\kuruma.dff"; // char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\player.dff"; // char *filename = "D:\\rockstargames\\pc\\gtavc\\models\\gta3_archive\\od_newscafe_dy.dff"; // char *filename = "D:\\rockstargames\\pc\\gtasa\\models\\gta3_archive\\admiral.dff"; diff --git a/tools/txdwrite/txdwrite.cpp b/tools/txdwrite/txdwrite.cpp index 626caab..b8a7354 100644 --- a/tools/txdwrite/txdwrite.cpp +++ b/tools/txdwrite/txdwrite.cpp @@ -14,18 +14,19 @@ int main(int argc, char *argv[]) { gta::attachPlugins(); + rw::ps2::registerNativeRaster(); rw::xbox::registerNativeRaster(); rw::d3d::registerNativeRaster(); // rw::version = 0x33002; // 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; if(argc < 2){ - printf("usage: %s in.txd\n", argv[0]); + printf("usage (%d): %s in.txd\n", rw::platform, argv[0]); return 0; }