git repos / blockattack-game

blame: source/code/gamecontroller.cpp

normal view · raw

826cf176 sago007 2016-03-12 10:53 1
/*
826cf176 sago007 2016-03-12 10:53 2
===========================================================================
826cf176 sago007 2016-03-12 10:53 3
blockattack - Block Attack - Rise of the Blocks
826cf176 sago007 2016-03-12 10:53 4
Copyright (C) 2005-2016 Poul Sander
826cf176 sago007 2016-03-12 10:53 5
826cf176 sago007 2016-03-12 10:53 6
This program is free software: you can redistribute it and/or modify
826cf176 sago007 2016-03-12 10:53 7
it under the terms of the GNU General Public License as published by
826cf176 sago007 2016-03-12 10:53 8
the Free Software Foundation, either version 2 of the License, or
826cf176 sago007 2016-03-12 10:53 9
(at your option) any later version.
826cf176 sago007 2016-03-12 10:53 10
826cf176 sago007 2016-03-12 10:53 11
This program is distributed in the hope that it will be useful,
826cf176 sago007 2016-03-12 10:53 12
but WITHOUT ANY WARRANTY; without even the implied warranty of
826cf176 sago007 2016-03-12 10:53 13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
826cf176 sago007 2016-03-12 10:53 14
GNU General Public License for more details.
826cf176 sago007 2016-03-12 10:53 15
826cf176 sago007 2016-03-12 10:53 16
You should have received a copy of the GNU General Public License
826cf176 sago007 2016-03-12 10:53 17
along with this program.  If not, see http://www.gnu.org/licenses/
826cf176 sago007 2016-03-12 10:53 18
826cf176 sago007 2016-03-12 10:53 19
Source information and contacts persons can be found at
826cf176 sago007 2016-03-12 10:53 20
http://www.blockattack.net
826cf176 sago007 2016-03-12 10:53 21
===========================================================================
826cf176 sago007 2016-03-12 10:53 22
*/
826cf176 sago007 2016-03-12 10:53 23
826cf176 sago007 2016-03-12 10:53 24
#include "gamecontroller.h"
826cf176 sago007 2016-03-12 10:53 25
#include "SDL_gamecontroller.h"
2cb68251 sago007 2016-03-14 18:01 26
#include "sago/platform_folders.h"
75ea368b sago007 2016-04-16 14:37 27
#include "common.h"
826cf176 sago007 2016-03-12 10:53 28
#include <iostream>
a077dceb sago007 2016-03-19 19:19 29
#include <map>
75ea368b sago007 2016-04-16 14:37 30
#include <SDL2/SDL_joystick.h>
826cf176 sago007 2016-03-12 10:53 31
2cb68251 sago007 2016-03-14 18:01 32
static bool verbose = false;
2cb68251 sago007 2016-03-14 18:01 33
a077dceb sago007 2016-03-19 19:19 34
struct ControllerStatus {
a077dceb sago007 2016-03-19 19:19 35
	std::map<int, bool> AxisInDeadZone;
f2dac7e4 sago007 2016-04-09 19:24 36
	int player = 1;
a077dceb sago007 2016-03-19 19:19 37
};
a077dceb sago007 2016-03-19 19:19 38
a077dceb sago007 2016-03-19 19:19 39
static std::map<SDL_JoystickID, ControllerStatus> controllerStatusMap;
bf4572f8 sago007 2018-04-10 22:25 40
static std::map<std::string, int> gamecontrollers_assigned;
bf4572f8 sago007 2018-04-10 22:25 41
static std::vector<std::string> supportedControllers;
a077dceb sago007 2016-03-19 19:19 42
a077dceb sago007 2016-03-19 19:19 43
2cb68251 sago007 2016-03-14 18:01 44
void GameControllerSetVerbose(bool value) {
2cb68251 sago007 2016-03-14 18:01 45
	verbose = value;
2cb68251 sago007 2016-03-14 18:01 46
}
2cb68251 sago007 2016-03-14 18:01 47
a35ab74b sago007 2016-04-02 10:26 48
static const char* GameControllerGetName(SDL_GameController* gamecontroller) {
2cb68251 sago007 2016-03-14 18:01 49
	const char* result = SDL_GameControllerName(gamecontroller);
2cb68251 sago007 2016-03-14 18:01 50
	if (!result) {
2cb68251 sago007 2016-03-14 18:01 51
		result = "Unnamed";
2cb68251 sago007 2016-03-14 18:01 52
	}
2cb68251 sago007 2016-03-14 18:01 53
	return result;
2cb68251 sago007 2016-03-14 18:01 54
}
2cb68251 sago007 2016-03-14 18:01 55
75ea368b sago007 2016-04-16 14:37 56
static std::string GetGuidAsHex(const SDL_JoystickGUID& guid) {
75ea368b sago007 2016-04-16 14:37 57
	std::string ret;
75ea368b sago007 2016-04-16 14:37 58
	char buffer[3];
092bdebe sago007 2017-03-19 14:39 59
	for (size_t j = 0; j < 16; j++) {
75ea368b sago007 2016-04-16 14:37 60
		snprintf(buffer, sizeof(buffer), "%02X", guid.data[j]);
75ea368b sago007 2016-04-16 14:37 61
		ret += buffer;
75ea368b sago007 2016-04-16 14:37 62
	}
75ea368b sago007 2016-04-16 14:37 63
	return ret;
75ea368b sago007 2016-04-16 14:37 64
}
75ea368b sago007 2016-04-16 14:37 65
75ea368b sago007 2016-04-16 14:37 66
75ea368b sago007 2016-04-16 14:37 67
static int GetNextPlayerByGui(const SDL_JoystickGUID& guid) {
75ea368b sago007 2016-04-16 14:37 68
	Config::getInstance()->setDefault("gc_AllToOnePlayer", "0");
75ea368b sago007 2016-04-16 14:37 69
	int fixedPlayer = Config::getInstance()->getInt("gc_AllToOnePlayer");
75ea368b sago007 2016-04-16 14:37 70
	if (fixedPlayer > 0 && fixedPlayer <= 2) {
75ea368b sago007 2016-04-16 14:37 71
		return fixedPlayer;
75ea368b sago007 2016-04-16 14:37 72
	}
75ea368b sago007 2016-04-16 14:37 73
	std::string guidAsHex= GetGuidAsHex(guid);
75ea368b sago007 2016-04-16 14:37 74
	std::string configName = "gc_assign_"+guidAsHex;
75ea368b sago007 2016-04-16 14:37 75
	Config::getInstance()->setDefault(configName, "1");
75ea368b sago007 2016-04-16 14:37 76
	int player = Config::getInstance()->getInt(configName) + gamecontrollers_assigned[guidAsHex];
75ea368b sago007 2016-04-16 14:37 77
	gamecontrollers_assigned[guidAsHex]++; //Next controller with same guid should be assigned to different player.
161a010c sago007 2016-05-06 14:00 78
	//std::cout << "Guid: " << guidAsHex << "\n";
092bdebe sago007 2017-03-19 14:39 79
75ea368b sago007 2016-04-16 14:37 80
	if (player%2==0) {
75ea368b sago007 2016-04-16 14:37 81
		return 2;  //Even number means player 2
75ea368b sago007 2016-04-16 14:37 82
	}
75ea368b sago007 2016-04-16 14:37 83
	return 1;
75ea368b sago007 2016-04-16 14:37 84
}
75ea368b sago007 2016-04-16 14:37 85
826cf176 sago007 2016-03-12 10:53 86
void InitGameControllers() {
2cb68251 sago007 2016-03-14 18:01 87
	std::string configFile = sago::getConfigHome()+"/blockattack/gamecontrollerdb.txt";
2cb68251 sago007 2016-03-14 18:01 88
	int errorCode = SDL_GameControllerAddMappingsFromFile(configFile.c_str());
2cb68251 sago007 2016-03-14 18:01 89
	if (errorCode == -1 && verbose) {
161a010c sago007 2016-05-06 14:00 90
		std::cerr << "Could not load mapping file: " << configFile << "\n";
2cb68251 sago007 2016-03-14 18:01 91
	}
2cb68251 sago007 2016-03-14 18:01 92
	if (verbose) {
161a010c sago007 2016-05-06 14:00 93
		std::cout << "Number of Game controllers: " << SDL_NumJoysticks() << "\n";
2cb68251 sago007 2016-03-14 18:01 94
	}
c7f2082f sago007 2016-03-13 11:48 95
	SDL_GameController* controller = nullptr;
826cf176 sago007 2016-03-12 10:53 96
	for (int i = 0; i < SDL_NumJoysticks(); ++i) {
826cf176 sago007 2016-03-12 10:53 97
		if (SDL_IsGameController(i)) {
826cf176 sago007 2016-03-12 10:53 98
			controller = SDL_GameControllerOpen(i);
092bdebe sago007 2017-03-19 14:39 99
			SDL_Joystick* j = SDL_GameControllerGetJoystick(controller);
f2dac7e4 sago007 2016-04-09 19:24 100
			SDL_JoystickID instanceId = SDL_JoystickInstanceID(j);
75ea368b sago007 2016-04-16 14:37 101
			SDL_JoystickGUID guid = SDL_JoystickGetGUID(j);
75ea368b sago007 2016-04-16 14:37 102
			int assingToPlayer = GetNextPlayerByGui(guid);
75ea368b sago007 2016-04-16 14:37 103
			controllerStatusMap[instanceId].player = assingToPlayer;
bf4572f8 sago007 2018-04-10 22:25 104
			supportedControllers.push_back(GameControllerGetName(controller));
2cb68251 sago007 2016-03-14 18:01 105
			if (verbose) {
161a010c sago007 2016-05-06 14:00 106
				std::cout << "Supported game controller detected: " << GameControllerGetName(controller) << ", mapping: " << SDL_GameControllerMapping(controller) <<  "\n";
161a010c sago007 2016-05-06 14:00 107
				std::cout << "Assigned to player: " << controllerStatusMap[instanceId].player << "\n";
2cb68251 sago007 2016-03-14 18:01 108
			}
826cf176 sago007 2016-03-12 10:53 109
		}
826cf176 sago007 2016-03-12 10:53 110
	}
826cf176 sago007 2016-03-12 10:53 111
}
ce5aa7d3 sago007 2016-03-13 11:44 112
bf4572f8 sago007 2018-04-10 22:25 113
const std::vector<std::string>& GetSupportedControllerNames() {
bf4572f8 sago007 2018-04-10 22:25 114
	return supportedControllers;
bf4572f8 sago007 2018-04-10 22:25 115
}
bf4572f8 sago007 2018-04-10 22:25 116
a077dceb sago007 2016-03-19 19:19 117
void checkDeadZone(const SDL_Event& event) {
a077dceb sago007 2016-03-19 19:19 118
	if (event.type != SDL_CONTROLLERAXISMOTION) {
a077dceb sago007 2016-03-19 19:19 119
		return;  //assert?
a077dceb sago007 2016-03-19 19:19 120
	}
a077dceb sago007 2016-03-19 19:19 121
	int value = event.caxis.value;
a077dceb sago007 2016-03-19 19:19 122
	if (value > -deadZoneLimit && value < deadZoneLimit) {
a077dceb sago007 2016-03-19 19:19 123
		controllerStatusMap[event.caxis.which].AxisInDeadZone[event.caxis.axis] = true;
a077dceb sago007 2016-03-19 19:19 124
	}
a077dceb sago007 2016-03-19 19:19 125
}
a077dceb sago007 2016-03-19 19:19 126
a077dceb sago007 2016-03-19 19:19 127
bool getDeadZone(SDL_JoystickID id, int axis) {
a077dceb sago007 2016-03-19 19:19 128
	return controllerStatusMap[id].AxisInDeadZone[axis];
a077dceb sago007 2016-03-19 19:19 129
}
a077dceb sago007 2016-03-19 19:19 130
a077dceb sago007 2016-03-19 19:19 131
void setDeadZone(SDL_JoystickID id, int axis, bool value) {
a077dceb sago007 2016-03-19 19:19 132
	controllerStatusMap[id].AxisInDeadZone[axis] = value;
a077dceb sago007 2016-03-19 19:19 133
}
a077dceb sago007 2016-03-19 19:19 134
f2dac7e4 sago007 2016-04-09 19:24 135
static bool skipThisPlayer(int playerNumber, const SDL_Event& event) {
f2dac7e4 sago007 2016-04-09 19:24 136
f2dac7e4 sago007 2016-04-09 19:24 137
	if (event.type == SDL_CONTROLLERBUTTONDOWN) {
f2dac7e4 sago007 2016-04-09 19:24 138
		ControllerStatus& cs = controllerStatusMap[event.cbutton.which];
f2dac7e4 sago007 2016-04-09 19:24 139
		if (cs.player == playerNumber) {
f2dac7e4 sago007 2016-04-09 19:24 140
			return false;
f2dac7e4 sago007 2016-04-09 19:24 141
		}
f2dac7e4 sago007 2016-04-09 19:24 142
	}
f2dac7e4 sago007 2016-04-09 19:24 143
	if (event.type == SDL_CONTROLLERAXISMOTION ) {
f2dac7e4 sago007 2016-04-09 19:24 144
		ControllerStatus& cs = controllerStatusMap[event.caxis.which];
f2dac7e4 sago007 2016-04-09 19:24 145
		if (cs.player == playerNumber) {
f2dac7e4 sago007 2016-04-09 19:24 146
			return false;
f2dac7e4 sago007 2016-04-09 19:24 147
		}
f2dac7e4 sago007 2016-04-09 19:24 148
	}
f2dac7e4 sago007 2016-04-09 19:24 149
	return true;
f2dac7e4 sago007 2016-04-09 19:24 150
}
f2dac7e4 sago007 2016-04-09 19:24 151
ce5aa7d3 sago007 2016-03-13 11:44 152
bool isPlayerDownEvent(int playerNumber, const SDL_Event& event) {
f2dac7e4 sago007 2016-04-09 19:24 153
	if (skipThisPlayer(playerNumber, event)) {
ce5aa7d3 sago007 2016-03-13 11:44 154
		return false;
ce5aa7d3 sago007 2016-03-13 11:44 155
	}
ce5aa7d3 sago007 2016-03-13 11:44 156
	if (event.type == SDL_CONTROLLERBUTTONDOWN) {
ce5aa7d3 sago007 2016-03-13 11:44 157
		if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN ) {
ce5aa7d3 sago007 2016-03-13 11:44 158
			return true;
ce5aa7d3 sago007 2016-03-13 11:44 159
		}
ce5aa7d3 sago007 2016-03-13 11:44 160
	}
