quake2ts 0.0.188 → 0.0.190

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.
Files changed (54) hide show
  1. package/package.json +1 -1
  2. package/packages/cgame/dist/index.cjs +256 -0
  3. package/packages/cgame/dist/index.cjs.map +1 -0
  4. package/packages/cgame/dist/index.d.cts +101 -0
  5. package/packages/cgame/dist/index.d.ts +99 -1
  6. package/packages/cgame/dist/index.js +250 -28
  7. package/packages/cgame/dist/index.js.map +1 -0
  8. package/packages/client/dist/browser/index.global.js +5 -5
  9. package/packages/client/dist/browser/index.global.js.map +1 -1
  10. package/packages/client/dist/cjs/index.cjs +34 -0
  11. package/packages/client/dist/cjs/index.cjs.map +1 -1
  12. package/packages/client/dist/esm/index.js +48 -14
  13. package/packages/client/dist/esm/index.js.map +1 -1
  14. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  15. package/packages/engine/dist/browser/index.global.js +9 -9
  16. package/packages/engine/dist/browser/index.global.js.map +1 -1
  17. package/packages/engine/dist/cjs/index.cjs +17 -0
  18. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  19. package/packages/engine/dist/esm/index.js +17 -0
  20. package/packages/engine/dist/esm/index.js.map +1 -1
  21. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  22. package/packages/game/dist/browser/index.global.js +2 -2
  23. package/packages/game/dist/browser/index.global.js.map +1 -1
  24. package/packages/game/dist/cjs/index.cjs +117 -117
  25. package/packages/game/dist/cjs/index.cjs.map +1 -1
  26. package/packages/game/dist/esm/index.js +117 -117
  27. package/packages/game/dist/esm/index.js.map +1 -1
  28. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  29. package/packages/game/dist/types/inventory/ammo.d.ts +2 -24
  30. package/packages/game/dist/types/inventory/ammo.d.ts.map +1 -1
  31. package/packages/game/dist/types/inventory/playerInventory.d.ts +2 -47
  32. package/packages/game/dist/types/inventory/playerInventory.d.ts.map +1 -1
  33. package/packages/shared/dist/browser/index.global.js +1 -1
  34. package/packages/shared/dist/browser/index.global.js.map +1 -1
  35. package/packages/shared/dist/cjs/index.cjs +153 -0
  36. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  37. package/packages/shared/dist/esm/index.js +142 -0
  38. package/packages/shared/dist/esm/index.js.map +1 -1
  39. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  40. package/packages/shared/dist/types/index.d.ts +1 -0
  41. package/packages/shared/dist/types/index.d.ts.map +1 -1
  42. package/packages/shared/dist/types/items/ammo.d.ts +33 -0
  43. package/packages/shared/dist/types/items/ammo.d.ts.map +1 -0
  44. package/packages/shared/dist/types/items/index.d.ts +7 -0
  45. package/packages/shared/dist/types/items/index.d.ts.map +1 -0
  46. package/packages/shared/dist/types/items/powerups.d.ts +31 -0
  47. package/packages/shared/dist/types/items/powerups.d.ts.map +1 -0
  48. package/packages/shared/dist/types/items/weapons.d.ts +25 -0
  49. package/packages/shared/dist/types/items/weapons.d.ts.map +1 -0
  50. package/packages/shared/dist/types/protocol/index.d.ts +2 -0
  51. package/packages/shared/dist/types/protocol/index.d.ts.map +1 -1
  52. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
  53. package/packages/cgame/dist/index.d.mts +0 -3
  54. package/packages/cgame/dist/index.mjs +0 -7
@@ -1,32 +1,254 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
1
+ // src/hud/messages.ts
2
+ var CENTER_PRINT_DURATION = 3e3;
3
+ var NOTIFY_DURATION = 5e3;
4
+ var MAX_NOTIFY_MESSAGES = 4;
5
+ var MessageSystem = class {
6
+ constructor() {
7
+ this.centerPrintMsg = null;
8
+ this.notifyMessages = [];
9
+ }
10
+ addCenterPrint(text, now) {
11
+ this.centerPrintMsg = {
12
+ text,
13
+ startTime: now,
14
+ duration: CENTER_PRINT_DURATION
15
+ };
16
+ }
17
+ addNotify(text, now) {
18
+ this.notifyMessages.push({
19
+ text,
20
+ startTime: now,
21
+ duration: NOTIFY_DURATION
22
+ });
23
+ if (this.notifyMessages.length > MAX_NOTIFY_MESSAGES) {
24
+ this.notifyMessages.shift();
25
+ }
26
+ }
27
+ // Additional methods for cgame API
28
+ setCenterPrint(text, now) {
29
+ this.centerPrintMsg = {
30
+ text,
31
+ startTime: now,
32
+ duration: CENTER_PRINT_DURATION
33
+ };
34
+ }
35
+ addNotification(text, is_chat, now) {
36
+ this.notifyMessages.push({
37
+ text,
38
+ startTime: now,
39
+ duration: NOTIFY_DURATION
40
+ });
41
+ if (this.notifyMessages.length > MAX_NOTIFY_MESSAGES) {
42
+ this.notifyMessages.shift();
43
+ }
44
+ }
45
+ clearNotifications() {
46
+ this.notifyMessages = [];
15
47
  }
16
- return to;
48
+ clearCenterPrint() {
49
+ this.centerPrintMsg = null;
50
+ }
51
+ drawCenterPrint(renderer, now, layout) {
52
+ if (!this.centerPrintMsg) return;
53
+ if (now > this.centerPrintMsg.startTime + this.centerPrintMsg.duration) {
54
+ this.centerPrintMsg = null;
55
+ return;
56
+ }
57
+ this.centerPrintMsg.text.length * 8;
58
+ const y = layout.CENTER_PRINT_Y;
59
+ renderer.drawCenterString(y, this.centerPrintMsg.text);
60
+ }
61
+ drawNotifications(renderer, now) {
62
+ while (this.notifyMessages.length > 0 && now > this.notifyMessages[0].startTime + this.notifyMessages[0].duration) {
63
+ this.notifyMessages.shift();
64
+ }
65
+ let y = 10;
66
+ for (const msg of this.notifyMessages) {
67
+ renderer.drawString(10, y, msg.text);
68
+ y += 10;
69
+ }
70
+ }
71
+ };
72
+
73
+ // src/hud/layout.ts
74
+ var REFERENCE_WIDTH = 640;
75
+ var REFERENCE_HEIGHT = 480;
76
+ var getHudLayout = (width, height) => {
77
+ const scaleX = width / REFERENCE_WIDTH;
78
+ const scaleY = height / REFERENCE_HEIGHT;
79
+ const scale = Math.min(scaleX, scaleY);
80
+ return {
81
+ // Status bar numbers - Anchored Bottom-Left / Center / Right
82
+ HEALTH_X: 100 * scale,
83
+ HEALTH_Y: height - (REFERENCE_HEIGHT - 450) * scale,
84
+ ARMOR_X: 200 * scale,
85
+ ARMOR_Y: height - (REFERENCE_HEIGHT - 450) * scale,
86
+ AMMO_X: width - (REFERENCE_WIDTH - 540) * scale,
87
+ // Anchor right? 540 is near right (640)
88
+ AMMO_Y: height - (REFERENCE_HEIGHT - 450) * scale,
89
+ // Center print messages - Center
90
+ CENTER_PRINT_X: width / 2,
91
+ CENTER_PRINT_Y: 100 * scale,
92
+ // Top anchor
93
+ // Weapon and powerup icons
94
+ WEAPON_ICON_X: 10 * scale,
95
+ WEAPON_ICON_Y: height - (REFERENCE_HEIGHT - 450) * scale,
96
+ POWERUP_X: width - (REFERENCE_WIDTH - 610) * scale,
97
+ POWERUP_Y: height - (REFERENCE_HEIGHT - 450) * scale,
98
+ scale
99
+ };
17
100
  };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
