get achievements working again
authorhgn <hgodden00@gmail.com>
Fri, 3 Dec 2021 20:35:54 +0000 (20:35 +0000)
committerhgn <hgodden00@gmail.com>
Fri, 3 Dec 2021 20:35:54 +0000 (20:35 +0000)
fishladder.c
maps/spam.map [new file with mode: 0644]
vg/config.h
vg/vg.h
vg/vg_platform.h
vg/vg_steamworks.h

index 73c9210a92474dadb5f3dbef33638a92ee957526..03d391de1838959d6436db660cc6801622c6c30b 100644 (file)
@@ -1,7 +1,7 @@
 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
 
-//#define VG_STEAM
-//#define VG_STEAM_APPID 1218140U
+#define VG_STEAM
+#define VG_STEAM_APPID 1218140U
 #include "vg/vg.h"
 #include "fishladder_resources.h"
 
@@ -332,7 +332,6 @@ struct world
        u32 score;
        u32 completed;
        u32 time;
-       
 } world = {};
 
 static void map_free(void)
@@ -709,6 +708,7 @@ static void map_serialize( FILE *stream )
 int main( int argc, char *argv[] )
 {
        vg_init( argc, argv, "Marble Computing | SPACE: Test | LeftClick: Toggle tile | RightClick: Drag wire" );
+       return 0;
 }
 
 static int console_credits( int argc, char const *argv[] )
@@ -1512,6 +1512,8 @@ void vg_update(void)
                                                        if( cell_entry->config == k_cell_type_con_r || cell_entry->config == k_cell_type_con_u 
                                                                || cell_entry->config == k_cell_type_con_l || cell_entry->config == k_cell_type_con_d )
                                                        {
+                                                               sw_set_achievement( "CAN_DO_THAT" );
+                                                       
                                                                fish->state = k_fish_state_soon_alive;
                                                                
                                                                fish->dir[0] = 0;
diff --git a/maps/spam.map b/maps/spam.map
new file mode 100644 (file)
index 0000000..1ce9c7c
--- /dev/null
@@ -0,0 +1,13 @@
+###############;
+#####-#########;abab
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+##           ##;
+###+#+#+#+#+###;abab,cccc,ccaa,aabb,bbbb
+###############;
index ac8df5531e9a084d97b35d3d9018dc906b7f6211..b9aef412206d479e92cbf18d464ba1e94c484121 100644 (file)
@@ -17,3 +17,15 @@ static struct axis_binding vg_axis_binds[] =
        { .name = "horizontal", .positive = GLFW_KEY_D,                                         .negative = GLFW_KEY_A },
        { .name = "vertical",   .positive = GLFW_KEY_W,                                         .negative = GLFW_KEY_S }
 };
+
+static struct vg_achievement vg_achievements[] =
+{
+       { .name = "CAN_DO_THAT" },
+       { .name = "TUTORIALS" },
+       { .name = "GRADUATE" },
+       { .name = "BANG" },
+       { .name = "GOOD_ENOUGH" },
+       { .name = "MIGHTY_CONSUMER" },
+       { .name = "SQUEEZE" },
+       { .name = "MASTER_ENGINEER" }
+};
diff --git a/vg/vg.h b/vg/vg.h
index 53670b24ad93f6034b9f87111f3585a60b11de75..2c86d4d3b596749469f7550c84947acca1118f6e 100644 (file)
--- a/vg/vg.h
+++ b/vg/vg.h
@@ -55,7 +55,7 @@ float vg_time_delta;
 #include "vg/vg_console.h"
 #include "vg/vg_debug.h"
 
-#include "steam/steamworks_thin.h"
+#include "vg/vg_steamworks.h"
 
 // Engine main
 // ===========================================================================================================