a077dceb sago007 2016-03-19 19:19 161
	if (event.type == SDL_CONTROLLERAXISMOTION  && event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY ) {
a35ab74b sago007 2016-04-02 10:26 162
		const SDL_ControllerAxisEvent& a = event.caxis;
f2dac7e4 sago007 2016-04-09 19:24 163
		checkDeadZone(event);
a077dceb sago007 2016-03-19 19:19 164
		if (getDeadZone(a.which, a.axis)) {
a077dceb sago007 2016-03-19 19:19 165
			if (event.caxis.value > deadZoneLimit) {
a077dceb sago007 2016-03-19 19:19 166
				setDeadZone(a.which,a.axis,false);
a077dceb sago007 2016-03-19 19:19 167
				return true;
a077dceb sago007 2016-03-19 19:19 168
			}
a077dceb sago007 2016-03-19 19:19 169
		}
a077dceb sago007 2016-03-19 19:19 170
	}
ce5aa7d3 sago007 2016-03-13 11:44 171
	return false;
ce5aa7d3 sago007 2016-03-13 11:44 172
}
ce5aa7d3 sago007 2016-03-13 11:44 173
ce5aa7d3 sago007 2016-03-13 11:44 174
bool isPlayerUpEvent(int playerNumber, const SDL_Event& event) {
f2dac7e4 sago007 2016-04-09 19:24 175
	if (skipThisPlayer(playerNumber, event)) {
ce5aa7d3 sago007 2016-03-13 11:44 176
		return false;
ce5aa7d3 sago007 2016-03-13 11:44 177
	}
ce5aa7d3 sago007 2016-03-13 11:44 178
	if (event.type == SDL_CONTROLLERBUTTONDOWN) {
ce5aa7d3 sago007 2016-03-13 11:44 179
		if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_UP ) {
ce5aa7d3 sago007 2016-03-13 11:44 180
			return true;
ce5aa7d3 sago007 2016-03-13 11:44 181
		}
ce5aa7d3 sago007 2016-03-13 11:44 182
	}
