/* PokeMini - Pokémon-Mini Emulator Copyright (C) 2009-2015 JustBurn This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "PokeMini.h" #include "CommandLine.h" #include "Joystick.h" // Temp joystick map static int TMP_enable; static int TMP_deviceid; static int TMP_axis_dpad; static int TMP_hats_dpad; static int TMP_joy[10]; static int JoyTestMode = 0; static int JoyLastButton = -1; static int JoyLastXAxis = 0; static int JoyLastYAxis = 0; static int JoyLastHat = 0; static int JoyDeadZone = 30000; static int JoyAllowDisable = 1; static char **Joybuttons_names = NULL; static int Joybuttons_num = JOY_BUTTONS; static TJoystickUpdateCB JoystickUpdateCB = NULL; static const char *JoyLastIndexStr[] = { "None", "Left", "Right", "Up", "Down" }; // Joystick menu int UIItems_JoystickC(int index, int reason); TUIMenu_Item UIItems_Joystick[] = { { 0, 0, "Go back...", UIItems_JoystickC }, { 0, 1, "Apply changes...", UIItems_JoystickC }, { 0, 21, "Check inputs...", UIItems_JoystickC }, { 0, 2, "Enable Joystick: %s", UIItems_JoystickC }, { 0, 20, "Device Index: %i", UIItems_JoystickC }, { 0, 3, "Axis as D-Pad: %s", UIItems_JoystickC }, { 0, 4, "Hats as D-Pad: %s", UIItems_JoystickC }, { 0, 8, "Menu", UIItems_JoystickC }, { 0, 9, "A", UIItems_JoystickC }, { 0, 10, "B", UIItems_JoystickC }, { 0, 11, "C", UIItems_JoystickC }, { 0, 12, "Up", UIItems_JoystickC }, { 0, 13, "Down", UIItems_JoystickC }, { 0, 14, "Left", UIItems_JoystickC }, { 0, 15, "Right", UIItems_JoystickC }, { 0, 16, "Power", UIItems_JoystickC }, { 0, 17, "Shake", UIItems_JoystickC }, { 9, 0, "Joystick", UIItems_JoystickC } }; static const char *PM_Keys[] = { "Menu", "A", "B", "C", "Up", "Down", "Left", "Right", "Power", "Shake" }; int JoyTestButtons(int line, char *outtext) { if (outtext == NULL) { JoyTestMode = line; return 0; } if (line == 0) { if (JoyLastButton == -1) { sprintf(outtext, "Last button: None"); } else if (Joybuttons_names && (JoyLastButton < Joybuttons_num)) { sprintf(outtext, "Last button: %s", Joybuttons_names[JoyLastButton+1]); } else { sprintf(outtext, "Last button: %i", JoyLastButton); } } if (line == 1) sprintf(outtext, "Last hat: %s", JoyLastIndexStr[JoyLastHat]); if (line == 2) sprintf(outtext, "X-Axis: %i", JoyLastXAxis); if (line == 3) sprintf(outtext, "Y-Axis: %i", JoyLastYAxis); return line < 4; } int UIItems_JoystickC(int index, int reason) { int i; if (reason == UIMENU_OK) { reason = UIMENU_RIGHT; } if (reason == UIMENU_CANCEL) { UIMenu_PrevMenu(); return 1; } if (reason == UIMENU_LEFT) { switch (index) { case 2: TMP_enable = !TMP_enable; break; case 3: TMP_axis_dpad = !TMP_axis_dpad; break; case 4: TMP_hats_dpad = !TMP_hats_dpad; break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: if (Joybuttons_names) { do { TMP_joy[index-8]--; if (TMP_joy[index-8] < -1) TMP_joy[index-8] = Joybuttons_num-1; } while (!Joybuttons_names[TMP_joy[index-8]+1]); } else { TMP_joy[index-8]--; if (TMP_joy[index-8] < -1) TMP_joy[index-8] = Joybuttons_num-1; } break; case 20: TMP_deviceid--; if (TMP_deviceid < 0) TMP_deviceid = 0; break; } } if (reason == UIMENU_RIGHT) { switch (index) { case 0: UIMenu_PrevMenu(); break; case 1: CommandLine.joyenabled = TMP_enable; CommandLine.joyaxis_dpad = TMP_axis_dpad; CommandLine.joyhats_dpad = TMP_hats_dpad; CommandLine.joyid = TMP_deviceid; for (i=0; i<10; i++) { CommandLine.joybutton[i] = TMP_joy[i]; } UIMenu_BeginMessage(); UIMenu_SetMessage("Joystick definition..", 1); UIMenu_SetMessage("", 1); UIMenu_SetMessage("Changes applied!", 0); UIMenu_EndMessage(60); if (JoystickUpdateCB) JoystickUpdateCB(CommandLine.joyenabled, CommandLine.joyid); break; case 2: TMP_enable = !TMP_enable; break; case 3: TMP_axis_dpad = !TMP_axis_dpad; break; case 4: TMP_hats_dpad = !TMP_hats_dpad; break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: if (Joybuttons_names) { do { TMP_joy[index-8]++; if (TMP_joy[index-8] >= Joybuttons_num) TMP_joy[index-8] = -1; } while (!Joybuttons_names[TMP_joy[index-8]+1]); } else { TMP_joy[index-8]++; if (TMP_joy[index-8] >= Joybuttons_num) TMP_joy[index-8] = -1; } break; case 20: TMP_deviceid++; if (TMP_deviceid >= 32) TMP_deviceid = 31; break; case 21: JoyLastButton = -1; JoyLastXAxis = 0; JoyLastYAxis = 0; JoyLastHat = 0; UIMenu_RealTimeMessage(JoyTestButtons); break; } } if (JoyAllowDisable) UIMenu_ChangeItem(UIItems_Joystick, 2, "Enable Joystick: %s", TMP_enable ? "Yes" : "No"); else UIMenu_ChangeItem(UIItems_Joystick, 2, "Enable Joystick: Yes"); UIMenu_ChangeItem(UIItems_Joystick, 3, "Axis as D-Pad: %s", TMP_axis_dpad ? "Yes" : "No"); UIMenu_ChangeItem(UIItems_Joystick, 4, "Hats as D-Pad: %s", TMP_hats_dpad ? "Yes" : "No"); UIMenu_ChangeItem(UIItems_Joystick, 20, "Device Index: %i", TMP_deviceid); if (Joybuttons_names) { for (i=0; i<10; i++) { if (Joybuttons_names[TMP_joy[i]+1]) UIMenu_ChangeItem(UIItems_Joystick, i+8, "%s Key: %s", PM_Keys[i], Joybuttons_names[TMP_joy[i]+1]); else UIMenu_ChangeItem(UIItems_Joystick, i+8, "%s Key: Invalid", PM_Keys[i]); } } else { for (i=0; i<10; i++) { if (TMP_joy[i] == -1) UIMenu_ChangeItem(UIItems_Joystick, i+8, "%s Key: Off", PM_Keys[i]); else UIMenu_ChangeItem(UIItems_Joystick, i+8, "%s Key: Button %d", PM_Keys[i], TMP_joy[i]); } } return 1; } // Setup joystick void JoystickSetup(char *platform, int allowdisable, int deadzone, char **bnames, int numbuttons, int *mapping) { int i; if (strcmp(platform, CommandLine.joyplatform)) { // If platform doesn't match, load default buttons if (mapping) { for (i=0; i<10; i++) CommandLine.joybutton[i] = mapping[i]; } } JoyAllowDisable = allowdisable; JoyDeadZone = deadzone; Joybuttons_names = bnames; Joybuttons_num = numbuttons; if (Joybuttons_num <= 0) Joybuttons_num = JOY_BUTTONS; } // Enter into the joystick menu void JoystickEnterMenu(void) { int i; TMP_enable = CommandLine.joyenabled; TMP_axis_dpad = CommandLine.joyaxis_dpad; TMP_hats_dpad = CommandLine.joyhats_dpad; for (i=0; i<10; i++) { if (CommandLine.joybutton[i] >= Joybuttons_num) TMP_joy[i] = -1; else TMP_joy[i] = CommandLine.joybutton[i]; } UIMenu_LoadItems(UIItems_Joystick, 0); } // Register callback of when the joystick configs get updated void JoystickUpdateCallback(TJoystickUpdateCB cb) { JoystickUpdateCB = cb; if (JoystickUpdateCB) JoystickUpdateCB(CommandLine.joyenabled, CommandLine.joyid); } // Process joystick buttons packed in bits void JoystickBitsEvent(uint32_t pressbits) { static uint32_t lastpressbits; uint32_t maskbit, togglebits = pressbits ^ lastpressbits; int index, joybutton, pressed; if (!CommandLine.joyenabled && JoyAllowDisable) { lastpressbits = pressbits; return; } if (JoyTestMode) { pressed = pressbits & togglebits; for (index=0; index<32; index++) { if (pressed & (1 << index)) JoyLastButton = index; } } for (index=0; index<10; index++) { joybutton = CommandLine.joybutton[index]; if (joybutton >= 0) { maskbit = (1 << joybutton); if (togglebits & maskbit) { if (index) { UIMenu_KeyEvent(index, (pressbits & maskbit) ? 1 : 0); } else { if (pressbits & maskbit) UI_Status = !UI_Status; } } } } lastpressbits = pressbits; } // Process joystick buttons void JoystickButtonsEvent(int button, int pressed) { int index; if (!CommandLine.joyenabled && JoyAllowDisable) return; if (pressed) JoyLastButton = button; for (index=0; index<10; index++) { if (CommandLine.joybutton[index] == button) { if (index) { UIMenu_KeyEvent(index, pressed); } else { if (pressed) UI_Status = !UI_Status; } } } } // Process joystick axis void JoystickAxisEvent(int axis, int value) { static int lastaxis0value = 0; static int lastaxis1value = 0; if (!CommandLine.joyenabled && JoyAllowDisable) { lastaxis1value = 0; lastaxis0value = 0; return; } if (axis) JoyLastYAxis = value; else JoyLastXAxis = value; if (CommandLine.joyaxis_dpad) { if (axis) { // Up and down if ((value < -JoyDeadZone) && (lastaxis1value >= -JoyDeadZone)) { UIMenu_KeyEvent(MINX_KEY_UP, 1); } else if ((value > JoyDeadZone) && (lastaxis1value <= JoyDeadZone)) { UIMenu_KeyEvent(MINX_KEY_DOWN, 1); } else if ((value > -JoyDeadZone) && (value <= JoyDeadZone) && ((lastaxis1value <= -JoyDeadZone) || (lastaxis1value >= JoyDeadZone))) { UIMenu_KeyEvent(MINX_KEY_UP, 0); UIMenu_KeyEvent(MINX_KEY_DOWN, 0); } lastaxis1value = value; } else { // Left and right if ((value < -JoyDeadZone) && (lastaxis0value >= -JoyDeadZone)) { UIMenu_KeyEvent(MINX_KEY_LEFT, 1); } else if ((value > JoyDeadZone) && (lastaxis0value <= JoyDeadZone)) { UIMenu_KeyEvent(MINX_KEY_RIGHT, 1); } else if ((value > -JoyDeadZone) && (value <= JoyDeadZone) && ((lastaxis0value <= -JoyDeadZone) || (lastaxis0value >= JoyDeadZone))) { UIMenu_KeyEvent(MINX_KEY_LEFT, 0); UIMenu_KeyEvent(MINX_KEY_RIGHT, 0); } lastaxis0value = value; } } } // Process joystick hats #define HAT_ONPRESS(a) ((hatsbitfield & (a)) && !(lasthatvalue & (a))) #define HAT_ONRELEASE(a) (!(hatsbitfield & (a)) && (lasthatvalue & (a))) #define HAT_ONCHANGE(a) ((hatsbitfield & (a)) ^ (lasthatvalue & (a))) void JoystickHatsEvent(int hatsbitfield) { static int lasthatvalue = 0; if (!CommandLine.joyenabled && JoyAllowDisable) { lasthatvalue = hatsbitfield; return; } if (CommandLine.joyhats_dpad) { if (HAT_ONCHANGE(JHAT_LEFT)) { if (HAT_ONPRESS(JHAT_LEFT)) { UIMenu_KeyEvent(MINX_KEY_LEFT, 1); JoyLastHat = 0; } if (HAT_ONRELEASE(JHAT_LEFT)) UIMenu_KeyEvent(MINX_KEY_LEFT, 0); } if (HAT_ONCHANGE(JHAT_RIGHT)) { if (HAT_ONPRESS(JHAT_RIGHT)) { UIMenu_KeyEvent(MINX_KEY_RIGHT, 1); JoyLastHat = 1; } if (HAT_ONRELEASE(JHAT_RIGHT)) UIMenu_KeyEvent(MINX_KEY_RIGHT, 0); } if (HAT_ONCHANGE(JHAT_UP)) { if (HAT_ONPRESS(JHAT_UP)) { UIMenu_KeyEvent(MINX_KEY_UP, 1); JoyLastHat = 2; } if (HAT_ONRELEASE(JHAT_UP)) UIMenu_KeyEvent(MINX_KEY_UP, 0); } if (HAT_ONCHANGE(JHAT_DOWN)) { if (HAT_ONPRESS(JHAT_DOWN)) { UIMenu_KeyEvent(MINX_KEY_DOWN, 1); JoyLastHat = 3; } if (HAT_ONRELEASE(JHAT_DOWN)) UIMenu_KeyEvent(MINX_KEY_DOWN, 0); } } lasthatvalue = hatsbitfield; }