mirror of https://github.com/aap/librw.git
Added functions for fixing/unfixing DMA pointers in PS2 data.
This commit is contained in:
parent
cbc31bdb25
commit
cec7963a9d
86
src/ps2.cpp
86
src/ps2.cpp
|
@ -45,11 +45,13 @@ ReadNativeData(Stream *stream, int32, void *object, int32, int32)
|
||||||
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->arePointersFixed = buf[1];
|
||||||
// TODO: force alignment
|
// TODO: force alignment
|
||||||
instance->data = new uint8[instance->dataSize];
|
instance->data = new uint8[instance->dataSize];
|
||||||
uint64 a = (uint64)instance->data ;
|
#ifdef RW_PS2
|
||||||
|
uint32 a = (uint32)instance->data;
|
||||||
assert(a % 0x10 == 0);
|
assert(a % 0x10 == 0);
|
||||||
|
#endif
|
||||||
stream->read(instance->data, instance->dataSize);
|
stream->read(instance->data, instance->dataSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,9 +67,11 @@ WriteNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
||||||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||||
InstanceData *instance = &header->instanceMeshes[i];
|
InstanceData *instance = &header->instanceMeshes[i];
|
||||||
|
if(instance->arePointersFixed == 2)
|
||||||
|
unfixDmaOffsets(instance);
|
||||||
uint32 buf[2];
|
uint32 buf[2];
|
||||||
buf[0] = instance->dataSize;
|
buf[0] = instance->dataSize;
|
||||||
buf[1] = instance->noRefChain;
|
buf[1] = instance->arePointersFixed;
|
||||||
stream->write(buf, 8);
|
stream->write(buf, 8);
|
||||||
stream->write(instance->data, instance->dataSize);
|
stream->write(instance->data, instance->dataSize);
|
||||||
}
|
}
|
||||||
|
@ -100,5 +104,81 @@ registerNativeDataPlugin(void)
|
||||||
(StreamGetSize)GetSizeNativeData);
|
(StreamGetSize)GetSizeNativeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RW_PS2
|
||||||
|
void
|
||||||
|
fixDmaOffsets(InstanceData *inst)
|
||||||
|
{
|
||||||
|
if(inst->arePointersFixed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 base = (uint32)inst->data;
|
||||||
|
uint32 *tag = (uint32*)inst->data;
|
||||||
|
for(;;){
|
||||||
|
switch(tag[0]&0x70000000){
|
||||||
|
// DMAcnt
|
||||||
|
case 0x10000000:
|
||||||
|
// no need to fix
|
||||||
|
tag += (1+(tag[0]&0xFFFF))*4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAref
|
||||||
|
case 0x30000000:
|
||||||
|
// fix address and jump to next
|
||||||
|
tag[1] = base + tag[1]*0x10;
|
||||||
|
tag += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAret
|
||||||
|
case 0x60000000:
|
||||||
|
// we're done
|
||||||
|
inst->arePointersFixed = 2;
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "error: unknown DMAtag %X\n", tag[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
unfixDmaOffsets(InstanceData *inst)
|
||||||
|
{
|
||||||
|
#ifdef RW_PS2
|
||||||
|
if(inst->arePointersFixed != 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 base = (uint32)inst->data;
|
||||||
|
uint32 *tag = (uint32*)inst->data;
|
||||||
|
for(;;){
|
||||||
|
switch(tag[0]&0x70000000){
|
||||||
|
// DMAcnt
|
||||||
|
case 0x10000000:
|
||||||
|
// no need to unfix
|
||||||
|
tag += (1+(tag[0]&0xFFFF))*4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAref
|
||||||
|
case 0x30000000:
|
||||||
|
// unfix address and jump to next
|
||||||
|
tag[1] = (tag[1] - base)/0x10;
|
||||||
|
tag += 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DMAret
|
||||||
|
case 0x60000000:
|
||||||
|
// we're done
|
||||||
|
inst->arePointersFixed = 0;
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "error: unknown DMAtag %X\n", tag[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/rwps2.h
10
src/rwps2.h
|
@ -3,7 +3,11 @@ namespace Ps2 {
|
||||||
|
|
||||||
struct InstanceData
|
struct InstanceData
|
||||||
{
|
{
|
||||||
uint32 noRefChain;
|
// 0 - addresses in ref tags need fixing
|
||||||
|
// 1 - no ref tags, so no fixing
|
||||||
|
// set by the program:
|
||||||
|
// 2 - ref tags are fixed, need to unfix before stream write
|
||||||
|
uint32 arePointersFixed;
|
||||||
uint32 dataSize;
|
uint32 dataSize;
|
||||||
uint8 *data;
|
uint8 *data;
|
||||||
Material *material;
|
Material *material;
|
||||||
|
@ -21,5 +25,9 @@ void WriteNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
||||||
int32 GetSizeNativeData(void *object, int32, int32);
|
int32 GetSizeNativeData(void *object, int32, int32);
|
||||||
void registerNativeDataPlugin(void);
|
void registerNativeDataPlugin(void);
|
||||||
|
|
||||||
|
// only RW_PS2
|
||||||
|
void fixDmaOffsets(InstanceData *inst);
|
||||||
|
void unfixDmaOffsets(InstanceData *inst);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue