Jump to content

Photo

Auto-Detecting Controller at Startup

Atari 2600 Detect Auto-Detect Paddle Joystick

11 replies to this topic

#1 JeremiahK OFFLINE  

JeremiahK

    Chopper Commander

  • 187 posts
  • Location:Indiana, USA

Posted Fri Jun 8, 2018 8:14 PM

As I am continuing to develop my first game, I ran into an issue that I couldn't find any information on.  I would like to have the system detect the controllers on startup.  This way, I can support multiple controllers in the game without using the difficulty switches or some other U/I system to select controller types, simply plug-and-play.

I first had the idea of using the fire button to get past the splash screen of the game.  However, moving the joystick instead could put the game into paddle mode, which wouldn't be good.  So instead, I discovered that you can simply dump the capacitors for the paddles, wait long enough (512 scanlines works), and then read INPT0 (and INPT2).

And that's it.

 

Here's the code I wrote, which works perfectly.  If a paddle is connected to the left I/O port at startup, the screen will be red.  Otherwise, the screen is black.

	CLEAN_START

	sta WSYNC	; ensure a whole scanline is spent dumping capacitors
	lda #$80
	sta VBLANK	; dump paddle capacitors to ground
WaitLoop
	sta WSYNC
	stx VBLANK	; (X=0) stop dumping capacitors
	sta WSYNC	; waste 2 scanlines per iteration
	dey		; Y starts and ends as 0
	bne WaitLoop	; wait 512 scanlines in loop (511 after grounding caps)

	lda INPT0	; D7 set if left paddle is connected, clear otherwise
	bpl Joystick
	lda #$46	; set bg color to red to signify a paddle, else black
	sta COLUBK	; in a game, you would set a bit in RAM, instead
Joystick

I attached a .bin and the source code.  Obviously, try it on a real system if you can, but it works in Stella, as well.

Attached Files


Edited by JeremiahK, Fri Jun 8, 2018 8:18 PM.


#2 DEBRO OFFLINE  

DEBRO

    Stargunner

  • 1,945 posts
  • Location:Atlanta, GA

Posted Sat Jun 9, 2018 8:00 AM

Hi there,

 

Very nice.

 

Also check out my disassembly of Astroblast. This game detects whether the paddle or joystick is present at startup. The routine is documented in the routine DetermineControllerType.

 

http://atariage.com/...st-disassembly/



#3 JeremiahK OFFLINE  

JeremiahK

    Chopper Commander

  • Topic Starter
  • 187 posts
  • Location:Indiana, USA

Posted Sat Jun 9, 2018 7:54 PM

Very interesting.  Here is the Astroblast method:

DetermineControllerType
   lda #DUMP_PORTS | DISABLE_TIA
   sta VBLANK
   ldx #0
.waitForCapacitorCharge
   bit INPT0                        ; check paddle 0 value
   bpl .continueDetermineControllerType; branch if capacitor not charged
   dex
   bne .waitForCapacitorCharge
   beq .setControllerTypeToPaddles  ; unconditional branch
   
.continueDetermineControllerType
   lda #DISABLE_TIA
   sta VBLANK                       ; disable TIA (i.e. D1 = 1)
   ldx #32                          ; wait ~538 scanlines (i.e. ~2 frames)
.outerLoopWait
   ldy #0
.innerLoopWait
   iny
   bne .innerLoopWait
   dex
   bne .outerLoopWait
   bit INPT0                        ; check paddle 0 value
   bpl .doneDetermineControllerType ; branch if capacitor not charged
.setControllerTypeToPaddles
   lda gameState                    ; get current game state value
   ora #USING_PADDLES
   sta gameState                    ; set game state to USING_PADDLES
.doneDetermineControllerType
   rts

It seems to be doing more or less exactly the same thing, except I am using WSYNC to waste time much more efficiently.



#4 alex_79 OFFLINE  

alex_79

    Stargunner

  • 1,171 posts
  • Location:Italy

Posted Sun Jun 10, 2018 1:30 PM

