Update to spice2x-25-04-25 (pre-apply)

> broken commit
This commit is contained in:
[ ]
2025-05-07 00:25:31 +09:00
parent 04dee88276
commit c94de456b5
543 changed files with 78491 additions and 91698 deletions
+115 -1
View File
@@ -38,13 +38,127 @@ std::vector<Button> &games::nost::get_buttons() {
"Key 25",
"Key 26",
"Key 27",
"Key 28"
"Key 28",
"Key 1 Soft",
"Key 2 Soft",
"Key 3 Soft",
"Key 4 Soft",
"Key 5 Soft",
"Key 6 Soft",
"Key 7 Soft",
"Key 8 Soft",
"Key 9 Soft",
"Key 10 Soft",
"Key 11 Soft",
"Key 12 Soft",
"Key 13 Soft",
"Key 14 Soft",
"Key 15 Soft",
"Key 16 Soft",
"Key 17 Soft",
"Key 18 Soft",
"Key 19 Soft",
"Key 20 Soft",
"Key 21 Soft",
"Key 22 Soft",
"Key 23 Soft",
"Key 24 Soft",
"Key 25 Soft",
"Key 26 Soft",
"Key 27 Soft",
"Key 28 Soft",
"Key 1 Medium",
"Key 2 Medium",
"Key 3 Medium",
"Key 4 Medium",
"Key 5 Medium",
"Key 6 Medium",
"Key 7 Medium",
"Key 8 Medium",
"Key 9 Medium",
"Key 10 Medium",
"Key 11 Medium",
"Key 12 Medium",
"Key 13 Medium",
"Key 14 Medium",
"Key 15 Medium",
"Key 16 Medium",
"Key 17 Medium",
"Key 18 Medium",
"Key 19 Medium",
"Key 20 Medium",
"Key 21 Medium",
"Key 22 Medium",
"Key 23 Medium",
"Key 24 Medium",
"Key 25 Medium",
"Key 26 Medium",
"Key 27 Medium",
"Key 28 Medium",
"Key 1 Hard",
"Key 2 Hard",
"Key 3 Hard",
"Key 4 Hard",
"Key 5 Hard",
"Key 6 Hard",
"Key 7 Hard",
"Key 8 Hard",
"Key 9 Hard",
"Key 10 Hard",
"Key 11 Hard",
"Key 12 Hard",
"Key 13 Hard",
"Key 14 Hard",
"Key 15 Hard",
"Key 16 Hard",
"Key 17 Hard",
"Key 18 Hard",
"Key 19 Hard",
"Key 20 Hard",
"Key 21 Hard",
"Key 22 Hard",
"Key 23 Hard",
"Key 24 Hard",
"Key 25 Hard",
"Key 26 Hard",
"Key 27 Hard",
"Key 28 Hard",
"Swipe Next Page",
"Swipe Previous Page",
"Touch Confirm",
"Touch Back",
"Touch Song 1",
"Touch Song 2",
"Touch Song 3",
"Touch Song 4",
"Touch Song 5",
"Touch Song 6",
"Touch Difficulty 1",
"Touch Difficulty 2",
"Touch Difficulty 3",
"Touch Difficulty 4"
);
}
return buttons;
}
std::string games::nost::get_buttons_help() {
// keep to max 100 characters wide
return
"For a MIDI piano, use [Key 1-28] for velocity-sensitive input.\n"
"For digital input (PC keyboard), use [Key 1-28 Medium].\n"
"For velocity-sensitive controllers in HID mode, use Analog tab.\n"
"\n"
"[Key 1-28] are velocity sensitive.\n"
"[Key 1-28 Soft] always trigger minimum velocity (ELEGANT in blue zone).\n"
"[Key 1-28 Medium] always trigger medium velocity (ELEGANT in both blue and yellow zones).\n"
"[Key 1-28 Hard] always trigger maximum velocity (ELEGANT in yellow zone)."
"\n"
"Swipe/Touch bindings are used for touch emulation, but enable -nostpoke first."
;
}
std::vector<Analog> &games::nost::get_analogs() {
static std::vector<Analog> analogs;
+100 -1
View File
@@ -7,7 +7,7 @@ namespace games::nost {
// all buttons in correct order
namespace Buttons {
enum {
enum Button {
Service,
Test,
CoinMech,
@@ -39,6 +39,104 @@ namespace games::nost {
Key26,
Key27,
Key28,
Key1Soft,
Key2Soft,
Key3Soft,
Key4Soft,
Key5Soft,
Key6Soft,
Key7Soft,
Key8Soft,
Key9Soft,
Key10Soft,
Key11Soft,
Key12Soft,
Key13Soft,
Key14Soft,
Key15Soft,
Key16Soft,
Key17Soft,
Key18Soft,
Key19Soft,
Key20Soft,
Key21Soft,
Key22Soft,
Key23Soft,
Key24Soft,
Key25Soft,
Key26Soft,
Key27Soft,
Key28Soft,
Key1Medium,
Key2Medium,
Key3Medium,
Key4Medium,
Key5Medium,
Key6Medium,
Key7Medium,
Key8Medium,
Key9Medium,
Key10Medium,
Key11Medium,
Key12Medium,
Key13Medium,
Key14Medium,
Key15Medium,
Key16Medium,
Key17Medium,
Key18Medium,
Key19Medium,
Key20Medium,
Key21Medium,
Key22Medium,
Key23Medium,
Key24Medium,
Key25Medium,
Key26Medium,
Key27Medium,
Key28Medium,
Key1Hard,
Key2Hard,
Key3Hard,
Key4Hard,
Key5Hard,
Key6Hard,
Key7Hard,
Key8Hard,
Key9Hard,
Key10Hard,
Key11Hard,
Key12Hard,
Key13Hard,
Key14Hard,
Key15Hard,
Key16Hard,
Key17Hard,
Key18Hard,
Key19Hard,
Key20Hard,
Key21Hard,
Key22Hard,
Key23Hard,
Key24Hard,
Key25Hard,
Key26Hard,
Key27Hard,
Key28Hard,
PokeNextPage,
PokePrevPage,
PokeConfirm,
PokeBack,
PokeSong1,
PokeSong2,
PokeSong3,
PokeSong4,
PokeSong5,
PokeSong6,
PokeDifficulty1,
PokeDifficulty2,
PokeDifficulty3,
PokeDifficulty4,
};
}
@@ -174,6 +272,7 @@ namespace games::nost {
// getters
std::vector<Button> &get_buttons();
std::string get_buttons_help();
std::vector<Analog> &get_analogs();
std::vector<Light> &get_lights();
}
+17 -1
View File
@@ -3,12 +3,15 @@
#define _WIN32_WINNT 0x0601
#include "nost.h"
#include "poke.h"
#include "hooks/setupapihook.h"
#include "misc/wintouchemu.h"
#include "avs/game.h"
namespace games::nost {
bool ENABLE_POKE = false;
NostGame::NostGame() : Game("Nostalgia") {
}
@@ -41,6 +44,19 @@ namespace games::nost {
setupapihook_add(touch_settings);
// custom touch
wintouchemu::hook("nostalgia", avs::game::DLL_INSTANCE);
// nostalgia crashes if you inject touch events too early
wintouchemu::hook("nostalgia", avs::game::DLL_INSTANCE, 20);
}
void NostGame::post_attach() {
if (ENABLE_POKE) {
poke::enable();
}
}
void NostGame::detach() {
if (ENABLE_POKE) {
poke::disable();
}
}
}
+4
View File
@@ -4,9 +4,13 @@
namespace games::nost {
extern bool ENABLE_POKE;
class NostGame : public games::Game {
public:
NostGame();
virtual void attach() override;
virtual void post_attach() override;
virtual void detach() override;
};
}
+204
View File
@@ -0,0 +1,204 @@
#include "poke.h"
#include <thread>
#include <optional>
#include "games/nost/io.h"
#include "cfg/api.h"
#include "rawinput/rawinput.h"
#include "misc/eamuse.h"
#include "touch/touch.h"
#include "util/logging.h"
namespace games::nost::poke {
static std::thread *THREAD = nullptr;
static volatile bool THREAD_RUNNING = false;
static const std::unordered_map<int, std::pair<LONG, LONG>> NOST_POKE_NUM {
{EAM_IO_KEYPAD_0, {760, 440}},
{EAM_IO_KEYPAD_1, {760, 385}},
{EAM_IO_KEYPAD_2, {820, 385}},
{EAM_IO_KEYPAD_3, {880, 385}},
{EAM_IO_KEYPAD_4, {760, 325}},
{EAM_IO_KEYPAD_5, {820, 325}},
{EAM_IO_KEYPAD_6, {880, 325}},
{EAM_IO_KEYPAD_7, {760, 265}},
{EAM_IO_KEYPAD_8, {820, 265}},
{EAM_IO_KEYPAD_9, {880, 265}},
{EAM_IO_KEYPAD_00, {820, 440}}, // erase button
{EAM_IO_KEYPAD_DECIMAL, {880, 440}} // also erase button
};
static const std::unordered_map<games::nost::Buttons::Button, std::pair<LONG, LONG>> NOST_POKE {
{games::nost::Buttons::Button::PokeConfirm, {1100, 525}},
{games::nost::Buttons::Button::PokeBack, {340, 100}},
{games::nost::Buttons::Button::PokeSong1, {450, 190}},
{games::nost::Buttons::Button::PokeSong2, {450, 330}},
{games::nost::Buttons::Button::PokeSong3, {450, 480}},
{games::nost::Buttons::Button::PokeSong4, {840, 190}},
{games::nost::Buttons::Button::PokeSong5, {840, 330}},
{games::nost::Buttons::Button::PokeSong6, {840, 480}},
{games::nost::Buttons::Button::PokeDifficulty1, {820, 240}},
{games::nost::Buttons::Button::PokeDifficulty2, {820, 320}},
{games::nost::Buttons::Button::PokeDifficulty3, {820, 410}},
{games::nost::Buttons::Button::PokeDifficulty4, {820, 490}},
};
void clear_touch_points(std::vector<TouchPoint> *touch_points) {
std::vector<DWORD> touch_ids;
for (auto &touch : *touch_points) {
touch_ids.emplace_back(touch.id);
}
touch_remove_points(&touch_ids);
touch_points->clear();
}
void enable() {
// check if already running
if (THREAD) {
return;
}
// create new thread
THREAD_RUNNING = true;
THREAD = new std::thread([] {
const DWORD touch_id = (DWORD)(0xFFFFFFFE);
const int swipe_anim_total_frames = 6;
const int swipe_anim_y = 300;
const int swipe_next_page_x_begin = 1120;
const int swipe_next_page_x_end = 1120-120;
const int swipe_prev_page_x_begin = 280-120;
const int swipe_prev_page_x_end = 280;
int next_page_anim_index = -1;
int prev_page_anim_index = -1;
std::vector<TouchPoint> touch_points;
bool touch_release = false;
// log
log_info("poke", "enabled");
// set variable to false to stop
while (THREAD_RUNNING) {
// clean up touch from last frame
if (!touch_points.empty()) {
if (touch_release) {
clear_touch_points(&touch_points);
touch_release = false;
} else {
touch_points.clear();
}
}
auto &buttons = games::nost::get_buttons();
if (0 <= next_page_anim_index) {
const auto delta =
(swipe_next_page_x_end - swipe_next_page_x_begin)
* (swipe_anim_total_frames - next_page_anim_index) / swipe_anim_total_frames;
TouchPoint tp {
.id = touch_id,
.x = (LONG)swipe_next_page_x_begin + delta,
.y = (LONG)swipe_anim_y,
.mouse = true,
};
touch_points.emplace_back(tp);
next_page_anim_index--;
if (next_page_anim_index < 0) {
touch_release = true;
}
} else if (0 <= prev_page_anim_index) {
const auto delta =
(swipe_prev_page_x_end - swipe_prev_page_x_begin)
* (swipe_anim_total_frames - prev_page_anim_index) / swipe_anim_total_frames;
TouchPoint tp {
.id = touch_id,
.x = (LONG)swipe_prev_page_x_begin + delta,
.y = (LONG)swipe_anim_y,
.mouse = true,
};
touch_points.emplace_back(tp);
prev_page_anim_index--;
if (prev_page_anim_index < 0) {
touch_release = true;
}
} else {
for (const auto& it : NOST_POKE) {
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(it.first))) {
TouchPoint tp {
.id = touch_id,
.x = it.second.first,
.y = it.second.second,
.mouse = true,
};
touch_points.emplace_back(tp);
touch_release = true;
break;
}
}
if (!touch_release) {
const auto state = eamuse_get_keypad_state(0);
if (state) {
for (const auto& it : NOST_POKE_NUM) {
if (state & (1 << it.first)) {
TouchPoint tp {
.id = touch_id,
.x = it.second.first,
.y = it.second.second,
.mouse = true,
};
touch_points.emplace_back(tp);
touch_release = true;
break;
}
}
}
}
// start animations for next frame
if (!touch_release) {
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(games::nost::Buttons::PokeNextPage))) {
next_page_anim_index = swipe_anim_total_frames;
}
if (GameAPI::Buttons::getState(RI_MGR, buttons.at(games::nost::Buttons::PokePrevPage))) {
prev_page_anim_index = swipe_anim_total_frames;
}
}
}
if (!touch_points.empty()) {
touch_write_points(&touch_points);
}
// slow down
Sleep(30);
}
return nullptr;
});
}
void disable() {
if (!THREAD) {
return;
}
// stop old thread
THREAD_RUNNING = false;
THREAD->join();
// delete thread
delete THREAD;
THREAD = nullptr;
// log
log_info("poke", "disabled");
}
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
namespace games::nost::poke {
void enable();
void disable();
}