mirror of
https://github.com/aap/librw.git
synced 2025-02-16 17:26:18 +00:00
various changes
This commit is contained in:
parent
6d56a23dd1
commit
ef58d76bc0
72
librw.sln
72
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}
|
{30552BB0-3B19-49A4-ABF4-87CF68AF9E38} = {30552BB0-3B19-49A4-ABF4-87CF68AF9E38}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug - null|Win32 = Debug - null|Win32
|
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.ActiveCfg = Release|Win32
|
||||||
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|Win32.Build.0 = Release|Win32
|
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|Win32.Build.0 = Release|Win32
|
||||||
{B487F101-0C2B-4F99-A1E0-B0B0C0F3FE7E}.Release|x64.ActiveCfg = Release|x64
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;RW_D3D9;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_USING_V110_SDK71_;_CRT_SECURE_NO_WARNINGS;RW_D3D9;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@ -192,17 +193,16 @@
|
|||||||
<ClCompile Include="src\d3d8.cpp" />
|
<ClCompile Include="src\d3d8.cpp" />
|
||||||
<ClCompile Include="src\d3d9.cpp" />
|
<ClCompile Include="src\d3d9.cpp" />
|
||||||
<ClCompile Include="src\geometry.cpp" />
|
<ClCompile Include="src\geometry.cpp" />
|
||||||
<ClCompile Include="src\gtaplg.cpp" />
|
|
||||||
<ClCompile Include="src\image.cpp" />
|
<ClCompile Include="src\image.cpp" />
|
||||||
<ClCompile Include="src\ogl.cpp" />
|
<ClCompile Include="src\ogl.cpp" />
|
||||||
<ClCompile Include="src\pipeline.cpp" />
|
<ClCompile Include="src\pipeline.cpp" />
|
||||||
<ClCompile Include="src\plugins.cpp" />
|
<ClCompile Include="src\plugins.cpp" />
|
||||||
<ClCompile Include="src\ps2.cpp" />
|
<ClCompile Include="src\ps2.cpp" />
|
||||||
|
<ClCompile Include="src\ps2raster.cpp" />
|
||||||
<ClCompile Include="src\rwbase.cpp" />
|
<ClCompile Include="src\rwbase.cpp" />
|
||||||
<ClCompile Include="src\xbox.cpp" />
|
<ClCompile Include="src\xbox.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\gtaplg.h" />
|
|
||||||
<ClInclude Include="src\rwbase.h" />
|
<ClInclude Include="src\rwbase.h" />
|
||||||
<ClInclude Include="src\rwd3d.h" />
|
<ClInclude Include="src\rwd3d.h" />
|
||||||
<ClInclude Include="src\rwd3d8.h" />
|
<ClInclude Include="src\rwd3d8.h" />
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
|
76
src/d3d.cpp
76
src/d3d.cpp
@ -416,6 +416,82 @@ D3dRaster::getNumLevels(Raster*)
|
|||||||
#endif
|
#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
|
int32
|
||||||
getLevelSize(Raster *raster, int32 level)
|
getLevelSize(Raster *raster, int32 level)
|
||||||
{
|
{
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
|
1378
src/gtaplg.cpp
1378
src/gtaplg.cpp
File diff suppressed because it is too large
Load Diff
139
src/gtaplg.h
139
src/gtaplg.h
@ -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);
|
|
||||||
|
|
||||||
}
|
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
@ -104,6 +102,8 @@ TexDictionary::streamGetSize(void)
|
|||||||
// Texture
|
// Texture
|
||||||
//
|
//
|
||||||
|
|
||||||
|
bool32 loadTextures;
|
||||||
|
|
||||||
Texture*
|
Texture*
|
||||||
Texture::create(Raster *raster)
|
Texture::create(Raster *raster)
|
||||||
{
|
{
|
||||||
@ -149,19 +149,22 @@ Texture::read(const char *name, const char *mask)
|
|||||||
tex = Texture::create(NULL);
|
tex = Texture::create(NULL);
|
||||||
strncpy(tex->name, name, 32);
|
strncpy(tex->name, name, 32);
|
||||||
strncpy(tex->mask, mask, 32);
|
strncpy(tex->mask, mask, 32);
|
||||||
// char *n = (char*)malloc(strlen(name) + 5);
|
Image *img = NULL;
|
||||||
// strcpy(n, name);
|
if(loadTextures){
|
||||||
// strcat(n, ".tga");
|
char *n = (char*)malloc(strlen(name) + 5);
|
||||||
// Image *img = readTGA(n);
|
strcpy(n, name);
|
||||||
// free(n);
|
strcat(n, ".tga");
|
||||||
// if(img){
|
img = readTGA(n);
|
||||||
// //raster = Raster::createFromImage(img);
|
free(n);
|
||||||
// raster = new Raster(0, 0, 0, 0x80);
|
if(img){
|
||||||
// img->destroy();
|
raster = Raster::createFromImage(img);
|
||||||
// }else
|
img->destroy();
|
||||||
|
}else
|
||||||
|
raster = Raster::create(0, 0, 0, 0x80);
|
||||||
|
}else
|
||||||
raster = Raster::create(0, 0, 0, 0x80);
|
raster = Raster::create(0, 0, 0, 0x80);
|
||||||
tex->raster = raster;
|
tex->raster = raster;
|
||||||
if(currentTexDictionary /*&& img*/)
|
if(currentTexDictionary)
|
||||||
currentTexDictionary->add(tex);
|
currentTexDictionary->add(tex);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
@ -184,9 +187,9 @@ Texture::streamRead(Stream *stream)
|
|||||||
stream->read(mask, length);
|
stream->read(mask, length);
|
||||||
|
|
||||||
Texture *tex = Texture::read(name, mask);
|
Texture *tex = Texture::read(name, mask);
|
||||||
tex->refCount++;
|
|
||||||
if(tex->refCount == 1)
|
if(tex->refCount == 1)
|
||||||
tex->filterAddressing = filterAddressing;
|
tex->filterAddressing = filterAddressing;
|
||||||
|
tex->refCount++; // TODO: RW doesn't do this, why?
|
||||||
|
|
||||||
tex->streamReadPlugins(stream);
|
tex->streamReadPlugins(stream);
|
||||||
|
|
||||||
@ -640,36 +643,15 @@ Raster::calculateNumLevels(int32 width, int32 height)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD BAD BAD BAD
|
|
||||||
Raster*
|
Raster*
|
||||||
Raster::createFromImage(Image *image)
|
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,
|
Raster *raster = Raster::create(image->width, image->height,
|
||||||
image->depth, format | 4 | 0x80);
|
image->depth, 4 | 0x80);
|
||||||
raster->stride = image->stride;
|
int32 offset = nativeOffsets[raster->platform];
|
||||||
|
assert(offset != 0 && "unimplemented raster platform");
|
||||||
raster->texels = new uint8[raster->stride*raster->height];
|
NativeRaster *nr = PLUGINOFFSET(NativeRaster, raster, offset);
|
||||||
memcpy(raster->texels, image->pixels, raster->stride*raster->height);
|
nr->fromImage(raster, image);
|
||||||
if(image->palette){
|
|
||||||
int size = raster->depth == 4 ? 16 : 256;
|
|
||||||
raster->palette = new uint8[size*4];
|
|
||||||
memcpy(raster->palette, image->palette, size*4);
|
|
||||||
}
|
|
||||||
return raster;
|
return raster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
@ -595,10 +593,10 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
|||||||
|
|
||||||
//{
|
//{
|
||||||
//float *mat = &skin->inverseMatrices[i*16];
|
//float *mat = &skin->inverseMatrices[i*16];
|
||||||
//printf("[ [ %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"
|
// " [ %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[0], mat[4], mat[8], mat[12],
|
||||||
// mat[1], mat[5], mat[9], mat[13],
|
// mat[1], mat[5], mat[9], mat[13],
|
||||||
// mat[2], mat[6], mat[10], mat[14],
|
// 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)
|
MatFX::getEffectIndex(uint32 type)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 2; i++)
|
for(int i = 0; i < 2; i++)
|
||||||
|
690
src/ps2.cpp
690
src/ps2.cpp
@ -3,16 +3,12 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
#include "rwpipeline.h"
|
#include "rwpipeline.h"
|
||||||
#include "rwobjects.h"
|
#include "rwobjects.h"
|
||||||
#include "rwps2.h"
|
#include "rwps2.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace ps2 {
|
namespace ps2 {
|
||||||
|
|
||||||
@ -282,6 +278,34 @@ instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
|
|||||||
return p;
|
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*
|
uint32*
|
||||||
instanceRGBA(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
|
instanceRGBA(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
|
||||||
{
|
{
|
||||||
@ -338,15 +362,18 @@ MatPipeline::dump(void)
|
|||||||
if(this->platform != PLATFORM_PS2)
|
if(this->platform != PLATFORM_PS2)
|
||||||
return;
|
return;
|
||||||
PipeAttribute *a;
|
PipeAttribute *a;
|
||||||
|
printf("%x %x\n", this->pluginID, this->pluginData);
|
||||||
for(uint i = 0; i < nelem(this->attribs); i++){
|
for(uint i = 0; i < nelem(this->attribs); i++){
|
||||||
a = this->attribs[i];
|
a = this->attribs[i];
|
||||||
if(a)
|
if(a)
|
||||||
printf("%d %s: %x\n", i, a->name, a->attrib);
|
printf("%d %s: %x\n", i, a->name, a->attrib);
|
||||||
}
|
}
|
||||||
printf("stride: %x\n", this->inputStride);
|
printf("stride: %x\n", this->inputStride);
|
||||||
|
printf("vertcount: %x\n", this->vifOffset/this->inputStride);
|
||||||
printf("triSCount: %x\n", this->triStripCount);
|
printf("triSCount: %x\n", this->triStripCount);
|
||||||
printf("triLCount: %x\n", this->triListCount);
|
printf("triLCount: %x\n", this->triListCount);
|
||||||
printf("vifOffset: %x\n", this->vifOffset);
|
printf("vifOffset: %x\n", this->vifOffset);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -506,20 +533,16 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||||||
*p++ = (a->attrib&0xFF004000)
|
*p++ = (a->attrib&0xFF004000)
|
||||||
| 0x8000 | nverts << 16 | i; // UNPACK
|
| 0x8000 | nverts << 16 | i; // UNPACK
|
||||||
|
|
||||||
switch(i){
|
if(a == &attribXYZ)
|
||||||
case 0:
|
|
||||||
p = instanceXYZ(p, g, m, idx, nverts);
|
p = instanceXYZ(p, g, m, idx, nverts);
|
||||||
break;
|
else if(a == &attribUV)
|
||||||
case 1:
|
|
||||||
p = instanceUV(p, g, m, idx, nverts);
|
p = instanceUV(p, g, m, idx, nverts);
|
||||||
break;
|
else if(a == &attribUV2)
|
||||||
case 2:
|
p = instanceUV2(p, g, m, idx, nverts);
|
||||||
|
else if(a == &attribRGBA)
|
||||||
p = instanceRGBA(p, g, m, idx, nverts);
|
p = instanceRGBA(p, g, m, idx, nverts);
|
||||||
break;
|
else if(a == &attribNormal)
|
||||||
case 3:
|
p = instanceNormal(p, g, m, idx, nverts);
|
||||||
p = instanceNormal(p,g, m, idx, nverts);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
idx += g->meshHeader->flags == 1
|
idx += g->meshHeader->flags == 1
|
||||||
? im.batchVertCount-2 : im.batchVertCount;
|
? 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 *verts = g->morphTargets[0].vertices;
|
||||||
float32 *tex = g->texCoords[0];
|
float32 *tex = g->texCoords[0];
|
||||||
|
float32 *tex1 = g->texCoords[1];
|
||||||
float32 *norms = g->morphTargets[0].normals;
|
float32 *norms = g->morphTargets[0].normals;
|
||||||
uint8 *cols = g->colors;
|
uint8 *cols = g->colors;
|
||||||
|
|
||||||
@ -742,10 +766,14 @@ findVertex(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
|
|||||||
if(mask & flags[i] & 0x1000 &&
|
if(mask & flags[i] & 0x1000 &&
|
||||||
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
||||||
goto cont;
|
goto cont;
|
||||||
|
if(mask & flags[i] & 0x2000 &&
|
||||||
|
!(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
|
||||||
|
goto cont;
|
||||||
return i;
|
return i;
|
||||||
cont:
|
cont:
|
||||||
verts += 3;
|
verts += 3;
|
||||||
tex += 2;
|
tex += 2;
|
||||||
|
tex1 += 2;
|
||||||
norms += 3;
|
norms += 3;
|
||||||
cols += 4;
|
cols += 4;
|
||||||
}
|
}
|
||||||
@ -763,10 +791,12 @@ insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v)
|
|||||||
memcpy(&geo->colors[i*4], v->c, 4);
|
memcpy(&geo->colors[i*4], v->c, 4);
|
||||||
if(mask & 0x1000)
|
if(mask & 0x1000)
|
||||||
memcpy(&geo->texCoords[0][i*2], v->t, 8);
|
memcpy(&geo->texCoords[0][i*2], v->t, 8);
|
||||||
|
if(mask & 0x2000)
|
||||||
|
memcpy(&geo->texCoords[1][i*2], v->t1, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 *verts = (float32*)data[AT_XYZ];
|
||||||
float32 *texcoords = (float32*)data[AT_UV];
|
float32 *texcoords = (float32*)data[AT_UV];
|
||||||
@ -777,8 +807,9 @@ defaultUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uin
|
|||||||
mask |= 0x10;
|
mask |= 0x10;
|
||||||
if(geo->geoflags & Geometry::PRELIT)
|
if(geo->geoflags & Geometry::PRELIT)
|
||||||
mask |= 0x100;
|
mask |= 0x100;
|
||||||
if(geo->numTexCoordSets > 0)
|
for(int32 i = 0; i < geo->numTexCoordSets; i++)
|
||||||
mask |= 0x1000;
|
mask |= 0x1000 << i;
|
||||||
|
int numUV = pipe->attribs[AT_UV] == &attribUV2 ? 2 : 1;
|
||||||
|
|
||||||
Vertex v;
|
Vertex v;
|
||||||
for(uint32 i = 0; i < mesh->numIndices; i++){
|
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);
|
memcpy(&v.c, colors, 4);
|
||||||
if(mask & 0x1000)
|
if(mask & 0x1000)
|
||||||
memcpy(&v.t, texcoords, 8);
|
memcpy(&v.t, texcoords, 8);
|
||||||
|
if(mask & 0x2000)
|
||||||
|
memcpy(&v.t1, texcoords+2, 8);
|
||||||
|
|
||||||
int32 idx = findVertex(geo, flags, mask, &v);
|
int32 idx = findVertex(geo, flags, mask, &v);
|
||||||
if(idx < 0)
|
if(idx < 0)
|
||||||
@ -801,7 +834,7 @@ defaultUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uin
|
|||||||
flags[idx] = mask;
|
flags[idx] = mask;
|
||||||
insertVertex(geo, idx, mask, &v);
|
insertVertex(geo, idx, mask, &v);
|
||||||
verts += 3;
|
verts += 3;
|
||||||
texcoords += 2;
|
texcoords += 2*numUV;
|
||||||
colors += 4;
|
colors += 4;
|
||||||
norms += 3;
|
norms += 3;
|
||||||
}
|
}
|
||||||
@ -1315,6 +1348,7 @@ static void
|
|||||||
atomicPDSRights(void *object, int32, int32, uint32 data)
|
atomicPDSRights(void *object, int32, int32, uint32 data)
|
||||||
{
|
{
|
||||||
Atomic *a = (Atomic*)object;
|
Atomic *a = (Atomic*)object;
|
||||||
|
//printf("atm pds: %x\n", data);
|
||||||
a->pipeline = (ObjPipeline*)getPDSPipe(data);
|
a->pipeline = (ObjPipeline*)getPDSPipe(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1322,6 +1356,7 @@ static void
|
|||||||
materialPDSRights(void *object, int32, int32, uint32 data)
|
materialPDSRights(void *object, int32, int32, uint32 data)
|
||||||
{
|
{
|
||||||
Material *m = (Material*)object;
|
Material *m = (Material*)object;
|
||||||
|
//printf("mat pds: %x\n", data);
|
||||||
m->pipeline = (ObjPipeline*)getPDSPipe(data);
|
m->pipeline = (ObjPipeline*)getPDSPipe(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,6 +1373,73 @@ registerPDSPlugin(int32 n)
|
|||||||
Material::setStreamRightsCallback(ID_PDS, materialPDSRights);
|
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
|
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
636
src/ps2raster.cpp
Normal file
636
src/ps2raster.cpp
Normal file
@ -0,0 +1,636 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -3,8 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "rwbase.h"
|
#include "rwbase.h"
|
||||||
#include "rwplugin.h"
|
#include "rwplugin.h"
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@ struct D3dRaster : NativeRaster
|
|||||||
virtual uint8 *lock(Raster *raster, int32 level);
|
virtual uint8 *lock(Raster *raster, int32 level);
|
||||||
virtual void unlock(Raster *raster, int32 level);
|
virtual void unlock(Raster *raster, int32 level);
|
||||||
virtual int32 getNumLevels(Raster *raster);
|
virtual int32 getNumLevels(Raster *raster);
|
||||||
|
virtual void fromImage(Raster *raster, Image *img);
|
||||||
};
|
};
|
||||||
|
|
||||||
int32 getLevelSize(Raster *raster, int32 level);
|
int32 getLevelSize(Raster *raster, int32 level);
|
||||||
|
@ -51,7 +51,7 @@ struct LLLink
|
|||||||
|
|
||||||
// Have to be careful since the link might be deleted.
|
// Have to be careful since the link might be deleted.
|
||||||
#define FORLIST(_link, _list) \
|
#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(); \
|
_next = (_link)->next, (_link) != (_list).end(); \
|
||||||
(_link) = _next)
|
(_link) = _next)
|
||||||
|
|
||||||
@ -303,18 +303,22 @@ struct Raster : PluginBase<Raster>
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IGNORERASTERIMP 1
|
extern bool32 loadTextures;
|
||||||
|
|
||||||
|
#define IGNORERASTERIMP 0
|
||||||
|
|
||||||
struct NativeRaster
|
struct NativeRaster
|
||||||
{
|
{
|
||||||
virtual void create(Raster*)
|
virtual void create(Raster*)
|
||||||
{ assert(IGNORERASTERIMP && "unimplemented"); };
|
{ assert(IGNORERASTERIMP && "NativeRaster::create unimplemented"); };
|
||||||
virtual uint8 *lock(Raster*, int32)
|
virtual uint8 *lock(Raster*, int32)
|
||||||
{ assert(IGNORERASTERIMP && "unimplemented"); return NULL; };
|
{ assert(IGNORERASTERIMP && "NativeRaster::lock unimplemented"); return NULL; };
|
||||||
virtual void unlock(Raster*, int32)
|
virtual void unlock(Raster*, int32)
|
||||||
{ assert(IGNORERASTERIMP && "unimplemented"); };
|
{ assert(IGNORERASTERIMP && "NativeRaster::unlock unimplemented"); };
|
||||||
virtual int32 getNumLevels(Raster*)
|
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;
|
struct TexDictionary;
|
||||||
@ -426,7 +430,8 @@ struct MatFX
|
|||||||
uint32 type;
|
uint32 type;
|
||||||
|
|
||||||
void setEffects(uint32 flags);
|
void setEffects(uint32 flags);
|
||||||
int32 getEffectIndex(uint32 type);
|
static uint32 getEffects(Material *m);
|
||||||
|
uint32 getEffectIndex(uint32 type);
|
||||||
void setBumpTexture(Texture *t);
|
void setBumpTexture(Texture *t);
|
||||||
void setBumpCoefficient(float32 coef);
|
void setBumpCoefficient(float32 coef);
|
||||||
void setEnvTexture(Texture *t);
|
void setEnvTexture(Texture *t);
|
||||||
|
10
src/rwps2.h
10
src/rwps2.h
@ -96,6 +96,7 @@ public:
|
|||||||
struct Vertex {
|
struct Vertex {
|
||||||
float32 p[3];
|
float32 p[3];
|
||||||
float32 t[2];
|
float32 t[2];
|
||||||
|
float32 t1[2];
|
||||||
uint8 c[4];
|
uint8 c[4];
|
||||||
float32 n[3];
|
float32 n[3];
|
||||||
};
|
};
|
||||||
@ -155,10 +156,10 @@ void allocateADC(Geometry *geo);
|
|||||||
|
|
||||||
// IDs used by SA
|
// IDs used by SA
|
||||||
// n atomic material
|
// n atomic material
|
||||||
// 1892 53f20080 53f20081 // ?
|
// 1892 53f20080 53f20081 // ? no night colors
|
||||||
// 1 53f20080 53f2008d // triad_buddha01.dff
|
// 1 53f20080 53f2008d // triad_buddha01.dff no night colors
|
||||||
// 56430 53f20082 53f20083 // world
|
// 56430 53f20082 53f20083 // world night colors
|
||||||
// 39 53f20082 53f2008f // reflective world
|
// 39 53f20082 53f2008f // reflective world night colors
|
||||||
// 6941 53f20084 53f20085 // vehicles
|
// 6941 53f20084 53f20085 // vehicles
|
||||||
// 3423 53f20084 53f20087 // vehicles
|
// 3423 53f20084 53f20087 // vehicles
|
||||||
// 4640 53f20084 53f2008b // vehicles
|
// 4640 53f20084 53f2008b // vehicles
|
||||||
@ -167,6 +168,7 @@ void allocateADC(Geometry *geo);
|
|||||||
Pipeline *getPDSPipe(uint32 data);
|
Pipeline *getPDSPipe(uint32 data);
|
||||||
void registerPDSPipe(Pipeline *pipe);
|
void registerPDSPipe(Pipeline *pipe);
|
||||||
void registerPDSPlugin(int32 n);
|
void registerPDSPlugin(int32 n);
|
||||||
|
void registerPluginPDSPipes(void);
|
||||||
|
|
||||||
// Native Texture and Raster
|
// Native Texture and Raster
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <rw.h>
|
#include <rw.h>
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <rw.h>
|
#include <rw.h>
|
||||||
#include <args.h>
|
#include <args.h>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user