From ef58d76bc040180b2b47327435900f2f90518129 Mon Sep 17 00:00:00 2001 From: aap Date: Sat, 6 Feb 2016 18:11:31 +0100 Subject: [PATCH] various changes --- librw.sln | 72 -- librw.vcxproj | 4 +- src/anim.cpp | 2 - src/clump.cpp | 2 - src/d3d.cpp | 76 ++ src/d3d8.cpp | 2 - src/d3d9.cpp | 2 - src/geometry.cpp | 2 - src/gtaplg.cpp | 1378 ------------------------------- src/gtaplg.h | 139 ---- src/image.cpp | 62 +- src/ogl.cpp | 2 - src/pipeline.cpp | 2 - src/plugins.cpp | 21 +- src/ps2.cpp | 690 +++------------- src/ps2raster.cpp | 636 ++++++++++++++ src/rwbase.cpp | 2 - src/rwd3d.h | 1 + src/rwobjects.h | 19 +- src/rwps2.h | 10 +- tools/dumprwtree/dumprwtree.cpp | 1 - tools/insttest/insttest.cpp | 1 - 22 files changed, 890 insertions(+), 2236 deletions(-) delete mode 100644 src/gtaplg.cpp delete mode 100644 src/gtaplg.h create mode 100644 src/ps2raster.cpp 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