mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-01 06:24:55 -07:00
Compare commits
2 Commits
2b6e76730b
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7aba7da3b6 | |||
| 197d76755b |
@@ -199,11 +199,11 @@ namespace games::iidx {
|
||||
addr_camera_manager = (addr_camera_manager_ptr - (uint8_t*) iidx_module) + disp_camera_manager + 7;
|
||||
|
||||
// addr_device_offset
|
||||
search_from = (addr_hook_a_ptr - (uint8_t*) iidx_module);
|
||||
search_from = addr_hook_a;
|
||||
uint8_t *addr_device_ptr = reinterpret_cast<uint8_t *>(find_pattern_from(
|
||||
iidx_module,
|
||||
"488B89",
|
||||
"XXX",
|
||||
"488B8F00000000488B014C8B870000000033D2FF9028010000",
|
||||
"XXX????XXXXXX????XXXXXXXX",
|
||||
3, 0, search_from));
|
||||
|
||||
if (addr_device_ptr == nullptr) {
|
||||
@@ -211,7 +211,7 @@ namespace games::iidx {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
addr_device_offset = *addr_device_ptr;
|
||||
addr_device_offset = *reinterpret_cast<uint32_t*>(addr_device_ptr);
|
||||
|
||||
// --- addr_afp_texture_offset ---
|
||||
uint8_t *addr_afp_texture_ptr = reinterpret_cast<uint8_t *>(find_pattern(
|
||||
@@ -233,13 +233,27 @@ namespace games::iidx {
|
||||
static void **__fastcall camera_hook_a(PBYTE a1) {
|
||||
std::call_once(hook_a_init, [&]{
|
||||
device = *reinterpret_cast<LPDIRECT3DDEVICE9EX*>(a1 + addr_device_offset);
|
||||
auto const preview = *reinterpret_cast<LPDIRECT3DTEXTURE9**>((uint8_t*)iidx_module + addr_textures);
|
||||
auto const registry = reinterpret_cast<Camera::TextureRegistry*>(
|
||||
reinterpret_cast<uint8_t*>(iidx_module) + addr_textures - offsetof(Camera::TextureRegistry, begin));
|
||||
auto const manager = reinterpret_cast<Camera::CCameraManager2*>((uint8_t*)iidx_module + addr_camera_manager);
|
||||
|
||||
camera_texture_a = manager->cameras->a->d3d9_texture(addr_afp_texture_offset);
|
||||
camera_texture_b = manager->cameras->b->d3d9_texture(addr_afp_texture_offset);
|
||||
preview_texture_a = preview;
|
||||
preview_texture_b = preview + 2;
|
||||
auto const camera_count = manager->begin ? manager->end - manager->begin : 0;
|
||||
auto const bind_camera = [&](size_t index, LPDIRECT3DTEXTURE9*& texture, LPDIRECT3DTEXTURE9*& preview) {
|
||||
if (index >= static_cast<size_t>(camera_count)) {
|
||||
return; // IIDX 34 only has the TOP camera.
|
||||
}
|
||||
auto const camera = manager->begin[index];
|
||||
auto const afp = camera ? camera->afp_texture(addr_afp_texture_offset) : nullptr;
|
||||
if (!afp || !registry->begin || afp->handle < registry->handle_base ||
|
||||
afp->handle - registry->handle_base >= registry->end - registry->begin) {
|
||||
log_warning("iidx:camhook", "invalid texture destination for camera {}", index);
|
||||
return;
|
||||
}
|
||||
texture = &afp->texture;
|
||||
preview = registry->begin + (afp->handle - registry->handle_base);
|
||||
};
|
||||
bind_camera(0, camera_texture_a, preview_texture_a);
|
||||
bind_camera(1, camera_texture_b, preview_texture_b);
|
||||
|
||||
init_local_camera();
|
||||
});
|
||||
@@ -381,10 +395,10 @@ namespace games::iidx {
|
||||
log_misc("iidx:camhook", "Adding user-preferred cameras");
|
||||
for (size_t i = 0; i < numDevices && LOCAL_CAMERA_LIST.size() < 2; i++) {
|
||||
auto pActivate = ppDevices[i];
|
||||
if ((int)i == preferred_top_index && top_camera == nullptr) {
|
||||
if ((int)i == preferred_top_index && top_camera == nullptr && camera_texture_a != nullptr) {
|
||||
log_misc("iidx:camhook", "Adding user-preferred top camera {} / '{}'", i, top_camera_id);
|
||||
top_camera = add_top_camera(pActivate);
|
||||
} else if ((int)i == preferred_front_index && front_camera == nullptr) {
|
||||
} else if ((int)i == preferred_front_index && front_camera == nullptr && camera_texture_b != nullptr) {
|
||||
log_misc("iidx:camhook", "Adding user-preferred front camera {} / '{}'", i, front_camera_id);
|
||||
front_camera = add_front_camera(pActivate);
|
||||
}
|
||||
@@ -402,16 +416,16 @@ namespace games::iidx {
|
||||
|
||||
if (!FLIP_CAMS) {
|
||||
// top camera first, then front
|
||||
if (top_camera == nullptr) {
|
||||
if (top_camera == nullptr && camera_texture_a != nullptr) {
|
||||
top_camera = add_top_camera(pActivate);
|
||||
} else if (front_camera == nullptr) {
|
||||
} else if (front_camera == nullptr && camera_texture_b != nullptr) {
|
||||
front_camera = add_front_camera(pActivate);
|
||||
}
|
||||
} else {
|
||||
// front first, then top
|
||||
if (front_camera == nullptr) {
|
||||
if (front_camera == nullptr && camera_texture_b != nullptr) {
|
||||
front_camera = add_front_camera(pActivate);
|
||||
} else if (top_camera == nullptr) {
|
||||
} else if (top_camera == nullptr && camera_texture_a != nullptr) {
|
||||
top_camera = add_top_camera(pActivate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,21 +70,31 @@ namespace games::iidx {
|
||||
class IIDXCameraSourceReaderCallback;
|
||||
|
||||
namespace Camera {
|
||||
struct AfpTexture {
|
||||
void* vftbl;
|
||||
IDirect3DTexture9* texture;
|
||||
uint32_t handle;
|
||||
};
|
||||
|
||||
struct TextureRegistry {
|
||||
uint32_t handle_base;
|
||||
uint32_t next_slot;
|
||||
IDirect3DTexture9** begin;
|
||||
IDirect3DTexture9** end;
|
||||
IDirect3DTexture9** capacity_end;
|
||||
};
|
||||
|
||||
struct PlayVideoCamera {
|
||||
IDirect3DTexture9** d3d9_texture(const uintptr_t offset) {
|
||||
auto const afp_texture = *reinterpret_cast<uint8_t**>
|
||||
(reinterpret_cast<uint8_t*>(this) + offset);
|
||||
return reinterpret_cast<IDirect3DTexture9**>(afp_texture + 0x8);
|
||||
AfpTexture* afp_texture(const uintptr_t offset) {
|
||||
return *reinterpret_cast<AfpTexture**>(reinterpret_cast<uint8_t*>(this) + offset);
|
||||
}
|
||||
};
|
||||
|
||||
struct CCameraManager2 {
|
||||
using camera_pointers = struct {
|
||||
PlayVideoCamera* a;
|
||||
PlayVideoCamera* b;
|
||||
};
|
||||
void* vftbl;
|
||||
camera_pointers* cameras;
|
||||
PlayVideoCamera** begin;
|
||||
PlayVideoCamera** end;
|
||||
PlayVideoCamera** capacity_end;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -248,6 +248,27 @@ typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_insert_coin_func)(
|
||||
uint8_t amount
|
||||
);
|
||||
|
||||
// get_coin_blocker (v0.6 and up)
|
||||
// gets the current shared coin blocker state
|
||||
// insert_coin bypasses the blocker regardless of this state
|
||||
//
|
||||
// blocked: receives true when coins are blocked, false when allowed
|
||||
|
||||
typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_get_coin_blocker_func)(
|
||||
bool *blocked
|
||||
);
|
||||
|
||||
// set_coin_blocker (v0.6 and up)
|
||||
// sets the shared coin blocker state used by normal coin input
|
||||
// this is not a persistent override; the game can change the state again
|
||||
// insert_coin bypasses the blocker regardless of this state
|
||||
//
|
||||
// blocked: true to block coins, false to allow them
|
||||
|
||||
typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_set_coin_blocker_func)(
|
||||
bool blocked
|
||||
);
|
||||
|
||||
typedef struct SPICE_SDK_MODULE_INFO {
|
||||
uint32_t size; // initialize to sizeof(SPICE_SDK_MODULE_INFO)
|
||||
uintptr_t base; // loaded address, not the preferred PE image base
|
||||
@@ -383,6 +404,9 @@ typedef struct SPICE_SDK_V0 {
|
||||
|
||||
spice_sdk_hook_library_func *hook_library;
|
||||
|
||||
spice_sdk_get_coin_blocker_func *get_coin_blocker;
|
||||
spice_sdk_set_coin_blocker_func *set_coin_blocker;
|
||||
|
||||
} SPICE_SDK_V0;
|
||||
|
||||
typedef void (__cdecl spice_sdk_destroy_callback_func)(
|
||||
|
||||
@@ -36,6 +36,8 @@ 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;
|
||||
static spice_sdk_get_coin_blocker_func sdk_get_coin_blocker;
|
||||
static spice_sdk_set_coin_blocker_func sdk_set_coin_blocker;
|
||||
static spice_sdk_get_module_info_func sdk_get_module_info;
|
||||
static spice_sdk_get_plugin_directory_func sdk_get_plugin_directory;
|
||||
static spice_sdk_register_d3d9_func sdk_register_d3d9;
|
||||
@@ -211,6 +213,14 @@ sdk_init(
|
||||
}
|
||||
// end of 0.5
|
||||
|
||||
if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, get_coin_blocker)) {
|
||||
v0->get_coin_blocker = sdk_get_coin_blocker;
|
||||
}
|
||||
if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, set_coin_blocker)) {
|
||||
v0->set_coin_blocker = sdk_set_coin_blocker;
|
||||
}
|
||||
// end of 0.6
|
||||
|
||||
// any newer minor iterations will need to check the size
|
||||
|
||||
{
|
||||
@@ -746,4 +756,37 @@ sdk_insert_coin(
|
||||
return SPICE_SDK_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SPICE_SDK_STATUS_CODE
|
||||
__cdecl
|
||||
sdk_get_coin_blocker(
|
||||
bool *blocked
|
||||
)
|
||||
{
|
||||
std::shared_lock lock(sdk_global_mutex);
|
||||
if (!sdk_initialized) {
|
||||
return SPICE_SDK_STATUS_TOO_LATE;
|
||||
}
|
||||
if (!blocked) {
|
||||
return SPICE_SDK_STATUS_INVALID_ARGUMENT_1;
|
||||
}
|
||||
|
||||
*blocked = eamuse_coin_get_block();
|
||||
return SPICE_SDK_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SPICE_SDK_STATUS_CODE
|
||||
__cdecl
|
||||
sdk_set_coin_blocker(
|
||||
bool blocked
|
||||
)
|
||||
{
|
||||
std::shared_lock lock(sdk_global_mutex);
|
||||
if (!sdk_initialized) {
|
||||
return SPICE_SDK_STATUS_TOO_LATE;
|
||||
}
|
||||
|
||||
eamuse_coin_set_block(blocked);
|
||||
return SPICE_SDK_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace sdk
|
||||
Reference in New Issue
Block a user