mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-06 06:32:56 +01:00
Merge pull request #2012 from Overv/develop
Add Steam overlay detection that pauses the game (#1903)
This commit is contained in:
@@ -76,6 +76,11 @@ else (WIN32)
|
||||
PKG_CHECK_MODULES(SPEEX REQUIRED speexdsp)
|
||||
endif (WIN32)
|
||||
|
||||
# Include libdl for dlopen
|
||||
if (UNIX)
|
||||
set(DLLIB dl)
|
||||
endif (UNIX)
|
||||
|
||||
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS})
|
||||
|
||||
LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS})
|
||||
@@ -93,4 +98,4 @@ endif (WIN32)
|
||||
# libopenrct2.dll -> openrct2.dll
|
||||
set_target_properties(${PROJECT} PROPERTIES PREFIX "")
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2_LIBRARIES} ${ORCTLIBS_LIB} ${JANSSON_LIBRARIES} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2_LIBRARIES} ${ORCTLIBS_LIB} ${JANSSON_LIBRARIES} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB})
|
||||
|
||||
@@ -3891,6 +3891,7 @@ STR_5549 :Year/Month/Day
|
||||
STR_5550 :{POP16}{POP16}Year {COMMA16}, {PUSH16}{PUSH16}{MONTH} {PUSH16}{PUSH16}{STRINGID}
|
||||
STR_5551 :Year/Day/Month
|
||||
STR_5552 :{POP16}{POP16}Year {COMMA16}, {PUSH16}{PUSH16}{PUSH16}{STRINGID} {MONTH}
|
||||
STR_5553 :Pause game when Steam overlay is open
|
||||
|
||||
#####################
|
||||
# Rides/attractions #
|
||||
|
||||
@@ -192,6 +192,7 @@ config_property_definition _generalDefinitions[] = {
|
||||
{ offsetof(general_configuration, day_night_cycle), "day_night_cycle", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(general_configuration, upper_case_banners), "upper_case_banners", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(general_configuration, allow_loading_with_incorrect_checksum),"allow_loading_with_incorrect_checksum", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(general_configuration, steam_overlay_pause), "steam_overlay_pause", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL },
|
||||
};
|
||||
|
||||
config_property_definition _interfaceDefinitions[] = {
|
||||
|
||||
@@ -166,6 +166,7 @@ typedef struct {
|
||||
uint8 day_night_cycle;
|
||||
uint8 upper_case_banners;
|
||||
uint8 allow_loading_with_incorrect_checksum;
|
||||
uint8 steam_overlay_pause;
|
||||
} general_configuration;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -2126,6 +2126,8 @@ enum {
|
||||
STR_DATE_FORMAT_YEAR_DAY_MONTH = 5551,
|
||||
STR_DATE_FORMAT_YDM = 5552,
|
||||
|
||||
STR_STEAM_OVERLAY_PAUSE = 5553,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
};
|
||||
|
||||
@@ -90,6 +90,8 @@ extern int gNumResolutions;
|
||||
extern resolution *gResolutions;
|
||||
extern SDL_Window *gWindow;
|
||||
|
||||
extern bool gSteamOverlayActive;
|
||||
|
||||
// Platform shared definitions
|
||||
void platform_update_fullscreen_resolutions();
|
||||
void platform_get_closest_resolution(int inWidth, int inHeight, int *outWidth, int *outHeight);
|
||||
@@ -143,6 +145,8 @@ uint16 platform_get_locale_language();
|
||||
uint8 platform_get_locale_measurement_format();
|
||||
uint8 platform_get_locale_temperature_format();
|
||||
|
||||
bool platform_check_steam_overlay_attached();
|
||||
|
||||
// Windows specific definitions
|
||||
#ifdef _WIN32
|
||||
// Defining WIN32_LEAN_AND_MEAN breaks dsound.h in audio.h (uncomment when dsound is finally removed)
|
||||
|
||||
@@ -59,6 +59,8 @@ SDL_PixelFormat *gBufferTextureFormat = NULL;
|
||||
SDL_Color gPalette[256];
|
||||
uint32 gPaletteHWMapped[256];
|
||||
|
||||
bool gSteamOverlayActive = false;
|
||||
|
||||
static SDL_Surface *_surface;
|
||||
static SDL_Palette *_palette;
|
||||
|
||||
@@ -73,6 +75,9 @@ static const int _fullscreen_modes[] = { 0, SDL_WINDOW_FULLSCREEN, SDL_WINDOW_FU
|
||||
static unsigned int _lastGestureTimestamp;
|
||||
static float _gestureRadius;
|
||||
|
||||
static uint32 _pixelBeforeOverlay;
|
||||
static uint32 _pixelAfterOverlay;
|
||||
|
||||
static void platform_create_window();
|
||||
static void platform_load_cursors();
|
||||
static void platform_unload_cursors();
|
||||
@@ -179,6 +184,39 @@ void platform_get_closest_resolution(int inWidth, int inHeight, int *outWidth, i
|
||||
}
|
||||
}
|
||||
|
||||
static void read_center_pixel(int width, int height, uint32 *pixel) {
|
||||
SDL_Rect centerPixelRegion = {width / 2, height / 2, 1, 1};
|
||||
SDL_RenderReadPixels(gRenderer, ¢erPixelRegion, SDL_PIXELFORMAT_RGBA8888, pixel, sizeof(uint32));
|
||||
}
|
||||
|
||||
// Should be called before SDL_RenderPresent to capture frame buffer before Steam overlay is drawn.
|
||||
static void overlay_pre_render_check(int width, int height) {
|
||||
read_center_pixel(width, height, &_pixelBeforeOverlay);
|
||||
}
|
||||
|
||||
// Should be called after SDL_RenderPresent, when Steam overlay has had the chance to be drawn.
|
||||
static void overlay_post_render_check(int width, int height) {
|
||||
static bool overlayActive = false;
|
||||
static bool pausedBeforeOverlay = false;
|
||||
|
||||
read_center_pixel(width, height, &_pixelAfterOverlay);
|
||||
|
||||
// Detect an active Steam overlay by checking if the center pixel is changed by the gray fade.
|
||||
// Will not be triggered by applications rendering to corners, like FRAPS, MSI Afterburner and Friends popups.
|
||||
bool newOverlayActive = _pixelBeforeOverlay != _pixelAfterOverlay;
|
||||
|
||||
// Toggle game pause state consistently with base pause state
|
||||
if (!overlayActive && newOverlayActive) {
|
||||
pausedBeforeOverlay = RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) & 1;
|
||||
|
||||
if (!pausedBeforeOverlay) pause_toggle();
|
||||
} else if (overlayActive && !newOverlayActive && !pausedBeforeOverlay) {
|
||||
pause_toggle();
|
||||
}
|
||||
|
||||
overlayActive = newOverlayActive;
|
||||
}
|
||||
|
||||
void platform_draw()
|
||||
{
|
||||
int width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16);
|
||||
@@ -215,7 +253,16 @@ void platform_draw()
|
||||
}
|
||||
|
||||
SDL_RenderCopy(gRenderer, gBufferTexture, NULL, NULL);
|
||||
|
||||
if (gSteamOverlayActive && gConfigGeneral.steam_overlay_pause) {
|
||||
overlay_pre_render_check(width, height);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(gRenderer);
|
||||
|
||||
if (gSteamOverlayActive && gConfigGeneral.steam_overlay_pause) {
|
||||
overlay_post_render_check(width, height);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Lock the surface before setting its pixels
|
||||
@@ -643,6 +690,9 @@ static void platform_create_window()
|
||||
|
||||
platform_update_fullscreen_resolutions();
|
||||
platform_set_fullscreen_mode(gConfigGeneral.fullscreen_mode);
|
||||
|
||||
// Check if steam overlay renderer is loaded into the process
|
||||
gSteamOverlayActive = platform_check_steam_overlay_attached();
|
||||
}
|
||||
|
||||
int platform_scancode_to_rct_keycode(int sdl_key)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "../cmdline.h"
|
||||
#include "../openrct2.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
/**
|
||||
* Unix, linux and fallback entry point to OpenRCT2.
|
||||
@@ -42,5 +43,36 @@ char platform_get_path_separator()
|
||||
}
|
||||
*/
|
||||
|
||||
// See http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html
|
||||
struct lmap {
|
||||
void* base_address;
|
||||
char* path;
|
||||
void* unused;
|
||||
struct lmap *next, *prev;
|
||||
};
|
||||
|
||||
struct dummy {
|
||||
void* pointers[3];
|
||||
struct dummy* ptr;
|
||||
};
|
||||
|
||||
bool platform_check_steam_overlay_attached() {
|
||||
void* processHandle = dlopen(NULL, RTLD_NOW);
|
||||
|
||||
struct dummy* p = (struct dummy*) processHandle;
|
||||
p = p->ptr;
|
||||
|
||||
struct lmap* pl = (struct lmap*) p->ptr;
|
||||
|
||||
while (pl != NULL) {
|
||||
if (strstr(pl->path, "gameoverlayrenderer.so") != NULL) {
|
||||
return true;
|
||||
}
|
||||
pl = pl->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -839,4 +840,9 @@ uint8 platform_get_locale_temperature_format()
|
||||
return TEMPERATURE_FORMAT_C;
|
||||
}
|
||||
}
|
||||
|
||||
bool platform_check_steam_overlay_attached()
|
||||
{
|
||||
return GetModuleHandle("GameOverlayRenderer.dll") != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -79,6 +79,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
|
||||
WIDX_HARDWARE_DISPLAY_CHECKBOX,
|
||||
WIDX_UNCAP_FPS_CHECKBOX,
|
||||
WIDX_MINIMIZE_FOCUS_LOSS,
|
||||
WIDX_STEAM_OVERLAY_PAUSE,
|
||||
WIDX_RENDERING_GROUP,
|
||||
WIDX_TILE_SMOOTHING_CHECKBOX,
|
||||
WIDX_GRIDLINES_CHECKBOX,
|
||||
@@ -168,7 +169,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
|
||||
|
||||
static rct_widget window_options_display_widgets[] = {
|
||||
MAIN_OPTIONS_WIDGETS,
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 53, 145, STR_HARDWARE_GROUP, STR_NONE }, // Hardware group
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 53, 160, STR_HARDWARE_GROUP, STR_NONE }, // Hardware group
|
||||
{ WWT_DROPDOWN, 1, 155, 299, 68, 79, STR_RESOLUTION_X_BY_Y, STR_NONE }, // resolution
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 288, 298, 69, 78, STR_DROPDOWN_GLYPH, STR_NONE },
|
||||
{ WWT_DROPDOWN, 1, 155, 299, 83, 94, 871, STR_NONE }, // fullscreen
|
||||
@@ -176,14 +177,15 @@ static rct_widget window_options_display_widgets[] = {
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 99, 110, STR_HARDWARE_DISPLAY, STR_NONE }, // hardware display
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 114, 125, STR_UNCAP_FPS, STR_NONE }, // uncap fps
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 129, 140, STR_MININISE_FULL_SCREEN_ON_FOCUS_LOSS, STR_NONE }, // minimise fullscreen focus loss
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 144, 155, STR_STEAM_OVERLAY_PAUSE, STR_NONE }, // minimise fullscreen focus loss
|
||||
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 149, 240, STR_RENDERING_GROUP, STR_NONE }, // Rendering group
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 164, 175, STR_TILE_SMOOTHING, STR_TILE_SMOOTHING_TIP }, // landscape smoothing
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 179, 190, STR_GRIDLINES, STR_GRIDLINES_TIP }, // gridlines
|
||||
{ WWT_DROPDOWN, 1, 155, 299, 193, 204, STR_NONE, STR_NONE }, // construction marker
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 288, 298, 194, 203, STR_DROPDOWN_GLYPH, STR_NONE },
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 209, 220, STR_CYCLE_DAY_NIGHT, STR_NONE }, // cycle day-night
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 224, 235, STR_UPPER_CASE_BANNERS, STR_NONE }, // upper case banners
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 164, 255, STR_RENDERING_GROUP, STR_NONE }, // Rendering group
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 179, 190, STR_TILE_SMOOTHING, STR_TILE_SMOOTHING_TIP }, // landscape smoothing
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 194, 205, STR_GRIDLINES, STR_GRIDLINES_TIP }, // gridlines
|
||||
{ WWT_DROPDOWN, 1, 155, 299, 208, 219, STR_NONE, STR_NONE }, // construction marker
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 288, 298, 209, 218, STR_DROPDOWN_GLYPH, STR_NONE },
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 224, 235, STR_CYCLE_DAY_NIGHT, STR_NONE }, // cycle day-night
|
||||
{ WWT_CHECKBOX, 1, 10, 290, 239, 250, STR_UPPER_CASE_BANNERS, STR_NONE }, // upper case banners
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
@@ -355,6 +357,7 @@ static uint32 window_options_page_enabled_widgets[] = {
|
||||
(1 << WIDX_HARDWARE_DISPLAY_CHECKBOX) |
|
||||
(1 << WIDX_UNCAP_FPS_CHECKBOX) |
|
||||
(1 << WIDX_MINIMIZE_FOCUS_LOSS) |
|
||||
(1 << WIDX_STEAM_OVERLAY_PAUSE) |
|
||||
(1 << WIDX_CONSTRUCTION_MARKER) |
|
||||
(1 << WIDX_CONSTRUCTION_MARKER_DROPDOWN) |
|
||||
(1 << WIDX_DAY_NIGHT_CHECKBOX) |
|
||||
@@ -502,6 +505,11 @@ static void window_options_mouseup(rct_window *w, int widgetIndex)
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_STEAM_OVERLAY_PAUSE:
|
||||
gConfigGeneral.steam_overlay_pause ^= 1;
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_DAY_NIGHT_CHECKBOX:
|
||||
gConfigGeneral.day_night_cycle ^= 1;
|
||||
config_save_default();
|
||||
@@ -1114,6 +1122,7 @@ static void window_options_invalidate(rct_window *w)
|
||||
widget_set_checkbox_value(w, WIDX_HARDWARE_DISPLAY_CHECKBOX, gConfigGeneral.hardware_display);
|
||||
widget_set_checkbox_value(w, WIDX_UNCAP_FPS_CHECKBOX, gConfigGeneral.uncap_fps);
|
||||
widget_set_checkbox_value(w, WIDX_MINIMIZE_FOCUS_LOSS, gConfigGeneral.minimize_fullscreen_focus_loss);
|
||||
widget_set_checkbox_value(w, WIDX_STEAM_OVERLAY_PAUSE, gConfigGeneral.steam_overlay_pause);
|
||||
widget_set_checkbox_value(w, WIDX_DAY_NIGHT_CHECKBOX, gConfigGeneral.day_night_cycle);
|
||||
widget_set_checkbox_value(w, WIDX_UPPER_CASE_BANNERS_CHECKBOX, gConfigGeneral.upper_case_banners);
|
||||
|
||||
@@ -1131,6 +1140,7 @@ static void window_options_invalidate(rct_window *w)
|
||||
window_options_display_widgets[WIDX_HARDWARE_DISPLAY_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_display_widgets[WIDX_UNCAP_FPS_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_display_widgets[WIDX_MINIMIZE_FOCUS_LOSS].type = WWT_CHECKBOX;
|
||||
window_options_display_widgets[WIDX_STEAM_OVERLAY_PAUSE].type = WWT_CHECKBOX;
|
||||
window_options_display_widgets[WIDX_DAY_NIGHT_CHECKBOX].type = WWT_CHECKBOX;
|
||||
window_options_display_widgets[WIDX_UPPER_CASE_BANNERS_CHECKBOX].type = WWT_CHECKBOX;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user