Files
RP412/MUNGA/TRACE.h
T
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

298 lines
6.2 KiB
C++

#pragma once
#include "plug.h"
#include "chain.h"
#include "time.h"
#include "config.h"
#if defined(TRACE_ON)
struct TraceSample
{
Scalar sampleFraction;
Word sampleFrame;
Byte traceNumber;
Byte sampleType;
enum Type
{
GoingUp = 0,
GoingDown,
Marker,
IntegerSnapshot,
ScalarSnapshot,
SuspendSampling,
ResumeSampling
};
};
template <class T> struct SnapshotOf : public TraceSample
{
T snapShot;
};
class Trace : public Plug
{
friend class TraceManager;
public:
enum Type
{
BitType,
IntegerType,
ScalarType
};
protected:
static Byte NextTraceID;
const char *traceName;
long lastFrameActivity;
Scalar lastFractionActivity;
Byte traceNumber;
Byte traceType;
Trace(const char* name, Type type);
MemoryStream *GetTraceLog();
void IncrementSampleCount();
virtual void DumpTraceStatus()=0;
virtual void ResetTrace()=0;
#if defined(USE_TIME_ANALYSIS)
virtual void StartTiming()=0;
virtual Scalar CalcuateUsage(long frame, Scalar fraction, double sample_time)=0;
virtual void PrintUsage(Scalar usage);
#endif
};
class BitTrace : public Trace
{
protected:
static Byte NextActiveLine;
Logical traceUp;
double lastUpTime, totalUpTime;
Byte activeLine;
#if defined(USE_ACTIVE_PROFILE)
static void SetLineImplementation(Byte line);
static void ClearLineImplementation(Byte line);
static Logical IsLineValidImplementation(Byte line);
#endif
void DumpTraceStatus();
void ResetTrace();
#if defined(USE_TIME_ANALYSIS)
void StartTiming();
Scalar CalculateUsage(long frame, Scalar fraction, double sample_time);
void PrintUsage(Scalar usage);
#endif
public:
BitTrace(const char *name);
void Set();
void Clear();
double GetLastUpTime()
{
Check(this);
return lastUpTime;
}
double GetTotalUpTime()
{
Check(this);
return totalUpTime;
}
};
template <class T> class TraceOf : public Trace
{
protected:
double weightedSum;
T currentValue;
TraceSample::Type sampleType;
void DumpTraceStatus();
void ResetTrace();
#if defined(USE_TIME_ANALYSIS)
void StartTiming();
Scalar CalculateUsage(long frame, Scalar fraction, double sample_time);
void PrintUsage(Scalar usage);
#endif
public:
TraceOf(const char* name, const T& initial_value, Type trace_type, TraceSample::Type sample_type);
void TakeSnapshot(const T& value);
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T> TraceOf<T>::TraceOf(const char* name, const T& initial_value, Type trace_type, TraceSample::Type sample_type) : Trace(name, trace_type)
{
currentValue = initial_value;
sampleType = sample_type;
TraceOf<T>::ResetTrace();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T> void TraceOf<T>::DumpTraceStatus()
{
Check(this);
DEBUG_STREAM << currentValue << std::flush;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T> void TraceOf<T>::ResetTrace()
{
#if defined(USE_TIME_ANALYSIS)
weightedSum = 0.0;
#endif
}
#if defined(USE_TIME_ANALYSIS)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T> void TraceOf<T>::StartTiming()
{
Check(this);
weightedSum = 0.0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T> Scalar TraceOf<T>::CalculateUsage(long frame, Scalar fraction, double sample_time)
{
double last_part = frame - lastFrameActivity;
last_part += fraction - lastFractionActivity;
weightedSum += last_part * currentValue;
Scalar result = weightedSum / sample_time;
Check_Fpu();
weightedSum = 0.0;
return result;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T> void TraceOf<T>::PrintUsage(Scalar usage)
{
Check(this);
DEBUG_STREAM << usage << std::flush;
}
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
template <class T> void TraceOf<T>::TakeSnapshot(const T& value)
{
Check(this);
#if defined(USE_TIME_ANALYSIS) || defined(USE_TRACE_LOG)
long frame = Now().ticks;
Scalar fraction = Get_Frame_Percent_Used();
#endif
#if defined(USE_TIME_ANALYSIS)
double last_part = frame - lastFrameActivity;
last_part += fraction - lastFractionActivity;
weightedSum += last_part * currentValue;
lastFrameActivity = frame;
lastFractionActivity = fraction;
#endif
currentValue = value;
#if defined(USE_TRACE_LOG)
IncrementSampleCount();
MemoryStream *log = GetTraceLog();
if (log)
{
Check(log);
SnapshotOf<T> *sample = (SnapshotOf<T>*)log->GetPointer();
sample->sampleType = (Byte)sampleType;
sample->traceNumber = traceNumber;
sample->sampleFrame = (Word)frame;
sample->sampleFraction = fraction;
sample->snapShot = currentValue;
log->AdvancePointer(sizeof(*sample));
}
#endif
}
//#######################################################################
//##################### TraceManager ##############################
//#######################################################################
class TraceManager SIGNATURED
{
friend class Trace;
protected:
ChainOf<Trace*> traceChain;
long sampleStartFrame;
Scalar sampleStartFraction;
int actualSampleCount, ignoredSampleCount;
MemoryStream *allocatedTraceLog, *activeTraceLog;
Byte traceCount;
void Add(Trace *trace);
public:
TraceManager();
~TraceManager();
Byte GetTraceCount()
{
Check(this);
return traceCount;
}
void DumpTracesStatus();
void ResetTraces();
#if defined(USE_TIME_ANALYSIS)
void StartTimingAnalysis();
int SnapshotTimingAnalysis(Logical print = false);
#endif
#if defined(USE_TRACE_LOG)
void CreateTraceLog(size_t max_trace_samples, Logical start_sampling);
void SaveTraceLog(const char* filename);
void MarkTraceLog();
void SuspendTraceLogging();
void ResumeTraceLogging();
#endif
Logical TestInstance() const;
};
extern TraceManager trace_manager;
inline MemoryStream* Trace::GetTraceLog()
{
Check(this);
Check(&trace_manager);
return trace_manager.activeTraceLog;
}
inline void Trace::IncrementSampleCount()
{
Check(this);
Check(&trace_manager);
if (!trace_manager.activeTraceLog)
++trace_manager.ignoredSampleCount;
else
++trace_manager.actualSampleCount;
}
# endif