mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 04:49:39 -10:00
git-svn-id: svn://svn.icculus.org/fs2open/branches/fs2_open_3_7_0@9674 387891d4-d844-0410-90c0-e4c51a9137d3
240 lines
5.1 KiB
C++
240 lines
5.1 KiB
C++
/*
|
|
* Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
|
|
*
|
|
* You may not sell or otherwise commercially exploit the source or things you
|
|
* created based on the source.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This module is intended as a debug tool to measure the speed of blocks of code and display
|
|
* that information as coloured bars across the top of the screen.
|
|
*
|
|
* This allows interactive measuring of components of the code, very useful for optimisztion.
|
|
*/
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#include <winbase.h>
|
|
#endif
|
|
|
|
#include "timerbar.h"
|
|
#include "globalincs/pstypes.h"
|
|
|
|
|
|
// Internal structure for handling frame data
|
|
typedef struct
|
|
{
|
|
LARGE_INTEGER start_value;
|
|
LARGE_INTEGER total_value;
|
|
|
|
LARGE_INTEGER average;
|
|
LARGE_INTEGER frame_total;
|
|
|
|
} timerbar_profile;
|
|
|
|
timerbar_profile profiles[MAX_NUM_TIMERBARS];
|
|
int timerbar_current_profile = 0;
|
|
|
|
LARGE_INTEGER timerbar_ultimate_start_value;
|
|
LARGE_INTEGER timerbar_last_start_value;
|
|
|
|
// Data needed for push and pop functionality
|
|
const int MAX_TB_STACK_SIZE = 100;
|
|
|
|
int timerbar_stack[MAX_TB_STACK_SIZE];
|
|
int timerbar_current_stack_layer = 0;
|
|
|
|
/**
|
|
* Pssst, hey, you. Ya wanna timerbar? Real cheap.
|
|
*
|
|
* @param value Index count value (?)
|
|
*/
|
|
void timerbar_push(int value)
|
|
{
|
|
if(timerbar_current_stack_layer >= MAX_TB_STACK_SIZE)
|
|
{
|
|
// To many pushs, this must be a bug
|
|
// Someone is letting code miss the pops, check for early retuns
|
|
Assert(!(timerbar_current_stack_layer >= MAX_TB_STACK_SIZE));
|
|
return;
|
|
}
|
|
|
|
timerbar_stack[timerbar_current_stack_layer] = timerbar_current_profile;
|
|
timerbar_current_stack_layer++;
|
|
|
|
timerbar_switch_type(value);
|
|
}
|
|
|
|
/*
|
|
*/
|
|
void timerbar_pop()
|
|
{
|
|
timerbar_current_stack_layer--;
|
|
if(timerbar_current_stack_layer < 0)
|
|
{
|
|
Assert(!(timerbar_current_stack_layer < 0));
|
|
timerbar_current_stack_layer = 0;
|
|
return;
|
|
}
|
|
|
|
timerbar_switch_type(timerbar_stack[timerbar_current_stack_layer]);
|
|
}
|
|
|
|
/**
|
|
* This pointer holds the draw function to use or NULL
|
|
*
|
|
* @param colour Colour index (>=0)
|
|
* @param x Coordinate position
|
|
* @param y Coordinate position
|
|
* @param w element width
|
|
* @param h element height
|
|
*/
|
|
void (*draw_func_ptr)(int colour, float x, float y, float w, float h) = NULL;
|
|
|
|
/*
|
|
*/
|
|
void timerbar_start_frame()
|
|
{
|
|
timerbar_current_stack_layer = 0;
|
|
timerbar_current_profile = 0;
|
|
|
|
if(QueryPerformanceCounter(&timerbar_ultimate_start_value) == FALSE)
|
|
{
|
|
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
|
|
draw_func_ptr = NULL;
|
|
}
|
|
|
|
timerbar_last_start_value = timerbar_ultimate_start_value;
|
|
|
|
}
|
|
|
|
// Constants need for timerbar_conv_and_draw calculations
|
|
const int WIDTH = 480;
|
|
const float WIDTHF = ((float) WIDTH) * 1.01f;
|
|
|
|
/**
|
|
* Internal conversion function to convert draw data into bars for the screen
|
|
*
|
|
* @param colour Colour index (>=0)
|
|
* @param xpos X position to start bar on
|
|
* @param xwidth Width of bar
|
|
* @param yrow Index of row bar belongs to
|
|
*/
|
|
void timerbar_conv_and_draw(int colour, int xpos, int xwidth, int yrow)
|
|
{
|
|
float fxpos = (float) xpos;
|
|
float fxwidth = (float) xwidth;
|
|
|
|
draw_func_ptr(colour,
|
|
fxpos / WIDTHF,
|
|
yrow * 0.01f,
|
|
fxwidth / WIDTHF,
|
|
0.005f);
|
|
}
|
|
|
|
/*
|
|
*/
|
|
void timerbar_end_frame()
|
|
{
|
|
// Now we want to draw the bars
|
|
if(draw_func_ptr == NULL)
|
|
{
|
|
// we have not been given a draw function so we are going to have to quit
|
|
return;
|
|
}
|
|
|
|
timerbar_switch_type(-1);
|
|
|
|
int last_xpos = 0;
|
|
int y_pos = 0;
|
|
|
|
|
|
for(int i = 0; i < MAX_NUM_TIMERBARS; i++)
|
|
{
|
|
// Nothing to render this frame
|
|
if(profiles[i].frame_total.QuadPart == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int xsize = (int) profiles[i].frame_total.QuadPart / 90;
|
|
|
|
// break condition in else
|
|
while(1)
|
|
{
|
|
// if bar runs over
|
|
if(last_xpos + xsize > WIDTH)
|
|
{
|
|
int rem_len = WIDTH - last_xpos;
|
|
|
|
// Draw from current position to the end of the bar
|
|
timerbar_conv_and_draw(i, last_xpos, rem_len, y_pos);
|
|
|
|
xsize -= rem_len;
|
|
last_xpos = 0;
|
|
y_pos++;
|
|
}
|
|
else
|
|
{
|
|
// Draw whats left and break for the next bar
|
|
timerbar_conv_and_draw(i,last_xpos, xsize, y_pos);
|
|
|
|
last_xpos += xsize;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// reset for next frame
|
|
profiles[i].frame_total.QuadPart = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Not entirely sure what this does.
|
|
*
|
|
* @param num Probably a pretend boolean
|
|
*/
|
|
void timerbar_switch_type(int num)
|
|
{
|
|
if(num >= MAX_NUM_TIMERBARS)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Calculate old profile's total
|
|
LARGE_INTEGER now;
|
|
if(QueryPerformanceCounter(&now) == FALSE)
|
|
{
|
|
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
|
|
}
|
|
|
|
profiles[timerbar_current_profile].frame_total.QuadPart +=
|
|
(now.QuadPart - timerbar_last_start_value.QuadPart);
|
|
|
|
if(num != -1)
|
|
{
|
|
// Switch to new profile
|
|
timerbar_current_profile = num;
|
|
}
|
|
|
|
// Update time to count from
|
|
if(QueryPerformanceCounter(&timerbar_last_start_value) == FALSE)
|
|
{
|
|
// DBUGFILE_OUTPUT_0("QueryPerformanceCounter not supported by hardware");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clears the instance of the timer bar
|
|
*
|
|
* Look at the parameters for "void (*draw_func_ptr)"
|
|
* They directly equate the new_draw_func_ptr, but we can't
|
|
* place params for a double stuffed function like this.
|
|
*/
|
|
void timerbar_set_draw_func(void (*new_draw_func_ptr)(int colour, float x, float y, float w, float h))
|
|
{
|
|
draw_func_ptr = new_draw_func_ptr;
|
|
}
|
|
|