mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-06 03:39:51 +00:00
[steam] Avoid crash taking screenshots after Steam client is closed
This commit is contained in:
parent
2f472f0760
commit
c8999af6d6
@ -48,6 +48,10 @@
|
|||||||
#include "ui/intern.h"
|
#include "ui/intern.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_STEAM
|
||||||
|
#include "steam/steam.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -366,6 +370,11 @@ void defer_invalid_rect(const gfx::Rect& rc)
|
|||||||
// Manager event handler.
|
// Manager event handler.
|
||||||
bool CustomizedGuiManager::onProcessMessage(Message* msg)
|
bool CustomizedGuiManager::onProcessMessage(Message* msg)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_STEAM
|
||||||
|
if (auto steamAPI = steam::SteamAPI::instance())
|
||||||
|
steamAPI->runCallbacks();
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (msg->type()) {
|
switch (msg->type()) {
|
||||||
|
|
||||||
case kCloseDisplayMessage: {
|
case kCloseDisplayMessage: {
|
||||||
|
@ -19,12 +19,34 @@
|
|||||||
|
|
||||||
namespace steam {
|
namespace steam {
|
||||||
|
|
||||||
|
typedef uint32_t HSteamPipe;
|
||||||
|
typedef uint32_t HSteamUser;
|
||||||
typedef uint32_t ScreenshotHandle;
|
typedef uint32_t ScreenshotHandle;
|
||||||
typedef void* ISteamScreenshots;
|
typedef void* ISteamScreenshots;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// Last callback received from Steam client when it's Steam is closed
|
||||||
|
kSteamServersDisconnected = 103,
|
||||||
|
kSteamUndocumentedLastCallback = 1009,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CallbackMsg_t {
|
||||||
|
HSteamUser steamUser;
|
||||||
|
int callback;
|
||||||
|
uint8_t* pubParam;
|
||||||
|
int cubParam;
|
||||||
|
};
|
||||||
|
|
||||||
// Steam main API
|
// Steam main API
|
||||||
typedef bool __cdecl (*SteamAPI_Init_Func)();
|
typedef bool __cdecl (*SteamAPI_Init_Func)();
|
||||||
typedef void __cdecl (*SteamAPI_Shutdown_Func)();
|
typedef void __cdecl (*SteamAPI_Shutdown_Func)();
|
||||||
|
typedef HSteamPipe __cdecl (*SteamAPI_GetHSteamPipe_Func)();
|
||||||
|
|
||||||
|
// Steam callbacks
|
||||||
|
typedef void __cdecl (*SteamAPI_ManualDispatch_Init_Func)();
|
||||||
|
typedef void __cdecl (*SteamAPI_ManualDispatch_RunFrame_Func)(HSteamPipe);
|
||||||
|
typedef bool __cdecl (*SteamAPI_ManualDispatch_GetNextCallback_Func)(HSteamPipe, CallbackMsg_t*);
|
||||||
|
typedef void __cdecl (*SteamAPI_ManualDispatch_FreeLastCallback_Func)(HSteamPipe);
|
||||||
|
|
||||||
// ISteamScreenshots
|
// ISteamScreenshots
|
||||||
typedef ISteamScreenshots* __cdecl (*SteamAPI_SteamScreenshots_v003_Func)();
|
typedef ISteamScreenshots* __cdecl (*SteamAPI_SteamScreenshots_v003_Func)();
|
||||||
@ -67,6 +89,21 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get functions to dispatch callbacks manually
|
||||||
|
auto SteamAPI_ManualDispatch_Init = GETPROC(SteamAPI_ManualDispatch_Init);
|
||||||
|
SteamAPI_ManualDispatch_RunFrame = GETPROC(SteamAPI_ManualDispatch_RunFrame);
|
||||||
|
SteamAPI_ManualDispatch_GetNextCallback = GETPROC(SteamAPI_ManualDispatch_GetNextCallback);
|
||||||
|
SteamAPI_ManualDispatch_FreeLastCallback = GETPROC(SteamAPI_ManualDispatch_FreeLastCallback);
|
||||||
|
auto SteamAPI_GetHSteamPipe = GETPROC(SteamAPI_GetHSteamPipe);
|
||||||
|
if (SteamAPI_ManualDispatch_Init &&
|
||||||
|
SteamAPI_ManualDispatch_RunFrame &&
|
||||||
|
SteamAPI_ManualDispatch_GetNextCallback &&
|
||||||
|
SteamAPI_ManualDispatch_FreeLastCallback &&
|
||||||
|
SteamAPI_GetHSteamPipe) {
|
||||||
|
SteamAPI_ManualDispatch_Init();
|
||||||
|
m_pipe = SteamAPI_GetHSteamPipe();
|
||||||
|
}
|
||||||
|
|
||||||
LOG("STEAM: Steam initialized\n");
|
LOG("STEAM: Steam initialized\n");
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
@ -81,13 +118,44 @@ public:
|
|||||||
SteamAPI_Shutdown();
|
SteamAPI_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
base::unload_dll(m_steamLib);
|
unloadLib();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initialized() const {
|
bool initialized() const {
|
||||||
return m_initialized;
|
return m_initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runCallbacks() {
|
||||||
|
if (!m_pipe)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ASSERT(SteamAPI_ManualDispatch_RunFrame);
|
||||||
|
ASSERT(SteamAPI_ManualDispatch_GetNextCallback);
|
||||||
|
ASSERT(SteamAPI_ManualDispatch_FreeLastCallback);
|
||||||
|
|
||||||
|
SteamAPI_ManualDispatch_RunFrame(m_pipe);
|
||||||
|
|
||||||
|
CallbackMsg_t msg;
|
||||||
|
if (SteamAPI_ManualDispatch_GetNextCallback(m_pipe, &msg)) {
|
||||||
|
//TRACEARGS("SteamAPI_ManualDispatch_GetNextCallback", msg.callback);
|
||||||
|
|
||||||
|
bool disconnected = false;
|
||||||
|
if (msg.callback == kSteamServersDisconnected ||
|
||||||
|
msg.callback == kSteamUndocumentedLastCallback) {
|
||||||
|
disconnected = true;
|
||||||
|
}
|
||||||
|
SteamAPI_ManualDispatch_FreeLastCallback(m_pipe);
|
||||||
|
|
||||||
|
// If the Steam client is closed, we have to unload the DLL and
|
||||||
|
// don't use the pipe or any Steam API at all, in other case we
|
||||||
|
// would crash.
|
||||||
|
if (disconnected) {
|
||||||
|
LOG("STEAM: Disconnected\n");
|
||||||
|
unloadLib();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool writeScreenshot(void* rgbBuffer,
|
bool writeScreenshot(void* rgbBuffer,
|
||||||
uint32_t sizeInBytes,
|
uint32_t sizeInBytes,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
@ -112,8 +180,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void unloadLib() {
|
||||||
|
base::unload_dll(m_steamLib);
|
||||||
|
m_steamLib = nullptr;
|
||||||
|
m_initialized = false;
|
||||||
|
m_pipe = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
base::dll m_steamLib = nullptr;
|
base::dll m_steamLib = nullptr;
|
||||||
|
|
||||||
|
// To handle callbacks manually
|
||||||
|
HSteamPipe m_pipe = 0;
|
||||||
|
SteamAPI_ManualDispatch_RunFrame_Func SteamAPI_ManualDispatch_RunFrame = nullptr;
|
||||||
|
SteamAPI_ManualDispatch_GetNextCallback_Func SteamAPI_ManualDispatch_GetNextCallback = nullptr;
|
||||||
|
SteamAPI_ManualDispatch_FreeLastCallback_Func SteamAPI_ManualDispatch_FreeLastCallback = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
SteamAPI* g_instance = nullptr;
|
SteamAPI* g_instance = nullptr;
|
||||||
@ -144,6 +225,11 @@ bool SteamAPI::initialized() const
|
|||||||
return m_impl->initialized();
|
return m_impl->initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SteamAPI::runCallbacks()
|
||||||
|
{
|
||||||
|
m_impl->runCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
bool SteamAPI::writeScreenshot(void* rgbBuffer,
|
bool SteamAPI::writeScreenshot(void* rgbBuffer,
|
||||||
uint32_t sizeInBytes,
|
uint32_t sizeInBytes,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
|
@ -19,6 +19,7 @@ public:
|
|||||||
~SteamAPI();
|
~SteamAPI();
|
||||||
|
|
||||||
bool initialized() const;
|
bool initialized() const;
|
||||||
|
void runCallbacks();
|
||||||
|
|
||||||
bool writeScreenshot(void* rgbBuffer,
|
bool writeScreenshot(void* rgbBuffer,
|
||||||
uint32_t sizeInBytes,
|
uint32_t sizeInBytes,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user