Skip to content

Commit 916e06b

Browse files
committed
more virtual dmd options
1 parent 0b1e5c2 commit 916e06b

4 files changed

Lines changed: 241 additions & 18 deletions

File tree

platforms/config.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ FLITE_SHA=6c9f20dc915b17f5619340069889db0aa007fcdc
77
ESPEAK_NG_SHA=1.52.0
88
PINMAME_SHA=06d84cf208fd5a7da71dc1ecc1e450d3b801f22d
99
LIBPPUC_SHA=61d02b4ed33580d2fdeef0826ae6dd1d7183c138
10-
LIBSDLDMD_SHA=9bd15dbd3498c65e4e9d6118e7b26bc1a6187767
10+
LIBSDLDMD_SHA=e1f5dc344478a33ab9a5085f9b462498a7abc1de
1111

1212
if [ -z "${BUILD_TYPE}" ]; then
1313
BUILD_TYPE="Release"

src/backbox.cpp

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <chrono>
66
#include <csignal>
7+
#include <cstdlib>
78
#include <cstdio>
89
#include <cstring>
910
#include <mutex>
@@ -38,6 +39,82 @@ const char* opt_rom = NULL;
3839
int game_state = 0;
3940
bool running = true;
4041

42+
void ConfigureSDLVideoDriverForHeadlessLinux()
43+
{
44+
#if defined(__linux__) && !defined(__ANDROID__)
45+
if (std::getenv("SDL_VIDEODRIVER") == nullptr && std::getenv("DISPLAY") == nullptr &&
46+
std::getenv("WAYLAND_DISPLAY") == nullptr)
47+
{
48+
setenv("SDL_VIDEODRIVER", "kmsdrm", 0);
49+
}
50+
#endif
51+
}
52+
53+
bool ResolveWindowPositionForScreen(int screenIndex, int offsetX, int offsetY, int* pResolvedX, int* pResolvedY)
54+
{
55+
if (pResolvedX == nullptr || pResolvedY == nullptr)
56+
{
57+
return false;
58+
}
59+
60+
if (screenIndex < 0)
61+
{
62+
*pResolvedX = offsetX;
63+
*pResolvedY = offsetY;
64+
return true;
65+
}
66+
67+
int numDisplays = 0;
68+
SDL_DisplayID* pDisplays = SDL_GetDisplays(&numDisplays);
69+
if (pDisplays == nullptr)
70+
{
71+
return false;
72+
}
73+
74+
const bool validDisplay = screenIndex < numDisplays;
75+
SDL_DisplayID displayId = 0;
76+
if (validDisplay)
77+
{
78+
displayId = pDisplays[screenIndex];
79+
}
80+
SDL_free(pDisplays);
81+
82+
if (!validDisplay)
83+
{
84+
SDL_SetError("Invalid screen index %d", screenIndex);
85+
return false;
86+
}
87+
88+
SDL_Rect displayBounds;
89+
if (!SDL_GetDisplayBounds(displayId, &displayBounds))
90+
{
91+
return false;
92+
}
93+
94+
*pResolvedX = displayBounds.x + offsetX;
95+
*pResolvedY = displayBounds.y + offsetY;
96+
return true;
97+
}
98+
99+
bool PositionWindowOnScreen(SDL_Window* pWindow, int screenIndex, int offsetX = 0, int offsetY = 0)
100+
{
101+
if (pWindow == nullptr || screenIndex < 0)
102+
{
103+
return true;
104+
}
105+
106+
int resolvedX = 0;
107+
int resolvedY = 0;
108+
if (!ResolveWindowPositionForScreen(screenIndex, offsetX, offsetY, &resolvedX, &resolvedY))
109+
{
110+
return false;
111+
}
112+
113+
SDL_SetWindowPosition(pWindow, resolvedX, resolvedY);
114+
while (!SDL_SyncWindow(pWindow));
115+
return true;
116+
}
117+
41118
uint32_t currentThreadId = 0;
42119
std::mutex threadMutex;
43120
uint32_t disconnectOtherClients = 0;
@@ -105,6 +182,14 @@ static struct cag_option options[] = {
105182
.access_name = "virtual-dmd-screen",
106183
.value_name = "VALUE",
107184
.description = "Show virtual DMD on a specific screen"},
185+
{.identifier = 'T',
186+
.access_name = "virtual-dmd-x",
187+
.value_name = "VALUE",
188+
.description = "Virtual DMD x position relative to the selected screen"},
189+
{.identifier = 'U',
190+
.access_name = "virtual-dmd-y",
191+
.value_name = "VALUE",
192+
.description = "Virtual DMD y position relative to the selected screen"},
108193
{.identifier = 'S',
109194
.access_name = "virtual-dmd-scale",
110195
.value_name = NULL,
@@ -189,6 +274,8 @@ int main(int argc, char* argv[])
189274
uint16_t opt_virtual_dmd_width = 1280;
190275
uint16_t opt_virtual_dmd_height = 320;
191276
int8_t opt_virtual_dmd_screen = -1;
277+
int opt_virtual_dmd_x = SDL_WINDOWPOS_UNDEFINED;
278+
int opt_virtual_dmd_y = SDL_WINDOWPOS_UNDEFINED;
192279
DMDUtil::SDLDMD* pVirtualDMD = nullptr;
193280
uint32_t threadId = 0;
194281

@@ -247,6 +334,12 @@ int main(int argc, char* argv[])
247334
case 'R':
248335
opt_virtual_dmd_screen = atoi(cag_option_get_value(&cag_context));
249336
break;
337+
case 'T':
338+
opt_virtual_dmd_x = atoi(cag_option_get_value(&cag_context));
339+
break;
340+
case 'U':
341+
opt_virtual_dmd_y = atoi(cag_option_get_value(&cag_context));
342+
break;
250343
case 'S':
251344
opt_virtual_dmd_scale = true;
252345
break;
@@ -275,11 +368,7 @@ int main(int argc, char* argv[])
275368

276369
if (opt_translite || opt_virtual_dmd)
277370
{
278-
// Set the SDL video driver for Linux framebuffer
279-
#ifdef __linux__
280-
setenv("SDL_VIDEODRIVER", "KMSDRM", 1);
281-
#endif
282-
371+
ConfigureSDLVideoDriverForHeadlessLinux();
283372
if (!SDL_Init(SDL_INIT_VIDEO))
284373
{
285374
printf("SDL_Init Error: %s\n", SDL_GetError());
@@ -297,8 +386,14 @@ int main(int argc, char* argv[])
297386
return SDL_APP_FAILURE;
298387
}
299388

300-
SDL_SetWindowPosition(pTransliteWindow, 0, 0);
301-
while (!SDL_SyncWindow(pTransliteWindow));
389+
if (!PositionWindowOnScreen(pTransliteWindow, opt_translite_screen))
390+
{
391+
printf("Failed to position translite window: %s\n", SDL_GetError());
392+
SDL_DestroyRenderer(pTransliteRenderer);
393+
SDL_DestroyWindow(pTransliteWindow);
394+
SDL_Quit();
395+
return 1;
396+
}
302397

303398
pTransliteTexture = IMG_LoadTexture(pTransliteRenderer, opt_translite);
304399
if (!pTransliteTexture)
@@ -361,7 +456,8 @@ int main(int argc, char* argv[])
361456
{
362457
pVirtualDMD = DMDUtil::CreateSDLDMD(*pDmd, "PPUC DMD", opt_virtual_dmd_width, opt_virtual_dmd_height,
363458
opt_virtual_dmd_window ? SDL_WINDOW_BORDERLESS : SDL_WINDOW_FULLSCREEN,
364-
opt_virtual_dmd_hd ? 256 : 128, opt_virtual_dmd_hd ? 64 : 32);
459+
opt_virtual_dmd_hd ? 256 : 128, opt_virtual_dmd_hd ? 64 : 32,
460+
opt_virtual_dmd_screen, opt_virtual_dmd_x, opt_virtual_dmd_y);
365461

366462
if (!pVirtualDMD)
367463
{

src/menu.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <algorithm>
55
#include <cerrno>
66
#include <cctype>
7+
#include <cstdlib>
78
#include <cstdio>
89
#include <cstdlib>
910
#include <cstring>
@@ -82,6 +83,17 @@ std::string ToLower(std::string value)
8283
return value;
8384
}
8485

86+
void ConfigureSDLVideoDriverForHeadlessLinux()
87+
{
88+
#if defined(__linux__) && !defined(__ANDROID__)
89+
if (std::getenv("SDL_VIDEODRIVER") == nullptr && std::getenv("DISPLAY") == nullptr &&
90+
std::getenv("WAYLAND_DISPLAY") == nullptr)
91+
{
92+
setenv("SDL_VIDEODRIVER", "kmsdrm", 0);
93+
}
94+
#endif
95+
}
96+
8597
bool FileExists(const fs::path& path)
8698
{
8799
std::error_code ec;
@@ -1124,6 +1136,7 @@ int main(int argc, char* argv[])
11241136

11251137
const SDL_InitFlags initFlags = SDL_INIT_VIDEO |
11261138
(optNoSound ? 0 : SDL_INIT_AUDIO);
1139+
ConfigureSDLVideoDriverForHeadlessLinux();
11271140
if (!SDL_Init(initFlags))
11281141
{
11291142
fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());

0 commit comments

Comments
 (0)