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;