emoemu 0.1.0

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 (213) hide show
  1. package/.claude/settings.local.json +77 -0
  2. package/.node-version +1 -0
  3. package/CLAUDE.md +435 -0
  4. package/README.md +404 -0
  5. package/TODO.md +655 -0
  6. package/dist/index.cjs +25108 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +25085 -0
  9. package/docs/building-libretro-cores-arm-mac.md +237 -0
  10. package/docs/config-file-format.md +488 -0
  11. package/docs/cores-trd.md +425 -0
  12. package/docs/headless-hardware-rendering-trd.md +676 -0
  13. package/docs/libretro-cores-trd.md +997 -0
  14. package/docs/mupen64-software-rendering-trd.md +751 -0
  15. package/docs/n64-support-trd.md +306 -0
  16. package/docs/native-rendering-trd.md +540 -0
  17. package/docs/native-ui-rendering-trd.md +1195 -0
  18. package/docs/netplay-trd.md +665 -0
  19. package/docs/retroarch-netplay-docs.md +277 -0
  20. package/docs/save-state-format.md +666 -0
  21. package/eslint.config.js +111 -0
  22. package/icon/icon.png +0 -0
  23. package/icon/icon.pxd +0 -0
  24. package/package.json +63 -0
  25. package/pnpm-workspace.yaml +10 -0
  26. package/src/Emulator/consts.ts +14 -0
  27. package/src/Emulator/index.ts +2496 -0
  28. package/src/Emulator/saveState/index.ts +155 -0
  29. package/src/Emulator/screenshot/index.ts +160 -0
  30. package/src/Emulator/terminalDimensions/index.ts +79 -0
  31. package/src/Emulator/types.ts +83 -0
  32. package/src/cli/commands/consts.ts +10 -0
  33. package/src/cli/commands/index.ts +462 -0
  34. package/src/cli/parseArgs/consts.ts +17 -0
  35. package/src/cli/parseArgs/index.ts +457 -0
  36. package/src/cli/parseArgs/types.ts +61 -0
  37. package/src/cli/runEmulator/index.ts +406 -0
  38. package/src/cli/runEmulator/types.ts +7 -0
  39. package/src/consts.ts +19 -0
  40. package/src/core/button/consts.ts +35 -0
  41. package/src/core/button/index.ts +123 -0
  42. package/src/core/core.ts +300 -0
  43. package/src/core/index.ts +19 -0
  44. package/src/cores/libretro/api/index.ts +334 -0
  45. package/src/cores/libretro/api/types.ts +148 -0
  46. package/src/cores/libretro/callbacks/consts.ts +41 -0
  47. package/src/cores/libretro/callbacks/index.ts +456 -0
  48. package/src/cores/libretro/consts.ts +45 -0
  49. package/src/cores/libretro/coreOptions/consts.ts +36 -0
  50. package/src/cores/libretro/coreOptions/index.ts +222 -0
  51. package/src/cores/libretro/environment/consts.ts +118 -0
  52. package/src/cores/libretro/environment/index.ts +1095 -0
  53. package/src/cores/libretro/index.ts +937 -0
  54. package/src/cores/libretro/loader/index.ts +496 -0
  55. package/src/cores/libretro/pixelFormat/consts.ts +43 -0
  56. package/src/cores/libretro/pixelFormat/index.ts +397 -0
  57. package/src/cores/libretro/types.ts +339 -0
  58. package/src/frontend/AudioManager/index.ts +420 -0
  59. package/src/frontend/SettingsManager/index.ts +250 -0
  60. package/src/frontend/config/index.ts +608 -0
  61. package/src/frontend/config/tests.ts +354 -0
  62. package/src/frontend/config/types.ts +36 -0
  63. package/src/frontend/consts.ts +114 -0
  64. package/src/frontend/coreBuilder/index.ts +644 -0
  65. package/src/frontend/coreBuilder/types.ts +15 -0
  66. package/src/frontend/coreDownloader/index.ts +620 -0
  67. package/src/frontend/coreDownloader/types.ts +17 -0
  68. package/src/frontend/corePreferences/index.ts +69 -0
  69. package/src/frontend/coreRegistry/index.ts +276 -0
  70. package/src/frontend/directoryCache/index.ts +75 -0
  71. package/src/frontend/index.ts +79 -0
  72. package/src/frontend/notifications/consts.ts +14 -0
  73. package/src/frontend/notifications/index.ts +250 -0
  74. package/src/frontend/playlist/consts.ts +168 -0
  75. package/src/frontend/playlist/index.ts +899 -0
  76. package/src/frontend/playlist/labelFormatter/consts.ts +15 -0
  77. package/src/frontend/playlist/labelFormatter/index.ts +155 -0
  78. package/src/frontend/playlist/labelFormatter/tests.ts +153 -0
  79. package/src/frontend/playlist/reader/index.ts +559 -0
  80. package/src/frontend/playlist/sync/index.ts +511 -0
  81. package/src/frontend/playlist/systemLookup/index.ts +233 -0
  82. package/src/frontend/playlist/utils/index.ts +50 -0
  83. package/src/frontend/romScanner/consts.ts +348 -0
  84. package/src/frontend/romScanner/index.ts +1957 -0
  85. package/src/frontend/saveServices/consts.ts +2 -0
  86. package/src/frontend/saveServices/index.ts +313 -0
  87. package/src/frontend/serviceProvider/index.ts +108 -0
  88. package/src/frontend/serviceProvider/types.ts +13 -0
  89. package/src/index.ts +428 -0
  90. package/src/input/Controller/consts.ts +50 -0
  91. package/src/input/Controller/index.ts +81 -0
  92. package/src/input/GamepadManager/consts.ts +22 -0
  93. package/src/input/GamepadManager/index.ts +418 -0
  94. package/src/input/InputManager/consts.ts +86 -0
  95. package/src/input/InputManager/index.ts +593 -0
  96. package/src/input/InputMapper/consts.ts +33 -0
  97. package/src/input/InputMapper/index.ts +436 -0
  98. package/src/input/consts.ts +410 -0
  99. package/src/input/gamepadProfiles/index.ts +1100 -0
  100. package/src/input/index.ts +38 -0
  101. package/src/input/inputUtils/index.ts +31 -0
  102. package/src/netplay/FrameBuffer/consts.ts +2 -0
  103. package/src/netplay/FrameBuffer/index.ts +364 -0
  104. package/src/netplay/FrameBuffer/tests.ts +286 -0
  105. package/src/netplay/InputBuffer/consts.ts +7 -0
  106. package/src/netplay/InputBuffer/index.ts +347 -0
  107. package/src/netplay/InputBuffer/tests.ts +166 -0
  108. package/src/netplay/NetplayClient/index.ts +976 -0
  109. package/src/netplay/NetplayConnection/index.ts +536 -0
  110. package/src/netplay/NetplayDiscovery/consts.ts +41 -0
  111. package/src/netplay/NetplayDiscovery/index.ts +525 -0
  112. package/src/netplay/NetplayServer/index.ts +1407 -0
  113. package/src/netplay/SyncManager/index.ts +984 -0
  114. package/src/netplay/SyncManager/tests.ts +419 -0
  115. package/src/netplay/consts.ts +371 -0
  116. package/src/netplay/crc32/consts.ts +14 -0
  117. package/src/netplay/crc32/index.ts +97 -0
  118. package/src/netplay/crc32/tests.ts +40 -0
  119. package/src/netplay/index.ts +41 -0
  120. package/src/netplay/netplayLogger/consts.ts +30 -0
  121. package/src/netplay/netplayLogger/index.ts +345 -0
  122. package/src/netplay/protocol/consts.ts +86 -0
  123. package/src/netplay/protocol/index.ts +1280 -0
  124. package/src/netplay/protocol/tests.ts +606 -0
  125. package/src/netplay/protocol/types.ts +20 -0
  126. package/src/netplay/types.ts +395 -0
  127. package/src/rendering/KittyRenderer/index.ts +616 -0
  128. package/src/rendering/NativeRenderer/index.ts +279 -0
  129. package/src/rendering/NativeRenderer/tests.ts +133 -0
  130. package/src/rendering/TerminalRenderer/index.ts +770 -0
  131. package/src/rendering/consts.ts +401 -0
  132. package/src/rendering/fonts/CozetteVector.ttf +0 -0
  133. package/src/rendering/index.ts +26 -0
  134. package/src/rendering/nativeUi/NativeWindowManager/index.ts +158 -0
  135. package/src/rendering/nativeUi/NativeWindowManager/tests.ts +81 -0
  136. package/src/rendering/nativeUi/consts.ts +6 -0
  137. package/src/rendering/nativeUi/index.ts +20 -0
  138. package/src/rendering/postProcessing/consts.ts +38 -0
  139. package/src/rendering/postProcessing/index.ts +923 -0
  140. package/src/rendering/shared/ansi/consts.ts +12 -0
  141. package/src/rendering/shared/ansi/index.ts +104 -0
  142. package/src/rendering/shared/consts.ts +2 -0
  143. package/src/rendering/shared/fitToTerminal/index.ts +67 -0
  144. package/src/ui/AddRomsPrompt/consts.ts +13 -0
  145. package/src/ui/AddRomsPrompt/index.tsx +781 -0
  146. package/src/ui/App/consts.ts +2 -0
  147. package/src/ui/App/index.tsx +456 -0
  148. package/src/ui/AppCapabilities/index.tsx +67 -0
  149. package/src/ui/ConfigContext/index.tsx +56 -0
  150. package/src/ui/CoreManager/consts.ts +11 -0
  151. package/src/ui/CoreManager/index.tsx +779 -0
  152. package/src/ui/CoreSelector/consts.ts +2 -0
  153. package/src/ui/CoreSelector/index.tsx +251 -0
  154. package/src/ui/DialogContainer/index.tsx +42 -0
  155. package/src/ui/DialogOptionsList/index.tsx +61 -0
  156. package/src/ui/DuplicateCrcPrompt/consts.ts +5 -0
  157. package/src/ui/DuplicateCrcPrompt/index.tsx +146 -0
  158. package/src/ui/GamepadContext/consts.ts +15 -0
  159. package/src/ui/GamepadContext/index.tsx +295 -0
  160. package/src/ui/NativeDialog/index.tsx +120 -0
  161. package/src/ui/NetplayDisconnectedDialog/index.tsx +93 -0
  162. package/src/ui/NetplayPauseMenu/consts.ts +2 -0
  163. package/src/ui/NetplayPauseMenu/index.tsx +97 -0
  164. package/src/ui/RomBrowser/NetplayPanel/consts.ts +24 -0
  165. package/src/ui/RomBrowser/NetplayPanel/index.tsx +520 -0
  166. package/src/ui/RomBrowser/SettingsPanel/index.tsx +478 -0
  167. package/src/ui/RomBrowser/consts.ts +61 -0
  168. package/src/ui/RomBrowser/index.tsx +1164 -0
  169. package/src/ui/RomBrowser/settingsConfig/index.ts +320 -0
  170. package/src/ui/RomBrowser/types.ts +67 -0
  171. package/src/ui/SaveStateDialog/consts.ts +2 -0
  172. package/src/ui/SaveStateDialog/index.tsx +225 -0
  173. package/src/ui/WarningDialog/index.tsx +113 -0
  174. package/src/ui/consts.ts +27 -0
  175. package/src/ui/hooks/useClearTerminal/consts.ts +2 -0
  176. package/src/ui/hooks/useClearTerminal/index.ts +37 -0
  177. package/src/ui/hooks/useDialogNavigation/index.ts +99 -0
  178. package/src/ui/hooks/useGamepad/consts.ts +21 -0
  179. package/src/ui/hooks/useGamepad/index.ts +194 -0
  180. package/src/ui/index.ts +27 -0
  181. package/src/utils/buffer/consts.ts +17 -0
  182. package/src/utils/buffer/index.ts +129 -0
  183. package/src/utils/color/consts.ts +58 -0
  184. package/src/utils/color/index.ts +183 -0
  185. package/src/utils/compression/consts.ts +50 -0
  186. package/src/utils/compression/index.ts +101 -0
  187. package/src/utils/consts.ts +2 -0
  188. package/src/utils/crc32/consts.ts +22 -0
  189. package/src/utils/crc32/index.ts +83 -0
  190. package/src/utils/ensureDirectory/index.ts +10 -0
  191. package/src/utils/format/consts.ts +8 -0
  192. package/src/utils/format/index.ts +53 -0
  193. package/src/utils/getErrorMessage/index.ts +10 -0
  194. package/src/utils/index.ts +113 -0
  195. package/src/utils/ini/index.ts +200 -0
  196. package/src/utils/kitty/consts.ts +13 -0
  197. package/src/utils/kitty/index.ts +181 -0
  198. package/src/utils/logger/consts.ts +35 -0
  199. package/src/utils/logger/index.ts +217 -0
  200. package/src/utils/paths/consts.ts +18 -0
  201. package/src/utils/paths/index.ts +151 -0
  202. package/src/utils/png/consts.ts +34 -0
  203. package/src/utils/png/index.ts +131 -0
  204. package/src/utils/readJsonFile/index.ts +16 -0
  205. package/src/utils/rotateLogFile/index.ts +44 -0
  206. package/src/utils/safeClose/index.ts +10 -0
  207. package/src/utils/terminal/consts.ts +8 -0
  208. package/src/utils/terminal/index.ts +102 -0
  209. package/src/utils/thumbnailRenderer/consts.ts +2 -0
  210. package/src/utils/thumbnailRenderer/index.ts +147 -0
  211. package/src/utils/typedError/index.ts +26 -0
  212. package/tsconfig.json +31 -0
  213. package/vitest.config.ts +13 -0
