mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e6b4c16cc | |||
| d6eb8f7125 | |||
| dc6850e479 | |||
| 2d623e179b | |||
| 884d665c1c | |||
| 2842fe7ec6 | |||
| 954e6022d9 | |||
| 955c50a9f3 | |||
| dc82c980b1 | |||
| 408ed17521 | |||
| f4050e9adb | |||
| badae01357 | |||
| 38d9939eb7 | |||
| f5a3caf536 | |||
| 027445afb1 | |||
| 63a3900b79 | |||
| f542a78347 | |||
| 4d32dde83e | |||
| 927170ce73 | |||
| 875a0f0765 | |||
| 3ad88ef15c | |||
| 7a6cadb176 | |||
| 4feca23240 | |||
| 2e52bebd3d | |||
| aa218d5be7 | |||
| 94f009991a | |||
| c3b9ce3fdc | |||
| 1517cf9a7c | |||
| f0f46296f2 |
@@ -7,7 +7,7 @@
|
|||||||
>
|
>
|
||||||
> Feel free to remove this section after you have read it.
|
> Feel free to remove this section after you have read it.
|
||||||
|
|
||||||
## Link to GitHub Issue, if one exists
|
## Link to GitHub Issue or related Pull Request, if one exists
|
||||||
#0
|
#0
|
||||||
|
|
||||||
## Description of change
|
## Description of change
|
||||||
|
|||||||
@@ -170,8 +170,8 @@ else()
|
|||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
|
||||||
|
|
||||||
# file prefix map for relative working directory
|
# file prefix map for relative working directory
|
||||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ffile-prefix-map=${CMAKE_SOURCE_DIR}=.")
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ffile-prefix-map=\"${CMAKE_SOURCE_DIR}=.\"")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffile-prefix-map=${CMAKE_SOURCE_DIR}=.")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffile-prefix-map=\"${CMAKE_SOURCE_DIR}=.\"")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# release with debug info flags
|
# release with debug info flags
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace api::modules {
|
|||||||
void DRS::touch_set(Request &req, Response &res) {
|
void DRS::touch_set(Request &req, Response &res) {
|
||||||
|
|
||||||
// get all touch points
|
// get all touch points
|
||||||
games::drs::drs_touch_t touches[16];
|
auto touches = std::make_unique<games::drs::drs_touch_t[]>(req.params.Size());
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (Value ¶m : req.params.GetArray()) {
|
for (Value ¶m : req.params.GetArray()) {
|
||||||
|
|
||||||
@@ -86,6 +86,6 @@ namespace api::modules {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply touch points
|
// apply touch points
|
||||||
games::drs::fire_touches(touches, i);
|
games::drs::fire_touches(touches.get(), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ then
|
|||||||
BUILD_TYPE="Debug"
|
BUILD_TYPE="Debug"
|
||||||
BUILDDIR_32=${BUILDDIR_32_DEBUG}
|
BUILDDIR_32=${BUILDDIR_32_DEBUG}
|
||||||
BUILDDIR_64=${BUILDDIR_64_DEBUG}
|
BUILDDIR_64=${BUILDDIR_64_DEBUG}
|
||||||
DIST_NAME=$(echo ${DIST_NAME} | sed 's/\.[^.]*$/-dbg&/')
|
DIST_NAME=$(echo "${DIST_NAME}" | sed 's/\.[^.]*$/-dbg&/')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# determine number of cores
|
# determine number of cores
|
||||||
@@ -114,7 +114,7 @@ time (
|
|||||||
fi
|
fi
|
||||||
mkdir -p ${BUILDDIR_32}
|
mkdir -p ${BUILDDIR_32}
|
||||||
pushd ${BUILDDIR_32} > /dev/null
|
pushd ${BUILDDIR_32} > /dev/null
|
||||||
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_32} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} $OLDPWD && ninja ${TARGETS_32}
|
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_32} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} "$OLDPWD" && ninja ${TARGETS_32}
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
|
|
||||||
# 64 bit
|
# 64 bit
|
||||||
@@ -127,7 +127,7 @@ time (
|
|||||||
fi
|
fi
|
||||||
mkdir -p ${BUILDDIR_64}
|
mkdir -p ${BUILDDIR_64}
|
||||||
pushd ${BUILDDIR_64} > /dev/null
|
pushd ${BUILDDIR_64} > /dev/null
|
||||||
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_64} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} $OLDPWD && ninja ${TARGETS_64}
|
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_64} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} "$OLDPWD" && ninja ${TARGETS_64}
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
@@ -234,7 +234,7 @@ mkdir -p ${OUTDIR}/src
|
|||||||
if ((INCLUDE_SRC > 0))
|
if ((INCLUDE_SRC > 0))
|
||||||
then
|
then
|
||||||
echo "Generating source file archive..."
|
echo "Generating source file archive..."
|
||||||
git archive --format tar.gz --prefix=spice2x/ HEAD ./ > ${OUTDIR}/src/spice2x-${GIT_BRANCH}.tar.gz 2>/dev/null || \
|
git archive --format tar.gz --prefix=spice2x/ HEAD ./ > "${OUTDIR}/src/spice2x-${GIT_BRANCH}.tar.gz" 2>/dev/null || \
|
||||||
echo "WARNING: Couldn't get git to create the archive. Is this a git repository?"
|
echo "WARNING: Couldn't get git to create the archive. Is this a git repository?"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -249,11 +249,11 @@ if ((DIST_ENABLE > 0))
|
|||||||
then
|
then
|
||||||
echo "Building dist..."
|
echo "Building dist..."
|
||||||
mkdir -p ${DIST_FOLDER}
|
mkdir -p ${DIST_FOLDER}
|
||||||
rm -rf ${DIST_FOLDER}/${DIST_NAME}
|
rm -rf "${DIST_FOLDER}/${DIST_NAME}"
|
||||||
pushd ${OUTDIR}/.. > /dev/null
|
pushd ${OUTDIR}/.. > /dev/null
|
||||||
zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME} spice2x -x "spice2x/extras/*" -z <<< "$DIST_COMMENT"
|
zip -qrXT9 "$OLDPWD/${DIST_FOLDER}/${DIST_NAME}" spice2x -x "spice2x/extras/*" -z <<< "$DIST_COMMENT"
|
||||||
echo "Building extras..."
|
echo "Building extras..."
|
||||||
zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME_EXTRAS} spice2x -z <<< "$DIST_COMMENT"
|
zip -qrXT9 "$OLDPWD/${DIST_FOLDER}/${DIST_NAME_EXTRAS}" spice2x -z <<< "$DIST_COMMENT"
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
docker build --pull $PWD/external/docker -t spicetools/deps --platform linux/x86_64
|
docker build --pull "$PWD/external/docker" -t spicetools/deps --platform linux/x86_64
|
||||||
docker build --build-context gitroot=$PWD/../../.git . -t spicetools/spice:latest
|
docker build --build-context gitroot="$PWD/../../.git" . -t spicetools/spice:latest
|
||||||
docker run --rm -v $PWD/dist:/src/src/spice2x/dist -v $PWD/bin:/src/src/spice2x/bin -v $PWD/.ccache:/src/src/spice2x/.ccache spicetools/spice "$@"
|
docker run --rm -v "$PWD/dist:/src/src/spice2x/dist" -v "$PWD/bin:/src/src/spice2x/bin" -v "$PWD/.ccache:/src/src/spice2x/.ccache" spicetools/spice "$@"
|
||||||
|
|||||||
@@ -644,10 +644,12 @@ float GameAPI::Analogs::getState(rawinput::Device *device, Analog &analog) {
|
|||||||
case rawinput::HID: {
|
case rawinput::HID: {
|
||||||
|
|
||||||
// get value
|
// get value
|
||||||
if (inverted) {
|
if (index < device->hidInfo->value_states.size()) {
|
||||||
value = 1.f - device->hidInfo->value_states[index];
|
if (inverted) {
|
||||||
} else {
|
value = 1.f - device->hidInfo->value_states[index];
|
||||||
value = device->hidInfo->value_states[index];
|
} else {
|
||||||
|
value = device->hidInfo->value_states[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// deadzone
|
// deadzone
|
||||||
|
|||||||
+33
-13
@@ -58,8 +58,28 @@ std::string Button::getVKeyString() {
|
|||||||
return "Pause";
|
return "Pause";
|
||||||
case 0x14:
|
case 0x14:
|
||||||
return "Caps Lock";
|
return "Caps Lock";
|
||||||
|
case 0x15:
|
||||||
|
return "IME Kana/Hangul";
|
||||||
|
case 0x16:
|
||||||
|
return "IME On";
|
||||||
|
case 0x17:
|
||||||
|
return "IME Junja";
|
||||||
|
case 0x18:
|
||||||
|
return "IME Final";
|
||||||
|
case 0x19:
|
||||||
|
return "IME Hanja/Kanji";
|
||||||
|
case 0x1A:
|
||||||
|
return "IME Off";
|
||||||
case 0x1B:
|
case 0x1B:
|
||||||
return "Escape";
|
return "Escape";
|
||||||
|
case 0x1C:
|
||||||
|
return "IME Convert";
|
||||||
|
case 0x1D:
|
||||||
|
return "IME Nonconvert";
|
||||||
|
case 0x1E:
|
||||||
|
return "IME Accept";
|
||||||
|
case 0x1F:
|
||||||
|
return "IME Mode Change";
|
||||||
case 0x20:
|
case 0x20:
|
||||||
return "Space";
|
return "Space";
|
||||||
case 0x21:
|
case 0x21:
|
||||||
@@ -255,9 +275,9 @@ std::string Button::getVKeyString() {
|
|||||||
case 0xA3:
|
case 0xA3:
|
||||||
return "Right Control";
|
return "Right Control";
|
||||||
case 0xA4:
|
case 0xA4:
|
||||||
return "Left Menu";
|
return "Left Alt";
|
||||||
case 0xA5:
|
case 0xA5:
|
||||||
return "Right Menu";
|
return "Right Alt";
|
||||||
default:
|
default:
|
||||||
|
|
||||||
// check win API
|
// check win API
|
||||||
@@ -301,17 +321,17 @@ std::string Button::getDisplayString(rawinput::RawInputManager* manager) {
|
|||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case rawinput::MOUSE: {
|
case rawinput::MOUSE: {
|
||||||
const char *btn = "Unknown";
|
const char *btn = "Unknown";
|
||||||
static const char *MOUSE_NAMES[] = {
|
static const std::array<const char *, 8>MOUSE_NAMES = {
|
||||||
"Left Mouse",
|
"Left Mouse",
|
||||||
"Right Mouse",
|
"Right Mouse",
|
||||||
"Middle Mouse",
|
"Middle Mouse",
|
||||||
"Mouse 1",
|
"Mouse 1",
|
||||||
"Mouse 2",
|
"Mouse 2",
|
||||||
"Mouse 3",
|
"Mouse 3",
|
||||||
"Mouse 4",
|
"Mouse 4",
|
||||||
"Mouse 5",
|
"Mouse 5",
|
||||||
};
|
};
|
||||||
if (vKey < sizeof(MOUSE_NAMES)) {
|
if (vKey < MOUSE_NAMES.size()) {
|
||||||
btn = MOUSE_NAMES[vKey];
|
btn = MOUSE_NAMES[vKey];
|
||||||
}
|
}
|
||||||
return fmt::format("{} ({})", btn, device->desc);
|
return fmt::format("{} ({})", btn, device->desc);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ private:
|
|||||||
double debounce_up = 0.0;
|
double debounce_up = 0.0;
|
||||||
double debounce_down = 0.0;
|
double debounce_down = 0.0;
|
||||||
bool invert = false;
|
bool invert = false;
|
||||||
|
bool is_temporary = false;
|
||||||
|
|
||||||
GameAPI::Buttons::State last_state = GameAPI::Buttons::BUTTON_NOT_PRESSED;
|
GameAPI::Buttons::State last_state = GameAPI::Buttons::BUTTON_NOT_PRESSED;
|
||||||
float last_velocity = 0.f;
|
float last_velocity = 0.f;
|
||||||
@@ -164,6 +165,14 @@ public:
|
|||||||
this->last_velocity = last_velocity;
|
this->last_velocity = last_velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isTemporary() const {
|
||||||
|
return this->is_temporary;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTemporary(bool is_temporary) {
|
||||||
|
this->is_temporary = is_temporary;
|
||||||
|
}
|
||||||
|
|
||||||
inline unsigned short getVelocityThreshold() const {
|
inline unsigned short getVelocityThreshold() const {
|
||||||
return this->velocity_threshold;
|
return this->velocity_threshold;
|
||||||
}
|
}
|
||||||
@@ -172,6 +181,20 @@ public:
|
|||||||
this->velocity_threshold = velocity_threshold;
|
this->velocity_threshold = velocity_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isValid() {
|
||||||
|
// temporarily created by UI
|
||||||
|
if (isTemporary()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing is set
|
||||||
|
if (getDeviceIdentifier().empty() && getVKey() == INVALID_VKEY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void getMidiVKey(int& channel, int& index);
|
void getMidiVKey(int& channel, int& index);
|
||||||
void setMidiVKey(rawinput::RawInputManager* manager, bool is_note, int channel, int index);
|
void setMidiVKey(rawinput::RawInputManager* manager, bool is_note, int channel, int index);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
|
#include "cfg/button.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code absolutely sucks.
|
* This code absolutely sucks.
|
||||||
@@ -10,6 +11,14 @@
|
|||||||
// settings
|
// settings
|
||||||
std::string CONFIG_PATH_OVERRIDE = "";
|
std::string CONFIG_PATH_OVERRIDE = "";
|
||||||
|
|
||||||
|
#define CFG_DEBUG_VERBOSE 0
|
||||||
|
|
||||||
|
#if CFG_DEBUG_VERBOSE
|
||||||
|
#define log_debug(module, format_str, ...) logger::push( \
|
||||||
|
LOG_FORMAT("M", module, format_str, ## __VA_ARGS__), logger::Style::GREY)
|
||||||
|
#else
|
||||||
|
#define log_debug(module, format_str, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
/// Constructor ///
|
/// Constructor ///
|
||||||
@@ -510,8 +519,10 @@ bool Config::updateBinding(const Game &game, const Button &button, int alternati
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tinyxml2::XMLElement *gameButtonNode = nullptr;
|
||||||
|
|
||||||
// iterate button nodes
|
// iterate button nodes
|
||||||
tinyxml2::XMLElement *gameButtonNode = gameButtonsNode->FirstChildElement("button");
|
gameButtonNode = gameButtonsNode->FirstChildElement("button");
|
||||||
int button_count = 0;
|
int button_count = 0;
|
||||||
while (gameButtonNode != nullptr) {
|
while (gameButtonNode != nullptr) {
|
||||||
const char *buttonNodeName = gameButtonNode->Attribute("name");
|
const char *buttonNodeName = gameButtonNode->Attribute("name");
|
||||||
@@ -574,6 +585,39 @@ bool Config::updateBinding(const Game &game, const Button &button, int alternati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trim the trailing invalid (unbound) alternatives
|
||||||
|
tinyxml2::XMLElement *to_delete = nullptr;
|
||||||
|
gameButtonNode = gameButtonsNode->LastChildElement("button");
|
||||||
|
while (gameButtonNode != nullptr) {
|
||||||
|
const char *name = gameButtonNode->Attribute("name");
|
||||||
|
const char *devid = gameButtonNode->Attribute("devid");
|
||||||
|
int vkey = INVALID_VKEY;
|
||||||
|
gameButtonNode->QueryIntAttribute("vkey", &vkey);
|
||||||
|
|
||||||
|
// wrong button, ignore and keep iterating backwards
|
||||||
|
if (name == nullptr || std::string(name) != button.getName()) {
|
||||||
|
gameButtonNode = gameButtonNode->PreviousSiblingElement("button");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// found a node for this button, which means to_delete is not the first one
|
||||||
|
// delete the node for to_delete
|
||||||
|
if (to_delete != nullptr) {
|
||||||
|
log_debug("cfg", "deleting excessive button binding for {}", name);
|
||||||
|
gameButtonsNode->DeleteChild(to_delete);
|
||||||
|
to_delete = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((devid == nullptr || strlen(devid) == 0) && vkey == INVALID_VKEY) {
|
||||||
|
// unbound button with no device ID, make a note of it so it can be deleted later
|
||||||
|
to_delete = gameButtonNode;
|
||||||
|
gameButtonNode = gameButtonNode->PreviousSiblingElement("button");
|
||||||
|
} else {
|
||||||
|
// valid binding found; stop iterating
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if button was not found
|
// check if button was not found
|
||||||
if (button_count == 0) {
|
if (button_count == 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -760,6 +804,37 @@ bool Config::updateBinding(const Game &game, const Light &light, int alternative
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trim the trailing invalid (unbound) alternatives
|
||||||
|
tinyxml2::XMLElement *to_delete = nullptr;
|
||||||
|
gameLightNode = gameLightsNode->LastChildElement("light");
|
||||||
|
while (gameLightNode != nullptr) {
|
||||||
|
const char *name = gameLightNode->Attribute("name");
|
||||||
|
const char *devid = gameLightNode->Attribute("devid");
|
||||||
|
|
||||||
|
// wrong light, ignore and keep iterating backwards
|
||||||
|
if (name == nullptr || std::string(name) != light.getName()) {
|
||||||
|
gameLightNode = gameLightNode->PreviousSiblingElement("light");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// found a node for this button, which means to_delete is not the first one
|
||||||
|
// delete the node for to_delete
|
||||||
|
if (to_delete != nullptr) {
|
||||||
|
log_debug("cfg", "deleting excessive light binding for {}", name);
|
||||||
|
gameLightsNode->DeleteChild(to_delete);
|
||||||
|
to_delete = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devid == nullptr || strlen(devid) == 0) {
|
||||||
|
// unbound light, make a note of it so it can be deleted later
|
||||||
|
to_delete = gameLightNode;
|
||||||
|
gameLightNode = gameLightNode->PreviousSiblingElement("light");
|
||||||
|
} else {
|
||||||
|
// valid binding found; stop iterating
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if light was not found
|
// check if light was not found
|
||||||
if (light_count == 0) {
|
if (light_count == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ private:
|
|||||||
std::string lightName;
|
std::string lightName;
|
||||||
std::string deviceIdentifier = "";
|
std::string deviceIdentifier = "";
|
||||||
unsigned int index = 0;
|
unsigned int index = 0;
|
||||||
|
bool is_temporary = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float last_state = 0.f;
|
float last_state = 0.f;
|
||||||
@@ -65,4 +66,26 @@ public:
|
|||||||
inline void setIndex(unsigned int index) {
|
inline void setIndex(unsigned int index) {
|
||||||
this->index = index;
|
this->index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isTemporary() const {
|
||||||
|
return this->is_temporary;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTemporary(bool is_temporary) {
|
||||||
|
this->is_temporary = is_temporary;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isValid() {
|
||||||
|
// temporarily created by UI
|
||||||
|
if (isTemporary()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing is set
|
||||||
|
if (getDeviceIdentifier().empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ enum class OptionType {
|
|||||||
Hex,
|
Hex,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class OptionPickerType {
|
||||||
|
None,
|
||||||
|
AsioDriver,
|
||||||
|
EACard,
|
||||||
|
CpuAffinity,
|
||||||
|
FilePath,
|
||||||
|
DirectoryPath,
|
||||||
|
};
|
||||||
|
|
||||||
struct OptionDefinition {
|
struct OptionDefinition {
|
||||||
std::string title;
|
std::string title;
|
||||||
// unique identifier used for flag matching but also stored in config files
|
// unique identifier used for flag matching but also stored in config files
|
||||||
@@ -32,6 +41,10 @@ struct OptionDefinition {
|
|||||||
bool sensitive = false;
|
bool sensitive = false;
|
||||||
std::vector<std::pair<std::string, std::string>> elements = {};
|
std::vector<std::pair<std::string, std::string>> elements = {};
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
OptionPickerType picker = OptionPickerType::None;
|
||||||
|
|
||||||
|
// for OptionPickerType::FilePath
|
||||||
|
std::string file_extension = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
class Option {
|
class Option {
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ namespace games::iidx {
|
|||||||
bool IIDXIO_LED_TICKER_READONLY = false;
|
bool IIDXIO_LED_TICKER_READONLY = false;
|
||||||
std::mutex IIDX_LED_TICKER_LOCK;
|
std::mutex IIDX_LED_TICKER_LOCK;
|
||||||
bool IIDX_TDJ_MONITOR_WARNING = false;
|
bool IIDX_TDJ_MONITOR_WARNING = false;
|
||||||
|
iidx_aio_emulation_state CURRENT_IO_EMULATION_STATE = iidx_aio_emulation_state::unknown;
|
||||||
|
|
||||||
// io
|
// io
|
||||||
static bool HAS_LIBAIO; // this is how we detect iidx27+
|
static bool HAS_LIBAIO; // this is how we detect iidx27+
|
||||||
@@ -453,7 +454,7 @@ namespace games::iidx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// windowed subscreen, enabled by default, unless turned off by user
|
// windowed subscreen, enabled by default, unless turned off by user
|
||||||
if (GRAPHICS_WINDOWED && !options->at(launcher::Options::spice2x_IIDXNoSub).value_bool()) {
|
if (GRAPHICS_WINDOWED && !options->at(launcher::Options::spice2x_IIDXNoSub).value_bool() && TDJ_MODE) {
|
||||||
GRAPHICS_IIDX_WSUB = true;
|
GRAPHICS_IIDX_WSUB = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,6 +935,8 @@ namespace games::iidx {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CURRENT_IO_EMULATION_STATE = state;
|
||||||
|
|
||||||
// log_warning below could be turned into log_fatal in the future once we gain confidence
|
// log_warning below could be turned into log_fatal in the future once we gain confidence
|
||||||
// that this isn't triggering when it's not supposed to
|
// that this isn't triggering when it's not supposed to
|
||||||
if (state == iidx_aio_emulation_state::bi2a_com2 && TDJ_MODE) {
|
if (state == iidx_aio_emulation_state::bi2a_com2 && TDJ_MODE) {
|
||||||
|
|||||||
@@ -11,6 +11,12 @@
|
|||||||
|
|
||||||
namespace games::iidx {
|
namespace games::iidx {
|
||||||
|
|
||||||
|
enum class iidx_aio_emulation_state {
|
||||||
|
unknown,
|
||||||
|
bi2a_com2,
|
||||||
|
bi2x_hook
|
||||||
|
};
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
|
|
||||||
extern bool FLIP_CAMS;
|
extern bool FLIP_CAMS;
|
||||||
@@ -38,6 +44,7 @@ namespace games::iidx {
|
|||||||
constexpr int IIDX_TAPELED_TOTAL = 17;
|
constexpr int IIDX_TAPELED_TOTAL = 17;
|
||||||
// data mapping
|
// data mapping
|
||||||
extern tapeledutils::tape_led TAPELED_MAPPING[IIDX_TAPELED_TOTAL];
|
extern tapeledutils::tape_led TAPELED_MAPPING[IIDX_TAPELED_TOTAL];
|
||||||
|
extern iidx_aio_emulation_state CURRENT_IO_EMULATION_STATE;
|
||||||
|
|
||||||
class IIDXGame : public games::Game {
|
class IIDXGame : public games::Game {
|
||||||
public:
|
public:
|
||||||
@@ -64,9 +71,5 @@ namespace games::iidx {
|
|||||||
bool is_tdj_fhd();
|
bool is_tdj_fhd();
|
||||||
void apply_audio_hacks();
|
void apply_audio_hacks();
|
||||||
|
|
||||||
enum class iidx_aio_emulation_state {
|
|
||||||
bi2a_com2,
|
|
||||||
bi2x_hook
|
|
||||||
};
|
|
||||||
void update_io_emulation_state(iidx_aio_emulation_state state);
|
void update_io_emulation_state(iidx_aio_emulation_state state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ namespace games {
|
|||||||
buttons_help.insert({ pc, pc::get_buttons_help() });
|
buttons_help.insert({ pc, pc::get_buttons_help() });
|
||||||
analogs.insert({ pc, pc::get_analogs() });
|
analogs.insert({ pc, pc::get_analogs() });
|
||||||
lights.insert({ pc, pc::get_lights() });
|
lights.insert({ pc, pc::get_lights() });
|
||||||
file_hints[pc].emplace_back("game/svm_Data");
|
file_hints[pc].emplace_back("game/svm.exe");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &get_games() {
|
const std::vector<std::string> &get_games() {
|
||||||
|
|||||||
@@ -21,8 +21,9 @@
|
|||||||
#include "util/socd_cleaner.h"
|
#include "util/socd_cleaner.h"
|
||||||
#include "util/time.h"
|
#include "util/time.h"
|
||||||
#include "util/libutils.h"
|
#include "util/libutils.h"
|
||||||
#include "misc/wintouchemu.h"
|
|
||||||
#include "misc/eamuse.h"
|
#include "misc/eamuse.h"
|
||||||
|
#include "misc/nativetouchhook.h"
|
||||||
|
#include "misc/wintouchemu.h"
|
||||||
#include "bi2x_hook.h"
|
#include "bi2x_hook.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
@@ -416,9 +417,11 @@ namespace games::sdvx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_valkyrie_model()) {
|
if (is_valkyrie_model()) {
|
||||||
// hook touch window
|
if (NATIVETOUCH) {
|
||||||
// in windowed mode, game can accept mouse input on the second screen
|
nativetouchhook::hook(avs::game::DLL_INSTANCE);
|
||||||
if (!NATIVETOUCH && !GRAPHICS_WINDOWED) {
|
} else if (!NATIVETOUCH && !GRAPHICS_WINDOWED) {
|
||||||
|
// hook touch window
|
||||||
|
// in windowed mode, game can accept mouse input on the second screen
|
||||||
wintouchemu::FORCE = true;
|
wintouchemu::FORCE = true;
|
||||||
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
|
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
|
||||||
wintouchemu::hook_title_ends(
|
wintouchemu::hook_title_ends(
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ namespace hooks::audio {
|
|||||||
bool USE_DUMMY = false;
|
bool USE_DUMMY = false;
|
||||||
WAVEFORMATEXTENSIBLE FORMAT {};
|
WAVEFORMATEXTENSIBLE FORMAT {};
|
||||||
std::optional<Backend> BACKEND = std::nullopt;
|
std::optional<Backend> BACKEND = std::nullopt;
|
||||||
size_t ASIO_DRIVER_ID = 0;
|
std::optional<size_t> ASIO_DRIVER_ID = std::nullopt;
|
||||||
|
std::string ASIO_DRIVER_NAME = "";
|
||||||
bool ASIO_FORCE_UNLOAD_ON_STOP = false;
|
bool ASIO_FORCE_UNLOAD_ON_STOP = false;
|
||||||
|
|
||||||
// private globals
|
// private globals
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmreg.h>
|
#include <mmreg.h>
|
||||||
@@ -20,7 +21,8 @@ namespace hooks::audio {
|
|||||||
extern bool USE_DUMMY;
|
extern bool USE_DUMMY;
|
||||||
extern WAVEFORMATEXTENSIBLE FORMAT;
|
extern WAVEFORMATEXTENSIBLE FORMAT;
|
||||||
extern std::optional<Backend> BACKEND;
|
extern std::optional<Backend> BACKEND;
|
||||||
extern size_t ASIO_DRIVER_ID;
|
extern std::optional<size_t> ASIO_DRIVER_ID;
|
||||||
|
extern std::string ASIO_DRIVER_NAME;
|
||||||
extern bool ASIO_FORCE_UNLOAD_ON_STOP;
|
extern bool ASIO_FORCE_UNLOAD_ON_STOP;
|
||||||
extern bool LOW_LATENCY_SHARED_WASAPI;
|
extern bool LOW_LATENCY_SHARED_WASAPI;
|
||||||
|
|
||||||
|
|||||||
@@ -218,13 +218,40 @@ void AsioBackend::set_thread_state(AsioThreadState state) {
|
|||||||
bool AsioBackend::load_driver() {
|
bool AsioBackend::load_driver() {
|
||||||
AsioDriverList asio_driver_list;
|
AsioDriverList asio_driver_list;
|
||||||
|
|
||||||
for (const auto &driver : asio_driver_list.driver_list) {
|
size_t driver_id = 0;
|
||||||
log_info("audio::asio", "Driver {}", driver.id);
|
std::string driver_name = "";
|
||||||
log_info("audio::asio", "... Name : {}", driver.name);
|
if (hooks::audio::ASIO_DRIVER_ID.has_value()) {
|
||||||
log_info("audio::asio", "... Path : {}", driver.dll_path);
|
driver_id = hooks::audio::ASIO_DRIVER_ID.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto driver_id = hooks::audio::ASIO_DRIVER_ID;
|
for (const auto &driver : asio_driver_list.driver_list) {
|
||||||
|
log_info("audio::asio", " Driver ID : {}", driver.id);
|
||||||
|
log_info("audio::asio", " ... Name : {}", driver.name);
|
||||||
|
log_info("audio::asio", " ... Path : {}", driver.dll_path);
|
||||||
|
|
||||||
|
if (!hooks::audio::ASIO_DRIVER_NAME.empty()) {
|
||||||
|
// match on driver name
|
||||||
|
if (driver.name == hooks::audio::ASIO_DRIVER_NAME) {
|
||||||
|
driver_id = driver.id;
|
||||||
|
driver_name = driver.name;
|
||||||
|
}
|
||||||
|
} else if (driver.id == driver_id) {
|
||||||
|
// match on driver index (0 for default or user-specified)
|
||||||
|
driver_name = driver.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driver_name.empty()) {
|
||||||
|
if (!hooks::audio::ASIO_DRIVER_NAME.empty()) {
|
||||||
|
log_warning(
|
||||||
|
"audio::asio",
|
||||||
|
"tried to look for ASIO driver but failed: {}", hooks::audio::ASIO_DRIVER_NAME);
|
||||||
|
}
|
||||||
|
log_fatal(
|
||||||
|
"audio::asio",
|
||||||
|
"could not find ASIO driver to use for conversion, fix your audio options and try again");
|
||||||
|
}
|
||||||
|
log_info("audio::asio", "will attempt to use the following ASIO driver: ID = {}, Name = {}", driver_id, driver_name);
|
||||||
|
|
||||||
IAsio *driver = nullptr;
|
IAsio *driver = nullptr;
|
||||||
auto ret = asio_driver_list.open_driver(driver_id, reinterpret_cast<void **>(&driver));
|
auto ret = asio_driver_list.open_driver(driver_id, reinterpret_cast<void **>(&driver));
|
||||||
|
|||||||
@@ -945,26 +945,37 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDeviceEx(
|
|||||||
|
|
||||||
for (size_t i = 0; i < num_adapters; i++) {
|
for (size_t i = 0; i < num_adapters; i++) {
|
||||||
auto *params = &pPresentationParameters[i];
|
auto *params = &pPresentationParameters[i];
|
||||||
if (!GRAPHICS_WINDOWED && i == 0) {
|
if (!GRAPHICS_WINDOWED){
|
||||||
GRAPHICS_FS_ORIGINAL_WIDTH = params->BackBufferWidth;
|
if (i == 0) {
|
||||||
GRAPHICS_FS_ORIGINAL_HEIGHT = params->BackBufferHeight;
|
GRAPHICS_FS_ORIGINAL_WIDTH = params->BackBufferWidth;
|
||||||
log_misc("graphics::d3d9", "original resolution: {}x{}", GRAPHICS_FS_ORIGINAL_WIDTH, GRAPHICS_FS_ORIGINAL_HEIGHT);
|
GRAPHICS_FS_ORIGINAL_HEIGHT = params->BackBufferHeight;
|
||||||
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
log_misc("graphics::d3d9", "original resolution: {}x{}", GRAPHICS_FS_ORIGINAL_WIDTH, GRAPHICS_FS_ORIGINAL_HEIGHT);
|
||||||
|
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
||||||
|
log_misc(
|
||||||
|
"graphics::d3d9",
|
||||||
|
"use custom resolution {}x{} => {}x{}",
|
||||||
|
params->BackBufferWidth, params->BackBufferHeight,
|
||||||
|
GRAPHICS_FS_CUSTOM_RESOLUTION.value().first,
|
||||||
|
GRAPHICS_FS_CUSTOM_RESOLUTION.value().second);
|
||||||
|
params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
||||||
|
params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
||||||
|
} else if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
||||||
|
log_misc(
|
||||||
|
"graphics::d3d9",
|
||||||
|
"swap full orientation {}x{} => {}x{}",
|
||||||
|
params->BackBufferWidth, params->BackBufferHeight,
|
||||||
|
params->BackBufferHeight, params->BackBufferWidth);
|
||||||
|
std::swap(params->BackBufferWidth, params->BackBufferHeight);
|
||||||
|
}
|
||||||
|
} else if (i == 1 && GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.has_value()) {
|
||||||
log_misc(
|
log_misc(
|
||||||
"graphics::d3d9",
|
"graphics::d3d9",
|
||||||
"use custom resolution {}x{} => {}x{}",
|
"use custom sub resolution {}x{} => {}x{}",
|
||||||
params->BackBufferWidth, params->BackBufferHeight,
|
params->BackBufferWidth, params->BackBufferHeight,
|
||||||
GRAPHICS_FS_CUSTOM_RESOLUTION.value().first,
|
GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().first,
|
||||||
GRAPHICS_FS_CUSTOM_RESOLUTION.value().second);
|
GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().second);
|
||||||
params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().first;
|
||||||
params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().second;
|
||||||
} else if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
|
||||||
log_misc(
|
|
||||||
"graphics::d3d9",
|
|
||||||
"swap full orientation {}x{} => {}x{}",
|
|
||||||
params->BackBufferWidth, params->BackBufferHeight,
|
|
||||||
params->BackBufferHeight, params->BackBufferWidth);
|
|
||||||
std::swap(params->BackBufferWidth, params->BackBufferHeight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -992,12 +1003,17 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDeviceEx(
|
|||||||
for (size_t i = 0; i < num_adapters; i++) {
|
for (size_t i = 0; i < num_adapters; i++) {
|
||||||
auto *fullscreen_display_mode = &pFullscreenDisplayMode[i];
|
auto *fullscreen_display_mode = &pFullscreenDisplayMode[i];
|
||||||
|
|
||||||
if (!GRAPHICS_WINDOWED && i == 0) {
|
if (!GRAPHICS_WINDOWED) {
|
||||||
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
if (i == 0) {
|
||||||
fullscreen_display_mode->Width = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
||||||
fullscreen_display_mode->Height = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
fullscreen_display_mode->Width = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
||||||
} else if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
fullscreen_display_mode->Height = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
||||||
std::swap(fullscreen_display_mode->Width, fullscreen_display_mode->Height);
|
} else if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
||||||
|
std::swap(fullscreen_display_mode->Width, fullscreen_display_mode->Height);
|
||||||
|
}
|
||||||
|
} else if (i == 1 && GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.has_value()) {
|
||||||
|
fullscreen_display_mode->Width = GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().first;
|
||||||
|
fullscreen_display_mode->Height = GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ bool GRAPHICS_9_ON_12_REQUESTED_BY_GAME = false;
|
|||||||
bool SUBSCREEN_FORCE_REDRAW = false;
|
bool SUBSCREEN_FORCE_REDRAW = false;
|
||||||
bool D3D9_DEVICE_HOOK_DISABLE = false;
|
bool D3D9_DEVICE_HOOK_DISABLE = false;
|
||||||
std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_FS_CUSTOM_RESOLUTION;
|
std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_FS_CUSTOM_RESOLUTION;
|
||||||
|
std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_FS_CUSTOM_RESOLUTION_SUB;
|
||||||
bool GRAPHICS_FS_ORIENTATION_SWAP = false;
|
bool GRAPHICS_FS_ORIENTATION_SWAP = false;
|
||||||
uint32_t GRAPHICS_FS_ORIGINAL_WIDTH = 0;
|
uint32_t GRAPHICS_FS_ORIGINAL_WIDTH = 0;
|
||||||
uint32_t GRAPHICS_FS_ORIGINAL_HEIGHT = 0;
|
uint32_t GRAPHICS_FS_ORIGINAL_HEIGHT = 0;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ extern std::optional<int> GRAPHICS_FORCE_VSYNC_BUFFER;
|
|||||||
extern bool GRAPHICS_FORCE_SINGLE_ADAPTER;
|
extern bool GRAPHICS_FORCE_SINGLE_ADAPTER;
|
||||||
extern bool GRAPHICS_PREVENT_SECONDARY_WINDOW;
|
extern bool GRAPHICS_PREVENT_SECONDARY_WINDOW;
|
||||||
extern std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_FS_CUSTOM_RESOLUTION;
|
extern std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_FS_CUSTOM_RESOLUTION;
|
||||||
|
extern std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_FS_CUSTOM_RESOLUTION_SUB;
|
||||||
extern bool GRAPHICS_FS_ORIENTATION_SWAP;
|
extern bool GRAPHICS_FS_ORIENTATION_SWAP;
|
||||||
extern uint32_t GRAPHICS_FS_ORIGINAL_WIDTH;
|
extern uint32_t GRAPHICS_FS_ORIGINAL_WIDTH;
|
||||||
extern uint32_t GRAPHICS_FS_ORIGINAL_HEIGHT;
|
extern uint32_t GRAPHICS_FS_ORIGINAL_HEIGHT;
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ void graphics_load_windowed_parameters() {
|
|||||||
cfg::SCREENRESIZE->window_offset_x = result.first;
|
cfg::SCREENRESIZE->window_offset_x = result.first;
|
||||||
cfg::SCREENRESIZE->window_offset_y = result.second;
|
cfg::SCREENRESIZE->window_offset_y = result.second;
|
||||||
} else {
|
} else {
|
||||||
log_warning("graphics-windowed", "failed to parse -windowpos");
|
log_fatal("graphics-windowed", "failed to parse -windowpos");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ void graphics_load_windowed_subscreen_parameters() {
|
|||||||
GRAPHICS_WSUB_WIDTH = result.first;
|
GRAPHICS_WSUB_WIDTH = result.first;
|
||||||
GRAPHICS_WSUB_HEIGHT = result.second;
|
GRAPHICS_WSUB_HEIGHT = result.second;
|
||||||
} else {
|
} else {
|
||||||
log_warning("graphics-windowed", "failed to parse -wsubsize");
|
log_fatal("graphics-windowed", "failed to parse -iidxwsubsize / -sdvxwsubsize");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ void graphics_load_windowed_subscreen_parameters() {
|
|||||||
GRAPHICS_WSUB_X = result.first;
|
GRAPHICS_WSUB_X = result.first;
|
||||||
GRAPHICS_WSUB_Y = result.second;
|
GRAPHICS_WSUB_Y = result.second;
|
||||||
} else {
|
} else {
|
||||||
log_warning("graphics-windowed", "failed to parse -wsubpos");
|
log_fatal("graphics-windowed", "failed to parse -iidxwsubpos / -sdvxwsubpos");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1011,18 +1011,26 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
if (options[launcher::Options::spice2x_DisableVolumeHook].value_bool()) {
|
if (options[launcher::Options::spice2x_DisableVolumeHook].value_bool()) {
|
||||||
hooks::audio::VOLUME_HOOK_ENABLED = false;
|
hooks::audio::VOLUME_HOOK_ENABLED = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options[launcher::Options::AudioBackend].is_active()) {
|
if (options[launcher::Options::AudioBackend].is_active()) {
|
||||||
auto &name = options[launcher::Options::AudioBackend].value_text();
|
auto &name = options[launcher::Options::AudioBackend].value_text();
|
||||||
auto backend = hooks::audio::name_to_backend(name.c_str());
|
auto backend = hooks::audio::name_to_backend(name.c_str());
|
||||||
if (!backend.has_value() && !cfg::CONFIGURATOR_STANDALONE) {
|
if (!backend.has_value() && !cfg::CONFIGURATOR_STANDALONE) {
|
||||||
log_fatal("launcher", "invalid audio backend: {}", name);
|
log_fatal("launcher", "invalid audio backend: {}", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
hooks::audio::BACKEND = backend;
|
hooks::audio::BACKEND = backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options[launcher::Options::AsioDriverId].is_active()) {
|
if (options[launcher::Options::AsioDriverId].is_active()) {
|
||||||
hooks::audio::ASIO_DRIVER_ID = options[launcher::Options::AsioDriverId].value_uint32();
|
hooks::audio::ASIO_DRIVER_ID = options[launcher::Options::AsioDriverId].value_uint32();
|
||||||
}
|
}
|
||||||
|
if (options[launcher::Options::AsioDriverName].is_active()) {
|
||||||
|
hooks::audio::BACKEND = hooks::audio::name_to_backend("asio");
|
||||||
|
hooks::audio::ASIO_DRIVER_NAME = options[launcher::Options::AsioDriverName].value_text();
|
||||||
|
// this new option overrides the old one
|
||||||
|
hooks::audio::ASIO_DRIVER_ID.reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (options[launcher::Options::AudioDummy].value_bool()) {
|
if (options[launcher::Options::AudioDummy].value_bool()) {
|
||||||
hooks::audio::USE_DUMMY = true;
|
hooks::audio::USE_DUMMY = true;
|
||||||
}
|
}
|
||||||
@@ -1083,8 +1091,8 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
std::pair<uint32_t, uint32_t> result;
|
std::pair<uint32_t, uint32_t> result;
|
||||||
if (parse_width_height(options[launcher::Options::spice2x_WindowSize].value_text(), result)) {
|
if (parse_width_height(options[launcher::Options::spice2x_WindowSize].value_text(), result)) {
|
||||||
GRAPHICS_WINDOW_SIZE = result;
|
GRAPHICS_WINDOW_SIZE = result;
|
||||||
} else {
|
} else if (!cfg_run && !cfg::CONFIGURATOR_STANDALONE) {
|
||||||
log_warning("launcher", "failed to parse -windowsize");
|
log_fatal("launcher", "failed to parse -windowsize");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options[launcher::Options::spice2x_WindowPosition].is_active()) {
|
if (options[launcher::Options::spice2x_WindowPosition].is_active()) {
|
||||||
@@ -1385,12 +1393,33 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (launcher::signal::DISABLE && !cfg::CONFIGURATOR_STANDALONE) {
|
||||||
|
log_warning(
|
||||||
|
"launcher",
|
||||||
|
"WARNING - user specified -signaldisable option\n\n\n"
|
||||||
|
"!!! !!!\n"
|
||||||
|
"!!! Using -signaldisable option disables all exception handling, !!!\n"
|
||||||
|
"!!! which means when the game crashes it will likely just vanish !!!\n"
|
||||||
|
"!!! without troubleshooting information in the logs. !!!\n"
|
||||||
|
"!!! !!!\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (options[launcher::Options::FullscreenResolution].is_active()) {
|
if (options[launcher::Options::FullscreenResolution].is_active()) {
|
||||||
std::pair<uint32_t, uint32_t> result;
|
std::pair<uint32_t, uint32_t> result;
|
||||||
if (parse_width_height(options[launcher::Options::FullscreenResolution].value_text(), result)) {
|
if (parse_width_height(options[launcher::Options::FullscreenResolution].value_text(), result)) {
|
||||||
GRAPHICS_FS_CUSTOM_RESOLUTION = result;
|
GRAPHICS_FS_CUSTOM_RESOLUTION = result;
|
||||||
} else {
|
} else if (!cfg_run && !cfg::CONFIGURATOR_STANDALONE) {
|
||||||
log_warning("launcher", "failed to parse -forceres");
|
log_fatal("launcher", "failed to parse -forceres");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options[launcher::Options::FullscreenSubResolution].is_active()) {
|
||||||
|
std::pair<uint32_t, uint32_t> result;
|
||||||
|
if (parse_width_height(options[launcher::Options::FullscreenSubResolution].value_text(), result)) {
|
||||||
|
GRAPHICS_FS_CUSTOM_RESOLUTION_SUB = result;
|
||||||
|
} else if (!cfg_run && !cfg::CONFIGURATOR_STANDALONE) {
|
||||||
|
log_fatal("launcher", "failed to parse -forceressub");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1867,7 +1896,7 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Polaris Chord
|
// Polaris Chord
|
||||||
if (check_dll("kamunity.dll") && fileutils::dir_exists("game/svm_Data")) {
|
if (check_dll("kamunity.dll") && fileutils::file_exists("game/svm.exe")) {
|
||||||
avs::game::DLL_NAME = "kamunity.dll";
|
avs::game::DLL_NAME = "kamunity.dll";
|
||||||
attach_io = true;
|
attach_io = true;
|
||||||
attach_pc = true;
|
attach_pc = true;
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.setting_name = "*.dll",
|
.setting_name = "*.dll",
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
// intentionally not setting a file picker here to discourage people setting this without a good reason
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "Open Configurator",
|
.title = "Open Configurator",
|
||||||
@@ -121,6 +122,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.setting_name = "E004010000000000",
|
.setting_name = "E004010000000000",
|
||||||
.category = "Network",
|
.category = "Network",
|
||||||
.sensitive = true,
|
.sensitive = true,
|
||||||
|
.picker = OptionPickerType::EACard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "Player 2 Card",
|
.title = "Player 2 Card",
|
||||||
@@ -130,6 +132,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.setting_name = "E004010000000000",
|
.setting_name = "E004010000000000",
|
||||||
.category = "Network",
|
.category = "Network",
|
||||||
.sensitive = true,
|
.sensitive = true,
|
||||||
|
.picker = OptionPickerType::EACard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Player1PinMacro
|
// Player1PinMacro
|
||||||
@@ -256,9 +259,21 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.hidden = true,
|
.hidden = true,
|
||||||
.category = "Graphics (Full Screen)"
|
.category = "Graphics (Full Screen)"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// FullscreenSubResolution
|
||||||
|
.title = "Force FS Subscreen Resolution (EXPERIMENTAL)",
|
||||||
|
.name = "forceressub",
|
||||||
|
.desc =
|
||||||
|
"Override fullscreen resolution requested by the game for second monitor, "
|
||||||
|
"useful if you have a sub monitor that is not quite exactly what the game expects.\n\n"
|
||||||
|
"WARNING: experimental as we have not done extensive testing to see if this causes desyncs.",
|
||||||
|
.type = OptionType::Text,
|
||||||
|
.setting_name = "1280,720",
|
||||||
|
.category = "Graphics (Full Screen)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// FullscreenSubRefreshRate
|
// FullscreenSubRefreshRate
|
||||||
.title = "Force Submonitor Refresh Rate (EXPERIMENTAL)",
|
.title = "Force FS Subscreen Refresh Rate (EXPERIMENTAL)",
|
||||||
.name = "graphics-force-refresh-sub",
|
.name = "graphics-force-refresh-sub",
|
||||||
.desc =
|
.desc =
|
||||||
"Override fullscreen refresh rate requested by the game for second monitor, "
|
"Override fullscreen refresh rate requested by the game for second monitor, "
|
||||||
@@ -606,6 +621,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.game_name = "Beatmania IIDX",
|
.game_name = "Beatmania IIDX",
|
||||||
.category = "Game Options",
|
.category = "Game Options",
|
||||||
|
.picker = OptionPickerType::AsioDriver,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "IIDX BIO2 Firmware Update",
|
.title = "IIDX BIO2 Firmware Update",
|
||||||
@@ -766,6 +782,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.game_name = "Sound Voltex",
|
.game_name = "Sound Voltex",
|
||||||
.category = "Game Options (Advanced)",
|
.category = "Game Options (Advanced)",
|
||||||
|
.picker = OptionPickerType::DirectoryPath,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "SDVX Printer Output Clear",
|
.title = "SDVX Printer Output Clear",
|
||||||
@@ -814,7 +831,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.category = "Game Options",
|
.category = "Game Options",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "SDVX Native Touch Handling",
|
.title = "SDVX FS Subscreen Native Touch Handling",
|
||||||
.name = "sdvxnativetouch",
|
.name = "sdvxnativetouch",
|
||||||
.desc = "Disables touch hooks and lets the game access a touch screen directly. "
|
.desc = "Disables touch hooks and lets the game access a touch screen directly. "
|
||||||
"Requires a touch screen to be connected as a secondary monitor. "
|
"Requires a touch screen to be connected as a secondary monitor. "
|
||||||
@@ -824,6 +841,18 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.game_name = "Sound Voltex",
|
.game_name = "Sound Voltex",
|
||||||
.category = "Game Options (Advanced)",
|
.category = "Game Options (Advanced)",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// spice2x_SDVXSubRedraw
|
||||||
|
.title = "SDVX FS Subscreen Force Redraw",
|
||||||
|
.name = "sp2x-sdvxsubredraw",
|
||||||
|
.display_name = "sdvxsubredraw",
|
||||||
|
.aliases= "sdvxsubredraw",
|
||||||
|
.desc = "Check if submonitor in fullscreen mode doesn't update every frame; "
|
||||||
|
"this option forces subscreen to redraw every frame.",
|
||||||
|
.type = OptionType::Bool,
|
||||||
|
.game_name = "Sound Voltex",
|
||||||
|
.category = "Game Options (Advanced)",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// spice2x_SDVXDigitalKnobSensitivity
|
// spice2x_SDVXDigitalKnobSensitivity
|
||||||
.title = "SDVX Digital Knob Sensitivity",
|
.title = "SDVX Digital Knob Sensitivity",
|
||||||
@@ -860,11 +889,12 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.display_name = "sdvxasio",
|
.display_name = "sdvxasio",
|
||||||
.aliases= "sdvxasio",
|
.aliases= "sdvxasio",
|
||||||
.desc = "ASIO driver name to use, replacing XONAR SOUND CARD(64). "
|
.desc = "ASIO driver name to use, replacing XONAR SOUND CARD(64). "
|
||||||
"String should match registry key under HLKM\\SOFTWARE\\ASIO\\ \n\n"
|
"String should match registry key under HKLM\\SOFTWARE\\ASIO\\ \n\n"
|
||||||
"SDVX is EXTREMELY picky about ASIO devices it can support!",
|
"SDVX is EXTREMELY picky about ASIO devices it can support!",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.game_name = "Sound Voltex",
|
.game_name = "Sound Voltex",
|
||||||
.category = "Game Options",
|
.category = "Game Options",
|
||||||
|
.picker = OptionPickerType::AsioDriver,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// spice2x_SDVXSubPos
|
// spice2x_SDVXSubPos
|
||||||
@@ -884,18 +914,6 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
{"bottomright", "for landscape"},
|
{"bottomright", "for landscape"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
// spice2x_SDVXSubRedraw
|
|
||||||
.title = "SDVX Subscreen Force Redraw",
|
|
||||||
.name = "sp2x-sdvxsubredraw",
|
|
||||||
.display_name = "sdvxsubredraw",
|
|
||||||
.aliases= "sdvxsubredraw",
|
|
||||||
.desc = "Check if second monitor for subscreen doesn't update every frame; "
|
|
||||||
"forces subscreen to redraw every frame, only needed for newer EG.",
|
|
||||||
.type = OptionType::Bool,
|
|
||||||
.game_name = "Sound Voltex",
|
|
||||||
.category = "Game Options (Advanced)",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.title = "Force Load DDR Module",
|
.title = "Force Load DDR Module",
|
||||||
.name = "ddr",
|
.name = "ddr",
|
||||||
@@ -1272,6 +1290,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Sets a custom path to the modules folder.",
|
.desc = "Sets a custom path to the modules folder.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
// intentionally not setting a folder picker here to discourage people setting this without a good reason
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "Screenshot Folder Override",
|
.title = "Screenshot Folder Override",
|
||||||
@@ -1279,6 +1298,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Sets a custom path to the screenshots folder.",
|
.desc = "Sets a custom path to the screenshots folder.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::DirectoryPath,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "Configuration Path Override",
|
.title = "Configuration Path Override",
|
||||||
@@ -1298,6 +1318,8 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
"If left empty, %appdata%\\spice2x\\spicetools_screen_resize.json will be used.",
|
"If left empty, %appdata%\\spice2x\\spicetools_screen_resize.json will be used.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::FilePath,
|
||||||
|
.file_extension = "JSON",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// PatchManagerConfigPath
|
// PatchManagerConfigPath
|
||||||
@@ -1307,6 +1329,8 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
"If left empty, %appdata%\\spice2x\\spicetools_patch_manager.json will be used.",
|
"If left empty, %appdata%\\spice2x\\spicetools_patch_manager.json will be used.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::FilePath,
|
||||||
|
.file_extension = "JSON",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "Intel SDE",
|
.title = "Intel SDE",
|
||||||
@@ -1314,6 +1338,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Path to Intel SDE kit path for automatic attaching.",
|
.desc = "Path to Intel SDE kit path for automatic attaching.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Development",
|
.category = "Development",
|
||||||
|
.picker = OptionPickerType::DirectoryPath
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "ea3-config.xml Override",
|
.title = "ea3-config.xml Override",
|
||||||
@@ -1321,6 +1346,8 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Sets a custom path to ea3-config.xml.",
|
.desc = "Sets a custom path to ea3-config.xml.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::FilePath,
|
||||||
|
.file_extension = "XML",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "app-config.xml Override",
|
.title = "app-config.xml Override",
|
||||||
@@ -1328,6 +1355,8 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Sets a custom path to app-config.xml.",
|
.desc = "Sets a custom path to app-config.xml.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::FilePath,
|
||||||
|
.file_extension = "XML",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "avs-config.xml Override",
|
.title = "avs-config.xml Override",
|
||||||
@@ -1335,6 +1364,8 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Sets a custom path to avs-config.xml.",
|
.desc = "Sets a custom path to avs-config.xml.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::FilePath,
|
||||||
|
.file_extension = "XML",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "bootstrap.xml Override",
|
.title = "bootstrap.xml Override",
|
||||||
@@ -1342,6 +1373,8 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Sets a custom path to bootstrap.xml.",
|
.desc = "Sets a custom path to bootstrap.xml.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::FilePath,
|
||||||
|
.file_extension = "XML",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "log.txt Override",
|
.title = "log.txt Override",
|
||||||
@@ -1349,6 +1382,8 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.desc = "Sets a custom path to log.txt.",
|
.desc = "Sets a custom path to log.txt.",
|
||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.category = "Path Overrides",
|
.category = "Path Overrides",
|
||||||
|
.picker = OptionPickerType::FilePath,
|
||||||
|
.file_extension = "TXT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "API TCP Port",
|
.title = "API TCP Port",
|
||||||
@@ -1658,6 +1693,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
"Must provide a hexadecimal mask (e.g., 0x1ff00).",
|
"Must provide a hexadecimal mask (e.g., 0x1ff00).",
|
||||||
.type = OptionType::Hex,
|
.type = OptionType::Hex,
|
||||||
.category = "Performance",
|
.category = "Performance",
|
||||||
|
.picker = OptionPickerType::CpuAffinity,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// spice2x_ProcessorEfficiencyClass
|
// spice2x_ProcessorEfficiencyClass
|
||||||
@@ -1730,11 +1766,13 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.category = "Audio (Hacks)",
|
.category = "Audio (Hacks)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "Spice Audio Hook Backend",
|
// AudioBackend
|
||||||
|
.title = "Spice Audio Hook Backend (DEPRECATED - use -asioconvert instead)",
|
||||||
.name = "audiobackend",
|
.name = "audiobackend",
|
||||||
.desc = "Selects the audio backend to use when spice audio hook is enabled, overriding exclusive WASAPI. "
|
.desc = "Selects the audio backend to use when spice audio hook is enabled, overriding exclusive WASAPI. "
|
||||||
"Does nothing for games that do not output to exclusive WASAPI.",
|
"Does nothing for games that do not output to exclusive WASAPI.",
|
||||||
.type = OptionType::Enum,
|
.type = OptionType::Enum,
|
||||||
|
.hidden = true,
|
||||||
.category = "Audio",
|
.category = "Audio",
|
||||||
.elements = {
|
.elements = {
|
||||||
{"asio", "ASIO"},
|
{"asio", "ASIO"},
|
||||||
@@ -1742,12 +1780,26 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "Spice Audio Hook ASIO Driver ID",
|
// AsioDriverId
|
||||||
|
.title = "Spice Audio Hook ASIO Driver ID (DEPRECATED - use -asioconvert instead)",
|
||||||
.name = "asiodriverid",
|
.name = "asiodriverid",
|
||||||
.desc = "Selects the ASIO driver id to use when Spice Audio Backend is set to ASIO.",
|
.desc = "Selects the ASIO driver id to use when Spice Audio Backend is set to ASIO.",
|
||||||
.type = OptionType::Integer,
|
.type = OptionType::Integer,
|
||||||
|
.hidden = true,
|
||||||
.category = "Audio",
|
.category = "Audio",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// AsioDriverName
|
||||||
|
.title = "WASAPI Exclusive to ASIO Conversion",
|
||||||
|
.name = "asioconvert",
|
||||||
|
.desc = "Converts WASAPI Exclusive audio output to ASIO. Value here should match registry key under HKLM\\SOFTWARE\\ASIO\\\n\n"
|
||||||
|
"Use this if the game is configured to use WASAPI Exclusive but you want to use your ASIO driver instead.\n\n"
|
||||||
|
"This should only be used as last resort if your audio device does not support WASAPI Exclusive.\n\n"
|
||||||
|
"Does nothing for games that do not output to exclusive WASAPI.",
|
||||||
|
.type = OptionType::Text,
|
||||||
|
.category = "Audio",
|
||||||
|
.picker = OptionPickerType::AsioDriver,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.title = "WASAPI Dummy Context",
|
.title = "WASAPI Dummy Context",
|
||||||
.name = "audiodummy",
|
.name = "audiodummy",
|
||||||
@@ -2251,7 +2303,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
// spice2x_IIDXNativeTouch
|
// spice2x_IIDXNativeTouch
|
||||||
.title = "IIDX Native Touch Handling",
|
.title = "IIDX TDJ Subscreen Native Touch Handling",
|
||||||
.name = "sp2x-iidxnativetouch",
|
.name = "sp2x-iidxnativetouch",
|
||||||
.display_name = "iidxnativetouch",
|
.display_name = "iidxnativetouch",
|
||||||
.aliases= "iidxnativetouch",
|
.aliases= "iidxnativetouch",
|
||||||
@@ -2580,6 +2632,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
|||||||
.type = OptionType::Text,
|
.type = OptionType::Text,
|
||||||
.game_name = "LovePlus",
|
.game_name = "LovePlus",
|
||||||
.category = "Game Options (Advanced)",
|
.category = "Game Options (Advanced)",
|
||||||
|
.picker = OptionPickerType::DirectoryPath,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.title = "LovePlus Printer Output Clear",
|
.title = "LovePlus Printer Output Clear",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace launcher {
|
|||||||
GraphicsForceRefresh,
|
GraphicsForceRefresh,
|
||||||
FullscreenResolution,
|
FullscreenResolution,
|
||||||
FullscreenOrientationFlip,
|
FullscreenOrientationFlip,
|
||||||
|
FullscreenSubResolution,
|
||||||
FullscreenSubRefreshRate,
|
FullscreenSubRefreshRate,
|
||||||
Graphics9On12,
|
Graphics9On12,
|
||||||
spice2x_Dx9On12,
|
spice2x_Dx9On12,
|
||||||
@@ -85,11 +86,11 @@ namespace launcher {
|
|||||||
SDVXPrinterJPGQuality,
|
SDVXPrinterJPGQuality,
|
||||||
SDVXDisableCameras,
|
SDVXDisableCameras,
|
||||||
SDVXNativeTouch,
|
SDVXNativeTouch,
|
||||||
|
spice2x_SDVXSubRedraw,
|
||||||
spice2x_SDVXDigitalKnobSensitivity,
|
spice2x_SDVXDigitalKnobSensitivity,
|
||||||
SDVXDigitalKnobSocd,
|
SDVXDigitalKnobSocd,
|
||||||
spice2x_SDVXAsioDriver,
|
spice2x_SDVXAsioDriver,
|
||||||
spice2x_SDVXSubPos,
|
spice2x_SDVXSubPos,
|
||||||
spice2x_SDVXSubRedraw,
|
|
||||||
LoadDDRModule,
|
LoadDDRModule,
|
||||||
DDR43Mode,
|
DDR43Mode,
|
||||||
DDRSkipCodecRegisteration,
|
DDRSkipCodecRegisteration,
|
||||||
@@ -186,6 +187,7 @@ namespace launcher {
|
|||||||
spice2x_DisableVolumeHook,
|
spice2x_DisableVolumeHook,
|
||||||
AudioBackend,
|
AudioBackend,
|
||||||
AsioDriverId,
|
AsioDriverId,
|
||||||
|
AsioDriverName,
|
||||||
AudioDummy,
|
AudioDummy,
|
||||||
DelayBy5Seconds,
|
DelayBy5Seconds,
|
||||||
spice2x_DelayByNSeconds,
|
spice2x_DelayByNSeconds,
|
||||||
|
|||||||
@@ -185,21 +185,30 @@ static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *Exception
|
|||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI SetConsoleCtrlHandler_hook(PHANDLER_ROUTINE pHandlerRoutine, BOOL Add) {
|
static BOOL WINAPI SetConsoleCtrlHandler_hook(PHANDLER_ROUTINE pHandlerRoutine, BOOL Add) {
|
||||||
log_misc("signal", "SetConsoleCtrlHandler hook hit");
|
static std::once_flag printed;
|
||||||
|
std::call_once(printed, []() {
|
||||||
|
log_misc("signal", "SetConsoleCtrlHandler hook hit (printing once)");
|
||||||
|
});
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter_hook(
|
static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter_hook(
|
||||||
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
|
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) {
|
||||||
{
|
|
||||||
log_info("signal", "SetUnhandledExceptionFilter hook hit");
|
static std::once_flag printed;
|
||||||
|
std::call_once(printed, []() {
|
||||||
|
log_info("signal", "SetUnhandledExceptionFilter hook hit (printing once)");
|
||||||
|
});
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PVOID WINAPI AddVectoredExceptionHandler_hook(ULONG First, PVECTORED_EXCEPTION_HANDLER Handler) {
|
static PVOID WINAPI AddVectoredExceptionHandler_hook(ULONG First, PVECTORED_EXCEPTION_HANDLER Handler) {
|
||||||
log_info("signal", "AddVectoredExceptionHandler hook hit");
|
static std::once_flag printed;
|
||||||
|
std::call_once(printed, []() {
|
||||||
|
log_info("signal", "AddVectoredExceptionHandler hook hit (printing once)");
|
||||||
|
});
|
||||||
|
|
||||||
return launcher::signal::USE_VEH_WORKAROUND ? INVALID_HANDLE_VALUE : nullptr;
|
return launcher::signal::USE_VEH_WORKAROUND ? INVALID_HANDLE_VALUE : nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-20
@@ -119,6 +119,7 @@ static std::string EAMIO_DLL_NAME = "eamio.dll";
|
|||||||
static robin_hood::unordered_map<int, std::thread *> BT5API_THREADS;
|
static robin_hood::unordered_map<int, std::thread *> BT5API_THREADS;
|
||||||
static robin_hood::unordered_map<int, int> BT5API_THREAD_RESULTS;
|
static robin_hood::unordered_map<int, int> BT5API_THREAD_RESULTS;
|
||||||
static uint8_t BT5API_CARD_STATES[] = {0, 0};
|
static uint8_t BT5API_CARD_STATES[] = {0, 0};
|
||||||
|
static uint16_t BT5API_KEYPAD_STATES[] = {0, 0};
|
||||||
|
|
||||||
static void bt5api_log(const char *bt5_module, const char *fmt, ...) {
|
static void bt5api_log(const char *bt5_module, const char *fmt, ...) {
|
||||||
|
|
||||||
@@ -240,46 +241,77 @@ void bt5api_hook(HINSTANCE module) {
|
|||||||
|
|
||||||
void bt5api_poll_reader_card(uint8_t unit_no) {
|
void bt5api_poll_reader_card(uint8_t unit_no) {
|
||||||
|
|
||||||
// check if initialized
|
// check if initialized or out of bounds
|
||||||
if (!EAMIO_DLL) {
|
if (!EAMIO_DLL || unit_no >= eamuse_get_game_keypads()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// poll
|
// poll
|
||||||
if (!eam_io_poll(unit_no)) {
|
if (!eam_io_poll(unit_no)) {
|
||||||
log_warning("bt5api", "polling bt5api reader {} returned failure",
|
log_warning("bt5api", "polling bt5api reader card {} returned failure",
|
||||||
static_cast<int>(unit_no));
|
static_cast<int>(unit_no));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get sensor state
|
// get sensor state
|
||||||
uint8_t sensor_state = eam_io_get_sensor_state(unit_no);
|
uint8_t sensor_state = eam_io_get_sensor_state(unit_no);
|
||||||
|
|
||||||
|
// if we have a change in state.
|
||||||
|
if(sensor_state != BT5API_CARD_STATES[unit_no]) {
|
||||||
|
|
||||||
// check for card in
|
// card inserted into the back.
|
||||||
if (sensor_state > BT5API_CARD_STATES[unit_no]) {
|
if(sensor_state & (1 << EAM_IO_SENSOR_BACK)) {
|
||||||
uint8_t card_id[8];
|
uint8_t card_id[8];
|
||||||
eam_io_read_card(unit_no, card_id, 8);
|
|
||||||
eamuse_card_insert(unit_no, card_id);
|
log_info("bt5api", "card unit {} inserted", static_cast<int>(unit_no));
|
||||||
|
|
||||||
|
// do the bt5 dance
|
||||||
|
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_CLOSE);
|
||||||
|
eam_io_poll(unit_no);
|
||||||
|
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_READ);
|
||||||
|
eam_io_poll(unit_no);
|
||||||
|
|
||||||
|
// ask the api for the card, then insert it into our engine.
|
||||||
|
eam_io_read_card(unit_no, card_id, 8);
|
||||||
|
eamuse_card_insert(unit_no, card_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if card removed entirely, do another bt5 dance!
|
||||||
|
if(sensor_state == 0) {
|
||||||
|
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_CLOSE);
|
||||||
|
eam_io_poll(unit_no);
|
||||||
|
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_OPEN);
|
||||||
|
|
||||||
|
log_info("bt5api", "card unit {} removed", static_cast<int>(unit_no));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save state
|
// save prev state
|
||||||
BT5API_CARD_STATES[unit_no] = sensor_state;
|
BT5API_CARD_STATES[unit_no] = sensor_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt5api_poll_reader_keypad(uint8_t unit_no) {
|
void bt5api_poll_reader_keypad(uint8_t unit_no) {
|
||||||
|
|
||||||
// check if initialized
|
// check if initialized or out of bounds
|
||||||
if (!EAMIO_DLL) {
|
if (!EAMIO_DLL || unit_no >= eamuse_get_game_keypads()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// poll
|
uint16_t keypad_current = eam_io_get_keypad_state(unit_no);
|
||||||
if (!eam_io_poll(unit_no)) {
|
uint16_t keypad_changes = ~BT5API_KEYPAD_STATES[unit_no] & keypad_current;
|
||||||
log_warning("bt5api", "polling bt5api reader {} returned failure",
|
|
||||||
static_cast<int>(unit_no));
|
// if user has pressed decimal for the first time, eject the slotted reader.
|
||||||
|
if(keypad_changes & (1 << EAM_IO_KEYPAD_DECIMAL)) {
|
||||||
|
log_info("bt5api", "card unit {} ejecting", static_cast<int>(unit_no));
|
||||||
|
|
||||||
|
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_EJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save the last pressed.
|
||||||
|
BT5API_KEYPAD_STATES[unit_no] = keypad_current;
|
||||||
|
|
||||||
// get keypad
|
// send off the state to the main engine.
|
||||||
eamuse_set_keypad_overrides_bt5(unit_no, eam_io_get_keypad_state(unit_no));
|
eamuse_set_keypad_overrides_bt5(unit_no, keypad_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt5api_dispose() {
|
void bt5api_dispose() {
|
||||||
|
|||||||
@@ -202,7 +202,14 @@ bool eamuse_card_insert_consume(int active_count, int unit_id) {
|
|||||||
|
|
||||||
// bt5api
|
// bt5api
|
||||||
if (BT5API_ENABLED) {
|
if (BT5API_ENABLED) {
|
||||||
bt5api_poll_reader_card((uint8_t) index);
|
// some bt5api want to be polled in order.
|
||||||
|
if (eamuse_get_game_keypads() > 1) {
|
||||||
|
bt5api_poll_reader_card(1);
|
||||||
|
bt5api_poll_reader_card(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bt5api_poll_reader_card((uint8_t) index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto insert card
|
// auto insert card
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
// mingw otherwise doesn't load touch stuff
|
// mingw otherwise doesn't load touch stuff
|
||||||
#define _WIN32_WINNT 0x0601
|
#define _WIN32_WINNT 0x0601
|
||||||
|
|
||||||
|
#include "avs/game.h"
|
||||||
#include "wintouchemu.h"
|
#include "wintouchemu.h"
|
||||||
|
#include "rawinput/touch.h"
|
||||||
|
#include "hooks/graphics/graphics.h"
|
||||||
|
|
||||||
#include "util/detour.h"
|
#include "util/detour.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
@@ -63,6 +66,11 @@ namespace nativetouchhook {
|
|||||||
point->cyContact = 0;
|
point->cyContact = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flip_touch_points(PTOUCHINPUT point) {
|
||||||
|
point->x = rawinput::touch::DISPLAY_SIZE_X * 100 - point->x;
|
||||||
|
point->y = rawinput::touch::DISPLAY_SIZE_Y * 100 - point->y;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL WINAPI GetTouchInputInfoHook(
|
static BOOL WINAPI GetTouchInputInfoHook(
|
||||||
HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) {
|
HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) {
|
||||||
|
|
||||||
@@ -72,9 +80,28 @@ namespace nativetouchhook {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool flip_values = false;
|
||||||
|
if (avs::game::is_model("KFC") && rawinput::touch::DISPLAY_INITIALIZED) {
|
||||||
|
log_debug(
|
||||||
|
"touch::native", "DISPLAY_ORIENTATION = {}, DISPLAY_SIZE_X = {}, DISPLAY_SIZE_Y = {}",
|
||||||
|
rawinput::touch::DISPLAY_ORIENTATION,
|
||||||
|
rawinput::touch::DISPLAY_SIZE_X,
|
||||||
|
rawinput::touch::DISPLAY_SIZE_Y);
|
||||||
|
if (rawinput::touch::DISPLAY_ORIENTATION == DMDO_270) {
|
||||||
|
flip_values = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < cInputs; i++) {
|
for (size_t i = 0; i < cInputs; i++) {
|
||||||
PTOUCHINPUT point = &pInputs[i];
|
PTOUCHINPUT point = &pInputs[i];
|
||||||
strip_contact_size(point);
|
|
||||||
|
if (avs::game::is_model("LDJ")) {
|
||||||
|
strip_contact_size(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flip_values) {
|
||||||
|
flip_touch_points(point);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/time.h"
|
#include "util/time.h"
|
||||||
#include "util/utils.h"
|
#include "util/utils.h"
|
||||||
|
#include "rawinput/touch.h"
|
||||||
|
|
||||||
#include "avs/game.h"
|
#include "avs/game.h"
|
||||||
|
|
||||||
@@ -126,6 +127,11 @@ namespace wintouchemu {
|
|||||||
WINDOW_TITLE_END = window_title_end;
|
WINDOW_TITLE_END = window_title_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flip_touch_points(PTOUCHINPUT point) {
|
||||||
|
point->x = rawinput::touch::DISPLAY_SIZE_X * 100 - point->x;
|
||||||
|
point->y = rawinput::touch::DISPLAY_SIZE_Y * 100 - point->y;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL WINAPI GetTouchInputInfoHook(HANDLE hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) {
|
static BOOL WINAPI GetTouchInputInfoHook(HANDLE hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) {
|
||||||
|
|
||||||
// check if original should be called
|
// check if original should be called
|
||||||
@@ -220,6 +226,12 @@ namespace wintouchemu {
|
|||||||
touch_input->cxContact = 0;
|
touch_input->cxContact = 0;
|
||||||
touch_input->cyContact = 0;
|
touch_input->cyContact = 0;
|
||||||
|
|
||||||
|
if (avs::game::is_model("KFC") &&
|
||||||
|
rawinput::touch::DISPLAY_INITIALIZED &&
|
||||||
|
rawinput::touch::DISPLAY_ORIENTATION == DMDO_270) {
|
||||||
|
flip_touch_points(touch_input);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (USE_MOUSE && !mouse_used) {
|
} else if (USE_MOUSE && !mouse_used) {
|
||||||
|
|
||||||
// disable further mouse inputs this call
|
// disable further mouse inputs this call
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace ImGui {
|
|||||||
|
|
||||||
void HelpMarker(const char* desc) {
|
void HelpMarker(const char* desc) {
|
||||||
ImGui::TextDisabled("(?)");
|
ImGui::TextDisabled("(?)");
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(TOOLTIP_FLAGS)) {
|
||||||
HelpTooltip(desc);
|
HelpTooltip(desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ namespace ImGui {
|
|||||||
ImGui::PushStyleColor(ImGuiCol_TextDisabled, ImVec4(1.f, 1.f, 0.f, 1.f));
|
ImGui::PushStyleColor(ImGuiCol_TextDisabled, ImVec4(1.f, 1.f, 0.f, 1.f));
|
||||||
ImGui::TextDisabled("(!)");
|
ImGui::TextDisabled("(!)");
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(TOOLTIP_FLAGS)) {
|
||||||
WarnTooltip(desc, warn);
|
WarnTooltip(desc, warn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,4 +92,75 @@ namespace ImGui {
|
|||||||
ImGui::GetColorU32(ImGuiCol_PlotHistogram),
|
ImGui::GetColorU32(ImGuiCol_PlotHistogram),
|
||||||
thickness);
|
thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string TruncateText(const std::string& p_text, float p_truncated_width, bool &truncated) {
|
||||||
|
std::string truncated_text = p_text;
|
||||||
|
|
||||||
|
const float text_width =
|
||||||
|
ImGui::CalcTextSize(p_text.c_str(), nullptr, true).x;
|
||||||
|
|
||||||
|
if (text_width > p_truncated_width) {
|
||||||
|
truncated = true;
|
||||||
|
constexpr const char* ELLIPSIS = " ...";
|
||||||
|
const float ellipsis_size = ImGui::CalcTextSize(ELLIPSIS).x;
|
||||||
|
|
||||||
|
int visible_chars = 0;
|
||||||
|
for (size_t i = 0; i < p_text.size(); i++) {
|
||||||
|
const float current_width = ImGui::CalcTextSize(
|
||||||
|
p_text.substr(0, i).c_str(), nullptr, true)
|
||||||
|
.x;
|
||||||
|
if (current_width + ellipsis_size > p_truncated_width) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
visible_chars = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
truncated_text = (p_text.substr(0, visible_chars) + ELLIPSIS).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return truncated_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextTruncated(const std::string& p_text, float p_truncated_width) {
|
||||||
|
if (p_text.empty()) {
|
||||||
|
ImGui::TextDisabled("-");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool truncated = false;
|
||||||
|
ImGui::TextUnformatted(TruncateText(p_text, p_truncated_width, truncated).c_str());
|
||||||
|
if (truncated && ImGui::IsItemHovered(TOOLTIP_FLAGS)) {
|
||||||
|
ImGui::HelpTooltip(p_text.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeleteButton(const std::string& tooltip) {
|
||||||
|
ImGui::PushID(tooltip.c_str());
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_Button, 0.7f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.f, 2.f));
|
||||||
|
bool clicked = ImGui::SmallButton("\u00D7"); // multiplication sign (×)
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
if (!tooltip.empty() && ImGui::IsItemHovered(TOOLTIP_FLAGS)) {
|
||||||
|
ImGui::HelpTooltip(tooltip.c_str());
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
return clicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClearButton(const std::string& tooltip) {
|
||||||
|
ImGui::PushID(tooltip.c_str());
|
||||||
|
// same colors as a checkbox
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_FrameBg));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetColorU32(ImGuiCol_FrameBgHovered));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetColorU32(ImGuiCol_FrameBgActive));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.97f, 0.97f, 0.97f, 1.00f));
|
||||||
|
bool clicked = ImGui::Button("\u00D7"); // multiplication sign (×)
|
||||||
|
ImGui::PopStyleColor(4);
|
||||||
|
if (!tooltip.empty() && ImGui::IsItemHovered(TOOLTIP_FLAGS)) {
|
||||||
|
ImGui::HelpTooltip(tooltip.c_str());
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
return clicked;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "external/imgui/imgui.h"
|
||||||
|
|
||||||
namespace ImGui {
|
namespace ImGui {
|
||||||
|
|
||||||
|
constexpr ImGuiHoveredFlags TOOLTIP_FLAGS =
|
||||||
|
(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled);
|
||||||
|
|
||||||
void HelpTooltip(const char* desc);
|
void HelpTooltip(const char* desc);
|
||||||
void HelpMarker(const char* desc);
|
void HelpMarker(const char* desc);
|
||||||
void WarnTooltip(const char* desc, const char* warn);
|
void WarnTooltip(const char* desc, const char* warn);
|
||||||
void WarnMarker(const char* desc, const char* warn);
|
void WarnMarker(const char* desc, const char* warn);
|
||||||
void DummyMarker();
|
void DummyMarker();
|
||||||
|
|
||||||
void Knob(float fraction, float size, float thickness = 2.f,
|
void Knob(float fraction, float size, float thickness = 2.f,
|
||||||
float pos_x = -1.f, float pos_y = -1.f);
|
float pos_x = -1.f, float pos_y = -1.f);
|
||||||
|
|
||||||
|
void TextTruncated(const std::string& p_text, float p_truncated_width);
|
||||||
|
bool DeleteButton(const std::string& tooltip);
|
||||||
|
bool ClearButton(const std::string& tooltip);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ void ImGui_ImplSpice_NewFrame() {
|
|||||||
memset(io.MouseDown, false, sizeof(io.MouseDown));
|
memset(io.MouseDown, false, sizeof(io.MouseDown));
|
||||||
|
|
||||||
// early quit if window not in focus
|
// early quit if window not in focus
|
||||||
if (!superexit::has_focus()) {
|
if (!superexit::has_focus() || rawinput::OS_WINDOW_ACTIVE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2293
-1729
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,6 @@ namespace overlay::windows {
|
|||||||
ConfigTab tab_selected = ConfigTab::CONFIG_TAB_INVALID;
|
ConfigTab tab_selected = ConfigTab::CONFIG_TAB_INVALID;
|
||||||
|
|
||||||
// buttons tab
|
// buttons tab
|
||||||
int buttons_page = 0;
|
|
||||||
bool buttons_keyboard_state[0xFF];
|
bool buttons_keyboard_state[0xFF];
|
||||||
bool buttons_bind_active = false;
|
bool buttons_bind_active = false;
|
||||||
bool buttons_many_active = false;
|
bool buttons_many_active = false;
|
||||||
@@ -55,7 +54,6 @@ namespace overlay::windows {
|
|||||||
int analogs_devices_control_selected = -1;
|
int analogs_devices_control_selected = -1;
|
||||||
|
|
||||||
// lights tab
|
// lights tab
|
||||||
int lights_page = 0;
|
|
||||||
std::vector<rawinput::Device *> lights_devices;
|
std::vector<rawinput::Device *> lights_devices;
|
||||||
int lights_devices_selected = -1;
|
int lights_devices_selected = -1;
|
||||||
int lights_devices_control_selected = -1;
|
int lights_devices_control_selected = -1;
|
||||||
@@ -78,6 +76,51 @@ namespace overlay::windows {
|
|||||||
std::string search_filter = "";
|
std::string search_filter = "";
|
||||||
std::string search_filter_in_lower_case = "";
|
std::string search_filter_in_lower_case = "";
|
||||||
|
|
||||||
|
std::filesystem::path file_picker_path;
|
||||||
|
std::thread *file_picker_thread = nullptr;
|
||||||
|
bool file_picker_done = false;
|
||||||
|
|
||||||
|
void build_buttons(const std::string &name, std::vector<Button> *buttons, int min = 0, int max = -1);
|
||||||
|
void build_button(
|
||||||
|
const std::string &name,
|
||||||
|
Button &primary_button,
|
||||||
|
Button *button,
|
||||||
|
const int button_it,
|
||||||
|
const int button_it_max,
|
||||||
|
const int alt_index);
|
||||||
|
|
||||||
|
void bind_button_popup(const std::string &bind_name, Button *button, const int button_it_max, const int alt_index);
|
||||||
|
void naive_button_popup(const std::string &naive_string, Button *button, const int button_it_max, const int alt_index);
|
||||||
|
void edit_button_popup(
|
||||||
|
const std::string &edit_name,
|
||||||
|
const std::string &button_display,
|
||||||
|
Button *button,
|
||||||
|
const float button_velocity,
|
||||||
|
const int alt_index);
|
||||||
|
void clear_button(Button *button, const int alt_index);
|
||||||
|
|
||||||
|
void build_analogs(const std::string &name, std::vector<Analog> *analogs);
|
||||||
|
void edit_analog_popup(Analog &analog);
|
||||||
|
|
||||||
|
void build_lights(const std::string &name, std::vector<Light> *lights);
|
||||||
|
void build_light(Light &primary_light, Light *light, const int light_index, const int alt_index);
|
||||||
|
void clear_light(Light *light, const int alt_index);
|
||||||
|
void edit_light_popup(Light &primary_light, Light *light, const int alt_index);
|
||||||
|
|
||||||
|
void build_cards();
|
||||||
|
std::string build_option_value_picker_title(const OptionDefinition& option);
|
||||||
|
void build_option_value_picker(Option& option);
|
||||||
|
void build_options(
|
||||||
|
std::vector<Option> *options, const std::string &category, const std::string *filter=nullptr);
|
||||||
|
void build_about();
|
||||||
|
void build_launcher();
|
||||||
|
void launch_shell(LPCSTR app, LPCSTR file=nullptr);
|
||||||
|
|
||||||
|
void build_menu(int *game_selected);
|
||||||
|
void shutdown_system(bool force, bool reboot_instead);
|
||||||
|
|
||||||
|
void set_alternating_row_colors(const int row_index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Config(SpiceOverlay *overlay);
|
Config(SpiceOverlay *overlay);
|
||||||
~Config() override;
|
~Config() override;
|
||||||
@@ -85,19 +128,6 @@ namespace overlay::windows {
|
|||||||
void read_card(int player = -1);
|
void read_card(int player = -1);
|
||||||
void write_card(int player);
|
void write_card(int player);
|
||||||
void build_content() override;
|
void build_content() override;
|
||||||
void build_buttons(const std::string &name, std::vector<Button> *buttons,
|
|
||||||
int min = 0, int max = -1);
|
|
||||||
void build_analogs(const std::string &name, std::vector<Analog> *analogs);
|
|
||||||
void build_lights(const std::string &name, std::vector<Light> *lights);
|
|
||||||
void build_cards();
|
|
||||||
void build_options(
|
|
||||||
std::vector<Option> *options, const std::string &category, const std::string *filter=nullptr);
|
|
||||||
void build_about();
|
|
||||||
void build_launcher();
|
|
||||||
void launch_shell(LPCSTR app, LPCSTR file=nullptr);
|
|
||||||
|
|
||||||
static void build_page_selector(int *page);
|
|
||||||
void build_menu(int *game_selected);
|
|
||||||
void shutdown_system(bool force, bool reboot_instead);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,10 +85,12 @@ namespace overlay::windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenericSubScreen::touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) {}
|
void GenericSubScreen::touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) {}
|
||||||
|
void GenericSubScreen::check_for_errors() {}
|
||||||
|
|
||||||
void GenericSubScreen::build_content() {
|
void GenericSubScreen::build_content() {
|
||||||
this->flags |= ImGuiWindowFlags_NoBackground;
|
this->flags |= ImGuiWindowFlags_NoBackground;
|
||||||
|
|
||||||
|
check_for_errors();
|
||||||
if (this->disabled_message.has_value()) {
|
if (this->disabled_message.has_value()) {
|
||||||
this->draws_window = true;
|
this->draws_window = true;
|
||||||
this->flags &= ~ImGuiWindowFlags_NoBackground;
|
this->flags &= ~ImGuiWindowFlags_NoBackground;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace overlay::windows {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out);
|
virtual void touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out);
|
||||||
|
virtual void check_for_errors();
|
||||||
ImVec2 overlay_content_top_left;
|
ImVec2 overlay_content_top_left;
|
||||||
ImVec2 overlay_content_size;
|
ImVec2 overlay_content_size;
|
||||||
std::optional<std::string> disabled_message = std::nullopt;
|
std::optional<std::string> disabled_message = std::nullopt;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace overlay::windows {
|
|||||||
|
|
||||||
static const size_t TICKER_SIZE = 9;
|
static const size_t TICKER_SIZE = 9;
|
||||||
static const ImVec4 DARK_GRAY(0.1f, 0.1f, 0.1f, 1.f);
|
static const ImVec4 DARK_GRAY(0.1f, 0.1f, 0.1f, 1.f);
|
||||||
|
static const ImVec4 YELLOW(1.f, 1.f, 0.f, 1.f);
|
||||||
static const ImVec4 RED(1.f, 0.f, 0.f, 1.f);
|
static const ImVec4 RED(1.f, 0.f, 0.f, 1.f);
|
||||||
static const float PADDING_Y = 8.f;
|
static const float PADDING_Y = 8.f;
|
||||||
static const float PADDING_X = 4.f;
|
static const float PADDING_X = 4.f;
|
||||||
@@ -91,6 +92,23 @@ namespace overlay::windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IIDXSegmentDisplay::build_content() {
|
void IIDXSegmentDisplay::build_content() {
|
||||||
|
|
||||||
|
// explicitly check if TDJ I/O is enabled to account for the fact that I/O emulation may be
|
||||||
|
// disabled
|
||||||
|
if (games::iidx::CURRENT_IO_EMULATION_STATE == games::iidx::iidx_aio_emulation_state::bi2x_hook) {
|
||||||
|
ImGui::TextUnformatted("");
|
||||||
|
ImGui::TextColored(
|
||||||
|
YELLOW,
|
||||||
|
"%s",
|
||||||
|
"Invalid I/O mode; DLL is configured for TDJ I/O!\n"
|
||||||
|
"Enable -iidxtdj if you want TDJ subscreen overlay.");
|
||||||
|
ImGui::TextUnformatted("");
|
||||||
|
if (ImGui::Button("Close")) {
|
||||||
|
this->set_active(false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char input_ticker[TICKER_SIZE];
|
char input_ticker[TICKER_SIZE];
|
||||||
|
|
||||||
// get ticker content from game
|
// get ticker content from game
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ namespace overlay::windows {
|
|||||||
this->title = "IIDX TDJ Subscreen";
|
this->title = "IIDX TDJ Subscreen";
|
||||||
|
|
||||||
if (GRAPHICS_IIDX_WSUB) {
|
if (GRAPHICS_IIDX_WSUB) {
|
||||||
this->disabled_message =
|
this->disabled_message = "Close this overlay and use the second window. (try ALT+TAB)";
|
||||||
"Close this overlay and use the second window.\n"
|
|
||||||
"If you don't see the window, double check your DLL type and apply TDJ I/O patches as needed.";
|
|
||||||
} else if (games::iidx::IIDX_TDJ_MONITOR_WARNING) {
|
} else if (games::iidx::IIDX_TDJ_MONITOR_WARNING) {
|
||||||
this->disabled_message = "TDJ mode subscreen overlay is not compatible with -monitor option";
|
this->disabled_message = "TDJ mode subscreen overlay is not compatible with -monitor option.";
|
||||||
}
|
}
|
||||||
|
|
||||||
float size = 0.5f;
|
float size = 0.5f;
|
||||||
@@ -44,6 +42,18 @@ namespace overlay::windows {
|
|||||||
ImGui::GetIO().DisplaySize.y - this->init_size.y - (ImGui::GetFrameHeight() / 2));
|
ImGui::GetIO().DisplaySize.y - this->init_size.y - (ImGui::GetFrameHeight() / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IIDXSubScreen::check_for_errors() {
|
||||||
|
if (games::iidx::CURRENT_IO_EMULATION_STATE ==
|
||||||
|
games::iidx::iidx_aio_emulation_state::bi2a_com2) {
|
||||||
|
|
||||||
|
// explicitly check if LDJ I/O is enabled (as opposed to checking if NOT TDJ I/O)
|
||||||
|
// to account for the fact that I/O emulation may be disabled
|
||||||
|
this->disabled_message =
|
||||||
|
"LDJ I/O detected; TDJ mode subscreen overlay requires TDJ I/O.\n"
|
||||||
|
"Ensure you apply applicable TDJ I/O patches, or run with TDJ DLL.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IIDXSubScreen::touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) {
|
void IIDXSubScreen::touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) {
|
||||||
if (!this->get_active()) {
|
if (!this->get_active()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ namespace overlay::windows {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) override;
|
void touch_transform(const ImVec2 xy_in, LONG *x_out, LONG *y_out) override;
|
||||||
|
void check_for_errors() override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace overlay::windows {
|
|||||||
{
|
{
|
||||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetFrameHeightWithSpacing());
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetFrameHeightWithSpacing());
|
||||||
this->build_button("+", tall, this->test_button, this->service_button);
|
this->build_button("+", tall, this->test_button, this->service_button);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
ImGui::HelpTooltip("SERVICE + TEST");
|
ImGui::HelpTooltip("SERVICE + TEST");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ namespace overlay::windows {
|
|||||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetFrameHeightWithSpacing());
|
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetFrameHeightWithSpacing());
|
||||||
this->build_button("<", leftright_size, this->left[p], nullptr, this->leftright_light[p]);
|
this->build_button("<", leftright_size, this->left[p], nullptr, this->leftright_light[p]);
|
||||||
this->build_button("+", tiny_size, this->help[p], this->start[p], nullptr);
|
this->build_button("+", tiny_size, this->help[p], this->start[p], nullptr);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
ImGui::HelpTooltip("HELP + START");
|
ImGui::HelpTooltip("HELP + START");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ namespace overlay::windows {
|
|||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
{
|
{
|
||||||
this->build_button("?", tiny_size, this->help[p], nullptr, this->help_light[p]);
|
this->build_button("?", tiny_size, this->help[p], nullptr, this->help_light[p]);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
ImGui::HelpTooltip("HELP");
|
ImGui::HelpTooltip("HELP");
|
||||||
}
|
}
|
||||||
this->build_button(">", leftright_size, this->right[p], nullptr, this->leftright_light[p]);
|
this->build_button(">", leftright_size, this->right[p], nullptr, this->leftright_light[p]);
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ namespace overlay::windows {
|
|||||||
"Lightning Model cabinets (TDJ) do not have any keypads; they use the subscreen.\n\n"
|
"Lightning Model cabinets (TDJ) do not have any keypads; they use the subscreen.\n\n"
|
||||||
"Fullscreen mode: bind a key in Overlay tab, and press it in game to show the subscreen, "
|
"Fullscreen mode: bind a key in Overlay tab, and press it in game to show the subscreen, "
|
||||||
"then use your mouse to click. Page Up button is the default binding.\n\n"
|
"then use your mouse to click. Page Up button is the default binding.\n\n"
|
||||||
"Windowed mode: look for the second window in the taskbar.\n\n"
|
"Windowed mode: look for the second window in the taskbar (or ALT+TAB).\n\n"
|
||||||
"Windowed mode with -iidxnosub: bring up the subscreen overlay (default Page Up).\n\n"
|
"Windowed mode with -iidxnosub: bring up the subscreen overlay (default Page Up).\n\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -721,7 +721,7 @@ namespace overlay::windows {
|
|||||||
if (style_color_pushed) {
|
if (style_color_pushed) {
|
||||||
ImGui::PopStyleColor(style_color_pushed);
|
ImGui::PopStyleColor(style_color_pushed);
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
show_patch_tooltip(patch);
|
show_patch_tooltip(patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,7 +762,7 @@ namespace overlay::windows {
|
|||||||
patch.last_status = is_patch_active(patch);
|
patch.last_status = is_patch_active(patch);
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
show_patch_tooltip(patch);
|
show_patch_tooltip(patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,7 +791,7 @@ namespace overlay::windows {
|
|||||||
}
|
}
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
show_patch_tooltip(patch);
|
show_patch_tooltip(patch);
|
||||||
}
|
}
|
||||||
} else if (patch.type == PatchType::Integer) {
|
} else if (patch.type == PatchType::Integer) {
|
||||||
@@ -807,7 +807,7 @@ namespace overlay::windows {
|
|||||||
apply_patch(patch, true);
|
apply_patch(patch, true);
|
||||||
config_dirty = true;
|
config_dirty = true;
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
show_patch_tooltip(patch);
|
show_patch_tooltip(patch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -824,7 +824,7 @@ namespace overlay::windows {
|
|||||||
ImGui::InputInt("##dummy_int_input", &patch.patch_number.value);
|
ImGui::InputInt("##dummy_int_input", &patch.patch_number.value);
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered(ImGui::TOOLTIP_FLAGS)) {
|
||||||
show_patch_tooltip(patch);
|
show_patch_tooltip(patch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace overlay::windows {
|
|||||||
if (GRAPHICS_PREVENT_SECONDARY_WINDOW) {
|
if (GRAPHICS_PREVENT_SECONDARY_WINDOW) {
|
||||||
this->disabled_message = "Subscreen has been disabled by the user (-sdvxnosub).";
|
this->disabled_message = "Subscreen has been disabled by the user (-sdvxnosub).";
|
||||||
} else {
|
} else {
|
||||||
this->disabled_message = "Overlay unavailable in windowed mode! Use the second window instead.";
|
this->disabled_message = "Overlay unavailable in windowed mode! Use the second window instead. (ALT+TAB)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ namespace rawinput {
|
|||||||
uint32_t MIDI_NOTE_SUSTAIN = 20;
|
uint32_t MIDI_NOTE_SUSTAIN = 20;
|
||||||
|
|
||||||
static MidiNoteAlgorithm MIDI_NOTE_ALGORITHM = MidiNoteAlgorithm::V2;
|
static MidiNoteAlgorithm MIDI_NOTE_ALGORITHM = MidiNoteAlgorithm::V2;
|
||||||
|
|
||||||
|
// the price we pay for making spice overlay consume from raw input
|
||||||
|
// making focus detection a nightmare
|
||||||
|
bool OS_WINDOW_ACTIVE = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rawinput::MidiNoteAlgorithm rawinput::get_midi_algorithm() {
|
rawinput::MidiNoteAlgorithm rawinput::get_midi_algorithm() {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "hotplug.h"
|
#include "hotplug.h"
|
||||||
|
#include "util/scope_guard.h"
|
||||||
|
|
||||||
namespace rawinput {
|
namespace rawinput {
|
||||||
|
|
||||||
@@ -31,6 +32,15 @@ namespace rawinput {
|
|||||||
extern bool NAIVE_REQUIRE_FOCUS;
|
extern bool NAIVE_REQUIRE_FOCUS;
|
||||||
extern bool RAWINPUT_REQUIRE_FOCUS;
|
extern bool RAWINPUT_REQUIRE_FOCUS;
|
||||||
|
|
||||||
|
// while active, prevents overlay from accepting any input
|
||||||
|
// can be used while OS modal dialog is shown on top of overlay/spicecfg
|
||||||
|
// always prefer RAII set_os_window_focus_guard instead of the global bool
|
||||||
|
extern bool OS_WINDOW_ACTIVE;
|
||||||
|
inline scope_guard set_os_window_focus_guard() {
|
||||||
|
rawinput::OS_WINDOW_ACTIVE = true;
|
||||||
|
return scope_guard {[]() { rawinput::OS_WINDOW_ACTIVE = false; }};
|
||||||
|
}
|
||||||
|
|
||||||
struct DeviceCallback {
|
struct DeviceCallback {
|
||||||
void *data;
|
void *data;
|
||||||
std::function<void(void*, Device*)> f;
|
std::function<void(void*, Device*)> f;
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ namespace rawinput::touch {
|
|||||||
bool INVERTED = false;
|
bool INVERTED = false;
|
||||||
|
|
||||||
// state
|
// state
|
||||||
static bool DISPLAY_INITIALIZED = false;
|
DWORD DISPLAY_ORIENTATION = DMDO_DEFAULT;
|
||||||
static DWORD DISPLAY_ORIENTATION = DMDO_DEFAULT;
|
long DISPLAY_SIZE_X = 1920L;
|
||||||
static long DISPLAY_SIZE_X = 1920L;
|
long DISPLAY_SIZE_Y = 1080L;
|
||||||
static long DISPLAY_SIZE_Y = 1080L;
|
bool DISPLAY_INITIALIZED = false;
|
||||||
|
|
||||||
bool is_touchscreen(Device *device) {
|
bool is_touchscreen(Device *device) {
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ namespace rawinput::touch {
|
|||||||
extern bool DISABLED;
|
extern bool DISABLED;
|
||||||
extern bool INVERTED;
|
extern bool INVERTED;
|
||||||
|
|
||||||
|
// global state
|
||||||
|
extern DWORD DISPLAY_ORIENTATION;
|
||||||
|
extern long DISPLAY_SIZE_X;
|
||||||
|
extern long DISPLAY_SIZE_Y;
|
||||||
|
extern bool DISPLAY_INITIALIZED;
|
||||||
|
|
||||||
bool is_touchscreen(Device *device);
|
bool is_touchscreen(Device *device);
|
||||||
void enable(Device *device);
|
void enable(Device *device);
|
||||||
void disable(Device *device);
|
void disable(Device *device);
|
||||||
|
|||||||
Reference in New Issue
Block a user