|
From: Lasse Kärkkäi. <tr...@us...> - 2009-10-16 16:11:49
|
Module: performous Branch: master Commit: 4ba2bc52b6d6f04f760d243ac542944ebb9e35ac Author: Lasse Karkkainen <tro...@tr...> Date: Fri Oct 16 19:11:34 2009 +0300 WIP MIDI drum support --- cmake/Modules/FindPortMidi.cmake | 21 +++++++++++++++++++++ data/performous.xml | 6 ++++++ game/CMakeLists.txt | 7 +++++++ game/joystick.cc | 24 ++++++++++++++++++++++++ game/joystick.hh | 20 ++++++++++++++++++-- game/portmidi.hh | 29 +++++++++++++++++++++++++++++ 6 files changed, 105 insertions(+), 2 deletions(-) diff --git a/cmake/Modules/FindPortMidi.cmake b/cmake/Modules/FindPortMidi.cmake new file mode 100644 index 0000000..f5126d8 --- /dev/null +++ b/cmake/Modules/FindPortMidi.cmake @@ -0,0 +1,21 @@ +# - Try to find PortMidi +# Once done, this will define +# +# PortMidi_FOUND - system has PortMidi +# PortMidi_INCLUDE_DIRS - the PortMidi include directories +# PortMidi_LIBRARIES - link these to use PortMidi +# PortMidi_VERSION - detected version of PortMidi +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +find_path(PortMidi_INCLUDE_DIR NAMES portmidi.h) +find_library(PortMidi_LIBRARY NAMES portmidi) +find_library(PortTime_LIBRARY NAMES porttime) + +set(PortMidi_PROCESS_INCLUDES PortMidi_INCLUDE_DIR) +set(PortMidi_PROCESS_LIBS PortMidi_LIBRARY PortTime_LIBRARY) +libfind_process(PortMidi) + diff --git a/data/performous.xml b/data/performous.xml index e0577a8..aa7cca9 100644 --- a/data/performous.xml +++ b/data/performous.xml @@ -63,6 +63,12 @@ <long>Enable keyboard as guitar (Frets on Fire mode).</long> </locale> </entry> + <entry name="game/midi_drums" type="string"> + <locale name="C"> + <short>MIDI drum mapping</short> + <long>Mapping of hardware MIDI device: devID:kick,pad1,pad2,pad3,pad4</long> + </locale> + </entry> <entry name="game/instruments" type="string_list"> <!-- Should be SDL_ID:{GUITAR_GUITARHERO|GUITAR_ROCKBAND|DRUMS_GUITARHERO|DRUMS_ROCKBAND} example: diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index e4e484a..4bca0db 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -19,6 +19,13 @@ foreach(lib SDL PangoCairo LibRSVG LibXML++ Magick++ GLEW AVFormat SWScale OpenG add_definitions(${${lib}_DEFINITIONS}) endforeach(lib) +find_package(PortMidi) +if(PortMidi_FOUND) + include_directories(PortMidi_INCLUDE_DIRS) + set(LIBS ${LIBS} ${PortMidi_LIBRARIES}) + add_definitions("-DHAVE_PORTMIDI") +endif(PortMidi_FOUND) + # Set default compile flags for GCC if(CMAKE_COMPILER_IS_GNUCXX) message(STATUS "GCC detected, adding compile flags") diff --git a/game/joystick.cc b/game/joystick.cc index 17f6fb8..d79396e 100644 --- a/game/joystick.cc +++ b/game/joystick.cc @@ -3,6 +3,26 @@ #include <boost/lexical_cast.hpp> +#ifdef HAVE_PORTMIDI +input::MidiDrums::MidiDrums(int devId): stream(devId) { + Private::devices[0x8000] = Private::InputDevPrivate(Private::DRUMS_MIDI); + event.type = Event::PRESS; + for (unsigned int i = 0; i < BUTTONS; ++i) event.pressed[i] = false; +} + +void input::MidiDrums::process() { + PmEvent ev; + while (Pm_Read(stream, &ev, 1) == 1) { + if ((ev.message & 0xFF) != 0x99) continue; + unsigned char ch = ev.message >> 8; + //unsigned char vel = ev.message >> 16; + event.button = ch % 5; + event.time = now(); + Private::devices[0x8000].addEvent(event); + } +} +#endif + static const unsigned SDL_BUTTONS = 6; int buttonFromSDL(input::Private::Type _type, unsigned int _sdl_button) { @@ -110,6 +130,9 @@ void input::SDL::init() { case input::Private::DRUMS_RB: std::cout << " Detected as: RockBand Drums (forced)" << std::endl; break; + case input::Private::DRUMS_MIDI: + std::cout << " Detected as: MIDI Drums (forced)" << std::endl; + break; } input::Private::devices[i] = input::Private::InputDevPrivate(forced_type[i]); } else if( name.find("Guitar Hero3") != std::string::npos ) { @@ -292,3 +315,4 @@ bool input::SDL::pushEvent(SDL_Event _e) { } return true; } + diff --git a/game/joystick.hh b/game/joystick.hh index d4ca2df..7499232 100644 --- a/game/joystick.hh +++ b/game/joystick.hh @@ -11,6 +11,10 @@ #include "xtime.hh" #include "configuration.hh" +#ifdef HAVE_PORTMIDI +#include "portmidi.hh" +#endif + namespace input { enum DevType { GUITAR, DRUMS }; @@ -26,7 +30,7 @@ namespace input { }; namespace Private { - enum Type {GUITAR_RB, DRUMS_RB, GUITAR_GH, DRUMS_GH}; + enum Type {GUITAR_RB, DRUMS_RB, GUITAR_GH, DRUMS_GH, DRUMS_MIDI}; static unsigned int KEYBOARD_ID = UINT_MAX; class InputDevPrivate { public: @@ -73,7 +77,7 @@ namespace input { (m_type == input::Private::GUITAR_GH || m_type == input::Private::GUITAR_RB) ) { return true; } else if( _type == input::DRUMS && - (m_type == input::Private::DRUMS_GH || m_type == input::Private::DRUMS_RB) ) { + (m_type == input::Private::DRUMS_GH || m_type == input::Private::DRUMS_RB || m_type == input::Private::DRUMS_MIDI) ) { return true; } else { return false; @@ -135,5 +139,17 @@ namespace input { // Returns true if event is taken, feed an InputDev by transforming SDL_Event into Event bool pushEvent(SDL_Event); } + +#ifdef HAVE_PORTMIDI + class MidiDrums { + public: + MidiDrums(int devId); + void process(); + private: + pm::Input stream; + Event event; + }; +#endif + }; diff --git a/game/portmidi.hh b/game/portmidi.hh new file mode 100644 index 0000000..848c0f2 --- /dev/null +++ b/game/portmidi.hh @@ -0,0 +1,29 @@ +#pragma once + +#include <portmidi.h> +#include <stdexcept> + +namespace pm { + struct Initialize { + Initialize() { Pm_Initialize(); } + ~Initialize() { Pm_Terminate(); } + }; + class Stream { + public: + operator PortMidiStream*() { return m_handle; } + + protected: + PortMidiStream* m_handle; + Stream(): m_handle() {} + ~Stream() { if (m_handle) Pm_Close(m_handle); } + }; + + class Input: public Stream { + public: + Input(int devId) { + PmError err = Pm_OpenInput(&m_handle, devId, 0, 1024, 0, 0); + if (err) throw std::runtime_error("Pm_OpenInput failed"); + } + }; +} + |