Skip to content

Commit 7758a17

Browse files
committed
[libretro] Reverting back to the use of clock()
clock() was previously replaced by frame time callback (1c8eb84 #2589) It introduced a few bugs that I tried to fix (#2829) But there is a [benchmark cartridge](https://tic80.com/play?cart=153) that calls time() to mesure itra-frame timing. This is how Gemini explains it: The situation involves two different timing requirements: Inter-Frame Timing (Game Speed): This is about ensuring the game logic advances correctly from one frame to the next. If 1/60th of a second has passed in the real world, the game should also advance its state by 1/60th of a second. The original fix (`state->frameTime += usec;`) solved this by correctly accumulating the time between frames. Intra-Frame Timing (Benchmark Measurement): This is what the benchmark cartridge needs. It uses TIC-80's `time()` function to measure how long an operation takes within a single frame. It records the start time, does a lot of drawing, records the end time, and calculates the difference. The original fix failed the benchmark test because the `state->frameTime` value is only updated once per frame. For the entire duration of the `MAINTIC()` function, the value returned by `time()` would be constant. Therefore, `time() - stime` would always be zero. -- The clock() solution is superior because it provides a high-resolution, continuously updating timer directly from the system's C library. clock(): This standard function returns the amount of processor time used by the program. Crucially, this value increases during the execution of a single frame. CLOCKS_PER_SEC: This constant provides the frequency of the clock() timer. When the benchmark calls time() (`clock() / CLOCKS_PER_SEC`), it gets a precise timestamp. After it finishes its work and calls time() again, the value from clock() will have increased, yielding a correct, non-zero `runningTime`. This solves the intra-frame timing problem. Simultaneously, because clock() is a consistently increasing counter, the TIC-80 engine can use it to perfectly measure the duration between frames, solving the inter-frame timing problem as well.
1 parent 2cc226b commit 7758a17

File tree

1 file changed

+2
-28
lines changed

1 file changed

+2
-28
lines changed

src/system/libretro/tic80_libretro.c

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ struct tic80_state
7777
int mouseHideTimer;
7878
int mouseHideTimerStart;
7979
tic80* tic;
80-
retro_usec_t frameTime;
8180
};
8281
static struct tic80_state* state = NULL;
8382

@@ -86,19 +85,15 @@ static struct tic80_state* state = NULL;
8685
*/
8786
static u64 tic80_libretro_counter()
8887
{
89-
if (state == NULL) {
90-
return 0;
91-
}
92-
93-
return (u64)state->frameTime;
88+
return clock();
9489
}
9590

9691
/**
9792
* TIC-80 callback; Request frequency.
9893
*/
9994
static u64 tic80_libretro_frequency()
10095
{
101-
return TIC80_FREQUENCY;
96+
return CLOCKS_PER_SEC;
10297
}
10398

10499
/**
@@ -155,17 +150,6 @@ void tic80_libretro_fallback_log(enum retro_log_level level, const char *fmt, ..
155150
va_end(va);
156151
}
157152

158-
/**
159-
* libretro callback; Called to indicate how much time has passed since last retro_run().
160-
*/
161-
void tic80_libretro_frame_time(retro_usec_t usec) {
162-
if (state == NULL) {
163-
return;
164-
}
165-
166-
state->frameTime += usec;
167-
}
168-
169153
/**
170154
* libretro callback; Global initialization.
171155
*/
@@ -1116,16 +1100,6 @@ RETRO_API bool retro_load_game(const struct retro_game_info *info)
11161100
return false;
11171101
}
11181102

1119-
// Set up the frame time callback.
1120-
struct retro_frame_time_callback frame_time = {
1121-
.callback = tic80_libretro_frame_time,
1122-
.reference = TIC80_FREQUENCY / TIC80_FRAMERATE,
1123-
};
1124-
if (!environ_cb(RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK, &frame_time)) {
1125-
log_cb(RETRO_LOG_ERROR, "[TIC-80] Failed to set frame time callback.\n");
1126-
return false;
1127-
}
1128-
11291103
// Set up the TIC-80 environment.
11301104
#if RETRO_IS_BIG_ENDIAN
11311105
state->tic = tic80_create(TIC80_SAMPLERATE, TIC80_PIXEL_COLOR_ARGB8888);

0 commit comments

Comments
 (0)