a077dceb sago007 2016-03-19 19:19 183
	if (event.type == SDL_CONTROLLERAXISMOTION  && event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY ) {
a077dceb sago007 2016-03-19 19:19 184
		checkDeadZone(event);
a35ab74b sago007 2016-04-02 10:26 185
		const SDL_ControllerAxisEvent& a = event.caxis;
a077dceb sago007 2016-03-19 19:19 186
		if (getDeadZone(a.which, a.axis)) {
a077dceb sago007 2016-03-19 19:19 187
			if (event.caxis.value < -deadZoneLimit) {
a077dceb sago007 2016-03-19 19:19 188
				setDeadZone(a.which,a.axis,false);
a077dceb sago007 2016-03-19 19:19 189
				return true;
a077dceb sago007 2016-03-19 19:19 190
			}
a077dceb sago007 2016-03-19 19:19 191
		}
a077dceb sago007 2016-03-19 19:19 192
	}
ce5aa7d3 sago007 2016-03-13 11:44 193
	return false;
ce5aa7d3 sago007 2016-03-13 11:44 194
}
ce5aa7d3 sago007 2016-03-13 11:44 195
ce5aa7d3 sago007 2016-03-13 11:44 196
bool isPlayerLeftEvent(int playerNumber, const SDL_Event& event) {
f2dac7e4 sago007 2016-04-09 19:24 197
	if (skipThisPlayer(playerNumber, event)) {
ce5aa7d3 sago007 2016-03-13 11:44 198
		return false;
ce5aa7d3 sago007 2016-03-13 11:44 199
	}
ce5aa7d3 sago007 2016-03-13 11:44 200
	if (event.type == SDL_CONTROLLERBUTTONDOWN) {
ce5aa7d3 sago007 2016-03-13 11:44 201
		if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT ) {
ce5aa7d3 sago007 2016-03-13 11:44 202
			return true;
ce5aa7d3 sago007 2016-03-13 11:44 203
		}
ce5aa7d3 sago007 2016-03-13 11:44 204
	}
