Skip to content

Commit 87e370b

Browse files
milkdropperMischa Spiegelmock
authored andcommitted
SDL changes (#305)
* Decrease default meshx to 128 to avoid low FPS. * Add feature for CTRL+F to move projectM to the next monitor. * Added feature CTRL+S to stretch projectM across multiple windows. * Revert "Added feature CTRL+S to stretch projectM across multiple windows." This reverts commit 2c0c980. * Feature: CTRL+S stretches projectM across multiple monitors.
1 parent 260a028 commit 87e370b

File tree

3 files changed

+116
-6
lines changed

3 files changed

+116
-6
lines changed

src/projectM-sdl/pmSDL.cpp

Lines changed: 113 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,93 @@ void projectMSDL::maximize() {
151151
resize(dm.w, dm.h);
152152
}
153153

154+
/* Stretch projectM across multiple monitors */
155+
void projectMSDL::stretchMonitors()
156+
{
157+
int displayCount = SDL_GetNumVideoDisplays();
158+
if (displayCount >= 2)
159+
{
160+
std::vector<SDL_Rect> displayBounds;
161+
for (int i = 0; i < displayCount; i++)
162+
{
163+
displayBounds.push_back(SDL_Rect());
164+
SDL_GetDisplayBounds(i, &displayBounds.back());
165+
}
166+
167+
int furthestX = 0;
168+
int furthestY = 0;
169+
int widest = 0;
170+
int highest = 0;
171+
int spanX = 0;
172+
int spanY = 0;
173+
int spanWidth = 0;
174+
int spanHeight = 0;
175+
176+
bool horizontal = true;
177+
bool vertical = true;
178+
179+
for (int i = 0; i < displayCount; i++)
180+
{
181+
if (displayBounds[0].x != displayBounds[i].x) vertical = false;
182+
if (displayBounds[0].y != displayBounds[i].y) horizontal = false;
183+
}
184+
185+
if (!vertical && !horizontal)
186+
{
187+
// If multiple montors are not perfectly aligned it's a bit of work to get the correct x,y and
188+
// dimensions But in my testing on Windows 10 even with the screen did not render correctly.
189+
// @todo more testing and make it work.
190+
SDL_Log(
191+
"SDL currently only supports multiple monitors that are aligned evenly in a vertical or "
192+
"horizontal position.");
193+
}
194+
else
195+
{
196+
for (int i = 0; i < displayCount; i++)
197+
{
198+
if (displayBounds[i].x < furthestX) spanX = displayBounds[i].x; // X furthest left device
199+
if (displayBounds[i].y < furthestY) spanY = displayBounds[i].y; // Y highest device
200+
if (displayBounds[i].h > highest) highest = displayBounds[i].h; // highest resolution Height
201+
if (displayBounds[i].h > widest) widest = displayBounds[i].w; // highest resolution Width
202+
if (horizontal) // perfectly aligned horizonal monitors.
203+
{
204+
spanHeight = highest;
205+
spanWidth = spanWidth + displayBounds[i].w;
206+
}
207+
else if (vertical) // perfectly aligned vertical monitors.
208+
{
209+
spanHeight = spanHeight + displayBounds[i].h;
210+
spanWidth = widest;
211+
}
212+
}
213+
SDL_SetWindowPosition(win, spanX, spanY);
214+
SDL_SetWindowSize(win, spanWidth, spanHeight);
215+
}
216+
}
217+
}
218+
219+
/* Moves projectM to the next monitor */
220+
void projectMSDL::nextMonitor()
221+
{
222+
int displayCount = SDL_GetNumVideoDisplays();
223+
int currentWindowIndex = SDL_GetWindowDisplayIndex(win);
224+
if (displayCount >= 2)
225+
{
226+
std::vector<SDL_Rect> displayBounds;
227+
int nextWindow = currentWindowIndex + 1;
228+
if (nextWindow > displayCount) nextWindow = 0;
229+
230+
for (int i = 0; i < displayCount; i++)
231+
{
232+
displayBounds.push_back(SDL_Rect());
233+
SDL_GetDisplayBounds(i, &displayBounds.back());
234+
}
235+
SDL_SetWindowPosition(win, displayBounds[nextWindow].x, displayBounds[nextWindow].y);
236+
SDL_SetWindowSize(win, displayBounds[nextWindow].w, displayBounds[nextWindow].h);
237+
maximize();
238+
}
239+
}
240+
154241
void projectMSDL::toggleFullScreen() {
155242
maximize();
156243
if (isFullScreen) {
@@ -180,8 +267,26 @@ void projectMSDL::keyHandler(SDL_Event *sdl_evt) {
180267
return;
181268
}
182269
break;
183-
184-
270+
case SDLK_s:
271+
if (sdl_mod & KMOD_LGUI || sdl_mod & KMOD_RGUI || sdl_mod & KMOD_LCTRL)
272+
{
273+
// command-s: [s]tretch monitors
274+
// Stereo requires fullscreen
275+
#if !STEREOSCOPIC_SBS
276+
stretchMonitors();
277+
#endif
278+
return; // handled
279+
}
280+
case SDLK_m:
281+
if (sdl_mod & KMOD_LGUI || sdl_mod & KMOD_RGUI || sdl_mod & KMOD_LCTRL)
282+
{
283+
// command-m: change [m]onitor
284+
// Stereo requires fullscreen
285+
#if !STEREOSCOPIC_SBS
286+
nextMonitor();
287+
#endif
288+
return; // handled
289+
}
185290
case SDLK_f:
186291
if (sdl_mod & KMOD_LGUI || sdl_mod & KMOD_RGUI || sdl_mod & KMOD_LCTRL) {
187292
// command-f: fullscreen
@@ -298,9 +403,12 @@ void projectMSDL::pollEvent() {
298403
switch (evt.type) {
299404
case SDL_WINDOWEVENT:
300405
switch (evt.window.event) {
301-
case SDL_WINDOWEVENT_RESIZED:
302-
resize(evt.window.data1, evt.window.data2);
303-
break;
406+
case SDL_WINDOWEVENT_RESIZED:
407+
resize(evt.window.data1, evt.window.data2);
408+
break;
409+
case SDL_WINDOWEVENT_SIZE_CHANGED:
410+
resize(evt.window.data1, evt.window.data2);
411+
break;
304412
}
305413
break;
306414
case SDL_KEYDOWN:

src/projectM-sdl/pmSDL.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class projectMSDL : public projectM {
9595
int openAudioInput();
9696
void beginAudioCapture();
9797
void endAudioCapture();
98+
void stretchMonitors();
99+
void nextMonitor();
98100
void toggleFullScreen();
99101
void resize(unsigned int width, unsigned int height);
100102
void renderFrame();

src/projectM-sdl/projectM_SDL_main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ srand((int)(time(NULL)));
332332
projectM::Settings settings;
333333
settings.windowWidth = width;
334334
settings.windowHeight = height;
335-
settings.meshX = 400;
335+
settings.meshX = 128;
336336
settings.meshY = settings.meshX * heightWidthRatio;
337337
settings.fps = 60;
338338
settings.smoothPresetDuration = 3; // seconds

0 commit comments

Comments
 (0)