mirror of
https://github.com/aap/librw.git
synced 2025-12-18 16:39:51 +00:00
Implemented rudimentary StreamMemory.
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user