Skip to content

Commit

Permalink
Add prototype Logitech gaming LCD support
Browse files Browse the repository at this point in the history
  • Loading branch information
HunterZ committed May 3, 2017
1 parent f3ad642 commit fdf4639
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 2 deletions.
19 changes: 19 additions & 0 deletions cmake/Modules/FindLogitechLCDLib.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# - Try to find LogitechLCDLib
# Once done this will define
# LOGITECHLCDLIB_FOUND - System has LogitechLCDLib
# LOGITECHLCDLIB_INCLUDE_DIRS - The LogitechLCDLib include directory
# LOGITECHLCDLIB_LIBRARIES - Link these to use LogitechLCDLib

find_path(LOGITECHLCDLIB_INCLUDE_DIR LogitechLCDLib.h)

find_library(LOGITECHLCDLIB_LIBRARY LogitechLCDLib.lib)

set(LOGITECHLCDLIB_LIBRARIES ${LOGITECHLCDLIB_LIBRARY})
set(LOGITECHLCDLIB_INCLUDE_DIRS ${LOGITECHLCDLIB_INCLUDE_DIR})

include(FindPackageHandleStandardArgs)
# Handle the QUIETLY and REQUIRED arguments and set LOGITECHLCDLIB_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(LOGITECHLCDLIB DEFAULT_MSG LOGITECHLCDLIB_LIBRARY LOGITECHLCDLIB_INCLUDE_DIR)

mark_as_advanced(CLEAR LOGITECHLCDLIB_LIBRARY LOGITECHLCDLIB_INCLUDE_DIR)
9 changes: 9 additions & 0 deletions mt32emu_qt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ option(mt32emu-qt_WITH_QT5 "Prefer Qt5 if Qt4 is also available" TRUE)
option(mt32emu-qt_WITH_ALSA_MIDI_SEQUENCER "Use ALSA MIDI sequencer" ${LINUX_FOUND})
option(mt32emu-qt_USE_PULSEAUDIO_DYNAMIC_LOADING "Load PulseAudio library dynamically" TRUE)
option(mt32emu-qt_WITH_DEBUG_WINCONSOLE "Use console for showing debug output on Windows" FALSE)
option(mt32emu-qt_WITH_LOGITECH_LCD "Enable Logitech gaming LCD support on Windows" FALSE)