@@ -139,14 +139,8 @@ static void vg_init( int argc, char *argv[], const char *window_name )
 {
 #ifdef VG_STEAM
        // Initialize steamworks
-       if( !sw_init( VG_STEAM_APPID ) )
-       {
-               vg_exiterr( "Steamworks failed to initialize" );
-       }
-       else
-       {
-               vg_register_exit( &sw_SteamAPI_Shutdown, "SteamAPI" );
-       }
+       if( !sw_init() )
+               return;
 #endif
        
        // Context creation
@@ -239,7 +233,7 @@ static void vg_init( int argc, char *argv[], const char *window_name )
                        glfwPollEvents();
                        
                        #ifdef VG_STEAM
-                       sw_RunSteamEventLoop();
+                       sw_event_loop();
                        #endif
                        
                        vg_time_last = vg_time;
index 24882841f007746d2d1642538fa904936f6bbda8..b1986b96d088e26732166a5020c6d6c2602e9d60 100644 (file)
@@ -25,6 +25,12 @@ typedef v3f                  boxf[2];
 // Resource types
 typedef struct vg_tex2d vg_tex2d;
 
+struct vg_achievement
+{
+       int is_set;
+       const char *name;
+};
+
 #define vg_static_assert _Static_assert
 
 #define vg_list_size( A ) (sizeof(A)/sizeof(A[0]))
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5bc04f221b31ee2e639c93327d867ef944ea689a 100644 (file)
@@ -0,0 +1,278 @@
+#if defined(__linux__) || defined(__APPLE__) 
+// The 32-bit version of gcc has the alignment requirement for uint64 and double set to
+// 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned.
+// The 64-bit version of gcc has the alignment requirement for these types set to
+// 8 meaning that unless we use #pragma pack(4) our structures will get bigger.
+// The 64-bit structure packing has to match the 32-bit structure packing for each platform.
+ #define VALVE_CALLBACK_PACK_SMALL
+#else
+ #define VALVE_CALLBACK_PACK_LARGE
+#endif
+
+#if defined( VALVE_CALLBACK_PACK_SMALL )
+ #pragma pack( push, 4 )
+#elif defined( VALVE_CALLBACK_PACK_LARGE )
+ #pragma pack( push, 8 )
+#else
+ #error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx
+#endif 
+
+// Types
+typedef void ISteamFriends;
+typedef void ISteamUserStats;
+typedef void ISteamUtils;
+typedef void ISteamUser;
+typedef void ISteamNetworking;
+
+typedef i32    HSteamPipe;
+typedef i32    HSteamUser;
+
+typedef int E_iCallBack_t;
+
+typedef u32 SNetSocket_t;                      // CreateP2PConnectionSocket()
+typedef u32 SNetListenSocket_t;        // CreateListenSocket()
+
+typedef u64    uint64_steamid;
+typedef u64 SteamAPICall_t;
+
+enum { k_iSteamUserCallbacks = 100 };
+enum { k_iSteamGameServerCallbacks = 200 };
+enum { k_iSteamFriendsCallbacks = 300 };
+enum { k_iSteamBillingCallbacks = 400 };
+enum { k_iSteamMatchmakingCallbacks = 500 };
+enum { k_iSteamContentServerCallbacks = 600 };
+enum { k_iSteamUtilsCallbacks = 700 };
+enum { k_iClientFriendsCallbacks = 800 };
+enum { k_iClientUserCallbacks = 900 };
+enum { k_iSteamAppsCallbacks = 1000 };
+enum { k_iSteamUserStatsCallbacks = 1100 };
+enum { k_iSteamNetworkingCallbacks = 1200 };
+enum { k_iSteamNetworkingSocketsCallbacks = 1220 };
+enum { k_iSteamNetworkingMessagesCallbacks = 1250 };
+enum { k_iSteamNetworkingUtilsCallbacks = 1280 };
+enum { k_iClientRemoteStorageCallbacks = 1300 };
+enum { k_iClientDepotBuilderCallbacks = 1400 };
+enum { k_iSteamGameServerItemsCallbacks = 1500 };
+enum { k_iClientUtilsCallbacks = 1600 };
+enum { k_iSteamGameCoordinatorCallbacks = 1700 };
+enum { k_iSteamGameServerStatsCallbacks = 1800 };
+enum { k_iSteam2AsyncCallbacks = 1900 };
+enum { k_iSteamGameStatsCallbacks = 2000 };
+enum { k_iClientHTTPCallbacks = 2100 };
+enum { k_iClientScreenshotsCallbacks = 2200 };
+enum { k_iSteamScreenshotsCallbacks = 2300 };
+enum { k_iClientAudioCallbacks = 2400 };
+enum { k_iClientUnifiedMessagesCallbacks = 2500 };
+enum { k_iSteamStreamLauncherCallbacks = 2600 };
+enum { k_iClientControllerCallbacks = 2700 };
+enum { k_iSteamControllerCallbacks = 2800 };
+enum { k_iClientParentalSettingsCallbacks = 2900 };
+enum { k_iClientDeviceAuthCallbacks = 3000 };
+enum { k_iClientNetworkDeviceManagerCallbacks = 3100 };
+enum { k_iClientMusicCallbacks = 3200 };
+enum { k_iClientRemoteClientManagerCallbacks = 3300 };
+enum { k_iClientUGCCallbacks = 3400 };
+enum { k_iSteamStreamClientCallbacks = 3500 };
+enum { k_IClientProductBuilderCallbacks = 3600 };
+enum { k_iClientShortcutsCallbacks = 3700 };
+enum { k_iClientRemoteControlManagerCallbacks = 3800 };
+enum { k_iSteamAppListCallbacks = 3900 };
+enum { k_iSteamMusicCallbacks = 4000 };
+enum { k_iSteamMusicRemoteCallbacks = 4100 };
+enum { k_iClientVRCallbacks = 4200 };
+enum { k_iClientGameNotificationCallbacks = 4300 }; 
+enum { k_iSteamGameNotificationCallbacks = 4400 }; 
+enum { k_iSteamHTMLSurfaceCallbacks = 4500 };
+enum { k_iClientVideoCallbacks = 4600 };
+enum { k_iClientInventoryCallbacks = 4700 };
+enum { k_iClientBluetoothManagerCallbacks = 4800 };
+enum { k_iClientSharedConnectionCallbacks = 4900 };
+enum { k_ISteamParentalSettingsCallbacks = 5000 };
+enum { k_iClientShaderCallbacks = 5100 };
+enum { k_iSteamGameSearchCallbacks = 5200 };
+enum { k_iSteamPartiesCallbacks = 5300 };
+enum { k_iClientPartiesCallbacks = 5400 };
+enum { k_iSteamSTARCallbacks = 5500 };
+enum { k_iClientSTARCallbacks = 5600 };
+enum { k_iSteamRemotePlayCallbacks = 5700 };
+enum { k_iClientCompatCallbacks = 5800 };
+enum { k_iSteamChatCallbacks = 5900 };
+
+// Structures
+typedef struct {  
+        u32 m_u32;
+    u64 m_u64;
+    u16 m_u16;
+    double m_d;
+} ValvePackingSentinel_t;
+
+typedef struct {
+
+       HSteamUser m_hSteamUser;        // Specific user to whom this callback applies.
+       int m_iCallback;                                // Callback identifier.  (Corresponds to the k_iCallback enum in the callback structure.)
+       uint8_t *m_pubParam;            // Points to the callback structure
+       int m_cubParam;                                 // Size of the data pointed to by m_pubParam
+       
+} CallbackMsg_t;
+
+typedef struct {
+
+       SteamAPICall_t m_hAsyncCall;
+       int m_iCallback;
+       u32 m_cubParam;
+       
+} SteamAPICallCompleted_t;
+#define SW_CBID_SteamAPICallCompleted (k_iSteamUtilsCallbacks + 3)
+
+
+#pragma pack( pop )
+
+// API
+void           SteamAPI_Shutdown();
+int            SteamAPI_Init();
+int            SteamAPI_RestartAppIfNecessary( u32 unOwnAppID );
+
+void           SteamAPI_ManualDispatch_Init();
+void           SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe );
+int            SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg );
+void           SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe );
+int            SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, int *pbFailed );
+void           SteamAPI_ReleaseCurrentThreadMemory();
+
+int            SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats *self, const char *pchName );
+
+HSteamPipe SteamAPI_GetHSteamPipe();
+HSteamUser SteamAPI_GetHSteamUser();
+
+struct
+{
+       ISteamFriends           *friends;
+       ISteamUser                      *user;
+       ISteamUserStats         *stats;
+       ISteamNetworking        *net;
+       
+       HSteamPipe                      pipe;
+} steam_api_classes;
+
+ISteamFriends          *SteamAPI_SteamFriends_v017();
+ISteamUser                     *SteamAPI_SteamUser_v021();
+ISteamUserStats        *SteamAPI_SteamUserStats_v012();
+ISteamNetworking       *SteamAPI_SteamNetworking_v006();
+
+static void sw_exit(void)
+{
+       SteamAPI_Shutdown();
+}
+
+static int sw_init(void)
+{
+       #if defined(VALVE_CALLBACK_PACK_SMALL)
+       if( sizeof(ValvePackingSentinel_t) != 24 ){
+               printf( "Struct packing error: ValvePackingSentinel_t expected 24 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t));
+               return 0;
+       }
+       #else
+               if( sizeof(ValvePackingSentinel_t) != 32 ){
+                       printf( "Struct packing error: ValvePackingSentinel_t expected 32 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t));
+                       return 0;
+               }
+       #endif
+       
+       vg_info( "Intializing steamworks\n" );
+       
+       if( SteamAPI_RestartAppIfNecessary( VG_STEAM_APPID ) == 1 )
+       {
+               vg_info( "Restarting app via steam\n" );
+               return 0;
+       }
+       
+       if( !SteamAPI_Init() )
+       {
+               vg_error( "Steamworks connection failed\n" );
+               return 0;
+       }
+       
+       SteamAPI_ManualDispatch_Init();
+       
+       steam_api_classes.friends = SteamAPI_SteamFriends_v017();
+       steam_api_classes.user = SteamAPI_SteamUser_v021();
+       steam_api_classes.stats = SteamAPI_SteamUserStats_v012();
+       steam_api_classes.net = SteamAPI_SteamNetworking_v006();
+       
+       if( !steam_api_classes.friends || !steam_api_classes.user || !steam_api_classes.stats || !steam_api_classes.net )
+       {
+               vg_error( "Steamworks interface pointers failed. Steamworks DLL may be old\n" );
+               SteamAPI_Shutdown();
+               return 0;
+       }
+       
+       steam_api_classes.pipe = SteamAPI_GetHSteamPipe();
+       vg_success( "Steamworks API running\n" );
+       
+       vg_register_exit( &sw_exit, "SteamAPI" );
+       return 1;
+}
+
+static void sw_event_loop(void)
+{
+       SteamAPI_ManualDispatch_RunFrame( steam_api_classes.pipe );
+       CallbackMsg_t callback;
+       
+       while( SteamAPI_ManualDispatch_GetNextCallback( steam_api_classes.pipe, &callback ) )
+       {
+               // Check for dispatching API call results
+               if( callback.m_iCallback == SW_CBID_SteamAPICallCompleted ){
+               
+                       SteamAPICallCompleted_t *pCallCompleted = (SteamAPICallCompleted_t *)&callback;
+                       void *pTmpCallResult = malloc( pCallCompleted->m_cubParam );
+                       int bFailed;
+                       
+                       if( SteamAPI_ManualDispatch_GetAPICallResult( 
+                               steam_api_classes.pipe, 
+                               pCallCompleted->m_hAsyncCall, 
+                               pTmpCallResult,
+                               pCallCompleted->m_cubParam, 
+                               pCallCompleted->m_iCallback, 
+                               &bFailed ) 
+                       )
+                       {
+                               // Dispatch the call result to the registered handler(s) for the
+                               // call identified by pCallCompleted->m_hAsyncCall
+                       }
+                       
+                       free( pTmpCallResult );
+               } 
+               else 
+               {
+                       // Look at callback.m_iCallback to see what kind of callback it is,
+                       // and dispatch to appropriate handler(s)
+                       
+                       vg_info( "steamworks_event::callback( %i )\n", callback.m_iCallback );
+                       
+                       //void *data = callback.m_pubParam;
+                       
+                       switch( callback.m_iCallback )
+                       {
+                               default: break;
+                       }
+               }
+               
+               SteamAPI_ManualDispatch_FreeLastCallback( steam_api_classes.pipe );
+       }
+}
+
+static void sw_set_achievement( const char *vg_ach_name )
+{
+       struct vg_achievement *ach = NULL;
+       
+       for( int i = 0; i < vg_list_size( vg_achievements ); i ++ )
+               if( !strcmp( vg_ach_name, vg_achievements[i].name ) )
+                       ach = &vg_achievements[i];
+       
+       if( !ach->is_set )
+       {
+               SteamAPI_ISteamUserStats_SetAchievement( steam_api_classes.stats, vg_ach_name );
+               ach->is_set = 1;
+               vg_success( "Achievement set: '%s'\n", vg_ach_name );
+       }
+}