quake2ts 0.0.299 → 0.0.301

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8309,6 +8309,13 @@ var NetworkMessageParser = class _NetworkMessageParser {
8309
8309
  if (bitsHigh & U_OLD_FRAME_HIGH) to.oldFrame = this.stream.readShort();
8310
8310
  }
8311
8311
  };
8312
+ var PlaybackState = /* @__PURE__ */ ((PlaybackState22) => {
8313
+ PlaybackState22[PlaybackState22["Stopped"] = 0] = "Stopped";
8314
+ PlaybackState22[PlaybackState22["Playing"] = 1] = "Playing";
8315
+ PlaybackState22[PlaybackState22["Paused"] = 2] = "Paused";
8316
+ PlaybackState22[PlaybackState22["Finished"] = 3] = "Finished";
8317
+ return PlaybackState22;
8318
+ })(PlaybackState || {});
8312
8319
  var DemoPlaybackController = class {
8313
8320
  // ms (10Hz default)
8314
8321
  constructor() {
@@ -11848,6 +11855,89 @@ var MultiplayerConnection = class {
11848
11855
  }
11849
11856
  };
11850
11857
 
11858
+ // src/ui/demo-controls.ts
11859
+ var DemoControls = class {
11860
+ constructor(playback) {
11861
+ this.isVisible = true;
11862
+ this.playback = playback;
11863
+ }
11864
+ render(renderer, width, height) {
11865
+ if (!this.isVisible) return;
11866
+ const state = this.playback.getState();
11867
+ const isPlaying = state === PlaybackState.Playing;
11868
+ const overlayHeight = 60;
11869
+ const y = height - overlayHeight;
11870
+ renderer.drawfillRect(0, y, width, overlayHeight, [0, 0, 0, 0.5]);
11871
+ const iconSize = 24;
11872
+ const iconY = y + (overlayHeight - iconSize) / 2;
11873
+ const iconX = 20;
11874
+ const statusText = isPlaying ? "PAUSE" : "PLAY";
11875
+ renderer.drawString(iconX, iconY, statusText);
11876
+ const speed = this.playback.getSpeed();
11877
+ const speedText = `Speed: ${speed}x`;
11878
+ renderer.drawCenterString(iconY, speedText);
11879
+ const currentTime = this.playback.getCurrentTime();
11880
+ const currentFormatted = this.formatTime(currentTime);
11881
+ const totalFormatted = "--:--";
11882
+ const timeText = `${currentFormatted} / ${totalFormatted}`;
11883
+ const timeX = width - 150;
11884
+ renderer.drawString(timeX, iconY, timeText);
11885
+ const timelineY = y + 5;
11886
+ const timelineHeight = 4;
11887
+ const timelineWidth = width - 40;
11888
+ const timelineX = 20;
11889
+ renderer.drawfillRect(timelineX, timelineY, timelineWidth, timelineHeight, [0.3, 0.3, 0.3, 1]);
11890
+ const progress = 0;
11891
+ const progressWidth = timelineWidth * progress;
11892
+ renderer.drawfillRect(timelineX, timelineY, progressWidth, timelineHeight, [1, 1, 1, 1]);
11893
+ const markerX = timelineX + progressWidth;
11894
+ renderer.drawfillRect(markerX - 2, timelineY - 2, 4, timelineHeight + 4, [1, 0, 0, 1]);
11895
+ const helpText = "[Space] Toggle [< >] Step [ [ ] ] Speed [Esc] Stop";
11896
+ renderer.drawCenterString(y + 35, helpText);
11897
+ }
11898
+ handleInput(key, down) {
11899
+ if (!down) return false;
11900
+ switch (key.toLowerCase()) {
11901
+ case " ":
11902
+ if (this.playback.getState() === PlaybackState.Playing) {
11903
+ this.playback.pause();
11904
+ } else if (this.playback.getState() === PlaybackState.Paused) {
11905
+ this.playback.play();
11906
+ }
11907
+ return true;
11908
+ case "arrowright":
11909
+ this.playback.stepForward();
11910
+ return true;
11911
+ case "arrowleft":
11912
+ this.playback.stepBackward();
11913
+ return true;
11914
+ case "]":
11915
+ this.changeSpeed(2);
11916
+ return true;
11917
+ case "[":
11918
+ this.changeSpeed(0.5);
11919
+ return true;
11920
+ case "escape":
11921
+ this.playback.stop();
11922
+ return true;
11923
+ }
11924
+ return false;
11925
+ }
11926
+ changeSpeed(factor) {
11927
+ const current = this.playback.getSpeed();
11928
+ let newSpeed = current * factor;
11929
+ if (newSpeed < 0.1) newSpeed = 0.1;
11930
+ if (newSpeed > 16) newSpeed = 16;
11931
+ this.playback.setSpeed(newSpeed);
11932
+ }
11933
+ formatTime(ms) {
11934
+ const totalSeconds = Math.floor(ms / 1e3);
11935
+ const minutes = Math.floor(totalSeconds / 60);
11936
+ const seconds = totalSeconds % 60;
11937
+ return `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
11938
+ }
11939
+ };
11940
+
11851
11941
  // src/input/bindings.ts
11852
11942
  var DEFAULT_BINDINGS = [
11853
11943
  { code: "KeyW", command: "+forward" },
@@ -12363,6 +12453,7 @@ function createClient(imports) {
12363
12453
  const prediction = new ClientPrediction2(imports.engine.trace, pointContents);
12364
12454
  const view = new ViewEffects2();
12365
12455
  const demoPlayback = new DemoPlaybackController();
12456
+ const demoControls = new DemoControls(demoPlayback);
12366
12457
  const demoHandler = new ClientNetworkHandler(imports);
12367
12458
  demoHandler.setView(view);
12368
12459
  let isDemoPlaying = false;
@@ -12557,6 +12648,11 @@ function createClient(imports) {
12557
12648
  return prediction.enqueueCommand(command);
12558
12649
  },
12559
12650
  handleInput(key, down) {
12651
+ if (isDemoPlaying) {
12652
+ if (demoControls.handleInput(key, down)) {
12653
+ return true;
12654
+ }
12655
+ }
12560
12656
  if (!menuSystem.isActive()) return false;
12561
12657
  if (!down) return true;
12562
12658
  const lowerKey = key.toLowerCase();
@@ -12776,6 +12872,9 @@ function createClient(imports) {
12776
12872
  if (menuSystem.isActive()) {
12777
12873
  Draw_Menu(imports.engine.renderer, menuSystem.getState(), imports.engine.renderer.width, imports.engine.renderer.height);
12778
12874
  }
12875
+ if (isDemoPlaying) {
12876
+ demoControls.render(imports.engine.renderer, imports.engine.renderer.width, imports.engine.renderer.height);
12877
+ }
12779
12878
  if (lastRendered && lastRendered.client) {
12780
12879
  wheelMenuSystem.render(imports.engine.renderer, imports.engine.renderer.width, imports.engine.renderer.height, lastRendered.client);
12781
12880
  }