mirror of
https://github.com/aap/librw.git
synced 2024-11-28 14:45:41 +00:00
more error handling
This commit is contained in:
parent
1bb17b3094
commit
634a96be07
56
src/anim.cpp
56
src/anim.cpp
@ -4,12 +4,13 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwplugins.h"
|
||||
|
||||
using namespace std;
|
||||
#define PLUGIN_ID 2 // ?
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -21,7 +22,7 @@ void
|
||||
registerAnimInterpolatorInfo(AnimInterpolatorInfo *interpInfo)
|
||||
{
|
||||
for(int32 i = 0; i < MAXINTERPINFO; i++)
|
||||
if(interpInfoList[i] == NULL){
|
||||
if(interpInfoList[i] == nil){
|
||||
interpInfoList[i] = interpInfo;
|
||||
return;
|
||||
}
|
||||
@ -35,7 +36,7 @@ findAnimInterpolatorInfo(int32 id)
|
||||
if(interpInfoList[i] && interpInfoList[i]->id == id)
|
||||
return interpInfoList[i];
|
||||
}
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
Animation*
|
||||
@ -65,7 +66,8 @@ Animation*
|
||||
Animation::streamRead(Stream *stream)
|
||||
{
|
||||
Animation *anim;
|
||||
assert(stream->readI32() == 0x100);
|
||||
if(stream->readI32() != 0x100)
|
||||
return nil;
|
||||
int32 typeID = stream->readI32();
|
||||
AnimInterpolatorInfo *interpInfo = findAnimInterpolatorInfo(typeID);
|
||||
int32 numFrames = stream->readI32();
|
||||
@ -156,7 +158,11 @@ UVAnimDictionary *currentUVAnimDictionary;
|
||||
UVAnimDictionary*
|
||||
UVAnimDictionary::create(void)
|
||||
{
|
||||
UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(*dict));
|
||||
UVAnimDictionary *dict = (UVAnimDictionary*)malloc(sizeof(UVAnimDictionary));
|
||||
if(dict == nil){
|
||||
RWERROR((ERR_ALLOC, sizeof(UVAnimDictionary)));
|
||||
return nil;
|
||||
}
|
||||
dict->animations.init();
|
||||
return dict;
|
||||
}
|
||||
@ -177,7 +183,6 @@ void
|
||||
UVAnimDictionary::add(Animation *anim)
|
||||
{
|
||||
UVAnimDictEntry *de = new UVAnimDictEntry;
|
||||
UVAnimCustomData *custom = (UVAnimCustomData*)anim->customData;
|
||||
de->anim = anim;
|
||||
this->animations.append(&de->inDict);
|
||||
}
|
||||
@ -185,14 +190,29 @@ UVAnimDictionary::add(Animation *anim)
|
||||
UVAnimDictionary*
|
||||
UVAnimDictionary::streamRead(Stream *stream)
|
||||
{
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
UVAnimDictionary *dict = UVAnimDictionary::create();
|
||||
if(dict == nil)
|
||||
return nil;
|
||||
int32 numAnims = stream->readI32();
|
||||
Animation *anim;
|
||||
for(int32 i = 0; i < numAnims; i++){
|
||||
assert(findChunk(stream, ID_ANIMANIMATION, NULL, NULL));
|
||||
dict->add(Animation::streamRead(stream));
|
||||
if(!findChunk(stream, ID_ANIMANIMATION, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "ANIMANIMATION"));
|
||||
goto fail;
|
||||
}
|
||||
anim = Animation::streamRead(stream);
|
||||
if(anim == nil)
|
||||
goto fail;
|
||||
dict->add(anim);
|
||||
}
|
||||
return dict;
|
||||
fail:
|
||||
dict->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -214,7 +234,6 @@ uint32
|
||||
UVAnimDictionary::streamGetSize(void)
|
||||
{
|
||||
uint32 size = 12 + 4;
|
||||
int32 numAnims = this->count();
|
||||
FORLIST(lnk, this->animations){
|
||||
UVAnimDictEntry *de = UVAnimDictEntry::fromDict(lnk);
|
||||
size += 12 + de->anim->streamGetSize();
|
||||
@ -231,7 +250,7 @@ UVAnimDictionary::find(const char *name)
|
||||
if(strncmp_ci(custom->name, name, 32) == 0)
|
||||
return anim;
|
||||
}
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -358,21 +377,24 @@ makeDummyAnimation(const char *name)
|
||||
return anim;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
char name[32];
|
||||
uint32 mask = stream->readI32();
|
||||
uint32 bit = 1;
|
||||
for(int32 i = 0; i < 8; i++){
|
||||
if(mask & bit){
|
||||
stream->read(name, 32);
|
||||
Animation *anim = NULL;
|
||||
Animation *anim = nil;
|
||||
if(currentUVAnimDictionary)
|
||||
anim = currentUVAnimDictionary->find(name);
|
||||
if(anim == NULL){
|
||||
if(anim == nil){
|
||||
anim = makeDummyAnimation(name);
|
||||
if(currentUVAnimDictionary)
|
||||
currentUVAnimDictionary->add(anim);
|
||||
@ -384,9 +406,10 @@ readUVAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
}
|
||||
bit <<= 1;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeUVAnim(Stream *stream, int32 size, void *object, int32 offset, int32)
|
||||
{
|
||||
UVAnim *uvanim = PLUGINOFFSET(UVAnim, object, offset);
|
||||
@ -406,6 +429,7 @@ writeUVAnim(Stream *stream, int32 size, void *object, int32 offset, int32)
|
||||
stream->write(custom->name, 32);
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
|
@ -6,3 +6,7 @@ ECODE(ERR_FILE,
|
||||
"Couldn't open file %s")
|
||||
ECODE(ERR_CHUNK,
|
||||
"Couldn't find chunk %s")
|
||||
ECODE(ERR_VERSION,
|
||||
"Unsupported version %X")
|
||||
ECODE(ERR_PLATFORM,
|
||||
"Unsupported platform %d")
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
@ -74,6 +72,8 @@ Clump::streamRead(Stream *stream)
|
||||
uint32 length, version;
|
||||
int32 buf[3];
|
||||
Clump *clump;
|
||||
int32 numGeometries;
|
||||
Geometry **geometryList;
|
||||
|
||||
if(!findChunk(stream, ID_STRUCT, &length, &version)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
@ -103,8 +103,8 @@ Clump::streamRead(Stream *stream)
|
||||
clump->setFrame(frmlst.frames[0]);
|
||||
|
||||
// Geometry list
|
||||
int32 numGeometries = 0;
|
||||
Geometry **geometryList = nil;
|
||||
numGeometries = 0;
|
||||
geometryList = nil;
|
||||
if(version >= 0x30400){
|
||||
if(!findChunk(stream, ID_GEOMETRYLIST, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "GEOMETRYLIST"));
|
||||
@ -502,13 +502,14 @@ Atomic::defaultRenderCB(Atomic *atomic)
|
||||
|
||||
// Atomic Rights plugin
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readAtomicRights(Stream *stream, int32, void *, int32, int32)
|
||||
{
|
||||
stream->read(atomicRights, 8);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Atomic *atomic = (Atomic*)object;
|
||||
@ -516,6 +517,7 @@ writeAtomicRights(Stream *stream, int32, void *object, int32, int32)
|
||||
buffer[0] = atomic->pipeline->pluginID;
|
||||
buffer[1] = atomic->pipeline->pluginData;
|
||||
stream->write(buffer, 8);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
@ -562,7 +560,6 @@ static void*
|
||||
createNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
D3dRaster *raster = PLUGINOFFSET(D3dRaster, object, offset);
|
||||
new (raster) D3dRaster;
|
||||
raster->texture = NULL;
|
||||
raster->palette = NULL;
|
||||
raster->format = 0;
|
||||
|
73
src/d3d8.cpp
73
src/d3d8.cpp
@ -4,6 +4,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
@ -11,7 +12,7 @@
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3d8.h"
|
||||
|
||||
using namespace std;
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
namespace d3d8 {
|
||||
@ -51,11 +52,12 @@ void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_D3D8);
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_D3D8)
|
||||
return object;
|
||||
InstanceDataHeader *header =
|
||||
(InstanceDataHeader*)geometry->instData;
|
||||
geometry->instData = NULL;
|
||||
geometry->instData = nil;
|
||||
InstanceData *inst = header->inst;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
deleteObject(inst->indexBuffer);
|
||||
@ -67,13 +69,20 @@ destroyNativeData(void *object, int32, int32)
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 vers;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
|
||||
assert(stream->readU32() == PLATFORM_D3D8);
|
||||
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;
|
||||
@ -96,8 +105,8 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
inst->material = geometry->materialList[matid];
|
||||
inst->vertexShader = *(uint32*)p; p += 4;
|
||||
inst->primType = *(uint32*)p; p += 4;
|
||||
inst->indexBuffer = NULL; p += 4;
|
||||
inst->vertexBuffer = NULL; p += 4;
|
||||
inst->indexBuffer = nil; p += 4;
|
||||
inst->vertexBuffer = nil; p += 4;
|
||||
inst->baseIndex = 0; p += 4;
|
||||
inst->vertexAlpha = *p++;
|
||||
inst->managed = 0; p++;
|
||||
@ -121,15 +130,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
|
||||
inst++;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_D3D8);
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_D3D8)
|
||||
return stream;
|
||||
stream->writeU32(PLATFORM_D3D8);
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
|
||||
@ -172,14 +183,16 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
unlockVertices(inst->vertexBuffer);
|
||||
inst++;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
int32
|
||||
getSizeNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_D3D8);
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_D3D8)
|
||||
return 0;
|
||||
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
InstanceData *inst = header->inst;
|
||||
@ -195,7 +208,7 @@ void
|
||||
registerNativeDataPlugin(void)
|
||||
{
|
||||
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
||||
NULL, destroyNativeData, NULL);
|
||||
nil, destroyNativeData, nil);
|
||||
Geometry::registerPluginStream(ID_NATIVEDATA,
|
||||
readNativeData,
|
||||
writeNativeData,
|
||||
@ -229,7 +242,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
inst->material = mesh->material;
|
||||
inst->vertexShader = 0;
|
||||
inst->primType = meshh->flags == 1 ? D3DPT_TRIANGLESTRIP : D3DPT_TRIANGLELIST;
|
||||
inst->vertexBuffer = NULL;
|
||||
inst->vertexBuffer = nil;
|
||||
inst->baseIndex = 0; // (maybe) not used by us
|
||||
inst->vertexAlpha = 0;
|
||||
inst->managed = 0;
|
||||
@ -257,7 +270,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
Geometry *geo = atomic->geometry;
|
||||
if((geo->geoflags & Geometry::NATIVE) == 0)
|
||||
return;
|
||||
assert(geo->instData != NULL);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_D3D8);
|
||||
geo->geoflags &= ~Geometry::NATIVE;
|
||||
geo->allocateData();
|
||||
@ -290,7 +303,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
Geometry *geo = atomic->geometry;
|
||||
if((geo->geoflags & Geometry::NATIVE) == 0)
|
||||
pipe->instance(atomic);
|
||||
assert(geo->instData != NULL);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_D3D8);
|
||||
if(pipe->renderCB)
|
||||
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
|
||||
@ -302,9 +315,9 @@ ObjPipeline::ObjPipeline(uint32 platform)
|
||||
this->impl.instance = d3d8::instance;
|
||||
this->impl.uninstance = d3d8::uninstance;
|
||||
this->impl.render = d3d8::render;
|
||||
this->instanceCB = NULL;
|
||||
this->uninstanceCB = NULL;
|
||||
this->renderCB = NULL;
|
||||
this->instanceCB = nil;
|
||||
this->uninstanceCB = nil;
|
||||
this->renderCB = nil;
|
||||
}
|
||||
|
||||
void
|
||||
@ -463,9 +476,19 @@ readAsImage(Stream *stream, int32 width, int32 height, int32 depth, int32 format
|
||||
Texture*
|
||||
readNativeTexture(Stream *stream)
|
||||
{
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
assert(stream->readU32() == PLATFORM_D3D8);
|
||||
Texture *tex = Texture::create(NULL);
|
||||
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();
|
||||
|
81
src/d3d9.cpp
81
src/d3d9.cpp
@ -4,6 +4,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
@ -11,6 +12,8 @@
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3d9.h"
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
namespace d3d9 {
|
||||
using namespace d3d;
|
||||
@ -70,11 +73,12 @@ void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_D3D9);
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_D3D9)
|
||||
return object;
|
||||
InstanceDataHeader *header =
|
||||
(InstanceDataHeader*)geometry->instData;
|
||||
geometry->instData = NULL;
|
||||
geometry->instData = nil;
|
||||
deleteObject(header->vertexDeclaration);
|
||||
deleteObject(header->indexBuffer);
|
||||
deleteObject(header->vertexStream[0].vertexBuffer);
|
||||
@ -84,13 +88,20 @@ destroyNativeData(void *object, int32, int32)
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 vers;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
|
||||
assert(stream->readU32() == PLATFORM_D3D9);
|
||||
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;
|
||||
@ -101,11 +112,11 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
uint8 *p = data;
|
||||
header->serialNumber = *(uint32*)p; p += 4;
|
||||
header->numMeshes = *(uint32*)p; p += 4;
|
||||
header->indexBuffer = NULL; 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 = NULL; 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];
|
||||
@ -117,7 +128,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
uint32 matid = *(uint32*)p; p += 4;
|
||||
inst->material = geometry->materialList[matid];
|
||||
inst->vertexAlpha = *(bool32*)p; p += 4;
|
||||
inst->vertexShader = NULL; p += 4;
|
||||
inst->vertexShader = nil; p += 4;
|
||||
inst->baseIndex = 0; p += 4;
|
||||
inst->numVertices = *(uint32*)p; p += 4;
|
||||
inst->startIndex = *(uint32*)p; p += 4;
|
||||
@ -147,7 +158,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
s->managed = *p++;
|
||||
s->dynamicLock = *p++;
|
||||
|
||||
if(s->vertexBuffer == NULL)
|
||||
if(s->vertexBuffer == nil)
|
||||
continue;
|
||||
// TODO: unset managed flag when using morph targets.
|
||||
// also uses different buffer type and locks differently
|
||||
@ -165,15 +176,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_D3D9);
|
||||
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;
|
||||
@ -228,7 +241,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
*p++ = s->dynamicLock;
|
||||
stream->write(data, 16);
|
||||
|
||||
if(s->vertexBuffer == NULL)
|
||||
if(s->vertexBuffer == nil)
|
||||
continue;
|
||||
uint8 *verts = lockVertices(s->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
|
||||
stream->write(verts, s->stride*header->totalNumVertex);
|
||||
@ -236,17 +249,19 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
return stream;
|
||||
}
|
||||
|
||||
int32
|
||||
getSizeNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_D3D9);
|
||||
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, NULL);
|
||||
uint32 numElt = getDeclaration(header->vertexDeclaration, nil);
|
||||
size += 4 + numElt*8;
|
||||
size += 2*header->totalNumIndex;
|
||||
size += 0x10 + header->vertexStream[0].stride*header->totalNumVertex;
|
||||
@ -258,7 +273,7 @@ void
|
||||
registerNativeDataPlugin(void)
|
||||
{
|
||||
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
||||
NULL, destroyNativeData, NULL);
|
||||
nil, destroyNativeData, nil);
|
||||
Geometry::registerPluginStream(ID_NATIVEDATA,
|
||||
readNativeData,
|
||||
writeNativeData,
|
||||
@ -298,7 +313,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
inst->numIndex = mesh->numIndices;
|
||||
inst->material = mesh->material;
|
||||
inst->vertexAlpha = 0;
|
||||
inst->vertexShader = NULL;
|
||||
inst->vertexShader = nil;
|
||||
inst->baseIndex = inst->minVert;
|
||||
inst->startIndex = startindex;
|
||||
inst->numPrimitives = header->primType == D3DPT_TRIANGLESTRIP ? inst->numIndex-2 : inst->numIndex/3;
|
||||
@ -325,7 +340,7 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
Geometry *geo = atomic->geometry;
|
||||
if((geo->geoflags & Geometry::NATIVE) == 0)
|
||||
return;
|
||||
assert(geo->instData != NULL);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_D3D9);
|
||||
geo->geoflags &= ~Geometry::NATIVE;
|
||||
geo->allocateData();
|
||||
@ -358,7 +373,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
Geometry *geo = atomic->geometry;
|
||||
if((geo->geoflags & Geometry::NATIVE) == 0)
|
||||
pipe->instance(atomic);
|
||||
assert(geo->instData != NULL);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_D3D9);
|
||||
if(pipe->renderCB)
|
||||
pipe->renderCB(atomic, (InstanceDataHeader*)geo->instData);
|
||||
@ -370,9 +385,9 @@ ObjPipeline::ObjPipeline(uint32 platform)
|
||||
this->impl.instance = d3d9::instance;
|
||||
this->impl.uninstance = d3d9::uninstance;
|
||||
this->impl.render = d3d9::render;
|
||||
this->instanceCB = NULL;
|
||||
this->uninstanceCB = NULL;
|
||||
this->renderCB = NULL;
|
||||
this->instanceCB = nil;
|
||||
this->uninstanceCB = nil;
|
||||
this->renderCB = nil;
|
||||
}
|
||||
|
||||
void
|
||||
@ -571,9 +586,19 @@ makeMatFXPipeline(void)
|
||||
Texture*
|
||||
readNativeTexture(Stream *stream)
|
||||
{
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
assert(stream->readU32() == PLATFORM_D3D9);
|
||||
Texture *tex = Texture::create(NULL);
|
||||
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();
|
||||
|
@ -1,14 +1,11 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
@ -260,15 +257,15 @@ FrameList_::streamRead(Stream *stream)
|
||||
return nil;
|
||||
}
|
||||
this->numFrames = stream->readI32();
|
||||
Frame **frameList = (Frame**)malloc(this->numFrames*sizeof(Frame*));
|
||||
if(frameList == nil){
|
||||
this->frames = (Frame**)malloc(this->numFrames*sizeof(Frame*));
|
||||
if(this->frames == nil){
|
||||
RWERROR((ERR_ALLOC, this->numFrames*sizeof(Frame*)));
|
||||
return nil;
|
||||
}
|
||||
for(int32 i = 0; i < this->numFrames; i++){
|
||||
Frame *f;
|
||||
stream->read(&buf, sizeof(buf));
|
||||
frameList[i] = f = Frame::create();
|
||||
this->frames[i] = f = Frame::create();
|
||||
if(f == nil){
|
||||
// TODO: clean up frames?
|
||||
free(this->frames);
|
||||
@ -284,10 +281,10 @@ FrameList_::streamRead(Stream *stream)
|
||||
f->matrix.posw = 1.0f;
|
||||
//f->matflag = buf.matflag;
|
||||
if(buf.parent >= 0)
|
||||
frameList[buf.parent]->addChild(f);
|
||||
this->frames[buf.parent]->addChild(f);
|
||||
}
|
||||
for(int32 i = 0; i < this->numFrames; i++)
|
||||
frameList[i]->streamReadPlugins(stream);
|
||||
this->frames[i]->streamReadPlugins(stream);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -334,6 +331,7 @@ FrameList_::streamGetSize(Frame *f)
|
||||
int32 numFrames = f->count();
|
||||
uint32 size = 12 + 12 + 4 + numFrames*(sizeof(FrameStreamData)+12);
|
||||
sizeCB(f, (void*)&size);
|
||||
return size;
|
||||
}
|
||||
|
||||
Frame**
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace rw {
|
||||
|
||||
Geometry*
|
||||
@ -699,14 +697,15 @@ Material::streamGetSize(void)
|
||||
|
||||
// Material Rights plugin
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readMaterialRights(Stream *stream, int32, void *, int32, int32)
|
||||
{
|
||||
stream->read(materialRights, 8);
|
||||
// printf("materialrights: %X %X\n", materialRights[0], materialRights[1]);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeMaterialRights(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Material *material = (Material*)object;
|
||||
@ -714,6 +713,7 @@ writeMaterialRights(Stream *stream, int32, void *object, int32, int32)
|
||||
buffer[0] = material->pipeline->pluginID;
|
||||
buffer[1] = material->pipeline->pluginData;
|
||||
stream->write(buffer, 8);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -721,7 +721,7 @@ getSizeMaterialRights(void *object, int32, int32)
|
||||
{
|
||||
Material *material = (Material*)object;
|
||||
if(material->pipeline == nil || material->pipeline->pluginID == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
return 8;
|
||||
}
|
||||
|
||||
|
133
src/image.cpp
133
src/image.cpp
@ -4,6 +4,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
@ -19,7 +20,7 @@
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -33,7 +34,10 @@ TexDictionary*
|
||||
TexDictionary::create(void)
|
||||
{
|
||||
TexDictionary *dict = (TexDictionary*)malloc(PluginBase::s_size);
|
||||
assert(dict != NULL);
|
||||
if(dict == nil){
|
||||
RWERROR((ERR_ALLOC, PluginBase::s_size));
|
||||
return nil;
|
||||
}
|
||||
dict->object.init(TexDictionary::ID, 0);
|
||||
dict->textures.init();
|
||||
dict->constructPlugins();
|
||||
@ -57,24 +61,38 @@ TexDictionary::find(const char *name)
|
||||
if(strncmp_ci(tex->name, name, 32) == 0)
|
||||
return tex;
|
||||
}
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
TexDictionary*
|
||||
TexDictionary::streamRead(Stream *stream)
|
||||
{
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
int32 numTex = stream->readI16();
|
||||
stream->readI16(); // some platform id (1 = d3d8, 2 = d3d9, 5 = opengl,
|
||||
// 6 = ps2, 8 = xbox)
|
||||
TexDictionary *txd = TexDictionary::create();
|
||||
if(txd == nil)
|
||||
return nil;
|
||||
Texture *tex;
|
||||
for(int32 i = 0; i < numTex; i++){
|
||||
assert(findChunk(stream, ID_TEXTURENATIVE, NULL, NULL));
|
||||
Texture *tex = Texture::streamReadNative(stream);
|
||||
if(!findChunk(stream, ID_TEXTURENATIVE, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "TEXTURENATIVE"));
|
||||
goto fail;
|
||||
}
|
||||
tex = Texture::streamReadNative(stream);
|
||||
if(tex == nil)
|
||||
goto fail;
|
||||
txd->add(tex);
|
||||
}
|
||||
txd->streamReadPlugins(stream);
|
||||
if(txd->streamReadPlugins(stream))
|
||||
return txd;
|
||||
fail:
|
||||
txd->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
@ -116,8 +134,11 @@ Texture*
|
||||
Texture::create(Raster *raster)
|
||||
{
|
||||
Texture *tex = (Texture*)malloc(PluginBase::s_size);
|
||||
assert(tex != NULL);
|
||||
tex->dict = NULL;
|
||||
if(tex == nil){
|
||||
RWERROR((ERR_ALLOC, PluginBase::s_size));
|
||||
return nil;
|
||||
}
|
||||
tex->dict = nil;
|
||||
tex->inDict.init();
|
||||
memset(tex->name, 0, 32);
|
||||
memset(tex->mask, 0, 32);
|
||||
@ -148,7 +169,7 @@ defaultFindCB(const char *name)
|
||||
if(currentTexDictionary)
|
||||
return currentTexDictionary->find(name);
|
||||
// TODO: RW searches *all* TXDs otherwise
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
static Texture*
|
||||
@ -169,14 +190,14 @@ defaultReadCB(const char *name, const char *mask)
|
||||
img->destroy();
|
||||
return tex;
|
||||
}else
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
Texture*
|
||||
Texture::read(const char *name, const char *mask)
|
||||
{
|
||||
(void)mask;
|
||||
Raster *raster = NULL;
|
||||
Raster *raster = nil;
|
||||
Texture *tex;
|
||||
|
||||
if(tex = Texture::findCB(name)){
|
||||
@ -185,11 +206,13 @@ Texture::read(const char *name, const char *mask)
|
||||
}
|
||||
if(loadTextures){
|
||||
tex = Texture::readCB(name, mask);
|
||||
if(tex == NULL)
|
||||
if(tex == nil)
|
||||
goto dummytex;
|
||||
}else{
|
||||
dummytex:
|
||||
tex = Texture::create(NULL);
|
||||
tex = Texture::create(nil);
|
||||
if(tex == nil)
|
||||
return nil;
|
||||
strncpy(tex->name, name, 32);
|
||||
if(mask)
|
||||
strncpy(tex->mask, mask, 32);
|
||||
@ -209,26 +232,38 @@ Texture::streamRead(Stream *stream)
|
||||
{
|
||||
uint32 length;
|
||||
char name[128], mask[128];
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
uint32 filterAddressing = stream->readU32();
|
||||
// TODO: if V addressing is 0, copy U
|
||||
// if using mipmap filter mode, set automipmapping,
|
||||
// if 0x10000 is set, set mipmapping
|
||||
|
||||
assert(findChunk(stream, ID_STRING, &length, NULL));
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
return nil;
|
||||
}
|
||||
stream->read(name, length);
|
||||
|
||||
assert(findChunk(stream, ID_STRING, &length, NULL));
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
return nil;
|
||||
}
|
||||
stream->read(mask, length);
|
||||
|
||||
Texture *tex = Texture::read(name, mask);
|
||||
if(tex == nil)
|
||||
return nil;
|
||||
if(tex->refCount == 1)
|
||||
tex->filterAddressing = filterAddressing;
|
||||
tex->refCount++; // TODO: RW doesn't do this, why?
|
||||
|
||||
tex->streamReadPlugins(stream);
|
||||
|
||||
if(tex->streamReadPlugins(stream))
|
||||
return tex;
|
||||
tex->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -271,7 +306,10 @@ Texture::streamGetSize(void)
|
||||
Texture*
|
||||
Texture::streamReadNative(Stream *stream)
|
||||
{
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
uint32 platform = stream->readU32();
|
||||
stream->seek(-16);
|
||||
if(platform == FOURCC_PS2)
|
||||
@ -283,7 +321,7 @@ Texture::streamReadNative(Stream *stream)
|
||||
if(platform == PLATFORM_XBOX)
|
||||
return xbox::readNativeTexture(stream);
|
||||
assert(0 && "unsupported platform");
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
@ -323,15 +361,18 @@ Texture::streamGetSizeNative(void)
|
||||
Image*
|
||||
Image::create(int32 width, int32 height, int32 depth)
|
||||
{
|
||||
Image *img = (Image*)malloc(sizeof(*img));
|
||||
assert(img != NULL);
|
||||
Image *img = (Image*)malloc(sizeof(Image));
|
||||
if(img == nil){
|
||||
RWERROR((ERR_ALLOC, sizeof(Image)));
|
||||
return nil;
|
||||
}
|
||||
img->flags = 0;
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
img->depth = depth;
|
||||
img->stride = 0;
|
||||
img->pixels = NULL;
|
||||
img->palette = NULL;
|
||||
img->pixels = nil;
|
||||
img->palette = nil;
|
||||
return img;
|
||||
}
|
||||
|
||||
@ -345,12 +386,12 @@ Image::destroy(void)
|
||||
void
|
||||
Image::allocate(void)
|
||||
{
|
||||
if(this->pixels == NULL){
|
||||
if(this->pixels == nil){
|
||||
this->stride = this->width*(this->depth==4 ? 1 : this->depth/8);
|
||||
this->pixels = new uint8[this->stride*this->height];
|
||||
this->flags |= 1;
|
||||
}
|
||||
if(this->palette == NULL){
|
||||
if(this->palette == nil){
|
||||
if(this->depth == 4 || this->depth == 8)
|
||||
this->palette = new uint8[(this->depth==4? 16 : 256)*4];
|
||||
this->flags |= 2;
|
||||
@ -401,7 +442,7 @@ Image::hasAlpha(void)
|
||||
return ret != 0xFF;
|
||||
}
|
||||
|
||||
static char *searchPaths = NULL;
|
||||
static char *searchPaths = nil;
|
||||
int numSearchPaths = 0;
|
||||
|
||||
void
|
||||
@ -413,7 +454,7 @@ Image::setSearchPath(const char *path)
|
||||
if(path)
|
||||
searchPaths = p = strdup(path);
|
||||
else{
|
||||
searchPaths = NULL;
|
||||
searchPaths = nil;
|
||||
return;
|
||||
}
|
||||
while(p && *p){
|
||||
@ -448,11 +489,14 @@ Image::getFilename(const char *name)
|
||||
printf("found %s\n", name);
|
||||
return strdup(name);
|
||||
}
|
||||
return NULL;
|
||||
return nil;
|
||||
}else
|
||||
for(int i = 0; i < numSearchPaths; i++){
|
||||
s = (char*)malloc(strlen(p)+len);
|
||||
assert(s != NULL);
|
||||
if(s == nil){
|
||||
RWERROR((ERR_ALLOC, strlen(p)+len));
|
||||
return nil;
|
||||
}
|
||||
strcpy(s, p);
|
||||
strcat(s, name);
|
||||
f = fopen(s, "r");
|
||||
@ -464,7 +508,7 @@ Image::getFilename(const char *name)
|
||||
::free(s);
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
@ -504,11 +548,11 @@ readTGA(const char *afilename)
|
||||
char *filename;
|
||||
int depth = 0, palDepth = 0;
|
||||
filename = Image::getFilename(afilename);
|
||||
if(filename == NULL)
|
||||
return NULL;
|
||||
if(filename == nil)
|
||||
return nil;
|
||||
uint32 length;
|
||||
uint8 *data = getFileContents(filename, &length);
|
||||
assert(data != NULL);
|
||||
assert(data != nil);
|
||||
free(filename);
|
||||
StreamMemory file;
|
||||
file.open(data, length);
|
||||
@ -528,8 +572,8 @@ readTGA(const char *afilename)
|
||||
|
||||
image = Image::create(header.width, header.height, depth);
|
||||
image->allocate();
|
||||
uint8 *palette = header.colorMapType ? image->palette : NULL;
|
||||
uint8 (*color)[4] = NULL;
|
||||
uint8 *palette = header.colorMapType ? image->palette : nil;
|
||||
uint8 (*color)[4] = nil;
|
||||
if(palette){
|
||||
int maxlen = depth == 4 ? 16 : 256;
|
||||
color = (uint8(*)[4])palette;
|
||||
@ -579,10 +623,13 @@ writeTGA(Image *image, const char *filename)
|
||||
{
|
||||
TGAHeader header;
|
||||
StreamFile file;
|
||||
assert(file.open(filename, "wb"));
|
||||
if(!file.open(filename, "wb")){
|
||||
RWERROR((ERR_FILE, filename));
|
||||
return;
|
||||
}
|
||||
header.IDlen = 0;
|
||||
header.imageType = image->palette != NULL ? 1 : 2;
|
||||
header.colorMapType = image->palette != NULL;
|
||||
header.imageType = image->palette != nil ? 1 : 2;
|
||||
header.colorMapType = image->palette != nil;
|
||||
header.colorMapOrigin = 0;
|
||||
header.colorMapLength = image->depth == 4 ? 16 :
|
||||
image->depth == 8 ? 256 : 0;
|
||||
@ -596,7 +643,7 @@ writeTGA(Image *image, const char *filename)
|
||||
file.write(&header, sizeof(header));
|
||||
|
||||
uint8 *pixels = image->pixels;
|
||||
uint8 *palette = header.colorMapType ? image->palette : NULL;
|
||||
uint8 *palette = header.colorMapType ? image->palette : nil;
|
||||
uint8 (*color)[4] = (uint8(*)[4])palette;;
|
||||
if(palette)
|
||||
for(int i = 0; i < header.colorMapLength; i++){
|
||||
@ -633,7 +680,7 @@ Raster*
|
||||
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
|
||||
{
|
||||
Raster *raster = (Raster*)malloc(PluginBase::s_size);
|
||||
assert(raster != NULL);
|
||||
assert(raster != nil);
|
||||
raster->platform = platform ? platform : rw::platform;
|
||||
raster->type = format & 0x7;
|
||||
raster->flags = format & 0xF8;
|
||||
@ -641,7 +688,7 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
|
||||
raster->width = width;
|
||||
raster->height = height;
|
||||
raster->depth = depth;
|
||||
raster->texels = raster->palette = NULL;
|
||||
raster->texels = raster->palette = nil;
|
||||
raster->constructPlugins();
|
||||
|
||||
engine[raster->platform].rasterCreate(raster);
|
||||
|
111
src/plugins.cpp
111
src/plugins.cpp
@ -4,6 +4,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
@ -15,7 +16,7 @@
|
||||
#include "rwd3d9.h"
|
||||
#include "rwwdgl.h"
|
||||
|
||||
using namespace std;
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
|
||||
@ -151,7 +152,7 @@ copyHAnim(void *dst, void *src, int32 offset, int32)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
int32 ver, numNodes;
|
||||
@ -176,9 +177,10 @@ readHAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
delete[] nodeFlags;
|
||||
delete[] nodeIDs;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
HAnimData *hanim = PLUGINOFFSET(HAnimData, object, offset);
|
||||
@ -186,7 +188,7 @@ writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
stream->writeI32(hanim->id);
|
||||
if(hanim->hierarchy == NULL){
|
||||
stream->writeI32(0);
|
||||
return;
|
||||
return stream;
|
||||
}
|
||||
HAnimHierarchy *hier = hanim->hierarchy;
|
||||
stream->writeI32(hier->numNodes);
|
||||
@ -197,6 +199,7 @@ writeHAnim(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
stream->writeI32(hier->nodeInfo[i].index);
|
||||
stream->writeI32(hier->nodeInfo[i].flags);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -270,7 +273,7 @@ registerHAnimPlugin(void)
|
||||
|
||||
// Mesh
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readMesh(Stream *stream, int32 len, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geo = (Geometry*)object;
|
||||
@ -315,9 +318,10 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
|
||||
}
|
||||
mesh++;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeMesh(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geo = (Geometry*)object;
|
||||
@ -352,6 +356,7 @@ writeMesh(Stream *stream, int32, void *object, int32, int32)
|
||||
}
|
||||
mesh++;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -418,7 +423,7 @@ destroyNativeData(void *object, int32 offset, int32 size)
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
||||
{
|
||||
ChunkHeaderInfo header;
|
||||
@ -433,13 +438,13 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
||||
platform = stream->readU32();
|
||||
stream->seek(-16);
|
||||
if(platform == PLATFORM_PS2)
|
||||
ps2::readNativeData(stream, len, object, o, s);
|
||||
return ps2::readNativeData(stream, len, object, o, s);
|
||||
else if(platform == PLATFORM_XBOX)
|
||||
xbox::readNativeData(stream, len, object, o, s);
|
||||
return xbox::readNativeData(stream, len, object, o, s);
|
||||
else if(platform == PLATFORM_D3D8)
|
||||
d3d8::readNativeData(stream, len, object, o, s);
|
||||
return d3d8::readNativeData(stream, len, object, o, s);
|
||||
else if(platform == PLATFORM_D3D9)
|
||||
d3d9::readNativeData(stream, len, object, o, s);
|
||||
return d3d9::readNativeData(stream, len, object, o, s);
|
||||
else{
|
||||
fprintf(stderr, "unknown platform %d\n", platform);
|
||||
stream->seek(len);
|
||||
@ -448,24 +453,26 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
||||
stream->seek(-12);
|
||||
wdgl::readNativeData(stream, len, object, o, s);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
if(geometry->instData == NULL)
|
||||
return;
|
||||
return stream;
|
||||
if(geometry->instData->platform == PLATFORM_PS2)
|
||||
ps2::writeNativeData(stream, len, object, o, s);
|
||||
return ps2::writeNativeData(stream, len, object, o, s);
|
||||
else if(geometry->instData->platform == PLATFORM_WDGL)
|
||||
wdgl::writeNativeData(stream, len, object, o, s);
|
||||
return wdgl::writeNativeData(stream, len, object, o, s);
|
||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
||||
xbox::writeNativeData(stream, len, object, o, s);
|
||||
return xbox::writeNativeData(stream, len, object, o, s);
|
||||
else if(geometry->instData->platform == PLATFORM_D3D8)
|
||||
d3d8::writeNativeData(stream, len, object, o, s);
|
||||
return d3d8::writeNativeData(stream, len, object, o, s);
|
||||
else if(geometry->instData->platform == PLATFORM_D3D9)
|
||||
d3d9::writeNativeData(stream, len, object, o, s);
|
||||
return d3d9::writeNativeData(stream, len, object, o, s);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -473,7 +480,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
if(geometry->instData == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
if(geometry->instData->platform == PLATFORM_PS2)
|
||||
return ps2::getSizeNativeData(object, offset, size);
|
||||
else if(geometry->instData->platform == PLATFORM_WDGL)
|
||||
@ -484,7 +491,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
|
||||
return d3d8::getSizeNativeData(object, offset, size);
|
||||
else if(geometry->instData->platform == PLATFORM_D3D9)
|
||||
return d3d9::getSizeNativeData(object, offset, size);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -548,7 +555,7 @@ copySkin(void *dst, void *src, int32 offset, int32)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
{
|
||||
uint8 header[4];
|
||||
@ -557,14 +564,15 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
if(geometry->instData){
|
||||
// TODO: function pointers
|
||||
if(geometry->instData->platform == PLATFORM_PS2)
|
||||
ps2::readNativeSkin(stream, len, object, offset);
|
||||
return ps2::readNativeSkin(stream, len, object, offset);
|
||||
else if(geometry->instData->platform == PLATFORM_WDGL)
|
||||
wdgl::readNativeSkin(stream, len, object, offset);
|
||||
return wdgl::readNativeSkin(stream, len, object, offset);
|
||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
||||
xbox::readNativeSkin(stream, len, object, offset);
|
||||
else
|
||||
return xbox::readNativeSkin(stream, len, object, offset);
|
||||
else{
|
||||
assert(0 && "unsupported native skin platform");
|
||||
return;
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
stream->read(header, 4); // numBones, numUsedBones, numWeights, unused
|
||||
@ -614,9 +622,10 @@ readSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
// no split skins in GTA
|
||||
if(!oldFormat)
|
||||
stream->seek(12);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
{
|
||||
uint8 header[4];
|
||||
@ -629,9 +638,10 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
wdgl::writeNativeSkin(stream, len, object, offset);
|
||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
||||
xbox::writeNativeSkin(stream, len, object, offset);
|
||||
else
|
||||
else{
|
||||
assert(0 && "unsupported native skin platform");
|
||||
return;
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||
@ -662,6 +672,7 @@ writeSkin(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
uint32 buffer[3] = { 0, 0, 0};
|
||||
stream->write(buffer, 12);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -835,17 +846,19 @@ copyAtomicMatFX(void *dst, void *src, int32 offset, int32)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void
|
||||
readAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
static Stream*
|
||||
readAtomicMatFX(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
if(stream->readI32())
|
||||
MatFX::enableEffects((Atomic*)object);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeAtomicMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
stream->writeI32(*PLUGINOFFSET(int32, object, offset));
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -1036,7 +1049,7 @@ copyMaterialMatFX(void *dst, void *src, int32 offset, int32)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
Texture *tex, *bumpedTex;
|
||||
@ -1057,13 +1070,19 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
coefficient = stream->readF32();
|
||||
bumpedTex = tex = NULL;
|
||||
if(stream->readI32()){
|
||||
assert(findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL));
|
||||
if(!findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL)){
|
||||
RWERROR((ERR_CHUNK, "TEXTURE"));
|
||||
return nil;
|
||||
}
|
||||
bumpedTex = Texture::streamRead(stream);
|
||||
}
|
||||
if(stream->readI32()){
|
||||
assert(findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL));
|
||||
if(!findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL)){
|
||||
RWERROR((ERR_CHUNK, "TEXTURE"));
|
||||
return nil;
|
||||
}
|
||||
tex = Texture::streamRead(stream);
|
||||
}
|
||||
idx = matfx->getEffectIndex(type);
|
||||
@ -1078,8 +1097,11 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
fbAlpha = stream->readI32();
|
||||
tex = NULL;
|
||||
if(stream->readI32()){
|
||||
assert(findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL));
|
||||
if(!findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL)){
|
||||
RWERROR((ERR_CHUNK, "TEXTURE"));
|
||||
return nil;
|
||||
}
|
||||
tex = Texture::streamRead(stream);
|
||||
}
|
||||
idx = matfx->getEffectIndex(type);
|
||||
@ -1094,8 +1116,11 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
dstBlend = stream->readI32();
|
||||
tex = NULL;
|
||||
if(stream->readI32()){
|
||||
assert(findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL));
|
||||
if(!findChunk(stream, ID_TEXTURE,
|
||||
NULL, NULL)){
|
||||
RWERROR((ERR_CHUNK, "TEXTURE"));
|
||||
return nil;
|
||||
}
|
||||
tex = Texture::streamRead(stream);
|
||||
}
|
||||
idx = matfx->getEffectIndex(type);
|
||||
@ -1106,9 +1131,10 @@ readMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
MatFX *matfx = *PLUGINOFFSET(MatFX*, object, offset);
|
||||
@ -1144,6 +1170,7 @@ writeMaterialMatFX(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
|
140
src/ps2.cpp
140
src/ps2.cpp
@ -4,6 +4,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
@ -12,6 +13,8 @@
|
||||
#include "rwps2.h"
|
||||
#include "rwps2plg.h"
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
namespace ps2 {
|
||||
|
||||
@ -28,8 +31,9 @@ void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||
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;
|
||||
@ -38,16 +42,24 @@ destroyNativeData(void *object, int32, int32)
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
assert(stream->readU32() == PLATFORM_PS2);
|
||||
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 != NULL);
|
||||
assert(geometry->meshHeader != nil);
|
||||
header->numMeshes = geometry->meshHeader->numMeshes;
|
||||
header->instanceMeshes = new InstanceData[header->numMeshes];
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
@ -66,15 +78,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
instance->material = geometry->meshHeader->mesh[i].material;
|
||||
// sizedebug(instance);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||
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++){
|
||||
@ -87,6 +101,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
stream->write(buf, 8);
|
||||
stream->write(instance->data, instance->dataSize);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
int32
|
||||
@ -94,8 +109,9 @@ getSizeNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
int32 size = 16;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||
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];
|
||||
@ -109,7 +125,7 @@ void
|
||||
registerNativeDataPlugin(void)
|
||||
{
|
||||
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
||||
NULL, destroyNativeData, NULL);
|
||||
nil, destroyNativeData, nil);
|
||||
Geometry::registerPluginStream(ID_NATIVEDATA,
|
||||
readNativeData,
|
||||
writeNativeData,
|
||||
@ -380,11 +396,11 @@ instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n)
|
||||
}
|
||||
|
||||
MatPipeline::MatPipeline(uint32 platform)
|
||||
: rw::Pipeline(platform), instanceCB(NULL), uninstanceCB(NULL),
|
||||
preUninstCB(NULL), postUninstCB(NULL)
|
||||
: rw::Pipeline(platform), instanceCB(nil), uninstanceCB(nil),
|
||||
preUninstCB(nil), postUninstCB(nil)
|
||||
{
|
||||
for(int i = 0; i < 10; i++)
|
||||
this->attribs[i] = NULL;
|
||||
this->attribs[i] = nil;
|
||||
}
|
||||
|
||||
void
|
||||
@ -653,7 +669,7 @@ MatPipeline::collectData(Geometry *g, InstanceData *inst, Mesh *m, uint8 *data[]
|
||||
InstMeshInfo im = getInstMeshInfo(this, g, m);
|
||||
|
||||
uint8 *raw = im.vertexSize*m->numIndices ?
|
||||
new uint8[im.vertexSize*m->numIndices] : NULL;
|
||||
new uint8[im.vertexSize*m->numIndices] : nil;
|
||||
uint8 *dp = raw;
|
||||
for(uint i = 0; i < nelem(this->attribs); i++)
|
||||
if(a = this->attribs[i])
|
||||
@ -706,7 +722,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
InstanceDataHeader *header = new InstanceDataHeader;
|
||||
geo->instData = header;
|
||||
header->platform = PLATFORM_PS2;
|
||||
assert(geo->meshHeader != NULL);
|
||||
assert(geo->meshHeader != nil);
|
||||
header->numMeshes = geo->meshHeader->numMeshes;
|
||||
header->instanceMeshes = new InstanceData[header->numMeshes];
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
@ -717,7 +733,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
m = pipe->groupPipeline ?
|
||||
pipe->groupPipeline :
|
||||
(MatPipeline*)mesh->material->pipeline;
|
||||
if(m == NULL)
|
||||
if(m == nil)
|
||||
m = defaultMatPipe;
|
||||
m->instance(geo, instance, mesh);
|
||||
instance->material = mesh->material;
|
||||
@ -761,7 +777,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
Geometry *geo = atomic->geometry;
|
||||
if((geo->geoflags & Geometry::NATIVE) == 0)
|
||||
return;
|
||||
assert(geo->instData != NULL);
|
||||
assert(geo->instData != nil);
|
||||
assert(geo->instData->platform == PLATFORM_PS2);
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
|
||||
// highest possible number of vertices
|
||||
@ -778,7 +794,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
m = pipe->groupPipeline ?
|
||||
pipe->groupPipeline :
|
||||
(MatPipeline*)mesh->material->pipeline;
|
||||
if(m == NULL) m = defaultMatPipe;
|
||||
if(m == nil) m = defaultMatPipe;
|
||||
if(m->preUninstCB) m->preUninstCB(m, geo);
|
||||
}
|
||||
geo->numVertices = 0;
|
||||
@ -789,9 +805,9 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
m = pipe->groupPipeline ?
|
||||
pipe->groupPipeline :
|
||||
(MatPipeline*)mesh->material->pipeline;
|
||||
if(m == NULL) m = defaultMatPipe;
|
||||
if(m == nil) m = defaultMatPipe;
|
||||
|
||||
uint8 *data[nelem(m->attribs)] = { NULL };
|
||||
uint8 *data[nelem(m->attribs)] = { nil };
|
||||
uint8 *raw = m->collectData(geo, instance, mesh, data);
|
||||
assert(m->uninstanceCB);
|
||||
m->uninstanceCB(m, geo, flags, mesh, data);
|
||||
@ -803,7 +819,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
m = pipe->groupPipeline ?
|
||||
pipe->groupPipeline :
|
||||
(MatPipeline*)mesh->material->pipeline;
|
||||
if(m == NULL) m = defaultMatPipe;
|
||||
if(m == nil) m = defaultMatPipe;
|
||||
if(m->postUninstCB) m->postUninstCB(m, geo);
|
||||
}
|
||||
|
||||
@ -811,7 +827,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
geo->generateTriangles(bits);
|
||||
delete[] flags;
|
||||
destroyNativeData(geo, 0, 0);
|
||||
geo->instData = NULL;
|
||||
geo->instData = nil;
|
||||
/*
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
Mesh *mesh = &geo->meshHeader->mesh[i];
|
||||
@ -826,7 +842,7 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
ObjPipeline::ObjPipeline(uint32 platform)
|
||||
: rw::ObjPipeline(platform)
|
||||
{
|
||||
this->groupPipeline = NULL;
|
||||
this->groupPipeline = nil;
|
||||
this->impl.instance = objInstance;
|
||||
this->impl.uninstance = objUninstance;
|
||||
}
|
||||
@ -900,13 +916,13 @@ genericPreCB(MatPipeline *pipe, Geometry *geo)
|
||||
void
|
||||
genericUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, uint8 *data[])
|
||||
{
|
||||
float32 *xyz = NULL, *xyzw = NULL;
|
||||
float32 *uv = NULL, *uv2 = NULL;
|
||||
uint8 *rgba = NULL;
|
||||
int8 *normals = NULL;
|
||||
uint32 *weights = NULL;
|
||||
int8 *adc = NULL;
|
||||
Skin *skin = NULL;
|
||||
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);
|
||||
|
||||
@ -1031,7 +1047,7 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
||||
ObjPipeline*
|
||||
makeDefaultPipeline(void)
|
||||
{
|
||||
if(defaultMatPipe == NULL){
|
||||
if(defaultMatPipe == nil){
|
||||
MatPipeline *pipe = new MatPipeline(PLATFORM_PS2);
|
||||
pipe->attribs[AT_XYZ] = &attribXYZ;
|
||||
pipe->attribs[AT_UV] = &attribUV;
|
||||
@ -1044,7 +1060,7 @@ makeDefaultPipeline(void)
|
||||
defaultMatPipe = pipe;
|
||||
}
|
||||
|
||||
if(defaultObjPipe == NULL){
|
||||
if(defaultObjPipe == nil){
|
||||
ObjPipeline *opipe = new ObjPipeline(PLATFORM_PS2);
|
||||
defaultObjPipe = opipe;
|
||||
}
|
||||
@ -1101,14 +1117,21 @@ makeMatFXPipeline(void)
|
||||
|
||||
// Skin
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||
{
|
||||
uint8 header[4];
|
||||
uint32 vers;
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
|
||||
assert(stream->readU32() == PLATFORM_PS2);
|
||||
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;
|
||||
@ -1140,9 +1163,10 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||
// last 3 ints are split data as in the other formats
|
||||
// TODO: what are the other 4?
|
||||
stream->seek(7*4);
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||
{
|
||||
uint8 header[4];
|
||||
@ -1170,13 +1194,14 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||
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 == NULL)
|
||||
if(skin == nil)
|
||||
return -1;
|
||||
int32 size = 12 + 4 + 4 + skin->numBones*64;
|
||||
// not sure which version introduced the new format
|
||||
@ -1206,7 +1231,7 @@ void
|
||||
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||
if(skin == NULL)
|
||||
if(skin == nil)
|
||||
return;
|
||||
instanceSkinData(g, m, skin, (uint32*)data[4]);
|
||||
}
|
||||
@ -1216,8 +1241,8 @@ int32
|
||||
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||
float32 *wghts = NULL;
|
||||
uint8 *inds = NULL;
|
||||
float32 *wghts = nil;
|
||||
uint8 *inds = nil;
|
||||
if(skin){
|
||||
wghts = skin->weights;
|
||||
inds = skin->indices;
|
||||
@ -1331,7 +1356,7 @@ void
|
||||
skinPreCB(MatPipeline*, Geometry *geo)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||
if(skin == NULL)
|
||||
if(skin == nil)
|
||||
return;
|
||||
uint8 *data = skin->data;
|
||||
float *invMats = skin->inverseMatrices;
|
||||
@ -1358,7 +1383,7 @@ int32 adcOffset;
|
||||
int8*
|
||||
getADCbits(Geometry *geo)
|
||||
{
|
||||
int8 *bits = NULL;
|
||||
int8 *bits = nil;
|
||||
if(adcOffset){
|
||||
ADCData *adc = PLUGINOFFSET(ADCData, geo, adcOffset);
|
||||
if(adc->adcFormatted)
|
||||
@ -1371,8 +1396,8 @@ int8*
|
||||
getADCbitsForMesh(Geometry *geo, Mesh *mesh)
|
||||
{
|
||||
int8 *bits = getADCbits(geo);
|
||||
if(bits == NULL)
|
||||
return NULL;
|
||||
if(bits == nil)
|
||||
return nil;
|
||||
int32 n = mesh - geo->meshHeader->mesh;
|
||||
for(int32 i = 0; i < n; i++)
|
||||
bits += geo->meshHeader->mesh[i].numIndices;
|
||||
@ -1430,7 +1455,7 @@ unconvertADC(Geometry *g)
|
||||
g->meshHeader = h;
|
||||
adc->adcFormatted = 0;
|
||||
delete[] adc->adcBits;
|
||||
adc->adcBits = NULL;
|
||||
adc->adcBits = nil;
|
||||
adc->numBits = 0;
|
||||
}
|
||||
|
||||
@ -1477,24 +1502,28 @@ destroyADC(void *object, int32 offset, int32)
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readADC(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
|
||||
assert(findChunk(stream, ID_ADC, NULL, NULL));
|
||||
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 = NULL;
|
||||
adc->adcBits = nil;
|
||||
adc->numBits = 0;
|
||||
return;
|
||||
return stream;
|
||||
}
|
||||
int32 size = adc->numBits+3 & ~3;
|
||||
adc->adcBits = new int8[size];
|
||||
stream->read(adc->adcBits, size);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeADC(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
{
|
||||
ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
|
||||
@ -1502,11 +1531,12 @@ writeADC(Stream *stream, int32 len, void *object, int32 offset, int32)
|
||||
writeChunkHeader(stream, ID_ADC, len-12);
|
||||
if(geometry->geoflags & Geometry::NATIVE){
|
||||
stream->writeI32(0);
|
||||
return;
|
||||
return stream;
|
||||
}
|
||||
stream->writeI32(adc->numBits);
|
||||
int32 size = adc->numBits+3 & ~3;
|
||||
stream->write(adc->adcBits, size);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -1564,7 +1594,7 @@ sizedebug(InstanceData *inst)
|
||||
return;
|
||||
uint32 *base = (uint32*)inst->data;
|
||||
uint32 *tag = (uint32*)inst->data;
|
||||
uint32 *last = NULL;
|
||||
uint32 *last = nil;
|
||||
for(;;){
|
||||
switch(tag[0]&0x70000000){
|
||||
case DMAcnt:
|
||||
|
@ -3,15 +3,16 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <new>
|
||||
|
||||
#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 {
|
||||
@ -385,7 +386,7 @@ rasterLock(Raster *raster, int32 level)
|
||||
// TODO
|
||||
(void)raster;
|
||||
(void)level;
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -400,7 +401,7 @@ static int32
|
||||
rasterNumLevels(Raster *raster)
|
||||
{
|
||||
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
|
||||
if(raster->texels == NULL) return 0;
|
||||
if(raster->texels == nil) return 0;
|
||||
if(raster->format & Raster::MIPMAP)
|
||||
return MAXLEVEL(ras)+1;
|
||||
return 1;
|
||||
@ -410,7 +411,6 @@ static void*
|
||||
createNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, object, offset);
|
||||
new (raster) Ps2Raster;
|
||||
raster->tex0[0] = 0;
|
||||
raster->tex0[1] = 0;
|
||||
raster->tex1[0] = 0;
|
||||
@ -426,7 +426,7 @@ createNativeRaster(void *object, int32 offset, int32)
|
||||
SETKL(raster, 0xFC0);
|
||||
|
||||
raster->dataSize = 0;
|
||||
raster->data = NULL;
|
||||
raster->data = nil;
|
||||
return object;
|
||||
}
|
||||
|
||||
@ -447,24 +447,27 @@ copyNativeRaster(void *dst, void *src, int32 offset, int32)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
readMipmap(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
uint16 val = stream->readI32();
|
||||
Texture *tex = (Texture*)object;
|
||||
if(tex->raster == NULL)
|
||||
return;
|
||||
if(tex->raster == nil)
|
||||
return stream;
|
||||
Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
|
||||
SETKL(raster, val);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
static Stream*
|
||||
writeMipmap(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
Texture *tex = (Texture*)object;
|
||||
assert(tex->raster);
|
||||
if(tex->raster)
|
||||
return nil;
|
||||
Ps2Raster *raster = PLUGINOFFSET(Ps2Raster, tex->raster, offset);
|
||||
stream->writeI32(raster->tex1[1]&0xFFFF);
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -487,7 +490,7 @@ registerNativeRaster(void)
|
||||
engine[PLATFORM_PS2].rasterUnlock = rasterUnlock;
|
||||
engine[PLATFORM_PS2].rasterNumLevels = rasterNumLevels;
|
||||
|
||||
Texture::registerPlugin(0, ID_SKYMIPMAP, NULL, NULL, NULL);
|
||||
Texture::registerPlugin(0, ID_SKYMIPMAP, nil, nil, nil);
|
||||
Texture::registerPluginStream(ID_SKYMIPMAP, readMipmap, writeMipmap, getSizeMipmap);
|
||||
}
|
||||
|
||||
@ -512,24 +515,47 @@ Texture*
|
||||
readNativeTexture(Stream *stream)
|
||||
{
|
||||
uint32 length, oldversion, version;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
assert(stream->readU32() == 0x00325350); // 'PS2\0'
|
||||
Texture *tex = Texture::create(NULL);
|
||||
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();
|
||||
assert(findChunk(stream, ID_STRING, &length, NULL));
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
goto fail;
|
||||
}
|
||||
stream->read(tex->name, length);
|
||||
assert(findChunk(stream, ID_STRING, &length, NULL));
|
||||
if(!findChunk(stream, ID_STRING, &length, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRING"));
|
||||
goto fail;
|
||||
}
|
||||
stream->read(tex->mask, length);
|
||||
|
||||
// Raster
|
||||
StreamRasterExt streamExt;
|
||||
oldversion = rw::version;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &version));
|
||||
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);
|
||||
Raster *raster;
|
||||
noNewStyleRasters = streamExt.type < 2;
|
||||
rw::version = version;
|
||||
raster = Raster::create(streamExt.width, streamExt.height,
|
||||
@ -538,36 +564,43 @@ readNativeTexture(Stream *stream)
|
||||
noNewStyleRasters = 0;
|
||||
rw::version = oldversion;
|
||||
tex->raster = raster;
|
||||
Ps2Raster *ras = PLUGINOFFSET(Ps2Raster, raster, nativeRasterOffset);
|
||||
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]);
|
||||
ras->tex0[0] = streamExt.tex0[0];
|
||||
ras->tex0[1] = streamExt.tex0[1];
|
||||
ras->tex1[0] = streamExt.tex1[0];
|
||||
ras->tex1[1] = ras->tex1[1]&~0xFF0000 | streamExt.tex1[1]<<16 & 0xFF0000;
|
||||
ras->miptbp1[0] = streamExt.miptbp1[0];
|
||||
ras->miptbp1[1] = streamExt.miptbp1[1];
|
||||
ras->miptbp2[0] = streamExt.miptbp2[0];
|
||||
ras->miptbp2[1] = streamExt.miptbp2[1];
|
||||
ras->texelSize = streamExt.texelSize;
|
||||
ras->paletteSize = streamExt.paletteSize;
|
||||
ras->gsSize = streamExt.gsSize;
|
||||
SETKL(ras, streamExt.mipmapVal);
|
||||
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]);
|
||||
|
||||
assert(findChunk(stream, ID_STRUCT, &length, NULL));
|
||||
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, ras->texelSize);
|
||||
stream->read(raster->palette-0x50, ras->paletteSize);
|
||||
stream->read(raster->texels-0x50, natras->texelSize);
|
||||
stream->read(raster->palette-0x50, natras->paletteSize);
|
||||
}
|
||||
|
||||
tex->streamReadPlugins(stream);
|
||||
if(tex->streamReadPlugins(stream))
|
||||
return tex;
|
||||
|
||||
fail:
|
||||
tex->destroy();
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -32,8 +32,8 @@ uint32 makeFVFDeclaration(uint32 flags, int32 numTex);
|
||||
int32 getStride(uint32 flags, int32 numTex);
|
||||
|
||||
void *destroyNativeData(void *object, int32, int32);
|
||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||
void writeNativeData(Stream *stream, int32 len, 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);
|
||||
|
||||
|
@ -55,8 +55,8 @@ void *createVertexDeclaration(VertexElement *elements);
|
||||
uint32 getDeclaration(void *declaration, VertexElement *elements);
|
||||
|
||||
void *destroyNativeData(void *object, int32, int32);
|
||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||
void writeNativeData(Stream *stream, int32 len, 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);
|
||||
|
||||
|
@ -6,8 +6,8 @@ namespace rw {
|
||||
typedef void *(*Constructor)(void *object, int32 offset, int32 size);
|
||||
typedef void *(*Destructor)(void *object, int32 offset, int32 size);
|
||||
typedef void *(*CopyConstructor)(void *dst, void *src, int32 offset, int32 size);
|
||||
typedef void (*StreamRead)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
|
||||
typedef void (*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
|
||||
typedef Stream *(*StreamRead)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
|
||||
typedef Stream *(*StreamWrite)(Stream *stream, int32 length, void *object, int32 offset, int32 size);
|
||||
typedef int32 (*StreamGetSize)(void *object, int32 offset, int32 size);
|
||||
typedef void (*RightsCallback)(void *object, int32 offset, int32 size, uint32 data);
|
||||
|
||||
|
@ -49,8 +49,8 @@ enum PS2AttibTypes {
|
||||
};
|
||||
|
||||
void *destroyNativeData(void *object, int32, int32);
|
||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||
void writeNativeData(Stream *stream, int32 len, 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);
|
||||
|
||||
|
@ -9,8 +9,8 @@ ObjPipeline *makeMatFXPipeline(void);
|
||||
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, Vertex *v);
|
||||
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, Vertex *v);
|
||||
|
||||
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||
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);
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
namespace rw {
|
||||
namespace wdgl {
|
||||
|
||||
@ -38,8 +39,8 @@ 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);
|
||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||
void writeNativeData(Stream *stream, int32 len, 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);
|
||||
|
||||
@ -59,8 +60,8 @@ ObjPipeline *makeDefaultPipeline(void);
|
||||
|
||||
// Skin plugin
|
||||
|
||||
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||
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);
|
||||
|
@ -30,8 +30,8 @@ struct InstanceDataHeader : rw::InstanceDataHeader
|
||||
};
|
||||
|
||||
void *destroyNativeData(void *object, int32, int32);
|
||||
void readNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||
void writeNativeData(Stream *stream, int32 len, 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);
|
||||
|
||||
@ -48,8 +48,8 @@ ObjPipeline *makeDefaultPipeline(void);
|
||||
|
||||
// Skin plugin
|
||||
|
||||
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||
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);
|
||||
|
40
src/wdgl.cpp
40
src/wdgl.cpp
@ -4,6 +4,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
@ -15,7 +16,7 @@
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
namespace wdgl {
|
||||
@ -217,7 +218,9 @@ void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData->platform == PLATFORM_WDGL);
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_WDGL)
|
||||
return object;
|
||||
InstanceDataHeader *header =
|
||||
(InstanceDataHeader*)geometry->instData;
|
||||
geometry->instData = NULL;
|
||||
@ -228,7 +231,7 @@ destroyNativeData(void *object, int32, int32)
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
@ -244,24 +247,30 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
header->dataSize = header->attribs[0].stride*geometry->numVertices;
|
||||
header->data = new uint8[header->dataSize];
|
||||
stream->read(header->data, header->dataSize);
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData->platform == PLATFORM_WDGL);
|
||||
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;
|
||||
assert(geometry->instData->platform == PLATFORM_WDGL);
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_WDGL)
|
||||
return 0;
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
return 4 + header->numAttribs*sizeof(AttribDesc) + header->dataSize;
|
||||
}
|
||||
@ -511,22 +520,30 @@ makeDefaultPipeline(void)
|
||||
|
||||
// Skin
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||
{
|
||||
uint32 vers;
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
|
||||
assert(stream->readU32() == PLATFORM_WDGL);
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||
{
|
||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||
@ -534,6 +551,7 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, object, offset);
|
||||
stream->writeI32(skin->numBones);
|
||||
stream->write(skin->inverseMatrices, skin->numBones*64);
|
||||
return stream;
|
||||
}
|
||||
|
||||
int32
|
||||
|
98
src/xbox.cpp
98
src/xbox.cpp
@ -3,9 +3,8 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
@ -13,7 +12,7 @@
|
||||
#include "rwplugins.h"
|
||||
#include "rwxbox.h"
|
||||
|
||||
using namespace std;
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
namespace xbox {
|
||||
@ -28,8 +27,9 @@ void*
|
||||
destroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_XBOX);
|
||||
if(geometry->instData == nil ||
|
||||
geometry->instData->platform != PLATFORM_XBOX)
|
||||
return object;
|
||||
InstanceDataHeader *header =
|
||||
(InstanceDataHeader*)geometry->instData;
|
||||
geometry->instData = NULL;
|
||||
@ -40,14 +40,25 @@ destroyNativeData(void *object, int32, int32)
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 vers;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
|
||||
assert(stream->readU32() == PLATFORM_XBOX);
|
||||
assert(vers >= 0x35000 && "can't handle native Xbox data < 0x35000");
|
||||
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;
|
||||
@ -86,15 +97,17 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
|
||||
header->vertexBuffer = new uint8[header->stride*header->numVertices];
|
||||
stream->read(header->vertexBuffer, header->stride*header->numVertices);
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
writeChunkHeader(stream, ID_STRUCT, len-12);
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_XBOX);
|
||||
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;
|
||||
@ -125,14 +138,16 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
|
||||
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;
|
||||
assert(geometry->instData != NULL);
|
||||
assert(geometry->instData->platform == PLATFORM_XBOX);
|
||||
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;
|
||||
}
|
||||
@ -347,14 +362,25 @@ struct NativeSkin
|
||||
int32 stride;
|
||||
};
|
||||
|
||||
void
|
||||
Stream*
|
||||
readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 vers;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &vers));
|
||||
assert(vers >= 0x35000 && "can't handle native xbox skin < 0x35000");
|
||||
assert(stream->readU32() == PLATFORM_XBOX);
|
||||
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;
|
||||
|
||||
@ -375,9 +401,10 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
||||
|
||||
// no split skins in GTA
|
||||
stream->seek(12);
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
Stream*
|
||||
writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
@ -400,6 +427,7 @@ writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset)
|
||||
stream->write(skin->inverseMatrices, skin->numBones*64);
|
||||
int32 buffer[3] = { 0, 0, 0};
|
||||
stream->write(buffer, 12);
|
||||
return stream;
|
||||
}
|
||||
|
||||
int32
|
||||
@ -604,18 +632,20 @@ copyVertexFmt(void *dst, void *src, int32 offset, int32)
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void
|
||||
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 void
|
||||
static Stream*
|
||||
writeVertexFmt(Stream *stream, int32, void *object, int32 offset, int32)
|
||||
{
|
||||
stream->writeI32(*PLUGINOFFSET(uint32, object, offset));
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -842,7 +872,6 @@ static void*
|
||||
createNativeRaster(void *object, int32 offset, int32)
|
||||
{
|
||||
XboxRaster *raster = PLUGINOFFSET(XboxRaster, object, offset);
|
||||
new (raster) XboxRaster;
|
||||
raster->texture = NULL;
|
||||
raster->palette = NULL;
|
||||
raster->format = 0;
|
||||
@ -888,11 +917,24 @@ registerNativeRaster(void)
|
||||
Texture*
|
||||
readNativeTexture(Stream *stream)
|
||||
{
|
||||
uint32 version;
|
||||
assert(findChunk(stream, ID_STRUCT, NULL, &version));
|
||||
assert(version >= 0x34001);
|
||||
assert(stream->readU32() == PLATFORM_XBOX);
|
||||
Texture *tex = Texture::create(NULL);
|
||||
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();
|
||||
|
Loading…
Reference in New Issue
Block a user