]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/joystick.cpp
Various fixes for GPU/DSP DIV instruction, fixes for joypad handling.
[virtualjaguar] / src / joystick.cpp
index 86940fc80dc1ae2d13f933784565fa9cfe6f8a79..e662bf1308526a475013527da707480c1c1eccf5 100644 (file)
@@ -3,8 +3,8 @@
 //
 // by cal2
 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
-// Cleanups/fixes by James Hammons
-// (C) 2010 Underground Software
+// Extensive rewrite by James Hammons
+// (C) 2013 Underground Software
 //
 // JLH = James Hammons <jlhamm@acm.org>
 //
@@ -14,9 +14,6 @@
 //
 
 #include "joystick.h"
-
-//#include <SDL.h>
-//#include <time.h>
 #include <string.h>                    // For memset()
 #include "gpu.h"
 #include "jaguar.h"
 // Global vars
 
 static uint8_t joystick_ram[4];
-uint8_t joypad_0_buttons[21];
-uint8_t joypad_1_buttons[21];
-
-bool keyBuffer[21];
+uint8_t joypad0Buttons[21];
+uint8_t joypad1Buttons[21];
+bool audioEnabled = false;
+bool joysticksEnabled = false;
 
-//SDL_Joystick * joystick1;
 
 bool GUIKeyHeld = false;
 extern int start_logging;
@@ -71,8 +67,8 @@ void JoystickExec(void)
 void JoystickReset(void)
 {
        memset(joystick_ram, 0x00, 4);
-       memset(joypad_0_buttons, 0, 21);
-       memset(joypad_1_buttons, 0, 21);
+       memset(joypad0Buttons, 0, 21);
+       memset(joypad1Buttons, 0, 21);
 }
 
 
@@ -81,17 +77,23 @@ void JoystickDone(void)
 }
 
 
