Skip to content

Commit

Permalink
Minimal initial steamworks integration.
Browse files Browse the repository at this point in the history
  • Loading branch information
aardappel committed Aug 2, 2017
1 parent 95c09ac commit 7e693cb
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 16 deletions.
9 changes: 5 additions & 4 deletions dev/lobster/lobster.vcxproj
Expand Up @@ -102,7 +102,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;SDL_XAUDIO2_HAS_SDK=1;BUILD_CONTEXT_$(SolutionName);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\steamworks\include;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<EnablePREfast>false</EnablePREfast>
<DisableSpecificWarnings>4127;4512;4201;4146;4456;4702</DisableSpecificWarnings>
Expand Down Expand Up @@ -132,7 +132,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;SDL_XAUDIO2_HAS_SDK=1;BUILD_CONTEXT_$(SolutionName);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\steamworks\include;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
Expand Down Expand Up @@ -161,7 +161,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;SDL_XAUDIO2_HAS_SDK=1;BUILD_CONTEXT_$(SolutionName);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\steamworks\include;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
Expand Down Expand Up @@ -194,7 +194,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;SDL_XAUDIO2_HAS_SDK=1;BUILD_CONTEXT_$(SolutionName);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\include;..\external\freetype\include;..\external\openvr\headers;..\external\steamworks\include;..\external\SDL\include;$(DXSDK_DIR)\Include</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
Expand Down Expand Up @@ -1047,6 +1047,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
</ClCompile>
<ClCompile Include="..\src\steamworks.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\lobster\shaders\default.materials" />
Expand Down
6 changes: 6 additions & 0 deletions dev/lobster/lobster.vcxproj.filters
Expand Up @@ -44,6 +44,9 @@
<Filter Include="compiler">
<UniqueIdentifier>{5b6e2421-9663-4999-a2ce-f1589fbbd7ec}</UniqueIdentifier>
</Filter>
<Filter Include="engine\steam">
<UniqueIdentifier>{d702a622-4917-41d5-a8c2-6f609fe925a0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\stdafx.h">
Expand Down Expand Up @@ -1011,6 +1014,9 @@
<ClCompile Include="..\src\cubegen.cpp">
<Filter>engine\meshgen</Filter>
</ClCompile>
<ClCompile Include="..\src\steamworks.cpp">
<Filter>engine\steam</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\TODO.txt" />
Expand Down
16 changes: 8 additions & 8 deletions dev/lobster/main.vcxproj
Expand Up @@ -113,8 +113,8 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>openvr_api.lib;../../build/lobster/language/languageDBG.lib;../../build/lobster/engine/engineDBG.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86;..\external\openvr\lib\win32</AdditionalLibraryDirectories>
<AdditionalDependencies>..\external\openvr\lib\win32\openvr_api.lib;..\external\steamworks\lib\win32\steam_api.lib;../../build/lobster/language/languageDBG.lib;../../build/lobster/engine/engineDBG.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86</AdditionalLibraryDirectories>
<StackCommitSize>
</StackCommitSize>
<StackReserveSize>
Expand All @@ -141,8 +141,8 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>openvr_api.lib;../../build/lobster/language/languageDBG64.lib;../../build/lobster/engine/engineDBG64.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86;..\external\openvr\lib\win64</AdditionalLibraryDirectories>
<AdditionalDependencies>..\external\openvr\lib\win64\openvr_api.lib;..\external\steamworks\lib\win64\steam_api.lib;../../build/lobster/language/languageDBG64.lib;../../build/lobster/engine/engineDBG64.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86</AdditionalLibraryDirectories>
<StackCommitSize>
</StackCommitSize>
<StackReserveSize>
Expand Down Expand Up @@ -172,8 +172,8 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86;..\external\openvr\lib\win32</AdditionalLibraryDirectories>
<AdditionalDependencies>openvr_api.lib;../../build/lobster/language/language.lib;../../build/lobster/engine/engine.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86</AdditionalLibraryDirectories>
<AdditionalDependencies>..\external\openvr\lib\win32\openvr_api.lib;..\external\steamworks\lib\win32\steam_api.lib;../../build/lobster/language/language.lib;../../build/lobster/engine/engine.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(TargetPath)</OutputFile>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<GenerateMapFile>false</GenerateMapFile>
Expand Down Expand Up @@ -205,8 +205,8 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86;..\external\openvr\lib\win64</AdditionalLibraryDirectories>
<AdditionalDependencies>openvr_api.lib;../../build/lobster/language/language64.lib;../../build/lobster/engine/engine64.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\lib;$(DXSDK_DIR)\Lib\x86</AdditionalLibraryDirectories>
<AdditionalDependencies>..\external\openvr\lib\win64\openvr_api.lib;..\external\steamworks\lib\win64\steam_api.lib;../../build/lobster/language/language64.lib;../../build/lobster/engine/engine64.lib;opengl32.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(TargetPath)</OutputFile>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<GenerateMapFile>false</GenerateMapFile>
Expand Down
6 changes: 3 additions & 3 deletions dev/src/glsystem.cpp
Expand Up @@ -106,10 +106,10 @@ void Set3DMode(float fovy, float ratio, float znear, float zfar) {
bool Is2DMode() { return mode2d; }

uchar *ReadPixels(const int2 &pos, const int2 &size) {
uchar *pixels = new uchar[size.x() * size.y() * 4];
uchar *pixels = new uchar[size.x() * size.y() * 3];
for (int y = 0; y < size.y(); y++)
GL_CALL(glReadPixels(pos.x(), pos.y() + size.y() - y - 1, size.x(), 1, GL_RGBA, GL_UNSIGNED_BYTE,
pixels + y * (size.x() * 4)));
GL_CALL(glReadPixels(pos.x(), pos.y() + size.y() - y - 1, size.x(), 1, GL_RGB, GL_UNSIGNED_BYTE,
pixels + y * (size.x() * 3)));
return pixels;
}

Expand Down
3 changes: 3 additions & 0 deletions dev/src/graphics.cpp
Expand Up @@ -40,7 +40,9 @@ uint GetTexture(Value &res) {
}

// Should be safe to call even if it wasn't initialized partially or at all.
// FIXME: move this elsewhere.
void GraphicsShutDown() {
extern void SteamShutDown(); SteamShutDown();
VRShutDown();
extern void CleanPhysics(); CleanPhysics();
extern void MeshGenClear(); MeshGenClear();
Expand All @@ -62,6 +64,7 @@ void GraphicsShutDown() {

bool GraphicsFrameStart() {
extern void CullFonts(); CullFonts();
extern void SteamUpdate(); SteamUpdate();
bool cb = SDLFrame();
lastframehitsize = lasthitsize;
lasthitsize = float3_0;
Expand Down
1 change: 1 addition & 0 deletions dev/src/platform.h
Expand Up @@ -80,4 +80,5 @@ extern string GetDateTime();

#if defined(_WIN32) // FIXME: Also make work on Linux/OS X.
#define PLATFORM_VR
#define PLATFORM_STEAMWORKS
#endif
3 changes: 2 additions & 1 deletion dev/src/sdlsystem.cpp
Expand Up @@ -630,7 +630,7 @@ int64_t SDLLoadFile(const char *absfilename, string *dest, int64_t start, int64_

bool ScreenShot(const char *filename) {
auto pixels = ReadPixels(int2(0), screensize);
auto ok = stbi_write_png(filename, screensize.x(), screensize.y(), 4, pixels, screensize.x() * 4);
auto ok = stbi_write_png(filename, screensize.x(), screensize.y(), 3, pixels, screensize.x() * 3);
delete[] pixels;
return ok != 0;
}
Expand Down Expand Up @@ -659,6 +659,7 @@ void RegisterCoreEngineBuiltins() {
extern void AddMeshGen(); lobster::RegisterBuiltin("meshgen", AddMeshGen);
extern void AddCubeGen(); lobster::RegisterBuiltin("cubegen", AddCubeGen);
extern void AddVR(); lobster::RegisterBuiltin("vr", AddVR);
extern void AddSteam(); lobster::RegisterBuiltin("steam", AddSteam);
}

void EngineExit(int code) {
Expand Down
200 changes: 200 additions & 0 deletions dev/src/steamworks.cpp
@@ -0,0 +1,200 @@
// Copyright 2017 Wouter van Oortmerssen. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "stdafx.h"

#include "vmdata.h"
#include "natreg.h"

#include "glinterface.h"
#include "sdlinterface.h"

#ifdef PLATFORM_STEAMWORKS

#include "steam/steam_api.h"

struct SteamState {
bool steamoverlayactive = false;
STEAM_CALLBACK(SteamState, OnGameOverlayActivated, GameOverlayActivated_t);
STEAM_CALLBACK(SteamState, OnScreenshotRequested, ScreenshotRequested_t);
};

void SteamState::OnGameOverlayActivated(GameOverlayActivated_t *callback) {
steamoverlayactive = callback->m_bActive;
Output(OUTPUT_INFO, "steam overlay toggle: %d", steamoverlayactive);
}

void SteamState::OnScreenshotRequested(ScreenshotRequested_t *) {
Output(OUTPUT_INFO, "steam screenshot requested");
auto size = GetScreenSize();
auto pixels = ReadPixels(int2(0), size);
SteamScreenshots()->WriteScreenshot(pixels, size.x() * size.y() * 3, size.x(), size.y());
delete[] pixels;
}

extern "C" void __cdecl SteamAPIDebugTextHook(int severity, const char *debugtext) {
Output(severity ? OUTPUT_WARN : OUTPUT_INFO, "%s", debugtext);
}

SteamState *steam = nullptr;

#endif // PLATFORM_STEAMWORKS

void SteamShutDown() {
#ifdef PLATFORM_STEAMWORKS
if (steam) {
delete steam;
SteamAPI_Shutdown();
}
steam = nullptr;
#endif // PLATFORM_STEAMWORKS
}

int SteamInit(uint appid, bool screenshots) {
SteamShutDown();
#ifdef PLATFORM_STEAMWORKS
#ifdef _DEBUG
(void)appid;
#else
if (appid && SteamAPI_RestartAppIfNecessary(appid)) {
Output(OUTPUT_INFO, "Not started from Steam");
return -1;
}
#endif
bool steaminit = SteamAPI_Init();
Output(OUTPUT_INFO, "Steam init: %d", steaminit);
if (!steaminit) return 0;
SteamUtils()->SetWarningMessageHook(&SteamAPIDebugTextHook);
steam = new SteamState();
SteamUserStats()->RequestCurrentStats();
if (screenshots) SteamScreenshots()->HookScreenshots(true);
return 1;
#else
return 0;
#endif // PLATFORM_STEAMWORKS
}

void SteamUpdate() {
#ifdef PLATFORM_STEAMWORKS
SteamAPI_RunCallbacks();
#endif // PLATFORM_STEAMWORKS
}

const char *UserName() {
#ifdef PLATFORM_STEAMWORKS
if (steam) return SteamFriends()->GetPersonaName();
#endif // PLATFORM_STEAMWORKS
return "";
}

bool UnlockAchievement(const char *name) {
#ifdef PLATFORM_STEAMWORKS
if (steam) {
auto ok = SteamUserStats()->SetAchievement(name);
return SteamUserStats()->StoreStats() && ok; // Force this to run.
}
#else
(void)name;
#endif // PLATFORM_STEAMWORKS
return false;
}

int SteamReadFile(const char *fn, string &buf) {
#ifdef PLATFORM_STEAMWORKS
if (steam) {
auto len = SteamRemoteStorage()->GetFileSize(fn);
if (len) {
buf.resize(len);
return SteamRemoteStorage()->FileRead(fn, (void *)buf.data(), len);
}
}
#endif // PLATFORM_STEAMWORKS
return 0;
}

bool SteamWriteFile(const char *fn, const void *buf, int len) {
#ifdef PLATFORM_STEAMWORKS
if (steam) {
return SteamRemoteStorage()->FileWrite(fn, buf, len);
}
#endif // PLATFORM_STEAMWORKS
return false;
}

using namespace lobster;

void AddSteam() {
STARTDECL(steam_init) (Value &appid, Value &ss) {
return Value(SteamInit((uint)appid.ival(), ss.True()));
}
ENDDECL2(steam_init, "appid,allowscreenshots", "II", "I",
"initializes SteamWorks. returns 1 if succesful, 0 on failure. Specify a non-0 appid if you"
" want to restart from steam if this wasn't started from steam (the return value in this"
" case will be -1 to indicate you should terminate this instance). If you don't specify an"
" appid here or in steam_appid.txt, init will likely fail. The other functions can still be"
" called even if steam isn't active."
" allowscreenshots automatically uploads screenshots to steam (triggered by steam).");

STARTDECL(steam_overlay) () {
return Value(steam && steam->steamoverlayactive);
}
ENDDECL0(steam_overlay, "", "", "I",
"returns true if the steam overlay is currently on (you may want to auto-pause if so)");

STARTDECL(steam_username) () {
return Value(g_vm->NewString(UserName()));
}
ENDDECL0(steam_username, "", "", "S",
"returns the name of the steam user, or empty string if not available.");

STARTDECL(steam_unlock_achievement) (Value &name) {
auto ok = UnlockAchievement(name.sval()->str());
name.DECRT();
return Value(ok);
}
ENDDECL1(steam_unlock_achievement, "achievementname", "S", "I",
"Unlocks an achievement and shows the achievement overlay if not already achieved before."
" Will also Q-up saving achievement to Steam."
" Returns true if succesful.");

STARTDECL(steam_write_file) (Value &file, Value &contents) {
auto fn = file.sval()->str();
auto s = contents.sval();
auto ok = SteamWriteFile(fn, s->str(), s->len);
if (!ok) {
ok = WriteFile(fn, true, s->str(), s->len);
}
file.DECRT();
contents.DECRT();
return Value(ok);
}
ENDDECL2(steam_write_file, "file,contents", "SS", "I",
"writes a file with the contents of a string to the steam cloud, or local storage if that"
" fails, returns false if writing wasn't possible at all");

STARTDECL(steam_read_file) (Value &file) {
auto fn = file.sval()->str();
string buf;
auto len = SteamReadFile(fn, buf);
if (!len) len = (int)LoadFile(fn, &buf);
file.DECRT();
if (len < 0) return Value();
auto s = g_vm->NewString(buf);
return Value(s);
}
ENDDECL1(steam_read_file, "file", "S", "S",
"returns the contents of a file as a string from the steam cloud if available, or otherwise"
" from local storage, or nil if the file can't be found at all.");
}

0 comments on commit 7e693cb

Please sign in to comment.