diff --git a/librw.sln b/librw.sln
index 7149c60..2a60e65 100644
--- a/librw.sln
+++ b/librw.sln
@@ -10,31 +10,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumprwtree", "tools\dumprwt
{30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dffwrite", "tools\dffwrite\dffwrite.vcxproj", "{85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}"
- ProjectSection(ProjectDependencies) = postProject
- {30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "insttest", "tools\insttest\insttest.vcxproj", "{2592ED29-F258-4949-AB45-7B873BF697F7}"
- ProjectSection(ProjectDependencies) = postProject
- {30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d9", "tools\d3d9\d3d9.vcxproj", "{E5D477C8-4CAF-43BF-B7E3-6689503D469F}"
- ProjectSection(ProjectDependencies) = postProject
- {30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txdwrite", "tools\txdwrite\txdwrite.vcxproj", "{403C35A9-6D06-4261-B305-9ED000F00136}"
- ProjectSection(ProjectDependencies) = postProject
- {30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rsltest", "tools\rsltest\rsltest.vcxproj", "{27ECE916-900F-49B2-8E9F-95E6B347E161}"
- ProjectSection(ProjectDependencies) = postProject
- {30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38}
- EndProjectSection
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug - null|Win32 = Debug - null|Win32
@@ -66,53 +41,6 @@ Global
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|Win32.ActiveCfg = Release|Win32
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|Win32.Build.0 = Release|Win32
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|x64.ActiveCfg = Release|x64
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug - null|Win32.Build.0 = Debug - null|Win32
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug - null|x64.ActiveCfg = Debug - null|x64
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug|Win32.ActiveCfg = Debug|Win32
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug|x64.ActiveCfg = Debug|x64
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Debug|x64.Build.0 = Debug|x64
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Release|Win32.ActiveCfg = Release|Win32
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Release|Win32.Build.0 = Release|Win32
- {85F56A7D-6EA2-4B9B-806A-87AF6C577FDF}.Release|x64.ActiveCfg = Release|x64
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug - null|Win32.Build.0 = Debug - null|Win32
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug - null|x64.ActiveCfg = Debug - null|x64
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug - null|x64.Build.0 = Debug - null|x64
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug|Win32.ActiveCfg = Debug|Win32
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug|x64.ActiveCfg = Debug|x64
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Debug|x64.Build.0 = Debug|x64
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.ActiveCfg = Release|Win32
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Release|Win32.Build.0 = Release|Win32
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Release|x64.ActiveCfg = Release|x64
- {2592ED29-F258-4949-AB45-7B873BF697F7}.Release|x64.Build.0 = Release|x64
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug - null|x64.ActiveCfg = Debug - null|x64
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|Win32.ActiveCfg = Debug|Win32
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|Win32.Build.0 = Debug|Win32
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|x64.ActiveCfg = Debug|x64
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|x64.Build.0 = Debug|x64
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|Win32.ActiveCfg = Release|Win32
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|Win32.Build.0 = Release|Win32
- {E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|x64.ActiveCfg = Release|x64
- {403C35A9-6D06-4261-B305-9ED000F00136}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
- {403C35A9-6D06-4261-B305-9ED000F00136}.Debug - null|Win32.Build.0 = Debug - null|Win32
- {403C35A9-6D06-4261-B305-9ED000F00136}.Debug - null|x64.ActiveCfg = Debug - null|x64
- {403C35A9-6D06-4261-B305-9ED000F00136}.Debug|Win32.ActiveCfg = Debug|Win32
- {403C35A9-6D06-4261-B305-9ED000F00136}.Debug|x64.ActiveCfg = Debug|x64
- {403C35A9-6D06-4261-B305-9ED000F00136}.Debug|x64.Build.0 = Debug|x64
- {403C35A9-6D06-4261-B305-9ED000F00136}.Release|Win32.ActiveCfg = Release|Win32
- {403C35A9-6D06-4261-B305-9ED000F00136}.Release|Win32.Build.0 = Release|Win32
- {403C35A9-6D06-4261-B305-9ED000F00136}.Release|x64.ActiveCfg = Release|x64
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|Win32.ActiveCfg = Debug - null|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|Win32.Build.0 = Debug - null|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug - null|x64.ActiveCfg = Debug - null|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug|Win32.ActiveCfg = Debug - null|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug|Win32.Build.0 = Debug - null|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Debug|x64.ActiveCfg = Debug - null|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Release|Win32.ActiveCfg = Release|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Release|Win32.Build.0 = Release|Win32
- {27ECE916-900F-49B2-8E9F-95E6B347E161}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/librw.vcxproj b/librw.vcxproj
index 645d99f..997b042 100644
--- a/librw.vcxproj
+++ b/librw.vcxproj
@@ -115,6 +115,7 @@
Disabled
true
_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;RW_D3D9;%(PreprocessorDefinitions)
+ MultiThreadedDebug
true
@@ -192,17 +193,16 @@
-
+
-
diff --git a/src/anim.cpp b/src/anim.cpp
index 7694602..2de9cae 100644
--- a/src/anim.cpp
+++ b/src/anim.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
diff --git a/src/clump.cpp b/src/clump.cpp
index 7db9b03..c8c55f3 100644
--- a/src/clump.cpp
+++ b/src/clump.cpp
@@ -4,8 +4,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
diff --git a/src/d3d.cpp b/src/d3d.cpp
index fe3a577..38a155d 100644
--- a/src/d3d.cpp
+++ b/src/d3d.cpp
@@ -416,6 +416,82 @@ D3dRaster::getNumLevels(Raster*)
#endif
}
+void
+D3dRaster::fromImage(Raster *raster, Image *image)
+{
+ int32 format;
+ if(image->depth == 32)
+ format = Raster::C8888;
+ else if(image->depth == 24)
+ format = Raster::C888;
+ else if(image->depth == 16)
+ format = Raster::C1555;
+ else if(image->depth == 8)
+ format = Raster::PAL8 | Raster::C8888;
+ else if(image->depth == 4)
+ format = Raster::PAL4 | Raster::C8888;
+ else
+ return;
+ format |= 4;
+
+ raster->type = format & 0x7;
+ raster->flags = format & 0xF8;
+ raster->format = format & 0xFF00;
+ this->create(raster);
+
+ uint8 *in, *out;
+ int pallength = 0;
+ if(raster->format & Raster::PAL4)
+ pallength = 16;
+ else if(raster->format & Raster::PAL8)
+ pallength = 256;
+ if(pallength){
+ in = image->palette;
+ out = (uint8*)this->palette;
+ for(int32 i = 0; i < pallength; i++){
+ out[0] = in[2];
+ out[1] = in[1];
+ out[2] = in[0];
+ out[3] = in[3];
+ in += 4;
+ out += 4;
+ }
+ }
+
+ in = image->pixels;
+ out = raster->lock(0);
+ if(pallength)
+ memcpy(out, in, raster->width*raster->height);
+ else
+ for(int32 y = 0; y < image->height; y++)
+ for(int32 x = 0; x < image->width; x++)
+ switch(raster->format & 0xF00){
+ case Raster::C8888:
+ out[0] = in[2];
+ out[1] = in[1];
+ out[2] = in[0];
+ out[3] = in[3];
+ in += 4;
+ out += 4;
+ break;
+ case Raster::C888:
+ out[0] = in[2];
+ out[1] = in[1];
+ out[2] = in[0];
+ out[3] = 0xFF;
+ in += 3;
+ out += 4;
+ break;
+ case Raster::C1555:
+ out[0] = in[0];
+ out[1] = in[1];
+ in += 2;
+ out += 2;
+ break;
+ }
+ raster->unlock(0);
+}
+
int32
getLevelSize(Raster *raster, int32 level)
{
diff --git a/src/d3d8.cpp b/src/d3d8.cpp
index d14aab8..d6d14f0 100644
--- a/src/d3d8.cpp
+++ b/src/d3d8.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
diff --git a/src/d3d9.cpp b/src/d3d9.cpp
index aff7519..8040f59 100644
--- a/src/d3d9.cpp
+++ b/src/d3d9.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
diff --git a/src/geometry.cpp b/src/geometry.cpp
index 9c5a84e..cc92e87 100644
--- a/src/geometry.cpp
+++ b/src/geometry.cpp
@@ -4,8 +4,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
diff --git a/src/gtaplg.cpp b/src/gtaplg.cpp
deleted file mode 100644
index 1846b23..0000000
--- a/src/gtaplg.cpp
+++ /dev/null
@@ -1,1378 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include
-
-#include "rwbase.h"
-#include "rwplugin.h"
-#include "rwpipeline.h"
-#include "rwobjects.h"
-#include "rwps2.h"
-#include "rwd3d.h"
-#include "rwxbox.h"
-#include "gtaplg.h"
-
-using namespace std;
-
-namespace rw {
-
-int32
-findPlatform(Clump *c)
-{
- FORLIST(lnk, c->atomics){
- Geometry *g = Atomic::fromClump(lnk)->geometry;
- if(g->instData)
- return g->instData->platform;
- }
- return 0;
-}
-
-void
-switchPipes(Clump *c, int32 platform)
-{
- FORLIST(lnk, c->atomics){
- Atomic *a = Atomic::fromClump(lnk);
- if(a->pipeline && a->pipeline->platform != platform){
- uint32 plgid = a->pipeline->pluginID;
- switch(plgid){
- case ID_SKIN:
- a->pipeline = skinGlobals.pipelines[platform];
- break;
- case ID_MATFX:
- a->pipeline = matFXGlobals.pipelines[platform];
- break;
- }
- }
- }
-}
-
-}
-
-namespace gta {
-
-void
-attachPlugins(void)
-{
- rw::ps2::registerPDSPlugin(12);
- gta::registerPDSPipes();
-
- rw::ps2::registerNativeRaster();
- rw::xbox::registerNativeRaster();
- rw::d3d::registerNativeRaster();
- int32 nativeRasterOffset = Raster::registerPlugin(sizeof(NativeRaster),
- 0x12340000 | PLATFORM_NULL, NULL, NULL, NULL);
- Raster::nativeOffsets[PLATFORM_NULL] = nativeRasterOffset;
-
- rw::registerMeshPlugin();
- rw::registerNativeDataPlugin();
- rw::registerAtomicRightsPlugin();
- rw::registerMaterialRightsPlugin();
- rw::xbox::registerVertexFormatPlugin();
- rw::registerSkinPlugin();
- rw::registerHAnimPlugin();
- gta::registerNodeNamePlugin();
- rw::registerMatFXPlugin();
- rw::registerUVAnimPlugin();
- rw::ps2::registerADCPlugin();
- gta::registerExtraNormalsPlugin();
- gta::registerExtraVertColorPlugin();
- gta::registerEnvSpecPlugin();
- gta::registerBreakableModelPlugin();
- gta::registerCollisionPlugin();
- gta::register2dEffectPlugin();
- gta::registerPipelinePlugin();
-
- rw::Atomic::init();
-}
-
-//
-// Frame
-//
-
-// Node Name
-
-int32 nodeNameOffset;
-
-static void*
-createNodeName(void *object, int32 offset, int32)
-{
- char *name = PLUGINOFFSET(char, object, offset);
- name[0] = '\0';
- return object;
-}
-
-static void*
-copyNodeName(void *dst, void *src, int32 offset, int32)
-{
- char *dstname = PLUGINOFFSET(char, dst, offset);
- char *srcname = PLUGINOFFSET(char, src, offset);
- strncpy(dstname, srcname, 23);
- return dst;
-}
-
-static void*
-destroyNodeName(void *object, int32, int32)
-{
- return object;
-}
-
-static void
-readNodeName(Stream *stream, int32 len, void *object, int32 offset, int32)
-{
- char *name = PLUGINOFFSET(char, object, offset);
- stream->read(name, len);
- name[len] = '\0';
- //printf("%s\n", name);
-}
-
-static void
-writeNodeName(Stream *stream, int32 len, void *object, int32 offset, int32)
-{
- char *name = PLUGINOFFSET(char, object, offset);
- stream->write(name, len);
-}
-
-static int32
-getSizeNodeName(void *object, int32 offset, int32)
-{
- char *name = PLUGINOFFSET(char, object, offset);
- int32 len = strlen(name);
- return len > 0 ? len : 0;
-}
-
-
-void
-registerNodeNamePlugin(void)
-{
- nodeNameOffset = Frame::registerPlugin(24, ID_NODENAME,
- createNodeName,
- destroyNodeName,
- copyNodeName);
- Frame::registerPluginStream(ID_NODENAME,
- readNodeName,
- writeNodeName,
- getSizeNodeName);
-}
-
-char*
-getNodeName(Frame *f)
-{
- return PLUGINOFFSET(char, f, nodeNameOffset);
-}
-
-//
-// Geometry
-//
-
-// Breakable Model
-
-int32 breakableOffset;
-
-static void*
-createBreakableModel(void *object, int32 offset, int32)
-{
- *PLUGINOFFSET(uint8*, object, offset) = 0;
- return object;
-}
-
-static void*
-destroyBreakableModel(void *object, int32 offset, int32)
-{
- uint8 *p = *PLUGINOFFSET(uint8*, object, offset);
- delete[] p;
- return object;
-}
-
-static void
-readBreakableModel(Stream *stream, int32, void *object, int32 o, int32)
-{
- uint32 header[13];
- uint32 hasBreakable = stream->readU32();
- if(hasBreakable == 0)
- return;
- stream->read(header, 13*4);
- uint32 size = header[1]*(12+8+4) + header[5]*(6+2) +
- header[8]*(32+32+12);
- uint8 *p = new uint8[sizeof(Breakable)+size];
- Breakable *breakable = (Breakable*)p;
- *PLUGINOFFSET(Breakable*, object, o) = breakable;
- breakable->position = header[0];
- breakable->numVertices = header[1];
- breakable->numFaces = header[5];
- breakable->numMaterials = header[8];
- p += sizeof(Breakable);
- stream->read(p, size);
- breakable->vertices = (float*)p;
- p += breakable->numVertices*12;
- breakable->texCoords = (float*)p;
- p += breakable->numVertices*8;
- breakable->colors = (uint8*)p;
- p += breakable->numVertices*4;
- breakable->faces = (uint16*)p;
- p += breakable->numFaces*6;
- breakable->matIDs = (uint16*)p;
- p += breakable->numFaces*2;
- breakable->texNames = (char(*)[32])p;
- p += breakable->numMaterials*32;
- breakable->maskNames = (char(*)[32])p;
- p += breakable->numMaterials*32;
- breakable->surfaceProps = (float32(*)[3])p;
-}
-
-static void
-writeBreakableModel(Stream *stream, int32, void *object, int32 o, int32)
-{
- uint32 header[13];
- Breakable *breakable = *PLUGINOFFSET(Breakable*, object, o);
- uint8 *p = (uint8*)breakable;
- if(breakable == NULL){
- stream->writeU32(0);
- return;
- }
- stream->writeU32(1);
- memset((char*)header, 0, 13*4);
- header[0] = breakable->position;
- header[1] = breakable->numVertices;
- header[5] = breakable->numFaces;
- header[8] = breakable->numMaterials;
- stream->write(header, 13*4);
- p += sizeof(Breakable);
- stream->write(p, breakable->numVertices*(12+8+4) +
- breakable->numFaces*(6+2) +
- breakable->numMaterials*(32+32+12));
-}
-
-static int32
-getSizeBreakableModel(void *object, int32 offset, int32)
-{
- Breakable *breakable = *PLUGINOFFSET(Breakable*, object, offset);
- if(breakable == NULL)
- return 0; //4;
- return 56 + breakable->numVertices*(12+8+4) +
- breakable->numFaces*(6+2) +
- breakable->numMaterials*(32+32+12);
-}
-
-void
-registerBreakableModelPlugin(void)
-{
- breakableOffset = Geometry::registerPlugin(sizeof(Breakable*),
- ID_BREAKABLE,
- createBreakableModel,
- destroyBreakableModel, NULL);
- Geometry::registerPluginStream(ID_BREAKABLE,
- readBreakableModel,
- writeBreakableModel,
- getSizeBreakableModel);
-}
-
-// Extra normals
-
-int32 extraNormalsOffset;
-
-static void*
-createExtraNormals(void *object, int32 offset, int32)
-{
- *PLUGINOFFSET(float*, object, offset) = NULL;
- return object;
-}
-
-static void*
-destroyExtraNormals(void *object, int32 offset, int32)
-{
- float *extranormals = *PLUGINOFFSET(float*, object, offset);
- delete[] extranormals;
- *PLUGINOFFSET(float*, object, offset) = NULL;
- return object;
-}
-
-static void
-readExtraNormals(Stream *stream, int32, void *object, int32 offset, int32)
-{
- Geometry *geo = (Geometry*)object;
- float **plgp = PLUGINOFFSET(float*, object, offset);
- if(*plgp)
- delete[] *plgp;
- float *extranormals = *plgp = new float[geo->numVertices*3];
- stream->read(extranormals, geo->numVertices*3*4);
-// printf("extra normals\n");
-
-// for(int i = 0; i < geo->numVertices; i++){
-// float *nx = extranormals+i*3;
-// float *n = geo->morphTargets[0].normals;
-// float len = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
-// printf("%f %f %f %f\n", n[0], n[1], n[2], len);
-// printf("%f %f %f\n", nx[0], nx[1], nx[2]);
-// }
-}
-
-static void
-writeExtraNormals(Stream *stream, int32, void *object, int32 offset, int32)
-{
- Geometry *geo = (Geometry*)object;
- float *extranormals = *PLUGINOFFSET(float*, object, offset);
- assert(extranormals != NULL);
- stream->write(extranormals, geo->numVertices*3*4);
-}
-
-static int32
-getSizeExtraNormals(void *object, int32 offset, int32)
-{
- Geometry *geo = (Geometry*)object;
- if(*PLUGINOFFSET(float*, object, offset))
- return geo->numVertices*3*4;
- return 0;
-}
-
-void
-registerExtraNormalsPlugin(void)
-{
- extraNormalsOffset = Geometry::registerPlugin(sizeof(void*),
- ID_EXTRANORMALS,
- createExtraNormals,
- destroyExtraNormals,
- NULL);
- Geometry::registerPluginStream(ID_EXTRANORMALS,
- readExtraNormals,
- writeExtraNormals,
- getSizeExtraNormals);
-}
-
-
-// Extra colors
-
-int32 extraVertColorOffset;
-
-void
-allocateExtraVertColors(Geometry *g)
-{
- ExtraVertColors *colordata =
- PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset);
- colordata->nightColors = new uint8[g->numVertices*4];
- colordata->dayColors = new uint8[g->numVertices*4];
- colordata->balance = 1.0f;
-}
-
-static void*
-createExtraVertColors(void *object, int32 offset, int32)
-{
- ExtraVertColors *colordata =
- PLUGINOFFSET(ExtraVertColors, object, offset);
- colordata->nightColors = NULL;
- colordata->dayColors = NULL;
- colordata->balance = 0.0f;
- return object;
-}
-
-static void*
-destroyExtraVertColors(void *object, int32 offset, int32)
-{
- ExtraVertColors *colordata =
- PLUGINOFFSET(ExtraVertColors, object, offset);
- delete[] colordata->nightColors;
- delete[] colordata->dayColors;
- return object;
-}
-
-static void
-readExtraVertColors(Stream *stream, int32, void *object, int32 offset, int32)
-{
- uint32 hasData;
- ExtraVertColors *colordata =
- PLUGINOFFSET(ExtraVertColors, object, offset);
- hasData = stream->readU32();
- if(!hasData)
- return;
- Geometry *geometry = (Geometry*)object;
- colordata->nightColors = new uint8[geometry->numVertices*4];
- colordata->dayColors = new uint8[geometry->numVertices*4];
- colordata->balance = 1.0f;
- stream->read(colordata->nightColors, geometry->numVertices*4);
- if(geometry->colors)
- memcpy(colordata->dayColors, geometry->colors,
- geometry->numVertices*4);
-}
-
-static void
-writeExtraVertColors(Stream *stream, int32, void *object, int32 offset, int32)
-{
- ExtraVertColors *colordata =
- PLUGINOFFSET(ExtraVertColors, object, offset);
- stream->writeU32(colordata->nightColors != NULL);
- if(colordata->nightColors){
- Geometry *geometry = (Geometry*)object;
- stream->write(colordata->nightColors, geometry->numVertices*4);
- }
-}
-
-static int32
-getSizeExtraVertColors(void *object, int32 offset, int32)
-{
- ExtraVertColors *colordata =
- PLUGINOFFSET(ExtraVertColors, object, offset);
- Geometry *geometry = (Geometry*)object;
- if(colordata->nightColors)
- return 4 + geometry->numVertices*4;
- return 0;
-}
-
-void
-registerExtraVertColorPlugin(void)
-{
- extraVertColorOffset = Geometry::registerPlugin(sizeof(ExtraVertColors),
- ID_EXTRAVERTCOLORS,
- createExtraVertColors,
- destroyExtraVertColors,
- NULL);
- Geometry::registerPluginStream(ID_EXTRAVERTCOLORS,
- readExtraVertColors,
- writeExtraVertColors,
- getSizeExtraVertColors);
-}
-
-// Environment mat
-
-int32 envMatOffset;
-
-static void*
-createEnvMat(void *object, int32 offset, int32)
-{
- *PLUGINOFFSET(EnvMat*, object, offset) = NULL;
- return object;
-}
-
-static void*
-destroyEnvMat(void *object, int32 offset, int32)
-{
- EnvMat **envmat = PLUGINOFFSET(EnvMat*, object, offset);
- delete *envmat;
- *envmat = NULL;
- return object;
-}
-
-static void*
-copyEnvMat(void *dst, void *src, int32 offset, int32)
-{
- EnvMat *srcenv = *PLUGINOFFSET(EnvMat*, src, offset);
- if(srcenv == NULL)
- return dst;
- EnvMat *dstenv = new EnvMat;
- dstenv->scaleX = srcenv->scaleX;
- dstenv->scaleY = srcenv->scaleY;
- dstenv->transScaleX = srcenv->transScaleX;
- dstenv->transScaleY = srcenv->transScaleY;
- dstenv->shininess = srcenv->shininess;
- dstenv->texture = NULL;
- *PLUGINOFFSET(EnvMat*, dst, offset) = dstenv;
- return dst;
-}
-
-struct EnvStream {
- float scaleX, scaleY;
- float transScaleX, transScaleY;
- float shininess;
- int32 zero;
-};
-
-static void
-readEnvMat(Stream *stream, int32, void *object, int32 offset, int32)
-{
- EnvStream buf;
- EnvMat *env = new EnvMat;
- *PLUGINOFFSET(EnvMat*, object, offset) = env;
- stream->read(&buf, sizeof(buf));
- env->scaleX = (int8)(buf.scaleX*8.0f);
- env->scaleY = (int8)(buf.scaleY*8.0f);
- env->transScaleX = (int8)(buf.transScaleX*8.0f);
- env->transScaleY = (int8)(buf.transScaleY*8.0f);
- env->shininess = (int8)(buf.shininess*255.0f);
- env->texture = NULL;
-}
-
-static void
-writeEnvMat(Stream *stream, int32, void *object, int32 offset, int32)
-{
- EnvStream buf;
- EnvMat *env = *PLUGINOFFSET(EnvMat*, object, offset);
- buf.scaleX = env->scaleX/8.0f;
- buf.scaleY = env->scaleY/8.0f;
- buf.transScaleX = env->transScaleX/8.0f;
- buf.transScaleY = env->transScaleY/8.0f;
- buf.shininess = env->shininess/8.0f;
- buf.zero = 0;
- stream->write(&buf, sizeof(buf));
-}
-
-static int32
-getSizeEnvMat(void *object, int32 offset, int32)
-{
- EnvMat *env = *PLUGINOFFSET(EnvMat*, object, offset);
- return env ? (int)sizeof(EnvStream) : 0;
-}
-
-// Specular mat
-
-int32 specMatOffset;
-
-static void*
-createSpecMat(void *object, int32 offset, int32)
-{
- *PLUGINOFFSET(SpecMat*, object, offset) = NULL;
- return object;
-}
-
-static void*
-destroySpecMat(void *object, int32 offset, int32)
-{
- SpecMat **specmat = PLUGINOFFSET(SpecMat*, object, offset);
- if(*specmat == NULL)
- return object;
- if((*specmat)->texture)
- (*specmat)->texture->destroy();
- delete *specmat;
- *specmat = NULL;
- return object;
-}
-
-static void*
-copySpecMat(void *dst, void *src, int32 offset, int32)
-{
- SpecMat *srcspec = *PLUGINOFFSET(SpecMat*, src, offset);
- if(srcspec == NULL)
- return dst;
- SpecMat *dstspec = new SpecMat;
- *PLUGINOFFSET(SpecMat*, dst, offset) = dstspec;
- dstspec->specularity = srcspec->specularity;
- dstspec->texture = srcspec->texture;
- dstspec->texture->refCount++;
- return dst;
-}
-
-struct SpecStream {
- float specularity;
- char texname[24];
-};
-
-static void
-readSpecMat(Stream *stream, int32, void *object, int32 offset, int32)
-{
- SpecStream buf;
- SpecMat *spec = new SpecMat;
- *PLUGINOFFSET(SpecMat*, object, offset) = spec;
- stream->read(&buf, sizeof(buf));
- spec->specularity = buf.specularity;
- spec->texture = Texture::create(NULL);
- strncpy(spec->texture->name, buf.texname, 24);
-}
-
-static void
-writeSpecMat(Stream *stream, int32, void *object, int32 offset, int32)
-{
- SpecStream buf;
- SpecMat *spec = *PLUGINOFFSET(SpecMat*, object, offset);
- buf.specularity = spec->specularity;
- strncpy(buf.texname, spec->texture->name, 24);
- stream->write(&buf, sizeof(buf));
-}
-
-static int32
-getSizeSpecMat(void *object, int32 offset, int32)
-{
- SpecMat *spec = *PLUGINOFFSET(SpecMat*, object, offset);
- return spec ? (int)sizeof(SpecStream) : 0;
-}
-
-void
-registerEnvSpecPlugin(void)
-{
- envMatOffset = Material::registerPlugin(sizeof(EnvMat*), ID_ENVMAT,
- createEnvMat,
- destroyEnvMat,
- copyEnvMat);
- Material::registerPluginStream(ID_ENVMAT, readEnvMat,
- writeEnvMat,
- getSizeEnvMat);
- specMatOffset = Material::registerPlugin(sizeof(SpecMat*), ID_SPECMAT,
- createSpecMat,
- destroySpecMat,
- copySpecMat);
- Material::registerPluginStream(ID_SPECMAT, readSpecMat,
- writeSpecMat,
- getSizeSpecMat);
-}
-
-// Pipeline
-
-int32 pipelineOffset;
-
-static void*
-createPipeline(void *object, int32 offset, int32)
-{
- *PLUGINOFFSET(uint32, object, offset) = 0;
- return object;
-}
-
-static void*
-copyPipeline(void *dst, void *src, int32 offset, int32)
-{
- *PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset);
- return dst;
-}
-
-static void
-readPipeline(Stream *stream, int32, void *object, int32 offset, int32)
-{
- *PLUGINOFFSET(uint32, object, offset) = stream->readU32();
-// printf("%x\n", *PLUGINOFFSET(uint32, object, offset));
-}
-
-static void
-writePipeline(Stream *stream, int32, void *object, int32 offset, int32)
-{
- stream->writeU32(*PLUGINOFFSET(uint32, object, offset));
-}
-
-static int32
-getSizePipeline(void *object, int32 offset, int32)
-{
- if(*PLUGINOFFSET(uint32, object, offset))
- return 4;
- return 0;
-}
-
-void
-registerPipelinePlugin(void)
-{
- pipelineOffset = Atomic::registerPlugin(sizeof(uint32), ID_PIPELINE,
- createPipeline,
- NULL,
- copyPipeline);
- Atomic::registerPluginStream(ID_PIPELINE, readPipeline,
- writePipeline, getSizePipeline);
-}
-
-uint32
-getPipelineID(Atomic *atomic)
-{
- return *PLUGINOFFSET(uint32, atomic, pipelineOffset);
-}
-
-void
-setPipelineID(Atomic *atomic, uint32 id)
-{
- *PLUGINOFFSET(uint32, atomic, pipelineOffset) = id;
-}
-
-// 2dEffect
-
-struct SizedData
-{
- uint32 size;
- uint8 *data;
-};
-
-int32 twodEffectOffset;
-
-static void*
-create2dEffect(void *object, int32 offset, int32)
-{
- SizedData *data;
- data = PLUGINOFFSET(SizedData, object, offset);
- data->size = 0;
- data->data = NULL;
- return object;
-}
-
-static void*
-destroy2dEffect(void *object, int32 offset, int32)
-{
- SizedData *data;
- data = PLUGINOFFSET(SizedData, object, offset);
- delete[] data->data;
- data->data = NULL;
- data->size = 0;
- return object;
-}
-
-static void*
-copy2dEffect(void *dst, void *src, int32 offset, int32)
-{
- SizedData *srcdata, *dstdata;
- dstdata = PLUGINOFFSET(SizedData, dst, offset);
- srcdata = PLUGINOFFSET(SizedData, src, offset);
- dstdata->size = srcdata->size;
- if(dstdata->size != 0){
- dstdata->data = new uint8[dstdata->size];
- memcpy(dstdata->data, srcdata->data, dstdata->size);
- }
- return dst;
-}
-
-static void
-read2dEffect(Stream *stream, int32 size, void *object, int32 offset, int32)
-{
- SizedData *data = PLUGINOFFSET(SizedData, object, offset);
- data->size = size;
- data->data = new uint8[data->size];
- stream->read(data->data, data->size);
-}
-
-static void
-write2dEffect(Stream *stream, int32, void *object, int32 offset, int32)
-{
- SizedData *data = PLUGINOFFSET(SizedData, object, offset);
- stream->write(data->data, data->size);
-}
-
-static int32
-getSize2dEffect(void *object, int32 offset, int32)
-{
- SizedData *data = PLUGINOFFSET(SizedData, object, offset);
- return data->size;
-}
-
-void
-register2dEffectPlugin(void)
-{
- twodEffectOffset = Geometry::registerPlugin(sizeof(SizedData), ID_2DEFFECT,
- create2dEffect,
- destroy2dEffect,
- copy2dEffect);
- Geometry::registerPluginStream(ID_2DEFFECT, read2dEffect,
- write2dEffect, getSize2dEffect);
-}
-
-// Collision
-
-int32 collisionOffset;
-
-static void*
-createCollision(void *object, int32 offset, int32)
-{
- SizedData *data;
- data = PLUGINOFFSET(SizedData, object, offset);
- data->size = 0;
- data->data = NULL;
- return object;
-}
-
-static void*
-destroyCollision(void *object, int32 offset, int32)
-{
- SizedData *data;
- data = PLUGINOFFSET(SizedData, object, offset);
- delete[] data->data;
- data->data = NULL;
- data->size = 0;
- return object;
-}
-
-static void*
-copyCollision(void *dst, void *src, int32 offset, int32)
-{
- SizedData *srcdata, *dstdata;
- dstdata = PLUGINOFFSET(SizedData, dst, offset);
- srcdata = PLUGINOFFSET(SizedData, src, offset);
- dstdata->size = srcdata->size;
- if(dstdata->size != 0){
- dstdata->data = new uint8[dstdata->size];
- memcpy(dstdata->data, srcdata->data, dstdata->size);
- }
- return dst;
-}
-
-static void
-readCollision(Stream *stream, int32 size, void *object, int32 offset, int32)
-{
- SizedData *data = PLUGINOFFSET(SizedData, object, offset);
- data->size = size;
- data->data = new uint8[data->size];
- stream->read(data->data, data->size);
-}
-
-static void
-writeCollision(Stream *stream, int32, void *object, int32 offset, int32)
-{
- SizedData *data = PLUGINOFFSET(SizedData, object, offset);
- stream->write(data->data, data->size);
-}
-
-static int32
-getSizeCollision(void *object, int32 offset, int32)
-{
- SizedData *data = PLUGINOFFSET(SizedData, object, offset);
- return data->size;
-}
-
-void
-registerCollisionPlugin(void)
-{
- collisionOffset = Clump::registerPlugin(sizeof(SizedData), ID_COLLISION,
- createCollision,
- destroyCollision,
- copyCollision);
- Clump::registerPluginStream(ID_COLLISION, readCollision,
- writeCollision, getSizeCollision);
-}
-
-/*
- * PS2
- */
-
-using namespace ps2;
-
-rw::PipeAttribute saXYZADC = {
- "saXYZADC",
- AT_V4_16 | AT_RW
-};
-
-rw::PipeAttribute saUV = {
- "saUV",
- AT_V2_16 | AT_RW
-};
-
-rw::PipeAttribute saUV2 = {
- "saUV2",
- AT_V4_16 | AT_RW
-};
-
-rw::PipeAttribute saRGBA = {
- "saRGBA",
- AT_V4_8 | AT_UNSGN | AT_RW
-};
-
-rw::PipeAttribute saRGBA2 = {
- "saRGBA2",
- AT_V4_16 | AT_UNSGN | AT_RW
-};
-
-rw::PipeAttribute saNormal = {
- "saNormal",
- AT_V4_8 | AT_RW
-};
-
-rw::PipeAttribute saWeights = {
- "saWeights",
- AT_V4_32 | AT_RW
-};
-
-static bool hasTex2(uint32 id)
-{
- return id == 0x53f2008b;
-}
-static bool hasNormals(uint32 id)
-{
- return id == 0x53f20085 || id == 0x53f20087 || id == 0x53f20089 ||
- id == 0x53f2008b || id == 0x53f2008d || id == 0x53f2008f;
-}
-static bool hasColors(uint32 id)
-{
- return id == 0x53f20081 || id == 0x53f20083 || id == 0x53f2008d || id == 0x53f2008f;
-}
-static bool hasColors2(uint32 id)
-{
- return id == 0x53f20083 || id == 0x53f2008f;
-}
-
-static void
-saPreCB(MatPipeline *p, Geometry *geo)
-{
- allocateADC(geo);
- if(hasColors2(p->pluginData) && extraVertColorOffset)
- allocateExtraVertColors(geo);
- if(p->pluginData == 0x53f20089)
- skinPreCB(p, geo);
-}
-
-static void
-saPostCB(MatPipeline *p, Geometry *geo)
-{
- skinPostCB(p, geo);
-}
-
-int32
-findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v)
-{
- Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
- float32 *wghts = NULL;
- uint8 *inds = NULL;
- if(skin){
- wghts = skin->weights;
- inds = skin->indices;
- }
- float32 *verts = g->morphTargets[0].vertices;
- float32 *tex0 = g->texCoords[0];
- float32 *tex1 = g->texCoords[1];
- float32 *norms = g->morphTargets[0].normals;
- uint8 *cols0 = g->colors;
- uint8 *cols1 = NULL;
- if(extraVertColorOffset)
- cols1 = PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset)->nightColors;
-
- for(int32 i = 0; i < g->numVertices; i++){
- uint32 flag = flags ? flags[i] : ~0;
- if(mask & flag & 0x1 &&
- !(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
- goto cont;
- if(mask & flag & 0x10 &&
- !(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
- goto cont;
- if(mask & flag & 0x100 &&
- !(cols0[0] == v->c[0] && cols0[1] == v->c[1] &&
- cols0[2] == v->c[2] && cols0[3] == v->c[3]))
- goto cont;
- if(mask & flag & 0x200 &&
- !(cols1[0] == v->c1[0] && cols1[1] == v->c1[1] &&
- cols1[2] == v->c1[2] && cols1[3] == v->c1[3]))
- goto cont;
- if(mask & flag & 0x1000 &&
- !(tex0[0] == v->t[0] && tex0[1] == v->t[1]))
- goto cont;
- if(mask & flag & 0x2000 &&
- !(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
- goto cont;
- if(mask & flag & 0x10000 &&
- !(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
- wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
- inds[0] == v->i[0] && inds[1] == v->i[1] &&
- inds[2] == v->i[2] && inds[3] == v->i[3]))
- goto cont;
- return i;
- cont:
- verts += 3;
- tex0 += 2;
- tex1 += 2;
- norms += 3;
- cols0 += 4;
- cols1 += 4;
- wghts += 4;
- inds += 4;
- }
- return -1;
-}
-
-void
-insertSAVertex(Geometry *geo, int32 i, uint32 mask, SaVert *v)
-{
- insertVertex(geo, i, mask, v);
- if(mask & 0x2000)
- memcpy(&geo->texCoords[1][i*2], v->t1, 8);
- if(mask & 0x200 && extraVertColorOffset){
- uint8 *cols1 =
- &PLUGINOFFSET(ExtraVertColors, geo, extraVertColorOffset)->nightColors[i*4];
- cols1[0] = v->c1[0];
- cols1[1] = v->c1[1];
- cols1[2] = v->c1[2];
- cols1[3] = v->c1[3];
- }
- if(mask & 0x10000 && skinGlobals.offset){
- Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
- memcpy(&skin->weights[i*4], v->w, 16);
- memcpy(&skin->indices[i*4], v->i, 4);
- }
-}
-
-static void
-saUninstanceCB(ps2::MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
-{
- uint32 id = pipe->pluginData;
- int16 *verts = (int16*)data[0];
- int16 *texcoords = (int16*)data[1];
- uint8 *colors = (uint8*)data[2];
- int8 *norms = (int8*)data[id == 0x53f20089 ? 2 : 3];
- uint32 *wghts = (uint32*)data[3];
- float vertScale = 1.0f/128.0f;
- if(id == 0x53f20085 || id == 0x53f20087 ||
- id == 0x53f20089 || id == 0x53f2008b)
- vertScale = 1.0f/1024.0f;
- uint32 mask = 0x1; // vertices
- int cinc = 4;
- int tinc = 2;
- if((geo->geoflags & Geometry::NORMALS) && hasNormals(id))
- mask |= 0x10;
- if((geo->geoflags & Geometry::PRELIT) && hasColors(id))
- mask |= 0x100;
- if(hasColors2(id)){
- mask |= 0x200;
- cinc *= 2;
- }
- if(geo->numTexCoordSets > 0)
- mask |= 0x1000;
- if(geo->numTexCoordSets > 0 && hasTex2(id)){
- mask |= 0x2000;
- tinc *= 2;
- }
- if(id == 0x53f20089)
- mask |= 0x10000;
- SaVert v;
- int32 idxstart = 0;
- for(Mesh *m = geo->meshHeader->mesh; m < mesh; m++)
- idxstart += m->numIndices;
- int8 *adc = PLUGINOFFSET(ADCData, geo, adcOffset)->adcBits;
- for(uint32 i = 0; i < mesh->numIndices; i++){
- v.p[0] = verts[0]*vertScale;
- v.p[1] = verts[1]*vertScale;
- v.p[2] = verts[2]*vertScale;
- if(mask & 0x10){
- v.n[0] = norms[0]/127.0f;
- v.n[1] = norms[1]/127.0f;
- v.n[2] = norms[2]/127.0f;
- }
- if(mask & 0x200){
- v.c[0] = colors[0];
- v.c[1] = colors[2];
- v.c[2] = colors[4];
- v.c[3] = colors[6];
- v.c1[0] = colors[1];
- v.c1[1] = colors[3];
- v.c1[2] = colors[5];
- v.c1[3] = colors[7];
- }else if(mask & 0x100){
- v.c[0] = colors[0];
- v.c[1] = colors[1];
- v.c[2] = colors[2];
- v.c[3] = colors[3];
- }
- if(mask & 0x1000){
- v.t[0] = texcoords[0]/4096.0f;
- v.t[1] = texcoords[1]/4096.0f;
- }
- if(mask & 0x2000){
- v.t1[0] = texcoords[2]/4096.0f;
- v.t1[1] = texcoords[3]/4096.0f;
- }
- if(mask & 0x10000){
- for(int j = 0; j < 4; j++){
- ((uint32*)v.w)[j] = wghts[j] & ~0x3FF;
- v.i[j] = (wghts[j] & 0x3FF) >> 2;
- if(v.i[j]) v.i[j]--;
- if(v.w[j] == 0.0f) v.i[j] = 0;
- }
- }
- int32 idx = findSAVertex(geo, flags, mask, &v);
- if(idx < 0)
- idx = geo->numVertices++;
- mesh->indices[i] = idx;
- adc[idxstart+i] = !!verts[3];
- flags[idx] = mask;
- insertSAVertex(geo, idx, mask, &v);
-
- verts += 4;
- texcoords += tinc;
- colors += cinc;
- norms += 4;
- wghts += 4;
- }
-}
-
-static void
-instanceSAPositions(Geometry *g, Mesh *m, int8 *adc, int16 *dst, float32 scale)
-{
- float32 *verts = g->morphTargets[0].vertices;
- uint16 j;
- for(uint32 i = 0; i < m->numIndices; i++){
- j = m->indices[i];
- dst[0] = verts[j*3+0]*scale;
- dst[1] = verts[j*3+1]*scale;
- dst[2] = verts[j*3+2]*scale;
- dst[3] = adc ? 0x8000*adc[i] : 0;
- dst += 4;
- }
-}
-
-static void
-instanceSATex(Geometry *g, Mesh *m, int16 *dst)
-{
- float32 *tex = g->texCoords[0];
- uint16 j;
- for(uint32 i = 0; i < m->numIndices; i++){
- j = m->indices[i];
- if(tex){
- dst[0] = tex[j*2+0]*4096.0f;
- dst[1] = tex[j*2+1]*4096.0f;
- }else{
- dst[0] = 0;
- dst[1] = 0;
- }
- dst += 2;
- }
-}
-
-static void
-instanceSADualTex(Geometry *g, Mesh *m, int16 *dst)
-{
- float32 *tex0 = g->texCoords[0];
- float32 *tex1 = g->texCoords[1];
- uint16 j;
- for(uint32 i = 0; i < m->numIndices; i++){
- j = m->indices[i];
- if(tex0){
- dst[0] = tex0[j*2+0]*4096.0f;
- dst[1] = tex0[j*2+1]*4096.0f;
- }else{
- dst[0] = 0;
- dst[1] = 0;
- }
- if(tex1){
- dst[2] = tex1[j*2+0]*4096.0f;
- dst[3] = tex1[j*2+1]*4096.0f;
- }else{
- dst[2] = 0;
- dst[3] = 0;
- }
- dst += 4;
- }
-}
-
-static void
-instanceSAColors(Geometry *g, Mesh *m, uint8 *dst)
-{
- uint8 *c = g->colors;
- uint16 j;
- for(uint32 i = 0; i < m->numIndices; i++){
- j = m->indices[i];
- if(c)
- memcpy(dst, &c[j*4], 4);
- else
- memset(dst, 0xFF, 4);
- dst += 4;
- }
-}
-
-static void
-instanceSADualColors(Geometry *g, Mesh *m, uint8 *dst)
-{
- uint8 *c0 = g->colors;
- uint8 *c1 =
- PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset)->nightColors;
- uint16 j;
- for(uint32 i = 0; i < m->numIndices; i++){
- j = m->indices[i];
- if(c0){
- dst[0] = c0[j*4+0];
- dst[2] = c0[j*4+1];
- dst[4] = c0[j*4+2];
- dst[6] = c0[j*4+3];
- }else{
- dst[0] = 0xFF;
- dst[2] = 0xFF;
- dst[4] = 0xFF;
- dst[6] = 0xFF;
- }
- if(c1){
- dst[1] = c1[j*4+0];
- dst[3] = c1[j*4+1];
- dst[6] = c1[j*4+2];
- dst[7] = c1[j*4+3];
- }else{
- dst[1] = 0xFF;
- dst[3] = 0xFF;
- dst[6] = 0xFF;
- dst[7] = 0xFF;
- }
- dst += 8;
- }
-}
-
-static void
-instanceSANormals(Geometry *g, Mesh *m, int8 *dst)
-{
- float32 *norms = g->morphTargets[0].normals;
- uint16 j;
- for(uint32 i = 0; i < m->numIndices; i++){
- j = m->indices[i];
- if(norms){
- dst[0] = norms[j*3+0]*127.0f;
- dst[1] = norms[j*3+1]*127.0f;
- dst[2] = norms[j*3+2]*127.0f;
- dst[3] = 0;
- }else
- memset(dst, 0, 4);
- dst += 4;
- }
-}
-
-static void
-saInstanceCB(MatPipeline *pipe, Geometry *g, Mesh *m, uint8 **data)
-{
- uint32 id = pipe->pluginData;
- float vertScale = 128.0f;
- if(id == 0x53f20085 || id == 0x53f20087 ||
- id == 0x53f20089 || id == 0x53f2008b)
- vertScale = 1024.0f;
- ADCData *adc = PLUGINOFFSET(ADCData, g, adcOffset);
-
- for(uint32 i = 0; i < nelem(pipe->attribs); i++){
- rw::PipeAttribute *a = pipe->attribs[i];
- if(a == &saXYZADC)
- instanceSAPositions(g, m, adc->adcFormatted ? adc->adcBits : NULL,
- (int16*)data[i], vertScale);
- if(a == &saUV)
- instanceSATex(g, m, (int16*)data[i]);
- if(a == &saUV2)
- instanceSADualTex(g, m, (int16*)data[i]);
- if(a == &saRGBA)
- instanceSAColors(g, m, (uint8*)data[i]);
- if(a == &saRGBA2)
- instanceSADualColors(g, m, (uint8*)data[i]);
- if(a == &saNormal)
- instanceSANormals(g, m, (int8*)data[i]);
- if(a == &saWeights){
- Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
- instanceSkinData(g, m, skin, (uint32*)data[i]);
- }
- }
-}
-
-void
-registerPDSPipes(void)
-{
- Pipeline *pipe;
- MatPipeline *mpipe;
-
- // Atomic pipes
-
- pipe = new ps2::ObjPipeline(PLATFORM_PS2);
- pipe->pluginID = ID_PDS;
- pipe->pluginData = 0x53f20080;
- ps2::registerPDSPipe(pipe);
-
- pipe = new ps2::ObjPipeline(PLATFORM_PS2);
- pipe->pluginID = ID_PDS;
- pipe->pluginData = 0x53f20082;
- ps2::registerPDSPipe(pipe);
-
- pipe = new ps2::ObjPipeline(PLATFORM_PS2);
- pipe->pluginID = ID_PDS;
- pipe->pluginData = 0x53f20084;
- ps2::registerPDSPipe(pipe);
-
- pipe = new ps2::ObjPipeline(PLATFORM_PS2);
- pipe->pluginID = ID_PDS;
- pipe->pluginData = 0x53f20088;
- ps2::registerPDSPipe(pipe);
-
- // Material pipes
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f20081;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV;
- mpipe->attribs[2] = &saRGBA;
- uint32 vertCount = MatPipeline::getVertCount(VU_Lights, 3, 3, 2);
- mpipe->setTriBufferSizes(3, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- ps2::registerPDSPipe(mpipe);
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f20083;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV;
- mpipe->attribs[2] = &saRGBA2;
- vertCount = MatPipeline::getVertCount(VU_Lights, 3, 3, 2);
- mpipe->setTriBufferSizes(3, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- ps2::registerPDSPipe(mpipe);
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f20085;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV;
- mpipe->attribs[3] = &saNormal;
- vertCount = MatPipeline::getVertCount(VU_Lights, 4, 3, 2);
- mpipe->setTriBufferSizes(4, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- ps2::registerPDSPipe(mpipe);
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f20087;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV;
- mpipe->attribs[3] = &saNormal;
- vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
- mpipe->setTriBufferSizes(4, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- ps2::registerPDSPipe(mpipe);
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f20089;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV;
- mpipe->attribs[2] = &saNormal;
- mpipe->attribs[3] = &saWeights;
-// these values give vertCount = 0x33 :/
-// vertCount = MatPipeline::getVertCount(0x2D0, 4, 3, 2);
- vertCount = 0x30;
- mpipe->setTriBufferSizes(4, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- mpipe->postUninstCB = saPostCB;
- ps2::registerPDSPipe(mpipe);
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f2008b;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV2;
- mpipe->attribs[3] = &saNormal;
- vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
- mpipe->setTriBufferSizes(4, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- ps2::registerPDSPipe(mpipe);
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f2008d;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV;
- mpipe->attribs[2] = &saRGBA;
- mpipe->attribs[3] = &saNormal;
- vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
- mpipe->setTriBufferSizes(4, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- ps2::registerPDSPipe(mpipe);
-
- mpipe = new MatPipeline(PLATFORM_PS2);
- mpipe->pluginID = ID_PDS;
- mpipe->pluginData = 0x53f2008f;
- mpipe->attribs[0] = &saXYZADC;
- mpipe->attribs[1] = &saUV;
- mpipe->attribs[2] = &saRGBA2;
- mpipe->attribs[3] = &saNormal;
- vertCount = MatPipeline::getVertCount(0x3BD, 4, 3, 3);
- mpipe->setTriBufferSizes(4, vertCount);
- mpipe->vifOffset = mpipe->inputStride*vertCount;
- mpipe->instanceCB = saInstanceCB;
- mpipe->preUninstCB = saPreCB;
- mpipe->uninstanceCB = saUninstanceCB;
- ps2::registerPDSPipe(mpipe);
-}
-
-}
diff --git a/src/gtaplg.h b/src/gtaplg.h
deleted file mode 100644
index 923b25d..0000000
--- a/src/gtaplg.h
+++ /dev/null
@@ -1,139 +0,0 @@
-namespace rw {
-int32 findPlatform(Clump *c);
-void switchPipes(Clump *c, int32 platform);
-};
-
-namespace gta {
-using namespace rw;
-
-enum
-{
- ID_EXTRANORMALS = 0x253f2f2,
- ID_PIPELINE = 0x253f2f3,
- ID_SPECMAT = 0x253f2f6,
- ID_2DEFFECT = 0x253f2f8, // geometry
- ID_EXTRAVERTCOLORS = 0x253f2f9,
- ID_COLLISION = 0x253f2fa, // clump
- ID_ENVMAT = 0x253f2fc,
- ID_BREAKABLE = 0x253f2fd,
- ID_NODENAME = 0x253f2fe
-};
-
-void attachPlugins(void);
-
-// Node name
-
-extern int32 nodeNameOffset;
-void registerNodeNamePlugin(void);
-char *getNodeName(Frame *f);
-
-// Breakable model
-
-struct Breakable
-{
- uint32 position;
- uint32 numVertices;
- uint32 numFaces;
- uint32 numMaterials;
-
- float32 *vertices;
- float32 *texCoords;
- uint8 *colors;
- uint16 *faces;
- uint16 *matIDs;
- char (*texNames)[32];
- char (*maskNames)[32];
- float32 (*surfaceProps)[3];
-};
-
-extern int32 breakableOffset;
-void registerBreakableModelPlugin(void);
-
-// Extra normals (only on Xbox)
-
-extern int32 extraNormalsOffset;
-void registerExtraNormalsPlugin(void);
-
-// Extra vert colors (not on Xbox)
-
-struct ExtraVertColors
-{
- uint8 *nightColors;
- uint8 *dayColors;
- float balance;
-};
-
-extern int32 extraVertColorOffset;
-void allocateExtraVertColors(Geometry *g);
-void registerExtraVertColorPlugin(void);
-
-// Environment mat
-
-struct EnvMat
-{
- int8 scaleX, scaleY;
- int8 transScaleX, transScaleY;
- int8 shininess;
- Texture *texture;
-};
-
-extern int32 envMatOffset;
-
-// Specular mat
-
-struct SpecMat
-{
- float specularity;
- Texture *texture;
-};
-
-extern int32 specMatOffset;
-
-void registerEnvSpecPlugin(void);
-
-// Pipeline
-
-// 0x53F2009A CCustomCarEnvMapPipeline
-//
-// PC & Mobile:
-// 0x53F20098 CCustomBuildingDNPipeline
-// 0x53F2009C CCustomBuildingPipeline
-//
-// Xbox
-// 0x53F2009E building !N !EN
-// 0x53F20096 building N !EN
-// 0x53F200A0 building !N EN (also env) non-DN custom instanceCB!
-// 0x53F200A2 building N EN (also env) DN custom instanceCB!
-
-extern int32 pipelineOffset;
-
-void registerPipelinePlugin(void);
-uint32 getPipelineID(Atomic *atomic);
-void setPipelineID(Atomic *atomic, uint32 id);
-
-// 2dEffect
-
-extern int32 twodEffectOffset;
-
-void register2dEffectPlugin(void);
-
-// Collision
-
-extern int32 collisionOffset;
-
-void registerCollisionPlugin(void);
-
-// PDS pipes
-
-struct SaVert : ps2::Vertex {
- float32 w[4];
- uint8 i[4];
- float32 t1[2];
- uint8 c1[4];
-};
-void insertSAVertex(Geometry *geo, int32 i, uint32 mask, SaVert *v);
-int32 findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v);
-
-void registerPDSPipes(void);
-
-}
diff --git a/src/image.cpp b/src/image.cpp
index 99a5eb8..94a8788 100755
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
@@ -104,6 +102,8 @@ TexDictionary::streamGetSize(void)
// Texture
//
+bool32 loadTextures;
+
Texture*
Texture::create(Raster *raster)
{
@@ -149,19 +149,22 @@ Texture::read(const char *name, const char *mask)
tex = Texture::create(NULL);
strncpy(tex->name, name, 32);
strncpy(tex->mask, mask, 32);
-// char *n = (char*)malloc(strlen(name) + 5);
-// strcpy(n, name);
-// strcat(n, ".tga");
-// Image *img = readTGA(n);
-// free(n);
-// if(img){
-// //raster = Raster::createFromImage(img);
-// raster = new Raster(0, 0, 0, 0x80);
-// img->destroy();
-// }else
+ Image *img = NULL;
+ if(loadTextures){
+ char *n = (char*)malloc(strlen(name) + 5);
+ strcpy(n, name);
+ strcat(n, ".tga");
+ img = readTGA(n);
+ free(n);
+ if(img){
+ raster = Raster::createFromImage(img);
+ img->destroy();
+ }else
+ raster = Raster::create(0, 0, 0, 0x80);
+ }else
raster = Raster::create(0, 0, 0, 0x80);
tex->raster = raster;
- if(currentTexDictionary /*&& img*/)
+ if(currentTexDictionary)
currentTexDictionary->add(tex);
return tex;
}
@@ -184,9 +187,9 @@ Texture::streamRead(Stream *stream)
stream->read(mask, length);
Texture *tex = Texture::read(name, mask);
- tex->refCount++;
if(tex->refCount == 1)
tex->filterAddressing = filterAddressing;
+ tex->refCount++; // TODO: RW doesn't do this, why?
tex->streamReadPlugins(stream);
@@ -640,36 +643,15 @@ Raster::calculateNumLevels(int32 width, int32 height)
return n;
}
-// BAD BAD BAD BAD
Raster*
Raster::createFromImage(Image *image)
{
- assert(0 && "cannot create raster from image");
- int32 format;
- // TODO: make that into a function
- if(image->depth == 32)
- format = Raster::C8888;
- else if(image->depth == 24)
- format = Raster::C888;
- else if(image->depth == 16)
- format = Raster::C1555;
- else if(image->depth == 8)
- format = Raster::PAL8 | Raster::C8888;
- else if(image->depth == 4)
- format = Raster::PAL4 | Raster::C8888;
- else
- return NULL;
Raster *raster = Raster::create(image->width, image->height,
- image->depth, format | 4 | 0x80);
- raster->stride = image->stride;
-
- raster->texels = new uint8[raster->stride*raster->height];
- memcpy(raster->texels, image->pixels, raster->stride*raster->height);
- if(image->palette){
- int size = raster->depth == 4 ? 16 : 256;
- raster->palette = new uint8[size*4];
- memcpy(raster->palette, image->palette, size*4);
- }
+ image->depth, 4 | 0x80);
+ int32 offset = nativeOffsets[raster->platform];
+ assert(offset != 0 && "unimplemented raster platform");
+ NativeRaster *nr = PLUGINOFFSET(NativeRaster, raster, offset);
+ nr->fromImage(raster, image);
return raster;
}
diff --git a/src/ogl.cpp b/src/ogl.cpp
index e6557d2..75c9a1b 100644
--- a/src/ogl.cpp
+++ b/src/ogl.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
diff --git a/src/pipeline.cpp b/src/pipeline.cpp
index 961b4d5..e2f6867 100644
--- a/src/pipeline.cpp
+++ b/src/pipeline.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
diff --git a/src/plugins.cpp b/src/plugins.cpp
index 9ba2649..03227fc 100644
--- a/src/plugins.cpp
+++ b/src/plugins.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
@@ -595,10 +593,10 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
//{
//float *mat = &skin->inverseMatrices[i*16];
- //printf("[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
- // " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
- // " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
- // " [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n",
+ //printf("[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
+ // " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
+ // " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
+ // " [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n",
// mat[0], mat[4], mat[8], mat[12],
// mat[1], mat[5], mat[9], mat[13],
// mat[2], mat[6], mat[10], mat[14],
@@ -913,7 +911,16 @@ MatFX::setEffects(uint32 type)
}
}
-int32
+uint32
+MatFX::getEffects(Material *m)
+{
+ MatFX *fx = *PLUGINOFFSET(MatFX*, m, matFXGlobals.materialOffset);
+ if(fx)
+ return fx->type;
+ return 0;
+}
+
+uint32
MatFX::getEffectIndex(uint32 type)
{
for(int i = 0; i < 2; i++)
diff --git a/src/ps2.cpp b/src/ps2.cpp
index 3dd1f2a..8fce8b4 100644
--- a/src/ps2.cpp
+++ b/src/ps2.cpp
@@ -3,16 +3,12 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
#include "rwpipeline.h"
#include "rwobjects.h"
#include "rwps2.h"
-using namespace std;
-
namespace rw {
namespace ps2 {
@@ -282,6 +278,34 @@ instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
return p;
}
+uint32*
+instanceUV2(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
+{
+ uint16 j;
+ uint32 *d0 = (uint32*)g->texCoords[0];
+ uint32 *d1 = (uint32*)g->texCoords[1];
+ for(uint32 i = idx; i < idx+n; i++){
+ j = m->indices[i];
+ if(g->numTexCoordSets > 0){
+ *p++ = d0[j*2+0];
+ *p++ = d0[j*2+1];
+ }else{
+ *p++ = 0;
+ *p++ = 0;
+ }
+ if(g->numTexCoordSets > 1){
+ *p++ = d1[j*2+0];
+ *p++ = d1[j*2+1];
+ }else{
+ *p++ = 0;
+ *p++ = 0;
+ }
+ }
+ while((uintptr)p % 0x10)
+ *p++ = 0;
+ return p;
+}
+
uint32*
instanceRGBA(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{
@@ -338,15 +362,18 @@ MatPipeline::dump(void)
if(this->platform != PLATFORM_PS2)
return;
PipeAttribute *a;
+ printf("%x %x\n", this->pluginID, this->pluginData);
for(uint i = 0; i < nelem(this->attribs); i++){
a = this->attribs[i];
if(a)
printf("%d %s: %x\n", i, a->name, a->attrib);
}
printf("stride: %x\n", this->inputStride);
+ printf("vertcount: %x\n", this->vifOffset/this->inputStride);
printf("triSCount: %x\n", this->triStripCount);
printf("triLCount: %x\n", this->triListCount);
printf("vifOffset: %x\n", this->vifOffset);
+ printf("\n");
}
void
@@ -506,20 +533,16 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
*p++ = (a->attrib&0xFF004000)
| 0x8000 | nverts << 16 | i; // UNPACK
- switch(i){
- case 0:
+ if(a == &attribXYZ)
p = instanceXYZ(p, g, m, idx, nverts);
- break;
- case 1:
+ else if(a == &attribUV)
p = instanceUV(p, g, m, idx, nverts);
- break;
- case 2:
+ else if(a == &attribUV2)
+ p = instanceUV2(p, g, m, idx, nverts);
+ else if(a == &attribRGBA)
p = instanceRGBA(p, g, m, idx, nverts);
- break;
- case 3:
- p = instanceNormal(p,g, m, idx, nverts);
- break;
- }
+ else if(a == &attribNormal)
+ p = instanceNormal(p, g, m, idx, nverts);
}
idx += g->meshHeader->flags == 1
? im.batchVertCount-2 : im.batchVertCount;
@@ -726,6 +749,7 @@ findVertex(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
{
float32 *verts = g->morphTargets[0].vertices;
float32 *tex = g->texCoords[0];
+ float32 *tex1 = g->texCoords[1];
float32 *norms = g->morphTargets[0].normals;
uint8 *cols = g->colors;
@@ -742,10 +766,14 @@ findVertex(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
if(mask & flags[i] & 0x1000 &&
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
goto cont;
+ if(mask & flags[i] & 0x2000 &&
+ !(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
+ goto cont;
return i;
cont:
verts += 3;
tex += 2;
+ tex1 += 2;
norms += 3;
cols += 4;
}
@@ -763,10 +791,12 @@ insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v)
memcpy(&geo->colors[i*4], v->c, 4);
if(mask & 0x1000)
memcpy(&geo->texCoords[0][i*2], v->t, 8);
+ if(mask & 0x2000)
+ memcpy(&geo->texCoords[1][i*2], v->t1, 8);
}
void
-defaultUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
+defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
{
float32 *verts = (float32*)data[AT_XYZ];
float32 *texcoords = (float32*)data[AT_UV];
@@ -777,8 +807,9 @@ defaultUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uin
mask |= 0x10;
if(geo->geoflags & Geometry::PRELIT)
mask |= 0x100;
- if(geo->numTexCoordSets > 0)
- mask |= 0x1000;
+ for(int32 i = 0; i < geo->numTexCoordSets; i++)
+ mask |= 0x1000 << i;
+ int numUV = pipe->attribs[AT_UV] == &attribUV2 ? 2 : 1;
Vertex v;
for(uint32 i = 0; i < mesh->numIndices; i++){
@@ -793,6 +824,8 @@ defaultUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uin
memcpy(&v.c, colors, 4);
if(mask & 0x1000)
memcpy(&v.t, texcoords, 8);
+ if(mask & 0x2000)
+ memcpy(&v.t1, texcoords+2, 8);
int32 idx = findVertex(geo, flags, mask, &v);
if(idx < 0)
@@ -801,7 +834,7 @@ defaultUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uin
flags[idx] = mask;
insertVertex(geo, idx, mask, &v);
verts += 3;
- texcoords += 2;
+ texcoords += 2*numUV;
colors += 4;
norms += 3;
}
@@ -1315,6 +1348,7 @@ static void
atomicPDSRights(void *object, int32, int32, uint32 data)
{
Atomic *a = (Atomic*)object;
+ //printf("atm pds: %x\n", data);
a->pipeline = (ObjPipeline*)getPDSPipe(data);
}
@@ -1322,6 +1356,7 @@ static void
materialPDSRights(void *object, int32, int32, uint32 data)
{
Material *m = (Material*)object;
+ //printf("mat pds: %x\n", data);
m->pipeline = (ObjPipeline*)getPDSPipe(data);
}
@@ -1338,6 +1373,73 @@ registerPDSPlugin(int32 n)
Material::setStreamRightsCallback(ID_PDS, materialPDSRights);
}
+void
+registerPluginPDSPipes(void)
+{
+ // Skin
+ MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
+ pipe->pluginID = ID_PDS;
+ pipe->pluginData = 0x11001; // rwPDS_G3_Generic_GrpMatPipeID
+ pipe->attribs[AT_XYZ] = &attribXYZ;
+ pipe->attribs[AT_UV] = &attribUV;
+ pipe->attribs[AT_RGBA] = &attribRGBA;
+ pipe->attribs[AT_NORMAL] = &attribNormal;
+ pipe->attribs[AT_NORMAL+1] = &attribWeights;
+ uint32 vertCount = MatPipeline::getVertCount(VU_Lights-0x100, 5, 3, 2);
+ pipe->setTriBufferSizes(5, vertCount);
+ pipe->vifOffset = pipe->inputStride*vertCount;
+ pipe->instanceCB = skinInstanceCB;
+ pipe->uninstanceCB = skinUninstanceCB;
+ pipe->preUninstCB = skinPreCB;
+ pipe->postUninstCB = skinPostCB;
+ registerPDSPipe(pipe);
+
+ ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
+ opipe->pluginID = ID_PDS;
+ opipe->pluginData = 0x11002; // rwPDS_G3_Skin_GrpAtmPipeID
+ opipe->groupPipeline = pipe;
+ registerPDSPipe(opipe);
+
+ // MatFX UV1
+ pipe = new MatPipeline(PLATFORM_PS2);
+ pipe->pluginID = ID_PDS;
+ pipe->pluginData = 0x1100b; // rwPDS_G3_MatfxUV1_GrpMatPipeID
+ pipe->attribs[AT_XYZ] = &attribXYZ;
+ pipe->attribs[AT_UV] = &attribUV;
+ pipe->attribs[AT_RGBA] = &attribRGBA;
+ pipe->attribs[AT_NORMAL] = &attribNormal;
+ vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
+ pipe->setTriBufferSizes(4, vertCount);
+ pipe->vifOffset = pipe->inputStride*vertCount;
+ pipe->uninstanceCB = defaultUninstanceCB;
+ registerPDSPipe(pipe);
+
+ opipe = new ObjPipeline(PLATFORM_PS2);
+ opipe->pluginID = ID_PDS;
+ opipe->pluginData = 0x1100d; // rwPDS_G3_MatfxUV1_GrpAtmPipeID
+ opipe->groupPipeline = pipe;
+ registerPDSPipe(opipe);
+
+ // MatFX UV2
+ pipe = new MatPipeline(PLATFORM_PS2);
+ pipe->pluginID = ID_PDS;
+ pipe->pluginData = 0x1100c; // rwPDS_G3_MatfxUV2_GrpMatPipeID
+ pipe->attribs[AT_XYZ] = &attribXYZ;
+ pipe->attribs[AT_UV] = &attribUV2;
+ pipe->attribs[AT_RGBA] = &attribRGBA;
+ pipe->attribs[AT_NORMAL] = &attribNormal;
+ vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3);
+ pipe->setTriBufferSizes(4, vertCount);
+ pipe->vifOffset = pipe->inputStride*vertCount;
+ pipe->uninstanceCB = defaultUninstanceCB;
+ registerPDSPipe(pipe);
+
+ opipe = new ObjPipeline(PLATFORM_PS2);
+ opipe->pluginID = ID_PDS;
+ opipe->pluginData = 0x1100e; // rwPDS_G3_MatfxUV2_GrpAtmPipeID
+ opipe->groupPipeline = pipe;
+ registerPDSPipe(opipe);
+}
// misc stuff
@@ -1406,555 +1508,5 @@ sizedebug(InstanceData *inst)
}
}
-// Raster
-
-int32 nativeRasterOffset;
-
-#define MAXLEVEL(r) ((r)->tex1[1]>>18 & 0x3F)
-#define SETMAXLEVEL(r, l) ((r)->tex1[1] = (r)->tex1[1]&~0xFF0000 | l<<18)
-#define SETKL(r, val) ((r)->tex1[1] = (r)->tex1[1]&~0xFFFF | (uint16)(val))
-static bool32 noNewStyleRasters;
-
-// i don't really understand this, stolen from RW
-static void
-ps2MinSize(int32 psm, int32 flags, int32 *minw, int32 *minh)
-{
- *minh = 1;
- switch(psm){
- case 0x00:
- case 0x30:
- *minw = 2; // 32 bit
- break;
- case 0x02:
- case 0x0A:
- case 0x32:
- case 0x3A:
- *minw = 4; // 16 bit
- break;
- case 0x01:
- case 0x13:
- case 0x14:
- case 0x1B:
- case 0x24:
- case 0x2C:
- case 0x31:
- *minw = 8; // everything else
- break;
- }
- if(flags & 0x2 && psm == 0x13){ // PSMT8
- *minw = 16;
- *minh = 4;
- }
- if(flags & 0x4 && psm == 0x14){ // PSMT4
- *minw = 32;
- *minh = 4;
- }
-}
-
-void
-Ps2Raster::create(Raster *raster)
-{
- int32 pageWidth, pageHeight;
- Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
- //printf("%x %x %x %x\n", raster->format, raster->flags, raster->type, noNewStyleRasters);
- assert(raster->type == 4); // Texture
- switch(raster->depth){
- case 4:
- pageWidth = 128;
- pageHeight = 128;
- break;
- case 8:
- pageWidth = 128;
- pageHeight = 64;
- break;
- case 16:
- pageWidth = 64;
- pageHeight = 64;
- break;
- case 32:
- pageWidth = 64;
- pageHeight = 32;
- break;
- default:
- assert(0 && "unsupported depth");
- }
- int32 logw = 0, logh = 0;
- int32 s;
- for(s = 1; s < raster->width; s *= 2)
- logw++;
- for(s = 1; s < raster->height; s *= 2)
- logh++;
- SETKL(ras, 0xFC0);
- //printf("%d %d %d %d\n", raster->width, logw, raster->height, logh);
- ras->tex0[0] |= (raster->width < pageWidth ? pageWidth : raster->width)/64 << 14;
- ras->tex0[0] |= logw << 26;
- ras->tex0[0] |= logh << 30;
- ras->tex0[1] |= logh >> 2;
-
- int32 paletteWidth, paletteHeight, paletteDepth;
- int32 palettePagewidth, palettePageheight;
- if(raster->format & (Raster::PAL4 | Raster::PAL8))
- switch(raster->format & 0xF00){
- case Raster::C1555:
- ras->tex0[1] |= 0xA << 19; // PSMCT16S
- paletteDepth = 2;
- palettePagewidth = palettePageheight = 64;
- break;
- case Raster::C8888:
- // PSMCT32
- paletteDepth = 4;
- palettePagewidth = 64;
- palettePageheight = 32;
- break;
- default:
- assert(0 && "unsupported palette format\n");
- }
- if(raster->format & Raster::PAL4){
- ras->tex0[0] |= 0x14 << 20; // PSMT4
- ras->tex0[1] |= 1<<29 | 1<<2; // CLD 1, TCC RGBA
- paletteWidth = 8;
- paletteHeight = 2;
- }else if(raster->format & Raster::PAL8){
- ras->tex0[0] |= 0x13 << 20; // PSMT8
- ras->tex0[1] |= 1<<29 | 1<<2; // CLD 1, TCC RGBA
- paletteWidth = paletteHeight = 16;
- }else{
- paletteWidth = 0;
- paletteHeight = 0;
- paletteDepth = 0;
- palettePagewidth = 0;
- palettePageheight = 0;
- switch(raster->format & 0xF00){
- case Raster::C1555:
- ras->tex0[0] |= 0xA << 20; // PSMCT16S
- ras->tex0[1] |= 1 << 2; // TCC RGBA
- break;
- case Raster::C8888:
- // PSMCT32
- ras->tex0[1] |= 1 << 2; // TCC RGBA
- break;
- case Raster::C888:
- ras->tex0[0] |= 1 << 20; // PSMCT24
- break;
- default:
- assert(0 && "unsupported raster format\n");
- }
- }
-
- raster->stride = raster->width*raster->depth/8;
- if(raster->format & Raster::MIPMAP){
- assert(0);
- }else{
- ras->texelSize = raster->stride*raster->depth+0xF & ~0xF;
- ras->paletteSize = paletteWidth*paletteHeight*paletteDepth;
- ras->miptbp1[0] |= 1<<14; // TBW1
- ras->miptbp1[1] |= 1<<2 | 1<<22; // TBW2,3
- ras->miptbp2[0] |= 1<<14; // TBW4
- ras->miptbp2[1] |= 1<<2 | 1<<22; // TBW5,6
- SETMAXLEVEL(ras, 0);
- int32 nPagW = (raster->width + pageWidth-1)/pageWidth;
- int32 nPagH = (raster->height + pageHeight-1)/pageHeight;
- ras->gsSize = (nPagW*nPagH*0x800)&~0x7FF;
- if(ras->paletteSize){
- // BITBLTBUF DBP
- if(pageWidth*nPagW > raster->width ||
- pageHeight*nPagH > raster->height)
- ras->tex1[0] = (ras->gsSize >> 6) - 4;
- else{
- ras->tex1[0] = ras->gsSize >> 6;
- }
- nPagW = (paletteWidth + palettePagewidth-1)/palettePagewidth;
- nPagH = (paletteHeight + palettePageheight-1)/palettePageheight;
- ras->gsSize += (nPagW*nPagH*0x800)&~0x7FF;
- }else
- ras->tex1[0] = 0;
- }
-
- // allocate data and fill with GIF packets
- ras->texelSize = ras->texelSize+0xF & ~0xF;
- int32 numLevels = MAXLEVEL(ras)+1;
- if(noNewStyleRasters ||
- (raster->width*raster->height*raster->depth & ~0x7F) >= 0x3FFF80){
- assert(0);
- }else{
- ras->flags |= 1; // include GIF packets
- int32 psm = ras->tex0[0]>>20 & 0x3F;
- //int32 cpsm = ras->tex0[1]>>19 & 0x3F;
- if(psm == 0x13){ // PSMT8
- ras->flags |= 2;
- // TODO: stuff
- }
- if(psm == 0x14){ // PSMT4
- // swizzle flag probably depends on version :/
- if(rw::version > 0x31000)
- ras->flags |= 4;
- // TODO: stuff
- }
- ras->texelSize = 0x50*numLevels; // GIF packets
- int32 minW, minH;
- ps2MinSize(psm, ras->flags, &minW, &minH);
- int32 w = raster->width;
- int32 h = raster->height;
- int32 mipw, miph;
- int32 n = numLevels;
- while(n--){
- mipw = w < minW ? minW : w;
- miph = h < minH ? minH : h;
- ras->texelSize += mipw*miph*raster->depth/8+0xF & ~0xF;
- w /= 2;
- h /= 2;
- }
- if(ras->paletteSize){
- if(rw::version > 0x31000 && paletteHeight == 2)
- paletteHeight = 3;
- ras->paletteSize = 0x50 +
- paletteDepth*paletteWidth*paletteHeight;
- }
- // TODO: allocate space for more DMA packets
- ras->dataSize = ras->paletteSize+ras->texelSize;
- uint8 *data = new uint8[ras->dataSize];
- assert(data);
- ras->data = data;
- raster->texels = data + 0x50;
- if(ras->paletteSize)
- raster->palette = data + ras->texelSize + 0x50;
- uint32 *p = (uint32*)data;
- w = raster->width;
- h = raster->height;
- for(n = 0; n < numLevels; n++){
- mipw = w < minW ? minW : w;
- miph = h < minH ? minH : h;
-
- // GIF tag
- *p++ = 3; // NLOOP = 3
- *p++ = 0x10000000; // NREG = 1
- *p++ = 0xE; // A+D
- *p++ = 0;
-
- // TRXPOS
- *p++ = 0; // TODO
- *p++ = 0; // TODO
- *p++ = 0x51;
- *p++ = 0;
-
- // TRXREG
- if(ras->flags & 2 && psm == 0x13 ||
- ras->flags & 4 && psm == 0x14){
- *p++ = mipw/2;
- *p++ = miph/2;
- }else{
- *p++ = mipw;
- *p++ = miph;
- }
- *p++ = 0x52;
- *p++ = 0;
-
- // TRXDIR
- *p++ = 0; // host -> local
- *p++ = 0;
- *p++ = 0x53;
- *p++ = 0;
-
- // GIF tag
- uint32 sz = mipw*miph*raster->depth/8 + 0xF >> 4;
- *p++ = sz;
- *p++ = 0x08000000; // IMAGE
- *p++ = 0;
- *p++ = 0;
-
- p += sz*4;
- w /= 2;
- h /= 2;
- }
- if(ras->paletteSize){
- p = (uint32*)(raster->palette - 0x50);
- // GIF tag
- *p++ = 3; // NLOOP = 3
- *p++ = 0x10000000; // NREG = 1
- *p++ = 0xE; // A+D
- *p++ = 0;
-
- // TRXPOS
- *p++ = 0; // TODO
- *p++ = 0; // TODO
- *p++ = 0x51;
- *p++ = 0;
-
- // TRXREG
- *p++ = paletteWidth;
- *p++ = paletteHeight;
- *p++ = 0x52;
- *p++ = 0;
-
- // TRXDIR
- *p++ = 0; // host -> local
- *p++ = 0;
- *p++ = 0x53;
- *p++ = 0;
-
- // GIF tag
- uint32 sz = paletteSize - 0x50 + 0xF >> 4;
- *p++ = sz;
- *p++ = 0x08000000; // IMAGE
- *p++ = 0;
- *p++ = 0;
-
- }
- }
-}
-
-uint8*
-Ps2Raster::lock(Raster *raster, int32 level)
-{
- // TODO
- (void)raster;
- (void)level;
- return NULL;
-}
-
-void
-Ps2Raster::unlock(Raster *raster, int32 level)
-{
- // TODO
- (void)raster;
- (void)level;
-}
-
-int32
-Ps2Raster::getNumLevels(Raster *raster)
-{
- Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
- if(raster->texels == NULL) return 0;
- if(raster->format & Raster::MIPMAP)
- return MAXLEVEL(ras)+1;
- return 1;
-}
-
-static void*
-createNativeRaster(void *object, int32 offset, int32)
-{
- Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset);
- new (raster) Ps2Raster;
- raster->tex0[0] = 0;
- raster->tex0[1] = 0;
- raster->tex1[0] = 0;
- raster->tex1[1] = 0;
- raster->miptbp1[0] = 0;
- raster->miptbp1[1] = 0;
- raster->miptbp2[0] = 0;
- raster->miptbp2[1] = 0;
- raster->texelSize = 0;
- raster->paletteSize = 0;
- raster->gsSize = 0;
- raster->flags = 0;
- SETKL(raster, 0xFC0);
-
- raster->dataSize = 0;
- raster->data = NULL;
- return object;
-}
-
-static void*
-destroyNativeRaster(void *object, int32 offset, int32)
-{
- // TODO
- (void)offset;
- 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 = *srcraster;
- return dst;
-}
-
-static void
-readMipmap(Stream *stream, int32, void *object, int32 offset, int32)
-{
- uint16 val = stream->readI32();
- Texture *tex = (Texture*)object;
- if(tex->raster == NULL)
- return;
- Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
- SETKL(raster, val);
-}
-
-static void
-writeMipmap(Stream *stream, int32, void *object, int32 offset, int32)
-{
- Texture *tex = (Texture*)object;
- assert(tex->raster);
- Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
- stream->writeI32(raster->tex1[1]&0xFFFF);
-}
-
-static int32
-getSizeMipmap(void*, int32, int32)
-{
- return rw::platform == PLATFORM_PS2 ? 4 : 0;
-}
-
-void
-registerNativeRaster(void)
-{
- nativeRasterOffset = Raster::registerPlugin(sizeof(Ps2Raster),
- 0x12340000 | PLATFORM_PS2,
- createNativeRaster,
- destroyNativeRaster,
- copyNativeRaster);
- Raster::nativeOffsets[PLATFORM_PS2] = nativeRasterOffset;
- Texture::registerPlugin(0, ID_SKYMIPMAP, NULL, NULL, NULL);
- Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap);
-}
-
-struct StreamRasterExt
-{
- int32 width;
- int32 height;
- int32 depth;
- uint16 rasterFormat;
- int16 type;
- uint32 tex0[2];
- uint32 tex1[2];
- uint32 miptbp1[2];
- uint32 miptbp2[2];
- uint32 texelSize;
- uint32 paletteSize;
- uint32 gsSize;
- uint32 mipmapVal;
-};
-
-Texture*
-readNativeTexture(Stream *stream)
-{
- uint32 length, oldversion, version;
- assert(findChunk(stream, ID_STRUCT, NULL, NULL));
- assert(stream->readU32() == 0x00325350); // 'PS2\0'
- Texture *tex = Texture::create(NULL);
-
- // Texture
- tex->filterAddressing = stream->readU32();
- assert(findChunk(stream, ID_STRING, &length, NULL));
- stream->read(tex->name, length);
- assert(findChunk(stream, ID_STRING, &length, NULL));
- stream->read(tex->mask, length);
-
- // Raster
- StreamRasterExt streamExt;
- oldversion = rw::version;
- assert(findChunk(stream, ID_STRUCT, NULL, NULL));
- assert(findChunk(stream, ID_STRUCT, NULL, &version));
- stream->read(&streamExt, 0x40);
- Raster *raster;
- noNewStyleRasters = streamExt.type < 2;
- rw::version = version;
- raster = Raster::create(streamExt.width, streamExt.height,
- streamExt.depth, streamExt.rasterFormat,
- PLATFORM_PS2);
- noNewStyleRasters = 0;
- rw::version = oldversion;
- tex->raster = raster;
- Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
- //printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
- // ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
- // ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
- ras->tex0[0] = streamExt.tex0[0];
- ras->tex0[1] = streamExt.tex0[1];
- ras->tex1[0] = streamExt.tex1[0];
- ras->tex1[1] = ras->tex1[1]&~0xFF0000 | streamExt.tex1[1]<<16 & 0xFF0000;
- ras->miptbp1[0] = streamExt.miptbp1[0];
- ras->miptbp1[1] = streamExt.miptbp1[1];
- ras->miptbp2[0] = streamExt.miptbp2[0];
- ras->miptbp2[1] = streamExt.miptbp2[1];
- ras->texelSize = streamExt.texelSize;
- ras->paletteSize = streamExt.paletteSize;
- ras->gsSize = streamExt.gsSize;
- SETKL(ras, streamExt.mipmapVal);
- //printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
- // ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
- // ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
-
- assert(findChunk(stream, ID_STRUCT, &length, NULL));
- if(streamExt.type < 2){
- stream->read(raster->texels, length);
- }else{
- stream->read(raster->texels-0x50, ras->texelSize);
- stream->read(raster->palette-0x50, ras->paletteSize);
- }
-
- tex->streamReadPlugins(stream);
- return tex;
-}
-
-void
-writeNativeTexture(Texture *tex, Stream *stream)
-{
- Raster *raster = tex->raster;
- Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
- int32 chunksize = getSizeNativeTexture(tex);
- writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize);
- writeChunkHeader(stream, ID_STRUCT, 8);
- stream->writeU32(FOURCC_PS2);
- stream->writeU32(tex->filterAddressing);
- int32 len = strlen(tex->name)+4 & ~3;
- writeChunkHeader(stream, ID_STRING, len);
- stream->write(tex->name, len);
- len = strlen(tex->mask)+4 & ~3;
- writeChunkHeader(stream, ID_STRING, len);
- stream->write(tex->mask, len);
-
- int32 sz = ras->texelSize + ras->paletteSize;
- writeChunkHeader(stream, ID_STRUCT, 12 + 64 + 12 + sz);
- writeChunkHeader(stream, ID_STRUCT, 64);
- StreamRasterExt streamExt;
- streamExt.width = raster->width;
- streamExt.height = raster->height;
- streamExt.depth = raster->depth;
- streamExt.rasterFormat = raster->format | raster->type;
- streamExt.type = 0;
- if(ras->flags == 2 && raster->depth == 8)
- streamExt.type = 1;
- if(ras->flags & 1)
- streamExt.type = 2;
- streamExt.tex0[0] = ras->tex0[0];
- streamExt.tex0[1] = ras->tex0[1];
- streamExt.tex1[0] = ras->tex1[0];
- streamExt.tex1[1] = ras->tex1[1]>>16 & 0xFF;
- streamExt.miptbp1[0] = ras->miptbp1[0];
- streamExt.miptbp1[1] = ras->miptbp1[1];
- streamExt.miptbp2[0] = ras->miptbp2[0];
- streamExt.miptbp2[1] = ras->miptbp2[1];
- streamExt.texelSize = ras->texelSize;
- streamExt.paletteSize = ras->paletteSize;
- streamExt.gsSize = ras->gsSize;
- streamExt.mipmapVal = ras->tex1[1]&0xFFFF;
- stream->write(&streamExt, 64);
-
- writeChunkHeader(stream, ID_STRUCT, sz);
- if(streamExt.type < 2){
- stream->write(raster->texels, sz);
- }else{
- stream->write(raster->texels-0x50, ras->texelSize);
- stream->write(raster->palette-0x50, ras->paletteSize);
- }
- tex->streamWritePlugins(stream);
-}
-
-uint32
-getSizeNativeTexture(Texture *tex)
-{
- uint32 size = 12 + 8;
- size += 12 + strlen(tex->name)+4 & ~3;
- size += 12 + strlen(tex->mask)+4 & ~3;
- size += 12 + 12 + 64 + 12;
- Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset);
- size += ras->texelSize + ras->paletteSize;
- size += 12 + tex->streamGetPluginSize();
- return size;
-}
-
}
}
diff --git a/src/ps2raster.cpp b/src/ps2raster.cpp
new file mode 100644
index 0000000..f414bb1
--- /dev/null
+++ b/src/ps2raster.cpp
@@ -0,0 +1,636 @@
+#include
+#include
+#include
+#include
+
+#include
+
+#include "rwbase.h"
+#include "rwplugin.h"
+#include "rwpipeline.h"
+#include "rwobjects.h"
+#include "rwps2.h"
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+namespace rw {
+namespace ps2 {
+
+int32 nativeRasterOffset;
+
+#define MAXLEVEL(r) ((r)->tex1[1]>>18 & 0x3F)
+#define SETMAXLEVEL(r, l) ((r)->tex1[1] = (r)->tex1[1]&~0xFF0000 | l<<18)
+#define SETKL(r, val) ((r)->tex1[1] = (r)->tex1[1]&~0xFFFF | (uint16)(val))
+static bool32 noNewStyleRasters;
+
+// i don't really understand this, stolen from RW
+static void
+ps2MinSize(int32 psm, int32 flags, int32 *minw, int32 *minh)
+{
+ *minh = 1;
+ switch(psm){
+ case 0x00:
+ case 0x30:
+ *minw = 2; // 32 bit
+ break;
+ case 0x02:
+ case 0x0A:
+ case 0x32:
+ case 0x3A:
+ *minw = 4; // 16 bit
+ break;
+ case 0x01:
+ case 0x13:
+ case 0x14:
+ case 0x1B:
+ case 0x24:
+ case 0x2C:
+ case 0x31:
+ *minw = 8; // everything else
+ break;
+ }
+ if(flags & 0x2 && psm == 0x13){ // PSMT8
+ *minw = 16;
+ *minh = 4;
+ }
+ if(flags & 0x4 && psm == 0x14){ // PSMT4
+ *minw = 32;
+ *minh = 4;
+ }
+}
+
+struct dword
+{
+ uint32 lo;
+ uint32 hi;
+};
+
+#define ALIGN64(x) ((x) + 0x3F & ~0x3F)
+
+void
+Ps2Raster::create(Raster *raster)
+{
+ uint64 bufferWidth[7], bufferBase[7];
+ int32 pageWidth, pageHeight;
+ Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
+
+ //printf("%x %x %x %x\n", raster->format, raster->flags, raster->type, noNewStyleRasters);
+ assert(raster->type == 4); // Texture
+ switch(raster->depth){
+ case 4:
+ pageWidth = 128;
+ pageHeight = 128;
+ break;
+ case 8:
+ pageWidth = 128;
+ pageHeight = 64;
+ break;
+ case 16:
+ pageWidth = 64;
+ pageHeight = 64;
+ break;
+ case 32:
+ pageWidth = 64;
+ pageHeight = 32;
+ break;
+ default:
+ assert(0 && "unsupported depth");
+ }
+ int32 logw = 0, logh = 0;
+ int32 s;
+ for(s = 1; s < raster->width; s *= 2)
+ logw++;
+ for(s = 1; s < raster->height; s *= 2)
+ logh++;
+ SETKL(ras, 0xFC0);
+ //printf("%d %d %d %d\n", raster->width, logw, raster->height, logh);
+ ras->tex0[0] |= (raster->width < pageWidth ? pageWidth : raster->width)/64 << 14;
+ ras->tex0[0] |= logw << 26;
+ ras->tex0[0] |= logh << 30;
+ ras->tex0[1] |= logh >> 2;
+
+ int32 paletteWidth, paletteHeight, paletteDepth;
+ int32 palettePagewidth, palettePageheight;
+ if(raster->format & (Raster::PAL4 | Raster::PAL8))
+ switch(raster->format & 0xF00){
+ case Raster::C1555:
+ ras->tex0[1] |= 0xA << 19; // PSMCT16S
+ paletteDepth = 2;
+ palettePagewidth = palettePageheight = 64;
+ break;
+ case Raster::C8888:
+ // PSMCT32
+ paletteDepth = 4;
+ palettePagewidth = 64;
+ palettePageheight = 32;
+ break;
+ default:
+ assert(0 && "unsupported palette format\n");
+ }
+ if(raster->format & Raster::PAL4){
+ ras->tex0[0] |= 0x14 << 20; // PSMT4
+ ras->tex0[1] |= 1<<29 | 1<<2; // CLD 1, TCC RGBA
+ paletteWidth = 8;
+ paletteHeight = 2;
+ }else if(raster->format & Raster::PAL8){
+ ras->tex0[0] |= 0x13 << 20; // PSMT8
+ ras->tex0[1] |= 1<<29 | 1<<2; // CLD 1, TCC RGBA
+ paletteWidth = paletteHeight = 16;
+ }else{
+ paletteWidth = 0;
+ paletteHeight = 0;
+ paletteDepth = 0;
+ palettePagewidth = 0;
+ palettePageheight = 0;
+ switch(raster->format & 0xF00){
+ case Raster::C1555:
+ ras->tex0[0] |= 0xA << 20; // PSMCT16S
+ ras->tex0[1] |= 1 << 2; // TCC RGBA
+ break;
+ case Raster::C8888:
+ // PSMCT32
+ ras->tex0[1] |= 1 << 2; // TCC RGBA
+ break;
+ case Raster::C888:
+ ras->tex0[0] |= 1 << 20; // PSMCT24
+ break;
+ default:
+ assert(0 && "unsupported raster format\n");
+ }
+ }
+
+ for(int i = 0; i < 7; i++){
+ bufferWidth[i] = 1;
+ bufferBase[i] = 0;
+ }
+
+ int32 mipw, miph;
+ int32 n;
+ int32 nPagW, nPagH;
+ int32 w = raster->width;
+ int32 h = raster->height;
+ int32 d = raster->depth;
+ raster->stride = w*d/8;
+
+ if(raster->format & Raster::MIPMAP){
+ static uint32 blockOffset32_24_8[8] = { 0, 2, 2, 8, 8, 10, 10, 32 };
+ static uint32 blockOffset16_4[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
+ static uint32 blockOffset16S[8] = { 0, 1, 8, 9, 4, 5, 12, 13 };
+ uint64 lastBufferWidth;
+ mipw = w;
+ miph = h;
+ lastBufferWidth = max(pageWidth, w)/64;
+ ras->texelSize = 0;
+ int32 gsoffset = 0;
+ int32 gsaddress = 0;
+ for(n = 0; n < 7; n++){
+ if(w >= 8 && h >= 8 && (mipw < 8 || miph < 8))
+ break;
+ ras->texelSize += ALIGN64(mipw*miph*d/8);
+ bufferWidth[n] = max(pageWidth, mipw)/64;
+
+ if(bufferWidth[n] != lastBufferWidth){
+ nPagW = ((w >> n-1) + pageWidth-1)/pageWidth;
+ nPagH = ((h >> n-1) + pageHeight-1)/pageHeight;
+ gsaddress = (gsoffset + nPagW*nPagH*0x800) & ~0x7FF;
+ }
+ lastBufferWidth = bufferWidth[n];
+ gsaddress = ALIGN64(gsaddress);
+ uint32 b = gsaddress/256 & 7;
+ switch(ras->tex0[0]>>20 & 0x3F){
+ case 0: case 1: case 0x13:
+ b = blockOffset32_24_8[b];
+ break;
+ case 2: case 0x14:
+ b = blockOffset16_4[b];
+ break;
+ case 0xA:
+ b = blockOffset16S[b];
+ break;
+ default:
+ // can't happen
+ break;
+ }
+ bufferBase[n] = b + (gsaddress>>11 << 5);
+ int32 stride = bufferWidth[n]/64*d/8;
+ gsaddress = ALIGN64(miph*stride/4 + gsoffset);
+
+ mipw /= 2;
+ miph /= 2;
+ }
+ assert(0);
+ }else{
+ ras->texelSize = raster->stride*raster->height+0xF & ~0xF;
+ ras->paletteSize = paletteWidth*paletteHeight*paletteDepth;
+ ras->miptbp1[0] |= 1<<14; // TBW1
+ ras->miptbp1[1] |= 1<<2 | 1<<22; // TBW2,3
+ ras->miptbp2[0] |= 1<<14; // TBW4
+ ras->miptbp2[1] |= 1<<2 | 1<<22; // TBW5,6
+ SETMAXLEVEL(ras, 0);
+ nPagW = (raster->width + pageWidth-1)/pageWidth;
+ nPagH = (raster->height + pageHeight-1)/pageHeight;
+ bufferBase[0] = 0;
+ bufferWidth[0] = nPagW * (pageWidth >> 6);
+ ras->gsSize = (nPagW*nPagH*0x800)&~0x7FF;
+ if(ras->paletteSize){
+ // BITBLTBUF DBP
+ if(pageWidth*nPagW > raster->width ||
+ pageHeight*nPagH > raster->height)
+ ras->tex1[0] = (ras->gsSize >> 6) - 4;
+ else{
+ ras->tex1[0] = ras->gsSize >> 6;
+ }
+ nPagW = (paletteWidth + palettePagewidth-1)/palettePagewidth;
+ nPagH = (paletteHeight + palettePageheight-1)/palettePageheight;
+ ras->gsSize += (nPagW*nPagH*0x800)&~0x7FF;
+ }else
+ ras->tex1[0] = 0;
+ }
+
+ // allocate data and fill with GIF packets
+ ras->texelSize = ras->texelSize+0xF & ~0xF;
+ int32 numLevels = MAXLEVEL(ras)+1;
+ if(noNewStyleRasters ||
+ (raster->width*raster->height*raster->depth & ~0x7F) >= 0x3FFF80){
+ assert(0);
+ }else{
+ ras->flags |= 1; // include GIF packets
+ int32 psm = ras->tex0[0]>>20 & 0x3F;
+ //int32 cpsm = ras->tex0[1]>>19 & 0x3F;
+ if(psm == 0x13){ // PSMT8
+ ras->flags |= 2;
+ // TODO: stuff
+ }
+ if(psm == 0x14){ // PSMT4
+ // swizzle flag probably depends on version :/
+ if(rw::version > 0x31000)
+ ras->flags |= 4;
+ // TODO: stuff
+ }
+ ras->texelSize = 0x50*numLevels; // GIF packets
+ int32 minW, minH;
+ ps2MinSize(psm, ras->flags, &minW, &minH);
+ w = raster->width;
+ h = raster->height;
+ n = numLevels;
+ while(n--){
+ mipw = w < minW ? minW : w;
+ miph = h < minH ? minH : h;
+ ras->texelSize += mipw*miph*raster->depth/8+0xF & ~0xF;
+ w /= 2;
+ h /= 2;
+ }
+ if(ras->paletteSize){
+ if(rw::version > 0x31000 && paletteHeight == 2)
+ paletteHeight = 3;
+ ras->paletteSize = 0x50 +
+ paletteDepth*paletteWidth*paletteHeight;
+ }
+ // TODO: allocate space for more DMA packets
+ ras->dataSize = ras->paletteSize+ras->texelSize;
+ uint8 *data = new uint8[ras->dataSize];
+ assert(data);
+ ras->data = data;
+ raster->texels = data + 0x50;
+ if(ras->paletteSize)
+ raster->palette = data + ras->texelSize + 0x50;
+ uint32 *p = (uint32*)data;
+ w = raster->width;
+ h = raster->height;
+ for(n = 0; n < numLevels; n++){
+ mipw = w < minW ? minW : w;
+ miph = h < minH ? minH : h;
+
+ // GIF tag
+ *p++ = 3; // NLOOP = 3
+ *p++ = 0x10000000; // NREG = 1
+ *p++ = 0xE; // A+D
+ *p++ = 0;
+
+ // TRXPOS
+ *p++ = 0; // TODO
+ *p++ = 0; // TODO
+ *p++ = 0x51;
+ *p++ = 0;
+
+ // TRXREG
+ if(ras->flags & 2 && psm == 0x13 ||
+ ras->flags & 4 && psm == 0x14){
+ *p++ = mipw/2;
+ *p++ = miph/2;
+ }else{
+ *p++ = mipw;
+ *p++ = miph;
+ }
+ *p++ = 0x52;
+ *p++ = 0;
+
+ // TRXDIR
+ *p++ = 0; // host -> local
+ *p++ = 0;
+ *p++ = 0x53;
+ *p++ = 0;
+
+ // GIF tag
+ uint32 sz = mipw*miph*raster->depth/8 + 0xF >> 4;
+ *p++ = sz;
+ *p++ = 0x08000000; // IMAGE
+ *p++ = 0;
+ *p++ = 0;
+
+ p += sz*4;
+ w /= 2;
+ h /= 2;
+ }
+
+ if(ras->paletteSize){
+ p = (uint32*)(raster->palette - 0x50);
+ // GIF tag
+ *p++ = 3; // NLOOP = 3
+ *p++ = 0x10000000; // NREG = 1
+ *p++ = 0xE; // A+D
+ *p++ = 0;
+
+ // TRXPOS
+ *p++ = 0; // TODO
+ *p++ = 0; // TODO
+ *p++ = 0x51;
+ *p++ = 0;
+
+ // TRXREG
+ *p++ = paletteWidth;
+ *p++ = paletteHeight;
+ *p++ = 0x52;
+ *p++ = 0;
+
+ // TRXDIR
+ *p++ = 0; // host -> local
+ *p++ = 0;
+ *p++ = 0x53;
+ *p++ = 0;
+
+ // GIF tag
+ uint32 sz = paletteSize - 0x50 + 0xF >> 4;
+ *p++ = sz;
+ *p++ = 0x08000000; // IMAGE
+ *p++ = 0;
+ *p++ = 0;
+ }
+ }
+}
+
+uint8*
+Ps2Raster::lock(Raster *raster, int32 level)
+{
+ // TODO
+ (void)raster;
+ (void)level;
+ return NULL;
+}
+
+void
+Ps2Raster::unlock(Raster *raster, int32 level)
+{
+ // TODO
+ (void)raster;
+ (void)level;
+}
+
+int32
+Ps2Raster::getNumLevels(Raster *raster)
+{
+ Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
+ if(raster->texels == NULL) return 0;
+ if(raster->format & Raster::MIPMAP)
+ return MAXLEVEL(ras)+1;
+ return 1;
+}
+
+static void*
+createNativeRaster(void *object, int32 offset, int32)
+{
+ Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset);
+ new (raster) Ps2Raster;
+ raster->tex0[0] = 0;
+ raster->tex0[1] = 0;
+ raster->tex1[0] = 0;
+ raster->tex1[1] = 0;
+ raster->miptbp1[0] = 0;
+ raster->miptbp1[1] = 0;
+ raster->miptbp2[0] = 0;
+ raster->miptbp2[1] = 0;
+ raster->texelSize = 0;
+ raster->paletteSize = 0;
+ raster->gsSize = 0;
+ raster->flags = 0;
+ SETKL(raster, 0xFC0);
+
+ raster->dataSize = 0;
+ raster->data = NULL;
+ return object;
+}
+
+static void*
+destroyNativeRaster(void *object, int32 offset, int32)
+{
+ // TODO
+ (void)offset;
+ 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 = *srcraster;
+ return dst;
+}
+
+static void
+readMipmap(Stream *stream, int32, void *object, int32 offset, int32)
+{
+ uint16 val = stream->readI32();
+ Texture *tex = (Texture*)object;
+ if(tex->raster == NULL)
+ return;
+ Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
+ SETKL(raster, val);
+}
+
+static void
+writeMipmap(Stream *stream, int32, void *object, int32 offset, int32)
+{
+ Texture *tex = (Texture*)object;
+ assert(tex->raster);
+ Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
+ stream->writeI32(raster->tex1[1]&0xFFFF);
+}
+
+static int32
+getSizeMipmap(void*, int32, int32)
+{
+ return rw::platform == PLATFORM_PS2 ? 4 : 0;
+}
+
+void
+registerNativeRaster(void)
+{
+ nativeRasterOffset = Raster::registerPlugin(sizeof(Ps2Raster),
+ 0x12340000 | PLATFORM_PS2,
+ createNativeRaster,
+ destroyNativeRaster,
+ copyNativeRaster);
+ Raster::nativeOffsets[PLATFORM_PS2] = nativeRasterOffset;
+ Texture::registerPlugin(0, ID_SKYMIPMAP, NULL, NULL, NULL);
+ Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap);
+}
+
+struct StreamRasterExt
+{
+ int32 width;
+ int32 height;
+ int32 depth;
+ uint16 rasterFormat;
+ int16 type;
+ uint32 tex0[2];
+ uint32 tex1[2];
+ uint32 miptbp1[2];
+ uint32 miptbp2[2];
+ uint32 texelSize;
+ uint32 paletteSize;
+ uint32 gsSize;
+ uint32 mipmapVal;
+};
+
+Texture*
+readNativeTexture(Stream *stream)
+{
+ uint32 length, oldversion, version;
+ assert(findChunk(stream, ID_STRUCT, NULL, NULL));
+ assert(stream->readU32() == 0x00325350); // 'PS2\0'
+ Texture *tex = Texture::create(NULL);
+
+ // Texture
+ tex->filterAddressing = stream->readU32();
+ assert(findChunk(stream, ID_STRING, &length, NULL));
+ stream->read(tex->name, length);
+ assert(findChunk(stream, ID_STRING, &length, NULL));
+ stream->read(tex->mask, length);
+
+ // Raster
+ StreamRasterExt streamExt;
+ oldversion = rw::version;
+ assert(findChunk(stream, ID_STRUCT, NULL, NULL));
+ assert(findChunk(stream, ID_STRUCT, NULL, &version));
+ stream->read(&streamExt, 0x40);
+ Raster *raster;
+ noNewStyleRasters = streamExt.type < 2;
+ rw::version = version;
+ raster = Raster::create(streamExt.width, streamExt.height,
+ streamExt.depth, streamExt.rasterFormat,
+ PLATFORM_PS2);
+ noNewStyleRasters = 0;
+ rw::version = oldversion;
+ tex->raster = raster;
+ Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
+ //printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
+ // ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
+ // ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
+ ras->tex0[0] = streamExt.tex0[0];
+ ras->tex0[1] = streamExt.tex0[1];
+ ras->tex1[0] = streamExt.tex1[0];
+ ras->tex1[1] = ras->tex1[1]&~0xFF0000 | streamExt.tex1[1]<<16 & 0xFF0000;
+ ras->miptbp1[0] = streamExt.miptbp1[0];
+ ras->miptbp1[1] = streamExt.miptbp1[1];
+ ras->miptbp2[0] = streamExt.miptbp2[0];
+ ras->miptbp2[1] = streamExt.miptbp2[1];
+ ras->texelSize = streamExt.texelSize;
+ ras->paletteSize = streamExt.paletteSize;
+ ras->gsSize = streamExt.gsSize;
+ SETKL(ras, streamExt.mipmapVal);
+ //printf("%08X%08X %08X%08X %08X%08X %08X%08X\n",
+ // ras->tex0[1], ras->tex0[0], ras->tex1[1], ras->tex1[0],
+ // ras->miptbp1[0], ras->miptbp1[1], ras->miptbp2[0], ras->miptbp2[1]);
+
+ assert(findChunk(stream, ID_STRUCT, &length, NULL));
+ if(streamExt.type < 2){
+ stream->read(raster->texels, length);
+ }else{
+ stream->read(raster->texels-0x50, ras->texelSize);
+ stream->read(raster->palette-0x50, ras->paletteSize);
+ }
+
+ tex->streamReadPlugins(stream);
+ return tex;
+}
+
+void
+writeNativeTexture(Texture *tex, Stream *stream)
+{
+ Raster *raster = tex->raster;
+ Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
+ int32 chunksize = getSizeNativeTexture(tex);
+ writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize);
+ writeChunkHeader(stream, ID_STRUCT, 8);
+ stream->writeU32(FOURCC_PS2);
+ stream->writeU32(tex->filterAddressing);
+ int32 len = strlen(tex->name)+4 & ~3;
+ writeChunkHeader(stream, ID_STRING, len);
+ stream->write(tex->name, len);
+ len = strlen(tex->mask)+4 & ~3;
+ writeChunkHeader(stream, ID_STRING, len);
+ stream->write(tex->mask, len);
+
+ int32 sz = ras->texelSize + ras->paletteSize;
+ writeChunkHeader(stream, ID_STRUCT, 12 + 64 + 12 + sz);
+ writeChunkHeader(stream, ID_STRUCT, 64);
+ StreamRasterExt streamExt;
+ streamExt.width = raster->width;
+ streamExt.height = raster->height;
+ streamExt.depth = raster->depth;
+ streamExt.rasterFormat = raster->format | raster->type;
+ streamExt.type = 0;
+ if(ras->flags == 2 && raster->depth == 8)
+ streamExt.type = 1;
+ if(ras->flags & 1)
+ streamExt.type = 2;
+ streamExt.tex0[0] = ras->tex0[0];
+ streamExt.tex0[1] = ras->tex0[1];
+ streamExt.tex1[0] = ras->tex1[0];
+ streamExt.tex1[1] = ras->tex1[1]>>16 & 0xFF;
+ streamExt.miptbp1[0] = ras->miptbp1[0];
+ streamExt.miptbp1[1] = ras->miptbp1[1];
+ streamExt.miptbp2[0] = ras->miptbp2[0];
+ streamExt.miptbp2[1] = ras->miptbp2[1];
+ streamExt.texelSize = ras->texelSize;
+ streamExt.paletteSize = ras->paletteSize;
+ streamExt.gsSize = ras->gsSize;
+ streamExt.mipmapVal = ras->tex1[1]&0xFFFF;
+ stream->write(&streamExt, 64);
+
+ writeChunkHeader(stream, ID_STRUCT, sz);
+ if(streamExt.type < 2){
+ stream->write(raster->texels, sz);
+ }else{
+ stream->write(raster->texels-0x50, ras->texelSize);
+ stream->write(raster->palette-0x50, ras->paletteSize);
+ }
+ tex->streamWritePlugins(stream);
+}
+
+uint32
+getSizeNativeTexture(Texture *tex)
+{
+ uint32 size = 12 + 8;
+ size += 12 + strlen(tex->name)+4 & ~3;
+ size += 12 + strlen(tex->mask)+4 & ~3;
+ size += 12 + 12 + 64 + 12;
+ Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset);
+ size += ras->texelSize + ras->paletteSize;
+ size += 12 + tex->streamGetPluginSize();
+ return size;
+}
+
+}
+}
\ No newline at end of file
diff --git a/src/rwbase.cpp b/src/rwbase.cpp
index eb26d3a..b20ac3d 100644
--- a/src/rwbase.cpp
+++ b/src/rwbase.cpp
@@ -3,8 +3,6 @@
#include
#include
-#include
-
#include "rwbase.h"
#include "rwplugin.h"
diff --git a/src/rwd3d.h b/src/rwd3d.h
index 4cf4a3a..11458f0 100644
--- a/src/rwd3d.h
+++ b/src/rwd3d.h
@@ -83,6 +83,7 @@ struct D3dRaster : NativeRaster
virtual uint8 *lock(Raster *raster, int32 level);
virtual void unlock(Raster *raster, int32 level);
virtual int32 getNumLevels(Raster *raster);
+ virtual void fromImage(Raster *raster, Image *img);
};
int32 getLevelSize(Raster *raster, int32 level);
diff --git a/src/rwobjects.h b/src/rwobjects.h
index c00de9c..6ad176e 100644
--- a/src/rwobjects.h
+++ b/src/rwobjects.h
@@ -51,7 +51,7 @@ struct LLLink
// Have to be careful since the link might be deleted.
#define FORLIST(_link, _list) \
- for(LLLink *_next = NULL, *_link = (_list).link.next; \
+ for(rw::LLLink *_next = NULL, *_link = (_list).link.next; \
_next = (_link)->next, (_link) != (_list).end(); \
(_link) = _next)
@@ -303,18 +303,22 @@ struct Raster : PluginBase
};
};
-#define IGNORERASTERIMP 1
+extern bool32 loadTextures;
+
+#define IGNORERASTERIMP 0
struct NativeRaster
{
virtual void create(Raster*)
- { assert(IGNORERASTERIMP && "unimplemented"); };
+ { assert(IGNORERASTERIMP && "NativeRaster::create unimplemented"); };
virtual uint8 *lock(Raster*, int32)
- { assert(IGNORERASTERIMP && "unimplemented"); return NULL; };
+ { assert(IGNORERASTERIMP && "NativeRaster::lock unimplemented"); return NULL; };
virtual void unlock(Raster*, int32)
- { assert(IGNORERASTERIMP && "unimplemented"); };
+ { assert(IGNORERASTERIMP && "NativeRaster::unlock unimplemented"); };
virtual int32 getNumLevels(Raster*)
- { assert(IGNORERASTERIMP && "unimplemented"); return 0; };
+ { assert(IGNORERASTERIMP && "NativeRaster::getNumLevels unimplemented"); return 0; };
+ virtual void fromImage(Raster*, Image *img)
+ { assert(IGNORERASTERIMP && "NativeRaster::fromImage unimplemented"); };
};
struct TexDictionary;
@@ -426,7 +430,8 @@ struct MatFX
uint32 type;
void setEffects(uint32 flags);
- int32 getEffectIndex(uint32 type);
+ static uint32 getEffects(Material *m);
+ uint32 getEffectIndex(uint32 type);
void setBumpTexture(Texture *t);
void setBumpCoefficient(float32 coef);
void setEnvTexture(Texture *t);
diff --git a/src/rwps2.h b/src/rwps2.h
index 2659a9b..4d1ef27 100644
--- a/src/rwps2.h
+++ b/src/rwps2.h
@@ -96,6 +96,7 @@ public:
struct Vertex {
float32 p[3];
float32 t[2];
+ float32 t1[2];
uint8 c[4];
float32 n[3];
};
@@ -155,10 +156,10 @@ void allocateADC(Geometry *geo);
// IDs used by SA
// n atomic material
-// 1892 53f20080 53f20081 // ?
-// 1 53f20080 53f2008d // triad_buddha01.dff
-// 56430 53f20082 53f20083 // world
-// 39 53f20082 53f2008f // reflective world
+// 1892 53f20080 53f20081 // ? no night colors
+// 1 53f20080 53f2008d // triad_buddha01.dff no night colors
+// 56430 53f20082 53f20083 // world night colors
+// 39 53f20082 53f2008f // reflective world night colors
// 6941 53f20084 53f20085 // vehicles
// 3423 53f20084 53f20087 // vehicles
// 4640 53f20084 53f2008b // vehicles
@@ -167,6 +168,7 @@ void allocateADC(Geometry *geo);
Pipeline *getPDSPipe(uint32 data);
void registerPDSPipe(Pipeline *pipe);
void registerPDSPlugin(int32 n);
+void registerPluginPDSPipes(void);
// Native Texture and Raster
diff --git a/tools/dumprwtree/dumprwtree.cpp b/tools/dumprwtree/dumprwtree.cpp
index f5ee4ae..e604534 100644
--- a/tools/dumprwtree/dumprwtree.cpp
+++ b/tools/dumprwtree/dumprwtree.cpp
@@ -2,7 +2,6 @@
#include
#include
#include
-#include
#include
diff --git a/tools/insttest/insttest.cpp b/tools/insttest/insttest.cpp
index 400c85c..7ec17ed 100644
--- a/tools/insttest/insttest.cpp
+++ b/tools/insttest/insttest.cpp
@@ -2,7 +2,6 @@
#include
#include
#include
-#include
#include
#include