From 96ed7fa8270a0c22878967b210378fcc75164c96 Mon Sep 17 00:00:00 2001 From: zicodxx <> Date: Mon, 21 Apr 2008 18:39:49 +0000 Subject: [PATCH] Reworked timer_delay2() and calc_frame_time() to be more accurate and CPU-friendly; -nicefps replayced by -nonicefps to disable sleeping for calc_frame_time; Implemented VSync via SDL; Fixed compilation issues; Code cleanup --- CHANGELOG.txt | 4 +++ arch/ogl/gr.c | 1 + arch/sdl/timer.c | 21 +++++--------- arch/win32/netdrv_ipx.c | 13 +++++---- d1x.ini | 2 +- main/config.c | 5 ++++ main/config.h | 1 + main/console.c | 2 +- main/custom.c | 3 +- main/game.c | 61 ++++++----------------------------------- main/gamesave.c | 18 +----------- main/inferno.c | 3 +- main/menu.c | 18 ++++++------ misc/args.c | 2 +- 14 files changed, 51 insertions(+), 103 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 98ba1f3c7..0df808210 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D1X-Rebirth Changelog +20080421 +-------- +main/console.c, main/custom.c, main/inferno.c, main/menu.c, main/gamesave.c, main/config.c, main/config.h, main/game.c, misc/args.c, d1x.ini, arch/ogl/gr.c, arch/sdl/timer.c, arch/win32/netdrv_ipx.c: Reworked timer_delay2() and calc_frame_time() to be more accurate and CPU-friendly; -nicefps replayced by -nonicefps to disable sleeping for calc_frame_time; Implemented VSync via SDL; Fixed compilation issues; Code cleanup + 20080419 -------- include/ogl_init.h, include/gr.h, include/strutil.h, include/internal.h, main/network.c, main/menu.c, main/game.c, d1x-rebirth.xcodeproj/project.pbxproj, SConstruct, arch/ogl/ogl.c, arch/ogl/gr.c, arch/sdl/joy.c, arch/sdl/gr.c, arch/carbon/conf.h: Made joy_flush also resetting button state; Improved glReticle; Implemented Fallback resolution if SDL may fail; Code cleanup diff --git a/arch/ogl/gr.c b/arch/ogl/gr.c index 6687647a0..0fba7c2e4 100644 --- a/arch/ogl/gr.c +++ b/arch/ogl/gr.c @@ -326,6 +326,7 @@ int gr_init(int mode) SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,0); SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE,0); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL,GameCfg.VSync); ogl_init_texture_list_internal(); diff --git a/arch/sdl/timer.c b/arch/sdl/timer.c index a80d1773f..9228dc0b8 100644 --- a/arch/sdl/timer.c +++ b/arch/sdl/timer.c @@ -1,9 +1,7 @@ -/* $Id: timer.c,v 1.1.1.1 2006/03/17 19:53:40 zicodxx Exp $ */ /* * * SDL library timer functions * - * */ #ifdef HAVE_CONFIG_H @@ -36,19 +34,14 @@ void timer_delay(fix seconds) // Replacement for timer_delay which considers calc time the program needs between frames (not reentrant) void timer_delay2(int fps) { - static u_int32_t last_render_time=0; + static u_int32_t FrameStart=0; + u_int32_t FrameLoop=0; - if (last_render_time > SDL_GetTicks()) // Fallback for SDL_GetTicks() wraparound - last_render_time = 0; - else + while (FrameLoop < 1000/fps) { - int FrameDelay = (1000/fps) // ms to pause between frames for desired FPS rate - - (SDL_GetTicks()-last_render_time)/(F1_0/1000) // Substract the time the game needs to do it's operations - - 10; // Substract 10ms inaccuracy due to OS scheduling - - if (FrameDelay > 0) - SDL_Delay(FrameDelay); - - last_render_time = SDL_GetTicks(); + SDL_Delay(1); + FrameLoop=SDL_GetTicks()-FrameStart; } + + FrameStart=SDL_GetTicks(); } diff --git a/arch/win32/netdrv_ipx.c b/arch/win32/netdrv_ipx.c index 6c9a0b362..d66ea6fdc 100644 --- a/arch/win32/netdrv_ipx.c +++ b/arch/win32/netdrv_ipx.c @@ -5,6 +5,7 @@ #include #include #include "netdrv.h" +#include "console.h" static socket_t IPX_sock; @@ -34,7 +35,7 @@ static int IPXOpenSocket(int port) sock = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX); if (sock == -1) { - con_printf(CON_URGENT,"IPX: could not open IPX socket.\n")); + con_printf(CON_URGENT,"IPX: could not open IPX socket.\n"); return -1; } @@ -42,7 +43,7 @@ static int IPXOpenSocket(int port) /* Permit broadcast output */ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST,(const char *)&opt, sizeof(opt)) == -1) { - con_printf(CON_URGENT,"IPX: could not set socket option for broadcast.\n")); + con_printf(CON_URGENT,"IPX: could not set socket option for broadcast.\n"); return -1; } @@ -55,7 +56,7 @@ static int IPXOpenSocket(int port) /* now bind to this port */ if (bind(sock, (struct sockaddr *) &ipxs, sizeof(ipxs)) == -1) { - con_printf(CON_URGENT,"IPX: could not bind socket to address\n")); + con_printf(CON_URGENT,"IPX: could not bind socket to address\n"); closesocket( sock ); return -1; } @@ -63,7 +64,7 @@ static int IPXOpenSocket(int port) len = sizeof(ipxs2); if (getsockname(sock,(struct sockaddr *)&ipxs2,&len) < 0) { - con_printf(CON_URGENT,"IPX: could not get socket name in IPXOpenSocket\n")); + con_printf(CON_URGENT,"IPX: could not get socket name in IPXOpenSocket\n"); closesocket( sock ); return -1; } @@ -71,7 +72,7 @@ static int IPXOpenSocket(int port) if (port == 0) { port = htons(ipxs2.sa_socket); - con_printf(CON_URGENT,"IPX: opened dynamic socket %04x\n", port)); + con_printf(CON_URGENT,"IPX: opened dynamic socket %04x\n", port); } memcpy(MyAddress, ipxs2.sa_netnum, 4); @@ -88,7 +89,7 @@ static int IPXOpenSocket(int port) static void IPXCloseSocket(void) { /* now close the file descriptor for the socket, and free it */ - con_printf(CON_URGENT,"IPX: closing file descriptor on socket %x\n", IPX_sock.socket)); + con_printf(CON_URGENT,"IPX: closing file descriptor on socket %x\n", IPX_sock.socket); closesocket(IPX_sock.fd); WSACleanup(); } diff --git a/d1x.ini b/d1x.ini index d5ba45b54..c26d7c407 100644 --- a/d1x.ini +++ b/d1x.ini @@ -1,7 +1,7 @@ System Options: ;-fps Enable FPS indicator by default -;-nicefps Free CPU-cycles. Less CPU load, but game may become choppy +;-nonicefps Don't free CPU-cycles ;-maxfps Set maximum framerate (1-80) ;-hogdir set shared data directory to ;-nohogdir Don't try to use shared data directory diff --git a/main/config.c b/main/config.c index 2c0a94f13..e67c8a34d 100644 --- a/main/config.c +++ b/main/config.c @@ -52,6 +52,7 @@ static char *AspectXStr="AspectX"; static char *AspectYStr="AspectY"; static char *WindowModeStr="WindowMode"; static char *TexFiltStr="TexFilt"; +static char *VSyncStr="VSync"; int ReadConfigFile() { @@ -71,6 +72,7 @@ int ReadConfigFile() GameCfg.AspectY = 4; GameCfg.WindowMode = 0; GameCfg.TexFilt = 0; + GameCfg.VSync = 0; infile = PHYSFSX_openReadBuffered("descent.cfg"); @@ -124,6 +126,8 @@ int ReadConfigFile() GameCfg.WindowMode = strtol(value, NULL, 10); else if (!strcmp(token, TexFiltStr)) GameCfg.TexFilt = strtol(value, NULL, 10); + else if (!strcmp(token, VSyncStr)) + GameCfg.VSync = strtol(value, NULL, 10); } } @@ -164,6 +168,7 @@ int WriteConfigFile() PHYSFSX_printf(infile, "%s=%i\n", AspectYStr, GameCfg.AspectY); PHYSFSX_printf(infile, "%s=%i\n", WindowModeStr, GameCfg.WindowMode); PHYSFSX_printf(infile, "%s=%i\n", TexFiltStr, GameCfg.TexFilt); + PHYSFSX_printf(infile, "%s=%i\n", VSyncStr, GameCfg.VSync); PHYSFS_close(infile); diff --git a/main/config.h b/main/config.h index 9e6e2d425..cd81db168 100644 --- a/main/config.h +++ b/main/config.h @@ -38,6 +38,7 @@ typedef struct Cfg int AspectY; int WindowMode; int TexFilt; + int VSync; } __attribute__ ((packed)) Cfg; extern struct Cfg GameCfg; diff --git a/main/console.c b/main/console.c index 12eb05e31..68666679a 100644 --- a/main/console.c +++ b/main/console.c @@ -96,7 +96,7 @@ void con_printf(int priority, char *fmt, ...) t=time(NULL); lt=localtime(&t); PHYSFSX_printf(gamelog_fp,"%02i:%02i:%02i ",lt->tm_hour,lt->tm_min,lt->tm_sec); - PHYSFSX_printf(gamelog_fp,"%s",buffer); + PHYSFSX_printf(gamelog_fp,"%s\n",buffer); } } } diff --git a/main/custom.c b/main/custom.c index 8c7441b44..dc0c0516e 100644 --- a/main/custom.c +++ b/main/custom.c @@ -230,7 +230,8 @@ int load_pigpog(char *pogname) { ubyte *p; CFILE *f; struct custom_info *custom_info, *cip; - int i, j, x, rc = -1; + int i, j, rc = -1; + unsigned int x = 0; if (!(f = cfopen((char *)pogname, "rb"))) return -1; // pog file doesn't exist diff --git a/main/game.c b/main/game.c index 29b1db498..6a93e6684 100644 --- a/main/game.c +++ b/main/game.c @@ -154,7 +154,6 @@ grs_canvas VR_editor_canvas; // The canvas that the editor writes to. grs_canvas *VR_offscreen_menu = NULL; // The offscreen data buffer for menus //end additions -- adb -int Debug_pause=0; //John's debugging pause system static int old_cockpit_mode=-1; int force_cockpit_redraw=0; int netplayerinfo_on=0; @@ -165,10 +164,6 @@ int *Toggle_var = &Dummy_var; char faded_in; #endif -#ifndef NDEBUG //these only exist if debugging -fix fixed_frametime=0; //if non-zero, set frametime to this -#endif - int Game_suspended=0; //if non-zero, nothing moves but player int create_special_path(void); void fill_background(int x,int y,int w,int h,int dx,int dy); @@ -756,30 +751,21 @@ void reset_time() void calc_frame_time() { + static u_int32_t FrameStart=0; + u_int32_t FrameLoop=0; fix timer_value,last_frametime = FrameTime; - timer_value = timer_get_fixed_seconds(); - FrameTime = timer_value - last_timer_value; - - // sleep for one frame to free CPU cycles if GameArg.SysUseNiceFPS is active. - if (GameArg.SysUseNiceFPS) - timer_delay2(GameArg.SysMaxFPS); - - while (FrameTime < f1_0 / GameArg.SysMaxFPS) + while (FrameLoop < 1000/GameArg.SysMaxFPS) { - timer_value = timer_get_fixed_seconds(); - FrameTime = timer_value - last_timer_value; + if (GameArg.SysUseNiceFPS) + SDL_Delay(1); + FrameLoop=SDL_GetTicks()-FrameStart; } -#ifndef NDEBUG - if (!(((FrameTime > 0) && (FrameTime <= F1_0)) || (Function_mode == FMODE_EDITOR) || (Newdemo_state == ND_STATE_PLAYBACK))) { - if (FrameTime == 0) - { - FrameTime = 1; - } + FrameStart=SDL_GetTicks(); - } -#endif + timer_value = i2f(FrameStart/1000) | fixdiv(i2f(FrameStart % 1000),i2f(1000)); + FrameTime = timer_value - last_timer_value; if ( Game_turbo_mode ) FrameTime *= 2; @@ -788,26 +774,6 @@ void calc_frame_time() if (FrameTime < 0) //if bogus frametime... FrameTime = last_frametime; //...then use time from last frame - -#ifndef NDEBUG - if (fixed_frametime) FrameTime = fixed_frametime; -#endif - -#ifndef NDEBUG - // Pause here!!! - if ( Debug_pause ) { - int c; - c = 0; - while( c==0 ) - c = key_peekkey(); - - if ( c == KEY_P ) { - Debug_pause = 0; - c = key_inkey(); - } - last_timer_value = timer_get_fixed_seconds(); - } -#endif } void move_player_2_segment(segment *seg,int side) @@ -899,14 +865,6 @@ extern fix Cruise_speed; void game_draw_hud_stuff() { - #ifndef NDEBUG - if (Debug_pause) { - gr_set_curfont( GAME_FONT ); - gr_set_fontcolor( BM_XRGB(31, 31, 31), -1 ); - gr_printf( 0x8000, (SHEIGHT/10), "Debug Pause - Press P to exit" ); - } - #endif - #ifdef CROSSHAIR if ( Viewer->type == OBJ_PLAYER ) laser_do_crosshair(Viewer); @@ -2354,7 +2312,6 @@ void HandleGameKey(int key) break; case KEY_DEBUGGED+KEY_COMMA: Render_zoom = fixmul(Render_zoom,62259); break; case KEY_DEBUGGED+KEY_PERIOD: Render_zoom = fixmul(Render_zoom,68985); break; - case KEY_DEBUGGED+KEY_P+KEY_SHIFTED: Debug_pause = 1; break; case KEY_DEBUGGED+KEY_F8: speedtest_init(); Speedtest_count = 1; break; case KEY_DEBUGGED+KEY_F9: speedtest_init(); Speedtest_count = 10; break; case KEY_DEBUGGED+KEY_D: diff --git a/main/gamesave.c b/main/gamesave.c index aa670a109..11ef833ff 100644 --- a/main/gamesave.c +++ b/main/gamesave.c @@ -1057,23 +1057,7 @@ int load_game_data(CFILE *LoadFile) } //================ READ CONTROL CENTER TRIGGER INFO =============== - - if (game_fileinfo.control_offset > -1) - { - if (!cfseek( LoadFile, game_fileinfo.control_offset,SEEK_SET )) { - for (i=0;i %s\n", "Set maximum framerate (1-80)"); printf( " -hogdir %s\n", "Set shared data directory to "); printf( " -nohogdir %s\n", "Don't try to use shared data directory"); @@ -227,7 +227,6 @@ void sdl_close() SDL_Quit(); } -extern fix fixed_frametime; extern void vfx_set_palette_sub(ubyte *); int MacHog = 0; // using a Mac hogfile? #define PROGNAME argv[0] diff --git a/main/menu.c b/main/menu.c index 298fa85e8..8619a4c16 100644 --- a/main/menu.c +++ b/main/menu.c @@ -612,19 +612,20 @@ void input_config() void do_graphics_menu() { - newmenu_item m[9]; + newmenu_item m[10]; int i = 0, j = 0; do { m[0].type = NM_TYPE_TEXT; m[0].text="Texture Filtering:"; - m[1].type = NM_TYPE_TEXT; m[1].text=" (Requires Game Restart)"; - m[2].type = NM_TYPE_RADIO; m[2].text = "None (Classical)"; m[2].value = 0; m[2].group = 0; - m[3].type = NM_TYPE_RADIO; m[3].text = "Bilinear"; m[3].value = 0; m[3].group = 0; - m[4].type = NM_TYPE_RADIO; m[4].text = "Trilinear"; m[4].value = 0; m[4].group = 0; + m[1].type = NM_TYPE_TEXT; m[1].text=" (requires restart)"; + m[2].type = NM_TYPE_RADIO; m[2].text = "None (Classical)"; m[2].value = 0; m[2].group = 0; + m[3].type = NM_TYPE_RADIO; m[3].text = "Bilinear"; m[3].value = 0; m[3].group = 0; + m[4].type = NM_TYPE_RADIO; m[4].text = "Trilinear"; m[4].value = 0; m[4].group = 0; m[5].type = NM_TYPE_TEXT; m[5].text=""; - m[6].type = NM_TYPE_CHECK; m[6].text="Transparency Effects"; m[6].value = PlayerCfg.OglAlphaEffects; - m[7].type = NM_TYPE_CHECK; m[7].text="Vectorial Reticle"; m[7].value = PlayerCfg.OglReticle; - m[8].type = NM_TYPE_CHECK; m[8].text="Screenshots w/o HUD"; m[8].value = PlayerCfg.OglPRShot; + m[6].type = NM_TYPE_CHECK; m[6].text="Transparency Effects"; m[6].value = PlayerCfg.OglAlphaEffects; + m[7].type = NM_TYPE_CHECK; m[7].text="Vectorial Reticle"; m[7].value = PlayerCfg.OglReticle; + m[8].type = NM_TYPE_CHECK; m[8].text="Screenshots w/o HUD"; m[8].value = PlayerCfg.OglPRShot; + m[9].type = NM_TYPE_CHECK; m[9].text="VSync (requires restart)"; m[9].value = GameCfg.VSync; m[GameCfg.TexFilt+2].value=1; @@ -636,6 +637,7 @@ void do_graphics_menu() PlayerCfg.OglAlphaEffects = m[6].value; PlayerCfg.OglReticle = m[7].value; PlayerCfg.OglPRShot = m[8].value; + GameCfg.VSync = m[9].value; } while( i>-1 ); } diff --git a/misc/args.c b/misc/args.c index 13f6d968d..e71914ec8 100644 --- a/misc/args.c +++ b/misc/args.c @@ -125,7 +125,7 @@ void ReadCmdArgs(void) GameArg.SysShowCmdHelp = (FindArg( "-help" ) || FindArg( "-h" ) || FindArg( "-?" ) || FindArg( "?" )); GameArg.SysFPSIndicator = FindArg("-fps"); - GameArg.SysUseNiceFPS = FindArg("-nicefps"); + GameArg.SysUseNiceFPS = !FindArg("-nonicefps"); GameArg.SysMaxFPS = get_int_arg("-maxfps", MAXIMUM_FPS); if (GameArg.SysMaxFPS <= 0 || GameArg.SysMaxFPS > MAXIMUM_FPS)