GRIM/EMI: Add Joystick/gamepad support
This commit is contained in:
parent
c0ccf26b05
commit
3d39e63da7
8 changed files with 198 additions and 9 deletions
48
backends/events/sdl/resvm-sdl-events.cpp
Normal file
48
backends/events/sdl/resvm-sdl-events.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* ResidualVM - A 3D game interpreter
|
||||
*
|
||||
* ResidualVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#if defined(SDL_BACKEND)
|
||||
|
||||
#include "resvm-sdl-events.h"
|
||||
|
||||
bool ResVmSdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
|
||||
event.type = Common::EVENT_JOYBUTTON_DOWN;
|
||||
event.joystick.button = ev.jbutton.button;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResVmSdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
|
||||
event.type = Common::EVENT_JOYBUTTON_UP;
|
||||
event.joystick.button = ev.jbutton.button;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResVmSdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
|
||||
event.type = Common::EVENT_JOYAXIS_MOTION;
|
||||
event.joystick.axis = ev.jaxis.axis;
|
||||
event.joystick.position = ev.jaxis.value;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
38
backends/events/sdl/resvm-sdl-events.h
Normal file
38
backends/events/sdl/resvm-sdl-events.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* ResidualVM - A 3D game interpreter
|
||||
*
|
||||
* ResidualVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKEND_EVENTS_RESVM_SDL
|
||||
#define BACKEND_EVENTS_RESVM_SDL
|
||||
|
||||
#include "sdl-events.h"
|
||||
|
||||
/**
|
||||
* Custom event source for ResidualVM with true joystick support.
|
||||
*/
|
||||
class ResVmSdlEventSource : public SdlEventSource {
|
||||
protected:
|
||||
bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event);
|
||||
bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
|
||||
bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -55,6 +55,7 @@ endif
|
|||
ifdef SDL_BACKEND
|
||||
MODULE_OBJS += \
|
||||
events/sdl/sdl-events.o \
|
||||
events/sdl/resvm-sdl-events.o \
|
||||
graphics/sdl/sdl-graphics.o \
|
||||
graphics/surfacesdl/surfacesdl-graphics.o \
|
||||
mixer/doublebuffersdl/doublebuffersdl-mixer.o \
|
||||
|
|
|
@ -42,8 +42,9 @@
|
|||
#else
|
||||
#include "backends/audiocd/sdl/sdl-audiocd.h"
|
||||
#endif
|
||||
|
||||
#include "backends/events/sdl/sdl-events.h"
|
||||
// ResidualVM:
|
||||
// #include "backends/events/sdl/sdl-events.h"
|
||||
#include "backends/events/sdl/resvm-sdl-events.h"
|
||||
#include "backends/mutex/sdl/sdl-mutex.h"
|
||||
#include "backends/timer/sdl/sdl-timer.h"
|
||||
#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
|
||||
|
@ -156,7 +157,7 @@ void OSystem_SDL::initBackend() {
|
|||
// Create the default event source, in case a custom backend
|
||||
// manager didn't provide one yet.
|
||||
if (_eventSource == 0)
|
||||
_eventSource = new SdlEventSource();
|
||||
_eventSource = new ResVmSdlEventSource(); // ResidualVm: was SdlEventSource
|
||||
|
||||
if (_graphicsManager == 0) {
|
||||
if (_graphicsManager == 0) {
|
||||
|
|
|
@ -87,8 +87,29 @@ enum EventType {
|
|||
,
|
||||
EVENT_VIRTUAL_KEYBOARD = 20
|
||||
#endif
|
||||
/* START of ResidualVM-specific code */
|
||||
,
|
||||
EVENT_JOYAXIS_MOTION = 23,
|
||||
EVENT_JOYBUTTON_DOWN = 24,
|
||||
EVENT_JOYBUTTON_UP = 25
|
||||
};
|
||||
|
||||
const int16 JOYAXIS_MIN = -32768;
|
||||
const int16 JOYAXIS_MAX = 32767;
|
||||
|
||||
/**
|
||||
* Data structure for joystick events
|
||||
*/
|
||||
struct JoystickState {
|
||||
/** The axis for EVENT_JOYAXIS_MOTION events */
|
||||
byte axis;
|
||||
/** The new axis position for EVENT_JOYAXIS_MOTION events */
|
||||
int16 position;
|
||||
/** The button index for EVENT_JOYBUTTON_DOWN/UP events */
|
||||
byte button;
|
||||
};
|
||||
/* END of ResidualVM-specific code */
|
||||
|
||||
typedef uint32 CustomEventType;
|
||||
/**
|
||||
* Data structure for an event. A pointer to an instance of Event
|
||||
|
@ -127,6 +148,14 @@ struct Event {
|
|||
*/
|
||||
Common::Point relMouse;
|
||||
|
||||
/**
|
||||
* Joystick data; only valid for joystick events (EVENT_JOYAXIS_MOTION,
|
||||
* EVENT_JOYBUTTON_DOWN and EVENT_JOYBUTTON_UP).
|
||||
*
|
||||
* This field is ResidualVM specific
|
||||
*/
|
||||
JoystickState joystick;
|
||||
|
||||
Event() : type(EVENT_INVALID), synthetic(false) {
|
||||
#ifdef ENABLE_KEYMAPPER
|
||||
customType = 0;
|
||||
|
|
|
@ -119,6 +119,10 @@ GrimEngine::GrimEngine(OSystem *syst, uint32 gameFlags, GrimGameType gameType, C
|
|||
_controlsEnabled[i] = false;
|
||||
_controlsState[i] = false;
|
||||
}
|
||||
_joyAxisPosition = new float[NUM_JOY_AXES];
|
||||
for (int i = 0; i < NUM_JOY_AXES; i++) {
|
||||
_joyAxisPosition[i] = 0;
|
||||
}
|
||||
_speechMode = TextAndVoice;
|
||||
_textSpeed = 7;
|
||||
_mode = _previousMode = NormalMode;
|
||||
|
@ -171,6 +175,7 @@ GrimEngine::GrimEngine(OSystem *syst, uint32 gameFlags, GrimGameType gameType, C
|
|||
GrimEngine::~GrimEngine() {
|
||||
delete[] _controlsEnabled;
|
||||
delete[] _controlsState;
|
||||
delete[] _joyAxisPosition;
|
||||
|
||||
clearPools();
|
||||
|
||||
|
@ -816,6 +821,10 @@ void GrimEngine::mainLoop() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (type == Common::EVENT_JOYAXIS_MOTION)
|
||||
handleJoyAxis(event.joystick.axis, event.joystick.position);
|
||||
if (type == Common::EVENT_JOYBUTTON_DOWN || type == Common::EVENT_JOYBUTTON_UP)
|
||||
handleJoyButton(type, event.joystick.button);
|
||||
}
|
||||
|
||||
if (_mode != PauseMode) {
|
||||
|
@ -1250,6 +1259,10 @@ void GrimEngine::setTextSpeed(int speed) {
|
|||
}
|
||||
|
||||
float GrimEngine::getControlAxis(int num) {
|
||||
int idx = num - KEYCODE_AXIS_JOY1_X;
|
||||
if (idx >= 0 && idx < NUM_JOY_AXES) {
|
||||
return _joyAxisPosition[idx];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,6 +193,8 @@ protected:
|
|||
|
||||
void handleControls(Common::EventType type, const Common::KeyState &key);
|
||||
void handleChars(Common::EventType type, const Common::KeyState &key);
|
||||
void handleJoyAxis(byte axis, int16 position);
|
||||
void handleJoyButton(Common::EventType type, byte button);
|
||||
void handleExit();
|
||||
void handlePause();
|
||||
void handleUserPaint();
|
||||
|
@ -243,6 +245,7 @@ protected:
|
|||
|
||||
bool *_controlsEnabled;
|
||||
bool *_controlsState;
|
||||
float *_joyAxisPosition;
|
||||
|
||||
bool _changeHardwareState;
|
||||
bool _changeFullscreenState;
|
||||
|
@ -336,6 +339,9 @@ enum {
|
|||
KEYCODE_EXTRA_LAST
|
||||
};
|
||||
|
||||
#define NUM_JOY_AXES (KEYCODE_AXIS_JOY1_V - KEYCODE_AXIS_JOY1_X + 1)
|
||||
#define NUM_JOY_BUTTONS (KEYCODE_JOY1_B20 - KEYCODE_JOY1_B1 + 1)
|
||||
|
||||
extern const ControlDescriptor controls[];
|
||||
|
||||
} // end of namespace Grim
|
||||
|
|
|
@ -203,7 +203,7 @@ const ControlDescriptor controls[] = {
|
|||
{ "KEY_JOY2_B8", KEYCODE_JOY2_B8 },
|
||||
{ "KEY_JOY2_B9", KEYCODE_JOY2_B9 },
|
||||
{ "KEY_JOY2_B10", KEYCODE_JOY2_B10 },
|
||||
{ "KEY_JOY2_HLEFT", KEYCODE_JOY1_HLEFT },
|
||||
{ "KEY_JOY2_HLEFT", KEYCODE_JOY2_HLEFT },
|
||||
{ "KEY_JOY2_HUP", KEYCODE_JOY2_HUP },
|
||||
{ "KEY_JOY2_HRIGHT", KEYCODE_JOY2_HRIGHT },
|
||||
{ "KEY_JOY2_HDOWN", KEYCODE_JOY2_HDOWN },
|
||||
|
@ -262,8 +262,8 @@ const ControlDescriptor controls[] = {
|
|||
{ "KEY_JOY2_LMUSHROOM", KEYCODE_JOY2_B15 },
|
||||
{ "KEY_JOY2_RMUSHROOM", KEYCODE_JOY2_B16 },
|
||||
|
||||
// tell EMI there is no joystick selected
|
||||
{ "joy_selected", -1 },
|
||||
// tell EMI that the joystick can be used
|
||||
{ "joy_selected", 1 },
|
||||
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
@ -316,9 +316,6 @@ void GrimEngine::handleControls(Common::EventType operation, const Common::KeySt
|
|||
if (!LuaBase::instance()->callback("buttonHandler", objects)) {
|
||||
error("handleControls: invalid keys handler");
|
||||
}
|
||||
// if (!LuaBase::instance()->callback("axisHandler", objects)) {
|
||||
// error("handleControls: invalid joystick handler");
|
||||
// }
|
||||
|
||||
if (operation == Common::EVENT_KEYDOWN)
|
||||
_controlsState[key.keycode] = true;
|
||||
|
@ -326,5 +323,61 @@ void GrimEngine::handleControls(Common::EventType operation, const Common::KeySt
|
|||
_controlsState[key.keycode] = false;
|
||||
}
|
||||
|
||||
void GrimEngine::handleJoyAxis(byte axis, int16 position) {
|
||||
if (axis > NUM_JOY_AXES)
|
||||
return;
|
||||
|
||||
int keycode = KEYCODE_AXIS_JOY1_X + axis;
|
||||
if (!_controlsEnabled[keycode])
|
||||
return;
|
||||
|
||||
float fpos;
|
||||
if (position < Common::JOYAXIS_MIN / 2) {
|
||||
fpos = -1;
|
||||
} else if (position > Common::JOYAXIS_MAX / 2) {
|
||||
fpos = 1;
|
||||
} else {
|
||||
fpos = 0;
|
||||
}
|
||||
|
||||
if (abs(fpos - _joyAxisPosition[axis]) > 0.1) {
|
||||
LuaObjects objects;
|
||||
objects.add(keycode);
|
||||
objects.add(fpos);
|
||||
if (!LuaBase::instance()->callback("axisHandler", objects)) {
|
||||
error("handleJoyAxis: invalid joystick handler");
|
||||
}
|
||||
_joyAxisPosition[axis] = fpos;
|
||||
}
|
||||
}
|
||||
|
||||
void GrimEngine::handleJoyButton(Common::EventType operation, byte button) {
|
||||
if (button > NUM_JOY_BUTTONS)
|
||||
return;
|
||||
|
||||
int keycode = KEYCODE_JOY1_B1 + button;
|
||||
if (!_controlsEnabled[keycode])
|
||||
return;
|
||||
|
||||
LuaObjects objects;
|
||||
objects.add(keycode);
|
||||
if (operation == Common::EVENT_JOYBUTTON_DOWN) {
|
||||
objects.add(1);
|
||||
objects.add(1);
|
||||
} else if (operation == Common::EVENT_JOYBUTTON_UP) {
|
||||
objects.addNil();
|
||||
objects.add(0);
|
||||
}
|
||||
objects.add(0);
|
||||
if (!LuaBase::instance()->callback("buttonHandler", objects)) {
|
||||
error("handleControls: invalid keys handler");
|
||||
}
|
||||
|
||||
if (operation == Common::EVENT_JOYBUTTON_DOWN)
|
||||
_controlsState[keycode] = true;
|
||||
else if (operation == Common::EVENT_JOYBUTTON_UP)
|
||||
_controlsState[keycode] = false;
|
||||
}
|
||||
|
||||
} // end of namespace Grim
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue