mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
rb: more touch options (#699)
## Link to GitHub Issue or related Pull Request, if one exists n/a ## Description of change Add two options: 1. option to adjust poll rate 2. option to change emulation size Also, the default configuration is changing from: * ~1000Hz ish to 120Hz (default) * 3x3 point to 1x1 point In theory this does not make a meaningful change to how the game plays. But if people want the old behavior they can change it. ## Testing Tested on Volzza2 and Reflesia.
This commit is contained in:
@@ -6,27 +6,32 @@
|
|||||||
#include "util/detour.h"
|
#include "util/detour.h"
|
||||||
#include "util/precise_timer.h"
|
#include "util/precise_timer.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
|
#include "cfg/configurator.h"
|
||||||
|
|
||||||
#include "touch.h"
|
#include "touch.h"
|
||||||
|
|
||||||
|
namespace games::rb {
|
||||||
|
uint16_t TOUCH_POLL_RATE = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static decltype(SleepEx) *SleepEx_orig;
|
static decltype(SleepEx) *SleepEx_orig;
|
||||||
|
|
||||||
static DWORD WINAPI SleepEx_hook(DWORD dwMilliseconds, BOOL bAltertable) {
|
static DWORD WINAPI SleepEx_hook(DWORD dwMilliseconds, BOOL bAlertable) {
|
||||||
|
|
||||||
// increase touch poll from ~110 FPS to ~500 FPS (Sleep) or ~1000 FPS (Win10 high-res timer)
|
// increase touch poll rate
|
||||||
if (dwMilliseconds == 8) {
|
if (dwMilliseconds == 8) {
|
||||||
dwMilliseconds = 1;
|
dwMilliseconds = 1000 / games::rb::TOUCH_POLL_RATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// most calls from rb are actually non-alertable
|
// most calls from rb are actually non-alertable
|
||||||
if (!bAltertable) {
|
if (!bAlertable) {
|
||||||
static thread_local timeutils::PreciseSleepTimer timer;
|
static thread_local timeutils::PreciseSleepTimer timer;
|
||||||
timer.sleep(dwMilliseconds);
|
timer.sleep(dwMilliseconds);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// call original
|
// call original
|
||||||
return SleepEx_orig(dwMilliseconds, bAltertable);
|
return SleepEx_orig(dwMilliseconds, bAlertable);
|
||||||
}
|
}
|
||||||
|
|
||||||
games::rb::RBGame::RBGame() : Game("Reflec Beat") {
|
games::rb::RBGame::RBGame() : Game("Reflec Beat") {
|
||||||
@@ -35,6 +40,10 @@ games::rb::RBGame::RBGame() : Game("Reflec Beat") {
|
|||||||
void games::rb::RBGame::attach() {
|
void games::rb::RBGame::attach() {
|
||||||
Game::attach();
|
Game::attach();
|
||||||
|
|
||||||
|
if (1000 < games::rb::TOUCH_POLL_RATE) {
|
||||||
|
log_fatal("rb", "-rbtouchsize is set too high; cannot exceed 1000");
|
||||||
|
}
|
||||||
|
|
||||||
// init stuff
|
// init stuff
|
||||||
devicehook_init();
|
devicehook_init();
|
||||||
|
|
||||||
@@ -47,7 +56,12 @@ void games::rb::RBGame::attach() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
|
if (0 < TOUCH_POLL_RATE) {
|
||||||
|
log_info("rb", "force increasing touch poll rate by hooking SleepEx ({}Hz)", TOUCH_POLL_RATE);
|
||||||
SleepEx_orig = detour::iat_try("SleepEx", SleepEx_hook, avs::game::DLL_INSTANCE);
|
SleepEx_orig = detour::iat_try("SleepEx", SleepEx_hook, avs::game::DLL_INSTANCE);
|
||||||
|
} else {
|
||||||
|
log_info("rb", "not changing touch poll rate (120Hz by default)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void games::rb::RBGame::detach() {
|
void games::rb::RBGame::detach() {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
namespace games::rb {
|
namespace games::rb {
|
||||||
|
|
||||||
extern uint16_t TOUCH_SCALING;
|
extern uint16_t TOUCH_SCALING;
|
||||||
|
extern uint8_t TOUCH_SIZE;
|
||||||
|
extern uint16_t TOUCH_POLL_RATE;
|
||||||
|
|
||||||
class RBGame : public games::Game {
|
class RBGame : public games::Game {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ static std::string WINDOW_TITLE = "REFLEC BEAT";
|
|||||||
|
|
||||||
namespace games::rb {
|
namespace games::rb {
|
||||||
uint16_t TOUCH_SCALING = 1000;
|
uint16_t TOUCH_SCALING = 1000;
|
||||||
|
uint8_t TOUCH_SIZE = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
games::rb::ReflecBeatTouchDeviceHandle::ReflecBeatTouchDeviceHandle(bool log_fps) {
|
games::rb::ReflecBeatTouchDeviceHandle::ReflecBeatTouchDeviceHandle(bool log_fps) {
|
||||||
@@ -160,16 +161,20 @@ int games::rb::ReflecBeatTouchDeviceHandle::read(LPVOID lpBuffer, DWORD nNumberO
|
|||||||
const auto point_x = (int) ((x - window_width / 2.0) * 48.0 / 54.0 + window_width / 2.0);
|
const auto point_x = (int) ((x - window_width / 2.0) * 48.0 / 54.0 + window_width / 2.0);
|
||||||
const auto point_y = (int) (y - window_height / 76);
|
const auto point_y = (int) (y - window_height / 76);
|
||||||
|
|
||||||
// insert 9 times with offset to double the precision
|
// center
|
||||||
grid_insert(data, point_x, point_y);
|
grid_insert(data, point_x, point_y);
|
||||||
grid_insert(data, point_x - offset_x, point_y);
|
|
||||||
grid_insert(data, point_x - offset_x, point_y - offset_y);
|
// surrounding points
|
||||||
grid_insert(data, point_x - offset_x, point_y + offset_y);
|
if (games::rb::TOUCH_SIZE == 3) {
|
||||||
grid_insert(data, point_x + offset_x, point_y);
|
grid_insert(data, point_x - offset_x, point_y); // west
|
||||||
grid_insert(data, point_x + offset_x, point_y + offset_y);
|
grid_insert(data, point_x - offset_x, point_y - offset_y); // northwest
|
||||||
grid_insert(data, point_x + offset_x, point_y - offset_y);
|
grid_insert(data, point_x - offset_x, point_y + offset_y); // southwest
|
||||||
grid_insert(data, point_x, point_y - offset_y);
|
grid_insert(data, point_x + offset_x, point_y); // east
|
||||||
grid_insert(data, point_x, point_y + offset_y);
|
grid_insert(data, point_x + offset_x, point_y + offset_y); // southeast
|
||||||
|
grid_insert(data, point_x + offset_x, point_y - offset_y); // northeast
|
||||||
|
grid_insert(data, point_x, point_y - offset_y); // north
|
||||||
|
grid_insert(data, point_x, point_y + offset_y); // south
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy data to buffer
|
// copy data to buffer
|
||||||
|
|||||||
@@ -1205,9 +1205,20 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reflec beat touch emulation
|
||||||
if (options[launcher::Options::spice2x_RBTouchScale].is_active()) {
|
if (options[launcher::Options::spice2x_RBTouchScale].is_active()) {
|
||||||
games::rb::TOUCH_SCALING = options[launcher::Options::spice2x_RBTouchScale].value_uint32();
|
games::rb::TOUCH_SCALING = options[launcher::Options::spice2x_RBTouchScale].value_uint32();
|
||||||
}
|
}
|
||||||
|
if (options[launcher::Options::RBTouchSize].is_active()) {
|
||||||
|
const auto text = options[launcher::Options::RBTouchSize].value_text();
|
||||||
|
if (text == "3") {
|
||||||
|
games::rb::TOUCH_SIZE = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options[launcher::Options::RBTouchPollRate].is_active()) {
|
||||||
|
games::rb::TOUCH_POLL_RATE = options[launcher::Options::RBTouchPollRate].value_uint32();
|
||||||
|
}
|
||||||
|
|
||||||
if (options[launcher::Options::spice2x_AsioForceUnload].value_bool()) {
|
if (options[launcher::Options::spice2x_AsioForceUnload].value_bool()) {
|
||||||
hooks::audio::ASIO_FORCE_UNLOAD_ON_STOP = true;
|
hooks::audio::ASIO_FORCE_UNLOAD_ON_STOP = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2317,7 +2317,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
// spice2x_RBTouchScale
|
// spice2x_RBTouchScale
|
||||||
.title = "RB Scale Touch Input",
|
.title = "RB Touch Emulation Scale",
|
||||||
.name = "sp2x-rbscaletouch",
|
.name = "sp2x-rbscaletouch",
|
||||||
.display_name = "rbscaletouch",
|
.display_name = "rbscaletouch",
|
||||||
.aliases= "rbscaletouch",
|
.aliases= "rbscaletouch",
|
||||||
@@ -2327,6 +2327,31 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.game_name = "Reflec Beat",
|
.game_name = "Reflec Beat",
|
||||||
.category = "Game Options",
|
.category = "Game Options",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// RBTouchSize
|
||||||
|
.title = "RB Touch Emulation Size",
|
||||||
|
.name = "rbtouchsize",
|
||||||
|
.desc = "Size of the touch area; how many IR sensors a single finger activates. Default: 1 (1x1).",
|
||||||
|
.type = OptionType::Enum,
|
||||||
|
.game_name = "Reflec Beat",
|
||||||
|
.category = "Game Options",
|
||||||
|
.elements = {
|
||||||
|
{"1", "1x1"},
|
||||||
|
{"3", "3x3"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// RBTouchPollRate
|
||||||
|
.title = "RB Touch Emulation Poll Hz",
|
||||||
|
.name = "rbtouchhz",
|
||||||
|
.desc = "By default, the game polls for touch at 120Hz. "
|
||||||
|
"This option overrides that rate; enter a number betwen 1 and 1000.\n\n"
|
||||||
|
"It should be noted that higher poll does not necessarily improve accuracy or performance.",
|
||||||
|
.type = OptionType::Integer,
|
||||||
|
.setting_name = "250",
|
||||||
|
.game_name = "Reflec Beat",
|
||||||
|
.category = "Game Options",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// spice2x_AsioForceUnload
|
// spice2x_AsioForceUnload
|
||||||
.title = "ASIO Force Unload On Stop",
|
.title = "ASIO Force Unload On Stop",
|
||||||
|
|||||||
@@ -242,6 +242,8 @@ namespace launcher {
|
|||||||
spice2x_JubeatLegacyTouch,
|
spice2x_JubeatLegacyTouch,
|
||||||
JubeatTouchAlgo,
|
JubeatTouchAlgo,
|
||||||
spice2x_RBTouchScale,
|
spice2x_RBTouchScale,
|
||||||
|
RBTouchSize,
|
||||||
|
RBTouchPollRate,
|
||||||
spice2x_AsioForceUnload,
|
spice2x_AsioForceUnload,
|
||||||
spice2x_IIDXNoESpec,
|
spice2x_IIDXNoESpec,
|
||||||
spice2x_IIDXWindowedTDJ,
|
spice2x_IIDXWindowedTDJ,
|
||||||
|
|||||||
Reference in New Issue
Block a user