@tmustier/pi-nes 0.2.10 → 0.2.12

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/README.md CHANGED
@@ -54,14 +54,15 @@ On first run, you'll be prompted to set your ROM directory and display quality.
54
54
 
55
55
  ## Configuration
56
56
 
57
- Config is stored at `~/.pi/nes/config.json`. Use `/nes config` for guided setup.
57
+ Config is stored at `~/.pi/nes/config.json`. Use `/nes config` for quick setup.
58
58
 
59
59
  ```json
60
60
  {
61
61
  "romDir": "/roms/nes",
62
62
  "saveDir": "/roms/nes/saves",
63
63
  "renderer": "image",
64
- "pixelScale": 1.2,
64
+ "imageQuality": "balanced",
65
+ "pixelScale": 1.0,
65
66
  "keybindings": {
66
67
  "up": ["up", "w"],
67
68
  "down": ["down", "s"],
@@ -82,7 +83,8 @@ Config is stored at `~/.pi/nes/config.json`. Use `/nes config` for guided setup.
82
83
  | `romDir` | `/roms/nes` | Where to look for ROM files |
83
84
  | `saveDir` | `/roms/nes/saves` | Where to store battery saves (defaults to `<romDir>/saves`) |
84
85
  | `renderer` | `"image"` | `"image"` (Kitty graphics) or `"text"` (ANSI) |
85
- | `pixelScale` | `1.2` | Display scale (0.5–4.0) |
86
+ | `imageQuality` | `"balanced"` | `"balanced"` (30 fps) or `"high"` (60 fps) |
87
+ | `pixelScale` | `1.0` | Display scale (0.5–4.0) |
86
88
 
87
89
  ## Terminal Support
88
90
 
@@ -5,12 +5,14 @@ import { DEFAULT_INPUT_MAPPING, type InputMapping } from "./input-map.js";
5
5
  import { normalizePath } from "./paths.js";
6
6
 
7
7
  export type RendererMode = "image" | "text";
8
+ export type ImageQuality = "balanced" | "high";
8
9
 
9
10
  export interface NesConfig {
10
11
  romDir: string;
11
12
  saveDir: string;
12
13
  enableAudio: boolean;
13
14
  renderer: RendererMode;
15
+ imageQuality: ImageQuality;
14
16
  pixelScale: number;
15
17
  keybindings: InputMapping;
16
18
  }
@@ -26,7 +28,8 @@ export const DEFAULT_CONFIG: NesConfig = {
26
28
  saveDir: getDefaultSaveDir(DEFAULT_ROM_DIR),
27
29
  enableAudio: false,
28
30
  renderer: "image",
29
- pixelScale: 1.2,
31
+ imageQuality: "balanced",
32
+ pixelScale: 1.0,
30
33
  keybindings: cloneMapping(DEFAULT_INPUT_MAPPING),
31
34
  };
32
35
 
@@ -35,6 +38,7 @@ interface RawConfig {
35
38
  saveDir?: unknown;
36
39
  enableAudio?: unknown;
37
40
  renderer?: unknown;
41
+ imageQuality?: unknown;
38
42
  pixelScale?: unknown;
39
43
  keybindings?: unknown;
40
44
  }
@@ -54,12 +58,15 @@ export function normalizeConfig(raw: unknown): NesConfig {
54
58
  typeof parsed.saveDir === "string" && parsed.saveDir.length > 0
55
59
  ? normalizePath(parsed.saveDir, saveDirFallback)
56
60
  : saveDirFallback;
61
+ const imageQuality = normalizeImageQuality(parsed.imageQuality);
62
+ const pixelScale = normalizePixelScale(parsed.pixelScale);
57
63
  return {
58
64
  romDir,
59
65
  saveDir,
60
66
  enableAudio: typeof parsed.enableAudio === "boolean" ? parsed.enableAudio : DEFAULT_CONFIG.enableAudio,
61
67
  renderer: parsed.renderer === "text" ? "text" : DEFAULT_CONFIG.renderer,
62
- pixelScale: normalizePixelScale(parsed.pixelScale),
68
+ imageQuality,
69
+ pixelScale,
63
70
  keybindings: normalizeKeybindings(parsed.keybindings),
64
71
  };
65
72
  }
@@ -111,6 +118,10 @@ function normalizePixelScale(raw: unknown): number {
111
118
  return Math.min(4, Math.max(0.5, raw));
112
119
  }
113
120
 
121
+ function normalizeImageQuality(raw: unknown): ImageQuality {
122
+ return raw === "high" ? "high" : "balanced";
123
+ }
124
+
114
125
  function normalizeKeybindings(raw: unknown): InputMapping {
115
126
  const mapping = cloneMapping(DEFAULT_INPUT_MAPPING);
116
127
  if (!raw || typeof raw !== "object") {
@@ -18,7 +18,8 @@ import { NesSession } from "./nes-session.js";
18
18
  import { listRoms } from "./roms.js";
19
19
  import { loadSram } from "./saves.js";
20
20
 
21
- const IMAGE_RENDER_INTERVAL_MS = 1000 / 30;
21
+ const IMAGE_RENDER_INTERVAL_BALANCED_MS = 1000 / 30;
22
+ const IMAGE_RENDER_INTERVAL_HIGH_MS = 1000 / 60;
22
23
  const TEXT_RENDER_INTERVAL_MS = 1000 / 60;
23
24
 
24
25
  let activeSession: NesSession | null = null;
@@ -174,35 +175,17 @@ async function configureWithWizard(
174
175
  }
175
176
  }
176
177
 
177
- const qualityChoice = await ctx.ui.select("Quality (pixel scale)", [
178
- "Balanced (1.2) - recommended",
179
- "Low (1.0) - faster",
180
- "High (1.5) - sharper",
181
- "Custom...",
178
+ const qualityChoice = await ctx.ui.select("Quality", [
179
+ "Balanced (recommended) 30 fps",
180
+ "High 60 fps",
182
181
  ]);
183
182
  if (!qualityChoice) {
184
183
  return false;
185
184
  }
186
185
 
187
- let pixelScale: number;
188
- if (qualityChoice.startsWith("Low")) {
189
- pixelScale = 1.0;
190
- } else if (qualityChoice.startsWith("Balanced")) {
191
- pixelScale = 1.2;
192
- } else if (qualityChoice.startsWith("High")) {
193
- pixelScale = 1.5;
194
- } else {
195
- const pixelScaleInput = await ctx.ui.input("Pixel scale (0.5 - 4)", config.pixelScale.toString());
196
- if (pixelScaleInput === undefined) {
197
- return false;
198
- }
199
- const parsed = pixelScaleInput.trim() === "" ? config.pixelScale : Number(pixelScaleInput);
200
- if (Number.isNaN(parsed)) {
201
- ctx.ui.notify("Pixel scale must be a number.", "error");
202
- return false;
203
- }
204
- pixelScale = parsed;
205
- }
186
+ const isHighQuality = qualityChoice.startsWith("High");
187
+ const imageQuality = isHighQuality ? "high" : "balanced";
188
+ const pixelScale = config.pixelScale;
206
189
 
207
190
  const defaultSaveDir = getDefaultSaveDir(config.romDir);
208
191
  const shouldSyncSaveDir = config.saveDir === defaultSaveDir;
@@ -211,6 +194,7 @@ async function configureWithWizard(
211
194
  ...config,
212
195
  romDir,
213
196
  saveDir,
197
+ imageQuality,
214
198
  pixelScale,
215
199
  });
216
200
  await saveConfig(normalized);
@@ -318,7 +302,11 @@ async function attachSession(
318
302
  }
319
303
  : undefined;
320
304
 
321
- const renderIntervalMs = config.renderer === "image" ? IMAGE_RENDER_INTERVAL_MS : TEXT_RENDER_INTERVAL_MS;
305
+ const renderIntervalMs = config.renderer === "image"
306
+ ? config.imageQuality === "high"
307
+ ? IMAGE_RENDER_INTERVAL_HIGH_MS
308
+ : IMAGE_RENDER_INTERVAL_BALANCED_MS
309
+ : TEXT_RENDER_INTERVAL_MS;
322
310
  session.setRenderIntervalMs(renderIntervalMs);
323
311
 
324
312
  await ctx.ui.custom(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmustier/pi-nes",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "NES emulator extension for pi",
5
5
  "keywords": [
6
6
  "pi-package",
package/spec.md CHANGED
@@ -70,7 +70,8 @@ pi-nes/
70
70
  - `saveDir`
71
71
  - `enableAudio`
72
72
  - `renderer` ("image" or "text")
73
- - `pixelScale` (float, e.g. 1.5)
73
+ - `imageQuality` ("balanced" or "high", controls render fps)
74
+ - `pixelScale` (float, e.g. 1.0)
74
75
  - `keybindings` (button-to-keys map, e.g. `{ "a": ["z"] }`)
75
76
 
76
77
  Note: audio output is currently disabled; setting `enableAudio` will show a warning.
@@ -88,5 +89,6 @@ Note: audio output is currently disabled; setting `enableAudio` will show a warn
88
89
  - Audio: disabled (no safe dependency selected).
89
90
  - Default ROM dir: `/roms/nes` (configurable).
90
91
  - Default core: `native`.
91
- - Default pixel scale: `1.2`.
92
+ - Default image quality: `balanced` (30 fps).
93
+ - Default pixel scale: `1.0`.
92
94
  - Default save dir: `/roms/nes/saves` (configurable).