mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 23:00:42 -07:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dc82c980b1 | |||
| 408ed17521 | |||
| f4050e9adb | |||
| badae01357 | |||
| 38d9939eb7 | |||
| f5a3caf536 | |||
| 027445afb1 | |||
| 63a3900b79 | |||
| f542a78347 | |||
| 4d32dde83e | |||
| 927170ce73 | |||
| 875a0f0765 | |||
| 3ad88ef15c | |||
| 7a6cadb176 | |||
| 4feca23240 | |||
| 2e52bebd3d | |||
| aa218d5be7 | |||
| 94f009991a | |||
| c3b9ce3fdc | |||
| 1517cf9a7c | |||
| f0f46296f2 |
@@ -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
|
||||||
|
|||||||
@@ -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,11 +644,13 @@ float GameAPI::Analogs::getState(rawinput::Device *device, Analog &analog) {
|
|||||||
case rawinput::HID: {
|
case rawinput::HID: {
|
||||||
|
|
||||||
// get value
|
// get value
|
||||||
|
if (index < device->hidInfo->value_states.size()) {
|
||||||
if (inverted) {
|
if (inverted) {
|
||||||
value = 1.f - device->hidInfo->value_states[index];
|
value = 1.f - device->hidInfo->value_states[index];
|
||||||
} else {
|
} else {
|
||||||
value = device->hidInfo->value_states[index];
|
value = device->hidInfo->value_states[index];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// deadzone
|
// deadzone
|
||||||
if (analog.isDeadzoneSet()) {
|
if (analog.isDeadzoneSet()) {
|
||||||
|
|||||||
@@ -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,7 +321,7 @@ 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",
|
||||||
@@ -311,7 +331,7 @@ std::string Button::getDisplayString(rawinput::RawInputManager* manager) {
|
|||||||
"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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -945,7 +945,8 @@ 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){
|
||||||
|
if (i == 0) {
|
||||||
GRAPHICS_FS_ORIGINAL_WIDTH = params->BackBufferWidth;
|
GRAPHICS_FS_ORIGINAL_WIDTH = params->BackBufferWidth;
|
||||||
GRAPHICS_FS_ORIGINAL_HEIGHT = params->BackBufferHeight;
|
GRAPHICS_FS_ORIGINAL_HEIGHT = params->BackBufferHeight;
|
||||||
log_misc("graphics::d3d9", "original resolution: {}x{}", GRAPHICS_FS_ORIGINAL_WIDTH, GRAPHICS_FS_ORIGINAL_HEIGHT);
|
log_misc("graphics::d3d9", "original resolution: {}x{}", GRAPHICS_FS_ORIGINAL_WIDTH, GRAPHICS_FS_ORIGINAL_HEIGHT);
|
||||||
@@ -966,6 +967,16 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3D9::CreateDeviceEx(
|
|||||||
params->BackBufferHeight, params->BackBufferWidth);
|
params->BackBufferHeight, params->BackBufferWidth);
|
||||||
std::swap(params->BackBufferWidth, params->BackBufferHeight);
|
std::swap(params->BackBufferWidth, params->BackBufferHeight);
|
||||||
}
|
}
|
||||||
|
} else if (i == 1 && GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.has_value()) {
|
||||||
|
log_misc(
|
||||||
|
"graphics::d3d9",
|
||||||
|
"use custom sub resolution {}x{} => {}x{}",
|
||||||
|
params->BackBufferWidth, params->BackBufferHeight,
|
||||||
|
GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().first,
|
||||||
|
GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().second);
|
||||||
|
params->BackBufferWidth = GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().first;
|
||||||
|
params->BackBufferHeight = GRAPHICS_FS_CUSTOM_RESOLUTION_SUB.value().second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("graphics::d3d9",
|
log_info("graphics::d3d9",
|
||||||
@@ -992,13 +1003,18 @@ 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 (i == 0) {
|
||||||
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
if (GRAPHICS_FS_CUSTOM_RESOLUTION.has_value()) {
|
||||||
fullscreen_display_mode->Width = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
fullscreen_display_mode->Width = GRAPHICS_FS_CUSTOM_RESOLUTION.value().first;
|
||||||
fullscreen_display_mode->Height = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
fullscreen_display_mode->Height = GRAPHICS_FS_CUSTOM_RESOLUTION.value().second;
|
||||||
} else if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
} else if (GRAPHICS_FS_ORIENTATION_SWAP) {
|
||||||
std::swap(fullscreen_display_mode->Width, fullscreen_display_mode->Height);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("graphics::d3d9",
|
log_info("graphics::d3d9",
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1083,8 +1083,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 +1385,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 +1888,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;
|
||||||
|
|||||||
@@ -256,9 +256,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, "
|
||||||
@@ -814,7 +826,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 +836,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",
|
||||||
@@ -884,18 +908,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",
|
||||||
@@ -2251,7 +2263,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",
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-14
@@ -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);
|
||||||
|
|
||||||
// check for card in
|
// if we have a change in state.
|
||||||
if (sensor_state > BT5API_CARD_STATES[unit_no]) {
|
if(sensor_state != BT5API_CARD_STATES[unit_no]) {
|
||||||
|
|
||||||
|
// card inserted into the back.
|
||||||
|
if(sensor_state & (1 << EAM_IO_SENSOR_BACK)) {
|
||||||
uint8_t card_id[8];
|
uint8_t card_id[8];
|
||||||
|
|
||||||
|
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);
|
eam_io_read_card(unit_no, card_id, 8);
|
||||||
eamuse_card_insert(unit_no, card_id);
|
eamuse_card_insert(unit_no, card_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save state
|
// 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 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get keypad
|
// save the last pressed.
|
||||||
eamuse_set_keypad_overrides_bt5(unit_no, eam_io_get_keypad_state(unit_no));
|
BT5API_KEYPAD_STATES[unit_no] = keypad_current;
|
||||||
|
|
||||||
|
// send off the state to the main engine.
|
||||||
|
eamuse_set_keypad_overrides_bt5(unit_no, keypad_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt5api_dispose() {
|
void bt5api_dispose() {
|
||||||
|
|||||||
@@ -202,8 +202,15 @@ bool eamuse_card_insert_consume(int active_count, int unit_id) {
|
|||||||
|
|
||||||
// bt5api
|
// bt5api
|
||||||
if (BT5API_ENABLED) {
|
if (BT5API_ENABLED) {
|
||||||
|
// 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);
|
bt5api_poll_reader_card((uint8_t) index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// auto insert card
|
// auto insert card
|
||||||
if (AUTO_INSERT_CARD[index]) {
|
if (AUTO_INSERT_CARD[index]) {
|
||||||
|
|||||||
@@ -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,77 @@ 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::SameLine();
|
||||||
|
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::SameLine();
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
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,17 +76,33 @@ 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 = "";
|
||||||
|
|
||||||
public:
|
void build_buttons(const std::string &name, std::vector<Button> *buttons, int min = 0, int max = -1);
|
||||||
Config(SpiceOverlay *overlay);
|
void build_button(
|
||||||
~Config() override;
|
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 read_card(int player = -1);
|
|
||||||
void write_card(int player);
|
|
||||||
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_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_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();
|
void build_cards();
|
||||||
void build_options(
|
void build_options(
|
||||||
std::vector<Option> *options, const std::string &category, const std::string *filter=nullptr);
|
std::vector<Option> *options, const std::string &category, const std::string *filter=nullptr);
|
||||||
@@ -96,8 +110,18 @@ namespace overlay::windows {
|
|||||||
void build_launcher();
|
void build_launcher();
|
||||||
void launch_shell(LPCSTR app, LPCSTR file=nullptr);
|
void launch_shell(LPCSTR app, LPCSTR file=nullptr);
|
||||||
|
|
||||||
static void build_page_selector(int *page);
|
|
||||||
void build_menu(int *game_selected);
|
void build_menu(int *game_selected);
|
||||||
void shutdown_system(bool force, bool reboot_instead);
|
void shutdown_system(bool force, bool reboot_instead);
|
||||||
|
|
||||||
|
void set_alternating_row_colors(const int row_index);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Config(SpiceOverlay *overlay);
|
||||||
|
~Config() override;
|
||||||
|
|
||||||
|
void read_card(int player = -1);
|
||||||
|
void write_card(int player);
|
||||||
|
void build_content() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user