Files
fs2open.github.com/code/io/timer.cpp
T
asarium 7e77b5a67c Merge branch 'master' into antipodes
Conflicts:
	.gitignore
	code/Makefile.am
	code/ai/ai.h
	code/ai/ai_profiles.cpp
	code/ai/ai_profiles.h
	code/ai/aibig.cpp
	code/ai/aicode.cpp
	code/ai/aiturret.cpp
	code/asteroid/asteroid.cpp
	code/asteroid/asteroid.h
	code/bmpman/bm_internal.h
	code/bmpman/bmpman.cpp
	code/bmpman/bmpman.h
	code/camera/camera.cpp
	code/camera/camera.h
	code/cfile/cfile.cpp
	code/cmdline/cmdline.cpp
	code/cmdline/cmdline.h
	code/controlconfig/controlsconfig.h
	code/controlconfig/controlsconfigcommon.cpp
	code/cutscene/movie.cpp
	code/cutscene/oggplayer.cpp
	code/debugconsole/consoleparse.cpp
	code/fred2/campaigneditordlg.cpp
	code/fred2/fred.cpp
	code/fred2/fred.rc
	code/fred2/missionsave.cpp
	code/fred2/resource.h
	code/fred2/sexp_tree.cpp
	code/fred2/sexp_tree.h
	code/fred2/shipflagsdlg.cpp
	code/fred2/shipflagsdlg.h
	code/fred2/shiptexturesdlg.cpp
	code/fred2/voiceactingmanager.cpp
	code/freespace2/freespace.cpp
	code/freespace2/freespace.rc
	code/gamehelp/contexthelp.cpp
	code/globalincs/alphacolors.cpp
	code/globalincs/alphacolors.h
	code/globalincs/version.h
	code/globalincs/vmallocator.h
	code/globalincs/windebug.cpp
	code/graphics/2d.cpp
	code/graphics/font.cpp
	code/graphics/generic.cpp
	code/graphics/generic.h
	code/graphics/grinternal.h
	code/graphics/gropengl.cpp
	code/graphics/gropengldraw.cpp
	code/graphics/gropenglextension.h
	code/graphics/gropenglpostprocessing.cpp
	code/graphics/gropenglstate.cpp
	code/graphics/gropenglstate.h
	code/graphics/gropengltexture.cpp
	code/graphics/gropengltnl.cpp
	code/hud/hud.cpp
	code/hud/hud.h
	code/hud/hudconfig.cpp
	code/hud/hudlock.cpp
	code/hud/hudmessage.cpp
	code/hud/hudparse.cpp
	code/hud/hudreticle.cpp
	code/hud/hudreticle.h
	code/hud/hudshield.cpp
	code/hud/hudsquadmsg.cpp
	code/hud/hudtarget.cpp
	code/hud/hudtarget.h
	code/hud/hudtargetbox.cpp
	code/inetfile/cftp.cpp
	code/inetfile/chttpget.cpp
	code/io/joy.cpp
	code/io/joy_ff.cpp
	code/io/key.cpp
	code/io/keycontrol.cpp
	code/io/mouse.cpp
	code/io/timer.cpp
	code/localization/localize.cpp
	code/localization/localize.h
	code/math/fvi.cpp
	code/math/vecmat.cpp
	code/menuui/credits.cpp
	code/menuui/mainhallmenu.cpp
	code/menuui/mainhallmenu.h
	code/menuui/optionsmenumulti.cpp
	code/menuui/playermenu.cpp
	code/mission/missionbriefcommon.cpp
	code/mission/missioncampaign.cpp
	code/mission/missiongoals.h
	code/mission/missionmessage.cpp
	code/mission/missionparse.cpp
	code/mission/missionparse.h
	code/missionui/missionbrief.cpp
	code/missionui/missioncmdbrief.cpp
	code/missionui/missiondebrief.cpp
	code/missionui/missionscreencommon.cpp
	code/missionui/missionshipchoice.cpp
	code/missionui/missionweaponchoice.cpp
	code/missionui/redalert.cpp
	code/missionui/redalert.h
	code/mod_table/mod_table.cpp
	code/mod_table/mod_table.h
	code/model/model.h
	code/model/modelcollide.cpp
	code/model/modelinterp.cpp
	code/model/modelread.cpp
	code/network/multi.cpp
	code/network/multi_dogfight.cpp
	code/network/multi_ingame.cpp
	code/network/multi_log.cpp
	code/network/multi_rate.cpp
	code/network/multiteamselect.cpp
	code/network/multiui.cpp
	code/network/multiutil.cpp
	code/network/stand_gui-unix.cpp
	code/object/collideshipship.cpp
	code/object/collideshipweapon.cpp
	code/object/object.cpp
	code/object/object.h
	code/object/objectsnd.cpp
	code/object/objectsort.cpp
	code/osapi/osapi.cpp
	code/osapi/osapi_unix.cpp
	code/osapi/outwnd.h
	code/parse/generic_log.cpp
	code/parse/lua.cpp
	code/parse/parselo.cpp
	code/parse/parselo.h
	code/parse/scripting.cpp
	code/parse/scripting.h
	code/parse/sexp.cpp
	code/parse/sexp.h
	code/physics/physics.cpp
	code/pilotfile/csg.cpp
	code/pilotfile/csg_convert.cpp
	code/pilotfile/pilotfile.cpp
	code/pilotfile/pilotfile_convert.h
	code/playerman/playercontrol.cpp
	code/radar/radardradis.cpp
	code/radar/radardradis.h
	code/radar/radarsetup.cpp
	code/radar/radarsetup.h
	code/ship/ship.cpp
	code/ship/ship.h
	code/ship/shipfx.cpp
	code/ship/shiphit.cpp
	code/sound/audiostr.cpp
	code/sound/ds.cpp
	code/sound/openal.cpp
	code/sound/rtvoice.cpp
	code/sound/sound.cpp
	code/sound/voicerec.cpp
	code/stats/medals.cpp
	code/stats/medals.h
	code/stats/scoring.cpp
	code/ui/ui.h
	code/weapon/beam.cpp
	code/weapon/weapon.h
	code/weapon/weapons.cpp
	code/wxfred2/aboutbox.cpp
	code/wxfred2/campaigneditor.cpp
	code/wxfred2/campaigneditor.h
	code/wxfred2/commandbriefingeditor.cpp
	code/wxfred2/debriefingeditor.cpp
	code/wxfred2/fredframe.cpp
	code/wxfred2/fredframe.h
	code/wxfred2/missionspecseditor.cpp
	code/wxfred2/missionspecseditor.h
	code/wxfred2/voiceactingmanagereditor.cpp
	code/wxfred2/wxfred.xrc
	code/wxfred2/wxfred2.cpp
	code/wxfred2/wxfred2.h
	configure.ac
	fs2open.Doxyfile
	jansson/LICENSE
	jansson/dump.c
	jansson/hashtable.c
	jansson/hashtable.h
	jansson/jansson.h
	jansson/jansson_config.h
	jansson/jansson_private.h
	jansson/load.c
	jansson/memory.c
	jansson/pack_unpack.c
	jansson/strbuffer.c
	jansson/strbuffer.h
	jansson/strconv.c
	jansson/utf.c
	jansson/utf.h
	jansson/value.c
	libpng/png.c
	libpng/png.h
	libpng/pngconf.h
	libpng/pngdebug.h
	libpng/pngerror.c
	libpng/pngget.c
	libpng/pnginfo.h
	libpng/pnglibconf.h
	libpng/pngmem.c
	libpng/pngpread.c
	libpng/pngpriv.h
	libpng/pngread.c
	libpng/pngrio.c
	libpng/pngrtran.c
	libpng/pngrutil.c
	libpng/pngset.c
	libpng/pngstruct.h
	libpng/pngtrans.c
	libpng/pngwio.c
	libpng/pngwrite.c
	libpng/pngwtran.c
	libpng/pngwutil.c
	projects/Eclipse/Freespace2/.project
	projects/MSVC_2005/Fred2.vcproj
	projects/MSVC_2005/Freespace2.sln
	projects/MSVC_2005/Freespace2.vcproj
	projects/MSVC_2005/code.vcproj
	projects/MSVC_2005/wxFRED2.vcproj
	projects/MSVC_2008/Fred2.vcproj
	projects/MSVC_2008/Freespace2.doxproj
	projects/MSVC_2008/Freespace2.vcproj
	projects/MSVC_2008/code.vcproj
	projects/MSVC_2010/Fred2.vcxproj
	projects/MSVC_2010/Freespace2.vcxproj
	projects/MSVC_2010/code.vcxproj
	projects/MSVC_2010/code.vcxproj.filters
	projects/MSVC_2010/wxFRED2.vcxproj
	projects/MSVC_2011/Fred2.vcxproj
	projects/MSVC_2011/Freespace2.vcxproj
	projects/MSVC_2011/code.vcxproj
	projects/MSVC_2011/code.vcxproj.filters
	projects/MSVC_2011/wxFRED2.vcxproj
	projects/MSVC_2013/Fred2.vcxproj
	projects/MSVC_2013/Freespace2.vcxproj
	projects/MSVC_2013/code.vcxproj
	projects/MSVC_2013/code.vcxproj.filters
	projects/MSVC_2013/libjpeg.vcxproj
	projects/MSVC_2013/liblua.vcxproj
	projects/MSVC_2013/libpng.vcxproj
	projects/MSVC_2013/wxFRED2.vcxproj
	projects/MSVC_2013/zlib.vcxproj
	projects/MSVC_6/Fred2.dsp
	projects/MSVC_6/Freespace2.dsp
	projects/MSVC_6/code.dsp
	projects/MSVC_6/wxFRED2.dsp
	projects/Xcode/English.lproj/InfoPlist.strings
	projects/Xcode/FS2_Open.xcodeproj/project.pbxproj
	projects/Xcode4/English.lproj/InfoPlist.strings
	projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj
	projects/Xcode4/Frameworks.tgz
	projects/codeblocks/Freespace2/Freespace2.cbp
	zlib/adler32.c
	zlib/compress.c
	zlib/crc32.c
	zlib/crc32.h
	zlib/deflate.c
	zlib/deflate.h
	zlib/infback.c
	zlib/inffast.c
	zlib/inffixed.h
	zlib/inflate.c
	zlib/inftrees.c
	zlib/trees.c
	zlib/uncompr.c
	zlib/zconf.h
	zlib/zlib.h
	zlib/zutil.c
	zlib/zutil.h
