Skip to content
Browse files

thcrap: Add Steam integration for games without. [V]

Because y'know, ZUN might have been lazy enough to not link to that DLL
and call a single function.
Or maybe he wasn't, and all of this was for nothing, because Tasofro
certainly won't be.

And yes, this means that thcrap now comes with a proprietary blob by
Valve Corporation. But before all the GNU/people (and Pooka) freak out:
• `steam_api.dll` will only ever be loaded if Steam is already
  installed. In that case, you already agree to running binaries by
  Valve on your system.
• Just as with `thcrap_update.dll`, you can always delete
  `steam_api.dll` to deactivate this feature… except that you have to
  re-delete it for every new build. Maybe we'll fix that too, let's see.
  • Loading branch information...
nmlgc committed Nov 13, 2017
1 parent 73d46da commit 3faaaef546699abb642f7e9b371415f770418f9a
Showing with 120 additions and 1 deletion.
  1. +2 −0
  2. BIN bin/steam_api.dll
  3. +116 −0 thcrap/src/steam.cpp
  4. +1 −0 thcrap/thcrap.vcxproj
  5. +1 −1 win32_utf8
@@ -31,6 +31,8 @@ It is mainly developed to facilitate self-updating, multilingual translation of

* Wildcard-based **file format patching hooks** called on file replacements - can apply patches to data files according to a (stackable!) JSON description.

* Optional **Steam integration** for games that are available through Steam, but don't come with Steam integration themselves. Can be disabled by deleting `steam_api.dll`.

* ... and all that without any significant impact on performance. ☺

### Modules included ###
BIN +220 KB bin/steam_api.dll
Binary file not shown.
@@ -0,0 +1,116 @@
* Touhou Community Reliant Automatic Patcher
* Main DLL
* ----
* Steam integration for games that are available through Steam, but don't
* come with Steam integration themselves. Requires Valve's `steam_api.dll`,
* which can be deleted to disable this feature.
* Initially, this was just meant to show the logged-in Steam user playing
* the current game, but this also gives us the Steam overlay for free.
* Doesn't seem to have any drawbacks either.
* Game-supporting plugins need to implement
* const char* __cdecl steam_appid(void)
* to return the AppID for the currently running game as a string, or a
* nullptr if it wasn't released on Steam.

#include "thcrap.h"

#ifdef _AMD64_
const stringref_t STEAM_API_DLL_FN = "steam_api64.dll";
const stringref_t STEAM_API_DLL_FN = "steam_api.dll";

typedef const char* __cdecl steam_appid_func_t(void);

// Steam API
// ---------
HKEY hSteamProcess;

typedef bool __cdecl DLL_FUNC_TYPE(SteamAPI, Init)();
typedef bool __cdecl DLL_FUNC_TYPE(SteamAPI, Shutdown)();

DLL_FUNC_DEF(SteamAPI, Shutdown);

#define STEAM_GET_PROC_ADDRESS(func) \
SteamAPI_##func = (SteamAPI_##func##_t*)GetProcAddress(hSteamAPI, "SteamAPI_"#func);
// ---------

extern "C" __declspec(dllexport) void steam_mod_post_init(void)
// Got an AppID?
auto steam_appid_func = (steam_appid_func_t*)func_get("steam_appid");
if(!steam_appid_func) {

auto appid = steam_appid_func();
if(!appid) {

// Got Steam?
"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_READ, &hSteamProcess
)) {
log_printf("[Steam] Not installed\n");

// Got steam_api.dll?
stringref_t thcrap_dir = json_object_get(runconfig_get(), "thcrap_dir");

size_t dll_fn_len = thcrap_dir.len + STEAM_API_DLL_FN.len + 1;
VLA(char, dll_fn, dll_fn_len);

char *p = dll_fn;
p = stringref_copy_advance_dst(p, thcrap_dir);
p = stringref_copy_advance_dst(p, STEAM_API_DLL_FN);

hSteamAPI = LoadLibraryU(dll_fn);
if(!hSteamAPI) {
"[Steam] Couldn't load %s (last error %u), no integration possible\n",
dll_fn, GetLastError()

if(!SteamAPI_Init || !SteamAPI_Shutdown) {
log_printf("[Steam] %s corrupt, no integration possible\n", dll_fn);

SetEnvironmentVariableU("SteamAppId", appid);
if(!SteamAPI_Init()) {
// TODO: Figure out why?
log_printf("[Steam] Initialization for AppID %s failed\n", appid);

log_printf("[Steam] Initialized for AppID %s\n", appid);

extern "C" __declspec(dllexport) void steam_mod_exit(void)
if(!SteamAPI_Shutdown) {
SteamAPI_Init = nullptr;
SteamAPI_Shutdown = nullptr;
@@ -63,6 +63,7 @@
<ClCompile Include="src\inject.cpp" />
<ClCompile Include="src\shelllink.cpp" />
<ClCompile Include="src\stack.cpp" />
<ClCompile Include="src\steam.cpp" />
<ClCompile Include="src\strings.cpp" />
<ClCompile Include="src\util.cpp" />
<ClCompile Include="src\textdisp.cpp" />

0 comments on commit 3faaaef

Please sign in to comment.
You can’t perform that action at this time.