101
+
102
+ // src/screen.ts
103
+ var cgi = null;
104
+ var hudNumberPics = [];
105
+ var numberWidth = 0;
106
+ var messageSystem = new MessageSystem();
107
+ function CG_InitScreen(imports) {
108
+ cgi = imports;
109
+ }
110
+ function CG_TouchPics() {
111
+ if (!cgi) return;
112
+ hudNumberPics.length = 0;
113
+ for (let i = 0; i < 10; i++) {
114
+ try {
115
+ const pic = cgi.Draw_RegisterPic(`pics/hud/num_${i}.pcx`);
116
+ hudNumberPics.push(pic);
117
+ if (i === 0) {
118
+ const size = cgi.Draw_GetPicSize(pic);
119
+ numberWidth = size.width;
120
+ }
121
+ } catch (e) {
122
+ cgi.Com_Print(`Warning: Failed to load HUD image: pics/hud/num_${i}.pcx
123
+ `);
124
+ }
125
+ }
126
+ }
127
+ function CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps) {
128
+ if (!cgi) {
129
+ console.error("CG_DrawHUD: cgame imports not initialized");
130
+ return;
131
+ }
132
+ cgi.CL_ClientTime();
133
+ getHudLayout(hud_vrect.width, hud_vrect.height);
134
+ if (ps.centerPrint) {
135
+ cgi.SCR_DrawFontString(
136
+ hud_vrect.width / 2,
137
+ hud_vrect.height / 2 - 20,
138
+ ps.centerPrint
139
+ );
140
+ }
141
+ if (ps.notify) {
142
+ cgi.SCR_DrawFontString(8, 8, ps.notify);
143
+ }
144
+ }
145
+ function CG_GetMessageSystem() {
146
+ return messageSystem;
147
+ }
19
148
 
20
149
  // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- GetCGameAPI: () => GetCGameAPI