-uint8_t JoystickReadByte(uint32_t offset)
+//uint8_t JoystickReadByte(uint32_t offset)
+uint16_t JoystickReadWord(uint32_t offset)
 {
-// For now, until we can fix the 2nd controller... :-P
-//memset(joypad_1_buttons, 0, 21);
+       // E, D, B, 7
+       uint8_t joypad0Offset[16] = {
+               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xFF, 0xFF, 0xFF, 0x08, 0xFF, 0x04, 0x00, 0xFF
+       };
+       uint8_t joypad1Offset[16] = {
+               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x04, 0xFF, 0x08, 0x0C, 0xFF
+       };
 
 #warning "No bounds checking done in JoystickReadByte!"
-//     extern bool hardwareTypeNTSC;
        offset &= 0x03;
 
        if (offset == 0)
        {
+#if 0
                uint8_t data = 0x00;
                int pad0Index = joystick_ram[1] & 0x0F;
                int pad1Index = (joystick_ram[1] >> 4) & 0x0F;
@@ -122,21 +124,54 @@ uint8_t JoystickReadByte(uint32_t offset)
                else if (!(pad1Index & 0x08))
                        pad1Index = 0;
 
-               if (joypad_0_buttons[(pad0Index << 2) + 0])     data |= 0x01;
-               if (joypad_0_buttons[(pad0Index << 2) + 1]) data |= 0x02;
-               if (joypad_0_buttons[(pad0Index << 2) + 2]) data |= 0x04;
-               if (joypad_0_buttons[(pad0Index << 2) + 3]) data |= 0x08;
-               if (joypad_1_buttons[(pad1Index << 2) + 0]) data |= 0x10;
-               if (joypad_1_buttons[(pad1Index << 2) + 1]) data |= 0x20;
-               if (joypad_1_buttons[(pad1Index << 2) + 2]) data |= 0x40;
-               if (joypad_1_buttons[(pad1Index << 2) + 3]) data |= 0x80;
+               if (joypad0Buttons[(pad0Index << 2) + 0]) data |= 0x01;
+               if (joypad0Buttons[(pad0Index << 2) + 1]) data |= 0x02;
+               if (joypad0Buttons[(pad0Index << 2) + 2]) data |= 0x04;
+               if (joypad0Buttons[(pad0Index << 2) + 3]) data |= 0x08;
+               if (joypad1Buttons[(pad1Index << 2) + 0]) data |= 0x10;
+               if (joypad1Buttons[(pad1Index << 2) + 1]) data |= 0x20;
+               if (joypad1Buttons[(pad1Index << 2) + 2]) data |= 0x40;
+               if (joypad1Buttons[(pad1Index << 2) + 3]) data |= 0x80;
 
                return ~data;
+#else
+               if (!joysticksEnabled)
+                       return 0xFF;
+
+               // Joystick data returns active low for buttons pressed, high for non-
+               // pressed.
+               uint16_t data = 0xFFFF;
+               uint8_t offset0 = joypad0Offset[joystick_ram[1] & 0x0F];
+               uint8_t offset1 = joypad1Offset[(joystick_ram[1] >> 4) & 0x0F];
+
+               if (offset0 != 0xFF)
+               {
+                       uint16_t mask[4] = { 0xFEFF, 0xFDFF, 0xFBFF, 0xF7FF };
+
+                       for(uint8_t i=0; i<4; i++)
+                               data &= (joypad0Buttons[offset0 + i] ? mask[i] : 0xFFFF);
+               }
+
+               if (offset1 != 0xFF)
+               {
+                       uint16_t mask[4] = { 0xEFFF, 0xDFFF, 0xBFFF, 0x7FFF };
+
+                       for(uint8_t i=0; i<4; i++)
+                               data &= (joypad1Buttons[offset1 + i] ? mask[i] : 0xFFFF);
+               }
+
+               return data;
+#endif
        }
-       else if (offset == 3)
+//     else if (offset == 3)
+       else if (offset == 2)
        {
                // Hardware ID returns NTSC/PAL identification bit here
-               uint8_t data = 0x2F | (vjs.hardwareTypeNTSC ? 0x10 : 0x00);
+               uint16_t data = 0xFFEF | (vjs.hardwareTypeNTSC ? 0x10 : 0x00);
+
+               if (!joysticksEnabled)
+                       return data;
+#if 0
                int pad0Index = joystick_ram[1] & 0x0F;
                int pad1Index = (joystick_ram[1] >> 4) & 0x0F;
 
@@ -145,67 +180,96 @@ uint8_t JoystickReadByte(uint32_t offset)
 #warning "!!! This reports TeamTap incorrectly when PAUSE pressed on controller #1 or #2 !!!"
                if (!(pad0Index & 0x01))
                {
-                       if (joypad_0_buttons[BUTTON_PAUSE])
+                       if (joypad0Buttons[BUTTON_PAUSE])
                                data ^= 0x01;
-                       if (joypad_0_buttons[BUTTON_A])
+                       if (joypad0Buttons[BUTTON_A])
                                data ^= 0x02;
                }
                else if (!(pad0Index & 0x02))
                {
-                       if (joypad_0_buttons[BUTTON_B])
+                       if (joypad0Buttons[BUTTON_B])
                                data ^= 0x02;
                }
                else if (!(pad0Index & 0x04))
                {
-                       if (joypad_0_buttons[BUTTON_C])
+                       if (joypad0Buttons[BUTTON_C])
                                data ^= 0x02;
                }
                else if (!(pad0Index & 0x08))
                {
-                       if (joypad_0_buttons[BUTTON_OPTION])
+                       if (joypad0Buttons[BUTTON_OPTION])
                                data ^= 0x02;
                }
 
                if (!(pad1Index & 0x08))
                {
-                       if (joypad_1_buttons[BUTTON_PAUSE])
+                       if (joypad1Buttons[BUTTON_PAUSE])
                                data ^= 0x04;
-                       if (joypad_1_buttons[BUTTON_A])
+                       if (joypad1Buttons[BUTTON_A])
                                data ^= 0x08;
                }
                else if (!(pad1Index & 0x04))
                {
-                       if (joypad_1_buttons[BUTTON_B])
+                       if (joypad1Buttons[BUTTON_B])
                                data ^= 0x08;
                }
                else if (!(pad1Index & 0x02))
                {
-                       if (joypad_1_buttons[BUTTON_C])
+                       if (joypad1Buttons[BUTTON_C])
                                data ^= 0x08;
                }
                else if (!(pad1Index & 0x01))
                {
-                       if (joypad_1_buttons[BUTTON_OPTION])
+                       if (joypad1Buttons[BUTTON_OPTION])
                                data ^= 0x08;
                }
+#else
+               // Joystick data returns active low for buttons pressed, high for non-
+               // pressed.
+               uint8_t offset0 = joypad0Offset[joystick_ram[1] & 0x0F] / 4;
+               uint8_t offset1 = joypad1Offset[(joystick_ram[1] >> 4) & 0x0F] / 4;
+
+               if (offset0 != 0xFF)
+               {
+                       uint8_t mask[4][2] = { { BUTTON_A, BUTTON_PAUSE }, { BUTTON_B, -1 }, { BUTTON_C, -1 }, { BUTTON_OPTION, -1 } };
+                       data &= (joypad0Buttons[mask[offset0][0]] ? 0xFFFD : 0xFFFF);
+
+                       if (mask[offset0][1] != -1)
+                               data &= (joypad0Buttons[mask[offset0][1]] ? 0xFFFE : 0xFFFF);
+               }
+
+               if (offset1 != 0xFF)
+               {
+                       uint8_t mask[4][2] = { { BUTTON_A, BUTTON_PAUSE }, { BUTTON_B, -1 }, { BUTTON_C, -1 }, { BUTTON_OPTION, -1 } };
+                       data &= (joypad1Buttons[mask[offset1][0]] ? 0xFFF7 : 0xFFFF);
+
+                       if (mask[offset1][1] != -1)
+                               data &= (joypad1Buttons[mask[offset1][1]] ? 0xFFFB : 0xFFFF);
+               }
+#endif
 
                return data;
        }
 
-       return joystick_ram[offset];
+//     return joystick_ram[offset];
+       return 0xFF;
 }
 
 
+#if 0
 uint16_t JoystickReadWord(uint32_t offset)
 {
        return ((uint16_t)JoystickReadByte((offset + 0) & 0x03) << 8) | JoystickReadByte((offset + 1) & 0x03);
 }
+#endif
 
 
+#if 0
 void JoystickWriteByte(uint32_t offset, uint8_t data)
 {
        joystick_ram[offset & 0x03] = data;
 }
+#endif
 
 
 void JoystickWriteWord(uint32_t offset, uint16_t data)
@@ -214,5 +278,11 @@ void JoystickWriteWord(uint32_t offset, uint16_t data)
        offset &= 0x03;
        joystick_ram[offset + 0] = (data >> 8) & 0xFF;
        joystick_ram[offset + 1] = data & 0xFF;
+
+       if (offset == 0)
+       {
+               audioEnabled = (data & 0x0100 ? true : false);
+               joysticksEnabled = (data & 0x8000 ? true : false);
+       }
 }