diff --git a/Makefile b/Makefile
index cfb0362..5094d07 100755
--- a/Makefile
+++ b/Makefile
@@ -197,7 +197,7 @@ CXX_SOURCES = $(MOONLIGHT_LIBRETRO_CXX_SOURCES) $(NANOGUI_CXX_SOURCES)
OBJECTS := $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
DEFINES += -DNANOGUI_USE_OPENGL -DNVG_STB_IMAGE_IMPLEMENTATION -DNANOGUI_NO_GLFW \
- -DHAS_SOCKLEN_T -DHAS_POLL -DHAS_FCNTL -D_GNU_SOURCE
+ -DHAS_SOCKLEN_T -DHAS_POLL -DHAS_FCNTL -D_GNU_SOURCE -D__LIBRETRO__
CFLAGS += -Wall -pedantic $(fpic) -std=gnu11 $(DEFINES)
CXXFLAGS += -std=gnu++17 -fno-permissive $(DEFINES)
diff --git a/moonlight.xcodeproj/project.pbxproj b/moonlight.xcodeproj/project.pbxproj
index ca860e7..a50f54e 100644
--- a/moonlight.xcodeproj/project.pbxproj
+++ b/moonlight.xcodeproj/project.pbxproj
@@ -560,6 +560,7 @@
3652F046245C292B001FABF3 /* src */ = {
isa = PBXGroup;
children = (
+ 3652F04E245C292B001FABF3 /* Limelight.h */,
3652F047245C292B001FABF3 /* PlatformThreads.h */,
3652F048245C292B001FABF3 /* Input.h */,
3652F049245C292B001FABF3 /* ControlStream.c */,
@@ -567,7 +568,6 @@
3652F04B245C292B001FABF3 /* Rtsp.h */,
3652F04C245C292B001FABF3 /* SimpleStun.c */,
3652F04D245C292B001FABF3 /* InputStream.c */,
- 3652F04E245C292B001FABF3 /* Limelight.h */,
3652F04F245C292B001FABF3 /* RtpFecQueue.h */,
3652F050245C292B001FABF3 /* RtspConnection.c */,
3652F051245C292B001FABF3 /* ByteBuffer.h */,
@@ -775,7 +775,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\nmake DEBUG=1\n";
+ shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\n#make DEBUG=1\n";
};
/* End PBXShellScriptBuildPhase section */
diff --git a/moonlight.xcodeproj/xcshareddata/xcschemes/moonlight.xcscheme b/moonlight.xcodeproj/xcshareddata/xcschemes/moonlight.xcscheme
index 56df672..8068702 100644
--- a/moonlight.xcodeproj/xcshareddata/xcschemes/moonlight.xcscheme
+++ b/moonlight.xcodeproj/xcshareddata/xcschemes/moonlight.xcscheme
@@ -41,12 +41,8 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
-
-
-
+
-
+
::failure("Firstly call connect() & pair()..."));
+ return;
+ }
+
+ perform_async([this, address, callback] {
+ int status = gs_quit_app(&m_server_data[address]);
+
+ nanogui::async([this, callback, status] {
+ if (status == GS_OK) {
+ callback(Result::success(true));
+ } else {
+ callback(Result::failure(gs_error != NULL ? gs_error : "Unknown error..."));
+ }
+ });
+ });
+}
diff --git a/src/GameStreamClient.hpp b/src/GameStreamClient.hpp
index 7730cf3..7a71e76 100644
--- a/src/GameStreamClient.hpp
+++ b/src/GameStreamClient.hpp
@@ -74,6 +74,7 @@ public:
void pair(const std::string &address, const std::string &pin, ServerCallback(bool) callback);
void applist(const std::string &address, ServerCallback(PAPP_LIST) callback);
void start(const std::string &address, STREAM_CONFIGURATION config, int app_id, ServerCallback(STREAM_CONFIGURATION) callback);
+ void quit(const std::string &address, ServerCallback(bool) callback);
private:
GameStreamClient() {};
diff --git a/src/moonlight_glfw.cpp b/src/moonlight_glfw.cpp
index 99848e9..7b0fede 100644
--- a/src/moonlight_glfw.cpp
+++ b/src/moonlight_glfw.cpp
@@ -4,7 +4,9 @@
#include "glsym/glsym.h"
#include "Application.hpp"
#include "GameStreamClient.hpp"
+#include "moonlight_libretro_wrapper.h"
#include "gl_render.h"
+#include "libretro.h"
int main(int argc, const char * argv[]) {
glfwInit();
@@ -37,6 +39,15 @@ int main(int argc, const char * argv[]) {
nanogui::scroll_callback_event(x, y);
});
+ glfwSetKeyCallback(window, [](GLFWwindow *w, int key, int scancode, int action, int mods) {
+ if (GLFW_KEY_A <= key && key <= GLFW_KEY_Z) {
+ keyboard_state[RETROK_a + key - GLFW_KEY_A] = action == GLFW_PRESS;
+ }
+
+ keyboard_state[RETROK_w] ? game_pad_state.buttonFlags |= UP_FLAG : game_pad_state.buttonFlags &= ~UP_FLAG;
+ keyboard_state[RETROK_s] ? game_pad_state.buttonFlags |= DOWN_FLAG : game_pad_state.buttonFlags &= ~DOWN_FLAG;
+ });
+
int width, height, fb_width, fb_height;
glfwGetWindowSize(window, &width, &height);
glfwGetFramebufferSize(window, &fb_width, &fb_height);
diff --git a/src/moonlight_libretro.c b/src/moonlight_libretro.c
index 9eaa256..63358cc 100644
--- a/src/moonlight_libretro.c
+++ b/src/moonlight_libretro.c
@@ -38,7 +38,7 @@ static retro_audio_sample_t audio_cb;
retro_audio_sample_batch_t audio_batch_cb;
static retro_environment_t environ_cb;
static retro_input_poll_t input_poll_cb;
-static retro_input_state_t input_state_cb;
+retro_input_state_t input_state_cb;
static retro_log_printf_t log_cb;
void retro_init(void) {
@@ -159,6 +159,8 @@ void retro_run(void) {
keyboard_state[i] = input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, i);
}
+ moonlight_libretro_wrapper_handle_game_pad();
+
// Draw
glBindFramebuffer(RARCH_GL_FRAMEBUFFER, hw_render.get_current_framebuffer());
diff --git a/src/moonlight_libretro_wrapper.cpp b/src/moonlight_libretro_wrapper.cpp
index 7e358ea..7bf1c0e 100644
--- a/src/moonlight_libretro_wrapper.cpp
+++ b/src/moonlight_libretro_wrapper.cpp
@@ -1,10 +1,11 @@
#include "moonlight_libretro_wrapper.h"
+#include "libretro.h"
+#include "gl_render.h"
#include "Application.hpp"
#include "GameStreamClient.hpp"
-#include "gl_render.h"
-#include
-#include "libretro.h"
+#include "Limelight.h"
#include
+#include
static bool moonlight_is_initialized = false;
@@ -12,6 +13,9 @@ static Application* app;
static std::string working_dir;
int16_t keyboard_state[RETROK_LAST];
+struct GamePadState game_pad_state;
+
+extern retro_input_state_t input_state_cb;
void moonlight_libretro_wrapper_preinit() {
OpenSSL_add_all_algorithms();
@@ -32,7 +36,7 @@ void moonlight_libretro_wrapper_init(int width, int height) {
nanogui::init();
app = new Application(Size(width, height), Size(width, height));
- nanogui::setup(1.0 / 60.0 * 1000);
+ //nanogui::setup(1.0 / 60.0 * 1000); no needs anymore?
}
void moonlight_libretro_wrapper_set_working_dir(const char* dir) {
@@ -49,6 +53,43 @@ void moonlight_libretro_wrapper_handle_mouse_button(int button, int action, int
nanogui::mouse_button_callback_event(button, action, modifiers);
}
+static void set_game_pad_state(short flag, int16_t state) {
+ if (state) {
+ game_pad_state.buttonFlags |= flag;
+ } else {
+ game_pad_state.buttonFlags &= ~flag;
+ }
+}
+
+void moonlight_libretro_wrapper_handle_game_pad() {
+ game_pad_state.leftStickX = input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
+ game_pad_state.leftStickY = input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y);
+ game_pad_state.rightStickX = input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X);
+ game_pad_state.rightStickY = input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y);
+
+ #define GAME_PAD_STATE(KEY) \
+ input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, KEY)
+
+ set_game_pad_state(UP_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_UP));
+ set_game_pad_state(DOWN_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_DOWN));
+ set_game_pad_state(LEFT_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_LEFT));
+ set_game_pad_state(RIGHT_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_RIGHT));
+
+ set_game_pad_state(BACK_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_SELECT));
+ set_game_pad_state(PLAY_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_START));
+
+ set_game_pad_state(A_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_A));
+ set_game_pad_state(B_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_B));
+ set_game_pad_state(X_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_X));
+ set_game_pad_state(Y_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_Y));
+
+ set_game_pad_state(LB_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_L));
+ set_game_pad_state(RB_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_R));
+
+ set_game_pad_state(LS_CLK_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_L3));
+ set_game_pad_state(RS_CLK_FLAG, GAME_PAD_STATE(RETRO_DEVICE_ID_JOYPAD_R3));
+}
+
void moonlight_libretro_wrapper_draw() {
nanogui::draw();
}
diff --git a/src/moonlight_libretro_wrapper.h b/src/moonlight_libretro_wrapper.h
index 20ec56e..d8412de 100755
--- a/src/moonlight_libretro_wrapper.h
+++ b/src/moonlight_libretro_wrapper.h
@@ -9,9 +9,22 @@
EXTERN int16_t keyboard_state[];
+struct GamePadState {
+ short buttonFlags;
+ unsigned char leftTrigger;
+ unsigned char rightTrigger;
+ short leftStickX;
+ short leftStickY;
+ short rightStickX;
+ short rightStickY;
+};
+
+EXTERN struct GamePadState game_pad_state;
+
EXTERN void moonlight_libretro_wrapper_preinit();
EXTERN void moonlight_libretro_wrapper_init(int width, int height);
EXTERN void moonlight_libretro_wrapper_set_working_dir(const char* dir);
EXTERN void moonlight_libretro_wrapper_handle_mouse_move(double x, double y);
EXTERN void moonlight_libretro_wrapper_handle_mouse_button(int button, int action, int modifiers);
+EXTERN void moonlight_libretro_wrapper_handle_game_pad();
EXTERN void moonlight_libretro_wrapper_draw();
diff --git a/src/ui/Application.cpp b/src/ui/Application.cpp
index 9534d4e..5d071e9 100644
--- a/src/ui/Application.cpp
+++ b/src/ui/Application.cpp
@@ -21,4 +21,9 @@ void Application::pop_window() {
m_windows.back()->set_visible(true);
perform_layout();
}
+
+ if (m_windows.size() == 1) {
+ auto main = static_cast(m_windows.front());
+ main->reload();
+ }
}
diff --git a/src/ui/windows/AddHostWindow.cpp b/src/ui/windows/AddHostWindow.cpp
index 2298260..7929f12 100644
--- a/src/ui/windows/AddHostWindow.cpp
+++ b/src/ui/windows/AddHostWindow.cpp
@@ -57,7 +57,7 @@ AddHostWindow::AddHostWindow(Widget *parent): ContentWindow(parent, "Add Host")
loader->dispose();
if (result.isSuccess()) {
- m_host_added_callback(result.value());
+ this->pop();
} else {
screen()->add(MessageDialog::Type::Information, "Error", result.error());
}
diff --git a/src/ui/windows/AddHostWindow.hpp b/src/ui/windows/AddHostWindow.hpp
index 9c8ce74..6998e81 100644
--- a/src/ui/windows/AddHostWindow.hpp
+++ b/src/ui/windows/AddHostWindow.hpp
@@ -5,9 +5,4 @@
class AddHostWindow: public ContentWindow {
public:
AddHostWindow(Widget *parent);
-
- void set_host_added_callback(const std::function &callback) { m_host_added_callback = callback; }
-
-private:
- std::function m_host_added_callback;
};
diff --git a/src/ui/windows/MainWindow.cpp b/src/ui/windows/MainWindow.cpp
index 4dbacd0..86c7475 100644
--- a/src/ui/windows/MainWindow.cpp
+++ b/src/ui/windows/MainWindow.cpp
@@ -47,11 +47,7 @@ void MainWindow::reload() {
auto button = container()->add