diff --git a/Makefile b/Makefile index e496a38..30f9da6 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,8 @@ BUILDDEF:=$(shell echo $(BUILD) | tr a-z A-Z | sed 's/^/-DRW_/') BUILDDIR=build-$(BUILD) SRCDIR=src #SRC := $(patsubst %.cpp,$(SRCDIR)/%.cpp, $(wildcard *.cpp)) -SRC := $(wildcard $(SRCDIR)/*.cpp) +SRC := $(wildcard $(SRCDIR)/*.cpp $(SRCDIR)/d3d/*.cpp $(SRCDIR)/ps2/*.cpp \ + $(SRCDIR)/gl/*.cpp) OBJ := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.o,$(SRC)) DEP := $(patsubst $(SRCDIR)/%.cpp,$(BUILDDIR)/%.d,$(SRC)) INC := -I/usr/local/include diff --git a/rw.h b/rw.h index da06c26..f4496f6 100644 --- a/rw.h +++ b/rw.h @@ -8,10 +8,10 @@ #include "src/rwobjects.h" #include "src/rwengine.h" #include "src/rwplugins.h" -#include "src/rwps2.h" -#include "src/rwps2plg.h" -#include "src/rwxbox.h" -#include "src/rwd3d.h" -#include "src/rwd3d8.h" -#include "src/rwd3d9.h" -#include "src/rwwdgl.h" +#include "src/ps2/rwps2.h" +#include "src/ps2/rwps2plg.h" +#include "src/d3d/rwxbox.h" +#include "src/d3d/rwd3d.h" +#include "src/d3d/rwd3d8.h" +#include "src/d3d/rwd3d9.h" +#include "src/gl/rwwdgl.h" diff --git a/src/d3d.cpp b/src/d3d.cpp deleted file mode 100644 index c050a9d..0000000 --- a/src/d3d.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwengine.h" -#include "rwd3d.h" - -namespace rw { -namespace d3d { - -bool32 isP8supported = 1; - -#ifdef RW_D3D9 -IDirect3DDevice9 *device = nil; -#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 -}; - -void* -createIndexBuffer(uint32 length) -{ -#ifdef RW_D3D9 - IDirect3DIndexBuffer9 *ibuf; - device->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0); - return ibuf; -#else - return new uint8[length]; -#endif -} - -uint16* -lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags) -{ - if(indexBuffer == nil) - return nil; -#ifdef RW_D3D9 - uint16 *indices; - IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer; - ibuf->Lock(offset, size, (void**)&indices, flags); - return indices; -#else - (void)offset; - (void)size; - (void)flags; - return (uint16*)indexBuffer; -#endif -} - -void -unlockIndices(void *indexBuffer) -{ - if(indexBuffer == nil) - return; -#ifdef RW_D3D9 - IDirect3DIndexBuffer9 *ibuf = (IDirect3DIndexBuffer9*)indexBuffer; - ibuf->Unlock(); -#endif -} - -void* -createVertexBuffer(uint32 length, uint32 fvf, int32 pool) -{ -#ifdef RW_D3D9 - IDirect3DVertexBuffer9 *vbuf; - device->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, (D3DPOOL)pool, &vbuf, 0); - return vbuf; -#else - (void)fvf; - (void)pool; - return new uint8[length]; -#endif -} - -uint8* -lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags) -{ - if(vertexBuffer == nil) - return nil; -#ifdef RW_D3D9 - uint8 *verts; - IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer; - vertbuf->Lock(offset, size, (void**)&verts, flags); - return verts; -#else - (void)offset; - (void)size; - (void)flags; - return (uint8*)vertexBuffer; -#endif -} - -void -unlockVertices(void *vertexBuffer) -{ - if(vertexBuffer == nil) - return; -#ifdef RW_D3D9 - IDirect3DVertexBuffer9 *vertbuf = (IDirect3DVertexBuffer9*)vertexBuffer; - vertbuf->Unlock(); -#endif -} - -void* -createTexture(int32 width, int32 height, int32 numlevels, uint32 format) -{ -#ifdef RW_D3D9 - IDirect3DTexture9 *tex; - device->CreateTexture(width, height, numlevels, 0, - (D3DFORMAT)format, D3DPOOL_MANAGED, &tex, nil); - return tex; -#else - 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 -} - -uint8* -lockTexture(void *texture, int32 level) -{ -#ifdef RW_D3D9 - IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture; - D3DLOCKED_RECT lr; - tex->LockRect(level, &lr, 0, 0); - return (uint8*)lr.pBits; -#else - RasterLevels *levels = (RasterLevels*)texture; - return levels->levels[level].data; -#endif -} - -void -unlockTexture(void *texture, int32 level) -{ - (void)texture; - (void)level; -#ifdef RW_D3D9 - IDirect3DTexture9 *tex = (IDirect3DTexture9*)texture; - tex->UnlockRect(level); -#endif -} - -void -deleteObject(void *object) -{ - if(object == nil) - return; -#ifdef RW_D3D9 - IUnknown *unk = (IUnknown*)object; - unk->Release(); -#else - delete[] (uint*)object; -#endif -} - -// Native Raster - -int32 nativeRasterOffset; - -static void -rasterCreate(Raster *raster) -{ - D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - static uint32 formatMap[] = { - 0, - D3DFMT_A1R5G5B5, - D3DFMT_R5G6B5, - D3DFMT_A4R4G4B4, - D3DFMT_L8, - D3DFMT_A8R8G8B8, - D3DFMT_X8R8G8B8, - 0, 0, 0, - D3DFMT_X1R5G5B5, - 0, 0, 0, 0, 0 - }; - static bool32 alphaMap[] = { - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 0, 0, 0, - 0, - 0, 0, 0, 0, 0 - }; - if(raster->flags & 0x80) - return; - uint32 format; - if(raster->format & (Raster::PAL4 | Raster::PAL8)){ - format = D3DFMT_P8; - natras->palette = new uint8[4*256]; - }else - format = formatMap[(raster->format >> 8) & 0xF]; - natras->format = 0; - natras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF]; - int32 levels = Raster::calculateNumLevels(raster->width, raster->height); - natras->texture = createTexture(raster->width, raster->height, - raster->format & Raster::MIPMAP ? levels : 1, - format); -} - -static uint8* -rasterLock(Raster *raster, int32 level) -{ - D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - return lockTexture(natras->texture, level); -} - -static void -rasterUnlock(Raster *raster, int32 level) -{ - D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - unlockTexture(natras->texture, level); -} - -static int32 -rasterNumLevels(Raster *raster) -{ - D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); -#ifdef RW_D3D9 - IDirect3DTexture9 *tex = (IDirect3DTexture9*)natras->texture; - return tex->GetLevelCount(); -#else - RasterLevels *levels = (RasterLevels*)natras->texture; - return levels->numlevels; -#endif -} - -static void -rasterFromImage(Raster *raster, Image *image) -{ - int32 format; - D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - switch(image->depth){ - case 32: - format = image->hasAlpha() ? Raster::C8888 : Raster::C888; - break; - case 24: - format = Raster::C888; - break; - case 16: - format = Raster::C1555; - break; - case 8: - format = Raster::PAL8 | Raster::C8888; - break; - case 4: - format = Raster::PAL4 | Raster::C8888; - break; - default: - return; - } - format |= 4; - - raster->type = format & 0x7; - raster->flags = format & 0xF8; - raster->format = format & 0xFF00; - rasterCreate(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*)natras->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; - } - } - - int32 inc = image->depth/8; - in = image->pixels; - out = raster->lock(0); - if(pallength) - memcpy(out, in, raster->width*raster->height); - else - // TODO: stride - 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 += inc; - out += 4; - break; - case Raster::C888: - out[0] = in[2]; - out[1] = in[1]; - out[2] = in[0]; - out[3] = 0xFF; - in += inc; - out += 4; - break; - case Raster::C1555: - out[0] = in[0]; - out[1] = in[1]; - in += 2; - out += 2; - break; - } - raster->unlock(0); -} - -int32 -getLevelSize(Raster *raster, int32 level) -{ - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); -#ifdef RW_D3D9 - IDirect3DTexture9 *tex = (IDirect3DTexture9*)ras->texture; - D3DSURFACE_DESC desc; - tex->GetLevelDesc(level, &desc); - return calculateTextureSize(desc.Width, desc.Height, 1, desc.Format); -#else - RasterLevels *levels = (RasterLevels*)ras->texture; - return levels->levels[level].size; -#endif -} - -void -allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha) -{ - static uint32 dxtMap[] = { - 0x31545844, // DXT1 - 0x32545844, // DXT2 - 0x33545844, // DXT3 - 0x34545844, // DXT4 - 0x35545844, // DXT5 - }; - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - ras->format = dxtMap[dxt-1]; - ras->hasAlpha = hasAlpha; - ras->texture = createTexture(raster->width, raster->height, - raster->format & Raster::MIPMAP ? numLevels : 1, - ras->format); - raster->flags &= ~0x80; -} - -void -setPalette(Raster *raster, void *palette, int32 size) -{ - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - memcpy(ras->palette, palette, 4*size); -} - -void -setTexels(Raster *raster, void *texels, int32 level) -{ - uint8 *dst = raster->lock(level); - memcpy(dst, texels, getLevelSize(raster, level)); - raster->unlock(level); -} - -static void* -createNativeRaster(void *object, int32 offset, int32) -{ - D3dRaster *raster = PLUGINOFFSET(D3dRaster, object, offset); - raster->texture = nil; - raster->palette = nil; - raster->format = 0; - raster->hasAlpha = 0; - raster->customFormat = 0; - return object; -} - -static void* -destroyNativeRaster(void *object, int32 offset, int32) -{ - // TODO: - (void)offset; - return object; -} - -static void* -copyNativeRaster(void *dst, void *, int32 offset, int32) -{ - D3dRaster *raster = PLUGINOFFSET(D3dRaster, dst, offset); - raster->texture = nil; - raster->palette = nil; - raster->format = 0; - raster->hasAlpha = 0; - raster->customFormat = 0; - return dst; -} - -void -registerNativeRaster(void) -{ - nativeRasterOffset = Raster::registerPlugin(sizeof(D3dRaster), - 0x12340000 | PLATFORM_D3D9, - createNativeRaster, - destroyNativeRaster, - copyNativeRaster); - driver[PLATFORM_D3D8].rasterNativeOffset = nativeRasterOffset; - driver[PLATFORM_D3D8].rasterCreate = rasterCreate; - driver[PLATFORM_D3D8].rasterLock = rasterLock; - driver[PLATFORM_D3D8].rasterUnlock = rasterUnlock; - driver[PLATFORM_D3D8].rasterNumLevels = rasterNumLevels; - driver[PLATFORM_D3D8].rasterFromImage = rasterFromImage; - - driver[PLATFORM_D3D9].rasterNativeOffset = nativeRasterOffset; - driver[PLATFORM_D3D9].rasterCreate = rasterCreate; - driver[PLATFORM_D3D9].rasterLock = rasterLock; - driver[PLATFORM_D3D9].rasterUnlock = rasterUnlock; - driver[PLATFORM_D3D9].rasterNumLevels = rasterNumLevels; - driver[PLATFORM_D3D9].rasterFromImage = rasterFromImage; -} - -} -} diff --git a/src/d3d8.cpp b/src/d3d8.cpp deleted file mode 100644 index ce4fd75..0000000 --- a/src/d3d8.cpp +++ /dev/null @@ -1,630 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwerror.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwengine.h" -#include "rwd3d.h" -#include "rwd3d8.h" - -#define PLUGIN_ID 2 - -namespace rw { -namespace d3d8 { -using namespace d3d; - -void -initializePlatform(void) -{ - driver[PLATFORM_D3D8].defaultPipeline = makeDefaultPipeline(); -} - -uint32 -makeFVFDeclaration(uint32 flags, int32 numTex) -{ - uint32 fvf = 0x2; - if(flags & Geometry::NORMALS) - fvf |= 0x10; - if(flags & Geometry::PRELIT) - fvf |= 0x40; - fvf |= numTex << 8; - return fvf; -} - -int32 -getStride(uint32 flags, int32 numTex) -{ - int32 stride = 12; - if(flags & Geometry::NORMALS) - stride += 12;; - if(flags & Geometry::PRELIT) - stride += 4; - stride += numTex*8; - return stride; -} - -void* -destroyNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_D3D8) - return object; - InstanceDataHeader *header = - (InstanceDataHeader*)geometry->instData; - geometry->instData = nil; - InstanceData *inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - deleteObject(inst->indexBuffer); - deleteObject(inst->vertexBuffer); - inst++; - } - delete[] header->inst; - delete header; - return object; -} - -Stream* -readNativeData(Stream *stream, int32, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_D3D8){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - InstanceDataHeader *header = new InstanceDataHeader; - geometry->instData = header; - header->platform = PLATFORM_D3D8; - - int32 size = stream->readI32(); - uint8 *data = new uint8[size]; - stream->read(data, size); - uint8 *p = data; - header->serialNumber = *(uint16*)p; p += 2; - header->numMeshes = *(uint16*)p; p += 2; - header->inst = new InstanceData[header->numMeshes]; - - InstanceData *inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - inst->minVert = *(uint32*)p; p += 4; - inst->stride = *(uint32*)p; p += 4; - inst->numVertices = *(uint32*)p; p += 4; - inst->numIndices = *(uint32*)p; p += 4; - uint32 matid = *(uint32*)p; p += 4; - inst->material = geometry->materialList[matid]; - inst->vertexShader = *(uint32*)p; p += 4; - inst->primType = *(uint32*)p; p += 4; - inst->indexBuffer = nil; p += 4; - inst->vertexBuffer = nil; p += 4; - inst->baseIndex = 0; p += 4; - inst->vertexAlpha = *p++; - inst->managed = 0; p++; - inst->remapped = 0; p++; // TODO: really unused? and what's that anyway? - inst++; - } - delete[] data; - - inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - inst->indexBuffer = createIndexBuffer(inst->numIndices*2); - uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); - stream->read(indices, 2*inst->numIndices); - unlockIndices(inst->indexBuffer); - - inst->managed = 1; - inst->vertexBuffer = createVertexBuffer(inst->stride*inst->numVertices, 0, D3DPOOL_MANAGED); - uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - stream->read(verts, inst->stride*inst->numVertices); - unlockVertices(inst->vertexBuffer); - - inst++; - } - return stream; -} - -Stream* -writeNativeData(Stream *stream, int32 len, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - writeChunkHeader(stream, ID_STRUCT, len-12); - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_D3D8) - return stream; - stream->writeU32(PLATFORM_D3D8); - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - - int32 size = 4 + geometry->meshHeader->numMeshes*0x2C; - uint8 *data = new uint8[size]; - stream->writeI32(size); - uint8 *p = data; - *(uint16*)p = header->serialNumber; p += 2; - *(uint16*)p = header->numMeshes; p += 2; - - InstanceData *inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - *(uint32*)p = inst->minVert; p += 4; - *(uint32*)p = inst->stride; p += 4; - *(uint32*)p = inst->numVertices; p += 4; - *(uint32*)p = inst->numIndices; p += 4; - int32 matid = findPointer(inst->material, (void**)geometry->materialList, geometry->numMaterials); - *(int32*)p = matid; p += 4; - *(uint32*)p = inst->vertexShader; p += 4; - *(uint32*)p = inst->primType; p += 4; - *(uint32*)p = 0; p += 4; // index buffer - *(uint32*)p = 0; p += 4; // vertex buffer - *(uint32*)p = inst->baseIndex; p += 4; - *p++ = inst->vertexAlpha; - *p++ = inst->managed; - *p++ = inst->remapped; - inst++; - } - stream->write(data, size); - delete[] data; - - inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); - stream->write(indices, 2*inst->numIndices); - unlockIndices(inst->indexBuffer); - - uint8 *verts = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - stream->write(verts, inst->stride*inst->numVertices); - unlockVertices(inst->vertexBuffer); - inst++; - } - return stream; -} - -int32 -getSizeNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_D3D8) - return 0; - - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - InstanceData *inst = header->inst; - int32 size = 12 + 4 + 4 + 4 + header->numMeshes*0x2C; - for(int32 i = 0; i < header->numMeshes; i++){ - size += inst->numIndices*2 + inst->numVertices*inst->stride; - inst++; - } - return size; -} - -void -registerNativeDataPlugin(void) -{ - Geometry::registerPlugin(0, ID_NATIVEDATA, - nil, destroyNativeData, nil); - Geometry::registerPluginStream(ID_NATIVEDATA, - readNativeData, - writeNativeData, - getSizeNativeData); -} - - -static void -instance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if(geo->geoflags & Geometry::NATIVE) - return; - geo->geoflags |= Geometry::NATIVE; - InstanceDataHeader *header = new InstanceDataHeader; - MeshHeader *meshh = geo->meshHeader; - geo->instData = header; - header->platform = PLATFORM_D3D8; - - header->serialNumber = 0; - header->numMeshes = meshh->numMeshes; - header->inst = new InstanceData[header->numMeshes]; - - InstanceData *inst = header->inst; - Mesh *mesh = meshh->mesh; - for(uint32 i = 0; i < header->numMeshes; i++){ - findMinVertAndNumVertices(mesh->indices, mesh->numIndices, - &inst->minVert, &inst->numVertices); - inst->numIndices = mesh->numIndices; - inst->material = mesh->material; - inst->vertexShader = 0; - inst->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST; - inst->vertexBuffer = nil; - inst->baseIndex = 0; // (maybe) not used by us - inst->vertexAlpha = 0; - inst->managed = 0; - inst->remapped = 0; - - inst->indexBuffer = createIndexBuffer(inst->numIndices*2); - uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); - if(inst->minVert == 0) - memcpy(indices, mesh->indices, inst->numIndices*2); - else - for(int32 j = 0; j < inst->numIndices; j++) - indices[j] = mesh->indices[j] - inst->minVert; - unlockIndices(inst->indexBuffer); - - pipe->instanceCB(geo, inst); - mesh++; - inst++; - } -} - -static void -uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if((geo->geoflags & Geometry::NATIVE) == 0) - return; - assert(geo->instData != nil); - assert(geo->instData->platform == PLATFORM_D3D8); - geo->geoflags &= ~Geometry::NATIVE; - geo->allocateData(); - geo->meshHeader->allocateIndices(); - - InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; - InstanceData *inst = header->inst; - Mesh *mesh = geo->meshHeader->mesh; - for(uint32 i = 0; i < header->numMeshes; i++){ - uint16 *indices = lockIndices(inst->indexBuffer, 0, 0, 0); - if(inst->minVert == 0) - memcpy(mesh->indices, indices, inst->numIndices*2); - else - for(int32 j = 0; j < inst->numIndices; j++) - mesh->indices[j] = indices[j] + inst->minVert; - unlockIndices(inst->indexBuffer); - - pipe->uninstanceCB(geo, inst); - mesh++; - inst++; - } - geo->generateTriangles(); - destroyNativeData(geo, 0, 0); -} - -static void -render(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if((geo->geoflags & Geometry::NATIVE) == 0) - pipe->instance(atomic); - assert(geo->instData != nil); - assert(geo->instData->platform == PLATFORM_D3D8); - if(pipe->renderCB) - pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData); -} - -ObjPipeline::ObjPipeline(uint32 platform) - : rw::ObjPipeline(platform) -{ - this->impl.instance = d3d8::instance; - this->impl.uninstance = d3d8::uninstance; - this->impl.render = d3d8::render; - this->instanceCB = nil; - this->uninstanceCB = nil; - this->renderCB = nil; -} - -void -defaultInstanceCB(Geometry *geo, InstanceData *inst) -{ - inst->vertexShader = makeFVFDeclaration(geo->geoflags, geo->numTexCoordSets); - inst->stride = getStride(geo->geoflags, geo->numTexCoordSets); - - inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride, - inst->vertexShader, D3DPOOL_MANAGED); - inst->managed = 1; - - uint8 *dst = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - instV3d(VERT_FLOAT3, dst, - &geo->morphTargets[0].vertices[3*inst->minVert], - inst->numVertices, inst->stride); - dst += 12; - - if(geo->geoflags & Geometry::NORMALS){ - instV3d(VERT_FLOAT3, dst, - &geo->morphTargets[0].normals[3*inst->minVert], - inst->numVertices, inst->stride); - dst += 12; - } - - inst->vertexAlpha = 0; - if(geo->geoflags & Geometry::PRELIT){ - inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[4*inst->minVert], - inst->numVertices, inst->stride); - dst += 4; - } - - for(int32 i = 0; i < geo->numTexCoordSets; i++){ - instV2d(VERT_FLOAT2, dst, &geo->texCoords[i][2*inst->minVert], - inst->numVertices, inst->stride); - dst += 8; - } - unlockVertices(inst->vertexBuffer); -} - -void -defaultUninstanceCB(Geometry *geo, InstanceData *inst) -{ - uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - uninstV3d(VERT_FLOAT3, - &geo->morphTargets[0].vertices[3*inst->minVert], - src, inst->numVertices, inst->stride); - src += 12; - - if(geo->geoflags & Geometry::NORMALS){ - uninstV3d(VERT_FLOAT3, - &geo->morphTargets[0].normals[3*inst->minVert], - src, inst->numVertices, inst->stride); - src += 12; - } - - inst->vertexAlpha = 0; - if(geo->geoflags & Geometry::PRELIT){ - uninstColor(VERT_ARGB, &geo->colors[4*inst->minVert], src, - inst->numVertices, inst->stride); - src += 4; - } - - for(int32 i = 0; i < geo->numTexCoordSets; i++){ - uninstV2d(VERT_FLOAT2, &geo->texCoords[i][2*inst->minVert], src, - inst->numVertices, inst->stride); - src += 8; - } - unlockVertices(inst->vertexBuffer); -} - -ObjPipeline* -makeDefaultPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - return pipe; -} - -ObjPipeline* -makeSkinPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - pipe->pluginID = ID_SKIN; - pipe->pluginData = 1; - return pipe; -} - -ObjPipeline* -makeMatFXPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D8); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - pipe->pluginID = ID_MATFX; - pipe->pluginData = 0; - return pipe; -} - -// Native Texture and Raster - -// only handles 4 and 8 bit textures right now -Raster* -readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format, int32 numLevels) -{ - uint8 palette[256*4]; - uint8 *data; - - Image *img = Image::create(width, height, 32); - img->allocate(); - - if(format & Raster::PAL4) - stream->read(palette, 4*32); - else if(format & Raster::PAL8) - stream->read(palette, 4*256); - - // Only read one mipmap - for(int32 i = 0; i < numLevels; i++){ - uint32 size = stream->readU32(); - if(i == 0){ - data = new uint8[size]; - stream->read(data, size); - }else - stream->seek(size); - } - - if(format & (Raster::PAL4 | Raster::PAL8)){ - uint8 *idx = data; - uint8 *pixels = img->pixels; - for(int y = 0; y < img->height; y++){ - uint8 *line = pixels; - for(int x = 0; x < img->width; x++){ - line[0] = palette[*idx*4+0]; - line[1] = palette[*idx*4+1]; - line[2] = palette[*idx*4+2]; - line[3] = palette[*idx*4+3]; - line += 4; - idx++; - } - pixels += img->stride; - } - } - - delete[] data; - Raster *ras = Raster::createFromImage(img); - img->destroy(); - return ras; -} - -Texture* -readNativeTexture(Stream *stream) -{ - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_D3D8){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - Texture *tex = Texture::create(nil); - if(tex == nil) - return nil; - - // Texture - tex->filterAddressing = stream->readU32(); - stream->read(tex->name, 32); - stream->read(tex->mask, 32); - - // Raster - uint32 format = stream->readU32(); - bool32 hasAlpha = stream->readI32(); - 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 pallength = 0; - if(format & Raster::PAL4 || format & Raster::PAL8){ - pallength = format & Raster::PAL4 ? 32 : 256; - if(!d3d::isP8supported){ - tex->raster = readAsImage(stream, width, height, depth, format|type, numLevels); - tex->streamReadPlugins(stream); - return tex; - } - } - - Raster *raster; - D3dRaster *ras; - if(compression){ - raster = Raster::create(width, height, depth, format | type | 0x80, PLATFORM_D3D8); - ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - allocateDXT(raster, compression, numLevels, hasAlpha); - ras->customFormat = 1; - }else{ - raster = Raster::create(width, height, depth, format | type, PLATFORM_D3D8); - ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - } - tex->raster = raster; - - // TODO: check if format supported and convert if necessary - - if(pallength != 0) - stream->read(ras->palette, 4*pallength); - - uint32 size; - uint8 *data; - for(int32 i = 0; i < numLevels; i++){ - size = stream->readU32(); - if(i < raster->getNumLevels()){ - data = raster->lock(i); - stream->read(data, size); - raster->unlock(i); - }else - stream->seek(size); - } - 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_D3D8); - - // Texture - stream->writeU32(tex->filterAddressing); - stream->write(tex->name, 32); - stream->write(tex->mask, 32); - - // Raster - Raster *raster = tex->raster; - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - int32 numLevels = raster->getNumLevels(); - stream->writeI32(raster->format); - stream->writeI32(ras->hasAlpha); - stream->writeU16(raster->width); - stream->writeU16(raster->height); - stream->writeU8(raster->depth); - stream->writeU8(numLevels); - stream->writeU8(raster->type); - int32 compression = 0; - if(ras->format) - switch(ras->format){ - case 0x31545844: // DXT1 - compression = 1; - break; - case 0x32545844: // DXT2 - compression = 2; - break; - case 0x33545844: // DXT3 - compression = 3; - break; - case 0x34545844: // DXT4 - compression = 4; - break; - case 0x35545844: // DXT5 - compression = 5; - break; - } - stream->writeU8(compression); - - if(raster->format & Raster::PAL4) - stream->write(ras->palette, 4*32); - else if(raster->format & Raster::PAL8) - stream->write(ras->palette, 4*256); - - uint32 size; - uint8 *data; - for(int32 i = 0; i < numLevels; i++){ - size = getLevelSize(raster, i); - stream->writeU32(size); - data = raster->lock(i); - stream->write(data, size); - raster->unlock(i); - } - tex->streamWritePlugins(stream); -} - -uint32 -getSizeNativeTexture(Texture *tex) -{ - uint32 size = 12 + 72 + 16; - int32 levels = tex->raster->getNumLevels(); - if(tex->raster->format & Raster::PAL4) - size += 4*32; - else if(tex->raster->format & Raster::PAL8) - size += 4*256; - for(int32 i = 0; i < levels; i++) - size += 4 + getLevelSize(tex->raster, i); - size += 12 + tex->streamGetPluginSize(); - return size; -} - -} -} diff --git a/src/d3d8render.cpp b/src/d3d8render.cpp deleted file mode 100644 index fe191b7..0000000 --- a/src/d3d8render.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwd3d.h" -#include "rwd3d8.h" - -namespace rw { -namespace d3d8 { -using namespace d3d; - -#ifndef RW_D3D9 -void defaultRenderCB(Atomic*, InstanceDataHeader*) {} -#else - -void -defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) -{ - Geometry *geo = atomic->geometry; - Frame *f = atomic->getFrame(); - device->SetTransform(D3DTS_WORLD, (D3DMATRIX*)f->getLTM()); - - InstanceData *inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - d3d::setTexture(0, inst->material->texture); - d3d::setMaterial(inst->material); - d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40)); - d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); - d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); - if(geo->geoflags & Geometry::PRELIT) - d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); - - device->SetFVF(inst->vertexShader); - device->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride); - device->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer); - uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3; - d3d::flushCache(); - device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex, - 0, inst->numVertices, 0, numPrim); - inst++; - } -} - -#endif -} -} diff --git a/src/d3d9.cpp b/src/d3d9.cpp deleted file mode 100644 index b09156a..0000000 --- a/src/d3d9.cpp +++ /dev/null @@ -1,727 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwerror.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwengine.h" -#include "rwd3d.h" -#include "rwd3d9.h" - -#define PLUGIN_ID 2 - -namespace rw { -namespace d3d9 { -using namespace d3d; - -// TODO: move to header, but not as #define -#ifndef RW_D3D9 -#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0} -#endif - -#define NUMDECLELT 12 - -void -initializePlatform(void) -{ - driver[PLATFORM_D3D9].defaultPipeline = makeDefaultPipeline(); -} - -void* -createVertexDeclaration(VertexElement *elements) -{ -#ifdef RW_D3D9 - IDirect3DVertexDeclaration9 *decl = 0; - device->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl); - return decl; -#else - int n = 0; - VertexElement *e = (VertexElement*)elements; - while(e[n++].stream != 0xFF) - ; - e = (VertexElement*)new uint8[n*sizeof(VertexElement)]; - memcpy(e, elements, n*sizeof(VertexElement)); - return e; -#endif -} - -uint32 -getDeclaration(void *declaration, VertexElement *elements) -{ -#ifdef RW_D3D9 - IDirect3DVertexDeclaration9 *decl = (IDirect3DVertexDeclaration9*)declaration; - UINT numElt; - decl->GetDeclaration((D3DVERTEXELEMENT9*)elements, &numElt); - return numElt; -#else - int n = 0; - VertexElement *e = (VertexElement*)declaration; - while(e[n++].stream != 0xFF) - ; - if(elements) - memcpy(elements, declaration, n*sizeof(VertexElement)); - return n; -#endif -} - - -void* -destroyNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_D3D9) - return object; - InstanceDataHeader *header = - (InstanceDataHeader*)geometry->instData; - geometry->instData = nil; - deleteObject(header->vertexDeclaration); - deleteObject(header->indexBuffer); - deleteObject(header->vertexStream[0].vertexBuffer); - deleteObject(header->vertexStream[1].vertexBuffer); - delete[] header->inst; - delete header; - return object; -} - -Stream* -readNativeData(Stream *stream, int32, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_D3D9){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - InstanceDataHeader *header = new InstanceDataHeader; - geometry->instData = header; - header->platform = PLATFORM_D3D9; - - int32 size = stream->readI32(); - uint8 *data = new uint8[size]; - stream->read(data, size); - uint8 *p = data; - header->serialNumber = *(uint32*)p; p += 4; - header->numMeshes = *(uint32*)p; p += 4; - header->indexBuffer = nil; p += 4; - header->primType = *(uint32*)p; p += 4; - p += 16*2; // skip vertex streams, they're repeated with the vertex buffers - header->useOffsets = *(bool32*)p; p += 4; - header->vertexDeclaration = nil; p += 4; - header->totalNumIndex = *(uint32*)p; p += 4; - header->totalNumVertex = *(uint32*)p; p += 4; - header->inst = new InstanceData[header->numMeshes]; - - InstanceData *inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - inst->numIndex = *(uint32*)p; p += 4; - inst->minVert = *(uint32*)p; p += 4; - uint32 matid = *(uint32*)p; p += 4; - inst->material = geometry->materialList[matid]; - inst->vertexAlpha = *(bool32*)p; p += 4; - inst->vertexShader = nil; p += 4; - inst->baseIndex = 0; p += 4; - inst->numVertices = *(uint32*)p; p += 4; - inst->startIndex = *(uint32*)p; p += 4; - inst->numPrimitives = *(uint32*)p; p += 4; - inst++; - } - - VertexElement elements[NUMDECLELT]; - uint32 numDeclarations = stream->readU32(); - stream->read(elements, numDeclarations*8); - header->vertexDeclaration = createVertexDeclaration(elements); - - header->indexBuffer = createIndexBuffer(header->totalNumIndex*2); - uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); - stream->read(indices, 2*header->totalNumIndex); - unlockIndices(header->indexBuffer); - - VertexStream *s; - p = data; - for(int i = 0; i < 2; i++){ - stream->read(p, 16); - s = &header->vertexStream[i]; - s->vertexBuffer = (void*)*(uint32*)p; p += 4; - s->offset = 0; p += 4; - s->stride = *(uint32*)p; p += 4; - s->geometryFlags = *(uint16*)p; p += 2; - s->managed = *p++; - s->dynamicLock = *p++; - - if(s->vertexBuffer == nil) - continue; - // TODO: unset managed flag when using morph targets. - // also uses different buffer type and locks differently - s->vertexBuffer = createVertexBuffer(s->stride*header->totalNumVertex, 0, D3DPOOL_MANAGED); - uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - stream->read(verts, s->stride*header->totalNumVertex); - unlockVertices(s->vertexBuffer); - } - - // TODO: somehow depends on number of streams used (baseIndex = minVert when more than one) - inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - inst->baseIndex = inst->minVert + header->vertexStream[0].offset / header->vertexStream[0].stride; - inst++; - } - - delete[] data; - return stream; -} - -Stream* -writeNativeData(Stream *stream, int32 len, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - writeChunkHeader(stream, ID_STRUCT, len-12); - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_D3D9) - return stream; - stream->writeU32(PLATFORM_D3D9); - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - int32 size = 64 + geometry->meshHeader->numMeshes*36; - uint8 *data = new uint8[size]; - stream->writeI32(size); - - uint8 *p = data; - *(uint32*)p = header->serialNumber; p += 4; - *(uint32*)p = header->numMeshes; p += 4; - p += 4; // skip index buffer - *(uint32*)p = header->primType; p += 4; - p += 16*2; // skip vertex streams, they're repeated with the vertex buffers - *(bool32*)p = header->useOffsets; p += 4; - p += 4; // skip vertex declaration - *(uint32*)p = header->totalNumIndex; p += 4; - *(uint32*)p = header->totalNumVertex; p += 4; - - InstanceData *inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - *(uint32*)p = inst->numIndex; p += 4; - *(uint32*)p = inst->minVert; p += 4; - int32 matid = findPointer(inst->material, (void**)geometry->materialList, geometry->numMaterials); - *(int32*)p = matid; p += 4; - *(bool32*)p = inst->vertexAlpha; p += 4; - *(uint32*)p = 0; p += 4; // vertex shader - *(uint32*)p = inst->baseIndex; p += 4; // not used but meh... - *(uint32*)p = inst->numVertices; p += 4; - *(uint32*)p = inst->startIndex; p += 4; - *(uint32*)p = inst->numPrimitives; p += 4; - inst++; - } - stream->write(data, size); - - VertexElement elements[NUMDECLELT]; - uint32 numElt = getDeclaration(header->vertexDeclaration, elements); - stream->writeU32(numElt); - stream->write(elements, 8*numElt); - - uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); - stream->write(indices, 2*header->totalNumIndex); - unlockIndices(header->indexBuffer); - - VertexStream *s; - for(int i = 0; i < 2; i++){ - s = &header->vertexStream[i]; - p = data; - *(uint32*)p = s->vertexBuffer ? 0xbadeaffe : 0; p += 4; - *(uint32*)p = s->offset; p += 4; - *(uint32*)p = s->stride; p += 4; - *(uint16*)p = s->geometryFlags; p += 2; - *p++ = s->managed; - *p++ = s->dynamicLock; - stream->write(data, 16); - - if(s->vertexBuffer == nil) - continue; - uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - stream->write(verts, s->stride*header->totalNumVertex); - unlockVertices(s->vertexBuffer); - } - - delete[] data; - return stream; -} - -int32 -getSizeNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_D3D9) - return 0; - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - int32 size = 12 + 4 + 4 + 64 + header->numMeshes*36; - uint32 numElt = getDeclaration(header->vertexDeclaration, nil); - size += 4 + numElt*8; - size += 2*header->totalNumIndex; - size += 0x10 + header->vertexStream[0].stride*header->totalNumVertex; - size += 0x10 + header->vertexStream[1].stride*header->totalNumVertex; - return size; -} - -void -registerNativeDataPlugin(void) -{ - Geometry::registerPlugin(0, ID_NATIVEDATA, - nil, destroyNativeData, nil); - Geometry::registerPluginStream(ID_NATIVEDATA, - readNativeData, - writeNativeData, - getSizeNativeData); -} - -static void -instance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if(geo->geoflags & Geometry::NATIVE) - return; - geo->geoflags |= Geometry::NATIVE; - InstanceDataHeader *header = new InstanceDataHeader; - MeshHeader *meshh = geo->meshHeader; - geo->instData = header; - header->platform = PLATFORM_D3D9; - - header->serialNumber = 0; - header->numMeshes = meshh->numMeshes; - header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST; - header->useOffsets = 0; - header->totalNumVertex = geo->numVertices; - header->totalNumIndex = meshh->totalIndices; - header->inst = new InstanceData[header->numMeshes]; - - header->indexBuffer = createIndexBuffer(header->totalNumIndex*2); - - uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); - InstanceData *inst = header->inst; - Mesh *mesh = meshh->mesh; - uint32 startindex = 0; - for(uint32 i = 0; i < header->numMeshes; i++){ - findMinVertAndNumVertices(mesh->indices, mesh->numIndices, - &inst->minVert, (int32*)&inst->numVertices); - inst->numIndex = mesh->numIndices; - inst->material = mesh->material; - inst->vertexAlpha = 0; - inst->vertexShader = nil; - inst->baseIndex = inst->minVert; - inst->startIndex = startindex; - inst->numPrimitives = header->primType == D3DPT_TRIANGLESTRIP ? inst->numIndex-2 : inst->numIndex/3; - if(inst->minVert == 0) - memcpy(&indices[inst->startIndex], mesh->indices, inst->numIndex*2); - else - for(uint32 j = 0; j < inst->numIndex; j++) - indices[inst->startIndex+j] = mesh->indices[j] - inst->minVert; - startindex += inst->numIndex; - mesh++; - inst++; - } - unlockIndices(header->indexBuffer); - - memset(&header->vertexStream, 0, 2*sizeof(VertexStream)); - - pipe->instanceCB(geo, header); -} - -static void -uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if((geo->geoflags & Geometry::NATIVE) == 0) - return; - assert(geo->instData != nil); - assert(geo->instData->platform == PLATFORM_D3D9); - geo->geoflags &= ~Geometry::NATIVE; - geo->allocateData(); - geo->meshHeader->allocateIndices(); - - InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; - uint16 *indices = lockIndices(header->indexBuffer, 0, 0, 0); - InstanceData *inst = header->inst; - Mesh *mesh = geo->meshHeader->mesh; - for(uint32 i = 0; i < header->numMeshes; i++){ - if(inst->minVert == 0) - memcpy(mesh->indices, &indices[inst->startIndex], inst->numIndex*2); - else - for(uint32 j = 0; j < inst->numIndex; j++) - mesh->indices[j] = indices[inst->startIndex+j] + inst->minVert; - mesh++; - inst++; - } - unlockIndices(header->indexBuffer); - - pipe->uninstanceCB(geo, header); - geo->generateTriangles(); - destroyNativeData(geo, 0, 0); -} - -static void -render(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if((geo->geoflags & Geometry::NATIVE) == 0) - pipe->instance(atomic); - assert(geo->instData != nil); - assert(geo->instData->platform == PLATFORM_D3D9); - if(pipe->renderCB) - pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData); -} - -ObjPipeline::ObjPipeline(uint32 platform) - : rw::ObjPipeline(platform) -{ - this->impl.instance = d3d9::instance; - this->impl.uninstance = d3d9::uninstance; - this->impl.render = d3d9::render; - this->instanceCB = nil; - this->uninstanceCB = nil; - this->renderCB = nil; -} - -void -defaultInstanceCB(Geometry *geo, InstanceDataHeader *header) -{ - VertexElement dcl[NUMDECLELT]; - - VertexStream *s = &header->vertexStream[0]; - s->offset = 0; - s->managed = 1; - s->geometryFlags = 0; - s->dynamicLock = 0; - - int i = 0; - dcl[i].stream = 0; - dcl[i].offset = 0; - dcl[i].type = D3DDECLTYPE_FLOAT3; - dcl[i].method = D3DDECLMETHOD_DEFAULT; - dcl[i].usage = D3DDECLUSAGE_POSITION; - dcl[i].usageIndex = 0; - i++; - uint16 stride = 12; - s->geometryFlags |= 0x2; - - bool isPrelit = (geo->geoflags & Geometry::PRELIT) != 0; - if(isPrelit){ - dcl[i].stream = 0; - dcl[i].offset = stride; - dcl[i].type = D3DDECLTYPE_D3DCOLOR; - dcl[i].method = D3DDECLMETHOD_DEFAULT; - dcl[i].usage = D3DDECLUSAGE_COLOR; - dcl[i].usageIndex = 0; - i++; - s->geometryFlags |= 0x8; - stride += 4; - } - - for(int32 n = 0; n < geo->numTexCoordSets; n++){ - dcl[i].stream = 0; - dcl[i].offset = stride; - dcl[i].type = D3DDECLTYPE_FLOAT2; - dcl[i].method = D3DDECLMETHOD_DEFAULT; - dcl[i].usage = D3DDECLUSAGE_TEXCOORD; - dcl[i].usageIndex = (uint8)n; - i++; - s->geometryFlags |= 0x10 << n; - stride += 8; - } - - bool hasNormals = (geo->geoflags & Geometry::NORMALS) != 0; - if(hasNormals){ - dcl[i].stream = 0; - dcl[i].offset = stride; - dcl[i].type = D3DDECLTYPE_FLOAT3; - dcl[i].method = D3DDECLMETHOD_DEFAULT; - dcl[i].usage = D3DDECLUSAGE_NORMAL; - dcl[i].usageIndex = 0; - i++; - s->geometryFlags |= 0x4; - stride += 12; - } - dcl[i] = D3DDECL_END(); - header->vertexStream[0].stride = stride; - - header->vertexDeclaration = createVertexDeclaration((VertexElement*)dcl); - - s->vertexBuffer = createVertexBuffer(header->totalNumVertex*s->stride, 0, D3DPOOL_MANAGED); - - // TODO: support both vertex buffers - uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++) - ; - instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, - geo->morphTargets[0].vertices, - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - - if(isPrelit){ - for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++) - ; - // TODO: vertex alpha (instance per mesh) - instColor(vertFormatMap[dcl[i].type], verts + dcl[i].offset, - geo->colors, - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - } - - for(int32 n = 0; n < geo->numTexCoordSets; n++){ - for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++) - ; - instV2d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, - geo->texCoords[n], - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - } - - if(hasNormals){ - for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++) - ; - instV3d(vertFormatMap[dcl[i].type], verts + dcl[i].offset, - geo->morphTargets[0].normals, - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - } - unlockVertices(s->vertexBuffer); -} - -void -defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header) -{ - VertexElement dcl[NUMDECLELT]; - - uint8 *verts[2]; - verts[0] = lockVertices(header->vertexStream[0].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - verts[1] = lockVertices(header->vertexStream[1].vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK); - - int i; - for(i = 0; dcl[i].usage != D3DDECLUSAGE_POSITION || dcl[i].usageIndex != 0; i++) - ; - uninstV3d(vertFormatMap[dcl[i].type], - geo->morphTargets[0].vertices, - verts[dcl[i].stream] + dcl[i].offset, - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - - if(geo->geoflags & Geometry::PRELIT){ - for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++) - ; - uninstColor(vertFormatMap[dcl[i].type], - geo->colors, - verts[dcl[i].stream] + dcl[i].offset, - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - } - - for(int32 n = 0; n < geo->numTexCoordSets; n++){ - for(i = 0; dcl[i].usage != D3DDECLUSAGE_TEXCOORD || dcl[i].usageIndex != n; i++) - ; - uninstV2d(vertFormatMap[dcl[i].type], - geo->texCoords[n], - verts[dcl[i].stream] + dcl[i].offset, - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - } - - if(geo->geoflags & Geometry::NORMALS){ - for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++) - ; - uninstV3d(vertFormatMap[dcl[i].type], - geo->morphTargets[0].normals, - verts[dcl[i].stream] + dcl[i].offset, - header->totalNumVertex, - header->vertexStream[dcl[i].stream].stride); - } - - unlockVertices(verts[0]); - unlockVertices(verts[1]); -} - -ObjPipeline* -makeDefaultPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - return pipe; -} - -ObjPipeline* -makeSkinPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - pipe->pluginID = ID_SKIN; - pipe->pluginData = 1; - return pipe; -} - -ObjPipeline* -makeMatFXPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_D3D9); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->renderCB = defaultRenderCB; - pipe->pluginID = ID_MATFX; - pipe->pluginData = 0; - return pipe; -} - -// Native Texture and Raster - -Texture* -readNativeTexture(Stream *stream) -{ - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_D3D9){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - Texture *tex = Texture::create(nil); - if(tex == nil) - return nil; - - // Texture - tex->filterAddressing = stream->readU32(); - stream->read(tex->name, 32); - stream->read(tex->mask, 32); - - // Raster - int32 format = stream->readI32(); - int32 d3dformat = stream->readI32(); - int32 width = stream->readU16(); - int32 height = stream->readU16(); - int32 depth = stream->readU8(); - int32 numLevels = stream->readU8(); - int32 type = stream->readU8(); - int32 flags = stream->readU8(); - - Raster *raster; - D3dRaster *ras; - - assert((flags & 2) == 0); - if(flags & 8){ - raster = Raster::create(width, height, depth, format | type | 0x80, PLATFORM_D3D9); - ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - ras->format = d3dformat; - ras->hasAlpha = flags & 1; - ras->texture = createTexture(raster->width, raster->height, - raster->format & Raster::MIPMAP ? numLevels : 1, - ras->format); - raster->flags &= ~0x80; - ras->customFormat = 1; - }else{ - raster = Raster::create(width, height, depth, format | type, PLATFORM_D3D9); - ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - } - tex->raster = raster; - - // TODO: check if format supported and convert if necessary - - if(raster->format & Raster::PAL4) - stream->read(ras->palette, 4*32); - else if(raster->format & Raster::PAL8) - stream->read(ras->palette, 4*256); - - uint32 size; - uint8 *data; - for(int32 i = 0; i < numLevels; i++){ - size = stream->readU32(); - if(i < raster->getNumLevels()){ - data = raster->lock(i); - stream->read(data, size); - raster->unlock(i); - }else - stream->seek(size); - } - 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_D3D9); - - // Texture - stream->writeU32(tex->filterAddressing); - stream->write(tex->name, 32); - stream->write(tex->mask, 32); - - // Raster - Raster *raster = tex->raster; - D3dRaster *ras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - int32 numLevels = raster->getNumLevels(); - stream->writeI32(raster->format); - stream->writeU32(ras->format); - stream->writeU16(raster->width); - stream->writeU16(raster->height); - stream->writeU8(raster->depth); - stream->writeU8(numLevels); - stream->writeU8(raster->type); - uint8 flags = 0; - if(ras->hasAlpha) - flags |= 1; - // 2 - cube map - // 4 - something about mipmaps... - if(ras->customFormat) - flags |= 8; - stream->writeU8(flags); - - if(raster->format & Raster::PAL4) - stream->write(ras->palette, 4*32); - else if(raster->format & Raster::PAL8) - stream->write(ras->palette, 4*256); - - uint32 size; - uint8 *data; - for(int32 i = 0; i < numLevels; i++){ - size = getLevelSize(raster, i); - stream->writeU32(size); - data = raster->lock(i); - stream->write(data, size); - raster->unlock(i); - } - tex->streamWritePlugins(stream); -} - -uint32 -getSizeNativeTexture(Texture *tex) -{ - uint32 size = 12 + 72 + 16; - int32 levels = tex->raster->getNumLevels(); - if(tex->raster->format & Raster::PAL4) - size += 4*32; - else if(tex->raster->format & Raster::PAL8) - size += 4*256; - for(int32 i = 0; i < levels; i++) - size += 4 + getLevelSize(tex->raster, i); - size += 12 + tex->streamGetPluginSize(); - return size; -} - -} -} diff --git a/src/d3d9render.cpp b/src/d3d9render.cpp deleted file mode 100644 index 6c84620..0000000 --- a/src/d3d9render.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwd3d.h" -#include "rwd3d9.h" - -namespace rw { -namespace d3d9 { -using namespace d3d; - -#ifndef RW_D3D9 -void defaultRenderCB(Atomic*, InstanceDataHeader*) {} -#else - -void -defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) -{ - Geometry *geo = atomic->geometry; - Frame *f = atomic->getFrame(); - device->SetTransform(D3DTS_WORLD, (D3DMATRIX*)f->getLTM()); - - device->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer, - 0, header->vertexStream[0].stride); - device->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer); - device->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration); - - InstanceData *inst = header->inst; - for(uint32 i = 0; i < header->numMeshes; i++){ - d3d::setTexture(0, inst->material->texture); - d3d::setMaterial(inst->material); - d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40)); - d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); - d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); - if(geo->geoflags & Geometry::PRELIT) - d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); - d3d::flushCache(); - device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, - 0, inst->numVertices, - inst->startIndex, inst->numPrimitives); - inst++; - } -} - -#endif -} -} diff --git a/src/d3ddriver.cpp b/src/d3ddriver.cpp deleted file mode 100644 index c6d652a..0000000 --- a/src/d3ddriver.cpp +++ /dev/null @@ -1,182 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwd3d.h" - -namespace rw { -namespace d3d { - -#ifdef RW_D3D9 - -#define MAXNUMSTATES D3DRS_BLENDOPALPHA -#define MAXNUMSTAGES 8 -#define MAXNUMTEXSTATES D3DTSS_CONSTANT -#define MAXNUMSAMPLERSTATES D3DSAMP_DMAPOFFSET - -static int32 numDirtyStates; -static uint32 dirtyStates[MAXNUMSTATES]; -static struct { - uint32 value; - bool32 dirty; -} stateCache[MAXNUMSTATES]; -static uint32 d3dStates[MAXNUMSTATES]; - -static int32 numDirtyTextureStageStates; -static struct { - uint32 stage; - uint32 type; -} dirtyTextureStageStates[MAXNUMTEXSTATES*MAXNUMSTAGES]; -static struct { - uint32 value; - bool32 dirty; -} textureStageStateCache[MAXNUMSTATES][MAXNUMSTAGES]; -static uint32 d3dTextureStageStates[MAXNUMSTATES][MAXNUMSTAGES]; - -static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES]; - -static Raster *d3dRaster[MAXNUMSTAGES]; - -static D3DMATERIAL9 d3dmaterial; - -void -setRenderState(uint32 state, uint32 value) -{ - if(stateCache[state].value != value){ - stateCache[state].value = value; - if(!stateCache[state].dirty){ - stateCache[state].dirty = 1; - dirtyStates[numDirtyStates++] = state; - } - } -} - -void -setTextureStageState(uint32 stage, uint32 type, uint32 value) -{ - if(textureStageStateCache[type][stage].value != value){ - textureStageStateCache[type][stage].value = value; - if(!textureStageStateCache[type][stage].dirty){ - textureStageStateCache[type][stage].dirty = 1; - dirtyTextureStageStates[numDirtyTextureStageStates].stage = stage; - dirtyTextureStageStates[numDirtyTextureStageStates].type = type; - numDirtyTextureStageStates++; - } - } -} - -void -flushCache(void) -{ - uint32 s, t; - uint32 v; - for(int32 i = 0; i < numDirtyStates; i++){ - s = dirtyStates[i]; - v = stateCache[s].value; - stateCache[s].dirty = 0; - if(d3dStates[s] != v){ - device->SetRenderState((D3DRENDERSTATETYPE)s, v); - d3dStates[s] = v; - } - } - numDirtyStates = 0; - for(int32 i = 0; i < numDirtyTextureStageStates; i++){ - s = dirtyTextureStageStates[i].stage; - t = dirtyTextureStageStates[i].type; - v = textureStageStateCache[t][s].value; - textureStageStateCache[t][s].dirty = 0; - if(d3dTextureStageStates[t][s] != v){ - device->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v); - d3dTextureStageStates[t][s] = v; - } - } - numDirtyTextureStageStates = 0; -} - -void -setSamplerState(uint32 stage, uint32 type, uint32 value) -{ - if(d3dSamplerStates[type][stage] != value){ - device->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value); - d3dSamplerStates[type][stage] = value; - } -} - -void -setRasterStage(uint32 stage, Raster *raster) -{ - D3dRaster *d3draster = nil; - if(raster != d3dRaster[stage]){ - d3dRaster[stage] = raster; - if(raster){ - d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); - device->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture); - }else - device->SetTexture(stage, nil); - } -} - -void -setTexture(uint32 stage, Texture *tex) -{ - static DWORD filternomip[] = { - 0, D3DTEXF_POINT, D3DTEXF_LINEAR, - D3DTEXF_POINT, D3DTEXF_LINEAR, - D3DTEXF_POINT, D3DTEXF_LINEAR - }; - static DWORD wrap[] = { - 0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR, - D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER - }; - if(tex == nil){ - setRasterStage(stage, nil); - return; - } - if(tex->raster){ - setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]); - setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]); - setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]); - setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]); - } - setRasterStage(stage, tex->raster); -} - -void -setMaterial(Material *mat) -{ - D3DMATERIAL9 mat9; - D3DCOLORVALUE black = { 0, 0, 0, 0 }; - float ambmult = mat->surfaceProps.ambient/255.0f; - float diffmult = mat->surfaceProps.diffuse/255.0f; - mat9.Ambient.r = mat->color.red*ambmult; - mat9.Ambient.g = mat->color.green*ambmult; - mat9.Ambient.b = mat->color.blue*ambmult; - mat9.Ambient.a = mat->color.alpha*ambmult; - mat9.Diffuse.r = mat->color.red*diffmult; - mat9.Diffuse.g = mat->color.green*diffmult; - mat9.Diffuse.b = mat->color.blue*diffmult; - mat9.Diffuse.a = mat->color.alpha*diffmult; - mat9.Power = 0.0f; - mat9.Emissive = black; - mat9.Specular = black; - if(d3dmaterial.Diffuse.r != mat9.Diffuse.r || - d3dmaterial.Diffuse.g != mat9.Diffuse.g || - d3dmaterial.Diffuse.b != mat9.Diffuse.b || - d3dmaterial.Diffuse.a != mat9.Diffuse.a || - d3dmaterial.Ambient.r != mat9.Ambient.r || - d3dmaterial.Ambient.g != mat9.Ambient.g || - d3dmaterial.Ambient.b != mat9.Ambient.b || - d3dmaterial.Ambient.a != mat9.Ambient.a){ - device->SetMaterial(&mat9); - d3dmaterial = mat9; - } -} - -#endif -} -} diff --git a/src/image.cpp b/src/image.cpp index 2e03e6e..c1eaa3e 100755 --- a/src/image.cpp +++ b/src/image.cpp @@ -9,11 +9,11 @@ #include "rwpipeline.h" #include "rwobjects.h" #include "rwengine.h" -#include "rwps2.h" -#include "rwd3d.h" -#include "rwxbox.h" -#include "rwd3d8.h" -#include "rwd3d9.h" +#include "ps2/rwps2.h" +#include "d3d/rwd3d.h" +#include "d3d/rwxbox.h" +#include "d3d/rwd3d8.h" +#include "d3d/rwd3d9.h" #ifdef _WIN32 /* srsly? */ diff --git a/src/pds.cpp b/src/pds.cpp deleted file mode 100644 index 581fe8a..0000000 --- a/src/pds.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwplugins.h" -#include "rwps2.h" -#include "rwps2plg.h" - -namespace rw { -namespace ps2 { - -struct PdsGlobals -{ - Pipeline **pipes; - int32 maxPipes; - int32 numPipes; -}; -static PdsGlobals pdsGlobals; - -Pipeline* -getPDSPipe(uint32 data) -{ - for(int32 i = 0; i < pdsGlobals.numPipes; i++) - if(pdsGlobals.pipes[i]->pluginData == data) - return pdsGlobals.pipes[i]; - return nil; -} - -void -registerPDSPipe(Pipeline *pipe) -{ - assert(pdsGlobals.numPipes < pdsGlobals.maxPipes); - pdsGlobals.pipes[pdsGlobals.numPipes++] = pipe; -} - -static void -atomicPDSRights(void *object, int32, int32, uint32 data) -{ - Atomic *a = (Atomic*)object; - a->pipeline = (ObjPipeline*)getPDSPipe(data); -// printf("atm pds: %x %x %x\n", data, a->pipeline->pluginID, a->pipeline->pluginData); -} - -static void -materialPDSRights(void *object, int32, int32, uint32 data) -{ - Material *m = (Material*)object; - m->pipeline = (ObjPipeline*)getPDSPipe(data); -// printf("mat pds: %x %x %x\n", data, m->pipeline->pluginID, m->pipeline->pluginData); -} - -void -registerPDSPlugin(int32 n) -{ - pdsGlobals.maxPipes = n; - pdsGlobals.numPipes = 0; - pdsGlobals.pipes = new Pipeline*[n]; - Atomic::registerPlugin(0, ID_PDS, nil, nil, nil); - Atomic::setStreamRightsCallback(ID_PDS, atomicPDSRights); - - Material::registerPlugin(0, ID_PDS, nil, nil, nil); - Material::setStreamRightsCallback(ID_PDS, materialPDSRights); -} - -void -registerPluginPDSPipes(void) -{ - // rwPDS_G3_Skin_GrpMatPipeID - MatPipeline *pipe = new MatPipeline(PLATFORM_PS2); - pipe->pluginID = ID_PDS; - pipe->pluginData = 0x11001; - 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 = genericUninstanceCB; - pipe->preUninstCB = skinPreCB; - pipe->postUninstCB = skinPostCB; - registerPDSPipe(pipe); - - // rwPDS_G3_Skin_GrpAtmPipeID - ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); - opipe->pluginID = ID_PDS; - opipe->pluginData = 0x11002; - opipe->groupPipeline = pipe; - registerPDSPipe(opipe); - - // rwPDS_G3_MatfxUV1_GrpMatPipeID - pipe = new MatPipeline(PLATFORM_PS2); - pipe->pluginID = ID_PDS; - pipe->pluginData = 0x1100b; - 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 = genericUninstanceCB; - registerPDSPipe(pipe); - - // rwPDS_G3_MatfxUV1_GrpAtmPipeID - opipe = new ObjPipeline(PLATFORM_PS2); - opipe->pluginID = ID_PDS; - opipe->pluginData = 0x1100d; - opipe->groupPipeline = pipe; - registerPDSPipe(opipe); - - // rwPDS_G3_MatfxUV2_GrpMatPipeID - pipe = new MatPipeline(PLATFORM_PS2); - pipe->pluginID = ID_PDS; - pipe->pluginData = 0x1100c; - 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 = genericUninstanceCB; - registerPDSPipe(pipe); - - // rwPDS_G3_MatfxUV2_GrpAtmPipeID - opipe = new ObjPipeline(PLATFORM_PS2); - opipe->pluginID = ID_PDS; - opipe->pluginData = 0x1100e; - opipe->groupPipeline = pipe; - registerPDSPipe(opipe); - - // RW World plugin - - // rwPDS_G3x_Generic_AtmPipeID - opipe = new ObjPipeline(PLATFORM_PS2); - opipe->pluginID = ID_PDS; - opipe->pluginData = 0x50001; - registerPDSPipe(opipe); - - // rwPDS_G3x_Skin_AtmPipeID - opipe = new ObjPipeline(PLATFORM_PS2); - opipe->pluginID = ID_PDS; - opipe->pluginData = 0x5000b; - registerPDSPipe(opipe); - - // rwPDS_G3xd_A4D_MatPipeID - pipe = new MatPipeline(PLATFORM_PS2); - pipe->pluginID = ID_PDS; - pipe->pluginData = 0x5002f; - pipe->attribs[0] = &attribXYZW; - pipe->attribs[1] = &attribUV; - pipe->attribs[2] = &attribNormal; - vertCount = 0x50; - pipe->setTriBufferSizes(3, vertCount); - pipe->vifOffset = pipe->inputStride*vertCount; - pipe->uninstanceCB = genericUninstanceCB; - pipe->preUninstCB = genericPreCB; - registerPDSPipe(pipe); - - // rwPDS_G3xd_A4DSkin_MatPipeID - pipe = new MatPipeline(PLATFORM_PS2); - pipe->pluginID = ID_PDS; - pipe->pluginData = 0x5003e; - pipe->attribs[0] = &attribXYZW; - pipe->attribs[1] = &attribUV; - pipe->attribs[2] = &attribNormal; - pipe->attribs[3] = &attribWeights; - vertCount = 0x30; - pipe->setTriBufferSizes(4, vertCount); - pipe->vifOffset = pipe->inputStride*vertCount; - pipe->instanceCB = skinInstanceCB; - pipe->uninstanceCB = genericUninstanceCB; - pipe->preUninstCB = genericPreCB; - pipe->postUninstCB = skinPostCB; - registerPDSPipe(pipe); -} - -} -} diff --git a/src/pipeline.cpp b/src/pipeline.cpp index e466762..691e9f5 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -7,7 +7,7 @@ #include "rwplg.h" #include "rwpipeline.h" #include "rwobjects.h" -#include "rwps2.h" +#include "ps2/rwps2.h" #define COLOR_ARGB(a,r,g,b) \ ((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) diff --git a/src/plugins.cpp b/src/plugins.cpp index 4bcdc95..fb85427 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -9,12 +9,12 @@ #include "rwpipeline.h" #include "rwobjects.h" #include "rwplugins.h" -#include "rwps2.h" -#include "rwps2plg.h" -#include "rwxbox.h" -#include "rwd3d8.h" -#include "rwd3d9.h" -#include "rwwdgl.h" +#include "ps2/rwps2.h" +#include "ps2/rwps2plg.h" +#include "d3d/rwxbox.h" +#include "d3d/rwd3d8.h" +#include "d3d/rwd3d9.h" +#include "gl/rwwdgl.h" #define PLUGIN_ID 2 diff --git a/src/ps2.cpp b/src/ps2.cpp deleted file mode 100644 index a2ea4f7..0000000 --- a/src/ps2.cpp +++ /dev/null @@ -1,1627 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwerror.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwengine.h" -#include "rwplugins.h" -#include "rwps2.h" -#include "rwps2plg.h" - -#define PLUGIN_ID 2 - -namespace rw { -namespace ps2 { - -void -initializePlatform(void) -{ - driver[PLATFORM_PS2].defaultPipeline = makeDefaultPipeline(); -} - -ObjPipeline *defaultObjPipe; -MatPipeline *defaultMatPipe; - -void* -destroyNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_PS2) - return object; - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - for(uint32 i = 0; i < header->numMeshes; i++) - delete[] header->instanceMeshes[i].data; - delete[] header->instanceMeshes; - delete header; - return object; -} - -Stream* -readNativeData(Stream *stream, int32, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_PS2){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - InstanceDataHeader *header = new InstanceDataHeader; - geometry->instData = header; - header->platform = PLATFORM_PS2; - assert(geometry->meshHeader != nil); - header->numMeshes = geometry->meshHeader->numMeshes; - header->instanceMeshes = new InstanceData[header->numMeshes]; - for(uint32 i = 0; i < header->numMeshes; i++){ - InstanceData *instance = &header->instanceMeshes[i]; - uint32 buf[2]; - stream->read(buf, 8); - instance->dataSize = buf[0]; - instance->arePointersFixed = buf[1]; -// TODO: force alignment - instance->data = new uint8[instance->dataSize]; -#ifdef RW_PS2 - uint32 a = (uint32)instance->data; - assert(a % 0x10 == 0); -#endif - stream->read(instance->data, instance->dataSize); - instance->material = geometry->meshHeader->mesh[i].material; -// sizedebug(instance); - } - return stream; -} - -Stream* -writeNativeData(Stream *stream, int32 len, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - writeChunkHeader(stream, ID_STRUCT, len-12); - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_PS2) - return stream; - stream->writeU32(PLATFORM_PS2); - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - for(uint32 i = 0; i < header->numMeshes; i++){ - InstanceData *instance = &header->instanceMeshes[i]; - if(instance->arePointersFixed == 2) - unfixDmaOffsets(instance); - uint32 buf[2]; - buf[0] = instance->dataSize; - buf[1] = instance->arePointersFixed; - stream->write(buf, 8); - stream->write(instance->data, instance->dataSize); - } - return stream; -} - -int32 -getSizeNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - int32 size = 16; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_PS2) - return 0; - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - for(uint32 i = 0; i < header->numMeshes; i++){ - InstanceData *instance = &header->instanceMeshes[i]; - size += 8; - size += instance->dataSize; - } - return size; -} - -void -registerNativeDataPlugin(void) -{ - Geometry::registerPlugin(0, ID_NATIVEDATA, - nil, destroyNativeData, nil); - Geometry::registerPluginStream(ID_NATIVEDATA, - readNativeData, - writeNativeData, - getSizeNativeData); -} - -#ifdef RW_PS2 -void -fixDmaOffsets(InstanceData *inst) -{ - if(inst->arePointersFixed) - return; - - uint32 base = (uint32)inst->data; - uint32 *tag = (uint32*)inst->data; - for(;;){ - switch(tag[0]&0x70000000){ - // DMAcnt - case 0x10000000: - // no need to fix - tag += (1+(tag[0]&0xFFFF))*4; - break; - - // DMAref - case 0x30000000: - // fix address and jump to next - tag[1] = base + tag[1]<<4; - tag += 4; - break; - - // DMAret - case 0x60000000: - // we're done - inst->arePointersFixed = 2; - return; - - default: - fprintf(stderr, "error: unknown DMAtag %X\n", tag[0]); - return; - } - } -} -#endif - -void -unfixDmaOffsets(InstanceData *inst) -{ - (void)inst; -#ifdef RW_PS2 - if(inst->arePointersFixed != 2) - return; - - uint32 base = (uint32)inst->data; - uint32 *tag = (uint32*)inst->data; - for(;;){ - switch(tag[0]&0x70000000){ - // DMAcnt - case 0x10000000: - // no need to unfix - tag += (1+(tag[0]&0xFFFF))*4; - break; - - // DMAref - case 0x30000000: - // unfix address and jump to next - tag[1] = (tag[1] - base)>>4; - tag += 4; - break; - - // DMAret - case 0x60000000: - // we're done - inst->arePointersFixed = 0; - return; - - default: - fprintf(stderr, "error: unknown DMAtag %X\n", tag[0]); - return; - } - } -#endif -} - -// Pipeline - -PipeAttribute attribXYZ = { - "XYZ", - AT_V3_32 -}; - -PipeAttribute attribXYZW = { - "XYZW", - AT_V4_32 -}; - -PipeAttribute attribUV = { - "UV", - AT_V2_32 -}; - -PipeAttribute attribUV2 = { - "UV2", - AT_V4_32 -}; - -PipeAttribute attribRGBA = { - "RGBA", - AT_V4_8 | AT_UNSGN -}; - -PipeAttribute attribNormal = { - "Normal", - AT_V3_8 // RW has V4_8 but uses V3_8, wtf? -}; - -PipeAttribute attribWeights = { - "Weights", - AT_V4_32 | AT_RW -}; - -static uint32 -attribSize(uint32 unpack) -{ - static uint32 size[] = { 32, 16, 8, 16 }; - return ((unpack>>26 & 3)+1)*size[unpack>>24 & 3]/8; -} - -#define QWC(x) (((x)+0xF)>>4) - -static uint32 -getBatchSize(MatPipeline *pipe, uint32 vertCount) -{ - PipeAttribute *a; - if(vertCount == 0) - return 0; - uint32 size = 1; // ITOP &c. at the end - for(uint i = 0; i < nelem(pipe->attribs); i++) - if((a = pipe->attribs[i]) && (a->attrib & AT_RW) == 0){ - size++; // UNPACK &c. - size += QWC(vertCount*attribSize(a->attrib)); - } - return size; -} - -uint32* -instanceXYZ(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n) -{ - uint16 j; - uint32 *d = (uint32*)g->morphTargets[0].vertices; - for(uint32 i = idx; i < idx+n; i++){ - j = m->indices[i]; - *p++ = d[j*3+0]; - *p++ = d[j*3+1]; - *p++ = d[j*3+2]; - } - while((uintptr)p % 0x10) - *p++ = 0; - return p; -} - -uint32* -instanceXYZW(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n) -{ - uint16 j; - uint32 *d = (uint32*)g->morphTargets[0].vertices; - int8 *adcbits = getADCbitsForMesh(g, m); - for(uint32 i = idx; i < idx+n; i++){ - j = m->indices[i]; - *p++ = d[j*3+0]; - *p++ = d[j*3+1]; - *p++ = d[j*3+2]; - *p++ = adcbits && adcbits[i] ? 0x8000 : 0; - } - // don't need to pad - return p; -} - -uint32* -instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n) -{ - uint16 j; - uint32 *d = (uint32*)g->texCoords[0]; - if((g->geoflags & Geometry::TEXTURED) || - (g->geoflags & Geometry::TEXTURED2)) - for(uint32 i = idx; i < idx+n; i++){ - j = m->indices[i]; - *p++ = d[j*2+0]; - *p++ = d[j*2+1]; - } - else - for(uint32 i = idx; i < idx+n; i++){ - *p++ = 0; - *p++ = 0; - } - while((uintptr)p % 0x10) - *p++ = 0; - return p; -} - -uint32* -instanceUV2(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n) -{ - uint16 j; - uint32 *d0 = (uint32*)g->texCoords[0]; - uint32 *d1 = (uint32*)g->texCoords[1]; - for(uint32 i = idx; i < idx+n; i++){ - j = m->indices[i]; - if(g->numTexCoordSets > 0){ - *p++ = d0[j*2+0]; - *p++ = d0[j*2+1]; - }else{ - *p++ = 0; - *p++ = 0; - } - if(g->numTexCoordSets > 1){ - *p++ = d1[j*2+0]; - *p++ = d1[j*2+1]; - }else{ - *p++ = 0; - *p++ = 0; - } - } - while((uintptr)p % 0x10) - *p++ = 0; - return p; -} - -uint32* -instanceRGBA(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n) -{ - uint16 j; - uint32 *d = (uint32*)g->colors; - if((g->geoflags & Geometry::PRELIT)) - for(uint32 i = idx; i < idx+n; i++){ - j = m->indices[i]; - *p++ = d[j]; - } - else - for(uint32 i = idx; i < idx+n; i++) - *p++ = 0xFF000000; - while((uintptr)p % 0x10) - *p++ = 0; - return p; -} - -uint32* -instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n) -{ - uint16 j; - float *d = g->morphTargets[0].normals; - uint8 *p = (uint8*)wp; - if((g->geoflags & Geometry::NORMALS)) - for(uint32 i = idx; i < idx+n; i++){ - j = m->indices[i]; - *p++ = d[j*3+0]*127.0f; - *p++ = d[j*3+1]*127.0f; - *p++ = d[j*3+2]*127.0f; - } - else - for(uint32 i = idx; i < idx+n; i++){ - *p++ = 0; - *p++ = 0; - *p++ = 0; - } - while((uintptr)p % 0x10) - *p++ = 0; - return (uint32*)p; -} - -MatPipeline::MatPipeline(uint32 platform) - : rw::Pipeline(platform), instanceCB(nil), uninstanceCB(nil), - preUninstCB(nil), postUninstCB(nil) -{ - for(int i = 0; i < 10; i++) - this->attribs[i] = nil; -} - -void -MatPipeline::dump(void) -{ - if(this->platform != PLATFORM_PS2) - return; - PipeAttribute *a; - printf("%x %x\n", this->pluginID, this->pluginData); - for(uint i = 0; i < nelem(this->attribs); i++){ - a = this->attribs[i]; - if(a) - printf("%d %s: %x\n", i, a->name, a->attrib); - } - printf("stride: %x\n", this->inputStride); - printf("vertcount: %x\n", this->vifOffset/this->inputStride); - printf("triSCount: %x\n", this->triStripCount); - printf("triLCount: %x\n", this->triListCount); - printf("vifOffset: %x\n", this->vifOffset); - printf("\n"); -} - -void -MatPipeline::setTriBufferSizes(uint32 inputStride, uint32 stripCount) -{ - this->inputStride = inputStride; - this->triListCount = stripCount/12*12; - PipeAttribute *a; - for(uint i = 0; i < nelem(this->attribs); i++){ - a = this->attribs[i]; - if(a && a->attrib & AT_RW) - goto brokenout; - } - this->triStripCount = stripCount/4*4; - return; -brokenout: - this->triStripCount = (stripCount-2)/4*4+2; -} - -// Instance format: -// no broken out clusters -// ====================== -// DMAret [FLUSH; MSKPATH3 || FLUSH; FLUSH] { -// foreach batch { -// foreach cluster { -// MARK/0; STMOD; STCYCL; UNPACK -// unpack-data -// } -// ITOP; MSCALF/MSCNT; // if first/not-first -// 0/FLUSH; 0/MSKPATH3 || 0/FLUSH; 0/FLUSH // if not-last/last -// } -// } -// -// broken out clusters -// =================== -// foreach batch { -// foreach broken out cluster { -// DMAref [STCYCL; UNPACK] -> pointer into unpack-data -// DMAcnt (empty) -// } -// DMAcnt/ret { -// foreach cluster { -// MARK/0; STMOD; STCYCL; UNPACK -// unpack-data -// } -// ITOP; MSCALF/MSCNT; // if first/not-first -// 0/FLUSH; 0/MSKPATH3 || 0/FLUSH; 0/FLUSH // if not-last/last -// } -// } -// unpack-data for broken out clusters - -uint32 markcnt = 0; - -enum { - DMAcnt = 0x10000000, - DMAref = 0x30000000, - DMAret = 0x60000000, - - VIF_NOP = 0, - VIF_STCYCL = 0x01000100, // WL = 1 - VIF_ITOP = 0x04000000, - VIF_STMOD = 0x05000000, - VIF_MSKPATH3 = 0x06000000, - VIF_MARK = 0x07000000, - VIF_FLUSH = 0x11000000, - VIF_MSCALF = 0x15000000, - VIF_MSCNT = 0x17000000, -}; - -struct InstMeshInfo -{ - uint32 numAttribs, numBrokenAttribs; - uint32 batchVertCount, lastBatchVertCount; - uint32 numBatches; - uint32 batchSize, lastBatchSize; - uint32 size; // size of DMA chain without broken out data - uint32 size2; // size of broken out data - uint32 vertexSize; - uint32 attribPos[10]; -}; - -InstMeshInfo -getInstMeshInfo(MatPipeline *pipe, Geometry *g, Mesh *m) -{ - PipeAttribute *a; - InstMeshInfo im; - im.numAttribs = 0; - im.numBrokenAttribs = 0; - im.vertexSize = 0; - for(uint i = 0; i < nelem(pipe->attribs); i++) - if(a = pipe->attribs[i]) - if(a->attrib & AT_RW) - im.numBrokenAttribs++; - else{ - im.vertexSize += attribSize(a->attrib); - im.numAttribs++; - } - if(g->meshHeader->flags == MeshHeader::TRISTRIP){ - im.numBatches = (m->numIndices-2) / (pipe->triStripCount-2); - im.batchVertCount = pipe->triStripCount; - im.lastBatchVertCount = (m->numIndices-2) % (pipe->triStripCount-2); - if(im.lastBatchVertCount){ - im.numBatches++; - im.lastBatchVertCount += 2; - } - }else{ // TRILIST; nothing else supported yet - im.numBatches = (m->numIndices+pipe->triListCount-1) / - pipe->triListCount; - im.batchVertCount = pipe->triListCount; - im.lastBatchVertCount = m->numIndices % pipe->triListCount; - } - if(im.lastBatchVertCount == 0) - im.lastBatchVertCount = im.batchVertCount; - - im.batchSize = getBatchSize(pipe, im.batchVertCount); - im.lastBatchSize = getBatchSize(pipe, im.lastBatchVertCount); - if(im.numBrokenAttribs == 0) - im.size = 1 + im.batchSize*(im.numBatches-1) + im.lastBatchSize; - else - im.size = 2*im.numBrokenAttribs*im.numBatches + - (1+im.batchSize)*(im.numBatches-1) + 1+im.lastBatchSize; - - /* figure out size and addresses of broken out sections */ - im.size2 = 0; - for(uint i = 0; i < nelem(im.attribPos); i++) - if((a = pipe->attribs[i]) && a->attrib & AT_RW){ - im.attribPos[i] = im.size2 + im.size; - im.size2 += QWC(m->numIndices*attribSize(a->attrib)); - } - - return im; -} - -void -MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m) -{ - PipeAttribute *a; - InstMeshInfo im = getInstMeshInfo(this, g, m); - - inst->dataSize = (im.size+im.size2)<<4; - inst->arePointersFixed = im.numBrokenAttribs == 0; - // TODO: force alignment - inst->data = new uint8[inst->dataSize]; - - /* make array of addresses of broken out sections */ - uint8 *datap[nelem(this->attribs)]; - uint8 **dp = datap; - for(uint i = 0; i < nelem(this->attribs); i++) - if((a = this->attribs[i]) && a->attrib & AT_RW) - dp[i] = inst->data + im.attribPos[i]*0x10; - - // TODO: not sure if this is correct - uint32 msk_flush = rw::version >= 0x35000 ? VIF_FLUSH : VIF_MSKPATH3; - - uint32 idx = 0; - uint32 *p = (uint32*)inst->data; - if(im.numBrokenAttribs == 0){ - *p++ = DMAret | im.size-1; - *p++ = 0; - *p++ = VIF_FLUSH; - *p++ = msk_flush; - } - for(uint32 j = 0; j < im.numBatches; j++){ - uint32 nverts, bsize; - if(j < im.numBatches-1){ - bsize = im.batchSize; - nverts = im.batchVertCount; - }else{ - bsize = im.lastBatchSize; - nverts = im.lastBatchVertCount; - } - for(uint i = 0; i < nelem(this->attribs); i++) - if((a = this->attribs[i]) && a->attrib & AT_RW){ - uint32 atsz = attribSize(a->attrib); - *p++ = DMAref | QWC(nverts*atsz); - *p++ = im.attribPos[i]; - *p++ = VIF_STCYCL | this->inputStride; - // Round up nverts so UNPACK will fit exactly into the DMA packet - // (can't pad with zeroes in broken out sections). - // TODO: check for clash with vifOffset somewhere - *p++ = (a->attrib&0xFF004000) - | 0x8000 | (QWC(nverts*atsz)<<4)/atsz << 16 | i; // UNPACK - - *p++ = DMAcnt; - *p++ = 0x0; - *p++ = VIF_NOP; - *p++ = VIF_NOP; - - im.attribPos[i] += g->meshHeader->flags == 1 ? - QWC((im.batchVertCount-2)*atsz) : - QWC(im.batchVertCount*atsz); - } - if(im.numBrokenAttribs){ - *p++ = (j < im.numBatches-1 ? DMAcnt : DMAret) | bsize; - *p++ = 0x0; - *p++ = VIF_NOP; - *p++ = VIF_NOP; - } - - for(uint i = 0; i < nelem(this->attribs); i++) - if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){ - if(rw::version >= 0x35000) - *p++ = VIF_NOP; - else - *p++ = VIF_MARK | markcnt++; - *p++ = VIF_STMOD; - *p++ = VIF_STCYCL | this->inputStride; - *p++ = (a->attrib&0xFF004000) - | 0x8000 | nverts << 16 | i; // UNPACK - - if(a == &attribXYZ) - p = instanceXYZ(p, g, m, idx, nverts); - else if(a == &attribXYZW) - p = instanceXYZW(p, g, m, idx, nverts); - else if(a == &attribUV) - p = instanceUV(p, g, m, idx, nverts); - else if(a == &attribUV2) - p = instanceUV2(p, g, m, idx, nverts); - else if(a == &attribRGBA) - p = instanceRGBA(p, g, m, idx, nverts); - else if(a == &attribNormal) - p = instanceNormal(p, g, m, idx, nverts); - } - idx += g->meshHeader->flags == 1 - ? im.batchVertCount-2 : im.batchVertCount; - - *p++ = VIF_ITOP | nverts; - *p++ = j == 0 ? VIF_MSCALF : VIF_MSCNT; - if(j < im.numBatches-1){ - *p++ = VIF_NOP; - *p++ = VIF_NOP; - }else{ - *p++ = VIF_FLUSH; - *p++ = msk_flush; - } - } - - if(this->instanceCB) - this->instanceCB(this, g, m, datap); -} - -uint8* -MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]) -{ - PipeAttribute *a; - InstMeshInfo im = getInstMeshInfo(this, g, m); - - uint8 *raw = im.vertexSize*m->numIndices ? - new uint8[im.vertexSize*m->numIndices] : nil; - uint8 *dp = raw; - for(uint i = 0; i < nelem(this->attribs); i++) - if(a = this->attribs[i]) - if(a->attrib & AT_RW){ - data[i] = inst->data + im.attribPos[i]*0x10; - }else{ - data[i] = dp; - dp += m->numIndices*attribSize(a->attrib); - } - - uint8 *datap[nelem(this->attribs)]; - memcpy(datap, data, sizeof(datap)); - - uint32 overlap = g->meshHeader->flags == 1 ? 2 : 0; - uint32 *p = (uint32*)inst->data; - if(im.numBrokenAttribs == 0) - p += 4; - for(uint32 j = 0; j < im.numBatches; j++){ - uint32 nverts = j < im.numBatches-1 ? im.batchVertCount : - im.lastBatchVertCount; - for(uint i = 0; i < nelem(this->attribs); i++) - if((a = this->attribs[i]) && a->attrib & AT_RW) - p += 8; - if(im.numBrokenAttribs) - p += 4; - for(uint i = 0; i < nelem(this->attribs); i++) - if((a = this->attribs[i]) && (a->attrib & AT_RW) == 0){ - uint32 asz = attribSize(a->attrib); - p += 4; - if((p[-1] & 0xff004000) != a->attrib){ - fprintf(stderr, "unexpected unpack: %08x %08x\n", p[-1], a->attrib); - assert(0 && "unexpected unpack\n"); - } - memcpy(datap[i], p, asz*nverts); - datap[i] += asz*(nverts-overlap); - p += QWC(asz*nverts)*4; - } - p += 4; - } - return raw; -} - -static void -objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if(geo->geoflags & Geometry::NATIVE) - return; - InstanceDataHeader *header = new InstanceDataHeader; - geo->instData = header; - header->platform = PLATFORM_PS2; - assert(geo->meshHeader != nil); - header->numMeshes = geo->meshHeader->numMeshes; - header->instanceMeshes = new InstanceData[header->numMeshes]; - for(uint32 i = 0; i < header->numMeshes; i++){ - Mesh *mesh = &geo->meshHeader->mesh[i]; - InstanceData *instance = &header->instanceMeshes[i]; - - MatPipeline *m; - m = pipe->groupPipeline ? - pipe->groupPipeline : - (MatPipeline*)mesh->material->pipeline; - if(m == nil) - m = defaultMatPipe; - m->instance(geo, instance, mesh); - instance->material = mesh->material; - } - geo->geoflags |= Geometry::NATIVE; -} - -static void -printVertCounts(InstanceData *inst, int flag) -{ - uint32 *d = (uint32*)inst->data; - uint32 id = 0; - if(inst->material->pipeline) - id = inst->material->pipeline->pluginData; - int stride; - if(inst->arePointersFixed){ - d += 4; - while(d[3]&0x60000000){ // skip UNPACKs - stride = d[2]&0xFF; - d += 4 + 4*QWC(attribSize(d[3])*((d[3]>>16)&0xFF)); - } - if(d[2] == 0) - printf("ITOP %x %d (%d) %x\n", *d, stride, flag, id); - }else{ - while((*d&0x70000000) == 0x30000000){ - stride = d[2]&0xFF; - printf("UNPACK %x %d (%d) %x\n", d[3], stride, flag, id); - d += 8; - } - if((*d&0x70000000) == 0x10000000){ - d += (*d&0xFFFF)*4; - printf("ITOP %x %d (%d) %x\n", *d, stride, flag, id); - } - } -} - -static void -objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if((geo->geoflags & Geometry::NATIVE) == 0) - return; - assert(geo->instData != nil); - assert(geo->instData->platform == PLATFORM_PS2); - InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; - // highest possible number of vertices - geo->numVertices = geo->meshHeader->totalIndices; - geo->geoflags &= ~Geometry::NATIVE; - geo->allocateData(); - geo->meshHeader->allocateIndices(); - uint32 *flags = new uint32[geo->numVertices]; - memset(flags, 0, 4*geo->numVertices); - memset(geo->meshHeader->mesh[0].indices, 0, 2*geo->meshHeader->totalIndices); - for(uint32 i = 0; i < header->numMeshes; i++){ - Mesh *mesh = &geo->meshHeader->mesh[i]; - MatPipeline *m; - m = pipe->groupPipeline ? - pipe->groupPipeline : - (MatPipeline*)mesh->material->pipeline; - if(m == nil) m = defaultMatPipe; - if(m->preUninstCB) m->preUninstCB(m, geo); - } - geo->numVertices = 0; - for(uint32 i = 0; i < header->numMeshes; i++){ - Mesh *mesh = &geo->meshHeader->mesh[i]; - InstanceData *instance = &header->instanceMeshes[i]; - MatPipeline *m; - m = pipe->groupPipeline ? - pipe->groupPipeline : - (MatPipeline*)mesh->material->pipeline; - if(m == nil) m = defaultMatPipe; - - uint8 *data[nelem(m->attribs)] = { nil }; - uint8 *raw = m->collectData(geo, instance, mesh, data); - assert(m->uninstanceCB); - m->uninstanceCB(m, geo, flags, mesh, data); - if(raw) delete[] raw; - } - for(uint32 i = 0; i < header->numMeshes; i++){ - Mesh *mesh = &geo->meshHeader->mesh[i]; - MatPipeline *m; - m = pipe->groupPipeline ? - pipe->groupPipeline : - (MatPipeline*)mesh->material->pipeline; - if(m == nil) m = defaultMatPipe; - if(m->postUninstCB) m->postUninstCB(m, geo); - } - - int8 *bits = getADCbits(geo); - geo->generateTriangles(bits); - delete[] flags; - destroyNativeData(geo, 0, 0); - geo->instData = nil; -/* - for(uint32 i = 0; i < header->numMeshes; i++){ - Mesh *mesh = &geo->meshHeader->mesh[i]; - InstanceData *instance = &header->instanceMeshes[i]; -// printf("numIndices: %d\n", mesh->numIndices); -// printDMA(instance); - printVertCounts(instance, geo->meshHeader->flags); - } -*/ -} - -ObjPipeline::ObjPipeline(uint32 platform) - : rw::ObjPipeline(platform) -{ - this->groupPipeline = nil; - this->impl.instance = objInstance; - this->impl.uninstance = objUninstance; -} - -/* -int32 -findVertex(Geometry *g, uint32 flags[], uint32 mask, Vertex *v) -{ - float32 *verts = g->morphTargets[0].vertices; - float32 *tex = g->texCoords[0]; - float32 *tex1 = g->texCoords[1]; - float32 *norms = g->morphTargets[0].normals; - uint8 *cols = g->colors; - - for(int32 i = 0; i < g->numVertices; i++){ - if(mask & flags[i] & 0x1 && - !(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2])) - goto cont; - if(mask & flags[i] & 0x10 && - !(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2])) - goto cont; - if(mask & flags[i] & 0x100 && - !(cols[0] == v->c[0] && cols[1] == v->c[1] && cols[2] == v->c[2] && cols[3] == v->c[3])) - goto cont; - if(mask & flags[i] & 0x1000 && - !(tex[0] == v->t[0] && tex[1] == v->t[1])) - goto cont; - if(mask & flags[i] & 0x2000 && - !(tex1[0] == v->t1[0] && tex1[1] == v->t1[1])) - goto cont; - return i; - cont: - verts += 3; - tex += 2; - tex1 += 2; - norms += 3; - cols += 4; - } - return -1; -} -*/ - -void -insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v) -{ - if(mask & 0x1) - memcpy(&geo->morphTargets[0].vertices[i*3], v->p, 12); - if(mask & 0x10) - memcpy(&geo->morphTargets[0].normals[i*3], v->n, 12); - if(mask & 0x100) - memcpy(&geo->colors[i*4], v->c, 4); - if(mask & 0x1000) - memcpy(&geo->texCoords[0][i*2], v->t, 8); - if(mask & 0x2000) - memcpy(&geo->texCoords[1][i*2], v->t1, 8); -} - -void -genericPreCB(MatPipeline *pipe, Geometry *geo) -{ - PipeAttribute *a; - for(int32 i = 0; i < nelem(pipe->attribs); i++) - if(a = pipe->attribs[i]) - if(a == &attribXYZW){ - allocateADC(geo); - break; - } - skinPreCB(pipe, geo); -} - -void -genericUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]) -{ - float32 *xyz = nil, *xyzw = nil; - float32 *uv = nil, *uv2 = nil; - uint8 *rgba = nil; - int8 *normals = nil; - uint32 *weights = nil; - int8 *adc = nil; - Skin *skin = nil; - if(skinGlobals.offset) - skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); - - PipeAttribute *a; - for(int32 i = 0; i < nelem(pipe->attribs); i++) - if(a = pipe->attribs[i]){ - if(a == &attribXYZ) xyz = (float32*)data[i]; - else if(a == &attribXYZW) xyzw = (float32*)data[i]; - else if(a == &attribUV) uv = (float32*)data[i]; - else if(a == &attribUV2) uv2 = (float32*)data[i]; - else if(a == &attribRGBA) rgba = data[i]; - else if(a == &attribNormal) normals = (int8*)data[i]; - else if(a == &attribWeights) weights = (uint32*)data[i]; - } - - uint32 mask = 0x1; // vertices - if(normals && geo->geoflags & Geometry::NORMALS) - mask |= 0x10; - if(rgba && geo->geoflags & Geometry::PRELIT) - mask |= 0x100; - if((uv || uv2) && geo->numTexCoordSets > 0) - mask |= 0x1000; - if(uv2 && geo->numTexCoordSets > 1) - mask |= 0x2000; - if(weights && skin) - mask |= 0x10000; - if(xyzw) - adc = getADCbitsForMesh(geo, mesh); - - Vertex v; - for(uint32 i = 0; i < mesh->numIndices; i++){ - if(mask & 0x1) - memcpy(&v.p, xyz ? xyz : xyzw, 12); - if(mask & 0x10){ - // TODO: figure out scaling :/ - v.n[0] = normals[0]/128.0f; - v.n[1] = normals[1]/128.0f; - v.n[2] = normals[2]/128.0f; - } - if(mask & 0x100) - memcpy(&v.c, rgba, 4); - if(mask & 0x1000) - memcpy(&v.t, uv ? uv : uv2, 8); - if(mask & 0x2000) - memcpy(&v.t1, uv2 + 2, 8); - if(mask & 0x10000) - for(int j = 0; j < 4; j++){ - ((uint32*)v.w)[j] = weights[j] & ~0x3FF; - v.i[j] = (weights[j] & 0x3FF) >> 2; - if(v.i[j]) v.i[j]--; - if(v.w[j] == 0.0f) v.i[j] = 0; - } - int32 idx = findVertexSkin(geo, flags, mask, &v); - if(idx < 0) - idx = geo->numVertices++; - mesh->indices[i] = idx; - if(adc) - adc[i] = xyzw[3] != 0.0f; - flags[idx] = mask; - insertVertexSkin(geo, idx, mask, &v); - if(xyz) xyz += 3; - if(xyzw) xyzw += 4; - if(uv) uv += 2; - if(uv2) uv2 += 4; - rgba += 4; - normals += 3; - weights += 4; - } -} - -/* -void -defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]) -{ - float32 *verts = (float32*)data[AT_XYZ]; - float32 *texcoords = (float32*)data[AT_UV]; - uint8 *colors = (uint8*)data[AT_RGBA]; - int8 *norms = (int8*)data[AT_NORMAL]; - uint32 mask = 0x1; // vertices - if(geo->geoflags & Geometry::NORMALS) - mask |= 0x10; - if(geo->geoflags & Geometry::PRELIT) - mask |= 0x100; - for(int32 i = 0; i < geo->numTexCoordSets; i++) - mask |= 0x1000 << i; - int numUV = pipe->attribs[AT_UV] == &attribUV2 ? 2 : 1; - - Vertex v; - for(uint32 i = 0; i < mesh->numIndices; i++){ - if(mask & 0x1) - memcpy(&v.p, verts, 12); - if(mask & 0x10){ - v.n[0] = norms[0]/127.0f; - v.n[1] = norms[1]/127.0f; - v.n[2] = norms[2]/127.0f; - } - if(mask & 0x100){ - memcpy(&v.c, colors, 4); - //v.c[3] = 0xFF; - } - if(mask & 0x1000) - memcpy(&v.t, texcoords, 8); - if(mask & 0x2000) - memcpy(&v.t1, texcoords+2, 8); - - int32 idx = findVertex(geo, flags, mask, &v); - if(idx < 0) - idx = geo->numVertices++; - mesh->indices[i] = idx; - flags[idx] = mask; - insertVertex(geo, idx, mask, &v); - verts += 3; - texcoords += 2*numUV; - colors += 4; - norms += 3; - } -} -*/ - -#undef QWC - -ObjPipeline* -makeDefaultPipeline(void) -{ - if(defaultMatPipe == nil){ - MatPipeline *pipe = new MatPipeline(PLATFORM_PS2); - pipe->attribs[AT_XYZ] = &attribXYZ; - pipe->attribs[AT_UV] = &attribUV; - pipe->attribs[AT_RGBA] = &attribRGBA; - pipe->attribs[AT_NORMAL] = &attribNormal; - uint32 vertCount = MatPipeline::getVertCount(VU_Lights,4,3,2); - pipe->setTriBufferSizes(4, vertCount); - pipe->vifOffset = pipe->inputStride*vertCount; - pipe->uninstanceCB = genericUninstanceCB; - defaultMatPipe = pipe; - } - - if(defaultObjPipe == nil){ - ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); - defaultObjPipe = opipe; - } - return defaultObjPipe; -} - -ObjPipeline* -makeSkinPipeline(void) -{ - MatPipeline *pipe = new MatPipeline(PLATFORM_PS2); - pipe->pluginID = ID_SKIN; - pipe->pluginData = 1; - 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 = genericUninstanceCB; - pipe->preUninstCB = skinPreCB; - pipe->postUninstCB = skinPostCB; - - ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); - opipe->pluginID = ID_SKIN; - opipe->pluginData = 1; - opipe->groupPipeline = pipe; - return opipe; -} - -ObjPipeline* -makeMatFXPipeline(void) -{ - MatPipeline *pipe = new MatPipeline(PLATFORM_PS2); - pipe->pluginID = ID_MATFX; - pipe->pluginData = 0; - pipe->attribs[AT_XYZ] = &attribXYZ; - pipe->attribs[AT_UV] = &attribUV; - pipe->attribs[AT_RGBA] = &attribRGBA; - pipe->attribs[AT_NORMAL] = &attribNormal; - uint32 vertCount = MatPipeline::getVertCount(0x3C5, 4, 3, 3); - pipe->setTriBufferSizes(4, vertCount); - pipe->vifOffset = pipe->inputStride*vertCount; - pipe->uninstanceCB = genericUninstanceCB; - - ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2); - opipe->pluginID = ID_MATFX; - opipe->pluginData = 0; - opipe->groupPipeline = pipe; - return opipe; -} - -// Skin - -Stream* -readNativeSkin(Stream *stream, int32, void *object, int32 offset) -{ - uint8 header[4]; - Geometry *geometry = (Geometry*)object; - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_PS2){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - stream->read(header, 4); - Skin *skin = new Skin; - *PLUGINOFFSET(Skin*, geometry, offset) = skin; - - // numUsedBones and numWeights appear in/after 34003 but not in/before 33002 - // (probably rw::version >= 0x34000) - bool oldFormat = header[1] == 0; - - // Use numBones for numUsedBones to allocate data - if(oldFormat) - skin->init(header[0], header[0], 0); - else - skin->init(header[0], header[1], 0); - skin->numWeights = header[2]; - - if(!oldFormat) - stream->read(skin->usedBones, skin->numUsedBones); - if(skin->numBones) - stream->read(skin->inverseMatrices, skin->numBones*64); - - // dummy data in case we need to write data in the new format - if(oldFormat){ - skin->numWeights = 4; - for(int32 i = 0; i < skin->numUsedBones; i++) - skin->usedBones[i] = i; - } - - if(!oldFormat) - // last 3 ints are split data as in the other formats - // TODO: what are the other 4? - stream->seek(7*4); - return stream; -} - -Stream* -writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset) -{ - uint8 header[4]; - - writeChunkHeader(stream, ID_STRUCT, len-12); - stream->writeU32(PLATFORM_PS2); - Skin *skin = *PLUGINOFFSET(Skin*, object, offset); - // not sure which version introduced the new format - bool oldFormat = version < 0x34000; - header[0] = skin->numBones; - if(oldFormat){ - header[1] = 0; - header[2] = 0; - }else{ - header[1] = skin->numUsedBones; - header[2] = skin->numWeights; - } - header[3] = 0; - stream->write(header, 4); - - if(!oldFormat) - stream->write(skin->usedBones, skin->numUsedBones); - stream->write(skin->inverseMatrices, skin->numBones*64); - if(!oldFormat){ - uint32 buffer[7] = { 0, 0, 0, 0, 0, 0, 0 }; - stream->write(buffer, 7*4); - } - return stream; -} - -int32 -getSizeNativeSkin(void *object, int32 offset) -{ - Skin *skin = *PLUGINOFFSET(Skin*, object, offset); - if(skin == nil) - return -1; - int32 size = 12 + 4 + 4 + skin->numBones*64; - // not sure which version introduced the new format - if(version >= 0x34000) - size += skin->numUsedBones + 16 + 12; - return size; -} - -void -instanceSkinData(Geometry*, Mesh *m, Skin *skin, uint32 *data) -{ - uint16 j; - float32 *weights = (float32*)data; - uint32 *indices = data; - for(uint32 i = 0; i < m->numIndices; i++){ - j = m->indices[i]; - for(int32 k = 0; k < 4; k++){ - *weights++ = skin->weights[j*4+k]; - *indices &= ~0x3FF; - *indices++ |= skin->indices[j*4+k] && skin->weights[j*4+k] ? - (skin->indices[j*4+k]+1) << 2 : 0; - } - } -} - -void -skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data) -{ - Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset); - if(skin == nil) - return; - instanceSkinData(g, m, skin, (uint32*)data[4]); -} - -// TODO: call base function perhaps? -int32 -findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v) -{ - Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset); - float32 *wghts = nil; - uint8 *inds = nil; - if(skin){ - wghts = skin->weights; - inds = skin->indices; - } - - float32 *verts = g->morphTargets[0].vertices; - float32 *tex = g->texCoords[0]; - float32 *tex1 = g->texCoords[1]; - float32 *norms = g->morphTargets[0].normals; - uint8 *cols = g->colors; - - for(int32 i = 0; i < g->numVertices; i++){ - uint32 flag = flags ? flags[i] : ~0; - if(mask & flag & 0x1 && - !(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2])) - goto cont; - if(mask & flag & 0x10 && - !(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2])) - goto cont; - if(mask & flag & 0x100 && - !(cols[0] == v->c[0] && cols[1] == v->c[1] && cols[2] == v->c[2] && cols[3] == v->c[3])) - goto cont; - if(mask & flag & 0x1000 && - !(tex[0] == v->t[0] && tex[1] == v->t[1])) - goto cont; - if(mask & flag & 0x2000 && - !(tex1[0] == v->t1[0] && tex1[1] == v->t1[1])) - goto cont; - if(mask & flag & 0x10000 && - !(wghts[0] == v->w[0] && wghts[1] == v->w[1] && - wghts[2] == v->w[2] && wghts[3] == v->w[3] && - inds[0] == v->i[0] && inds[1] == v->i[1] && - inds[2] == v->i[2] && inds[3] == v->i[3])) - goto cont; - return i; - cont: - verts += 3; - tex += 2; - norms += 3; - cols += 4; - wghts += 4; - inds += 4; - } - return -1; -} - -void -insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v) -{ - Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); - insertVertex(geo, i, mask, v); - if(mask & 0x10000){ - memcpy(&skin->weights[i*4], v->w, 16); - memcpy(&skin->indices[i*4], v->i, 4); - } -} - -/* -void -skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]) -{ - float32 *verts = (float32*)data[AT_XYZ]; - float32 *texcoords = (float32*)data[AT_UV]; - uint8 *colors = (uint8*)data[AT_RGBA]; - int8 *norms = (int8*)data[AT_NORMAL]; - uint32 *wghts = (uint32*)data[AT_NORMAL+1]; - uint32 mask = 0x1; // vertices - if(geo->geoflags & Geometry::NORMALS) - mask |= 0x10; - if(geo->geoflags & Geometry::PRELIT) - mask |= 0x100; - if(geo->numTexCoordSets > 0) - mask |= 0x1000; - mask |= 0x10000; - - Vertex v; - for(uint32 i = 0; i < mesh->numIndices; i++){ - if(mask & 0x1) - memcpy(&v.p, verts, 12); - if(mask & 0x10){ - v.n[0] = norms[0]/127.0f; - v.n[1] = norms[1]/127.0f; - v.n[2] = norms[2]/127.0f; - } - if(mask & 0x100) - memcpy(&v.c, colors, 4); - if(mask & 0x1000) - memcpy(&v.t, texcoords, 8); - for(int j = 0; j < 4; j++){ - ((uint32*)v.w)[j] = wghts[j] & ~0x3FF; - v.i[j] = (wghts[j] & 0x3FF) >> 2; - if(v.i[j]) v.i[j]--; - if(v.w[j] == 0.0f) v.i[j] = 0; - } - int32 idx = findVertexSkin(geo, flags, mask, &v); - if(idx < 0) - idx = geo->numVertices++; - mesh->indices[i] = idx; - flags[idx] = mask; - insertVertexSkin(geo, idx, mask, &v); - verts += 3; - texcoords += 2; - colors += 4; - norms += 3; - wghts += 4; - } -} -*/ - -void -skinPreCB(MatPipeline*, Geometry *geo) -{ - Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); - if(skin == nil) - return; - uint8 *data = skin->data; - float *invMats = skin->inverseMatrices; - // meshHeader->totalIndices is highest possible number of vertices again - skin->init(skin->numBones, skin->numBones, geo->meshHeader->totalIndices); - memcpy(skin->inverseMatrices, invMats, skin->numBones*64); - delete[] data; -} - -void -skinPostCB(MatPipeline*, Geometry *geo) -{ - Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); - if(skin){ - skin->findNumWeights(geo->numVertices); - skin->findUsedBones(geo->numVertices); - } -} - -// ADC - -int32 adcOffset; - -int8* -getADCbits(Geometry *geo) -{ - int8 *bits = nil; - if(adcOffset){ - ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset); - if(adc->adcFormatted) - bits = adc->adcBits; - } - return bits; -} - -int8* -getADCbitsForMesh(Geometry *geo, Mesh *mesh) -{ - int8 *bits = getADCbits(geo); - if(bits == nil) - return nil; - int32 n = mesh - geo->meshHeader->mesh; - for(int32 i = 0; i < n; i++) - bits += geo->meshHeader->mesh[i].numIndices; - return bits; -} - -// TODO -void -convertADC(Geometry*) -{ -} - -// Not optimal but works -void -unconvertADC(Geometry *g) -{ - ADCData *adc = PLUGINOFFSET(ADCData, g, adcOffset); - if(!adc->adcFormatted) - return; - int8 *b = adc->adcBits; - MeshHeader *h = new MeshHeader; - h->flags = g->meshHeader->flags; // should be tristrip - h->numMeshes = g->meshHeader->numMeshes; - h->mesh = new Mesh[h->numMeshes]; - Mesh *oldm = g->meshHeader->mesh; - Mesh *newm = h->mesh; - h->totalIndices = 0; - for(int32 i = 0; i < h->numMeshes; i++){ - newm->material = oldm->material; - newm->numIndices = oldm->numIndices; - for(uint32 j = 0; j < oldm->numIndices; j++) - if(*b++) - newm->numIndices += 2; - h->totalIndices += newm->numIndices; - newm++; - oldm++; - } - h->allocateIndices(); - b = adc->adcBits; - oldm = g->meshHeader->mesh; - newm = h->mesh; - for(int32 i = 0; i < h->numMeshes; i++){ - int32 n = 0; - for(uint32 j = 0; j < oldm->numIndices; j++){ - if(*b++){ - newm->indices[n++] = oldm->indices[j-1]; - newm->indices[n++] = oldm->indices[j-1]; - } - newm->indices[n++] = oldm->indices[j]; - } - newm++; - oldm++; - } - delete g->meshHeader; - g->meshHeader = h; - adc->adcFormatted = 0; - delete[] adc->adcBits; - adc->adcBits = nil; - adc->numBits = 0; -} - -void -allocateADC(Geometry *geo) -{ - ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset); - adc->adcFormatted = 1; - adc->numBits = geo->meshHeader->totalIndices; - int32 size = adc->numBits+3 & ~3; - adc->adcBits = new int8[size]; - memset(adc->adcBits, 0, size); -} - -static void* -createADC(void *object, int32 offset, int32) -{ - ADCData *adc = PLUGINOFFSET(ADCData, object, offset); - adc->adcFormatted = 0; - return object; -} - -static void* -copyADC(void *dst, void *src, int32 offset, int32) -{ - ADCData *dstadc = PLUGINOFFSET(ADCData, dst, offset); - ADCData *srcadc = PLUGINOFFSET(ADCData, src, offset); - dstadc->adcFormatted = srcadc->adcFormatted; - if(!dstadc->adcFormatted) - return dst; - dstadc->numBits = srcadc->numBits; - int32 size = dstadc->numBits+3 & ~3; - dstadc->adcBits = new int8[size]; - memcpy(dstadc->adcBits, srcadc->adcBits, size); - return dst; -} - -static void* -destroyADC(void *object, int32 offset, int32) -{ - ADCData *adc = PLUGINOFFSET(ADCData, object, offset); - if(adc->adcFormatted) - delete[] adc->adcBits; - return object; -} - -static Stream* -readADC(Stream *stream, int32, void *object, int32 offset, int32) -{ - ADCData *adc = PLUGINOFFSET(ADCData, object, offset); - if(!findChunk(stream, ID_ADC, nil, nil)){ - RWERROR((ERR_CHUNK, "ADC")); - return nil; - } - adc->numBits = stream->readI32(); - adc->adcFormatted = 1; - if(adc->numBits == 0){ - adc->adcBits = nil; - adc->numBits = 0; - return stream; - } - int32 size = adc->numBits+3 & ~3; - adc->adcBits = new int8[size]; - stream->read(adc->adcBits, size); - return stream; -} - -static Stream* -writeADC(Stream *stream, int32 len, void *object, int32 offset, int32) -{ - ADCData *adc = PLUGINOFFSET(ADCData, object, offset); - Geometry *geometry = (Geometry*)object; - writeChunkHeader(stream, ID_ADC, len-12); - if(geometry->geoflags & Geometry::NATIVE){ - stream->writeI32(0); - return stream; - } - stream->writeI32(adc->numBits); - int32 size = adc->numBits+3 & ~3; - stream->write(adc->adcBits, size); - return stream; -} - -static int32 -getSizeADC(void *object, int32 offset, int32) -{ - Geometry *geometry = (Geometry*)object; - ADCData *adc = PLUGINOFFSET(ADCData, object, offset); - if(!adc->adcFormatted) - return 0; - if(geometry->geoflags & Geometry::NATIVE) - return 16; - return 16 + (adc->numBits+3 & ~3); -} - -void -registerADCPlugin(void) -{ - adcOffset = Geometry::registerPlugin(sizeof(ADCData), ID_ADC, - createADC, destroyADC, copyADC); - Geometry::registerPluginStream(ID_ADC, - readADC, - writeADC, - getSizeADC); -} - -// misc stuff - -void -printDMA(InstanceData *inst) -{ - uint32 *tag = (uint32*)inst->data; - for(;;){ - switch(tag[0]&0x70000000){ - case DMAcnt: - printf("%08x %08x\n", tag[0], tag[1]); - tag += (1+(tag[0]&0xFFFF))*4; - break; - - case DMAref: - printf("%08x %08x\n", tag[0], tag[1]); - tag += 4; - break; - - case DMAret: - printf("%08x %08x\n", tag[0], tag[1]); - return; - } - } -} - -void -sizedebug(InstanceData *inst) -{ - if(inst->arePointersFixed == 2) - return; - uint32 *base = (uint32*)inst->data; - uint32 *tag = (uint32*)inst->data; - uint32 *last = nil; - for(;;){ - switch(tag[0]&0x70000000){ - case DMAcnt: - tag += (1+(tag[0]&0xFFFF))*4; - break; - - case DMAref: - last = base + tag[1]*4 + (tag[0]&0xFFFF)*4; - tag += 4; - break; - - case DMAret: - tag += (1+(tag[0]&0xFFFF))*4; - uint32 diff; - if(!last) - diff = (uint8*)tag - (uint8*)base; - else - diff = (uint8*)last - (uint8*)base; - printf("%x %x %x\n", inst->dataSize-diff, diff, inst->dataSize); - return; - - default: - printf("unkown DMAtag: %X %X\n", tag[0], tag[1]); - break; - } - } -} - -} -} diff --git a/src/ps2raster.cpp b/src/ps2raster.cpp deleted file mode 100644 index 4da707a..0000000 --- a/src/ps2raster.cpp +++ /dev/null @@ -1,674 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwerror.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwengine.h" -#include "rwps2.h" - -#define PLUGIN_ID 0 - -#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) - -static void -rasterCreate(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 = ras->paletteSize - 0x50 + 0xF >> 4; - *p++ = sz; - *p++ = 0x08000000; // IMAGE - *p++ = 0; - *p++ = 0; - } - } -} - -static uint8* -rasterLock(Raster *raster, int32 level) -{ - // TODO - (void)raster; - (void)level; - return nil; -} - -static void -rasterUnlock(Raster *raster, int32 level) -{ - // TODO - (void)raster; - (void)level; -} - -static int32 -rasterNumLevels(Raster *raster) -{ - Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset); - if(raster->texels == nil) 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); - 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 = nil; - 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 Stream* -readMipmap(Stream *stream, int32, void *object, int32 offset, int32) -{ - uint16 val = stream->readI32(); - Texture *tex = (Texture*)object; - if(tex->raster == nil) - return stream; - Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset); - SETKL(raster, val); - return stream; -} - -static Stream* -writeMipmap(Stream *stream, int32, void *object, int32 offset, int32) -{ - Texture *tex = (Texture*)object; - if(tex->raster) - return nil; - Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset); - stream->writeI32(raster->tex1[1]&0xFFFF); - return stream; -} - -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); - driver[PLATFORM_PS2].rasterNativeOffset = nativeRasterOffset; - driver[PLATFORM_PS2].rasterCreate = rasterCreate; - driver[PLATFORM_PS2].rasterLock = rasterLock; - driver[PLATFORM_PS2].rasterUnlock = rasterUnlock; - driver[PLATFORM_PS2].rasterNumLevels = rasterNumLevels; - - Texture::registerPlugin(0, ID_SKYMIPMAP, nil, nil, nil); - 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; - uint32 fourcc; - Raster *raster; - Ps2Raster *natras; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")); - return nil; - } - fourcc = stream->readU32(); - if(fourcc != FOURCC_PS2){ - RWERROR((ERR_PLATFORM, fourcc)); - return nil; - } - Texture *tex = Texture::create(nil); - if(tex == nil) - return nil; - - // Texture - tex->filterAddressing = stream->readU32(); - if(!findChunk(stream, ID_STRING, &length, nil)){ - RWERROR((ERR_CHUNK, "STRING")); - goto fail; - } - stream->read(tex->name, length); - if(!findChunk(stream, ID_STRING, &length, nil)){ - RWERROR((ERR_CHUNK, "STRING")); - goto fail; - } - stream->read(tex->mask, length); - - // Raster - StreamRasterExt streamExt; - oldversion = rw::version; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")); - goto fail; - } - if(!findChunk(stream, ID_STRUCT, nil, &version)){ - RWERROR((ERR_CHUNK, "STRUCT")); - goto fail; - } - stream->read(&streamExt, 0x40); - 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; - natras = 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]); - natras->tex0[0] = streamExt.tex0[0]; - natras->tex0[1] = streamExt.tex0[1]; - natras->tex1[0] = streamExt.tex1[0]; - natras->tex1[1] = natras->tex1[1]&~0xFF0000 | - streamExt.tex1[1]<<16 & 0xFF0000; - natras->miptbp1[0] = streamExt.miptbp1[0]; - natras->miptbp1[1] = streamExt.miptbp1[1]; - natras->miptbp2[0] = streamExt.miptbp2[0]; - natras->miptbp2[1] = streamExt.miptbp2[1]; - natras->texelSize = streamExt.texelSize; - natras->paletteSize = streamExt.paletteSize; - natras->gsSize = streamExt.gsSize; - SETKL(natras, 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]); - - if(!findChunk(stream, ID_STRING, &length, nil)){ - RWERROR((ERR_CHUNK, "STRING")); - goto fail; - } - if(streamExt.type < 2){ - stream->read(raster->texels, length); - }else{ - stream->read(raster->texels-0x50, natras->texelSize); - stream->read(raster->palette-0x50, natras->paletteSize); - } - if(tex->streamReadPlugins(stream)) - return tex; - -fail: - tex->destroy(); - return nil; -} - -void -writeNativeTexture(Texture *tex, Stream *stream) -{ - Raster *raster = tex->raster; - Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset); - int32 chunksize = getSizeNativeTexture(tex); - writeChunkHeader(stream, ID_TEXTURENATIVE, chunksize); - writeChunkHeader(stream, ID_STRUCT, 8); - stream->writeU32(FOURCC_PS2); - stream->writeU32(tex->filterAddressing); - int32 len = strlen(tex->name)+4 & ~3; - writeChunkHeader(stream, ID_STRING, len); - stream->write(tex->name, len); - len = strlen(tex->mask)+4 & ~3; - writeChunkHeader(stream, ID_STRING, len); - stream->write(tex->mask, len); - - int32 sz = ras->texelSize + ras->paletteSize; - writeChunkHeader(stream, ID_STRUCT, 12 + 64 + 12 + sz); - writeChunkHeader(stream, ID_STRUCT, 64); - StreamRasterExt streamExt; - streamExt.width = raster->width; - streamExt.height = raster->height; - streamExt.depth = raster->depth; - streamExt.rasterFormat = raster->format | raster->type; - streamExt.type = 0; - if(ras->flags == 2 && raster->depth == 8) - streamExt.type = 1; - if(ras->flags & 1) - streamExt.type = 2; - streamExt.tex0[0] = ras->tex0[0]; - streamExt.tex0[1] = ras->tex0[1]; - streamExt.tex1[0] = ras->tex1[0]; - streamExt.tex1[1] = ras->tex1[1]>>16 & 0xFF; - streamExt.miptbp1[0] = ras->miptbp1[0]; - streamExt.miptbp1[1] = ras->miptbp1[1]; - streamExt.miptbp2[0] = ras->miptbp2[0]; - streamExt.miptbp2[1] = ras->miptbp2[1]; - streamExt.texelSize = ras->texelSize; - streamExt.paletteSize = ras->paletteSize; - streamExt.gsSize = ras->gsSize; - streamExt.mipmapVal = ras->tex1[1]&0xFFFF; - stream->write(&streamExt, 64); - - writeChunkHeader(stream, ID_STRUCT, sz); - if(streamExt.type < 2){ - stream->write(raster->texels, sz); - }else{ - stream->write(raster->texels-0x50, ras->texelSize); - stream->write(raster->palette-0x50, ras->paletteSize); - } - tex->streamWritePlugins(stream); -} - -uint32 -getSizeNativeTexture(Texture *tex) -{ - uint32 size = 12 + 8; - size += 12 + strlen(tex->name)+4 & ~3; - size += 12 + strlen(tex->mask)+4 & ~3; - size += 12 + 12 + 64 + 12; - Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, tex->raster, nativeRasterOffset); - size += ras->texelSize + ras->paletteSize; - size += 12 + tex->streamGetPluginSize(); - return size; -} - -} -} diff --git a/src/rwbase.cpp b/src/rwbase.cpp index ee29211..023fbc0 100644 --- a/src/rwbase.cpp +++ b/src/rwbase.cpp @@ -12,11 +12,11 @@ #include "rwobjects.h" #include "rwplugins.h" #include "rwengine.h" -#include "rwps2.h" -#include "rwxbox.h" -#include "rwd3d8.h" -#include "rwd3d9.h" -#include "rwwdgl.h" +#include "ps2/rwps2.h" +#include "d3d/rwxbox.h" +#include "d3d/rwd3d8.h" +#include "d3d/rwd3d9.h" +#include "gl/rwwdgl.h" namespace rw { diff --git a/src/rwd3d.h b/src/rwd3d.h deleted file mode 100644 index 04ebde0..0000000 --- a/src/rwd3d.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifdef RW_D3D9 -#include -#endif - -namespace rw { -namespace d3d { - -extern bool32 isP8supported; - -#ifdef RW_D3D9 -extern IDirect3DDevice9 *device; -#else -enum { - D3DLOCK_NOSYSLOCK = 0, // ignored - D3DPOOL_MANAGED = 0, // ignored - D3DPT_TRIANGLELIST = 4, - D3DPT_TRIANGLESTRIP = 5, - - - D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.) - D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.) - D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.) - D3DDECLTYPE_FLOAT4 = 3, // 4D float - D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range - // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A) - D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte - D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.) - D3DDECLTYPE_SHORT4 = 7, // 4D signed short - - D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0 - D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1) - D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0) - D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1) - D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0) - D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1) - D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1) - D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1) - D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values - D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused. - - - D3DDECLMETHOD_DEFAULT = 0, - - - D3DDECLUSAGE_POSITION = 0, - D3DDECLUSAGE_BLENDWEIGHT, // 1 - D3DDECLUSAGE_BLENDINDICES, // 2 - D3DDECLUSAGE_NORMAL, // 3 - D3DDECLUSAGE_PSIZE, // 4 - D3DDECLUSAGE_TEXCOORD, // 5 - D3DDECLUSAGE_TANGENT, // 6 - D3DDECLUSAGE_BINORMAL, // 7 - D3DDECLUSAGE_TESSFACTOR, // 8 - D3DDECLUSAGE_POSITIONT, // 9 - D3DDECLUSAGE_COLOR, // 10 - D3DDECLUSAGE_FOG, // 11 - D3DDECLUSAGE_DEPTH, // 12 - D3DDECLUSAGE_SAMPLE, // 13 -}; -#endif - -extern int vertFormatMap[]; - -void *createIndexBuffer(uint32 length); -uint16 *lockIndices(void *indexBuffer, uint32 offset, uint32 size, uint32 flags); -void unlockIndices(void *indexBuffer); -void *createVertexBuffer(uint32 length, uint32 fvf, int32 pool); -uint8 *lockVertices(void *vertexBuffer, uint32 offset, uint32 size, uint32 flags); -void unlockVertices(void *vertexBuffer); -void *createTexture(int32 width, int32 height, int32 levels, uint32 format); -uint8 *lockTexture(void *texture, int32 level); -void unlockTexture(void *texture, int32 level); -void deleteObject(void *object); - -// Native Texture and Raster - -struct D3dRaster -{ - void *texture; - void *palette; - uint32 format; - bool32 hasAlpha; - bool32 customFormat; -}; - -int32 getLevelSize(Raster *raster, int32 level); -void allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha); -void setPalette(Raster *raster, void *palette, int32 size); -void setTexels(Raster *raster, void *texels, int32 level); - -extern int32 nativeRasterOffset; -void registerNativeRaster(void); - -// Rendering - -void setRenderState(uint32 state, uint32 value); -void setTextureStageState(uint32 stage, uint32 type, uint32 value); -void flushCache(void); -void setSamplerState(uint32 stage, uint32 type, uint32 value); - -void setTexture(uint32 stage, Texture *tex); -void setMaterial(Material *mat); - -} -} diff --git a/src/rwd3d8.h b/src/rwd3d8.h deleted file mode 100644 index d8aac01..0000000 --- a/src/rwd3d8.h +++ /dev/null @@ -1,67 +0,0 @@ -namespace rw { -namespace d3d8 { - -void initializePlatform(void); - -struct InstanceData -{ - uint32 minVert; - int32 stride; - int32 numVertices; - int32 numIndices; - Material *material; - uint32 vertexShader; - uint32 primType; - void *indexBuffer; - void *vertexBuffer; - uint32 baseIndex; - uint8 vertexAlpha; - uint8 managed; - uint8 remapped; -}; - -struct InstanceDataHeader : rw::InstanceDataHeader -{ - uint16 serialNumber; - uint16 numMeshes; - - InstanceData *inst; -}; - -uint32 makeFVFDeclaration(uint32 flags, int32 numTex); -int32 getStride(uint32 flags, int32 numTex); - -void *destroyNativeData(void *object, int32, int32); -Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); -Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); -int32 getSizeNativeData(void *object, int32, int32); -void registerNativeDataPlugin(void); - -class ObjPipeline : public rw::ObjPipeline -{ -public: - void (*instanceCB)(Geometry *geo, InstanceData *header); - void (*uninstanceCB)(Geometry *geo, InstanceData *header); - void (*renderCB)(Atomic *atomic, InstanceDataHeader *header); - - ObjPipeline(uint32 platform); -}; - -void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header); -void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header); -void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header); - -ObjPipeline *makeDefaultPipeline(void); - -ObjPipeline *makeSkinPipeline(void); - -ObjPipeline *makeMatFXPipeline(void); - -// Native Texture and Raster - -Texture *readNativeTexture(Stream *stream); -void writeNativeTexture(Texture *tex, Stream *stream); -uint32 getSizeNativeTexture(Texture *tex); - -} -} diff --git a/src/rwd3d9.h b/src/rwd3d9.h deleted file mode 100644 index a382965..0000000 --- a/src/rwd3d9.h +++ /dev/null @@ -1,90 +0,0 @@ -namespace rw { -namespace d3d9 { - -void initializePlatform(void); - -struct VertexElement -{ - uint16 stream; - uint16 offset; - uint8 type; - uint8 method; - uint8 usage; - uint8 usageIndex; -}; - -struct VertexStream -{ - void *vertexBuffer; - uint32 offset; - uint32 stride; - uint16 geometryFlags; - uint8 managed; - uint8 dynamicLock; -}; - -struct InstanceData -{ - uint32 numIndex; - uint32 minVert; - Material *material; - bool32 vertexAlpha; - void *vertexShader; - uint32 baseIndex; - uint32 numVertices; - uint32 startIndex; - uint32 numPrimitives; -}; - -struct InstanceDataHeader : rw::InstanceDataHeader -{ - uint32 serialNumber; - uint32 numMeshes; - void *indexBuffer; - uint32 primType; - VertexStream vertexStream[2]; - bool32 useOffsets; - void *vertexDeclaration; - uint32 totalNumIndex; - uint32 totalNumVertex; - - InstanceData *inst; -}; - -void *createVertexDeclaration(VertexElement *elements); -uint32 getDeclaration(void *declaration, VertexElement *elements); - -void *destroyNativeData(void *object, int32, int32); -Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); -Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); -int32 getSizeNativeData(void *object, int32, int32); -void registerNativeDataPlugin(void); - -class ObjPipeline : public rw::ObjPipeline -{ -public: - void (*instanceCB)(Geometry *geo, InstanceDataHeader *header); - void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header); - void (*renderCB)(Atomic *atomic, InstanceDataHeader *header); - - ObjPipeline(uint32 platform); -}; - -void defaultInstanceCB(Geometry *geo, InstanceDataHeader *header); -void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header); -void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header); - -ObjPipeline *makeDefaultPipeline(void); - -ObjPipeline *makeSkinPipeline(void); - -ObjPipeline *makeMatFXPipeline(void); - -// Native Texture and Raster - -Texture *readNativeTexture(Stream *stream); -void writeNativeTexture(Texture *tex, Stream *stream); -uint32 getSizeNativeTexture(Texture *tex); - -} -} diff --git a/src/rwps2.h b/src/rwps2.h deleted file mode 100644 index 27bff0a..0000000 --- a/src/rwps2.h +++ /dev/null @@ -1,204 +0,0 @@ -namespace rw { -namespace ps2 { - -void initializePlatform(void); - -struct InstanceData -{ - // 0 - addresses in ref tags need fixing - // 1 - no ref tags, so no fixing - // set by the program: - // 2 - ref tags are fixed, need to unfix before stream write - uint32 arePointersFixed; - uint32 dataSize; - uint8 *data; - Material *material; -}; - -struct InstanceDataHeader : rw::InstanceDataHeader -{ - uint32 numMeshes; - InstanceData *instanceMeshes; -}; - -enum { - VU_Lights = 0x3d0 -}; - -enum PS2Attribs { - AT_V2_32 = 0x64000000, - AT_V2_16 = 0x65000000, - AT_V2_8 = 0x66000000, - AT_V3_32 = 0x68000000, - AT_V3_16 = 0x69000000, - AT_V3_8 = 0x6A000000, - AT_V4_32 = 0x6C000000, - AT_V4_16 = 0x6D000000, - AT_V4_8 = 0x6E000000, - AT_UNSGN = 0x00004000, - - AT_RW = 0x6 -}; - -// Not really types as in RW but offsets -enum PS2AttibTypes { - AT_XYZ = 0, - AT_UV = 1, - AT_RGBA = 2, - AT_NORMAL = 3 -}; - -void *destroyNativeData(void *object, int32, int32); -Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); -Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); -int32 getSizeNativeData(void *object, int32, int32); -void registerNativeDataPlugin(void); - -void printDMA(InstanceData *inst); -void sizedebug(InstanceData *inst); - -// only RW_PS2 -void fixDmaOffsets(InstanceData *inst); -void unfixDmaOffsets(InstanceData *inst); -// - -struct PipeAttribute -{ - const char *name; - uint32 attrib; -}; - -extern PipeAttribute attribXYZ; -extern PipeAttribute attribXYZW; -extern PipeAttribute attribUV; -extern PipeAttribute attribUV2; -extern PipeAttribute attribRGBA; -extern PipeAttribute attribNormal; -extern PipeAttribute attribWeights; - -class MatPipeline : public rw::Pipeline -{ -public: - uint32 vifOffset; - uint32 inputStride; - uint32 triStripCount, triListCount; - PipeAttribute *attribs[10]; - void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**); - void (*uninstanceCB)(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**); - void (*preUninstCB)(MatPipeline*, Geometry*); - void (*postUninstCB)(MatPipeline*, Geometry*); - // RW has more: - // instanceTestCB() - // resEntryAllocCB() - // bridgeCB() - // postMeshCB() - // vu1code - // primtype - - static uint32 getVertCount(uint32 top, uint32 inAttribs, - uint32 outAttribs, uint32 outBufs) { - return (top-outBufs)/(inAttribs*2+outAttribs*outBufs); - } - - MatPipeline(uint32 platform); - void dump(void); - void setTriBufferSizes(uint32 inputStride, uint32 stripCount); - void instance(Geometry *g, InstanceData *inst, Mesh *m); - uint8 *collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]); -}; - -class ObjPipeline : public rw::ObjPipeline -{ -public: - MatPipeline *groupPipeline; - // RW has more: - // setupCB() - // finalizeCB() - // lightOffset - // lightSize - - ObjPipeline(uint32 platform); -}; - -struct Vertex { - float32 p[3]; - float32 t[2]; - float32 t1[2]; - uint8 c[4]; - float32 n[3]; - // skin - float32 w[4]; - uint8 i[4]; -}; - -void insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v); - -extern ObjPipeline *defaultObjPipe; -extern MatPipeline *defaultMatPipe; - -void genericUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]); -void genericPreCB(MatPipeline *pipe, Geometry *geo); // skin and ADC -//void defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]); -void skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data); -//void skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[]); - -ObjPipeline *makeDefaultPipeline(void); -void dumpPipeline(rw::Pipeline *pipe); - -// ADC plugin - -// Each element in adcBits corresponds to an index in Mesh->indices, -// this assumes the Mesh indices are ADC formatted. -// ADCData->numBits != Mesh->numIndices. ADCData->numBits is probably -// equal to Mesh->numIndices before the Mesh gets ADC formatted. -// -// Can't convert between ADC-formatted and non-ADC-formatted yet :( - -struct ADCData -{ - bool32 adcFormatted; - int8 *adcBits; - int32 numBits; -}; -extern int32 adcOffset; -void registerADCPlugin(void); - -int8 *getADCbits(Geometry *geo); -int8 *getADCbitsForMesh(Geometry *geo, Mesh *mesh); -void convertADC(Geometry *g); -void unconvertADC(Geometry *geo); -void allocateADC(Geometry *geo); - -// PDS plugin - -Pipeline *getPDSPipe(uint32 data); -void registerPDSPipe(Pipeline *pipe); -void registerPDSPlugin(int32 n); -void registerPluginPDSPipes(void); - -// Native Texture and Raster - -struct Ps2Raster -{ - uint32 tex0[2]; - uint32 tex1[2]; - uint32 miptbp1[2]; - uint32 miptbp2[2]; - uint32 texelSize; - uint32 paletteSize; - uint32 gsSize; - int8 flags; - - uint8 *data; //tmp - uint32 dataSize; -}; - -extern int32 nativeRasterOffset; -void registerNativeRaster(void); - -Texture *readNativeTexture(Stream *stream); -void writeNativeTexture(Texture *tex, Stream *stream); -uint32 getSizeNativeTexture(Texture *tex); - -} -} diff --git a/src/rwps2plg.h b/src/rwps2plg.h deleted file mode 100644 index ac2d3be..0000000 --- a/src/rwps2plg.h +++ /dev/null @@ -1,22 +0,0 @@ -namespace rw { -namespace ps2 { - -ObjPipeline *makeSkinPipeline(void); -ObjPipeline *makeMatFXPipeline(void); - -// Skin plugin - -void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v); -int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v); - -Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset); -Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset); -int32 getSizeNativeSkin(void *object, int32 offset); - -void instanceSkinData(Geometry *g, Mesh *m, Skin *skin, uint32 *data); - -void skinPreCB(MatPipeline*, Geometry*); -void skinPostCB(MatPipeline*, Geometry*); - -} -} diff --git a/src/rwwdgl.h b/src/rwwdgl.h deleted file mode 100644 index badf959..0000000 --- a/src/rwwdgl.h +++ /dev/null @@ -1,83 +0,0 @@ - -namespace rw { -namespace wdgl { - -// NOTE: This is not really RW OpenGL! It's specific to WarDrum's GTA ports - -void initializePlatform(void); - -struct AttribDesc -{ - // arguments to glVertexAttribPointer (should use OpenGL types here) - // Vertex = 0, TexCoord, Normal, Color, Weight, Bone Index, Extra Color - uint32 index; - // float = 0, byte, ubyte, short, ushort - int32 type; - bool32 normalized; - int32 size; - uint32 stride; - uint32 offset; -}; - -struct InstanceDataHeader : rw::InstanceDataHeader -{ - int32 numAttribs; - AttribDesc *attribs; - uint32 dataSize; - uint8 *data; - - // needed for rendering - uint32 vbo; - uint32 ibo; -}; - -// only RW_OPENGL -void uploadGeo(Geometry *geo); -void setAttribPointers(InstanceDataHeader *inst); - -void packattrib(uint8 *dst, float32 *src, AttribDesc *a, float32 scale); -void unpackattrib(float *dst, uint8 *src, AttribDesc *a, float32 scale); - -void *destroyNativeData(void *object, int32, int32); -Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); -Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); -int32 getSizeNativeData(void *object, int32, int32); -void registerNativeDataPlugin(void); - -void printPipeinfo(Atomic *a); - -class ObjPipeline : public rw::ObjPipeline -{ -public: - uint32 numCustomAttribs; - uint32 (*instanceCB)(Geometry *g, int32 i, uint32 offset); - void (*uninstanceCB)(Geometry *g); - - ObjPipeline(uint32 platform); -}; - -ObjPipeline *makeDefaultPipeline(void); - -// Skin plugin - -Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset); -Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset); -int32 getSizeNativeSkin(void *object, int32 offset); - -ObjPipeline *makeSkinPipeline(void); - -ObjPipeline *makeMatFXPipeline(void); - -// Raster - -struct Texture : rw::Texture -{ - void upload(void); - void bind(int n); -}; - -extern int32 nativeRasterOffset; -void registerNativeRaster(void); - -} -} diff --git a/src/rwxbox.h b/src/rwxbox.h deleted file mode 100644 index 1c16af1..0000000 --- a/src/rwxbox.h +++ /dev/null @@ -1,181 +0,0 @@ -namespace rw { -namespace xbox { - -void initializePlatform(void); - -struct InstanceData -{ - uint32 minVert; - int32 numVertices; - int32 numIndices; - void *indexBuffer; - Material *material; - uint32 vertexShader; -}; - -struct InstanceDataHeader : rw::InstanceDataHeader -{ - int32 size; - uint16 serialNumber; - uint16 numMeshes; - uint32 primType; - int32 numVertices; - int32 stride; - void *vertexBuffer; - bool32 vertexAlpha; - InstanceData *begin; - InstanceData *end; - - uint8 *data; -}; - -void *destroyNativeData(void *object, int32, int32); -Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); -Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32); -int32 getSizeNativeData(void *object, int32, int32); -void registerNativeDataPlugin(void); - -class ObjPipeline : public rw::ObjPipeline -{ -public: - void (*instanceCB)(Geometry *geo, InstanceDataHeader *header); - void (*uninstanceCB)(Geometry *geo, InstanceDataHeader *header); - - ObjPipeline(uint32 platform); -}; - -ObjPipeline *makeDefaultPipeline(void); - -// Skin plugin - -Stream *readNativeSkin(Stream *stream, int32, void *object, int32 offset); -Stream *writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset); -int32 getSizeNativeSkin(void *object, int32 offset); - -ObjPipeline *makeSkinPipeline(void); - -ObjPipeline *makeMatFXPipeline(void); - -// Vertex Format plugin - -extern uint32 vertexFormatSizes[6]; - -uint32 *getVertexFmt(Geometry *g); -uint32 makeVertexFmt(int32 flags, uint32 numTexSets); -uint32 getVertexFmtStride(uint32 fmt); - -void registerVertexFormatPlugin(void); - -// Native Texture and Raster - -struct XboxRaster -{ - void *texture; - void *palette; - uint32 format; - bool32 hasAlpha; - bool32 unknownFlag; -}; - -int32 getLevelSize(Raster *raster, int32 level); - -extern int32 nativeRasterOffset; -void registerNativeRaster(void); - -Texture *readNativeTexture(Stream *stream); -void writeNativeTexture(Texture *tex, Stream *stream); -uint32 getSizeNativeTexture(Texture *tex); - -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, -}; - -} -} diff --git a/src/wdgl.cpp b/src/wdgl.cpp deleted file mode 100644 index 628bc8b..0000000 --- a/src/wdgl.cpp +++ /dev/null @@ -1,793 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwerror.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwengine.h" -#include "rwplugins.h" -#include "rwwdgl.h" - -#ifdef RW_OPENGL -#include -#endif - -#define PLUGIN_ID 2 - -namespace rw { -namespace wdgl { - -void -initializePlatform(void) -{ - driver[PLATFORM_WDGL].defaultPipeline = makeDefaultPipeline(); -} - - -// VC -// 8733 0 0 0 3 -// 45 1 0 0 2 -// 8657 1 3 0 2 -// 4610 2 1 1 3 -// 4185 3 2 1 4 -// 256 4 2 1 4 -// 201 4 4 1 4 -// 457 5 2 0 4 - -// SA -// 20303 0 0 0 3 vertices: 3 floats -// 53 1 0 0 2 texCoords: 2 floats -// 20043 1 3 0 2 texCoords: 2 shorts -// 6954 2 1 1 3 normal: 3 bytes normalized -// 13527 3 2 1 4 color: 4 ubytes normalized -// 196 4 2 1 4 weight: 4 ubytes normalized -// 225 4 4 1 4 weight: 4 ushorts normalized -// 421 5 2 0 4 indices: 4 ubytes -// 12887 6 2 1 4 extracolor:4 ubytes normalized - -/* -static void -printAttribInfo(AttribDesc *attribs, int n) -{ - for(int i = 0; i < n; i++) - printf("%x %x %x %x\n", - attribs[i].index, - attribs[i].type, - attribs[i].normalized, - attribs[i].size); -} -*/ - -#ifdef RW_OPENGL -void -uploadGeo(Geometry *geo) -{ - InstanceDataHeader *inst = (InstanceDataHeader*)geo->instData; - MeshHeader *meshHeader = geo->meshHeader; - - glGenBuffers(1, &inst->vbo); - glBindBuffer(GL_ARRAY_BUFFER, inst->vbo); - glBufferData(GL_ARRAY_BUFFER, inst->dataSize, - inst->data, GL_STATIC_DRAW); - - glGenBuffers(1, &inst->ibo); - glBindBuffer(GL_ARRAY_BUFFER, inst->ibo); - glBufferData(GL_ARRAY_BUFFER, meshHeader->totalIndices*2, - 0, GL_STATIC_DRAW); - GLintptr offset = 0; - for(uint32 i = 0; i < meshHeader->numMeshes; i++){ - Mesh *mesh = &meshHeader->mesh[i]; - glBufferSubData(GL_ARRAY_BUFFER, offset, mesh->numIndices*2, - mesh->indices); - offset += mesh->numIndices*2; - } - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void -setAttribPointers(InstanceDataHeader *inst) -{ - static GLenum attribType[] = { - GL_FLOAT, - GL_BYTE, GL_UNSIGNED_BYTE, - GL_SHORT, GL_UNSIGNED_SHORT - }; - for(int32 i = 0; i < inst->numAttribs; i++){ - AttribDesc *a = &inst->attribs[i]; - glEnableVertexAttribArray(a->index); - glVertexAttribPointer(a->index, a->size, attribType[a->type], - a->normalized, a->stride, - (void*)(uint64)a->offset); - } -} -#endif - -void -packattrib(uint8 *dst, float32 *src, AttribDesc *a, float32 scale=1.0f) -{ - int8 *i8dst; - uint16 *u16dst; - int16 *i16dst; - - switch(a->type){ - case 0: // float - memcpy(dst, src, a->size*4); - break; - - // TODO: maybe have loop inside if? - case 1: // byte - i8dst = (int8*)dst; - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - i8dst[i] = src[i]*scale; - else - i8dst[i] = src[i]*127.0f; - } - break; - - case 2: // ubyte - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - dst[i] = src[i]*scale; - else - dst[i] = src[i]*255.0f; - } - break; - - case 3: // short - i16dst = (int16*)dst; - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - i16dst[i] = src[i]*scale; - else - i16dst[i] = src[i]*32767.0f; - } - break; - - case 4: // ushort - u16dst = (uint16*)dst; - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - u16dst[i] = src[i]*scale; - else - u16dst[i] = src[i]*65535.0f; - } - break; - } -} - -void -unpackattrib(float *dst, uint8 *src, AttribDesc *a, float32 scale=1.0f) -{ - int8 *i8src; - uint16 *u16src; - int16 *i16src; - - switch(a->type){ - case 0: // float - memcpy(dst, src, a->size*4); - break; - - // TODO: maybe have loop inside if? - case 1: // byte - i8src = (int8*)src; - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - dst[i] = i8src[i]/scale; - else - dst[i] = i8src[i]/127.0f; - } - break; - - case 2: // ubyte - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - dst[i] = src[i]/scale; - else - dst[i] = src[i]/255.0f; - } - break; - - case 3: // short - i16src = (int16*)src; - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - dst[i] = i16src[i]/scale; - else - dst[i] = i16src[i]/32767.0f; - } - break; - - case 4: // ushort - u16src = (uint16*)src; - for(int i = 0; i < a->size; i++){ - if(!a->normalized) - dst[i] = u16src[i]/scale; - else - dst[i] = u16src[i]/65435.0f; - } - break; - } -} - -void* -destroyNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_WDGL) - return object; - InstanceDataHeader *header = - (InstanceDataHeader*)geometry->instData; - geometry->instData = nil; - // TODO: delete ibo and vbo - delete[] header->attribs; - delete[] header->data; - delete header; - return object; -} - -Stream* -readNativeData(Stream *stream, int32, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - InstanceDataHeader *header = new InstanceDataHeader; - geometry->instData = header; - header->platform = PLATFORM_WDGL; - header->vbo = 0; - header->ibo = 0; - header->numAttribs = stream->readU32(); - header->attribs = new AttribDesc[header->numAttribs]; - stream->read(header->attribs, - header->numAttribs*sizeof(AttribDesc)); - header->dataSize = header->attribs[0].stride*geometry->numVertices; - header->data = new uint8[header->dataSize]; - stream->read(header->data, header->dataSize); - return stream; -} - -Stream* -writeNativeData(Stream *stream, int32, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_WDGL) - return stream; - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - stream->writeU32(header->numAttribs); - stream->write(header->attribs, header->numAttribs*sizeof(AttribDesc)); - stream->write(header->data, header->dataSize); - return stream; -} - -int32 -getSizeNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_WDGL) - return 0; - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize; -} - -void -registerNativeDataPlugin(void) -{ - Geometry::registerPlugin(0, ID_NATIVEDATA, - nil, destroyNativeData, nil); - Geometry::registerPluginStream(ID_NATIVEDATA, - readNativeData, - writeNativeData, - getSizeNativeData); -} - -void -printPipeinfo(Atomic *a) -{ - Geometry *g = a->geometry; - if(g->instData == nil || g->instData->platform != PLATFORM_WDGL) - return; - int32 plgid = 0; - if(a->pipeline) - plgid = a->pipeline->pluginID; - printf("%s %x: ", debugFile, plgid); - InstanceDataHeader *h = (InstanceDataHeader*)g->instData; - for(int i = 0; i < h->numAttribs; i++) - printf("%x(%x) ", h->attribs[i].index, h->attribs[i].type); - printf("\n"); -} - -static void -instance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if(geo->geoflags & Geometry::NATIVE) - return; - InstanceDataHeader *header = new InstanceDataHeader; - geo->instData = header; - header->platform = PLATFORM_WDGL; - header->vbo = 0; - header->ibo = 0; - header->numAttribs = - pipe->numCustomAttribs + 1 + (geo->numTexCoordSets > 0); - if(geo->geoflags & Geometry::PRELIT) - header->numAttribs++; - if(geo->geoflags & Geometry::NORMALS) - header->numAttribs++; - int32 offset = 0; - header->attribs = new AttribDesc[header->numAttribs]; - - AttribDesc *a = header->attribs; - // Vertices - a->index = 0; - a->type = 0; - a->normalized = 0; - a->size = 3; - a->offset = offset; - offset += 12; - a++; - int32 firstCustom = 1; - - // texCoords, only one set here - if(geo->numTexCoordSets){ - a->index = 1; - a->type = 3; - a->normalized = 0; - a->size = 2; - a->offset = offset; - offset += 4; - a++; - firstCustom++; - } - - if(geo->geoflags & Geometry::NORMALS){ - a->index = 2; - a->type = 1; - a->normalized = 1; - a->size = 3; - a->offset = offset; - offset += 4; - a++; - firstCustom++; - } - - if(geo->geoflags & Geometry::PRELIT){ - a->index = 3; - a->type = 2; - a->normalized = 1; - a->size = 4; - a->offset = offset; - offset += 4; - a++; - firstCustom++; - } - - if(pipe->instanceCB) - offset += pipe->instanceCB(geo, firstCustom, offset); - else{ - header->dataSize = offset*geo->numVertices; - header->data = new uint8[header->dataSize]; - } - - a = header->attribs; - for(int32 i = 0; i < header->numAttribs; i++) - a[i].stride = offset; - - uint8 *p = header->data + a->offset; - float32 *vert = geo->morphTargets->vertices; - for(int32 i = 0; i < geo->numVertices; i++){ - packattrib(p, vert, a); - vert += 3; - p += a->stride; - } - a++; - - if(geo->numTexCoordSets){ - p = header->data + a->offset; - float32 *texcoord = geo->texCoords[0]; - for(int32 i = 0; i < geo->numVertices; i++){ - packattrib(p, texcoord, a, 512.0f); - texcoord += 2; - p += a->stride; - } - a++; - } - - if(geo->geoflags & Geometry::NORMALS){ - p = header->data + a->offset; - float32 *norm = geo->morphTargets->normals; - for(int32 i = 0; i < geo->numVertices; i++){ - packattrib(p, norm, a); - norm += 3; - p += a->stride; - } - a++; - } - - if(geo->geoflags & Geometry::PRELIT){ - // TODO: this seems too complicated - p = header->data + a->offset; - uint8 *color = geo->colors; - float32 f[4]; - for(int32 i = 0; i < geo->numVertices; i++){ - f[0] = color[0]/255.0f; - f[1] = color[1]/255.0f; - f[2] = color[2]/255.0f; - f[3] = color[3]/255.0f; - packattrib(p, f, a); - color += 4; - p += a->stride; - } - a++; - } - geo->geoflags |= Geometry::NATIVE; -} - -static void -uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if((geo->geoflags & Geometry::NATIVE) == 0) - return; - assert(geo->instData != nil); - assert(geo->instData->platform == PLATFORM_WDGL); - geo->geoflags &= ~Geometry::NATIVE; - geo->allocateData(); - - uint8 *p; - float32 *texcoord = geo->texCoords[0]; - uint8 *color = geo->colors; - float32 *vert = geo->morphTargets->vertices; - float32 *norm = geo->morphTargets->normals; - float32 f[4]; - - InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; - for(int i = 0; i < header->numAttribs; i++){ - AttribDesc *a = &header->attribs[i]; - p = header->data + a->offset; - - switch(a->index){ - case 0: // Vertices - for(int32 i = 0; i < geo->numVertices; i++){ - unpackattrib(vert, p, a); - vert += 3; - p += a->stride; - } - break; - - case 1: // texCoords - for(int32 i = 0; i < geo->numVertices; i++){ - unpackattrib(texcoord, p, a, 512.0f); - texcoord += 2; - p += a->stride; - } - break; - - case 2: // normals - for(int32 i = 0; i < geo->numVertices; i++){ - unpackattrib(norm, p, a); - norm += 3; - p += a->stride; - } - break; - - case 3: // colors - for(int32 i = 0; i < geo->numVertices; i++){ - // TODO: this seems too complicated - unpackattrib(f, p, a); - color[0] = f[0]*255.0f; - color[1] = f[1]*255.0f; - color[2] = f[2]*255.0f; - color[3] = f[3]*255.0f; - color += 4; - p += a->stride; - } - break; - } - } - - if(pipe->uninstanceCB) - pipe->uninstanceCB(geo); - - geo->generateTriangles(); - - destroyNativeData(geo, 0, 0); -} - -ObjPipeline::ObjPipeline(uint32 platform) - : rw::ObjPipeline(platform) -{ - this->numCustomAttribs = 0; - this->impl.instance = wdgl::instance; - this->impl.uninstance = wdgl::uninstance; - this->instanceCB = nil; - this->uninstanceCB = nil; -} - -ObjPipeline* -makeDefaultPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_WDGL); - return pipe; -} - -// Skin - -Stream* -readNativeSkin(Stream *stream, int32, void *object, int32 offset) -{ - Geometry *geometry = (Geometry*)object; - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, nil)){ - RWERROR((ERR_CHUNK, "STRUCT")); - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_GL){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - Skin *skin = new Skin; - *PLUGINOFFSET(Skin*, geometry, offset) = skin; - - int32 numBones = stream->readI32(); - skin->init(numBones, 0, 0); - stream->read(skin->inverseMatrices, skin->numBones*64); - return stream; -} - -Stream* -writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset) -{ - writeChunkHeader(stream, ID_STRUCT, len-12); - stream->writeU32(PLATFORM_WDGL); - Skin *skin = *PLUGINOFFSET(Skin*, object, offset); - stream->writeI32(skin->numBones); - stream->write(skin->inverseMatrices, skin->numBones*64); - return stream; -} - -int32 -getSizeNativeSkin(void *object, int32 offset) -{ - Skin *skin = *PLUGINOFFSET(Skin*, object, offset); - if(skin == nil) - return -1; - int32 size = 12 + 4 + 4 + skin->numBones*64; - return size; -} - -uint32 -skinInstanceCB(Geometry *g, int32 i, uint32 offset) -{ - InstanceDataHeader *header = (InstanceDataHeader*)g->instData; - AttribDesc *a = &header->attribs[i]; - // weights - a->index = 4; - a->type = 2; /* but also short o_O */ - a->normalized = 1; - a->size = 4; - a->offset = offset; - offset += 4; - a++; - - // indices - a->index = 5; - a->type = 2; - a->normalized = 0; - a->size = 4; - a->offset = offset; - offset += 4; - - header->dataSize = offset*g->numVertices; - header->data = new uint8[header->dataSize]; - - Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset); - if(skin == nil) - return 8; - - a = &header->attribs[i]; - uint8 *wgt = header->data + a[0].offset; - uint8 *idx = header->data + a[1].offset; - uint8 *indices = skin->indices; - float32 *weights = skin->weights; - for(int32 i = 0; i < g->numVertices; i++){ - packattrib(wgt, weights, a); - weights += 4; - wgt += offset; - idx[0] = *indices++; - idx[1] = *indices++; - idx[2] = *indices++; - idx[3] = *indices++; - idx += offset; - } - - return 8; -} - -void -skinUninstanceCB(Geometry *geo) -{ - InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; - - Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); - if(skin == nil) - return; - - uint8 *data = skin->data; - float *invMats = skin->inverseMatrices; - skin->init(skin->numBones, skin->numBones, geo->numVertices); - memcpy(skin->inverseMatrices, invMats, skin->numBones*64); - delete[] data; - - uint8 *p; - float *weights = skin->weights; - uint8 *indices = skin->indices; - for(int i = 0; i < header->numAttribs; i++){ - AttribDesc *a = &header->attribs[i]; - p = header->data + a->offset; - - switch(a->index){ - case 4: // weights - for(int32 i = 0; i < geo->numVertices; i++){ - unpackattrib(weights, p, a); - weights += 4; - p += a->stride; - } - break; - - case 5: // indices - for(int32 i = 0; i < geo->numVertices; i++){ - *indices++ = p[0]; - *indices++ = p[1]; - *indices++ = p[2]; - *indices++ = p[3]; - p += a->stride; - } - break; - } - } - - skin->findNumWeights(geo->numVertices); - skin->findUsedBones(geo->numVertices); -} - -ObjPipeline* -makeSkinPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_WDGL); - pipe->pluginID = ID_SKIN; - pipe->pluginData = 1; - pipe->numCustomAttribs = 2; - pipe->instanceCB = skinInstanceCB; - pipe->uninstanceCB = skinUninstanceCB; - return pipe; -} - -ObjPipeline* -makeMatFXPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_WDGL); - pipe->pluginID = ID_MATFX; - pipe->pluginData = 0; - return pipe; -} - -// Raster - -int32 nativeRasterOffset; - -#ifdef RW_OPENGL -struct GlRaster { - GLuint id; -}; - -static void* -createNativeRaster(void *object, int32 offset, int32) -{ - GlRaster *raster = PLUGINOFFSET(GlRaster, object, offset); - raster->id = 0; - return object; -} - -static void* -destroyNativeRaster(void *object, int32 offset, int32) -{ - // TODO: - return object; -} - -static void* -copyNativeRaster(void *dst, void *, int32 offset, int32) -{ - GlRaster *raster = PLUGINOFFSET(GlRaster, dst, offset); - raster->id = 0; - return dst; -} - -void -registerNativeRaster(void) -{ - nativeRasterOffset = Raster::registerPlugin(sizeof(GlRaster), - 0x12340000 | PLATFORM_WDGL, - createNativeRaster, - destroyNativeRaster, - copyNativeRaster); -} - -void -Texture::upload(void) -{ - GLuint id; - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - Raster *r = this->raster; - if(r->palette){ - printf("can't upload paletted raster\n"); - return; - } - - static GLenum filter[] = { - 0, GL_NEAREST, GL_LINEAR, - GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, - GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR - }; - static GLenum filternomip[] = { - 0, GL_NEAREST, GL_LINEAR, - GL_NEAREST, GL_LINEAR, - GL_NEAREST, GL_LINEAR - }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - filternomip[this->filterAddressing & 0xFF]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - filternomip[this->filterAddressing & 0xFF]); - - static GLenum wrap[] = { - 0, GL_REPEAT, GL_MIRRORED_REPEAT, - GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER - }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - wrap[(this->filterAddressing >> 8) & 0xF]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - wrap[(this->filterAddressing >> 12) & 0xF]); - - switch(r->format & 0xF00){ - case Raster::C8888: - glTexImage2D(GL_TEXTURE_2D, 0, 4, r->width, r->height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, r->texels); - break; - default: - printf("unsupported raster format: %x\n", r->format); - break; - } - glBindTexture(GL_TEXTURE_2D, 0); - GlRaster *glr = PLUGINOFFSET(GlRaster, r, nativeRasterOffset); - glr->id = id; -} - -void -Texture::bind(int n) -{ - Raster *r = this->raster; - GlRaster *glr = PLUGINOFFSET(GlRaster, r, nativeRasterOffset); - glActiveTexture(GL_TEXTURE0+n); - if(r){ - if(glr->id == 0) - this->upload(); - glBindTexture(GL_TEXTURE_2D, glr->id); - }else - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - -} -#endif - -} -} diff --git a/src/world.cpp b/src/world.cpp new file mode 100644 index 0000000..4d612b1 --- /dev/null +++ b/src/world.cpp @@ -0,0 +1,46 @@ +#include +#include +#include + +#include "rwbase.h" +#include "rwerror.h" +#include "rwplg.h" +#include "rwpipeline.h" +#include "rwobjects.h" +#include "rwengine.h" + +#define PLUGIN_ID 2 + +namespace rw { + +World* +World::create(void) +{ + World *world = (World*)malloc(PluginBase::s_size); + if(world == nil){ + RWERROR((ERR_ALLOC, PluginBase::s_size)); + return nil; + } + world->object.init(World::ID, 0); + world->lights.init(); + world->directionalLights.init(); + return world; +} + +void +World::addLight(Light *light) +{ + light->world = this; + if(light->getType() < Light::POINT){ + this->directionalLights.append(&light->inWorld); + }else + this->lights.append(&light->inWorld); +} + +void +World::addCamera(Camera *cam) +{ + cam->world = this; +} + +} diff --git a/src/xbox.cpp b/src/xbox.cpp deleted file mode 100644 index f0c1699..0000000 --- a/src/xbox.cpp +++ /dev/null @@ -1,1050 +0,0 @@ -#include -#include -#include -#include - -#include "rwbase.h" -#include "rwerror.h" -#include "rwplg.h" -#include "rwpipeline.h" -#include "rwobjects.h" -#include "rwengine.h" -#include "rwplugins.h" -#include "rwxbox.h" - -#define PLUGIN_ID 2 - -namespace rw { -namespace xbox { - -void -initializePlatform(void) -{ - driver[PLATFORM_XBOX].defaultPipeline = makeDefaultPipeline(); -} - -void* -destroyNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_XBOX) - return object; - InstanceDataHeader *header = - (InstanceDataHeader*)geometry->instData; - geometry->instData = nil; - delete[] (uint8*)header->vertexBuffer; - delete[] header->begin; - delete[] header->data; - delete header; - return object; -} - -Stream* -readNativeData(Stream *stream, int32, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - uint32 vers; - uint32 platform; - if(!findChunk(stream, ID_STRUCT, nil, &vers)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_XBOX){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - if(vers < 0x35000){ - RWERROR((ERR_VERSION, vers)); - return nil; - } - InstanceDataHeader *header = new InstanceDataHeader; - geometry->instData = header; - header->platform = PLATFORM_XBOX; - - int32 size = stream->readI32(); - // The 0x18 byte are the resentryheader. - // We don't have it but it's used for alignment. - header->data = new uint8[size + 0x18]; - uint8 *p = header->data+0x18+4; - stream->read(p, size-4); - - header->size = size; - header->serialNumber = *(uint16*)p; p += 2; - header->numMeshes = *(uint16*)p; p += 2; - header->primType = *(uint32*)p; p += 4; - header->numVertices = *(uint32*)p; p += 4; - header->stride = *(uint32*)p; p += 4; - // RxXboxVertexFormat in 3.3 here - p += 4; // skip vertexBuffer pointer - header->vertexAlpha = *(bool32*)p; p += 4; - p += 8; // skip begin, end pointers - - InstanceData *inst = new InstanceData[header->numMeshes]; - header->begin = inst; - for(int i = 0; i < header->numMeshes; i++){ - inst->minVert = *(uint32*)p; p += 4; - inst->numVertices = *(int32*)p; p += 4; - inst->numIndices = *(int32*)p; p += 4; - inst->indexBuffer = header->data + *(uint32*)p; p += 4; - p += 8; // skip material and vertexShader - inst->vertexShader = 0; - // pixelShader in 3.3 here - inst++; - } - header->end = inst; - - header->vertexBuffer = new uint8[header->stride*header->numVertices]; - stream->read(header->vertexBuffer, header->stride*header->numVertices); - return stream; -} - -Stream* -writeNativeData(Stream *stream, int32 len, void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - writeChunkHeader(stream, ID_STRUCT, len-12); - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_XBOX) - return stream; - stream->writeU32(PLATFORM_XBOX); - assert(rw::version >= 0x35000 && "can't write native Xbox data < 0x35000"); - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - - // we just fill header->data and write that - uint8 *p = header->data+0x18; - *(int32*)p = header->size; p += 4; - *(uint16*)p = header->serialNumber; p += 2; - *(uint16*)p = header->numMeshes; p += 2; - *(uint32*)p = header->primType; p += 4; - *(uint32*)p = header->numVertices; p += 4; - *(uint32*)p = header->stride; p += 4; - // RxXboxVertexFormat in 3.3 here - p += 4; // skip vertexBuffer pointer - *(bool32*)p = header->vertexAlpha; p += 4; - p += 8; // skip begin, end pointers - - InstanceData *inst = header->begin; - for(int i = 0; i < header->numMeshes; i++){ - *(uint32*)p = inst->minVert; p += 4; - *(int32*)p = inst->numVertices; p += 4; - *(int32*)p = inst->numIndices; p += 4; - *(uint32*)p = (uint8*)inst->indexBuffer - header->data; p += 4; - p += 8; // skip material and vertexShader - // pixelShader in 3.3 here - inst++; - } - - stream->write(header->data+0x18, header->size); - stream->write(header->vertexBuffer, header->stride*header->numVertices); - return stream; -} - -int32 -getSizeNativeData(void *object, int32, int32) -{ - Geometry *geometry = (Geometry*)object; - if(geometry->instData == nil || - geometry->instData->platform != PLATFORM_XBOX) - return 0; - InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData; - return 12 + 4 + header->size + header->stride*header->numVertices; -} - -void -registerNativeDataPlugin(void) -{ - Geometry::registerPlugin(0, ID_NATIVEDATA, - nil, destroyNativeData, nil); - Geometry::registerPluginStream(ID_NATIVEDATA, - readNativeData, - writeNativeData, - getSizeNativeData); -} - -static void -instance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - enum { - D3DPT_TRIANGLELIST = 5, - D3DPT_TRIANGLESTRIP = 6, - }; - - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if(geo->geoflags & Geometry::NATIVE) - return; - geo->geoflags |= Geometry::NATIVE; - InstanceDataHeader *header = new InstanceDataHeader; - MeshHeader *meshh = geo->meshHeader; - geo->instData = header; - header->platform = PLATFORM_XBOX; - - header->size = 0x24 + meshh->numMeshes*0x18 + 0x10; - Mesh *mesh = meshh->mesh; - for(uint32 i = 0; i < meshh->numMeshes; i++) - header->size += (mesh++->numIndices*2 + 0xF) & ~0xF; - // The 0x18 byte are the resentryheader. - // We don't have it but it's used for alignment. - header->data = new uint8[header->size + 0x18]; - header->serialNumber = 0; - header->numMeshes = meshh->numMeshes; - header->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST; - header->numVertices = geo->numVertices; - header->vertexAlpha = 0; - // set by the instanceCB - header->stride = 0; - header->vertexBuffer = nil; - - InstanceData *inst = new InstanceData[header->numMeshes]; - header->begin = inst; - mesh = meshh->mesh; - uint8 *indexbuf = (uint8*)header->data + ((0x18 + 0x24 + header->numMeshes*0x18 + 0xF)&~0xF); - for(uint32 i = 0; i < header->numMeshes; i++){ - findMinVertAndNumVertices(mesh->indices, mesh->numIndices, - &inst->minVert, &inst->numVertices); - inst->numIndices = mesh->numIndices; - inst->indexBuffer = indexbuf; - memcpy(inst->indexBuffer, mesh->indices, inst->numIndices*sizeof(uint16)); - indexbuf += (inst->numIndices*2 + 0xF) & ~0xF; - inst->material = mesh->material; - inst->vertexShader = 0; // TODO? - mesh++; - inst++; - } - header->end = inst; - - pipe->instanceCB(geo, header); -} - -static void -uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic) -{ - ObjPipeline *pipe = (ObjPipeline*)rwpipe; - Geometry *geo = atomic->geometry; - if((geo->geoflags & Geometry::NATIVE) == 0) - return; - assert(geo->instData != nil); - assert(geo->instData->platform == PLATFORM_XBOX); - geo->geoflags &= ~Geometry::NATIVE; - geo->allocateData(); - geo->meshHeader->allocateIndices(); - - InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; - InstanceData *inst = header->begin; - Mesh *mesh = geo->meshHeader->mesh; - for(uint32 i = 0; i < header->numMeshes; i++){ - uint16 *indices = (uint16*)inst->indexBuffer; - memcpy(mesh->indices, indices, inst->numIndices*2); - mesh++; - inst++; - } - - pipe->uninstanceCB(geo, header); - geo->generateTriangles(); - destroyNativeData(geo, 0, 0); -} - -ObjPipeline::ObjPipeline(uint32 platform) - : rw::ObjPipeline(platform) -{ - this->impl.instance = xbox::instance; - this->impl.uninstance = xbox::uninstance; - this->instanceCB = nil; - this->uninstanceCB = nil; -} - - -int v3dFormatMap[] = { - -1, VERT_BYTE3, VERT_SHORT3, VERT_NORMSHORT3, VERT_COMPNORM, VERT_FLOAT3 -}; - -int v2dFormatMap[] = { - -1, VERT_BYTE2, VERT_SHORT2, VERT_NORMSHORT2, VERT_COMPNORM, VERT_FLOAT2 -}; - -void -defaultInstanceCB(Geometry *geo, InstanceDataHeader *header) -{ - uint32 *vertexFmt = getVertexFmt(geo); - if(*vertexFmt == 0) - *vertexFmt = makeVertexFmt(geo->geoflags, geo->numTexCoordSets); - header->stride = getVertexFmtStride(*vertexFmt); - header->vertexBuffer = new uint8[header->stride*header->numVertices]; - uint8 *dst = (uint8*)header->vertexBuffer; - - uint32 fmt = *vertexFmt; - uint32 sel = fmt & 0xF; - instV3d(v3dFormatMap[sel], dst, geo->morphTargets[0].vertices, - header->numVertices, header->stride); - dst += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; - - sel = (fmt >> 4) & 0xF; - if(sel){ - instV3d(v3dFormatMap[sel], dst, geo->morphTargets[0].normals, - header->numVertices, header->stride); - dst += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; - } - - if(fmt & 0x1000000){ - header->vertexAlpha = instColor(VERT_ARGB, dst, geo->colors, - header->numVertices, header->stride); - dst += 4; - } - - for(int i = 0; i < 4; i++){ - sel = (fmt >> (i*4 + 8)) & 0xF; - if(sel == 0) - break; - instV2d(v2dFormatMap[sel], dst, geo->texCoords[i], - header->numVertices, header->stride); - dst += sel == 4 ? 4 : 2*vertexFormatSizes[sel]; - } - - if(fmt & 0xE000000) - assert(0 && "can't instance tangents or whatever it is"); -} - -void -defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header) -{ - uint32 *vertexFmt = getVertexFmt(geo); - uint32 fmt = *vertexFmt; - assert(fmt != 0); - uint8 *src = (uint8*)header->vertexBuffer; - - uint32 sel = fmt & 0xF; - uninstV3d(v3dFormatMap[sel], geo->morphTargets[0].vertices, src, - header->numVertices, header->stride); - src += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; - - sel = (fmt >> 4) & 0xF; - if(sel){ - uninstV3d(v3dFormatMap[sel], geo->morphTargets[0].normals, src, - header->numVertices, header->stride); - src += sel == 4 ? 4 : 3*vertexFormatSizes[sel]; - } - - if(fmt & 0x1000000){ - uninstColor(VERT_ARGB, geo->colors, src, - header->numVertices, header->stride); - src += 4; - } - - for(int i = 0; i < 4; i++){ - sel = (fmt >> (i*4 + 8)) & 0xF; - if(sel == 0) - break; - uninstV2d(v2dFormatMap[sel], geo->texCoords[i], src, - header->numVertices, header->stride); - src += sel == 4 ? 4 : 2*vertexFormatSizes[sel]; - } -} - -ObjPipeline* -makeDefaultPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - return pipe; -} - -// Skin plugin - -struct NativeSkin -{ - int32 table1[256]; // maps indices to bones - int32 table2[256]; // maps bones to indices - int32 numUsedBones; - void *vertexBuffer; - int32 stride; -}; - -Stream* -readNativeSkin(Stream *stream, int32, void *object, int32 offset) -{ - Geometry *geometry = (Geometry*)object; - uint32 vers, platform; - if(!findChunk(stream, ID_STRUCT, nil, &vers)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_XBOX){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - if(vers < 0x35000){ - RWERROR((ERR_VERSION, vers)); - return nil; - } - - Skin *skin = new Skin; - *PLUGINOFFSET(Skin*, geometry, offset) = skin; - - int32 numBones = stream->readI32(); - skin->init(numBones, 0, 0); - NativeSkin *natskin = new NativeSkin; - skin->platformData = natskin; - stream->read(natskin->table1, 256*sizeof(int32)); - stream->read(natskin->table2, 256*sizeof(int32)); - natskin->numUsedBones = stream->readI32(); - skin->numWeights = stream->readI32(); - stream->seek(4); // skip pointer to vertexBuffer - natskin->stride = stream->readI32(); - int32 size = geometry->numVertices*natskin->stride; - natskin->vertexBuffer = new uint8[size]; - stream->read(natskin->vertexBuffer, size); - stream->read(skin->inverseMatrices, skin->numBones*64); - - // no split skins in GTA - stream->seek(12); - return stream; -} - -Stream* -writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset) -{ - Geometry *geometry = (Geometry*)object; - Skin *skin = *PLUGINOFFSET(Skin*, object, offset); - assert(skin->platformData); - assert(rw::version >= 0x35000 && "can't handle native xbox skin < 0x35000"); - NativeSkin *natskin = (NativeSkin*)skin->platformData; - - writeChunkHeader(stream, ID_STRUCT, len-12); - stream->writeU32(PLATFORM_XBOX); - stream->writeI32(skin->numBones); - stream->write(natskin->table1, 256*sizeof(int32)); - stream->write(natskin->table2, 256*sizeof(int32)); - stream->writeI32(natskin->numUsedBones); - stream->writeI32(skin->numWeights); - stream->writeU32(0xBADEAFFE); // pointer to vertexBuffer - stream->writeI32(natskin->stride); - stream->write(natskin->vertexBuffer, - geometry->numVertices*natskin->stride); - stream->write(skin->inverseMatrices, skin->numBones*64); - int32 buffer[3] = { 0, 0, 0}; - stream->write(buffer, 12); - return stream; -} - -int32 -getSizeNativeSkin(void *object, int32 offset) -{ - Geometry *geometry = (Geometry*)object; - Skin *skin = *PLUGINOFFSET(Skin*, object, offset); - if(skin == nil) - return -1; - if(skin->platformData == nil) - return -1; - NativeSkin *natskin = (NativeSkin*)skin->platformData; - return 12 + 8 + 2*256*4 + 4*4 + - natskin->stride*geometry->numVertices + skin->numBones*64 + 12; -} - -void -skinInstanceCB(Geometry *geo, InstanceDataHeader *header) -{ - defaultInstanceCB(geo, header); - - Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); - if(skin == nil) - return; - NativeSkin *natskin = new NativeSkin; - skin->platformData = natskin; - - natskin->numUsedBones = skin->numUsedBones; - memset(natskin->table1, 0xFF, sizeof(natskin->table1)); - memset(natskin->table2, 0x00, sizeof(natskin->table2)); - for(int32 i = 0; i < skin->numUsedBones; i++){ - natskin->table1[i] = skin->usedBones[i]; - natskin->table2[skin->usedBones[i]] = i; - } - - natskin->stride = 3*skin->numWeights; - uint8 *vbuf = new uint8[header->numVertices*natskin->stride]; - natskin->vertexBuffer = vbuf; - - int32 w[4]; - int sum; - float *weights = skin->weights; - uint8 *p = vbuf; - int32 numVertices = header->numVertices; - while(numVertices--){ - sum = 0; - for(int i = 1; i < skin->numWeights; i++){ - w[i] = weights[i]*255.0f + 0.5f; - sum += w[i]; - } - w[0] = 255 - sum; - for(int i = 0; i < skin->numWeights; i++) - p[i] = w[i]; - p += natskin->stride; - weights += 4; - } - - numVertices = header->numVertices; - p = vbuf + skin->numWeights; - uint8 *indices = skin->indices; - uint16 *idx; - while(numVertices--){ - idx = (uint16*)p; - for(int i = 0; i < skin->numWeights; i++) - idx[i] = 3*natskin->table2[indices[i]]; - p += natskin->stride; - indices += 4; - } -} - -void -skinUninstanceCB(Geometry *geo, InstanceDataHeader *header) -{ - defaultUninstanceCB(geo, header); - - Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset); - if(skin == nil) - return; - NativeSkin *natskin = (NativeSkin*)skin->platformData; - - uint8 *data = skin->data; - float *invMats = skin->inverseMatrices; - skin->init(skin->numBones, natskin->numUsedBones, geo->numVertices); - memcpy(skin->inverseMatrices, invMats, skin->numBones*64); - delete[] data; - - for(int32 j = 0; j < skin->numUsedBones; j++) - skin->usedBones[j] = natskin->table1[j]; - - float *weights = skin->weights; - uint8 *indices = skin->indices; - uint8 *p = (uint8*)natskin->vertexBuffer; - int32 numVertices = header->numVertices; - float w[4]; - uint8 i[4]; - uint16 *ip; - while(numVertices--){ - w[0] = w[1] = w[2] = w[3] = 0.0f; - i[0] = i[1] = i[2] = i[3] = 0; - - for(int32 j = 0; j < skin->numWeights; j++) - w[j] = *p++/255.0f; - - ip = (uint16*)p; - for(int32 j = 0; j < skin->numWeights; j++){ - i[j] = natskin->table1[*ip++/3]; - if(w[j] == 0.0f) i[j] = 0; // clean up a bit - } - p = (uint8*)ip; - - for(int32 j = 0; j < 4; j++){ - *weights++ = w[j]; - *indices++ = i[j]; - } - } - - delete[] (uint8*)natskin->vertexBuffer; - delete natskin; -} - -ObjPipeline* -makeSkinPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); - pipe->instanceCB = skinInstanceCB; - pipe->uninstanceCB = skinUninstanceCB; - pipe->pluginID = ID_SKIN; - pipe->pluginData = 1; - return pipe; -} - -ObjPipeline* -makeMatFXPipeline(void) -{ - ObjPipeline *pipe = new ObjPipeline(PLATFORM_XBOX); - pipe->instanceCB = defaultInstanceCB; - pipe->uninstanceCB = defaultUninstanceCB; - pipe->pluginID = ID_MATFX; - pipe->pluginData = 0; - return pipe; -} - -// Vertex Format Plugin - -static int32 vertexFmtOffset; - -uint32 vertexFormatSizes[6] = { - 0, 1, 2, 2, 4, 4 -}; - -uint32* -getVertexFmt(Geometry *g) -{ - return PLUGINOFFSET(uint32, g, vertexFmtOffset); -} - -uint32 -makeVertexFmt(int32 flags, uint32 numTexSets) -{ - if(numTexSets > 4) - numTexSets = 4; - uint32 fmt = 0x5; // FLOAT3 - if(flags & Geometry::NORMALS) - fmt |= 0x40; // NORMPACKED3 - for(uint32 i = 0; i < numTexSets; i++) - fmt |= 0x500 << i*4; // FLOAT2 - if(flags & Geometry::PRELIT) - fmt |= 0x1000000; // D3DCOLOR - return fmt; -} - -uint32 -getVertexFmtStride(uint32 fmt) -{ - uint32 stride = 0; - uint32 v = fmt & 0xF; - uint32 n = (fmt >> 4) & 0xF; - stride += v == 4 ? 4 : 3*vertexFormatSizes[v]; - stride += n == 4 ? 4 : 3*vertexFormatSizes[n]; - if(fmt & 0x1000000) - stride += 4; - for(int i = 0; i < 4; i++){ - uint32 t = (fmt >> (i*4 + 8)) & 0xF; - stride += t == 4 ? 4 : 2*vertexFormatSizes[t]; - } - if(fmt & 0xE000000) - stride += 8; - return stride; -} - -static void* -createVertexFmt(void *object, int32 offset, int32) -{ - *PLUGINOFFSET(uint32, object, offset) = 0; - return object; -} - -static void* -copyVertexFmt(void *dst, void *src, int32 offset, int32) -{ - *PLUGINOFFSET(uint32, dst, offset) = *PLUGINOFFSET(uint32, src, offset); - return dst; -} - -static Stream* -readVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) -{ - uint32 fmt = stream->readU32(); - *PLUGINOFFSET(uint32, object, offset) = fmt; - // TODO: ? create and attach "vertex shader" - return stream; -} - -static Stream* -writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32) -{ - stream->writeI32(*PLUGINOFFSET(uint32, object, offset)); - return stream; -} - -static int32 -getSizeVertexFmt(void*, int32, int32) -{ - if(rw::platform != PLATFORM_XBOX) - return -1; - return 4; -} - -void -registerVertexFormatPlugin(void) -{ - vertexFmtOffset = Geometry::registerPlugin(sizeof(uint32), ID_VERTEXFMT, - createVertexFmt, nil, copyVertexFmt); - Geometry::registerPluginStream(ID_VERTEXFMT, - readVertexFmt, - writeVertexFmt, - getSizeVertexFmt); -} - -// Native Texture and Raster - -int32 nativeRasterOffset; - -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; - } -} - -static 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; -} - -static void -rasterCreate(Raster *raster) -{ - XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); - 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 - }; - if(raster->flags & 0x80) - return; - uint32 format; - if(raster->format & (Raster::PAL4 | Raster::PAL8)){ - format = D3DFMT_P8; - natras->palette = new uint8[4*256]; - }else - format = formatMap[(raster->format >> 8) & 0xF]; - natras->format = 0; - natras->hasAlpha = alphaMap[(raster->format >> 8) & 0xF]; - int32 levels = Raster::calculateNumLevels(raster->width, raster->height); - natras->texture = createTexture(raster->width, raster->height, - raster->format & Raster::MIPMAP ? levels : 1, - format); -} - -static uint8* -rasterLock(Raster *raster, int32 level) -{ - XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); - RasterLevels *levels = (RasterLevels*)natras->texture; - return levels->levels[level].data; -} - -static void -rasterUnlock(Raster*, int32) -{ -} - -static int32 -rasterNumLevels(Raster *raster) -{ - XboxRaster *natras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); - RasterLevels *levels = (RasterLevels*)natras->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; -} - -static void* -createNativeRaster(void *object, int32 offset, int32) -{ - XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset); - raster->texture = nil; - raster->palette = nil; - raster->format = 0; - raster->hasAlpha = 0; - raster->unknownFlag = 0; - return object; -} - -static void* -destroyNativeRaster(void *object, int32, int32) -{ - // TODO: - return object; -} - -static void* -copyNativeRaster(void *dst, void *, int32 offset, int32) -{ - XboxRaster *raster = PLUGINOFFSET(XboxRaster, dst, offset); - raster->texture = nil; - raster->palette = nil; - raster->format = 0; - raster->hasAlpha = 0; - raster->unknownFlag = 0; - return dst; -} - -void -registerNativeRaster(void) -{ - nativeRasterOffset = Raster::registerPlugin(sizeof(XboxRaster), - 0x12340000 | PLATFORM_XBOX, - createNativeRaster, - destroyNativeRaster, - copyNativeRaster); - driver[PLATFORM_XBOX].rasterNativeOffset = nativeRasterOffset; - driver[PLATFORM_XBOX].rasterCreate = rasterCreate; - driver[PLATFORM_XBOX].rasterLock = rasterLock; - driver[PLATFORM_XBOX].rasterUnlock = rasterUnlock; - driver[PLATFORM_XBOX].rasterNumLevels = rasterNumLevels; -} - -Texture* -readNativeTexture(Stream *stream) -{ - uint32 vers, platform; - if(!findChunk(stream, ID_STRUCT, nil, &vers)){ - RWERROR((ERR_CHUNK, "STRUCT")) - return nil; - } - platform = stream->readU32(); - if(platform != PLATFORM_XBOX){ - RWERROR((ERR_PLATFORM, platform)); - return nil; - } - if(version < 0x34001){ - RWERROR((ERR_VERSION, version)); - return nil; - } - Texture *tex = Texture::create(nil); - if(tex == nil) - return nil; - - - // 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 = Raster::create(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->height, - raster->format & Raster::MIPMAP ? numLevels : 1, - ras->format); - raster->flags &= ~0x80; - }else - raster = Raster::create(width, height, depth, format | type, PLATFORM_XBOX); - XboxRaster *ras = PLUGINOFFSET(XboxRaster, raster, nativeRasterOffset); - tex->raster = raster; - - if(raster->format & Raster::PAL4) - stream->read(ras->palette, 4*32); - else if(raster->format & Raster::PAL8) - stream->read(ras->palette, 4*256); - - // 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); - - if(raster->format & Raster::PAL4) - stream->write(ras->palette, 4*32); - else if(raster->format & Raster::PAL8) - stream->write(ras->palette, 4*256); - - // 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; - if(tex->raster->format & Raster::PAL4) - size += 4*32; - else if(tex->raster->format & Raster::PAL8) - size += 4*256; - size += 12 + tex->streamGetPluginSize(); - return size; -} - -} -}