diff --git a/src/spice2x/api/modules/coin.cpp b/src/spice2x/api/modules/coin.cpp index 4f4937de..14e955e5 100644 --- a/src/spice2x/api/modules/coin.cpp +++ b/src/spice2x/api/modules/coin.cpp @@ -61,7 +61,7 @@ namespace api::modules { return error_type(res, "amount", "int"); // add to coin stock - eamuse_coin_set_stock(eamuse_coin_get_stock() + std::max(0, req.params[0].GetInt())); + eamuse_coin_add(std::max(0, req.params[0].GetInt())); } /* diff --git a/src/spice2x/misc/eamuse.cpp b/src/spice2x/misc/eamuse.cpp index d16ee5ea..91186ff8 100644 --- a/src/spice2x/misc/eamuse.cpp +++ b/src/spice2x/misc/eamuse.cpp @@ -331,8 +331,8 @@ int eamuse_coin_consume_stock() { return COIN_STOCK.exchange(0, std::memory_order_relaxed); } -int eamuse_coin_add() { - return COIN_STOCK.fetch_add(1, std::memory_order_relaxed) + 1; +void eamuse_coin_add(int amount) { + COIN_STOCK.fetch_add(amount, std::memory_order_relaxed); } void eamuse_coin_insert() { diff --git a/src/spice2x/misc/eamuse.h b/src/spice2x/misc/eamuse.h index 366ba106..d495b441 100644 --- a/src/spice2x/misc/eamuse.h +++ b/src/spice2x/misc/eamuse.h @@ -59,7 +59,7 @@ void eamuse_coin_set_stock(int amount); bool eamuse_coin_consume(int amount); int eamuse_coin_consume_stock(); -int eamuse_coin_add(); +void eamuse_coin_add(int amount = 1); void eamuse_coin_insert(); void eamuse_pin_macro_start_thread(); diff --git a/src/spice2x/sdk/include/spicesdk.h b/src/spice2x/sdk/include/spicesdk.h index 40450df5..2a52603b 100644 --- a/src/spice2x/sdk/include/spicesdk.h +++ b/src/spice2x/sdk/include/spicesdk.h @@ -237,6 +237,16 @@ typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_add_toast_func)( const char *text ); +// insert_coin (v0.3 and up) +// adds to the shared coin stock, bypassing the coin blocker like the Spice API +// +// amount: number of coins to insert (0 to 255); use 1 for a single coin +// zero succeeds without changing the stock + +typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_insert_coin_func)( + uint8_t amount +); + typedef struct SPICE_SDK_V0 { uint32_t size; @@ -262,6 +272,8 @@ typedef struct SPICE_SDK_V0 { spice_sdk_add_toast_func *add_toast; + spice_sdk_insert_coin_func *insert_coin; + } SPICE_SDK_V0; typedef void (__cdecl spice_sdk_destroy_callback_func)( diff --git a/src/spice2x/sdk/sample/v0/cpp/v0_cpp.cpp b/src/spice2x/sdk/sample/v0/cpp/v0_cpp.cpp index 8511230d..fe7b2e16 100644 --- a/src/spice2x/sdk/sample/v0/cpp/v0_cpp.cpp +++ b/src/spice2x/sdk/sample/v0/cpp/v0_cpp.cpp @@ -76,9 +76,35 @@ static ArrowButton arrow_buttons[] = { // worker thread for I/O static void worker_thread_main(std::stop_token stop_token) { + bool coin_previous_state[10] = {}; while (!stop_token.stop_requested()) { + + // insert coin + const bool control_pressed = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0; + for (uint8_t amount = 0; amount < 10; amount++) { + const bool coin_pressed = control_pressed && + ((GetAsyncKeyState('0' + amount) & 0x8000) != 0); + + if (coin_pressed && !coin_previous_state[amount] && spice.insert_coin) { + const auto status = spice.insert_coin(amount); + if (status != SPICE_SDK_STATUS_SUCCESS) { + LOG_INFO(std::format( + "coin insertion failed: {}", + static_cast(status)).c_str()); + } else { + const auto message = std::format( + "v0_cpp: inserted {} coin{}", amount, amount == 1 ? "" : "s"); + LOG_INFO(message.c_str()); + if (spice.add_toast) { + spice.add_toast(SPICE_SDK_TOAST_LEVEL_SUCCESS, message.c_str()); + } + } + } + coin_previous_state[amount] = coin_pressed; + } + + // check for ctrl + arrow keys and trigger p1 pad arrows for (auto& arrow : arrow_buttons) { - // check for ctrl + arrow keys and trigger p1 pad arrows if (((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) && ((GetAsyncKeyState(arrow.key) & 0x8000) != 0)) { spice.set_button(arrow.button, true, 1.f); @@ -88,7 +114,7 @@ static void worker_thread_main(std::stop_token stop_token) { if (spice.add_toast) { spice.add_toast( SPICE_SDK_TOAST_LEVEL_INFO, - std::format("let me hear you say: {}", arrow.name).c_str()); + std::format("v0_cpp: let me hear you say: {}", arrow.name).c_str()); } else { LOG_INFO(std::format("let me hear you say: {}", arrow.name).c_str()); } diff --git a/src/spice2x/sdk/sdk.cpp b/src/spice2x/sdk/sdk.cpp index e860b525..e61bd059 100644 --- a/src/spice2x/sdk/sdk.cpp +++ b/src/spice2x/sdk/sdk.cpp @@ -31,6 +31,7 @@ static spice_sdk_clear_touch_func sdk_clear_touch; static spice_sdk_insert_card_func sdk_insert_card; static spice_sdk_set_keypad_func sdk_set_keypad; static spice_sdk_add_toast_func sdk_add_toast; +static spice_sdk_insert_coin_func sdk_insert_coin; struct SdkModule { std::string dll; @@ -175,8 +176,13 @@ sdk_init( if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, add_toast)) { v0->add_toast = sdk_add_toast; } - // end of 0.2 + + if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, insert_coin)) { + v0->insert_coin = sdk_insert_coin; + } + // end of 0.3 + // any newer minor iterations will need to check the size { @@ -640,5 +646,21 @@ sdk_add_toast( return SPICE_SDK_STATUS_SUCCESS; } +SPICE_SDK_STATUS_CODE +__cdecl +sdk_insert_coin( + uint8_t amount +) +{ + std::shared_lock lock(sdk_global_mutex); + if (!sdk_initialized) { + return SPICE_SDK_STATUS_TOO_LATE; + } + + if (amount > 0) { + eamuse_coin_add(amount); + } + return SPICE_SDK_STATUS_SUCCESS; +} } // namespace sdk \ No newline at end of file