// // F_RunWipe // // // After setting up the screens you want to // wipe, calling this will do a 'typical' // wipe. // void F_RunWipe(tic_t duration, boolean drawMenu) { tic_t wipestart, tics, nowtime, y; boolean done; wipestart = I_GetTime() - 1; y = wipestart + duration; // init a timeout do { do { nowtime = I_GetTime(); tics = nowtime - wipestart; if (!tics) I_Sleep(); } while (!tics); wipestart = nowtime; #ifdef SHUFFLE done = F_ScreenWipe(0, 0, vid.width, vid.height, tics); #else if (rendermode == render_soft) done = F_ScreenWipe(0, 0, vid.width, vid.height, tics); else done = true; #endif I_OsPolling(); I_UpdateNoBlit(); if (drawMenu) M_Drawer(); // menu is drawn even on top of wipes if (rendermode == render_soft) I_FinishUpdate(); // page flip or blit buffer } while (!done && I_GetTime() < y); }
void TryRunTics (void) { int runtics; int entertime = I_GetTime(); // Wait for tics to run while (1) { #ifdef HAVE_NET NetUpdate(); #else D_BuildNewTiccmds(); #endif runtics = (server ? remotetic : maketic) - gametic; if (!runtics) { if (server) I_WaitForPacket(ms_to_next_tick); else I_uSleep(ms_to_next_tick*1000); if (I_GetTime() - entertime > 10) { remotesend--; if (server) { char buf[sizeof(packet_header_t) + 1]; packet_set((packet_header_t *)buf, PKT_RETRANS, remotetic); buf[sizeof(buf) - 1] = consoleplayer; I_SendPacket((packet_header_t *)buf, sizeof buf); } M_Ticker(); return; } } else break; } while (runtics--) { #ifdef HAVE_NET if (server) CheckQueuedPackets(); #endif if (advancedemo) D_DoAdvanceDemo (); M_Ticker (); G_Ticker (); gametic++; #ifdef HAVE_NET NetUpdate(); // Keep sending our tics to avoid stalling remote nodes #endif } }
// Checks if we need to ask the server for a re-request of the current download // chunk void CL_DownloadTicker() { dtime_t diff = 0; if(gamestate != GS_DOWNLOAD || download.filename.empty()) { return; } if (download.timeout) { // Calculate how many seconds have elapsed since the last server // response diff = I_GetTime() - download.timeout; if (diff) diff /= I_ConvertTimeFromMs(1000); } else { download.timeout = I_GetTime(); return; } if (diff >= 3) { DPrintf("No response from server for %d seconds, re-requesting\n", diff); MSG_WriteMarker(&net_buffer, clc_wantwad); MSG_WriteString(&net_buffer, download.filename.c_str()); MSG_WriteString(&net_buffer, download.md5.c_str()); MSG_WriteLong(&net_buffer, download.got_bytes); NET_SendPacket(net_buffer, serveraddr); download.timeout = 0; ++download.retrycount; } if (download.retrycount >= 5) { Printf(PRINT_HIGH, "Server hasn't responded to download re-requests, aborting\n"); download.retrycount = 0; download.timeout = 0; CL_QuitNetGame(); gamestate = GS_STARTUP; } }
void TryRunTics(void) { // get real tics int entertic = I_GetTime(); int counts; // get available tics NetUpdate(); counts = maketic - gametic; if (!counts && !vid_capfps) return; if (counts < 1) counts = 1; // wait for new tics if needed while (maketic < gametic + counts) { NetUpdate(); // Still no tics to run? Sleep until some are available. if (maketic < gametic + counts) { // If we're in a netgame, we might spin forever waiting for // new network data to be received. So don't stay in here // forever - give the menu a chance to work. if (I_GetTime() - entertic >= MAX_NETGAME_STALL_TICS) return; I_Sleep(1); } } // run the count tics while (counts--) { if (advancetitle) D_DoAdvanceTitle(); G_Ticker(); gametic++; gametime++; if (netcmds[0].buttons & BT_SPECIAL) netcmds[0].buttons = 0; NetUpdate(); } }
void TryRunTics (void) { int runtics; int entertime = I_GetTime(); // Wait for tics to run while (1) { NetUpdate(); runtics = (server ? remotetic : maketic) - gametic; if (!runtics) { if (!movement_smooth) { if (server) I_WaitForPacket(ms_to_next_tick); else I_uSleep(ms_to_next_tick*1000); } if (I_GetTime() - entertime > 10) { if (server) { char buf[sizeof(packet_header_t)+1]; remotesend--; packet_set((packet_header_t *)buf, PKT_RETRANS, remotetic); buf[sizeof(buf)-1] = consoleplayer; I_SendPacket((packet_header_t *)buf, sizeof buf); } M_Ticker(); return; } { WasRenderedInTryRunTics = TRUE; if (movement_smooth && gamestate==wipegamestate) { isExtraDDisplay = TRUE; D_Display(); isExtraDDisplay = FALSE; } } } else break; } while (runtics--) { if (server) CheckQueuedPackets(); if (advancedemo) D_DoAdvanceDemo (); M_Ticker (); I_GetTime_SaveMS(); G_Ticker (); P_Checksum(gametic); gametic++; NetUpdate(); // Keep sending our tics to avoid stalling remote nodes } }
// wait for all ackreturns with timeout in seconds void Net_WaitAllAckReceived(UINT32 timeout) { tic_t tictac = I_GetTime(); timeout = tictac + timeout*TICRATE; HGetPacket(); while (timeout > I_GetTime() && !Net_AllAckReceived()) { while (tictac == I_GetTime()) I_Sleep(); tictac = I_GetTime(); HGetPacket(); Net_AckTicker(); } }
// // V_ClassicFPSDrawer // // sf: classic fps ticker kept seperate // void V_ClassicFPSDrawer(void) { static int lasttic; int i = I_GetTime(); int tics = i - lasttic; lasttic = i; if (tics > 20) tics = 20; // SoM: ANYRES if(vbscreen.scaled) { for (i=0 ; i<tics*2 ; i+=2) V_ColorBlockScaled(&vbscreen, 0xff, i, SCREENHEIGHT-1, 1, 1); for ( ; i<20*2 ; i+=2) V_ColorBlockScaled(&vbscreen, 0x00, i, SCREENHEIGHT-1, 1, 1); } else { for (i=0 ; i<tics*2 ; i+=2) V_ColorBlock(&vbscreen, 0xff, i, SCREENHEIGHT-1, 1, 1); for ( ; i<20*2 ; i+=2) V_ColorBlock(&vbscreen, 0x00, i, SCREENHEIGHT-1, 1, 1); } }
void I_FinishUpdate(void) { static int lasttic; int tics; int i; // draws little dots on the bottom of the screen, a simple fps meter if (devparm) { i = I_GetTime(); tics = i - lasttic; lasttic = i; if (tics > 20) tics = 20; for (i = 0; i < tics * 2; i += 2) screens[0][(SCREENHEIGHT - 2) * SCREENWIDTH + i + 3] = 0xff; for (; i < 20 * 2; i += 2) screens[0][(SCREENHEIGHT - 2) * SCREENWIDTH + i + 3] = 0x0; } // blit frame memcpy(vga_getgraphmem(), screens[0], SCREENWIDTH * SCREENHEIGHT); // sleep a bit if there was no sound update if (!snd_updated) { I_WaitVBL(1); } }
static void R_ShowStats(void) { #define KEEPTIMES 10 static int keeptime[KEEPTIMES], showtime; #ifdef INTERNETC static int cnt; #endif int now = I_GetTime(); if (now - showtime > 35) { doom_printf("Frame rate %d fps\nSegs %d, Visplanes %d, Sprites %d", (35*KEEPTIMES)/(now - keeptime[0]), rendered_segs, rendered_visplanes, rendered_vissprites); #ifdef INTERNETC if(cnt==5){ cnt=0; printf("Frame rate %d fps Segs %d, Visplanes %d, Sprites %d\n", (35*KEEPTIMES)/(now - keeptime[0]), rendered_segs, rendered_visplanes, rendered_vissprites); } ++cnt; #endif showtime = now; } memmove(keeptime, keeptime+1, sizeof(keeptime[0]) * (KEEPTIMES-1)); keeptime[KEEPTIMES-1] = now; }
// // V_TextFPSDrawer // void V_TextFPSDrawer(void) { static char fpsStr[16]; static int fhistory[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; static int lasttic = 0, slot = 0; vfont_t *font; float fps = 0; int i, thistic, totaltics = 0; thistic = I_GetTime(); fhistory[slot & 15] = thistic != lasttic ? thistic - lasttic : 1; slot++; for(i = 0; i < 16; i++) totaltics += fhistory[i]; if(totaltics) fps = (float)TICRATE / (totaltics / 16.0f); psnprintf(fpsStr, sizeof(fpsStr), FC_GRAY "FPS: %.2f", fps); lasttic = thistic; font = E_FontForName("ee_smallfont"); V_FontWriteText(font, fpsStr, 5, 10); }
boolean Net_GetNetStat(void) { const tic_t t = I_GetTime(); static INT64 oldsendbyte = 0; if (statstarttic+STATLENGTH <= t) { const tic_t df = t-statstarttic; const INT64 newsendbyte = sendbytes - oldsendbyte; sendbps = (INT32)(newsendbyte*TICRATE)/df; getbps = (getbytes*TICRATE)/df; if (sendackpacket) lostpercent = 100.0f*(float)retransmit/(float)sendackpacket; else lostpercent = 0.0f; if (getackpacket) duppercent = 100.0f*(float)duppacket/(float)getackpacket; else duppercent = 0.0f; if (ticruned) gamelostpercent = 100.0f*(float)ticmiss/(float)ticruned; else gamelostpercent = 0.0f; ticmiss = ticruned = 0; oldsendbyte = sendbytes; getbytes = 0; sendackpacket = getackpacket = duppacket = retransmit = 0; statstarttic = t; return 1; } return 0; }
void ST_DrawFPS(int offset) { static int frames; static int lasttick=0; static int fps; int ticks; int n; ticks = I_GetTime(); if(!lasttick) { lasttick = ticks; frames = fps = 0; } frames++; if(ticks - lasttick >= TICRATE) { lasttick = ticks; fps = frames; frames = 0; if(fps > 99) { fps = 99; } } n = fps; Draw_Text(0, offset, WHITE, 0.35f, false, "FPS: %i", n); }
void SCR_DisplayTicRate(void) { tic_t i; tic_t ontic = I_GetTime(); tic_t totaltics = 0; INT32 ticcntcolor = 0; for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) fpsgraph[i % TICRATE] = false; fpsgraph[ontic % TICRATE] = true; for (i = 0;i < TICRATE;++i) if (fpsgraph[i]) ++totaltics; if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; V_DrawString(vid.width-(24*vid.dupx), vid.height-(16*vid.dupy), V_YELLOWMAP|V_NOSCALESTART, "FPS"); V_DrawString(vid.width-(40*vid.dupx), vid.height-( 8*vid.dupy), ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE)); lasttic = ontic; }
void D_WipeDraw() { int wipestart; boolean done; wipestart = I_GetTime () - 1; // MIKE 11/08 don't busy wait here during wipes, let Flash update /* do { do { nowtime = I_GetTime (); tics = nowtime - wipestart; } while (!tics); wipestart = nowtime;*/ done = wipe_ScreenWipe(wipe_Melt , 0, 0, SCREENWIDTH, SCREENHEIGHT, 1); if(done)wipe = false; // MIKE 11/08 I_UpdateNoBlit (); M_Drawer (); // menu is drawn even on top of wipes I_FinishUpdate (); // page flip or blit buffer //} while (!done); }
// // D_ProcessEvents // Send all the events of the given timestamp down the responder chain // void D_ProcessEvents (void) { event_t *ev; // [RH] If testing mode, do not accept input until test is over if (testingmode) { if (testingmode <= I_GetTime()) { M_RestoreMode (); } else { M_ModeFlashTestText(); } return; } for (; eventtail != eventhead ; eventtail = ++eventtail<MAXEVENTS ? eventtail : 0) { ev = &events[eventtail]; if (C_Responder (ev)) continue; // console ate the event if (M_Responder (ev)) continue; // menu ate the event G_Responder (ev); } }
// // D_DoomLoop // void D_DoomLoop (void) { while (1) { try { SV_RunTics (); // will run at least one tic } catch (CRecoverableError &error) { Printf (PRINT_HIGH, "ERROR: %s\n", error.GetMessage().c_str()); Printf (PRINT_HIGH, "sleeping for 10 seconds before map reload..."); // denis - drop clients SV_SendDisconnectSignal(); // denis - sleep to conserve server resources (in case of recurring problem) I_WaitForTic(I_GetTime() + 1000*10/TICRATE); // denis - reload with current settings G_ChangeMap (); // denis - todo - throw I_FatalError if this keeps happening } } }
static void NET_SDL_SendPacket(net_addr_t *addr, net_packet_t *packet) { UDPpacket sdl_packet; IPaddress ip; if (addr == &net_broadcast_addr) { SDLNet_ResolveHost(&ip, NULL, port); ip.host = INADDR_BROADCAST; } else { ip = *((IPaddress *) addr->handle); } #if 0 { static int this_second_sent = 0; static int lasttime; this_second_sent += packet->len + 64; if (I_GetTime() - lasttime > TICRATE) { printf("%i bytes sent in the last second\n", this_second_sent); lasttime = I_GetTime(); this_second_sent = 0; } } #endif #ifdef DROP_PACKETS if ((rand() % 4) == 0) return; #endif sdl_packet.channel = 0; sdl_packet.data = packet->data; sdl_packet.len = packet->len; sdl_packet.address = ip; if (!SDLNet_UDP_Send(udpsocket, -1, &sdl_packet)) { I_Error("NET_SDL_SendPacket: Error transmitting packet: %s", SDLNet_GetError()); } }
// resend the data if needed void Net_AckTicker(void) { #ifndef NONET INT32 i; for (i = 0; i < MAXACKPACKETS; i++) { const INT32 nodei = ackpak[i].destinationnode; node_t *node = &nodes[nodei]; #ifdef NEWPING if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime()) #else if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime()) #endif { if (ackpak[i].resentnum > 10 && (node->flags & CLOSE)) { DEBFILE(va("ack %d sent 10 times so connection is supposed lost: node %d\n", i, nodei)); Net_CloseConnection(nodei | FORCECLOSE); ackpak[i].acknum = 0; continue; } #ifdef NEWPING DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime, NODETIMEOUT, I_GetTime())); #else DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime, node->timeout, I_GetTime())); #endif M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length); ackpak[i].senttime = I_GetTime(); ackpak[i].resentnum++; ackpak[i].nextacknum = node->nextacknum; retransmit++; // for stat HSendPacket((INT32)(node - nodes), false, ackpak[i].acknum, (size_t)(ackpak[i].length - BASEPACKETSIZE)); } } for (i = 1; i < MAXNETNODES; i++) { // this is something like node open flag if (nodes[i].firstacktosend) { // we haven't sent a packet for a long time // acknowledge packet if needed if (nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime()) Net_SendAcks(i); if (!(nodes[i].flags & CLOSE) && nodes[i].lasttimepacketreceived + connectiontimeout < I_GetTime()) { Net_ConnectionTimeout(i); } } } #endif }
void I_GetTime_SaveMS(void) { if (!movement_smooth) return; tic_vars.start = I_GetTime(); // SDL_GetTicks(); tic_vars.next = (unsigned int) ((tic_vars.start * tic_vars.msec + 1.0f) / tic_vars.msec); tic_vars.step = tic_vars.next - tic_vars.start;
// // CheckAbort // void CheckAbort (void) { event_t *ev; int stoptic; stoptic = I_GetTime () + 2; while (I_GetTime() < stoptic) I_StartTic (); I_StartTic (); for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) ) { ev = &events[eventtail]; if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE) I_Error ("Network game synchronization aborted."); } }
boolean I_StartDisplay(void) { if (InDisplay) return false; start_displaytime = I_GetTime(); //DL_GetTicks(); InDisplay = true; return true;
// wait for all ackreturns with timeout in seconds void Net_WaitAllAckReceived(UINT32 timeout) { #ifdef NONET (void)timeout; #else tic_t tictac = I_GetTime(); timeout = tictac + timeout*NEWTICRATE; HGetPacket(); while (timeout > I_GetTime() && !Net_AllAckReceived()) { while (tictac == I_GetTime()) I_Sleep(); tictac = I_GetTime(); HGetPacket(); Net_AckTicker(); } #endif }
// // I_FinishUpdate // void I_FinishUpdate (void) { static int lasttic; int tics; int i; // UNUSED static unsigned char *bigscreen=0; if (!initialized) return; if (noblit) return; UpdateGrab(); // Don't update the screen if the window isn't visible. // Not doing this breaks under Windows when we alt-tab away // while fullscreen. if (!(SDL_GetAppState() & SDL_APPACTIVE)) return; // draws little dots on the bottom of the screen if (devparm) { i = I_GetTime(); tics = i - lasttic; lasttic = i; if (tics > 20) tics = 20; for (i=0 ; i<tics*2 ; i+=4) screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff; for ( ; i<20*4 ; i+=4) screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0; } // draw to screen BlitArea(0, 0, SCREENWIDTH, SCREENHEIGHT); // If we have a palette to set, the act of setting the palette // updates the screen if (palette_to_set) { SDL_SetColors(screen, palette, 0, 256); palette_to_set = false; } else { SDL_Flip(screen); } }
// return a free acknum and copy netbuffer in the ackpak table static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) { node_t *node = &nodes[doomcom->remotenode]; INT32 i, numfreeslote = 0; if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0) { DEBFILE(va("too fast %d %d\n",node->remotefirstack,node->nextacknum)); return false; } for (i = 0; i < MAXACKPACKETS; i++) if (!ackpak[i].acknum) { // for low priority packet, make sure let freeslotes so urgents packets can be sent numfreeslote++; if (netbuffer->packettype >= PT_CANFAIL && numfreeslote < URGENTFREESLOTENUM) continue; ackpak[i].acknum = node->nextacknum; ackpak[i].nextacknum = node->nextacknum; node->nextacknum++; if (!node->nextacknum) node->nextacknum++; ackpak[i].destinationnode = (UINT8)(node - nodes); ackpak[i].length = doomcom->datalength; if (lowtimer) { // lowtime mean can't be sent now so try it soon as possible ackpak[i].senttime = 0; ackpak[i].resentnum = 1; } else { ackpak[i].senttime = I_GetTime(); ackpak[i].resentnum = 0; } M_Memcpy(ackpak[i].pak.raw, netbuffer, ackpak[i].length); *freeack = ackpak[i].acknum; sendackpacket++; // for stat return true; } #ifdef PARANOIA if (devparm) I_OutputMsg("No more free ackpacket\n"); #endif if (netbuffer->packettype < PT_CANFAIL) I_Error("Connection lost\n"); return false; }
static void tryruntics(void) { int runtics; int entertime = I_GetTime(); while (1) { D_BuildNewTiccmds(); runtics = maketic - gametic; if (runtics) break; I_uSleep(ms_to_next_tick * 1000); if (I_GetTime() - entertime > 10) { M_Ticker(); return; } } while (runtics--) { M_Ticker(); G_Ticker(); gametic++; } }
void D_BuildNewTiccmds(void) { static int lastmadetic; int newtics = I_GetTime() - lastmadetic; lastmadetic += newtics; while (newtics--) { I_StartTic(); if (maketic - gametic > BACKUPTICS/2) break; G_BuildTiccmd(&localcmds[maketic%BACKUPTICS]); maketic++; } }
static void D_Wipe(void) { boolean done; int wipestart = I_GetTime () - 1; do { int nowtime, tics; do { //I_uSleep(5000); // CPhipps - don't thrash cpu in this loop nowtime = I_GetTime(); tics = nowtime - wipestart; } while (!tics); wipestart = nowtime; done = wipe_ScreenWipe(0,0,SCREENWIDTH,SCREENHEIGHT,tics); M_Drawer(); // menu is drawn even on top of wipes I_FinishUpdate(); // page flip or blit buffer } while (!done); }
static inline void Net_ConnectionTimeout(INT32 node) { // send a very special packet to self (hack the reboundstore queue) // main code will handle it reboundstore[rebound_head].packettype = PT_NODETIMEOUT; reboundstore[rebound_head].ack = 0; reboundstore[rebound_head].ackreturn = 0; reboundstore[rebound_head].u.textcmd[0] = (UINT8)node; reboundsize[rebound_head] = (INT16)(BASEPACKETSIZE + 1); rebound_head = (rebound_head+1) % MAXREBOUND; // do not redo it quickly (if we do not close connection it is // for a good reason!) nodes[node].lasttimepacketreceived = I_GetTime(); }
static void R_ShowStats(void) { #define KEEPTIMES 10 static int keeptime[KEEPTIMES], showtime; int now = I_GetTime(); if (now - showtime > 35) { #ifdef GL_DOOM doom_printf("Frame rate %d fps\nWalls %d, Flats %d, Sprites %d", #else doom_printf("Frame rate %d fps\nSegs %d, Visplanes %d, Sprites %d", #endif (35*KEEPTIMES)/(now - keeptime[0]), rendered_segs, rendered_visplanes, rendered_vissprites); showtime = now; }
// // I_FinishUpdate // void I_FinishUpdate (void) { // draws little dots on the bottom of the screen (frame rate) if (devparm) { static int lasttic = 0; int curtic = I_GetTime(); int tics = curtic - lasttic; lasttic = curtic; if (tics > 20) { tics = 20; } int i; for (i=0 ; i<tics*2 ; i+=2) { screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff; } for ( ; i<20*2 ; i+=2) { screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0; } } if (sel4doom_imgId != -1) { sel4doom_diplay_ppm(sel4doom_imgId); } // ------------------------ if (multiply == 1) { unsigned int *src = (unsigned int *) screens[0]; unsigned int *dst = sel4doom_fb; for (int y = SCREENHEIGHT; y; y--) { for (int x = SCREENWIDTH; x; x -= 4) { /* We process four pixels per iteration. */ unsigned int fourpix = *src++; //first "src" pixel *dst++ = sel4doom_colors32[fourpix & 0xff]; //second "src" pixel *dst++ = sel4doom_colors32[(fourpix >> 8) & 0xff]; //third "src" pixel *dst++ = sel4doom_colors32[(fourpix >> 16) & 0xff]; //fourth "src" pixel *dst++ = sel4doom_colors32[fourpix >> 24]; } dst += row_offset; } return; }