mirror of
https://github.com/ivanizag/izapple2.git
synced 2026-04-20 04:16:41 +00:00
Screen modes working
This commit is contained in:
@@ -16,7 +16,7 @@ A modern React + TypeScript frontend for the izapple2 Apple II emulator, compile
|
||||
- Pause/Resume
|
||||
- Reset
|
||||
- Speed toggle
|
||||
- Screen mode selection (NTSC, Plain, Green, Amber)
|
||||
- Screen mode selection (NTSC, Plain, Green)
|
||||
- Screenshot download
|
||||
- ✅ Real-time status display (CPU frequency, disk status)
|
||||
- ✅ Responsive design
|
||||
@@ -113,7 +113,7 @@ The production files will be in `dist/`.
|
||||
- **Reset**: Reboot the Apple II
|
||||
- **Toggle Speed**: Switch between normal and fast speed
|
||||
- **Screenshot**: Download current screen as PNG
|
||||
- **Screen Mode**: Select display mode (NTSC, Plain, Green, Amber)
|
||||
- **Screen Mode**: Select display mode (NTSC, Plain, Green)
|
||||
|
||||
**Status Bar** (bottom):
|
||||
- Shows CPU frequency in MHz
|
||||
@@ -298,7 +298,7 @@ interface EmulatorAPI {
|
||||
|
||||
// Configuration
|
||||
toggleSpeed(): void;
|
||||
setScreenMode(mode: 'ntsc' | 'plain' | 'green' | 'amber'): void;
|
||||
setScreenMode(mode: 'ntsc' | 'plain' | 'green'): void;
|
||||
|
||||
// Screenshot
|
||||
screenshot(): void;
|
||||
|
||||
@@ -77,11 +77,6 @@ func setupAPI(a *izapple2.Apple2, game *Game) {
|
||||
})
|
||||
|
||||
// Configuration
|
||||
api["toggleSpeed"] = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||
a.SendCommand(izapple2.CommandToggleSpeed)
|
||||
return nil
|
||||
})
|
||||
|
||||
api["setScreenMode"] = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||
if len(args) < 1 {
|
||||
return nil
|
||||
@@ -94,9 +89,6 @@ func setupAPI(a *izapple2.Apple2, game *Game) {
|
||||
game.screenMode = screen.ScreenModePlain
|
||||
case "green":
|
||||
game.screenMode = screen.ScreenModeGreen
|
||||
case "amber":
|
||||
// Amber not available, use green as fallback
|
||||
game.screenMode = screen.ScreenModeGreen
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -105,8 +105,15 @@ func (g *Game) putKey(key ebiten.Key) {
|
||||
}
|
||||
|
||||
var globalGame *Game
|
||||
var initialized bool
|
||||
|
||||
func main() {
|
||||
if initialized {
|
||||
fmt.Println("main() called again - ignoring to prevent duplicate Game instances")
|
||||
return
|
||||
}
|
||||
initialized = true
|
||||
|
||||
a, err := izapple2.CreateConfiguredApple()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
@@ -118,6 +125,11 @@ func main() {
|
||||
}
|
||||
|
||||
func ebitenRun(a *izapple2.Apple2) {
|
||||
if globalGame != nil {
|
||||
fmt.Println("ebitenRun() called again - ignoring to prevent duplicate Game instances")
|
||||
return
|
||||
}
|
||||
|
||||
game := &Game{
|
||||
a: a,
|
||||
speaker: newWasmSpeaker(),
|
||||
|
||||
@@ -32,7 +32,7 @@ export interface DiskInfo {
|
||||
loaded: boolean;
|
||||
}
|
||||
|
||||
export type ScreenMode = 'ntsc' | 'plain' | 'green' | 'amber';
|
||||
export type ScreenMode = 'ntsc' | 'plain' | 'green';
|
||||
|
||||
// Extend Window interface for WASM API
|
||||
declare global {
|
||||
|
||||
@@ -1,7 +1,25 @@
|
||||
// WASM loader - initializes the Go WebAssembly module
|
||||
|
||||
let wasmLoading = false;
|
||||
let wasmLoaded = false;
|
||||
let loadPromise: Promise<void> | null = null;
|
||||
|
||||
export async function loadWASM(): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// If already loaded, return immediately
|
||||
if (wasmLoaded) {
|
||||
console.log('WASM already loaded, skipping');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// If currently loading, return the existing promise
|
||||
if (wasmLoading && loadPromise) {
|
||||
console.log('WASM loading in progress, waiting...');
|
||||
return loadPromise;
|
||||
}
|
||||
|
||||
// Start loading
|
||||
wasmLoading = true;
|
||||
loadPromise = new Promise((resolve, reject) => {
|
||||
// Load wasm_exec.js if not already loaded
|
||||
if (!window.Go) {
|
||||
const script = document.createElement('script');
|
||||
@@ -13,6 +31,8 @@ export async function loadWASM(): Promise<void> {
|
||||
initWASM(resolve, reject);
|
||||
}
|
||||
});
|
||||
|
||||
return loadPromise;
|
||||
}
|
||||
|
||||
async function initWASM(
|
||||
@@ -33,13 +53,17 @@ async function initWASM(
|
||||
// Wait a bit for the emulator to initialize and export functions
|
||||
setTimeout(() => {
|
||||
if (window.wasmAPI) {
|
||||
wasmLoaded = true;
|
||||
wasmLoading = false;
|
||||
resolve();
|
||||
} else {
|
||||
wasmLoading = false;
|
||||
console.error('WASM API not found on window object');
|
||||
reject(new Error('WASM API not initialized'));
|
||||
}
|
||||
}, 1000);
|
||||
} catch (error) {
|
||||
wasmLoading = false;
|
||||
console.error('Failed to initialize WASM:', error);
|
||||
reject(error as Error);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
PlayArrow,
|
||||
Pause,
|
||||
Refresh,
|
||||
Speed,
|
||||
CameraAlt,
|
||||
} from '@mui/icons-material';
|
||||
import { emulator } from '../api/emulator';
|
||||
@@ -32,9 +31,7 @@ export function ControlPanel({ paused }: ControlPanelProps) {
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
if (window.confirm('Reset the emulator? This will clear memory.')) {
|
||||
emulator.reset();
|
||||
}
|
||||
emulator.reset();
|
||||
};
|
||||
|
||||
const handleScreenModeChange = (event: SelectChangeEvent) => {
|
||||
@@ -45,10 +42,6 @@ export function ControlPanel({ paused }: ControlPanelProps) {
|
||||
emulator.screenshot();
|
||||
};
|
||||
|
||||
const handleSpeedToggle = () => {
|
||||
emulator.toggleSpeed();
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -73,12 +66,6 @@ export function ControlPanel({ paused }: ControlPanelProps) {
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="Toggle Speed (Full/NTSC)">
|
||||
<IconButton onClick={handleSpeedToggle}>
|
||||
<Speed />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="Screenshot">
|
||||
<IconButton onClick={handleScreenshot}>
|
||||
<CameraAlt />
|
||||
@@ -95,7 +82,6 @@ export function ControlPanel({ paused }: ControlPanelProps) {
|
||||
<MenuItem value="ntsc">NTSC</MenuItem>
|
||||
<MenuItem value="plain">Plain</MenuItem>
|
||||
<MenuItem value="green">Green</MenuItem>
|
||||
<MenuItem value="amber">Amber</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user