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.
@@ -3843,6 +3843,150 @@ var AMMO_TYPE_COUNT2 = Object.keys(AmmoType2).length / 2;
3843
3843
  var import_cgame2 = require("@quake2ts/cgame");
3844
3844
  var import_cgame3 = require("@quake2ts/cgame");
3845
3845
 
3846
+ // src/cgameBridge.ts
3847
+ function createCGameImport(imports, state) {
3848
+ const picCache = /* @__PURE__ */ new Map();
3849
+ const pendingPics = /* @__PURE__ */ new Set();
3850
+ const getRenderer = () => imports.engine.renderer;
3851
+ return {
3852
+ // Frame timing
3853
+ get tick_rate() {
3854
+ return state.tickRate;
3855
+ },
3856
+ get frame_time_s() {
3857
+ return state.frameTimeMs / 1e3;
3858
+ },
3859
+ get frame_time_ms() {
3860
+ return state.frameTimeMs;
3861
+ },
3862
+ // Console
3863
+ Com_Print: (msg) => {
3864
+ console.log(`[CGAME] ${msg}`);
3865
+ },
3866
+ Com_Error: (msg) => {
3867
+ console.error(`[CGAME ERROR] ${msg}`);
3868
+ },
3869
+ // Config strings
3870
+ get_configstring: (num) => {
3871
+ return state.configStrings.get(num) || "";
3872
+ },
3873
+ // Memory (No-op in JS)
3874
+ TagMalloc: (size, tag) => ({}),
3875
+ TagFree: (ptr) => {
3876
+ },
3877
+ FreeTags: (tag) => {
3878
+ },
3879
+ // Cvars
3880
+ cvar: (name, value, flags) => {
3881
+ const existing = imports.host?.cvars?.get(name);
3882
+ if (existing) return existing;
3883
+ return null;
3884
+ },
3885
+ cvar_set: (name, value) => {
3886
+ imports.host?.cvars?.setValue(name, value);
3887
+ },
3888
+ cvar_forceset: (name, value) => {
3889
+ imports.host?.cvars?.setValue(name, value);
3890
+ },
3891
+ // Client state
3892
+ CL_FrameValid: () => true,
3893
+ // Always assume valid for now
3894
+ CL_FrameTime: () => state.frameTimeMs,
3895
+ CL_ClientTime: () => state.frameTimeMs,
3896
+ // Use frame time as client time
3897
+ CL_ServerFrame: () => state.serverFrame,
3898
+ CL_ServerProtocol: () => state.serverProtocol,
3899
+ // Client info
3900
+ CL_GetClientName: (playerNum) => {
3901
+ return state.getClientName(playerNum);
3902
+ },
3903
+ CL_GetClientPic: (playerNum) => {
3904
+ return "";
3905
+ },
3906
+ CL_GetClientDogtag: (playerNum) => {
3907
+ return "";
3908
+ },
3909
+ CL_GetKeyBinding: (key) => {
3910
+ return state.getKeyBinding(key);
3911
+ },
3912
+ // Drawing
3913
+ Draw_RegisterPic: (name) => {
3914
+ if (picCache.has(name)) {
3915
+ return name;
3916
+ }
3917
+ if (pendingPics.has(name)) {
3918
+ return name;
3919
+ }
3920
+ pendingPics.add(name);
3921
+ if (imports.engine.assets) {
3922
+ imports.engine.assets.loadTexture(name).then((texture) => {
3923
+ if (imports.engine.renderer) {
3924
+ const pic = imports.engine.renderer.registerTexture(name, texture);
3925
+ picCache.set(name, pic);
3926
+ }
3927
+ pendingPics.delete(name);
3928
+ }).catch((err) => {
3929
+ console.warn(`[CGameImport] Failed to load pic: ${name}`, err);
3930
+ pendingPics.delete(name);
3931
+ });
3932
+ }
3933
+ return name;
3934
+ },
3935
+ Draw_GetPicSize: (picHandle) => {
3936
+ const name = picHandle;
3937
+ const pic = picCache.get(name);
3938
+ if (pic) {
3939
+ return { width: pic.width, height: pic.height };
3940
+ }
3941
+ return { width: 0, height: 0 };
3942
+ },
3943
+ SCR_DrawChar: (x, y, char) => {
3944
+ getRenderer()?.drawString(x, y, String.fromCharCode(char));
3945
+ },
3946
+ SCR_DrawPic: (x, y, picHandle) => {
3947
+ const name = picHandle;
3948
+ const pic = picCache.get(name);
3949
+ if (pic) {
3950
+ getRenderer()?.drawPic(x, y, pic);
3951
+ }
3952
+ },
3953
+ SCR_DrawColorPic: (x, y, picHandle, color, alpha) => {
3954
+ const name = picHandle;
3955
+ const pic = picCache.get(name);
3956
+ if (pic) {
3957
+ getRenderer()?.drawPic(x, y, pic, [color.x, color.y, color.z, alpha]);
3958
+ }
3959
+ },
3960
+ SCR_DrawFontString: (x, y, str3) => {
3961
+ getRenderer()?.drawString(x, y, str3);
3962
+ },
3963
+ SCR_DrawCenterString: (y, str3) => {
3964
+ getRenderer()?.drawCenterString(y, str3);
3965
+ },
3966
+ SCR_MeasureFontString: (str3) => {
3967
+ const stripped = str3.replace(/\^[0-9]/g, "");
3968
+ return stripped.length * 8;
3969
+ },
3970
+ SCR_FontLineHeight: () => 8,
3971
+ SCR_SetAltTypeface: (alt) => {
3972
+ },
3973
+ SCR_DrawBind: (x, y, command) => {
3974
+ const key = state.getKeyBinding(command);
3975
+ getRenderer()?.drawString(x, y, `[${command}]`);
3976
+ },
3977
+ // Localization
3978
+ Localize: (key) => key,
3979
+ // State queries
3980
+ CL_GetTextInput: () => "",
3981
+ CL_GetWarnAmmoCount: () => 5,
3982
+ CL_InAutoDemoLoop: () => state.inAutoDemo,
3983
+ // Prediction Trace
3984
+ PM_Trace: (start, end, mins, maxs) => {
3985
+ return imports.engine.trace(start, end, mins, maxs);
3986
+ }
3987
+ };
3988
+ }
3989
+
3846
3990
  // src/hud/crosshair.ts
