mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +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 <cassert>
|
||||
|
||||
//#include <iostream>
|
||||
//#include <fstream>
|
||||
//#include <list>
|
||||
#include <new>
|
||||
|
||||
#include "rw.h"
|
||||
@ -21,17 +18,32 @@ main(int argc, char *argv[])
|
||||
registerNodeNamePlugin();
|
||||
registerBreakableModelPlugin();
|
||||
registerNativeDataPlugin();
|
||||
// registerNativeDataPS2Plugin();
|
||||
// Ps2::registerNativeDataPlugin();
|
||||
registerMeshPlugin();
|
||||
Rw::Clump *c;
|
||||
|
||||
// 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);
|
||||
c = Rw::Clump::streamRead(&in);
|
||||
assert(c != NULL);
|
||||
|
||||
in.close();
|
||||
delete[] data;
|
||||
|
||||
// Rw::Image *tga = Rw::readTGA("b.tga");
|
||||
// assert(tga != NULL);
|
||||
@ -41,10 +53,19 @@ main(int argc, char *argv[])
|
||||
// Rw::Gl::Instance(c->atomicList[i]);
|
||||
|
||||
// ofstream out(argv[2], ios::binary);
|
||||
Rw::StreamFile out;
|
||||
out.open(argv[2], "wb");
|
||||
// Rw::StreamFile out;
|
||||
// out.open(argv[2], "wb");
|
||||
data = new Rw::uint8[256*1024];
|
||||
Rw::StreamMemory out;
|
||||
out.open(data, 0, 256*1024);
|
||||
c->streamWrite(&out);
|
||||
|
||||
cf = fopen(argv[2], "wb");
|
||||
assert(cf != NULL);
|
||||
fwrite(data, out.getLength(), 1, cf);
|
||||
fclose(cf);
|
||||
out.close();
|
||||
delete[] data;
|
||||
|
||||
delete c;
|
||||
|
||||
|
@ -201,7 +201,7 @@ destroyNativeData(void *object, int32 offset, int32 size)
|
||||
if(geometry->instData == NULL)
|
||||
return object;
|
||||
if(geometry->instData->platform == PLATFORM_PS2)
|
||||
return DestroyNativeDataPS2(object, offset, size);
|
||||
return Ps2::DestroyNativeData(object, offset, size);
|
||||
if(geometry->instData->platform == PLATFORM_OGL)
|
||||
return Gl::DestroyNativeData(object, offset, size);
|
||||
return object;
|
||||
@ -223,7 +223,7 @@ readNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
||||
platform = stream->readU32();
|
||||
stream->seek(-16);
|
||||
if(platform == PLATFORM_PS2)
|
||||
ReadNativeDataPS2(stream, len, object, o, s);
|
||||
Ps2::ReadNativeData(stream, len, object, o, s);
|
||||
else if(platform == PLATFORM_XBOX)
|
||||
stream->seek(len);
|
||||
}else{
|
||||
@ -239,7 +239,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32 o, int32 s)
|
||||
if(geometry->instData == NULL)
|
||||
return;
|
||||
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)
|
||||
Gl::WriteNativeData(stream, len, object, o, s);
|
||||
}
|
||||
@ -251,7 +251,7 @@ getSizeNativeData(void *object, int32 offset, int32 size)
|
||||
if(geometry->instData == NULL)
|
||||
return -1;
|
||||
if(geometry->instData->platform == PLATFORM_PS2)
|
||||
return GetSizeNativeDataPS2(object, offset, size);
|
||||
return Ps2::GetSizeNativeData(object, offset, size);
|
||||
else if(geometry->instData->platform == PLATFORM_XBOX)
|
||||
return -1;
|
||||
else if(geometry->instData->platform == PLATFORM_OGL)
|
||||
@ -270,17 +270,6 @@ registerNativeDataPlugin(void)
|
||||
(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
|
||||
|
||||
// TODO: put this in a header
|
||||
|
43
src/ps2.cpp
43
src/ps2.cpp
@ -13,14 +13,14 @@
|
||||
using namespace std;
|
||||
|
||||
namespace Rw {
|
||||
namespace Ps2 {
|
||||
|
||||
void*
|
||||
DestroyNativeDataPS2(void *object, int32, int32)
|
||||
DestroyNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||
PS2InstanceDataHeader *header =
|
||||
(PS2InstanceDataHeader*)geometry->instData;
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++)
|
||||
delete[] header->instanceMeshes[i].data;
|
||||
delete[] header->instanceMeshes;
|
||||
@ -29,40 +29,42 @@ DestroyNativeDataPS2(void *object, int32, int32)
|
||||
}
|
||||
|
||||
void
|
||||
ReadNativeDataPS2(Stream *stream, int32, void *object, int32, int32)
|
||||
ReadNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
||||
assert(stream->readU32() == PLATFORM_PS2);
|
||||
PS2InstanceDataHeader *header = new PS2InstanceDataHeader;
|
||||
InstanceDataHeader *header = new InstanceDataHeader;
|
||||
geometry->instData = header;
|
||||
header->platform = PLATFORM_PS2;
|
||||
assert(geometry->meshHeader != NULL);
|
||||
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++){
|
||||
PS2InstanceData *instance = &header->instanceMeshes[i];
|
||||
InstanceData *instance = &header->instanceMeshes[i];
|
||||
uint32 buf[2];
|
||||
stream->read(buf, 8);
|
||||
instance->dataSize = buf[0];
|
||||
instance->noRefChain = buf[1];
|
||||
// TODO: force alignment
|
||||
instance->data = new uint8[instance->dataSize];
|
||||
uint64 a = (uint64)instance->data ;
|
||||
assert(a % 0x10 == 0);
|
||||
stream->read(instance->data, instance->dataSize);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32)
|
||||
WriteNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
WriteChunkHeader(stream, ID_STRUCT, len-12);
|
||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||
stream->writeU32(PLATFORM_PS2);
|
||||
assert(geometry->instData != NULL);
|
||||
PS2InstanceDataHeader *header =
|
||||
(PS2InstanceDataHeader*)geometry->instData;
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
PS2InstanceData *instance = &header->instanceMeshes[i];
|
||||
InstanceData *instance = &header->instanceMeshes[i];
|
||||
uint32 buf[2];
|
||||
buf[0] = instance->dataSize;
|
||||
buf[1] = instance->noRefChain;
|
||||
@ -72,20 +74,31 @@ WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32)
|
||||
}
|
||||
|
||||
int32
|
||||
GetSizeNativeDataPS2(void *object, int32, int32)
|
||||
GetSizeNativeData(void *object, int32, int32)
|
||||
{
|
||||
Geometry *geometry = (Geometry*)object;
|
||||
int32 size = 16;
|
||||
assert(geometry->instData->platform == PLATFORM_PS2);
|
||||
assert(geometry->instData != NULL);
|
||||
PS2InstanceDataHeader *header =
|
||||
(PS2InstanceDataHeader*)geometry->instData;
|
||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
PS2InstanceData *instance = &header->instanceMeshes[i];
|
||||
InstanceData *instance = &header->instanceMeshes[i];
|
||||
size += 8;
|
||||
size += instance->dataSize;
|
||||
}
|
||||
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 <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#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::open(const char *path, const char *mode)
|
||||
{
|
||||
|
21
src/rwbase.h
21
src/rwbase.h
@ -38,6 +38,27 @@ public:
|
||||
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
|
||||
{
|
||||
FILE *file;
|
||||
|
@ -230,5 +230,4 @@ private:
|
||||
void registerNodeNamePlugin(void);
|
||||
void registerMeshPlugin(void);
|
||||
void registerNativeDataPlugin(void);
|
||||
void registerNativeDataPS2Plugin(void);
|
||||
void registerBreakableModelPlugin(void);
|
||||
|
17
src/rwps2.h
17
src/rwps2.h
@ -1,6 +1,7 @@
|
||||
namespace Rw {
|
||||
namespace Ps2 {
|
||||
|
||||
struct PS2InstanceData
|
||||
struct InstanceData
|
||||
{
|
||||
uint32 noRefChain;
|
||||
uint32 dataSize;
|
||||
@ -8,15 +9,17 @@ struct PS2InstanceData
|
||||
Material *material;
|
||||
};
|
||||
|
||||
struct PS2InstanceDataHeader : InstanceDataHeader
|
||||
struct InstanceDataHeader : Rw::InstanceDataHeader
|
||||
{
|
||||
uint32 numMeshes;
|
||||
PS2InstanceData *instanceMeshes;
|
||||
InstanceData *instanceMeshes;
|
||||
};
|
||||
|
||||
void *DestroyNativeDataPS2(void *object, int32, int32);
|
||||
void ReadNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32);
|
||||
void WriteNativeDataPS2(Stream *stream, int32 len, void *object, int32, int32);
|
||||
int32 GetSizeNativeDataPS2(void *object, int32, int32);
|
||||
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);
|
||||
int32 GetSizeNativeData(void *object, int32, int32);
|
||||
void registerNativeDataPlugin(void);
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user