sm64pc/enhancements/fps.patch

61 lines
1.8 KiB
Diff

diff --git a/src/game/game.c b/src/game/game.c
index ad800839..4a37549b 100644
--- a/src/game/game.c
+++ b/src/game/game.c
@@ -52,6 +52,47 @@ struct DemoInput *gCurrDemoInput = NULL; // demo input sequence
u16 gDemoInputListID = 0;
struct DemoInput gRecordedDemoInput = { 0 }; // possibly removed in EU. TODO: Check
+// SDK states that 1 cycle takes about 21.33 nanoseconds
+#define SECONDS_PER_CYCLE 0.00000002133f
+
+#define FPS_COUNTER_X_POS 24
+#define FPS_COUNTER_Y_POS 190
+
+static OSTime gLastOSTime = 0;
+static float gFrameTime = 0.0f;
+static u16 gFrames = 0;
+static u16 gFPS = 0;
+static u8 gRenderFPS = FALSE;
+
+static void calculate_frameTime_from_OSTime(OSTime diff) {
+ gFrameTime += diff * SECONDS_PER_CYCLE;
+ gFrames++;
+}
+
+static void render_fps(void) {
+ // Toggle rendering framerate with the L button.
+ if (gPlayer1Controller->buttonPressed & L_TRIG) {
+ gRenderFPS ^= 1;
+ }
+
+ if (gRenderFPS) {
+ OSTime newTime = osGetTime();
+
+ calculate_frameTime_from_OSTime(newTime - gLastOSTime);
+
+ // If frame time is longer or equal to a second, update FPS counter.
+ if (gFrameTime >= 1.0f) {
+ gFPS = gFrames;
+ gFrames = 0;
+ gFrameTime -= 1.0f;
+ }
+
+ print_text_fmt_int(FPS_COUNTER_X_POS, FPS_COUNTER_Y_POS, "FPS %d", gFPS);
+
+ gLastOSTime = newTime;
+ }
+}
+
// this function records distinct inputs over a 255-frame interval to RAM locations and was likely
// used to record the demo sequences seen in the final game. This function is unused.
static void record_demo(void) {
@@ -334,5 +375,7 @@ void thread5_game_loop(UNUSED void *arg) {
// amount of free space remaining.
print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead);
}
+
+ render_fps();
}
}