1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-16 09:38:29 +02:00
VVVVVV/desktop_version/src/Network.c
Misa 6a3a1fe147
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.

This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.

I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 17:23:59 -05:00

159 lines
3.1 KiB
C

#include <stdint.h>
#include "MakeAndPlay.h"
#define UNUSED(expr) (void)(expr)
#ifdef MAKEANDPLAY
#ifdef STEAM_NETWORK
#undef STEAM_NETWORK
#endif
#ifdef GOG_NETWORK
#undef GOG_NETWORK
#endif
#endif
#ifdef STEAM_NETWORK
#define STEAM_NUM 1
#else
#define STEAM_NUM 0
#endif
#ifdef GOG_NETWORK
#define GOG_NUM 1
#else
#define GOG_NUM 0
#endif
#define NUM_BACKENDS (STEAM_NUM+GOG_NUM)
#define DECLARE_BACKEND(name) \
int32_t name##_init(void); \
void name##_shutdown(void); \
void name##_update(void); \
void name##_unlockAchievement(const char *name); \
int32_t name##_getAchievementProgress(const char *name); \
void name##_setAchievementProgress(const char *name, int32_t stat);
#ifdef STEAM_NETWORK
DECLARE_BACKEND(STEAM)
#endif
#ifdef GOG_NETWORK
DECLARE_BACKEND(GOG)
#endif
#undef DECLARE_BACKEND
typedef struct NetworkBackend
{
int32_t IsInit;
int32_t (*Init)(void);
void (*Shutdown)(void);
void (*Update)(void);
void (*UnlockAchievement)(const char*);
int32_t (*GetAchievementProgress)(const char*);
void (*SetAchievementProgress)(const char*, int32_t);
} NetworkBackend;
#if NUM_BACKENDS > 0
static NetworkBackend backends[NUM_BACKENDS];
#endif
int NETWORK_init(void)
{
int32_t any = 0;
#define ASSIGN_BACKEND(name, index) \
backends[index].Init = name##_init; \
backends[index].Shutdown = name##_shutdown; \
backends[index].Update = name##_update; \
backends[index].UnlockAchievement = name##_unlockAchievement; \
backends[index].GetAchievementProgress = name##_getAchievementProgress; \
backends[index].SetAchievementProgress = name##_setAchievementProgress;
#ifdef STEAM_NETWORK
ASSIGN_BACKEND(STEAM, 0)
#endif
#ifdef GOG_NETWORK
ASSIGN_BACKEND(GOG, STEAM_NUM)
#endif
#undef ASSIGN_BACKEND
#if NUM_BACKENDS > 0
int32_t i;
for (i = 0; i < NUM_BACKENDS; i += 1)
{
backends[i].IsInit = backends[i].Init();
any |= backends[i].IsInit;
}
#endif
return any;
}
void NETWORK_shutdown(void)
{
#if NUM_BACKENDS > 0
int32_t i;
for (i = 0; i < NUM_BACKENDS; i += 1)
if (backends[i].IsInit)
{
backends[i].Shutdown();
}
#endif
}
void NETWORK_update(void)
{
#if NUM_BACKENDS > 0
int32_t i;
for (i = 0; i < NUM_BACKENDS; i += 1)
if (backends[i].IsInit)
{
backends[i].Update();
}
#endif
}
void NETWORK_unlockAchievement(const char *name)
{
#if NUM_BACKENDS > 0
int32_t i;
for (i = 0; i < NUM_BACKENDS; i += 1)
if (backends[i].IsInit)
{
backends[i].UnlockAchievement(name);
}
#else
UNUSED(name);
#endif
}
int32_t NETWORK_getAchievementProgress(const char *name)
{
/* The highest stat gets priority, will eventually pass to the others */
int32_t max = 0;
#if NUM_BACKENDS > 0
int32_t i, stat;
for (i = 0; i < NUM_BACKENDS; i += 1)
if (backends[i].IsInit)
{
stat = backends[i].GetAchievementProgress(name);
if (stat > max)
{
max = stat;
}
}
#else
UNUSED(name);
#endif
return max;
}
void NETWORK_setAchievementProgress(const char *name, int32_t stat)
{
#if NUM_BACKENDS > 0
int32_t i;
for (i = 0; i < NUM_BACKENDS; i += 1)
if (backends[i].IsInit)
{
backends[i].SetAchievementProgress(name, stat);
}
#else
UNUSED(name);
UNUSED(stat);
#endif
}