add_definitions(-DAPP_VERSION="${mt32emu_qt_VERSION}")
add_definitions(-DBUILD_SYSTEM="${CMAKE_SYSTEM_NAME}")
Expand Down Expand Up @@ -85,6 +86,14 @@ if(CMAKE_SYSTEM_NAME STREQUAL Windows OR CYGWIN)
else()
set(CMAKE_WIN32_EXECUTABLE True)
endif()
if(mt32emu-qt_WITH_LOGITECH_LCD)
find_package(LogitechLCDLib REQUIRED)
if(LOGITECHLCDLIB_FOUND)
add_definitions(-DWITH_LOGITECH_LCD)
include_directories(${LOGITECHLCDLIB_INCLUDE_DIRS})
set(EXT_LIBS ${EXT_LIBS} ${LOGITECHLCDLIB_LIBRARIES})
endif()
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
add_definitions(-DWITH_COREMIDI_DRIVER -DWITH_COREAUDIO_DRIVER)
list(APPEND mt32emu_qt_SOURCES
Expand Down
16 changes: 16 additions & 0 deletions mt32emu_qt/src/Master.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
#include "mididrv/OSSMidiPortDriver.h"
#endif

#ifdef WITH_LOGITECH_LCD
#include "LogitechLCDLib.h"
#endif

static const int ACTUAL_SETTINGS_VERSION = 2;

static Master *instance = NULL;
Expand Down Expand Up @@ -112,6 +116,14 @@ Master::Master() {
qRegisterMetaType<MidiSession *>("MidiSession*");
qRegisterMetaType<MidiSession **>("MidiSession**");
qRegisterMetaType<SynthState>("SynthState");

#ifdef WITH_LOGITECH_LCD
if (LogiLcdInit(L"mt32emu_qt", LOGI_LCD_TYPE_MONO))
{
LogiLcdMonoSetText(0, L"Munt: MT-32 Emulator");
LogiLcdUpdate();
}
#endif
}

Master::~Master() {
Expand Down Expand Up @@ -144,6 +156,10 @@ Master::~Master() {
}

MasterClock::cleanup();

#ifdef WITH_LOGITECH_LCD
LogiLcdShutdown();
#endif
}

void Master::initAudioDrivers() {
Expand Down
79 changes: 77 additions & 2 deletions mt32emu_qt/src/SynthStateMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,52 @@
#include "ui_SynthWidget.h"
#include "font_6x8.h"

#ifdef WITH_LOGITECH_LCD
#include <vector>
#include "LogitechLCDLib.h"
namespace
{
const std::vector<BYTE> logiPixelMatrixEmpty(LOGI_LCD_MONO_HEIGHT * LOGI_LCD_MONO_WIDTH, 0);
std::vector<BYTE> logiPixelMatrix(logiPixelMatrixEmpty);
wchar_t* logiTextTitle(L"Munt: MT-32 Emulator");
wchar_t* logiTextMidiMessageOff(L"MIDI MESSAGE: -");
wchar_t* logiTextMidiMessageOn(L"MIDI MESSAGE: *");
wchar_t* logiTextBlank(L"");

void MuntLogiLcdPaint(const bool clear)
{
if (clear)
{
logiPixelMatrix = logiPixelMatrixEmpty;
LogiLcdMonoSetText(3, logiTextBlank);
}
LogiLcdMonoSetBackground(logiPixelMatrix.data());
LogiLcdMonoSetText(0, logiTextTitle);
LogiLcdMonoSetText(1, logiTextBlank); // this line is for ROM info (TODO)
LogiLcdMonoSetText(2, logiTextBlank); // this line is for MT-32 LCD emu
LogiLcdUpdate();
}

void MuntLogiLcdSetLED(bool enabled)
{
/*
for (std::size_t pixelRow(33); pixelRow < 43; ++pixelRow)
{
for (std::size_t pixelCol(75); pixelCol < 85; ++pixelCol)
{
logiPixelMatrix[pixelRow * LOGI_LCD_MONO_WIDTH + pixelCol] =
(enabled ? 0xff : 0);
}
}
*/
LogiLcdMonoSetText(3, enabled ?
logiTextMidiMessageOn :
logiTextMidiMessageOff);
MuntLogiLcdPaint(false);
}
}
#endif

static const MasterClockNanos LCD_MESSAGE_DISPLAYING_NANOS = 2 * MasterClock::NANOS_PER_SECOND;
static const MasterClockNanos LCD_TIMBRE_NAME_DISPLAYING_NANOS = 1 * MasterClock::NANOS_PER_SECOND;
static const MasterClockNanos MIDI_MESSAGE_LED_MINIMUM_NANOS = 60 * MasterClock::NANOS_PER_MILLISECOND;
Expand Down Expand Up @@ -96,12 +142,18 @@ void SynthStateMonitor::enableMonitor(bool enable) {
} else {
enabled = false;
}
#ifdef WITH_LOGITECH_LCD
MuntLogiLcdPaint(true);
#endif
}

void SynthStateMonitor::handleSynthStateChange(SynthState state) {
enableMonitor(state == SynthState_OPEN);
lcdWidget.reset();
midiMessageLED.setColor(&COLOR_GRAY);
#ifdef WITH_LOGITECH_LCD
MuntLogiLcdPaint(true);
#endif

for (unsigned int i = 0; i < partialCount; i++) {
partialStateLED[i]->setColor(&partialStateColor[PartialState_INACTIVE]);
Expand All @@ -117,6 +169,9 @@ void SynthStateMonitor::handleMIDIMessagePlayed() {
if (ui->synthFrame->isVisible() && synthRoute->getState() == SynthRouteState_OPEN) {
midiMessageLED.setColor(&COLOR_GREEN);
midiMessageLEDStartNanos = MasterClock::getClockNanos();
#ifdef WITH_LOGITECH_LCD
MuntLogiLcdSetLED(true);
#endif
}
}

Expand Down Expand Up @@ -161,8 +216,14 @@ void SynthStateMonitor::handleUpdate() {
if (midiMessageOn) {
midiMessageLED.setColor(&COLOR_GREEN);
midiMessageLEDStartNanos = nanosNow;
#ifdef WITH_LOGITECH_LCD
MuntLogiLcdSetLED(true);
#endif
} else if ((nanosNow - midiMessageLEDStartNanos) > MIDI_MESSAGE_LED_MINIMUM_NANOS) {
midiMessageLED.setColor(&COLOR_GRAY);
#ifdef WITH_LOGITECH_LCD
MuntLogiLcdSetLED(false);
#endif
}
}

Expand Down Expand Up @@ -223,6 +284,9 @@ void LCDWidget::paintEvent(QPaintEvent *) {
QPainter lcdPainter(this);
if (monitor.synthRoute->getState() != SynthRouteState_OPEN) {
lcdPainter.drawPixmap(0, 0, lcdOffBackground);
#ifdef WITH_LOGITECH_LCD
MuntLogiLcdPaint(true);
#endif
return;
}
lcdPainter.drawPixmap(0, 0, lcdOnBackground);
Expand All @@ -233,8 +297,7 @@ void LCDWidget::paintEvent(QPaintEvent *) {
yat = 0;

for (int i = 0; i < 20; i++) {
unsigned char c;
c = 0x20;
unsigned char c(0x20);
if (i < lcdText.size()) {
c = lcdText[i];
}
Expand All @@ -255,10 +318,19 @@ void LCDWidget::paintEvent(QPaintEvent *) {
fval = Font_6x8[c][t];
}
for (int m = 4; m >= 0; --m) {
#ifdef WITH_LOGITECH_LCD
const std::size_t lpmIndex((22 + ((yat-1)/2)) * LOGI_LCD_MONO_WIDTH + (xat/2));
#endif
if ((fval >> m) & 1) {
lcdPainter.fillRect(xat, yat, 2, 2, lcdFgColor);
#ifdef WITH_LOGITECH_LCD
logiPixelMatrix[lpmIndex] = 0xff;
#endif
} else {
lcdPainter.fillRect(xat, yat, 2, 2, lcdBgColor);
#ifdef WITH_LOGITECH_LCD
logiPixelMatrix[lpmIndex] = 0;
#endif
}
xat += 2;
}
Expand All @@ -267,6 +339,9 @@ void LCDWidget::paintEvent(QPaintEvent *) {
}
xstart += 12;
}
#ifdef WITH_LOGITECH_LCD
MuntLogiLcdPaint(false);
#endif
}

void LCDWidget::handleLCDMessageDisplayed(const QString useText) {
Expand Down

0 comments on commit fdf4639

Please sign in to comment.