mirror of
https://github.com/aap/librw.git
synced 2025-02-16 17:26:18 +00:00
Implemented rudimentary StreamMemory.
This commit is contained in:
parent
e9819e9f8a
commit
cbc31bdb25
37
dffwrite.cpp
37
dffwrite.cpp
@ -3,9 +3,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
//#include <iostream>
|
|
||||||
//#include <fstream>
|
|
||||||
//#include <list>
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include "rw.h"
|
#include "rw.h"
|
||||||
@ -21,17 +18,32 @@ main(int argc, char *argv[])
|
|||||||
registerNodeNamePlugin();
|
registerNodeNamePlugin();
|
||||||
registerBreakableModelPlugin();
|
registerBreakableModelPlugin();
|
||||||
registerNativeDataPlugin();
|
registerNativeDataPlugin();
|
||||||
// registerNativeDataPS2Plugin();
|
// Ps2::registerNativeDataPlugin();
|
||||||
registerMeshPlugin();
|
registerMeshPlugin();
|
||||||
Rw::Clump *c;
|
Rw::Clump *c;
|
||||||
|
|
||||||
// ifstream in(argv[1], ios::binary);
|
// ifstream in(argv[1], ios::binary);
|
||||||
Rw::StreamFile in;
|
|
||||||
in.open(argv[1], "rb");
|
// Rw::StreamFile in;
|
||||||
|
// in.open(argv[1], "rb");
|
||||||
|
|
||||||
|
FILE *cf = fopen(argv[1], "rb");
|
||||||
|
assert(cf != NULL);
|
||||||
|
fseek(cf, 0, SEEK_END);
|
||||||
|
Rw::uint32 len = ftell(cf);
|
||||||
|
fseek(cf, 0, SEEK_SET);
|
||||||
|
Rw::uint8 *data = new Rw::uint8[len];
|
||||||
|
fread(data, len, 1, cf);
|
||||||
|
fclose(cf);
|
||||||
|
Rw::StreamMemory in;
|
||||||
|
in.open(data, len);
|
||||||
|
|
||||||
Rw::FindChunk(&in, Rw::ID_CLUMP, NULL, NULL);
|
Rw::FindChunk(&in, Rw::ID_CLUMP, NULL, NULL);
|
||||||
c = Rw::Clump::streamRead(&in);
|
c = Rw::Clump::streamRead(&in);
|
||||||
assert(c != NULL);
|
assert(c != NULL);
|
||||||
|
|
||||||
in.close();
|
in.close();
|
||||||
|
delete[] data;
|
||||||
|
|
||||||
// Rw::Image *tga = Rw::readTGA("b.tga");
|
// Rw::Image *tga = Rw::readTGA("b.tga");
|
||||||
// assert(tga != NULL);
|
// assert(tga != NULL);
|
||||||
@ -41,10 +53,19 @@ main(int argc, char *argv[])
|
|||||||
// Rw::Gl::Instance(c->atomicList[i]);
|
// Rw::Gl::Instance(c->atomicList[i]);
|
||||||
|
|
||||||
// ofstream out(argv[2], ios::binary);
|
// ofstream out(argv[2], ios::binary);
|
||||||
Rw::StreamFile out;
|
// Rw::StreamFile out;
|
||||||
out.open(argv[2], "wb");
|
// out.open(argv[2], "wb");
|
||||||
|
data = new Rw::uint8[256*1024];
|
||||||
|
Rw::StreamMemory out;
|
||||||
|
out.open(data, 0, 256*1024);
|
||||||
c->streamWrite(&out);
|
c->streamWrite(&out);
|
||||||
|
|
||||||
|
cf = fopen(argv[2], "wb");
|
||||||
|
assert(cf != NULL);
|
||||||
|
fwrite(data, out.getLength(), 1, cf);
|
||||||
|
fclose(cf);
|
||||||
out.close();
|
out.close();
|
||||||
|
delete[] data;
|
||||||
|
|
||||||
delete c;
|
delete c;
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ destroyNativeData(void *object, int32 offset, int32 size)
|
|||||||
if(geometry->instData == NULL)
|
if(geometry->instData == NULL)
|
||||||
return object;
|
return object;
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
return DestroyNativeDataPS2(object, offset, size);
|
return Ps2::DestroyNativeData(object, offset, size);
|
||||||
if(geometry->instData->platform == PLATFORM_OGL)
|
if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
return Gl::DestroyNativeData(object, offset, size);
|
return Gl::DestroyNativeData(object, offset, size);
|
||||||
return object;
|
return object;
|
||||||
@ -223,7 +223,7 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
|||||||
platform = stream->readU32();
|
platform = stream->readU32();
|
||||||
stream->seek(-16);
|
stream->seek(-16);
|
||||||
if(platform == PLATFORM_PS2)
|
if(platform == PLATFORM_PS2)
|
||||||
ReadNativeDataPS2(stream, len, object, o, s);
|
Ps2::ReadNativeData(stream, len, object, o, s);
|
||||||
else if(platform == PLATFORM_XBOX)
|
else if(platform == PLATFORM_XBOX)
|
||||||
stream->seek(len);
|
stream->seek(len);
|
||||||
}else{
|
}else{
|
||||||
@ -239,7 +239,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
|||||||
if(geometry->instData == NULL)
|
if(geometry->instData == NULL)
|
||||||
return;
|
return;
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
WriteNativeDataPS2(stream, len, object, o, s);
|
Ps2::WriteNativeData(stream, len, object, o, s);
|
||||||
else if(geometry->instData->platform == PLATFORM_OGL)
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
Gl::WriteNativeData(stream, len, object, o, s);
|
Gl::WriteNativeData(stream, len, object, o, s);
|
||||||
}
|
}
|
||||||
@ -251,7 +251,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
|
|||||||
if(geometry->instData == NULL)
|
if(geometry->instData == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if(geometry->instData->platform == PLATFORM_PS2)
|
if(geometry->instData->platform == PLATFORM_PS2)
|
||||||
return GetSizeNativeDataPS2(object, offset, size);
|
return Ps2::GetSizeNativeData(object, offset, size);
|
||||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
else if(geometry->instData->platform == PLATFORM_XBOX)
|
||||||
return -1;
|
return -1;
|
||||||
else if(geometry->instData->platform == PLATFORM_OGL)
|
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||||
@ -270,17 +270,6 @@ registerNativeDataPlugin(void)
|
|||||||
(StreamGetSize)getSizeNativeData);
|
(StreamGetSize)getSizeNativeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
registerNativeDataPS2Plugin(void)
|
|
||||||
{
|
|
||||||
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
|
||||||
NULL, DestroyNativeDataPS2, NULL);
|
|
||||||
Geometry::registerPluginStream(ID_NATIVEDATA,
|
|
||||||
(StreamRead)ReadNativeDataPS2,
|
|
||||||
(StreamWrite)WriteNativeDataPS2,
|
|
||||||
(StreamGetSize)GetSizeNativeDataPS2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Breakable Model
|
// Breakable Model
|
||||||
|
|
||||||
// TODO: put this in a header
|
// TODO: put this in a header
|
||||||
|
43
src/ps2.cpp
43
src/ps2.cpp
@ -13,14 +13,14 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace Rw {
|
namespace Rw {
|
||||||
|
namespace Ps2 {
|
||||||
|
|
||||||
void*
|
void*
|
||||||
DestroyNativeDataPS2(void *object, int32, int32)
|
DestroyNativeData(void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||||
PS2InstanceDataHeader *header =
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
(PS2InstanceDataHeader*)geometry->instData;
|
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++)
|
for(uint32 i = 0; i < header->numMeshes; i++)
|
||||||
delete[] header->instanceMeshes[i].data;
|
delete[] header->instanceMeshes[i].data;
|
||||||
delete[] header->instanceMeshes;
|
delete[] header->instanceMeshes;
|
||||||
@ -29,40 +29,42 @@ DestroyNativeDataPS2(void *object, int32, int32)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ReadNativeDataPS2(Stream *stream, int32, void *object, int32, int32)
|
ReadNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
||||||
assert(stream->readU32() == PLATFORM_PS2);
|
assert(stream->readU32() == PLATFORM_PS2);
|
||||||
PS2InstanceDataHeader *header = new PS2InstanceDataHeader;
|
InstanceDataHeader *header = new InstanceDataHeader;
|
||||||
geometry->instData = header;
|
geometry->instData = header;
|
||||||
header->platform = PLATFORM_PS2;
|
header->platform = PLATFORM_PS2;
|
||||||
assert(geometry->meshHeader != NULL);
|
assert(geometry->meshHeader != NULL);
|
||||||
header->numMeshes = geometry->meshHeader->numMeshes;
|
header->numMeshes = geometry->meshHeader->numMeshes;
|
||||||
header->instanceMeshes = new PS2InstanceData[header->numMeshes];
|
header->instanceMeshes = new InstanceData[header->numMeshes];
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
PS2InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
uint32 buf[2];
|
uint32 buf[2];
|
||||||
stream->read(buf, 8);
|
stream->read(buf, 8);
|
||||||
instance->dataSize = buf[0];
|
instance->dataSize = buf[0];
|
||||||
instance->noRefChain = buf[1];
|
instance->noRefChain = buf[1];
|
||||||
|
// TODO: force alignment
|
||||||
instance->data = new uint8[instance->dataSize];
|
instance->data = new uint8[instance->dataSize];
|
||||||
|
uint64 a = (uint64)instance->data ;
|
||||||
|
assert(a % 0x10 == 0);
|
||||||
stream->read(instance->data, instance->dataSize);
|
stream->read(instance->data, instance->dataSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32)
|
WriteNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
WriteChunkHeader(stream, ID_STRUCT, len-12);
|
WriteChunkHeader(stream, ID_STRUCT, len-12);
|
||||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||||
stream->writeU32(PLATFORM_PS2);
|
stream->writeU32(PLATFORM_PS2);
|
||||||
assert(geometry->instData != NULL);
|
assert(geometry->instData != NULL);
|
||||||
PS2InstanceDataHeader *header =
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
(PS2InstanceDataHeader*)geometry->instData;
|
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
PS2InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
uint32 buf[2];
|
uint32 buf[2];
|
||||||
buf[0] = instance->dataSize;
|
buf[0] = instance->dataSize;
|
||||||
buf[1] = instance->noRefChain;
|
buf[1] = instance->noRefChain;
|
||||||
@ -72,20 +74,31 @@ WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
GetSizeNativeDataPS2(void *object, int32, int32)
|
GetSizeNativeData(void *object, int32, int32)
|
||||||
{
|
{
|
||||||
Geometry *geometry = (Geometry*)object;
|
Geometry *geometry = (Geometry*)object;
|
||||||
int32 size = 16;
|
int32 size = 16;
|
||||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||||
assert(geometry->instData != NULL);
|
assert(geometry->instData != NULL);
|
||||||
PS2InstanceDataHeader *header =
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
(PS2InstanceDataHeader*)geometry->instData;
|
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
PS2InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
size += 8;
|
size += 8;
|
||||||
size += instance->dataSize;
|
size += instance->dataSize;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
registerNativeDataPlugin(void)
|
||||||
|
{
|
||||||
|
Geometry::registerPlugin(0, ID_NATIVEDATA,
|
||||||
|
NULL, DestroyNativeData, NULL);
|
||||||
|
Geometry::registerPluginStream(ID_NATIVEDATA,
|
||||||
|
(StreamRead)ReadNativeData,
|
||||||
|
(StreamWrite)WriteNativeData,
|
||||||
|
(StreamGetSize)GetSizeNativeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
@ -113,6 +114,94 @@ Stream::readF32(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StreamMemory::close(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
StreamMemory::write(const void *data, uint32 len)
|
||||||
|
{
|
||||||
|
if(this->eof())
|
||||||
|
return 0;
|
||||||
|
uint32 l = len;
|
||||||
|
if(this->position+l > this->length){
|
||||||
|
if(this->position+l > this->capacity)
|
||||||
|
l = this->capacity-this->position;
|
||||||
|
this->length = this->position+l;
|
||||||
|
}
|
||||||
|
memcpy(&this->data[this->position], data, l);
|
||||||
|
this->position += l;
|
||||||
|
if(len != l)
|
||||||
|
this->position = S_EOF;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
StreamMemory::read(void *data, uint32 len)
|
||||||
|
{
|
||||||
|
if(this->eof())
|
||||||
|
return 0;
|
||||||
|
uint32 l = len;
|
||||||
|
if(this->position+l > this->length)
|
||||||
|
l = this->length-this->position;
|
||||||
|
memcpy(data, &this->data[this->position], l);
|
||||||
|
this->position += l;
|
||||||
|
if(len != l)
|
||||||
|
this->position = S_EOF;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StreamMemory::seek(int32 offset, int32 whence)
|
||||||
|
{
|
||||||
|
if(whence == 0)
|
||||||
|
this->position = offset;
|
||||||
|
else if(whence == 1)
|
||||||
|
this->position += offset;
|
||||||
|
else
|
||||||
|
this->position = this->length-offset;
|
||||||
|
if(this->position > this->length){
|
||||||
|
// TODO: ideally this would depend on the mode
|
||||||
|
if(this->position > this->capacity)
|
||||||
|
this->position = S_EOF;
|
||||||
|
else
|
||||||
|
this->length = this->position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
StreamMemory::tell(void)
|
||||||
|
{
|
||||||
|
return this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StreamMemory::eof(void)
|
||||||
|
{
|
||||||
|
return this->position == S_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamMemory*
|
||||||
|
StreamMemory::open(uint8 *data, uint32 length, uint32 capacity)
|
||||||
|
{
|
||||||
|
this->data = data;
|
||||||
|
this->capacity = capacity;
|
||||||
|
this->length = length;
|
||||||
|
if(this->capacity < this->length)
|
||||||
|
this->capacity = this->length;
|
||||||
|
this->position = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
StreamMemory::getLength(void)
|
||||||
|
{
|
||||||
|
return this->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
StreamFile*
|
StreamFile*
|
||||||
StreamFile::open(const char *path, const char *mode)
|
StreamFile::open(const char *path, const char *mode)
|
||||||
{
|
{
|
||||||
|
21
src/rwbase.h
21
src/rwbase.h
@ -38,6 +38,27 @@ public:
|
|||||||
float32 readF32(void);
|
float32 readF32(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StreamMemory : public Stream
|
||||||
|
{
|
||||||
|
uint8 *data;
|
||||||
|
uint32 length;
|
||||||
|
uint32 capacity;
|
||||||
|
uint32 position;
|
||||||
|
public:
|
||||||
|
void close(void);
|
||||||
|
uint32 write(const void *data, uint32 length);
|
||||||
|
uint32 read(void *data, uint32 length);
|
||||||
|
void seek(int32 offset, int32 whence);
|
||||||
|
uint32 tell(void);
|
||||||
|
bool eof(void);
|
||||||
|
StreamMemory *open(uint8 *data, uint32 length, uint32 capacity = 0);
|
||||||
|
uint32 getLength(void);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
S_EOF = 0xFFFFFFFF
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class StreamFile : public Stream
|
class StreamFile : public Stream
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
@ -230,5 +230,4 @@ private:
|
|||||||
void registerNodeNamePlugin(void);
|
void registerNodeNamePlugin(void);
|
||||||
void registerMeshPlugin(void);
|
void registerMeshPlugin(void);
|
||||||
void registerNativeDataPlugin(void);
|
void registerNativeDataPlugin(void);
|
||||||
void registerNativeDataPS2Plugin(void);
|
|
||||||
void registerBreakableModelPlugin(void);
|
void registerBreakableModelPlugin(void);
|
||||||
|
17
src/rwps2.h
17
src/rwps2.h
@ -1,6 +1,7 @@
|
|||||||
namespace Rw {
|
namespace Rw {
|
||||||
|
namespace Ps2 {
|
||||||
|
|
||||||
struct PS2InstanceData
|
struct InstanceData
|
||||||
{
|
{
|
||||||
uint32 noRefChain;
|
uint32 noRefChain;
|
||||||
uint32 dataSize;
|
uint32 dataSize;
|
||||||
@ -8,15 +9,17 @@ struct PS2InstanceData
|
|||||||
Material *material;
|
Material *material;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PS2InstanceDataHeader : InstanceDataHeader
|
struct InstanceDataHeader : Rw::InstanceDataHeader
|
||||||
{
|
{
|
||||||
uint32 numMeshes;
|
uint32 numMeshes;
|
||||||
PS2InstanceData *instanceMeshes;
|
InstanceData *instanceMeshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
void *DestroyNativeDataPS2(void *object, int32, int32);
|
void *DestroyNativeData(void *object, int32, int32);
|
||||||
void ReadNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32);
|
void ReadNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||||
void WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32);
|
void WriteNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||||
int32 GetSizeNativeDataPS2(void *object, int32, int32);
|
int32 GetSizeNativeData(void *object, int32, int32);
|
||||||
|
void registerNativeDataPlugin(void);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user