mirror of
				https://github.com/aap/librw.git
				synced 2025-11-04 00:41:59 +00:00 
			
		
		
		
	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user