3847
3991
  var crosshairPic = null;
3848
3992
  var crosshairIndex = 0;
@@ -4740,6 +4884,9 @@ var ClientNetworkHandler = class {
4740
4884
  }
4741
4885
  return latestState;
4742
4886
  }
4887
+ get latestServerFrame() {
4888
+ return this.latestFrame?.serverFrame ?? 0;
4889
+ }
4743
4890
  };
4744
4891
 
4745
4892
  // src/configStrings.ts
@@ -6154,6 +6301,33 @@ function createClient(imports) {
6154
6301
  let lastRendered;
6155
6302
  let lastView;
6156
6303
  let camera;
6304
+ let clientInAutoDemo = false;
6305
+ const stateProvider = {
6306
+ get tickRate() {
6307
+ return 10;
6308
+ },
6309
+ // Default 10Hz
6310
+ get frameTimeMs() {
6311
+ return latestFrame?.timeMs ?? 0;
6312
+ },
6313
+ get serverFrame() {
6314
+ return demoHandler.latestServerFrame;
6315
+ },
6316
+ // Corrected access
6317
+ get serverProtocol() {
6318
+ return 34;
6319
+ },
6320
+ get configStrings() {
6321
+ return configStrings;
6322
+ },
6323
+ getClientName: (num) => `Player ${num}`,
6324
+ getKeyBinding: (key) => `[${key}]`,
6325
+ get inAutoDemo() {
6326
+ return clientInAutoDemo;
6327
+ }
6328
+ };
6329
+ const cgameImport = createCGameImport(imports, stateProvider);
6330
+ const cg = (0, import_cgame2.GetCGameAPI)(cgameImport);
6157
6331
  let fovValue = 90;
6158
6332
  let isZooming = false;
6159
6333
  if (imports.host) {
@@ -6230,6 +6404,7 @@ function createClient(imports) {
6230
6404
  if (initial?.state) {
6231
6405
  prediction.setAuthoritative(initial);
6232
6406
  }
6407
+ cg.Init();
6233
6408
  if (imports.engine.assets && imports.engine.renderer) {
6234
6409
  loadingScreen.start(100, "Loading assets...");
6235
6410
  Init_Hud(imports.engine.renderer, imports.engine.assets).then(() => {
@@ -6459,6 +6634,7 @@ function createClient(imports) {
6459
6634
  this.Shutdown();
6460
6635
  },
6461
6636
  Shutdown() {
6637
+ cg.Shutdown();
6462
6638
  latestFrame = void 0;
6463
6639
  lastRendered = void 0;
6464
6640
  if (imports.host?.cvars) {