Skip to content

Commit

Permalink
Merge pull request #729 from LordEidi/master
Browse files Browse the repository at this point in the history
Introducing game controller rumble in SDL builds
  • Loading branch information
Gadgetoid committed Jan 6, 2022
2 parents 27b9434 + 5704f77 commit 1204303
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 14 deletions.
65 changes: 65 additions & 0 deletions 32blit-sdl/Input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ int Input::find_button(int button) {
}

Input::Input(System *target) : target(target) {
// Open all joysticks as game controllers
for(int n = 0; n < SDL_NumJoysticks(); n++) {

if(SDL_IsGameController(n)) {

auto gc = SDL_GameControllerOpen(n);
if(gc != nullptr) {
_add_controller(gc);
}
}
}
}

Input::~Input() {
for (auto gc : game_controllers)
{
_remove_controller(gc.gc_id);
}
game_controllers.clear();
}

bool Input::handle_mouse(int button, bool state, int x, int y) {
Expand Down Expand Up @@ -132,6 +151,34 @@ bool Input::handle_controller_motion(int axis, int value) {
return false;
}

void Input::handle_controller_added(Sint32 joystick_index) {

SDL_GameController* gc = SDL_GameControllerOpen(joystick_index);
if (gc != nullptr) {
_add_controller(gc);
}
}

void Input::handle_controller_removed(Sint32 joystick_index) {

auto gc_removed = SDL_GameControllerFromInstanceID(joystick_index);
if(gc_removed != nullptr) {
_remove_controller(gc_removed);
}
}

void Input::rumble_controllers(const float& volume) {

if(volume > 0) {
for (auto gc : game_controllers) {
if(gc.can_rumble) {
auto frequency = volume * 0xFFFF;
SDL_GameControllerRumble(gc.gc_id, frequency, frequency, 50);
}
}
}
}

void Input::_virtual_tilt(int x, int y, int half_w, int half_h) {
float z = 80.0f;
x = x - half_w;
Expand All @@ -149,3 +196,21 @@ void Input::_virtual_analog(int x, int y, int half_w, int half_h) {
target->set_joystick(0, jx);
target->set_joystick(1, jy);
}

void Input::_add_controller(SDL_GameController* gc) {
// welcome rumble to test if it can rumble
auto can_rumble = SDL_GameControllerRumble(gc, 0xFFFF, 0xFFFF, 200);

GameController gcs = {gc, can_rumble == 0};
game_controllers.push_back(gcs);
}

void Input::_remove_controller(SDL_GameController* gc) {
game_controllers.erase(
std::remove_if(game_controllers.begin(), game_controllers.end(), [&](GameController const & controller) {
return controller.gc_id == gc;
}),
game_controllers.end());

SDL_GameControllerClose(gc);
}
28 changes: 24 additions & 4 deletions 32blit-sdl/Input.hpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,47 @@
#include <map>
#include <vector>
#include <algorithm>
class System;

struct GameController
{
SDL_GameController* gc_id;
bool can_rumble;
};

class Input {
public:
static std::map<int, int> keys;
static std::map<int, int> buttons;

static int find_key(int key);
static int find_key(int key);
static int find_button(int button);

Input(System *system);
explicit Input(System *system);
~Input();

// Input handlers return true if they handled the event
bool handle_mouse(int button, bool state, int x, int y);
bool handle_keyboard(int key, bool state);
bool handle_controller_button(int button, bool state);
bool handle_controller_motion(int axis, int value);

private:
// controller specific functions
void handle_controller_added(Sint32 joystick_index);
void handle_controller_removed(Sint32 joystick_index);

void rumble_controllers(const float& volume);

private:
System *target;

void _virtual_analog(int, int, int, int);
std::vector<GameController> game_controllers;

void _virtual_analog(int, int, int, int);
void _virtual_tilt(int, int, int, int);

void _add_controller(SDL_GameController* gc);
void _remove_controller(SDL_GameController* gc);

bool left_ctrl = false;
};
14 changes: 5 additions & 9 deletions 32blit-sdl/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ void handle_event(SDL_Event &event) {
break;

case SDL_CONTROLLERDEVICEADDED:
SDL_GameControllerOpen(event.cdevice.which);
blit_input->handle_controller_added(event.cdevice.which);
break;

case SDL_CONTROLLERDEVICEREMOVED:
SDL_GameControllerClose(SDL_GameControllerFromInstanceID(event.cdevice.which));
blit_input->handle_controller_removed(event.cdevice.which);
break;

case SDL_RENDER_TARGETS_RESET:
Expand Down Expand Up @@ -233,13 +233,8 @@ int main(int argc, char *argv[]) {
SDL_SetWindowPosition(window, x, y);
}

// Open all joysticks as game controllers
for(int n=0; n<SDL_NumJoysticks(); n++) {
SDL_GameControllerOpen(n);
}

blit_system = new System();
blit_input = new Input(blit_system);
blit_system = new System();
blit_input = new Input(blit_system);
blit_multiplayer = new Multiplayer(mp_mode, mp_address);
blit_renderer = new Renderer(window, System::width, System::height);
blit_audio = new Audio();
Expand Down Expand Up @@ -272,6 +267,7 @@ int main(int argc, char *argv[]) {

blit_system->stop();
delete blit_system;
delete blit_input;
delete blit_multiplayer;
delete blit_renderer;

Expand Down
6 changes: 5 additions & 1 deletion 32blit-sdl/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@

#include "File.hpp"
#include "System.hpp"
#include "Input.hpp"
#include "32blit.hpp"
#include "UserCode.hpp"
#include "JPEG.hpp"
#include "Multiplayer.hpp"

#include "engine/api_private.hpp"

extern Input *blit_input;

// blit framebuffer memory
static uint8_t framebuffer[320 * 240 * 3];
static blit::Pen palette[256];
Expand Down Expand Up @@ -303,7 +306,8 @@ void System::loop()
blit::joystick.y = shadow_joystick[1];
SDL_UnlockMutex(m_input);
blit::tick(::now());
blit::render(::now());
blit_input->rumble_controllers(blit::vibration);
blit::render(::now());
blit_multiplayer->update();
}

Expand Down

0 comments on commit 1204303

Please sign in to comment.