@tmustier/pi-nes 0.2.27 → 0.2.29
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/extensions/nes/index.ts
CHANGED
|
@@ -172,7 +172,7 @@ async function configureWithWizard(
|
|
|
172
172
|
const imageQuality = isHighQuality ? "high" : "balanced";
|
|
173
173
|
|
|
174
174
|
const filterOptions: Array<{ label: string; value: VideoFilter }> = [
|
|
175
|
-
{ label: "Sharp — pixel-perfect, no filtering", value: "off" },
|
|
175
|
+
{ label: "Sharp (default) — pixel-perfect, no filtering", value: "off" },
|
|
176
176
|
{ label: "CRT Soft — subtle retro look", value: "ntsc-rgb" },
|
|
177
177
|
{ label: "CRT Classic — authentic scanlines + color bleed", value: "ntsc-composite" },
|
|
178
178
|
];
|
|
@@ -45,6 +45,7 @@ export class NesSession {
|
|
|
45
45
|
private readonly maxCatchUpFrames: number;
|
|
46
46
|
private renderHook: (() => void) | null = null;
|
|
47
47
|
private tickTimer: ReturnType<typeof setInterval> | null = null;
|
|
48
|
+
private renderTimer: ReturnType<typeof setInterval> | null = null;
|
|
48
49
|
private saveTimer: ReturnType<typeof setInterval> | null = null;
|
|
49
50
|
private saveInFlight = false;
|
|
50
51
|
private stopping = false;
|
|
@@ -109,6 +110,8 @@ export class NesSession {
|
|
|
109
110
|
this.tick();
|
|
110
111
|
}, this.frameIntervalMs);
|
|
111
112
|
|
|
113
|
+
this.startRenderTimer();
|
|
114
|
+
|
|
112
115
|
this.saveTimer = setInterval(() => {
|
|
113
116
|
void this.saveIfNeeded(false);
|
|
114
117
|
}, this.saveIntervalMs);
|
|
@@ -116,11 +119,20 @@ export class NesSession {
|
|
|
116
119
|
|
|
117
120
|
setRenderHook(hook: (() => void) | null): void {
|
|
118
121
|
this.renderHook = hook;
|
|
122
|
+
if (hook) {
|
|
123
|
+
this.startRenderTimer();
|
|
124
|
+
} else {
|
|
125
|
+
this.stopRenderTimer();
|
|
126
|
+
}
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
setRenderIntervalMs(intervalMs: number): void {
|
|
122
130
|
this.renderIntervalMs = Math.max(0, intervalMs);
|
|
123
131
|
this.stats.renderIntervalMs = this.renderIntervalMs;
|
|
132
|
+
if (this.renderTimer) {
|
|
133
|
+
this.stopRenderTimer();
|
|
134
|
+
this.startRenderTimer();
|
|
135
|
+
}
|
|
124
136
|
}
|
|
125
137
|
|
|
126
138
|
getStats(): NesSessionStats {
|
|
@@ -136,6 +148,7 @@ export class NesSession {
|
|
|
136
148
|
clearInterval(this.tickTimer);
|
|
137
149
|
this.tickTimer = null;
|
|
138
150
|
}
|
|
151
|
+
this.stopRenderTimer();
|
|
139
152
|
this.loopDelay.disable();
|
|
140
153
|
if (this.saveTimer) {
|
|
141
154
|
clearInterval(this.saveTimer);
|
|
@@ -145,6 +158,28 @@ export class NesSession {
|
|
|
145
158
|
this.core.dispose();
|
|
146
159
|
}
|
|
147
160
|
|
|
161
|
+
private startRenderTimer(): void {
|
|
162
|
+
if (this.renderTimer || !this.renderHook || this.stopping) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const intervalMs = this.renderIntervalMs > 0 ? this.renderIntervalMs : this.frameIntervalMs;
|
|
166
|
+
this.renderTimer = setInterval(() => {
|
|
167
|
+
if (!this.renderHook || this.stopping) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.lastRenderTime = performance.now();
|
|
171
|
+
this.statsWindow.renders += 1;
|
|
172
|
+
this.renderHook();
|
|
173
|
+
}, Math.max(1, intervalMs));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private stopRenderTimer(): void {
|
|
177
|
+
if (this.renderTimer) {
|
|
178
|
+
clearInterval(this.renderTimer);
|
|
179
|
+
this.renderTimer = null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
148
183
|
private tick(): void {
|
|
149
184
|
if (this.stopping) {
|
|
150
185
|
return;
|
|
@@ -178,12 +213,6 @@ export class NesSession {
|
|
|
178
213
|
this.core.tick();
|
|
179
214
|
}
|
|
180
215
|
|
|
181
|
-
if (this.renderHook && now - this.lastRenderTime >= this.renderIntervalMs) {
|
|
182
|
-
this.lastRenderTime = now;
|
|
183
|
-
this.statsWindow.renders += 1;
|
|
184
|
-
this.renderHook();
|
|
185
|
-
}
|
|
186
|
-
|
|
187
216
|
const windowDuration = now - this.statsWindow.startTime;
|
|
188
217
|
if (windowDuration >= 1000) {
|
|
189
218
|
const seconds = windowDuration / 1000;
|
|
@@ -47,6 +47,7 @@ function getKittyShmModule(): KittyShmModule | null {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export class NesImageRenderer {
|
|
50
|
+
|
|
50
51
|
private readonly imageId = allocateImageId();
|
|
51
52
|
private cachedImage?: { base64: string; width: number; height: number };
|
|
52
53
|
private cachedRaw?: { sequence: string; columns: number; rows: number };
|