Skip to content
This repository was archived by the owner on Jun 4, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
08d9dec
Added controller rumble support.
Oct 20, 2022
0610021
Remove explicit fullscreen handling
utopiafallen Oct 22, 2022
627494e
Restore overrideEscFullscreen permission
utopiafallen Oct 22, 2022
b88decd
Fix black screen when starting game stream
utopiafallen Oct 22, 2022
d584fa9
Updated Video Decode Shader with black crush mitigation logic
Oct 23, 2022
291797f
More progress with shaders
Oct 23, 2022
411dcd2
Black crush mitigation disabled now works.
Oct 23, 2022
1a0de99
Hookup black crush mitigation to UI
utopiafallen Oct 23, 2022
392516d
Additional logging for black crush mitigation state
utopiafallen Oct 23, 2022
0cef86a
Tweak luminance scaling to happen in xyY space
utopiafallen Oct 23, 2022
cd01cf7
Validate controllers when handling rumble events from GameStream
utopiafallen Oct 23, 2022
943495f
Black crush tweaks and fix UI state
utopiafallen Oct 28, 2022
a6d6f9e
Fix false colors
utopiafallen Oct 28, 2022
deaa241
Better fix for corrupted colors
utopiafallen Nov 1, 2022
9681890
Plumb moonlight-common-c log messages into the console
cgutman Oct 31, 2022
842e869
Plumb RTSP session URL into LiStartConnection()
cgutman Oct 31, 2022
373524a
Fix passing GFE version to LiStartConnection()
cgutman Oct 31, 2022
795e8fc
Update moonlight-common-c
cgutman Oct 31, 2022
3596b18
Fix typo in error path
cgutman Oct 31, 2022
dfc0ab5
Update moonlight-common-c
cgutman Nov 7, 2022
0dfe4c3
Improvements to haptic error handling
cgutman Nov 7, 2022
f4468cd
Fix mysterious Y offset in input coordinates
cgutman Nov 7, 2022
9f78933
Fix mouse position glitches near the edges in absolute mode
cgutman Nov 7, 2022
b40562b
Fix last frame from previous session displaying when starting a new one
cgutman Nov 7, 2022
acb4c97
Fix garbled audio playing at the start of each stream after the first…
cgutman Nov 7, 2022
26a95d3
Add release build script
cgutman Nov 7, 2022
4a89829
Fix stray ')' introduced when rebasing
utopiafallen Nov 7, 2022
f4eaaa0
Skip black crush mitigation in shader when mitigation is disabled
utopiafallen Jan 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions auddec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
// at a time.

static short s_CircularBuffer[CIRCULAR_BUFFER_SIZE][FRAME_SIZE * MAX_CHANNEL_COUNT];
static int s_ReadIndex = 0;
static int s_WriteIndex = 0;
static int s_ReadIndex;
static int s_WriteIndex;

