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];
|
||||
stream->read(buf, 8);
|
||||
instance->dataSize = buf[0];
|
||||
instance->noRefChain = buf[1];
|
||||
instance->arePointersFixed = buf[1];
|
||||
// TODO: force alignment
|
||||
instance->data = new uint8[instance->dataSize];
|
||||
uint64 a = (uint64)instance->data ;
|
||||
#ifdef RW_PS2
|
||||
uint32 a = (uint32)instance->data;
|
||||
assert(a % 0x10 == 0);
|
||||
#endif
|
||||
stream->read(instance->data, instance->dataSize);
|
||||
}
|
||||
}
|
||||
|
@ -65,9 +67,11 @@ WriteNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
|||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
InstanceData *instance = &header->instanceMeshes[i];
|
||||
if(instance->arePointersFixed == 2)
|
||||
unfixDmaOffsets(instance);
|
||||
uint32 buf[2];
|
||||
buf[0] = instance->dataSize;
|
||||
buf[1] = instance->noRefChain;
|
||||
buf[1] = instance->arePointersFixed;
|
||||
stream->write(buf, 8);
|
||||
stream->write(instance->data, instance->dataSize);
|
||||
}
|
||||
|
@ -100,5 +104,81 @@ registerNativeDataPlugin(void)
|
|||
(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
|
||||
{
|
||||
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;
|
||||
uint8 *data;
|
||||
Material *material;
|
||||
|
@ -21,5 +25,9 @@ void WriteNativeData(Stream *stream, int32 len, void *object, int32, int32);
|
|||
int32 GetSizeNativeData(void *object, int32, int32);
|
||||
void registerNativeDataPlugin(void);
|
||||
|
||||
// only RW_PS2
|
||||
void fixDmaOffsets(InstanceData *inst);
|
||||
void unfixDmaOffsets(InstanceData *inst);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue