1. Make sure the legacy `timestamp_until()` and `timestamp_since()` functions check for any type of invalid timestamp
2. Add a useful `isFinite()` function
3. A timestamp delta on an immediate timestamp is more properly the actual delta, rather than another immediate timestamp
Because time compression adjusts the raw timestamp to be 0, it must use the exact value, not the snapshotted value, or the mission time will be slightly off. So this commit fixes that problem, as well as making sure that changes in time compression always occur at the start of a frame.
Prior to the timer upgrade, all simulation timestamps shared identical timer and timestamp values for the duration of the frame, since they were only updated within the `game_set_frametime` function. Since the timer upgrade depends on the system clock, timestamps evaluated near the end of the frame will be very slightly later than timestamps evaluated near the beginning of the frame. It is desirable to keep them all in sync.
This PR tweaks the timestamp system to take a snapshot at the beginning of the frame, then use that snapshot for the entire duration of the frame. This only affects simulation timestamps; real-time timestamps still use the live timer.
* Revert "synchronize simulation timestamps across the entire frame"
* try a proper fix instead of revert
* make sure nothing is reverted
* and back to full revert
Originally the check for event delay was this:
```
if ( (fix) Mission_events[i].timestamp + delay >= Missiontime )
return SEXP_FALSE;
```
This returns false even when the mission time is equal to the timestamp. Therefore the timestamp check needs to use >, not >=.
Thanks to Durandal and ShivanSpS for helping to track this down.
Prior to the timer upgrade, all simulation timestamps shared identical timer and timestamp values for the duration of the frame, since they were only updated within the `game_set_frametime` function. Since the timer upgrade depends on the system clock, timestamps evaluated near the end of the frame will be very slightly later than timestamps evaluated near the beginning of the frame. It is desirable to keep them all in sync.
This PR tweaks the timestamp system to take a snapshot at the beginning of the frame, then use that snapshot for the entire duration of the frame. This only affects simulation timestamps; real-time timestamps still use the live timer.
For all POFs that use animated textures, if no starting timestamp is specified, assume animation started at the beginning of the mission. This fixes a bug reported in Starfox: Event Horizon where weapon POF animated textures stopped animating after the texture timestamp upgrade.
These fix up the in-game confirm packet and help sync client and server through a few timing fixes.
Co-Authored-By: Taylor Richards <[email protected]>
The movie player code was missing some important functionality, in particular:
1) There was only one timing method to get real-time elapsed time, which was not suitable for pausing or time compression
2) There was an improper cast for the FPS property, causing a script error
3) The `getSeconds` method lost precision during casting
This patches those deficiencies.
A bit overkill for some of this but just covering the bases.
* fix issues with in-game join
* fix multi messaging and multi pause screen
* make sure maintenance stuff (pings, voice, file xfer, etc.) isn't
affected by pausing or time compression
The new timestamps should use the timestamp ticker, which accounts for pauses and time compression, not the standard timer, which measures absolute elapsed time. This fixes the bug reported on Discord where the supernova timer did not pause when the game was paused.
This adds a type-safe TIMESTAMP, similar to UI_TIMESTAMP. Eventually all of the FSO codebase will be switched over to this new type. In the meantime, just the supernova code is switched over.
If a breakpoint is hit in the code, the SDL time will keep running even though FSO doesn't realize things are effectively, if not actually, paused. Detect this situation and adjust the timestamp offset to compensate.
Previously, the game used a dead-reckoning system for measuring time, where several time counters were incremented as long as time was running. This unfortunately has no way to synchronize time in the long term, and therefore in-game time will tend to run faster or slower than real time by a few percent, depending on various factors.
This PR redesigns the timestamp system to use the SDL time counter which will always keep it in sync with real time. However this necessarily involves a bit of clever handling when the game is paused and unpaused. It also revealed several minor bugs in several places in the code where timestamps were handled.
This PR is currently in draft status until the design can be updated to handle time compression. In all other respects it should be working.
* Object Update Refactor
1. Keeps the object update packet aligned, even if the ship is dying or has not yet arrived on the client.
2. Properly handles model point shields (yes, that's what was causing multi to crash the most!)
3. Reworks positional interpolation timing and adds rotational interpolation, by sending timing information with every object update packet in a header shared between objects.
4. Saves a lot of bandwidth by only sending data that is changing. (no more sending all subsystems once per second!)
5. Better handles out of order packets (but can still use their information if recent enough!)
6. Builds the basis for Rollback by beginning to record the positions and orientations and velocities of ships for the last 30 frames.
7. Adds subsystem rotation -- Yeah, you saw that right, subsystems will now spin in multi.
8. Waypoint movement is now enabled via sexp, and time to arrival of waypoints is updated on the target info gauge.
* Fix edge case crash and Incorporate feedback
* Clean Up Interpolate Angles Quick
* Restrain the client
* How was this still here???
* Make sure every part of OO uses OOC_INDEX_NULLPTR_SUBSYSTEM define
* Fix Way to Store Return Values
* Ok travis, we get it
* Ok travis.........
If FSO runs for a very long time (5 hours to be exact) then the SDL
performance counter reaches a value so hight that rescaling it to
microseconds causes an overflow which is bad.
This fixes that by implementing the rescaling by computing the factor in
the timer initialization code and then multiplying the SDL time with
that. This uses the same principle as the changes done by @TheMatthew in #1082.
According to the tests done by @chief1983, this fixes#1237.
This creates a factor that is used to multiply the timestamp. It will
overflow less, (once every 300 years or so) and not lose as much precision
as the previous implementation.
The performance is slightly improved, there are no more branches and one
floating point multiply.
Note: this relies on long double having a 64 bit mantissa. This is the
case on x86 Windows, Linux, and Mac OS. However, it is unconfirmed to
work on other architechtures.
Signed-off-by: Matthew Khouzam <[email protected]>