Commit graph

9 commits

Author SHA1 Message Date
643c1d0294 Replace non-ASCII characters in comments with ASCII equivalents
Em dashes (---) replaced with --, arrows replaced with ->.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:58:47 +08:00
fe628a2cc4 Remove PVS data from demo format, derive during playback
Stop recording currentOrigin, absmin, absmax, linked per entity
(44 bytes per moving entity per frame). During playback, G_RunFrame
computes currentOrigin via BG_EvaluateTrajectory and calls
trap_LinkEntity to register in BSP for PVS.

svFlags still recorded (1-bit change flag + 4 bytes when changed).
Entity linking moved from SVD_ReadFrame (server, no trajectory eval)
to G_RunFrame demo mode (game module, has BG_EvaluateTrajectory).

Scan all MAX_GENTITIES during playback since recorded entities may
have indices above level.num_entities (game-module-spawned count).

Demo format bumped to v3. Significant file size reduction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 05:00:21 +08:00
5a98ef02cf Use cached g_svDemoPlaying.integer instead of trap_Cvar syscalls
sv_demoplaying is set before devmap, synced during G_RegisterCvars,
and updated every frame by G_UpdateCvars. No need for defensive
trap_Cvar_VariableIntegerValue calls which add unnecessary syscall
overhead on every invocation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 04:32:57 +08:00
2ce4aa88f2 Fix follow mode switching and PVS during pause
Three issues fixed:

1. ClientThink called ClientThink_real during demo playback, which
   ran server-side PmoveSingle and overwrote the client-owned
   ps.origin. Now ClientThink returns early in demo mode after
   updating pers.cmd (for button access).

2. Buttons never reached the server while paused: SV_UserMove
   discards usercmds with duplicate serverTime (line 1421). During
   pause, all usercmds have frozen serverTime. Fix: always process
   the last usercmd in the packet during demo playback.

3. Spectator button handling in G_RunFrame demo mode processes
   MOUSE1 (attack) to cycle follow targets via Cmd_FollowCycle_f.
   Removed debug print.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 04:31:39 +08:00
6e13c747ba Client-owned camera for demo spectator
cgame runs its own PmoveSingle for the free camera using real time,
independent of server time. Solves pause freezing — camera moves
smoothly while svs.time is frozen.

Changes:
- usercmd_t: add optional origin[3] with 1-bit flag (zero cost for
  normal gameplay, 13 bytes during demo viewing)
- msg.c: serialize optional origin in usercmd delta encoding
- CG_SETCLIENTORIGIN trap: cgame sends camera origin to engine
- cl_input.c: CL_FinishMove writes cgame origin into usercmd
- cg_predict.c: CG_PredictPlayerState runs local PmoveSingle for
  free camera in svDemo mode, sends origin via trap for PVS
- cg_snapshot.c: detect follow→free camera transition, init camera
  from last known position
- cg_main.c: detect svDemo mode from CS_SVDEMO configstring,
  lazy-init camera from first snapshot's spectator spawn
- g_main.c: G_InitGame sets CS_SVDEMO configstring, G_RunFrame
  copies cmd.origin to ps.origin for PVS instead of ClientThink_real
- bg_public.h: CS_SVDEMO configstring index (26)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 03:51:51 +08:00
0bd116982a Add player follow mode during demo playback
Call CalculateRanks and ClientEndFrame for the spectator in demo
mode G_RunFrame. SpectatorClientEndFrame copies the followed
player's recorded playerState into the spectator's ps, giving
first-person view with full HUD (health, armor, ammo, weapon).

Standard spectator controls work: mouse1 to cycle, mouse2 to
enter follow from free camera.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 04:52:58 +08:00
1f8c8aea1c Record playerStates for scoreboard and future follow mode
Record delta-compressed playerState_t for each active player per
frame using MSG_WriteDeltaPlayerstate. During playback, inject
into game module via SV_GameClientNum and mark players as
CON_CONNECTED with correct team. CalculateRanks and the
scoreboard now show recorded players with scores.

This also lays the groundwork for player-follow spectating.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 04:46:40 +08:00
a8044aad8b Server-side demo recording and playback (netdemo)
Records full entity state array each server frame, enabling
free-camera demo playback from any viewpoint.

Recording:
- svdemo_record <name> / svdemo_stop
- Captures entityState_t + PVS fields (svFlags, linked,
  currentOrigin, absmin, absmax) for all active entities
- Records configstring changes per frame
- File format: svdemos/<name>.svdm

Playback:
- svdemo_play <name>
- Loads map with maxclients=64, reserves recorded player slots
  (CS_ZOMBIE with safe rate/timing) so spectator gets a high slot
- Injects recorded entities into sv.gentities each frame with
  SV_LinkEntity for PVS visibility
- Re-applies demo configstrings (CS_PLAYERS etc.) after map load,
  skipping CS_SERVERINFO/CS_SYSTEMINFO to avoid latch restarts
- Game module runs in demo mode (sv_demoplaying cvar): G_RunFrame
  only processes spectator movement, skips all entity logic
- Spectator forced to TEAM_SPECTATOR on connect (ClientBegin)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 04:28:55 +08:00
Sergei Shubin
4c57221941 Initial commit: Quake 3 1.32b GPL source 2026-03-18 13:32:24 +08:00