quake2ts 0.0.198 → 0.0.199

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.
@@ -3813,18 +3813,20 @@ import { ClientPrediction, interpolatePredictionState as interpolatePredictionSt
3813
3813
  import { ViewEffects } from "@quake2ts/cgame";
3814
3814
 
3815
3815
  // src/cgameBridge.ts
3816
- function createCGameImport(imports) {
3816
+ function createCGameImport(imports, state) {
3817
+ const picCache = /* @__PURE__ */ new Map();
3818
+ const pendingPics = /* @__PURE__ */ new Set();
3817
3819
  const getRenderer = () => imports.engine.renderer;
3818
3820
  return {
3819
- // Frame timing - stubbed for now until we fix the access pattern
3821
+ // Frame timing
3820
3822
  get tick_rate() {
3821
- return 10;
3823
+ return state.tickRate;
3822
3824
  },
3823
3825
  get frame_time_s() {
3824
- return 0;
3826
+ return state.frameTimeMs / 1e3;
3825
3827
  },
3826
3828
  get frame_time_ms() {
3827
- return 0;
3829
+ return state.frameTimeMs;
3828
3830
  },
3829
3831
  // Console
3830
3832
  Com_Print: (msg) => {
@@ -3835,7 +3837,7 @@ function createCGameImport(imports) {
3835
3837
  },
3836
3838
  // Config strings
3837
3839
  get_configstring: (num) => {
3838
- return "";
3840
+ return state.configStrings.get(num) || "";
3839
3841
  },
3840
3842
  // Memory (No-op in JS)
3841
3843
  TagMalloc: (size, tag) => ({}),
@@ -3845,27 +3847,27 @@ function createCGameImport(imports) {
3845
3847
  },
3846
3848
  // Cvars
3847
3849
  cvar: (name, value, flags) => {
3850
+ const existing = imports.host?.cvars?.get(name);
3851
+ if (existing) return existing;
3848
3852
  return null;
3849
3853
  },
3850
3854
  cvar_set: (name, value) => {
3851
- if (imports.host?.cvars) {
3852
- imports.host.cvars.setValue(name, value);
3853
- }
3855
+ imports.host?.cvars?.setValue(name, value);
3854
3856
  },
3855
3857
  cvar_forceset: (name, value) => {
3856
- if (imports.host?.cvars) {
3857
- imports.host.cvars.setValue(name, value);
3858
- }
3858
+ imports.host?.cvars?.setValue(name, value);
3859
3859
  },
3860
3860
  // Client state
3861
3861
  CL_FrameValid: () => true,
3862
- CL_FrameTime: () => 0,
3863
- CL_ClientTime: () => 0,
3864
- CL_ServerFrame: () => 0,
3865
- CL_ServerProtocol: () => 34,
3862
+ // Always assume valid for now
3863
+ CL_FrameTime: () => state.frameTimeMs,
3864
+ CL_ClientTime: () => state.frameTimeMs,
3865
+ // Use frame time as client time
3866
+ CL_ServerFrame: () => state.serverFrame,
3867
+ CL_ServerProtocol: () => state.serverProtocol,
3866
3868
  // Client info
3867
3869
  CL_GetClientName: (playerNum) => {
3868
- return `Player ${playerNum}`;
3870
+ return state.getClientName(playerNum);
3869
3871
  },
3870
3872
  CL_GetClientPic: (playerNum) => {
3871
3873
  return "";
@@ -3874,25 +3876,55 @@ function createCGameImport(imports) {
3874
3876
  return "";
3875
3877
  },
3876
3878
  CL_GetKeyBinding: (key) => {
3877
- return `[${key}]`;
3879
+ return state.getKeyBinding(key);
3878
3880
  },
3879
3881
  // Drawing
3880
3882
  Draw_RegisterPic: (name) => {
3881
- if (imports.engine.assets) {
3883
+ if (picCache.has(name)) {
3882
3884
  return name;
3883
3885
  }
3886
+ if (pendingPics.has(name)) {
3887
+ return name;
3888
+ }
3889
+ pendingPics.add(name);
3890
+ if (imports.engine.assets) {
3891
+ imports.engine.assets.loadTexture(name).then((texture) => {
3892
+ if (imports.engine.renderer) {
3893
+ const pic = imports.engine.renderer.registerTexture(name, texture);
3894
+ picCache.set(name, pic);
3895
+ }
3896
+ pendingPics.delete(name);
3897
+ }).catch((err) => {
3898
+ console.warn(`[CGameImport] Failed to load pic: ${name}`, err);
3899
+ pendingPics.delete(name);
3900
+ });
3901
+ }
3884
3902
  return name;
3885
3903
  },
3886
- Draw_GetPicSize: (pic) => {
3887
- return { width: 32, height: 32 };
3904
+ Draw_GetPicSize: (picHandle) => {
3905
+ const name = picHandle;
3906
+ const pic = picCache.get(name);
3907
+ if (pic) {
3908
+ return { width: pic.width, height: pic.height };
3909
+ }
3910
+ return { width: 0, height: 0 };
3888
3911
  },
3889
3912
  SCR_DrawChar: (x, y, char) => {
3890
3913
  getRenderer()?.drawString(x, y, String.fromCharCode(char));
3891
3914
  },
3892
- SCR_DrawPic: (x, y, pic) => {
3893
- const name = pic;
3915
+ SCR_DrawPic: (x, y, picHandle) => {
3916
+ const name = picHandle;
3917
+ const pic = picCache.get(name);
3918
+ if (pic) {
3919
+ getRenderer()?.drawPic(x, y, pic);
3920
+ }
3894
3921
  },
3895
- SCR_DrawColorPic: (x, y, pic, color, alpha) => {
3922
+ SCR_DrawColorPic: (x, y, picHandle, color, alpha) => {
3923
+ const name = picHandle;
3924
+ const pic = picCache.get(name);
3925
+ if (pic) {
3926
+ getRenderer()?.drawPic(x, y, pic, [color.x, color.y, color.z, alpha]);
3927
+ }
3896
3928
  },
3897
3929
  SCR_DrawFontString: (x, y, str3) => {
3898
3930
  getRenderer()?.drawString(x, y, str3);
@@ -3908,6 +3940,7 @@ function createCGameImport(imports) {
3908
3940
  SCR_SetAltTypeface: (alt) => {
3909
3941
  },
3910
3942
  SCR_DrawBind: (x, y, command) => {
3943
+ const key = state.getKeyBinding(command);
3911
3944
  getRenderer()?.drawString(x, y, `[${command}]`);
3912
3945
  },
3913
3946
  // Localization
@@ -3915,11 +3948,10 @@ function createCGameImport(imports) {
3915
3948
  // State queries
3916
3949
  CL_GetTextInput: () => "",
3917
3950
  CL_GetWarnAmmoCount: () => 5,
3918
- // Low ammo threshold
3919
- CL_InAutoDemoLoop: () => false,
3951
+ CL_InAutoDemoLoop: () => state.inAutoDemo,
3920
3952
  // Prediction Trace
3921
3953
  PM_Trace: (start, end, mins, maxs) => {
3922
- return imports.engine.trace(start, end);
3954
+ return imports.engine.trace(start, end, mins, maxs);
3923
3955
  }
3924
3956
  };
3925
3957
  }
@@ -4821,6 +4853,9 @@ var ClientNetworkHandler = class {
4821
4853
  }
4822
4854
  return latestState;
4823
4855
  }
4856
+ get latestServerFrame() {
4857
+ return this.latestFrame?.serverFrame ?? 0;
4858
+ }
4824
4859
  };
4825
4860
 
4826
4861
  // src/configStrings.ts
@@ -6238,7 +6273,32 @@ function createClient(imports) {
6238
6273
  let lastRendered;
6239
6274
  let lastView;
6240
6275
  let camera;
6241
- const cgameImport = createCGameImport(imports);
6276
+ let clientInAutoDemo = false;
6277
+ const stateProvider = {
6278
+ get tickRate() {
6279
+ return 10;
6280
+ },
6281
+ // Default 10Hz
6282
+ get frameTimeMs() {
6283
+ return latestFrame?.timeMs ?? 0;
6284
+ },
6285
+ get serverFrame() {
6286
+ return demoHandler.latestServerFrame;
6287
+ },
6288
+ // Corrected access
6289
+ get serverProtocol() {
6290
+ return 34;
6291
+ },
6292
+ get configStrings() {
6293
+ return configStrings;
6294
+ },
6295
+ getClientName: (num) => `Player ${num}`,
6296
+ getKeyBinding: (key) => `[${key}]`,
6297
+ get inAutoDemo() {
6298
+ return clientInAutoDemo;
6299
+ }
6300
+ };
6301
+ const cgameImport = createCGameImport(imports, stateProvider);
6242
6302
  const cg = GetCGameAPI(cgameImport);
6243
6303
  let fovValue = 90;
6244
6304
  let isZooming = false;