@@ -0,0 +1,12 @@
1
+ // Escape character
2
+ export const ESC = '\x1b';
3
+
4
+ // Common sequences
5
+ export const RESET = '\x1b[0m';
6
+ export const HALF_BLOCK_TOP = '\u2580'; // Upper half block
7
+ export const HALF_BLOCK_BOTTOM = '\u2584'; // Lower half block
8
+ export const FULL_BLOCK = '\u2588'; // Full block
9
+
10
+ // Kitty graphics protocol
11
+ export const APC = `${ESC}_G`; // Application Program Command for graphics
12
+ export const ST = `${ESC}\\`; // String Terminator
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Shared ANSI escape sequence utilities.
3
+ */
4
+
5
+ import { clamp } from 'remeda';
6
+ import { COLOR_MAX } from '../consts';
7
+
8
+ export * from './consts';
9
+
10
+ import { ESC, RESET, HALF_BLOCK_TOP } from './consts';
11
+
12
+ /**
13
+ * Move cursor to specific position (1-based row and column).
14
+ */
15
+ export const moveCursor = (row: number, col: number): string => `${ESC}[${row};${col}H`;
16
+
17
+ /**
18
+ * Move cursor to top-left corner.
19
+ */
20
+ export const moveCursorHome = (): string => `${ESC}[H`;
21
+
22
+ /**
23
+ * Move cursor to specific row, column 1.
24
+ */
25
+ export const moveCursorToRow = (row: number): string => `${ESC}[${row};1H`;
26
+
27
+ /**
28
+ * Clear entire screen and move cursor home.
29
+ */
30
+ export const clearScreen = (): string => `${ESC}[2J${ESC}[H`;
31
+
32
+ /**
33
+ * Clear from cursor to end of line.
34
+ */
35
+ export const clearLine = (): string => `${ESC}[K`;
36
+
37
+ /**
38
+ * Hide cursor.
39
+ */
40
+ export const hideCursor = (): string => `${ESC}[?25l`;
41
+
42
+ /**
43
+ * Show cursor.
44
+ */
45
+ export const showCursor = (): string => `${ESC}[?25h`;
46
+
47
+ /**
48
+ * Set foreground color using 24-bit true color.
49
+ * Clamps values to 0-255 and defaults undefined/NaN to 0.
50
+ */
51
+ export const fgTrueColor = (r: number, g: number, b: number): string => {
52
+ const safeR = Number.isFinite(r) ? clamp(r, { min: 0, max: COLOR_MAX }) : 0;
53
+ const safeG = Number.isFinite(g) ? clamp(g, { min: 0, max: COLOR_MAX }) : 0;
54
+ const safeB = Number.isFinite(b) ? clamp(b, { min: 0, max: COLOR_MAX }) : 0;
55
+ return `${ESC}[38;2;${safeR};${safeG};${safeB}m`;
56
+ };
57
+
58
+ /**
59
+ * Set background color using 24-bit true color.
60
+ * Clamps values to 0-255 and defaults undefined/NaN to 0.
61
+ */
62
+ export const bgTrueColor = (r: number, g: number, b: number): string => {
63
+ const safeR = Number.isFinite(r) ? clamp(r, { min: 0, max: COLOR_MAX }) : 0;
64
+ const safeG = Number.isFinite(g) ? clamp(g, { min: 0, max: COLOR_MAX }) : 0;
65
+ const safeB = Number.isFinite(b) ? clamp(b, { min: 0, max: COLOR_MAX }) : 0;
66
+ return `${ESC}[48;2;${safeR};${safeG};${safeB}m`;
67
+ };
68
+
69
+ /**
70
+ * Set foreground color using ANSI 256-color palette.
71
+ * Clamps values to 0-255 and defaults undefined/NaN to 0.
72
+ */
73
+ export const fgAnsi256 = (code: number): string => {
74
+ const safeCode = Number.isFinite(code) ? clamp(Math.floor(code), { min: 0, max: COLOR_MAX }) : 0;
75
+ return `${ESC}[38;5;${safeCode}m`;
76
+ };
77
+
78
+ /**
79
+ * Set background color using ANSI 256-color palette.
80
+ * Clamps values to 0-255 and defaults undefined/NaN to 0.
81
+ */
82
+ export const bgAnsi256 = (code: number): string => {
83
+ const safeCode = Number.isFinite(code) ? clamp(Math.floor(code), { min: 0, max: COLOR_MAX }) : 0;
84
+ return `${ESC}[48;5;${safeCode}m`;
85
+ };
86
+
87
+ /**
88
+ * Render a half-block character with top and bottom colors (true color).
89
+ */
90
+ export const halfBlockTrueColor = (topR: number, topG: number, topB: number, bottomR: number, bottomG: number, bottomB: number): string => fgTrueColor(topR, topG, topB) +
91
+ bgTrueColor(bottomR, bottomG, bottomB) +
92
+ HALF_BLOCK_TOP + RESET;
93
+
94
+ /**
95
+ * Render a half-block character with top and bottom colors (256-color).
96
+ */
97
+ export const halfBlockAnsi256 = (fgCode: number, bgCode: number): string => fgAnsi256(fgCode) + bgAnsi256(bgCode) + HALF_BLOCK_TOP + RESET;
98
+
99
+ /**
100
+ * Render a grayscale half-block character.
101
+ */
102
+ export const halfBlockGrayscale = (topGray: number, bottomGray: number): string => fgTrueColor(topGray, topGray, topGray) +
103
+ bgTrueColor(bottomGray, bottomGray, bottomGray) +
104
+ HALF_BLOCK_TOP + RESET;
@@ -0,0 +1,2 @@
1
+ /** Maximum value for 8-bit color channel (0-255) */
2
+ export const COLOR_MAX = 255;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Utility for calculating display dimensions that fit within available
3
+ * terminal space while maintaining a given aspect ratio.
4
+ */
5
+
6
+ import { MIN_DISPLAY_COLS, MIN_DISPLAY_ROWS } from '../..';
7
+
8
+ interface FitToTerminalOptions {
9
+ availableCols: number;
10
+ availableRows: number;
11
+ aspectRatio: number;
12
+ requestedWidth?: number;
13
+ requestedHeight?: number;
14
+ }
15
+
16
+ interface DisplaySize {
17
+ width: number;
18
+ height: number;
19
+ }
20
+
21
+ /**
22
+ * Calculate the largest display dimensions that fit within the available
23
+ * terminal space while maintaining the given aspect ratio.
24
+ *
25
+ * When both requestedWidth and requestedHeight are provided, they are used as-is.
26
+ * When only one is provided, the other is computed from the aspect ratio.
27
+ * When neither is provided, the display auto-fits to fill available space.
28
+ */
29
+ export const fitToTerminal = ({
30
+ availableCols,
31
+ availableRows,
32
+ aspectRatio,
33
+ requestedWidth,
34
+ requestedHeight,
35
+ }: FitToTerminalOptions): DisplaySize => {
36
+ let width: number;
37
+ let height: number;
38
+
39
+ if (requestedWidth !== undefined && requestedHeight !== undefined) {
40
+ width = requestedWidth;
41
+ height = requestedHeight;
42
+ } else if (requestedWidth !== undefined) {
43
+ width = Math.min(requestedWidth, availableCols);
44
+ height = Math.floor(width / aspectRatio);
45
+ } else if (requestedHeight !== undefined) {
46
+ height = Math.min(requestedHeight, availableRows);
47
+ width = Math.floor(height * aspectRatio);
48
+ } else {
49
+ // Auto-fit: start from available height, compute width
50
+ height = availableRows;
51
+ width = Math.floor(height * aspectRatio);
52
+
53
+ // If computed width exceeds available cols, scale down from width
54
+ if (width > availableCols) {
55
+ width = availableCols;
56
+ height = Math.floor(width / aspectRatio);
57
+ }
58
+ }
59
+
60
+ // Clamp to min/max bounds
61
+ width = Math.max(width, MIN_DISPLAY_COLS);
62
+ height = Math.max(height, MIN_DISPLAY_ROWS);
63
+ width = Math.min(width, availableCols);
64
+ height = Math.min(height, availableRows);
65
+
66
+ return { width, height };
67
+ };
@@ -0,0 +1,13 @@
1
+ /** Progress bar full value (100%) */
2
+ export const PROGRESS_FULL = 100;
3
+
4
+ /** Progress multiplier for percentage calculation */
5
+ export const PROGRESS_MULTIPLIER = 100;
6
+
7
+ /** Maximum number of path suggestions to show */
8
+ export const MAX_PATH_SUGGESTIONS = 10;
9
+
10
+ /** Menu item indices */
11
+ export const MENU_DIRECTORY = 0;
12
+ export const MENU_IMPORT = 1;
13
+ export const MENU_EXIT = 2;