Untitled

 avatar
unknown
plain_text
4 years ago
1.7 kB
6
Indexable
//
// Globals
//

extern CGame *cgame;
CGame *cgame = NULL;

//
// Save qvm handles from VM_LoadQVM into cgame and uigame
//

typedef vmHeader_t *VM_LoadQVM_t(vm_t *vm, qboolean alloc);

vmHeader_t *urth_VM_LoadQVM(vm_t *vm, qboolean alloc) {
	unprotect(urt->VM_LoadQVM);		// FIXME: Why detour's tramp is reprotected ?
	vmHeader_t *result = urt->VM_LoadQVM(vm, alloc);

	// LOG_DEBUG("VM_LoadQVM(): " << vm->name << " vm " << std::hex << (void *)vm);

	if (!strcmp(vm->name, CGAME_QVM_NAME))
		cgame = new CGame(vm);
	else if (!strcmp(vm->name, UIGAME_QVM_NAME))
		uigame = new UIGame(vm);

	return result;
}

//
// Modified one-way VM_ArgPtr without error checking
//

void *Qvm::VM_ArgPtr(intptr_t offset) {
	return(this->vm->dataBase + (offset & this->vm->dataMask));
}

--

//
// Example of using modified vm_argpt in CL_CGameSystemCalls (Client) to intercept syscalls, saves snapshot
//

intptr_t urth_CL_CgameSystemCalls(intptr_t *args) {
	bool callSyscall = true;

	switch (args[0]) {

		case CG_GETSNAPSHOT:
			cgame->snap = cgame->snap;
			cgame->nextSnap = (snapshot_t *)cgame->VM_ArgPtr(args[2]);
			
			if (!cgame->snap)
				cgame->snap = cgame->nextSnap;
			break;
		default:
			break;
	}

	if (!callSyscall)
		return 0;

	intptr_t result = urt->CL_CgameSystemCalls(args);

	return result;
}

//
// Examples using modified CM_ArgPtr to read offset directly from QVM, this points to cgame, but can expliciticaly call any qvm with handle
//

	this->cg_numSolidEntities = (int *)this->VM_ArgPtr(0x38d28c); // old 0x38d274
	this->cg_solidEntities = (centity_t **)this->VM_ArgPtr(0x38ce8c); // old offset - 0x38ce74
Editor is loading...