2015-04-25 16:48:43 +02:00

417 lines
7.4 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#include <limits.h>
#include "globalincs/pstypes.h"
#include "io/timer.h"
#include "graphics/2d.h"
#include "globalincs/alphacolors.h"
#define THREADED // to use the proper set of macros
#include "osapi/osapi.h" // for multi-thread macros
#ifndef NDEBUG
#define USE_TIMING
#endif
static int Timer_inited = 0;
static SDL_mutex* Timer_lock;
void timer_close()
{
if ( Timer_inited ) {
Timer_inited = 0;
SDL_DestroyMutex( Timer_lock );
}
}
void timer_init()
{
if ( !Timer_inited ) {
Timer_lock = SDL_CreateMutex();
Timer_inited = 1;
atexit(timer_close);
}
}
static uint timer_get()
{
return SDL_GetTicks();
}
fix timer_get_fixed_seconds()
{
if (!Timer_inited) {
Int3(); // Make sure you call timer_init before anything that uses timer functions!
return 0;
}
longlong a = timer_get();
a *= 65536;
return (fix)(a / 1000);
}
fix timer_get_fixed_secondsX()
{
return timer_get_fixed_seconds();
}
fix timer_get_approx_seconds()
{
return timer_get_fixed_seconds();
}
int timer_get_seconds()
{
if (!Timer_inited) {
Int3();
return 0;
}
return (timer_get() / 1000);
}
int timer_get_milliseconds()
{
if (!Timer_inited) {
Int3(); // Make sure you call timer_init before anything that uses timer functions!
return 0;
}
return timer_get();
}
int timer_get_microseconds()
{
if (!Timer_inited) {
Int3(); // Make sure you call timer_init before anything that uses timer functions!
return 0;
}
return timer_get() * 1000;
}
// 0 means invalid,
// 1 means always return true
// 2 and above actually check the time
int timestamp_ticker = 2;
void timestamp_reset()
{
timestamp_ticker = 2;
}
// Restrict all time values between 0 and MAX_TIME
// so we don't have to use UINTs to calculate rollover.
// For debugging & testing, you could set this to
// something like 1 minute (6000).
#define MAX_TIME (INT_MAX/2)
void timestamp_inc(float frametime)
{
timestamp_ticker += (int)(frametime*TIMESTAMP_FREQUENCY);
if ( timestamp_ticker > MAX_TIME ) {
timestamp_ticker = 2; // Roll!
}
if (timestamp_ticker < 2 ) {
mprintf(("Whoa!!! timestamp_ticker < 2 -- resetting to 2!!!\n"));
timestamp_ticker = 2;
}
}
int timestamp(int delta_ms )
{
int t2;
if (delta_ms < 0 ) return 0;
if (delta_ms == 0 ) return 1;
t2 = timestamp_ticker + delta_ms;
if ( t2 > MAX_TIME ) {
// wrap!!!
t2 = delta_ms - (MAX_TIME-timestamp_ticker);
}
if (t2 < 2 ) t2 = 2; // hack??
return t2;
}
// Returns milliseconds until timestamp will elapse.
// Negative value gives milliseconds ago that timestamp elapsed.
int timestamp_until(int stamp)
{
// JAS: FIX
// HACK!! This doesn't handle rollover!
// (Will it ever happen?)
return stamp - timestamp_ticker;
/*
uint delta;
delta = stamp - timestamp_ticker;
if (delta > UINT_MAX/2)
delta = UINT_MAX - delta + 1;
else if (delta < - ( (int) (UINT_MAX/2)))
delta = UINT_MAX + delta + 1;
return delta;
*/
}
// alternate timestamp functions. The way these work is you call xtimestamp() to get the
// current counter value, and then call
int timestamp()
{
return timestamp_ticker;
}
int timestamp_has_time_elapsed(int stamp, int time)
{
int t;
if (time <= 0)
return 1;
t = stamp + time;
if (t <= timestamp_ticker)
return 1; // if we are unlucky enough to have it wrap on us, this will assume time has elapsed.
return 0;
}
// timing functions -------------------------------------------------------------------------------
#define MAX_TIMING_EVENTS 15
// timing struct
#ifdef USE_TIMING
typedef struct timing {
char name[64];
int microseconds_total;
int start;
int ref_count;
} timing;
timing Timing_frame;
timing Timing_events[MAX_TIMING_EVENTS];
int Timing_event_count = 0;
#endif
// lookup a timing event
int timing_event_lookup(char *event_name)
{
#ifndef USE_TIMING
return -1;
#else
int idx;
// sanity
if(event_name == NULL){
return -1;
}
// look through all events
for(idx=0; idx<MAX_TIMING_EVENTS; idx++){
if(!stricmp(Timing_events[idx].name, event_name)){
return idx;
}
}
return -1;
#endif
}
// start timing frame stuff
void timing_frame_start()
{
#ifndef USE_TIMING
return;
#else
int idx;
// restart the frame
Timing_event_count = 0;
Timing_frame.start = timer_get_microseconds();
for(idx=0; idx<MAX_TIMING_EVENTS; idx++){
Timing_events[idx].microseconds_total = 0;
strcpy_s(Timing_events[idx].name, "");
Timing_events[idx].ref_count = 0;
}
#endif
}
// done timing the frame
void timing_frame_stop()
{
#ifndef USE_TIMING
return;
#else
int stop_time;
// stop time
stop_time = timer_get_microseconds();
// calc times
Timing_frame.microseconds_total = stop_time - Timing_frame.start;
#endif
}
// get the total frame time in microseconds
int timing_frame_total()
{
#ifndef USE_TIMING
return 0;
#else
return Timing_frame.microseconds_total;
#endif
}
// time an individual event
void timing_event_start(char *event_name)
{
#ifndef USE_TIMING
return;
#else
int event;
// sanity
if(event_name == NULL){
return;
}
// try and find the event
event = timing_event_lookup(event_name);
// if we already have one
if(event != -1){
Assert(Timing_events[event].ref_count == 0);
Timing_events[event].start = timer_get_microseconds();
Timing_events[event].ref_count++;
}
// if we need to add a new one
else {
if(Timing_event_count < MAX_TIMING_EVENTS){
strcpy_s(Timing_events[Timing_event_count].name, event_name);
Timing_events[Timing_event_count].start = timer_get_microseconds();
Timing_events[Timing_event_count++].ref_count++;
}
}
#endif
}
// stop timing an event
void timing_event_stop(char *event_name)
{
#ifndef USE_TIMING
return;
#else
int event;
// sanity
if(event_name == NULL){
return;
}
// try and find the event
event = timing_event_lookup(event_name);
// if we already have one
if(event != -1){
Assert(Timing_events[event].ref_count == 1);
Timing_events[event].microseconds_total += timer_get_microseconds() - Timing_events[event].start;
Timing_events[event].ref_count--;
}
#endif
}
// get the total time for an event in microseconds
int timing_event_total(char *event_name)
{
#ifndef USE_TIMING
return -1;
#else
int event;
// sanity
if(event_name == NULL){
return -1;
}
// try and find the event
event = timing_event_lookup(event_name);
if(event == -1){
return -1;
}
return Timing_events[event].microseconds_total;
#endif
}
// get the percentage of total frametime for the event (0.0 to 1.0)
float timing_event_pct(char *event_name)
{
#ifndef USE_TIMING
return 0.0f;
#else
int event;
// sanity
if(event_name == NULL){
return -1.0f;
}
// try and find the event
event = timing_event_lookup(event_name);
if(event == -1){
return -1.0f;
}
return (float)((double)Timing_events[event].microseconds_total / (double)Timing_frame.microseconds_total);
#endif
}
// display timing
void timing_display(int x, int y)
{
#ifndef USE_TIMING
return;
#else
int idx;
int line_height = gr_get_font_height() + 1;
gr_set_color_fast(&Color_bright_blue);
// total time
gr_printf_no_resize(x, y, "Total time %f\n", (float)timing_frame_total() / 1000000.0f);
y += line_height;
// each event percentage
for(idx=0; idx<Timing_event_count; idx++){
gr_printf_no_resize(x, y, "%s: %f\n", Timing_events[idx].name, timing_event_pct(Timing_events[idx].name));
y += line_height;
}
#endif
}