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.
- package/.claude/settings.local.json +77 -0
- package/.node-version +1 -0
- package/CLAUDE.md +435 -0
- package/README.md +404 -0
- package/TODO.md +655 -0
- package/dist/index.cjs +25108 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +25085 -0
- package/docs/building-libretro-cores-arm-mac.md +237 -0
- package/docs/config-file-format.md +488 -0
- package/docs/cores-trd.md +425 -0
- package/docs/headless-hardware-rendering-trd.md +676 -0
- package/docs/libretro-cores-trd.md +997 -0
- package/docs/mupen64-software-rendering-trd.md +751 -0
- package/docs/n64-support-trd.md +306 -0
- package/docs/native-rendering-trd.md +540 -0
- package/docs/native-ui-rendering-trd.md +1195 -0
- package/docs/netplay-trd.md +665 -0
- package/docs/retroarch-netplay-docs.md +277 -0
- package/docs/save-state-format.md +666 -0
- package/eslint.config.js +111 -0
- package/icon/icon.png +0 -0
- package/icon/icon.pxd +0 -0
- package/package.json +63 -0
- package/pnpm-workspace.yaml +10 -0
- package/src/Emulator/consts.ts +14 -0
- package/src/Emulator/index.ts +2496 -0
- package/src/Emulator/saveState/index.ts +155 -0
- package/src/Emulator/screenshot/index.ts +160 -0
- package/src/Emulator/terminalDimensions/index.ts +79 -0
- package/src/Emulator/types.ts +83 -0
- package/src/cli/commands/consts.ts +10 -0
- package/src/cli/commands/index.ts +462 -0
- package/src/cli/parseArgs/consts.ts +17 -0
- package/src/cli/parseArgs/index.ts +457 -0
- package/src/cli/parseArgs/types.ts +61 -0
- package/src/cli/runEmulator/index.ts +406 -0
- package/src/cli/runEmulator/types.ts +7 -0
- package/src/consts.ts +19 -0
- package/src/core/button/consts.ts +35 -0
- package/src/core/button/index.ts +123 -0
- package/src/core/core.ts +300 -0
- package/src/core/index.ts +19 -0
- package/src/cores/libretro/api/index.ts +334 -0
- package/src/cores/libretro/api/types.ts +148 -0
- package/src/cores/libretro/callbacks/consts.ts +41 -0
- package/src/cores/libretro/callbacks/index.ts +456 -0
- package/src/cores/libretro/consts.ts +45 -0
- package/src/cores/libretro/coreOptions/consts.ts +36 -0
- package/src/cores/libretro/coreOptions/index.ts +222 -0
- package/src/cores/libretro/environment/consts.ts +118 -0
- package/src/cores/libretro/environment/index.ts +1095 -0
- package/src/cores/libretro/index.ts +937 -0
- package/src/cores/libretro/loader/index.ts +496 -0
- package/src/cores/libretro/pixelFormat/consts.ts +43 -0
- package/src/cores/libretro/pixelFormat/index.ts +397 -0
- package/src/cores/libretro/types.ts +339 -0
- package/src/frontend/AudioManager/index.ts +420 -0
- package/src/frontend/SettingsManager/index.ts +250 -0
- package/src/frontend/config/index.ts +608 -0
- package/src/frontend/config/tests.ts +354 -0
- package/src/frontend/config/types.ts +36 -0
- package/src/frontend/consts.ts +114 -0
- package/src/frontend/coreBuilder/index.ts +644 -0
- package/src/frontend/coreBuilder/types.ts +15 -0
- package/src/frontend/coreDownloader/index.ts +620 -0
- package/src/frontend/coreDownloader/types.ts +17 -0
- package/src/frontend/corePreferences/index.ts +69 -0
- package/src/frontend/coreRegistry/index.ts +276 -0
- package/src/frontend/directoryCache/index.ts +75 -0
- package/src/frontend/index.ts +79 -0
- package/src/frontend/notifications/consts.ts +14 -0
- package/src/frontend/notifications/index.ts +250 -0
- package/src/frontend/playlist/consts.ts +168 -0
- package/src/frontend/playlist/index.ts +899 -0
- package/src/frontend/playlist/labelFormatter/consts.ts +15 -0
- package/src/frontend/playlist/labelFormatter/index.ts +155 -0
- package/src/frontend/playlist/labelFormatter/tests.ts +153 -0
- package/src/frontend/playlist/reader/index.ts +559 -0
- package/src/frontend/playlist/sync/index.ts +511 -0
- package/src/frontend/playlist/systemLookup/index.ts +233 -0
- package/src/frontend/playlist/utils/index.ts +50 -0
- package/src/frontend/romScanner/consts.ts +348 -0
- package/src/frontend/romScanner/index.ts +1957 -0
- package/src/frontend/saveServices/consts.ts +2 -0
- package/src/frontend/saveServices/index.ts +313 -0
- package/src/frontend/serviceProvider/index.ts +108 -0
- package/src/frontend/serviceProvider/types.ts +13 -0
- package/src/index.ts +428 -0
- package/src/input/Controller/consts.ts +50 -0
- package/src/input/Controller/index.ts +81 -0
- package/src/input/GamepadManager/consts.ts +22 -0
- package/src/input/GamepadManager/index.ts +418 -0
- package/src/input/InputManager/consts.ts +86 -0
- package/src/input/InputManager/index.ts +593 -0
- package/src/input/InputMapper/consts.ts +33 -0
- package/src/input/InputMapper/index.ts +436 -0
- package/src/input/consts.ts +410 -0
- package/src/input/gamepadProfiles/index.ts +1100 -0
- package/src/input/index.ts +38 -0
- package/src/input/inputUtils/index.ts +31 -0
- package/src/netplay/FrameBuffer/consts.ts +2 -0
- package/src/netplay/FrameBuffer/index.ts +364 -0
- package/src/netplay/FrameBuffer/tests.ts +286 -0
- package/src/netplay/InputBuffer/consts.ts +7 -0
- package/src/netplay/InputBuffer/index.ts +347 -0
- package/src/netplay/InputBuffer/tests.ts +166 -0
- package/src/netplay/NetplayClient/index.ts +976 -0
- package/src/netplay/NetplayConnection/index.ts +536 -0
- package/src/netplay/NetplayDiscovery/consts.ts +41 -0
- package/src/netplay/NetplayDiscovery/index.ts +525 -0
- package/src/netplay/NetplayServer/index.ts +1407 -0
- package/src/netplay/SyncManager/index.ts +984 -0
- package/src/netplay/SyncManager/tests.ts +419 -0
- package/src/netplay/consts.ts +371 -0
- package/src/netplay/crc32/consts.ts +14 -0
- package/src/netplay/crc32/index.ts +97 -0
- package/src/netplay/crc32/tests.ts +40 -0
- package/src/netplay/index.ts +41 -0
- package/src/netplay/netplayLogger/consts.ts +30 -0
- package/src/netplay/netplayLogger/index.ts +345 -0
- package/src/netplay/protocol/consts.ts +86 -0
- package/src/netplay/protocol/index.ts +1280 -0
- package/src/netplay/protocol/tests.ts +606 -0
- package/src/netplay/protocol/types.ts +20 -0
- package/src/netplay/types.ts +395 -0
- package/src/rendering/KittyRenderer/index.ts +616 -0
- package/src/rendering/NativeRenderer/index.ts +279 -0
- package/src/rendering/NativeRenderer/tests.ts +133 -0
- package/src/rendering/TerminalRenderer/index.ts +770 -0
- package/src/rendering/consts.ts +401 -0
- package/src/rendering/fonts/CozetteVector.ttf +0 -0
- package/src/rendering/index.ts +26 -0
- package/src/rendering/nativeUi/NativeWindowManager/index.ts +158 -0
- package/src/rendering/nativeUi/NativeWindowManager/tests.ts +81 -0
- package/src/rendering/nativeUi/consts.ts +6 -0
- package/src/rendering/nativeUi/index.ts +20 -0
- package/src/rendering/postProcessing/consts.ts +38 -0
- package/src/rendering/postProcessing/index.ts +923 -0
- package/src/rendering/shared/ansi/consts.ts +12 -0
- package/src/rendering/shared/ansi/index.ts +104 -0
- package/src/rendering/shared/consts.ts +2 -0
- package/src/rendering/shared/fitToTerminal/index.ts +67 -0
- package/src/ui/AddRomsPrompt/consts.ts +13 -0
- package/src/ui/AddRomsPrompt/index.tsx +781 -0
- package/src/ui/App/consts.ts +2 -0
- package/src/ui/App/index.tsx +456 -0
- package/src/ui/AppCapabilities/index.tsx +67 -0
- package/src/ui/ConfigContext/index.tsx +56 -0
- package/src/ui/CoreManager/consts.ts +11 -0
- package/src/ui/CoreManager/index.tsx +779 -0
- package/src/ui/CoreSelector/consts.ts +2 -0
- package/src/ui/CoreSelector/index.tsx +251 -0
- package/src/ui/DialogContainer/index.tsx +42 -0
- package/src/ui/DialogOptionsList/index.tsx +61 -0
- package/src/ui/DuplicateCrcPrompt/consts.ts +5 -0
- package/src/ui/DuplicateCrcPrompt/index.tsx +146 -0
- package/src/ui/GamepadContext/consts.ts +15 -0
- package/src/ui/GamepadContext/index.tsx +295 -0
- package/src/ui/NativeDialog/index.tsx +120 -0
- package/src/ui/NetplayDisconnectedDialog/index.tsx +93 -0
- package/src/ui/NetplayPauseMenu/consts.ts +2 -0
- package/src/ui/NetplayPauseMenu/index.tsx +97 -0
- package/src/ui/RomBrowser/NetplayPanel/consts.ts +24 -0
- package/src/ui/RomBrowser/NetplayPanel/index.tsx +520 -0
- package/src/ui/RomBrowser/SettingsPanel/index.tsx +478 -0
- package/src/ui/RomBrowser/consts.ts +61 -0
- package/src/ui/RomBrowser/index.tsx +1164 -0
- package/src/ui/RomBrowser/settingsConfig/index.ts +320 -0
- package/src/ui/RomBrowser/types.ts +67 -0
- package/src/ui/SaveStateDialog/consts.ts +2 -0
- package/src/ui/SaveStateDialog/index.tsx +225 -0
- package/src/ui/WarningDialog/index.tsx +113 -0
- package/src/ui/consts.ts +27 -0
- package/src/ui/hooks/useClearTerminal/consts.ts +2 -0
- package/src/ui/hooks/useClearTerminal/index.ts +37 -0
- package/src/ui/hooks/useDialogNavigation/index.ts +99 -0
- package/src/ui/hooks/useGamepad/consts.ts +21 -0
- package/src/ui/hooks/useGamepad/index.ts +194 -0
- package/src/ui/index.ts +27 -0
- package/src/utils/buffer/consts.ts +17 -0
- package/src/utils/buffer/index.ts +129 -0
- package/src/utils/color/consts.ts +58 -0
- package/src/utils/color/index.ts +183 -0
- package/src/utils/compression/consts.ts +50 -0
- package/src/utils/compression/index.ts +101 -0
- package/src/utils/consts.ts +2 -0
- package/src/utils/crc32/consts.ts +22 -0
- package/src/utils/crc32/index.ts +83 -0
- package/src/utils/ensureDirectory/index.ts +10 -0
- package/src/utils/format/consts.ts +8 -0
- package/src/utils/format/index.ts +53 -0
- package/src/utils/getErrorMessage/index.ts +10 -0
- package/src/utils/index.ts +113 -0
- package/src/utils/ini/index.ts +200 -0
- package/src/utils/kitty/consts.ts +13 -0
- package/src/utils/kitty/index.ts +181 -0
- package/src/utils/logger/consts.ts +35 -0
- package/src/utils/logger/index.ts +217 -0
- package/src/utils/paths/consts.ts +18 -0
- package/src/utils/paths/index.ts +151 -0
- package/src/utils/png/consts.ts +34 -0
- package/src/utils/png/index.ts +131 -0
- package/src/utils/readJsonFile/index.ts +16 -0
- package/src/utils/rotateLogFile/index.ts +44 -0
- package/src/utils/safeClose/index.ts +10 -0
- package/src/utils/terminal/consts.ts +8 -0
- package/src/utils/terminal/index.ts +102 -0
- package/src/utils/thumbnailRenderer/consts.ts +2 -0
- package/src/utils/thumbnailRenderer/index.ts +147 -0
- package/src/utils/typedError/index.ts +26 -0
- package/tsconfig.json +31 -0
- package/vitest.config.ts +13 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System Lookup Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides structured lookup of vendor and system names from file extensions.
|
|
5
|
+
* Parses RetroArch database names like "Sega - Mega Drive - Genesis.lpl" into
|
|
6
|
+
* separate vendor ("Sega") and system ("Mega Drive - Genesis") components.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { RETROARCH_DATABASE_NAMES, PLAYLIST_EXTENSION } from '..';
|
|
10
|
+
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Types
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Structured system information with separate vendor and system name.
|
|
17
|
+
*/
|
|
18
|
+
export interface SystemInfo {
|
|
19
|
+
/** Hardware vendor/manufacturer (e.g., "Nintendo", "Sega", "NEC") */
|
|
20
|
+
vendor: string;
|
|
21
|
+
/** System/console name (e.g., "Nintendo 64", "Mega Drive - Genesis") */
|
|
22
|
+
system: string;
|
|
23
|
+
/** Full display name combining vendor and system (e.g., "Nintendo - Nintendo 64") */
|
|
24
|
+
fullName: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Constants
|
|
29
|
+
// =============================================================================
|
|
30
|
+
|
|
31
|
+
/** Separator between vendor and system in database names */
|
|
32
|
+
const VENDOR_SYSTEM_SEPARATOR = ' - ';
|
|
33
|
+
|
|
34
|
+
/** Default vendor when system info cannot be parsed */
|
|
35
|
+
const DEFAULT_VENDOR = 'Unknown';
|
|
36
|
+
|
|
37
|
+
/** Default system when system info cannot be parsed */
|
|
38
|
+
const DEFAULT_SYSTEM = 'Unknown System';
|
|
39
|
+
|
|
40
|
+
// =============================================================================
|
|
41
|
+
// Internal Lookup Map
|
|
42
|
+
// =============================================================================
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parsed system info keyed by normalized extension (with leading dot).
|
|
46
|
+
* Built once from RETROARCH_DATABASE_NAMES on first access.
|
|
47
|
+
*/
|
|
48
|
+
let systemInfoMap: Map<string, SystemInfo> | null = null;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Parse a database name into vendor and system components.
|
|
52
|
+
* Database names follow the format: "{Vendor} - {System}.lpl"
|
|
53
|
+
*
|
|
54
|
+
* Examples:
|
|
55
|
+
* - "Sega - Mega Drive - Genesis.lpl" → { vendor: "Sega", system: "Mega Drive - Genesis" }
|
|
56
|
+
* - "Nintendo - Nintendo 64.lpl" → { vendor: "Nintendo", system: "Nintendo 64" }
|
|
57
|
+
*/
|
|
58
|
+
const parseDatabaseName = (dbName: string): SystemInfo => {
|
|
59
|
+
// Remove .lpl extension if present
|
|
60
|
+
const name = dbName.endsWith(PLAYLIST_EXTENSION)
|
|
61
|
+
? dbName.slice(0, -PLAYLIST_EXTENSION.length)
|
|
62
|
+
: dbName;
|
|
63
|
+
|
|
64
|
+
// Split on first " - " to get vendor and system
|
|
65
|
+
const separatorIndex = name.indexOf(VENDOR_SYSTEM_SEPARATOR);
|
|
66
|
+
|
|
67
|
+
if (separatorIndex === -1) {
|
|
68
|
+
// No separator found - use whole name as system
|
|
69
|
+
return {
|
|
70
|
+
vendor: DEFAULT_VENDOR,
|
|
71
|
+
system: name || DEFAULT_SYSTEM,
|
|
72
|
+
fullName: name || DEFAULT_SYSTEM,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const vendor = name.slice(0, separatorIndex);
|
|
77
|
+
const system = name.slice(separatorIndex + VENDOR_SYSTEM_SEPARATOR.length);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
vendor: vendor || DEFAULT_VENDOR,
|
|
81
|
+
system: system || DEFAULT_SYSTEM,
|
|
82
|
+
fullName: name,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Build the system info lookup map from RETROARCH_DATABASE_NAMES.
|
|
88
|
+
* Only includes entries with file extension keys (starting with .).
|
|
89
|
+
*/
|
|
90
|
+
const buildSystemInfoMap = (): Map<string, SystemInfo> => {
|
|
91
|
+
const map = new Map<string, SystemInfo>();
|
|
92
|
+
|
|
93
|
+
for (const [key, dbName] of Object.entries(RETROARCH_DATABASE_NAMES)) {
|
|
94
|
+
// Normalize the key - add leading dot if missing
|
|
95
|
+
const normalizedKey = key.startsWith('.') ? key.toLowerCase() : `.${key.toLowerCase()}`;
|
|
96
|
+
|
|
97
|
+
// Skip if we already have this extension (prefer the dotted version)
|
|
98
|
+
if (map.has(normalizedKey)) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
map.set(normalizedKey, parseDatabaseName(dbName));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return map;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get or build the system info map (lazy initialization).
|
|
110
|
+
*/
|
|
111
|
+
const getSystemInfoMap = (): Map<string, SystemInfo> => {
|
|
112
|
+
if (!systemInfoMap) {
|
|
113
|
+
systemInfoMap = buildSystemInfoMap();
|
|
114
|
+
}
|
|
115
|
+
return systemInfoMap;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// Public API
|
|
120
|
+
// =============================================================================
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get structured system information for a file extension.
|
|
124
|
+
*
|
|
125
|
+
* @param extension - File extension (with or without leading dot, e.g., ".gen" or "gen")
|
|
126
|
+
* @returns SystemInfo with vendor, system, and fullName; or default values if not found
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* getSystemInfo('.gen')
|
|
130
|
+
* // → { vendor: 'Sega', system: 'Mega Drive - Genesis', fullName: 'Sega - Mega Drive - Genesis' }
|
|
131
|
+
*
|
|
132
|
+
* getSystemInfo('n64')
|
|
133
|
+
* // → { vendor: 'Nintendo', system: 'Nintendo 64', fullName: 'Nintendo - Nintendo 64' }
|
|
134
|
+
*/
|
|
135
|
+
export const getSystemInfo = (extension: string): SystemInfo => {
|
|
136
|
+
const normalizedExt = extension.startsWith('.')
|
|
137
|
+
? extension.toLowerCase()
|
|
138
|
+
: `.${extension.toLowerCase()}`;
|
|
139
|
+
|
|
140
|
+
const info = getSystemInfoMap().get(normalizedExt);
|
|
141
|
+
|
|
142
|
+
if (info) {
|
|
143
|
+
return info;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Return default for unknown extensions
|
|
147
|
+
return {
|
|
148
|
+
vendor: DEFAULT_VENDOR,
|
|
149
|
+
system: DEFAULT_SYSTEM,
|
|
150
|
+
fullName: DEFAULT_SYSTEM,
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get the vendor name for a file extension.
|
|
156
|
+
*
|
|
157
|
+
* @param extension - File extension (with or without leading dot)
|
|
158
|
+
* @returns Vendor name (e.g., "Sega", "Nintendo") or "Unknown" if not found
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* getVendor('.gen') // → 'Sega'
|
|
162
|
+
* getVendor('nes') // → 'Nintendo'
|
|
163
|
+
*/
|
|
164
|
+
export const getVendor = (extension: string): string => {
|
|
165
|
+
return getSystemInfo(extension).vendor;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get the system name for a file extension.
|
|
170
|
+
*
|
|
171
|
+
* @param extension - File extension (with or without leading dot)
|
|
172
|
+
* @returns System name (e.g., "Mega Drive - Genesis") or "Unknown System" if not found
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* getSystemByExtension('.gen') // → 'Mega Drive - Genesis'
|
|
176
|
+
* getSystemByExtension('n64') // → 'Nintendo 64'
|
|
177
|
+
*/
|
|
178
|
+
export const getSystemByExtension = (extension: string): string => {
|
|
179
|
+
return getSystemInfo(extension).system;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get all unique vendors from the database.
|
|
184
|
+
*
|
|
185
|
+
* @returns Array of vendor names, sorted alphabetically
|
|
186
|
+
*/
|
|
187
|
+
export const getAllVendors = (): string[] => {
|
|
188
|
+
const vendors = new Set<string>();
|
|
189
|
+
|
|
190
|
+
for (const info of getSystemInfoMap().values()) {
|
|
191
|
+
vendors.add(info.vendor);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return [...vendors].sort();
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get all systems for a specific vendor.
|
|
199
|
+
*
|
|
200
|
+
* @param vendor - Vendor name (case-insensitive)
|
|
201
|
+
* @returns Array of system names for that vendor, sorted alphabetically
|
|
202
|
+
*/
|
|
203
|
+
export const getSystemsForVendor = (vendor: string): string[] => {
|
|
204
|
+
const normalizedVendor = vendor.toLowerCase();
|
|
205
|
+
const systems = new Set<string>();
|
|
206
|
+
|
|
207
|
+
for (const info of getSystemInfoMap().values()) {
|
|
208
|
+
if (info.vendor.toLowerCase() === normalizedVendor) {
|
|
209
|
+
systems.add(info.system);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return [...systems].sort();
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get all extensions for a specific system.
|
|
218
|
+
*
|
|
219
|
+
* @param system - System name (case-insensitive, e.g., "Mega Drive - Genesis")
|
|
220
|
+
* @returns Array of extensions (with dots) that map to this system
|
|
221
|
+
*/
|
|
222
|
+
export const getExtensionsForSystem = (system: string): string[] => {
|
|
223
|
+
const normalizedSystem = system.toLowerCase();
|
|
224
|
+
const extensions: string[] = [];
|
|
225
|
+
|
|
226
|
+
for (const [ext, info] of getSystemInfoMap().entries()) {
|
|
227
|
+
if (info.system.toLowerCase() === normalizedSystem) {
|
|
228
|
+
extensions.push(ext);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return extensions.sort();
|
|
233
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playlist Utility Functions
|
|
3
|
+
*
|
|
4
|
+
* Shared utility functions used by playlist reader and sync modules.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { realpathSync } from 'fs';
|
|
8
|
+
import { resolve, isAbsolute } from 'path';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Normalize a path for consistent lookups across different filesystems.
|
|
12
|
+
* Uses realpathSync when the file exists (handles case-insensitive filesystems correctly),
|
|
13
|
+
* falls back to resolve for non-existent files.
|
|
14
|
+
*/
|
|
15
|
+
export const normalizePath = (filePath: string): string => {
|
|
16
|
+
try {
|
|
17
|
+
// realpathSync returns the canonical path with correct case on case-insensitive FS
|
|
18
|
+
return realpathSync(filePath);
|
|
19
|
+
} catch {
|
|
20
|
+
// File doesn't exist - use resolve for path normalization only
|
|
21
|
+
return resolve(filePath);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a path from a playlist entry, handling:
|
|
27
|
+
* - Absolute paths
|
|
28
|
+
* - Relative paths resolved against playlist directory
|
|
29
|
+
* - Windows vs Unix path separators
|
|
30
|
+
*/
|
|
31
|
+
export const resolvePath = (
|
|
32
|
+
entryPath: string,
|
|
33
|
+
playlistDirectory?: string
|
|
34
|
+
): string => {
|
|
35
|
+
// Normalize path separators to current platform
|
|
36
|
+
const normalizedPath = entryPath.replace(/\\/g, '/');
|
|
37
|
+
|
|
38
|
+
// If it's an absolute path, use it directly
|
|
39
|
+
if (isAbsolute(normalizedPath) || /^[A-Za-z]:/.test(entryPath)) {
|
|
40
|
+
return normalizedPath;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Resolve relative paths against playlist directory
|
|
44
|
+
if (playlistDirectory) {
|
|
45
|
+
return resolve(playlistDirectory, normalizedPath);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Last resort: return as-is
|
|
49
|
+
return normalizedPath;
|
|
50
|
+
};
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// File Size Constants
|
|
3
|
+
// =============================================================================
|
|
4
|
+
|
|
5
|
+
/** Minimum file size for a valid ROM (most ROMs are at least 8KB) */
|
|
6
|
+
export const MIN_ROM_SIZE = 1024;
|
|
7
|
+
|
|
8
|
+
/** Size of buffer to read for binary detection (small for speed) */
|
|
9
|
+
export const BINARY_CHECK_SIZE = 512;
|
|
10
|
+
|
|
11
|
+
/** Maximum bytes to read for ROM header metadata extraction (default fallback) */
|
|
12
|
+
export const HEADER_READ_SIZE = 65536;
|
|
13
|
+
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// Per-Format Header Size Requirements
|
|
16
|
+
// =============================================================================
|
|
17
|
+
|
|
18
|
+
/** NES: iNES header is 16 bytes, but read 512 for binary detection */
|
|
19
|
+
export const NES_REQUIRED_HEADER_SIZE = 512;
|
|
20
|
+
|
|
21
|
+
/** Game Boy: Header ends at 0x150 (336 bytes) */
|
|
22
|
+
export const GB_REQUIRED_HEADER_SIZE = 512;
|
|
23
|
+
|
|
24
|
+
/** SNES: HiROM with copier header at 0x101C0 + 32 bytes = 66,016 bytes */
|
|
25
|
+
export const SNES_REQUIRED_HEADER_SIZE = 66048;
|
|
26
|
+
|
|
27
|
+
/** Genesis: Header at 0x100-0x200 (512 bytes) */
|
|
28
|
+
export const GENESIS_REQUIRED_HEADER_SIZE = 512;
|
|
29
|
+
|
|
30
|
+
/** GBA: Header at 0x00-0xC0 (192 bytes), read 512 for binary detection */
|
|
31
|
+
export const GBA_REQUIRED_HEADER_SIZE = 512;
|
|
32
|
+
|
|
33
|
+
/** Non-printable character ratio threshold for binary detection (10%) */
|
|
34
|
+
export const BINARY_DETECTION_THRESHOLD = 0.1;
|
|
35
|
+
|
|
36
|
+
// =============================================================================
|
|
37
|
+
// File Size Formatting
|
|
38
|
+
// =============================================================================
|
|
39
|
+
|
|
40
|
+
/** Bytes in a kilobyte */
|
|
41
|
+
export const BYTES_PER_KB = 1024;
|
|
42
|
+
|
|
43
|
+
/** Bytes in a megabyte */
|
|
44
|
+
export const BYTES_PER_MB = BYTES_PER_KB * BYTES_PER_KB;
|
|
45
|
+
|
|
46
|
+
// =============================================================================
|
|
47
|
+
// iNES Header Constants
|
|
48
|
+
// =============================================================================
|
|
49
|
+
|
|
50
|
+
/** iNES header minimum size (16 bytes) */
|
|
51
|
+
export const INES_HEADER_SIZE = 16;
|
|
52
|
+
|
|
53
|
+
/** iNES magic bytes */
|
|
54
|
+
export const INES_MAGIC_N = 0x4e;
|
|
55
|
+
export const INES_MAGIC_E = 0x45;
|
|
56
|
+
export const INES_MAGIC_S = 0x53;
|
|
57
|
+
export const INES_MAGIC_EOF = 0x1a;
|
|
58
|
+
|
|
59
|
+
/** iNES header byte indices */
|
|
60
|
+
export const INES_PRG_BANKS_BYTE = 4;
|
|
61
|
+
export const INES_CHR_BANKS_BYTE = 5;
|
|
62
|
+
export const INES_FLAGS6_BYTE = 6;
|
|
63
|
+
export const INES_FLAGS7_BYTE = 7;
|
|
64
|
+
|
|
65
|
+
/** iNES mapper extraction constants */
|
|
66
|
+
export const INES_MAPPER_HIGH_SHIFT = 4;
|
|
67
|
+
export const INES_MAPPER_LOW_MASK = 0x0f;
|
|
68
|
+
export const INES_MAPPER_HIGH_MASK = 0xf0;
|
|
69
|
+
|
|
70
|
+
/** iNES PRG/CHR bank sizes */
|
|
71
|
+
export const INES_PRG_BANK_SIZE_KB = 16;
|
|
72
|
+
export const INES_CHR_BANK_SIZE_KB = 8;
|
|
73
|
+
|
|
74
|
+
/** iNES flags6 battery bit */
|
|
75
|
+
export const INES_BATTERY_BIT = 0x02;
|
|
76
|
+
|
|
77
|
+
/** iNES flags7 PAL bit */
|
|
78
|
+
export const INES_PAL_BIT = 0x01;
|
|
79
|
+
|
|
80
|
+
/** NES 2.0 format detection */
|
|
81
|
+
export const NES2_FORMAT_MASK = 0x0c;
|
|
82
|
+
export const NES2_FORMAT_VALUE = 0x08;
|
|
83
|
+
export const NES2_PRG_RAM_BYTE = 10;
|
|
84
|
+
export const NES2_PRG_RAM_MASK = 0x0f;
|
|
85
|
+
export const NES2_PRG_RAM_MAX_SHIFT = 16;
|
|
86
|
+
export const NES2_PRG_RAM_BASE = 64;
|
|
87
|
+
|
|
88
|
+
/** Default NES SRAM size (8KB) */
|
|
89
|
+
export const DEFAULT_NES_SRAM_KB = 8;
|
|
90
|
+
|
|
91
|
+
// =============================================================================
|
|
92
|
+
// Game Boy Header Constants
|
|
93
|
+
// =============================================================================
|
|
94
|
+
|
|
95
|
+
/** Minimum GB header size */
|
|
96
|
+
export const GB_MIN_HEADER_SIZE = 0x150;
|
|
97
|
+
|
|
98
|
+
/** GB header field offsets */
|
|
99
|
+
export const GB_TITLE_START = 0x134;
|
|
100
|
+
export const GB_TITLE_END = 0x144;
|
|
101
|
+
export const GB_CGB_FLAG = 0x143;
|
|
102
|
+
export const GB_SGB_FLAG = 0x146;
|
|
103
|
+
export const GB_CART_TYPE = 0x147;
|
|
104
|
+
export const GB_ROM_SIZE = 0x148;
|
|
105
|
+
export const GB_RAM_SIZE = 0x149;
|
|
106
|
+
export const GB_OLD_LICENSEE = 0x14b;
|
|
107
|
+
export const GB_NEW_LICENSEE_START = 0x144;
|
|
108
|
+
export const GB_NEW_LICENSEE_END = 0x145;
|
|
109
|
+
export const GB_HEADER_CHECKSUM = 0x14d;
|
|
110
|
+
export const GB_CHECKSUM_START = 0x134;
|
|
111
|
+
export const GB_CHECKSUM_END = 0x14c;
|
|
112
|
+
|
|
113
|
+
/** GB special values */
|
|
114
|
+
export const GB_NEW_LICENSEE_MARKER = 0x33;
|
|
115
|
+
export const GB_SGB_SUPPORT_VALUE = 0x03;
|
|
116
|
+
export const GB_CGB_ENHANCED_VALUE = 0x80;
|
|
117
|
+
export const GB_CGB_ONLY_VALUE = 0xc0;
|
|
118
|
+
|
|
119
|
+
/** GB cartridge types with battery - individual values */
|
|
120
|
+
export const GB_CART_MBC1_RAM_BATTERY = 0x03;
|
|
121
|
+
export const GB_CART_MBC2_BATTERY = 0x06;
|
|
122
|
+
export const GB_CART_MBC3_TIMER_BATTERY = 0x0f;
|
|
123
|
+
export const GB_CART_MBC3_TIMER_RAM_BATTERY = 0x10;
|
|
124
|
+
export const GB_CART_MBC3_RAM_BATTERY = 0x13;
|
|
125
|
+
export const GB_CART_MBC5_RAM_BATTERY = 0x1b;
|
|
126
|
+
export const GB_CART_MBC5_RUMBLE_RAM_BATTERY = 0x1e;
|
|
127
|
+
|
|
128
|
+
/** GB cartridge types with battery */
|
|
129
|
+
export const GB_BATTERY_CART_TYPES = [
|
|
130
|
+
GB_CART_MBC1_RAM_BATTERY,
|
|
131
|
+
GB_CART_MBC2_BATTERY,
|
|
132
|
+
GB_CART_MBC3_TIMER_BATTERY,
|
|
133
|
+
GB_CART_MBC3_TIMER_RAM_BATTERY,
|
|
134
|
+
GB_CART_MBC3_RAM_BATTERY,
|
|
135
|
+
GB_CART_MBC5_RAM_BATTERY,
|
|
136
|
+
GB_CART_MBC5_RUMBLE_RAM_BATTERY,
|
|
137
|
+
] as const;
|
|
138
|
+
|
|
139
|
+
/** GB cartridge type names lookup table */
|
|
140
|
+
export const GB_CARTRIDGE_TYPES: Record<number, string> = {
|
|
141
|
+
0x00: 'ROM Only',
|
|
142
|
+
0x01: 'MBC1',
|
|
143
|
+
0x02: 'MBC1+RAM',
|
|
144
|
+
0x03: 'MBC1+RAM+Battery',
|
|
145
|
+
0x05: 'MBC2',
|
|
146
|
+
0x06: 'MBC2+Battery',
|
|
147
|
+
0x0f: 'MBC3+Timer+Battery',
|
|
148
|
+
0x10: 'MBC3+Timer+RAM+Battery',
|
|
149
|
+
0x11: 'MBC3',
|
|
150
|
+
0x12: 'MBC3+RAM',
|
|
151
|
+
0x13: 'MBC3+RAM+Battery',
|
|
152
|
+
0x19: 'MBC5',
|
|
153
|
+
0x1a: 'MBC5+RAM',
|
|
154
|
+
0x1b: 'MBC5+RAM+Battery',
|
|
155
|
+
0x1c: 'MBC5+Rumble',
|
|
156
|
+
0x1d: 'MBC5+Rumble+RAM',
|
|
157
|
+
0x1e: 'MBC5+Rumble+RAM+Battery',
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/** GB ROM size names lookup table */
|
|
161
|
+
export const GB_ROM_SIZES: Record<number, string> = {
|
|
162
|
+
0x00: '32 KB',
|
|
163
|
+
0x01: '64 KB',
|
|
164
|
+
0x02: '128 KB',
|
|
165
|
+
0x03: '256 KB',
|
|
166
|
+
0x04: '512 KB',
|
|
167
|
+
0x05: '1 MB',
|
|
168
|
+
0x06: '2 MB',
|
|
169
|
+
0x07: '4 MB',
|
|
170
|
+
0x08: '8 MB',
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/** GB RAM size names lookup table */
|
|
174
|
+
export const GB_RAM_SIZES: Record<number, string> = {
|
|
175
|
+
0x01: '2 KB',
|
|
176
|
+
0x02: '8 KB',
|
|
177
|
+
0x03: '32 KB',
|
|
178
|
+
0x04: '128 KB',
|
|
179
|
+
0x05: '64 KB',
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// =============================================================================
|
|
183
|
+
// SNES Header Constants
|
|
184
|
+
// =============================================================================
|
|
185
|
+
|
|
186
|
+
/** SNES header locations (without/with copier header) */
|
|
187
|
+
export const SNES_LOROM_OFFSET = 0x7fc0;
|
|
188
|
+
export const SNES_HIROM_OFFSET = 0xffc0;
|
|
189
|
+
export const SNES_LOROM_COPIER_OFFSET = 0x81c0;
|
|
190
|
+
export const SNES_HIROM_COPIER_OFFSET = 0x101c0;
|
|
191
|
+
|
|
192
|
+
/** SNES header requires 32 bytes minimum */
|
|
193
|
+
export const SNES_HEADER_MIN_SIZE = 32;
|
|
194
|
+
|
|
195
|
+
/** SNES header field offsets (relative to header base) */
|
|
196
|
+
export const SNES_TITLE_LENGTH = 21;
|
|
197
|
+
export const SNES_MAKEUP_OFFSET = 0x15;
|
|
198
|
+
export const SNES_ROM_TYPE_OFFSET = 0x16;
|
|
199
|
+
export const SNES_ROM_SIZE_OFFSET = 0x17;
|
|
200
|
+
export const SNES_SRAM_SIZE_OFFSET = 0x18;
|
|
201
|
+
export const SNES_COUNTRY_OFFSET = 0x19;
|
|
202
|
+
export const SNES_PUBLISHER_OFFSET = 0x1a;
|
|
203
|
+
export const SNES_CHECKSUM_OFFSET = 0x1e;
|
|
204
|
+
export const SNES_CHECKSUM_HIGH_OFFSET = 0x1f;
|
|
205
|
+
export const SNES_COMPLEMENT_OFFSET = 0x1c;
|
|
206
|
+
export const SNES_COMPLEMENT_HIGH_OFFSET = 0x1d;
|
|
207
|
+
|
|
208
|
+
/** SNES checksum XOR mask */
|
|
209
|
+
export const SNES_CHECKSUM_XOR = 0xffff;
|
|
210
|
+
|
|
211
|
+
/** SNES makeup byte bits */
|
|
212
|
+
export const SNES_HIROM_BIT = 0x01;
|
|
213
|
+
export const SNES_FASTROM_BIT = 0x10;
|
|
214
|
+
|
|
215
|
+
/** SNES ROM types without special chips */
|
|
216
|
+
export const SNES_ROM_ONLY = 0x00;
|
|
217
|
+
export const SNES_ROM_RAM = 0x01;
|
|
218
|
+
export const SNES_ROM_RAM_BATTERY = 0x02;
|
|
219
|
+
|
|
220
|
+
/** SNES ROM types with battery - individual values */
|
|
221
|
+
export const SNES_ROM_TYPE_BATTERY = 0x02;
|
|
222
|
+
export const SNES_ROM_TYPE_DSP_BATTERY = 0x05;
|
|
223
|
+
export const SNES_ROM_TYPE_SUPERFX_BATTERY = 0x15;
|
|
224
|
+
export const SNES_ROM_TYPE_SUPERFX2_BATTERY = 0x1a;
|
|
225
|
+
export const SNES_ROM_TYPE_OBC1_BATTERY = 0x25;
|
|
226
|
+
export const SNES_ROM_TYPE_SA1_BATTERY = 0x35;
|
|
227
|
+
export const SNES_ROM_TYPE_SDD1_BATTERY = 0x45;
|
|
228
|
+
export const SNES_ROM_TYPE_SRTC_BATTERY = 0x55;
|
|
229
|
+
|
|
230
|
+
/** SNES ROM types with battery */
|
|
231
|
+
export const SNES_BATTERY_ROM_TYPES = [
|
|
232
|
+
SNES_ROM_TYPE_BATTERY,
|
|
233
|
+
SNES_ROM_TYPE_DSP_BATTERY,
|
|
234
|
+
SNES_ROM_TYPE_SUPERFX_BATTERY,
|
|
235
|
+
SNES_ROM_TYPE_SUPERFX2_BATTERY,
|
|
236
|
+
SNES_ROM_TYPE_OBC1_BATTERY,
|
|
237
|
+
SNES_ROM_TYPE_SA1_BATTERY,
|
|
238
|
+
SNES_ROM_TYPE_SDD1_BATTERY,
|
|
239
|
+
SNES_ROM_TYPE_SRTC_BATTERY,
|
|
240
|
+
] as const;
|
|
241
|
+
|
|
242
|
+
/** SNES chip type names lookup table */
|
|
243
|
+
export const SNES_CHIP_TYPES: Record<number, string> = {
|
|
244
|
+
0x00: 'ROM',
|
|
245
|
+
0x01: 'ROM+RAM',
|
|
246
|
+
0x02: 'ROM+RAM+Battery',
|
|
247
|
+
0x03: 'DSP',
|
|
248
|
+
0x04: 'DSP+RAM',
|
|
249
|
+
0x05: 'DSP+RAM+Battery',
|
|
250
|
+
0x13: 'SuperFX',
|
|
251
|
+
0x14: 'SuperFX+RAM',
|
|
252
|
+
0x15: 'SuperFX+RAM+Battery',
|
|
253
|
+
0x1a: 'SuperFX2+RAM+Battery',
|
|
254
|
+
0x23: 'OBC1',
|
|
255
|
+
0x24: 'OBC1+RAM',
|
|
256
|
+
0x25: 'OBC1+RAM+Battery',
|
|
257
|
+
0x33: 'SA-1',
|
|
258
|
+
0x34: 'SA-1+RAM',
|
|
259
|
+
0x35: 'SA-1+RAM+Battery',
|
|
260
|
+
0x43: 'S-DD1',
|
|
261
|
+
0x45: 'S-DD1+RAM+Battery',
|
|
262
|
+
0x55: 'S-RTC+RAM+Battery',
|
|
263
|
+
0xe3: 'Super Game Boy',
|
|
264
|
+
0xf3: 'Cx4',
|
|
265
|
+
0xf5: 'SPC7110',
|
|
266
|
+
0xf6: 'SPC7110+RTC',
|
|
267
|
+
0xf9: 'ST010/ST011',
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
/** SNES size code max */
|
|
271
|
+
export const SNES_SIZE_CODE_MAX = 16;
|
|
272
|
+
|
|
273
|
+
/** SNES PAL region threshold */
|
|
274
|
+
export const SNES_PAL_THRESHOLD = 0x02;
|
|
275
|
+
|
|
276
|
+
// =============================================================================
|
|
277
|
+
// Genesis Header Constants
|
|
278
|
+
// =============================================================================
|
|
279
|
+
|
|
280
|
+
/** Genesis header minimum size */
|
|
281
|
+
export const GENESIS_MIN_HEADER_SIZE = 0x200;
|
|
282
|
+
|
|
283
|
+
/** Genesis header field offsets */
|
|
284
|
+
export const GENESIS_SYSTEM_TYPE_START = 0x100;
|
|
285
|
+
export const GENESIS_SYSTEM_TYPE_END = 0x110;
|
|
286
|
+
export const GENESIS_DOMESTIC_NAME_START = 0x120;
|
|
287
|
+
export const GENESIS_DOMESTIC_NAME_END = 0x150;
|
|
288
|
+
export const GENESIS_OVERSEAS_NAME_START = 0x150;
|
|
289
|
+
export const GENESIS_OVERSEAS_NAME_END = 0x180;
|
|
290
|
+
export const GENESIS_SERIAL_START = 0x183;
|
|
291
|
+
export const GENESIS_SERIAL_END = 0x18e;
|
|
292
|
+
export const GENESIS_IO_SUPPORT_START = 0x190;
|
|
293
|
+
export const GENESIS_IO_SUPPORT_END = 0x1a0;
|
|
294
|
+
export const GENESIS_ROM_START_ADDR = 0x1a0;
|
|
295
|
+
export const GENESIS_ROM_END_ADDR = 0x1a4;
|
|
296
|
+
export const GENESIS_RAM_START_ADDR = 0x1b4;
|
|
297
|
+
export const GENESIS_RAM_END_ADDR = 0x1b8;
|
|
298
|
+
export const GENESIS_REGION_START = 0x1f0;
|
|
299
|
+
export const GENESIS_REGION_END = 0x1f3;
|
|
300
|
+
export const GENESIS_COPYRIGHT_START = 0x110;
|
|
301
|
+
export const GENESIS_COPYRIGHT_END = 0x120;
|
|
302
|
+
|
|
303
|
+
/** Genesis size validation */
|
|
304
|
+
export const GENESIS_MAX_ROM_SIZE = 0x10000000;
|
|
305
|
+
export const GENESIS_MAX_RAM_SIZE = 0x100000;
|
|
306
|
+
export const GENESIS_INVALID_RAM_MARKER = 0xffffffff;
|
|
307
|
+
|
|
308
|
+
// =============================================================================
|
|
309
|
+
// GBA Header Constants
|
|
310
|
+
// =============================================================================
|
|
311
|
+
|
|
312
|
+
/** GBA header minimum size */
|
|
313
|
+
export const GBA_MIN_HEADER_SIZE = 0xc0;
|
|
314
|
+
|
|
315
|
+
/** GBA header field offsets */
|
|
316
|
+
export const GBA_TITLE_START = 0xa0;
|
|
317
|
+
export const GBA_TITLE_END = 0xac;
|
|
318
|
+
export const GBA_GAME_CODE_START = 0xac;
|
|
319
|
+
export const GBA_GAME_CODE_END = 0xb0;
|
|
320
|
+
export const GBA_MAKER_CODE_START = 0xb0;
|
|
321
|
+
export const GBA_MAKER_CODE_END = 0xb2;
|
|
322
|
+
export const GBA_UNIT_CODE = 0xb3;
|
|
323
|
+
export const GBA_HEADER_CHECKSUM = 0xbd;
|
|
324
|
+
export const GBA_CHECKSUM_START = 0xa0;
|
|
325
|
+
export const GBA_CHECKSUM_END = 0xbd;
|
|
326
|
+
|
|
327
|
+
/** GBA valid unit code */
|
|
328
|
+
export const GBA_VALID_UNIT_CODE = 0x96;
|
|
329
|
+
|
|
330
|
+
/** GBA checksum adjustment */
|
|
331
|
+
export const GBA_CHECKSUM_ADJUSTMENT = 0x19;
|
|
332
|
+
|
|
333
|
+
/** GBA game code region index (4th character) */
|
|
334
|
+
export const GBA_REGION_CHAR_INDEX = 3;
|
|
335
|
+
|
|
336
|
+
/** GBA game code length */
|
|
337
|
+
export const GBA_GAME_CODE_LENGTH = 4;
|
|
338
|
+
|
|
339
|
+
/** GBA maker code length */
|
|
340
|
+
export const GBA_MAKER_CODE_LENGTH = 2;
|
|
341
|
+
|
|
342
|
+
// =============================================================================
|
|
343
|
+
// Checksum Constants
|
|
344
|
+
// =============================================================================
|
|
345
|
+
|
|
346
|
+
/** 8-bit checksum mask */
|
|
347
|
+
export const CHECKSUM_BYTE_MASK = 0xff;
|
|
348
|
+
|