a077dceb sago007 2016-03-19 19:19 205
	if (event.type == SDL_CONTROLLERAXISMOTION  && event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX ) {
a077dceb sago007 2016-03-19 19:19 206
		checkDeadZone(event);
a35ab74b sago007 2016-04-02 10:26 207
		const SDL_ControllerAxisEvent& a = event.caxis;
a077dceb sago007 2016-03-19 19:19 208
		if (getDeadZone(a.which, a.axis)) {
a077dceb sago007 2016-03-19 19:19 209
			if (event.caxis.value < -deadZoneLimit) {
a077dceb sago007 2016-03-19 19:19 210
				setDeadZone(a.which,a.axis,false);
a077dceb sago007 2016-03-19 19:19 211
				return true;
a077dceb sago007 2016-03-19 19:19 212
			}
a077dceb sago007 2016-03-19 19:19 213
		}
a077dceb sago007 2016-03-19 19:19 214
	}
ce5aa7d3 sago007 2016-03-13 11:44 215
	return false;
ce5aa7d3 sago007 2016-03-13 11:44 216
}
ce5aa7d3 sago007 2016-03-13 11:44 217
ce5aa7d3 sago007 2016-03-13 11:44 218
bool isPlayerRightEvent(int playerNumber, const SDL_Event& event) {
f2dac7e4 sago007 2016-04-09 19:24 219
	if (skipThisPlayer(playerNumber, event)) {
ce5aa7d3 sago007 2016-03-13 11:44 220
		return false;
ce5aa7d3 sago007 2016-03-13 11:44 221
	}
ce5aa7d3 sago007 2016-03-13 11:44 222
	if (event.type == SDL_CONTROLLERBUTTONDOWN) {
ce5aa7d3 sago007 2016-03-13 11:44 223
		if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT ) {
ce5aa7d3 sago007 2016-03-13 11:44 224
			return true;
ce5aa7d3 sago007 2016-03-13 11:44 225
		}
ce5aa7d3 sago007 2016-03-13 11:44 226
	}
