summaryrefslogtreecommitdiff
path: root/src/qcommon/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qcommon/vm.c')
-rw-r--r--src/qcommon/vm.c88
1 files changed, 61 insertions, 27 deletions
diff --git a/src/qcommon/vm.c b/src/qcommon/vm.c
index 5476a085..c53d8067 100644
--- a/src/qcommon/vm.c
+++ b/src/qcommon/vm.c
@@ -378,15 +378,20 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
// load the image
Com_sprintf( filename, sizeof(filename), "vm/%s.qvm", vm->name );
Com_Printf( "Loading vm file %s...\n", filename );
- length = FS_ReadFile( filename, &header.v );
+
+ length = FS_ReadFileDir(filename, vm->searchPath, &header.v);
+
if ( !header.h ) {
Com_Printf( "Failed.\n" );
VM_Free( vm );
+
+ Com_Printf(S_COLOR_YELLOW "Warning: Couldn't open VM file %s\n", filename);
+
return NULL;
}
// show where the qvm was loaded from
- Cmd_ExecuteString( va( "which %s\n", filename ) );
+ FS_Which(filename, vm->searchPath);
if( LittleLong( header.h->vmMagic ) == VM_MAGIC_VER2 ) {
Com_Printf( "...which has vmMagic VM_MAGIC_VER2\n" );
@@ -401,9 +406,13 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
|| header.h->bssLength < 0
|| header.h->dataLength < 0
|| header.h->litLength < 0
- || header.h->codeLength <= 0 ) {
- VM_Free( vm );
- Com_Error( ERR_FATAL, "%s has bad header", filename );
+ || header.h->codeLength <= 0 )
+ {
+ VM_Free(vm);
+ FS_FreeFile(header.v);
+
+ Com_Printf(S_COLOR_YELLOW "Warning: %s has bad header\n", filename);
+ return NULL;
}
} else if( LittleLong( header.h->vmMagic ) == VM_MAGIC ) {
// byte swap the header
@@ -416,14 +425,21 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc ) {
if ( header.h->bssLength < 0
|| header.h->dataLength < 0
|| header.h->litLength < 0
- || header.h->codeLength <= 0 ) {
- VM_Free( vm );
- Com_Error( ERR_FATAL, "%s has bad header", filename );
+ || header.h->codeLength <= 0 )
+ {
+ VM_Free(vm);
+ FS_FreeFile(header.v);
+
+ Com_Printf(S_COLOR_YELLOW "Warning: %s has bad header\n", filename);
+ return NULL;
}
} else {
VM_Free( vm );
- Com_Error( ERR_FATAL, "%s does not have a recognisable "
- "magic number in its header", filename );
+ FS_FreeFile(header.v);
+
+ Com_Printf(S_COLOR_YELLOW "Warning: %s does not have a recognisable "
+ "magic number in its header\n", filename);
+ return NULL;
}
// round up to next power of 2 so all data operations can
@@ -525,7 +541,9 @@ vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
vmInterpret_t interpret ) {
vm_t *vm;
vmHeader_t *header;
- int i, remaining;
+ int i, remaining, retval;
+ char filename[MAX_OSPATH];
+ void *startSearch = NULL;
if ( !module || !module[0] || !systemCalls ) {
Com_Error( ERR_FATAL, "VM_Create: bad parms" );
@@ -554,25 +572,41 @@ vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
vm = &vmTable[i];
- Q_strncpyz( vm->name, module, sizeof( vm->name ) );
- vm->systemCall = systemCalls;
+ Q_strncpyz(vm->name, module, sizeof(vm->name));
- if ( interpret == VMI_NATIVE ) {
- // try to load as a system dll
- Com_Printf( "Loading dll file %s.\n", vm->name );
- vm->dllHandle = Sys_LoadDll( module, &vm->entryPoint, VM_DllSyscall );
- if ( vm->dllHandle ) {
- return vm;
+ do
+ {
+ retval = FS_FindVM(&startSearch, filename, sizeof(filename), module, (interpret == VMI_NATIVE));
+
+ if(retval == VMI_NATIVE)
+ {
+ Com_Printf("Try loading dll file %s\n", filename);
+
+ vm->dllHandle = Sys_LoadDll(filename, &vm->entryPoint, VM_DllSyscall);
+
+ if(vm->dllHandle)
+ {
+ vm->systemCall = systemCalls;
+ return vm;
+ }
+
+ Com_Printf("Failed loading dll, trying next\n");
}
-
- Com_Printf( "Failed to load dll, looking for qvm.\n" );
- interpret = VMI_COMPILED;
- }
-
- // load the image
- if( !( header = VM_LoadQVM( vm, qtrue ) ) ) {
+ else if(retval == VMI_COMPILED)
+ {
+ vm->searchPath = startSearch;
+ if((header = VM_LoadQVM(vm, qtrue)))
+ break;
+
+ // VM_Free overwrites the name on failed load
+ Q_strncpyz(vm->name, module, sizeof(vm->name));
+ }
+ } while(retval >= 0);
+
+ if(retval < 0)
return NULL;
- }
+
+ vm->systemCall = systemCalls;
// allocate space for the jump targets, which will be filled in by the compile/prep functions
vm->instructionCount = header->instructionCount;