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 ); --