24
- });
25
- module.exports = __toCommonJS(index_exports);
26
- function GetCGameAPI() {
27
- return {};
28
- }
29
- // Annotate the CommonJS export names for ESM import in node:
30
- 0 && (module.exports = {
31
- GetCGameAPI
32
- });
150
+ var cgi2 = null;
151
+ function Init() {
152
+ if (!cgi2) {
153
+ console.error("CGame Init: cgame imports not set");
154
+ return;
155
+ }
156
+ cgi2.Com_Print("===== CGame Initialization =====\n");
157
+ CG_InitScreen(cgi2);
158
+ cgi2.Com_Print("CGame initialized\n");
159
+ }
160
+ function Shutdown() {
161
+ if (cgi2) {
162
+ cgi2.Com_Print("CGame shutdown\n");
163
+ }
164
+ cgi2 = null;
165
+ }
166
+ function DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps) {
167
+ CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps);
168
+ }
169
+ function TouchPics() {
170
+ CG_TouchPics();
171
+ }
172
+ function GetLayoutFlags(ps) {
173
+ return 0;
174
+ }
175
+ function GetActiveWeaponWheelWeapon(ps) {
176
+ return 0;
177
+ }
178
+ function GetOwnedWeaponWheelWeapons(ps) {
179
+ return [];
180
+ }
181
+ function GetWeaponWheelAmmoCount(ps, weapon) {
182
+ return 0;
183
+ }
184
+ function GetPowerupWheelCount(ps) {
185
+ return 0;
186
+ }
187
+ function GetHitMarkerDamage(ps) {
188
+ return 0;
189
+ }
190
+ function Pmove(pmove) {
191
+ }
192
+ function ParseConfigString(i, s) {
193
+ }
194
+ function ParseCenterPrint(str, isplit, instant) {
195
+ if (!cgi2) return;
196
+ const messageSystem2 = CG_GetMessageSystem();
197
+ messageSystem2.setCenterPrint(str, cgi2.CL_ClientTime());
198
+ }
199
+ function NotifyMessage(isplit, msg, is_chat) {
200
+ if (!cgi2) return;
201
+ const messageSystem2 = CG_GetMessageSystem();
202
+ messageSystem2.addNotification(msg, is_chat, cgi2.CL_ClientTime());
203
+ }
204
+ function ClearNotify(isplit) {
205
+ const messageSystem2 = CG_GetMessageSystem();
206
+ messageSystem2.clearNotifications();
207
+ }
208
+ function ClearCenterprint(isplit) {
209
+ const messageSystem2 = CG_GetMessageSystem();
210
+ messageSystem2.clearCenterPrint();
211
+ }
212
+ function GetMonsterFlashOffset(id) {
213
+ return { x: 0, y: 0, z: 0 };
214
+ }
215
+ function GetExtension(name) {
216
+ return null;
217
+ }
218
+ function GetCGameAPI(imports) {
219
+ cgi2 = imports;
220
+ return {
221
+ // Lifecycle
222
+ Init,
223
+ Shutdown,
224
+ // Rendering
225
+ DrawHUD,
226
+ TouchPics,
227
+ // Layout
228
+ LayoutFlags: GetLayoutFlags,
229
+ // Weapon wheel
230
+ GetActiveWeaponWheelWeapon,
231
+ GetOwnedWeaponWheelWeapons,
232
+ GetWeaponWheelAmmoCount,
233
+ GetPowerupWheelCount,
234
+ // Hit markers
235
+ GetHitMarkerDamage,
236
+ // Prediction
237
+ Pmove,
238
+ // Parsing
239
+ ParseConfigString,
240
+ ParseCenterPrint,
241
+ NotifyMessage,
242
+ // State management
243
+ ClearNotify,
244
+ ClearCenterprint,
245
+ // Effects
246
+ GetMonsterFlashOffset,
247
+ // Extension
248
+ GetExtension
249
+ };
250
+ }
251
+
252
+ export { GetCGameAPI };
253
+ //# sourceMappingURL=index.js.map
254
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hud/messages.ts","../src/hud/layout.ts","../src/screen.ts","../src/index.ts"],"names":["cgi","messageSystem"],"mappings":"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","file":"index.js","sourcesContent":["import { Renderer } from '@quake2ts/engine';\nimport { getHudLayout } from './layout.js';\n\ninterface Message {\n text: string;\n startTime: number;\n duration: number;\n}\n\nconst CENTER_PRINT_DURATION = 3000;\nconst NOTIFY_DURATION = 5000;\nconst MAX_NOTIFY_MESSAGES = 4;\n\nexport class MessageSystem {\n private centerPrintMsg: Message | null = null;\n private notifyMessages: Message[] = [];\n\n addCenterPrint(text: string, now: number) {\n this.centerPrintMsg = {\n text,\n startTime: now,\n duration: CENTER_PRINT_DURATION,\n };\n }\n\n addNotify(text: string, now: number) {\n this.notifyMessages.push({\n text,\n startTime: now,\n duration: NOTIFY_DURATION,\n });\n\n if (this.notifyMessages.length > MAX_NOTIFY_MESSAGES) {\n this.notifyMessages.shift();\n }\n }\n\n // Additional methods for cgame API\n setCenterPrint(text: string, now: number) {\n this.centerPrintMsg = {\n text,\n startTime: now,\n duration: CENTER_PRINT_DURATION,\n };\n }\n\n addNotification(text: string, is_chat: boolean, now: number) {\n this.notifyMessages.push({\n text,\n startTime: now,\n duration: NOTIFY_DURATION,\n });\n\n if (this.notifyMessages.length > MAX_NOTIFY_MESSAGES) {\n this.notifyMessages.shift();\n }\n }\n\n clearNotifications() {\n this.notifyMessages = [];\n }\n\n clearCenterPrint() {\n this.centerPrintMsg = null;\n }\n\n drawCenterPrint(renderer: Renderer, now: number, layout: ReturnType<typeof getHudLayout>) {\n if (!this.centerPrintMsg) return;\n\n if (now > this.centerPrintMsg.startTime + this.centerPrintMsg.duration) {\n this.centerPrintMsg = null;\n return;\n }\n\n // Draw centered text\n const width = this.centerPrintMsg.text.length * 8;\n // We ignore layout.CENTER_PRINT_X because drawCenterString calculates X automatically\n const y = layout.CENTER_PRINT_Y;\n\n renderer.drawCenterString(y, this.centerPrintMsg.text);\n }\n\n drawNotifications(renderer: Renderer, now: number) {\n // Remove expired messages\n while (this.notifyMessages.length > 0 && now > this.notifyMessages[0].startTime + this.notifyMessages[0].duration) {\n this.notifyMessages.shift();\n }\n\n let y = 10; // Start near top-left\n for (const msg of this.notifyMessages) {\n renderer.drawString(10, y, msg.text);\n y += 10; // Line height\n }\n }\n}\n","// Dynamic Layout Scaling\nconst REFERENCE_WIDTH = 640;\nconst REFERENCE_HEIGHT = 480;\n\nexport const getHudLayout = (width: number, height: number) => {\n // Determine scale factor - usually based on height to preserve aspect ratio logic or just scale uniform\n // Quake 2 typically scales 2D elements.\n const scaleX = width / REFERENCE_WIDTH;\n const scaleY = height / REFERENCE_HEIGHT;\n const scale = Math.min(scaleX, scaleY); // Uniform scaling\n\n // Or we can just center the 640x480 rect?\n // Modern approach: Scale UI to fit, or anchor to edges.\n // Let's implement edge anchoring logic relative to 640x480 coordinates.\n\n // Original constants (approximate):\n // HEALTH_X: 100, HEALTH_Y: 450\n // ARMOR_X: 200, ARMOR_Y: 450\n // AMMO_X: 540, AMMO_Y: 450\n // CENTER_PRINT: Center screen\n // WEAPON_ICON: Bottom left\n // POWERUP: Bottom right?\n\n // We'll return scaled coordinates.\n // For bottom elements, we should anchor to bottom.\n\n return {\n // Status bar numbers - Anchored Bottom-Left / Center / Right\n HEALTH_X: 100 * scale,\n HEALTH_Y: height - (REFERENCE_HEIGHT - 450) * scale,\n\n ARMOR_X: 200 * scale,\n ARMOR_Y: height - (REFERENCE_HEIGHT - 450) * scale,\n\n AMMO_X: width - (REFERENCE_WIDTH - 540) * scale, // Anchor right? 540 is near right (640)\n AMMO_Y: height - (REFERENCE_HEIGHT - 450) * scale,\n\n // Center print messages - Center\n CENTER_PRINT_X: width / 2,\n CENTER_PRINT_Y: 100 * scale, // Top anchor\n\n // Weapon and powerup icons\n WEAPON_ICON_X: 10 * scale,\n WEAPON_ICON_Y: height - (REFERENCE_HEIGHT - 450) * scale,\n\n POWERUP_X: width - (REFERENCE_WIDTH - 610) * scale,\n POWERUP_Y: height - (REFERENCE_HEIGHT - 450) * scale,\n\n scale: scale\n };\n};\n\n// Backward compatibility (deprecated, but useful for initial refactor)\nexport const HUD_LAYOUT = {\n HEALTH_X: 100,\n HEALTH_Y: 450,\n ARMOR_X: 200,\n ARMOR_Y: 450,\n AMMO_X: 540,\n AMMO_Y: 450,\n CENTER_PRINT_X: 320,\n CENTER_PRINT_Y: 100,\n WEAPON_ICON_X: 10,\n WEAPON_ICON_Y: 450,\n POWERUP_X: 610,\n POWERUP_Y: 450,\n};\n","/**\n * CGame HUD Screen Drawing\n * Reference: rerelease/cg_screen.cpp\n *\n * This module handles all HUD rendering for the cgame package, including:\n * - Status bar (health, armor, ammo)\n * - Crosshair\n * - Damage indicators\n * - Pickup notifications\n * - Messages and center print\n * - Subtitles\n */\n\nimport type { PlayerState } from '@quake2ts/shared';\nimport type { CGameImport } from './types.js';\n\n// HUD component imports\nimport { Draw_Crosshair, Init_Crosshair } from './hud/crosshair.js';\nimport { Init_Icons } from './hud/icons.js';\nimport { Draw_Damage, Init_Damage } from './hud/damage.js';\nimport { Draw_Diagnostics } from './hud/diagnostics.js';\nimport { MessageSystem } from './hud/messages.js';\nimport { SubtitleSystem } from './hud/subtitles.js';\nimport { Draw_Blends } from './hud/blends.js';\nimport { Draw_Pickup } from './hud/pickup.js';\nimport { Draw_StatusBar } from './hud/statusbar.js';\nimport { getHudLayout } from './hud/layout.js';\n\n// Module-level state\nlet cgi: CGameImport | null = null;\nconst hudNumberPics: unknown[] = []; // Will hold pic handles from cgi.Draw_RegisterPic()\nlet numberWidth = 0;\n\n// Message and subtitle systems\nconst messageSystem = new MessageSystem();\nconst subtitleSystem = new SubtitleSystem();\n\n/**\n * Initialize the CGame screen module with import functions.\n * Reference: rerelease/cg_screen.cpp InitCGame()\n */\nexport function CG_InitScreen(imports: CGameImport): void {\n cgi = imports;\n}\n\n/**\n * Precache all HUD images.\n * Reference: rerelease/cg_screen.cpp:1689 (TouchPics)\n *\n * This is called during level load to register all required HUD assets.\n */\nexport function CG_TouchPics(): void {\n if (!cgi) return;\n\n // Load HUD number pics\n hudNumberPics.length = 0;\n for (let i = 0; i < 10; i++) {\n try {\n const pic = cgi.Draw_RegisterPic(`pics/hud/num_${i}.pcx`);\n hudNumberPics.push(pic);\n if (i === 0) {\n const size = cgi.Draw_GetPicSize(pic);\n numberWidth = size.width;\n }\n } catch (e) {\n cgi.Com_Print(`Warning: Failed to load HUD image: pics/hud/num_${i}.pcx\\n`);\n }\n }\n\n // TODO: Call Init functions for other HUD components\n // These will need to be adapted to use cgi.Draw_RegisterPic()\n // instead of direct asset manager access\n}\n\n/**\n * Main HUD drawing function.\n * Reference: rerelease/cg_screen.cpp CG_DrawHUD()\n *\n * Called each frame by the client to render the HUD overlay.\n *\n * @param isplit - Split-screen index (0 for single player)\n * @param data - Additional HUD data (unused in initial implementation)\n * @param hud_vrect - Virtual HUD rectangle (screen coordinates)\n * @param hud_safe - Safe area rectangle (for overscan)\n * @param scale - HUD scale factor\n * @param playernum - Player number\n * @param ps - Current player state\n */\nexport function CG_DrawHUD(\n isplit: number,\n data: unknown,\n hud_vrect: { x: number; y: number; width: number; height: number },\n hud_safe: { x: number; y: number; width: number; height: number },\n scale: number,\n playernum: number,\n ps: PlayerState\n): void {\n if (!cgi) {\n console.error('CG_DrawHUD: cgame imports not initialized');\n return;\n }\n\n // TODO: Implement full HUD rendering using cgi drawing functions\n // For now, this is a placeholder structure\n\n // The full implementation will need to:\n // 1. Read stats from ps.stats[] array using STAT_* constants\n // 2. Use cgi.SCR_DrawPic(), cgi.SCR_DrawChar(), etc. for rendering\n // 3. Calculate layout based on hud_vrect and hud_safe\n // 4. Draw all HUD components in correct order:\n // - Screen blends (damage, powerups)\n // - Status bar\n // - Pickup messages\n // - Damage indicators\n // - Center print\n // - Notifications\n // - Subtitles\n // - Crosshair\n\n const timeMs = cgi.CL_ClientTime();\n const layout = getHudLayout(hud_vrect.width, hud_vrect.height);\n\n // Basic placeholder rendering\n // TODO: Adapt each Draw_* function to use cgi instead of renderer\n\n if (ps.centerPrint) {\n cgi.SCR_DrawFontString(\n hud_vrect.width / 2,\n hud_vrect.height / 2 - 20,\n ps.centerPrint\n );\n }\n\n if (ps.notify) {\n cgi.SCR_DrawFontString(8, 8, ps.notify);\n }\n}\n\n/**\n * Get message system instance.\n * Used by parsing functions to add messages.\n */\nexport function CG_GetMessageSystem(): MessageSystem {\n return messageSystem;\n}\n\n/**\n * Get subtitle system instance.\n * Used by audio system to display subtitles.\n */\nexport function CG_GetSubtitleSystem(): SubtitleSystem {\n return subtitleSystem;\n}\n","/**\n * CGame Module Entry Point\n * Reference: rerelease/cg_main.cpp\n *\n * This module provides the GetCGameAPI() function that returns the cgame_export_t\n * interface to the client engine.\n */\n\nimport type { CGameImport, CGameExport } from './types.js';\nimport type { PlayerState, Vec3 } from '@quake2ts/shared';\nimport { LayoutFlags } from '@quake2ts/shared';\nimport { CG_InitScreen, CG_TouchPics, CG_DrawHUD, CG_GetMessageSystem, CG_GetSubtitleSystem } from './screen.js';\n\n// Module-level state\nlet cgi: CGameImport | null = null;\n\n/**\n * Initialize the CGame module.\n * Reference: rerelease/cg_main.cpp InitCGame()\n */\nfunction Init(): void {\n if (!cgi) {\n console.error('CGame Init: cgame imports not set');\n return;\n }\n\n cgi.Com_Print('===== CGame Initialization =====\\n');\n\n // Initialize screen/HUD module\n CG_InitScreen(cgi);\n\n cgi.Com_Print('CGame initialized\\n');\n}\n\n/**\n * Shutdown the CGame module.\n * Reference: rerelease/cg_main.cpp ShutdownCGame()\n */\nfunction Shutdown(): void {\n if (cgi) {\n cgi.Com_Print('CGame shutdown\\n');\n }\n cgi = null;\n}\n\n/**\n * Main HUD drawing function (wrapper for CG_DrawHUD).\n * Reference: rerelease/cg_screen.cpp CG_DrawHUD()\n */\nfunction DrawHUD(\n isplit: number,\n data: unknown,\n hud_vrect: { x: number; y: number; width: number; height: number },\n hud_safe: { x: number; y: number; width: number; height: number },\n scale: number,\n playernum: number,\n ps: PlayerState\n): void {\n CG_DrawHUD(isplit, data, hud_vrect, hud_safe, scale, playernum, ps);\n}\n\n/**\n * Precache all HUD images.\n * Reference: rerelease/cg_screen.cpp TouchPics()\n */\nfunction TouchPics(): void {\n CG_TouchPics();\n}\n\n/**\n * Get layout flags for current player state.\n * Reference: rerelease/cg_screen.cpp\n */\nfunction GetLayoutFlags(ps: PlayerState): LayoutFlags {\n // TODO: Implement proper layout flag calculation\n // Based on inventory state, help state, intermission, etc.\n return 0 as LayoutFlags; // No flags set by default\n}\n\n/**\n * Placeholder stubs for remaining CGameExport functions.\n * These will be implemented as needed.\n */\n\nfunction GetActiveWeaponWheelWeapon(ps: PlayerState): number {\n return 0;\n}\n\nfunction GetOwnedWeaponWheelWeapons(ps: PlayerState): number[] {\n return [];\n}\n\nfunction GetWeaponWheelAmmoCount(ps: PlayerState, weapon: number): number {\n return 0;\n}\n\nfunction GetPowerupWheelCount(ps: PlayerState): number {\n return 0;\n}\n\nfunction GetHitMarkerDamage(ps: PlayerState): number {\n return 0;\n}\n\nfunction Pmove(pmove: unknown): void {\n // TODO: Implement client-side movement prediction\n // Should call shared Pmove() function\n}\n\nfunction ParseConfigString(i: number, s: string): void {\n // TODO: Implement config string parsing\n // Handle CONFIG_N64_PHYSICS, CS_AIRACCEL, etc.\n}\n\nfunction ParseCenterPrint(str: string, isplit: number, instant: boolean): void {\n if (!cgi) return;\n const messageSystem = CG_GetMessageSystem();\n // TODO: Parse layout strings and handle key bindings\n messageSystem.setCenterPrint(str, cgi.CL_ClientTime());\n}\n\nfunction NotifyMessage(isplit: number, msg: string, is_chat: boolean): void {\n if (!cgi) return;\n const messageSystem = CG_GetMessageSystem();\n messageSystem.addNotification(msg, is_chat, cgi.CL_ClientTime());\n}\n\nfunction ClearNotify(isplit: number): void {\n const messageSystem = CG_GetMessageSystem();\n messageSystem.clearNotifications();\n}\n\nfunction ClearCenterprint(isplit: number): void {\n const messageSystem = CG_GetMessageSystem();\n messageSystem.clearCenterPrint();\n}\n\nfunction GetMonsterFlashOffset(id: number): Vec3 {\n return { x: 0, y: 0, z: 0 };\n}\n\nfunction GetExtension(name: string): unknown {\n return null;\n}\n\n/**\n * Main entry point for CGame module.\n * Reference: rerelease/cg_main.cpp GetCGameAPI()\n *\n * @param imports - Functions provided by the client engine\n * @returns CGame export interface\n */\nexport function GetCGameAPI(imports: CGameImport): CGameExport {\n cgi = imports;\n\n return {\n // Lifecycle\n Init,\n Shutdown,\n\n // Rendering\n DrawHUD,\n TouchPics,\n\n // Layout\n LayoutFlags: GetLayoutFlags,\n\n // Weapon wheel\n GetActiveWeaponWheelWeapon,\n GetOwnedWeaponWheelWeapons,\n GetWeaponWheelAmmoCount,\n GetPowerupWheelCount,\n\n // Hit markers\n GetHitMarkerDamage,\n\n // Prediction\n Pmove,\n\n // Parsing\n ParseConfigString,\n ParseCenterPrint,\n NotifyMessage,\n\n // State management\n ClearNotify,\n ClearCenterprint,\n\n // Effects\n GetMonsterFlashOffset,\n\n // Extension\n GetExtension,\n };\n}\n"]}