#ifdef MKXPZ_STEAM #include "binding-util.h" #include "steamshim_child.h" #define STEAMSHIM_GETV(t, v, d) \ while (STEAMSHIM_alive()) { \ const STEAMSHIM_Event *e = STEAMSHIM_pump(); \ if (e && e->type == t) { \ d = e->v; \ break; \ } \ } #define STEAMSHIM_GETV_EXP(t, exp) \ while (STEAMSHIM_alive()) { \ const STEAMSHIM_Event *e = STEAMSHIM_pump(); \ if (e && e->type == t) { \ exp; \ break; \ } \ } #define STEAMSHIM_GET_OK(t, d) STEAMSHIM_GETV(t, okay, d) #define STEAMSHIM_GETV_AND_OK(t, v, dst, ok) \ while (STEAMSHIM_alive()) { \ const STEAMSHIM_Event *e = STEAMSHIM_pump(); \ if (e && e->type == t) { \ dst = e->v; \ ok = e->okay; \ break; \ } \ } RB_METHOD_GUARD(CUSLSetStat) { RB_UNUSED_PARAM; VALUE name, stat; rb_scan_args(argc, argv, "2", &name, &stat); SafeStringValue(name); bool ret; if (RB_TYPE_P(stat, RUBY_T_FLOAT)) { STEAMSHIM_setStatF(RSTRING_PTR(name), (float)RFLOAT_VALUE(stat)); STEAMSHIM_GET_OK(SHIMEVENT_SETSTATF, ret); } else if (RB_TYPE_P(stat, RUBY_T_FIXNUM)) { STEAMSHIM_setStatI(RSTRING_PTR(name), (int)NUM2INT(stat)); STEAMSHIM_GET_OK(SHIMEVENT_SETSTATI, ret); } else { throw Exception(Exception::TypeError, "Statistic value must be either an integer or float."); } return rb_bool_new(ret); } RB_METHOD_GUARD_END RB_METHOD(CUSLGetStatI) { RB_UNUSED_PARAM; VALUE name; rb_scan_args(argc, argv, "1", &name); SafeStringValue(name); int resi; bool valid; STEAMSHIM_getStatI(RSTRING_PTR(name)); STEAMSHIM_GETV_AND_OK(SHIMEVENT_GETSTATI, ivalue, resi, valid); if (!valid) return Qnil; return INT2NUM(resi); } RB_METHOD(CUSLGetStatF) { RB_UNUSED_PARAM; VALUE name; rb_scan_args(argc, argv, "1", &name); SafeStringValue(name); float resf; bool valid; STEAMSHIM_getStatI(RSTRING_PTR(name)); STEAMSHIM_GETV_AND_OK(SHIMEVENT_GETSTATI, fvalue, resf, valid); if (!valid) return Qnil; return rb_float_new(resf); } RB_METHOD(CUSLGetAchievement) { RB_UNUSED_PARAM; VALUE name; rb_scan_args(argc, argv, "1", &name); SafeStringValue(name); bool ret; bool valid; STEAMSHIM_getAchievement(RSTRING_PTR(name)); STEAMSHIM_GETV_AND_OK(SHIMEVENT_GETACHIEVEMENT, ivalue, ret, valid); if (!valid) return Qnil; return rb_bool_new(ret); } RB_METHOD(CUSLSetAchievement) { RB_UNUSED_PARAM; VALUE name; rb_scan_args(argc, argv, "1", &name); SafeStringValue(name); bool ret; STEAMSHIM_setAchievement(RSTRING_PTR(name), true); STEAMSHIM_GET_OK(SHIMEVENT_SETACHIEVEMENT, ret); return rb_bool_new(ret); } RB_METHOD(CUSLClearAchievement) { RB_UNUSED_PARAM; VALUE name; rb_scan_args(argc, argv, "1", &name); SafeStringValue(name); bool ret; STEAMSHIM_setAchievement(RSTRING_PTR(name), false); STEAMSHIM_GET_OK(SHIMEVENT_SETACHIEVEMENT, ret); return rb_bool_new(ret); } RB_METHOD(CUSLGetAchievementAndUnlockTime) { RB_UNUSED_PARAM; VALUE name; rb_scan_args(argc, argv, "1", &name); SafeStringValue(name); bool achieved; unsigned long long time; bool valid; STEAMSHIM_getAchievement(RSTRING_PTR(name)); STEAMSHIM_GETV_EXP(SHIMEVENT_GETACHIEVEMENT, { valid = e->okay; achieved = e->ivalue; time = e->epochsecs; }); if (!valid) return Qnil; VALUE ret = rb_ary_new(); rb_ary_push(ret, rb_bool_new(achieved)); if (!time) { rb_ary_push(ret, Qnil); return ret; } VALUE t = rb_funcall(rb_cTime, rb_intern("at"), 1, ULL2NUM(time)); rb_ary_push(ret, t); return ret; } RB_METHOD(CUSLStoreStats) { RB_UNUSED_PARAM; rb_check_argc(argc, 0); bool ok; STEAMSHIM_storeStats(); STEAMSHIM_GET_OK(SHIMEVENT_STATSSTORED, ok); return rb_bool_new(ok); } RB_METHOD(CUSLResetAllStats) { RB_UNUSED_PARAM; bool achievementsToo; rb_get_args(argc, argv, "b", &achievementsToo); STEAMSHIM_resetStats(achievementsToo); STEAMSHIM_GET_OK(SHIMEVENT_RESETSTATS, achievementsToo); return rb_bool_new(achievementsToo); } void CUSLBindingInit() { STEAMSHIM_requestStats(); bool ok; STEAMSHIM_GET_OK(SHIMEVENT_STATSRECEIVED, ok); VALUE mSteamLite = rb_define_module("SteamLite"); _rb_define_module_function(mSteamLite, "get_stat_i", CUSLGetStatI); _rb_define_module_function(mSteamLite, "get_stat_f", CUSLGetStatF); _rb_define_module_function(mSteamLite, "set_stat", CUSLSetStat); _rb_define_module_function(mSteamLite, "store_stats", CUSLStoreStats); _rb_define_module_function(mSteamLite, "get_achievement", CUSLGetAchievement); _rb_define_module_function(mSteamLite, "set_achievement", CUSLSetAchievement); _rb_define_module_function(mSteamLite, "clear_achievement", CUSLClearAchievement); _rb_define_module_function(mSteamLite, "get_achievement_and_unlock_time", CUSLGetAchievementAndUnlockTime); _rb_define_module_function(mSteamLite, "reset_all_stats", CUSLResetAllStats); } #endif