mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-05 01:38:12 -07:00
Compare commits
7 Commits
26-09-01
...
112b1aecb0
| Author | SHA1 | Date | |
|---|---|---|---|
| 112b1aecb0 | |||
| de466db29f | |||
| 08e99dea4a | |||
| 00e904539e | |||
| eaab4698eb | |||
| a48eccab93 | |||
| 81c913726d |
@@ -29,4 +29,33 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: spice2x-ci-${{ env.COMMIT_SHORT_SHA }}
|
name: spice2x-ci-${{ env.COMMIT_SHORT_SHA }}
|
||||||
path: src/spice2x/bin
|
path: src/spice2x/bin
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
msvc-ci:
|
||||||
|
name: Build (MSVC ${{ matrix.arch }}-bit)
|
||||||
|
# windows-latest ships Visual Studio 2026; pin to the VS 2022 image, which is
|
||||||
|
# the toolset spice2x is actually developed against
|
||||||
|
runs-on: windows-2022
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: 32
|
||||||
|
platform: Win32
|
||||||
|
target: spicetools_spice spicetools_cfg
|
||||||
|
- arch: 64
|
||||||
|
platform: x64
|
||||||
|
target: spicetools_spice64
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./src/spice2x
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- name: Configure
|
||||||
|
run: >
|
||||||
|
cmake -S . -B cmake-build-msvc-${{ matrix.arch }}
|
||||||
|
-A ${{ matrix.platform }}
|
||||||
|
- name: Compile
|
||||||
|
run: >
|
||||||
|
cmake --build cmake-build-msvc-${{ matrix.arch }}
|
||||||
|
--config Release --target ${{ matrix.target }}
|
||||||
|
|||||||
+1
-1
@@ -105,5 +105,5 @@ if (conditional)
|
|||||||
* We don't use GSL.
|
* We don't use GSL.
|
||||||
* Don't throw exceptions.
|
* Don't throw exceptions.
|
||||||
* Stick to smart pointers. For interfacing with C Win32 API and raw buffers, use `unique_plain_ptr`.
|
* Stick to smart pointers. For interfacing with C Win32 API and raw buffers, use `unique_plain_ptr`.
|
||||||
* Writing in C is also completely acceptable.
|
* Writing in C is also completely acceptable but prefer to use RAII patterns.
|
||||||
* Other than that, there are no strict rules for code formatting, but please attempt to emulate the style around the code you are modifying.
|
* Other than that, there are no strict rules for code formatting, but please attempt to emulate the style around the code you are modifying.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "cfg/configurator.h"
|
#include "cfg/configurator.h"
|
||||||
#include "external/rapidjson/document.h"
|
#include "external/rapidjson/document.h"
|
||||||
|
#include "external/rapidjson/error/en.h"
|
||||||
#include "util/crypt.h"
|
#include "util/crypt.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/utils.h"
|
#include "util/utils.h"
|
||||||
@@ -92,6 +93,7 @@ Controller::Controller(unsigned short port, std::string password, bool pretty)
|
|||||||
// bind socket to address
|
// bind socket to address
|
||||||
if (bind(this->server, (sockaddr *) &server_address, sizeof(sockaddr)) == -1) {
|
if (bind(this->server, (sockaddr *) &server_address, sizeof(sockaddr)) == -1) {
|
||||||
log_warning("api", "could not bind socket on port {}: {}", port, get_last_error_string());
|
log_warning("api", "could not bind socket on port {}: {}", port, get_last_error_string());
|
||||||
|
closesocket(this->server);
|
||||||
this->server = INVALID_SOCKET;
|
this->server = INVALID_SOCKET;
|
||||||
if (!cfg::CONFIGURATOR_STANDALONE) {
|
if (!cfg::CONFIGURATOR_STANDALONE) {
|
||||||
log_fatal("api", "failed to start server");
|
log_fatal("api", "failed to start server");
|
||||||
@@ -102,6 +104,7 @@ Controller::Controller(unsigned short port, std::string password, bool pretty)
|
|||||||
// set socket to listen
|
// set socket to listen
|
||||||
if (listen(this->server, server_backlog) == -1) {
|
if (listen(this->server, server_backlog) == -1) {
|
||||||
log_warning("api", "could not listen to socket on port {}: {}", port, get_last_error_string());
|
log_warning("api", "could not listen to socket on port {}: {}", port, get_last_error_string());
|
||||||
|
closesocket(this->server);
|
||||||
this->server = INVALID_SOCKET;
|
this->server = INVALID_SOCKET;
|
||||||
if (!cfg::CONFIGURATOR_STANDALONE) {
|
if (!cfg::CONFIGURATOR_STANDALONE) {
|
||||||
log_fatal("api", "failed to start server");
|
log_fatal("api", "failed to start server");
|
||||||
@@ -312,6 +315,8 @@ bool Controller::process_request(ClientState *state, const char *in, size_t in_s
|
|||||||
|
|
||||||
// check for parse error
|
// check for parse error
|
||||||
if (document.HasParseError()) {
|
if (document.HasParseError()) {
|
||||||
|
log_warning("api", "Request JSON parse error: {} (byte offset {}, decrypted request length {} bytes)",
|
||||||
|
GetParseError_En(document.GetParseError()), document.GetErrorOffset(), in_size);
|
||||||
|
|
||||||
// return empty response and close connection
|
// return empty response and close connection
|
||||||
out->push_back(0);
|
out->push_back(0);
|
||||||
@@ -443,7 +448,9 @@ void Controller::free_socket() {
|
|||||||
this->server = INVALID_SOCKET;
|
this->server = INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->websocket->free_socket();
|
if (this->websocket) {
|
||||||
|
this->websocket->free_socket();
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &s : this->serial) {
|
for (auto &s : this->serial) {
|
||||||
s->free_port();
|
s->free_port();
|
||||||
|
|||||||
@@ -41,21 +41,21 @@ namespace api {
|
|||||||
bool pretty;
|
bool pretty;
|
||||||
|
|
||||||
// server
|
// server
|
||||||
WebSocketController *websocket;
|
WebSocketController *websocket = nullptr;
|
||||||
std::vector<SerialController *> serial;
|
std::vector<SerialController *> serial;
|
||||||
std::vector<std::thread> server_workers;
|
std::vector<std::thread> server_workers;
|
||||||
std::vector<std::thread> server_handlers;
|
std::vector<std::thread> server_handlers;
|
||||||
std::mutex server_handlers_m;
|
std::mutex server_handlers_m;
|
||||||
std::vector<api::ClientState *> client_states;
|
std::vector<api::ClientState *> client_states;
|
||||||
std::mutex client_states_m;
|
std::mutex client_states_m;
|
||||||
SOCKET server;
|
SOCKET server = INVALID_SOCKET;
|
||||||
void server_worker();
|
void server_worker();
|
||||||
void connection_handler(ClientState client_state);
|
void connection_handler(ClientState client_state);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// state
|
// state
|
||||||
bool server_running;
|
bool server_running = false;
|
||||||
|
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
Controller(unsigned short port, std::string password, bool pretty);
|
Controller(unsigned short port, std::string password, bool pretty);
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace api::modules {
|
|||||||
return error_type(res, "amount", "int");
|
return error_type(res, "amount", "int");
|
||||||
|
|
||||||
// add to coin stock
|
// 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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#if SPICE64 && !SPICE_XP
|
#if SPICE64 && !SPICE_XP
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
#include "mf_wrappers.h"
|
#include "mf_wrappers.h"
|
||||||
#include "avs/game.h"
|
#include "avs/game.h"
|
||||||
@@ -46,9 +47,7 @@ struct PredefinedHook {
|
|||||||
uintptr_t hook_afp_texture_offset;
|
uintptr_t hook_afp_texture_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
PredefinedHook g_predefinedHooks[] = {};
|
std::array<PredefinedHook, 0> g_predefinedHooks = {};
|
||||||
|
|
||||||
const DWORD g_predefinedHooksLength = ARRAYSIZE(g_predefinedHooks);
|
|
||||||
|
|
||||||
namespace games::iidx {
|
namespace games::iidx {
|
||||||
|
|
||||||
@@ -110,14 +109,14 @@ namespace games::iidx {
|
|||||||
auto pe = fmt::format("{:x}_{:x}", time_date_stamp, address_of_entry_point);
|
auto pe = fmt::format("{:x}_{:x}", time_date_stamp, address_of_entry_point);
|
||||||
log_info("iidx:camhook", "Locating predefined hook addresses for LDJ-{}", pe);
|
log_info("iidx:camhook", "Locating predefined hook addresses for LDJ-{}", pe);
|
||||||
|
|
||||||
for (DWORD i = 0; i < g_predefinedHooksLength; i++) {
|
for (auto &hook : g_predefinedHooks) {
|
||||||
if (pe.compare(g_predefinedHooks[i].pe_identifier) == 0) {
|
if (pe.compare(hook.pe_identifier) == 0) {
|
||||||
log_misc("iidx:camhook", "Found predefined addresses");
|
log_misc("iidx:camhook", "Found predefined addresses");
|
||||||
addr_hook_a = g_predefinedHooks[i].hook_a;
|
addr_hook_a = hook.hook_a;
|
||||||
addr_textures = g_predefinedHooks[i].hook_textures;
|
addr_textures = hook.hook_textures;
|
||||||
addr_camera_manager = g_predefinedHooks[i].hook_camera_manager;
|
addr_camera_manager = hook.hook_camera_manager;
|
||||||
addr_device_offset = g_predefinedHooks[i].hook_device_offset;
|
addr_device_offset = hook.hook_device_offset;
|
||||||
addr_afp_texture_offset = g_predefinedHooks[i].hook_afp_texture_offset;
|
addr_afp_texture_offset = hook.hook_afp_texture_offset;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ DEFINE_GUID(IID_IAudioClient,
|
|||||||
0x1cb9ad4c, 0xdbfa, 0x4c32,
|
0x1cb9ad4c, 0xdbfa, 0x4c32,
|
||||||
0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2);
|
0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2);
|
||||||
|
|
||||||
|
DEFINE_GUID(IID_IAudioClient3,
|
||||||
|
0x7ed4ee07, 0x8e67, 0x4cd4,
|
||||||
|
0x8c, 0x1a, 0x2b, 0x7a, 0x59, 0x87, 0xad, 0x42);
|
||||||
|
|
||||||
DEFINE_GUID(IID_IAudioClock,
|
DEFINE_GUID(IID_IAudioClock,
|
||||||
0xcd63314f, 0x3fba, 0x4a1b,
|
0xcd63314f, 0x3fba, 0x4a1b,
|
||||||
0x81, 0x2c, 0xef, 0x96, 0x35, 0x87, 0x28, 0xe7);
|
0x81, 0x2c, 0xef, 0x96, 0x35, 0x87, 0x28, 0xe7);
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
#include "d3d9_device.h"
|
#include "d3d9_device.h"
|
||||||
|
|
||||||
|
// windows.h defines many stupid things
|
||||||
|
#undef small
|
||||||
|
|
||||||
bool gfdm_two_head_exclusive() {
|
bool gfdm_two_head_exclusive() {
|
||||||
return games::gitadora::is_arena_model()
|
return games::gitadora::is_arena_model()
|
||||||
&& games::gitadora::ARENA_TWO_HEAD_EXCLUSIVE
|
&& games::gitadora::ARENA_TWO_HEAD_EXCLUSIVE
|
||||||
|
|||||||
+636
-814
File diff suppressed because it is too large
Load Diff
@@ -325,6 +325,8 @@ namespace launcher {
|
|||||||
OBSWebSocketDebug,
|
OBSWebSocketDebug,
|
||||||
ScreenshotIncludeOverlay,
|
ScreenshotIncludeOverlay,
|
||||||
ScreenshotSubscreens,
|
ScreenshotSubscreens,
|
||||||
|
|
||||||
|
_Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OptionsCategory {
|
enum class OptionsCategory {
|
||||||
|
|||||||
@@ -331,8 +331,8 @@ int eamuse_coin_consume_stock() {
|
|||||||
return COIN_STOCK.exchange(0, std::memory_order_relaxed);
|
return COIN_STOCK.exchange(0, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eamuse_coin_add() {
|
void eamuse_coin_add(int amount) {
|
||||||
return COIN_STOCK.fetch_add(1, std::memory_order_relaxed) + 1;
|
COIN_STOCK.fetch_add(amount, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eamuse_coin_insert() {
|
void eamuse_coin_insert() {
|
||||||
@@ -621,6 +621,7 @@ int eamuse_get_game_keypads() {
|
|||||||
avs::game::is_model("JDX") ||
|
avs::game::is_model("JDX") ||
|
||||||
avs::game::is_model("KDX") ||
|
avs::game::is_model("KDX") ||
|
||||||
avs::game::is_model("MDX") ||
|
avs::game::is_model("MDX") ||
|
||||||
|
avs::game::is_model("KDM") ||
|
||||||
avs::game::is_model("J33") ||
|
avs::game::is_model("J33") ||
|
||||||
avs::game::is_model("K33") ||
|
avs::game::is_model("K33") ||
|
||||||
avs::game::is_model("L33") ||
|
avs::game::is_model("L33") ||
|
||||||
@@ -637,6 +638,7 @@ int eamuse_get_game_keypads_name() {
|
|||||||
|
|
||||||
if (game_name == "Beatmania IIDX" ||
|
if (game_name == "Beatmania IIDX" ||
|
||||||
game_name == "Dance Dance Revolution" ||
|
game_name == "Dance Dance Revolution" ||
|
||||||
|
game_name == "Dance Evolution" ||
|
||||||
game_name == "GitaDora")
|
game_name == "GitaDora")
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void eamuse_coin_set_stock(int amount);
|
|||||||
bool eamuse_coin_consume(int amount);
|
bool eamuse_coin_consume(int amount);
|
||||||
int eamuse_coin_consume_stock();
|
int eamuse_coin_consume_stock();
|
||||||
|
|
||||||
int eamuse_coin_add();
|
void eamuse_coin_add(int amount = 1);
|
||||||
void eamuse_coin_insert();
|
void eamuse_coin_insert();
|
||||||
|
|
||||||
void eamuse_pin_macro_start_thread();
|
void eamuse_pin_macro_start_thread();
|
||||||
|
|||||||
@@ -237,6 +237,16 @@ typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_add_toast_func)(
|
|||||||
const char *text
|
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 {
|
typedef struct SPICE_SDK_V0 {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
@@ -262,6 +272,8 @@ typedef struct SPICE_SDK_V0 {
|
|||||||
|
|
||||||
spice_sdk_add_toast_func *add_toast;
|
spice_sdk_add_toast_func *add_toast;
|
||||||
|
|
||||||
|
spice_sdk_insert_coin_func *insert_coin;
|
||||||
|
|
||||||
} SPICE_SDK_V0;
|
} SPICE_SDK_V0;
|
||||||
|
|
||||||
typedef void (__cdecl spice_sdk_destroy_callback_func)(
|
typedef void (__cdecl spice_sdk_destroy_callback_func)(
|
||||||
|
|||||||
@@ -76,9 +76,35 @@ static ArrowButton arrow_buttons[] = {
|
|||||||
|
|
||||||
// worker thread for I/O
|
// worker thread for I/O
|
||||||
static void worker_thread_main(std::stop_token stop_token) {
|
static void worker_thread_main(std::stop_token stop_token) {
|
||||||
|
bool coin_previous_state[10] = {};
|
||||||
while (!stop_token.stop_requested()) {
|
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<int>(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) {
|
for (auto& arrow : arrow_buttons) {
|
||||||
// check for ctrl + arrow keys and trigger p1 pad arrows
|
|
||||||
if (((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) &&
|
if (((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) &&
|
||||||
((GetAsyncKeyState(arrow.key) & 0x8000) != 0)) {
|
((GetAsyncKeyState(arrow.key) & 0x8000) != 0)) {
|
||||||
spice.set_button(arrow.button, true, 1.f);
|
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) {
|
if (spice.add_toast) {
|
||||||
spice.add_toast(
|
spice.add_toast(
|
||||||
SPICE_SDK_TOAST_LEVEL_INFO,
|
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 {
|
} else {
|
||||||
LOG_INFO(std::format("let me hear you say: {}", arrow.name).c_str());
|
LOG_INFO(std::format("let me hear you say: {}", arrow.name).c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-1
@@ -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_insert_card_func sdk_insert_card;
|
||||||
static spice_sdk_set_keypad_func sdk_set_keypad;
|
static spice_sdk_set_keypad_func sdk_set_keypad;
|
||||||
static spice_sdk_add_toast_func sdk_add_toast;
|
static spice_sdk_add_toast_func sdk_add_toast;
|
||||||
|
static spice_sdk_insert_coin_func sdk_insert_coin;
|
||||||
|
|
||||||
struct SdkModule {
|
struct SdkModule {
|
||||||
std::string dll;
|
std::string dll;
|
||||||
@@ -175,8 +176,13 @@ sdk_init(
|
|||||||
if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, add_toast)) {
|
if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, add_toast)) {
|
||||||
v0->add_toast = sdk_add_toast;
|
v0->add_toast = sdk_add_toast;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of 0.2
|
// 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
|
// any newer minor iterations will need to check the size
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -219,6 +225,7 @@ sdk_log(
|
|||||||
log_warning(facility_str.c_str(), "{}", message);
|
log_warning(facility_str.c_str(), "{}", message);
|
||||||
break;
|
break;
|
||||||
case SPICE_SDK_LOG_LEVEL_FATAL:
|
case SPICE_SDK_LOG_LEVEL_FATAL:
|
||||||
|
lock.unlock();
|
||||||
log_fatal(facility_str.c_str(), "{}", message);
|
log_fatal(facility_str.c_str(), "{}", message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -640,5 +647,21 @@ sdk_add_toast(
|
|||||||
return SPICE_SDK_STATUS_SUCCESS;
|
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
|
} // namespace sdk
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
|
|
||||||
#define LDR_DLL_NOTIFICATION_REASON_LOADED 1
|
#define LDR_DLL_NOTIFICATION_REASON_LOADED 1
|
||||||
@@ -43,4 +44,4 @@ NTSTATUS NTAPI LdrRegisterDllNotification(
|
|||||||
|
|
||||||
NTSTATUS NTAPI LdrUnregisterDllNotification(
|
NTSTATUS NTAPI LdrUnregisterDllNotification(
|
||||||
PVOID Cookie
|
PVOID Cookie
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user