Sophie

Sophie

distrib > Fedora > 13 > x86_64 > by-pkgid > 08163ffb50475ea8ee1ba869af0dfe3e > files > 6

quake3-1.36-8.svn1802.fc13.src.rpm

From: Simon McVittie <smcv@debian.org>
Date: Wed, 21 Jul 2010 19:50:32 +0100
Subject: [PATCH] Add a special vmMagic that causes equivalent native code to be loaded instead

This means that mods can build everything from source without relying on
the non-GPL q3lcc compiler. By padding the fake QVM with bytes chosen
to match the CRC-32 of the upstream-released QVM, it's even possible to
be network-compatible with the upstream one, and so play on pure servers.

Origin: vendor, Debian
Forwarded: no
---
 code/qcommon/qfiles.h |    4 ++++
 code/qcommon/vm.c     |   18 ++++++++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/code/qcommon/qfiles.h b/code/qcommon/qfiles.h
index 7f1ef96..e3515b4 100644
--- a/code/qcommon/qfiles.h
+++ b/code/qcommon/qfiles.h
@@ -52,6 +52,10 @@ QVM files
 
 #define	VM_MAGIC			0x12721444
 #define	VM_MAGIC_VER2	0x12721445
+
+/* 'NTVE', but backwards because the QVM format is little-endian */
+#define	VM_MAGIC_USE_NATIVE	0x4556544E
+
 typedef struct {
 	int		vmMagic;
 
diff --git a/code/qcommon/vm.c b/code/qcommon/vm.c
index 2ccc24f..83832d1 100644
--- a/code/qcommon/vm.c
+++ b/code/qcommon/vm.c
@@ -384,6 +384,18 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
 		return NULL;
 	}
 
+	if (LittleLong( header.h->vmMagic ) == VM_MAGIC_USE_NATIVE) {
+		Com_Printf( "...which has vmMagic VM_MAGIC_USE_NATIVE.\n" );
+		Com_Printf( "Loading DLL file %s instead.\n", vm->name );
+		vm->dllHandle = Sys_LoadDll( vm->name, vm->fqpath , &vm->entryPoint, VM_DllSyscall );
+		if ( !vm->dllHandle ) {
+			Com_Printf( "Failed to load DLL.\n" );
+			VM_Free( vm );
+			return NULL;
+		}
+		return header.h;
+	}
+
 	if( LittleLong( header.h->vmMagic ) == VM_MAGIC_VER2 ) {
 		Com_Printf( "...which has vmMagic VM_MAGIC_VER2\n" );
 
@@ -570,6 +582,12 @@ vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
 		return NULL;
 	}
 
+	if ( vm->dllHandle ) {
+		// it was replaced by a DLL anyway
+		FS_FreeFile( header );
+		return vm;
+	}
+
 	// allocate space for the jump targets, which will be filled in by the compile/prep functions
 	vm->instructionCount = header->instructionCount;
 	vm->instructionPointers = Hunk_Alloc( vm->instructionCount*4, h_high );
--