From a5b739f4f217105078f334b1a8652bf42fb67103 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 30 Nov 2025 18:26:25 -0800
Subject: [PATCH] Added the Steamworks SDK to the build
---
.gitmodules | 3 +
CMakeLists.txt | 19 ++++
Xcode/Maelstrom.xcodeproj/project.pbxproj | 33 +++++++
external/SteamworksSDK | 1 +
game/main.cpp | 8 ++
game/steam.cpp | 100 ++++++++++++++++++++++
game/steam.h | 30 +++++++
7 files changed, 194 insertions(+)
create mode 160000 external/SteamworksSDK
create mode 100644 game/steam.cpp
create mode 100644 game/steam.h
diff --git a/.gitmodules b/.gitmodules
index 45920c96..c38f048a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
[submodule "external/SDL_net"]
path = external/SDL_net
url = https://github.com/libsdl-org/SDL_net
+[submodule "external/SteamworksSDK"]
+ path = external/SteamworksSDK
+ url = https://github.com/rlabrecque/SteamworksSDK
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 39511f66..f9176074 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -70,6 +70,8 @@ set(MAELSTROM_SOURCES
game/scores.cpp
game/scores.h
game/shinobi.h
+ game/steam.cpp
+ game/steam.h
screenlib/SDL_FrameBuf.cpp
screenlib/SDL_FrameBuf.h
@@ -156,6 +158,23 @@ if(NOT WIN32)
endif()
endif()
+dep_option(STEAM "Build with Steam support" ON "WIN32 OR LINUX OR MACOS" OFF)
+
+if(STEAM)
+ target_compile_definitions(Maelstrom PRIVATE ENABLE_STEAM)
+ target_include_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/public")
+ if(WIN32)
+ target_link_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/win64")
+ target_link_libraries(Maelstrom PRIVATE steam_api64)
+ elseif(LINUX)
+ target_link_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/linux64")
+ target_link_libraries(Maelstrom PRIVATE steam_api)
+ elseif(MACOS)
+ target_link_directories(Maelstrom PRIVATE "${CMAKE_SOURCE_DIR}/external/SteamworksSDK/redistributable_bin/osx")
+ target_link_libraries(Maelstrom PRIVATE steam_api)
+ endif()
+endif()
+
target_link_libraries(Maelstrom PRIVATE SDLmac)
target_link_libraries(Maelstrom PRIVATE SDL3::SDL3)
target_link_libraries(Maelstrom PRIVATE SDL3_net::SDL3_net)
diff --git a/Xcode/Maelstrom.xcodeproj/project.pbxproj b/Xcode/Maelstrom.xcodeproj/project.pbxproj
index ff16c606..a6c43670 100644
--- a/Xcode/Maelstrom.xcodeproj/project.pbxproj
+++ b/Xcode/Maelstrom.xcodeproj/project.pbxproj
@@ -60,6 +60,9 @@
AA928E512EDB9D830005200A /* Mac_Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA928E4F2EDB9D830005200A /* Mac_Sound.cpp */; };
AA929E852EDBA1900005200A /* Docs in Resources */ = {isa = PBXBuildFile; fileRef = AA929E842EDBA1900005200A /* Docs */; };
AA929E872EDBA3B80005200A /* Data in Resources */ = {isa = PBXBuildFile; fileRef = AA929E862EDBA3B80005200A /* Data */; };
+ F3CC41422F60E6A10033BDFA /* steam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F3CC41412F60E6A10033BDFA /* steam.cpp */; };
+ F3CC41582F610E2C0033BDFA /* libsteam_api.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F3CC41572F610E2C0033BDFA /* libsteam_api.dylib */; platformFilters = (macos, ); };
+ F3CC415B2F610F110033BDFA /* libsteam_api.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = F3CC41572F610E2C0033BDFA /* libsteam_api.dylib */; platformFilters = (macos, ); settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -75,6 +78,16 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
+ F3CC415A2F610F080033BDFA /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 6;
+ files = (
+ F3CC415B2F610F110033BDFA /* libsteam_api.dylib in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
@@ -196,6 +209,9 @@
AA928E4F2EDB9D830005200A /* Mac_Sound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Mac_Sound.cpp; sourceTree = "<group>"; };
AA929E842EDBA1900005200A /* Docs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Docs; path = ../Docs; sourceTree = "<group>"; };
AA929E862EDBA3B80005200A /* Data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Data; path = ../Data; sourceTree = "<group>"; };
+ F3CC41402F60E6A10033BDFA /* steam.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = steam.h; sourceTree = "<group>"; };
+ F3CC41412F60E6A10033BDFA /* steam.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = steam.cpp; sourceTree = "<group>"; };
+ F3CC41572F610E2C0033BDFA /* libsteam_api.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsteam_api.dylib; path = ../external/SteamworksSDK/redistributable_bin/osx/libsteam_api.dylib; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -203,6 +219,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ F3CC41582F610E2C0033BDFA /* libsteam_api.dylib in Frameworks */,
AA9285A42EDB9A6A0005200A /* SDL3.framework in Frameworks */,
AA9285A22EDB9A5D0005200A /* SDL3_net.framework in Frameworks */,
);
@@ -216,6 +233,7 @@
children = (
AA9284C72EDB8CEE0005200A /* SDL.xcodeproj */,
AA9285942EDB9A3D0005200A /* SDL_net.xcodeproj */,
+ F3CC41572F610E2C0033BDFA /* libsteam_api.dylib */,
AA929E862EDBA3B80005200A /* Data */,
AA929E842EDBA1900005200A /* Docs */,
AA928DB12EDB9C5F0005200A /* game */,
@@ -301,6 +319,8 @@
AA928DE22EDB9CA60005200A /* scores.h */,
AA928DE32EDB9CA60005200A /* scores.cpp */,
AA928DE42EDB9CA60005200A /* shinobi.h */,
+ F3CC41402F60E6A10033BDFA /* steam.h */,
+ F3CC41412F60E6A10033BDFA /* steam.cpp */,
);
name = game;
path = ../game;
@@ -421,6 +441,7 @@
AA9284B02EDB8BB30005200A /* Frameworks */,
AA92857A2EDB8EA00005200A /* Embed Frameworks */,
AA929E702EDBA0880005200A /* Resources */,
+ F3CC415A2F610F080033BDFA /* CopyFiles */,
);
buildRules = (
);
@@ -498,6 +519,7 @@
AA928DE62EDB9CA60005200A /* about.cpp in Sources */,
AA928DE72EDB9CA60005200A /* MaelstromUI.cpp in Sources */,
AA928DE82EDB9CA60005200A /* rect.cpp in Sources */,
+ F3CC41422F60E6A10033BDFA /* steam.cpp in Sources */,
AA928DE92EDB9CA60005200A /* netplay.cpp in Sources */,
AA928DEA2EDB9CA60005200A /* objects.cpp in Sources */,
AA928DEB2EDB9CA60005200A /* game.cpp in Sources */,
@@ -593,12 +615,19 @@
"DEBUG=1",
"$(inherited)",
);
+ "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = (
+ "DEBUG=1",
+ "$(inherited)",
+ ENABLE_STEAM,
+ );
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = ../external/SteamworksSDK/public;
+ LIBRARY_SEARCH_PATHS = ../external/SteamworksSDK/redistributable_bin/osx;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
@@ -648,12 +677,16 @@
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = "";
+ "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = ENABLE_STEAM;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = ../external/SteamworksSDK/public;
+ LIBRARY_SEARCH_PATHS = ../external/SteamworksSDK/redistributable_bin/osx;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
diff --git a/external/SteamworksSDK b/external/SteamworksSDK
new file mode 160000
index 00000000..34d9338a
--- /dev/null
+++ b/external/SteamworksSDK
@@ -0,0 +1 @@
+Subproject commit 34d9338aa892213861bd9f84c4dd9c5b7fd23de7
diff --git a/game/main.cpp b/game/main.cpp
index f70c948f..4ae46bef 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -41,6 +41,7 @@
#include "about.h"
#include "game.h"
#include "netplay.h"
+#include "steam.h"
#include "main.h"
#include "../utils/files.h"
@@ -201,6 +202,8 @@ int main(int argc, char *argv[])
}
}
+ InitSteam();
+
/* Initialize everything. :) */
if ( DoInitializations(window_flags) < 0 ) {
/* An error message was already printed */
@@ -232,10 +235,15 @@ int main(int argc, char *argv[])
while ( gRunning ) {
ShowFrame(0);
+ UpdateSteam();
+
DelayFrame();
}
CleanUp();
#endif
+
+ QuitSteam();
+
return 0;
} /* -- main */
diff --git a/game/steam.cpp b/game/steam.cpp
new file mode 100644
index 00000000..27d8263e
--- /dev/null
+++ b/game/steam.cpp
@@ -0,0 +1,100 @@
+/*
+ Maelstrom: Open Source version of the classic game by Ambrosia Software
+ Copyright (C) 1997-2011 Sam Lantinga
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+
+#include "steam.h"
+
+#ifdef ENABLE_STEAM
+
+#include <SDL3/SDL.h>
+#define strncpy SDL_strlcpy
+
+#include <steam/steam_api.h>
+
+class SteamCallbacks
+{
+public:
+ SteamCallbacks() { }
+ ~SteamCallbacks() { }
+
+private:
+ STEAM_CALLBACK(SteamCallbacks, OnRemotePlaySessionConnected, SteamRemotePlaySessionConnected_t);
+ STEAM_CALLBACK(SteamCallbacks, OnRemotePlaySessionDisconnected, SteamRemotePlaySessionDisconnected_t);
+};
+static SteamCallbacks steam;
+
+void SteamCallbacks::OnRemotePlaySessionConnected(SteamRemotePlaySessionConnected_t *pParam)
+{
+}
+
+void SteamCallbacks::OnRemotePlaySessionDisconnected(SteamRemotePlaySessionDisconnected_t *pParam)
+{
+}
+
+
+bool InitSteam()
+{
+ SDL_setenv_unsafe("SteamAppId", "480", true);
+
+ SteamErrMsg error;
+ if (SteamAPI_InitEx(&error) != k_ESteamAPIInitResult_OK) {
+ SDL_Log("Couldn't initialize Steam: %s", error);
+ return false;
+ }
+
+ // Enable passing remote mouse and keyboard into our application
+ SteamRemotePlay()->BEnableRemotePlayTogetherDirectInput();
+
+ return true;
+}
+
+void UpdateSteam()
+{
+ SteamAPI_RunCallbacks();
+
+ uint32 count;
+ RemotePlayInput_t events[32];
+ while ((count = SteamRemotePlay()->GetInput(events, SDL_arraysize(events))) > 0) {
+ // Process remote input
+ }
+}
+
+void QuitSteam()
+{
+ SteamAPI_Shutdown();
+}
+
+#else
+
+bool InitSteam()
+{
+ return false;
+}
+
+void UpdateSteam()
+{
+}
+
+void QuitSteam()
+{
+}
+
+#endif // ENABLE_STEAM
diff --git a/game/steam.h b/game/steam.h
new file mode 100644
index 00000000..eccb40cf
--- /dev/null
+++ b/game/steam.h
@@ -0,0 +1,30 @@
+/*
+ Maelstrom: Open Source version of the classic game by Ambrosia Software
+ Copyright (C) 1997-2011 Sam Lantinga
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+
+#ifndef _steam_h
+#define _steam_h
+
+extern bool InitSteam();
+extern void UpdateSteam();
+extern void QuitSteam();
+
+#endif // _steam_h