Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions code/dropship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "dsurface.h"
#include "font.h"
#include "globals.h"
#include "hostclock.h"
#include "house.h"
#include "infatype.h"
#include "keyboard.h"
Expand Down Expand Up @@ -247,7 +248,7 @@ struct CrossDissolveEffect
FromSurface(from_surface),
ToSurface(to_surface),
Alpha(0),
StartTime(::timeGetTime()),
StartTime(Host_Milliseconds()),
FromBlitter(from_blitter),
ToBlitter(to_blitter),
WasDrawn(false)
Expand Down Expand Up @@ -557,7 +558,7 @@ void Dropship_Screen(void)

DynamicVectorClass<ButtonFadeEffect *> button_fades;

unsigned int money_display_time = ::timeGetTime();
unsigned int money_display_time = Host_Milliseconds();
unsigned int screen_start_time = money_display_time;
int loadout_anim_frame = 0;
unsigned int last_input_time = 0;
Expand Down Expand Up @@ -613,7 +614,7 @@ void Dropship_Screen(void)
KeyNumType input = button_list->Input();
if (!recent_click && (input & KN_BUTTON) != 0) {
input = (KeyNumType)(input & ~KN_BUTTON);
last_input_time = ::timeGetTime();
last_input_time = Host_Milliseconds();

if (input <= _cameo_count && selected_count < dropship_count * SLOT_PER_DROPSHIP) {
int candidate_index = cameo_top + input - 1;
Expand Down Expand Up @@ -650,13 +651,13 @@ void Dropship_Screen(void)
int light_row = (input - 1) / 2;
if (light_frame[light_row] == (unsigned int)-1) {
light_frame[light_row] = 0;
light_start[light_row] = ::timeGetTime();
light_start[light_row] = Host_Milliseconds();
}

force_light_redraw = true;
for (j = 0; ; ++j) {
if (j >= button_fades.Count()) {
ButtonFadeEffect *fade = new ButtonFadeEffect(::timeGetTime(), candidate_index, 127.0f, -1.0f, false);
ButtonFadeEffect *fade = new ButtonFadeEffect(Host_Milliseconds(), candidate_index, 127.0f, -1.0f, false);
if (usage_index != -1 && Scen->AllowableUnitCounts[usage_index] >= Scen->AllowableUnitMaximums[usage_index]) {
force_info_redraw = true;
fade->StopAtLow = true;
Expand Down Expand Up @@ -709,7 +710,7 @@ void Dropship_Screen(void)
if (Scen->AllowableUnitCounts[usage_index] >= Scen->AllowableUnitMaximums[usage_index]) {
for (j = 0; j < candidates.Count(); ++j) {
if (candidates[j] == selections[remove_index]) {
ButtonFadeEffect *fade = new ButtonFadeEffect(::timeGetTime(), j, 127.0f, -1.0f, false);
ButtonFadeEffect *fade = new ButtonFadeEffect(Host_Milliseconds(), j, 127.0f, -1.0f, false);
fade->Direction = 1.0f;
fade->Alpha = 63.0f;
button_fades.Add(fade);
Expand Down Expand Up @@ -780,7 +781,7 @@ void Dropship_Screen(void)
for (i = 0; i < ARRAY_SIZE(_green_light_ys); ++i) {
if (light_frame[i] != (unsigned int)-1) {
int frame = light_frame[i];
int next_frame = (timeGetTime() - light_start[i]) / _light_rate;
int next_frame = (Host_Milliseconds() - light_start[i]) / _light_rate;
if (next_frame != frame || force_light_redraw) {
int light_y = y + _green_light_ys[i];
int light_x = x + _light_x;
Expand Down Expand Up @@ -816,14 +817,14 @@ void Dropship_Screen(void)
ButtonFadeEffect *effect = button_fades[i];
int alpha;
if (effect->Direction < 0.0f) {
alpha = 127 - (_fade_rate * timeGetTime() - _fade_rate * effect->StartTime) / _fade_scale;
alpha = 127 - (_fade_rate * Host_Milliseconds() - _fade_rate * effect->StartTime) / _fade_scale;
if (alpha < _fade_low) {
alpha = _fade_low;
effect->Direction = 1.0f;
effect->StartTime = timeGetTime();
effect->StartTime = Host_Milliseconds();
}
} else {
alpha = (_fade_rate * timeGetTime() - _fade_rate * effect->StartTime) / _fade_scale + _fade_low;
alpha = (_fade_rate * Host_Milliseconds() - _fade_rate * effect->StartTime) / _fade_scale + _fade_low;
if (alpha > 127) {
alpha = 127;
}
Expand Down Expand Up @@ -867,7 +868,7 @@ void Dropship_Screen(void)
--j;
}

int alpha = std::min(255ul, (_dissolve_rate * timeGetTime() - _dissolve_rate * effect->StartTime) / _dissolve_scale);
int alpha = std::min(255ul, (_dissolve_rate * Host_Milliseconds() - _dissolve_rate * effect->StartTime) / _dissolve_scale);

if (alpha != effect->Alpha || overlap_drawn) {
effect->Alpha = alpha;
Expand Down Expand Up @@ -899,17 +900,17 @@ void Dropship_Screen(void)
}
}

recent_click = (::timeGetTime() - last_input_time) < _click_delay;
recent_click = (Host_Milliseconds() - last_input_time) < _click_delay;

int loadout_count = loadout_shape->Get_Count();
int next_loadout_frame = ((::timeGetTime() - screen_start_time) / _loadout_rate) % loadout_count;
int next_loadout_frame = ((Host_Milliseconds() - screen_start_time) / _loadout_rate) % loadout_count;
if (next_loadout_frame != loadout_anim_frame) {
loadout_anim_frame = next_loadout_frame;
Draw_Shape(*HiddenSurface, *drawer_dropship, loadout_shape, loadout_anim_frame, Point2D(0, 0), Rect(Point2D(x, y) + Point2D(_loadout_x, _loadout_y), loadout_shape->Get_Width(), loadout_shape->Get_Height()), SHAPE_NORMAL);
redraw = true;
}

unsigned int now = ::timeGetTime();
unsigned int now = Host_Milliseconds();
if ((unsigned int)money != money_display) {
unsigned int elapsed = now - money_display_time;
if (elapsed >= _money_rate) {
Expand All @@ -933,7 +934,7 @@ void Dropship_Screen(void)
}

if (pilot_frame >= 0) {
int next_pilot_frame = (::timeGetTime() - pilot_start_time) / _pilot_rate;
int next_pilot_frame = (Host_Milliseconds() - pilot_start_time) / _pilot_rate;
if (next_pilot_frame != pilot_frame) {
if (next_pilot_frame < pilotlight_shape->Get_Count()) {
pilot_frame = next_pilot_frame;
Expand All @@ -950,7 +951,7 @@ void Dropship_Screen(void)
if (pilot_timer == 0) {
if (Scen->RandomNumber(0, INT_MAX - 1) / (double)(INT_MAX - 1) < _pilot_chance) {
pilot_frame = 0;
pilot_start_time = ::timeGetTime();
pilot_start_time = Host_Milliseconds();
Draw_Shape(*HiddenSurface, *drawer_dropship, pilotlight_shape, 0, Point2D(0, 0), Rect(x + _pilot_x, y + _pilot_y, pilotlight_shape->Get_Width(), pilotlight_shape->Get_Height()), SHAPE_NORMAL);
redraw = true;
}
Expand Down
5 changes: 3 additions & 2 deletions code/gametime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include "gametime.h"

#include "hostclock.h"
#include "win.h"

//==========================================================================
Expand All @@ -59,7 +60,7 @@ GameTimeClass Game_Time;
*=========================================================================*/
GameTimeClass::GameTimeClass( void )
{
game_start_time = timeGetTime();
game_start_time = Host_Milliseconds();
}


Expand All @@ -81,7 +82,7 @@ unsigned int GameTimeClass::Get_Time( void )
unsigned int curr_windows_time;
unsigned int game_time;

curr_windows_time = timeGetTime();
curr_windows_time = Host_Milliseconds();
if ( curr_windows_time <= game_start_time ) {
// Handles the case if the windows time wraps while playing the game.
game_time = MAX_ULONG - game_start_time + curr_windows_time;
Expand Down
24 changes: 24 additions & 0 deletions code/hostclock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* O P E N T S
*******************************************************************************
* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright 2026 OpenTS contributors
*
* See LICENSE.md for applicable additional terms and warranty disclaimers.
******************************************************************************/

#pragma once

#include <chrono>
#include <cstdint>

// The engine's coarse clock, in milliseconds from a clock that only ever moves forward.
// Every caller measures an interval with it and none depends on where it starts. The
// reading wraps roughly every forty nine days, so compare differences and not the
// readings themselves.
inline uint32_t Host_Milliseconds(void)
{
return((uint32_t)std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch()).count());
}

3 changes: 2 additions & 1 deletion code/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
#include "gamedlg.h"
#include "getcpu.h"
#include "globals.h"
#include "hostclock.h"
#include "houstype.h"
#include "incdec.h"
#include "infatype.h"
Expand Down Expand Up @@ -1888,7 +1889,7 @@ void Init_Random(void)
Seed = CustomSeed;
} else {
CryptRandom.Get(&Seed, sizeof(Seed));
Seed = GetTickCount();
Seed = Host_Milliseconds();
//srand(time(NULL));
//Seed = rand();
}
Expand Down
5 changes: 3 additions & 2 deletions code/mainloop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "fog.h"
#include "globals.h"
#include "goptions.h"
#include "hostclock.h"
#include "ipxmgr.h"
#include "language\language.h"
#include "logic.h"
Expand Down Expand Up @@ -227,7 +228,7 @@ bool Main_Loop(void)
//
// Initialize our AI processing timer
//
Session.ProcessTimer = timeGetTime();/// TickCount;
Session.ProcessTimer = Host_Milliseconds();/// TickCount;

if (Session.TrapCheckHeap) {
Debug_Trap_Check_Heap = true;
Expand Down Expand Up @@ -346,7 +347,7 @@ bool Main_Loop(void)
//
// Measure how long it took to process the AI
//
Session.ProcessTicks += std::min<int>(1000, (timeGetTime() - Session.ProcessTimer)); // (TickCount - Session.ProcessTimer)
Session.ProcessTicks += std::min<int>(1000, (Host_Milliseconds() - Session.ProcessTimer)); // (TickCount - Session.ProcessTimer)
Session.ProcessFrames++;

/*
Expand Down
17 changes: 12 additions & 5 deletions code/milsectmr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "dbgprint.h"
#include "getcpu.h"
#include "hostclock.h"
#include "mpu.h"
#include "win.h"

Expand All @@ -29,8 +30,9 @@
/// <summary>
/// Creates the millisecond timer and works out how to drive it.
/// This routine will ask the processor for its clock rate so that the cycle counter can be
/// scaled into milliseconds. Machines that will not report a rate fall back to the Windows
/// multimedia timer, whose resolution is raised to one millisecond for the life of the timer.
/// scaled into milliseconds. Machines that will not report a rate fall back to the host
/// clock instead. The resolution raised here no longer sharpens that reading, but the
/// request is process wide and the game's waits are rounded up to whatever is in force.
/// </summary>
MillisecondTimerClass::MillisecondTimerClass(void)
{
Expand All @@ -39,7 +41,10 @@ MillisecondTimerClass::MillisecondTimerClass(void)
unsigned int low = Get_CPU_Rate(high);

if (low == 0 && high == 0) {
// Windows only; no other host has a resolution to bid for.
#ifdef _WIN32
timeBeginPeriod(PERIOD_RESOLUTION);
#endif

} else {
double dl = low;
Expand All @@ -61,7 +66,10 @@ MillisecondTimerClass::MillisecondTimerClass(void)
MillisecondTimerClass::~MillisecondTimerClass(void)
{
if (Frequency != 1.0) {
// Windows only; no other host has a resolution to bid for.
#ifdef _WIN32
timeEndPeriod(PERIOD_RESOLUTION);
#endif
}
}

Expand All @@ -70,8 +78,7 @@ MillisecondTimerClass::~MillisecondTimerClass(void)
/// Fetches the current time, expressed in milliseconds.
/// This routine is used every time the timer is read. The processor's own cycle counter
/// supplies the value when the machine is new enough to have one, since it is both cheaper
/// and finer grained than the system timer. Otherwise the Windows multimedia timer is
/// consulted instead.
/// and finer grained than the host clock. Otherwise the host clock is read instead.
/// </summary>
/// <returns>Returns with the current time in milliseconds.</returns>
MillisecondTimerClass::operator double () const
Expand All @@ -94,5 +101,5 @@ MillisecondTimerClass::operator double () const
return(LI_TO_DBL(dh, dl) / Frequency);
}

return(timeGetTime());
return(Host_Milliseconds());
}
2 changes: 1 addition & 1 deletion code/milsectmr.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MillisecondTimerClass
/*
* This is the number of processor clock cycles that pass in one millisecond, and
* the raw cycle count is divided by it to yield a time. If it is 1.0, then the
* processor would not report its rate and the multimedia timer is read instead.
* processor would not report its rate and the host clock is read instead.
*/
double Frequency;
};
22 changes: 15 additions & 7 deletions code/mstimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@

#include "mstimer.h"

#include "hostclock.h"
#include "win.h"


/// <summary>
/// Asks Windows for one millisecond timer resolution.
/// This routine is called when the timer is created so that the readings it hands out
/// are fine grained enough for the game to pace itself by.
/// Requests one millisecond timer resolution for as long as this object exists.
/// The reading itself no longer needs it, since hostclock.h answers that from a clock of
/// its own. The request is process wide, though, and every wait the game paces itself with
/// is rounded up to whatever resolution is in force.
/// </summary>
MillisecondSystemTimerClass::MillisecondSystemTimerClass(void)
{
// Windows only; no other host has a resolution to bid for.
#ifdef _WIN32
timeBeginPeriod(1);
#endif
}


Expand All @@ -32,7 +37,10 @@ MillisecondSystemTimerClass::MillisecondSystemTimerClass(void)
/// </summary>
MillisecondSystemTimerClass::~MillisecondSystemTimerClass(void)
{
// Windows only; no other host has a resolution to bid for.
#ifdef _WIN32
timeEndPeriod(1);
#endif
}


Expand All @@ -41,19 +49,19 @@ MillisecondSystemTimerClass::~MillisecondSystemTimerClass(void)
/// This is the sampling routine that the timer templates call whenever they need to
/// know how much time has passed.
/// </summary>
/// <returns>Returns with the number of milliseconds elapsed since Windows started.</returns>
/// <returns>Returns with the host clock's millisecond reading.</returns>
int MillisecondSystemTimerClass::operator () (void) const
{
return(timeGetTime());
return(Host_Milliseconds());
}


/// <summary>
/// Converts the timer into its current millisecond reading.
/// This routine lets the timer object be used wherever a plain time value is expected.
/// </summary>
/// <returns>Returns with the number of milliseconds elapsed since Windows started.</returns>
/// <returns>Returns with the host clock's millisecond reading.</returns>
MillisecondSystemTimerClass::operator int (void) const
{
return(timeGetTime());
return(Host_Milliseconds());
}
3 changes: 2 additions & 1 deletion code/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "dbgprint.h"
#include "gamedirs.h" // for Search_Files.
#include "globals.h"
#include "hostclock.h"
#include "ipxmgr.h"
#include "language\language.h"
#include "msgloop.h"
Expand Down Expand Up @@ -937,7 +938,7 @@ unsigned int SessionClass::Compute_Unique_ID(void)
//------------------------------------------------------------------------
// time(&tm);
// id = (unsigned long)tm;
id = timeGetTime();
id = Host_Milliseconds();

//------------------------------------------------------------------------
// Now add in the free space on the hard drive
Expand Down
Loading