Hello, so much time passed, and I'm curious if anyone played with Steam SDK during that time. Because of that I'm bumping this topic, but that's not only reason.
Lately I was checking whats changed with this, one thing updating GCC used by GLBasic helped with some stuff, another thing that I noticed is very important update in Steam SDK - one of previous problems was Callback system, now Valve allows to use 'manual dispatch API' that lets to omit callback's completely. Still there are other issues, so shorting a long story: GLB uses GCC compiler, Steam_api.dll (and internal steam_client.dll) is compiled with MSVC this may cause some problems. I really don't like such messing with C++, all those standards, conventions, pointers, eh..
So really narrowing it down, thanks to all above we can include Steam API headers in GLB projects like this:
// some Steam SDK playing around
// put 'Steam_SDK\redistributable_bin\steam_api.lib' to '\public' and 'steam_api.dll' to project .app folder where exe is
// add those commands to project options
// cmp -I"your_Steam_SDK_path\public\steam"
// lnk -L"your_Steam_SDK_path\public" -lsteam_api
// put below stuff in separate file
// in main source file just call Steam_Test()
INLINE
// why not to add this
//#include "iostream" // this is causing some errors now, in previous Steam SDK it was needed?
#include "stdio.h"
#include "stdint.h"
#include "assert.h"
// trick to add VS style nullptr to older GCC versions
// Scott Meyers. More Effective C++ 1996
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
const // this is a const object...
class {
public:
template<class T> // convertible to any type
operator T*() const // of null non-member
{ return 0; } // pointer...
template<class C, class T> // or any type of null
operator T C::*() const // member pointer...
{ return 0; }
private:
void operator&() const; // whose address can't be taken
} nullptr = {};
// current SteamSDK uses 'static_assert' macros in some functions
// trick to add static_assert support on older C/C++ standards (as GLB core wont compile properly on C++11)
// Joseph Quinsey : https://stackoverflow.com/questions/54357949/static-assert-for-c90-on-gcc
#define TOKENPASTE(a, b) a ## b // "##" is the "Token Pasting Operator"
#define TOKENPASTE2(a,b) TOKENPASTE(a, b) // expand then paste
#define static_assert(x, msg) enum { TOKENPASTE2(ASSERT_line_,__LINE__) = 1 / (msg && (x)) }
// and here goes Steam stuff
#include "steam_api.h"
// yeap that's all, now you can use it ;-)
//CSteamID your_uid; // some dummy test
ENDINLINE
FUNCTION Steam_Test%:
LOCAL init_ok%, user_lvl%, app_id%, owner_uid%, your_uid%, friends_count%
LOCAL your_name$, some_name$, test_str$
INLINE
init_ok = SteamAPI_Init();
user_lvl = SteamUser()->GetPlayerSteamLevel();
your_name_Str = SteamFriends()->GetPersonaName();
app_id = SteamUtils()->GetAppID(); // this will give GLBasic appid, as app runs from it, using it from standalone exe will give proper ID
CSteamID steamID;
AccountID_t taccountid;
steamID = SteamApps()->GetAppOwner(); // get CSteamID struct
owner_uid = steamID.ConvertToUint64(); // this should be Your SteamID3 ?? but for some reason it isn't or maybe I'm missing something
//taccountid = steamID.GetAccountID(); // unsigned int
//owner_uid = int(taccountid); // this also doesn't give proper Steam ID
// problems starts here
steamID = SteamUser()->GetSteamID(); // sometime this causes Access Violation Exception :-((
//taccountid = steamID.GetAccountID();
//your_uid = taccountid;
your_uid = steamID.ConvertToUint64(); // this should give your proper SteamID3
// both owner_uid and your_uid should be same, yet they differs, maybe some binary Flags are added that's not mentioned in docs
// even more mess, this is copied from official doc
int nFriends = SteamFriends()->GetFriendCount( k_EFriendFlagImmediate );
if ( nFriends == -1) nFriends = 0;
friends_count = nFriends; // this works
for ( int i = 0; i < nFriends; ++i )
{
CSteamID friendSteamID;
//friendSteamID = SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate ); // this will cause Access Violation Exception
//some_name_Str = SteamFriends()->GetFriendPersonaName( friendSteamID );
}
// end using Steam API
SteamAPI_Shutdown();
ENDINLINE
DEBUG "proper init: " + init_ok% + ", your lvl: " + (user_lvl%) + ", you name: '" + (your_name$) + "'"
DEBUG ", You have: " + (friends_count%) + " friends on Steam, some name: '" + some_name$ + "', your_id: " + your_uid%
DEBUG ", app_id: " + app_id% + ", owner_id: " + owner_uid% + "\n"
// if that debug was in one line then some variables get mesed up - like user_lvl%
ENDFUNCTION
Remember to put steam_api.lib & .dll to proper directories, above code is another concept how it could look when current issues would be resolved.
Using some stuff causes 'Access Violation Exceptions', some other things doesn't work properly from what I see and I'm not sure why, I'm just C++ peasant ;-)
With this method one important thing matters, You need to use Steam GLB version (>16) as it has newer GCC compiler. Probably some tricks could help with above mentioned problems, but it's just nah.. for me :/
Method showed in my first post - using Steam API functions through 'DECLARE' is still a solution, it's working with older GLB versions, it has some other issues but if achievements stuff would work it would be fine for me..
EDIT: my initial post - just to keep it in history:
I'm curious if anyone tried to make use of Steam API, for achievements, leaderboards or whatever.
As during fast looking at GLBasic made games on Steam I didn't see any project that support those features. Most notable would be support for achievements.
Some basic stuff can be done with INLINE, using DECLARE to call steam_api.dll functions.
main.gbas
DEBUG "False: " + FALSE + ", True: " + TRUE + "\n"
DEBUG "Steam init: " + SAPI_SteamAPI_init() + "\n"
SAPI_SteamAPI_Shutdown()
steam_min.gbas
INLINE
}
extern "C" {
#include <cstdio>
}
namespace __GLBASIC__ {
typedef bool _Bool;
typedef unsigned char uint8;
typedef signed char int8;
typedef short int16;
typedef unsigned short uint16;
typedef int int32;
const char* STEAMUSER_INTERFACE_VERSION = "SteamUser019";
typedef int32 HSteamPipe;
typedef int32 HSteamUser;
typedef int32 ISteamUser;
DECLARE(SteamAPI_Init, "steam_api.dll", (), bool);
DECLARE(SteamAPI_Shutdown, "steam_api.dll", (), void);
DECLARE(SteamClient, "steam_api.dll", (), intptr_t);
DECLARE(SteamAPI_ISteamClient_CreateSteamPipe, "steam_api.dll", (intptr_t), HSteamPipe);
DECLARE(SteamAPI_ISteamClient_BReleaseSteamPipe, "steam_api.dll", (intptr_t, HSteamPipe), bool);
DECLARE(SteamAPI_ISteamClient_ConnectToGlobalUser, "steam_api.dll", (intptr_t, HSteamPipe), HSteamUser);
DECLARE(SteamAPI_ISteamClient_GetISteamUser, "steam_api.dll", (intptr_t, HSteamUser, HSteamPipe, const char *), intptr_t);
DECLARE(SteamAPI_ISteamUser_GetPlayerSteamLevel, "steam_api.dll", (intptr_t), int);
ENDINLINE
FUNCTION SAPI_SteamAPI_init%:
LOCAL ret%, user_lvl%
INLINE
ret = SteamAPI_Init();
intptr_t sclient;
sclient = SteamClient();
HSteamPipe hsteampipe;
HSteamUser hsteamuser;
hsteampipe = SteamAPI_ISteamClient_CreateSteamPipe(sclient);
hsteamuser = SteamAPI_ISteamClient_ConnectToGlobalUser(sclient, hsteampipe);
intptr_t isteamuser;
isteamuser = SteamAPI_ISteamClient_GetISteamUser(sclient, hsteamuser, hsteampipe, STEAMUSER_INTERFACE_VERSION);;
user_lvl = SteamAPI_ISteamUser_GetPlayerSteamLevel(isteamuser);
SteamAPI_ISteamClient_BReleaseSteamPipe(sclient, hsteampipe);
ENDINLINE
DEBUG "your lvl: " + user_lvl% + "\n"
RETURN ret%
ENDFUNCTION
FUNCTION SAPI_SteamAPI_Shutdown%:
INLINE
SteamAPI_Shutdown();
ENDINLINE
ENDFUNCTION
Put 'steam_api.dll' to project exe folder, and create 'steam_appid.txt' containing your app_id to make this work. And result is that app will print in Debug Your (currently logged in) Steam Level (that from crafting game badges)..
Only issue with this, I have no idea how to make callback's from those functions (yet from what I saw, some other language ports just ignore this problem), many of them works asynchronously, and after completed they invoke/call some callback function, like this, you request for user stats, when Steam internal function get current stats, it callback to some function that normally is in project source. Can this be done with EXPORT, or are some other tricks to do this.
Including whole Steam API with 'steam_api_flat.h' header also can be some solution but proper including/linking is currently out of my scope

Help of some C++ expert is needed here
