snes9x/gtk/src/gtk_control.h

145 lines
3.5 KiB
C
Raw Normal View History

/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
2010-09-25 15:46:12 +00:00
#ifndef __GTK_CONTROL_H
#define __GTK_CONTROL_H
#include <queue>
#include <array>
2010-09-25 15:46:12 +00:00
#include "gtk_binding.h"
#include "SDL.h"
2019-07-16 16:16:10 +00:00
// SDL.h may include altivec.h which redefines vector and bool
#undef vector
#undef bool
2010-09-25 15:46:12 +00:00
const int NUM_JOYPADS = 10;
2010-09-25 15:46:12 +00:00
enum {
JOY_MODE_GLOBAL = 0,
JOY_MODE_INDIVIDUAL = 1,
JOY_MODE_CALIBRATE = 2
};
2010-09-25 15:46:12 +00:00
enum {
JOY_RELEASED = 0,
JOY_PRESSED = 1
};
2010-09-25 15:46:12 +00:00
enum {
PORT_COMMAND_FULLSCREEN = 1,
PORT_COMMAND_SAVE_SPC = 2,
PORT_OPEN_ROM = 3,
PORT_PAUSE = 4,
PORT_SEEK_TO_FRAME = 5,
PORT_QUIT = 6,
PORT_SWAP_CONTROLLERS = 7,
PORT_REWIND = 8,
PORT_QUICKLOAD0 = 9,
PORT_QUICKLOAD1 = 10,
PORT_QUICKLOAD2 = 11,
PORT_QUICKLOAD3 = 12,
PORT_QUICKLOAD4 = 13,
PORT_QUICKLOAD5 = 14,
PORT_QUICKLOAD6 = 15,
PORT_QUICKLOAD7 = 16,
PORT_QUICKLOAD8 = 17,
2018-11-06 22:30:50 +00:00
PORT_QUICKLOAD9 = 18,
PORT_SAVESLOT = 19,
PORT_LOADSLOT = 20,
PORT_INCREMENTSAVESLOT = 21,
PORT_DECREMENTLOADSLOT = 22,
PORT_INCREMENTSLOT = 23,
PORT_DECREMENTSLOT = 24,
2018-11-08 20:23:37 +00:00
PORT_GRABMOUSE = 25
};
2010-09-25 15:46:12 +00:00
typedef struct BindingLink
{
const char *button_name;
const char *snes9x_name;
} BindingLink;
extern const BindingLink b_links[];
extern const int b_breaks[];
const int NUM_JOYPAD_LINKS = 24;
const int NUM_EMU_LINKS = 62;
2010-09-25 15:46:12 +00:00
typedef struct JoypadBinding
{
std::array<Binding, NUM_JOYPAD_LINKS> data;
2010-09-25 15:46:12 +00:00
} JoypadBinding;
bool S9xGrabJoysticks();
void S9xReleaseJoysticks();
2010-09-25 15:46:12 +00:00
typedef struct JoyEvent
{
unsigned int parameter;
unsigned int state;
} JoyEvent;
typedef struct Calibration
{
int min;
int max;
int center;
} Calibration;
class JoyDevice
{
public:
JoyDevice();
~JoyDevice();
int get_event(JoyEvent *event);
void flush();
void handle_event(SDL_Event *event);
void register_centers();
gtk: Support adding/removing joysticks at runtime Reworked how/where SDL events are polled: - poll_joystick_events is now a static member of JoyDevice so it can be called from outside when needed (preference window for config and caliration). - S9xProcessEvents calls JoyDevice::poll_joystick_events directly so events are polled when no joysticks are attached. - JoyDevice::poll_joystick_events handles SDL_JOYDEVICE{ADDED,REMOVED} events. - Individual JoyDevice no longer call poll_joystick_events from get_events. Reworked how attached joysticks are maintained in Snes9xConfig: - Use a map for joysticks keyed on SDL JoystickID (instance id in sdl parlance), which is stable while a joystick is attached instead of an array keyed on device_index. The instance id is what poll_joystick_events gets with every event (except for SDL_JOYDEVICEADDED which gets a device_index...) Instance id is an incrementing int starting from 0, they are never reused. i.e. each attach/dettach/attach cycle yields a new id. Whereas device index are reused and can "move". - On SDL_JOYDEVICEADDED the joystick is handed a "joynum", that is, an int from 0 to NUM_JOYPADS-1. A new joystick always get the lowest available joynum. (joynum was already a member of JoyDevice but wasn't initialized, this seemed like a proper way to use it.) - On SDL_JOYDEVICEREMOVED, the joystick associated with the instance id is simply removed from the map. All this allows for the following behaviors. It is possible to start without any joystick, add one joystick and it works. (disconnect/reconnect cycles with a single joystick also work) Joystick numbers are "stable" while they remain connected. For example: - Start with joystick0 and joystick1 connected - if joystick0 is disconnected, joystick1 keeps its number and keeps working - if joystick0 (or any new joystick) is connected at this time, it gets to become joystick0 If all joysticks are disconnected while snes9x is running, the order of the "reconnections" will determine the joystick number of each joystick. I think there is room for improvement still, with regards to code organization. For instance, there could be a "JoyDevices" class which would handle all the attached JoyDevice. This would allow moving all the "joystick_*" methods from Snes9xConfig to that new class, and poll_joystick_events could also be moved there. The functionality wouldn't change, but the intent/ownership would probably be clearer.
2022-02-16 04:14:11 +00:00
bool set_sdl_joystick(unsigned int device_index, int slot);
static void poll_joystick_events();
gtk: Support adding/removing joysticks at runtime Reworked how/where SDL events are polled: - poll_joystick_events is now a static member of JoyDevice so it can be called from outside when needed (preference window for config and caliration). - S9xProcessEvents calls JoyDevice::poll_joystick_events directly so events are polled when no joysticks are attached. - JoyDevice::poll_joystick_events handles SDL_JOYDEVICE{ADDED,REMOVED} events. - Individual JoyDevice no longer call poll_joystick_events from get_events. Reworked how attached joysticks are maintained in Snes9xConfig: - Use a map for joysticks keyed on SDL JoystickID (instance id in sdl parlance), which is stable while a joystick is attached instead of an array keyed on device_index. The instance id is what poll_joystick_events gets with every event (except for SDL_JOYDEVICEADDED which gets a device_index...) Instance id is an incrementing int starting from 0, they are never reused. i.e. each attach/dettach/attach cycle yields a new id. Whereas device index are reused and can "move". - On SDL_JOYDEVICEADDED the joystick is handed a "joynum", that is, an int from 0 to NUM_JOYPADS-1. A new joystick always get the lowest available joynum. (joynum was already a member of JoyDevice but wasn't initialized, this seemed like a proper way to use it.) - On SDL_JOYDEVICEREMOVED, the joystick associated with the instance id is simply removed from the map. All this allows for the following behaviors. It is possible to start without any joystick, add one joystick and it works. (disconnect/reconnect cycles with a single joystick also work) Joystick numbers are "stable" while they remain connected. For example: - Start with joystick0 and joystick1 connected - if joystick0 is disconnected, joystick1 keeps its number and keeps working - if joystick0 (or any new joystick) is connected at this time, it gets to become joystick0 If all joysticks are disconnected while snes9x is running, the order of the "reconnections" will determine the joystick number of each joystick. I think there is room for improvement still, with regards to code organization. For instance, there could be a "JoyDevices" class which would handle all the attached JoyDevice. This would allow moving all the "joystick_*" methods from Snes9xConfig to that new class, and poll_joystick_events could also be moved there. The functionality wouldn't change, but the intent/ownership would probably be clearer.
2022-02-16 04:14:11 +00:00
std::string description;
SDL_Joystick *filedes;
gtk: Support adding/removing joysticks at runtime Reworked how/where SDL events are polled: - poll_joystick_events is now a static member of JoyDevice so it can be called from outside when needed (preference window for config and caliration). - S9xProcessEvents calls JoyDevice::poll_joystick_events directly so events are polled when no joysticks are attached. - JoyDevice::poll_joystick_events handles SDL_JOYDEVICE{ADDED,REMOVED} events. - Individual JoyDevice no longer call poll_joystick_events from get_events. Reworked how attached joysticks are maintained in Snes9xConfig: - Use a map for joysticks keyed on SDL JoystickID (instance id in sdl parlance), which is stable while a joystick is attached instead of an array keyed on device_index. The instance id is what poll_joystick_events gets with every event (except for SDL_JOYDEVICEADDED which gets a device_index...) Instance id is an incrementing int starting from 0, they are never reused. i.e. each attach/dettach/attach cycle yields a new id. Whereas device index are reused and can "move". - On SDL_JOYDEVICEADDED the joystick is handed a "joynum", that is, an int from 0 to NUM_JOYPADS-1. A new joystick always get the lowest available joynum. (joynum was already a member of JoyDevice but wasn't initialized, this seemed like a proper way to use it.) - On SDL_JOYDEVICEREMOVED, the joystick associated with the instance id is simply removed from the map. All this allows for the following behaviors. It is possible to start without any joystick, add one joystick and it works. (disconnect/reconnect cycles with a single joystick also work) Joystick numbers are "stable" while they remain connected. For example: - Start with joystick0 and joystick1 connected - if joystick0 is disconnected, joystick1 keeps its number and keeps working - if joystick0 (or any new joystick) is connected at this time, it gets to become joystick0 If all joysticks are disconnected while snes9x is running, the order of the "reconnections" will determine the joystick number of each joystick. I think there is room for improvement still, with regards to code organization. For instance, there could be a "JoyDevices" class which would handle all the attached JoyDevice. This would allow moving all the "joystick_*" methods from Snes9xConfig to that new class, and poll_joystick_events could also be moved there. The functionality wouldn't change, but the intent/ownership would probably be clearer.
2022-02-16 04:14:11 +00:00
SDL_JoystickID instance_id;
std::queue<JoyEvent> queue;
int mode;
int joynum;
std::vector<Calibration> calibration;
std::vector<int> axis;
std::vector<int> hat;
bool enabled;
private:
void add_event(unsigned int parameter, unsigned int state);
2010-09-25 15:46:12 +00:00
};
class JoyDevices
{
public:
void clear();
bool add(int sdl_device_index);
bool remove(SDL_JoystickID instance_id);
void register_centers();
void flush_events();
void set_mode(int mode);
void poll_events();
std::map<SDL_JoystickID, std::unique_ptr<JoyDevice>>::const_iterator begin() const { return joysticks.begin(); }
std::map<SDL_JoystickID, std::unique_ptr<JoyDevice>>::const_iterator end() const { return joysticks.end(); }
private:
JoyDevice *get_joystick(SDL_JoystickID instance_id);
std::map<SDL_JoystickID, std::unique_ptr<JoyDevice>> joysticks;
};
gtk: Support adding/removing joysticks at runtime Reworked how/where SDL events are polled: - poll_joystick_events is now a static member of JoyDevice so it can be called from outside when needed (preference window for config and caliration). - S9xProcessEvents calls JoyDevice::poll_joystick_events directly so events are polled when no joysticks are attached. - JoyDevice::poll_joystick_events handles SDL_JOYDEVICE{ADDED,REMOVED} events. - Individual JoyDevice no longer call poll_joystick_events from get_events. Reworked how attached joysticks are maintained in Snes9xConfig: - Use a map for joysticks keyed on SDL JoystickID (instance id in sdl parlance), which is stable while a joystick is attached instead of an array keyed on device_index. The instance id is what poll_joystick_events gets with every event (except for SDL_JOYDEVICEADDED which gets a device_index...) Instance id is an incrementing int starting from 0, they are never reused. i.e. each attach/dettach/attach cycle yields a new id. Whereas device index are reused and can "move". - On SDL_JOYDEVICEADDED the joystick is handed a "joynum", that is, an int from 0 to NUM_JOYPADS-1. A new joystick always get the lowest available joynum. (joynum was already a member of JoyDevice but wasn't initialized, this seemed like a proper way to use it.) - On SDL_JOYDEVICEREMOVED, the joystick associated with the instance id is simply removed from the map. All this allows for the following behaviors. It is possible to start without any joystick, add one joystick and it works. (disconnect/reconnect cycles with a single joystick also work) Joystick numbers are "stable" while they remain connected. For example: - Start with joystick0 and joystick1 connected - if joystick0 is disconnected, joystick1 keeps its number and keeps working - if joystick0 (or any new joystick) is connected at this time, it gets to become joystick0 If all joysticks are disconnected while snes9x is running, the order of the "reconnections" will determine the joystick number of each joystick. I think there is room for improvement still, with regards to code organization. For instance, there could be a "JoyDevices" class which would handle all the attached JoyDevice. This would allow moving all the "joystick_*" methods from Snes9xConfig to that new class, and poll_joystick_events could also be moved there. The functionality wouldn't change, but the intent/ownership would probably be clearer.
2022-02-16 04:14:11 +00:00
void S9xDeinitInputDevices();
Binding S9xGetBindingByName(const char *name);
bool S9xIsMousePluggedIn();
2010-09-25 15:46:12 +00:00
#endif /* __GTK_CONTROL_H*/