/* ==================== Host_Init ==================== */ static void Host_Init (void) { int i; const char* os; char vabuf[1024]; if (COM_CheckParm("-profilegameonly")) Sys_AllowProfiling(false); // LordHavoc: quake never seeded the random number generator before... heh if (COM_CheckParm("-benchmark")) { Xrand_Init(1); srand(0); // predictable random sequence for -benchmark } else { Xrand_Init(0); srand((unsigned int)time(NULL)); } Cvar_InitTable(); // FIXME: this is evil, but possibly temporary // LordHavoc: doesn't seem very temporary... // LordHavoc: made this a saved cvar // COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers) if (COM_CheckParm("-developer")) { developer.value = developer.integer = 1; developer.string = "1"; } if (COM_CheckParm("-developer2") || COM_CheckParm("-developer3")) { developer.value = developer.integer = 1; developer.string = "1"; developer_extra.value = developer_extra.integer = 1; developer_extra.string = "1"; developer_insane.value = developer_insane.integer = 1; developer_insane.string = "1"; developer_memory.value = developer_memory.integer = 1; developer_memory.string = "1"; developer_memorydebug.value = developer_memorydebug.integer = 1; developer_memorydebug.string = "1"; } if (COM_CheckParm("-developer3")) { gl_paranoid.integer = 1;gl_paranoid.string = "1"; gl_printcheckerror.integer = 1;gl_printcheckerror.string = "1"; } // COMMANDLINEOPTION: Console: -nostdout disables text output to the terminal the game was launched from if (COM_CheckParm("-nostdout")) sys_nostdout = 1; // used by everything Memory_Init(); // initialize console command/cvar/alias/command execution systems Cmd_Init(); // initialize memory subsystem cvars/commands Memory_Init_Commands(); // initialize console and logging and its cvars/commands Con_Init(); // initialize various cvars that could not be initialized earlier u8_Init(); Curl_Init_Commands(); Cmd_Init_Commands(); Sys_Init_Commands(); COM_Init_Commands(); FS_Init_Commands(); // initialize console window (only used by sys_win.c) Sys_InitConsole(); // initialize the self-pack (must be before COM_InitGameType as it may add command line options) FS_Init_SelfPack(); // detect gamemode from commandline options or executable name COM_InitGameType(); // construct a version string for the corner of the console os = DP_OS_NAME; #ifdef VECXIS_RELEASE dpsnprintf (engineversion, sizeof (engineversion), "vdprm %s (Running %s) %s", os, gamename, buildstring); #else dpsnprintf (engineversion, sizeof (engineversion), "DarkPlacesRM %s (Running %s) %s", os, gamename, buildstring); #endif Con_Printf("%s\n", engineversion); // initialize process nice level Sys_InitProcessNice(); // initialize ixtable Mathlib_Init(); // initialize filesystem (including fs_basedir, fs_gamedir, -game, scr_screenshot_name) FS_Init(); // register the cvars for session locking Host_InitSession(); // must be after FS_Init Crypto_Init(); Crypto_Init_Commands(); NetConn_Init(); Curl_Init(); //PR_Init(); //PR_Cmd_Init(); PRVM_Init(); Mod_Init(); World_Init(); SV_Init(); V_Init(); // some cvars needed by server player physics (cl_rollangle etc) Host_InitCommands(); Host_InitLocal(); Host_ServerOptions(); IRC_Init(); Thread_Init(); if (cls.state == ca_dedicated) Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server (or disconnect all clients if running a server)"); else { Con_DPrintf("Initializing client\n"); R_Modules_Init(); Palette_Init(); #ifdef CONFIG_MENU MR_Init_Commands(); #endif VID_Shared_Init(); VID_Init(); Render_Init(); S_Init(); #ifdef CONFIG_CD CDAudio_Init(); #endif Key_Init(); CL_Init(); } // save off current state of aliases, commands and cvars for later restore if FS_GameDir_f is called // NOTE: menu commands are freed by Cmd_RestoreInitState Cmd_SaveInitState(); // FIXME: put this into some neat design, but the menu should be allowed to crash // without crashing the whole game, so this should just be a short-time solution // here comes the not so critical stuff if (setjmp(host_abortframe)) { return; } Host_AddConfigText(); Cbuf_Execute(); // if stuffcmds wasn't run, then quake.rc is probably missing, use default if (!host_stuffcmdsrun) { Cbuf_AddText("exec default.cfg\nexec " CONFIGFILENAME "\nexec autoexec.cfg\nstuffcmds\n"); Cbuf_Execute(); } // put up the loading image so the user doesn't stare at a black screen... SCR_BeginLoadingPlaque(true); #ifdef CONFIG_MENU if (cls.state != ca_dedicated) { MR_Init(); } #endif // check for special benchmark mode // COMMANDLINEOPTION: Client: -benchmark <demoname> runs a timedemo and quits, results of any timedemo can be found in gamedir/benchmark.log (for example id1/benchmark.log) i = COM_CheckParm("-benchmark"); if (i && i + 1 < com_argc) if (!sv.active && !cls.demoplayback && !cls.connect_trying) { Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", com_argv[i + 1])); Cbuf_Execute(); } // check for special demo mode // COMMANDLINEOPTION: Client: -demo <demoname> runs a playdemo and quits i = COM_CheckParm("-demo"); if (i && i + 1 < com_argc) if (!sv.active && !cls.demoplayback && !cls.connect_trying) { Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\n", com_argv[i + 1])); Cbuf_Execute(); } // COMMANDLINEOPTION: Client: -capturedemo <demoname> captures a playdemo and quits i = COM_CheckParm("-capturedemo"); if (i && i + 1 < com_argc) if (!sv.active && !cls.demoplayback && !cls.connect_trying) { Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1])); Cbuf_Execute(); } if (cls.state == ca_dedicated || COM_CheckParm("-listen")) if (!sv.active && !cls.demoplayback && !cls.connect_trying) { Cbuf_AddText("startmap_dm\n"); Cbuf_Execute(); } if (!sv.active && !cls.demoplayback && !cls.connect_trying) { #ifdef CONFIG_MENU Cbuf_AddText("togglemenu 1\n"); #endif Cbuf_Execute(); } Con_DPrint("========Initialized=========\n"); //Host_StartVideo(); if (cls.state != ca_dedicated) SV_StartThread(); }
void BGM_PlayMIDIorMusic (const char *filename) { /* instead of searching by the order of music_handlers, do so by * the order of searchpath priority: the file from the searchpath * with the highest path_id is most likely from our own gamedir * itself. this way, if a mod has egyp1 as a mp3 or a midi, which * is below *.ogg in the music_handler order, the mp3 or midi will * still have priority over egyp1.ogg from, say, data1. */ char tmp[MAX_QPATH]; const char *ext, *dir; unsigned int path_id, prev_id, type; qboolean try_midi_stream; music_handler_t *handler; if (music_handlers == NULL) return; BGM_Stop(); if (!filename || !*filename) { Con_DPrintf("null music file name\n"); return; } ext = COM_FileGetExtension(filename); if (*ext != '\0') { BGM_Play(filename); return; } prev_id = 0; type = 0; dir = ext = NULL; handler = music_handlers; try_midi_stream = false; while (handler) { if (! handler->is_available) goto _next; if (! MIDITYPE(handler->type) && (no_extmusic || !bgm_extmusic.value)) goto _next; q_snprintf(tmp, sizeof(tmp), "%s/%s.%s", handler->dir, filename, handler->ext); if (! FS_FileExists(tmp, &path_id)) { if (handler->type == MIDIDRIVER_MID) break; goto _next; } if (path_id > prev_id) { prev_id = path_id; type = handler->type; ext = handler->ext; dir = handler->dir; if (handler->type == MIDIDRIVER_MID) { if (handler->next && handler->next->is_available) try_midi_stream = true; break; } } _next: handler = handler->next; } if (ext == NULL) Con_Printf("Couldn't handle music file %s\n", filename); else { q_snprintf(tmp, sizeof(tmp), "%s/%s.%s", dir, filename, ext); switch (type) { case MIDIDRIVER_MID: if (BGM_Play_mididrv(tmp) == 0) return; /* success */ /* BGM_MIDIDRV is followed by CODECTYPE_MID streamer. * Even if the midi driver failed, we may still have * a chance with the streamer if it's available... */ if (!try_midi_stream) break; type = CODECTYPE_MID; default: bgmstream = S_CodecOpenStreamType(tmp, type); if (bgmstream) return; /* success */ } Con_Printf("Couldn't handle music file %s\n", tmp); } }
/* ================ R_RecursiveClipBPoly ================ */ static void R_RecursiveClipBPoly(const entity_t *e, bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) { bedge_t *psideedges[2], *pnextedge, *ptedge; int i, side, lastside; float dist, frac, lastdist; mplane_t *splitplane, tplane; mvertex_t *pvert, *plastvert, *ptvert; mnode_t *pn; psideedges[0] = psideedges[1] = NULL; makeclippededge = false; // transform the BSP plane into model space // FIXME: cache these? splitplane = pnode->plane; tplane.dist = splitplane->dist - DotProduct(r_entorigin, splitplane->normal); tplane.normal[0] = DotProduct(entity_rotation[0], splitplane->normal); tplane.normal[1] = DotProduct(entity_rotation[1], splitplane->normal); tplane.normal[2] = DotProduct(entity_rotation[2], splitplane->normal); // clip edges to BSP plane for (; pedges; pedges = pnextedge) { pnextedge = pedges->pnext; // set the status for the last point as the previous point // FIXME: cache this stuff somehow? plastvert = pedges->v[0]; lastdist = DotProduct(plastvert->position, tplane.normal) - tplane.dist; if (lastdist > 0) lastside = 0; else lastside = 1; pvert = pedges->v[1]; dist = DotProduct(pvert->position, tplane.normal) - tplane.dist; if (dist > 0) side = 0; else side = 1; if (side != lastside) { // clipped if (numbverts >= MAX_BMODEL_VERTS) return; // generate the clipped vertex frac = lastdist / (lastdist - dist); ptvert = &pbverts[numbverts++]; ptvert->position[0] = plastvert->position[0] + frac * (pvert->position[0] - plastvert->position[0]); ptvert->position[1] = plastvert->position[1] + frac * (pvert->position[1] - plastvert->position[1]); ptvert->position[2] = plastvert->position[2] + frac * (pvert->position[2] - plastvert->position[2]); // split into two edges, one on each side, and remember entering // and exiting points // FIXME: share the clip edge by having a winding direction flag? if (numbedges > MAX_BMODEL_EDGES - 2) { Con_Printf("Out of edges for bmodel\n"); return; } ptedge = &pbedges[numbedges]; ptedge->pnext = psideedges[lastside]; psideedges[lastside] = ptedge; ptedge->v[0] = plastvert; ptedge->v[1] = ptvert; ptedge = &pbedges[numbedges + 1]; ptedge->pnext = psideedges[side]; psideedges[side] = ptedge; ptedge->v[0] = ptvert; ptedge->v[1] = pvert; numbedges += 2; if (side == 0) { // entering for front, exiting for back pfrontenter = ptvert; makeclippededge = true; } else { pfrontexit = ptvert; makeclippededge = true; } } else { // add the edge to the appropriate side pedges->pnext = psideedges[side]; psideedges[side] = pedges; } } // if anything was clipped, reconstitute and add the edges along the clip // plane to both sides (but in opposite directions) if (makeclippededge) { if (numbedges > MAX_BMODEL_EDGES - 2) { Con_Printf("Out of edges for bmodel\n"); return; } ptedge = &pbedges[numbedges]; ptedge->pnext = psideedges[0]; psideedges[0] = ptedge; ptedge->v[0] = pfrontexit; ptedge->v[1] = pfrontenter; ptedge = &pbedges[numbedges + 1]; ptedge->pnext = psideedges[1]; psideedges[1] = ptedge; ptedge->v[0] = pfrontenter; ptedge->v[1] = pfrontexit; numbedges += 2; } /* draw or recurse further */ for (i = 0; i < 2; i++) { if (psideedges[i]) { /* * draw if we've reached a non-solid leaf, done if all that's left * is a solid leaf, and continue down the tree if it's not a leaf */ pn = pnode->children[i]; // we're done with this branch if the node or leaf isn't in the PVS if (pn->visframe == r_visframecount) { if (pn->contents < 0) { if (pn->contents != CONTENTS_SOLID) { r_currentbkey = ((mleaf_t *)pn)->key; R_RenderBmodelFace(e, psideedges[i], psurf); } } else { R_RecursiveClipBPoly(e, psideedges[i], pn, psurf); } } } } }
int TTY_Connect(int handle, char *host) { double start; ComPort *p; char *response = NULL; keydest_t save_key_dest; char dialstring[64]; byte b; p = handleToPort[handle]; if ((p->modemStatus & MODEM_STATUS_MASK) != MODEM_STATUS_MASK) { Con_Printf ("Serial: line not ready ("); if ((p->modemStatus & MSR_CTS) == 0) Con_Printf(" CTS"); if ((p->modemStatus & MSR_DSR) == 0) Con_Printf(" DSR"); if ((p->modemStatus & MSR_CD) == 0) Con_Printf(" CD"); Con_Printf(" )"); return -1; } // discard any scraps in the input buffer while (! EMPTY (p->inputQueue)) DEQUEUE (p->inputQueue, b); CheckStatus (p); if (p->useModem) { save_key_dest = key_dest; key_dest = key_console; key_count = -2; Con_Printf ("Dialing...\n"); sprintf(dialstring, "AT D%c %s\r", p->dialType, host); Modem_Command (p, dialstring); start = Sys_FloatTime(); while(1) { if ((Sys_FloatTime() - start) > 60.0) { Con_Printf("Dialing failure!\n"); break; } Sys_SendKeyEvents (); if (key_count == 0) { if (key_lastpress != K_ESCAPE) { key_count = -2; continue; } Con_Printf("Aborting...\n"); while ((Sys_FloatTime() - start) < 5.0) ; disable(); p->outputQueue.head = p->outputQueue.tail = 0; p->inputQueue.head = p->inputQueue.tail = 0; outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) & ~MCR_DTR); enable(); start = Sys_FloatTime(); while ((Sys_FloatTime() - start) < 0.75) ; outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) | MCR_DTR); response = "Aborted"; break; } response = Modem_Response(p); if (!response) continue; if (Q_strncmp(response, "CONNECT", 7) == 0) { disable(); p->modemRang = true; p->modemConnected = true; p->outputQueue.head = p->outputQueue.tail = 0; p->inputQueue.head = p->inputQueue.tail = 0; enable(); key_dest = save_key_dest; key_count = 0; m_return_onerror = false; return 0; } if (Q_strncmp(response, "NO CARRIER", 10) == 0) break; if (Q_strncmp(response, "NO DIALTONE", 11) == 0) break; if (Q_strncmp(response, "NO DIAL TONE", 12) == 0) break; if (Q_strncmp(response, "NO ANSWER", 9) == 0) break; if (Q_strncmp(response, "BUSY", 4) == 0) break; if (Q_strncmp(response, "ERROR", 5) == 0) break; } key_dest = save_key_dest; key_count = 0; if (m_return_onerror) { key_dest = key_menu; m_state = m_return_state; m_return_onerror = false; Q_strncpy(m_return_reason, response, 31); } return -1; } m_return_onerror = false; return 0; }
void R_SplitEntityOnNode (mnode_t *node) { efrag_t *ef; mplane_t *splitplane; mleaf_t *leaf; int sides; if(node->contents == BSP_CONTENTS_SOLID) return; // add an efrag if the node is a leaf if ( node->contents < 0) { if (!r_pefragtopnode) r_pefragtopnode = node; leaf = (mleaf_t *)node; // grab an efrag off the free list ef = cl.free_efrags; if (!ef) { //johnfitz -- less spammy overflow message if (!dev_overflows.efrags || dev_overflows.efrags + CONSOLE_RESPAM_TIME < realtime ) { Con_Printf ("Too many efrags!\n"); dev_overflows.efrags = realtime; } //johnfitz return; // no free fragments... } cl.free_efrags = cl.free_efrags->entnext; ef->entity = r_addent; // add the entity link *lastlink = ef; lastlink = &ef->entnext; ef->entnext = NULL; // set the leaf links ef->leaf = leaf; ef->leafnext = leaf->efrags; leaf->efrags = ef; return; } // NODE_MIXED splitplane = node->plane; sides = World_BoxOnPlaneSide(r_emins, r_emaxs, splitplane); if (sides == 3) { // split on this plane // if this is the first splitter of this bmodel, remember it if (!r_pefragtopnode) r_pefragtopnode = node; } // recurse down the contacted sides if (sides & 1) R_SplitEntityOnNode (node->children[0]); if (sides & 2) R_SplitEntityOnNode (node->children[1]); }
//============================================================================= // Get regular UltraSound configuration if any //============================================================================= static qboolean GUS_GetGUSData(void) { char *Ultrasnd; int GusBase,Dma1,Dma2,Irq1,Irq2,i; Ultrasnd=getenv("ULTRASND"); if (Ultrasnd==NULL) return(false); sscanf(Ultrasnd,"%x,%i,%i,%i,%i",&GusBase,&Dma1,&Dma2,&Irq1,&Irq2); DmaChannel=Dma1 & 0x07; // Make sure there is a GUS at GUS base dos_outportb(GusBase+0x08,0x55); if (dos_inportb(GusBase+0x0A)!=0x55) return(false); dos_outportb(GusBase+0x08,0xAA); if (dos_inportb(GusBase+0x0A)!=0xAA) return(false); Gf1TimerControl = GusBase+0x008; Gf1PageRegister = GusBase+0x102; Gf1RegisterSelect = GusBase+0x103; Gf1DataLow = GusBase+0x104; Gf1DataHigh = GusBase+0x105; // Reset the GUS SetGf18(MASTER_RESET,0x00); Gf1Delay(); Gf1Delay(); SetGf18(MASTER_RESET,0x01); Gf1Delay(); Gf1Delay(); // Set to max (32) voices SetGf18(SET_VOICES,0xDF); // Clear any pending IRQ's ClearGf1Ints(); // Set all registers to known values for (i=0;i<32;i++) { dos_outportb(Gf1PageRegister,i); SetGf18(SET_CONTROL,0x03); SetGf18(SET_VOLUME_CONTROL,0x03); Gf1Delay(); SetGf18(SET_CONTROL,0x03); SetGf18(SET_VOLUME_CONTROL,0x03); SetGf116(SET_START_HIGH,0); SetGf116(SET_START_LOW,0); SetGf116(SET_END_HIGH,0); SetGf116(SET_END_LOW,0); SetGf116(SET_ACC_HIGH,0); SetGf116(SET_ACC_LOW,0); SetGf18(SET_VOLUME_RATE,63); SetGf18(SET_VOLUME_START,5); SetGf18(SET_VOLUME_END,251); SetGf116(SET_VOLUME,5<<8); } // Clear any pending IRQ's ClearGf1Ints(); // Enable DAC etc. SetGf18(MASTER_RESET,0x07); // Enable line output so we can hear something dos_outportb(GusBase,0x08); HaveCodec=0; Con_Printf("Sound Card is UltraSound\n"); return(true); }
static void ComPort_Enable(ComPort *p) { void (*isr)(void); int n; byte b; if (p->enabled) { Con_Printf("Already enabled\n"); return; } // disable all UART interrupts outportb (p->uart + INTERRUPT_ENABLE_REGISTER, 0); // clear out any buffered uncoming data while((inportb (p->uart + LINE_STATUS_REGISTER)) & LSR_DATA_READY) inportb (p->uart + RECEIVE_BUFFER_REGISTER); // get the current line and modem status p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER); // clear any UART interrupts do { n = inportb (p->uart + INTERRUPT_ID_REGISTER) & 7; if (n == IIR_RX_DATA_READY_INTERRUPT) inportb (p->uart + RECEIVE_BUFFER_REGISTER); } while (!(n & 1)); if (p->uartType == UART_AUTO) { outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE); b = inportb (p->uart + INTERRUPT_ID_REGISTER); if ((b & IIR_FIFO_ENABLED) == IIR_FIFO_ENABLED) p->uartType = UART_16550; else p->uartType = UART_8250; } // save the old interrupt handler _go32_dpmi_get_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeSaveInfo); if (p->uartType == UART_8250) { outportb (p->uart + FIFO_CONTROL_REGISTER, 0); if (p == handleToPort[0]) isr = COM1_ISR_8250; else isr = COM2_ISR_8250; } else { outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE | FCR_RCVR_FIFO_RESET | FCR_XMIT_FIFO_RESET | FCR_TRIGGER_08); if (p == handleToPort[0]) isr = COM1_ISR_16550; else isr = COM2_ISR_16550; } p->protectedModeInfo.pm_offset = (int)isr; n = _go32_dpmi_allocate_iret_wrapper(&p->protectedModeInfo); if (n) { Con_Printf("serial: protected mode callback allocation failed\n"); return; } // disable interrupts at the processor disable(); // install our interrupt handlers now _go32_dpmi_set_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeInfo); // enable our interrupt at the PIC outportb (0x21, inportb (0x21) & ~(1<<p->irq)); // enable interrupts at the processor enable(); // enable interrupts at the PIC outportb (0x20, 0xc2); // set baud rate & line control outportb (p->uart + LINE_CONTROL_REGISTER, LCR_DLAB | p->lineControl); outportb (p->uart, p->baudBits); outportb (p->uart + 1, 0); outportb (p->uart + LINE_CONTROL_REGISTER, p->lineControl); // set modem control register & enable uart interrupt generation outportb(p->uart + MODEM_CONTROL_REGISTER, MCR_OUT2 | MCR_RTS | MCR_DTR); // enable the individual interrupts at the uart outportb (p->uart + INTERRUPT_ENABLE_REGISTER, IER_RX_DATA_READY | IER_TX_HOLDING_REGISTER_EMPTY | IER_LINE_STATUS | IER_MODEM_STATUS); p->enabled = true; }
void R_Shader_Init(void) { //RenderState_ShaderPermutation *s; char *vertstring, *fragstring; //unsigned int vertstrings_count, fragstrings_count; //const char *vertstrings_list[R_SHADERPERMUTATION_LIMIT]; //const char *fragstrings_list[R_SHADERPERMUTATION_LIMIT]; // set up the lighting shaders memset(&r_refdef.lightShader, 0, sizeof(r_refdef.lightShader)); // if (!R.ext.ARB_fragment_shader) if (!gl_support_GLSL_shaders) return; // vertstring = File_LoadFile("shaders/light.vert", NULL); // fragstring = File_LoadFile("shaders/light.frag", NULL); #define VERTEX_SHADER_FILENAME "shaders/standard.vert" #define FRAGMENT_SHADER_FILENAME "shaders/standard.frag" vertstring = COM_LoadMallocFile( VERTEX_SHADER_FILENAME ); fragstring = COM_LoadMallocFile( FRAGMENT_SHADER_FILENAME ); if (!vertstring || !fragstring) r_refdef.lightShader.programObject = R_CompileGLSLProgram (1, &builtinvertshader, 1, &builtinfragshader); else r_refdef.lightShader.programObject = R_CompileGLSLProgram( 1, &vertstring, 1, &fragstring ); if( r_refdef.lightShader.programObject == 0 ) { Con_Printf( "Couldn't load light shaders '" VERTEX_SHADER_FILENAME "' and '" FRAGMENT_SHADER_FILENAME "'!\n" ); } // free the source strings if (fragstring) Z_Free( fragstring ); if (vertstring) Z_Free( vertstring ); // determine the uniform locations #define UNIFORM( name ) r_refdef.lightShader.##name = qglGetUniformLocationARB( r_refdef.lightShader.programObject, #name ); UNIFORM( lightPosition ); //UNIFORM( eyePosition ); UNIFORM( viewToLightMatrix ); UNIFORM( diffuseSampler ); //UNIFORM( normalSampler ); //UNIFORM( specularSampler ); UNIFORM( lightColor ); UNIFORM( lightMaxDistance ); /* Black: According to the specs, these two caps don't exist so comment them out for a beginning. */ /* // ? glEnable(GL_FRAGMENT_SHADER_ARB); glEnable(GL_VERTEX_SHADER_ARB); */ /* for (i = 0, s = r_refdef.shader_standard;i < R_LIGHTSHADERPERMUTATION_LIMIT;i++, s++) { // build the source list for this shader permutation vertstrings_count = 0; fragstrings_count = 0; if (i & R_LIGHTSHADERPERMUTATION_SPECULAR) { vertstrings_list[vertstrings_count++] = "#define USESPECULAR\n"; fragstrings_list[fragstrings_count++] = "#define USESPECULAR\n"; } if (i & R_LIGHTSHADERPERMUTATION_FOG) { vertstrings_list[vertstrings_count++] = "#define USEFOG\n"; fragstrings_list[fragstrings_count++] = "#define USEFOG\n"; } if (i & R_LIGHTSHADERPERMUTATION_CUBEFILTER) { vertstrings_list[vertstrings_count++] = "#define USECUBEFILTER\n"; fragstrings_list[fragstrings_count++] = "#define USECUBEFILTER\n"; } if (i & R_LIGHTSHADERPERMUTATION_OFFSETMAPPING) { vertstrings_list[vertstrings_count++] = "#define USEOFFSETMAPPING\n"; fragstrings_list[fragstrings_count++] = "#define USEOFFSETMAPPING\n"; } vertstrings_list[vertstrings_count++] = vertstring; fragstrings_list[fragstrings_count++] = fragstring; // vertstrings_list[vertstrings_count++] = vertstring ? vertstring : builtinshader_standard_vert; // fragstrings_list[fragstrings_count++] = fragstring ? fragstring : builtinshader_standard_frag; // compile this shader permutation s->programmObject = R_CompileGLSL(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list); if (!s->programmObject) { // Console_Printf("permutation %s %s %s %s failed for lighting shader (glsl/light.frag and .vert), some features may not work properly!\n", i & 1 ? "specular" : "", i & 1 ? "fog" : "", i & 1 ? "cubefilter" : "", i & 1 ? "offsetmapping" : ""); Con_Printf("permutation %s %s %s %s failed for lighting shader (shaders/standard.frag and .vert), some features may not work properly!\n", i & 1 ? "specular" : "", i & 1 ? "fog" : "", i & 1 ? "cubefilter" : "", i & 1 ? "offsetmapping" : ""); continue; } // R_CheckError(); // switch to the new program object qglUseProgramObjectARB(s->programmObject); // fetch all the uniform locations s->loc_LightPosition = qglGetUniformLocationARB(s->programmObject, "LightPosition"); s->loc_EyePosition = qglGetUniformLocationARB(s->programmObject, "EyePosition"); s->loc_LightColor = qglGetUniformLocationARB(s->programmObject, "LightColor"); s->loc_OffsetMapping_Scale = qglGetUniformLocationARB(s->programmObject, "OffsetMapping_Scale"); s->loc_OffsetMapping_Bias = qglGetUniformLocationARB(s->programmObject, "OffsetMapping_Bias"); s->loc_SpecularPower = qglGetUniformLocationARB(s->programmObject, "SpecularPower"); s->loc_FogRangeRecip = qglGetUniformLocationARB(s->programmObject, "FogRangeRecip"); s->loc_AmbientScale = qglGetUniformLocationARB(s->programmObject, "AmbientScale"); s->loc_DiffuseScale = qglGetUniformLocationARB(s->programmObject, "DiffuseScale"); s->loc_SpecularScale = qglGetUniformLocationARB(s->programmObject, "SpecularScale"); s->loc_Texture_Normal = qglGetUniformLocationARB(s->programmObject, "Texture_Normal"); s->loc_Texture_Color = qglGetUniformLocationARB(s->programmObject, "Texture_Color"); s->loc_Texture_Gloss = qglGetUniformLocationARB(s->programmObject, "Texture_Gloss"); s->loc_Texture_Cube = qglGetUniformLocationARB(s->programmObject, "Texture_Cube"); s->loc_Texture_FogMask = qglGetUniformLocationARB(s->programmObject, "Texture_FogMask"); // set static uniforms if (s->loc_Texture_Normal) qglUniform1iARB(s->loc_Texture_Normal, 0); if (s->loc_Texture_Color) qglUniform1iARB(s->loc_Texture_Color, 1); if (s->loc_Texture_Gloss) qglUniform1iARB(s->loc_Texture_Gloss, 2); if (s->loc_Texture_Cube) qglUniform1iARB(s->loc_Texture_Cube, 3); if (s->loc_Texture_FogMask) qglUniform1iARB(s->loc_Texture_FogMask, 4); // R_CheckError(); } // free the source strings if (fragstring) // Mem_Free(&fragstring); free(&fragstring); if (vertstring) // Mem_Free(&vertstring); free(&vertstring); // switch back to fixed function program qglUseProgramObjectARB( 0 ); */ }
/* ======== LoadPCX ======== */ byte* LoadPCX (vfsfile_t *f) { pcx_t *pcx, pcxbuf; byte palette[768]; byte *pix, *image_rgba; int x, y; int dataByte, runLength; int count; // // parse the PCX file // VFS_READ (f, &pcxbuf, sizeof(pcxbuf)); pcx = &pcxbuf; if (pcx->manufacturer != 0x0a || pcx->version != 5 || pcx->encoding != 1 || pcx->bits_per_pixel != 8 || pcx->xmax > 320 || pcx->ymax > 256) { Con_Printf ("Bad pcx file\n"); VFS_CLOSE(f); return NULL; } // seek to palette VFS_SEEK(f, VFS_GETLEN(f)-768); VFS_READ(f, palette, 768); VFS_SEEK(f, sizeof(pcxbuf) - 4); count = (pcx->xmax+1) * (pcx->ymax+1); image_rgba = malloc( count * 4); for (y=0 ; y<=pcx->ymax ; y++) { pix = image_rgba + 4*y*(pcx->xmax+1); for (x=0 ; x<=pcx->xmax ; ) { dataByte = VFS_GETC(f); if((dataByte & 0xC0) == 0xC0) { runLength = dataByte & 0x3F; dataByte = VFS_GETC(f); } else runLength = 1; while(runLength-- > 0) { pix[0] = palette[dataByte*3]; pix[1] = palette[dataByte*3+1]; pix[2] = palette[dataByte*3+2]; pix[3] = 255; pix += 4; x++; } } } VFS_CLOSE(f); image_width = pcx->xmax+1; image_height = pcx->ymax+1; return image_rgba; }
/* ============= ED_ParseEval Can parse either fields or globals returns false if error ============= */ static qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s) { int i; char string[128]; ddef_t *def; char *v, *w; void *d; dfunction_t *func; d = (void *)((int *)base + key->ofs); switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: *(string_t *)d = ED_NewString(s); break; case ev_float: *(float *)d = atof (s); break; case ev_vector: strcpy (string, s); v = string; w = string; for (i = 0; i < 3; i++) { while (*v && *v != ' ') v++; *v = 0; ((float *)d)[i] = atof (w); w = v = v+1; } break; case ev_entity: *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s))); break; case ev_field: def = ED_FindField (s); if (!def) { //johnfitz -- HACK -- suppress error becuase fog/sky fields might not be mentioned in defs.qc if (strncmp(s, "sky", 3) && strcmp(s, "fog")) Con_DPrintf ("Can't find field %s\n", s); return false; } *(int *)d = G_INT(def->ofs); break; case ev_function: func = ED_FindFunction (s); if (!func) { Con_Printf ("Can't find function %s\n", s); return false; } *(func_t *)d = func - pr_functions; break; default: break; } return true; }
// From DP, edited by Entar int R_LoadWorldLights(void) { int n, a, style, shadow, flags; char tempchar, *lightsstring, *s, *t, name[MAX_QPATH], cubemapname[MAX_QPATH]; float origin[3], radius, color[3], angles[3], corona, coronasizescale, ambientscale, diffusescale, specularscale; R_ShaderLight_Definition light; shaderlight = R_DROPLIGHT_MAX_LIGHTS; if (cl.worldmodel == NULL) { Con_Print("No map loaded.\n"); return false; } COM_StripExtension (cl.worldmodel->name, name); strlcat (name, ".rtlights", sizeof (name)); // lightsstring = (char *)FS_LoadFile(name, tempmempool, false, NULL); lightsstring = (char *)COM_LoadTempFile(name); if (lightsstring) { s = lightsstring; n = 0; while (*s) { t = s; /* shadow = true; for (;COM_Parse(t, true) && strcmp( if (COM_Parse(t, true)) { if (com_token[0] == '!') { shadow = false; origin[0] = atof(com_token+1); } else origin[0] = atof(com_token); if (Com_Parse(t } */ t = s; while (*s && *s != '\n' && *s != '\r') s++; if (!*s) break; tempchar = *s; shadow = true; // check for modifier flags if (*t == '!') { shadow = false; t++; } *s = 0; a = sscanf(t, "%f %f %f %f %f %f %f %d %s %f %f %f %f %f %f %f %f %i", &origin[0], &origin[1], &origin[2], &radius, &color[0], &color[1], &color[2], &style, cubemapname, &corona, &angles[0], &angles[1], &angles[2], &coronasizescale, &ambientscale, &diffusescale, &specularscale, &flags); *s = tempchar; // if (a < 18) // flags = LIGHTFLAG_REALTIMEMODE; if (a < 17) specularscale = 1; if (a < 16) diffusescale = 1; if (a < 15) ambientscale = 0; if (a < 14) coronasizescale = 0.25f; if (a < 13) VectorClear(angles); if (a < 10) corona = 0; if (a < 9 || !strcmp(cubemapname, "\"\"")) cubemapname[0] = 0; // remove quotes on cubemapname if (cubemapname[0] == '"' && cubemapname[strlen(cubemapname) - 1] == '"') { size_t namelen; namelen = strlen(cubemapname) - 2; memmove(cubemapname, cubemapname + 1, namelen); cubemapname[namelen] = '\0'; } if (a < 8) { Con_Printf("found %d parameters on line %i, should be 8 or more parameters (origin[0] origin[1] origin[2] radius color[0] color[1] color[2] style \"cubemapname\" corona angles[0] angles[1] angles[2] coronasizescale ambientscale diffusescale specularscale flags)\n", a, n + 1); break; } // check if we've hit our limit if (shaderlight < R_MIN_SHADER_DLIGHTS) { // R_Shadow_UpdateWorldLight(R_Shadow_NewWorldLight(), origin, angles, color, radius, corona, style, shadow, cubemapname, coronasizescale, ambientscale, diffusescale, specularscale, flags); VectorCopy (color, light.color); light.maxDistance = radius; VectorCopy(origin, light.origin); VectorCopy(angles, light.angles); light.corona = corona; light.style = style; light.shadow = shadow; sprintf (light.cubemapname, cubemapname); light.coronasizescale = coronasizescale; light.ambientscale = ambientscale; light.diffusescale = diffusescale; light.specularscale = specularscale; light.flags = flags; R_Shader_SetLight( shaderlight, &light ); shaderlight++; } if (*s == '\r') s++; if (*s == '\n') s++; n++; } if (*s) Con_Printf("invalid rtlights file \"%s\"\n", name); // free(lightsstring); return true; } return false; }
int WIPX_Init ( void ) { int i; char buff[MAXHOSTNAMELEN]; struct qsockaddr addr; char *p; int r; WORD wVersionRequested; if (COM_CheckParm ("-noipx")) return -1; // make sure LoadLibrary has happened successfully if (!winsock_lib_initialized) return -1; if (winsock_initialized == 0) { wVersionRequested = MAKEWORD(1, 1); r = pWSAStartup (MAKEWORD(1, 1), &winsockdata); if (r) { Con_Printf ("Winsock initialization failed.\n"); return -1; } } winsock_initialized++; for (i = 0; i < IPXSOCKETS; i++) ipxsocket[i] = 0; // determine my name & address if (pgethostname(buff, MAXHOSTNAMELEN) == 0) { // if the quake hostname isn't set, set it to the machine name if (Q_strcmp(hostname->string, "UNNAMED") == 0) { // see if it's a text IP address (well, close enough) for (p = buff; *p; p++) if ((*p < '0' || *p > '9') && *p != '.') break; // if it is a real name, strip off the domain; we only want the host if (*p) { for (i = 0; i < 15; i++) if (buff[i] == '.') break; buff[i] = 0; } Cvar_Set (hostname, buff); } } if ((net_controlsocket = WIPX_OpenSocket (0)) == -1) { Con_Printf("WIPX_Init: Unable to open control socket\n"); if (--winsock_initialized == 0) pWSACleanup (); return -1; } ((struct sockaddr_ipx *)&broadcastaddr)->sa_family = AF_IPX; memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_netnum, 0, 4); memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_nodenum, 0xff, 6); ((struct sockaddr_ipx *)&broadcastaddr)->sa_socket = htons((unsigned short)net_hostport); WIPX_GetSocketAddr (net_controlsocket, &addr); Q_strcpy(my_ipx_address, WIPX_AddrToString (&addr)); p = Q_strrchr (my_ipx_address, ':'); if (p) *p = 0; Con_Printf("Winsock IPX Initialized\n"); ipxAvailable = true; return net_controlsocket; }
void Host_Main(void) { double time1 = 0; double time2 = 0; double time3 = 0; double cl_timer = 0, sv_timer = 0; double clframetime, deltacleantime, olddirtytime, dirtytime; double wait; int pass1, pass2, pass3, i; char vabuf[1024]; qboolean playing; Host_Init(); realtime = 0; host_dirtytime = Sys_DirtyTime(); for (;;) { if (setjmp(host_abortframe)) { SCR_ClearLoadingScreen(false); continue; // something bad happened, or the server disconnected } olddirtytime = host_dirtytime; dirtytime = Sys_DirtyTime(); deltacleantime = dirtytime - olddirtytime; if (deltacleantime < 0) { // warn if it's significant if (deltacleantime < -0.01) Con_Printf("Host_Mingled: time stepped backwards (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime); deltacleantime = 0; } else if (deltacleantime >= 1800) { Con_Printf("Host_Mingled: time stepped forward (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime); deltacleantime = 0; } realtime += deltacleantime; host_dirtytime = dirtytime; cl_timer += deltacleantime; sv_timer += deltacleantime; if (!svs.threaded) { svs.perf_acc_realtime += deltacleantime; // Look for clients who have spawned playing = false; for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++) if(host_client->begun) if(host_client->netconnection) playing = true; if(sv.time < 10) { // don't accumulate time for the first 10 seconds of a match // so things can settle svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0; } else if(svs.perf_acc_realtime > 5) { svs.perf_cpuload = 1 - svs.perf_acc_sleeptime / svs.perf_acc_realtime; svs.perf_lost = svs.perf_acc_lost / svs.perf_acc_realtime; if(svs.perf_acc_offset_samples > 0) { svs.perf_offset_max = svs.perf_acc_offset_max; svs.perf_offset_avg = svs.perf_acc_offset / svs.perf_acc_offset_samples; svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg); } if(svs.perf_lost > 0 && developer_extra.integer) if(playing) // only complain if anyone is looking Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf))); svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0; } } if (slowmo.value < 0.00001 && slowmo.value != 0) Cvar_SetValue("slowmo", 0); if (host_framerate.value < 0.00001 && host_framerate.value != 0) Cvar_SetValue("host_framerate", 0); // keep the random time dependent, but not when playing demos/benchmarking if(!*sv_random_seed.string && !cls.demoplayback) { xrand(); rand(); } // get new key events Key_EventQueue_Unblock(); SndSys_SendKeyEvents(); Sys_SendKeyEvents(); NetConn_UpdateSockets(); Log_DestBuffer_Flush(); // receive packets on each main loop iteration, as the main loop may // be undersleeping due to select() detecting a new packet if (sv.active && !svs.threaded) NetConn_ServerFrame(); Curl_Run(); // check for commands typed to the host Host_GetConsoleCommands(); // when a server is running we only execute console commands on server frames // (this mainly allows frikbot .way config files to work properly by staying in sync with the server qc) // otherwise we execute them on client frames if (sv.active ? sv_timer > 0 : cl_timer > 0) { // process console commands // R_TimeReport("preconsole"); CL_VM_PreventInformationLeaks(); Cbuf_Frame(); // R_TimeReport("console"); } //Con_Printf("%6.0f %6.0f\n", cl_timer * 1000000.0, sv_timer * 1000000.0); // if the accumulators haven't become positive yet, wait a while if (cls.state == ca_dedicated) wait = sv_timer * -1000000.0; else if (!sv.active || svs.threaded) wait = cl_timer * -1000000.0; else wait = max(cl_timer, sv_timer) * -1000000.0; if (!cls.timedemo && wait >= 1) { double time0, delta; if(host_maxwait.value <= 0) wait = min(wait, 1000000.0); else wait = min(wait, host_maxwait.value * 1000.0); if(wait < 1) wait = 1; // because we cast to int time0 = Sys_DirtyTime(); if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) { NetConn_SleepMicroseconds((int)wait); if (cls.state != ca_dedicated) NetConn_ClientFrame(); // helps server browser get good ping values // TODO can we do the same for ServerFrame? Probably not. } else Sys_Sleep((int)wait); delta = Sys_DirtyTime() - time0; if (delta < 0 || delta >= 1800) delta = 0; if (!svs.threaded) svs.perf_acc_sleeptime += delta; // R_TimeReport("sleep"); continue; } // limit the frametime steps to no more than 100ms each if (cl_timer > 0.1) cl_timer = 0.1; if (sv_timer > 0.1) { if (!svs.threaded) svs.perf_acc_lost += (sv_timer - 0.1); sv_timer = 0.1; } R_TimeReport("---"); //------------------- // // server operations // //------------------- // limit the frametime steps to no more than 100ms each if (sv.active && sv_timer > 0 && !svs.threaded) { // execute one or more server frames, with an upper limit on how much // execution time to spend on server frames to avoid freezing the game if // the server is overloaded, this execution time limit means the game will // slow down if the server is taking too long. int framecount, framelimit = 1; double advancetime, aborttime = 0; float offset; prvm_prog_t *prog = SVVM_prog; // run the world state // don't allow simulation to run too fast or too slow or logic glitches can occur // stop running server frames if the wall time reaches this value if (sys_ticrate.value <= 0) advancetime = sv_timer; else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer) { // synchronize to the client frametime, but no less than 10ms and no more than 100ms advancetime = bound(0.01, cl_timer, 0.1); } else { advancetime = sys_ticrate.value; // listen servers can run multiple server frames per client frame framelimit = cl_maxphysicsframesperserverframe.integer; aborttime = Sys_DirtyTime() + 0.1; } if(slowmo.value > 0 && slowmo.value < 1) advancetime = min(advancetime, 0.1 / slowmo.value); else advancetime = min(advancetime, 0.1); if(advancetime > 0) { offset = Sys_DirtyTime() - dirtytime;if (offset < 0 || offset >= 1800) offset = 0; offset += sv_timer; ++svs.perf_acc_offset_samples; svs.perf_acc_offset += offset; svs.perf_acc_offset_squared += offset * offset; if(svs.perf_acc_offset_max < offset) svs.perf_acc_offset_max = offset; } // only advance time if not paused // the game also pauses in singleplayer when menu or console is used sv.frametime = advancetime * slowmo.value; if (host_framerate.value) sv.frametime = host_framerate.value; if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused))) sv.frametime = 0; for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++) { sv_timer -= advancetime; // move things around and think unless paused if (sv.frametime) SV_Physics(); // if this server frame took too long, break out of the loop if (framelimit > 1 && Sys_DirtyTime() >= aborttime) break; } R_TimeReport("serverphysics"); // send all messages to the clients SV_SendClientMessages(); if (sv.paused == 1 && realtime > sv.pausedstart && sv.pausedstart > 0) { prog->globals.fp[OFS_PARM0] = realtime - sv.pausedstart; PRVM_serverglobalfloat(time) = sv.time; prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing"); } // send an heartbeat if enough time has passed since the last one NetConn_Heartbeat(0); R_TimeReport("servernetwork"); } else if (!svs.threaded) { // don't let r_speeds display jump around R_TimeReport("serverphysics"); R_TimeReport("servernetwork"); } //------------------- // // client operations // //------------------- if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo || ((vid_activewindow ? cl_maxfps : cl_maxidlefps).value < 1))) { if(cls.td_frames < -2 || cls.td_frames > 0) { TimeDemo_BeginFrame(&tdstats); } R_TimeReport("---"); Collision_Cache_NewFrame(); R_TimeReport("photoncache"); // decide the simulation time if (cls.capturevideo.active) { //*** if (cls.capturevideo.realtime) clframetime = cl.realframetime = max(cl_timer, 1.0 / cls.capturevideo.framerate); else { clframetime = 1.0 / cls.capturevideo.framerate; cl.realframetime = max(cl_timer, clframetime); } } else if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo) { clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value); // when running slow, we need to sleep to keep input responsive wait = bound(0, cl_maxfps_alwayssleep.value * 1000, 100000); if (wait > 0) Sys_Sleep((int)wait); } else if (!vid_activewindow && cl_maxidlefps.value >= 1 && !cls.timedemo) clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxidlefps.value); else clframetime = cl.realframetime = cl_timer; // apply slowmo scaling clframetime *= cl.movevars_timescale; // scale playback speed of demos by slowmo cvar if (cls.demoplayback) { clframetime *= slowmo.value; // if demo playback is paused, don't advance time at all if (cls.demopaused) clframetime = 0; } else { // host_framerate overrides all else if (host_framerate.value) clframetime = host_framerate.value; if (cl.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused))) clframetime = 0; } if (cls.timedemo) clframetime = cl.realframetime = cl_timer; // deduct the frame time from the accumulator cl_timer -= cl.realframetime; cl.oldtime = cl.time; cl.time += clframetime; // update video if (host_speeds.integer) time1 = Sys_DirtyTime(); R_TimeReport("pre-input"); // Collect input into cmd CL_Input(); R_TimeReport("input"); // check for new packets NetConn_ClientFrame(); // read a new frame from a demo if needed CL_ReadDemoMessage(); R_TimeReport("clientnetwork"); // now that packets have been read, send input to server CL_SendMove(); R_TimeReport("sendmove"); // update client world (interpolate entities, create trails, etc) CL_UpdateWorld(); R_TimeReport("lerpworld"); CL_Video_Frame(); R_TimeReport("client"); CL_UpdateScreen(); R_TimeReport("render"); if (host_speeds.integer) time2 = Sys_DirtyTime(); // update audio if(cl.csqc_usecsqclistener) { S_Update(&cl.csqc_listenermatrix); cl.csqc_usecsqclistener = false; } else S_Update(&r_refdef.view.matrix); #ifdef CONFIG_CD CDAudio_Update(); R_TimeReport("audio"); #endif // reset gathering of mouse input in_mouse_x = in_mouse_y = 0; if(cls.td_frames < -2 || cls.td_frames > 0) { TimeDemo_EndFrame(&tdstats); } if (host_speeds.integer) { pass1 = (int)((time1 - time3)*1000000); time3 = Sys_DirtyTime(); pass2 = (int)((time2 - time1)*1000000); pass3 = (int)((time3 - time2)*1000000); Con_Printf("%6ius total %6ius server %6ius gfx %6ius snd\n", pass1+pass2+pass3, pass1, pass2, pass3); } } #if MEMPARANOIA Mem_CheckSentinelsGlobal(); #else if (developer_memorydebug.integer) Mem_CheckSentinelsGlobal(); #endif // if there is some time remaining from this frame, reset the timers if (cl_timer >= 0) cl_timer = 0; if (sv_timer >= 0) { if (!svs.threaded) svs.perf_acc_lost += sv_timer; sv_timer = 0; } IRC_Frame(); host_framecount++; } }
/* ===================== SV_DropClient Called when the player is getting totally kicked off the host if (crash = true), don't bother sending signofs ===================== */ void SV_DropClient(qboolean crash) { prvm_prog_t *prog = SVVM_prog; int i; Con_Printf("Client \"%s\" dropped\n", host_client->name); SV_StopDemoRecording(host_client); // make sure edict is not corrupt (from a level change for example) host_client->edict = PRVM_EDICT_NUM(host_client - svs.clients + 1); if (host_client->netconnection) { // tell the client to be gone if (!crash) { // LordHavoc: no opportunity for resending, so use unreliable 3 times unsigned char bufdata[8]; sizebuf_t buf; memset(&buf, 0, sizeof(buf)); buf.data = bufdata; buf.maxsize = sizeof(bufdata); MSG_WriteByte(&buf, svc_disconnect); NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false); NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false); NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false); } } // call qc ClientDisconnect function // LordHavoc: don't call QC if server is dead (avoids recursive // Host_Error in some mods when they run out of edicts) if (host_client->clientconnectcalled && sv.active && host_client->edict) { // call the prog function for removing a client // this will set the body to a dead frame, among other things int saveSelf = PRVM_serverglobaledict(self); host_client->clientconnectcalled = false; PRVM_serverglobalfloat(time) = sv.time; PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); prog->ExecuteProgram(prog, PRVM_serverfunction(ClientDisconnect), "QC function ClientDisconnect is missing"); PRVM_serverglobaledict(self) = saveSelf; } if (host_client->netconnection) { // break the net connection NetConn_Close(host_client->netconnection); host_client->netconnection = NULL; } // if a download is active, close it if (host_client->download_file) { Con_DPrintf("Download of %s aborted when %s dropped\n", host_client->download_name, host_client->name); FS_Close(host_client->download_file); host_client->download_file = NULL; host_client->download_name[0] = 0; host_client->download_expectedposition = 0; host_client->download_started = false; } // remove leaving player from scoreboard host_client->name[0] = 0; host_client->colors = 0; host_client->frags = 0; // send notification to all clients // get number of client manually just to make sure we get it right... i = host_client - svs.clients; MSG_WriteByte (&sv.reliable_datagram, svc_updatename); MSG_WriteByte (&sv.reliable_datagram, i); MSG_WriteString (&sv.reliable_datagram, host_client->name); MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors); MSG_WriteByte (&sv.reliable_datagram, i); MSG_WriteByte (&sv.reliable_datagram, host_client->colors); MSG_WriteByte (&sv.reliable_datagram, svc_updatefrags); MSG_WriteByte (&sv.reliable_datagram, i); MSG_WriteShort (&sv.reliable_datagram, host_client->frags); // free the client now if (host_client->entitydatabase) EntityFrame_FreeDatabase(host_client->entitydatabase); if (host_client->entitydatabase4) EntityFrame4_FreeDatabase(host_client->entitydatabase4); if (host_client->entitydatabase5) EntityFrame5_FreeDatabase(host_client->entitydatabase5); if (sv.active) { // clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags PRVM_ED_ClearEdict(prog, host_client->edict); } // clear the client struct (this sets active to false) memset(host_client, 0, sizeof(*host_client)); // update server listing on the master because player count changed // (which the master uses for filtering empty/full servers) NetConn_Heartbeat(1); if (sv.loadgame) { for (i = 0;i < svs.maxclients;i++) if (svs.clients[i].active && !svs.clients[i].spawned) break; if (i == svs.maxclients) { Con_Printf("Loaded game, everyone rejoined - unpausing\n"); sv.paused = sv.loadgame = false; // we're basically done with loading now } } }
/* <9a345> ../engine/sv_log.c:439 */ void SV_DelLogAddress_f(void) { const char *s; int nPort; char szAdr[MAX_PATH]; netadr_t adr; LOGLIST_T *list; LOGLIST_T *prev; qboolean found = FALSE; if (Cmd_Argc() != 3) { Con_Printf("logaddress_del: usage\nlogaddress_del ip port\n"); for (list = firstLog; list != NULL; list = list->next) Con_Printf("current: %s\n", NET_AdrToString(list->log.net_address_)); return; } nPort = Q_atoi(Cmd_Argv(2)); if (!nPort) { Con_Printf("logaddress_del: must specify a valid port\n"); return; } s = Cmd_Argv(1); if (!s || *s == '\0') { Con_Printf("logaddress_del: unparseable address\n"); return; } Q_snprintf(szAdr, sizeof(szAdr), "%s:%i", s, nPort); if (!NET_StringToAdr(szAdr,&adr)) { Con_Printf("logaddress_del: unable to resolve %s\n", szAdr); return; } if (!firstLog) { Con_Printf("logaddress_del: No addresses added yet\n"); return; } for(list = firstLog, prev = firstLog; list != NULL; list = list->next) { #ifdef REHLDS_FIXES //for IPX if (NET_CompareAdr(adr,list->log.net_address_)) #else if (Q_memcmp(adr.ip, list->log.net_address_.ip, 4) == 0 && adr.port == list->log.net_address_.port) #endif // REHLDS_FIXES { found = TRUE; if (list == prev) { firstLog = prev->next; Mem_Free(prev); } else { prev->next = list->next; Mem_Free(list); } break; } prev = list; } if (!found) { Con_Printf("logaddress_del: Couldn't find address in list\n"); return; } Con_Printf("deleting: %s\n", NET_AdrToString(adr)); }
/* ================== CL_ParseServerInfo ================== */ void CL_ParseServerInfo (void) { char *str; int i; int nummodels, numsounds; char model_precache[MAX_MODELS][MAX_QPATH]; char sound_precache[MAX_SOUNDS][MAX_QPATH]; Con_DPrintf ("Serverinfo packet received.\n"); // // wipe the client_state_t struct // CL_ClearState (); // parse protocol version number i = MSG_ReadLong (); if (i != PROTOCOL_VERSION) { Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION); return; } // parse maxclients cl.maxclients = MSG_ReadByte (); if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD) { Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients); return; } cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores"); // parse gametype cl.gametype = MSG_ReadByte (); // parse signon message str = MSG_ReadString (); Q_strncpy (cl.levelname, str, sizeof(cl.levelname)-1); // seperate the printfs so the server message can have a color Con_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"); Con_Printf ("%c%s\n", 2, str); // // first we go through and touch all of the precache data that still // happens to be in the cache, so precaching something else doesn't // needlessly purge it // // precache models memset (cl.model_precache, 0, sizeof(cl.model_precache)); for (nummodels=1 ; ; nummodels++) { str = MSG_ReadString (); if (!str[0]) break; if (nummodels==MAX_MODELS) { Con_Printf ("Server sent too many model precaches\n"); return; } Q_strcpy (model_precache[nummodels], str); Mod_TouchModel (str); } // precache sounds memset (cl.sound_precache, 0, sizeof(cl.sound_precache)); for (numsounds=1 ; ; numsounds++) { str = MSG_ReadString (); if (!str[0]) break; if (numsounds==MAX_SOUNDS) { Con_Printf ("Server sent too many sound precaches\n"); return; } Q_strcpy (sound_precache[numsounds], str); S_TouchSound (str); } // // now we try to load everything else until a cache allocation fails // for (i=1 ; i<nummodels ; i++) { cl.model_precache[i] = Mod_ForName (model_precache[i], false); if (cl.model_precache[i] == NULL) { Con_Printf("Model %s not found\n", model_precache[i]); return; } CL_KeepaliveMessage (); } S_BeginPrecaching (); for (i=1 ; i<numsounds ; i++) { cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]); CL_KeepaliveMessage (); } S_EndPrecaching (); // local state cl_entities[0].model = cl.worldmodel = cl.model_precache[1]; R_NewMap (); Hunk_Check (); // make sure nothing is hurt noclip_anglehack = false; // noclip is turned off at start }
//============================================================================= // Get UltraSound MAX configuration if any //============================================================================= static qboolean GUS_GetMAXData(void) { char *Ultrasnd,*Ultra16; int i; int GusBase,Dma1,Dma2,Irq1,Irq2; int CodecBase,CodecDma,CodecIrq,CodecType; BYTE MaxVal; Ultrasnd=getenv("ULTRASND"); Ultra16=getenv("ULTRA16"); if (Ultrasnd==NULL || Ultra16==NULL) return(false); sscanf(Ultrasnd,"%x,%i,%i,%i,%i",&GusBase,&Dma1,&Dma2,&Irq1,&Irq2); sscanf(Ultra16,"%x,%i,%i,%i",&CodecBase,&CodecDma,&CodecIrq,&CodecType); if (CodecType==0 && CodecDma!=0) DmaChannel=CodecDma & 0x07; else DmaChannel=Dma2 & 0x07; // Make sure there is a GUS at GUS base dos_outportb(GusBase+0x08,0x55); if (dos_inportb(GusBase+0x0A)!=0x55) return(false); dos_outportb(GusBase+0x08,0xAA); if (dos_inportb(GusBase+0x0A)!=0xAA) return(false); // Program CODEC control register MaxVal=((CodecBase & 0xF0)>>4) | 0x40; if (Dma1 > 3) MaxVal|=0x10; if (Dma2 > 3) MaxVal|=0x20; dos_outportb(GusBase+0x106,MaxVal); CodecRegisterSelect=CodecBase; CodecData=CodecBase+1; CodecStatus=CodecBase+2; // Make sure there is a CODEC at the CODEC base // Clear any pending IRQs dos_inportb(CodecStatus); dos_outportb(CodecStatus,0); // Wait for 'INIT' bit to clear for (i=0;i<0xFFFF;i++) if ((dos_inportb(CodecRegisterSelect) & 0x80) == 0) break; if (i==0xFFFF) return(false); // Get chip revision - can not be zero dos_outportb(CodecRegisterSelect,CODEC_MODE_AND_ID); if ((dos_inportb(CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) return(false); if ((dos_inportb(CodecData) & 0x0F) == 0) return(false); HaveCodec=1; Con_Printf("Sound Card is UltraSound MAX\n"); return(true); }
/* ===================== CL_ParseServerMessage ===================== */ void CL_ParseServerMessage (void) { int cmd; int i; // // if recording demos, copy the message out // if (cl_shownet.value == 1) Con_Printf ("%i ",net_message.cursize); else if (cl_shownet.value == 2) Con_Printf ("------------------\n"); cl.onground = false; // unless the server says otherwise // // parse the message // MSG_BeginReading (); while (1) { if (msg_badread) Host_Error ("CL_ParseServerMessage: Bad server message"); cmd = MSG_ReadByte (); if (cmd == -1) { SHOWNET("END OF MESSAGE"); return; // end of message } // if the high bit of the command byte is set, it is a fast update if (cmd & 128) { SHOWNET("fast update"); CL_ParseUpdate (cmd&127); continue; } SHOWNET(svc_strings[cmd]); // other commands switch (cmd) { default: Host_Error ("CL_ParseServerMessage: Illegible server message\n"); break; case svc_nop: // Con_Printf ("svc_nop\n"); break; case svc_time: cl.mtime[1] = cl.mtime[0]; cl.mtime[0] = MSG_ReadFloat (); break; case svc_clientdata: i = MSG_ReadShort (); CL_ParseClientdata (i); break; case svc_version: i = MSG_ReadLong (); if (i != PROTOCOL_VERSION) Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION); break; case svc_disconnect: Host_EndGame ("Server disconnected\n"); case svc_print: Con_Printf ("%s", MSG_ReadString ()); break; case svc_centerprint: SCR_CenterPrint (MSG_ReadString ()); break; case svc_stufftext: Cbuf_AddText (MSG_ReadString ()); break; case svc_damage: V_ParseDamage (); break; case svc_serverinfo: CL_ParseServerInfo (); vid.recalc_refdef = true; // leave intermission full screen break; case svc_setangle: for (i=0 ; i<3 ; i++) cl.viewangles[i] = MSG_ReadAngle (); break; case svc_setview: cl.viewentity = MSG_ReadShort (); break; case svc_lightstyle: i = MSG_ReadByte (); if (i >= MAX_LIGHTSTYLES) Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); Q_strcpy (cl_lightstyle[i].map, MSG_ReadString()); cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); break; case svc_sound: CL_ParseStartSoundPacket(); break; case svc_stopsound: i = MSG_ReadShort(); S_StopSound(i>>3, i&7); break; case svc_updatename: Sbar_Changed (); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD"); Q_strcpy (cl.scores[i].name, MSG_ReadString ()); break; case svc_updatefrags: Sbar_Changed (); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD"); cl.scores[i].frags = MSG_ReadShort (); break; case svc_updatecolors: Sbar_Changed (); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD"); cl.scores[i].colors = MSG_ReadByte (); CL_NewTranslation (i); break; case svc_particle: R_ParseParticleEffect (); break; case svc_spawnbaseline: i = MSG_ReadShort (); // must use CL_EntityNum() to force cl.num_entities up CL_ParseBaseline (CL_EntityNum(i)); break; case svc_spawnstatic: CL_ParseStatic (); break; case svc_temp_entity: CL_ParseTEnt (); break; case svc_setpause: { cl.paused = MSG_ReadByte (); if (cl.paused) { CDAudio_Pause (); } else { CDAudio_Resume (); } } break; case svc_signonnum: i = MSG_ReadByte (); if (i <= cls.signon) Host_Error ("Received signon %i when at %i", i, cls.signon); cls.signon = i; CL_SignonReply (); break; case svc_killedmonster: cl.stats[STAT_MONSTERS]++; break; case svc_foundsecret: cl.stats[STAT_SECRETS]++; break; case svc_updatestat: i = MSG_ReadByte (); if (i < 0 || i >= MAX_CL_STATS) Sys_Error ("svc_updatestat: %i is invalid", i); cl.stats[i] = MSG_ReadLong ();; break; case svc_spawnstaticsound: CL_ParseStaticSound (); break; case svc_cdtrack: cl.cdtrack = MSG_ReadByte (); cl.looptrack = MSG_ReadByte (); if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) ) CDAudio_Play ((byte)cls.forcetrack, true); else CDAudio_Play ((byte)cl.cdtrack, true); break; case svc_intermission: cl.intermission = 1; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen break; case svc_finale: cl.intermission = 2; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint (MSG_ReadString ()); break; case svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint (MSG_ReadString ()); break; case svc_sellscreen: Cmd_ExecuteString ("help", src_command); break; } } }
static void Modem_Hangup4(ComPort *p) { Modem_Response(p); Con_Printf("Hangup complete\n"); p->modemConnected = false; }
dir_t Sys_listdir (const char *path, const char *ext, int sort_type) { static file_t list[MAX_DIRFILES]; dir_t dir; char pathname[MAX_OSPATH]; DIR *d; DIR *testdir; //bliP: list dir struct dirent *oneentry; qbool all; int r; pcre *preg = NULL; const char *errbuf; memset(list, 0, sizeof(list)); memset(&dir, 0, sizeof(dir)); dir.files = list; all = !strncmp(ext, ".*", 3); if (!all) if (!(preg = pcre_compile(ext, PCRE_CASELESS, &errbuf, &r, NULL))) { Con_Printf("Sys_listdir: pcre_compile(%s) error: %s at offset %d\n", ext, errbuf, r); Q_free(preg); return dir; } if (!(d = opendir(path))) { if (!all) Q_free(preg); return dir; } while ((oneentry = readdir(d))) { if (!strncmp(oneentry->d_name, ".", 2) || !strncmp(oneentry->d_name, "..", 3)) continue; if (!all) { switch (r = pcre_exec(preg, NULL, oneentry->d_name, strlen(oneentry->d_name), 0, 0, NULL, 0)) { case 0: break; case PCRE_ERROR_NOMATCH: continue; default: Con_Printf("Sys_listdir: pcre_exec(%s, %s) error code: %d\n", ext, oneentry->d_name, r); Q_free(preg); return dir; } } snprintf(pathname, sizeof(pathname), "%s/%s", path, oneentry->d_name); if ((testdir = opendir(pathname))) { dir.numdirs++; list[dir.numfiles].isdir = true; list[dir.numfiles].size = list[dir.numfiles].time = 0; closedir(testdir); } else { list[dir.numfiles].isdir = false; //list[dir.numfiles].time = Sys_FileTime(pathname); dir.size += (list[dir.numfiles].size = Sys_FileSizeTime(pathname, &list[dir.numfiles].time)); } strlcpy (list[dir.numfiles].name, oneentry->d_name, MAX_DEMO_NAME); if (++dir.numfiles == MAX_DIRFILES - 1) break; } closedir(d); if (!all) Q_free(preg); switch (sort_type) { case SORT_NO: break; case SORT_BY_DATE: qsort((void *)list, dir.numfiles, sizeof(file_t), Sys_compare_by_date); break; case SORT_BY_NAME: qsort((void *)list, dir.numfiles, sizeof(file_t), Sys_compare_by_name); break; } return dir; }
static void Modem_Init(ComPort *p) { double start; char *response; Con_Printf ("Initializing modem...\n"); // write 0 to MCR, wait 1/2 sec, then write the real value back again // I got this from the guys at head-to-head who say it's necessary. outportb(p->uart + MODEM_CONTROL_REGISTER, 0); start = Sys_FloatTime(); while ((Sys_FloatTime() - start) < 0.5) ; outportb(p->uart + MODEM_CONTROL_REGISTER, MCR_OUT2 | MCR_RTS | MCR_DTR); start = Sys_FloatTime(); while ((Sys_FloatTime() - start) < 0.25) ; if (*p->clear) { Modem_Command (p, p->clear); start = Sys_FloatTime(); while(1) { if ((Sys_FloatTime() - start) > 3.0) { Con_Printf("No response - clear failed\n"); p->enabled = false; goto failed; } response = Modem_Response(p); if (!response) continue; if (Q_strncmp(response, "OK", 2) == 0) break; if (Q_strncmp(response, "ERROR", 5) == 0) { p->enabled = false; goto failed; } } } if (*p->startup) { Modem_Command (p, p->startup); start = Sys_FloatTime(); while(1) { if ((Sys_FloatTime() - start) > 3.0) { Con_Printf("No response - init failed\n"); p->enabled = false; goto failed; } response = Modem_Response(p); if (!response) continue; if (Q_strncmp(response, "OK", 2) == 0) break; if (Q_strncmp(response, "ERROR", 5) == 0) { p->enabled = false; goto failed; } } } p->modemInitialized = true; return; failed: if (m_return_onerror) { key_dest = key_menu; m_state = m_return_state; m_return_onerror = false; Q_strcpy(m_return_reason, "Initialization Failed"); } return; }
int WINS_Init (void) { int i; char buff[MAXHOSTNAMELEN]; char *p; int r; WORD wVersionRequested; HINSTANCE hInst; // initialize the Winsock function vectors (we do this instead of statically linking // so we can run on Win 3.1, where there isn't necessarily Winsock) hInst = LoadLibrary("wsock32.dll"); if (hInst == NULL) { Con_Printf ("Failed to load winsock.dll\n"); winsock_lib_initialized = false; return -1; } winsock_lib_initialized = true; pWSAStartup = (void *)GetProcAddress(hInst, "WSAStartup"); pWSACleanup = (void *)GetProcAddress(hInst, "WSACleanup"); pWSAGetLastError = (void *)GetProcAddress(hInst, "WSAGetLastError"); psocket = (void *)GetProcAddress(hInst, "socket"); pioctlsocket = (void *)GetProcAddress(hInst, "ioctlsocket"); psetsockopt = (void *)GetProcAddress(hInst, "setsockopt"); precvfrom = (void *)GetProcAddress(hInst, "recvfrom"); psendto = (void *)GetProcAddress(hInst, "sendto"); pclosesocket = (void *)GetProcAddress(hInst, "closesocket"); pgethostname = (void *)GetProcAddress(hInst, "gethostname"); pgethostbyname = (void *)GetProcAddress(hInst, "gethostbyname"); pgethostbyaddr = (void *)GetProcAddress(hInst, "gethostbyaddr"); pgetsockname = (void *)GetProcAddress(hInst, "getsockname"); if (!pWSAStartup || !pWSACleanup || !pWSAGetLastError || !psocket || !pioctlsocket || !psetsockopt || !precvfrom || !psendto || !pclosesocket || !pgethostname || !pgethostbyname || !pgethostbyaddr || !pgetsockname) { Con_Printf ("Couldn't GetProcAddress from winsock.dll\n"); return -1; } if (COM_CheckParm ("-noudp")) return -1; if (winsock_initialized == 0) { wVersionRequested = MAKEWORD(1, 1); r = pWSAStartup (MAKEWORD(1, 1), &winsockdata); if (r) { Con_Printf ("Winsock initialization failed.\n"); return -1; } } winsock_initialized++; // determine my name if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR) { Con_DPrintf ("Winsock TCP/IP Initialization failed.\n"); if (--winsock_initialized == 0) pWSACleanup (); return -1; } // if the quake hostname isn't set, set it to the machine name if (strcmp(hostname.string, "UNNAMED") == 0) { // see if it's a text IP address (well, close enough) for (p = buff; *p; p++) if ((*p < '0' || *p > '9') && *p != '.') break; // if it is a real name, strip off the domain; we only want the host if (*p) { for (i = 0; i < 15; i++) if (buff[i] == '.') break; buff[i] = 0; } Cvar_Set ("hostname", buff); } i = COM_CheckParm ("-ip"); if (i) { if (i < com_argc-1) { myAddr = inet_addr(com_argv[i+1]); if (myAddr == INADDR_NONE) Sys_Error ("%s is not a valid IP address", com_argv[i+1]); strcpy(my_tcpip_address, com_argv[i+1]); } else { Sys_Error ("NET_Init: you must specify an IP address after -ip"); } } else { myAddr = INADDR_ANY; strcpy(my_tcpip_address, "INADDR_ANY"); } // JPG 3.02 - support for a trusted qsmack bot i = COM_CheckParm ("-qsmack"); if (i) { if (i < com_argc-1) { qsmackAddr = inet_addr(com_argv[i+1]); if (qsmackAddr == INADDR_NONE) Sys_Error ("%s is not a valid IP address", com_argv[i+1]); } else Sys_Error ("NET_Init: you must specify an IP address after -qsmack"); } else qsmackAddr = INADDR_ANY; if ((net_controlsocket = WINS_OpenSocket (0)) == -1) { Con_Printf("WINS_Init: Unable to open control socket\n"); if (--winsock_initialized == 0) pWSACleanup (); return -1; } ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET; ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST; ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons((unsigned short)net_hostport); Con_Printf("Winsock TCP/IP Initialized\n"); tcpipAvailable = true; return net_controlsocket; }
void Com_f (void) { ComPort *p; int portNumber; int i; int n; // first, determine which port they're messing with portNumber = Q_atoi(Cmd_Argv (0) + 3) - 1; if (portNumber > 1) return; p = handleToPort[portNumber]; if (Cmd_Argc() == 1) { Con_Printf("Settings for COM%i\n", portNumber + 1); Con_Printf("enabled: %s\n", p->enabled ? "true" : "false"); Con_Printf("uart: "); if (p->uartType == UART_AUTO) Con_Printf("auto\n"); else if (p->uartType == UART_8250) Con_Printf("8250\n"); else Con_Printf("16550\n"); Con_Printf("port: %x\n", p->uart); Con_Printf("irq: %i\n", p->irq); Con_Printf("baud: %i\n", 115200 / p->baudBits); Con_Printf("CTS: %s\n", (p->modemStatusIgnore & MSR_CTS) ? "ignored" : "honored"); Con_Printf("DSR: %s\n", (p->modemStatusIgnore & MSR_DSR) ? "ignored" : "honored"); Con_Printf("CD: %s\n", (p->modemStatusIgnore & MSR_CD) ? "ignored" : "honored"); if (p->useModem) { Con_Printf("type: Modem\n"); Con_Printf("clear: %s\n", p->clear); Con_Printf("startup: %s\n", p->startup); Con_Printf("shutdown: %s\n", p->shutdown); } else Con_Printf("type: Direct connect\n"); return; } if (Cmd_CheckParm ("disable")) { if (p->enabled) ComPort_Disable(p); p->modemInitialized = false; return; } if (Cmd_CheckParm ("reset")) { ComPort_Disable(p); ResetComPortConfig (p); return; } if ((i = Cmd_CheckParm ("port")) != 0) { if (p->enabled) { Con_Printf("COM port must be disabled to change port\n"); return; } p->uart = Q_atoi (Cmd_Argv (i+1)); } if ((i = Cmd_CheckParm ("irq")) != 0) { if (p->enabled) { Con_Printf("COM port must be disabled to change irq\n"); return; } p->irq = Q_atoi (Cmd_Argv (i+1)); } if ((i = Cmd_CheckParm ("baud")) != 0) { if (p->enabled) { Con_Printf("COM port must be disabled to change baud\n"); return; } n = Q_atoi (Cmd_Argv (i+1)); if (n == 0) Con_Printf("Invalid baud rate specified\n"); else p->baudBits = 115200 / n; } if (Cmd_CheckParm ("8250")) { if (p->enabled) { Con_Printf("COM port must be disabled to change uart\n"); return; } p->uartType = UART_8250; } if (Cmd_CheckParm ("16550")) { if (p->enabled) { Con_Printf("COM port must be disabled to change uart\n"); return; } p->uartType = UART_16550; } if (Cmd_CheckParm ("auto")) { if (p->enabled) { Con_Printf("COM port must be disabled to change uart\n"); return; } p->uartType = UART_AUTO; } if (Cmd_CheckParm ("pulse")) p->dialType = 'P'; if (Cmd_CheckParm ("tone")) p->dialType = 'T'; if (Cmd_CheckParm ("direct")) p->useModem = false; if (Cmd_CheckParm ("modem")) p->useModem = true; if ((i = Cmd_CheckParm ("clear")) != 0) { Q_strncpy (p->clear, Cmd_Argv (i+1), 16); } if ((i = Cmd_CheckParm ("startup")) != 0) { Q_strncpy (p->startup, Cmd_Argv (i+1), 32); p->modemInitialized = false; } if ((i = Cmd_CheckParm ("shutdown")) != 0) { Q_strncpy (p->shutdown, Cmd_Argv (i+1), 16); } if (Cmd_CheckParm ("-cts")) { p->modemStatusIgnore |= MSR_CTS; p->modemStatus |= MSR_CTS; } if (Cmd_CheckParm ("+cts")) { p->modemStatusIgnore &= (~MSR_CTS); p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; } if (Cmd_CheckParm ("-dsr")) { p->modemStatusIgnore |= MSR_DSR; p->modemStatus |= MSR_DSR; } if (Cmd_CheckParm ("+dsr")) { p->modemStatusIgnore &= (~MSR_DSR); p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; } if (Cmd_CheckParm ("-cd")) { p->modemStatusIgnore |= MSR_CD; p->modemStatus |= MSR_CD; } if (Cmd_CheckParm ("+cd")) { p->modemStatusIgnore &= (~MSR_CD); p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; } if (Cmd_CheckParm ("enable")) { if (!p->enabled) ComPort_Enable(p); if (p->useModem && !p->modemInitialized) Modem_Init (p); } }
/* ================== SndSys_InitDirectSound DirectSound 5 support ================== */ static sndinitstat SndSys_InitDirectSound (const snd_format_t* requested) { DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; DWORD dwSize; DSCAPS dscaps; WAVEFORMATEXTENSIBLE format, pformat; HRESULT hresult; int reps; if (! SndSys_BuildWaveFormat(requested, &format)) return SIS_FAILURE; if (!hInstDS) { hInstDS = LoadLibrary("dsound.dll"); if (hInstDS == NULL) { Con_Print("Couldn't load dsound.dll\n"); return SIS_FAILURE; } pDirectSoundCreate = (HRESULT (__stdcall *)(GUID *, LPDIRECTSOUND *,IUnknown *))GetProcAddress(hInstDS,"DirectSoundCreate"); if (!pDirectSoundCreate) { Con_Print("Couldn't get DS proc addr\n"); return SIS_FAILURE; } } while ((hresult = pDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK) { if (hresult != DSERR_ALLOCATED) { Con_Print("DirectSound create failed\n"); return SIS_FAILURE; } if (MessageBox (NULL, "The sound hardware is in use by another app.\n\n" "Select Retry to try to start sound again or Cancel to run Quake with no sound.", "Sound not available", MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) { Con_Print("DirectSoundCreate failure\n hardware already in use\n"); return SIS_NOTAVAIL; } } dscaps.dwSize = sizeof(dscaps); if (DS_OK != IDirectSound_GetCaps (pDS, &dscaps)) { Con_Print("Couldn't get DS caps\n"); } if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { Con_Print("No DirectSound driver installed\n"); SndSys_Shutdown (); return SIS_FAILURE; } if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { Con_Print("Set coop level failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } // get access to the primary buffer, if possible, so we can set the // sound hardware format memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); primary_format_set = false; // COMMANDLINEOPTION: Windows DirectSound: -snoforceformat uses the format that DirectSound returns, rather than forcing it if (!COM_CheckParm ("-snoforceformat")) { if (DS_OK == IDirectSound_CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL)) { pformat = format; if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, (WAVEFORMATEX*)&pformat)) { Con_Print("Set primary sound buffer format: no\n"); } else { Con_Print("Set primary sound buffer format: yes\n"); primary_format_set = true; } } } // COMMANDLINEOPTION: Windows DirectSound: -primarysound locks the sound hardware for exclusive use if (!primary_format_set || !COM_CheckParm ("-primarysound")) { HRESULT result; // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE(requested); dsbuf.lpwfxFormat = (WAVEFORMATEX*)&format; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); result = IDirectSound_CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL); if (result != DS_OK || requested->channels != format.Format.nChannels || requested->width != format.Format.wBitsPerSample / 8 || requested->speed != format.Format.nSamplesPerSec) { Con_Printf("DS:CreateSoundBuffer Failed (%d): channels=%u, width=%u, speed=%u\n", (int)result, (unsigned)format.Format.nChannels, (unsigned)format.Format.wBitsPerSample / 8, (unsigned)format.Format.nSamplesPerSec); SndSys_Shutdown (); return SIS_FAILURE; } if (DS_OK != IDirectSoundBuffer_GetCaps (pDSBuf, &dsbcaps)) { Con_Print("DS:GetCaps failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } Con_Print("Using secondary sound buffer\n"); } else { if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY)) { Con_Print("Set coop level failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } if (DS_OK != IDirectSoundBuffer_GetCaps (pDSPBuf, &dsbcaps)) { Con_Print("DS:GetCaps failed\n"); return SIS_FAILURE; } pDSBuf = pDSPBuf; Con_Print("Using primary sound buffer\n"); } // Make sure mixer is active IDirectSoundBuffer_Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); Con_Printf(" %d channel(s)\n" " %d bits/sample\n" " %d samples/sec\n", requested->channels, requested->width * 8, requested->speed); gSndBufSize = dsbcaps.dwBufferBytes; // initialize the buffer reps = 0; while ((hresult = IDirectSoundBuffer_Lock(pDSBuf, 0, gSndBufSize, (LPVOID*)&lpData, &dwSize, NULL, NULL, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Con_Print("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } if (++reps > 10000) { Con_Print("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); SndSys_Shutdown (); return SIS_FAILURE; } } memset(lpData, 0, dwSize); IDirectSoundBuffer_Unlock(pDSBuf, lpData, dwSize, NULL, 0); IDirectSoundBuffer_Stop(pDSBuf); IDirectSoundBuffer_Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); dwStartTime = 0; dsound_time = 0; snd_renderbuffer = Snd_CreateRingBuffer(requested, gSndBufSize / (requested->width * requested->channels), lpData); dsound_init = true; return SIS_SUCCESS; }
void BGM_Play (const char *filename) { char tmp[MAX_QPATH]; const char *ext; music_handler_t *handler; BGM_Stop(); if (music_handlers == NULL) return; if (!filename || !*filename) { Con_DPrintf("null music file name\n"); return; } ext = COM_FileGetExtension(filename); if (! *ext) /* try all things */ { BGM_Play_noext(filename, ANY_CODECTYPE); return; } /* use the filename as is */ handler = music_handlers; while (handler) { if (handler->is_available && !q_strcasecmp(ext, handler->ext)) break; handler = handler->next; } if (!handler) { Con_Printf("Unhandled extension for %s\n", filename); return; } q_snprintf(tmp, sizeof(tmp), "%s/%s", handler->dir, filename); switch (handler->player) { case BGM_MIDIDRV: if (BGM_Play_mididrv(tmp) == 0) return; /* success */ /* BGM_MIDIDRV is followed by CODECTYPE_MID streamer. * Even if the midi driver failed, we may still have * a chance with the streamer if it's available... */ if (! (handler->next && handler->next->is_available)) break; handler = handler->next; case BGM_STREAMER: bgmstream = S_CodecOpenStreamType(tmp, handler->type); if (bgmstream) return; /* success */ break; case BGM_NONE: default: break; } Con_Printf("Couldn't handle music file %s\n", filename); }
/* ============== Hunk_Print If "all" is specified, every single allocation is printed. Otherwise, allocations with the same name will be totaled up before printing. ============== */ void Hunk_Print (qboolean all) { hunk_t *h, *next, *endlow, *starthigh, *endhigh; int count, sum; int totalblocks; char name[HUNKNAME_LEN]; count = 0; sum = 0; totalblocks = 0; h = (hunk_t *)hunk_base; endlow = (hunk_t *)(hunk_base + hunk_low_used); starthigh = (hunk_t *)(hunk_base + hunk_size - hunk_high_used); endhigh = (hunk_t *)(hunk_base + hunk_size); Con_Printf (" :%8i total hunk size\n", hunk_size); Con_Printf ("-------------------------\n"); while (1) { // // skip to the high hunk if done with low hunk // if ( h == endlow ) { Con_Printf ("-------------------------\n"); Con_Printf (" :%8i REMAINING\n", hunk_size - hunk_low_used - hunk_high_used); Con_Printf ("-------------------------\n"); h = starthigh; } // // if totally done, break // if ( h == endhigh ) break; // // run consistancy checks // if (h->sentinal != HUNK_SENTINAL) Sys_Error ("Hunk_Check: trahsed sentinal"); if (h->size < (int) sizeof(hunk_t) || h->size + (byte *)h - hunk_base > hunk_size) Sys_Error ("Hunk_Check: bad size"); next = (hunk_t *)((byte *)h+h->size); count++; totalblocks++; sum += h->size; // // print the single block // memcpy (name, h->name, HUNKNAME_LEN); if (all) Con_Printf ("%8p :%8i %8s\n",h, h->size, name); // // print the total // if (next == endlow || next == endhigh || strncmp (h->name, next->name, HUNKNAME_LEN - 1)) { if (!all) Con_Printf (" :%8i %8s (TOTAL)\n",sum, name); count = 0; sum = 0; } h = next; } Con_Printf ("-------------------------\n"); Con_Printf ("%8i total blocks\n", totalblocks); }
static void BGM_UpdateStream (void) { int res; /* Number of bytes read. */ int bufferSamples; int fileSamples; int fileBytes; byte raw[16384]; if (bgmstream->status != STREAM_PLAY) return; /* don't bother playing anything if musicvolume is 0 */ if (bgmvolume.value <= 0) return; /* see how many samples should be copied into the raw buffer */ if (s_rawend < paintedtime) s_rawend = paintedtime; while (s_rawend < paintedtime + MAX_RAW_SAMPLES) { bufferSamples = MAX_RAW_SAMPLES - (s_rawend - paintedtime); /* decide how much data needs to be read from the file */ fileSamples = bufferSamples * bgmstream->info.rate / shm->speed; if (!fileSamples) return; /* our max buffer size */ fileBytes = fileSamples * (bgmstream->info.width * bgmstream->info.channels); if (fileBytes > (int) sizeof(raw)) { fileBytes = (int) sizeof(raw); fileSamples = fileBytes / (bgmstream->info.width * bgmstream->info.channels); } /* Read */ res = S_CodecReadStream(bgmstream, fileBytes, raw); if (res < fileBytes) { fileBytes = res; fileSamples = res / (bgmstream->info.width * bgmstream->info.channels); } if (res > 0) /* data: add to raw buffer */ { S_RawSamples(fileSamples, bgmstream->info.rate, bgmstream->info.width, bgmstream->info.channels, raw, bgmvolume.value); } else if (res == 0) /* EOF */ { if (bgmloop) { if (S_CodecRewindStream(bgmstream) < 0) { BGM_Stop(); return; } } else { BGM_Stop(); return; } } else /* res < 0: some read error */ { Con_Printf("Stream read error (%i), stopping.\n", res); BGM_Stop(); return; } } }
/* <9a28f> ../engine/sv_log.c:321 */ void SV_AddLogAddress_f(void) { const char *s; int nPort; char szAdr[MAX_PATH]; netadr_t adr; LOGLIST_T *list; qboolean found = FALSE; LOGLIST_T *tmp; if (Cmd_Argc() != 3) { Con_Printf("logaddress_add: usage\nlogaddress_add ip port\n"); for (list = firstLog; list != NULL; list = list->next) Con_Printf("current: %s\n", NET_AdrToString(list->log.net_address_)); return; } nPort = Q_atoi(Cmd_Argv(2)); if (!nPort) { Con_Printf("logaddress_add: must specify a valid port\n"); return; } s = Cmd_Argv(1); if (!s || *s == '\0') { Con_Printf("logaddress_add: unparseable address\n"); return; } Q_snprintf(szAdr, sizeof(szAdr), "%s:%i", s, nPort); if (!NET_StringToAdr(szAdr, &adr)) { Con_Printf("logaddress_add: unable to resolve %s\n", szAdr); return; } if (firstLog) { for (list = firstLog; list != NULL; list = list->next) { #ifdef REHLDS_FIXES //for IPX support if (NET_CompareAdr(adr, list->log.net_address_)) #else if (Q_memcmp(adr.ip, list->log.net_address_.ip, 4) == 0 && adr.port == list->log.net_address_.port) #endif // REHLDS_FIXES { found = TRUE; break; } } if (found) { Con_Printf("logaddress_add: address already in list\n"); return; } tmp = (LOGLIST_T *)Mem_Malloc(sizeof(LOGLIST_T)); if (!tmp) { Con_Printf("logaddress_add: error allocating new node\n"); return; } tmp->next = NULL; Q_memcpy(&tmp->log.net_address_, &adr, sizeof(netadr_t)); list = firstLog; while (list->next) list = list->next; list->next = tmp; } else { firstLog = (LOGLIST_T *)Mem_Malloc(sizeof(LOGLIST_T)); if (!firstLog) { Con_Printf("logaddress_add: error allocating new node\n"); return; } firstLog->next = NULL; Q_memcpy(&firstLog->log.net_address_, &adr, sizeof(netadr_t)); } Con_Printf("logaddress_add: %s\n", NET_AdrToString(adr)); }
/* * CCmdBind */ int CCmdBind(int argc, char **argv) { boolean prefixGiven = true; char validEventName[16], buff[80]; char prefix = '+', *begin; event_t event; int repeat = !stricmp(argv[0], "bindr") || !stricmp(argv[0], "safebindr"); int safe = !strnicmp(argv[0], "safe", 4); if(argc < 2 || argc > 3) { Con_Printf("Usage: %s (event) (cmd)\n", argv[0]); return true; } begin = argv[1]; if(strlen(argv[1]) > 1) // Can the event have a prefix? { prefix = argv[1][0]; begin = argv[1] + 1; if(prefix != '+' && prefix != '-' && prefix != '*') { begin = argv[1]; prefix = '+'; prefixGiven = false; } } else prefixGiven = false; if(argc == 2 && !prefixGiven) { char prefixes[3] = { '+', '-', '*' }; int i; // We're clearing a binding. If no prefix has been given, // +, - and * are all cleared. for(i = 0; i < 3; i++) { sprintf(buff, "%c%s", prefixes[i], argv[1]); B_EventBuilder(buff, &event, true); // Convert it to an event_t B_Bind(&event, NULL); } return true; } if(argc == 3) { char cprefix = argv[2][0]; if(cprefix != '+' && cprefix != '-' && begin == argv[1]) { // Bind both the + and -. sprintf(validEventName, "-%s", argv[1]); sprintf(buff, "-%s", argv[2]); if(Con_ActionCommand(buff, true)) { B_EventBuilder(validEventName, &event, true); if(safe && B_GetBinding(&event, false)) return false; B_Bind(&event, buff); sprintf(validEventName, "+%s", argv[1]); sprintf(buff, "+%s", argv[2]); B_EventBuilder(validEventName, &event, true); B_Bind(&event, buff); return true; } } } sprintf(validEventName, "%c%s", prefix, begin); //Con_Printf( "Binding %s : %s.\n", validEventName, argc==2? "(nothing)" : argv[2]); // Convert the name to an event. B_EventBuilder(validEventName, &event, true); if(safe && B_GetBinding(&event, false)) return false; // Now we can create a binding for it. B_Bind(&event, argc == 2 ? NULL : argv[2]); // A repeater? if(repeat && event.type == ev_keydown) { event.type = ev_keyrepeat; B_Bind(&event, argc == 2 ? NULL : argv[2]); } return true; }
/* ================== SCR_UpdateScreen This is called every frame, and can also be called explicitly to flush text to the screen. WARNING: be very careful calling this from elsewhere, because the refresh needs almost the entire 256k of stack space! ================== */ void SCR_UpdateScreen (void) { static float oldscr_viewsize; static float oldlcd_x; vrect_t vrect; if (scr_skipupdate || block_drawing) return; scr_copytop = 0; scr_copyeverything = 0; if (scr_disabled_for_loading) { if (realtime - scr_disabled_time > 60) { scr_disabled_for_loading = false; Con_Printf ("load failed.\n"); } else return; } if (cls.state == ca_dedicated) return; // stdout only if (!scr_initialized || !con_initialized) return; // not initialized yet if (scr_viewsize.value != oldscr_viewsize) { oldscr_viewsize = scr_viewsize.value; vid.recalc_refdef = 1; } // // check for vid changes // if (oldfov != scr_fov.value) { oldfov = scr_fov.value; vid.recalc_refdef = true; } if (oldlcd_x != lcd_x.value) { oldlcd_x = lcd_x.value; vid.recalc_refdef = true; } if (oldscreensize != scr_viewsize.value) { oldscreensize = scr_viewsize.value; vid.recalc_refdef = true; } if (vid.recalc_refdef) { // something changed, so reorder the screen #ifdef USEFPM SCR_CalcRefdefFPM (); #else SCR_CalcRefdef (); #endif } // // do 3D refresh drawing, and then update the screen // D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly if (scr_fullupdate++ < vid.numpages) { // clear the entire screen scr_copyeverything = 1; Draw_TileClear (0,0,vid.width,vid.height); Sbar_Changed (); } pconupdate = NULL; SCR_SetUpToDrawConsole (); SCR_EraseCenterString (); D_DisableBackBufferAccess (); // for adapters that can't stay mapped in // for linear writes all the time VID_LockBuffer (); #ifdef USEFPM V_RenderViewFPM(); #else V_RenderView (); #endif VID_UnlockBuffer (); D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly if (scr_drawdialog) { Sbar_Draw (); Draw_FadeScreen (); SCR_DrawNotifyString (); scr_copyeverything = true; } else if (scr_drawloading) { SCR_DrawLoading (); Sbar_Draw (); } else if (cl.intermission == 1 && key_dest == key_game) { Sbar_IntermissionOverlay (); } else if (cl.intermission == 2 && key_dest == key_game) { Sbar_FinaleOverlay (); SCR_CheckDrawCenterString (); } else if (cl.intermission == 3 && key_dest == key_game) { SCR_CheckDrawCenterString (); } else { SCR_DrawRam (); SCR_DrawNet (); SCR_DrawTurtle (); SCR_DrawPause (); SCR_CheckDrawCenterString (); #ifdef USEFPM Sbar_DrawFPM (); #else Sbar_Draw (); #endif SCR_DrawConsole (); M_Draw (); } D_DisableBackBufferAccess (); // for adapters that can't stay mapped in // for linear writes all the time if (pconupdate) { D_UpdateRects (pconupdate); } V_UpdatePalette (); // // update one of three areas // if (scr_copyeverything) { vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height; vrect.pnext = 0; VID_Update (&vrect); } else if (scr_copytop) { vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height - sb_lines; vrect.pnext = 0; VID_Update (&vrect); } else { vrect.x = scr_vrect.x; vrect.y = scr_vrect.y; vrect.width = scr_vrect.width; vrect.height = scr_vrect.height; vrect.pnext = 0; VID_Update (&vrect); } }