More SDL work

This commit is contained in:
Cameron Gutman 2018-06-23 22:16:59 -07:00
parent 283327dcce
commit 416724f843
11 changed files with 212 additions and 30 deletions

View File

@ -58,7 +58,9 @@ SOURCES += \
gui/popupmanager.cpp \ gui/popupmanager.cpp \
http/identitymanager.cpp \ http/identitymanager.cpp \
http/nvhttp.cpp \ http/nvhttp.cpp \
http/nvpairingmanager.cpp http/nvpairingmanager.cpp \
streaming/video.c \
streaming/connection.cpp
HEADERS += \ HEADERS += \
utils.h \ utils.h \
@ -66,13 +68,14 @@ HEADERS += \
gui/popupmanager.h \ gui/popupmanager.h \
http/identitymanager.h \ http/identitymanager.h \
http/nvhttp.h \ http/nvhttp.h \
http/nvpairingmanager.h http/nvpairingmanager.h \
streaming/streaming.h
FORMS += \ FORMS += \
gui/mainwindow.ui gui/mainwindow.ui
RESOURCES += \ RESOURCES += \
resources.qrc gui/resources.qrc
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../moonlight-common-c/release/ -lmoonlight-common-c win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../moonlight-common-c/release/ -lmoonlight-common-c
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../moonlight-common-c/debug/ -lmoonlight-common-c else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../moonlight-common-c/debug/ -lmoonlight-common-c

View File

@ -20,23 +20,6 @@ MainWindow::MainWindow(QWidget *parent) :
// connect(myButton, &QAbstractButton::clicked, this, &MainWindow::on_actionExit_triggered); // connect(myButton, &QAbstractButton::clicked, this, &MainWindow::on_actionExit_triggered);
} }
void MainWindow::closeEvent(QCloseEvent *event)
{
const QMessageBox::StandardButton ret
= QMessageBox::warning(this, tr("Application"),
tr("something-something-close?"),
QMessageBox::Yes | QMessageBox::No);
switch (ret) {
case QMessageBox::Yes:
event->accept();
break;
case QMessageBox::No:
default:
event->ignore();
break;
}
}
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete ui; delete ui;

View File

@ -16,9 +16,6 @@ public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = 0);
~MainWindow(); ~MainWindow();
protected:
void closeEvent(QCloseEvent *event) override;
private slots: private slots:
void on_actionExit_triggered(); void on_actionExit_triggered();
void on_newHostBtn_clicked(); void on_newHostBtn_clicked();

View File

@ -153,7 +153,7 @@ NvPairingManager::signMessage(QByteArray message)
size_t signatureLength = 0; size_t signatureLength = 0;
EVP_DigestSignFinal(ctx, NULL, &signatureLength); EVP_DigestSignFinal(ctx, NULL, &signatureLength);
QByteArray signature(signatureLength, 0); QByteArray signature((int)signatureLength, 0);
EVP_DigestSignFinal(ctx, reinterpret_cast<unsigned char*>(signature.data()), &signatureLength); EVP_DigestSignFinal(ctx, reinterpret_cast<unsigned char*>(signature.data()), &signatureLength);
EVP_MD_CTX_destroy(ctx); EVP_MD_CTX_destroy(ctx);

View File

@ -1,6 +1,11 @@
#include "gui/mainwindow.h" #include "gui/mainwindow.h"
#include <QApplication> #include <QApplication>
// Don't let SDL hook our main function, since Qt is already
// doing the same thing
#define SDL_MAIN_HANDLED
#include <SDL.h>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// MacOS directive to prevent the menu bar from being merged into the native bar // MacOS directive to prevent the menu bar from being merged into the native bar
@ -15,6 +20,20 @@ int main(int argc, char *argv[])
MainWindow w; MainWindow w;
w.show(); w.show();
return a.exec(); // Ensure that SDL is always initialized since we may need to use it
// for non-streaming purposes (like checking on audio devices)
SDL_SetMainReady();
if (SDL_Init(SDL_INIT_VIDEO |
SDL_INIT_AUDIO |
SDL_INIT_GAMECONTROLLER) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_Init() failed: %s",
SDL_GetError());
}
int err = a.exec();
SDL_Quit();
return err;
} }

View File

@ -128,3 +128,12 @@ void SdlAudioDecodeAndPlaySample(char* sampleData, int sampleLength)
} }
} }
} }
AUDIO_RENDERER_CALLBACKS k_AudioCallbacks = {
SdlAudioInit,
SdlAudioStart,
SdlAudioStop,
SdlAudioCleanup,
SdlAudioDecodeAndPlaySample,
CAPABILITY_DIRECT_SUBMIT
};

View File

