chore: CRLF to LF
This commit is contained in:
@@ -1,44 +1,44 @@
|
||||
#include "acio_status_buffers.h"
|
||||
#include "overlay/imgui/extensions.h"
|
||||
#include "external/imgui/imgui_memory_editor.h"
|
||||
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
ACIOStatusBuffers::ACIOStatusBuffers(SpiceOverlay *overlay, acio::ACIOModule *module)
|
||||
: Window(overlay), module(module) {
|
||||
this->title = module->name + " Status Buffers";
|
||||
this->init_size = ImVec2(600, 400);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->active = true;
|
||||
|
||||
// configure editor defaults
|
||||
this->editor = new MemoryEditor();
|
||||
this->editor->OptShowDataPreview = true;
|
||||
this->editor->PreviewDataType = MemoryEditor::DataType::DataType_U16;
|
||||
}
|
||||
|
||||
ACIOStatusBuffers::~ACIOStatusBuffers() {
|
||||
|
||||
// kill editor
|
||||
delete this->editor;
|
||||
}
|
||||
|
||||
void ACIOStatusBuffers::build_content() {
|
||||
|
||||
// freeze checkbox
|
||||
if (module->status_buffer_freeze) {
|
||||
ImGui::Checkbox("Freeze", module->status_buffer_freeze);
|
||||
ImGui::SameLine();
|
||||
ImGui::HelpMarker("Prevent automatic modifications to the buffer.");
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
// draw editor
|
||||
this->editor->DrawContents(
|
||||
this->module->status_buffer,
|
||||
this->module->status_buffer_size);
|
||||
}
|
||||
}
|
||||
#include "acio_status_buffers.h"
|
||||
#include "overlay/imgui/extensions.h"
|
||||
#include "external/imgui/imgui_memory_editor.h"
|
||||
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
ACIOStatusBuffers::ACIOStatusBuffers(SpiceOverlay *overlay, acio::ACIOModule *module)
|
||||
: Window(overlay), module(module) {
|
||||
this->title = module->name + " Status Buffers";
|
||||
this->init_size = ImVec2(600, 400);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->active = true;
|
||||
|
||||
// configure editor defaults
|
||||
this->editor = new MemoryEditor();
|
||||
this->editor->OptShowDataPreview = true;
|
||||
this->editor->PreviewDataType = MemoryEditor::DataType::DataType_U16;
|
||||
}
|
||||
|
||||
ACIOStatusBuffers::~ACIOStatusBuffers() {
|
||||
|
||||
// kill editor
|
||||
delete this->editor;
|
||||
}
|
||||
|
||||
void ACIOStatusBuffers::build_content() {
|
||||
|
||||
// freeze checkbox
|
||||
if (module->status_buffer_freeze) {
|
||||
ImGui::Checkbox("Freeze", module->status_buffer_freeze);
|
||||
ImGui::SameLine();
|
||||
ImGui::HelpMarker("Prevent automatic modifications to the buffer.");
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
// draw editor
|
||||
this->editor->DrawContents(
|
||||
this->module->status_buffer,
|
||||
this->module->status_buffer_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
#include "acio/acio.h"
|
||||
|
||||
struct MemoryEditor;
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class ACIOStatusBuffers : public Window {
|
||||
public:
|
||||
|
||||
ACIOStatusBuffers(SpiceOverlay *overlay, acio::ACIOModule *module);
|
||||
~ACIOStatusBuffers() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
acio::ACIOModule *module;
|
||||
MemoryEditor *editor;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
#include "acio/acio.h"
|
||||
|
||||
struct MemoryEditor;
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class ACIOStatusBuffers : public Window {
|
||||
public:
|
||||
|
||||
ACIOStatusBuffers(SpiceOverlay *overlay, acio::ACIOModule *module);
|
||||
~ACIOStatusBuffers() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
acio::ACIOModule *module;
|
||||
MemoryEditor *editor;
|
||||
};
|
||||
}
|
||||
|
||||
+260
-260
@@ -1,260 +1,260 @@
|
||||
#include <games/io.h>
|
||||
#include "card_manager.h"
|
||||
|
||||
#include "external/rapidjson/document.h"
|
||||
#include "external/rapidjson/writer.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/utils.h"
|
||||
#include "util/fileutils.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
CardManager::CardManager(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "Card Manager";
|
||||
this->init_size = ImVec2(300, 200);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->toggle_button = games::OverlayButtons::ToggleCardManager;
|
||||
this->config_path = std::string(getenv("APPDATA")) + "\\spicetools_card_manager.json";
|
||||
if (fileutils::file_exists(this->config_path)) {
|
||||
this->config_load();
|
||||
}
|
||||
}
|
||||
|
||||
CardManager::~CardManager() {
|
||||
}
|
||||
|
||||
void CardManager::build_content() {
|
||||
|
||||
// get window size
|
||||
auto window_size = ImGui::GetWindowSize();
|
||||
|
||||
// name field
|
||||
ImGui::InputTextWithHint("Card Name", "Main Card",
|
||||
this->name_buffer, std::size(this->name_buffer));
|
||||
|
||||
// card field
|
||||
ImGui::InputTextWithHint("Card ID", "E0040123456789AB",
|
||||
this->card_buffer,
|
||||
std::size(this->card_buffer),
|
||||
ImGuiInputTextFlags_CharsHexadecimal
|
||||
| ImGuiInputTextFlags_CharsUppercase);
|
||||
|
||||
// add card button
|
||||
if (strlen(this->card_buffer) == 16) {
|
||||
if (ImGui::Button("Add Card", ImVec2(-1.f, 0.f))) {
|
||||
|
||||
// save entry
|
||||
CardEntry entry {
|
||||
.name = this->name_buffer,
|
||||
.id = this->card_buffer
|
||||
};
|
||||
this->cards.emplace_back(entry);
|
||||
this->config_dirty = true;
|
||||
|
||||
// clear input fields
|
||||
memset(this->name_buffer, 0, sizeof(this->name_buffer));
|
||||
memset(this->card_buffer, 0, sizeof(this->card_buffer));
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("Enter card identifier...");
|
||||
}
|
||||
|
||||
// cards area
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginChild("cards", ImVec2(0, window_size.y - 128))) {
|
||||
for (auto &card : this->cards) {
|
||||
|
||||
// get card name
|
||||
std::string card_name = card.name;
|
||||
if (card.name.size() > 0) {
|
||||
card_name += " - ";
|
||||
}
|
||||
card_name += card.id;
|
||||
|
||||
// draw entry
|
||||
ImGui::PushID(&card);
|
||||
if (ImGui::Selectable(card_name.c_str(), card.selected)) {
|
||||
|
||||
// unselect other cards
|
||||
for (auto &card_disable : this->cards) {
|
||||
card_disable.selected = false;
|
||||
}
|
||||
|
||||
// mark this card as the selected one
|
||||
card.selected = true;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// insert P1 button
|
||||
if (ImGui::Button("Insert P1")) {
|
||||
auto card = this->cards_get_selected();
|
||||
uint8_t card_bin[8];
|
||||
if (card && card->id.length() == 16 && hex2bin(card->id.c_str(), card_bin)) {
|
||||
eamuse_card_insert(0, card_bin);
|
||||
}
|
||||
}
|
||||
|
||||
// insert P2 button
|
||||
if (eamuse_get_game_keypads() > 1) {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Insert P2")) {
|
||||
auto card = this->cards_get_selected();
|
||||
uint8_t card_bin[8];
|
||||
if (card && card->id.length() == 16 && hex2bin(card->id.c_str(), card_bin)) {
|
||||
eamuse_card_insert(1, card_bin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save button
|
||||
if (this->config_dirty) {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save")) {
|
||||
this->config_save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CardEntry *CardManager::cards_get_selected() {
|
||||
|
||||
// iterate cards
|
||||
for (auto &card : this->cards) {
|
||||
|
||||
// check if selected and return pointer
|
||||
if (card.selected) {
|
||||
return &card;
|
||||
}
|
||||
}
|
||||
|
||||
// no card selected
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CardManager::config_load() {
|
||||
log_info("cardmanager", "loading config");
|
||||
|
||||
// clear cards
|
||||
this->cards.clear();
|
||||
|
||||
// read config file
|
||||
std::string config = fileutils::text_read(this->config_path);
|
||||
if (!config.empty()) {
|
||||
|
||||
// parse document
|
||||
Document doc;
|
||||
doc.Parse(config.c_str());
|
||||
|
||||
// check parse error
|
||||
auto error = doc.GetParseError();
|
||||
if (error) {
|
||||
log_warning("cardmanager", "config parse error: {}", error);
|
||||
}
|
||||
|
||||
// verify root is a dict
|
||||
if (doc.IsObject()) {
|
||||
|
||||
// find pages
|
||||
auto pages = doc.FindMember("pages");
|
||||
if (pages != doc.MemberEnd() && pages->value.IsArray()) {
|
||||
|
||||
// iterate pages
|
||||
for (auto &page : pages->value.GetArray()) {
|
||||
if (page.IsObject()) {
|
||||
|
||||
// get cards
|
||||
auto cards = page.FindMember("cards");
|
||||
if (cards != doc.MemberEnd() && cards->value.IsArray()) {
|
||||
|
||||
// iterate cards
|
||||
for (auto &card : cards->value.GetArray()) {
|
||||
if (card.IsObject()) {
|
||||
|
||||
// find attributes
|
||||
auto name = card.FindMember("name");
|
||||
if (name == doc.MemberEnd() || !name->value.IsString()) {
|
||||
log_warning("cardmanager", "card name not found");
|
||||
continue;
|
||||
}
|
||||
auto id = card.FindMember("id");
|
||||
if (id == doc.MemberEnd() || !id->value.IsString()) {
|
||||
log_warning("cardmanager", "card id not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
// save entry
|
||||
CardEntry entry {
|
||||
.name = name->value.GetString(),
|
||||
.id = id->value.GetString()
|
||||
};
|
||||
this->cards.emplace_back(entry);
|
||||
|
||||
} else {
|
||||
log_warning("cardmanager", "card is not an object");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_warning("cardmanager", "cards not found or not an array");
|
||||
}
|
||||
} else {
|
||||
log_warning("cardmanager", "page is not an object");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_warning("cardmanager", "pages not found or not an array");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CardManager::config_save() {
|
||||
log_info("cardmanager", "saving config");
|
||||
|
||||
// create document
|
||||
Document doc;
|
||||
doc.Parse(
|
||||
"{"
|
||||
" \"pages\": ["
|
||||
" {"
|
||||
" \"cards\": ["
|
||||
" ]"
|
||||
" }"
|
||||
" ]"
|
||||
"}"
|
||||
);
|
||||
|
||||
// check parse error
|
||||
auto error = doc.GetParseError();
|
||||
if (error) {
|
||||
log_warning("cardmanager", "template parse error: {}", error);
|
||||
}
|
||||
|
||||
// add cards
|
||||
auto &cards = doc["pages"][0]["cards"];
|
||||
for (auto &entry : this->cards) {
|
||||
Value card(kObjectType);
|
||||
card.AddMember("name", StringRef(entry.name.c_str()), doc.GetAllocator());
|
||||
card.AddMember("id", StringRef(entry.id.c_str()), doc.GetAllocator());
|
||||
cards.PushBack(card, doc.GetAllocator());
|
||||
}
|
||||
|
||||
// build JSON
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
doc.Accept(writer);
|
||||
|
||||
// save to file
|
||||
if (fileutils::text_write(this->config_path, buffer.GetString())) {
|
||||
this->config_dirty = false;
|
||||
} else {
|
||||
log_warning("cardmanager", "unable to save config file to {}", this->config_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
#include <games/io.h>
|
||||
#include "card_manager.h"
|
||||
|
||||
#include "external/rapidjson/document.h"
|
||||
#include "external/rapidjson/writer.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/utils.h"
|
||||
#include "util/fileutils.h"
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
CardManager::CardManager(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "Card Manager";
|
||||
this->init_size = ImVec2(300, 200);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->toggle_button = games::OverlayButtons::ToggleCardManager;
|
||||
this->config_path = std::string(getenv("APPDATA")) + "\\spicetools_card_manager.json";
|
||||
if (fileutils::file_exists(this->config_path)) {
|
||||
this->config_load();
|
||||
}
|
||||
}
|
||||
|
||||
CardManager::~CardManager() {
|
||||
}
|
||||
|
||||
void CardManager::build_content() {
|
||||
|
||||
// get window size
|
||||
auto window_size = ImGui::GetWindowSize();
|
||||
|
||||
// name field
|
||||
ImGui::InputTextWithHint("Card Name", "Main Card",
|
||||
this->name_buffer, std::size(this->name_buffer));
|
||||
|
||||
// card field
|
||||
ImGui::InputTextWithHint("Card ID", "E0040123456789AB",
|
||||
this->card_buffer,
|
||||
std::size(this->card_buffer),
|
||||
ImGuiInputTextFlags_CharsHexadecimal
|
||||
| ImGuiInputTextFlags_CharsUppercase);
|
||||
|
||||
// add card button
|
||||
if (strlen(this->card_buffer) == 16) {
|
||||
if (ImGui::Button("Add Card", ImVec2(-1.f, 0.f))) {
|
||||
|
||||
// save entry
|
||||
CardEntry entry {
|
||||
.name = this->name_buffer,
|
||||
.id = this->card_buffer
|
||||
};
|
||||
this->cards.emplace_back(entry);
|
||||
this->config_dirty = true;
|
||||
|
||||
// clear input fields
|
||||
memset(this->name_buffer, 0, sizeof(this->name_buffer));
|
||||
memset(this->card_buffer, 0, sizeof(this->card_buffer));
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("Enter card identifier...");
|
||||
}
|
||||
|
||||
// cards area
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginChild("cards", ImVec2(0, window_size.y - 128))) {
|
||||
for (auto &card : this->cards) {
|
||||
|
||||
// get card name
|
||||
std::string card_name = card.name;
|
||||
if (card.name.size() > 0) {
|
||||
card_name += " - ";
|
||||
}
|
||||
card_name += card.id;
|
||||
|
||||
// draw entry
|
||||
ImGui::PushID(&card);
|
||||
if (ImGui::Selectable(card_name.c_str(), card.selected)) {
|
||||
|
||||
// unselect other cards
|
||||
for (auto &card_disable : this->cards) {
|
||||
card_disable.selected = false;
|
||||
}
|
||||
|
||||
// mark this card as the selected one
|
||||
card.selected = true;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// insert P1 button
|
||||
if (ImGui::Button("Insert P1")) {
|
||||
auto card = this->cards_get_selected();
|
||||
uint8_t card_bin[8];
|
||||
if (card && card->id.length() == 16 && hex2bin(card->id.c_str(), card_bin)) {
|
||||
eamuse_card_insert(0, card_bin);
|
||||
}
|
||||
}
|
||||
|
||||
// insert P2 button
|
||||
if (eamuse_get_game_keypads() > 1) {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Insert P2")) {
|
||||
auto card = this->cards_get_selected();
|
||||
uint8_t card_bin[8];
|
||||
if (card && card->id.length() == 16 && hex2bin(card->id.c_str(), card_bin)) {
|
||||
eamuse_card_insert(1, card_bin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save button
|
||||
if (this->config_dirty) {
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save")) {
|
||||
this->config_save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CardEntry *CardManager::cards_get_selected() {
|
||||
|
||||
// iterate cards
|
||||
for (auto &card : this->cards) {
|
||||
|
||||
// check if selected and return pointer
|
||||
if (card.selected) {
|
||||
return &card;
|
||||
}
|
||||
}
|
||||
|
||||
// no card selected
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CardManager::config_load() {
|
||||
log_info("cardmanager", "loading config");
|
||||
|
||||
// clear cards
|
||||
this->cards.clear();
|
||||
|
||||
// read config file
|
||||
std::string config = fileutils::text_read(this->config_path);
|
||||
if (!config.empty()) {
|
||||
|
||||
// parse document
|
||||
Document doc;
|
||||
doc.Parse(config.c_str());
|
||||
|
||||
// check parse error
|
||||
auto error = doc.GetParseError();
|
||||
if (error) {
|
||||
log_warning("cardmanager", "config parse error: {}", error);
|
||||
}
|
||||
|
||||
// verify root is a dict
|
||||
if (doc.IsObject()) {
|
||||
|
||||
// find pages
|
||||
auto pages = doc.FindMember("pages");
|
||||
if (pages != doc.MemberEnd() && pages->value.IsArray()) {
|
||||
|
||||
// iterate pages
|
||||
for (auto &page : pages->value.GetArray()) {
|
||||
if (page.IsObject()) {
|
||||
|
||||
// get cards
|
||||
auto cards = page.FindMember("cards");
|
||||
if (cards != doc.MemberEnd() && cards->value.IsArray()) {
|
||||
|
||||
// iterate cards
|
||||
for (auto &card : cards->value.GetArray()) {
|
||||
if (card.IsObject()) {
|
||||
|
||||
// find attributes
|
||||
auto name = card.FindMember("name");
|
||||
if (name == doc.MemberEnd() || !name->value.IsString()) {
|
||||
log_warning("cardmanager", "card name not found");
|
||||
continue;
|
||||
}
|
||||
auto id = card.FindMember("id");
|
||||
if (id == doc.MemberEnd() || !id->value.IsString()) {
|
||||
log_warning("cardmanager", "card id not found");
|
||||
continue;
|
||||
}
|
||||
|
||||
// save entry
|
||||
CardEntry entry {
|
||||
.name = name->value.GetString(),
|
||||
.id = id->value.GetString()
|
||||
};
|
||||
this->cards.emplace_back(entry);
|
||||
|
||||
} else {
|
||||
log_warning("cardmanager", "card is not an object");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_warning("cardmanager", "cards not found or not an array");
|
||||
}
|
||||
} else {
|
||||
log_warning("cardmanager", "page is not an object");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_warning("cardmanager", "pages not found or not an array");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CardManager::config_save() {
|
||||
log_info("cardmanager", "saving config");
|
||||
|
||||
// create document
|
||||
Document doc;
|
||||
doc.Parse(
|
||||
"{"
|
||||
" \"pages\": ["
|
||||
" {"
|
||||
" \"cards\": ["
|
||||
" ]"
|
||||
" }"
|
||||
" ]"
|
||||
"}"
|
||||
);
|
||||
|
||||
// check parse error
|
||||
auto error = doc.GetParseError();
|
||||
if (error) {
|
||||
log_warning("cardmanager", "template parse error: {}", error);
|
||||
}
|
||||
|
||||
// add cards
|
||||
auto &cards = doc["pages"][0]["cards"];
|
||||
for (auto &entry : this->cards) {
|
||||
Value card(kObjectType);
|
||||
card.AddMember("name", StringRef(entry.name.c_str()), doc.GetAllocator());
|
||||
card.AddMember("id", StringRef(entry.id.c_str()), doc.GetAllocator());
|
||||
cards.PushBack(card, doc.GetAllocator());
|
||||
}
|
||||
|
||||
// build JSON
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
doc.Accept(writer);
|
||||
|
||||
// save to file
|
||||
if (fileutils::text_write(this->config_path, buffer.GetString())) {
|
||||
this->config_dirty = false;
|
||||
} else {
|
||||
log_warning("cardmanager", "unable to save config file to {}", this->config_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
struct CardEntry {
|
||||
std::string name = "unnamed";
|
||||
std::string id = "E004000000000000";
|
||||
bool selected = false;
|
||||
};
|
||||
|
||||
class CardManager : public Window {
|
||||
public:
|
||||
|
||||
CardManager(SpiceOverlay *overlay);
|
||||
~CardManager() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
|
||||
std::string config_path;
|
||||
bool config_dirty = false;
|
||||
std::vector<CardEntry> cards;
|
||||
char name_buffer[65] {};
|
||||
char card_buffer[17] {};
|
||||
|
||||
CardEntry *cards_get_selected();
|
||||
void config_load();
|
||||
void config_save();
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
struct CardEntry {
|
||||
std::string name = "unnamed";
|
||||
std::string id = "E004000000000000";
|
||||
bool selected = false;
|
||||
};
|
||||
|
||||
class CardManager : public Window {
|
||||
public:
|
||||
|
||||
CardManager(SpiceOverlay *overlay);
|
||||
~CardManager() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
|
||||
std::string config_path;
|
||||
bool config_dirty = false;
|
||||
std::vector<CardEntry> cards;
|
||||
char name_buffer[65] {};
|
||||
char card_buffer[17] {};
|
||||
|
||||
CardEntry *cards_get_selected();
|
||||
void config_load();
|
||||
void config_save();
|
||||
};
|
||||
}
|
||||
|
||||
+53
-53
@@ -1,53 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class Control : public Window {
|
||||
public:
|
||||
|
||||
Control(SpiceOverlay *overlay);
|
||||
~Control() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
|
||||
// state
|
||||
char card_input[17] {};
|
||||
|
||||
// other windows
|
||||
bool demo_open = false;
|
||||
bool metrics_open = false;
|
||||
std::vector<float> cpu_values;
|
||||
|
||||
// memory editor
|
||||
bool memory_editor_open = false;
|
||||
int memory_editor_selection = -1;
|
||||
std::vector<std::pair<std::string, HMODULE>> memory_editor_modules;
|
||||
std::vector<const char*> memory_editor_names;
|
||||
ImGuiTextFilter memory_editor_filter;
|
||||
|
||||
// pane views
|
||||
void top_row_buttons();
|
||||
void img_gui_view();
|
||||
void avs_info_view();
|
||||
void acio_view();
|
||||
void cpu_view();
|
||||
void graphics_view();
|
||||
void buttons_view();
|
||||
void analogs_view();
|
||||
void lights_view();
|
||||
void cards_view();
|
||||
void coin_view();
|
||||
void control_view();
|
||||
void api_view();
|
||||
void raw_input_view();
|
||||
void touch_view();
|
||||
void lcd_view();
|
||||
void about_view();
|
||||
void ddr_timing_view();
|
||||
void iidx_effectors_view();
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class Control : public Window {
|
||||
public:
|
||||
|
||||
Control(SpiceOverlay *overlay);
|
||||
~Control() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
|
||||
// state
|
||||
char card_input[17] {};
|
||||
|
||||
// other windows
|
||||
bool demo_open = false;
|
||||
bool metrics_open = false;
|
||||
std::vector<float> cpu_values;
|
||||
|
||||
// memory editor
|
||||
bool memory_editor_open = false;
|
||||
int memory_editor_selection = -1;
|
||||
std::vector<std::pair<std::string, HMODULE>> memory_editor_modules;
|
||||
std::vector<const char*> memory_editor_names;
|
||||
ImGuiTextFilter memory_editor_filter;
|
||||
|
||||
// pane views
|
||||
void top_row_buttons();
|
||||
void img_gui_view();
|
||||
void avs_info_view();
|
||||
void acio_view();
|
||||
void cpu_view();
|
||||
void graphics_view();
|
||||
void buttons_view();
|
||||
void analogs_view();
|
||||
void lights_view();
|
||||
void cards_view();
|
||||
void coin_view();
|
||||
void control_view();
|
||||
void api_view();
|
||||
void raw_input_view();
|
||||
void touch_view();
|
||||
void lcd_view();
|
||||
void about_view();
|
||||
void ddr_timing_view();
|
||||
void iidx_effectors_view();
|
||||
};
|
||||
}
|
||||
|
||||
+22
-22
@@ -1,22 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class EADevWindow : public Window {
|
||||
public:
|
||||
|
||||
EADevWindow(SpiceOverlay *overlay);
|
||||
~EADevWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
static void automap_hook(void *user, const char *data);
|
||||
|
||||
private:
|
||||
|
||||
bool automap_autoscroll = true;
|
||||
bool automap_scroll_to_bottom = false;
|
||||
std::vector<std::string> automap_data;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class EADevWindow : public Window {
|
||||
public:
|
||||
|
||||
EADevWindow(SpiceOverlay *overlay);
|
||||
~EADevWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
static void automap_hook(void *user, const char *data);
|
||||
|
||||
private:
|
||||
|
||||
bool automap_autoscroll = true;
|
||||
bool automap_scroll_to_bottom = false;
|
||||
std::vector<std::string> automap_data;
|
||||
};
|
||||
}
|
||||
|
||||
+29
-29
@@ -1,29 +1,29 @@
|
||||
#include "fps.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
FPS::FPS(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "FPS & Frame Time";
|
||||
this->flags = ImGuiWindowFlags_NoTitleBar
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_NoResize
|
||||
| ImGuiWindowFlags_AlwaysAutoResize
|
||||
| ImGuiWindowFlags_NoDecoration
|
||||
| ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoNavFocus
|
||||
| ImGuiWindowFlags_NoNavInputs;
|
||||
this->bg_alpha = 0.4f;
|
||||
}
|
||||
|
||||
const ImVec2 FPS::initial_pos() {
|
||||
return ImVec2(ImGui::GetIO().DisplaySize.x - 100, 10);
|
||||
}
|
||||
|
||||
void FPS::build_content() {
|
||||
|
||||
// frame timers
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
ImGui::Text("FPS: %.1f", io.Framerate);
|
||||
ImGui::Text("FT: %.2fms", 1000 / io.Framerate);
|
||||
}
|
||||
}
|
||||
#include "fps.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
FPS::FPS(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "FPS & Frame Time";
|
||||
this->flags = ImGuiWindowFlags_NoTitleBar
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_NoResize
|
||||
| ImGuiWindowFlags_AlwaysAutoResize
|
||||
| ImGuiWindowFlags_NoDecoration
|
||||
| ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoNavFocus
|
||||
| ImGuiWindowFlags_NoNavInputs;
|
||||
this->bg_alpha = 0.4f;
|
||||
}
|
||||
|
||||
const ImVec2 FPS::initial_pos() {
|
||||
return ImVec2(ImGui::GetIO().DisplaySize.x - 100, 10);
|
||||
}
|
||||
|
||||
void FPS::build_content() {
|
||||
|
||||
// frame timers
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
ImGui::Text("FPS: %.1f", io.Framerate);
|
||||
ImGui::Text("FT: %.2fms", 1000 / io.Framerate);
|
||||
}
|
||||
}
|
||||
|
||||
+15
-15
@@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class FPS : public Window {
|
||||
public:
|
||||
|
||||
FPS(SpiceOverlay *overlay);
|
||||
|
||||
const ImVec2 initial_pos() override;
|
||||
void build_content() override;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class FPS : public Window {
|
||||
public:
|
||||
|
||||
FPS(SpiceOverlay *overlay);
|
||||
|
||||
const ImVec2 initial_pos() override;
|
||||
void build_content() override;
|
||||
};
|
||||
}
|
||||
|
||||
+31
-31
@@ -1,31 +1,31 @@
|
||||
#ifndef SPICETOOLS_OVERLAY_WINDOWS_IIDX_SUB_H
|
||||
#define SPICETOOLS_OVERLAY_WINDOWS_IIDX_SUB_H
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class IIDXSubScreen : public Window {
|
||||
public:
|
||||
IIDXSubScreen(SpiceOverlay *overlay);
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
bool build_texture(IDirect3DSurface9 *surface);
|
||||
void draw_texture();
|
||||
|
||||
std::optional<std::string> status_message = std::nullopt;
|
||||
|
||||
IDirect3DDevice9 *device = nullptr;
|
||||
IDirect3DTexture9 *texture = nullptr;
|
||||
ImVec2 texture_size;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SPICETOOLS_OVERLAY_WINDOWS_IIDX_SUB_H
|
||||
#ifndef SPICETOOLS_OVERLAY_WINDOWS_IIDX_SUB_H
|
||||
#define SPICETOOLS_OVERLAY_WINDOWS_IIDX_SUB_H
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class IIDXSubScreen : public Window {
|
||||
public:
|
||||
IIDXSubScreen(SpiceOverlay *overlay);
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
bool build_texture(IDirect3DSurface9 *surface);
|
||||
void draw_texture();
|
||||
|
||||
std::optional<std::string> status_message = std::nullopt;
|
||||
|
||||
IDirect3DDevice9 *device = nullptr;
|
||||
IDirect3DTexture9 *texture = nullptr;
|
||||
ImVec2 texture_size;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SPICETOOLS_OVERLAY_WINDOWS_IIDX_SUB_H
|
||||
|
||||
+94
-94
@@ -1,94 +1,94 @@
|
||||
#include <games/io.h>
|
||||
#include "keypad.h"
|
||||
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
Keypad::Keypad(SpiceOverlay *overlay, size_t unit) : Window(overlay), unit(unit) {
|
||||
this->title = "Keypad P" + to_string(unit + 1);
|
||||
this->flags = ImGuiWindowFlags_NoResize
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_AlwaysAutoResize;
|
||||
|
||||
switch (this->unit) {
|
||||
case 0: {
|
||||
this->toggle_button = games::OverlayButtons::ToggleVirtualKeypadP1;
|
||||
this->init_pos = ImVec2(
|
||||
26,
|
||||
ImGui::GetIO().DisplaySize.y - 264);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
this->toggle_button = games::OverlayButtons::ToggleVirtualKeypadP2;
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x - 220,
|
||||
ImGui::GetIO().DisplaySize.y - 264);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Keypad::~Keypad() {
|
||||
|
||||
// reset overrides
|
||||
eamuse_set_keypad_overrides_overlay(this->unit, 0);
|
||||
}
|
||||
|
||||
void Keypad::build_content() {
|
||||
|
||||
// buttons
|
||||
static const struct {
|
||||
const char *text;
|
||||
int flag;
|
||||
} BUTTONS[] = {
|
||||
{ "7", 1 << EAM_IO_KEYPAD_7 },
|
||||
{ "8", 1 << EAM_IO_KEYPAD_8 },
|
||||
{ "9", 1 << EAM_IO_KEYPAD_9 },
|
||||
{ "4", 1 << EAM_IO_KEYPAD_4 },
|
||||
{ "5", 1 << EAM_IO_KEYPAD_5 },
|
||||
{ "6", 1 << EAM_IO_KEYPAD_6 },
|
||||
{ "1", 1 << EAM_IO_KEYPAD_1 },
|
||||
{ "2", 1 << EAM_IO_KEYPAD_2 },
|
||||
{ "3", 1 << EAM_IO_KEYPAD_3 },
|
||||
{ "0", 1 << EAM_IO_KEYPAD_0 },
|
||||
{ "00", 1 << EAM_IO_KEYPAD_00 },
|
||||
{ ".", 1 << EAM_IO_KEYPAD_DECIMAL },
|
||||
{ "Insert Card", 1 << EAM_IO_INSERT },
|
||||
};
|
||||
|
||||
// reset overrides
|
||||
eamuse_set_keypad_overrides_overlay(this->unit, 0);
|
||||
|
||||
// build grid
|
||||
for (size_t i = 0; i < std::size(BUTTONS); i++) {
|
||||
auto &button = BUTTONS[i];
|
||||
|
||||
// push id and alignment
|
||||
ImGui::PushID(4096 + i);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f, 0.5f));
|
||||
|
||||
// add selectable (fill last line)
|
||||
if (i == std::size(BUTTONS) - 1) {
|
||||
ImGui::Selectable(button.text, false, 0, ImVec2(112, 32));
|
||||
} else {
|
||||
ImGui::Selectable(button.text, false, 0, ImVec2(32, 32));
|
||||
}
|
||||
|
||||
// mouse down handler
|
||||
if (ImGui::IsItemHovered() && ImGui::IsAnyMouseDown()) {
|
||||
eamuse_set_keypad_overrides_overlay(this->unit, button.flag);
|
||||
}
|
||||
|
||||
// pop id and alignment
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopID();
|
||||
|
||||
// line join
|
||||
if ((i % 3) < 2) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#include <games/io.h>
|
||||
#include "keypad.h"
|
||||
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
Keypad::Keypad(SpiceOverlay *overlay, size_t unit) : Window(overlay), unit(unit) {
|
||||
this->title = "Keypad P" + to_string(unit + 1);
|
||||
this->flags = ImGuiWindowFlags_NoResize
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_AlwaysAutoResize;
|
||||
|
||||
switch (this->unit) {
|
||||
case 0: {
|
||||
this->toggle_button = games::OverlayButtons::ToggleVirtualKeypadP1;
|
||||
this->init_pos = ImVec2(
|
||||
26,
|
||||
ImGui::GetIO().DisplaySize.y - 264);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
this->toggle_button = games::OverlayButtons::ToggleVirtualKeypadP2;
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x - 220,
|
||||
ImGui::GetIO().DisplaySize.y - 264);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Keypad::~Keypad() {
|
||||
|
||||
// reset overrides
|
||||
eamuse_set_keypad_overrides_overlay(this->unit, 0);
|
||||
}
|
||||
|
||||
void Keypad::build_content() {
|
||||
|
||||
// buttons
|
||||
static const struct {
|
||||
const char *text;
|
||||
int flag;
|
||||
} BUTTONS[] = {
|
||||
{ "7", 1 << EAM_IO_KEYPAD_7 },
|
||||
{ "8", 1 << EAM_IO_KEYPAD_8 },
|
||||
{ "9", 1 << EAM_IO_KEYPAD_9 },
|
||||
{ "4", 1 << EAM_IO_KEYPAD_4 },
|
||||
{ "5", 1 << EAM_IO_KEYPAD_5 },
|
||||
{ "6", 1 << EAM_IO_KEYPAD_6 },
|
||||
{ "1", 1 << EAM_IO_KEYPAD_1 },
|
||||
{ "2", 1 << EAM_IO_KEYPAD_2 },
|
||||
{ "3", 1 << EAM_IO_KEYPAD_3 },
|
||||
{ "0", 1 << EAM_IO_KEYPAD_0 },
|
||||
{ "00", 1 << EAM_IO_KEYPAD_00 },
|
||||
{ ".", 1 << EAM_IO_KEYPAD_DECIMAL },
|
||||
{ "Insert Card", 1 << EAM_IO_INSERT },
|
||||
};
|
||||
|
||||
// reset overrides
|
||||
eamuse_set_keypad_overrides_overlay(this->unit, 0);
|
||||
|
||||
// build grid
|
||||
for (size_t i = 0; i < std::size(BUTTONS); i++) {
|
||||
auto &button = BUTTONS[i];
|
||||
|
||||
// push id and alignment
|
||||
ImGui::PushID(4096 + i);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f, 0.5f));
|
||||
|
||||
// add selectable (fill last line)
|
||||
if (i == std::size(BUTTONS) - 1) {
|
||||
ImGui::Selectable(button.text, false, 0, ImVec2(112, 32));
|
||||
} else {
|
||||
ImGui::Selectable(button.text, false, 0, ImVec2(32, 32));
|
||||
}
|
||||
|
||||
// mouse down handler
|
||||
if (ImGui::IsItemHovered() && ImGui::IsAnyMouseDown()) {
|
||||
eamuse_set_keypad_overrides_overlay(this->unit, button.flag);
|
||||
}
|
||||
|
||||
// pop id and alignment
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopID();
|
||||
|
||||
// line join
|
||||
if ((i % 3) < 2) {
|
||||
ImGui::SameLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
-19
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class Keypad : public Window {
|
||||
private:
|
||||
|
||||
size_t unit = 0;
|
||||
|
||||
public:
|
||||
|
||||
Keypad(SpiceOverlay *overlay, size_t unit);
|
||||
~Keypad() override;
|
||||
|
||||
void build_content() override;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class Keypad : public Window {
|
||||
private:
|
||||
|
||||
size_t unit = 0;
|
||||
|
||||
public:
|
||||
|
||||
Keypad(SpiceOverlay *overlay, size_t unit);
|
||||
~Keypad() override;
|
||||
|
||||
void build_content() override;
|
||||
};
|
||||
}
|
||||
|
||||
+122
-122
@@ -1,122 +1,122 @@
|
||||
#include "log.h"
|
||||
#include "util/utils.h"
|
||||
#include "util/fileutils.h"
|
||||
#include "games/io.h"
|
||||
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
Log::Log(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "Log";
|
||||
this->toggle_button = games::OverlayButtons::ToggleLog;
|
||||
this->init_size = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x * 0.8f,
|
||||
ImGui::GetIO().DisplaySize.y * 0.8f);
|
||||
this->size_min = ImVec2(250, 200);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
|
||||
// read existing contents from file
|
||||
if (LOG_FILE_PATH.length() > 0) {
|
||||
auto contents = fileutils::text_read(LOG_FILE_PATH);
|
||||
if (contents.length() > 0) {
|
||||
this->log_hook(this, contents, logger::Style::DEFAULT, contents);
|
||||
}
|
||||
}
|
||||
|
||||
// add log hook
|
||||
logger::hook_add(&log_hook, this);
|
||||
}
|
||||
|
||||
Log::~Log() {
|
||||
|
||||
// remove log hook
|
||||
logger::hook_remove(&log_hook, this);
|
||||
}
|
||||
|
||||
void Log::clear() {
|
||||
|
||||
// lock and clear the data vector
|
||||
std::lock_guard<std::mutex> lock(this->log_data_m);
|
||||
this->log_data.clear();
|
||||
}
|
||||
|
||||
void Log::build_content() {
|
||||
|
||||
// clear button
|
||||
if (ImGui::Button("Clear")) {
|
||||
this->clear();
|
||||
}
|
||||
|
||||
// autoscroll option
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Autoscroll", &this->autoscroll);
|
||||
|
||||
// filter
|
||||
ImGui::SameLine();
|
||||
this->filter.Draw("Filter", -50.f);
|
||||
|
||||
// log area
|
||||
ImGui::Separator();
|
||||
ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
// iterate log data
|
||||
this->log_data_m.lock();
|
||||
for (auto &data : log_data) {
|
||||
|
||||
// ignore empty lines and check filter
|
||||
if (data.first != "\r\n" && this->filter.PassFilter(data.first.c_str())) {
|
||||
|
||||
// decide on color
|
||||
ImVec4 col(1.f, 1.f, 1.f, 1.f);
|
||||
switch (data.second) {
|
||||
case logger::GREY:
|
||||
col = ImVec4(0.6f, 0.6f, 0.6f, 1.f);
|
||||
break;
|
||||
case logger::YELLOW:
|
||||
col = ImVec4(1.f, 1.f, 0.f, 1.f);
|
||||
break;
|
||||
case logger::RED:
|
||||
col = ImVec4(1.f, 0.f, 0.f, 1.f);
|
||||
break;
|
||||
case logger::DEFAULT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// draw text
|
||||
ImGui::TextColored(col, "%s", data.first.c_str());
|
||||
}
|
||||
}
|
||||
this->log_data_m.unlock();
|
||||
|
||||
// automatic scrolling to bottom
|
||||
if (scroll_to_bottom) {
|
||||
scroll_to_bottom = false;
|
||||
ImGui::SetScrollHereY(1.f);
|
||||
}
|
||||
|
||||
// end log area
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
bool Log::log_hook(void *user, const std::string &data, logger::Style style, std::string &out) {
|
||||
|
||||
// get reference from user pointer
|
||||
auto This = reinterpret_cast<Log *>(user);
|
||||
|
||||
// copy log data
|
||||
This->log_data_m.lock();
|
||||
This->log_data.emplace_back(data, style);
|
||||
This->log_data_m.unlock();
|
||||
|
||||
// autoscroll
|
||||
if (This->autoscroll) {
|
||||
This->scroll_to_bottom = true;
|
||||
}
|
||||
|
||||
// don't replace log data
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#include "log.h"
|
||||
#include "util/utils.h"
|
||||
#include "util/fileutils.h"
|
||||
#include "games/io.h"
|
||||
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
Log::Log(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "Log";
|
||||
this->toggle_button = games::OverlayButtons::ToggleLog;
|
||||
this->init_size = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x * 0.8f,
|
||||
ImGui::GetIO().DisplaySize.y * 0.8f);
|
||||
this->size_min = ImVec2(250, 200);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
|
||||
// read existing contents from file
|
||||
if (LOG_FILE_PATH.length() > 0) {
|
||||
auto contents = fileutils::text_read(LOG_FILE_PATH);
|
||||
if (contents.length() > 0) {
|
||||
this->log_hook(this, contents, logger::Style::DEFAULT, contents);
|
||||
}
|
||||
}
|
||||
|
||||
// add log hook
|
||||
logger::hook_add(&log_hook, this);
|
||||
}
|
||||
|
||||
Log::~Log() {
|
||||
|
||||
// remove log hook
|
||||
logger::hook_remove(&log_hook, this);
|
||||
}
|
||||
|
||||
void Log::clear() {
|
||||
|
||||
// lock and clear the data vector
|
||||
std::lock_guard<std::mutex> lock(this->log_data_m);
|
||||
this->log_data.clear();
|
||||
}
|
||||
|
||||
void Log::build_content() {
|
||||
|
||||
// clear button
|
||||
if (ImGui::Button("Clear")) {
|
||||
this->clear();
|
||||
}
|
||||
|
||||
// autoscroll option
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Autoscroll", &this->autoscroll);
|
||||
|
||||
// filter
|
||||
ImGui::SameLine();
|
||||
this->filter.Draw("Filter", -50.f);
|
||||
|
||||
// log area
|
||||
ImGui::Separator();
|
||||
ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
// iterate log data
|
||||
this->log_data_m.lock();
|
||||
for (auto &data : log_data) {
|
||||
|
||||
// ignore empty lines and check filter
|
||||
if (data.first != "\r\n" && this->filter.PassFilter(data.first.c_str())) {
|
||||
|
||||
// decide on color
|
||||
ImVec4 col(1.f, 1.f, 1.f, 1.f);
|
||||
switch (data.second) {
|
||||
case logger::GREY:
|
||||
col = ImVec4(0.6f, 0.6f, 0.6f, 1.f);
|
||||
break;
|
||||
case logger::YELLOW:
|
||||
col = ImVec4(1.f, 1.f, 0.f, 1.f);
|
||||
break;
|
||||
case logger::RED:
|
||||
col = ImVec4(1.f, 0.f, 0.f, 1.f);
|
||||
break;
|
||||
case logger::DEFAULT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// draw text
|
||||
ImGui::TextColored(col, "%s", data.first.c_str());
|
||||
}
|
||||
}
|
||||
this->log_data_m.unlock();
|
||||
|
||||
// automatic scrolling to bottom
|
||||
if (scroll_to_bottom) {
|
||||
scroll_to_bottom = false;
|
||||
ImGui::SetScrollHereY(1.f);
|
||||
}
|
||||
|
||||
// end log area
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
bool Log::log_hook(void *user, const std::string &data, logger::Style style, std::string &out) {
|
||||
|
||||
// get reference from user pointer
|
||||
auto This = reinterpret_cast<Log *>(user);
|
||||
|
||||
// copy log data
|
||||
This->log_data_m.lock();
|
||||
This->log_data.emplace_back(data, style);
|
||||
This->log_data_m.unlock();
|
||||
|
||||
// autoscroll
|
||||
if (This->autoscroll) {
|
||||
This->scroll_to_bottom = true;
|
||||
}
|
||||
|
||||
// don't replace log data
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+28
-28
@@ -1,28 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include "overlay/window.h"
|
||||
#include "launcher/logger.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class Log : public Window {
|
||||
private:
|
||||
|
||||
std::vector<std::pair<std::string, logger::Style>> log_data;
|
||||
std::mutex log_data_m;
|
||||
ImGuiTextFilter filter;
|
||||
bool scroll_to_bottom = true;
|
||||
bool autoscroll = true;
|
||||
|
||||
void clear();
|
||||
|
||||
public:
|
||||
|
||||
Log(SpiceOverlay *overlay);
|
||||
~Log() override;
|
||||
|
||||
void build_content() override;
|
||||
static bool log_hook(void *user, const std::string &data, logger::Style style, std::string &out);
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include "overlay/window.h"
|
||||
#include "launcher/logger.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class Log : public Window {
|
||||
private:
|
||||
|
||||
std::vector<std::pair<std::string, logger::Style>> log_data;
|
||||
std::mutex log_data_m;
|
||||
ImGuiTextFilter filter;
|
||||
bool scroll_to_bottom = true;
|
||||
bool autoscroll = true;
|
||||
|
||||
void clear();
|
||||
|
||||
public:
|
||||
|
||||
Log(SpiceOverlay *overlay);
|
||||
~Log() override;
|
||||
|
||||
void build_content() override;
|
||||
static bool log_hook(void *user, const std::string &data, logger::Style style, std::string &out);
|
||||
};
|
||||
}
|
||||
|
||||
+129
-129
@@ -1,129 +1,129 @@
|
||||
#include "midi.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
static std::string midi_cmd_str(uint8_t cmd) {
|
||||
const char *name = "UNKNOWN";
|
||||
switch (cmd) {
|
||||
case 0x8:
|
||||
name = "NOTE OFF";
|
||||
break;
|
||||
case 0x9:
|
||||
name = "NOTE ON";
|
||||
break;
|
||||
case 0xA:
|
||||
name = "POLY.PRESS.";
|
||||
break;
|
||||
case 0xB:
|
||||
name = "CTRL CHANGE";
|
||||
break;
|
||||
case 0xC:
|
||||
name = "PRG CHANGE";
|
||||
break;
|
||||
case 0xD:
|
||||
name = "CHAN.PRESS.";
|
||||
break;
|
||||
case 0xE:
|
||||
name = "PITCH BEND";
|
||||
break;
|
||||
case 0xF:
|
||||
name = "SYSTEM";
|
||||
break;
|
||||
}
|
||||
return fmt::format("{} (0x{:2X})", name, cmd);
|
||||
}
|
||||
|
||||
MIDIWindow::MIDIWindow(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "MIDI Control";
|
||||
this->init_size = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x * 0.8f,
|
||||
ImGui::GetIO().DisplaySize.y * 0.8f);
|
||||
this->size_min = ImVec2(250, 200);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->active = true;
|
||||
|
||||
// add hook for receiving midi messages
|
||||
RI_MGR->add_callback_midi(this, MIDIWindow::midi_hook);
|
||||
}
|
||||
|
||||
MIDIWindow::~MIDIWindow() {
|
||||
RI_MGR->remove_callback_midi(this, MIDIWindow::midi_hook);
|
||||
}
|
||||
|
||||
void MIDIWindow::build_content() {
|
||||
|
||||
// reset button
|
||||
if (ImGui::Button("Reset")) {
|
||||
this->midi_data.clear();
|
||||
}
|
||||
|
||||
// autoscroll checkbox
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Autoscroll", &this->autoscroll);
|
||||
|
||||
// log section
|
||||
ImGui::BeginChild("MidiLog", ImVec2(), false);
|
||||
|
||||
// header
|
||||
ImGui::Columns(5, "MidiLogColumns", true);
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Device"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Command"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Channel"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Data 1"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Data 2"); ImGui::NextColumn();
|
||||
|
||||
// data
|
||||
ImGui::Separator();
|
||||
for (auto &data : this->midi_data) {
|
||||
|
||||
// set color
|
||||
srand(data.device->id * 2111);
|
||||
float hue = ((float) rand()) / ((float) RAND_MAX);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImColor::HSV(hue, 0.8f, 0.8f, 1.f).Value);
|
||||
|
||||
// data cells
|
||||
ImGui::Text("%i: %s", (int) data.device->id, data.device->desc.c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("%s", midi_cmd_str(data.cmd).c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("0x%02X - %i", data.ch, data.ch);
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("0x%02X", data.b1);
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("0x%02X", data.b2);
|
||||
ImGui::NextColumn();
|
||||
|
||||
// clean up
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
// autoscroll
|
||||
if (this->autoscroll_apply) {
|
||||
this->autoscroll_apply = false;
|
||||
ImGui::SetScrollHereY(1.f);
|
||||
}
|
||||
|
||||
// clean up section
|
||||
ImGui::Columns();
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void MIDIWindow::midi_hook(void *user, rawinput::Device *device,
|
||||
uint8_t cmd, uint8_t ch, uint8_t b1, uint8_t b2) {
|
||||
auto This = (MIDIWindow*) user;
|
||||
This->midi_data.emplace_back(MIDIData {
|
||||
.device = device,
|
||||
.cmd = cmd,
|
||||
.ch = ch,
|
||||
.b1 = b1,
|
||||
.b2 = b2,
|
||||
});
|
||||
if (This->autoscroll) {
|
||||
This->autoscroll_apply = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "midi.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
static std::string midi_cmd_str(uint8_t cmd) {
|
||||
const char *name = "UNKNOWN";
|
||||
switch (cmd) {
|
||||
case 0x8:
|
||||
name = "NOTE OFF";
|
||||
break;
|
||||
case 0x9:
|
||||
name = "NOTE ON";
|
||||
break;
|
||||
case 0xA:
|
||||
name = "POLY.PRESS.";
|
||||
break;
|
||||
case 0xB:
|
||||
name = "CTRL CHANGE";
|
||||
break;
|
||||
case 0xC:
|
||||
name = "PRG CHANGE";
|
||||
break;
|
||||
case 0xD:
|
||||
name = "CHAN.PRESS.";
|
||||
break;
|
||||
case 0xE:
|
||||
name = "PITCH BEND";
|
||||
break;
|
||||
case 0xF:
|
||||
name = "SYSTEM";
|
||||
break;
|
||||
}
|
||||
return fmt::format("{} (0x{:2X})", name, cmd);
|
||||
}
|
||||
|
||||
MIDIWindow::MIDIWindow(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "MIDI Control";
|
||||
this->init_size = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x * 0.8f,
|
||||
ImGui::GetIO().DisplaySize.y * 0.8f);
|
||||
this->size_min = ImVec2(250, 200);
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->active = true;
|
||||
|
||||
// add hook for receiving midi messages
|
||||
RI_MGR->add_callback_midi(this, MIDIWindow::midi_hook);
|
||||
}
|
||||
|
||||
MIDIWindow::~MIDIWindow() {
|
||||
RI_MGR->remove_callback_midi(this, MIDIWindow::midi_hook);
|
||||
}
|
||||
|
||||
void MIDIWindow::build_content() {
|
||||
|
||||
// reset button
|
||||
if (ImGui::Button("Reset")) {
|
||||
this->midi_data.clear();
|
||||
}
|
||||
|
||||
// autoscroll checkbox
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Autoscroll", &this->autoscroll);
|
||||
|
||||
// log section
|
||||
ImGui::BeginChild("MidiLog", ImVec2(), false);
|
||||
|
||||
// header
|
||||
ImGui::Columns(5, "MidiLogColumns", true);
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Device"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Command"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Channel"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Data 1"); ImGui::NextColumn();
|
||||
ImGui::TextColored(ImVec4(1.f, 0.7f, 0, 1), "Data 2"); ImGui::NextColumn();
|
||||
|
||||
// data
|
||||
ImGui::Separator();
|
||||
for (auto &data : this->midi_data) {
|
||||
|
||||
// set color
|
||||
srand(data.device->id * 2111);
|
||||
float hue = ((float) rand()) / ((float) RAND_MAX);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImColor::HSV(hue, 0.8f, 0.8f, 1.f).Value);
|
||||
|
||||
// data cells
|
||||
ImGui::Text("%i: %s", (int) data.device->id, data.device->desc.c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("%s", midi_cmd_str(data.cmd).c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("0x%02X - %i", data.ch, data.ch);
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("0x%02X", data.b1);
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("0x%02X", data.b2);
|
||||
ImGui::NextColumn();
|
||||
|
||||
// clean up
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
// autoscroll
|
||||
if (this->autoscroll_apply) {
|
||||
this->autoscroll_apply = false;
|
||||
ImGui::SetScrollHereY(1.f);
|
||||
}
|
||||
|
||||
// clean up section
|
||||
ImGui::Columns();
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void MIDIWindow::midi_hook(void *user, rawinput::Device *device,
|
||||
uint8_t cmd, uint8_t ch, uint8_t b1, uint8_t b2) {
|
||||
auto This = (MIDIWindow*) user;
|
||||
This->midi_data.emplace_back(MIDIData {
|
||||
.device = device,
|
||||
.cmd = cmd,
|
||||
.ch = ch,
|
||||
.b1 = b1,
|
||||
.b2 = b2,
|
||||
});
|
||||
if (This->autoscroll) {
|
||||
This->autoscroll_apply = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-30
@@ -1,30 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
struct MIDIData {
|
||||
rawinput::Device *device;
|
||||
uint8_t cmd, ch;
|
||||
uint8_t b1, b2;
|
||||
};
|
||||
|
||||
class MIDIWindow : public Window {
|
||||
public:
|
||||
|
||||
MIDIWindow(SpiceOverlay *overlay);
|
||||
~MIDIWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
static void midi_hook(void *user, rawinput::Device *device,
|
||||
uint8_t cmd, uint8_t ch, uint8_t b1, uint8_t b2);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<MIDIData> midi_data;
|
||||
bool autoscroll = true;
|
||||
bool autoscroll_apply = false;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "rawinput/rawinput.h"
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
struct MIDIData {
|
||||
rawinput::Device *device;
|
||||
uint8_t cmd, ch;
|
||||
uint8_t b1, b2;
|
||||
};
|
||||
|
||||
class MIDIWindow : public Window {
|
||||
public:
|
||||
|
||||
MIDIWindow(SpiceOverlay *overlay);
|
||||
~MIDIWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
static void midi_hook(void *user, rawinput::Device *device,
|
||||
uint8_t cmd, uint8_t ch, uint8_t b1, uint8_t b2);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<MIDIData> midi_data;
|
||||
bool autoscroll = true;
|
||||
bool autoscroll_apply = false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,81 +1,81 @@
|
||||
#include <games/io.h>
|
||||
|
||||
#include "screen_resize.h"
|
||||
#include "cfg/screen_resize.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
ScreenResize::ScreenResize(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "Screen Resize";
|
||||
this->flags = ImGuiWindowFlags_AlwaysAutoResize;
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->toggle_button = games::OverlayButtons::ToggleScreenResize;
|
||||
this->toggle_screen_resize = games::OverlayButtons::ScreenResize;
|
||||
}
|
||||
|
||||
ScreenResize::~ScreenResize() {
|
||||
}
|
||||
|
||||
void ScreenResize::build_content() {
|
||||
|
||||
// enable checkbox
|
||||
ImGui::Checkbox("Enable Screen Resize", &cfg::SCREENRESIZE->enable_screen_resize);
|
||||
if (cfg::SCREENRESIZE->enable_screen_resize) {
|
||||
|
||||
// general settings
|
||||
ImGui::Checkbox("Enable Linear Filter", &cfg::SCREENRESIZE->enable_linear_filter);
|
||||
ImGui::InputInt("X Offset", &cfg::SCREENRESIZE->offset_x);
|
||||
ImGui::InputInt("Y Offset", &cfg::SCREENRESIZE->offset_y);
|
||||
|
||||
// aspect ratio
|
||||
ImGui::Checkbox("Keep Aspect Ratio", &cfg::SCREENRESIZE->keep_aspect_ratio);
|
||||
if (cfg::SCREENRESIZE->keep_aspect_ratio) {
|
||||
if (ImGui::SliderFloat("Scale", &cfg::SCREENRESIZE->scale_x, 0.65f, 2.0f)) {
|
||||
cfg::SCREENRESIZE->scale_y = cfg::SCREENRESIZE->scale_x;
|
||||
}
|
||||
} else {
|
||||
ImGui::SliderFloat("Width Scale", &cfg::SCREENRESIZE->scale_x, 0.65f, 2.0f);
|
||||
ImGui::SliderFloat("Height Scale", &cfg::SCREENRESIZE->scale_y, 0.65f, 2.0f);
|
||||
}
|
||||
|
||||
// reset button
|
||||
if (ImGui::Button("Reset")) {
|
||||
cfg::SCREENRESIZE->offset_x = 0;
|
||||
cfg::SCREENRESIZE->offset_y = 0;
|
||||
cfg::SCREENRESIZE->scale_x = 1;
|
||||
cfg::SCREENRESIZE->scale_y = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// load button
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Load")) {
|
||||
cfg::SCREENRESIZE->config_load();
|
||||
}
|
||||
|
||||
// save button
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save")) {
|
||||
cfg::SCREENRESIZE->config_save();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenResize::update() {
|
||||
Window::update();
|
||||
if (this->toggle_screen_resize != ~0u) {
|
||||
auto overlay_buttons = games::get_buttons_overlay(eamuse_get_game());
|
||||
bool toggle_screen_resize_new = overlay_buttons
|
||||
&& this->overlay->hotkeys_triggered()
|
||||
&& GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(this->toggle_screen_resize));
|
||||
|
||||
if (toggle_screen_resize_new && !this->toggle_screen_resize_state) {
|
||||
cfg::SCREENRESIZE->enable_screen_resize = !cfg::SCREENRESIZE->enable_screen_resize;
|
||||
}
|
||||
this->toggle_screen_resize_state = toggle_screen_resize_new;
|
||||
}
|
||||
}
|
||||
}
|
||||
#include <games/io.h>
|
||||
|
||||
#include "screen_resize.h"
|
||||
#include "cfg/screen_resize.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "util/logging.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
ScreenResize::ScreenResize(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "Screen Resize";
|
||||
this->flags = ImGuiWindowFlags_AlwaysAutoResize;
|
||||
this->init_pos = ImVec2(
|
||||
ImGui::GetIO().DisplaySize.x / 2 - this->init_size.x / 2,
|
||||
ImGui::GetIO().DisplaySize.y / 2 - this->init_size.y / 2);
|
||||
this->toggle_button = games::OverlayButtons::ToggleScreenResize;
|
||||
this->toggle_screen_resize = games::OverlayButtons::ScreenResize;
|
||||
}
|
||||
|
||||
ScreenResize::~ScreenResize() {
|
||||
}
|
||||
|
||||
void ScreenResize::build_content() {
|
||||
|
||||
// enable checkbox
|
||||
ImGui::Checkbox("Enable Screen Resize", &cfg::SCREENRESIZE->enable_screen_resize);
|
||||
if (cfg::SCREENRESIZE->enable_screen_resize) {
|
||||
|
||||
// general settings
|
||||
ImGui::Checkbox("Enable Linear Filter", &cfg::SCREENRESIZE->enable_linear_filter);
|
||||
ImGui::InputInt("X Offset", &cfg::SCREENRESIZE->offset_x);
|
||||
ImGui::InputInt("Y Offset", &cfg::SCREENRESIZE->offset_y);
|
||||
|
||||
// aspect ratio
|
||||
ImGui::Checkbox("Keep Aspect Ratio", &cfg::SCREENRESIZE->keep_aspect_ratio);
|
||||
if (cfg::SCREENRESIZE->keep_aspect_ratio) {
|
||||
if (ImGui::SliderFloat("Scale", &cfg::SCREENRESIZE->scale_x, 0.65f, 2.0f)) {
|
||||
cfg::SCREENRESIZE->scale_y = cfg::SCREENRESIZE->scale_x;
|
||||
}
|
||||
} else {
|
||||
ImGui::SliderFloat("Width Scale", &cfg::SCREENRESIZE->scale_x, 0.65f, 2.0f);
|
||||
ImGui::SliderFloat("Height Scale", &cfg::SCREENRESIZE->scale_y, 0.65f, 2.0f);
|
||||
}
|
||||
|
||||
// reset button
|
||||
if (ImGui::Button("Reset")) {
|
||||
cfg::SCREENRESIZE->offset_x = 0;
|
||||
cfg::SCREENRESIZE->offset_y = 0;
|
||||
cfg::SCREENRESIZE->scale_x = 1;
|
||||
cfg::SCREENRESIZE->scale_y = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// load button
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Load")) {
|
||||
cfg::SCREENRESIZE->config_load();
|
||||
}
|
||||
|
||||
// save button
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save")) {
|
||||
cfg::SCREENRESIZE->config_save();
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenResize::update() {
|
||||
Window::update();
|
||||
if (this->toggle_screen_resize != ~0u) {
|
||||
auto overlay_buttons = games::get_buttons_overlay(eamuse_get_game());
|
||||
bool toggle_screen_resize_new = overlay_buttons
|
||||
&& this->overlay->hotkeys_triggered()
|
||||
&& GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(this->toggle_screen_resize));
|
||||
|
||||
if (toggle_screen_resize_new && !this->toggle_screen_resize_state) {
|
||||
cfg::SCREENRESIZE->enable_screen_resize = !cfg::SCREENRESIZE->enable_screen_resize;
|
||||
}
|
||||
this->toggle_screen_resize_state = toggle_screen_resize_new;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class ScreenResize : public Window {
|
||||
public:
|
||||
ScreenResize(SpiceOverlay *overlay);
|
||||
~ScreenResize() override;
|
||||
|
||||
void build_content() override;
|
||||
void update();
|
||||
|
||||
private:
|
||||
size_t toggle_screen_resize = ~0u;
|
||||
bool toggle_screen_resize_state = false;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class ScreenResize : public Window {
|
||||
public:
|
||||
ScreenResize(SpiceOverlay *overlay);
|
||||
~ScreenResize() override;
|
||||
|
||||
void build_content() override;
|
||||
void update();
|
||||
|
||||
private:
|
||||
size_t toggle_screen_resize = ~0u;
|
||||
bool toggle_screen_resize_state = false;
|
||||
};
|
||||
}
|
||||
|
||||
+218
-218
@@ -1,218 +1,218 @@
|
||||
#include "vr.h"
|
||||
#include "misc/vrutil.h"
|
||||
#include "util/logging.h"
|
||||
#include "games/io.h"
|
||||
#include "games/drs/drs.h"
|
||||
#include "avs/game.h"
|
||||
#include "overlay/imgui/extensions.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
VRWindow::VRWindow(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "VR";
|
||||
this->flags = ImGuiWindowFlags_None;
|
||||
this->toggle_button = games::OverlayButtons::ToggleVRControl;
|
||||
this->init_size = ImVec2(500, 800);
|
||||
this->size_min = ImVec2(250, 200);
|
||||
}
|
||||
|
||||
VRWindow::~VRWindow() {
|
||||
}
|
||||
|
||||
void VRWindow::build_content() {
|
||||
ImGui::BeginTabBar("VRTabBar");
|
||||
if (ImGui::BeginTabItem("Info")) {
|
||||
build_info();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (avs::game::is_model("REC")) {
|
||||
if (ImGui::BeginTabItem("Dancefloor")) {
|
||||
build_dancefloor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VRWindow::build_info() {
|
||||
|
||||
// status
|
||||
auto status = vrutil::STATUS;
|
||||
switch (status) {
|
||||
case vrutil::VRStatus::Disabled:
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.4f, 0.4f, 0.4f, 1.f),
|
||||
"Disabled");
|
||||
if (ImGui::Button("Start")) {
|
||||
vrutil::init();
|
||||
if (avs::game::is_model("REC")) {
|
||||
games::drs::start_vr();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case vrutil::VRStatus::Error:
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.8f, 0.1f, 0.1f, 1.f),
|
||||
"Error");
|
||||
if (ImGui::Button("Restart")) {
|
||||
vrutil::shutdown();
|
||||
vrutil::init();
|
||||
}
|
||||
break;
|
||||
case vrutil::VRStatus::Running:
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.1f, 0.8f, 0.1f, 1.f),
|
||||
"Running");
|
||||
if (ImGui::Button("Stop")) {
|
||||
vrutil::shutdown();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// rescan
|
||||
if (ImGui::Button("Rescan Devices")) {
|
||||
vrutil::scan(true);
|
||||
}
|
||||
|
||||
// data table header
|
||||
ImGui::Columns(2);
|
||||
ImGui::Text("Device");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Position");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Separator();
|
||||
|
||||
// HMD/Left/Right data
|
||||
vr::TrackedDevicePose_t hmd_pose, left_pose, right_pose;
|
||||
vr::VRControllerState_t left_state, right_state;
|
||||
vrutil::get_hmd_pose(&hmd_pose);
|
||||
vrutil::get_con_pose(vrutil::INDEX_LEFT, &left_pose, &left_state);
|
||||
vrutil::get_con_pose(vrutil::INDEX_RIGHT, &right_pose, &right_state);
|
||||
auto hmd_pos = vrutil::get_translation(hmd_pose.mDeviceToAbsoluteTracking);
|
||||
auto left_pos = vrutil::get_translation(left_pose.mDeviceToAbsoluteTracking);
|
||||
auto right_pos = vrutil::get_translation(right_pose.mDeviceToAbsoluteTracking);
|
||||
ImGui::Text("HMD");
|
||||
ImGui::NextColumn();
|
||||
ImGui::TextUnformatted(fmt::format(
|
||||
"X={:3f} Y={:3f} Z={:3f}",
|
||||
hmd_pos.x, hmd_pos.y, hmd_pos.z).c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Left");
|
||||
ImGui::NextColumn();
|
||||
ImGui::TextUnformatted(fmt::format(
|
||||
"X={:3f} Y={:3f} Z={:3f}",
|
||||
left_pos.x, left_pos.y, left_pos.z).c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Right");
|
||||
ImGui::NextColumn();
|
||||
ImGui::TextUnformatted(fmt::format(
|
||||
"X={:3f} Y={:3f} Z={:3f}",
|
||||
right_pos.x, right_pos.y, right_pos.z).c_str());
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
|
||||
void VRWindow::build_dancefloor() {
|
||||
ImGui::Separator();
|
||||
|
||||
// settings
|
||||
ImGui::DragFloat3("Scale", &games::drs::VR_SCALE[0], 0.1f);
|
||||
ImGui::DragFloat3("Offset", &games::drs::VR_OFFSET[0], 0.1f);
|
||||
ImGui::DragFloat("Rotation", &games::drs::VR_ROTATION, 0.5f);
|
||||
for (int i = 0; i < (int) std::size(games::drs::VR_FOOTS); ++i) {
|
||||
auto &foot = games::drs::VR_FOOTS[i];
|
||||
ImGui::Separator();
|
||||
ImGui::PushID(&foot);
|
||||
ImGui::Text("%s Foot", i == 0 ? "Left" : "Right");
|
||||
ImGui::InputInt("Device Index", (int*) &foot.index, 1, 1);
|
||||
ImGui::DragFloat("Length", &foot.length,
|
||||
0.005f, 0.001f, 1000.f);
|
||||
ImGui::DragFloat("Size Base", &foot.size_base,
|
||||
0.005f, 0.001f, 1000.f);
|
||||
ImGui::DragFloat("Size Scale", &foot.size_scale,
|
||||
0.005f, 0.001f, 1000.f);
|
||||
ImGui::DragFloat4("Rotation Quat", &foot.rotation.x, 0.001f, -1, 1);
|
||||
if (ImGui::Button("Calibrate")) {
|
||||
vr::TrackedDevicePose_t pose;
|
||||
vr::VRControllerState_t state;
|
||||
vrutil::get_con_pose(foot.get_index(), &pose, &state);
|
||||
foot.length = foot.height + 0.02f;
|
||||
auto pose_rot = vrutil::get_rotation(pose.mDeviceToAbsoluteTracking.m);
|
||||
foot.rotation = linalg::qmul(linalg::qinv(pose_rot),
|
||||
vrutil::get_rotation((float) M_PI * -0.5f, 0, 0));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::HelpMarker("Place the controller to the lower part of your leg "
|
||||
"and press this button to auto calibrate angle and length");
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// prepare view
|
||||
auto draw_list = ImGui::GetWindowDrawList();
|
||||
auto canvas_pos = ImGui::GetCursorScreenPos();
|
||||
auto canvas_size = ImGui::GetContentRegionAvail();
|
||||
float offset_x = canvas_size.x * 0.5f;
|
||||
float offset_y = canvas_size.y * 0.1f;
|
||||
float off_x = offset_x + canvas_pos.x;
|
||||
float off_y = offset_y + canvas_pos.y;
|
||||
float scale = std::min(canvas_size.x, canvas_size.y) / 60;
|
||||
|
||||
// axis
|
||||
draw_list->AddLine(
|
||||
ImVec2(canvas_pos.x, off_y),
|
||||
ImVec2(canvas_pos.x + canvas_size.x, off_y),
|
||||
ImColor(255, 0, 0, 128));
|
||||
draw_list->AddLine(
|
||||
ImVec2(off_x, canvas_pos.y),
|
||||
ImVec2(off_x, canvas_pos.y + canvas_size.y),
|
||||
ImColor(0, 255, 0, 128));
|
||||
|
||||
// tiles
|
||||
for (int x = 0; x < 38; x++) {
|
||||
for (int y = 0; y < 49; y++) {
|
||||
auto &led = games::drs::DRS_TAPELED[x + y * 38];
|
||||
ImColor color((int) led[0], (int) led[1], (int) led[2]);
|
||||
ImVec2 p1((x - 19) * scale + off_x, (y + 0) * scale + off_y);
|
||||
ImVec2 p2((x - 18) * scale + off_x, (y + 1) * scale + off_y);
|
||||
draw_list->AddRectFilled(p1, p2, color, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
// foots
|
||||
const float foot_box = 2.f * scale;
|
||||
for (auto &foot : games::drs::VR_FOOTS) {
|
||||
vr::TrackedDevicePose_t pose;
|
||||
vr::VRControllerState_t state;
|
||||
vrutil::get_con_pose(foot.get_index(), &pose, &state);
|
||||
if (pose.bPoseIsValid) {
|
||||
|
||||
// position
|
||||
auto pos = vrutil::get_translation(pose.mDeviceToAbsoluteTracking);
|
||||
pos = foot.to_world(pos);
|
||||
pos.x -= 19;
|
||||
pos *= scale;
|
||||
ImColor color(255, 0, 255);
|
||||
if (foot.event.type == games::drs::DRS_DOWN
|
||||
|| (foot.event.type == games::drs::DRS_MOVE)) {
|
||||
auto size_factor = foot.event.width / (foot.size_base + foot.size_scale);
|
||||
color = ImColor((int) (size_factor * 127) + 128, 0, 0);
|
||||
}
|
||||
ImVec2 p1(pos.x + off_x - foot_box * 0.5f,
|
||||
pos.y + off_y - foot_box * 0.5f);
|
||||
ImVec2 p2(pos.x + off_x + foot_box * 0.5f,
|
||||
pos.y + off_y + foot_box * 0.5f);
|
||||
draw_list->AddRectFilled(p1, p2, color, 0.f);
|
||||
|
||||
// direction
|
||||
auto direction = -linalg::qzdir(linalg::qmul(
|
||||
vrutil::get_rotation(pose.mDeviceToAbsoluteTracking.m),
|
||||
foot.rotation));
|
||||
direction = linalg::aliases::float3 {
|
||||
-direction.z, direction.x, direction.y
|
||||
};
|
||||
auto end = pos + direction * foot.length * scale;
|
||||
draw_list->AddLine(
|
||||
ImVec2(pos.x + off_x, pos.y + off_y),
|
||||
ImVec2(end.x + off_x, end.y + off_y),
|
||||
ImColor(0, 255, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "vr.h"
|
||||
#include "misc/vrutil.h"
|
||||
#include "util/logging.h"
|
||||
#include "games/io.h"
|
||||
#include "games/drs/drs.h"
|
||||
#include "avs/game.h"
|
||||
#include "overlay/imgui/extensions.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
VRWindow::VRWindow(SpiceOverlay *overlay) : Window(overlay) {
|
||||
this->title = "VR";
|
||||
this->flags = ImGuiWindowFlags_None;
|
||||
this->toggle_button = games::OverlayButtons::ToggleVRControl;
|
||||
this->init_size = ImVec2(500, 800);
|
||||
this->size_min = ImVec2(250, 200);
|
||||
}
|
||||
|
||||
VRWindow::~VRWindow() {
|
||||
}
|
||||
|
||||
void VRWindow::build_content() {
|
||||
ImGui::BeginTabBar("VRTabBar");
|
||||
if (ImGui::BeginTabItem("Info")) {
|
||||
build_info();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (avs::game::is_model("REC")) {
|
||||
if (ImGui::BeginTabItem("Dancefloor")) {
|
||||
build_dancefloor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VRWindow::build_info() {
|
||||
|
||||
// status
|
||||
auto status = vrutil::STATUS;
|
||||
switch (status) {
|
||||
case vrutil::VRStatus::Disabled:
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.4f, 0.4f, 0.4f, 1.f),
|
||||
"Disabled");
|
||||
if (ImGui::Button("Start")) {
|
||||
vrutil::init();
|
||||
if (avs::game::is_model("REC")) {
|
||||
games::drs::start_vr();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case vrutil::VRStatus::Error:
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.8f, 0.1f, 0.1f, 1.f),
|
||||
"Error");
|
||||
if (ImGui::Button("Restart")) {
|
||||
vrutil::shutdown();
|
||||
vrutil::init();
|
||||
}
|
||||
break;
|
||||
case vrutil::VRStatus::Running:
|
||||
ImGui::TextColored(
|
||||
ImVec4(0.1f, 0.8f, 0.1f, 1.f),
|
||||
"Running");
|
||||
if (ImGui::Button("Stop")) {
|
||||
vrutil::shutdown();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// rescan
|
||||
if (ImGui::Button("Rescan Devices")) {
|
||||
vrutil::scan(true);
|
||||
}
|
||||
|
||||
// data table header
|
||||
ImGui::Columns(2);
|
||||
ImGui::Text("Device");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Position");
|
||||
ImGui::NextColumn();
|
||||
ImGui::Separator();
|
||||
|
||||
// HMD/Left/Right data
|
||||
vr::TrackedDevicePose_t hmd_pose, left_pose, right_pose;
|
||||
vr::VRControllerState_t left_state, right_state;
|
||||
vrutil::get_hmd_pose(&hmd_pose);
|
||||
vrutil::get_con_pose(vrutil::INDEX_LEFT, &left_pose, &left_state);
|
||||
vrutil::get_con_pose(vrutil::INDEX_RIGHT, &right_pose, &right_state);
|
||||
auto hmd_pos = vrutil::get_translation(hmd_pose.mDeviceToAbsoluteTracking);
|
||||
auto left_pos = vrutil::get_translation(left_pose.mDeviceToAbsoluteTracking);
|
||||
auto right_pos = vrutil::get_translation(right_pose.mDeviceToAbsoluteTracking);
|
||||
ImGui::Text("HMD");
|
||||
ImGui::NextColumn();
|
||||
ImGui::TextUnformatted(fmt::format(
|
||||
"X={:3f} Y={:3f} Z={:3f}",
|
||||
hmd_pos.x, hmd_pos.y, hmd_pos.z).c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Left");
|
||||
ImGui::NextColumn();
|
||||
ImGui::TextUnformatted(fmt::format(
|
||||
"X={:3f} Y={:3f} Z={:3f}",
|
||||
left_pos.x, left_pos.y, left_pos.z).c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Right");
|
||||
ImGui::NextColumn();
|
||||
ImGui::TextUnformatted(fmt::format(
|
||||
"X={:3f} Y={:3f} Z={:3f}",
|
||||
right_pos.x, right_pos.y, right_pos.z).c_str());
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
|
||||
void VRWindow::build_dancefloor() {
|
||||
ImGui::Separator();
|
||||
|
||||
// settings
|
||||
ImGui::DragFloat3("Scale", &games::drs::VR_SCALE[0], 0.1f);
|
||||
ImGui::DragFloat3("Offset", &games::drs::VR_OFFSET[0], 0.1f);
|
||||
ImGui::DragFloat("Rotation", &games::drs::VR_ROTATION, 0.5f);
|
||||
for (int i = 0; i < (int) std::size(games::drs::VR_FOOTS); ++i) {
|
||||
auto &foot = games::drs::VR_FOOTS[i];
|
||||
ImGui::Separator();
|
||||
ImGui::PushID(&foot);
|
||||
ImGui::Text("%s Foot", i == 0 ? "Left" : "Right");
|
||||
ImGui::InputInt("Device Index", (int*) &foot.index, 1, 1);
|
||||
ImGui::DragFloat("Length", &foot.length,
|
||||
0.005f, 0.001f, 1000.f);
|
||||
ImGui::DragFloat("Size Base", &foot.size_base,
|
||||
0.005f, 0.001f, 1000.f);
|
||||
ImGui::DragFloat("Size Scale", &foot.size_scale,
|
||||
0.005f, 0.001f, 1000.f);
|
||||
ImGui::DragFloat4("Rotation Quat", &foot.rotation.x, 0.001f, -1, 1);
|
||||
if (ImGui::Button("Calibrate")) {
|
||||
vr::TrackedDevicePose_t pose;
|
||||
vr::VRControllerState_t state;
|
||||
vrutil::get_con_pose(foot.get_index(), &pose, &state);
|
||||
foot.length = foot.height + 0.02f;
|
||||
auto pose_rot = vrutil::get_rotation(pose.mDeviceToAbsoluteTracking.m);
|
||||
foot.rotation = linalg::qmul(linalg::qinv(pose_rot),
|
||||
vrutil::get_rotation((float) M_PI * -0.5f, 0, 0));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::HelpMarker("Place the controller to the lower part of your leg "
|
||||
"and press this button to auto calibrate angle and length");
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// prepare view
|
||||
auto draw_list = ImGui::GetWindowDrawList();
|
||||
auto canvas_pos = ImGui::GetCursorScreenPos();
|
||||
auto canvas_size = ImGui::GetContentRegionAvail();
|
||||
float offset_x = canvas_size.x * 0.5f;
|
||||
float offset_y = canvas_size.y * 0.1f;
|
||||
float off_x = offset_x + canvas_pos.x;
|
||||
float off_y = offset_y + canvas_pos.y;
|
||||
float scale = std::min(canvas_size.x, canvas_size.y) / 60;
|
||||
|
||||
// axis
|
||||
draw_list->AddLine(
|
||||
ImVec2(canvas_pos.x, off_y),
|
||||
ImVec2(canvas_pos.x + canvas_size.x, off_y),
|
||||
ImColor(255, 0, 0, 128));
|
||||
draw_list->AddLine(
|
||||
ImVec2(off_x, canvas_pos.y),
|
||||
ImVec2(off_x, canvas_pos.y + canvas_size.y),
|
||||
ImColor(0, 255, 0, 128));
|
||||
|
||||
// tiles
|
||||
for (int x = 0; x < 38; x++) {
|
||||
for (int y = 0; y < 49; y++) {
|
||||
auto &led = games::drs::DRS_TAPELED[x + y * 38];
|
||||
ImColor color((int) led[0], (int) led[1], (int) led[2]);
|
||||
ImVec2 p1((x - 19) * scale + off_x, (y + 0) * scale + off_y);
|
||||
ImVec2 p2((x - 18) * scale + off_x, (y + 1) * scale + off_y);
|
||||
draw_list->AddRectFilled(p1, p2, color, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
// foots
|
||||
const float foot_box = 2.f * scale;
|
||||
for (auto &foot : games::drs::VR_FOOTS) {
|
||||
vr::TrackedDevicePose_t pose;
|
||||
vr::VRControllerState_t state;
|
||||
vrutil::get_con_pose(foot.get_index(), &pose, &state);
|
||||
if (pose.bPoseIsValid) {
|
||||
|
||||
// position
|
||||
auto pos = vrutil::get_translation(pose.mDeviceToAbsoluteTracking);
|
||||
pos = foot.to_world(pos);
|
||||
pos.x -= 19;
|
||||
pos *= scale;
|
||||
ImColor color(255, 0, 255);
|
||||
if (foot.event.type == games::drs::DRS_DOWN
|
||||
|| (foot.event.type == games::drs::DRS_MOVE)) {
|
||||
auto size_factor = foot.event.width / (foot.size_base + foot.size_scale);
|
||||
color = ImColor((int) (size_factor * 127) + 128, 0, 0);
|
||||
}
|
||||
ImVec2 p1(pos.x + off_x - foot_box * 0.5f,
|
||||
pos.y + off_y - foot_box * 0.5f);
|
||||
ImVec2 p2(pos.x + off_x + foot_box * 0.5f,
|
||||
pos.y + off_y + foot_box * 0.5f);
|
||||
draw_list->AddRectFilled(p1, p2, color, 0.f);
|
||||
|
||||
// direction
|
||||
auto direction = -linalg::qzdir(linalg::qmul(
|
||||
vrutil::get_rotation(pose.mDeviceToAbsoluteTracking.m),
|
||||
foot.rotation));
|
||||
direction = linalg::aliases::float3 {
|
||||
-direction.z, direction.x, direction.y
|
||||
};
|
||||
auto end = pos + direction * foot.length * scale;
|
||||
draw_list->AddLine(
|
||||
ImVec2(pos.x + off_x, pos.y + off_y),
|
||||
ImVec2(end.x + off_x, end.y + off_y),
|
||||
ImColor(0, 255, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-17
@@ -1,17 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class VRWindow : public Window {
|
||||
public:
|
||||
|
||||
VRWindow(SpiceOverlay *overlay);
|
||||
~VRWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
void build_info();
|
||||
void build_dancefloor();
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class VRWindow : public Window {
|
||||
public:
|
||||
|
||||
VRWindow(SpiceOverlay *overlay);
|
||||
~VRWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
void build_info();
|
||||
void build_dancefloor();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class WndManagerWindow : public Window {
|
||||
public:
|
||||
|
||||
WndManagerWindow(SpiceOverlay *overlay);
|
||||
~WndManagerWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
|
||||
int window_current = -1;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include "overlay/window.h"
|
||||
|
||||
namespace overlay::windows {
|
||||
|
||||
class WndManagerWindow : public Window {
|
||||
public:
|
||||
|
||||
WndManagerWindow(SpiceOverlay *overlay);
|
||||
~WndManagerWindow() override;
|
||||
|
||||
void build_content() override;
|
||||
|
||||
private:
|
||||
|
||||
int window_current = -1;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user