mirror of
https://github.com/dualshock-tools/dualshock-tools.github.io.git
synced 2026-03-01 11:19:54 +03:00
Allow finetuning of analog sticks using the controller's buttons
This commit is contained in:
committed by
dualshock-tools
parent
9bb9f2f082
commit
71633d7718
220
core.js
220
core.js
@@ -17,10 +17,17 @@ var gj = 0;
|
||||
var gu = 0;
|
||||
|
||||
// DS5 finetuning
|
||||
var finetune_original_data = []
|
||||
var last_written_finetune_data = []
|
||||
var finetune_visible = false
|
||||
var on_finetune_updating = false
|
||||
let finetune_original_data = []
|
||||
let last_written_finetune_data = []
|
||||
let finetune_visible = false
|
||||
let on_finetune_updating = false
|
||||
|
||||
// Active stick tracking for finetune modal
|
||||
let active_stick = 'left' // 'left' or 'right'
|
||||
|
||||
// Continuous D-pad adjustment tracking
|
||||
let dpad_adjustment_interval = null
|
||||
let dpad_adjustment_timeout = null
|
||||
|
||||
// Global object to keep track of button states
|
||||
const ds_button_states = {
|
||||
@@ -1255,7 +1262,7 @@ async function ds5_finetune() {
|
||||
finetune_original_data = data
|
||||
finetune_visible = true
|
||||
|
||||
refresh_finetune()
|
||||
refresh_finetune_sticks();
|
||||
}
|
||||
|
||||
async function ds5_get_inmemory_module_data() {
|
||||
@@ -1314,9 +1321,7 @@ async function write_finetune_data(data) {
|
||||
await device.sendFeatureReport(0x80, alloc_req(0x80, pkg))
|
||||
}
|
||||
|
||||
function refresh_finetune() {
|
||||
if (!finetune_visible)
|
||||
return;
|
||||
function refresh_finetune_sticks() {
|
||||
if (on_finetune_updating)
|
||||
return;
|
||||
|
||||
@@ -1328,6 +1333,47 @@ function ds5_finetune_update_all() {
|
||||
const { left, right } = ds_button_states.sticks;
|
||||
ds5_finetune_update("finetuneStickCanvasL", left.x, left.y);
|
||||
ds5_finetune_update("finetuneStickCanvasR", right.x, right.y);
|
||||
|
||||
// Highlight the active finetune input based on stick position
|
||||
highlight_active_finetune_input();
|
||||
}
|
||||
|
||||
function highlight_active_finetune_input() {
|
||||
const sticks = ds_button_states.sticks;
|
||||
const currentStick = sticks[active_stick];
|
||||
const deadzone = 0.3;
|
||||
|
||||
// Clear highlights from all inputs first
|
||||
const inputs = ["LL", "LT", "RL", "RT", "LR", "LB", "RR", "RB"];
|
||||
inputs.forEach(suffix => {
|
||||
$(`#finetune${suffix}`).removeClass("border-primary border-2");
|
||||
});
|
||||
|
||||
// Clear label highlights
|
||||
const labelIds = ["Lx-lbl", "Ly-lbl", "Rx-lbl", "Ry-lbl"];
|
||||
labelIds.forEach(suffix => {
|
||||
$(`#finetuneStickCanvas${suffix}`).removeClass("text-primary");
|
||||
});
|
||||
|
||||
// Only highlight if stick is moved significantly from center
|
||||
if (Math.abs(currentStick.x) >= deadzone || Math.abs(currentStick.y) >= deadzone) {
|
||||
const quadrant = get_stick_quadrant(currentStick.x, currentStick.y);
|
||||
const inputSuffix = get_finetune_input_suffix_for_quadrant(active_stick, quadrant);
|
||||
if (inputSuffix) {
|
||||
// Highllight the corresponding finetune input box
|
||||
$(`#finetune${inputSuffix}`).addClass("border-primary border-2");
|
||||
|
||||
// Also highlight the corresponding LX/LY label to observe
|
||||
let labelId = "";
|
||||
if (active_stick === 'left') {
|
||||
labelId = `finetuneStickCanvas${quadrant === 'left' || quadrant === 'right' ? "Lx" : "Ly"}-lbl`;
|
||||
} else { // right
|
||||
labelId = `finetuneStickCanvas${quadrant === 'left' || quadrant === 'right' ? "Rx" : "Ry"}-lbl`;
|
||||
}
|
||||
|
||||
$(`#${labelId}`).addClass("text-primary");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ds5_finetune_update(name, plx, ply) {
|
||||
@@ -1350,10 +1396,150 @@ function ds5_finetune_update(name, plx, ply) {
|
||||
function finetune_close() {
|
||||
$("#finetuneModal").modal("hide");
|
||||
finetune_visible = false
|
||||
stop_continuous_dpad_adjustment();
|
||||
|
||||
finetune_original_data = []
|
||||
}
|
||||
|
||||
function set_stick_to_finetune(stick) {
|
||||
// Stop any continuous adjustments when switching sticks
|
||||
stop_continuous_dpad_adjustment();
|
||||
|
||||
active_stick = stick;
|
||||
|
||||
// Remove active class from both cards
|
||||
$("#left-stick-card").removeClass("stick-card-active");
|
||||
$("#right-stick-card").removeClass("stick-card-active");
|
||||
|
||||
// Add active class to the selected card
|
||||
if (stick === 'left') {
|
||||
$("#left-stick-card").addClass("stick-card-active");
|
||||
} else {
|
||||
$("#right-stick-card").addClass("stick-card-active");
|
||||
}
|
||||
}
|
||||
|
||||
function handle_finetune_stick_switching(changes) {
|
||||
if (changes.l1) {
|
||||
set_stick_to_finetune('left');
|
||||
} else if (changes.r1) {
|
||||
set_stick_to_finetune('right');
|
||||
}
|
||||
}
|
||||
|
||||
function get_stick_quadrant(x, y) {
|
||||
// Determine which quadrant the stick is in based on x,y coordinates
|
||||
// x and y are normalized values between -1 and 1
|
||||
if (Math.abs(x) > Math.abs(y)) {
|
||||
return x > 0 ? 'right' : 'left';
|
||||
} else {
|
||||
return y > 0 ? 'down' : 'up';
|
||||
}
|
||||
}
|
||||
|
||||
function get_finetune_input_suffix_for_quadrant(stick, quadrant) {
|
||||
if (stick === 'left') {
|
||||
switch (quadrant) {
|
||||
case 'left': return "LL";
|
||||
case 'up': return "LT";
|
||||
case 'right': return "LR";
|
||||
case 'down': return "LB";
|
||||
}
|
||||
} else if (stick === 'right') {
|
||||
switch (quadrant) {
|
||||
case 'left': return "RL";
|
||||
case 'up': return "RT";
|
||||
case 'right': return "RR";
|
||||
case 'down': return "RB";
|
||||
}
|
||||
}
|
||||
return null; // Invalid
|
||||
}
|
||||
|
||||
function handle_finetune_dpad_adjustment(changes) {
|
||||
const sticks = ds_button_states.sticks;
|
||||
const currentStick = sticks[active_stick];
|
||||
|
||||
// Only adjust if stick is moved significantly from center
|
||||
const deadzone = 0.1;
|
||||
if (Math.abs(currentStick.x) < deadzone && Math.abs(currentStick.y) < deadzone) {
|
||||
stop_continuous_dpad_adjustment();
|
||||
return;
|
||||
}
|
||||
|
||||
const quadrant = get_stick_quadrant(currentStick.x, currentStick.y);
|
||||
|
||||
// Check for button press events (not current state)
|
||||
// Use different step sizes based on quadrant - right/down values are much larger
|
||||
const adjustmentStep = (quadrant === 'right' || quadrant === 'down') ? 15 : 3;
|
||||
let adjustment = 0;
|
||||
|
||||
if (quadrant === 'left' || quadrant === 'right') {
|
||||
// Horizontal quadrants: left increases, right decreases
|
||||
if (changes.left || changes.square) {
|
||||
adjustment = adjustmentStep;
|
||||
} else if (changes.right || changes.circle) {
|
||||
adjustment = -adjustmentStep;
|
||||
} else if ([changes.left, changes.right, changes.square, changes.circle].includes(false)) {
|
||||
// Button was released
|
||||
stop_continuous_dpad_adjustment();
|
||||
return;
|
||||
}
|
||||
} else if (quadrant === 'up' || quadrant === 'down') {
|
||||
// Vertical quadrants: up increases, down decreases
|
||||
if (changes.up || changes.triangle) {
|
||||
adjustment = adjustmentStep;
|
||||
} else if (changes.down || changes.cross) {
|
||||
adjustment = -adjustmentStep;
|
||||
} else if ([changes.up, changes.down, changes.triangle, changes.cross].includes(false)) {
|
||||
// Button was released
|
||||
stop_continuous_dpad_adjustment();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Start continuous adjustment on button press
|
||||
if (adjustment !== 0) {
|
||||
start_continuous_dpad_adjustment(active_stick, quadrant, adjustment);
|
||||
}
|
||||
}
|
||||
|
||||
function start_continuous_dpad_adjustment(active_stick, quadrant, adjustment) {
|
||||
stop_continuous_dpad_adjustment();
|
||||
|
||||
const inputSuffix = get_finetune_input_suffix_for_quadrant(active_stick, quadrant);
|
||||
const element = $(`#finetune${inputSuffix}`);
|
||||
|
||||
if (!element.length) return;
|
||||
|
||||
// Perform initial adjustment immediately...
|
||||
perform_dpad_adjustment(element, adjustment);
|
||||
|
||||
// ...then prime continuous adjustment
|
||||
dpad_adjustment_timeout = setTimeout(() => {
|
||||
dpad_adjustment_interval = setInterval(() => {
|
||||
perform_dpad_adjustment(element, adjustment);
|
||||
}, 150);
|
||||
}, 400); // Initial delay before continuous adjustment starts (400ms)
|
||||
}
|
||||
|
||||
function stop_continuous_dpad_adjustment() {
|
||||
clearInterval(dpad_adjustment_interval);
|
||||
dpad_adjustment_interval = null;
|
||||
|
||||
clearTimeout(dpad_adjustment_timeout);
|
||||
dpad_adjustment_timeout = null;
|
||||
}
|
||||
|
||||
async function perform_dpad_adjustment(element, adjustment) {
|
||||
const currentValue = parseInt(element.val()) || 0;
|
||||
const newValue = Math.max(0, Math.min(65535, currentValue + adjustment));
|
||||
element.val(newValue);
|
||||
|
||||
// Trigger the change event to update the finetune data
|
||||
await on_finetune_change();
|
||||
}
|
||||
|
||||
function finetune_save() {
|
||||
finetune_close();
|
||||
|
||||
@@ -1847,9 +2033,6 @@ function update_stick_graphics(changes, {is_ds5}) {
|
||||
if (!changes || !changes.sticks) return;
|
||||
|
||||
refresh_sticks();
|
||||
if (is_ds5) {
|
||||
refresh_finetune();
|
||||
}
|
||||
}
|
||||
|
||||
function update_ds_button_svg(changes, BUTTON_MAP) {
|
||||
@@ -2003,13 +2186,18 @@ function process_ds_input({data}) {
|
||||
|
||||
// Use DS5 map: dpad byte 7, L2 analog 4, R2 analog 5
|
||||
const changes = record_ds_button_states(data, DS5_BUTTON_MAP, 7, 4, 5);
|
||||
|
||||
if(current_active_tab === 'controller-tab') {
|
||||
update_stick_graphics(changes, { is_ds5: true });
|
||||
update_ds_button_svg(changes, DS5_BUTTON_MAP);
|
||||
if(finetune_visible) {
|
||||
refresh_finetune_sticks();
|
||||
handle_finetune_stick_switching(changes);
|
||||
handle_finetune_dpad_adjustment(changes);
|
||||
} else {
|
||||
update_stick_graphics(changes, { is_ds5: true });
|
||||
update_ds_button_svg(changes, DS5_BUTTON_MAP);
|
||||
|
||||
const points = parse_touch_points(data, 32);
|
||||
update_touchpad_circles(points);
|
||||
const points = parse_touch_points(data, 32);
|
||||
update_touchpad_circles(points);
|
||||
}
|
||||
}
|
||||
|
||||
if(current_active_tab === 'tests-tab') {
|
||||
|
||||
161
index.html
161
index.html
@@ -41,6 +41,84 @@
|
||||
<style>
|
||||
dl.row dt { font-weight: normal; }
|
||||
dl.row dd { font-family: monospace; }
|
||||
|
||||
/* Active stick card styling */
|
||||
.stick-card-active {
|
||||
border: 1px solid #0d6efd !important;
|
||||
box-shadow: 0 0 10px rgba(13, 110, 253, 0.3) !important;
|
||||
}
|
||||
|
||||
.stick-card-active .card-header {
|
||||
background-color: #0d6efd !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* Styling for coordinate labels - base state to prevent layout shift */
|
||||
#finetuneStickCanvasLx-lbl,
|
||||
#finetuneStickCanvasLy-lbl,
|
||||
#finetuneStickCanvasRx-lbl,
|
||||
#finetuneStickCanvasRy-lbl {
|
||||
padding: 2px 4px !important;
|
||||
border-radius: 3px !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* Styling for finetune input boxes - base state to prevent layout shift */
|
||||
input[id^="finetune"] {
|
||||
border: 2px solid transparent !important;
|
||||
width: 90px !important;
|
||||
min-width: 90px !important;
|
||||
}
|
||||
|
||||
/* Styling for highlighted finetune input boxes */
|
||||
input[id^="finetune"].border-primary {
|
||||
border: 2px solid #0d6efd !important;
|
||||
}
|
||||
|
||||
/* Styling for highlighted coordinate labels */
|
||||
#finetuneStickCanvasLx-lbl.text-primary,
|
||||
#finetuneStickCanvasLy-lbl.text-primary,
|
||||
#finetuneStickCanvasRx-lbl.text-primary,
|
||||
#finetuneStickCanvasRy-lbl.text-primary {
|
||||
color: #0d6efd !important;
|
||||
background-color: rgba(13, 110, 253, 0.1) !important;
|
||||
}
|
||||
|
||||
/* CSS Grid layout for finetune inputs around canvas */
|
||||
.finetune-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
grid-template-areas:
|
||||
". top ."
|
||||
"left center right"
|
||||
". bottom .";
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
.finetune-top {
|
||||
grid-area: top;
|
||||
}
|
||||
|
||||
.finetune-left {
|
||||
grid-area: left;
|
||||
}
|
||||
|
||||
.finetune-center {
|
||||
grid-area: center;
|
||||
}
|
||||
|
||||
.finetune-right {
|
||||
grid-area: right;
|
||||
}
|
||||
|
||||
.finetune-bottom {
|
||||
grid-area: bottom;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
@@ -443,7 +521,7 @@ dl.row dd { font-family: monospace; }
|
||||
|
||||
<!-- Finetune Modal -->
|
||||
<div class="modal fade" id="finetuneModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="finetuneModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg modal-fullscreen-lg-down">
|
||||
<div class="modal-dialog modal-dialog-centered modal-xl modal-fullscreen-lg-down">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5 ds-i18n" id="finetuneModalLabel">Finetune stick calibration</h1>
|
||||
@@ -451,33 +529,40 @@ dl.row dd { font-family: monospace; }
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="ds-i18n">This screen allows to finetune raw calibration data on your controller</p>
|
||||
<div class="alert alert-info" role="alert">
|
||||
<i class="fas fa-info-circle"></i> <span class="ds-i18n">
|
||||
Press L1 to select Left stick, R1 to select Right stick</span><br/><br/>
|
||||
<span class="ds-i18n">While holding the stick to be adjusted straight up/down/left/right, observe the highlighted value at the bottom of then dialog, then use the D-pad buttons to adjust the finetune value:</span><br/>
|
||||
<small class="ds-i18n">
|
||||
• Move the stick position towards the center until it is just smaller than 1.00 (or larger than -1.00) then move back to 1.00 (or -1.00)<br>
|
||||
• Repeat the adjustment for the left/right and up/down pairs several times until you can move away from 1.00 with only one button press.
|
||||
</small>
|
||||
</div>
|
||||
<div style="width: 100%; display: flex; justify-content: center;">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col col-lg-6 col-12">
|
||||
|
||||
<div class="card text-bg-light" >
|
||||
<div class="card text-bg-light stick-card-active" id="left-stick-card">
|
||||
<div class="card-header"><span class="ds-i18n">Left stick</span></div>
|
||||
<div class="card-body">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<table>
|
||||
<tr><td></td><td style="text-align: center;">
|
||||
<input id="finetuneLT" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td><td></td></tr>
|
||||
<tr>
|
||||
<td height="160px" style="vertical-align: middle; align: right;">
|
||||
<input id="finetuneLL" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td>
|
||||
<td><canvas id="finetuneStickCanvasL" width="150" height="150"></canvas></td>
|
||||
<td height="160px" style="vertical-align: middle; align: left;">
|
||||
<input id="finetuneLR" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td></td><td style="text-align: center;">
|
||||
<input id="finetuneLB" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td><td></td></tr>
|
||||
</table>
|
||||
<div class="finetune-grid">
|
||||
<div class="finetune-top">
|
||||
<input id="finetuneLT" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-left">
|
||||
<input id="finetuneLL" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-center">
|
||||
<canvas id="finetuneStickCanvasL" width="150" height="150"></canvas>
|
||||
</div>
|
||||
<div class="finetune-right">
|
||||
<input id="finetuneLR" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-bottom">
|
||||
<input id="finetuneLB" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
@@ -520,28 +605,26 @@ dl.row dd { font-family: monospace; }
|
||||
|
||||
</div> <!-- col -->
|
||||
<div class="col col-lg-6 col-12">
|
||||
<div class="card text-bg-light" >
|
||||
<div class="card text-bg-light" id="right-stick-card">
|
||||
<div class="card-header"><span class="ds-i18n">Right stick</span></div>
|
||||
<div class="card-body">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<table>
|
||||
<tr><td></td><td style="text-align: center;">
|
||||
<input id="finetuneRT" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td><td></td></tr>
|
||||
<tr>
|
||||
<td height="160px" style="vertical-align: middle; align: right;">
|
||||
<input id="finetuneRL" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td>
|
||||
<td><canvas id="finetuneStickCanvasR" width="150" height="150"></canvas></td>
|
||||
<td height="160px" style="vertical-align: middle; align: left;">
|
||||
<input id="finetuneRR" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td></td><td style="text-align: center;">
|
||||
<input id="finetuneRB" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</td><td></td></tr>
|
||||
</table>
|
||||
<div class="finetune-grid">
|
||||
<div class="finetune-top">
|
||||
<input id="finetuneRT" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-left">
|
||||
<input id="finetuneRL" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-center">
|
||||
<canvas id="finetuneStickCanvasR" width="150" height="150"></canvas>
|
||||
</div>
|
||||
<div class="finetune-right">
|
||||
<input id="finetuneRR" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-bottom">
|
||||
<input id="finetuneRB" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
|
||||
Reference in New Issue
Block a user