- Small change to search path order - local files not in .pk3s take precedence over files in pk3s. Should make life easier for modders/mappers wanting to override textures that are already contained in some older pk3

- Make VM loading more robust, change loading order: when vm_* == 0 first try loading DLL, then QVM in *each* search directory/path
- Fix FS_FileForHandle that would return a FILE pointer to invalid file handle 0
This commit is contained in:
Thilo Schulz 2011-06-15 22:09:26 +00:00
parent 1ff28b3b2e
commit 9219cde4e8
6 changed files with 584 additions and 368 deletions

View file

@ -377,15 +377,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" );
@ -400,9 +405,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
@ -415,14 +424,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
@ -524,7 +540,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" );
@ -553,25 +571,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");
}
else if(retval == VMI_COMPILED)
{
vm->searchPath = startSearch;
if((header = VM_LoadQVM(vm, qtrue)))
break;
Com_Printf( "Failed to load dll, looking for qvm.\n" );
interpret = VMI_COMPILED;
}
// load the image
if( !( header = VM_LoadQVM( vm, qtrue ) ) ) {
// 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;