@@ -26,6 +26,7 @@ import { toHfe } from "./disc-hfe.js";
26
26
import { Keyboard } from "./keyboard.js" ;
27
27
import { GamepadSource } from "./gamepad-source.js" ;
28
28
import { MicrophoneInput } from "./microphone-input.js" ;
29
+ import { MouseJoystickSource } from "./mouse-joystick-source.js" ;
29
30
import {
30
31
buildUrlFromParams ,
31
32
guessModelFromHostname ,
@@ -93,6 +94,7 @@ const paramTypes = {
93
94
logFdcCommands : ParamTypes . BOOL ,
94
95
logFdcStateChanges : ParamTypes . BOOL ,
95
96
coProcessor : ParamTypes . BOOL ,
97
+ mouseJoystickEnabled : ParamTypes . BOOL ,
96
98
97
99
// Numeric parameters
98
100
speed : ParamTypes . INT ,
@@ -241,13 +243,15 @@ const config = new Config(function (changed) {
241
243
emulationConfig . keyLayout = changed . keyLayout ;
242
244
keyboard . setKeyLayout ( changed . keyLayout ) ;
243
245
}
244
- // Restore gamepad as source for the old channels
245
- for ( let oldChannel = 0 ; oldChannel < 4 ; ++ oldChannel )
246
- processor . adconverter . setChannelSource ( oldChannel , gamepadSource ) ;
247
- if ( changed . microphoneChannel !== undefined ) {
248
- const channel = changed . microphoneChannel ;
249
- console . log ( `Moving microphone to channel ${ channel } ` ) ;
250
- setupMicrophone ( channel ) . then ( ( ) => { } ) ;
246
+ // Handle ADC source changes
247
+ if ( changed . mouseJoystickEnabled !== undefined || changed . microphoneChannel !== undefined ) {
248
+ // Update sources based on new settings
249
+ updateAdcSources ( parsedQuery . mouseJoystickEnabled , parsedQuery . microphoneChannel ) ;
250
+
251
+ // Handle microphone initialization if needed
252
+ if ( changed . microphoneChannel !== undefined ) {
253
+ setupMicrophone ( ) . then ( ( ) => { } ) ;
254
+ }
251
255
}
252
256
updateUrl ( ) ;
253
257
} ) ;
@@ -262,6 +266,7 @@ config.setEconet(parsedQuery.hasEconet);
262
266
config . setMusic5000 ( parsedQuery . hasMusic5000 ) ;
263
267
config . setTeletext ( parsedQuery . hasTeletextAdaptor ) ;
264
268
config . setMicrophoneChannel ( parsedQuery . microphoneChannel ) ;
269
+ config . setMouseJoystickEnabled ( parsedQuery . mouseJoystickEnabled ) ;
265
270
266
271
model = config . model ;
267
272
@@ -507,19 +512,41 @@ processor = new Cpu6502(
507
512
econet ,
508
513
) ;
509
514
510
- // Set up gamepad as the default source for all channels
515
+ // Create input sources
511
516
const gamepadSource = new GamepadSource ( emulationConfig . getGamepads ) ;
512
- processor . adconverter . setChannelSource ( 0 , gamepadSource ) ;
513
- processor . adconverter . setChannelSource ( 1 , gamepadSource ) ;
514
- processor . adconverter . setChannelSource ( 2 , gamepadSource ) ;
515
- processor . adconverter . setChannelSource ( 3 , gamepadSource ) ;
516
517
517
518
// Create MicrophoneInput but don't enable by default
518
519
const microphoneInput = new MicrophoneInput ( ) ;
519
520
microphoneInput . setErrorCallback ( ( message ) => {
520
521
showError ( "accessing microphone" , message ) ;
521
522
} ) ;
522
523
524
+ // Create MouseJoystickSource but don't enable by default
525
+ const screenCanvas = document . getElementById ( "screen" ) ;
526
+ const mouseJoystickSource = new MouseJoystickSource ( screenCanvas ) ;
527
+
528
+ // Helper to manage ADC source configuration
529
+ function updateAdcSources ( mouseJoystickEnabled , microphoneChannel ) {
530
+ // Default all channels to gamepad
531
+ for ( let ch = 0 ; ch < 4 ; ch ++ ) {
532
+ processor . adconverter . setChannelSource ( ch , gamepadSource ) ;
533
+ }
534
+
535
+ // Apply mouse joystick if enabled (takes priority on channels 0 & 1)
536
+ if ( mouseJoystickEnabled ) {
537
+ processor . adconverter . setChannelSource ( 0 , mouseJoystickSource ) ;
538
+ processor . adconverter . setChannelSource ( 1 , mouseJoystickSource ) ;
539
+ mouseJoystickSource . setVia ( processor . sysvia ) ;
540
+ } else {
541
+ mouseJoystickSource . setVia ( null ) ;
542
+ }
543
+
544
+ // Apply microphone if configured (can override any channel)
545
+ if ( microphoneChannel !== undefined ) {
546
+ processor . adconverter . setChannelSource ( microphoneChannel , microphoneInput ) ;
547
+ }
548
+ }
549
+
523
550
async function ensureMicrophoneRunning ( ) {
524
551
if ( microphoneInput . audioContext && microphoneInput . audioContext . state !== "running" ) {
525
552
try {
@@ -533,19 +560,14 @@ async function ensureMicrophoneRunning() {
533
560
return true ;
534
561
}
535
562
536
- async function setupMicrophone ( channel ) {
563
+ async function setupMicrophone ( ) {
537
564
const $micPermissionStatus = $ ( "#micPermissionStatus" ) ;
538
565
$micPermissionStatus . text ( "Requesting microphone access..." ) ;
539
566
540
567
// Try to initialise the microphone
541
568
const success = await microphoneInput . initialise ( ) ;
542
569
if ( success ) {
543
- console . log ( "Microphone: Successfully initialised from URL parameters" ) ;
544
- // Set microphone as source for its channel
545
- console . log ( `Setting microphone as source for channel ${ channel } ` ) ;
546
- processor . adconverter . setChannelSource ( channel , microphoneInput ) ;
547
570
$micPermissionStatus . text ( "Microphone connected successfully" ) ;
548
-
549
571
await ensureMicrophoneRunning ( ) ;
550
572
551
573
// Try starting audio context from user gesture
@@ -554,7 +576,6 @@ async function setupMicrophone(channel) {
554
576
} ;
555
577
document . addEventListener ( "click" , tryAgain ) ;
556
578
} else {
557
- console . error ( "Microphone: Failed to initialise from URL parameters:" , microphoneInput . getErrorMessage ( ) ) ;
558
579
$micPermissionStatus . text ( `Error: ${ microphoneInput . getErrorMessage ( ) || "Unknown error" } ` ) ;
559
580
config . setMicrophoneChannel ( undefined ) ;
560
581
// Update URL to remove the parameter
@@ -564,16 +585,16 @@ async function setupMicrophone(channel) {
564
585
}
565
586
566
587
if ( parsedQuery . microphoneChannel !== undefined ) {
567
- console . log ( "Microphone: Initialising from URL parameters" ) ;
568
-
569
588
// We need to use setTimeout to make sure this runs after the page has loaded
570
589
// This is needed because some browsers require user interaction for audio context
571
590
setTimeout ( async ( ) => {
572
- console . log ( "Microphone: Delayed initialisation starting" ) ;
573
- await setupMicrophone ( parsedQuery . microphoneChannel ) ;
591
+ await setupMicrophone ( ) ;
574
592
} , 1000 ) ;
575
593
}
576
594
595
+ // Apply ADC source settings from URL parameters
596
+ updateAdcSources ( parsedQuery . mouseJoystickEnabled , parsedQuery . microphoneChannel ) ;
597
+
577
598
// Initialise keyboard now that processor exists
578
599
keyboard = new Keyboard ( {
579
600
processor,
0 commit comments