mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-22 17:49:43 +01:00
Hook Steam screenshots and send internal capture
Using the Steamworks API, we can hook the screenshot function and listen for a screenshot request callback to send in our own screenshot. This applies the screenshot improvements to Steam screenshots as well. Doing this requires adding some C wrapper functions, as our interface with the Steam API is only conducted through C.
This commit is contained in:
parent
f05827f268
commit
ae5ef9753c
3 changed files with 122 additions and 5 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "GraphicsUtil.h"
|
||||||
#include "Localization.h"
|
#include "Localization.h"
|
||||||
#include "UtilityClass.h"
|
#include "UtilityClass.h"
|
||||||
|
|
||||||
|
@ -27,4 +29,14 @@ uint32_t LOC_toupper_ch(uint32_t ch)
|
||||||
return loc::toupper_ch(ch);
|
return loc::toupper_ch(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_Surface* GRAPHICS_tempScreenshot(void)
|
||||||
|
{
|
||||||
|
return graphics.tempScreenshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t UTIL_TakeScreenshot(SDL_Surface** surface)
|
||||||
|
{
|
||||||
|
return TakeScreenshot(surface);
|
||||||
|
}
|
||||||
|
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CWRAPPERS_H
|
#ifndef CWRAPPERS_H
|
||||||
#define CWRAPPERS_H
|
#define CWRAPPERS_H
|
||||||
|
|
||||||
|
#include <SDL_surface.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -9,6 +10,8 @@ extern "C" {
|
||||||
|
|
||||||
char* HELP_number_words(int _t, const char* number_class);
|
char* HELP_number_words(int _t, const char* number_class);
|
||||||
uint32_t LOC_toupper_ch(uint32_t ch);
|
uint32_t LOC_toupper_ch(uint32_t ch);
|
||||||
|
SDL_Surface* GRAPHICS_tempScreenshot(void);
|
||||||
|
uint8_t UTIL_TakeScreenshot(SDL_Surface** surface);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,14 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "CWrappers.h"
|
||||||
#include "Vlogging.h"
|
#include "Vlogging.h"
|
||||||
|
|
||||||
/* Steamworks interface versions */
|
/* Steamworks interface versions */
|
||||||
|
|
||||||
#define VVVVVV_STEAMCLIENT "SteamClient017"
|
#define VVVVVV_STEAMCLIENT "SteamClient017"
|
||||||
#define VVVVVV_STEAMUSERSTATS "STEAMUSERSTATS_INTERFACE_VERSION011"
|
#define VVVVVV_STEAMUSERSTATS "STEAMUSERSTATS_INTERFACE_VERSION011"
|
||||||
|
#define VVVVVV_STEAMSCREENSHOTS "STEAMSCREENSHOTS_INTERFACE_VERSION003"
|
||||||
|
|
||||||
/* Shared object file name */
|
/* Shared object file name */
|
||||||
|
|
||||||
|
@ -28,6 +30,20 @@
|
||||||
|
|
||||||
struct ISteamClient;
|
struct ISteamClient;
|
||||||
struct ISteamUserStats;
|
struct ISteamUserStats;
|
||||||
|
struct ISteamScreenshots;
|
||||||
|
struct CallbackMsg_t
|
||||||
|
{
|
||||||
|
int32_t m_hSteamUser;
|
||||||
|
int32_t m_iCallback;
|
||||||
|
uint8_t* m_pubParam;
|
||||||
|
int32_t m_cubParam;
|
||||||
|
};
|
||||||
|
struct SteamAPICallCompleted_t
|
||||||
|
{
|
||||||
|
uint64_t m_hAsyncCall;
|
||||||
|
int32_t m_iCallback;
|
||||||
|
uint32_t m_cubParam;
|
||||||
|
};
|
||||||
|
|
||||||
#define FUNC_LIST \
|
#define FUNC_LIST \
|
||||||
FOREACH_FUNC(uint8_t, SteamAPI_Init, (void)) \
|
FOREACH_FUNC(uint8_t, SteamAPI_Init, (void)) \
|
||||||
|
@ -47,10 +63,42 @@ struct ISteamUserStats;
|
||||||
FOREACH_FUNC(uint8_t, SteamAPI_ISteamUserStats_SetAchievement, ( \
|
FOREACH_FUNC(uint8_t, SteamAPI_ISteamUserStats_SetAchievement, ( \
|
||||||
struct ISteamUserStats*, \
|
struct ISteamUserStats*, \
|
||||||
const char* \
|
const char* \
|
||||||
|
)) \
|
||||||
|
FOREACH_FUNC(struct ISteamScreenshots*, SteamAPI_ISteamClient_GetISteamScreenshots, ( \
|
||||||
|
struct ISteamClient*, \
|
||||||
|
int32_t, \
|
||||||
|
int32_t, \
|
||||||
|
const char* \
|
||||||
|
)) \
|
||||||
|
FOREACH_FUNC(void, SteamAPI_ISteamScreenshots_HookScreenshots, (\
|
||||||
|
struct ISteamScreenshots*, \
|
||||||
|
uint8_t \
|
||||||
|
)) \
|
||||||
|
FOREACH_FUNC(uint32_t, SteamAPI_ISteamScreenshots_WriteScreenshot, ( \
|
||||||
|
struct ISteamScreenshots*, \
|
||||||
|
void*, \
|
||||||
|
uint32_t, \
|
||||||
|
int32_t, \
|
||||||
|
int32_t \
|
||||||
|
)) \
|
||||||
|
FOREACH_FUNC(void, SteamAPI_ManualDispatch_Init, (void)) \
|
||||||
|
FOREACH_FUNC(void, SteamAPI_ManualDispatch_RunFrame, (int32_t)) \
|
||||||
|
FOREACH_FUNC(uint8_t, SteamAPI_ManualDispatch_GetNextCallback, (int32_t, struct CallbackMsg_t*)) \
|
||||||
|
FOREACH_FUNC(void, SteamAPI_ManualDispatch_FreeLastCallback, (int32_t)) \
|
||||||
|
FOREACH_FUNC(uint8_t, SteamAPI_ManualDispatch_GetAPICallResult, ( \
|
||||||
|
int32_t, \
|
||||||
|
uint64_t, \
|
||||||
|
void*, \
|
||||||
|
int32_t, \
|
||||||
|
int32_t, \
|
||||||
|
uint8_t* \
|
||||||
))
|
))
|
||||||
|
|
||||||
static void *libHandle = NULL;
|
#define iScreenshotRequested 2302
|
||||||
static struct ISteamUserStats *steamUserStats = NULL;
|
|
||||||
|
static void* libHandle = NULL;
|
||||||
|
static struct ISteamUserStats* steamUserStats = NULL;
|
||||||
|
static struct ISteamScreenshots* steamScreenshots = NULL;
|
||||||
|
|
||||||
#define FOREACH_FUNC(rettype, name, params) static rettype (*name) params = NULL;
|
#define FOREACH_FUNC(rettype, name, params) static rettype (*name) params = NULL;
|
||||||
FUNC_LIST
|
FUNC_LIST
|
||||||
|
@ -68,15 +116,42 @@ static void ClearPointers(void)
|
||||||
#undef FOREACH_FUNC
|
#undef FOREACH_FUNC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void run_screenshot()
|
||||||
|
{
|
||||||
|
if (!libHandle)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlog_info("taking a screenshot");
|
||||||
|
|
||||||
|
SDL_Surface* surface = GRAPHICS_tempScreenshot();
|
||||||
|
uint8_t success = UTIL_TakeScreenshot(&surface);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SteamAPI_ISteamScreenshots_WriteScreenshot(
|
||||||
|
steamScreenshots,
|
||||||
|
surface->pixels,
|
||||||
|
surface->w * surface->h * surface->format->BytesPerPixel,
|
||||||
|
surface->w,
|
||||||
|
surface->h
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/* NETWORK API Implementation */
|
/* NETWORK API Implementation */
|
||||||
|
|
||||||
|
static int32_t steamPipe = 0;
|
||||||
|
|
||||||
int32_t STEAM_init(void)
|
int32_t STEAM_init(void)
|
||||||
{
|
{
|
||||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) || defined(__DragonFly__)
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) || defined(__DragonFly__)
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
struct ISteamClient *steamClient;
|
struct ISteamClient *steamClient;
|
||||||
int32_t steamUser, steamPipe;
|
int32_t steamUser;
|
||||||
|
|
||||||
libHandle = SDL_LoadObject(STEAM_LIBRARY);
|
libHandle = SDL_LoadObject(STEAM_LIBRARY);
|
||||||
if (!libHandle)
|
if (!libHandle)
|
||||||
|
@ -102,6 +177,7 @@ int32_t STEAM_init(void)
|
||||||
ClearPointers();
|
ClearPointers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
SteamAPI_ManualDispatch_Init();
|
||||||
steamClient = SteamInternal_CreateInterface(VVVVVV_STEAMCLIENT);
|
steamClient = SteamInternal_CreateInterface(VVVVVV_STEAMCLIENT);
|
||||||
steamUser = SteamAPI_GetHSteamUser();
|
steamUser = SteamAPI_GetHSteamUser();
|
||||||
steamPipe = SteamAPI_GetHSteamPipe();
|
steamPipe = SteamAPI_GetHSteamPipe();
|
||||||
|
@ -126,6 +202,20 @@ int32_t STEAM_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
SteamAPI_ISteamUserStats_RequestCurrentStats(steamUserStats);
|
SteamAPI_ISteamUserStats_RequestCurrentStats(steamUserStats);
|
||||||
|
steamScreenshots = SteamAPI_ISteamClient_GetISteamScreenshots(
|
||||||
|
steamClient,
|
||||||
|
steamUser,
|
||||||
|
steamPipe,
|
||||||
|
VVVVVV_STEAMSCREENSHOTS
|
||||||
|
);
|
||||||
|
if (!steamScreenshots)
|
||||||
|
{
|
||||||
|
SteamAPI_Shutdown();
|
||||||
|
vlog_error(VVVVVV_STEAMSCREENSHOTS " not created!");
|
||||||
|
ClearPointers();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SteamAPI_ISteamScreenshots_HookScreenshots(steamScreenshots, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,9 +230,21 @@ void STEAM_shutdown(void)
|
||||||
|
|
||||||
void STEAM_update(void)
|
void STEAM_update(void)
|
||||||
{
|
{
|
||||||
if (libHandle)
|
if (!libHandle)
|
||||||
{
|
{
|
||||||
SteamAPI_RunCallbacks();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SteamAPI_ManualDispatch_RunFrame(steamPipe);
|
||||||
|
struct CallbackMsg_t callback;
|
||||||
|
SDL_zero(callback);
|
||||||
|
while (SteamAPI_ManualDispatch_GetNextCallback(steamPipe, &callback))
|
||||||
|
{
|
||||||
|
if (callback.m_iCallback == iScreenshotRequested)
|
||||||
|
{
|
||||||
|
run_screenshot();
|
||||||
|
}
|
||||||
|
SteamAPI_ManualDispatch_FreeLastCallback(steamPipe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue