mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-01 06:24:55 -07:00
144 lines
4.7 KiB
C++
144 lines
4.7 KiB
C++
#include "touch_debug.h"
|
|
|
|
#include <array>
|
|
#include <atomic>
|
|
#include <cstring>
|
|
#include <mutex>
|
|
|
|
#include "external/imgui/imgui.h"
|
|
#include "games/rb/rb.h"
|
|
#include "games/rb/touch_defs.h"
|
|
|
|
namespace games::rb {
|
|
|
|
struct TouchDebugState {
|
|
std::array<unsigned char, TOUCH_PACKET_SIZE> packet {};
|
|
bool is_landscape = false;
|
|
};
|
|
|
|
std::atomic_bool TOUCH_DEBUG_OVERLAY = false;
|
|
static std::atomic_bool TOUCH_ACTIVE = false;
|
|
static std::mutex TOUCH_DEBUG_STATE_M;
|
|
static TouchDebugState TOUCH_DEBUG_STATE;
|
|
|
|
static float touch_scale_factor() {
|
|
return TOUCH_SCALING / (float) TOUCH_SCALE_DEFAULT;
|
|
}
|
|
|
|
static void clear_touch_debug_state() {
|
|
std::lock_guard<std::mutex> lock(TOUCH_DEBUG_STATE_M);
|
|
TOUCH_DEBUG_STATE = {};
|
|
}
|
|
|
|
static TouchDebugState get_touch_debug_state() {
|
|
std::lock_guard<std::mutex> lock(TOUCH_DEBUG_STATE_M);
|
|
return TOUCH_DEBUG_STATE;
|
|
}
|
|
|
|
static bool packet_bit_active(
|
|
const std::array<unsigned char, TOUCH_PACKET_SIZE> &packet, int bit) {
|
|
return (packet[TOUCH_PACKET_DATA_OFFSET + bit / 8] & (1u << (bit % 8))) != 0;
|
|
}
|
|
|
|
static int sensor_center(int sensor, int sensor_count, int extent) {
|
|
return ((sensor * 2 + 1) * extent) / (sensor_count * 2);
|
|
}
|
|
|
|
static float sensor_span_position(int sensor, int sensor_count, int extent) {
|
|
return sensor * (extent - 1) / (float) (sensor_count - 1);
|
|
}
|
|
|
|
bool touch_debug_overlay_enabled() {
|
|
return TOUCH_DEBUG_OVERLAY && TOUCH_ACTIVE.load(std::memory_order_acquire);
|
|
}
|
|
|
|
void touch_draw_debug_overlay() {
|
|
if (!touch_debug_overlay_enabled()) {
|
|
return;
|
|
}
|
|
|
|
const auto &io = ImGui::GetIO();
|
|
int width = static_cast<int>(io.DisplaySize.x);
|
|
int height = static_cast<int>(io.DisplaySize.y);
|
|
if (width <= 0 || height <= 0) {
|
|
return;
|
|
}
|
|
|
|
const float scale_factor = touch_scale_factor();
|
|
const float left = width * (1.f - scale_factor) / 2.f;
|
|
const float top = height * (1.f - scale_factor) / 2.f;
|
|
const float right = width - left;
|
|
const float bottom = height - top;
|
|
|
|
TouchDebugState state = get_touch_debug_state();
|
|
ImDrawList *draw_list = ImGui::GetBackgroundDrawList();
|
|
auto draw_line = [&](float x1, float y1, float x2, float y2) {
|
|
draw_list->AddLine(
|
|
ImVec2(x1, y1), ImVec2(x2, y2),
|
|
IM_COL32(0, 255, 64, 255), 2.f);
|
|
};
|
|
|
|
// show the valid input area when touch scaling restricts it
|
|
if (TOUCH_SCALING != TOUCH_SCALE_DEFAULT) {
|
|
draw_list->AddRect(
|
|
ImVec2(left, top), ImVec2(right, bottom),
|
|
IM_COL32(255, 255, 255, 255), 0.f, 0, 2.f);
|
|
}
|
|
|
|
// spread the usable X sensors 2..45 from edge to edge
|
|
for (int sensor = X_SENSOR_FIRST_ACTIVE; sensor <= X_SENSOR_LAST_ACTIVE; sensor++) {
|
|
if (!packet_bit_active(state.packet, X_SENSOR_FIRST_BIT + sensor)) {
|
|
continue;
|
|
}
|
|
|
|
float position = sensor_span_position(
|
|
sensor - X_SENSOR_FIRST_ACTIVE, X_SENSOR_ACTIVE_COUNT,
|
|
state.is_landscape ? height : width);
|
|
if (state.is_landscape) {
|
|
float y = top + position * scale_factor;
|
|
draw_line(left, y, right, y);
|
|
} else {
|
|
float x = left + position * scale_factor;
|
|
draw_line(x, top, x, bottom);
|
|
}
|
|
}
|
|
|
|
for (int sensor = 0; sensor < Y_SENSOR_COUNT; sensor++) {
|
|
if (!packet_bit_active(state.packet, Y_SENSOR_FIRST_BIT - sensor)) {
|
|
continue;
|
|
}
|
|
|
|
int position = sensor_center(
|
|
sensor, Y_SENSOR_COUNT,
|
|
state.is_landscape ? width : height);
|
|
if (state.is_landscape) {
|
|
float x = right - position * scale_factor;
|
|
draw_line(x, top, x, bottom);
|
|
} else {
|
|
float y = top + position * scale_factor;
|
|
draw_line(left, y, right, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
void touch_debug_attach() {
|
|
clear_touch_debug_state();
|
|
TOUCH_ACTIVE.store(true, std::memory_order_release);
|
|
}
|
|
|
|
void touch_debug_detach() {
|
|
TOUCH_ACTIVE.store(false, std::memory_order_release);
|
|
clear_touch_debug_state();
|
|
}
|
|
|
|
void touch_debug_publish(const unsigned char *data, bool is_landscape) {
|
|
if (!TOUCH_DEBUG_OVERLAY) {
|
|
return;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(TOUCH_DEBUG_STATE_M);
|
|
memcpy(TOUCH_DEBUG_STATE.packet.data(), data, TOUCH_PACKET_SIZE);
|
|
TOUCH_DEBUG_STATE.is_landscape = is_landscape;
|
|
}
|
|
}
|