mirror of
https://github.com/aap/librw.git
synced 2024-11-28 22:55:42 +00:00
implemented basic read/write of xbox textures
This commit is contained in:
parent
b39d9d2b89
commit
926b0a639a
13
librw.sln
13
librw.sln
@ -21,6 +21,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "insttest", "tools\insttest\
|
||||
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
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -53,6 +61,11 @@ Global
|
||||
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E5D477C8-4CAF-43BF-B7E3-6689503D469F}.Release|Win32.Build.0 = Release|Win32
|
||||
{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|Win32.ActiveCfg = Debug|Win32
|
||||
{403C35A9-6D06-4261-B305-9ED000F00136}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{403C35A9-6D06-4261-B305-9ED000F00136}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
266
src/d3d.cpp
266
src/d3d.cpp
@ -18,8 +18,166 @@ namespace d3d {
|
||||
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DDevice9 *device = NULL;
|
||||
#else
|
||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
|
||||
((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
|
||||
enum {
|
||||
D3DFMT_UNKNOWN = 0,
|
||||
|
||||
D3DFMT_R8G8B8 = 20,
|
||||
D3DFMT_A8R8G8B8 = 21,
|
||||
D3DFMT_X8R8G8B8 = 22,
|
||||
D3DFMT_R5G6B5 = 23,
|
||||
D3DFMT_X1R5G5B5 = 24,
|
||||
D3DFMT_A1R5G5B5 = 25,
|
||||
D3DFMT_A4R4G4B4 = 26,
|
||||
D3DFMT_R3G3B2 = 27,
|
||||
D3DFMT_A8 = 28,
|
||||
D3DFMT_A8R3G3B2 = 29,
|
||||
D3DFMT_X4R4G4B4 = 30,
|
||||
D3DFMT_A2B10G10R10 = 31,
|
||||
D3DFMT_A8B8G8R8 = 32,
|
||||
D3DFMT_X8B8G8R8 = 33,
|
||||
D3DFMT_G16R16 = 34,
|
||||
D3DFMT_A2R10G10B10 = 35,
|
||||
D3DFMT_A16B16G16R16 = 36,
|
||||
|
||||
D3DFMT_A8P8 = 40,
|
||||
D3DFMT_P8 = 41,
|
||||
|
||||
D3DFMT_L8 = 50,
|
||||
D3DFMT_A8L8 = 51,
|
||||
D3DFMT_A4L4 = 52,
|
||||
|
||||
D3DFMT_V8U8 = 60,
|
||||
D3DFMT_L6V5U5 = 61,
|
||||
D3DFMT_X8L8V8U8 = 62,
|
||||
D3DFMT_Q8W8V8U8 = 63,
|
||||
D3DFMT_V16U16 = 64,
|
||||
D3DFMT_A2W10V10U10 = 67,
|
||||
|
||||
D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'),
|
||||
D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'),
|
||||
D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'),
|
||||
D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'),
|
||||
D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'),
|
||||
D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'),
|
||||
D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'),
|
||||
D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'),
|
||||
D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'),
|
||||
|
||||
D3DFMT_D16_LOCKABLE = 70,
|
||||
D3DFMT_D32 = 71,
|
||||
D3DFMT_D15S1 = 73,
|
||||
D3DFMT_D24S8 = 75,
|
||||
D3DFMT_D24X8 = 77,
|
||||
D3DFMT_D24X4S4 = 79,
|
||||
D3DFMT_D16 = 80,
|
||||
|
||||
D3DFMT_D32F_LOCKABLE = 82,
|
||||
D3DFMT_D24FS8 = 83,
|
||||
|
||||
// d3d9ex only
|
||||
/* Z-Stencil formats valid for CPU access */
|
||||
D3DFMT_D32_LOCKABLE = 84,
|
||||
D3DFMT_S8_LOCKABLE = 85,
|
||||
|
||||
D3DFMT_L16 = 81,
|
||||
|
||||
D3DFMT_VERTEXDATA =100,
|
||||
D3DFMT_INDEX16 =101,
|
||||
D3DFMT_INDEX32 =102,
|
||||
|
||||
D3DFMT_Q16W16V16U16 =110,
|
||||
|
||||
D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M','E','T','1'),
|
||||
|
||||
// Floating point surface formats
|
||||
|
||||
// s10e5 formats (16-bits per channel)
|
||||
D3DFMT_R16F = 111,
|
||||
D3DFMT_G16R16F = 112,
|
||||
D3DFMT_A16B16G16R16F = 113,
|
||||
|
||||
// IEEE s23e8 formats (32-bits per channel)
|
||||
D3DFMT_R32F = 114,
|
||||
D3DFMT_G32R32F = 115,
|
||||
D3DFMT_A32B32G32R32F = 116,
|
||||
|
||||
D3DFMT_CxV8U8 = 117,
|
||||
|
||||
// d3d9ex only
|
||||
// Monochrome 1 bit per pixel format
|
||||
D3DFMT_A1 = 118,
|
||||
// 2.8 biased fixed point
|
||||
D3DFMT_A2B10G10R10_XR_BIAS = 119,
|
||||
// Binary format indicating that the data has no inherent type
|
||||
D3DFMT_BINARYBUFFER = 199,
|
||||
};
|
||||
#endif
|
||||
|
||||
// stolen from d3d8to9
|
||||
static uint32
|
||||
calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format)
|
||||
{
|
||||
#define D3DFMT_W11V11U10 65
|
||||
switch(format){
|
||||
default:
|
||||
case D3DFMT_UNKNOWN:
|
||||
return 0;
|
||||
case D3DFMT_R3G3B2:
|
||||
case D3DFMT_A8:
|
||||
case D3DFMT_P8:
|
||||
case D3DFMT_L8:
|
||||
case D3DFMT_A4L4:
|
||||
return width * height * depth;
|
||||
case D3DFMT_R5G6B5:
|
||||
case D3DFMT_X1R5G5B5:
|
||||
case D3DFMT_A1R5G5B5:
|
||||
case D3DFMT_A4R4G4B4:
|
||||
case D3DFMT_A8R3G3B2:
|
||||
case D3DFMT_X4R4G4B4:
|
||||
case D3DFMT_A8P8:
|
||||
case D3DFMT_A8L8:
|
||||
case D3DFMT_V8U8:
|
||||
case D3DFMT_L6V5U5:
|
||||
case D3DFMT_D16_LOCKABLE:
|
||||
case D3DFMT_D15S1:
|
||||
case D3DFMT_D16:
|
||||
case D3DFMT_UYVY:
|
||||
case D3DFMT_YUY2:
|
||||
return width * 2 * height * depth;
|
||||
case D3DFMT_R8G8B8:
|
||||
return width * 3 * height * depth;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
case D3DFMT_X8R8G8B8:
|
||||
case D3DFMT_A2B10G10R10:
|
||||
case D3DFMT_A8B8G8R8:
|
||||
case D3DFMT_X8B8G8R8:
|
||||
case D3DFMT_G16R16:
|
||||
case D3DFMT_X8L8V8U8:
|
||||
case D3DFMT_Q8W8V8U8:
|
||||
case D3DFMT_V16U16:
|
||||
case D3DFMT_W11V11U10:
|
||||
case D3DFMT_A2W10V10U10:
|
||||
case D3DFMT_D32:
|
||||
case D3DFMT_D24S8:
|
||||
case D3DFMT_D24X8:
|
||||
case D3DFMT_D24X4S4:
|
||||
return width * 4 * height * depth;
|
||||
case D3DFMT_DXT1:
|
||||
assert(depth <= 1);
|
||||
return ((width + 3) >> 2) * ((height + 3) >> 2) * 8;
|
||||
case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
assert(depth <= 1);
|
||||
return ((width + 3) >> 2) * ((height + 3) >> 2) * 16;
|
||||
}
|
||||
}
|
||||
|
||||
int vertFormatMap[] = {
|
||||
-1, VERT_FLOAT2, VERT_FLOAT3, -1, VERT_ARGB
|
||||
};
|
||||
@ -101,15 +259,43 @@ unlockVertices(void *vertexBuffer)
|
||||
}
|
||||
|
||||
void*
|
||||
createTexture(int32 width, int32 height, int32 levels, uint32 format)
|
||||
createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
|
||||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DTexture9 *tex;
|
||||
device->CreateTexture(width, height, levels, 0,
|
||||
device->CreateTexture(width, height, numlevels, 0,
|
||||
(D3DFORMAT)format, D3DPOOL_MANAGED, &tex, NULL);
|
||||
return tex;
|
||||
#else
|
||||
assert(0 && "only supported with RW_D3D9");
|
||||
int32 w = width;
|
||||
int32 h = height;
|
||||
int32 size = 0;
|
||||
for(int32 i = 0; i < numlevels; i++){
|
||||
size += calculateTextureSize(w, h, 1, format);
|
||||
w /= 2;
|
||||
if(w == 0) w = 1;
|
||||
h /= 2;
|
||||
if(h == 0) h = 1;
|
||||
}
|
||||
uint8 *data = new uint8[sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size];
|
||||
RasterLevels *levels = (RasterLevels*)data;
|
||||
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
|
||||
levels->numlevels = numlevels;
|
||||
levels->format = format;
|
||||
w = width;
|
||||
h = height;
|
||||
for(int32 i = 0; i < numlevels; i++){
|
||||
levels->levels[i].width = w;
|
||||
levels->levels[i].height = h;
|
||||
levels->levels[i].data = data;
|
||||
levels->levels[i].size = calculateTextureSize(w, h, 1, format);
|
||||
data += levels->levels[i].size;
|
||||
w /= 2;
|
||||
if(w == 0) w = 1;
|
||||
h /= 2;
|
||||
if(h == 0) h = 1;
|
||||
}
|
||||
return levels;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -122,7 +308,8 @@ lockTexture(void *texture, int32 level)
|
||||
tex->LockRect(level, &lr, 0, 0);
|
||||
return (uint8*)lr.pBits;
|
||||
#else
|
||||
assert(0 && "only supported with RW_D3D9");
|
||||
RasterLevels *levels = (RasterLevels*)texture;
|
||||
return levels->levels[level].data;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -185,8 +372,9 @@ makeNativeRaster(Raster *raster)
|
||||
uint32 format = formatMap[(raster->format >> 8) & 0xF];
|
||||
ras->format = 0;
|
||||
ras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF];
|
||||
int32 levels = Raster::calculateNumLevels(raster->width, raster->height);
|
||||
ras->texture = createTexture(raster->width, raster->width,
|
||||
raster->format & Raster::MIPMAP ? 0 : 1,
|
||||
raster->format & Raster::MIPMAP ? levels : 1,
|
||||
format);
|
||||
assert((raster->flags & (Raster::PAL4 | Raster::PAL8)) == 0);
|
||||
}
|
||||
@ -213,71 +401,11 @@ getNumLevels(Raster *raster)
|
||||
IDirect3DTexture9 *tex = (IDirect3DTexture9*)ras->texture;
|
||||
return tex->GetLevelCount();
|
||||
#else
|
||||
assert(0 && "only supported with RW_D3D9");
|
||||
RasterLevels *levels = (RasterLevels*)ras->texture;
|
||||
return levels->numlevels;
|
||||
#endif
|
||||
}
|
||||
|
||||
// stolen from d3d8to9
|
||||
uint32
|
||||
calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format)
|
||||
{
|
||||
#define D3DFMT_W11V11U10 65
|
||||
switch(format){
|
||||
default:
|
||||
case D3DFMT_UNKNOWN:
|
||||
return 0;
|
||||
case D3DFMT_R3G3B2:
|
||||
case D3DFMT_A8:
|
||||
case D3DFMT_P8:
|
||||
case D3DFMT_L8:
|
||||
case D3DFMT_A4L4:
|
||||
return width * height * depth;
|
||||
case D3DFMT_R5G6B5:
|
||||
case D3DFMT_X1R5G5B5:
|
||||
case D3DFMT_A1R5G5B5:
|
||||
case D3DFMT_A4R4G4B4:
|
||||
case D3DFMT_A8R3G3B2:
|
||||
case D3DFMT_X4R4G4B4:
|
||||
case D3DFMT_A8P8:
|
||||
case D3DFMT_A8L8:
|
||||
case D3DFMT_V8U8:
|
||||
case D3DFMT_L6V5U5:
|
||||
case D3DFMT_D16_LOCKABLE:
|
||||
case D3DFMT_D15S1:
|
||||
case D3DFMT_D16:
|
||||
case D3DFMT_UYVY:
|
||||
case D3DFMT_YUY2:
|
||||
return width * 2 * height * depth;
|
||||
case D3DFMT_R8G8B8:
|
||||
return width * 3 * height * depth;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
case D3DFMT_X8R8G8B8:
|
||||
case D3DFMT_A2B10G10R10:
|
||||
case D3DFMT_A8B8G8R8:
|
||||
case D3DFMT_X8B8G8R8:
|
||||
case D3DFMT_G16R16:
|
||||
case D3DFMT_X8L8V8U8:
|
||||
case D3DFMT_Q8W8V8U8:
|
||||
case D3DFMT_V16U16:
|
||||
case D3DFMT_W11V11U10:
|
||||
case D3DFMT_A2W10V10U10:
|
||||
case D3DFMT_D32:
|
||||
case D3DFMT_D24S8:
|
||||
case D3DFMT_D24X8:
|
||||
case D3DFMT_D24X4S4:
|
||||
return width * 4 * height * depth;
|
||||
case D3DFMT_DXT1:
|
||||
assert(depth <= 1);
|
||||
return ((width + 3) >> 2) * ((height + 3) >> 2) * 8;
|
||||
case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
assert(depth <= 1);
|
||||
return ((width + 3) >> 2) * ((height + 3) >> 2) * 16;
|
||||
}
|
||||
}
|
||||
|
||||
int32
|
||||
getLevelSize(Raster *raster, int32 level)
|
||||
{
|
||||
@ -288,10 +416,12 @@ getLevelSize(Raster *raster, int32 level)
|
||||
tex->GetLevelDesc(level, &desc);
|
||||
return calculateTextureSize(desc.Width, desc.Height, 1, desc.Format);
|
||||
#else
|
||||
assert(0 && "only supported with RW_D3D9");
|
||||
RasterLevels *levels = (RasterLevels*)ras->texture;
|
||||
return levels->levels[level].size;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
createNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
|
@ -419,7 +419,7 @@ readNativeTexture(Stream *stream)
|
||||
ras->format = dxtMap[compression-1];
|
||||
ras->hasAlpha = hasAlpha;
|
||||
ras->texture = createTexture(raster->width, raster->width,
|
||||
raster->format & Raster::MIPMAP ? 0 : 1,
|
||||
raster->format & Raster::MIPMAP ? numLevels : 1,
|
||||
ras->format);
|
||||
raster->flags &= ~0x80;
|
||||
}else
|
||||
@ -432,7 +432,7 @@ readNativeTexture(Stream *stream)
|
||||
|
||||
uint32 size;
|
||||
uint8 *data;
|
||||
for(uint32 i = 0; i < numLevels; i++){
|
||||
for(int32 i = 0; i < numLevels; i++){
|
||||
size = stream->readU32();
|
||||
if(i < raster->getNumLevels()){
|
||||
data = raster->lock(i);
|
||||
@ -493,7 +493,7 @@ writeNativeTexture(Texture *tex, Stream *stream)
|
||||
|
||||
uint32 size;
|
||||
uint8 *data;
|
||||
for(uint32 i = 0; i < numLevels; i++){
|
||||
for(int32 i = 0; i < numLevels; i++){
|
||||
size = getLevelSize(raster, i);
|
||||
stream->writeU32(size);
|
||||
data = raster->lock(i);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwd3d.h"
|
||||
#include "rwxbox.h"
|
||||
#include "rwd3d8.h"
|
||||
|
||||
using namespace std;
|
||||
@ -81,7 +82,6 @@ uint32
|
||||
TexDictionary::streamGetSize(void)
|
||||
{
|
||||
uint32 size = 12 + 4;
|
||||
Texture *tex;
|
||||
for(Texture *tex = this->first; tex; tex = tex->next)
|
||||
size += 12 + tex->streamGetSizeNative();
|
||||
size += 12 + this->streamGetPluginSize();
|
||||
@ -210,6 +210,8 @@ Texture::streamReadNative(Stream *stream)
|
||||
{
|
||||
if(rw::platform == PLATFORM_D3D8)
|
||||
return d3d8::readNativeTexture(stream);
|
||||
if(rw::platform == PLATFORM_XBOX)
|
||||
return xbox::readNativeTexture(stream);
|
||||
assert(0 && "unsupported platform");
|
||||
return NULL;
|
||||
}
|
||||
@ -219,6 +221,8 @@ Texture::streamWriteNative(Stream *stream)
|
||||
{
|
||||
if(this->raster->platform == PLATFORM_D3D8)
|
||||
d3d8::writeNativeTexture(this, stream);
|
||||
else if(this->raster->platform == PLATFORM_XBOX)
|
||||
xbox::writeNativeTexture(this, stream);
|
||||
else
|
||||
assert(0 && "unsupported platform");
|
||||
}
|
||||
@ -228,6 +232,8 @@ Texture::streamGetSizeNative(void)
|
||||
{
|
||||
if(this->raster->platform == PLATFORM_D3D8)
|
||||
return d3d8::getSizeNativeTexture(this);
|
||||
if(this->raster->platform == PLATFORM_XBOX)
|
||||
return xbox::getSizeNativeTexture(this);
|
||||
assert(0 && "unsupported platform");
|
||||
return 0;
|
||||
}
|
||||
@ -530,6 +536,8 @@ Raster::Raster(int32 width, int32 height, int32 depth, int32 format, int32 platf
|
||||
if(this->platform == PLATFORM_D3D8 ||
|
||||
this->platform == PLATFORM_D3D9)
|
||||
d3d::makeNativeRaster(this);
|
||||
if(this->platform == PLATFORM_XBOX)
|
||||
xbox::makeNativeRaster(this);
|
||||
this->constructPlugins();
|
||||
}
|
||||
|
||||
@ -543,18 +551,23 @@ Raster::~Raster(void)
|
||||
uint8*
|
||||
Raster::lock(int32 level)
|
||||
{
|
||||
if(this->platform == PLATFORM_D3D8 ||
|
||||
if(this->platform == PLATFORM_D3D8 ||
|
||||
this->platform == PLATFORM_D3D9)
|
||||
return d3d::lockRaster(this, level);
|
||||
if(this->platform == PLATFORM_XBOX)
|
||||
return xbox::lockRaster(this, level);
|
||||
assert(0 && "unsupported raster platform");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Raster::unlock(int32 level)
|
||||
{
|
||||
if(this->platform == PLATFORM_D3D8 ||
|
||||
if(this->platform == PLATFORM_D3D8 ||
|
||||
this->platform == PLATFORM_D3D9)
|
||||
d3d::unlockRaster(this, level);
|
||||
else if(this->platform == PLATFORM_XBOX)
|
||||
xbox::unlockRaster(this, level);
|
||||
else
|
||||
assert(0 && "unsupported raster platform");
|
||||
}
|
||||
@ -562,13 +575,25 @@ Raster::unlock(int32 level)
|
||||
int32
|
||||
Raster::getNumLevels(void)
|
||||
{
|
||||
if(this->platform == PLATFORM_D3D8 ||
|
||||
if(this->platform == PLATFORM_D3D8 ||
|
||||
this->platform == PLATFORM_D3D9)
|
||||
return d3d::getNumLevels(this);
|
||||
if(this->platform == PLATFORM_XBOX)
|
||||
return xbox::getNumLevels(this);
|
||||
assert(0 && "unsupported raster platform");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32
|
||||
Raster::calculateNumLevels(int32 width, int32 height)
|
||||
{
|
||||
int32 size = width >= height ? width : height;
|
||||
int32 n;
|
||||
for(n = 0; size != 0; n++)
|
||||
size /= 2;
|
||||
return n;
|
||||
}
|
||||
|
||||
// BAD BAD BAD BAD
|
||||
Raster*
|
||||
Raster::createFromImage(Image *image)
|
||||
|
17
src/rwd3d.h
17
src/rwd3d.h
@ -72,20 +72,21 @@ void deleteObject(void *object);
|
||||
|
||||
// Native Raster
|
||||
|
||||
struct D3dRaster {
|
||||
void *texture; // IDirect3DTexture9
|
||||
void makeNativeRaster(Raster *raster);
|
||||
uint8 *lockRaster(Raster *raster, int32 level);
|
||||
void unlockRaster(Raster *raster, int32 level);
|
||||
int32 getNumLevels(Raster *raster);
|
||||
int32 getLevelSize(Raster *raster, int32 level);
|
||||
|
||||
struct D3dRaster
|
||||
{
|
||||
void *texture;
|
||||
void *palette;
|
||||
uint32 format;
|
||||
bool32 hasAlpha;
|
||||
};
|
||||
|
||||
extern int32 nativeRasterOffset;
|
||||
|
||||
void makeNativeRaster(Raster *raster);
|
||||
uint8 *lockRaster(Raster *raster, int32 level);
|
||||
void unlockRaster(Raster *raster, int32 level);
|
||||
int32 getNumLevels(Raster *raster);
|
||||
int32 getLevelSize(Raster *raster, int32 level);
|
||||
void registerNativeRaster(void);
|
||||
|
||||
}
|
||||
|
@ -95,6 +95,17 @@ struct Image
|
||||
Image *readTGA(const char *filename);
|
||||
void writeTGA(Image *image, const char *filename);
|
||||
|
||||
// used to emulate d3d and xbox textures
|
||||
struct RasterLevels
|
||||
{
|
||||
int32 numlevels;
|
||||
uint32 format;
|
||||
struct Level {
|
||||
int32 width, height, size;
|
||||
uint8 *data;
|
||||
} levels[1]; // 0 is illegal :/
|
||||
};
|
||||
|
||||
struct Raster : PluginBase<Raster>
|
||||
{
|
||||
int32 platform;
|
||||
@ -114,6 +125,7 @@ struct Raster : PluginBase<Raster>
|
||||
uint8 *lock(int32 level);
|
||||
void unlock(int32 level);
|
||||
int32 getNumLevels(void);
|
||||
static int32 calculateNumLevels(int32 width, int32 height);
|
||||
|
||||
enum Format {
|
||||
DEFAULT = 0,
|
||||
|
25
src/rwxbox.h
25
src/rwxbox.h
@ -66,5 +66,30 @@ uint32 getVertexFmtStride(uint32 fmt);
|
||||
|
||||
void registerVertexFormatPlugin(void);
|
||||
|
||||
// Native Texture and Raster
|
||||
|
||||
void makeNativeRaster(Raster *raster);
|
||||
uint8 *lockRaster(Raster *raster, int32 level);
|
||||
void unlockRaster(Raster *raster, int32 level);
|
||||
int32 getNumLevels(Raster *raster);
|
||||
int32 getLevelSize(Raster *raster, int32 level);
|
||||
|
||||
Texture *readNativeTexture(Stream *stream);
|
||||
void writeNativeTexture(Texture *tex, Stream *stream);
|
||||
uint32 getSizeNativeTexture(Texture *tex);
|
||||
|
||||
struct XboxRaster
|
||||
{
|
||||
void *texture;
|
||||
void *palette;
|
||||
uint32 format;
|
||||
bool32 hasAlpha;
|
||||
bool32 unknownFlag;
|
||||
// int32 compression;
|
||||
};
|
||||
|
||||
extern int32 nativeRasterOffset;
|
||||
void registerNativeRaster(void);
|
||||
|
||||
}
|
||||
}
|
||||
|
444
src/xbox.cpp
444
src/xbox.cpp
@ -16,6 +16,97 @@ using namespace std;
|
||||
namespace rw {
|
||||
namespace xbox {
|
||||
|
||||
enum {
|
||||
D3DFMT_UNKNOWN = 0xFFFFFFFF,
|
||||
|
||||
/* Swizzled formats */
|
||||
|
||||
D3DFMT_A8R8G8B8 = 0x00000006,
|
||||
D3DFMT_X8R8G8B8 = 0x00000007,
|
||||
D3DFMT_R5G6B5 = 0x00000005,
|
||||
D3DFMT_R6G5B5 = 0x00000027,
|
||||
D3DFMT_X1R5G5B5 = 0x00000003,
|
||||
D3DFMT_A1R5G5B5 = 0x00000002,
|
||||
D3DFMT_A4R4G4B4 = 0x00000004,
|
||||
D3DFMT_A8 = 0x00000019,
|
||||
D3DFMT_A8B8G8R8 = 0x0000003A,
|
||||
D3DFMT_B8G8R8A8 = 0x0000003B,
|
||||
D3DFMT_R4G4B4A4 = 0x00000039,
|
||||
D3DFMT_R5G5B5A1 = 0x00000038,
|
||||
D3DFMT_R8G8B8A8 = 0x0000003C,
|
||||
D3DFMT_R8B8 = 0x00000029,
|
||||
D3DFMT_G8B8 = 0x00000028,
|
||||
|
||||
D3DFMT_P8 = 0x0000000B,
|
||||
|
||||
D3DFMT_L8 = 0x00000000,
|
||||
D3DFMT_A8L8 = 0x0000001A,
|
||||
D3DFMT_AL8 = 0x00000001,
|
||||
D3DFMT_L16 = 0x00000032,
|
||||
|
||||
D3DFMT_V8U8 = 0x00000028,
|
||||
D3DFMT_L6V5U5 = 0x00000027,
|
||||
D3DFMT_X8L8V8U8 = 0x00000007,
|
||||
D3DFMT_Q8W8V8U8 = 0x0000003A,
|
||||
D3DFMT_V16U16 = 0x00000033,
|
||||
|
||||
D3DFMT_D16_LOCKABLE = 0x0000002C,
|
||||
D3DFMT_D16 = 0x0000002C,
|
||||
D3DFMT_D24S8 = 0x0000002A,
|
||||
D3DFMT_F16 = 0x0000002D,
|
||||
D3DFMT_F24S8 = 0x0000002B,
|
||||
|
||||
/* YUV formats */
|
||||
|
||||
D3DFMT_YUY2 = 0x00000024,
|
||||
D3DFMT_UYVY = 0x00000025,
|
||||
|
||||
/* Compressed formats */
|
||||
|
||||
D3DFMT_DXT1 = 0x0000000C,
|
||||
D3DFMT_DXT2 = 0x0000000E,
|
||||
D3DFMT_DXT3 = 0x0000000E,
|
||||
D3DFMT_DXT4 = 0x0000000F,
|
||||
D3DFMT_DXT5 = 0x0000000F,
|
||||
|
||||
/* Linear formats */
|
||||
|
||||
D3DFMT_LIN_A1R5G5B5 = 0x00000010,
|
||||
D3DFMT_LIN_A4R4G4B4 = 0x0000001D,
|
||||
D3DFMT_LIN_A8 = 0x0000001F,
|
||||
D3DFMT_LIN_A8B8G8R8 = 0x0000003F,
|
||||
D3DFMT_LIN_A8R8G8B8 = 0x00000012,
|
||||
D3DFMT_LIN_B8G8R8A8 = 0x00000040,
|
||||
D3DFMT_LIN_G8B8 = 0x00000017,
|
||||
D3DFMT_LIN_R4G4B4A4 = 0x0000003E,
|
||||
D3DFMT_LIN_R5G5B5A1 = 0x0000003D,
|
||||
D3DFMT_LIN_R5G6B5 = 0x00000011,
|
||||
D3DFMT_LIN_R6G5B5 = 0x00000037,
|
||||
D3DFMT_LIN_R8B8 = 0x00000016,
|
||||
D3DFMT_LIN_R8G8B8A8 = 0x00000041,
|
||||
D3DFMT_LIN_X1R5G5B5 = 0x0000001C,
|
||||
D3DFMT_LIN_X8R8G8B8 = 0x0000001E,
|
||||
|
||||
D3DFMT_LIN_A8L8 = 0x00000020,
|
||||
D3DFMT_LIN_AL8 = 0x0000001B,
|
||||
D3DFMT_LIN_L16 = 0x00000035,
|
||||
D3DFMT_LIN_L8 = 0x00000013,
|
||||
|
||||
D3DFMT_LIN_V16U16 = 0x00000036,
|
||||
D3DFMT_LIN_V8U8 = 0x00000017,
|
||||
D3DFMT_LIN_L6V5U5 = 0x00000037,
|
||||
D3DFMT_LIN_X8L8V8U8 = 0x0000001E,
|
||||
D3DFMT_LIN_Q8W8V8U8 = 0x00000012,
|
||||
|
||||
D3DFMT_LIN_D24S8 = 0x0000002E,
|
||||
D3DFMT_LIN_F24S8 = 0x0000002F,
|
||||
D3DFMT_LIN_D16 = 0x00000030,
|
||||
D3DFMT_LIN_F16 = 0x00000031,
|
||||
|
||||
D3DFMT_VERTEXDATA = 100,
|
||||
D3DFMT_INDEX16 = 101,
|
||||
};
|
||||
|
||||
void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
@ -472,8 +563,8 @@ skinUninstanceCB(Geometry *geo, InstanceDataHeader *header)
|
||||
memcpy(skin->inverseMatrices, invMats, skin->numBones*64);
|
||||
delete[] data;
|
||||
|
||||
for(int32 i = 0; i < skin->numUsedBones; i++)
|
||||
skin->usedBones[i] = natskin->table1[i];
|
||||
for(int32 j = 0; j < skin->numUsedBones; j++)
|
||||
skin->usedBones[j] = natskin->table1[j];
|
||||
|
||||
float *weights = skin->weights;
|
||||
uint8 *indices = skin->indices;
|
||||
@ -623,5 +714,354 @@ registerVertexFormatPlugin(void)
|
||||
getSizeVertexFmt);
|
||||
}
|
||||
|
||||
// Native Texture and Raster
|
||||
|
||||
static uint32
|
||||
calculateTextureSize(uint32 width, uint32 height, uint32 depth, uint32 format)
|
||||
{
|
||||
#define D3DFMT_W11V11U10 65
|
||||
switch(format){
|
||||
default:
|
||||
case D3DFMT_UNKNOWN:
|
||||
return 0;
|
||||
case D3DFMT_A8:
|
||||
case D3DFMT_P8:
|
||||
case D3DFMT_L8:
|
||||
case D3DFMT_AL8:
|
||||
case D3DFMT_LIN_A8:
|
||||
case D3DFMT_LIN_AL8:
|
||||
case D3DFMT_LIN_L8:
|
||||
return width * height * depth;
|
||||
case D3DFMT_R5G6B5:
|
||||
case D3DFMT_R6G5B5:
|
||||
case D3DFMT_X1R5G5B5:
|
||||
case D3DFMT_A1R5G5B5:
|
||||
case D3DFMT_A4R4G4B4:
|
||||
case D3DFMT_R4G4B4A4:
|
||||
case D3DFMT_R5G5B5A1:
|
||||
case D3DFMT_R8B8:
|
||||
case D3DFMT_G8B8:
|
||||
case D3DFMT_A8L8:
|
||||
case D3DFMT_L16:
|
||||
//case D3DFMT_V8U8:
|
||||
//case D3DFMT_L6V5U5:
|
||||
case D3DFMT_D16_LOCKABLE:
|
||||
//case D3DFMT_D16:
|
||||
case D3DFMT_F16:
|
||||
case D3DFMT_YUY2:
|
||||
case D3DFMT_UYVY:
|
||||
case D3DFMT_LIN_A1R5G5B5:
|
||||
case D3DFMT_LIN_A4R4G4B4:
|
||||
case D3DFMT_LIN_G8B8:
|
||||
case D3DFMT_LIN_R4G4B4A4:
|
||||
case D3DFMT_LIN_R5G5B5A1:
|
||||
case D3DFMT_LIN_R5G6B5:
|
||||
case D3DFMT_LIN_R6G5B5:
|
||||
case D3DFMT_LIN_R8B8:
|
||||
case D3DFMT_LIN_X1R5G5B5:
|
||||
case D3DFMT_LIN_A8L8:
|
||||
case D3DFMT_LIN_L16:
|
||||
//case D3DFMT_LIN_V8U8:
|
||||
//case D3DFMT_LIN_L6V5U5:
|
||||
case D3DFMT_LIN_D16:
|
||||
case D3DFMT_LIN_F16:
|
||||
return width * 2 * height * depth;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
case D3DFMT_X8R8G8B8:
|
||||
case D3DFMT_A8B8G8R8:
|
||||
case D3DFMT_B8G8R8A8:
|
||||
case D3DFMT_R8G8B8A8:
|
||||
//case D3DFMT_X8L8V8U8:
|
||||
//case D3DFMT_Q8W8V8U8:
|
||||
case D3DFMT_V16U16:
|
||||
case D3DFMT_D24S8:
|
||||
case D3DFMT_F24S8:
|
||||
case D3DFMT_LIN_A8B8G8R8:
|
||||
case D3DFMT_LIN_A8R8G8B8:
|
||||
case D3DFMT_LIN_B8G8R8A8:
|
||||
case D3DFMT_LIN_R8G8B8A8:
|
||||
case D3DFMT_LIN_X8R8G8B8:
|
||||
case D3DFMT_LIN_V16U16:
|
||||
//case D3DFMT_LIN_X8L8V8U8:
|
||||
//case D3DFMT_LIN_Q8W8V8U8:
|
||||
case D3DFMT_LIN_D24S8:
|
||||
case D3DFMT_LIN_F24S8:
|
||||
return width * 4 * height * depth;
|
||||
case D3DFMT_DXT1:
|
||||
assert(depth <= 1);
|
||||
return ((width + 3) >> 2) * ((height + 3) >> 2) * 8;
|
||||
//case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
//case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
assert(depth <= 1);
|
||||
return ((width + 3) >> 2) * ((height + 3) >> 2) * 16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32 nativeRasterOffset;
|
||||
|
||||
void*
|
||||
createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
|
||||
{
|
||||
int32 w = width;
|
||||
int32 h = height;
|
||||
int32 size = 0;
|
||||
for(int32 i = 0; i < numlevels; i++){
|
||||
size += calculateTextureSize(w, h, 1, format);
|
||||
w /= 2;
|
||||
if(w == 0) w = 1;
|
||||
h /= 2;
|
||||
if(h == 0) h = 1;
|
||||
}
|
||||
size = (size+3)&~3;
|
||||
uint8 *data = new uint8[sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1)+size];
|
||||
RasterLevels *levels = (RasterLevels*)data;
|
||||
data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(numlevels-1);
|
||||
levels->numlevels = numlevels;
|
||||
levels->format = format;
|
||||
w = width;
|
||||
h = height;
|
||||
for(int32 i = 0; i < numlevels; i++){
|
||||
levels->levels[i].width = w;
|
||||
levels->levels[i].height = h;
|
||||
levels->levels[i].data = data;
|
||||
levels->levels[i].size = calculateTextureSize(w, h, 1, format);
|
||||
data += levels->levels[i].size;
|
||||
w /= 2;
|
||||
if(w == 0) w = 1;
|
||||
h /= 2;
|
||||
if(h == 0) h = 1;
|
||||
}
|
||||
return levels;
|
||||
}
|
||||
|
||||
void
|
||||
makeNativeRaster(Raster *raster)
|
||||
{
|
||||
static uint32 formatMap[] = {
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_A1R5G5B5,
|
||||
D3DFMT_R5G6B5,
|
||||
D3DFMT_A4R4G4B4,
|
||||
D3DFMT_L8,
|
||||
D3DFMT_A8R8G8B8,
|
||||
D3DFMT_X8R8G8B8,
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_X1R5G5B5,
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_UNKNOWN,
|
||||
D3DFMT_UNKNOWN
|
||||
};
|
||||
static bool32 alphaMap[] = {
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0, 0
|
||||
};
|
||||
XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||
if(raster->flags & 0x80)
|
||||
return;
|
||||
uint32 format = formatMap[(raster->format >> 8) & 0xF];
|
||||
ras->format = 0;
|
||||
ras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF];
|
||||
int32 levels = Raster::calculateNumLevels(raster->width, raster->height);
|
||||
ras->texture = createTexture(raster->width, raster->width,
|
||||
raster->format & Raster::MIPMAP ? levels : 1,
|
||||
format);
|
||||
assert((raster->flags & (Raster::PAL4 | Raster::PAL8)) == 0);
|
||||
}
|
||||
|
||||
uint8*
|
||||
lockRaster(Raster *raster, int32 level)
|
||||
{
|
||||
XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||
RasterLevels *levels = (RasterLevels*)ras->texture;
|
||||
return levels->levels[level].data;
|
||||
}
|
||||
|
||||
void
|
||||
unlockRaster(Raster *raster, int32 level)
|
||||
{
|
||||
}
|
||||
|
||||
int32
|
||||
getNumLevels(Raster *raster)
|
||||
{
|
||||
XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||
RasterLevels *levels = (RasterLevels*)ras->texture;
|
||||
return levels->numlevels;
|
||||
}
|
||||
|
||||
int32
|
||||
getLevelSize(Raster *raster, int32 level)
|
||||
{
|
||||
XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||
RasterLevels *levels = (RasterLevels*)ras->texture;
|
||||
return levels->levels[level].size;
|
||||
}
|
||||
|
||||
Texture*
|
||||
readNativeTexture(Stream *stream)
|
||||
{
|
||||
uint32 version;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &version));
|
||||
assert(version >= 0x34001);
|
||||
assert(stream->readU32() == PLATFORM_XBOX);
|
||||
Texture *tex = new Texture;
|
||||
|
||||
// Texture
|
||||
tex->filterAddressing = stream->readU32();
|
||||
stream->read(tex->name, 32);
|
||||
stream->read(tex->mask, 32);
|
||||
|
||||
// Raster
|
||||
int32 format = stream->readI32();
|
||||
bool32 hasAlpha = stream->readI16();
|
||||
bool32 unknownFlag = stream->readI16();
|
||||
int32 width = stream->readU16();
|
||||
int32 height = stream->readU16();
|
||||
int32 depth = stream->readU8();
|
||||
int32 numLevels = stream->readU8();
|
||||
int32 type = stream->readU8();
|
||||
int32 compression = stream->readU8();
|
||||
int32 totalSize = stream->readI32();
|
||||
|
||||
assert(unknownFlag == 0);
|
||||
Raster *raster;
|
||||
if(compression){
|
||||
raster = new Raster(width, height, depth, format | type | 0x80, PLATFORM_XBOX);
|
||||
XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||
ras->format = compression;
|
||||
ras->hasAlpha = hasAlpha;
|
||||
ras->texture = createTexture(raster->width, raster->width,
|
||||
raster->format & Raster::MIPMAP ? numLevels : 1,
|
||||
ras->format);
|
||||
raster->flags &= ~0x80;
|
||||
}else
|
||||
raster = new Raster(width, height, depth, format | type, PLATFORM_XBOX);
|
||||
tex->raster = raster;
|
||||
|
||||
if(raster->format & (Raster::PAL4 | Raster::PAL8))
|
||||
assert(0 && "don't support palettes");
|
||||
|
||||
// exploit the fact that mipmaps are allocated consecutively
|
||||
uint8 *data = raster->lock(0);
|
||||
stream->read(data, totalSize);
|
||||
raster->unlock(0);
|
||||
|
||||
tex->streamReadPlugins(stream);
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
writeNativeTexture(Texture *tex, Stream *stream)
|
||||
{
|
||||
int32 chunksize = getSizeNativeTexture(tex);
|
||||
int32 plgsize = tex->streamGetPluginSize();
|
||||
writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize);
|
||||
writeChunkHeader(stream, ID_STRUCT, chunksize-24-plgsize);
|
||||
stream->writeU32(PLATFORM_XBOX);
|
||||
|
||||
// Texture
|
||||
stream->writeU32(tex->filterAddressing);
|
||||
stream->write(tex->name, 32);
|
||||
stream->write(tex->mask, 32);
|
||||
|
||||
// Raster
|
||||
Raster *raster = tex->raster;
|
||||
XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset);
|
||||
int32 numLevels = raster->getNumLevels();
|
||||
stream->writeI32(raster->format);
|
||||
stream->writeI16(ras->hasAlpha);
|
||||
stream->writeI16(ras->unknownFlag);
|
||||
stream->writeU16(raster->width);
|
||||
stream->writeU16(raster->height);
|
||||
stream->writeU8(raster->depth);
|
||||
stream->writeU8(numLevels);
|
||||
stream->writeU8(raster->type);
|
||||
stream->writeU8(ras->format);
|
||||
|
||||
int32 totalSize = 0;
|
||||
for(int32 i = 0; i < numLevels; i++)
|
||||
totalSize += getLevelSize(tex->raster, i);
|
||||
totalSize = (totalSize+3)&~3;
|
||||
stream->writeI32(totalSize);
|
||||
|
||||
// exploit the fact that mipmaps are allocated consecutively
|
||||
uint8 *data = raster->lock(0);
|
||||
stream->write(data, totalSize);
|
||||
raster->unlock(0);
|
||||
|
||||
tex->streamWritePlugins(stream);
|
||||
}
|
||||
|
||||
uint32
|
||||
getSizeNativeTexture(Texture *tex)
|
||||
{
|
||||
uint32 size = 12 + 72 + 16 + 4;
|
||||
int32 levels = tex->raster->getNumLevels();
|
||||
for(int32 i = 0; i < levels; i++)
|
||||
size += getLevelSize(tex->raster, i);
|
||||
size = (size+3)&~3;
|
||||
size += 12 + tex->streamGetPluginSize();
|
||||
return size;
|
||||
}
|
||||
|
||||
static void*
|
||||
createNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset);
|
||||
raster->texture = NULL;
|
||||
raster->palette = NULL;
|
||||
raster->format = 0;
|
||||
raster->hasAlpha = 0;
|
||||
raster->unknownFlag = 0;
|
||||
// raster->compression = 0;
|
||||
return object;
|
||||
}
|
||||
|
||||
static void*
|
||||
destroyNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
// TODO:
|
||||
return object;
|
||||
}
|
||||
|
||||
static void*
|
||||
copyNativeRaster(void *dst, void *, int32 offset, int32)
|
||||
{
|
||||
XboxRaster *raster = PLUGINOFFSET(XboxRaster, dst, offset);
|
||||
raster->texture = NULL;
|
||||
raster->palette = NULL;
|
||||
raster->format = 0;
|
||||
raster->hasAlpha = 0;
|
||||
raster->unknownFlag = 0;
|
||||
// raster->compression = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
void
|
||||
registerNativeRaster(void)
|
||||
{
|
||||
nativeRasterOffset = Raster::registerPlugin(sizeof(XboxRaster),
|
||||
0x12340000 | PLATFORM_XBOX,
|
||||
createNativeRaster,
|
||||
destroyNativeRaster,
|
||||
copyNativeRaster);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
50
tools/txdwrite/txdwrite.cpp
Normal file
50
tools/txdwrite/txdwrite.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
#include <rw.h>
|
||||
#include <src/gtaplg.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace rw;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
gta::attachPlugins();
|
||||
rw::xbox::registerNativeRaster();
|
||||
rw::d3d::registerNativeRaster();
|
||||
|
||||
// rw::version = 0x33002;
|
||||
// rw::platform = rw::PLATFORM_PS2;
|
||||
// rw::platform = rw::PLATFORM_OGL;
|
||||
rw::platform = rw::PLATFORM_XBOX;
|
||||
// rw::platform = rw::PLATFORM_D3D8;
|
||||
// rw::platform = rw::PLATFORM_D3D9;
|
||||
|
||||
if(argc < 2){
|
||||
printf("usage: %s in.txd\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rw::StreamFile in;
|
||||
if(in.open(argv[1], "rb") == NULL){
|
||||
printf("couldn't open file\n");
|
||||
return 1;
|
||||
}
|
||||
rw::findChunk(&in, rw::ID_TEXDICTIONARY, NULL, NULL);
|
||||
rw::TexDictionary *txd;
|
||||
txd = rw::TexDictionary::streamRead(&in);
|
||||
assert(txd);
|
||||
in.close();
|
||||
rw::currentTexDictionary = txd;
|
||||
|
||||
rw::StreamFile out;
|
||||
out.open("out.txd", "wb");
|
||||
txd->streamWrite(&out);
|
||||
out.close();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user