static void AudioPlayerSampleCallback(void* samples, uint32_t buffer_size, void* data) {
// It should only ask us for complete buffers
Expand All @@ -36,6 +36,9 @@ static void AudioPlayerSampleCallback(void* samples, uint32_t buffer_size, void*

int MoonlightInstance::AudDecInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags) {
int rc;

// Reset the ring buffer to empty
s_ReadIndex = s_WriteIndex = 0;

g_Instance->m_OpusDecoder = opus_multistream_decoder_create(opusConfig->sampleRate,
opusConfig->channelCount,
Expand Down
8 changes: 7 additions & 1 deletion connectionlistener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ void MoonlightInstance::ClDisplayTransientMessage(const char* message) {

void MoonlightInstance::ClLogMessage(const char* format, ...) {
va_list va;
char message[1024];

va_start(va, format);
vfprintf(stderr, format, va);
vsnprintf(message, sizeof(message), format, va);
va_end(va);

pp::Var response(std::string("LogMsg: ") + std::string(message));
g_Instance->PostMessage(response);
}

CONNECTION_LISTENER_CALLBACKS MoonlightInstance::s_ClCallbacks = {
Expand All @@ -56,4 +61,5 @@ CONNECTION_LISTENER_CALLBACKS MoonlightInstance::s_ClCallbacks = {
.connectionStarted = MoonlightInstance::ClConnectionStarted,
.connectionTerminated = MoonlightInstance::ClConnectionTerminated,
.logMessage = MoonlightInstance::ClLogMessage,
.rumble = MoonlightInstance::ClControllerRumble,
};
16 changes: 16 additions & 0 deletions do-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
fail()
{
echo "$1" 1>&2
exit 1
}

git diff-index --quiet HEAD -- || fail "Release builds must not have unstaged changes!"

rm moonlight-chrome.zip
make clean || fail "Clean failed"
make -j$(nproc) || fail "Build failed"


zip moonlight-chrome.zip -r . -i pnacl/Release/moonlight-chrome.* -i manifest.json -i index.html -i LICENSE || fail "Zip failed"
zip moonlight-chrome.zip -r icons || fail "Zip failed"
zip moonlight-chrome.zip -r static || fail "Zip failed"
13 changes: 13 additions & 0 deletions gamepad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include <Limelight.h>

#include <sstream>

static const unsigned short k_StandardGamepadButtonMapping[] = {
A_FLAG, B_FLAG, X_FLAG, Y_FLAG,
LB_FLAG, RB_FLAG,
Expand Down Expand Up @@ -127,3 +129,14 @@ void MoonlightInstance::PollGamepads() {
controllerIndex++;
}
}

void MoonlightInstance::ClControllerRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor)
{
const float weakMagnitude = static_cast<float>(highFreqMotor) / static_cast<float>(UINT16_MAX);
const float strongMagnitude = static_cast<float>(lowFreqMotor) / static_cast<float>(UINT16_MAX);

std::ostringstream ss;
ss << controllerNumber << "," << weakMagnitude << "," << strongMagnitude;
pp::Var response(std::string("controllerRumble: ") + ss.str());
g_Instance->PostMessage(response);
}
10 changes: 10 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@
</div>
</div>

<div class="nav-menu-parent">
<label id="blackCrushMitigateBtn" class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="blackCrushMitigationEnabledSwitch">
<input type="checkbox" id="blackCrushMitigationEnabledSwitch" class="mdl-icon-toggle__input">
<i class="mdl-icon-toggle__label material-icons">exposure</i>
</label>
<div id="blackCrushMitigateTooltip" class="mdl-tooltip" for="blackCrushMitigateBtn">
Attempt to mitigate display black crush by boosting the brightness of very dark colors
</div>
</div>

<div class="nav-menu-parent">
<label id="optimizeGamesBtn" class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="optimizeGamesSwitch">
<input type="checkbox" id="optimizeGamesSwitch" class="mdl-icon-toggle__input">
Expand Down
10 changes: 5 additions & 5 deletions input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ void MoonlightInstance::ReportMouseMovement() {
LiSendMouseMoveEvent(m_MouseDeltaX, m_MouseDeltaY);
m_MouseDeltaX = m_MouseDeltaY = 0;
} else if (m_MousePositionX != 0 || m_MousePositionY != 0) {
LiSendMousePositionEvent(m_MousePositionX, m_MousePositionY, m_PluginRect.width(), m_PluginRect.height());
// Clamp the input coordinates to the plugin area
short x = MIN(MAX(m_MousePositionX, 0), m_PluginRect.width());
short y = MIN(MAX(m_MousePositionY, 0), m_PluginRect.height());
LiSendMousePositionEvent(x, y, m_PluginRect.width(), m_PluginRect.height());
m_MousePositionX = 0;
m_MousePositionY = 0;
}
Expand Down Expand Up @@ -283,11 +286,8 @@ bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
sqrt(pow(m_LastTouchUpPoint.x() - touchPoint.x(), 2) +
pow(m_LastTouchUpPoint.y() - touchPoint.y(), 2)) > TOUCH_DEAD_ZONE_RADIUS) {
// Scale the touch coordinates to the video rect
//
// For some reason, the x coordinate is already relative to the plugin rect,
// while the y coordinate is not. No clue why that is the case but oh well...
short x = MIN(MAX(touchPoint.x(), 0), m_PluginRect.width());
short y = MIN(MAX(touchPoint.y() - m_PluginRect.y(), 0), m_PluginRect.height());
short y = MIN(MAX(touchPoint.y(), 0), m_PluginRect.height());

// Update the mouse position prior to sending the button down
LiSendMousePositionEvent(x, y, m_PluginRect.width(), m_PluginRect.height());
Expand Down
9 changes: 9 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ void* MoonlightInstance::ConnectionThreadFunc(void* context) {
serverInfo.address = me->m_Host.c_str();
serverInfo.serverInfoAppVersion = me->m_AppVersion.c_str();
serverInfo.serverInfoGfeVersion = me->m_GfeVersion.c_str();
serverInfo.rtspSessionUrl = me->m_RtspUrl.c_str();

err = LiStartConnection(&serverInfo,
&me->m_StreamConfig,
Expand Down Expand Up @@ -203,6 +204,8 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args)
std::string mouse_lock = args.Get(7).AsString();
std::string appversion = args.Get(8).AsString();
std::string gfeversion = args.Get(9).AsString();
std::string rtspurl = args.Get(10).AsString();
std::string blackCrushMitigationEnable = args.Get(11).AsString();

pp::Var response("Setting stream width to: " + width);
PostMessage(response);
Expand All @@ -224,6 +227,10 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args)
PostMessage(response);
response = ("Setting mouse lock to: " + mouse_lock);
PostMessage(response);
response = ("Setting RTSP URL to: " + rtspurl);
PostMessage(response);
response = ("Setting black crush mitigation to: " + blackCrushMitigationEnable);
PostMessage(response);

// Populate the stream configuration
LiInitializeStreamConfiguration(&m_StreamConfig);
Expand All @@ -248,7 +255,9 @@ void MoonlightInstance::HandleStartStream(int32_t callbackId, pp::VarArray args)
m_Host = host;
m_AppVersion = appversion;
m_GfeVersion = gfeversion;
m_RtspUrl = rtspurl;
m_MouseLockingFeatureEnabled = stoi(mouse_lock);
m_BlackCrushMitigationEnable = stoi(blackCrushMitigationEnable);

// Initialize the rendering surface before starting the connection
if (InitializeRenderingSurface(m_StreamConfig.width, m_StreamConfig.height)) {
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Moonlight Game Streaming",
"short_name": "Moonlight",
"version": "0.10.21",
"version": "0.10.22",
"description": "Open-source client for NVIDIA GameStream",
"icons": {
"128": "icons/icon128.png",
Expand Down
10 changes: 9 additions & 1 deletion moonlight.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
explicit MoonlightInstance(PP_Instance instance) :
pp::Instance(instance),
pp::MouseLock(this),
m_BlackCrushMitigationEnable(false),
m_curveTexture(-1u),
m_HasNextPicture(false),
m_IsPainting(false),
m_OpusDecoder(NULL),
Expand Down Expand Up @@ -137,6 +139,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
static void ClDisplayMessage(const char* message);
static void ClDisplayTransientMessage(const char* message);
static void ClLogMessage(const char* format, ...);
static void ClControllerRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor);

static Shader CreateProgram(const char* vertexShader, const char* fragmentShader);
static void CreateShader(GLuint program, GLenum type, const char* source, int size);
Expand Down Expand Up @@ -165,6 +168,9 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
void NvHTTPInit(int32_t callbackId, pp::VarArray args);
void NvHTTPRequest(int32_t, int32_t callbackId, pp::VarArray args);

public:
const PPB_Gamepad* m_GamepadApi;

private:
static CONNECTION_LISTENER_CALLBACKS s_ClCallbacks;
static DECODER_RENDERER_CALLBACKS s_DrCallbacks;
Expand All @@ -173,6 +179,7 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
std::string m_Host;
std::string m_AppVersion;
std::string m_GfeVersion;
std::string m_RtspUrl;
bool m_MouseLockingFeatureEnabled;
STREAM_CONFIGURATION m_StreamConfig;
bool m_Running;
Expand All @@ -186,6 +193,8 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
Shader m_RectangleArbShader;
Shader m_ExternalOesShader;
PP_VideoPicture m_NextPicture;
bool m_BlackCrushMitigationEnable;
GLuint m_curveTexture;
bool m_HasNextPicture;
PP_VideoPicture m_CurrentPicture;
bool m_IsPainting;
Expand All @@ -196,7 +205,6 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock {
pp::Audio m_AudioPlayer;

double m_LastPadTimestamps[4];
const PPB_Gamepad* m_GamepadApi;
pp::CompletionCallbackFactory<MoonlightInstance> m_CallbackFactory;
bool m_MouseLocked;
bool m_WaitingForAllModifiersUp;
Expand Down
17 changes: 3 additions & 14 deletions static/js/background.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
const windowId = "1337";
function createWindow(state) {
chrome.app.window.create('index.html', {
state: state,
bounds: {
width: 960,
height: 540
}
}, function(window) {
// workaround:
// state = 'normal' in some cases not work (e.g. starting app from 'chrome://extensions' always open window in fullscreen mode)
// it requires manually restoring window state to 'normal'
if (state == 'normal') {
setTimeout(function() {
window.restore();
}, 1000);
}
state: "normal",
id: windowId,
});
}

Expand Down
Loading