Keep in mind that a Sega Genesis/Megadrive pad will fail the test and will be detected as a paddle instead. There are pullup resistors connected to pins 5 and 9 inside the controller that cause the paddle caps to be recharged. Pin 9 (INPT1 or INPT3 depending on which port the controller is plugged in) can be grounded if button C is pressed (That's how that extra button can be read by some homebrews and hacks), while the pullup in pin 5 (INPT0/INPT2) is always connected so the related capacitor will always be recharged.

Those controllers are a common choice for people who prefer D-pads over a classic joystick, so you might want to consider a way to make them work with your game.

For example, you can add a way to force joystick mode by holding a button while powering the console (the RESET or SELECT switch, for example or a button/direction on the controller ). The Harmony menu forces joystick mode by holding the fire button on the controller itself ("B" on the genesis pad).

Or you could add code to revert to joystick mode if any of the UP/DOWN directions or the firebutton is pressed.


 



#5 JeremiahK OFFLINE  

JeremiahK

    Chopper Commander

  • Topic Starter
  • 187 posts
  • Location:Indiana, USA

Posted Sun Jun 10, 2018 8:23 PM

Does that mean that the auto-detection would correctly detect a Sega Genesis controller as a "joystick" if you read from INPT1/INPT3, as long as button C was not pressed at startup?  Or would it only detect a joystick type controller if button C was pressed?



#6 JeremiahK OFFLINE  

JeremiahK

    Chopper Commander

  • Topic Starter
  • 187 posts
  • Location:Indiana, USA

Posted Sun Jun 10, 2018 10:21 PM

I am pretty sure it's the latter, now that I carefully re-read your previous post.

In that case, I think the best solution is to check the fire button on startup, since you can't accidentally do that with a paddle.

 

Here's an update to my auto-detect program.  There are bars on either side of the screen, representing the left and right I/O ports.  They are each one of three colors (red = paddle auto-detected, blue = joystick auto-detected, green = joystick forced).  You can force joystick mode by pressing the fire button.  I would love to know if this works with Sega Genesis and other non-Atari controllers, although I would bet it works fine.

Attached Files


Edited by JeremiahK, Sun Jun 10, 2018 10:22 PM.


#7 TheHoboInYourRoom OFFLINE  

TheHoboInYourRoom

    Moonsweeper

  • 401 posts
  • Whackadoo thingamajig
  • Location:Illinois

Posted Mon Jun 11, 2018 11:14 AM

Genesis controller in the left port, auto-detected as a paddle.



#8 ZackAttack OFFLINE  

ZackAttack

    Dragonstomper

  • 733 posts
  • Location:Orlando, FL US

Posted Mon Jun 11, 2018 2:25 PM

Maybe there is a difference between the charge time of paddle controllers and the sega controllers which can be used to distinguish them?



#9 JeremiahK OFFLINE  

JeremiahK

    Chopper Commander

  • Topic Starter
  • 187 posts
  • Location:Indiana, USA

Posted Mon Jun 11, 2018 5:10 PM

Hopefully, but I don't think so, since the paddles are variable. Meaning that if the paddle is turned just so, it will think it's a Genesis controller.
Hobo, did you hold the fire button equivalent at startup?

#10 TheHoboInYourRoom OFFLINE  

TheHoboInYourRoom

    Moonsweeper

  • 401 posts
  • Whackadoo thingamajig
  • Location:Illinois

Posted Mon Jun 11, 2018 7:56 PM

Hobo, did you hold the fire button equivalent at startup?

I tried that as well, and it forced joystick interpretation as you'd expect.
Without pressing the button, it's seen as a paddle.



#11 JeremiahK OFFLINE  

JeremiahK

    Chopper Commander

  • Topic Starter
  • 187 posts
  • Location:Indiana, USA

Posted Mon Jun 11, 2018 9:39 PM

Ok, thanks, that is how it is supposed to work for now. I will have to try and figure out if it's possible to auto-detect properly, though.

#12 JeremiahK OFFLINE  

JeremiahK

    Chopper Commander

  • Topic Starter
  • 187 posts
  • Location:Indiana, USA

Posted Mon Jun 11, 2018 9:47 PM

One workaround would be to make the user press fire to exit the splash screen. That way, if a paddle was detected, but a joystick's fire button was pressed, it would switch to joystick mode.

 

Edit: That would only work with one controller, though.


Edited by JeremiahK, Mon Jun 11, 2018 10:33 PM.






Also tagged with one or more of these keywords: Atari 2600, Detect, Auto-Detect, Paddle, Joystick

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users