/*============================================================================= Name : Tracking.c Purpose : Functions and data to visually track numbers on-screen. Created 7/21/1999 by lmoloney Copyright Relic Entertainment, Inc. All rights reserved. =============================================================================*/ #include "tracking.h" #if NUMBER_TRACKING //if anything in this module is enabled, #include #include "main.h" #include "debug.h" #include "memory.h" #include "prim2d.h" #include "font.h" #include "key.h" /*============================================================================= Data: =============================================================================*/ trackvalue trkValue[TRK_NumberTracks]; sdword trkTrackIndex = 0; bool trkTrackingVisual = FALSE; struct { char *minusString, *plusString; real32 base; } trkRangeString[] = { {"-100M", "+100M", 100000000.0f}, {"-10M", "+10M", 10000000.0f}, {"-1M", "+1M", 1000000.0f}, {"-100K", "+100K", 100000.0f}, {"-10K", "+10K", 10000.0f}, {"-1K", "+1K", 1000.0f}, {"-100", "+100", 100.0f}, {"-10", "+10", 10.0f}, {"-1", "+1", 1.0f}, {"-100m", "+100m", 0.1f}, {"-10m", "+10m", 0.01f}, {"-1m", "+1m", 0.001f}, {"-100u", "+100u", 0.0001f}, {"-10u", "+10u", 0.00001f}, {"-1u", "+1u", 0.000001f}, {"-100n", "+100n", 0.0000001f}, {"-10n", "+10n", 0.00000001f}, {"-1n", "+1n", 0.000000001f}, {NULL, NULL, 0.0f} }; /*============================================================================= Functions: =============================================================================*/ /*----------------------------------------------------------------------------- Name : trkTrackValueAddFn Description : Add a value to track Inputs : name - name of the value to track - to be displayed on-screen number - pointer number to track timer - pointer to timer number, such as taskTimeElaped c - color to render the bar in Outputs : Return : ----------------------------------------------------------------------------*/ void trkTrackValueAddFn(char *name, real32 *number, real32 *timer, color c) { dbgAssert(trkTrackIndex < TRK_NumberTracks - 1); trkValue[trkTrackIndex].value = number; trkValue[trkTrackIndex].lastValue = *number; trkValue[trkTrackIndex].name = memStringDupeNV(name); trkValue[trkTrackIndex].timer = timer; trkValue[trkTrackIndex].lastTime = *timer; trkValue[trkTrackIndex].c = c; trkTrackIndex++; } /*----------------------------------------------------------------------------- Name : trkTrackValueRemoveFn Description : Remove a track value by name Inputs : name - name of track value to remove. All values of matching name will be removed. Outputs : Return : ----------------------------------------------------------------------------*/ void trkTrackValueRemoveFn(char *name) { sdword index, j; for (index = 0; index < trkTrackIndex; index++) { if (!strcmp(name, trkValue[index].name)) { for (j = index + 1; j < trkTrackIndex; j++) { trkValue[j - 1] = trkValue[j]; } index--; trkTrackIndex--; } } } /*----------------------------------------------------------------------------- Name : trkTrackValueRemoveAllFn Description : Remove all tracking values Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void trkTrackValueRemoveAllFn(void) { sdword index; for (index = 0; index < trkTrackIndex; index++) { memFree(trkValue[index].name); } trkTrackIndex = 0; } /*----------------------------------------------------------------------------- Name : trkTrackValuesDisplayFn Description : Renders all the track values Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void trkTrackValuesDisplayFn(void) { sdword index, range; sdword x, y, xMin, xMax, xMed, width, height; real32 delta, timeElapsed; rectangle rect; if (keyIsStuck(TRK_ToggleKey)) { keyClearSticky(TRK_ToggleKey); trkTrackingVisual ^= TRUE; } if (!trkTrackingVisual || trkTrackIndex == 0) { return; } /* if (timeElapsed == 0.0f) { return; } */ height = fontHeight(" ") + 1; y = (MAIN_WindowHeight - (height * trkTrackIndex)) / 2; width = fontWidth("+100M") + 1; x = MAIN_WindowWidth - width * 2 - TRK_TrackWidth; xMin = x + width; xMax = xMin + TRK_TrackWidth; xMed = (xMin + xMax) / 2; for (index = 0; index < trkTrackIndex; index++, y += height) { timeElapsed = *trkValue[index].timer - trkValue[index].lastTime; trkValue[index].lastTime = *trkValue[index].timer; if (timeElapsed == 0.0f) { continue; } //print the name of the value fontPrint(x - fontWidth(trkValue[index].name), y, trkValue[index].c, trkValue[index].name); delta = abs(*trkValue[index].value - trkValue[index].lastValue) / timeElapsed;//see how much it has changed if (delta == 0.0f) { //don't do anything else if it has not changed continue; } //find what range to print in if (delta / trkRangeString[0].base > 10.0f) { //if it's bigger than the biggest range continue; } for (range = 0; trkRangeString[range].minusString; range++) { if (delta / trkRangeString[range].base >= 1.0f) { //if this is the right range //get the real delta and bias it against the base delta = (trkValue[index].lastValue - *trkValue[index].value) / timeElapsed / trkRangeString[range].base; rect.y0 = y; rect.y1 = y + height - 1; if (delta < 0.0f) { rect.x0 = xMed + (sdword)(delta * (real32)TRK_TrackWidth / 20.0f); rect.x1 = xMed; } else { rect.x0 = xMed; rect.x1 = xMed + (sdword)(delta * (real32)TRK_TrackWidth / 20.0f); } dbgAssert(rect.x0 != rect.x1); primRectSolid2(&rect, trkValue[index].c); fontPrint(xMin - fontWidth(trkRangeString[range].minusString) - 1, y, colWhite, trkRangeString[range].minusString); fontPrint(xMax + 1, y, colWhite, trkRangeString[range].plusString); break; } } trkValue[index].lastValue = *trkValue[index].value; } } #endif //NUMBER_TRACKING