This is a very small walkthrough of some of Quake 1. Unfinished.

01

Files of interest:

Host_Init (host.c) is the actual entry point of Quake. This entry point is called from a main function located in one of the sys_*.c prefixed files. So I'm guessing you'd compile Quake with just one of these files that are targeting your platform (though in reality you'd just grab a modern quake engine like vkQuake). In any case, the main function calls, in order, these two functions:

Sys_Init()
Host_Init(&parms);

Sys_Init does some platform system checks (OS version, memory etc).

Host_Init is where Quake actually starts initialization of the game/engine. This function seems to largely sets up commands (host.c):

Memory_Init (parms->membase, parms->memsize);
Cbuf_Init ();
Cmd_Init ();
V_Init ();
Chase_Init ();
Host_InitVCR (parms);
COM_Init (parms->basedir);
Host_InitLocal ();
W_LoadWadFile ("gfx.wad");
Key_Init ();
Con_Init ();
M_Init ();
PR_Init ();
Mod_Init ();
NET_Init ();
SV_Init ();

But once we've exited Host_Init, we enter the main loop of Quake where we update a delta time value and run game code (via Host_Frame):

oldtime = Sys_FloatTime () - 0.1;
while (1)
  {
    // find time spent rendering last frame
    newtime = Sys_FloatTime ();
    time = newtime - oldtime;

    if (cls.state == ca_dedicated)
      {   // play vcrfiles at max speed
        if (time < sys_ticrate.value && (vcrFile == -1 || recording) )
          {
            usleep(1);
            continue;       // not time to run a server only tic yet
          }
        time = sys_ticrate.value;
      }

    if (time > sys_ticrate.value*2)
      oldtime = newtime;
    else
      oldtime += time;

    Host_Frame (time);

Note: cls is a struct defined in client.h as client_static_t that is extern'd as cls. And state is a field in this struct which is defined as an enum (cactive_t) that has three potential values: ca_dedicated, ca_disconnected, and ca_connected.

ca_dedicated: Running the game as an online server that quake players would literally connect to.

The other two values I'm not sure about. It might be the case that ca_disconnected is for quitting and final deallocation of the game, and that as you play the game normally the value is always ca_connected whether you're connected to a dedicated server or running a local one. From what I can tell, Quake employs a network architecture even as a singleplayer game.

In any case, what this main loop does every frame:

And finally, at the end of each iteration we call Host_Frame. This is where absolutely everything gets done, even though you can't tell at first glance.

For example, in its function body, it calls an "internal" or "shadow" function _Host_Frame and this function in turns has, among other things, these lines:

if (sv.active)
  Host_ServerFrame ();

Which updates all the physics. Eventually this calls Host_ServerFrame which calls the actual physics functions: SV_RunClients, SV_Physics etc.

Phew. And that's just the physics.

02

Alright, so we've figured out that the main loop of Quake is in a sys_*.c file, and that the bulk of behavior frame to frame is Host_Frame() and _Host_Frame(). Lets figure out where we get to the physics calculations. Well, eventually. A slight detour first.

Inside Host_Frame, ignoring some time precision stuff we enter _Host_Frame. Inside this function is:

if (sv.active)
    Host_ServerFrame ();

And in this function, the third line is:

// run the world state
pr_global_struct->frametime = host_frametime;

Where the hell does this pr_global_struct come from? A grep will show that its used all over the place. Often for storing some physics information but other things as well such as if our gamemode is a deathmatch or how many secrets we've found. It's obviously a struct but its seemingly not defined as one anywhere. Eventually we stumble upon pr_edict.c (awesome name) and in it:

globalvars_t	*pr_global_struct;

And so another question: where and what is globalvars_t? Notice that every quake file includes quakedef.h. But even when we look in that file globalvars_t isn't present. But within this header file are more includes, and an important one: progs.h.

In progs.h we see a similar variable declaration as in pr_edict.c but as an extern:

extern	globalvars_t	*pr_global_struct;

So, we're on the right track. But again, where is this globalvars_t type/struct coming from? The file has two includes:

#include "pr_comp.h"			// defs shared with qcc
#include "progdefs.h"			// generated by program cdefs

pr_comp.h doesn't show anything related, but it is useful to note that this file doesn't have any includes itself, so its self contained. That leaves progdefs.h and luckily for us, its a simple file. In its entirety:

#ifdef QUAKE2
#include "progdefs.q2"
#else
#include "progdefs.q1"
#endif

We're interested in quake 1 so the .q1 file it is. And we finally see the actual struct that globalvars_t is:

typedef struct
{   int           pad[28];
    int           self;
    int           other;
    int           world;
    float	  time;
    float	  frametime;
    float	  force_retouch;
    string_t      mapname;
    float	  deathmatch;
    float	  coop;
    float	  teamplay;
    float	  serverflags;
    float	  total_secrets;
    float	  total_monsters;
    float	  found_secrets;
    float	  killed_monsters;
    float	  parm1;
    float	  parm2;
    float	  parm3;
    float	  parm4;
    float	  parm5;
    float	  parm6;
    float	  parm7;
    float	  parm8;
    float	  parm9;
    float	  parm10;
    float	  parm11;
    float	  parm12;
    float	  parm13;
    float	  parm14;
    float	  parm15;
    float	  parm16;
    vec3_t	  v_forward;
    vec3_t	  v_up;
    vec3_t	  v_right;
    float	  trace_allsolid;
    float	  trace_startsolid;
    float	  trace_fraction;
    vec3_t	  trace_endpos;
    vec3_t	  trace_plane_normal;
    float	  trace_plane_dist;
    int           trace_ent;
    float	  trace_inopen;
    float	  trace_inwater;
    int           msg_entity;
    func_t	  main;
    func_t	  StartFrame;
    func_t	  PlayerPreThink;
    func_t	  PlayerPostThink;
    func_t	  ClientKill;
    func_t	  ClientConnect;
    func_t	  PutClientInServer;
    func_t	  ClientDisconnect;
    func_t	  SetNewParms;
    func_t	  SetChangeParms;
} globalvars_t;

There's also another struct called entvars_t in the file. So, this is a QuakeC'ism as the file indicates:

/* file generated by qcc, do not modify */

qcc = QuakeC Compiler

Looking at the struct I can't really see any coherence to this grouping of variables. It's quite random so I take it as these are variables used a lot and that needed to be stuffed somewhere.

And so, all our original line here is doing:

pr_global_struct->frametime = host_frametime;

Is updating the frametime of the local Quake server (as opposed to the client).