Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the client async #310

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

Make the client async #310

wants to merge 5 commits into from

Conversation

Yamagi
Copy link
Contributor

@Yamagi Yamagi commented Aug 27, 2020

Hi,
@DanielGibson asked me if I could have a look at dhewm3s timing code and estimate if it's possible to make the client asynchronous, i.e. render as many frames as possible without breaking the game logic. This is a very first try. The approach taken is the same as in Yamagi Quake II. The client is split into two time zones, renderframes for the renderer and clientframes for everything else.

General observations:

  • The timer subsystem is very inaccurate, about +/- 3 milliseconds offset per 16 milliseconds.

What's working:

  • I've played through Mars City without any obvious problems.
  • Most (I haven't found a broken one) GUIs including the PDA.
  • The animations seem to be okay.
  • The sound is okay and in sync with the animations and videos.
  • Scripts aren't obviously broken at least.

What's not working:

  • The game crashed once with Assertion 'node1->object == NULL && node2->object == NULL' failed. in BTree.h:442. I'm unable to reproduce it. The coredump was broken, so no chance to further investigate it.

What's missing:

  • Logic that slows down things a little bit currently we're burning the CPU in a tight spinloop.
  • cvars to configure client- and render frames per second.
  • A cvar to switch the async stuff off.
  • Windows and OS X are broken.
  • A lot of testing.

The big question is if this is the way to go or if it would be better to make the timer subsystem more accurate and split the global TRIGGER_EVENT_ONE timer (which is now unused) into two distinct times. One for the client and one for the renderer. In any case it is possible to make dhewm3 asynchronous and it looks easier than I initially thought.

@DanielGibson DanielGibson marked this pull request as draft August 28, 2020 16:20
@Yamagi Yamagi changed the title [do not merge] Make the client async Make the client async Aug 28, 2020
To separate the client into time zones (planned are are at least two,
one for the renderer and one for everything else) precise time counter
independent of the complicated and delay prone timer framework are
needed.

* Move Sys_Milliseconds() from threads.cpp (were it doesn't belong) into
  the system depended code.
* Implement Sys_Microseconds() for Windows and Posix plattform.
* Make Sys_Milliseconds() a wrapper around Sys_Microseconds().
* Add header entries for Sys_Microseconds().
* Implement some kind of break, i.e. slow the main loop a little bit
  down and use special OPCODES to tell the CPU that we are in a very
  tight spin loop. This prevent overheating.
* Introduce the render timezone for the renderer, call the renderer up
  to 300 times a second. This is currently hartcoded, a cvar will be
  introduced in a later commit.
* Everything else is the game timezone, hartcoded to 60 frames. The game
  can't run faster anyways.
* COmment old timeer based break. The code isn't removed because we need
  it to optionally support the old behaviour without time zones.
@Yamagi
Copy link
Contributor Author

Yamagi commented Aug 31, 2020

I just forced pushed the branch:

  • Code cleanup.
  • Unbreak Windows and OS X.

To make it clear. The goal of this pull request is to split the client into at least two time zones and allow the addition of more time zones at a later time. The goal is not to solve the 60 hz problem. That will be done (if ever) at a later time.

@Yamagi
Copy link
Contributor Author

Yamagi commented Sep 4, 2020

I've added two cvars:

  • com_asyncClient to switch between the synchronous and asynchronous client. Defaults to 0, synchronous client. The code for the synchronous client is unchanged from Vanilla Doom 3, there's no emulation like in YQ2.
  • com_renderFPS the limit the number of frames rendered when com_asyncClient is 1. Defaults to 300.

Both cvar can be set at runtime without restart. I've played through the Alpha Laps, the game seems to run fine in async mode.

@DanielGibson
Copy link
Member

just a quick untested win32 build of this branch rebased on current master: dhewm3_1.5.1_RC2+async_win32.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants