vm_t *VM_Create( const char *module, int (*systemCalls)(int *), vmInterpret_t interpret ) { vm_t *vm; vmHeader_t *header; int length; int dataLength; int i; char filename[MAX_QPATH]; if ( !module || !module[0] || !systemCalls ) { Com_Error( ERR_FATAL, "VM_Create: bad parms" ); } // see if we already have the VM for ( i = 0 ; i < MAX_VM ; i++ ) { if (!Q_stricmp(vmTable[i].name, module)) { vm = &vmTable[i]; return vm; } } // find a free vm for ( i = 0 ; i < MAX_VM ; i++ ) { if ( !vmTable[i].name[0] ) { break; } } if ( i == MAX_VM ) { Com_Error( ERR_FATAL, "VM_Create: no free vm_t" ); } vm = &vmTable[i]; Q_strncpyz( vm->name, module, sizeof( vm->name ) ); vm->systemCall = systemCalls; 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; } Com_Printf( "Failed to load dll, looking for qvm.\n" ); interpret = VMI_COMPILED; } // 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, (void **)&header ); if ( !header ) { Com_Printf( "Failed.\n" ); VM_Free( vm ); return NULL; } // byte swap the header for ( i = 0 ; i < sizeof( *header ) / 4 ; i++ ) { ((int *)header)[i] = LittleLong( ((int *)header)[i] ); } // validate if ( header->vmMagic != VM_MAGIC || header->bssLength < 0 || header->dataLength < 0 || header->litLength < 0 || header->codeLength <= 0 ) { VM_Free( vm ); Com_Error( ERR_FATAL, "%s has bad header", filename ); } // round up to next power of 2 so all data operations can // be mask protected dataLength = header->dataLength + header->litLength + header->bssLength; for ( i = 0 ; dataLength > ( 1 << i ) ; i++ ) { } dataLength = 1 << i; // allocate zero filled space for initialized and uninitialized data vm->dataBase = (unsigned char *)VM_Alloc( dataLength ); vm->dataMask = dataLength - 1; // copy the intialized data Com_Memcpy( vm->dataBase, (byte *)header + header->dataOffset, header->dataLength + header->litLength ); // byte swap the longs for ( i = 0 ; i < header->dataLength ; i += 4 ) { *(int *)(vm->dataBase + i) = LittleLong( *(int *)(vm->dataBase + i ) ); } // allocate space for the jump targets, which will be filled in by the compile/prep functions vm->instructionPointersLength = header->instructionCount * 4; vm->instructionPointers = (int *)VM_Alloc( vm->instructionPointersLength ); // copy or compile the instructions vm->codeLength = header->codeLength; if ( interpret >= VMI_COMPILED ) { vm->compiled = qtrue; VM_Compile( vm, header ); } else { vm->compiled = qfalse; VM_PrepareInterpreter( vm, header ); } // free the original file FS_FreeFile( header ); // load the map file VM_LoadSymbols( vm ); // the stack is implicitly at the end of the image vm->programStack = vm->dataMask + 1; vm->stackBottom = vm->programStack - STACK_SIZE; return vm; }
/* ==================== CL_UISystemCalls The ui module is making a system call ==================== */ intptr_t CL_UISystemCalls( intptr_t *args ) { switch ( args[0] ) { case UI_ERROR: Com_Error( ERR_DROP, "%s", (const char*)VMA(1) ); return 0; case UI_PRINT: Com_Printf( "%s", (const char*)VMA(1) ); return 0; case UI_MILLISECONDS: return Sys_Milliseconds(); case UI_CVAR_REGISTER: Cvar_Register( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[4] ); return 0; case UI_CVAR_UPDATE: Cvar_Update( VMA( 1 ) ); return 0; case UI_CVAR_SET: Cvar_SetSafe( VMA(1), VMA(2) ); return 0; case UI_CVAR_VARIABLEVALUE: return FloatAsInt( Cvar_VariableValue( VMA( 1 ) ) ); case UI_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( VMA( 1 ), VMA( 2 ), args[3] ); return 0; case UI_CVAR_SETVALUE: Cvar_SetValueSafe( VMA(1), VMF(2) ); return 0; case UI_CVAR_RESET: Cvar_Reset( VMA( 1 ) ); return 0; case UI_CVAR_CREATE: Cvar_Register( NULL, VMA(1), VMA(2), args[3] ); return 0; case UI_CVAR_INFOSTRINGBUFFER: Cvar_InfoStringBuffer( args[1], VMA( 2 ), args[3] ); return 0; case UI_ARGC: return Cmd_Argc(); case UI_ARGV: Cmd_ArgvBuffer( args[1], VMA( 2 ), args[3] ); return 0; case UI_CMD_EXECUTETEXT: if(args[1] == EXEC_NOW && (!strncmp(VMA(2), "snd_restart", 11) || !strncmp(VMA(2), "vid_restart", 11) || !strncmp(VMA(2), "quit", 5))) { Com_Printf (S_COLOR_YELLOW "turning EXEC_NOW '%.11s' into EXEC_INSERT\n", (const char*)VMA(2)); args[1] = EXEC_INSERT; } Cbuf_ExecuteText( args[1], VMA( 2 ) ); return 0; case UI_FS_FOPENFILE: return FS_FOpenFileByMode( VMA( 1 ), VMA( 2 ), args[3] ); case UI_FS_READ: FS_Read( VMA( 1 ), args[2], args[3] ); return 0; //----(SA) added case UI_FS_SEEK: FS_Seek( args[1], args[2], args[3] ); return 0; //----(SA) end case UI_FS_WRITE: FS_Write( VMA( 1 ), args[2], args[3] ); return 0; case UI_FS_FCLOSEFILE: FS_FCloseFile( args[1] ); return 0; case UI_FS_DELETEFILE: return FS_Delete( VMA( 1 ) ); case UI_FS_GETFILELIST: return FS_GetFileList( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[4] ); case UI_R_REGISTERMODEL: return re.RegisterModel( VMA( 1 ) ); case UI_R_REGISTERSKIN: return re.RegisterSkin( VMA( 1 ) ); case UI_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( VMA( 1 ) ); case UI_R_CLEARSCENE: re.ClearScene(); return 0; case UI_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( VMA( 1 ) ); return 0; case UI_R_ADDPOLYTOSCENE: re.AddPolyToScene( args[1], args[2], VMA( 3 ) ); return 0; // Ridah case UI_R_ADDPOLYSTOSCENE: re.AddPolysToScene( args[1], args[2], VMA( 3 ), args[4] ); return 0; // done. case UI_R_ADDLIGHTTOSCENE: re.AddLightToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6] ); return 0; case UI_R_ADDCORONATOSCENE: re.AddCoronaToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6], args[7] ); return 0; case UI_R_RENDERSCENE: re.RenderScene( VMA( 1 ) ); return 0; case UI_R_SETCOLOR: re.SetColor( VMA( 1 ) ); return 0; case UI_R_DRAWSTRETCHPIC: re.DrawStretchPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9] ); return 0; case UI_R_MODELBOUNDS: re.ModelBounds( args[1], VMA( 2 ), VMA( 3 ) ); return 0; case UI_UPDATESCREEN: SCR_UpdateScreen(); return 0; case UI_CM_LERPTAG: return re.LerpTag( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[4] ); case UI_S_REGISTERSOUND: #ifdef DOOMSOUND ///// (SA) DOOMSOUND return S_RegisterSound( VMA( 1 ) ); #else return S_RegisterSound( VMA( 1 ), qfalse ); #endif ///// (SA) DOOMSOUND case UI_S_STARTLOCALSOUND: S_StartLocalSound( args[1], args[2] ); return 0; //----(SA) added case UI_S_FADESTREAMINGSOUND: S_FadeStreamingSound( VMF( 1 ), args[2], args[3] ); return 0; case UI_S_FADEALLSOUNDS: S_FadeAllSounds( VMF( 1 ), args[2] ); return 0; //----(SA) end case UI_KEY_KEYNUMTOSTRINGBUF: Key_KeynumToStringBuf( args[1], VMA( 2 ), args[3] ); return 0; case UI_KEY_GETBINDINGBUF: Key_GetBindingBuf( args[1], VMA( 2 ), args[3] ); return 0; case UI_KEY_SETBINDING: Key_SetBinding( args[1], VMA( 2 ) ); return 0; case UI_KEY_ISDOWN: return Key_IsDown( args[1] ); case UI_KEY_GETOVERSTRIKEMODE: return Key_GetOverstrikeMode(); case UI_KEY_SETOVERSTRIKEMODE: Key_SetOverstrikeMode( args[1] ); return 0; case UI_KEY_CLEARSTATES: Key_ClearStates(); return 0; case UI_KEY_GETCATCHER: return Key_GetCatcher(); case UI_KEY_SETCATCHER: // Don't allow the ui module to close the console Key_SetCatcher( args[1] | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ); return 0; case UI_GETCLIPBOARDDATA: CL_GetClipboardData( VMA(1), args[2] ); return 0; case UI_GETCLIENTSTATE: GetClientState( VMA( 1 ) ); return 0; case UI_GETGLCONFIG: CL_GetGlconfig( VMA( 1 ) ); return 0; case UI_GETCONFIGSTRING: return GetConfigString( args[1], VMA( 2 ), args[3] ); case UI_LAN_LOADCACHEDSERVERS: LAN_LoadCachedServers(); return 0; case UI_LAN_SAVECACHEDSERVERS: LAN_SaveServersToCache(); return 0; case UI_LAN_ADDSERVER: return LAN_AddServer( args[1], VMA( 2 ), VMA( 3 ) ); case UI_LAN_REMOVESERVER: LAN_RemoveServer( args[1], VMA( 2 ) ); return 0; case UI_LAN_GETPINGQUEUECOUNT: return LAN_GetPingQueueCount(); case UI_LAN_CLEARPING: LAN_ClearPing( args[1] ); return 0; case UI_LAN_GETPING: LAN_GetPing( args[1], VMA( 2 ), args[3], VMA( 4 ) ); return 0; case UI_LAN_GETPINGINFO: LAN_GetPingInfo( args[1], VMA( 2 ), args[3] ); return 0; case UI_LAN_GETSERVERCOUNT: return LAN_GetServerCount( args[1] ); case UI_LAN_GETSERVERADDRESSSTRING: LAN_GetServerAddressString( args[1], args[2], VMA( 3 ), args[4] ); return 0; case UI_LAN_GETSERVERINFO: LAN_GetServerInfo( args[1], args[2], VMA( 3 ), args[4] ); return 0; case UI_LAN_GETSERVERPING: return LAN_GetServerPing( args[1], args[2] ); case UI_LAN_MARKSERVERVISIBLE: LAN_MarkServerVisible( args[1], args[2], args[3] ); return 0; case UI_LAN_SERVERISVISIBLE: return LAN_ServerIsVisible( args[1], args[2] ); case UI_LAN_UPDATEVISIBLEPINGS: return LAN_UpdateVisiblePings( args[1] ); case UI_LAN_RESETPINGS: LAN_ResetPings( args[1] ); return 0; case UI_LAN_SERVERSTATUS: return LAN_GetServerStatus( VMA( 1 ), VMA( 2 ), args[3] ); case UI_LAN_COMPARESERVERS: return LAN_CompareServers( args[1], args[2], args[3], args[4], args[5] ); case UI_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case UI_GET_CDKEY: CLUI_GetCDKey( VMA( 1 ), args[2] ); return 0; case UI_SET_CDKEY: #ifndef STANDALONE CLUI_SetCDKey( VMA( 1 ) ); #endif return 0; case UI_R_REGISTERFONT: re.RegisterFont( VMA( 1 ), args[2], VMA( 3 ) ); return 0; case UI_MEMSET: Com_Memset( VMA(1), args[2], args[3] ); return args[1]; case UI_MEMCPY: Com_Memset( VMA(1), args[2], args[3] ); return args[1]; case UI_STRNCPY: strncpy( VMA(1), VMA(2), args[3] ); return args[1]; case UI_SIN: return FloatAsInt( sin( VMF( 1 ) ) ); case UI_COS: return FloatAsInt( cos( VMF( 1 ) ) ); case UI_ATAN2: return FloatAsInt( atan2( VMF( 1 ), VMF( 2 ) ) ); case UI_SQRT: return FloatAsInt( sqrt( VMF( 1 ) ) ); case UI_FLOOR: return FloatAsInt( floor( VMF( 1 ) ) ); case UI_CEIL: return FloatAsInt( ceil( VMF( 1 ) ) ); case UI_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine( VMA( 1 ) ); case UI_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle( VMA( 1 ) ); case UI_PC_FREE_SOURCE: return botlib_export->PC_FreeSourceHandle( args[1] ); case UI_PC_READ_TOKEN: return botlib_export->PC_ReadTokenHandle( args[1], VMA( 2 ) ); case UI_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], VMA( 2 ), VMA( 3 ) ); case UI_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case UI_S_STARTBACKGROUNDTRACK: // S_StartBackgroundTrack( VMA( 1 ), VMA( 2 ), args[3] ); //----(SA) added fadeup time S_StartBackgroundTrack( VMA( 1 ), VMA( 2 ) ); return 0; case UI_REAL_TIME: return Com_RealTime( VMA( 1 ) ); case UI_CIN_PLAYCINEMATIC: Com_DPrintf( "UI_CIN_PlayCinematic\n" ); return CIN_PlayCinematic( VMA( 1 ), args[2], args[3], args[4], args[5], args[6] ); case UI_CIN_STOPCINEMATIC: return CIN_StopCinematic( args[1] ); case UI_CIN_RUNCINEMATIC: return CIN_RunCinematic( args[1] ); case UI_CIN_DRAWCINEMATIC: CIN_DrawCinematic( args[1] ); return 0; case UI_CIN_SETEXTENTS: CIN_SetExtents( args[1], args[2], args[3], args[4], args[5] ); return 0; case UI_R_REMAP_SHADER: re.RemapShader( VMA( 1 ), VMA( 2 ), VMA( 3 ) ); return 0; case UI_VERIFY_CDKEY: return CL_CDKeyValidate( VMA( 1 ), VMA( 2 ) ); // NERVE - SMF case UI_CL_GETLIMBOSTRING: return CL_GetLimboString( args[1], VMA( 2 ) ); // -NERVE - SMF // New in IORTCW case UI_ALLOC: return VM_Alloc( args[1] ); default: Com_Error( ERR_DROP, "Bad UI system trap: %ld", (long int) args[0] ); } return 0; }
/* =============== VM_LoadSymbols =============== */ void VM_LoadSymbols( vm_t *vm ) { int len; char *mapfile, *token; const char *text_p; char name[MAX_QPATH]; char symbols[MAX_QPATH]; vmSymbol_t **prev, *sym; int count; int value; int chars; int segment; int numInstructions; // don't load symbols if not developer if ( !com_developer->integer ) { return; } COM_StripExtension( vm->name, name, sizeof( name ) ); Com_sprintf( symbols, sizeof( symbols ), "vm/%s.map", name ); len = FS_ReadFile( symbols, (void **)&mapfile ); if ( !mapfile ) { Com_Printf( "Couldn't load symbol file: %s\n", symbols ); return; } numInstructions = vm->instructionPointersLength >> 2; // parse the symbols text_p = mapfile; prev = &vm->symbols; count = 0; #ifdef CRAZY_SYMBOL_MAP VM_SetSymbolMap(vm); #endif while ( 1 ) { token = COM_Parse( &text_p ); if ( !token[0] ) { break; } segment = ParseHex( token ); if ( segment ) { COM_Parse( &text_p ); COM_Parse( &text_p ); continue; // only load code segment values } token = COM_Parse( &text_p ); if ( !token[0] ) { Com_Printf( "WARNING: incomplete line at end of file\n" ); break; } value = ParseHex( token ); token = COM_Parse( &text_p ); if ( !token[0] ) { Com_Printf( "WARNING: incomplete line at end of file\n" ); break; } chars = strlen( token ); sym = (struct vmSymbol_s *)VM_Alloc( sizeof( *sym ) + chars ); *prev = sym; prev = &sym->next; sym->next = NULL; // convert value from an instruction number to a code offset if ( value >= 0 && value < numInstructions ) { value = vm->instructionPointers[value]; } sym->symValue = value; Q_strncpyz( sym->symName, token, chars + 1 ); #ifdef CRAZY_SYMBOL_MAP (*g_symbolMap)[value] = sym; #endif count++; } vm->numSymbols = count; Com_Printf( "%i symbols parsed from %s\n", count, symbols ); FS_FreeFile( mapfile ); }
/* ======================================================================================================================================= CL_CgameSystemCalls The cgame module is making a system call. ======================================================================================================================================= */ intptr_t CL_CgameSystemCalls(intptr_t *args) { switch (args[0]) { case CG_PRINT: Com_Printf("%s", (const char *)VMA(1)); return 0; case CG_ERROR: Com_Error(ERR_DROP, "%s", (const char *)VMA(1)); return 0; case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register(VMA(1), VMA(2), VMA(3), args[4]); return 0; case CG_CVAR_UPDATE: Cvar_Update(VMA(1)); return 0; case CG_CVAR_SET: Cvar_SetSafe(VMA(1), VMA(2)); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer(VMA(1), VMA(2), args[3]); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: Cmd_ArgvBuffer(args[1], VMA(2), args[3]); return 0; case CG_ARGS: Cmd_ArgsBuffer(VMA(1), args[2]); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode(VMA(1), VMA(2), args[3]); case CG_FS_READ: FS_Read(VMA(1), args[2], args[3]); return 0; case CG_FS_WRITE: return FS_Write(VMA(1), args[2], args[3]); case CG_FS_FCLOSEFILE: FS_FCloseFile(args[1]); return 0; case CG_SENDCONSOLECOMMAND: Cbuf_AddText(VMA(1)); return 0; case CG_ADDCOMMAND: CL_AddCgameCommand(VMA(1)); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommandSafe(VMA(1)); return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand(VMA(1), qfalse); return 0; case CG_UPDATESCREEN: // this is used during lengthy level loading, so pump message loop // Com_EventLoop(); // FIXME: if a server restarts here, BAD THINGS HAPPEN! // We can't call Com_EventLoop here, a restart will crash and this _does_ happen // if there is a map change while we are downloading at pk3. // ZOID SCR_UpdateScreen(); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap(VMA(1)); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel(args[1]); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel(VMA(1), VMA(2), qfalse); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel(VMA(1), VMA(2), qtrue); case CG_CM_POINTCONTENTS: return CM_PointContents(VMA(1), args[2]); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents(VMA(1), args[2], VMA(3), VMA(4)); case CG_CM_BOXTRACE: CM_BoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qfalse); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue); return 0; case CG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qtrue); return 0; case CG_CM_MARKFRAGMENTS: return re.MarkFragments(args[1], VMA(2), VMA(3), args[4], VMA(5), args[6], VMA(7)); case CG_S_STARTSOUND: S_StartSound(VMA(1), args[2], args[3], args[4]); return 0; case CG_S_STARTSOUNDEX: S_StartSoundEx(VMA(1), args[2], args[3], args[4], args[5]); return 0; // end case CG_S_STARTLOCALSOUND: S_StartLocalSound(args[1], args[2]); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds(args[1]); // (SA) modified so no_pvs sounds can function // if killall, then stop all sounds // if (args[1] == 1) { // S_ClearSounds(qtrue, qfalse); // } else if (args[1] == 2) { // S_ClearSounds(qtrue, qtrue); // } return 0; case CG_S_ADDLOOPINGSOUND: // FIXME MrE: handling of looping sounds changed S_AddLoopingSound(args[1], VMA(2), VMA(3), args[4], args[5], args[6]); return 0; // not in use // case CG_S_ADDREALLOOPINGSOUND: // S_AddLoopingSound(args[1], VMA(2), VMA(3), args[4], args[5], args[6]); // // S_AddRealLoopingSound(args[1], VMA(2), VMA(3), args[4], args[5]); // return 0; case CG_S_STOPSTREAMINGSOUND: S_StopEntStreamingSound(args[1]); return 0; case CG_S_STOPLOOPINGSOUND: // not functional anymore, since we reverted to old looping code // S_StopLoopingSound(args[1]); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition(args[1], VMA(2)); return 0; // talking animations case CG_S_GETVOICEAMPLITUDE: return S_GetVoiceAmplitude(args[1]); // done. case CG_S_RESPATIALIZE: S_Respatialize(args[1], VMA(2), VMA(3), args[4]); return 0; case CG_S_REGISTERSOUND: #ifdef DOOMSOUND // / // (SA) DOOMSOUND return S_RegisterSound(VMA(1)); #else return S_RegisterSound(VMA(1), qfalse); #endif // / // (SA) DOOMSOUND case CG_S_STARTBACKGROUNDTRACK: // S_StartBackgroundTrack(VMA(1), VMA(2), args[3]); // added fadeup time S_StartBackgroundTrack(VMA(1), VMA(2)); return 0; case CG_S_FADESTREAMINGSOUND: S_FadeStreamingSound(VMF(1), args[2], args[3]); // added music / all - streaming options return 0; case CG_S_STARTSTREAMINGSOUND: S_StartStreamingSound(VMA(1), VMA(2), args[3], args[4], args[5]); return 0; case CG_S_FADEALLSOUNDS: S_FadeAllSounds(VMF(1), args[2]); return 0; case CG_R_LOADWORLDMAP: re.LoadWorld(VMA(1)); return 0; case CG_R_REGISTERMODEL: return re.RegisterModel(VMA(1)); case CG_R_REGISTERSKIN: return re.RegisterSkin(VMA(1)); case CG_R_GETSKINMODEL: return re.GetSkinModel(args[1], VMA(2), VMA(3)); case CG_R_GETMODELSHADER: return re.GetShaderFromModel(args[1], args[2], args[3]); case CG_R_REGISTERSHADER: return re.RegisterShader(VMA(1)); case CG_R_REGISTERFONT: re.RegisterFont(VMA(1), args[2], VMA(3)); return 0; case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip(VMA(1)); case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene(VMA(1)); return 0; case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene(args[1], args[2], VMA(3)); return 0; // Ridah case CG_R_ADDPOLYSTOSCENE: re.AddPolysToScene(args[1], args[2], VMA(3), args[4]); return 0; case CG_RB_ZOMBIEFXADDNEWHIT: re.ZombieFXAddNewHit(args[1], VMA(2), VMA(3)); return 0; // done. // case CG_R_LIGHTFORPOINT: // return re.LightForPoint(VMA(1), VMA(2), VMA(3), VMA(4)); case CG_R_ADDLIGHTTOSCENE: re.AddLightToScene(VMA(1), VMF(2), VMF(3), VMF(4), VMF(5), args[6]); return 0; // case CG_R_ADDADDITIVELIGHTTOSCENE: // re.AddAdditiveLightToScene(VMA(1), VMF(2), VMF(3), VMF(4), VMF(5)); // return 0; case CG_R_ADDCORONATOSCENE: re.AddCoronaToScene(VMA(1), VMF(2), VMF(3), VMF(4), VMF(5), args[6], args[7]); return 0; case CG_R_SETFOG: re.SetFog(args[1], args[2], args[3], VMF(4), VMF(5), VMF(6), VMF(7)); return 0; case CG_R_RENDERSCENE: re.RenderScene(VMA(1)); return 0; case CG_R_SETCOLOR: re.SetColor(VMA(1)); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic(VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9]); return 0; case CG_R_DRAWSTRETCHPIC_GRADIENT: re.DrawStretchPicGradient(VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9], VMA(10), args[11]); return 0; case CG_R_MODELBOUNDS: re.ModelBounds(args[1], VMA(2), VMA(3)); return 0; case CG_R_LERPTAG: return re.LerpTag(VMA(1), VMA(2), VMA(3), args[4]); case CG_GETGLCONFIG: CL_GetGlconfig(VMA(1)); return 0; case CG_GETGAMESTATE: CL_GetGameState(VMA(1)); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber(VMA(1), VMA(2)); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot(args[1], VMA(2)); case CG_GETSERVERCOMMAND: return CL_GetServerCommand(args[1]); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd(args[1], VMA(2)); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue(args[1], args[2], VMF(3), args[4]); // modified // added fourth arg [cld] return 0; case CG_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case CG_KEY_ISDOWN: return Key_IsDown(args[1]); case CG_KEY_GETCATCHER: return Key_GetCatcher(); case CG_KEY_SETCATCHER: // Don't allow the cgame module to close the console Key_SetCatcher(args[1]|(Key_GetCatcher() & KEYCATCH_CONSOLE)); return 0; case CG_KEY_GETKEY: return Key_GetKey(VMA(1)); case CG_MEMSET: Com_Memset(VMA(1), args[2], args[3]); return args[1]; case CG_MEMCPY: Com_Memcpy(VMA(1), VMA(2), args[3]); return args[1]; case CG_STRNCPY: strncpy(VMA(1), VMA(2), args[3]); return args[1]; case CG_SIN: return FloatAsInt(sin(VMF(1))); case CG_COS: return FloatAsInt(cos(VMF(1))); case CG_ATAN2: return FloatAsInt(atan2(VMF(1), VMF(2))); case CG_SQRT: return FloatAsInt(sqrt(VMF(1))); case CG_FLOOR: return FloatAsInt(floor(VMF(1))); case CG_CEIL: return FloatAsInt(ceil(VMF(1))); case CG_ACOS: return FloatAsInt(Q_acos(VMF(1))); case CG_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine(VMA(1)); case CG_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle(VMA(1)); case CG_PC_FREE_SOURCE: return botlib_export->PC_FreeSourceHandle(args[1]); case CG_PC_READ_TOKEN: return botlib_export->PC_ReadTokenHandle(args[1], VMA(2)); case CG_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine(args[1], VMA(2), VMA(3)); case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime(VMA(1)); case CG_SNAPVECTOR: Q_SnapVector(VMA(1)); return 0; case CG_SENDMOVESPEEDSTOGAME: SV_SendMoveSpeedsToGame(args[1], VMA(2)); return 0; case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic(args[1]); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic(args[1]); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic(args[1]); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]); return 0; case CG_R_REMAP_SHADER: re.RemapShader(VMA(1), VMA(2), VMA(3)); return 0; case CG_TESTPRINTINT: // Com_Printf("%s%i\n", (const char *)VMA(1), args[2]); return 0; case CG_TESTPRINTFLOAT: // Com_Printf("%s%f\n", (const char *)VMA(1), VMF(2)); return 0; case CG_LOADCAMERA: return loadCamera(args[1], VMA(2)); case CG_STARTCAMERA: if (args[1] == 0) { // CAM_PRIMARY cl.cameraMode = qtrue; } startCamera(args[1], args[2]); return 0; case CG_STOPCAMERA: if (args[1] == 0) { // CAM_PRIMARY cl.cameraMode = qfalse; } // stopCamera(args[1]); return 0; case CG_GETCAMERAINFO: return getCameraInfo(args[1], args[2], VMA(3), VMA(4), VMA(5)); case CG_GET_ENTITY_TOKEN: return re.GetEntityToken(VMA(1), args[2]); case CG_INGAME_POPUP: if (VMA(1) && !Q_stricmp(VMA(1), "briefing")) { // ---- (SA) added VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_BRIEFING); return 0; } if (clc.state == CA_ACTIVE && !clc.demoplaying) { // NERVE - SMF if (VMA(1) && !Q_stricmp(VMA(1), "UIMENU_WM_PICKTEAM")) { VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_PICKTEAM); } else if (VMA(1) && !Q_stricmp(VMA(1), "UIMENU_WM_PICKPLAYER")) { VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_PICKPLAYER); } else if (VMA(1) && !Q_stricmp(VMA(1), "UIMENU_WM_QUICKMESSAGE")) { VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_QUICKMESSAGE); } else if (VMA(1) && !Q_stricmp(VMA(1), "UIMENU_WM_LIMBO")) { VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_LIMBO); } // - NERVE - SMF else if (VMA(1) && !Q_stricmp(VMA(1), "hbook1")) { // ---- (SA) VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK1); } else if (VMA(1) && !Q_stricmp(VMA(1), "hbook2")) { // ---- (SA) VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK2); } else if (VMA(1) && !Q_stricmp(VMA(1), "hbook3")) { // ---- (SA) VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK3); } else if (VMA(1) && !Q_stricmp(VMA(1), "pregame")) { // ---- (SA) added VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_PREGAME); } else { VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_CLIPBOARD); } } return 0; // NERVE - SMF case CG_INGAME_CLOSEPOPUP: VM_Call(uivm, UI_KEY_EVENT, K_ESCAPE, qtrue); return 0; case CG_LIMBOCHAT: if (VMA(1)) { CL_AddToLimboChat(VMA(1)); } return 0; // - NERVE - SMF case CG_GETMODELINFO: return SV_GetModelInfo(args[1], VMA(2), VMA(3)); // New in IORTCW case CG_ALLOC: return VM_Alloc(args[1]); default: assert(0); Com_Error(ERR_DROP, "Bad cgame system trap: %ld", (long int)args[0]); } return 0; }