JeremiahK Posted June 9, 2018 Share Posted June 9, 2018 (edited) 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. paddletest.bin paddletest.asm Edited June 9, 2018 by JeremiahK 2 Quote Link to comment Share on other sites More sharing options...
DEBRO Posted June 9, 2018 Share Posted June 9, 2018 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/forums/topic/269044-astroblast-disassembly/ 2 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted June 10, 2018 Author Share Posted June 10, 2018 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. Quote Link to comment Share on other sites More sharing options...
alex_79 Posted June 10, 2018 Share Posted June 10, 2018 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. 2 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted June 11, 2018 Author Share Posted June 11, 2018 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? Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted June 11, 2018 Author Share Posted June 11, 2018 (edited) 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. paddletest.bin paddletest.asm Edited June 11, 2018 by JeremiahK Quote Link to comment Share on other sites More sharing options...
TheHoboInYourRoom Posted June 11, 2018 Share Posted June 11, 2018 Genesis controller in the left port, auto-detected as a paddle. 1 Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted June 11, 2018 Share Posted June 11, 2018 Maybe there is a difference between the charge time of paddle controllers and the sega controllers which can be used to distinguish them? 1 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted June 11, 2018 Author Share Posted June 11, 2018 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? Quote Link to comment Share on other sites More sharing options...
TheHoboInYourRoom Posted June 12, 2018 Share Posted June 12, 2018 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. 1 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted June 12, 2018 Author Share Posted June 12, 2018 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. Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted June 12, 2018 Author Share Posted June 12, 2018 (edited) 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 June 12, 2018 by JeremiahK Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.