@ -0,0 +1,138 @@
#include "streaming.h"
#include <Limelight.h>
#include <SDL.h>
#include <QMessageBox>
bool g_StreamActive;
QMessageBox* g_ProgressBox;
static
void
ClStageStarting(int stage)
{
char buffer[512];
sprintf(buffer, "Starting %s...", LiGetStageName(stage));
g_ProgressBox->setText(buffer);
}
static
void
ClStageFailed(int stage, long errorCode)
{
char buffer[512];
sprintf(buffer, "Failed %s with error: %ld",
LiGetStageName(stage), errorCode);
g_ProgressBox->setText(buffer);
}
static
void
ClConnectionTerminated(long errorCode)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Connection terminated: %ld",
errorCode);
// Push a quit event to the main loop
SDL_Event event;
event.type = SDL_QUIT;
event.quit.timestamp = SDL_GetTicks();
SDL_PushEvent(&event);
}
static
void
ClLogMessage(const char* format, ...)
{
va_list ap;
va_start(ap, format);
SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION,
SDL_LOG_PRIORITY_INFO,
format,
ap);
va_end(ap);
}
int
StartConnection(PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION streamConfig, QMessageBox* progressBox)
{
CONNECTION_LISTENER_CALLBACKS listener;
// Hold onto this for our callbacks
g_ProgressBox = progressBox;
if (streamConfig->audioConfiguration < 0) {
// This signals to us that we should auto-detect
streamConfig->audioConfiguration = SdlDetermineAudioConfiguration();
}
LiInitializeConnectionCallbacks(&listener);
listener.stageStarting = ClStageStarting;
listener.stageFailed = ClStageFailed;
listener.connectionTerminated = ClConnectionTerminated;
listener.logMessage = ClLogMessage;
int err = LiStartConnection(serverInfo, streamConfig, &listener,
&k_VideoCallbacks, &k_AudioCallbacks,
NULL, 0, NULL, 0);
if (err != 0) {
SDL_Quit();
return err;
}
// Before we get into our loop, close the message box used to
// display progress
Q_ASSERT(g_ProgressBox == progressBox);
progressBox->close();
delete progressBox;
g_ProgressBox = nullptr;
// Hijack this thread to be the SDL main thread. We have to do this
// because we want to suspend all Qt processing until the stream is over.
SDL_Event event;
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Quit event received");
goto Exit;
case SDL_KEYUP:
case SDL_KEYDOWN:
SdlHandleKeyEvent(&event.key);
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
SdlHandleMouseButtonEvent(&event.button);
break;
case SDL_MOUSEMOTION:
SdlHandleMouseMotionEvent(&event.motion);
break;
case SDL_MOUSEWHEEL:
SdlHandleMouseWheelEvent(&event.wheel);
break;
case SDL_CONTROLLERAXISMOTION:
SdlHandleControllerAxisEvent(&event.caxis);
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
SdlHandleControllerButtonEvent(&event.cbutton);
break;
case SDL_CONTROLLERDEVICEADDED:
case SDL_CONTROLLERDEVICEREMOVED:
SdlHandleControllerDeviceEvent(&event.cdevice);
break;
}
}
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_WaitEvent() failed: %s",
SDL_GetError());
Exit:
g_StreamActive = false;
LiStopConnection();
return 0;
}

View File

@ -24,11 +24,11 @@ typedef struct _GAMEPAD_STATE {
} GAMEPAD_STATE, *PGAMEPAD_STATE; } GAMEPAD_STATE, *PGAMEPAD_STATE;
#define MAX_GAMEPADS 4 #define MAX_GAMEPADS 4
GAMEPAD_STATE g_GamepadState[MAX_GAMEPADS]; static GAMEPAD_STATE g_GamepadState[MAX_GAMEPADS];
unsigned short g_GamepadMask; static unsigned short g_GamepadMask;
bool g_MultiController; static bool g_MultiController;
const short k_ButtonMap[] = { static const short k_ButtonMap[] = {
A_FLAG, B_FLAG, X_FLAG, Y_FLAG, A_FLAG, B_FLAG, X_FLAG, Y_FLAG,
BACK_FLAG, SPECIAL_FLAG, PLAY_FLAG, BACK_FLAG, SPECIAL_FLAG, PLAY_FLAG,
LS_CLK_FLAG, RS_CLK_FLAG, LS_CLK_FLAG, RS_CLK_FLAG,
@ -320,7 +320,7 @@ static PGAMEPAD_STATE FindStateForGamepad(SDL_JoystickID id)
return NULL; return NULL;
} }
void SendGamepadState(PGAMEPAD_STATE state) static void SendGamepadState(PGAMEPAD_STATE state)
{ {
SDL_assert(g_GamepadMask == 0x1 || g_MultiController); SDL_assert(g_GamepadMask == 0x1 || g_MultiController);
LiSendMultiControllerEvent(state->index, LiSendMultiControllerEvent(state->index,

30
app/streaming/streaming.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <Limelight.h>
#include <SDL.h>
#include <QMessageBox>
#ifdef __cplusplus
extern "C" {
#endif
extern AUDIO_RENDERER_CALLBACKS k_AudioCallbacks;
extern DECODER_RENDERER_CALLBACKS k_VideoCallbacks;
int SdlDetermineAudioConfiguration(void);
void SdlInitializeGamepad(bool multiController);
void SdlHandleControllerDeviceEvent(SDL_ControllerDeviceEvent* event);
void SdlHandleControllerButtonEvent(SDL_ControllerButtonEvent* event);
void SdlHandleControllerAxisEvent(SDL_ControllerAxisEvent* event);
void SdlHandleMouseWheelEvent(SDL_MouseWheelEvent* event);
void SdlHandleMouseMotionEvent(SDL_MouseMotionEvent* event);
void SdlHandleMouseButtonEvent(SDL_MouseButtonEvent* event);
void SdlHandleKeyEvent(SDL_KeyboardEvent* event);
#ifdef __cplusplus
}
#endif
// This function uses C++ linkage
int StartConnection(PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION streamConfig, QMessageBox* progressBox);

3
app/streaming/video.c Normal file
View File

@ -0,0 +1,3 @@
#include <Limelight.h>
DECODER_RENDERER_CALLBACKS k_VideoCallbacks;