/* ==================== RE_BeginFrame If running in stereo, RE_BeginFrame will be called twice for each RE_EndFrame ==================== */ void RE_BeginFrame( stereoFrame_t stereoFrame ) { drawBufferCommand_t *cmd; if ( !tr.registered ) { return; } glState.finishCalled = qfalse; tr.frameCount++; tr.frameSceneNum = 0; // // do overdraw measurement // if ( r_measureOverdraw->integer ) { if ( glConfig.stencilBits < 4 ) { Com_Printf ("Warning: not enough stencil bits to measure overdraw: %d\n", glConfig.stencilBits ); ri.Cvar_Set( "r_measureOverdraw", "0" ); r_measureOverdraw->modified = qfalse; } else if ( r_shadows->integer == 2 ) { Com_Printf ("Warning: stencil shadows and overdraw measurement are mutually exclusive\n" ); ri.Cvar_Set( "r_measureOverdraw", "0" ); r_measureOverdraw->modified = qfalse; } else { R_SyncRenderThread(); qglEnable( GL_STENCIL_TEST ); qglStencilMask( ~0U ); qglClearStencil( 0U ); qglStencilFunc( GL_ALWAYS, 0U, ~0U ); qglStencilOp( GL_KEEP, GL_INCR, GL_INCR ); } r_measureOverdraw->modified = qfalse; } else { // this is only reached if it was on and is now off if ( r_measureOverdraw->modified ) { R_SyncRenderThread(); qglDisable( GL_STENCIL_TEST ); } r_measureOverdraw->modified = qfalse; } // // texturemode stuff // if ( r_textureMode->modified || r_ext_texture_filter_anisotropic->modified) { R_SyncRenderThread(); GL_TextureMode( r_textureMode->string ); r_textureMode->modified = qfalse; r_ext_texture_filter_anisotropic->modified = qfalse; } // // gamma stuff // if ( r_gamma->modified ) { r_gamma->modified = qfalse; R_SyncRenderThread(); R_SetColorMappings(); } // check for errors if ( !r_ignoreGLErrors->integer ) { int err; R_SyncRenderThread(); if ( ( err = qglGetError() ) != GL_NO_ERROR ) { Com_Error( ERR_FATAL, "RE_BeginFrame() - glGetError() failed (0x%x)!\n", err ); } } // // draw buffer stuff // cmd = (drawBufferCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) ); if ( !cmd ) { return; } cmd->commandId = RC_DRAW_BUFFER; if ( glConfig.stereoEnabled ) { if ( stereoFrame == STEREO_LEFT ) { cmd->buffer = (int)GL_BACK_LEFT; } else if ( stereoFrame == STEREO_RIGHT ) { cmd->buffer = (int)GL_BACK_RIGHT; } else { Com_Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame ); } } else { if ( stereoFrame != STEREO_CENTER ) { Com_Error( ERR_FATAL, "RE_BeginFrame: Stereo is disabled, but stereoFrame was %i", stereoFrame ); } // if ( !Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) ) { // cmd->buffer = (int)GL_FRONT; // } else { cmd->buffer = (int)GL_BACK; } } }
int BG_SiegeGetPairedValue(char *buf, char *key, char *outbuf) { int i = 0; int j; int k; char checkKey[4096]; while (buf[i]) { if (buf[i] != ' ' && buf[i] != '{' && buf[i] != '}' && buf[i] != '\n' && buf[i] != '\r') { //we're on a valid character if (buf[i] == '/' && buf[i+1] == '/') { //this is a comment, so skip over it while (buf[i] && buf[i] != '\n' && buf[i] != '\r') { i++; } } else { //parse to the next space/endline/eos and check this value against our key value. j = 0; while (buf[i] != ' ' && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB && buf[i]) { if (buf[i] == '/' && buf[i+1] == '/') { //hit a comment, break out. break; } checkKey[j] = buf[i]; j++; i++; } checkKey[j] = 0; k = i; while (buf[k] && (buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\r')) { k++; } if (buf[k] == '{') { //this is not the start of a value but rather of a group. We don't want to look in subgroups so skip over the whole thing. int openB = 0; while (buf[i] && (buf[i] != '}' || openB)) { if (buf[i] == '{') { openB++; } else if (buf[i] == '}') { openB--; } if (openB < 0) { Com_Error(ERR_DROP, "Unexpected closing bracket (too many) while parsing to end of group '%s'", checkKey); } if (buf[i] == '}' && !openB) { //this is the end of the group break; } i++; } if (buf[i] == '}') { i++; } } else { //Is this the one we want? if (buf[i] != '/' || buf[i+1] != '/') { //make sure we didn't stop on a comment, if we did then this is considered an error in the file. if (!Q_stricmp(checkKey, key)) { //guess so. Parse along to the next valid character, then put that into the output buffer and return 1. while ((buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r' || buf[i] == SIEGECHAR_TAB) && buf[i]) { i++; } if (buf[i]) { //We're at the start of the value now. qboolean parseToQuote = qfalse; if (buf[i] == '\"') { //if the value is in quotes, then stop at the next quote instead of ' ' i++; parseToQuote = qtrue; } j = 0; while ( ((!parseToQuote && buf[i] != ' ' && buf[i] != '\n' && buf[i] != '\r') || (parseToQuote && buf[i] != '\"')) ) { if (buf[i] == '/' && buf[i+1] == '/') { //hit a comment after the value? This isn't an ideal way to be writing things, but we'll support it anyway. break; } outbuf[j] = buf[i]; j++; i++; if (!buf[i]) { if (parseToQuote) { Com_Error(ERR_DROP, "Unexpected EOF while looking for endquote, error finding paired value for '%s'", key); } else { Com_Error(ERR_DROP, "Unexpected EOF while looking for space or endline, error finding paired value for '%s'", key); } } } outbuf[j] = 0; return 1; //we got it, so return 1. } else { Com_Error(ERR_DROP, "Error parsing file, unexpected EOF while looking for valud '%s'", key); } } else { //if that wasn't the desired key, then make sure we parse to the end of the line, so we don't mistake a value for a key while (buf[i] && buf[i] != '\n') { i++; } } } else { Com_Error(ERR_DROP, "Error parsing file, found comment, expected value for '%s'", key); } } } } if (!buf[i]) { break; } i++; } return 0; //guess we never found it. }
/* ================ ClipSkyPolygon ================ */ static void ClipSkyPolygon (int nump, vec3_t vecs, int stage) { float *norm; float *v; qboolean front, back; float d, e; float dists[MAX_CLIP_VERTS]; int sides[MAX_CLIP_VERTS]; vec3_t newv[2][MAX_CLIP_VERTS]; int newc[2]; int i, j; if (nump > MAX_CLIP_VERTS-2) Com_Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS"); if (stage == 6) { // fully clipped, so draw it AddSkyPolygon (nump, vecs); return; } front = back = qfalse; norm = sky_clip[stage]; for (i=0, v = vecs ; i<nump ; i++, v+=3) { d = DotProduct (v, norm); if (d > ON_EPSILON) { front = qtrue; sides[i] = SIDE_FRONT; } else if (d < -ON_EPSILON) { back = qtrue; sides[i] = SIDE_BACK; } else sides[i] = SIDE_ON; dists[i] = d; } if (!front || !back) { // not clipped ClipSkyPolygon (nump, vecs, stage+1); return; } // clip it sides[i] = sides[0]; dists[i] = dists[0]; VectorCopy (vecs, (vecs+(i*3)) ); newc[0] = newc[1] = 0; for (i=0, v = vecs ; i<nump ; i++, v+=3) { switch (sides[i]) { case SIDE_FRONT: VectorCopy (v, newv[0][newc[0]]); newc[0]++; break; case SIDE_BACK: VectorCopy (v, newv[1][newc[1]]); newc[1]++; break; case SIDE_ON: VectorCopy (v, newv[0][newc[0]]); newc[0]++; VectorCopy (v, newv[1][newc[1]]); newc[1]++; break; } if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) continue; d = dists[i] / (dists[i] - dists[i+1]); for (j=0 ; j<3 ; j++) { e = v[j] + d*(v[j+3] - v[j]); newv[0][newc[0]][j] = e; newv[1][newc[1]][j] = e; } newc[0]++; newc[1]++; } // continue ClipSkyPolygon (newc[0], newv[0][0], stage+1); ClipSkyPolygon (newc[1], newv[1][0], stage+1); }
/* ============== VID_LoadRefresh ============== */ qboolean VID_LoadRefresh( char *name ) { refimport_t ri; #ifndef REF_HARD_LINKED GetRefAPI_t GetRefAPI; #endif if ( reflib_active ) { re.Shutdown(); VID_FreeReflib (); } Com_Printf( "------- Loading %s -------\n", name ); #ifndef REF_HARD_LINKED if ( ( reflib_library = LoadLibrary( name ) ) == NULL ) { Com_Printf( "LoadLibrary(\"%s\") failed\n", name ); return false; } #endif ri.Cmd_AddCommand = Cmd_AddCommand; ri.Cmd_RemoveCommand = Cmd_RemoveCommand; ri.Cmd_Argc = Cmd_Argc; ri.Cmd_Argv = Cmd_Argv; ri.Cmd_ExecuteText = Cbuf_ExecuteText; ri.Con_Printf = VID_Printf; ri.Sys_Error = VID_Error; ri.FS_LoadFile = FS_LoadFile; ri.FS_FreeFile = FS_FreeFile; ri.FS_Gamedir = FS_Gamedir; ri.Cvar_Get = Cvar_Get; ri.Cvar_Set = Cvar_Set; ri.Cvar_SetValue = Cvar_SetValue; ri.Vid_GetModeInfo = VID_GetModeInfo; ri.Vid_MenuInit = VID_MenuInit; ri.Vid_NewWindow = VID_NewWindow; #ifndef REF_HARD_LINKED if ( ( GetRefAPI = (void *) GetProcAddress( reflib_library, "GetRefAPI" ) ) == NULL ) Com_Error( ERR_FATAL, "GetProcAddress failed on %s", name ); #endif re = GetRefAPI( ri ); if (re.api_version != API_VERSION) { VID_FreeReflib (); Com_Error (ERR_FATAL, "%s has incompatible api_version", name); } if ( re.Init( global_hInstance, MainWndProc ) == -1 ) { re.Shutdown(); VID_FreeReflib (); return false; } Com_Printf( "------------------------------------\n"); reflib_active = true; //====== //PGM vidref_val = VIDREF_OTHER; if(vid_ref) { if(!strcmp (vid_ref->string, "gl")) vidref_val = VIDREF_GL; else if(!strcmp(vid_ref->string, "soft")) vidref_val = VIDREF_SOFT; } //PGM //====== return true; }
void BG_SiegeParseTeamFile(const char *filename) { fileHandle_t f; int len; char teamInfo[2048]; char parseBuf[1024]; char lookString[256]; int i = 1; qboolean success = qtrue; len = trap->FS_Open(filename, &f, FS_READ); if (!f || len >= 2048) { return; } trap->FS_Read( teamInfo, len, f ); trap->FS_Close( f ); teamInfo[len] = 0; if (BG_SiegeGetPairedValue(teamInfo, "name", parseBuf)) { Q_strncpyz(bgSiegeTeams[bgNumSiegeTeams].name, parseBuf, sizeof(bgSiegeTeams[0].name)); } else { Com_Error(ERR_DROP, "Siege team with no name definition"); } //I don't entirely like doing things this way but it's the easiest way. #ifdef _CGAME if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", parseBuf)) bgSiegeTeams[bgNumSiegeTeams].friendlyShader = trap->R_RegisterShaderNoMip(parseBuf); #else bgSiegeTeams[bgNumSiegeTeams].friendlyShader = 0; #endif bgSiegeTeams[bgNumSiegeTeams].numClasses = 0; if (BG_SiegeGetValueGroup(teamInfo, "Classes", teamInfo)) { while (success && i < MAX_SIEGE_CLASSES) { //keep checking for group values named class# up to MAX_SIEGE_CLASSES until we can't find one. Q_strncpyz(lookString, va("class%i", i), sizeof(lookString)); success = BG_SiegeGetPairedValue(teamInfo, lookString, parseBuf); if (!success) { break; } bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses] = BG_SiegeFindClassByName(parseBuf); if (!bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses]) { Com_Printf( "Invalid class specified: '%s'\n", parseBuf); } bgSiegeTeams[bgNumSiegeTeams].numClasses++; i++; } } if (!bgSiegeTeams[bgNumSiegeTeams].numClasses) { Com_Error(ERR_DROP, "Team defined with no allowable classes\n"); } //If we get here then it was a success, so increment the team number bgNumSiegeTeams++; }
/* ================== SCR_DrawScreenField This will be called twice if rendering in stereo mode ================== */ void SCR_DrawScreenField(stereoFrame_t stereoFrame) { re.BeginFrame(stereoFrame); // wide aspect ratio screens need to have the sides cleared // unless they are displaying game renderings if (cls.state != CA_ACTIVE && cls.state != CA_CINEMATIC) { if (cls.glconfig.vidWidth * 480 > cls.glconfig.vidHeight * 640) { re.SetColor(g_color_table[0]); re.DrawStretchPic(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, 0, 0, 0, cls.whiteShader); re.SetColor(NULL); } } // if the menu is going to cover the entire screen, we // don't need to render anything under it if (uivm && !VM_Call(uivm, UI_IS_FULLSCREEN)) { switch (cls.state) { default: Com_Error(ERR_FATAL, "SCR_DrawScreenField: bad cls.state"); break; case CA_CINEMATIC: SCR_DrawCinematic(); break; case CA_DISCONNECTED: // force menu up S_StopAllSounds(); VM_Call(uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN); break; case CA_CONNECTING: case CA_CHALLENGING: case CA_CONNECTED: // connecting clients will only show the connection dialog // refresh to update the time VM_Call(uivm, UI_REFRESH, cls.realtime); VM_Call(uivm, UI_DRAW_CONNECT_SCREEN, qfalse); break; case CA_LOADING: case CA_PRIMED: // draw the game information screen and loading progress CL_CGameRendering(stereoFrame); // also draw the connection information, so it doesn't // flash away too briefly on local or lan games // refresh to update the time VM_Call(uivm, UI_REFRESH, cls.realtime); VM_Call(uivm, UI_DRAW_CONNECT_SCREEN, qtrue); break; case CA_ACTIVE: // always supply STEREO_CENTER as vieworg offset is now done by the engine. CL_CGameRendering(stereoFrame); SCR_DrawDemoRecording(); #ifdef USE_VOIP SCR_DrawVoipMeter(); #endif break; } } // the menu draws next if (Key_GetCatcher() & KEYCATCH_UI && uivm) { VM_Call(uivm, UI_REFRESH, cls.realtime); } // console draws next Con_DrawConsole(); // debug graph can be drawn on top of anything if (cl_debuggraph->integer || cl_timegraph->integer || cl_debugMove->integer) { SCR_DrawDebugGraph(); } }
/* ============== VM_CallCompiled This function is called directly by the generated code ============== */ int VM_CallCompiled( vm_t *vm, int *args ) { int stack[1024]; int programCounter; int programStack; int stackOnEntry; byte *image; void *entryPoint; void *opStack; int *oldInstructionPointers; oldInstructionPointers = instructionPointers; currentVM = vm; instructionPointers = vm->instructionPointers; // interpret the code vm->currentlyInterpreting = qtrue; callMask = vm->dataMask; // we might be called recursively, so this might not be the very top programStack = vm->programStack; stackOnEntry = programStack; // set up the stack frame image = vm->dataBase; programCounter = 0; programStack -= 48; *(int *)&image[ programStack + 44] = args[9]; *(int *)&image[ programStack + 40] = args[8]; *(int *)&image[ programStack + 36] = args[7]; *(int *)&image[ programStack + 32] = args[6]; *(int *)&image[ programStack + 28] = args[5]; *(int *)&image[ programStack + 24] = args[4]; *(int *)&image[ programStack + 20] = args[3]; *(int *)&image[ programStack + 16] = args[2]; *(int *)&image[ programStack + 12] = args[1]; *(int *)&image[ programStack + 8 ] = args[0]; *(int *)&image[ programStack + 4 ] = 0; // return stack *(int *)&image[ programStack ] = -1; // will terminate the loop on return // off we go into generated code... entryPoint = vm->codeBase; opStack = &stack; #ifdef _MSC_VER __asm { pushad mov esi, programStack; mov edi, opStack call entryPoint mov programStack, esi mov opStack, edi popad } #else { static int memProgramStack; static void *memOpStack; static void *memEntryPoint; memProgramStack = programStack; memOpStack = opStack; memEntryPoint = entryPoint; __asm__(" pushal \n" \ " movl %0,%%esi \n" \ " movl %1,%%edi \n" \ " call *%2 \n" \ " movl %%esi,%0 \n" \ " movl %%edi,%1 \n" \ " popal \n" \ : "=m" (memProgramStack), "=m" (memOpStack) \ : "m" (memEntryPoint), "m" (memProgramStack), "m" (memOpStack) \ : "si", "di" \ ); programStack = memProgramStack; opStack = memOpStack; } #endif if ( opStack != &stack[1] ) { Com_Error( ERR_DROP, "opStack corrupted in compiled code" ); } if ( programStack != stackOnEntry - 48 ) { Com_Error( ERR_DROP, "programStack corrupted in compiled code" ); } vm->programStack = stackOnEntry; // in case we were recursively called by another vm instructionPointers = oldInstructionPointers; return *(int *)opStack; }
/** * @brief Kills an actor (all that is needed is the local entity state set to STATE_DEAD). * @note Also changes the animation to a random death sequence and appends the dead animation * @param[in] msg The netchannel message * @param[in] self Pointer to the event structure that is currently executed */ void CL_ActorRevitalised (const eventRegister_t *self, struct dbuffer *msg) { le_t *le, *floor; int entnum, state; NET_ReadFormat(msg, self->formatString, &entnum, &state); /* get les */ le = LE_Get(entnum); if (!le) LE_NotFoundError(entnum); if (!LE_IsStunned(le) && !LE_IsLivingActor(le)) Com_Error(ERR_DROP, "CL_ActorRevitalised: Can't revitalise, LE is not a dead or stunned actor"); LE_Lock(le); /* link any floor container into the actor temp floor container */ floor = LE_Find(ET_ITEM, le->pos); if (floor) FLOOR(le) = FLOOR(floor); le->state = state; /* play animation */ LE_SetThink(le, LET_StartIdle); /* Print some info about the death or stun. */ if (le->team == cls.team) { const character_t *chr = CL_ActorGetChr(le); if (chr) { char tmpbuf[128]; Com_sprintf(tmpbuf, lengthof(tmpbuf), _("%s was revitalised\n"), chr->name); HUD_DisplayMessage(tmpbuf); } } else { switch (le->team) { case (TEAM_CIVILIAN): HUD_DisplayMessage(_("A civilian was revitalised.\n")); break; case (TEAM_ALIEN): HUD_DisplayMessage(_("An alien was revitalised.\n")); break; case (TEAM_PHALANX): HUD_DisplayMessage(_("A soldier was revitalised.\n")); break; default: HUD_DisplayMessage(va(_("A member of team %i was revitalised.\n"), le->team)); break; } } VectorCopy(player_maxs, le->maxs); /* add team members to the actor list */ CL_ActorAddToTeamList(le); /* update pathing as we maybe not can walk onto this actor anymore */ CL_ActorConditionalMoveCalc(selActor); LE_Unlock(le); }
void *Z_Malloc(int iSize, memtag_t eTag, qboolean bZeroit /* = qfalse */, int iUnusedAlign /* = 4 */) { gbMemFreeupOccured = qfalse; if (iSize == 0) { zoneHeader_t *pMemory = (zoneHeader_t *) &gZeroMalloc; return &pMemory[1]; } // Add in tracking info // int iRealSize = (iSize + sizeof(zoneHeader_t) + sizeof(zoneTail_t)); // Allocate a chunk... // zoneHeader_t *pMemory = NULL; while (pMemory == NULL) { #ifdef _WIN32 if (gbMemFreeupOccured) { Sleep(1000); // sleep for a second, so Windows has a chance to shuffle mem to de-swiss-cheese it } #endif if (bZeroit) { pMemory = (zoneHeader_t *) calloc ( iRealSize, 1 ); } else { pMemory = (zoneHeader_t *) malloc ( iRealSize ); } if (!pMemory) { // new bit, if we fail to malloc memory, try dumping some of the cached stuff that's non-vital and try again... // // ditch the BSP cache... // extern qboolean CM_DeleteCachedMap(qboolean bGuaranteedOkToDelete); if (CM_DeleteCachedMap(qfalse)) { gbMemFreeupOccured = qtrue; continue; // we've just ditched a whole load of memory, so try again with the malloc } // ditch any sounds not used on this level... // extern qboolean SND_RegisterAudio_LevelLoadEnd(qboolean bDeleteEverythingNotUsedThisLevel); if (SND_RegisterAudio_LevelLoadEnd(qtrue)) { gbMemFreeupOccured = qtrue; continue; // we've dropped at least one sound, so try again with the malloc } #ifndef DEDICATED // ditch any image_t's (and associated GL memory) not used on this level... // extern qboolean RE_RegisterImages_LevelLoadEnd(void); if (RE_RegisterImages_LevelLoadEnd()) { gbMemFreeupOccured = qtrue; continue; // we've dropped at least one image, so try again with the malloc } #endif // ditch the model-binaries cache... (must be getting desperate here!) // extern qboolean RE_RegisterModels_LevelLoadEnd(qboolean bDeleteEverythingNotUsedThisLevel); if (RE_RegisterModels_LevelLoadEnd(qtrue)) { gbMemFreeupOccured = qtrue; continue; } // as a last panic measure, dump all the audio memory, but not if we're in the audio loader // (which is annoying, but I'm not sure how to ensure we're not dumping any memory needed by the sound // currently being loaded if that was the case)... // // note that this keeps querying until it's freed up as many bytes as the requested size, but freeing // several small blocks might not mean that one larger one is satisfiable after freeup, however that'll // just make it go round again and try for freeing up another bunch of blocks until the total is satisfied // again (though this will have freed twice the requested amount in that case), so it'll either work // eventually or not free up enough and drop through to the final ERR_DROP. No worries... // extern qboolean gbInsideLoadSound; extern int SND_FreeOldestSound(); if (!gbInsideLoadSound) { int iBytesFreed = SND_FreeOldestSound(); if (iBytesFreed) { int iTheseBytesFreed = 0; while ( (iTheseBytesFreed = SND_FreeOldestSound()) != 0) { iBytesFreed += iTheseBytesFreed; if (iBytesFreed >= iRealSize) break; // early opt-out since we've managed to recover enough (mem-contiguity issues aside) } gbMemFreeupOccured = qtrue; continue; } } // sigh, dunno what else to try, I guess we'll have to give up and report this as an out-of-mem error... // // findlabel: "recovermem" Com_Printf(S_COLOR_RED"Z_Malloc(): Failed to alloc %d bytes (TAG_%s) !!!!!\n", iSize, psTagStrings[eTag]); Z_Details_f(); Com_Error(ERR_FATAL,"(Repeat): Z_Malloc(): Failed to alloc %d bytes (TAG_%s) !!!!!\n", iSize, psTagStrings[eTag]); return NULL; } } // Link in pMemory->iMagic = ZONE_MAGIC; pMemory->eTag = eTag; pMemory->iSize = iSize; pMemory->pNext = TheZone.Header.pNext; TheZone.Header.pNext = pMemory; if (pMemory->pNext) { pMemory->pNext->pPrev = pMemory; } pMemory->pPrev = &TheZone.Header; // // add tail... // ZoneTailFromHeader(pMemory)->iMagic = ZONE_MAGIC; // Update stats... // TheZone.Stats.iCurrent += iSize; TheZone.Stats.iCount++; TheZone.Stats.iSizesPerTag [eTag] += iSize; TheZone.Stats.iCountsPerTag [eTag]++; if (TheZone.Stats.iCurrent > TheZone.Stats.iPeak) { TheZone.Stats.iPeak = TheZone.Stats.iCurrent; } #ifdef DETAILED_ZONE_DEBUG_CODE mapAllocatedZones[pMemory]++; #endif Z_Validate(); // check for corruption void *pvReturnMem = &pMemory[1]; return pvReturnMem; }
/* ==================== CL_UISystemCalls The ui module is making a system call ==================== */ intptr_t CL_UISystemCalls( intptr_t *args ) { switch( args[0] ) { //rww - alright, DO NOT EVER add a GAME/CGAME/UI generic call without adding a trap to match, and //all of these traps must be shared and have cases in sv_game, cl_cgame, and cl_ui. They must also //all be in the same order, and start at 100. case TRAP_MEMSET: Com_Memset( VMA(1), args[2], args[3] ); return 0; case TRAP_MEMCPY: Com_Memcpy( VMA(1), VMA(2), args[3] ); return 0; case TRAP_STRNCPY: strncpy( (char *)VMA(1), (const char *)VMA(2), args[3] ); return args[1]; case TRAP_SIN: return FloatAsInt( sin( VMF(1) ) ); case TRAP_COS: return FloatAsInt( cos( VMF(1) ) ); case TRAP_ATAN2: return FloatAsInt( atan2( VMF(1), VMF(2) ) ); case TRAP_SQRT: return FloatAsInt( sqrt( VMF(1) ) ); case TRAP_MATRIXMULTIPLY: MatrixMultiply( (vec3_t *)VMA(1), (vec3_t *)VMA(2), (vec3_t *)VMA(3) ); return 0; case TRAP_ANGLEVECTORS: AngleVectors( (const float *)VMA(1), (float *)VMA(2), (float *)VMA(3), (float *)VMA(4) ); return 0; case TRAP_PERPENDICULARVECTOR: PerpendicularVector( (float *)VMA(1), (const float *)VMA(2) ); return 0; case TRAP_FLOOR: return FloatAsInt( floor( VMF(1) ) ); case TRAP_CEIL: return FloatAsInt( ceil( VMF(1) ) ); case TRAP_TESTPRINTINT: return 0; case TRAP_TESTPRINTFLOAT: return 0; case TRAP_ACOS: return FloatAsInt( Q_acos( VMF(1) ) ); case TRAP_ASIN: return FloatAsInt( Q_asin( VMF(1) ) ); case UI_ERROR: Com_Error( ERR_DROP, "%s", VMA(1) ); return 0; case UI_PRINT: Com_Printf( "%s", VMA(1) ); return 0; case UI_MILLISECONDS: return Sys_Milliseconds(); case UI_CVAR_REGISTER: Cvar_Register( (vmCvar_t *)VMA(1), (const char *)VMA(2), (const char *)VMA(3), args[4] ); return 0; case UI_CVAR_UPDATE: Cvar_Update( (vmCvar_t *)VMA(1) ); return 0; case UI_CVAR_SET: Cvar_Set( (const char *)VMA(1), (const char *)VMA(2) ); return 0; case UI_CVAR_VARIABLEVALUE: return FloatAsInt( Cvar_VariableValue( (const char *)VMA(1) ) ); case UI_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( (const char *)VMA(1), (char *)VMA(2), args[3] ); return 0; case UI_CVAR_SETVALUE: Cvar_SetValue( (const char *)VMA(1), VMF(2) ); return 0; case UI_CVAR_RESET: Cvar_Reset( (const char *)VMA(1) ); return 0; case UI_CVAR_CREATE: Cvar_Get( (const char *)VMA(1), (const char *)VMA(2), args[3] ); return 0; case UI_CVAR_INFOSTRINGBUFFER: Cvar_InfoStringBuffer( args[1], (char *)VMA(2), args[3] ); return 0; case UI_ARGC: return Cmd_Argc(); case UI_ARGV: Cmd_ArgvBuffer( args[1], (char *)VMA(2), args[3] ); return 0; case UI_CMD_EXECUTETEXT: Cbuf_ExecuteText( args[1], (const char *)VMA(2) ); return 0; case UI_FS_FOPENFILE: return FS_FOpenFileByMode( (const char *)VMA(1), (int *)VMA(2), (fsMode_t)args[3] ); case UI_FS_READ: FS_Read2( VMA(1), args[2], args[3] ); return 0; 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_GETFILELIST: return FS_GetFileList( (const char *)VMA(1), (const char *)VMA(2), (char *)VMA(3), args[4] ); case UI_R_REGISTERMODEL: return re->RegisterModel( (const char *)VMA(1) ); case UI_R_REGISTERSKIN: return re->RegisterSkin( (const char *)VMA(1) ); case UI_R_REGISTERSHADERNOMIP: return re->RegisterShaderNoMip( (const char *)VMA(1) ); case UI_R_SHADERNAMEFROMINDEX: { char *gameMem = (char *)VMA(1); const char *retMem = re->ShaderNameFromIndex(args[2]); if (retMem) { strcpy(gameMem, retMem); } else { gameMem[0] = 0; } } return 0; case UI_R_CLEARSCENE: re->ClearScene(); return 0; case UI_R_ADDREFENTITYTOSCENE: re->AddRefEntityToScene( (const refEntity_t *)VMA(1) ); return 0; case UI_R_ADDPOLYTOSCENE: re->AddPolyToScene( args[1], args[2], (const polyVert_t *)VMA(3), 1 ); return 0; case UI_R_ADDLIGHTTOSCENE: #ifdef VV_LIGHTING VVLightMan.RE_AddLightToScene( (const float *)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); #else re->AddLightToScene( (const float *)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); #endif return 0; case UI_R_RENDERSCENE: re->RenderScene( (const refdef_t *)VMA(1) ); return 0; case UI_R_SETCOLOR: re->SetColor( (const float *)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], (float *)VMA(2), (float *)VMA(3) ); return 0; case UI_UPDATESCREEN: SCR_UpdateScreen(); return 0; case UI_CM_LERPTAG: re->LerpTag( (orientation_t *)VMA(1), args[2], args[3], args[4], VMF(5), (const char *)VMA(6) ); return 0; case UI_S_REGISTERSOUND: return S_RegisterSound( (const char *)VMA(1) ); case UI_S_STARTLOCALSOUND: S_StartLocalSound( args[1], args[2] ); return 0; case UI_KEY_KEYNUMTOSTRINGBUF: Key_KeynumToStringBuf( args[1], (char *)VMA(2), args[3] ); return 0; case UI_KEY_GETBINDINGBUF: Key_GetBindingBuf( args[1], (char *)VMA(2), args[3] ); return 0; case UI_KEY_SETBINDING: Key_SetBinding( args[1], (const char *)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( (qboolean)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: GetClipboardData( (char *)VMA(1), args[2] ); return 0; case UI_GETCLIENTSTATE: GetClientState( (uiClientState_t *)VMA(1) ); return 0; case UI_GETGLCONFIG: CL_GetGlconfig( (glconfig_t *)VMA(1) ); return 0; case UI_GETCONFIGSTRING: return GetConfigString( args[1], (char *)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], (const char *)VMA(2), (const char *)VMA(3)); case UI_LAN_REMOVESERVER: LAN_RemoveServer(args[1], (const char *)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], (char *)VMA(2), args[3], (int *)VMA(4) ); return 0; case UI_LAN_GETPINGINFO: LAN_GetPingInfo( args[1], (char *)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], (char *)VMA(3), args[4] ); return 0; case UI_LAN_GETSERVERINFO: LAN_GetServerInfo( args[1], args[2], (char *)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], (qboolean)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( (char *)VMA(1), (char *)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_R_REGISTERFONT: return re->RegisterFont( (const char *)VMA(1) ); case UI_R_FONT_STRLENPIXELS: return re->Font_StrLenPixels( (const char *)VMA(1), args[2], VMF(3) ); case UI_R_FONT_STRLENCHARS: return re->Font_StrLenChars( (const char *)VMA(1) ); case UI_R_FONT_STRHEIGHTPIXELS: return re->Font_HeightPixels( args[1], VMF(2) ); case UI_R_FONT_DRAWSTRING: re->Font_DrawString( args[1], args[2], (const char *)VMA(3), (const float *) VMA(4), args[5], args[6], VMF(7) ); return 0; case UI_LANGUAGE_ISASIAN: return re->Language_IsAsian(); case UI_LANGUAGE_USESSPACES: return re->Language_UsesSpaces(); case UI_ANYLANGUAGE_READCHARFROMSTRING: return re->AnyLanguage_ReadCharFromString( (const char *)VMA(1), (int *) VMA(2), (qboolean *) VMA(3) ); case UI_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine( (char *)VMA(1) ); case UI_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle( (const char *)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], (struct pc_token_s *)VMA(2) ); case UI_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], (char *)VMA(2), (int *)VMA(3) ); case UI_PC_LOAD_GLOBAL_DEFINES: return botlib_export->PC_LoadGlobalDefines ( (char *)VMA(1) ); case UI_PC_REMOVE_ALL_GLOBAL_DEFINES: botlib_export->PC_RemoveAllGlobalDefines ( ); return 0; case UI_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case UI_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( (const char *)VMA(1), (const char *)VMA(2), qfalse); return 0; case UI_REAL_TIME: return Com_RealTime( (struct qtime_s *)VMA(1) ); case UI_CIN_PLAYCINEMATIC: Com_DPrintf("UI_CIN_PlayCinematic\n"); return CIN_PlayCinematic((const char *)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( (const char *)VMA(1), (const char *)VMA(2), (const char *)VMA(3) ); return 0; case UI_SP_GETNUMLANGUAGES: return SE_GetNumLanguages(); case UI_SP_GETLANGUAGENAME: char *languageName,*holdName; holdName = ((char *)VMA(2)); languageName = (char *) SE_GetLanguageName(args[1]); Q_strncpyz( holdName, languageName,128 ); return 0; case UI_SP_GETSTRINGTEXTSTRING: const char* text; assert(VMA(1)); assert(VMA(2)); text = SE_GetString((const char *) VMA(1)); Q_strncpyz( (char *) VMA(2), text, args[3] ); return qtrue; /* Ghoul2 Insert Start */ /* Ghoul2 Insert Start */ case UI_G2_LISTSURFACES: re->G2API_ListSurfaces( (CGhoul2Info *) args[1] ); return 0; case UI_G2_LISTBONES: re->G2API_ListBones( (CGhoul2Info *) args[1], args[2]); return 0; case UI_G2_HAVEWEGHOULMODELS: return re->G2API_HaveWeGhoul2Models( *((CGhoul2Info_v *)args[1]) ); case UI_G2_SETMODELS: re->G2API_SetGhoul2ModelIndexes( *((CGhoul2Info_v *)args[1]),(qhandle_t *)VMA(2),(qhandle_t *)VMA(3)); return 0; case UI_G2_GETBOLT: return re->G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9)); case UI_G2_GETBOLT_NOREC: re->G2API_BoltMatrixReconstruction( qfalse );//gG2_GBMNoReconstruct = qtrue; return re->G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9)); case UI_G2_GETBOLT_NOREC_NOROT: //RAZFIXME: cgame reconstructs bolt matrix, why is this different? re->G2API_BoltMatrixReconstruction( qfalse );//gG2_GBMNoReconstruct = qtrue; re->G2API_BoltMatrixSPMethod( qtrue );//gG2_GBMUseSPMethod = qtrue; return re->G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9)); case UI_G2_INITGHOUL2MODEL: #ifdef _FULL_G2_LEAK_CHECKING g_G2AllocServer = 0; #endif return re->G2API_InitGhoul2Model((CGhoul2Info_v **)VMA(1), (const char *)VMA(2), args[3], (qhandle_t) args[4], (qhandle_t) args[5], args[6], args[7]); case UI_G2_COLLISIONDETECT: case UI_G2_COLLISIONDETECTCACHE: return 0; //not supported for ui case UI_G2_ANGLEOVERRIDE: return re->G2API_SetBoneAngles(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), (float *)VMA(4), args[5], (const Eorientations) args[6], (const Eorientations) args[7], (const Eorientations) args[8], (qhandle_t *)VMA(9), args[10], args[11] ); case UI_G2_CLEANMODELS: #ifdef _FULL_G2_LEAK_CHECKING g_G2AllocServer = 0; #endif re->G2API_CleanGhoul2Models((CGhoul2Info_v **)VMA(1)); // re->G2API_CleanGhoul2Models((CGhoul2Info_v **)args[1]); return 0; case UI_G2_PLAYANIM: return re->G2API_SetBoneAnim(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), args[4], args[5], args[6], VMF(7), args[8], VMF(9), args[10]); case UI_G2_GETBONEANIM: { CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]); int modelIndex = args[10]; return re->G2API_GetBoneAnim(&g2[modelIndex], (const char*)VMA(2), args[3], (float *)VMA(4), (int *)VMA(5), (int *)VMA(6), (int *)VMA(7), (float *)VMA(8), (int *)VMA(9)); } case UI_G2_GETBONEFRAME: { //rwwFIXMEFIXME: Just make a G2API_GetBoneFrame func too. This is dirty. CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]); int modelIndex = args[6]; int iDontCare1 = 0, iDontCare2 = 0, iDontCare3 = 0; float fDontCare1 = 0; return re->G2API_GetBoneAnim(&g2[modelIndex], (const char*)VMA(2), args[3], (float *)VMA(4), &iDontCare1, &iDontCare2, &iDontCare3, &fDontCare1, (int *)VMA(5)); } case UI_G2_GETGLANAME: // return (int)G2API_GetGLAName(*((CGhoul2Info_v *)VMA(1)), args[2]); { char *point = ((char *)VMA(3)); char *local; local = re->G2API_GetGLAName(*((CGhoul2Info_v *)args[1]), args[2]); if (local) { strcpy(point, local); } } return 0; case UI_G2_COPYGHOUL2INSTANCE: return (int)re->G2API_CopyGhoul2Instance(*((CGhoul2Info_v *)args[1]), *((CGhoul2Info_v *)args[2]), args[3]); case UI_G2_COPYSPECIFICGHOUL2MODEL: re->G2API_CopySpecificG2Model(*((CGhoul2Info_v *)args[1]), args[2], *((CGhoul2Info_v *)args[3]), args[4]); return 0; case UI_G2_DUPLICATEGHOUL2INSTANCE: #ifdef _FULL_G2_LEAK_CHECKING g_G2AllocServer = 0; #endif re->G2API_DuplicateGhoul2Instance(*((CGhoul2Info_v *)args[1]), (CGhoul2Info_v **)VMA(2)); return 0; case UI_G2_HASGHOUL2MODELONINDEX: return (int)re->G2API_HasGhoul2ModelOnIndex((CGhoul2Info_v **)VMA(1), args[2]); //return (int)G2API_HasGhoul2ModelOnIndex((CGhoul2Info_v **)args[1], args[2]); case UI_G2_REMOVEGHOUL2MODEL: #ifdef _FULL_G2_LEAK_CHECKING g_G2AllocServer = 0; #endif return (int)re->G2API_RemoveGhoul2Model((CGhoul2Info_v **)VMA(1), args[2]); //return (int)G2API_RemoveGhoul2Model((CGhoul2Info_v **)args[1], args[2]); case UI_G2_ADDBOLT: return re->G2API_AddBolt(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3)); // case UI_G2_REMOVEBOLT: // return G2API_RemoveBolt(*((CGhoul2Info_v *)VMA(1)), args[2]); case UI_G2_SETBOLTON: re->G2API_SetBoltInfo(*((CGhoul2Info_v *)args[1]), args[2], args[3]); return 0; #ifdef _SOF2 case UI_G2_ADDSKINGORE: re->G2API_AddSkinGore(*((CGhoul2Info_v *)args[1]),*(SSkinGoreData *)VMA(2)); return 0; #endif // _SOF2 /* Ghoul2 Insert End */ case UI_G2_SETROOTSURFACE: return re->G2API_SetRootSurface(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3)); case UI_G2_SETSURFACEONOFF: return re->G2API_SetSurfaceOnOff(*((CGhoul2Info_v *)args[1]), (const char *)VMA(2), /*(const int)VMA(3)*/args[3]); case UI_G2_SETNEWORIGIN: return re->G2API_SetNewOrigin(*((CGhoul2Info_v *)args[1]), /*(const int)VMA(2)*/args[2]); case UI_G2_GETTIME: return re->G2API_GetTime(0); case UI_G2_SETTIME: re->G2API_SetTime(args[1], args[2]); return 0; case UI_G2_SETRAGDOLL: return 0; //not supported for ui break; case UI_G2_ANIMATEG2MODELS: return 0; //not supported for ui break; case UI_G2_SETBONEIKSTATE: return re->G2API_SetBoneIKState(*((CGhoul2Info_v *)args[1]), args[2], (const char *)VMA(3), args[4], (sharedSetBoneIKStateParams_t *)VMA(5)); case UI_G2_IKMOVE: return re->G2API_IKMove(*((CGhoul2Info_v *)args[1]), args[2], (sharedIKMoveParams_t *)VMA(3)); case UI_G2_GETSURFACENAME: { //Since returning a pointer in such a way to a VM seems to cause MASSIVE FAILURE<tm>, we will shove data into the pointer the vm passes instead char *point = ((char *)VMA(4)); char *local; int modelindex = args[3]; CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]); local = re->G2API_GetSurfaceName(&g2[modelindex], args[2]); if (local) { strcpy(point, local); } } return 0; case UI_G2_SETSKIN: { CGhoul2Info_v &g2 = *((CGhoul2Info_v *)args[1]); int modelIndex = args[2]; return re->G2API_SetSkin(&g2[modelIndex], args[3], args[4]); } case UI_G2_ATTACHG2MODEL: { CGhoul2Info_v *g2From = ((CGhoul2Info_v *)args[1]); CGhoul2Info_v *g2To = ((CGhoul2Info_v *)args[3]); return re->G2API_AttachG2Model(*g2From, args[2], *g2To, args[4], args[5]); } /* Ghoul2 Insert End */ default: Com_Error( ERR_DROP, "Bad UI system trap: %ld", (long int) args[0] ); } return 0; }
/* ============ BG_VoiceParse ============ */ static voiceCmd_t *BG_VoiceParse( const char *name ) { voiceCmd_t *voiceCmds = NULL; voiceCmd_t *top = NULL; pc_token_t token; qboolean parsingCmd = qfalse; int handle; handle = trap_Parse_LoadSource( va( "voice/%s.voice", name ) ); if ( !handle ) { return NULL; } while ( trap_Parse_ReadToken( handle, &token ) ) { if ( parsingCmd ) { if ( token.string[ 0 ] == '{' ) { voiceCmds->tracks = BG_VoiceParseCommand( handle ); parsingCmd = qfalse; continue; } else { int line; char filename[ MAX_QPATH ]; trap_Parse_SourceFileAndLine( handle, filename, &line ); Com_Error( ERR_FATAL, "BG_VoiceParse(): " "parse error on line %d of %s", line, filename ); } } if ( strlen( token.string ) >= MAX_VOICE_CMD_LEN ) { int line; char filename[ MAX_QPATH ]; trap_Parse_SourceFileAndLine( handle, filename, &line ); Com_Error( ERR_FATAL, "BG_VoiceParse(): " "command \"%s\" exceeds MAX_VOICE_CMD_LEN (%d) on line %d of %s", token.string, MAX_VOICE_CMD_LEN, line, filename ); } if ( top == NULL ) { voiceCmds = BG_Alloc( sizeof( voiceCmd_t ) ); top = voiceCmds; } else { voiceCmds->next = BG_Alloc( sizeof( voiceCmd_t ) ); voiceCmds = voiceCmds->next; } Q_strncpyz( voiceCmds->cmd, token.string, sizeof( voiceCmds->cmd ) ); voiceCmds->next = NULL; parsingCmd = qtrue; } trap_Parse_FreeSource( handle ); return top; }
/* ================= Sys_GetGameAPI Loads the game dll ================= */ void *Sys_GetGameAPI (void *parms) { void *(*GetGameAPI) (void *); FILE *fp; char name[MAX_OSPATH]; char *path; char *str_p; #if defined __i386__ const char *gamename = "gamei386.so"; #elif defined __x86_64__ const char *gamename = "gamex86_64.so"; #elif defined __alpha__ const char *gamename = "gameaxp.so"; #elif defined __powerpc__ const char *gamename = "gameppc.so"; #elif defined __arm__ const char *gamename = "gamesarm.so"; #else #error Unknown arch #endif setreuid(getuid(), getuid()); setegid(getgid()); if (game_library) Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); Com_Printf("------- Loading %s -------\n", gamename); // now run through the search paths path = NULL; while (1) { path = FS_NextPath (path); if (!path) return NULL; // couldn't find one anywhere snprintf (name, MAX_OSPATH, "%s/%s", path, gamename); /* skip it if it just doesn't exist */ fp = fopen(name, "rb"); if (fp == NULL) continue; fclose(fp); game_library = dlopen (name, RTLD_NOW); if (game_library) { Com_MDPrintf ("LoadLibrary (%s)\n",name); break; } else { Com_Printf ("LoadLibrary (%s):", name); path = dlerror(); str_p = strchr(path, ':'); // skip the path (already shown) if (str_p == NULL) str_p = path; else str_p++; Com_Printf ("%s\n", str_p); return NULL; } } GetGameAPI = (void *)dlsym (game_library, "GetGameAPI"); if (!GetGameAPI) { Sys_UnloadGame (); return NULL; } return GetGameAPI (parms); }
//BBi //int CL_UISystemCalls( int *args ) { intptr_t CL_UISystemCalls ( intptr_t* args) { //BBi switch ( args[0] ) { case UI_ERROR: #if !defined RTCW_ET Com_Error( ERR_DROP, "%s", VMA( 1 ) ); #else Com_Error( ERR_DROP, "%s", (char *)VMA( 1 ) ); #endif // RTCW_XX return 0; case UI_PRINT: #if !defined RTCW_ET Com_Printf( "%s", VMA( 1 ) ); #else Com_Printf( "%s", (char *)VMA( 1 ) ); #endif // RTCW_XX return 0; case UI_MILLISECONDS: return Sys_Milliseconds(); case UI_CVAR_REGISTER: Cvar_Register( static_cast<vmCvar_t*> (VMA( 1 )), static_cast<const char*> (VMA( 2 )), static_cast<const char*> (VMA( 3 )), args[4] ); return 0; case UI_CVAR_UPDATE: Cvar_Update( static_cast<vmCvar_t*> (VMA( 1 )) ); return 0; case UI_CVAR_SET: Cvar_Set( static_cast<const char*> (VMA( 1 )), static_cast<char*> (VMA( 2 )) ); return 0; case UI_CVAR_VARIABLEVALUE: return FloatAsInt( Cvar_VariableValue( static_cast<const char*> (VMA( 1 )) ) ); case UI_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( static_cast<const char*> (VMA( 1 )), static_cast<char*> (VMA( 2 )), args[3] ); return 0; #if defined RTCW_ET case UI_CVAR_LATCHEDVARIABLESTRINGBUFFER: Cvar_LatchedVariableStringBuffer( static_cast<const char*> (VMA( 1 )), static_cast<char*> (VMA( 2 )), args[3] ); return 0; #endif // RTCW_XX case UI_CVAR_SETVALUE: Cvar_SetValue( static_cast<const char*> (VMA( 1 )), VMF( 2 ) ); return 0; case UI_CVAR_RESET: Cvar_Reset( static_cast<const char*> (VMA( 1 )) ); return 0; case UI_CVAR_CREATE: Cvar_Get( static_cast<const char*> (VMA( 1 )), static_cast<char*> (VMA( 2 )), args[3] ); return 0; case UI_CVAR_INFOSTRINGBUFFER: Cvar_InfoStringBuffer( args[1], static_cast<char*> (VMA( 2 )), args[3] ); return 0; case UI_ARGC: return Cmd_Argc(); case UI_ARGV: Cmd_ArgvBuffer( args[1], static_cast<char*> (VMA( 2 )), args[3] ); return 0; case UI_CMD_EXECUTETEXT: Cbuf_ExecuteText( args[1], static_cast<const char*> (VMA( 2 )) ); return 0; #if defined RTCW_ET case UI_ADDCOMMAND: Cmd_AddCommand( static_cast<const char*> (VMA( 1 )), NULL ); return 0; #endif // RTCW_XX case UI_FS_FOPENFILE: return FS_FOpenFileByMode( static_cast<const char*> (VMA( 1 )), static_cast<fileHandle_t*> (VMA( 2 )), fsMode_t (args[3]) ); case UI_FS_READ: FS_Read( VMA( 1 ), args[2], args[3] ); return 0; #if defined RTCW_SP //----(SA) added case UI_FS_SEEK: FS_Seek( args[1], args[2], args[3] ); return 0; //----(SA) end #endif // RTCW_XX 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( static_cast<char*> (VMA( 1 )) ); case UI_FS_GETFILELIST: return FS_GetFileList( static_cast<const char*> (VMA( 1 )), static_cast<const char*> (VMA( 2 )), static_cast<char*> (VMA( 3 )), args[4] ); case UI_R_REGISTERMODEL: return re.RegisterModel( static_cast<const char*> (VMA( 1 )) ); case UI_R_REGISTERSKIN: return re.RegisterSkin( static_cast<const char*> (VMA( 1 )) ); case UI_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( static_cast<const char*> (VMA( 1 )) ); case UI_R_CLEARSCENE: re.ClearScene(); return 0; case UI_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( static_cast<const refEntity_t*> (VMA( 1 )) ); return 0; case UI_R_ADDPOLYTOSCENE: re.AddPolyToScene( args[1], args[2], static_cast<const polyVert_t*> (VMA( 3 )) ); return 0; // Ridah case UI_R_ADDPOLYSTOSCENE: re.AddPolysToScene( args[1], args[2], static_cast<const polyVert_t*> (VMA( 3 )), args[4] ); return 0; // done. case UI_R_ADDLIGHTTOSCENE: #if !defined RTCW_ET re.AddLightToScene( static_cast<const vec_t*> (VMA( 1 )), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6] ); #else // ydnar: new dlight code //% re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5), args[6] ); re.AddLightToScene( static_cast<const vec_t*> (VMA( 1 )), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), args[7], args[8] ); #endif // RTCW_XX return 0; case UI_R_ADDCORONATOSCENE: re.AddCoronaToScene( static_cast<const vec_t*> (VMA( 1 )), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6], args[7] ); return 0; case UI_R_RENDERSCENE: re.RenderScene( static_cast<const refdef_t*> (VMA( 1 )) ); return 0; case UI_R_SETCOLOR: re.SetColor( static_cast<const float*> (VMA( 1 )) ); return 0; #if defined RTCW_ET case UI_R_DRAW2DPOLYS: re.Add2dPolys( static_cast<polyVert_t*> (VMA( 1 )), args[2], args[3] ); return 0; #endif // RTCW_XX 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; #if defined RTCW_ET case UI_R_DRAWROTATEDPIC: re.DrawRotatedPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9], VMF( 10 ) ); return 0; #endif // RTCW_XX case UI_R_MODELBOUNDS: re.ModelBounds( args[1], static_cast<vec_t*> (VMA( 2 )), static_cast<vec_t*> (VMA( 3 )) ); return 0; case UI_UPDATESCREEN: SCR_UpdateScreen(); return 0; case UI_CM_LERPTAG: return re.LerpTag( static_cast<orientation_t*> (VMA( 1 )), static_cast<refEntity_t*> (VMA( 2 )), static_cast<const char*> (VMA( 3 )), args[4] ); case UI_S_REGISTERSOUND: #ifdef DOOMSOUND ///// (SA) DOOMSOUND return S_RegisterSound( VMA( 1 ) ); #else #if !defined RTCW_ET return S_RegisterSound( static_cast<const char*> (VMA( 1 )), qfalse ); #else return S_RegisterSound( static_cast<const char*> (VMA( 1 )), args[2] ); #endif // RTCW_XX #endif ///// (SA) DOOMSOUND case UI_S_STARTLOCALSOUND: #if !defined RTCW_ET S_StartLocalSound( args[1], args[2] ); #else S_StartLocalSound( args[1], args[2], args[3] ); #endif // RTCW_XX return 0; #if !defined RTCW_MP //----(SA) added case UI_S_FADESTREAMINGSOUND: S_FadeStreamingSound( VMF( 1 ), args[2], args[3] ); return 0; case UI_S_FADEALLSOUNDS: #if !defined RTCW_ET S_FadeAllSounds( VMF( 1 ), args[2] ); #else S_FadeAllSounds( VMF( 1 ), args[2], args[3] ); #endif // RTCW_XX return 0; //----(SA) end #endif // RTCW_XX case UI_KEY_KEYNUMTOSTRINGBUF: Key_KeynumToStringBuf( args[1], static_cast<char*> (VMA( 2 )), args[3] ); return 0; case UI_KEY_GETBINDINGBUF: Key_GetBindingBuf( args[1], static_cast<char*> (VMA( 2 )), args[3] ); return 0; case UI_KEY_SETBINDING: Key_SetBinding( args[1], static_cast<const char*> (VMA( 2 )) ); return 0; #if defined RTCW_ET case UI_KEY_BINDINGTOKEYS: Key_GetBindingByString( static_cast<const char*> (VMA( 1 )), static_cast<int*> (VMA( 2 )), static_cast<int*> (VMA( 3 )) ); return 0; #endif // RTCW_XX 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: Key_SetCatcher( args[1] ); return 0; case UI_GETCLIPBOARDDATA: GetClipboardData( static_cast<char*> (VMA( 1 )), args[2] ); return 0; case UI_GETCLIENTSTATE: GetClientState( static_cast<uiClientState_t*> (VMA( 1 )) ); return 0; case UI_GETGLCONFIG: CL_GetGlconfig( static_cast<glconfig_t*> (VMA( 1 )) ); return 0; case UI_GETCONFIGSTRING: return GetConfigString( args[1], static_cast<char*> (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], static_cast<const char*> (VMA( 2 )), static_cast<const char*> (VMA( 3 )) ); case UI_LAN_REMOVESERVER: LAN_RemoveServer( args[1], static_cast<const char*> (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], static_cast<char*> (VMA( 2 )), args[3], static_cast<int*> (VMA( 4 )) ); return 0; case UI_LAN_GETPINGINFO: LAN_GetPingInfo( args[1], static_cast<char*> (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], static_cast<char*> (VMA( 3 )), args[4] ); return 0; case UI_LAN_GETSERVERINFO: LAN_GetServerInfo( args[1], args[2], static_cast<char*> (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( static_cast<char*> (VMA( 1 )), static_cast<char*> (VMA( 2 )), args[3] ); #if defined RTCW_ET case UI_LAN_SERVERISINFAVORITELIST: return LAN_ServerIsInFavoriteList( args[1], args[2] ); #endif // RTCW_XX #if !defined RTCW_SP case UI_SET_PBCLSTATUS: return 0; case UI_SET_PBSVSTATUS: return 0; #endif // RTCW_XX 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( static_cast<char*> (VMA( 1 )), args[2] ); return 0; case UI_SET_CDKEY: CLUI_SetCDKey( static_cast<char*> (VMA( 1 )) ); return 0; case UI_R_REGISTERFONT: re.RegisterFont( static_cast<const char*> (VMA( 1 )), args[2], static_cast<fontInfo_t*> (VMA( 3 )) ); return 0; case UI_MEMSET: return (int)memset( VMA( 1 ), args[2], args[3] ); case UI_MEMCPY: return (int)memcpy( VMA( 1 ), VMA( 2 ), args[3] ); case UI_STRNCPY: return (int)strncpy( static_cast<char*> (VMA( 1 )), static_cast<const char*> (VMA( 2 )), args[3] ); case UI_SIN: return FloatAsInt( c::sin( VMF( 1 ) ) ); case UI_COS: return FloatAsInt( c::cos( VMF( 1 ) ) ); case UI_ATAN2: return FloatAsInt( c::atan2( VMF( 1 ), VMF( 2 ) ) ); case UI_SQRT: return FloatAsInt( c::sqrt( VMF( 1 ) ) ); case UI_FLOOR: return FloatAsInt( c::floor( VMF( 1 ) ) ); case UI_CEIL: return FloatAsInt( c::ceil( VMF( 1 ) ) ); case UI_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine( static_cast<char*> (VMA( 1 )) ); #if defined RTCW_ET case UI_PC_REMOVE_ALL_GLOBAL_DEFINES: botlib_export->PC_RemoveAllGlobalDefines(); return 0; #endif // RTCW_XX case UI_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle( static_cast<const char*> (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], static_cast<pc_token_t*> (VMA( 2 )) ); case UI_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], static_cast<char*> (VMA( 2 )), static_cast<int*> (VMA( 3 )) ); #if defined RTCW_ET case UI_PC_UNREAD_TOKEN: botlib_export->PC_UnreadLastTokenHandle( args[1] ); return 0; #endif // RTCW_XX case UI_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case UI_S_STARTBACKGROUNDTRACK: #if !defined RTCW_MP S_StartBackgroundTrack( static_cast<const char*> (VMA( 1 )), static_cast<const char*> (VMA( 2 )), args[3] ); //----(SA) added fadeup time #else S_StartBackgroundTrack( static_cast<const char*> (VMA( 1 )), static_cast<const char*> (VMA( 2 )) ); #endif // RTCW_XX return 0; case UI_REAL_TIME: return Com_RealTime( static_cast<qtime_t*> (VMA( 1 )) ); case UI_CIN_PLAYCINEMATIC: Com_DPrintf( "UI_CIN_PlayCinematic\n" ); return CIN_PlayCinematic( static_cast<const char*> (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( static_cast<const char*> (VMA( 1 )), static_cast<const char*> (VMA( 2 )), static_cast<const char*> (VMA( 3 )) ); return 0; case UI_VERIFY_CDKEY: return CL_CDKeyValidate( static_cast<const char*> (VMA( 1 )), static_cast<const char*> (VMA( 2 )) ); // NERVE - SMF case UI_CL_GETLIMBOSTRING: return CL_GetLimboString( args[1], static_cast<char*> (VMA( 2 )) ); #if defined RTCW_SP // -NERVE - SMF #endif // RTCW_XX #if !defined RTCW_SP case UI_CL_TRANSLATE_STRING: CL_TranslateString( static_cast<const char*> (VMA( 1 )), static_cast<char*> (VMA( 2 )) ); return 0; // -NERVE - SMF // DHM - Nerve case UI_CHECKAUTOUPDATE: CL_CheckAutoUpdate(); return 0; case UI_GET_AUTOUPDATE: CL_GetAutoUpdate(); return 0; // DHM - Nerve case UI_OPENURL: CL_OpenURL( (const char *)VMA( 1 ) ); return 0; #endif // RTCW_XX #if defined RTCW_ET case UI_GETHUNKDATA: Com_GetHunkInfo( static_cast<int*> (VMA( 1 )), static_cast<int*> (VMA( 2 )) ); return 0; #endif // RTCW_XX default: Com_Error( ERR_DROP, "Bad UI system trap: %i", args[0] ); } return 0; }
// show_bug.cgi?id=574 int S_GetSoundLength( sfxHandle_t sfxHandle ) { Com_Error( ERR_DROP, "null_snddma.c: S_GetSoundLength\n" ); return 0; }
/* =================== CL_GetServerCommand Set up argc/argv for the given command =================== */ qboolean CL_GetServerCommand( int serverCommandNumber ) { char *s; char *cmd; static char bigConfigString[BIG_INFO_STRING]; int argc; // if we have irretrievably lost a reliable command, drop the connection if ( serverCommandNumber <= clc.serverCommandSequence - MAX_RELIABLE_COMMANDS ) { // when a demo record was started after the client got a whole bunch of // reliable commands then the client never got those first reliable commands if ( clc.demoplaying ) return qfalse; Com_Error( ERR_DROP, "CL_GetServerCommand: a reliable command was cycled out" ); return qfalse; } if ( serverCommandNumber > clc.serverCommandSequence ) { Com_Error( ERR_DROP, "CL_GetServerCommand: requested a command not received" ); return qfalse; } s = clc.serverCommands[ serverCommandNumber & ( MAX_RELIABLE_COMMANDS - 1 ) ]; clc.lastExecutedServerCommand = serverCommandNumber; Com_DPrintf( "serverCommand: %i : %s\n", serverCommandNumber, s ); rescan: Cmd_TokenizeString( s ); cmd = Cmd_Argv(0); argc = Cmd_Argc(); if ( !strcmp( cmd, "disconnect" ) ) { // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=552 // allow server to indicate why they were disconnected if ( argc >= 2 ) Com_Error( ERR_SERVERDISCONNECT, "Server disconnected - %s", Cmd_Argv( 1 ) ); else Com_Error( ERR_SERVERDISCONNECT, "Server disconnected\n" ); } if ( !strcmp( cmd, "bcs0" ) ) { Com_sprintf( bigConfigString, BIG_INFO_STRING, "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2) ); return qfalse; } if ( !strcmp( cmd, "bcs1" ) ) { s = Cmd_Argv(2); if( strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING ) { Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" ); } strcat( bigConfigString, s ); return qfalse; } if ( !strcmp( cmd, "bcs2" ) ) { s = Cmd_Argv(2); if( strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING ) { Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" ); } strcat( bigConfigString, s ); strcat( bigConfigString, "\"" ); s = bigConfigString; goto rescan; } if ( !strcmp( cmd, "cs" ) ) { CL_ConfigstringModified(); // reparse the string, because CL_ConfigstringModified may have done another Cmd_TokenizeString() Cmd_TokenizeString( s ); return qtrue; } if ( !strcmp( cmd, "map_restart" ) ) { // clear notify lines and outgoing commands before passing // the restart to the cgame Con_ClearNotify(); Com_Memset( cl.cmds, 0, sizeof( cl.cmds ) ); return qtrue; } // the clientLevelShot command is used during development // to generate 128*128 screenshots from the intermission // point of levels for the menu system to use // we pass it along to the cgame to make apropriate adjustments, // but we also clear the console and notify lines here if ( !strcmp( cmd, "clientLevelShot" ) ) { // don't do it if we aren't running the server locally, // otherwise malicious remote servers could overwrite // the existing thumbnails if ( !com_sv_running->integer ) { return qfalse; } // close the console Con_Close(); // take a special screenshot next frame Cbuf_AddText( "wait ; wait ; wait ; wait ; screenshot levelshot\n" ); return qtrue; } // we may want to put a "connect to other server" command here // cgame can now act on the command return qtrue; }
/* ================== SV_DirectConnect A "connect" OOB command has been received ================== */ void SV_DirectConnect( netadr_t from ) { char userinfo[MAX_INFO_STRING]; int i; client_t *cl, *newcl; client_t temp; sharedEntity_t *ent; int clientNum; int version; int qport; int challenge; char *password; int startIndex; char *denied; int count; char *ip; Com_DPrintf ("SVC_DirectConnect ()\n"); // Check whether this client is banned. if ( SV_IsBanned( &from, qfalse ) ) { NET_OutOfBandPrint( NS_SERVER, from, "print\nYou are banned from this server.\n" ); Com_DPrintf( " rejected connect from %s (banned)\n", NET_AdrToString(from) ); return; } Q_strncpyz( userinfo, Cmd_Argv(1), sizeof(userinfo) ); version = atoi( Info_ValueForKey( userinfo, "protocol" ) ); if ( version != PROTOCOL_VERSION ) { NET_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i (yours is %i).\n", PROTOCOL_VERSION, version ); Com_DPrintf (" rejected connect from version %i\n", version); return; } challenge = atoi( Info_ValueForKey( userinfo, "challenge" ) ); qport = atoi( Info_ValueForKey( userinfo, "qport" ) ); // quick reject for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) { /* This was preventing sv_reconnectlimit from working. It seems like commenting this out has solved the problem. HOwever, if there is a future problem then it could be this. if ( cl->state == CS_FREE ) { continue; } */ if ( NET_CompareBaseAdr( from, cl->netchan.remoteAddress ) && ( cl->netchan.qport == qport || from.port == cl->netchan.remoteAddress.port ) ) { if (( svs.time - cl->lastConnectTime) < (sv_reconnectlimit->integer * 1000)) { NET_OutOfBandPrint( NS_SERVER, from, "print\nReconnect rejected : too soon\n" ); Com_DPrintf ("%s:reconnect rejected : too soon\n", NET_AdrToString (from)); return; } break; } } // don't let "ip" overflow userinfo string if ( NET_IsLocalAddress (from) ) ip = "localhost"; else ip = (char *)NET_AdrToString( from ); if( ( strlen( ip ) + strlen( userinfo ) + 4 ) >= MAX_INFO_STRING ) { NET_OutOfBandPrint( NS_SERVER, from, "print\nUserinfo string length exceeded. " "Try removing setu cvars from your config.\n" ); return; } Info_SetValueForKey( userinfo, "ip", ip ); // see if the challenge is valid (localhost clients don't need to challenge) if (!NET_IsLocalAddress(from)) { // Verify the received challenge against the expected challenge if (!SV_VerifyChallenge(challenge, from)) { NET_OutOfBandPrint( NS_SERVER, from, "print\nIncorrect challenge for your address.\n" ); return; } } newcl = &temp; Com_Memset (newcl, 0, sizeof(client_t)); // if there is already a slot for this ip, reuse it for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) { if ( cl->state == CS_FREE ) { continue; } if ( NET_CompareBaseAdr( from, cl->netchan.remoteAddress ) && ( cl->netchan.qport == qport || from.port == cl->netchan.remoteAddress.port ) ) { Com_Printf ("%s:reconnect\n", NET_AdrToString (from)); newcl = cl; // VVFIXME - both SOF2 and Wolf remove this call, claiming it blows away the user's info // disconnect the client from the game first so any flags the // player might have are dropped GVM_ClientDisconnect( newcl - svs.clients ); // goto gotnewcl; } } // find a client slot // if "sv_privateClients" is set > 0, then that number // of client slots will be reserved for connections that // have "password" set to the value of "sv_privatePassword" // Info requests will report the maxclients as if the private // slots didn't exist, to prevent people from trying to connect // to a full server. // This is to allow us to reserve a couple slots here on our // servers so we can play without having to kick people. // check for privateClient password password = Info_ValueForKey( userinfo, "password" ); if ( !strcmp( password, sv_privatePassword->string ) ) { startIndex = 0; } else { // skip past the reserved slots startIndex = sv_privateClients->integer; } newcl = NULL; for ( i = startIndex; i < sv_maxclients->integer ; i++ ) { cl = &svs.clients[i]; if (cl->state == CS_FREE) { newcl = cl; break; } } if ( !newcl ) { if ( NET_IsLocalAddress( from ) ) { count = 0; for ( i = startIndex; i < sv_maxclients->integer ; i++ ) { cl = &svs.clients[i]; if (cl->netchan.remoteAddress.type == NA_BOT) { count++; } } // if they're all bots if (count >= sv_maxclients->integer - startIndex) { SV_DropClient(&svs.clients[sv_maxclients->integer - 1], "only bots on server"); newcl = &svs.clients[sv_maxclients->integer - 1]; } else { Com_Error( ERR_FATAL, "server is full on local connect\n" ); return; } } else { const char *SV_GetStringEdString(char *refSection, char *refName); NET_OutOfBandPrint( NS_SERVER, from, va("print\n%s\n", SV_GetStringEdString("MP_SVGAME","SERVER_IS_FULL"))); Com_DPrintf ("Rejected a connection.\n"); return; } } // we got a newcl, so reset the reliableSequence and reliableAcknowledge cl->reliableAcknowledge = 0; cl->reliableSequence = 0; gotnewcl: // build a new connection // accept the new client // this is the only place a client_t is ever initialized *newcl = temp; clientNum = newcl - svs.clients; ent = SV_GentityNum( clientNum ); newcl->gentity = ent; // save the challenge newcl->challenge = challenge; // save the address Netchan_Setup (NS_SERVER, &newcl->netchan , from, qport); // save the userinfo Q_strncpyz( newcl->userinfo, userinfo, sizeof(newcl->userinfo) ); // get the game a chance to reject this connection or modify the userinfo denied = GVM_ClientConnect( clientNum, qtrue, qfalse ); // firstTime = qtrue if ( denied ) { NET_OutOfBandPrint( NS_SERVER, from, "print\n%s\n", denied ); Com_DPrintf ("Game rejected a connection: %s.\n", denied); return; } SV_UserinfoChanged( newcl ); // send the connect packet to the client NET_OutOfBandPrint( NS_SERVER, from, "connectResponse" ); Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name ); newcl->state = CS_CONNECTED; newcl->nextSnapshotTime = svs.time; newcl->lastPacketTime = svs.time; newcl->lastConnectTime = svs.time; // when we receive the first packet from the client, we will // notice that it is from a different serverid and that the // gamestate message was not just sent, forcing a retransmit newcl->gamestateMessageNum = -1; newcl->lastUserInfoChange = 0; //reset the delay newcl->lastUserInfoCount = 0; //reset the count // if this was the first client on the server, or the last client // the server can hold, send a heartbeat to the master. count = 0; for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) { if ( svs.clients[i].state >= CS_CONNECTED ) { count++; } } if ( count == 1 || count == sv_maxclients->integer ) { SV_Heartbeat_f(); } }
/* ==================== 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_LITERAL_ARGS: Cmd_LiteralArgsBuffer( VMA(1), args[2] ); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] ); case CG_FS_READ: FS_Read2( VMA(1), args[2], args[3] ); return 0; case CG_FS_WRITE: FS_Write( VMA(1), args[2], args[3] ); return 0; case CG_FS_FCLOSEFILE: FS_FCloseFile( args[1] ); return 0; case CG_FS_SEEK: return FS_Seek( args[1], args[2], args[3] ); case CG_FS_GETFILELIST: return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] ); 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) ); 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), /*int capsule*/ qfalse ); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ 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], TT_AABB ); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], TT_CAPSULE ); 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), TT_AABB ); 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), TT_CAPSULE ); return 0; case CG_CM_BISPHERETRACE: CM_BiSphereTrace( VMA(1), VMA(2), VMA(3), VMF(4), VMF(5), args[6], args[7] ); return 0; case CG_CM_TRANSFORMEDBISPHERETRACE: CM_TransformedBiSphereTrace( VMA(1), VMA(2), VMA(3), VMF(4), VMF(5), args[6], args[7], VMA(8) ); 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_STARTLOCALSOUND: S_StartLocalSound( args[1], args[2] ); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds(args[1]); return 0; case CG_S_ADDLOOPINGSOUND: S_AddLoopingSound( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_ADDREALLOOPINGSOUND: S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_STOPLOOPINGSOUND: S_StopLoopingSound( args[1] ); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[1], VMA(2) ); return 0; case CG_S_RESPATIALIZE: S_Respatialize( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_REGISTERSOUND: return S_RegisterSound( VMA(1), args[2] ); case CG_S_SOUNDDURATION: return S_SoundDuration( args[1] ); case CG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( VMA(1), VMA(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_REGISTERSHADER: return re.RegisterShader( VMA(1) ); case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( VMA(1) ); case CG_R_REGISTERFONT: re.RegisterFont( VMA(1), args[2], VMA(3)); 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), 1 ); return 0; case CG_R_ADDPOLYSTOSCENE: re.AddPolyToScene( args[1], args[2], VMA(3), args[4] ); return 0; 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) ); return 0; case CG_R_ADDADDITIVELIGHTTOSCENE: re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); 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_MODELBOUNDS: re.ModelBounds( args[1], VMA(2), VMA(3) ); return 0; case CG_R_LERPTAG: return re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) ); 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], VMF(2) ); 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_GETDEMOSTATE: return CL_DemoState( ); case CG_GETDEMOPOS: return CL_DemoPos( ); case CG_GETDEMONAME: CL_DemoName( VMA(1), args[2] ); return 0; case CG_KEY_KEYNUMTOSTRINGBUF: Key_KeynumToStringBuf( args[1], VMA(2), args[3] ); return 0; case CG_KEY_GETBINDINGBUF: Key_GetBindingBuf( args[1], VMA(2), args[3] ); return 0; case CG_KEY_SETBINDING: Key_SetBinding( args[1], VMA(2) ); return 0; case CG_PARSE_ADD_GLOBAL_DEFINE: return Parse_AddGlobalDefine( VMA(1) ); case CG_PARSE_LOAD_SOURCE: return Parse_LoadSourceHandle( VMA(1) ); case CG_PARSE_FREE_SOURCE: return Parse_FreeSourceHandle( args[1] ); case CG_PARSE_READ_TOKEN: return Parse_ReadTokenHandle( args[1], VMA(2) ); case CG_PARSE_SOURCE_FILE_AND_LINE: return Parse_SourceFileAndLine( args[1], VMA(2), VMA(3) ); case CG_KEY_SETOVERSTRIKEMODE: Key_SetOverstrikeMode( args[1] ); return 0; case CG_KEY_GETOVERSTRIKEMODE: return Key_GetOverstrikeMode( ); case CG_MEMSET: Com_Memset( VMA(1), args[2], args[3] ); return 0; case CG_MEMCPY: Com_Memcpy( VMA(1), VMA(2), args[3] ); return 0; 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_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime( VMA(1) ); case CG_SNAPVECTOR: Sys_SnapVector( VMA(1) ); 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_LOADCAMERA: return loadCamera(VMA(1)); case CG_STARTCAMERA: startCamera(args[1]); return 0; case CG_GETCAMERAINFO: return getCameraInfo(args[1], VMA(2), VMA(3)); */ case CG_GET_ENTITY_TOKEN: return re.GetEntityToken( VMA(1), args[2] ); case CG_R_INPVS: return re.inPVS( VMA(1), VMA(2) ); default: assert(0); Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] ); } return 0; }
void *Sys_GetGameAPI (void *parms) { void *(*GetGameAPI) (void *); const char *basepath; const char *cdpath; const char *gamedir; const char *homepath; #ifdef MACOS_X const char *apppath; #endif const char *fn; const char *gamename; if(Cvar_VariableIntegerValue("com_jk2")) { gamename = "jk2game" ARCH_STRING DLL_EXT; } else { gamename = "jagame" ARCH_STRING DLL_EXT; } if (game_library) Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); // check the current debug directory first for development purposes homepath = Cvar_VariableString( "fs_homepath" ); basepath = Cvar_VariableString( "fs_basepath" ); cdpath = Cvar_VariableString( "fs_cdpath" ); gamedir = Cvar_VariableString( "fs_game" ); #ifdef MACOS_X apppath = Cvar_VariableString( "fs_apppath" ); #endif if(!gamedir || !gamedir[0]) gamedir = BASEGAME; fn = FS_BuildOSPath( basepath, gamedir, gamename ); game_library = Sys_LoadLibrary( fn ); //First try in mod directories. basepath -> homepath -> cdpath if (!game_library) { if (homepath[0]) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); fn = FS_BuildOSPath( homepath, gamedir, gamename); game_library = Sys_LoadLibrary( fn ); } } #ifdef MACOS_X if (!game_library) { if( apppath[0] ) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); fn = FS_BuildOSPath( apppath, gamedir, gamename ); game_library = Sys_LoadLibrary( fn ); } } #endif if (!game_library) { if( cdpath[0] ) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); fn = FS_BuildOSPath( cdpath, gamedir, gamename ); game_library = Sys_LoadLibrary( fn ); } } //Now try in base. basepath -> homepath -> cdpath if (!game_library) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); fn = FS_BuildOSPath( basepath, BASEGAME, gamename); game_library = Sys_LoadLibrary( fn ); } if (!game_library) { if ( homepath[0] ) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); fn = FS_BuildOSPath( homepath, BASEGAME, gamename); game_library = Sys_LoadLibrary( fn ); } } #ifdef MACOS_X if (!game_library) { if( apppath[0] ) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); fn = FS_BuildOSPath( apppath, BASEGAME, gamename ); game_library = Sys_LoadLibrary( fn ); } } #endif if (!game_library) { if( cdpath[0] ) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); fn = FS_BuildOSPath( cdpath, BASEGAME, gamename ); game_library = Sys_LoadLibrary( fn ); } } //Still couldn't find it. if (!game_library) { Com_Printf( "Sys_GetGameAPI(%s) failed: \"%s\"\n", fn, Sys_LibraryError() ); Com_Error( ERR_FATAL, "Couldn't load game" ); } Com_Printf ( "Sys_GetGameAPI(%s): succeeded ...\n", fn ); GetGameAPI = (void *(*)(void *))Sys_LoadFunction (game_library, "GetGameAPI"); if (!GetGameAPI) { Sys_UnloadGame (); return NULL; } return GetGameAPI (parms); }
/** * @sa CL_ActorAddToTeamList * @sa G_AppearPerishEvent * @sa CL_ActorAdd * @note EV_ACTOR_APPEAR */ void CL_ActorAppear (const eventRegister_t *self, dbuffer *msg) { le_t *le, *leResponsible; int entnum, entnumResponsible, modelnum1, modelnum2; int teamDefID = -1; /* check if the actor is already visible */ entnum = NET_ReadShort(msg); entnumResponsible = NET_ReadShort(msg); le = LE_Get(entnum); leResponsible = LE_Get(entnumResponsible); if (entnumResponsible != SKIP_LOCAL_ENTITY && !leResponsible) LE_NotFoundError(entnumResponsible); /* mission start - no actor is spawned yet - so create it */ if (!le) le = LE_Add(entnum); /* Locking should be unnecessary if CL_CheckDefault filters this call, since this event starts and * ends in this function only. Adding lock/unlock just to be sure. */ LE_Lock(le); /* maybe added via CL_ActorAdd before */ le->flags &= ~LE_INVISIBLE; /* get the info */ NET_ReadFormat(msg, self->formatString, &le->team, &teamDefID, &le->gender, &le->ucn, &le->pnum, &le->pos, &le->angle, &le->right, &le->left, &modelnum1, &modelnum2, &le->bodySkin, &le->headSkin, &le->state, &le->fieldSize, &le->maxTU, &le->maxMorale, &le->maxHP); if (teamDefID < 0 || teamDefID > csi.numTeamDefs) Com_Printf("CL_ActorAppear: Invalid teamDef index\n"); else le->teamDef = &csi.teamDef[teamDefID]; switch (le->fieldSize) { case ACTOR_SIZE_NORMAL: le->addFunc = CL_AddActor; le->type = ET_ACTOR; break; case ACTOR_SIZE_2x2: le->addFunc = CL_AddUGV; le->type = ET_ACTOR2x2; break; default: Com_Error(ERR_DROP, "Unknown fieldSize for le in CL_ActorAppear (EV_ACTOR_APPEAR)"); } le->modelnum1 = modelnum1; le->modelnum2 = modelnum2; le->model1 = LE_GetDrawModel(modelnum1); le->model2 = LE_GetDrawModel(modelnum2); Grid_PosToVec(cl.mapData->map, le->fieldSize, le->pos, le->origin); le->angles[YAW] = directionAngles[le->angle]; if (LE_IsDead(le) && !LE_IsStunned(le)) le->contents = CONTENTS_DEADACTOR; else le->contents = CONTENTS_ACTOR; VectorCopy(player_mins, le->mins); if (LE_IsDead(le)) VectorCopy(player_dead_maxs, le->maxs); else VectorCopy(player_maxs, le->maxs); LE_SetThink(le, LET_StartIdle); /* count spotted aliens (also stunned) */ cl.numEnemiesSpotted = CL_CountVisibleEnemies(); if (LE_IsLivingActor(le)) { if (cl.actTeam != cls.team) { /* center view (if wanted) */ LE_CenterView(le); } /* draw line of sight */ if (le->team != cls.team) { if (leResponsible) CL_DrawLineOfSight(leResponsible, le); /* message */ if (le->team != TEAM_CIVILIAN) { if (GAME_TeamIsKnown(le->teamDef)) { char tmpbuf[128]; Com_sprintf(tmpbuf, sizeof(tmpbuf), _("Enemy spotted: %s!"), _(le->teamDef->name)); HUD_DisplayMessage(tmpbuf); } else HUD_DisplayMessage(_("Unknown enemy spotted!")); } else HUD_DisplayMessage(_("Civilian spotted.")); /* update pathing as new actor could block path */ CL_ActorConditionalMoveCalc(leResponsible ? leResponsible : selActor); } } /* add team members to the actor list */ CL_ActorAddToTeamList(le); LE_Unlock(le); }
/* ===================== CL_ParseDownload A download message has been received from the server ===================== */ void CL_ParseDownload (sizebuf_t *msg, qboolean dataIsCompressed) { int size, percent; char name[MAX_OSPATH]; // int r; // read the data size = MSG_ReadShort (msg); percent = MSG_ReadByte (msg); if (size < 0) { if (size == -1) Com_Printf ("Server does not have this file.\n"); else Com_Printf ("Bad download data from server.\n"); cls.downloadtempname[0] = 0; cls.downloadname[0] = 0; cls.failed_download = true; if (cls.download) { // if here, we tried to resume a file but the server said no fclose (cls.download); cls.download = NULL; } CL_RequestNextDownload (); return; } // open the file if not opened yet if (!cls.download) { if (!cls.downloadtempname[0]) { Com_Printf ("Received download packet without request. Ignored.\n"); msg->readcount += size; return; } CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); FS_CreatePath (name); cls.download = fopen (name, "wb"); if (!cls.download) { msg->readcount += size; Com_Printf ("Failed to open %s\n", cls.downloadtempname); CL_RequestNextDownload (); return; } } if (dataIsCompressed) { uint16 uncompressedLen; byte uncompressed[0xFFFF]; uncompressedLen = MSG_ReadShort (msg); if (!uncompressedLen) Com_Error (ERR_DROP, "uncompressedLen == 0"); ZLibDecompress (msg->data + msg->readcount, size, uncompressed, uncompressedLen, -15); fwrite (uncompressed, 1, uncompressedLen, cls.download); Com_DPrintf ("svc_zdownload(%s): %d -> %d\n", cls.downloadname, size, uncompressedLen); } else { fwrite (msg->data + msg->readcount, 1, size, cls.download); } //fwrite (net_message.data + net_message.readcount, 1, size, cls.download); msg->readcount += size; if (percent != 100) { // request next block // change display routines by zoid cls.downloadpercent = percent; MSG_WriteByte (&cls.netchan.message, clc_stringcmd); SZ_Print (&cls.netchan.message, "nextdl"); } else { CL_FinishDownload(); // get another file if needed CL_RequestNextDownload (); } }
/* ================= VM_Compile ================= */ void VM_Compile( vm_t *vm, vmHeader_t *header ) { int op; int maxLength; int v; int i; qboolean opt; // allocate a very large temp buffer, we will shrink it later maxLength = header->codeLength * 8; buf = Z_Malloc( maxLength ); jused = Z_Malloc(header->instructionCount + 2 ); Com_Memset(jused, 0, header->instructionCount+2); // ensure that the optimisation pass knows about all the jump // table targets for( i = 0; i < vm->numJumpTableTargets; i++ ) { jused[ *(int *)(vm->jumpTableTargets + ( i * sizeof( int ) ) ) ] = 1; } for(pass=0;pass<2;pass++) { oc0 = -23423; oc1 = -234354; pop0 = -43435; pop1 = -545455; // translate all instructions pc = 0; instruction = 0; code = (byte *)header + header->codeOffset; compiledOfs = 0; LastCommand = LAST_COMMAND_NONE; while ( instruction < header->instructionCount ) { if ( compiledOfs > maxLength - 16 ) { Com_Error( ERR_FATAL, "VM_CompileX86: maxLength exceeded" ); } vm->instructionPointers[ instruction ] = compiledOfs; instruction++; if ( pc > header->codeLength ) { Com_Error( ERR_FATAL, "VM_CompileX86: pc > header->codeLength" ); } op = code[ pc ]; pc++; switch ( op ) { case 0: break; case OP_BREAK: EmitString( "CC" ); // int 3 break; case OP_ENTER: EmitString( "81 EE" ); // sub esi, 0x12345678 Emit4( Constant4() ); break; case OP_CONST: if (code[pc+4] == OP_LOAD4) { EmitAddEDI4(vm); EmitString( "BB" ); // mov ebx, 0x12345678 Emit4( (Constant4()&vm->dataMask) + (int)vm->dataBase); EmitString( "8B 03" ); // mov eax, dword ptr [ebx] EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax pc++; // OP_LOAD4 instruction += 1; break; } if (code[pc+4] == OP_LOAD2) { EmitAddEDI4(vm); EmitString( "BB" ); // mov ebx, 0x12345678 Emit4( (Constant4()&vm->dataMask) + (int)vm->dataBase); EmitString( "0F B7 03" ); // movzx eax, word ptr [ebx] EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax pc++; // OP_LOAD4 instruction += 1; break; } if (code[pc+4] == OP_LOAD1) { EmitAddEDI4(vm); EmitString( "BB" ); // mov ebx, 0x12345678 Emit4( (Constant4()&vm->dataMask) + (int)vm->dataBase); EmitString( "0F B6 03" ); // movzx eax, byte ptr [ebx] EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax pc++; // OP_LOAD4 instruction += 1; break; } if (code[pc+4] == OP_STORE4) { opt = EmitMovEBXEDI(vm, (vm->dataMask & ~3)); EmitString( "B8" ); // mov eax, 0x12345678 Emit4( Constant4() ); // if (!opt) { // EmitString( "81 E3" ); // and ebx, 0x12345678 // Emit4( vm->dataMask & ~3 ); // } EmitString( "89 83" ); // mov dword ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 pc++; // OP_STORE4 instruction += 1; break; } if (code[pc+4] == OP_STORE2) { opt = EmitMovEBXEDI(vm, (vm->dataMask & ~1)); EmitString( "B8" ); // mov eax, 0x12345678 Emit4( Constant4() ); // if (!opt) { // EmitString( "81 E3" ); // and ebx, 0x12345678 // Emit4( vm->dataMask & ~1 ); // } EmitString( "66 89 83" ); // mov word ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 pc++; // OP_STORE4 instruction += 1; break; } if (code[pc+4] == OP_STORE1) { opt = EmitMovEBXEDI(vm, vm->dataMask); EmitString( "B8" ); // mov eax, 0x12345678 Emit4( Constant4() ); // if (!opt) { // EmitString( "81 E3" ); // and ebx, 0x12345678 // Emit4( vm->dataMask ); // } EmitString( "88 83" ); // mov byte ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 pc++; // OP_STORE4 instruction += 1; break; } if (code[pc+4] == OP_ADD) { EmitString( "81 07" ); // add dword ptr [edi], 0x1234567 Emit4( Constant4() ); pc++; // OP_ADD instruction += 1; break; } if (code[pc+4] == OP_SUB) { EmitString( "81 2F" ); // sub dword ptr [edi], 0x1234567 Emit4( Constant4() ); pc++; // OP_ADD instruction += 1; break; } EmitAddEDI4(vm); EmitString( "C7 07" ); // mov dword ptr [edi], 0x12345678 lastConst = Constant4(); Emit4( lastConst ); if (code[pc] == OP_JUMP) { jused[lastConst] = 1; } break; case OP_LOCAL: EmitAddEDI4(vm); EmitString( "8D 86" ); // lea eax, [0x12345678 + esi] oc0 = oc1; oc1 = Constant4(); Emit4( oc1 ); EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax break; case OP_ARG: EmitMovEAXEDI(vm); // mov eax,dword ptr [edi] EmitString( "89 86" ); // mov dword ptr [esi+database],eax // FIXME: range check Emit4( Constant1() + (int)vm->dataBase ); EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_CALL: EmitString( "C7 86" ); // mov dword ptr [esi+database],0x12345678 Emit4( (int)vm->dataBase ); Emit4( pc ); EmitString( "FF 15" ); // call asmCallPtr Emit4( (int)&asmCallPtr ); break; case OP_PUSH: EmitAddEDI4(vm); break; case OP_POP: EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_LEAVE: v = Constant4(); EmitString( "81 C6" ); // add esi, 0x12345678 Emit4( v ); EmitString( "C3" ); // ret break; case OP_LOAD4: if (code[pc] == OP_CONST && code[pc+5] == OP_ADD && code[pc+6] == OP_STORE4) { if (oc0 == oc1 && pop0 == OP_LOCAL && pop1 == OP_LOCAL) { compiledOfs -= 11; vm->instructionPointers[ instruction-1 ] = compiledOfs; } pc++; // OP_CONST v = Constant4(); EmitMovEBXEDI(vm, vm->dataMask); if (v == 1 && oc0 == oc1 && pop0 == OP_LOCAL && pop1 == OP_LOCAL) { EmitString( "FF 83"); // inc dword ptr [ebx + 0x12345678] Emit4( (int)vm->dataBase ); } else { EmitString( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678] Emit4( (int)vm->dataBase ); EmitString( "05" ); // add eax, const Emit4( v ); if (oc0 == oc1 && pop0 == OP_LOCAL && pop1 == OP_LOCAL) { EmitString( "89 83" ); // mov dword ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); } else { EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 EmitString( "8B 1F" ); // mov ebx, dword ptr [edi] EmitString( "89 83" ); // mov dword ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); } } EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 pc++; // OP_ADD pc++; // OP_STORE instruction += 3; break; } if (code[pc] == OP_CONST && code[pc+5] == OP_SUB && code[pc+6] == OP_STORE4) { if (oc0 == oc1 && pop0 == OP_LOCAL && pop1 == OP_LOCAL) { compiledOfs -= 11; vm->instructionPointers[ instruction-1 ] = compiledOfs; } EmitMovEBXEDI(vm, vm->dataMask); EmitString( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678] Emit4( (int)vm->dataBase ); pc++; // OP_CONST v = Constant4(); if (v == 1 && oc0 == oc1 && pop0 == OP_LOCAL && pop1 == OP_LOCAL) { EmitString( "FF 8B"); // dec dword ptr [ebx + 0x12345678] Emit4( (int)vm->dataBase ); } else { EmitString( "2D" ); // sub eax, const Emit4( v ); if (oc0 == oc1 && pop0 == OP_LOCAL && pop1 == OP_LOCAL) { EmitString( "89 83" ); // mov dword ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); } else { EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 EmitString( "8B 1F" ); // mov ebx, dword ptr [edi] EmitString( "89 83" ); // mov dword ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); } } EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 pc++; // OP_SUB pc++; // OP_STORE instruction += 3; break; } if (buf[compiledOfs-2] == 0x89 && buf[compiledOfs-1] == 0x07) { compiledOfs -= 2; vm->instructionPointers[ instruction-1 ] = compiledOfs; EmitString( "8B 80"); // mov eax, dword ptr [eax + 0x1234567] Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax break; } EmitMovEBXEDI(vm, vm->dataMask); EmitString( "8B 83" ); // mov eax, dword ptr [ebx + 0x12345678] Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax break; case OP_LOAD2: EmitMovEBXEDI(vm, vm->dataMask); EmitString( "0F B7 83" ); // movzx eax, word ptr [ebx + 0x12345678] Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax break; case OP_LOAD1: EmitMovEBXEDI(vm, vm->dataMask); EmitString( "0F B6 83" ); // movzx eax, byte ptr [ebx + 0x12345678] Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax break; case OP_STORE4: EmitMovEAXEDI(vm); EmitString( "8B 5F FC" ); // mov ebx, dword ptr [edi-4] // if (pop1 != OP_CALL) { // EmitString( "81 E3" ); // and ebx, 0x12345678 // Emit4( vm->dataMask & ~3 ); // } EmitString( "89 83" ); // mov dword ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 break; case OP_STORE2: EmitMovEAXEDI(vm); EmitString( "8B 5F FC" ); // mov ebx, dword ptr [edi-4] // EmitString( "81 E3" ); // and ebx, 0x12345678 // Emit4( vm->dataMask & ~1 ); EmitString( "66 89 83" ); // mov word ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 break; case OP_STORE1: EmitMovEAXEDI(vm); EmitString( "8B 5F FC" ); // mov ebx, dword ptr [edi-4] // EmitString( "81 E3" ); // and ebx, 0x12345678 // Emit4( vm->dataMask ); EmitString( "88 83" ); // mov byte ptr [ebx+0x12345678], eax Emit4( (int)vm->dataBase ); EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 break; case OP_EQ: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "75 06" ); // jne +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_NE: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "74 06" ); // je +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_LTI: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "7D 06" ); // jnl +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_LEI: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "7F 06" ); // jnle +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_GTI: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "7E 06" ); // jng +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_GEI: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "7C 06" ); // jnge +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_LTU: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "73 06" ); // jnb +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_LEU: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "77 06" ); // jnbe +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_GTU: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "76 06" ); // jna +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_GEU: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "8B 47 04" ); // mov eax, dword ptr [edi+4] EmitString( "3B 47 08" ); // cmp eax, dword ptr [edi+8] EmitString( "72 06" ); // jnae +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_EQF: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "D9 47 04" ); // fld dword ptr [edi+4] EmitString( "D8 5F 08" ); // fcomp dword ptr [edi+8] EmitString( "DF E0" ); // fnstsw ax EmitString( "F6 C4 40" ); // test ah,0x40 EmitString( "74 06" ); // je +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_NEF: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "D9 47 04" ); // fld dword ptr [edi+4] EmitString( "D8 5F 08" ); // fcomp dword ptr [edi+8] EmitString( "DF E0" ); // fnstsw ax EmitString( "F6 C4 40" ); // test ah,0x40 EmitString( "75 06" ); // jne +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_LTF: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "D9 47 04" ); // fld dword ptr [edi+4] EmitString( "D8 5F 08" ); // fcomp dword ptr [edi+8] EmitString( "DF E0" ); // fnstsw ax EmitString( "F6 C4 01" ); // test ah,0x01 EmitString( "74 06" ); // je +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_LEF: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "D9 47 04" ); // fld dword ptr [edi+4] EmitString( "D8 5F 08" ); // fcomp dword ptr [edi+8] EmitString( "DF E0" ); // fnstsw ax EmitString( "F6 C4 41" ); // test ah,0x41 EmitString( "74 06" ); // je +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_GTF: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "D9 47 04" ); // fld dword ptr [edi+4] EmitString( "D8 5F 08" ); // fcomp dword ptr [edi+8] EmitString( "DF E0" ); // fnstsw ax EmitString( "F6 C4 41" ); // test ah,0x41 EmitString( "75 06" ); // jne +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_GEF: EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 EmitString( "D9 47 04" ); // fld dword ptr [edi+4] EmitString( "D8 5F 08" ); // fcomp dword ptr [edi+8] EmitString( "DF E0" ); // fnstsw ax EmitString( "F6 C4 01" ); // test ah,0x01 EmitString( "75 06" ); // jne +6 EmitString( "FF 25" ); // jmp [0x12345678] v = Constant4(); jused[v] = 1; Emit4( (int)vm->instructionPointers + v*4 ); break; case OP_NEGI: EmitString( "F7 1F" ); // neg dword ptr [edi] break; case OP_ADD: EmitMovEAXEDI(vm); // mov eax, dword ptr [edi] EmitString( "01 47 FC" ); // add dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_SUB: EmitMovEAXEDI(vm); // mov eax, dword ptr [edi] EmitString( "29 47 FC" ); // sub dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_DIVI: EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4] EmitString( "99" ); // cdq EmitString( "F7 3F" ); // idiv dword ptr [edi] EmitString( "89 47 FC" ); // mov dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_DIVU: EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4] EmitString( "33 D2" ); // xor edx, edx EmitString( "F7 37" ); // div dword ptr [edi] EmitString( "89 47 FC" ); // mov dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_MODI: EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4] EmitString( "99" ); // cdq EmitString( "F7 3F" ); // idiv dword ptr [edi] EmitString( "89 57 FC" ); // mov dword ptr [edi-4],edx EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_MODU: EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4] EmitString( "33 D2" ); // xor edx, edx EmitString( "F7 37" ); // div dword ptr [edi] EmitString( "89 57 FC" ); // mov dword ptr [edi-4],edx EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_MULI: EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4] EmitString( "F7 2F" ); // imul dword ptr [edi] EmitString( "89 47 FC" ); // mov dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_MULU: EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4] EmitString( "F7 27" ); // mul dword ptr [edi] EmitString( "89 47 FC" ); // mov dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_BAND: EmitMovEAXEDI(vm); // mov eax, dword ptr [edi] EmitString( "21 47 FC" ); // and dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_BOR: EmitMovEAXEDI(vm); // mov eax, dword ptr [edi] EmitString( "09 47 FC" ); // or dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_BXOR: EmitMovEAXEDI(vm); // mov eax, dword ptr [edi] EmitString( "31 47 FC" ); // xor dword ptr [edi-4],eax EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_BCOM: EmitString( "F7 17" ); // not dword ptr [edi] break; case OP_LSH: EmitString( "8B 0F" ); // mov ecx, dword ptr [edi] EmitString( "D3 67 FC" ); // shl dword ptr [edi-4], cl EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_RSHI: EmitString( "8B 0F" ); // mov ecx, dword ptr [edi] EmitString( "D3 7F FC" ); // sar dword ptr [edi-4], cl EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_RSHU: EmitString( "8B 0F" ); // mov ecx, dword ptr [edi] EmitString( "D3 6F FC" ); // shr dword ptr [edi-4], cl EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_NEGF: EmitString( "D9 07" ); // fld dword ptr [edi] EmitString( "D9 E0" ); // fchs EmitString( "D9 1F" ); // fstp dword ptr [edi] break; case OP_ADDF: EmitString( "D9 47 FC" ); // fld dword ptr [edi-4] EmitString( "D8 07" ); // fadd dword ptr [edi] EmitString( "D9 5F FC" ); // fstp dword ptr [edi-4] EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 break; case OP_SUBF: EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 EmitString( "D9 07" ); // fld dword ptr [edi] EmitString( "D8 67 04" ); // fsub dword ptr [edi+4] EmitString( "D9 1F" ); // fstp dword ptr [edi] break; case OP_DIVF: EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 EmitString( "D9 07" ); // fld dword ptr [edi] EmitString( "D8 77 04" ); // fdiv dword ptr [edi+4] EmitString( "D9 1F" ); // fstp dword ptr [edi] break; case OP_MULF: EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 EmitString( "D9 07" ); // fld dword ptr [edi] EmitString( "D8 4f 04" ); // fmul dword ptr [edi+4] EmitString( "D9 1F" ); // fstp dword ptr [edi] break; case OP_CVIF: EmitString( "DB 07" ); // fild dword ptr [edi] EmitString( "D9 1F" ); // fstp dword ptr [edi] break; case OP_CVFI: #ifndef FTOL_PTR // WHENHELLISFROZENOVER // not IEEE complient, but simple and fast EmitString( "D9 07" ); // fld dword ptr [edi] EmitString( "DB 1F" ); // fistp dword ptr [edi] #else // FTOL_PTR // call the library conversion function EmitString( "D9 07" ); // fld dword ptr [edi] EmitString( "FF 15" ); // call ftolPtr Emit4( (int)&ftolPtr ); EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax #endif break; case OP_SEX8: EmitString( "0F BE 07" ); // movsx eax, byte ptr [edi] EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax break; case OP_SEX16: EmitString( "0F BF 07" ); // movsx eax, word ptr [edi] EmitCommand(LAST_COMMAND_MOV_EDI_EAX); // mov dword ptr [edi], eax break; case OP_BLOCK_COPY: // FIXME: range check EmitString( "56" ); // push esi EmitString( "57" ); // push edi EmitString( "8B 37" ); // mov esi,[edi] EmitString( "8B 7F FC" ); // mov edi,[edi-4] EmitString( "B9" ); // mov ecx,0x12345678 Emit4( Constant4() >> 2 ); EmitString( "B8" ); // mov eax, datamask Emit4( vm->dataMask ); EmitString( "BB" ); // mov ebx, database Emit4( (int)vm->dataBase ); EmitString( "23 F0" ); // and esi, eax EmitString( "03 F3" ); // add esi, ebx EmitString( "23 F8" ); // and edi, eax EmitString( "03 FB" ); // add edi, ebx EmitString( "F3 A5" ); // rep movsd EmitString( "5F" ); // pop edi EmitString( "5E" ); // pop esi EmitCommand(LAST_COMMAND_SUB_DI_8); // sub edi, 8 break; case OP_JUMP: EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4 EmitString( "8B 47 04" ); // mov eax,dword ptr [edi+4] // FIXME: range check EmitString( "FF 24 85" ); // jmp dword ptr [instructionPointers + eax * 4] Emit4( (int)vm->instructionPointers ); break; default: Com_Error( ERR_DROP, "VM_CompileX86: bad opcode %i at offset %i", op, pc ); } pop0 = pop1; pop1 = op; } } // copy to an exact size buffer on the hunk vm->codeLength = compiledOfs; #ifdef VM_X86_MMAP vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if(vm->codeBase == (void*)-1) Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory"); #elif _WIN32 // allocate memory with EXECUTE permissions under windows. vm->codeBase = VirtualAlloc(NULL, compiledOfs, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(!vm->codeBase) Com_Error(ERR_DROP, "VM_CompileX86: VirtualAlloc failed"); #else vm->codeBase = malloc(compiledOfs); #endif Com_Memcpy( vm->codeBase, buf, compiledOfs ); #ifdef VM_X86_MMAP if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC)) Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed"); #elif _WIN32 { DWORD oldProtect = 0; // remove write permissions. if(!VirtualProtect(vm->codeBase, compiledOfs, PAGE_EXECUTE_READ, &oldProtect)) Com_Error(ERR_DROP, "VM_CompileX86: VirtualProtect failed"); } #endif Z_Free( buf ); Z_Free( jused ); Com_Printf( "VM file %s compiled to %i bytes of code\n", vm->name, compiledOfs ); vm->destroy = VM_Destroy_Compiled; // offset all the instruction pointers for the new location for ( i = 0 ; i < header->instructionCount ; i++ ) { vm->instructionPointers[i] += (int)vm->codeBase; } }
/* ================== CL_ParseServerData ================== */ qboolean CL_ParseServerData (sizebuf_t *msg) { char *str; int i; Com_DPrintf ("Serverdata packet received.\n"); // // wipe the client_state_t struct // CL_ClearState (); cls.state = ca_connected; // parse protocol version number i = MSG_ReadLong (msg); cls.serverProtocol = i; cl.servercount = MSG_ReadLong (msg); cl.attractloop = MSG_ReadByte (msg); if (cl.attractloop) { //cls.serverProtocol = PROTOCOL_VERSION_DEFAULT; } else if (i != PROTOCOL_VERSION_DEFAULT && i != PROTOCOL_VERSION_R1Q2) { Com_Error (ERR_DROP, "Server is using unknown protocol %d.", i); } // game directory str = MSG_ReadString (msg); Q_strncpyz (cl.gamedir, str, sizeof(cl.gamedir)); str = cl.gamedir; // set gamedir if (!Com_ServerState()) { Cvar_SetLatched("game", str); if( FS_NeedRestart() ) { CL_RestartFilesystem(true); } } // parse player entity number cl.playernum = MSG_ReadShort (msg); // get the full level name str = MSG_ReadString (msg); cl.pmp.strafeHack = false; cl.pmp.speedMultiplier = 1; cl.pmp.airaccelerate = 0; cls.protocolVersion = 0; if (cls.serverProtocol == PROTOCOL_VERSION_R1Q2) { i = MSG_ReadByte(msg); if( i ) { Com_Printf("'Enhanced' R1Q2 servers are not supported, falling back to protocol 34.\n" ); CL_Disconnect(); cls.serverProtocol = PROTOCOL_VERSION_DEFAULT; CL_Reconnect_f (); return false; } i = MSG_ReadShort(msg); if (i < PROTOCOL_VERSION_R1Q2_MINIMUM || i > PROTOCOL_VERSION_R1Q2_CURRENT) { if (cl.attractloop) { if ( i < PROTOCOL_VERSION_R1Q2_MINIMUM ) Com_Printf("This demo was recorded with an earlier version of the R1Q2 protocol. It may not play back properly.\n"); else Com_Printf("This demo was recorded with a later version of the R1Q2 protocol. It may not play back properly.\n"); } else { if( i < PROTOCOL_VERSION_R1Q2_MINIMUM ) { Com_Printf("Server uses OLDER minor R1Q2 protocol version than minimum supported (%i < %i), falling back to protocol 34.\n", i, PROTOCOL_VERSION_R1Q2_MINIMUM); CL_Disconnect(); cls.serverProtocol = PROTOCOL_VERSION_DEFAULT; CL_Reconnect_f (); return false; } Com_Printf("Server uses NEWER minor R1Q2 protocol version (%i > %i), some features will be unavailable.\n", i, PROTOCOL_VERSION_R1Q2_CURRENT); } } if (i >= 1903) { MSG_ReadByte(msg); cl.pmp.strafeHack = MSG_ReadByte(msg); } cl.pmp.speedMultiplier = 2; cls.protocolVersion = i; } if (cl.playernum == -1) { // playing a cinematic or showing a pic, not a level SCR_PlayCinematic (str); } else { // seperate the printfs so the server message can have a color Com_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); Com_Printf ("%c%s\n", 2, str); // need to prep refresh at next oportunity cl.refresh_prepped = false; if((unsigned)cl.playernum >= MAX_CLIENTS) { cl.playernum = ( MAX_CLIENTS - 1 ); } } return true; }
/* ============ VID_CheckChanges This function gets called once just before drawing each frame, and it's sole purpose in life is to check to see if any of the video mode parameters have changed, and if they have to update the rendering DLL and/or video mode to match. ============ */ void VID_CheckChanges (void) { char name[100]; if ( win_noalttab->modified ) { if ( win_noalttab->value ) { WIN_DisableAltTab(); } else { WIN_EnableAltTab(); } win_noalttab->modified = false; } if ( vid_ref->modified ) { cl.force_refdef = true; // can't use a paused refdef S_StopAllSounds(); } while (vid_ref->modified) { /* ** refresh has changed */ vid_ref->modified = false; vid_fullscreen->modified = true; cl.refresh_prepped = false; cls.disable_screen = true; Com_sprintf( name, sizeof(name), "ref_%s.dll", vid_ref->string ); if ( !VID_LoadRefresh( name ) ) { if ( strcmp (vid_ref->string, "soft") == 0 ) Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!"); Cvar_Set( "vid_ref", "soft" ); /* ** drop the console if we fail to load a refresh */ if ( cls.key_dest != key_console ) { Con_ToggleConsole_f(); } } cls.disable_screen = false; } /* ** update our window position */ if ( vid_xpos->modified || vid_ypos->modified ) { if (!vid_fullscreen->value) VID_UpdateWindowPosAndSize( vid_xpos->value, vid_ypos->value ); vid_xpos->modified = false; vid_ypos->modified = false; } }
/* ================ CL_ParseConfigString ================ */ void CL_ParseConfigString (sizebuf_t *msg) { int i, length; char *s; char olds[MAX_QPATH]; i = MSG_ReadShort (msg); if ((unsigned)i >= MAX_CONFIGSTRINGS) Com_Error (ERR_DROP, "configstring > MAX_CONFIGSTRINGS"); Q_strncpyz (olds, cl.configstrings[i], sizeof(olds)); s = MSG_ReadString(msg); length = strlen(s); if (i != CS_NAME && i < CS_GENERAL) { if (i >= CS_STATUSBAR && i < CS_AIRACCEL) { Q_strncpyz(cl.configstrings[i], s, MAX_QPATH * (CS_AIRACCEL - i)); } else { if (length >= MAX_QPATH) Com_Printf ("WARNING: Configstring %d of length %d exceeds MAX_QPATH.\n", i, length); Q_strncpyz(cl.configstrings[i], s, MAX_QPATH); } } else { Q_strncpyz(cl.configstrings[i], s, MAX_QPATH * (MAX_CONFIGSTRINGS - i)); } // do something apropriate if(i == CS_AIRACCEL) { cl.pmp.airaccelerate = atoi(cl.configstrings[CS_AIRACCEL]) ? true : false; } else if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES) { CL_SetLightstyle (i - CS_LIGHTS); } else if (i == CS_CDTRACK) { #ifdef CD_AUDIO if (cl.refresh_prepped) CDAudio_Play (atoi(cl.configstrings[CS_CDTRACK]), true); #endif } else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS) { if( i == CS_MODELS + 1 ) { if( length > 9 ) { Q_strncpyz( cls.mapname, s + 5, sizeof( cls.mapname ) ); // skip "maps/" cls.mapname[strlen( cls.mapname ) - 4] = 0; // cut off ".bsp" } } if (cl.refresh_prepped) { cl.model_draw[i-CS_MODELS] = R_RegisterModel (cl.configstrings[i]); if (cl.configstrings[i][0] == '*') cl.model_clip[i-CS_MODELS] = CM_InlineModel (cl.configstrings[i]); else cl.model_clip[i-CS_MODELS] = NULL; } } else if (i >= CS_SOUNDS && i < CS_SOUNDS+MAX_MODELS) { if (cl.refresh_prepped) cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]); } else if (i >= CS_IMAGES && i < CS_IMAGES+MAX_MODELS) { if (cl.refresh_prepped) cl.image_precache[i-CS_IMAGES] = Draw_FindPic (cl.configstrings[i]); } else if (i == CS_MAXCLIENTS) { cl.maxclients = atoi(cl.configstrings[CS_MAXCLIENTS]); clamp(cl.maxclients, 0, MAX_CLIENTS); } else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS) { if (cl.refresh_prepped && strcmp(olds, s)) CL_ParseClientinfo (i-CS_PLAYERSKINS); } }
int BG_SiegeGetValueGroup(char *buf, char *group, char *outbuf) { int i = 0; int j; char checkGroup[4096]; qboolean isGroup; int parseGroups = 0; while (buf[i]) { if (buf[i] != ' ' && buf[i] != '{' && buf[i] != '}' && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB) { //we're on a valid character if (buf[i] == '/' && buf[i+1] == '/') { //this is a comment, so skip over it while (buf[i] && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB) { i++; } } else { //parse to the next space/endline/eos and check this value against our group value. j = 0; while (buf[i] != ' ' && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB && buf[i] != '{' && buf[i]) { if (buf[i] == '/' && buf[i+1] == '/') { //hit a comment, break out. break; } checkGroup[j] = buf[i]; j++; i++; } checkGroup[j] = 0; //Make sure this is a group as opposed to a globally defined value. if (buf[i] == '/' && buf[i+1] == '/') { //stopped on a comment, so first parse to the end of it. while (buf[i] && buf[i] != '\n' && buf[i] != '\r') { i++; } while (buf[i] == '\n' || buf[i] == '\r') { i++; } } if (!buf[i]) { Com_Error(ERR_DROP, "Unexpected EOF while looking for group '%s'", group); } isGroup = qfalse; while ( buf[i] && (buf[i] == ' ' || buf[i] == SIEGECHAR_TAB || buf[i] == '\n' || buf[i] == '\r') ) { //parse to the next valid character i++; } if (buf[i] == '{') { //if the next valid character is an opening bracket, then this is indeed a group isGroup = qtrue; } //Is this the one we want? if (isGroup && !Q_stricmp(checkGroup, group)) { //guess so. Parse until we hit the { indicating the beginning of the group. while (buf[i] != '{' && buf[i]) { i++; } if (buf[i]) { //We're at the start of the group now, so parse to the closing bracket. j = 0; parseGroups = 0; while ((buf[i] != '}' || parseGroups) && buf[i]) { if (buf[i] == '{') { //increment for the opening bracket. parseGroups++; } else if (buf[i] == '}') { //decrement for the closing bracket parseGroups--; } if (parseGroups < 0) { //Syntax error, I guess. Com_Error(ERR_DROP, "Found a closing bracket without an opening bracket while looking for group '%s'", group); } if ((buf[i] != '{' || parseGroups > 1) && (buf[i] != '}' || parseGroups > 0)) { //don't put the start and end brackets for this group into the output buffer outbuf[j] = buf[i]; j++; } if (buf[i] == '}' && !parseGroups) { //Alright, we can break out now. break; } i++; } outbuf[j] = 0; //Verify that we ended up on the closing bracket. if (buf[i] != '}') { Com_Error(ERR_DROP, "Group '%s' is missing a closing bracket", group); } //Strip the tabs so we're friendly for value parsing. BG_SiegeStripTabs(outbuf); return 1; //we got it, so return 1. } else { Com_Error(ERR_DROP, "Error parsing group in file, unexpected EOF before opening bracket while looking for group '%s'", group); } } else if (!isGroup) { //if it wasn't a group, parse to the end of the line while (buf[i] && buf[i] != '\n' && buf[i] != '\r') { i++; } } else { //this was a group but we not the one we wanted to find, so parse by it. parseGroups = 0; while (buf[i] && (buf[i] != '}' || parseGroups)) { if (buf[i] == '{') { parseGroups++; } else if (buf[i] == '}') { parseGroups--; } if (parseGroups < 0) { //Syntax error, I guess. Com_Error(ERR_DROP, "Found a closing bracket without an opening bracket while looking for group '%s'", group); } if (buf[i] == '}' && !parseGroups) { //Alright, we can break out now. break; } i++; } if (buf[i] != '}') { Com_Error(ERR_DROP, "Found an opening bracket without a matching closing bracket while looking for group '%s'", group); } i++; } } } else if (buf[i] == '{') { //we're in a group that isn't the one we want, so parse to the end. parseGroups = 0; while (buf[i] && (buf[i] != '}' || parseGroups)) { if (buf[i] == '{') { parseGroups++; } else if (buf[i] == '}') { parseGroups--; } if (parseGroups < 0) { //Syntax error, I guess. Com_Error(ERR_DROP, "Found a closing bracket without an opening bracket while looking for group '%s'", group); } if (buf[i] == '}' && !parseGroups) { //Alright, we can break out now. break; } i++; } if (buf[i] != '}') { Com_Error(ERR_DROP, "Found an opening bracket without a matching closing bracket while looking for group '%s'", group); } } if (!buf[i]) { break; } i++; } return 0; //guess we never found it. }
static void SV_InitRef( void ) { refimport_t ri = {0}; refexport_t *ret; Com_Printf( "----- Initializing Renderer ----\n" ); //set up the import table ri.Printf = SV_RefPrintf; ri.Error = Com_Error; ri.OPrintf = Com_OPrintf; ri.Milliseconds = Sys_Milliseconds2; //FIXME: unix+mac need this ri.Hunk_AllocateTempMemory = Hunk_AllocateTempMemory; ri.Hunk_FreeTempMemory = Hunk_FreeTempMemory; ri.Hunk_Alloc = Hunk_Alloc; ri.Hunk_MemoryRemaining = Hunk_MemoryRemaining; ri.Z_Malloc = Z_Malloc; ri.Z_Free = Z_Free; ri.Z_MemSize = Z_MemSize; ri.Z_MorphMallocTag = Z_MorphMallocTag; ri.Cmd_ExecuteString = Cmd_ExecuteString; ri.Cmd_Argc = Cmd_Argc; ri.Cmd_Argv = Cmd_Argv; ri.Cmd_ArgsBuffer = Cmd_ArgsBuffer; ri.Cmd_AddCommand = Cmd_AddCommand; ri.Cmd_RemoveCommand = Cmd_RemoveCommand; ri.Cvar_Set = Cvar_Set; ri.Cvar_Get = Cvar_Get; ri.Cvar_VariableStringBuffer = Cvar_VariableStringBuffer; ri.Cvar_VariableString = Cvar_VariableString; ri.Cvar_VariableValue = Cvar_VariableValue; ri.Cvar_VariableIntegerValue = Cvar_VariableIntegerValue; ri.Sys_LowPhysicalMemory = Sys_LowPhysicalMemory; ri.SE_GetString = SE_GetString; ri.FS_FreeFile = FS_FreeFile; ri.FS_FreeFileList = FS_FreeFileList; ri.FS_Read = FS_Read; ri.FS_ReadFile = FS_ReadFile; ri.FS_FCloseFile = FS_FCloseFile; ri.FS_FOpenFileRead = FS_FOpenFileRead; ri.FS_FOpenFileWrite = FS_FOpenFileWrite; ri.FS_FOpenFileByMode = FS_FOpenFileByMode; ri.FS_FileExists = FS_FileExists; ri.FS_FileIsInPAK = FS_FileIsInPAK; ri.FS_ListFiles = FS_ListFiles; ri.FS_Write = FS_Write; ri.FS_WriteFile = FS_WriteFile; ri.CM_BoxTrace = CM_BoxTrace; ri.CM_DrawDebugSurface = CM_DrawDebugSurface; // ri.CM_CullWorldBox = CM_CullWorldBox; // ri.CM_TerrainPatchIterate = CM_TerrainPatchIterate; // ri.CM_RegisterTerrain = CM_RegisterTerrain; // ri.CM_ShutdownTerrain = CM_ShutdownTerrain; ri.CM_ClusterPVS = CM_ClusterPVS; ri.CM_LeafArea = CM_LeafArea; ri.CM_LeafCluster = CM_LeafCluster; ri.CM_PointLeafnum = CM_PointLeafnum; ri.CM_PointContents = CM_PointContents; ri.VM_Call = VM_Call; ri.Com_TheHunkMarkHasBeenMade = Com_TheHunkMarkHasBeenMade; ri.SV_GetConfigstring = SV_GetConfigstring; ri.SV_SetConfigstring = SV_SetConfigstring; // ri.S_RestartMusic = S_RestartMusic; // ri.SND_RegisterAudio_LevelLoadEnd = SND_RegisterAudio_LevelLoadEnd; // ri.CIN_RunCinematic = CIN_RunCinematic; // ri.CIN_PlayCinematic = CIN_PlayCinematic; // ri.CIN_UploadCinematic = CIN_UploadCinematic; // ri.CL_WriteAVIVideoFrame = CL_WriteAVIVideoFrame; // g2 data access ri.GetSharedMemory = GetSharedMemory; // ri.GetCgameVM = GetCgameVM; ri.GetGameVM = GetGameVM; ri.GetCurrentVM = GetCurrentVM; // ugly win32 backend ri.CM_GetCachedMapDiskImage = CM_GetCachedMapDiskImage; ri.CM_SetCachedMapDiskImage = CM_SetCachedMapDiskImage; ri.CM_SetUsingCache = CM_SetUsingCache; //RAZFIXME: Might have to do something about this... ri.GetG2VertSpaceServer = GetG2VertSpaceServer; G2VertSpaceServer = &CMiniHeap_singleton; ret = GetRefAPI( REF_API_VERSION, &ri ); #if defined __USEA3D && defined __A3D_GEOM hA3Dg_ExportRenderGeom (ret); #endif // Com_Printf( "-------------------------------\n"); if ( !ret ) { Com_Error (ERR_FATAL, "Couldn't initialize refresh" ); } re = *ret; }
void BG_SiegeParseClassFile(const char *filename, siegeClassDesc_t *descBuffer) { fileHandle_t f; int len; int i; char classInfo[4096]; char parseBuf[4096]; len = trap->FS_Open( filename, &f, FS_READ ); if (!f || len >= 4096) { return; } trap->FS_Read( classInfo, len, f ); trap->FS_Close( f ); classInfo[len] = 0; //first get the description if we have a buffer for it if (descBuffer) { if (!BG_SiegeGetPairedValue(classInfo, "description", descBuffer->desc)) { Q_strncpyz(descBuffer->desc, "DESCRIPTION UNAVAILABLE", sizeof(descBuffer->desc)); } //Hit this assert? Memory has already been trashed. Increase //SIEGE_CLASS_DESC_LEN. assert(strlen(descBuffer->desc) < SIEGE_CLASS_DESC_LEN); } BG_SiegeGetValueGroup(classInfo, "ClassInfo", classInfo); //Parse name if (BG_SiegeGetPairedValue(classInfo, "name", parseBuf)) { Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].name, parseBuf, sizeof(bgSiegeClasses[0].name)); } else { Com_Error(ERR_DROP, "Siege class without name entry"); } //Parse forced model if (BG_SiegeGetPairedValue(classInfo, "model", parseBuf)) { Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].forcedModel, parseBuf, sizeof(bgSiegeClasses[0].forcedModel)); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].forcedModel[0] = 0; } //Parse forced skin if (BG_SiegeGetPairedValue(classInfo, "skin", parseBuf)) { Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].forcedSkin, parseBuf, sizeof(bgSiegeClasses[0].forcedSkin)); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].forcedSkin[0] = 0; } //Parse first saber if (BG_SiegeGetPairedValue(classInfo, "saber1", parseBuf)) { Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].saber1, parseBuf, sizeof(bgSiegeClasses[0].saber1)); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saber1[0] = 0; } //Parse second saber if (BG_SiegeGetPairedValue(classInfo, "saber2", parseBuf)) { Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].saber2, parseBuf, sizeof(bgSiegeClasses[0].saber2)); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saber2[0] = 0; } //Parse forced saber stance if (BG_SiegeGetPairedValue(classInfo, "saberstyle", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].saberStance = BG_SiegeTranslateGenericTable(parseBuf, StanceTable, qtrue); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saberStance = 0; } //Parse forced saber color if (BG_SiegeGetPairedValue(classInfo, "sabercolor", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].forcedSaberColor = atoi(parseBuf); bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qtrue; } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qfalse; } //Parse forced saber2 color if (BG_SiegeGetPairedValue(classInfo, "saber2color", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].forcedSaber2Color = atoi(parseBuf); bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qtrue; } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qfalse; } //Parse weapons if (BG_SiegeGetPairedValue(classInfo, "weapons", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].weapons = BG_SiegeTranslateGenericTable(parseBuf, WPTable, qtrue); } else { Com_Error(ERR_DROP, "Siege class without weapons entry"); } if (!(bgSiegeClasses[bgNumSiegeClasses].weapons & (1 << WP_SABER))) { //make sure it has melee if there's no saber bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_MELEE); //always give them this too if they are not a saber user //bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_BRYAR_PISTOL); } //Parse forcepowers if (BG_SiegeGetPairedValue(classInfo, "forcepowers", parseBuf)) { BG_SiegeTranslateForcePowers(parseBuf, &bgSiegeClasses[bgNumSiegeClasses]); } else { //fine, clear out the powers. i = 0; while (i < NUM_FORCE_POWERS) { bgSiegeClasses[bgNumSiegeClasses].forcePowerLevels[i] = 0; i++; } } //Parse classflags if (BG_SiegeGetPairedValue(classInfo, "classflags", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].classflags = BG_SiegeTranslateGenericTable(parseBuf, bgSiegeClassFlagNames, qtrue); } else { //fine, we'll 0 it. bgSiegeClasses[bgNumSiegeClasses].classflags = 0; } //Parse maxhealth if (BG_SiegeGetPairedValue(classInfo, "maxhealth", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].maxhealth = atoi(parseBuf); } else { //It's alright, just default to 100 then. bgSiegeClasses[bgNumSiegeClasses].maxhealth = 100; } //Parse starthealth if (BG_SiegeGetPairedValue(classInfo, "starthealth", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].starthealth = atoi(parseBuf); } else { //It's alright, just default to 100 then. bgSiegeClasses[bgNumSiegeClasses].starthealth = bgSiegeClasses[bgNumSiegeClasses].maxhealth; } //Parse startarmor if (BG_SiegeGetPairedValue(classInfo, "maxarmor", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].maxarmor = atoi(parseBuf); } else { //It's alright, just default to 0 then. bgSiegeClasses[bgNumSiegeClasses].maxarmor = 0; } //Parse startarmor if (BG_SiegeGetPairedValue(classInfo, "startarmor", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].startarmor = atoi(parseBuf); if (!bgSiegeClasses[bgNumSiegeClasses].maxarmor) { //if they didn't specify a damn max armor then use this. bgSiegeClasses[bgNumSiegeClasses].maxarmor = bgSiegeClasses[bgNumSiegeClasses].startarmor; } } else { //default to maxarmor. bgSiegeClasses[bgNumSiegeClasses].startarmor = bgSiegeClasses[bgNumSiegeClasses].maxarmor; } //Parse speed (this is a multiplier value) if (BG_SiegeGetPairedValue(classInfo, "speed", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].speed = atof(parseBuf); } else { //It's alright, just default to 1 then. bgSiegeClasses[bgNumSiegeClasses].speed = 1.0f; } //Parse shader for ui to use if (BG_SiegeGetPairedValue(classInfo, "uishader", parseBuf)) { #if defined(_GAME) bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0; memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait)); #elif defined(_CGAME) bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0; memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait)); #elif defined(_UI) //ui bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = trap->R_RegisterShaderNoMip(parseBuf); memcpy(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,parseBuf,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait)); #endif } else { //I guess this is an essential.. we don't want to render bad shaders or anything. Com_Error(ERR_DROP, "Siege class without uishader entry"); } //Parse shader for ui to use if (BG_SiegeGetPairedValue(classInfo, "class_shader", parseBuf)) { #ifdef _GAME bgSiegeClasses[bgNumSiegeClasses].classShader = 0; #else //cgame, ui #if defined(_CGAME) bgSiegeClasses[bgNumSiegeClasses].classShader = trap->R_RegisterShaderNoMip(parseBuf); #elif defined(_UI) bgSiegeClasses[bgNumSiegeClasses].classShader = trap->R_RegisterShaderNoMip(parseBuf); #endif assert( bgSiegeClasses[bgNumSiegeClasses].classShader ); if ( !bgSiegeClasses[bgNumSiegeClasses].classShader ) { //Com_Error( ERR_DROP, "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name ); Com_Printf( "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name ); } // A very hacky way to determine class . . . else #endif { // Find the base player class based on the icon name - very bad, I know. int titleLength, arrayTitleLength; char *holdBuf; titleLength = strlen(parseBuf); for (i=0;i<SPC_MAX;i++) { // Back up arrayTitleLength = strlen(classTitles[i]); if (arrayTitleLength>titleLength) // Too long { break; } holdBuf = parseBuf + ( titleLength - arrayTitleLength); if (!strcmp(holdBuf,classTitles[i])) { bgSiegeClasses[bgNumSiegeClasses].playerClass = i; break; } } // In case the icon name doesn't match up if (i>=SPC_MAX) { bgSiegeClasses[bgNumSiegeClasses].playerClass = SPC_INFANTRY; } } } else { //No entry! Bad bad bad //Com_Error( ERR_DROP, "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name ); Com_Printf( "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name ); } //Parse holdable items to use if (BG_SiegeGetPairedValue(classInfo, "holdables", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].invenItems = BG_SiegeTranslateGenericTable(parseBuf, HoldableTable, qtrue); } else { //Just don't start out with any then. bgSiegeClasses[bgNumSiegeClasses].invenItems = 0; } //Parse powerups to use if (BG_SiegeGetPairedValue(classInfo, "powerups", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].powerups = BG_SiegeTranslateGenericTable(parseBuf, PowerupTable, qtrue); } else { //Just don't start out with any then. bgSiegeClasses[bgNumSiegeClasses].powerups = 0; } //A successful read. bgNumSiegeClasses++; }
/* ===================== CL_CgameError ===================== */ void CL_CgameError( const char *string ) { Com_Error( ERR_DROP, "%s", string ); }
/* ============ Cvar_Get If the variable already exists, the value will not be set unless CVAR_ROM The flags will be or'ed in if the variable exists. ============ */ cvar_t *Cvar_Get( const char *var_name, const char *var_value, uint32_t flags ) { cvar_t *var; long hash; int index; if ( !var_name || ! var_value ) { Com_Error( ERR_FATAL, "Cvar_Get: NULL parameter" ); } if ( !Cvar_ValidateString( var_name ) ) { Com_Printf("invalid cvar name string: %s\n", var_name ); var_name = "BADNAME"; } #if 0 // FIXME: values with backslash happen if ( !Cvar_ValidateString( var_value ) ) { Com_Printf("invalid cvar value string: %s\n", var_value ); var_value = "BADVALUE"; } #endif var = Cvar_FindVar (var_name); if ( var ) { var_value = Cvar_Validate(var, var_value, qfalse); // Make sure the game code cannot mark engine-added variables as gamecode vars if(var->flags & CVAR_VM_CREATED) { if(!(flags & CVAR_VM_CREATED)) var->flags &= ~CVAR_VM_CREATED; } else if (!(var->flags & CVAR_USER_CREATED)) { if(flags & CVAR_VM_CREATED) flags &= ~CVAR_VM_CREATED; } // if the C code is now specifying a variable that the user already // set a value for, take the new value as the reset value if ( var->flags & CVAR_USER_CREATED ) { var->flags &= ~CVAR_USER_CREATED; Cvar_FreeString( var->resetString ); var->resetString = CopyString( var_value ); if(flags & CVAR_ROM) { // this variable was set by the user, // so force it to value given by the engine. if(var->latchedString) Cvar_FreeString(var->latchedString); var->latchedString = CopyString(var_value); } } // Make sure servers cannot mark engine-added variables as SERVER_CREATED if(var->flags & CVAR_SERVER_CREATED) { if(!(flags & CVAR_SERVER_CREATED)) var->flags &= ~CVAR_SERVER_CREATED; } else { if(flags & CVAR_SERVER_CREATED) flags &= ~CVAR_SERVER_CREATED; } var->flags |= flags; // only allow one non-empty reset string without a warning if ( !var->resetString[0] ) { // we don't have a reset string yet Cvar_FreeString( var->resetString ); var->resetString = CopyString( var_value ); } else if ( var_value[0] && strcmp( var->resetString, var_value ) ) { Com_DPrintf( S_COLOR_YELLOW "Warning: cvar \"%s\" given initial values: \"%s\" and \"%s\"\n", var_name, var->resetString, var_value ); } // if we have a latched string, take that value now if ( var->latchedString ) { char *s; s = var->latchedString; var->latchedString = NULL; // otherwise cvar_set2 would free it Cvar_Set2( var_name, s, 0, qtrue ); Cvar_FreeString( s ); } // ZOID--needs to be set so that cvars the game sets as // SERVERINFO get sent to clients cvar_modifiedFlags |= flags; return var; } // // allocate a new cvar // // find a free cvar for(index = 0; index < MAX_CVARS; index++) { if(!cvar_indexes[index].name) break; } if(index >= MAX_CVARS) { if(!com_errorEntered) Com_Error(ERR_FATAL, "Error: Too many cvars, cannot create a new one!"); return NULL; } var = &cvar_indexes[index]; if(index >= cvar_numIndexes) cvar_numIndexes = index + 1; var->name = CopyString (var_name); var->string = CopyString (var_value); var->modified = qtrue; var->modificationCount = 1; var->value = atof (var->string); var->integer = atoi(var->string); var->resetString = CopyString( var_value ); var->validate = qfalse; // link the variable in var->next = cvar_vars; if(cvar_vars) cvar_vars->prev = var; var->prev = NULL; cvar_vars = var; var->flags = flags; // note what types of cvars have been modified (userinfo, archive, serverinfo, systeminfo) cvar_modifiedFlags |= var->flags; hash = generateHashValue(var_name); var->hashIndex = hash; var->hashNext = hashTable[hash]; if(hashTable[hash]) hashTable[hash]->hashPrev = var; var->hashPrev = NULL; hashTable[hash] = var; return var; }
void CL_InitRef( void ) { refexport_t *ret; refimport_t rit; char dllName[MAX_OSPATH]; GetRefAPI_t GetRefAPI; Com_Printf( "----- Initializing Renderer ----\n" ); cl_renderer = Cvar_Get( "cl_renderer", DEFAULT_RENDER_LIBRARY, CVAR_ARCHIVE|CVAR_LATCH ); Com_sprintf( dllName, sizeof( dllName ), "%s_" ARCH_STRING DLL_EXT, cl_renderer->string ); #ifdef _WIN32 if( !(rendererLib = (void *)LoadLibrary( dllName )) && strcmp( cl_renderer->string, cl_renderer->resetString ) ) #else if( !(rendererLib = Sys_LoadDll( dllName, qfalse )) && strcmp( cl_renderer->string, cl_renderer->resetString ) ) #endif { Com_Printf( "failed: trying to load fallback renderer\n" ); Cvar_ForceReset( "cl_renderer" ); Com_sprintf( dllName, sizeof( dllName ), DEFAULT_RENDER_LIBRARY "_" ARCH_STRING DLL_EXT ); #ifdef _WIN32 rendererLib = (void *)LoadLibrary( dllName ); #else rendererLib = Sys_LoadDll( dllName, qfalse ); #endif } if ( !rendererLib ) { Com_Error( ERR_FATAL, "Failed to load renderer" ); } #ifdef _WIN32 GetRefAPI = (GetRefAPI_t)GetProcAddress( (HMODULE)rendererLib, "GetRefAPI" ); if ( !GetRefAPI ) Com_Error( ERR_FATAL, "CL_InitRef(): NULL GetRefAPI on handle for %s\n", dllName ); #else GetRefAPI = (GetRefAPI_t)Sys_LoadFunction( rendererLib, "GetRefAPI" ); if ( !GetRefAPI ) Com_Error( ERR_FATAL, "Can't load symbol GetRefAPI: '%s'", Sys_LibraryError() ); #endif #define RIT(y) rit.y = y RIT(CIN_PlayCinematic); RIT(CIN_RunCinematic); RIT(CIN_UploadCinematic); RIT(CL_IsRunningInGameCinematic); RIT(Cmd_AddCommand); RIT(Cmd_Argc); RIT(Cmd_ArgsBuffer); RIT(Cmd_Argv); RIT(Cmd_ExecuteString); RIT(Cmd_RemoveCommand); RIT(CM_ClusterPVS); RIT(CM_CullWorldBox); RIT(CM_DeleteCachedMap); RIT(CM_DrawDebugSurface); RIT(CM_PointContents); RIT(CM_RegisterTerrain); RIT(CM_ShutdownTerrain); RIT(CM_TerrainPatchIterate); RIT(Cvar_Get); RIT(Cvar_Set); RIT(Cvar_SetValue); RIT(Cvar_VariableIntegerValue); RIT(Cvar_VariableString); RIT(Cvar_VariableStringBuffer); RIT(Cvar_VariableValue); RIT(FS_FCloseFile); RIT(FS_FileIsInPAK); RIT(FS_FOpenFileByMode); RIT(FS_FOpenFileRead); RIT(FS_FOpenFileWrite); RIT(FS_FreeFile); RIT(FS_FreeFileList); RIT(FS_ListFiles); RIT(FS_Read); RIT(FS_ReadFile); RIT(FS_Write); RIT(FS_WriteFile); RIT(Hunk_ClearToMark); RIT(SG_Append); RIT(SND_RegisterAudio_LevelLoadEnd); RIT(SV_GetConfigstring); //RIT(SV_PointContents); RIT(SV_SetConfigstring); RIT(SV_Trace); RIT(S_RestartMusic); RIT(Z_Free); RIT(Z_Malloc); RIT(Z_MemSize); RIT(Z_MorphMallocTag); RIT(Hunk_ClearToMark); #ifndef _WIN32 RIT(IN_Init); RIT(IN_Shutdown); RIT(IN_Restart); #endif // Not-so-nice usage / doesn't go along with my epic macro rit.Error = Com_Error; rit.FS_FileExists = S_FileExists; rit.GetG2VertSpaceServer = GetG2VertSpaceServer; #ifdef _WIN32 rit.GetWinVars = GetWindowsVariables; #endif rit.LowPhysicalMemory = Sys_LowPhysicalMemory; rit.Milliseconds = Sys_Milliseconds; rit.Printf = CL_RefPrintf; rit.SE_GetString = String_GetStringValue; rit.CM_ShaderTableCleanup = ShaderTableCleanup; rit.SV_Trace = SV_Trace; rit.gpvCachedMapDiskImage = get_gpvCachedMapDiskImage; rit.gsCachedMapDiskImage = get_gsCachedMapDiskImage; rit.gbUsingCachedMapDataRightNow = get_gbUsingCachedMapDataRightNow; rit.gbAlreadyDoingLoad = get_gbAlreadyDoingLoad; rit.com_frameTime = get_com_frameTime; rit.SV_PointContents = SV_PointContents; ret = GetRefAPI( REF_API_VERSION, &rit ); if ( !ret ) { Com_Error (ERR_FATAL, "Couldn't initialize refresh" ); } re = *ret; Com_Printf( "-------------------------------\n"); // unpause so the cgame definately gets a snapshot and renders a frame Cvar_Set( "cl_paused", "0" ); }