a077dceb sago007 2016-03-19 19:19 227
	if (event.type == SDL_CONTROLLERAXISMOTION  && event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX ) {
a077dceb sago007 2016-03-19 19:19 228
		checkDeadZone(event);
a35ab74b sago007 2016-04-02 10:26 229
		const SDL_ControllerAxisEvent& a = event.caxis;
a077dceb sago007 2016-03-19 19:19 230
		if (getDeadZone(a.which, a.axis)) {
a077dceb sago007 2016-03-19 19:19 231
			if (event.caxis.value > deadZoneLimit) {
a077dceb sago007 2016-03-19 19:19 232
				setDeadZone(a.which,a.axis,false);
a077dceb sago007 2016-03-19 19:19 233
				return true;
a077dceb sago007 2016-03-19 19:19 234
			}
a077dceb sago007 2016-03-19 19:19 235
		}
a077dceb sago007 2016-03-19 19:19 236
	}
ce5aa7d3 sago007 2016-03-13 11:44 237
	return false;
ce5aa7d3 sago007 2016-03-13 11:44 238
}
ce5aa7d3 sago007 2016-03-13 11:44 239
ce5aa7d3 sago007 2016-03-13 11:44 240
bool isPlayerSwitchEvent(int playerNumber, const SDL_Event& event) {
f2dac7e4 sago007 2016-04-09 19:24 241
	if (skipThisPlayer(playerNumber, event)) {
ce5aa7d3 sago007 2016-03-13 11:44 242
		return false;
ce5aa7d3 sago007 2016-03-13 11:44 243
	}
ce5aa7d3 sago007 2016-03-13 11:44 244
	if (event.type == SDL_CONTROLLERBUTTONDOWN) {
ce5aa7d3 sago007 2016-03-13 11:44 245
		if (event.cbutton.button == SDL_CONTROLLER_BUTTON_A || event.cbutton.button == SDL_CONTROLLER_BUTTON_B ) {
ce5aa7d3 sago007 2016-03-13 11:44 246
			return true;
ce5aa7d3 sago007 2016-03-13 11:44 247
		}
ce5aa7d3 sago007 2016-03-13 11:44 248
	}
ce5aa7d3 sago007 2016-03-13 11:44 249
	return false;
ce5aa7d3 sago007 2016-03-13 11:44 250
}
ce5aa7d3 sago007 2016-03-13 11:44 251
ce5aa7d3 sago007 2016-03-13 11:44 252
bool isPlayerPushEvent(int playerNumber, const SDL_Event& event) {
f2dac7e4 sago007 2016-04-09 19:24 253
	if (skipThisPlayer(playerNumber, event)) {
ce5aa7d3 sago007 2016-03-13 11:44 254
		return false;
ce5aa7d3 sago007 2016-03-13 11:44 255
	}
ce5aa7d3 sago007 2016-03-13 11:44 256
	if (event.type == SDL_CONTROLLERBUTTONDOWN) {
ce5aa7d3 sago007 2016-03-13 11:44 257
		if (event.cbutton.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER || event.cbutton.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER ) {
ce5aa7d3 sago007 2016-03-13 11:44 258
			return true;
ce5aa7d3 sago007 2016-03-13 11:44 259
		}
ce5aa7d3 sago007 2016-03-13 11:44 260
	}
ce5aa7d3 sago007 2016-03-13 11:44 261
	return false;
ce5aa7d3 sago007 2016-03-13 11:44 262
}