quake2ts 0.0.197 → 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.
@@ -3809,9 +3809,153 @@ var AmmoType2 = /* @__PURE__ */ ((AmmoType22) => {
3809
3809
  var AMMO_TYPE_COUNT2 = Object.keys(AmmoType2).length / 2;
3810
3810
 
3811
3811
  // src/index.ts
3812
- import { ClientPrediction, interpolatePredictionState as interpolatePredictionState2 } from "@quake2ts/cgame";
3812
+ import { ClientPrediction, interpolatePredictionState as interpolatePredictionState2, GetCGameAPI } from "@quake2ts/cgame";
3813
3813
  import { ViewEffects } from "@quake2ts/cgame";
3814
3814
 
3815
+ // src/cgameBridge.ts
3816
+ function createCGameImport(imports, state) {
3817
+ const picCache = /* @__PURE__ */ new Map();
3818
+ const pendingPics = /* @__PURE__ */ new Set();
3819
+ const getRenderer = () => imports.engine.renderer;
3820
+ return {
3821
+ // Frame timing
3822
+ get tick_rate() {
3823
+ return state.tickRate;
3824
+ },
3825
+ get frame_time_s() {
3826
+ return state.frameTimeMs / 1e3;
3827
+ },
3828
+ get frame_time_ms() {
3829
+ return state.frameTimeMs;
3830
+ },
3831
+ // Console
3832
+ Com_Print: (msg) => {
3833
+ console.log(`[CGAME] ${msg}`);
3834
+ },
3835
+ Com_Error: (msg) => {
3836
+ console.error(`[CGAME ERROR] ${msg}`);
3837
+ },
3838
+ // Config strings
3839
+ get_configstring: (num) => {
3840
+ return state.configStrings.get(num) || "";
3841
+ },
3842
+ // Memory (No-op in JS)
3843
+ TagMalloc: (size, tag) => ({}),
3844
+ TagFree: (ptr) => {
3845
+ },
3846
+ FreeTags: (tag) => {
3847
+ },
3848
+ // Cvars
3849
+ cvar: (name, value, flags) => {
3850
+ const existing = imports.host?.cvars?.get(name);
3851
+ if (existing) return existing;
3852
+ return null;
3853
+ },
3854
+ cvar_set: (name, value) => {
3855
+ imports.host?.cvars?.setValue(name, value);
3856
+ },
3857
+ cvar_forceset: (name, value) => {
3858
+ imports.host?.cvars?.setValue(name, value);
3859
+ },
3860
+ // Client state
3861
+ CL_FrameValid: () => true,
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,
3868
+ // Client info
3869
+ CL_GetClientName: (playerNum) => {
3870
+ return state.getClientName(playerNum);
3871
+ },
3872
+ CL_GetClientPic: (playerNum) => {
3873
+ return "";
3874
+ },
3875
+ CL_GetClientDogtag: (playerNum) => {
3876
+ return "";
3877
+ },
3878
+ CL_GetKeyBinding: (key) => {
3879
+ return state.getKeyBinding(key);
3880
+ },
3881
+ // Drawing
3882
+ Draw_RegisterPic: (name) => {
3883
+ if (picCache.has(name)) {
3884
+ return name;
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
+ }
3902
+ return name;
3903
+ },
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 };
3911
+ },
3912
+ SCR_DrawChar: (x, y, char) => {
3913
+ getRenderer()?.drawString(x, y, String.fromCharCode(char));
3914
+ },
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
+ }
3921
+ },
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
+ }
3928
+ },
3929
+ SCR_DrawFontString: (x, y, str3) => {
3930
+ getRenderer()?.drawString(x, y, str3);
3931
+ },
3932
+ SCR_DrawCenterString: (y, str3) => {
3933
+ getRenderer()?.drawCenterString(y, str3);
3934
+ },
3935
+ SCR_MeasureFontString: (str3) => {
3936
+ const stripped = str3.replace(/\^[0-9]/g, "");
3937
+ return stripped.length * 8;
3938
+ },
3939
+ SCR_FontLineHeight: () => 8,
3940
+ SCR_SetAltTypeface: (alt) => {
3941
+ },
3942
+ SCR_DrawBind: (x, y, command) => {
3943
+ const key = state.getKeyBinding(command);
3944
+ getRenderer()?.drawString(x, y, `[${command}]`);
3945
+ },
3946
+ // Localization
3947
+ Localize: (key) => key,
3948
+ // State queries
3949
+ CL_GetTextInput: () => "",
3950
+ CL_GetWarnAmmoCount: () => 5,
3951
+ CL_InAutoDemoLoop: () => state.inAutoDemo,
3952
+ // Prediction Trace
3953
+ PM_Trace: (start, end, mins, maxs) => {
3954
+ return imports.engine.trace(start, end, mins, maxs);
3955
+ }
3956
+ };
3957
+ }
3958
+
3815
3959
  // src/hud/crosshair.ts
3816
3960
  var crosshairPic = null;
3817
3961
  var crosshairIndex = 0;
@@ -4709,6 +4853,9 @@ var ClientNetworkHandler = class {
4709
4853
  }
4710
4854
  return latestState;
4711
4855
  }
4856
+ get latestServerFrame() {
4857
+ return this.latestFrame?.serverFrame ?? 0;
4858
+ }
4712
4859
  };
4713
4860
 
4714
4861
  // src/configStrings.ts
@@ -6126,6 +6273,33 @@ function createClient(imports) {
6126
6273
  let lastRendered;
6127
6274
  let lastView;
6128
6275
  let camera;
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);
6302
+ const cg = GetCGameAPI(cgameImport);
6129
6303
  let fovValue = 90;
6130
6304
  let isZooming = false;
6131
6305
  if (imports.host) {
@@ -6202,6 +6376,7 @@ function createClient(imports) {
6202
6376
  if (initial?.state) {
6203
6377
  prediction.setAuthoritative(initial);
6204
6378
  }
6379
+ cg.Init();
6205
6380
  if (imports.engine.assets && imports.engine.renderer) {
6206
6381
  loadingScreen.start(100, "Loading assets...");
6207
6382
  Init_Hud(imports.engine.renderer, imports.engine.assets).then(() => {
@@ -6431,6 +6606,7 @@ function createClient(imports) {
6431
6606
  this.Shutdown();
6432
6607
  },
6433
6608
  Shutdown() {
6609
+ cg.Shutdown();
6434
6610
  latestFrame = void 0;
6435
6611
  lastRendered = void 0;
6436
6612
  if (imports.host?.cvars) {