Skip to content

Commit

Permalink
Added basic game controller support
Browse files Browse the repository at this point in the history
  • Loading branch information
wivlaro committed Dec 19, 2024
1 parent 6f3d997 commit 3f93afb
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 16 deletions.
9 changes: 4 additions & 5 deletions src/AnimatorAsset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,10 @@ namespace MagnumGame {
Debug{} << "\tMesh" << meshId << ":" << meshName;
auto meshData = importer.mesh(meshId);

for (auto attrId = 0U; attrId < meshData->attributeCount(); attrId++) {
auto attrName = meshData->attributeName(attrId);

// Debug{} << "\tAttribute" << attrId << ":" << attrName << "format=" << meshData->attributeFormat(attrId) << " offset=" << meshData->attributeOffset(attrId) << " stride=" << meshData->attributeStride(attrId) << " arraySize=" << meshData->attributeArraySize(attrId) << " morphTargetId=" << meshData->attributeMorphTargetId(attrId);
}
// for (auto attrId = 0U; attrId < meshData->attributeCount(); attrId++) {
// auto attrName = meshData->attributeName(attrId);
// Debug{} << "\tAttribute" << attrId << ":" << attrName << "format=" << meshData->attributeFormat(attrId) << " offset=" << meshData->attributeOffset(attrId) << " stride=" << meshData->attributeStride(attrId) << " arraySize=" << meshData->attributeArraySize(attrId) << " morphTargetId=" << meshData->attributeMorphTargetId(attrId);
// }

[[maybe_unused]]
auto &mesh = _meshes[meshId] = MeshTools::compile(*meshData);
Expand Down
7 changes: 7 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ add_executable(MagnumGameApp MagnumGameApp.cpp
ShadowCasterShader.h
ShadowCasterShader.cpp
)
if (NOT CORRADE_TARGET_EMSCRIPTEN)
target_sources(MagnumGameApp PRIVATE
SdlGameController.cpp
SdlGameController.h
)
endif()

target_link_libraries(MagnumGameApp PRIVATE
Corrade::Main
Magnum::Application
Expand Down
1 change: 1 addition & 0 deletions src/GameState.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <BulletCollision/CollisionShapes/btSphereShape.h>
#include <Magnum/BulletIntegration/DebugDraw.h>

#include "GameAssets.h"
#include "MagnumGameApp.h"
Expand Down
19 changes: 19 additions & 0 deletions src/MagnumGameApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#include "GameState.h"
#include "UserInterface.h"

#ifdef MAGNUMGAME_SDL
#include <SDL2/SDL.h>
#include "SdlGameController.h"
#endif

#ifdef BT_USE_DOUBLE_PRECISION
#error sorry, this example does not support Bullet with double precision enabled
Expand Down Expand Up @@ -125,6 +129,11 @@ namespace MagnumGame {
setMinimalLoopPeriod(8.0_msec);
#endif
_timeline.start();

#ifndef CORRADE_TARGET_EMSCRIPTEN
SDL_Init(SDL_INIT_GAMECONTROLLER);
_gameController.emplace(_gameState);
#endif
}

bool MagnumGameApp::isPlaying() {
Expand All @@ -148,6 +157,14 @@ namespace MagnumGame {
.bind();

if (isPlaying()) {

#ifdef MAGNUMGAME_SDL
auto cameraControl = _gameController->getCameraDirectionalControlVector();
if (!cameraControl.isZero()) {
_gameState->getCamera()->rotateBy(cameraControl.x() * 90.0_degf * _timeline.previousFrameDuration(), cameraControl.y() * -90.0_degf * _timeline.previousFrameDuration());
}
#endif

_gameState->setControl(getPlayerControlVector());
_gameState->update();
updateStatusText();
Expand Down Expand Up @@ -207,6 +224,8 @@ namespace MagnumGame {

CHECK_GL_ERROR();
}


}

MAGNUM_APPLICATION_MAIN(MagnumGame::MagnumGameApp)
17 changes: 10 additions & 7 deletions src/MagnumGameApp.h
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
#pragma once
#include <Magnum/GL/Mesh.h>

#ifndef CORRADE_TARGET_EMSCRIPTEN
#include <Magnum/Platform/Sdl2Application.h>
#else
#include <Magnum/Platform/EmscriptenApplication.h>
#endif

#include <map>
#include <Corrade/Containers/StridedArrayView.h>
#include <unordered_map>
#include <Magnum/GL/Mesh.h>
#include <Corrade/PluginManager/Manager.h>
#include <Magnum/Timeline.h>
#include <Magnum/BulletIntegration/DebugDraw.h>
#include <Magnum/DebugTools/ResourceManager.h>
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/GL/Renderbuffer.h>
#include <Magnum/SceneGraph/FeatureGroup.h>
#include <Magnum/Text/DistanceFieldGlyphCache.h>
#include <Magnum/Shaders/DistanceFieldVectorGL.h>

#include "Animator.h"
#include "RigidBody.h"
#include "CameraController.h"
#include "DebugLines.h"
#include "MagnumGameCommon.h"

namespace MagnumGame {
class UIText;
Expand All @@ -34,6 +31,7 @@ namespace MagnumGame {
class GameAssets;
class Animator;
struct AnimatorAsset;
class SdlGameController;

class MagnumGameApp : public Platform::Application {
public:
Expand Down Expand Up @@ -64,8 +62,9 @@ namespace MagnumGame {
void pointerMoveEvent(PointerMoveEvent &event) override;
void scrollEvent(ScrollEvent &event) override;

#ifdef MAGNUM_SDL2APPLICATION_MAIN
#ifdef MAGNUMGAME_SDL
void anyEvent(SDL_Event &event) override;

#endif


Expand Down Expand Up @@ -96,6 +95,10 @@ namespace MagnumGame {
Containers::Pointer<DebugLines> _debugLines;
Containers::Pointer<Tweakables> _tweakables;

#ifdef MAGNUMGAME_SDL
Containers::Pointer<SdlGameController> _gameController;
#endif

int _controllerKeysHeld;
std::unordered_map<Long,Vector2> _pointerPressLocations{};

Expand Down
23 changes: 21 additions & 2 deletions src/MagnumGameApp_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
#include <Magnum/GL/PixelFormat.h>
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/Image.h>
#ifdef MAGNUM_SDL2APPLICATION_MAIN
#ifdef MAGNUMGAME_SDL
#include <SDL_events.h>
#include "SdlGameController.h"
#endif

#include "GameState.h"
Expand Down Expand Up @@ -38,10 +39,21 @@ namespace MagnumGame {


Vector2 MagnumGameApp::getPlayerControlVector() const {
return {
Vector2 control{
((_controllerKeysHeld&KEY_RIGHT)?1.0f:0.0f) - ((_controllerKeysHeld&KEY_LEFT)?1.0f:0.0f),
((_controllerKeysHeld&KEY_FORWARD)?1.0f:0.0f) - ((_controllerKeysHeld&KEY_BACKWARD)?1.0f:0.0f),
};

#ifdef MAGNUMGAME_SDL
if (_gameController) {
auto gameControllerVector = _gameController->getPlayerDirectionalControlVector();
if (!gameControllerVector.isZero()) {
control = gameControllerVector;
}
}
#endif

return control;
}


Expand Down Expand Up @@ -166,7 +178,14 @@ namespace MagnumGame {
void MagnumGameApp::anyEvent(SDL_Event &event) {
if (event.type == SDL_WINDOWEVENT_FOCUS_LOST) {
_controllerKeysHeld = 0;
return ;
}
if (_gameController) {
if (_gameController->handleEvent(event)) {
return;
}
}
Debug{} << "Unhandled SDL event" << event.type;
}
#endif
}
7 changes: 7 additions & 0 deletions src/MagnumGameCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

#include <Magnum/GL/Renderer.h>
#include <Magnum/SceneGraph/MatrixTransformation3D.h>

#ifndef CORRADE_TARGET_EMSCRIPTEN
#define MAGNUMGAME_SDL
#else
#define MAGNUMGAME_EMSCRIPTEN
#endif

using namespace Magnum;
using namespace Magnum::Math::Literals;

Expand Down
7 changes: 5 additions & 2 deletions src/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Created by Bill Robinson on 15/07/2024.
//

#include <vector>
#include <Magnum/BulletIntegration/Integration.h>
#include "Player.h"

#include "OnGroundQuery.h"
Expand Down Expand Up @@ -73,7 +73,10 @@ namespace MagnumGame {
if (!controlVector.isZero()) {
cameraControlVector = cameraObjectMatrix.transformVector({ controlVector.x(), 0, -controlVector.y() });
cameraControlVector.y() = 0;
cameraControlVector = cameraControlVector.normalized();
auto vectorLength = cameraControlVector.length();
if (vectorLength > 1) {
cameraControlVector /= vectorLength;
}
}
else {
cameraControlVector = {};
Expand Down
87 changes: 87 additions & 0 deletions src/SdlGameController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//
// Created by Bill Robinson on 19/12/2024.
//

#include "SdlGameController.h"
#include "GameState.h"
#include "Player.h"

namespace MagnumGame {
static SDL_GameController *findController() {
for (int i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
return SDL_GameControllerOpen(i);
}
}

return nullptr;
}

SdlGameController::SdlGameController(Containers::Pointer<GameState> &gameState)
: _controller(findController()),
_gameState(gameState) {
}

SdlGameController::~SdlGameController() {
if (_controller) {
SDL_GameControllerClose(_controller);
}
}

Vector2 SdlGameController::readAxisVector(::SDL_GameControllerAxis xAxis, ::SDL_GameControllerAxis yAxis) const {
Vector2 input{
static_cast<float>(SDL_GameControllerGetAxis(_controller, xAxis)) / (1 << 15),
static_cast<float>(SDL_GameControllerGetAxis(_controller, yAxis)) / (1 << 15)
};

if (abs(input.x()) < JoystickDeadzone) {
input.x() = 0;
}
if (abs(input.y()) < JoystickDeadzone) {
input.y() = 0;
}
return input;
}

Vector2 SdlGameController::getPlayerDirectionalControlVector() const {
if (_controller) {
auto vector = readAxisVector(SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTY);
vector.y() = -vector.y();
return vector;
}
return {0, 0};
}

Vector2 SdlGameController::getCameraDirectionalControlVector() const {
if (_controller) {
return readAxisVector(SDL_CONTROLLER_AXIS_RIGHTX, SDL_CONTROLLER_AXIS_RIGHTY);
}
return {0, 0};
}


bool SdlGameController::handleEvent(const SDL_Event &event) {
switch (event.type) {
case SDL_CONTROLLERDEVICEADDED:
if (!_controller) {
_controller = SDL_GameControllerOpen(event.cdevice.which);
return true;
}
break;
case SDL_CONTROLLERDEVICEREMOVED:
if (_controller && event.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(_controller))) {
SDL_GameControllerClose(_controller);
_controller = findController();
return true;
}
break;
case SDL_CONTROLLERBUTTONDOWN:
if (event.cbutton.button == SDL_CONTROLLER_BUTTON_A) {
_gameState->getPlayer()->tryJump();
return true;
}
break;
}
return false;
}
}
37 changes: 37 additions & 0 deletions src/SdlGameController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <SDL_events.h>

#include "MagnumGameCommon.h"
#include <Magnum/Math/Vector2.h>
#include <SDL2/SDL_gamecontroller.h>

namespace MagnumGame {

class GameState;


class SdlGameController {
public:
explicit SdlGameController(Containers::Pointer<GameState>& gameState);
~SdlGameController();

Vector2 readAxisVector(SDL_GameControllerAxis xAxis, SDL_GameControllerAxis yAxis) const;

Vector2 getPlayerDirectionalControlVector() const;

Vector2 getCameraDirectionalControlVector() const;

bool handleEvent(const SDL_Event &event);

static inline float JoystickDeadzone = 0.05f;

private:
SDL_GameController* _controller;
Containers::Pointer<GameState>& _gameState;
};

}



0 comments on commit 3f93afb

Please sign in to comment.