mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-04 21:50:38 -04:00
add steam and achivements, improve console
This commit is contained in:
parent
9bfb0f1d5d
commit
f49a7490c1
13 changed files with 360 additions and 258 deletions
|
@ -3,6 +3,20 @@ project(skeldal)
|
||||||
|
|
||||||
# Najít SDL2 knihovnu
|
# Najít SDL2 knihovnu
|
||||||
find_package(SDL2 REQUIRED)
|
find_package(SDL2 REQUIRED)
|
||||||
|
set(STEAMWORKS_SDK_DIR "${CMAKE_SOURCE_DIR}/external/steamworks/")
|
||||||
|
# Check if Steamworks SDK directories exist
|
||||||
|
if(NOT EXISTS "${STEAMWORKS_SDK_DIR}/public")
|
||||||
|
message(FATAL_ERROR "❌ Could not find Steamworks SDK 'public' headers.
|
||||||
|
Make sure to download the Steamworks SDK and place it in:${STEAMWORKS_SDK_DIR}
|
||||||
|
Expected directory: ${STEAMWORKS_SDK_DIR}/public
|
||||||
|
")
|
||||||
|
endif()
|
||||||
|
if(NOT EXISTS "${STEAMWORKS_SDK_DIR}/redistributable_bin")
|
||||||
|
message(FATAL_ERROR "❌ Could not find Steamworks SDK 'redistributable_bin' libraries.
|
||||||
|
Make sure to download the Steamworks SDK and place it in: ${STEAMWORKS_SDK_DIR}
|
||||||
|
Expected directory: ${STEAMWORKS_SDK_DIR}/redistributable_bin
|
||||||
|
")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
add_compile_options(/W4 /EHa /DNOMINMAX /D_CRT_SECURE_NO_WARNINGS /J)
|
add_compile_options(/W4 /EHa /DNOMINMAX /D_CRT_SECURE_NO_WARNINGS /J)
|
||||||
|
@ -19,7 +33,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/)
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/)
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/)
|
||||||
|
|
||||||
include_directories( ${SDL2_INCLUDE_DIRS})
|
include_directories( ${SDL2_INCLUDE_DIRS})
|
||||||
enable_testing()
|
include_directories(${STEAMWORKS_SDK_DIR}/public)
|
||||||
add_subdirectory(libs)
|
add_subdirectory(libs)
|
||||||
add_subdirectory(platform)
|
add_subdirectory(platform)
|
||||||
add_subdirectory(game)
|
add_subdirectory(game)
|
||||||
|
|
6
external/steamworks/.gitignore
vendored
Normal file
6
external/steamworks/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Exclude all files
|
||||||
|
*
|
||||||
|
|
||||||
|
# Allow only get_sdk.md
|
||||||
|
!get_sdk.md
|
||||||
|
!.gitignore
|
20
external/steamworks/get_sdk.md
vendored
Normal file
20
external/steamworks/get_sdk.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Download and Extract Steamworks SDK
|
||||||
|
|
||||||
|
Follow these steps to download and extract the Steamworks SDK:
|
||||||
|
|
||||||
|
## Steps to Download and Extract
|
||||||
|
1. Visit the official [Steamworks SDK page](https://partner.steamgames.com/).
|
||||||
|
2. Log in with your Steam developer account.
|
||||||
|
3. Navigate to the "SDK & Tools" section.
|
||||||
|
4. Download the latest version of the Steamworks SDK.
|
||||||
|
5. Once downloaded, extract the contents of the SDK archive into this directory.
|
||||||
|
|
||||||
|
## Required Directory Structure
|
||||||
|
After extraction, ensure the following directories exist in this location:
|
||||||
|
- `redistributable_bin/`
|
||||||
|
- `public/`
|
||||||
|
- `tools/`
|
||||||
|
- `sdk/`
|
||||||
|
- `samples/`
|
||||||
|
|
||||||
|
If any of these directories are missing, re-download and extract the SDK to ensure all files are included.
|
328
game/console.c
328
game/console.c
|
@ -1,5 +1,6 @@
|
||||||
#include <libs/bgraph.h>
|
#include <libs/bgraph.h>
|
||||||
#include <libs/event.h>
|
#include <libs/event.h>
|
||||||
|
#include <platform/achievements.h>
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -106,209 +107,6 @@ void spell_group_invis()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void advence_player(int player,int level,char auto_advance)
|
|
||||||
{
|
|
||||||
THUMAN *h;
|
|
||||||
float mh,mv;
|
|
||||||
|
|
||||||
if (level<2) return;
|
|
||||||
h=postavy+player;
|
|
||||||
mh=(float)human_selected->jidlo/MAX_HLAD(human_selected);
|
|
||||||
mv=(float)human_selected->voda/MAX_ZIZEN(human_selected);
|
|
||||||
human_selected=h;
|
|
||||||
h->exp=level_map[level-2];
|
|
||||||
check_player_new_level(h);
|
|
||||||
if (auto_advance)
|
|
||||||
{
|
|
||||||
int vlssuma=h->vlastnosti[VLS_SILA]+
|
|
||||||
h->vlastnosti[VLS_OBRAT]+
|
|
||||||
h->vlastnosti[VLS_POHYB]+
|
|
||||||
h->vlastnosti[VLS_SMAGIE];
|
|
||||||
int b,i;
|
|
||||||
|
|
||||||
for(i=0;i<4;i++)
|
|
||||||
{
|
|
||||||
b=h->vlastnosti[i]*h->bonus/vlssuma;
|
|
||||||
h->bonus-=b;vlssuma-=h->vlastnosti[i];
|
|
||||||
while (b--) advance_vls(i);
|
|
||||||
}
|
|
||||||
prepocitat_postavu(human_selected);
|
|
||||||
}
|
|
||||||
human_selected->jidlo=(int)(mh*MAX_HLAD(human_selected));
|
|
||||||
human_selected->voda=(int)(mv*MAX_ZIZEN(human_selected));
|
|
||||||
wzprintf("%s ziskal%s uroven cislo %d\r\n",h->jmeno,h->female?"a":"",level);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern char folow_mode;
|
|
||||||
extern char folow_mob;
|
|
||||||
void macro_drop_item();
|
|
||||||
|
|
||||||
static char take_money()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (!wzscanf("Kolik: (0 - zrusit):","%d",&i)) return 0;
|
|
||||||
money+=i;
|
|
||||||
if (i)
|
|
||||||
{
|
|
||||||
SEND_LOG("(WIZARD) Take Money %d, total %d",i,money);
|
|
||||||
}
|
|
||||||
return (i!=0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ALL "ALL"
|
|
||||||
static char purge_map()
|
|
||||||
{
|
|
||||||
char buffer[200];
|
|
||||||
char *c;
|
|
||||||
|
|
||||||
STOP();
|
|
||||||
/* struct find_t rc;
|
|
||||||
int rs;
|
|
||||||
|
|
||||||
concat(c,pathtable[SR_TEMP],"*.TMP");
|
|
||||||
rs=_dos_findfirst(c,_A_NORMAL,&rc);
|
|
||||||
while (rs==0)
|
|
||||||
{
|
|
||||||
if (rc.name[0]!='~') wzputs(rc.name);
|
|
||||||
rs=_dos_findnext(&rc);
|
|
||||||
}
|
|
||||||
_dos_findclose(&rc);*/
|
|
||||||
wzprintf("\r\n Zadej jmeno tempu (all - vse):");gets(buffer);
|
|
||||||
if (buffer[0]==0) return 0;
|
|
||||||
strupper(buffer);
|
|
||||||
concat(c,pathtable[SR_TEMP],buffer);
|
|
||||||
if (strcmp(buffer,ALL) && check_file_exists_ex(c))
|
|
||||||
{
|
|
||||||
wzputs("Soubor nenalezen!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SEND_LOG("(WIZARD) Purge Map: '%s'",buffer,0);
|
|
||||||
if (!strcmp(buffer,ALL)) purge_temps(0);
|
|
||||||
else remove(c);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char heal_meditate(void)
|
|
||||||
{
|
|
||||||
int a,b,i;
|
|
||||||
THUMAN *p;
|
|
||||||
|
|
||||||
if (!wzscanf("Obnovit postavu c: (0 - vsechny, -1 - zrusit):","%d",&b)) return 0;
|
|
||||||
if (b==-1) return 0;
|
|
||||||
if (b) a=b-1;else a=0,b=POCET_POSTAV;
|
|
||||||
p=postavy+a;
|
|
||||||
for(i=a;i<b;i++,p++) if (p->used && p->lives)
|
|
||||||
{
|
|
||||||
p->lives=p->vlastnosti[VLS_MAXHIT];
|
|
||||||
p->mana=p->vlastnosti[VLS_MAXMANA];
|
|
||||||
p->kondice=p->vlastnosti[VLS_KONDIC];
|
|
||||||
p->jidlo=MAX_HLAD(p);
|
|
||||||
p->voda=MAX_ZIZEN(p);
|
|
||||||
SEND_LOG("(WIZARD) Restoring character '%s'",p->jmeno,0);
|
|
||||||
bott_draw(1);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char raise_death(void)
|
|
||||||
{
|
|
||||||
int b;
|
|
||||||
THUMAN *p;
|
|
||||||
char *c,*d;
|
|
||||||
|
|
||||||
if (!wzscanf("Obzivit postavu c: (0 a -1 - zrusit):","%d",&b)) return 0;
|
|
||||||
b--;
|
|
||||||
if (b<0) return 0;
|
|
||||||
p=postavy+b;
|
|
||||||
p->lives=p->vlastnosti[VLS_MAXHIT];
|
|
||||||
p->mana=p->vlastnosti[VLS_MAXMANA];
|
|
||||||
p->kondice=p->vlastnosti[VLS_KONDIC];
|
|
||||||
c="(WIZARD) '%s' has been returned to game by gods power!";d=strchr(c,'\'');
|
|
||||||
wzprintf(d,p->jmeno);putchar('\r\n');
|
|
||||||
bott_draw(1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static char raise_killed_monster(HWND hDlg)
|
|
||||||
{
|
|
||||||
HWND listdlg=PrepareListWindow(hDlg);
|
|
||||||
HWND list=GetDlgItem(listdlg,IDC_LIST);
|
|
||||||
char buff[256];
|
|
||||||
int i;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
for (i=0;i<MAX_MOBS;i++) if (~mobs[i].vlajky & MOB_LIVE && mobs[i].cislo_vzoru!=0)
|
|
||||||
{
|
|
||||||
int p;
|
|
||||||
_snprintf(buff,sizeof(buff),"%4d. %s (sector: %d home %d)",i,mobs[i].name,mobs[i].sector,mobs[i].home_pos);
|
|
||||||
kamenik2windows(buff,strlen(buff),buff);
|
|
||||||
p=ListBox_AddString(list,buff);
|
|
||||||
ListBox_SetItemData(list,p,i);
|
|
||||||
}
|
|
||||||
res=PumpDialogMessages(listdlg);
|
|
||||||
while (res==IDOK)
|
|
||||||
{
|
|
||||||
int cnt;
|
|
||||||
for (i=0,cnt=ListBox_GetCount(list);i<cnt;i++) if (ListBox_GetSel(list,i))
|
|
||||||
{
|
|
||||||
int idx=ListBox_GetItemData(list,i);
|
|
||||||
mobs[idx].vlajky|=MOB_LIVE;
|
|
||||||
mobs[idx].lives=mobs[idx].vlastnosti[VLS_MAXHIT];
|
|
||||||
wzprintf("%s znovu povstal(a)\r\n",mobs[idx].name);
|
|
||||||
SEND_LOG("(WIZARD) '%s' has been raised",mobs[idx].name,0);
|
|
||||||
}
|
|
||||||
res=PumpDialogMessages(listdlg);
|
|
||||||
}
|
|
||||||
CloseListWindow(listdlg);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char advance_weapon()
|
|
||||||
{
|
|
||||||
int p,i;
|
|
||||||
char buff[128];
|
|
||||||
THUMAN *h;
|
|
||||||
if (!wzscanf("Cislo postavy: (0 = Zpet)","%d",&p)) return 0;
|
|
||||||
if (p==0) return 0;
|
|
||||||
h=postavy+p-1;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int bonus, value;
|
|
||||||
for(i=0;i<TPW_MAX;i++) wzprintf("%d. %-15s: %2d Exp %5d\r\n",i+1,texty[91+i],h->bonus_zbrani[i],h->weapon_expy[i]);
|
|
||||||
if (!wzscanf("<Zbran> <Hodnota>","%[^\n]",buff)) return 0;
|
|
||||||
if (buff[0]==0) return 0;
|
|
||||||
if (sscanf(buff,"%d %d",&bonus,&value)!=2) wzputs("Huh?!");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bonus--;
|
|
||||||
if (bonus<0 || bonus>=TPW_MAX) wzputs("Spatna zbran");
|
|
||||||
else
|
|
||||||
if (value<0 || value>=10) wzputs("Spatna hodnota");
|
|
||||||
else
|
|
||||||
h->bonus_zbrani[bonus]=value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static reload_mobs()
|
|
||||||
{
|
|
||||||
extern char reset_mobiles;
|
|
||||||
reset_mobiles=1;
|
|
||||||
strcopy_n(loadlevel.name,level_fname,12);
|
|
||||||
loadlevel.start_pos=viewsector;
|
|
||||||
loadlevel.name[12]=0;
|
|
||||||
loadlevel.dir=viewdir;
|
|
||||||
send_message(E_CLOSE_MAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static char display_game_status(void)
|
static char display_game_status(void)
|
||||||
|
@ -319,44 +117,39 @@ static char display_game_status(void)
|
||||||
TSECTOR *ss;
|
TSECTOR *ss;
|
||||||
int i,cn,astr;
|
int i,cn,astr;
|
||||||
|
|
||||||
SEND_LOG("(WIZARD) Starting wizard window at Sect %d Side %d",viewsector,viewdir);
|
wzprintf("Sector: %5d Dir: %d Group %d \n",viewsector,viewdir,cur_group);
|
||||||
wzprintf("Sektor: %5d Smer: %d Skupina %d \r\n",viewsector,viewdir,cur_group);
|
for(i=0,p=postavy;i<POCET_POSTAV;i++,p++) {
|
||||||
for(i=0,p=postavy;i<POCET_POSTAV;i++,p++)
|
if (p->used) {
|
||||||
if (p->used)
|
wzprintf("%d.%-14s (%d) Sek:%5d Smr:%d HPReg:%d MPReg:%d VPReg:%d %04X%s\n",i+1,p->jmeno,p->groupnum,p->sektor,p->direction,p->vlastnosti[VLS_HPREG],
|
||||||
wzprintf("%d.%-14s (%d) Sek:%5d Smr:%d HPReg:%d MPReg:%d VPReg:%d %04X%s\r\n",i+1,p->jmeno,p->groupnum,p->sektor,p->direction,p->vlastnosti[VLS_HPREG],
|
p->vlastnosti[VLS_MPREG], p->vlastnosti[VLS_VPREG], p->vlastnosti[VLS_KOUZLA], p->lives?"":"(dead)");
|
||||||
p->vlastnosti[VLS_MPREG], p->vlastnosti[VLS_VPREG], p->vlastnosti[VLS_KOUZLA], p->lives?"":"(smrt)");
|
}
|
||||||
else
|
}
|
||||||
wzprintf("%d. (nepouzito)\r\n",i);
|
wzprintf("Held items: ");
|
||||||
wzputs("");
|
|
||||||
wzprintf("Predmet(y) v mysi: ");
|
|
||||||
v=picked_item;
|
v=picked_item;
|
||||||
if (v==NULL) wzprintf("<zadne>");else while(*v) wzprintf("%d ",abs(*v++)-1);
|
if (v==NULL) wzprintf("<none>\n");else while(*v) wzprintf("%d \n",abs(*v++)-1);
|
||||||
wzputs("\r\n");
|
|
||||||
for(i=0,cn=0,astr=0;i<MAX_MOBS;i++)
|
for(i=0,cn=0,astr=0;i<MAX_MOBS;i++)
|
||||||
{
|
{
|
||||||
if (mobs[i].vlajky & MOB_LIVE) cn++;
|
if (mobs[i].vlajky & MOB_LIVE) cn++;
|
||||||
if (mobs[i].vlajky & MOB_MOBILE) astr++;
|
if (mobs[i].vlajky & MOB_MOBILE) astr++;
|
||||||
}
|
}
|
||||||
wzprintf("Celkem potvor ve hre: %5d (+%d) astral mobiles\r\n"
|
wzprintf("Total monsters: %5d (+%d astral)\n"
|
||||||
"Celkem predmetu ve hre:%5d\r\n"
|
"Total items: %5d (+%d clones)\n",cn-astr,astr,item_count,item_count-it_count_orgn);
|
||||||
" .. z toho klonu: %5d\r\n",cn-astr,astr,item_count,item_count-it_count_orgn);
|
|
||||||
|
|
||||||
wzputs("");
|
|
||||||
ss=map_sectors+viewsector;
|
ss=map_sectors+viewsector;
|
||||||
s=map_sides+viewsector*4+viewdir;
|
s=map_sides+viewsector*4+viewdir;
|
||||||
wzprintf("Sector: (%d) Podlaha %d Strop %d Cil akce %d Smer akce %d Akce %d\r\n",
|
wzprintf("Sector: (%d) Floor %d Ceil %d Action target %d Action side %d Action ID %d\r\n",
|
||||||
ss->sector_type, ss->floor,ss->ceil,ss->sector_tag,ss->side_tag,ss->action);
|
ss->sector_type, ss->floor,ss->ceil,ss->sector_tag,ss->side_tag,ss->action);
|
||||||
wzprintf(" Vychody: Sev %d Vych %d Jih %d Z<>p %d\r\n",ss->step_next[0],ss->step_next[1],ss->step_next[2],ss->step_next[3]);
|
wzprintf(" Exits: North %d East %d South %d West %d\n",ss->step_next[0],ss->step_next[1],ss->step_next[2],ss->step_next[3]);
|
||||||
wzprintf(" Vlajky: %02X %02X ",ss->flags,map_coord[viewsector].flags);show_flags(map_coord[viewsector].flags,mc_flags,12);
|
wzprintf(" FLAGS: %02X %02X ",ss->flags,map_coord[viewsector].flags);
|
||||||
wzputs("\r\n");
|
show_flags(map_coord[viewsector].flags,mc_flags,12);
|
||||||
wzprintf("Stena: Prim %d Sec %d Obl %d Anim_prim %d/%d Anim_sec %d/%d\r\n",
|
wzprintf("\nSide: Prim %d Sec %d Arc %d Anim_prim %d/%d Anim_sec %d/%d\n",
|
||||||
s->prim,s->sec,s->oblouk & 0xf,s->prim_anim>>4,s->prim_anim & 0xf,s->sec_anim>>4,s->sec_anim & 0xf);
|
s->prim,s->sec,s->oblouk & 0xf,s->prim_anim>>4,s->prim_anim & 0xf,s->sec_anim>>4,s->sec_anim & 0xf);
|
||||||
wzprintf(" Cil akce %d Smer akce %d Akce %d\r\n",s->action,s->sector_tag,s->side_tag & 0x3);
|
wzprintf(" Action target %d Action side %d Action %d\n",s->action,s->sector_tag,s->side_tag & 0x3);
|
||||||
wzprintf(" Multiakce: %s\r\n",macros[viewsector*4+viewdir].action_list==NULL?"<zadna>":"Existuje");
|
wzprintf(" Multiaction: %s\n",macros[viewsector*4+viewdir].action_list==NULL?"No":"Yes");
|
||||||
wzprintf(" Vlajky: %04X %02X %02X ",s->flags,s->oblouk>>4,s->side_tag>>2);
|
wzprintf(" Flags: %04X %02X %02X\n",s->flags,s->oblouk>>4,s->side_tag>>2);
|
||||||
wzputs("");
|
|
||||||
show_flags(s->flags,side_flags,32);
|
show_flags(s->flags,side_flags,32);
|
||||||
show_flags(s->oblouk>>4,obl_flags,4);
|
show_flags(s->oblouk>>4,obl_flags,4);
|
||||||
|
wzprintf("\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +165,7 @@ extern char pass_all_mobs;
|
||||||
static char console_input_line[console_max_characters+1] = "";
|
static char console_input_line[console_max_characters+1] = "";
|
||||||
static char *console_output_lines[console_max_lines] = {};
|
static char *console_output_lines[console_max_lines] = {};
|
||||||
static int console_top_line = 0;
|
static int console_top_line = 0;
|
||||||
|
static const char *console_command = NULL;
|
||||||
|
|
||||||
static const int console_x = 0;
|
static const int console_x = 0;
|
||||||
static const int console_y = SCREEN_OFFLINE;
|
static const int console_y = SCREEN_OFFLINE;
|
||||||
|
@ -415,11 +209,27 @@ char console_is_visible() {
|
||||||
return console_visible;
|
return console_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void console_add_line(const char *line) {
|
static void console_add_line(const char *line);
|
||||||
|
|
||||||
|
static void flush_console_command() {
|
||||||
|
if (console_command) {
|
||||||
|
const char *cmd = concat2("> ", console_command);
|
||||||
|
console_command = NULL;
|
||||||
|
console_add_line(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void console_add_line_s(const char *line, size_t sz) {
|
||||||
|
flush_console_command();
|
||||||
free(console_output_lines[console_max_lines-1]);
|
free(console_output_lines[console_max_lines-1]);
|
||||||
memmove(console_output_lines+1,console_output_lines, (console_max_lines-1)*sizeof(char *));
|
memmove(console_output_lines+1,console_output_lines, (console_max_lines-1)*sizeof(char *));
|
||||||
console_output_lines[0] = strdup(line);
|
console_output_lines[0] = malloc(sz+1);
|
||||||
|
memcpy(console_output_lines[0], line, sz);
|
||||||
|
console_output_lines[0][sz] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void console_add_line(const char *line) {
|
||||||
|
console_add_line_s(line, strlen(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -527,6 +337,10 @@ static int process_on_off_command(const char *cmd, char on) {
|
||||||
dead_food = on;
|
dead_food = on;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (istrcmp(cmd, "trace-dialogs") == 0) {
|
||||||
|
trace_dialogs = on;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,6 +459,20 @@ static int process_actions(const char *command) {
|
||||||
load_map(lname);
|
load_map(lname);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (istrcmp(command, "steam") == 0) {
|
||||||
|
if (is_steam_available()) {
|
||||||
|
char *c = get_steam_status();;
|
||||||
|
wzputs(c);
|
||||||
|
free(c);
|
||||||
|
} else {
|
||||||
|
wzputs("N/A");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (istrcmp(command,"help") == 0) {
|
||||||
|
wzputs("Help has left the chat. Try the forums, brave wanderer. Set your inner-eye on");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -741,6 +569,34 @@ static int process_with_params(const char *cmd, const char *args) {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (istrcmp(cmd, "achieve") == 0) {
|
||||||
|
return !set_achievement(args);
|
||||||
|
}
|
||||||
|
if (istrcmp(cmd, "unachieve") == 0) {
|
||||||
|
return !clear_achievement(args);
|
||||||
|
}
|
||||||
|
if (istrcmp(cmd, "talk") == 0) {
|
||||||
|
if (args[0] == 0) return 0;
|
||||||
|
int id;
|
||||||
|
char pgf = 0;
|
||||||
|
if (args[0] == '/') {
|
||||||
|
pgf = 1;
|
||||||
|
args++;
|
||||||
|
}
|
||||||
|
id = atoi(args);
|
||||||
|
if (!pgf) id = id * 128;
|
||||||
|
if (dialog_is_paragraph(id)) {
|
||||||
|
call_dialog(id, -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (istrcmp(cmd, "unvisit") == 0) {
|
||||||
|
if (args[0] == 0) return 0;
|
||||||
|
int id = atoi(args);
|
||||||
|
return dialog_set_notvisited(id);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,13 +637,15 @@ static void console_keyboard(EVENT_MSG *msg, void **_) {
|
||||||
}
|
}
|
||||||
msg->msg = -1;
|
msg->msg = -1;
|
||||||
} else if (c == '\r') {
|
} else if (c == '\r') {
|
||||||
|
console_command = console_input_line;
|
||||||
PARSED_COMMAND cmd = parse_command(console_input_line);
|
PARSED_COMMAND cmd = parse_command(console_input_line);
|
||||||
char ok = process_command(cmd);
|
char ok = process_command(cmd);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
console_add_line(console_input_line);
|
flush_console_command();
|
||||||
console_top_line = 0;
|
console_top_line = 0;
|
||||||
console_input_line[0] = 0;
|
console_input_line[0] = 0;
|
||||||
}
|
}
|
||||||
|
console_command = NULL;
|
||||||
free(cmd.cmd_buffer);
|
free(cmd.cmd_buffer);
|
||||||
msg->msg = -1;
|
msg->msg = -1;
|
||||||
} else if (c >=32 && len < console_max_characters) {
|
} else if (c >=32 && len < console_max_characters) {
|
||||||
|
@ -856,7 +714,13 @@ void wzprintf(const char *text,...)
|
||||||
|
|
||||||
static void wzputs(const char *text)
|
static void wzputs(const char *text)
|
||||||
{
|
{
|
||||||
console_add_line(text);
|
const char *sep = strchr(text, '\n');
|
||||||
|
while (sep != NULL) {
|
||||||
|
console_add_line_s(text, sep-text);
|
||||||
|
text = sep+1;
|
||||||
|
sep = strchr(text, '\n');
|
||||||
|
}
|
||||||
|
if (text[0] != 0) console_add_line_s(text, strlen(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,8 @@ static int dialog_mob=0;
|
||||||
|
|
||||||
static char code_page=1;
|
static char code_page=1;
|
||||||
|
|
||||||
|
char trace_dialogs=0;
|
||||||
|
|
||||||
static char case_click(int id,int xa,int ya,int xr,int yr);
|
static char case_click(int id,int xa,int ya,int xr,int yr);
|
||||||
static char ask_who_proc(int id,int xa,int ya,int xr,int yr);
|
static char ask_who_proc(int id,int xa,int ya,int xr,int yr);
|
||||||
|
|
||||||
|
@ -222,11 +224,7 @@ static void run_anim(char *name,int speed,int rep)
|
||||||
|
|
||||||
static void error(char *text)
|
static void error(char *text)
|
||||||
{
|
{
|
||||||
char buff[256];
|
wzprintf("%.125s paragraph %d\r\nLocal_pgf=%d / DIALOG : %d / SENTENCE : %d\r\n",text,last_pgf+local_pgf,local_pgf,local_pgf/128,last_pgf);
|
||||||
sprintf(buff,"%.125s v odstavci %d\r\nLocal_pgf=%d / DIALOG : %d / SENTENCE : %d\r\n",text,last_pgf+local_pgf,local_pgf,local_pgf/128,last_pgf);
|
|
||||||
// MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
|
|
||||||
SEND_LOG("(DIALOGS) Dialog error detected at %d:%d",local_pgf/128,last_pgf);
|
|
||||||
SEND_LOG("(DIALOGS) Error description: %s",text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_dialog_picture()
|
static void show_dialog_picture()
|
||||||
|
@ -253,7 +251,7 @@ static T_PARAGRAPH *find_paragraph(int num)
|
||||||
{
|
{
|
||||||
char s[80];
|
char s[80];
|
||||||
|
|
||||||
sprintf(s,"Odstavec %d neexistuje! Odkaz byl vyvol<6F>n",num);
|
sprintf(s,"Paragraph %d doesn't exists! Called from",num);
|
||||||
error(s);
|
error(s);
|
||||||
return (T_PARAGRAPH *)pp;
|
return (T_PARAGRAPH *)pp;
|
||||||
}
|
}
|
||||||
|
@ -283,6 +281,7 @@ static void goto_paragraph(int prgf)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
z=find_paragraph(prgf);
|
z=find_paragraph(prgf);
|
||||||
|
if (trace_dialogs) wzprintf("Dialog goto_paragraph %d (visited=%d)\n",prgf+local_pgf, z->visited);
|
||||||
if (z->visited) z->first=1;
|
if (z->visited) z->first=1;
|
||||||
if (z->alt==z->num || !z->visited)
|
if (z->alt==z->num || !z->visited)
|
||||||
{
|
{
|
||||||
|
@ -1507,3 +1506,20 @@ char load_dialog_info(TMPFILE_RD *f)
|
||||||
SEND_LOG("(DIALOGS)(SAVELOAD) Done...");
|
SEND_LOG("(DIALOGS)(SAVELOAD) Done...");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char dialog_is_paragraph(int id) {
|
||||||
|
const int *pp=(const int *)ablock(H_DIALOGY_DAT);
|
||||||
|
int pocet=*pp;
|
||||||
|
pp+=2;
|
||||||
|
const T_PARAGRAPH *z=(const T_PARAGRAPH *)pp;
|
||||||
|
for(int i=0;i<pocet;i++,z++) if (z->num==(unsigned)id) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char dialog_set_notvisited(int pgf) {
|
||||||
|
local_pgf = 0;
|
||||||
|
if (!dialog_is_paragraph(pgf)) return 0;
|
||||||
|
set_nvisited(pgf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1738,7 +1738,9 @@ short *q_item_one(int i,int itnum); //test zda postava i ma vec itnum
|
||||||
short *q_item(int itnum,int sector); //test zda-li aspon jeden na sectoru ma vec itnum
|
short *q_item(int itnum,int sector); //test zda-li aspon jeden na sectoru ma vec itnum
|
||||||
void change_flag(int flag,char mode); //meni vlajku = 0 - reset, 1 - set, 2 - neg
|
void change_flag(int flag,char mode); //meni vlajku = 0 - reset, 1 - set, 2 - neg
|
||||||
char test_flag(int flag); //vraci stav vlajky;
|
char test_flag(int flag); //vraci stav vlajky;
|
||||||
|
char dialog_is_paragraph(int id); //vraci zda-li je id dialogem
|
||||||
|
char dialog_set_notvisited(int pgf); //nastavi ze stranka nebyla navstivena
|
||||||
|
extern char trace_dialogs;
|
||||||
|
|
||||||
|
|
||||||
//generator
|
//generator
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <platform/platform.h>
|
#include <platform/platform.h>
|
||||||
|
#include <platform/achievements.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -723,7 +724,7 @@ void do_timer(void)
|
||||||
|
|
||||||
void done_skeldal(void)
|
void done_skeldal(void)
|
||||||
{
|
{
|
||||||
|
achievements_shutdown();
|
||||||
|
|
||||||
close_manager();
|
close_manager();
|
||||||
close_story_file();
|
close_story_file();
|
||||||
|
@ -987,7 +988,9 @@ void init_skeldal(const INI_CONFIG *cfg)
|
||||||
|
|
||||||
cti_texty();
|
cti_texty();
|
||||||
timer_tree.next=NULL;
|
timer_tree.next=NULL;
|
||||||
init_events();
|
init_events();
|
||||||
|
|
||||||
|
achievements_init();
|
||||||
|
|
||||||
char verr = game_display_init(ini_section_open(cfg, "video"), "Skeldal");
|
char verr = game_display_init(ini_section_open(cfg, "video"), "Skeldal");
|
||||||
if (!verr)
|
if (!verr)
|
||||||
|
|
|
@ -209,7 +209,7 @@ Attack 4-7, Defense 1-2"
|
||||||
"
|
"
|
||||||
104,"Scales of Fate
|
104,"Scales of Fate
|
||||||
"
|
"
|
||||||
105,"Potion – White
|
105,"Potion <EFBFBD> White
|
||||||
"
|
"
|
||||||
106,"Automapping
|
106,"Automapping
|
||||||
"
|
"
|
||||||
|
@ -250,7 +250,7 @@ Gift from the Talking Tree"
|
||||||
"
|
"
|
||||||
125,"Tree Trunk
|
125,"Tree Trunk
|
||||||
"
|
"
|
||||||
126,"Potion – Green
|
126,"Potion <EFBFBD> Green
|
||||||
"
|
"
|
||||||
127,"Haste Potion
|
127,"Haste Potion
|
||||||
"
|
"
|
||||||
|
@ -258,14 +258,14 @@ Gift from the Talking Tree"
|
||||||
"
|
"
|
||||||
129,"Chill Potion
|
129,"Chill Potion
|
||||||
"
|
"
|
||||||
130,"Silver Jug – Empty
|
130,"Silver Jug <EFBFBD> Empty
|
||||||
"
|
"
|
||||||
131,"Golden Jug – Empty
|
131,"Golden Jug <EFBFBD> Empty
|
||||||
"
|
"
|
||||||
132,"Silver Jug
|
132,"Silver Jug
|
||||||
Filled with Water from the Spring of Death"
|
Filled from the Spring of Death"
|
||||||
133,"Golden Jug
|
133,"Golden Jug
|
||||||
Filled with Water from the Spring of Life"
|
Filled from the Spring of Life"
|
||||||
134,"Mushroom
|
134,"Mushroom
|
||||||
"
|
"
|
||||||
135,"Tworg Fur Coat
|
135,"Tworg Fur Coat
|
||||||
|
@ -300,9 +300,9 @@ Fire Protection +40%"
|
||||||
"
|
"
|
||||||
150,"Heart of the Earth
|
150,"Heart of the Earth
|
||||||
"
|
"
|
||||||
151,"Water from Queen Mithel's Fountain
|
151,"Queen Mithel's Water
|
||||||
"
|
"
|
||||||
152,"Scroll of the Thought of Victory
|
152,"Scroll of Thought of Victory
|
||||||
"
|
"
|
||||||
153,"Sword of Retribution
|
153,"Sword of Retribution
|
||||||
Quest item"
|
Quest item"
|
||||||
|
@ -323,7 +323,7 @@ Attack 9-11, Air 9-13, Def. +3"
|
||||||
161,"Long War Spear
|
161,"Long War Spear
|
||||||
Attack 5-7, Defense 3-5"
|
Attack 5-7, Defense 3-5"
|
||||||
162,"Axe with Enekra's Blessing
|
162,"Axe with Enekra's Blessing
|
||||||
Attack 10-12, Earth 9-14, Protection +2"
|
Attack 10-12, Earth 9-14, Prot. +2"
|
||||||
163,"Destroyed Axe
|
163,"Destroyed Axe
|
||||||
"
|
"
|
||||||
164,"Destroyed Shield
|
164,"Destroyed Shield
|
||||||
|
@ -338,7 +338,7 @@ Defense +8, Elements +20%"
|
||||||
Attack 9-11, Air 8-10"
|
Attack 9-11, Air 8-10"
|
||||||
169,"Shater's Crossbow
|
169,"Shater's Crossbow
|
||||||
Attack 9-13, Air 10-12"
|
Attack 9-13, Air 10-12"
|
||||||
170,"Helmet of Invisibility Invisibility
|
170,"Helmet of Invisibility
|
||||||
"
|
"
|
||||||
171,"Potion of Strength
|
171,"Potion of Strength
|
||||||
"
|
"
|
||||||
|
|
|
|
@ -39,7 +39,7 @@ id,string
|
||||||
43,Cancel
|
43,Cancel
|
||||||
44,Escape
|
44,Escape
|
||||||
45,Rearm
|
45,Rearm
|
||||||
46,State
|
46,Wait
|
||||||
47,Magic
|
47,Magic
|
||||||
48,Start
|
48,Start
|
||||||
49,Throw
|
49,Throw
|
||||||
|
|
|
|
@ -11,6 +11,7 @@ target_sources(skeldal_platform PRIVATE
|
||||||
error.cpp
|
error.cpp
|
||||||
timer.cpp
|
timer.cpp
|
||||||
getopt.c
|
getopt.c
|
||||||
|
achievements.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(all_libs
|
set(all_libs
|
||||||
|
@ -19,7 +20,7 @@ set(all_libs
|
||||||
skeldal_platform
|
skeldal_platform
|
||||||
skeldal_sdl
|
skeldal_sdl
|
||||||
skeldal_libs
|
skeldal_libs
|
||||||
${SDL2_LIBRARIES}
|
${SDL2_LIBRARIES}
|
||||||
${STANDARD_LIBRARIES})
|
${STANDARD_LIBRARIES})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -34,7 +35,24 @@ if(WIN32)
|
||||||
windows/skeldal.rc
|
windows/skeldal.rc
|
||||||
)
|
)
|
||||||
target_compile_definitions(skeldal_platform PRIVATE PLATFORM_WINDOWS)
|
target_compile_definitions(skeldal_platform PRIVATE PLATFORM_WINDOWS)
|
||||||
target_link_libraries(skeldal ${all_libs})
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
# 64-bit
|
||||||
|
set(STEAMLIB ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api64.lib)
|
||||||
|
set(STEAMDLL ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api64.dll)
|
||||||
|
target_compile_definitions(skeldal_platform PRIVATE PLATFORM_WINDOWS_64)
|
||||||
|
else()
|
||||||
|
# 32-bit
|
||||||
|
set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/win32/steam_api.lib)
|
||||||
|
set(STEAMDLL ${STEAMWORKS_SDK_DIR}redistributable_bin/win64/steam_api.dll)
|
||||||
|
target_compile_definitions(skeldal_platform PRIVATE PLATFORM_WINDOWS_32)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(skeldal ${all_libs} ${STEAMLIB})
|
||||||
|
|
||||||
|
add_custom_command(TARGET skeldal POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
${STEAMDLL} $<TARGET_FILE_DIR:skeldal>
|
||||||
|
)
|
||||||
|
|
||||||
message(STATUS "Building for Windows")
|
message(STATUS "Building for Windows")
|
||||||
|
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
|
@ -46,13 +64,22 @@ elseif(UNIX AND NOT APPLE)
|
||||||
target_sources(skeldal_bin PRIVATE
|
target_sources(skeldal_bin PRIVATE
|
||||||
linux/app_start.cpp
|
linux/app_start.cpp
|
||||||
)
|
)
|
||||||
target_compile_definitions(skeldal_platform PRIVATE PLATFORM_LINUX)
|
target_compile_definitions(skeldal_bin PRIVATE PLATFORM_LINUX)
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
# 64-bit
|
||||||
|
set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/linux64/libsteam_api.so)
|
||||||
|
target_compile_definitions(skeldal_bin PRIVATE PLATFORM_LINUX_64)
|
||||||
|
else()
|
||||||
|
# 32-bit
|
||||||
|
set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/linux32/libsteam_api.so)
|
||||||
|
target_compile_definitions(skeldal_bin PRIVATE PLATFORM_LINUX_32)
|
||||||
|
endif()
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET skeldal_bin POST_BUILD
|
TARGET skeldal_bin POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
${CMAKE_CURRENT_LIST_DIR}/linux/skeldal.sh
|
${CMAKE_CURRENT_LIST_DIR}/linux/skeldal.sh
|
||||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/skeldal.sh)
|
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/skeldal.sh)
|
||||||
target_link_libraries(skeldal_bin ${all_libs})
|
target_link_libraries(skeldal_bin ${all_libs} ${STEAMLIB})
|
||||||
message(STATUS "Building for Linux")
|
message(STATUS "Building for Linux")
|
||||||
|
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
|
@ -64,8 +91,10 @@ elseif(APPLE)
|
||||||
linux/app_start.cpp
|
linux/app_start.cpp
|
||||||
)
|
)
|
||||||
target_compile_definitions(mylib PRIVATE PLATFORM_MACOS)
|
target_compile_definitions(mylib PRIVATE PLATFORM_MACOS)
|
||||||
|
set(STEAMLIB ${STEAMWORKS_SDK_DIR}/redistributable_bin/osx/libsteam_api.dylib)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
|
||||||
message(STATUS "Building for macOS")
|
message(STATUS "Building for macOS")
|
||||||
target_link_libraries(skeldal ${all_libs})
|
target_link_libraries(skeldal ${all_libs} ${STEAMLIB})
|
||||||
else()
|
else()
|
||||||
error("Platform not detected, please add new platform here")
|
error("Platform not detected, please add new platform here")
|
||||||
endif()
|
endif()
|
||||||
|
|
103
platform/achievements.cpp
Normal file
103
platform/achievements.cpp
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
#include "achievements.h"
|
||||||
|
#include <steam/steam_api.h>
|
||||||
|
#include "error.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <libs/event.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
static char steam_available = 0;
|
||||||
|
static char steam_initialized = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void run_steam_callbacks(const EVENT_MSG *msg,void **) {
|
||||||
|
if (msg->msg == E_IDLE) {
|
||||||
|
SteamAPI_RunCallbacks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void achievements_init()
|
||||||
|
{
|
||||||
|
if (!steam_initialized) {
|
||||||
|
steam_initialized = 1;
|
||||||
|
steam_available = SteamAPI_Init();
|
||||||
|
if (steam_available) {
|
||||||
|
send_message(E_ADD, E_IDLE, &run_steam_callbacks);
|
||||||
|
SteamUserStats()->RequestUserStats(SteamUser()->GetSteamID());
|
||||||
|
} else {
|
||||||
|
steam_available = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void achievements_shutdown()
|
||||||
|
{
|
||||||
|
if (steam_available) {
|
||||||
|
send_message(E_DONE, E_IDLE, &run_steam_callbacks);
|
||||||
|
SteamAPI_Shutdown();
|
||||||
|
steam_available = 0;
|
||||||
|
steam_initialized = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t set_achievement(const char *id)
|
||||||
|
{
|
||||||
|
achievements_init();
|
||||||
|
|
||||||
|
if (!steam_available) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamUserStats() && SteamUserStats()->SetAchievement(id)) {
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t clear_achievement(const char *id)
|
||||||
|
{
|
||||||
|
achievements_init();
|
||||||
|
|
||||||
|
if (!steam_available) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamUserStats() && SteamUserStats()->ClearAchievement(id)) {
|
||||||
|
SteamUserStats()->StoreStats();
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char is_steam_available()
|
||||||
|
{
|
||||||
|
return steam_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *get_steam_status()
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
int num_achievements = SteamUserStats()->GetNumAchievements();
|
||||||
|
oss << "SteamAPI_Init: " << ( SteamAPI_Init() ? "success" : "failure") << "\n";
|
||||||
|
oss << "UserStats pointer: " << SteamUserStats() << "\n";
|
||||||
|
oss << "Is Steam overlay enabled:" << (SteamUtils()->IsOverlayEnabled() ? "yes" : "no") << "\n";
|
||||||
|
oss << "AppID: "<< SteamUtils()->GetAppID() << "\n";
|
||||||
|
oss << "Num Achievements: " << num_achievements << "\n";
|
||||||
|
for (int i = 0; i < num_achievements; ++i) {
|
||||||
|
const char* name = SteamUserStats()->GetAchievementName(i);
|
||||||
|
bool achieved = false;
|
||||||
|
SteamUserStats()->GetAchievement(name, &achieved);
|
||||||
|
|
||||||
|
oss << "[" << i << "] " << name << " - " << (achieved ? "Yes" : "No") << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string str = oss.str();
|
||||||
|
char *out = strdup(str.c_str());
|
||||||
|
return out;
|
||||||
|
}
|
36
platform/achievements.h
Normal file
36
platform/achievements.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialize Steam (if available). Optional to call.
|
||||||
|
// If not called manually, will auto-init on first achievement set.
|
||||||
|
void achievements_init();
|
||||||
|
void achievements_shutdown();
|
||||||
|
|
||||||
|
/// Set an achievement by its API name (if Steam available, otherwise ignored)
|
||||||
|
/**
|
||||||
|
* @param id The API name of the achievement to set.
|
||||||
|
* @return 0 on success, -1 steam is not running (for diagnostic only)
|
||||||
|
*/
|
||||||
|
int8_t set_achievement(const char* id);
|
||||||
|
|
||||||
|
// Clear an achievement by its API name (if Steam available, otherwise ignored)
|
||||||
|
/**
|
||||||
|
* @param id The API name of the achievement to set.
|
||||||
|
* @return 0 on success, -1 steam is not running (for diagnostic only)
|
||||||
|
*/
|
||||||
|
int8_t clear_achievement(const char* id);
|
||||||
|
|
||||||
|
/// returns whether steam is available
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
char is_steam_available();
|
||||||
|
|
||||||
|
char *get_steam_status();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -11,6 +11,15 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <steam/steam_api.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>.
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <chrono>
|
||||||
|
#include <string_view>
|
||||||
|
#include <stop_token>
|
||||||
|
|
||||||
void SDLContext::SDL_Deleter::operator ()(SDL_Window* window) {
|
void SDLContext::SDL_Deleter::operator ()(SDL_Window* window) {
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue