diff --git a/TODO b/TODO index ae3f2fe..a216054 100644 --- a/TODO +++ b/TODO @@ -22,22 +22,17 @@ Clump & related: Skin (old III dffs) Geometry ((Morph)) 0x105 - Texture - (Sky Mipmap Val) 0x110 - only stubs: R* 2dfx 0x253F2F8 R* Collision 0x253F2FA -Texture Dictionary - -.anm/.ska - -- anim interpolation (only stubs right now) +Texture Dictionary / Native Textures - Pipelines (PDS, Xbox, PC) -- ADC +- ADC conversion - uninstance geometry (PS2) +- anim interpolation (only stubs right now) diff --git a/src/anim.cpp b/src/anim.cpp index 823da00..240ea97 100644 --- a/src/anim.cpp +++ b/src/anim.cpp @@ -66,9 +66,30 @@ Animation::streamRead(Stream *stream) return anim; } +Animation* +Animation::streamReadLegacy(Stream *stream) +{ + Animation *anim; + AnimInterpolatorInfo *interpInfo = findAnimInterpolatorInfo(1); + int32 numFrames = stream->readI32(); + int32 flags = stream->readI32(); + float duration = stream->readF32(); + anim = new Animation(interpInfo, numFrames, flags, duration); + HAnimKeyFrame *frames = (HAnimKeyFrame*)anim->keyframes; + for(int32 i = 0; i < anim->numFrames; i++){ + stream->read(frames[i].q, 4*4); + stream->read(frames[i].t, 3*4); + frames[i].time = stream->readF32(); + int32 prev = stream->readI32(); + frames[i].prev = &frames[prev]; + } + return anim; +} + bool Animation::streamWrite(Stream *stream) { + writeChunkHeader(stream, ID_ANIMANIMATION, this->streamGetSize()); stream->writeI32(0x100); stream->writeI32(this->interpInfo->id); stream->writeI32(this->numFrames); @@ -78,6 +99,23 @@ Animation::streamWrite(Stream *stream) return true; } +bool +Animation::streamWriteLegacy(Stream *stream) +{ + stream->writeI32(this->numFrames); + stream->writeI32(this->flags); + stream->writeF32(this->duration); + assert(interpInfo->id == 1); + HAnimKeyFrame *frames = (HAnimKeyFrame*)this->keyframes; + for(int32 i = 0; i < this->numFrames; i++){ + stream->write(frames[i].q, 4*4); + stream->write(frames[i].t, 3*4); + stream->writeF32(frames[i].time); + stream->writeI32(frames[i].prev - frames); + } + return true; +} + uint32 Animation::streamGetSize(void) { @@ -114,10 +152,8 @@ UVAnimDictionary::streamWrite(Stream *stream) writeChunkHeader(stream, ID_UVANIMDICT, size); writeChunkHeader(stream, ID_STRUCT, 4); stream->writeI32(this->numAnims); - for(int32 i = 0; i < this->numAnims; i++){ - writeChunkHeader(stream, ID_ANIMANIMATION, this->anims[i]->streamGetSize()); + for(int32 i = 0; i < this->numAnims; i++) this->anims[i]->streamWrite(stream); - } return true; } @@ -241,6 +277,19 @@ copyUVAnim(void *dst, void *src, int32 offset, int32) return dst; } +Animation* +makeDummyAnimation(const char *name) +{ + AnimInterpolatorInfo *interpInfo = findAnimInterpolatorInfo(0x1C0); + Animation *anim = new Animation(interpInfo, 2, 0, 1.0f); + UVAnimCustomData *custom = (UVAnimCustomData*)anim->customData; +// UVAnimKeyFrame *frames = (UVAnimKeyFrame*)anim->keyframes; + strncpy(custom->name, name, 32); + memset(custom->nodeToUVChannel, 0, sizeof(custom->nodeToUVChannel)); + // TODO: init the frames + return anim; +} + static void readUVAnim(Stream *stream, int32, void *object, int32 offset, int32) { @@ -252,8 +301,11 @@ readUVAnim(Stream *stream, int32, void *object, int32 offset, int32) for(int32 i = 0; i < 8; i++){ if(mask & bit){ stream->read(name, 32); - assert(currentUVAnimDictionary != NULL); - Animation *anim = currentUVAnimDictionary->find(name); + Animation *anim = NULL; + if(currentUVAnimDictionary) + anim = currentUVAnimDictionary->find(name); + if(anim == NULL) + anim = makeDummyAnimation(name); AnimInterpolator *interp = new AnimInterpolator(anim); uvanim->interp[i] = interp; } diff --git a/src/gtaplg.cpp b/src/gtaplg.cpp index f675bd6..eed108a 100644 --- a/src/gtaplg.cpp +++ b/src/gtaplg.cpp @@ -21,6 +21,7 @@ void attachPlugins(void) { rw::ps2::registerPDSPlugin(); + rw::ps2::registerNativeRaster(); rw::registerMeshPlugin(); rw::registerNativeDataPlugin(); rw::registerAtomicRightsPlugin(); diff --git a/src/image.cpp b/src/image.cpp index c60820a..be4fd54 100755 --- a/src/image.cpp +++ b/src/image.cpp @@ -90,9 +90,10 @@ Texture::read(const char *name, const char *mask) if(img){ raster = Raster::createFromImage(img); delete img; - } + }else + raster = new Raster; tex->raster = raster; - if(currentTexDictionary) + if(currentTexDictionary && img) currentTexDictionary->add(tex); return tex; } @@ -103,9 +104,10 @@ Texture::streamRead(Stream *stream) uint32 length; char name[32], mask[32]; assert(findChunk(stream, ID_STRUCT, NULL, NULL)); - uint32 filterAddressing = stream->readU16(); - // TODO: what is this? (mipmap? i think) - stream->seek(2); + uint32 filterAddressing = stream->readU32(); + // TODO: if V addressing is 0, copy U + // if using mipmap filter mode, set automipmapping, + // if 0x10000 is set, set mipmapping assert(findChunk(stream, ID_STRING, &length, NULL)); stream->read(name, length); @@ -115,7 +117,8 @@ Texture::streamRead(Stream *stream) Texture *tex = Texture::read(name, mask); tex->refCount++; - tex->filterAddressing = filterAddressing; + if(tex->refCount == 1) + tex->filterAddressing = filterAddressing; tex->streamReadPlugins(stream); diff --git a/src/ogl.cpp b/src/ogl.cpp index 7d44edc..e6557d2 100644 --- a/src/ogl.cpp +++ b/src/ogl.cpp @@ -683,7 +683,7 @@ void registerNativeRaster(void) { nativeRasterOffset = Raster::registerPlugin(sizeof(GlRaster), - 0x12340001, + 0x12340000 | PLATFORM_OGL, createNativeRaster, destroyNativeRaster, copyNativeRaster); diff --git a/src/plugins.cpp b/src/plugins.cpp index 970cd3d..966a9f2 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -66,10 +66,7 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32) int32 ver, numNodes; HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset); ver = stream->readI32(); - if(ver != 0x100){ - fprintf(stderr, "hanim ver was not 0x100\n"); - return; - } + assert(ver == 0x100); hanim->id = stream->readI32(); numNodes = stream->readI32(); if(numNodes != 0){ @@ -131,6 +128,37 @@ getSizeHAnim(void *object, int32 offset, int32) return 12; } +static void +hAnimFrameRead(Stream *stream, Animation *anim) +{ + HAnimKeyFrame *frames = (HAnimKeyFrame*)anim->keyframes; + for(int32 i = 0; i < anim->numFrames; i++){ + frames[i].time = stream->readF32(); + stream->read(frames[i].q, 4*4); + stream->read(frames[i].t, 3*4); + int32 prev = stream->readI32(); + frames[i].prev = &frames[prev]; + } +} + +static void +hAnimFrameWrite(Stream *stream, Animation *anim) +{ + HAnimKeyFrame *frames = (HAnimKeyFrame*)anim->keyframes; + for(int32 i = 0; i < anim->numFrames; i++){ + stream->writeF32(frames[i].time); + stream->write(frames[i].q, 4*4); + stream->write(frames[i].t, 3*4); + stream->writeI32(frames[i].prev - frames); + } +} + +static uint32 +hAnimFrameGetSize(Animation *anim) +{ + return anim->numFrames*(4 + 4*4 + 3*4 + 4); +} + void registerHAnimPlugin(void) { @@ -141,6 +169,15 @@ registerHAnimPlugin(void) readHAnim, writeHAnim, getSizeHAnim); + + AnimInterpolatorInfo *info = new AnimInterpolatorInfo; + info->id = 1; + info->keyFrameSize = sizeof(HAnimKeyFrame); + info->customDataSize = sizeof(HAnimKeyFrame); + info->streamRead = hAnimFrameRead; + info->streamWrite = hAnimFrameWrite; + info->streamGetSize = hAnimFrameGetSize; + registerAnimInterpolatorInfo(info); } diff --git a/src/ps2.cpp b/src/ps2.cpp index 5e02cc3..79418ab 100644 --- a/src/ps2.cpp +++ b/src/ps2.cpp @@ -1110,5 +1110,75 @@ sizedebug(InstanceData *inst) } } +// Raster + +int32 nativeRasterOffset; + +struct Ps2Raster +{ + int32 mipmap; +}; + +static void* +createNativeRaster(void *object, int32 offset, int32) +{ + Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset); + raster->mipmap = 0xFC0; + return object; +} + +static void* +destroyNativeRaster(void *object, int32 offset, int32) +{ + return object; +} + +static void* +copyNativeRaster(void *dst, void *src, int32 offset, int32) +{ + Ps2Raster *dstraster = PLUGINOFFSET(Ps2Raster, dst, offset); + Ps2Raster *srcraster = PLUGINOFFSET(Ps2Raster, src, offset); + dstraster->mipmap = srcraster->mipmap; + return dst; +} + +static void +readMipmap(Stream *stream, int32 len, void *object, int32 offset, int32) +{ + int32 val = stream->readI32(); + Texture *tex = (Texture*)object; + if(tex->raster == NULL) + return; + Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset); + raster->mipmap = val; +} + +static void +writeMipmap(Stream *stream, int32 len, void *object, int32 offset, int32) +{ + Texture *tex = (Texture*)object; + assert(tex->raster); + Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset); + stream->writeI32(raster->mipmap); +} + +static int32 +getSizeMipmap(void *object, int32 offset, int32) +{ + return rw::platform == PLATFORM_PS2 ? 4 : 0; +} + +void +registerNativeRaster(void) +{ + nativeRasterOffset = Raster::registerPlugin(sizeof(Ps2Raster), + 0x12340000 | PLATFORM_PS2, + createNativeRaster, + destroyNativeRaster, + copyNativeRaster); + Texture::registerPlugin(0, ID_SKYMIPMAP, NULL, NULL, NULL); + Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap); +} + } } diff --git a/src/rwobjects.h b/src/rwobjects.h index ca54aa4..3c8e403 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -33,6 +33,14 @@ struct Frame : PluginBase, Object void setDirty(void); }; +struct HAnimKeyFrame +{ + HAnimKeyFrame *prev; + float time; + float q[4]; + float t[3]; +}; + struct HAnimNodeInfo { int32 id; @@ -125,7 +133,7 @@ struct Texture : PluginBase { char name[32]; char mask[32]; - uint32 filterAddressing; + uint32 filterAddressing; // VVVVUUUU FFFFFFFF Raster *raster; int32 refCount; @@ -434,7 +442,9 @@ struct Animation Animation(AnimInterpolatorInfo*, int32 numFrames, int32 flags, float duration); static Animation *streamRead(Stream *stream); + static Animation *streamReadLegacy(Stream *stream); bool streamWrite(Stream *stream); + bool streamWriteLegacy(Stream *stream); uint32 streamGetSize(void); }; diff --git a/src/rwps2.h b/src/rwps2.h index 59866b5..c1f86a3 100644 --- a/src/rwps2.h +++ b/src/rwps2.h @@ -116,5 +116,10 @@ void registerADCPlugin(void); void registerPDSPlugin(void); +// Raster + +extern int32 nativeRasterOffset; +void registerNativeRaster(void); + } } diff --git a/tools/d3d9/d3dInit.cpp b/tools/d3d9/d3dInit.cpp index 81bb7b8..b824eb7 100644 --- a/tools/d3d9/d3dInit.cpp +++ b/tools/d3d9/d3dInit.cpp @@ -48,7 +48,7 @@ void registerNativeRaster(void) { nativeRasterOffset = Raster::registerPlugin(sizeof(D3d9Raster), - 0x12340002, + 0x12340000 | PLATFORM_D3D9, createNativeRaster, destroyNativeRaster, copyNativeRaster); diff --git a/tools/insttest/insttest.cpp b/tools/insttest/insttest.cpp index 23bebf3..7f54f73 100644 --- a/tools/insttest/insttest.cpp +++ b/tools/insttest/insttest.cpp @@ -16,9 +16,9 @@ main(int argc, char *argv[]) gta::attachPlugins(); // rw::version = 0x33002; -// rw::platform = rw::PLATFORM_PS2; + 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;