Skip to content

Commit

Permalink
Add optional Steam API support for the 2021 rerelease
Browse files Browse the repository at this point in the history
- achievements
- rich presence
- playtime tracking

Disabled by passing `-nosteamapi` on the command line.

Note: the Steam API library is not distributed with IW and is not required for normal execution, it is only used if it's already present on the player's system.
  • Loading branch information
andrei-drexler committed Sep 16, 2024
1 parent 4fdb626 commit 9629e2d
Show file tree
Hide file tree
Showing 9 changed files with 441 additions and 2 deletions.
6 changes: 5 additions & 1 deletion Quake/cl_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "quakedef.h"
#include "bgmusic.h"
#include "steam.h"

const char *svc_strings[] =
{
Expand Down Expand Up @@ -1373,7 +1374,10 @@ void CL_ParseServerMessage (void)
//used by the 2021 rerelease
case svc_achievement:
str = MSG_ReadString();
Con_DPrintf("Ignoring svc_achievement (%s)\n", str);
if (cls.demoplayback)
Con_DPrintf ("Ignoring svc_achievement (%s)\n", str);
else if (!Steam_SetAchievement (str))
Con_DPrintf ("Couldn't set achievement \"%s\"\n", str);
break;
case svc_localsound:
CL_ParseLocalSound();
Expand Down
7 changes: 7 additions & 0 deletions Quake/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -3018,6 +3018,10 @@ static void COM_InitBaseDir (void)
else if (!Sys_GetSteamQuakeUserDir (com_nightdivedir, sizeof (com_nightdivedir), steamquake.library))
com_nightdivedir[0] = '\0';
}
else
{
memset (&steamquake, 0, sizeof (steamquake));
}
if (steam)
goto storesetup;
}
Expand Down Expand Up @@ -3076,6 +3080,9 @@ static void COM_InitBaseDir (void)
flavor = remastered[0] ? QUAKE_FLAVOR_REMASTERED : QUAKE_FLAVOR_ORIGINAL;
q_strlcpy (path, flavor == QUAKE_FLAVOR_REMASTERED ? remastered : original, sizeof (path));

if (steamquake.appid)
Steam_Init (&steamquake);

if (COM_SetBaseDir (path))
{
if (!Sys_GetAltUserPrefDir (flavor == QUAKE_FLAVOR_REMASTERED, com_userprefdir, sizeof (com_userprefdir)))
Expand Down
32 changes: 31 additions & 1 deletion Quake/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "quakedef.h"
#include "bgmusic.h"
#include "steam.h"
#include <setjmp.h>

/*
Expand Down Expand Up @@ -967,6 +968,8 @@ void Host_ServerFrame (void)

typedef struct summary_s {
struct {
int players;
int max_players;
int skill;
int monsters;
int total_monsters;
Expand All @@ -976,6 +979,20 @@ typedef struct summary_s {
char map[countof (cl.mapname)];
} summary_t;

/*
==================
CountActiveClients
==================
*/
static int CountActiveClients (void)
{
int i, active;
for (i = active = 0; i < cl.maxclients; i++)
if (cl.scores[i].name[0])
active++;
return active;
}

/*
==================
GetGameSummary
Expand All @@ -991,6 +1008,8 @@ static void GetGameSummary (summary_t *s)
else
{
q_strlcpy (s->map, cl.mapname, countof (s->map));
s->stats.players = CountActiveClients ();
s->stats.max_players = cl.maxclients;
s->stats.skill = (int) skill.value;
s->stats.monsters = cl.stats[STAT_MONSTERS];
s->stats.total_monsters = cl.stats[STAT_TOTALMONSTERS];
Expand All @@ -1007,7 +1026,7 @@ UpdateWindowTitle
static void UpdateWindowTitle (void)
{
static float timeleft = 0.f;
static summary_t last;
static summary_t last = {{-1}}; // negative value to force initial update
summary_t current;

timeleft -= host_frametime;
Expand Down Expand Up @@ -1039,10 +1058,19 @@ static void UpdateWindowTitle (void)
current.stats.secrets, current.stats.total_secrets
);
VID_SetWindowTitle (title);

if (current.stats.max_players > 1)
Steam_SetStatus_Multiplayer (current.stats.players, current.stats.max_players, utf8name);
else
Steam_SetStatus_SinglePlayer (utf8name);
}
else
{
VID_SetWindowTitle (WINDOW_TITLE_STRING);
if (cls.state == ca_connected)
Steam_ClearStatus ();
else
Steam_SetStatus_Menu ();
}
}

Expand Down Expand Up @@ -1444,6 +1472,8 @@ void Host_Shutdown(void)
// keep Con_Printf from trying to update the screen
scr_disabled_for_loading = true;

Steam_Shutdown ();

AsyncQueue_Destroy (&async_queue);

Host_ShutdownSave ();
Expand Down
2 changes: 2 additions & 0 deletions Quake/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,7 @@ void M_SinglePlayer_Key (int key)
Cbuf_AddText ("maxplayers 1\n");
Cbuf_AddText ("deathmatch 0\n"); //johnfitz
Cbuf_AddText ("coop 0\n"); //johnfitz
Cbuf_AddText ("campaign 1\n");
Cbuf_AddText ("map start\n");
break;

Expand Down Expand Up @@ -2201,6 +2202,7 @@ void M_Skill_Key (int key)
Cbuf_AddText ("maxplayers 1\n");
Cbuf_AddText ("deathmatch 0\n"); //johnfitz
Cbuf_AddText ("coop 0\n"); //johnfitz
Cbuf_AddText ("campaign 0\n");
Cbuf_AddText (va ("map \"%s\"\n", m_skill_mapname));
}
break;
Expand Down
Loading

2 comments on commit 9629e2d

@Calinou
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, is it possible to support Steam cloud saves with this approach?

@andrei-drexler
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tried it, but I think writing save files to Saved Games\Nightdive Studios\Quake (included in the cloud save config) would be enough to get them synced. It might also be possible to use ISteamRemoteStorage to write to a custom location, but I haven't tried that, either.

Please sign in to comment.