-
Notifications
You must be signed in to change notification settings - Fork 213
Expand file tree
/
Copy pathindex.html
More file actions
426 lines (386 loc) · 22.8 KB
/
index.html
File metadata and controls
426 lines (386 loc) · 22.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DualShock Calibration GUI</title>
<link id="bootstrap-css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/fontawesome.min.css"
integrity="sha384-NvKbDTEnL+A8F/AA5Tc5kmMLSJHUO868P+lDtTpJIeQdGYaUIuLr4lVGOEA1OcMy"
crossorigin="anonymous">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/all.min.css"
integrity="sha384-h/hnnw1Bi4nbpD6kE7nYfCXzovi622sY5WBxww8ARKwpdLj5kUWjRuyiXaD1U2JT"
crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
crossorigin="anonymous"></script>
<meta http-equiv="Permissions-Policy" content="interest-cohort=()">
<script type="module" src="js/core.js"></script>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="shortcut icon" href="/favicon.ico" />
<meta name="apple-mobile-web-app-title" content="DS Tools" />
<!-- External CSS files -->
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/finetune.css">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<nav class="navbar bg-body-tertiary navbar-expand-md bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand ds-i18n" href="https://dualshock-tools.github.io">DualShock Calibration GUI</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse container-fluid justify-content-end" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link ds-i18n" href="#" onclick="show_faq_modal();">Frequently Asked Questions</a>
</li>
<li class="nav-item dropdown" id="navbarNavAltMarkup">
<a class="nav-link dropdown-toggle" id="langMenuButton" role="button" href="#" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true">
<svg class="bi text-secondary" width="1.5em" height="1.5em" ><use xlink:href="#lang"/></svg> <span id="curLang">English</span>
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="langMenuButton" id="availLangs">
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div class="container p-2">
<!-- Unsupported Browser Warning -->
<div id="missinghid" style="bottom: 80px; left: 0; right: 0; z-index: 1030; padding: 12px 20px; display: none;">
<div class="container">
<div style="border: 2px solid #0d6efd; border-radius: 8px; color: #0d6efd; padding: 12px; background-color: white;">
<p class="mb-1">
<i class="fas fa-hand"></i>
<span class="ds-i18n">Unsupported browser.</span>
</p>
<p class="mb-1">
<span class="ds-i18n">Please use a web browser with WebHID support (e.g. Google Chrome or Microsoft Edge) on a PC or Mac.</span>
<span class="ds-i18n">Firefox is supported with the WebHID extension installed.</span>
</p>
<p class="mb-0">
<span class="ds-i18n">Using this utility on a phone or tablet is not supported.</span>
</p>
</div>
</div>
</div>
<div id="offlinebar" class="vstack p-2" style="display: none;">
<p class="ds-i18n">Please connect a DualShock 4, a DualSense, DualSense Edge or VR2 controller to your computer and press Connect.</p>
<button id="btnconnect" type="button" class="btn btn-outline-primary" onclick="connect()">
<span class="spinner-border spinner-border-sm" style="display: none;" id="connectspinner" aria-hidden="true"></span>
<span class="ds-i18n">Connect</span>
</button>
<br>
</div>
<div id="onlinebar" class="vstack p-2" style="display: none;">
<div class="row">
<div class="col-sm-9 hstack">
<p><b class="ds-i18n">Connected to:</b></p> <p id="devname"></p>
</div>
<div class="col-sm-3">
<p id="d-bat" style="text-align: right;"></p>
</div>
</div>
<button type="button" class="btn btn-outline-secondary ds-i18n" onclick="disconnect()">Disconnect</button><br>
</div>
<div id="mainmenu" class="container" style="display: none;">
<ul class="nav nav-tabs mb-3" id="mainTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="controller-tab" data-bs-toggle="tab" data-bs-target="#controller-content" type="button" role="tab" aria-controls="controller-content" aria-selected="true">
<i class="fas fa-gamepad"></i> <span class="ds-i18n">Calibration</span>
</button>
</li>
<!-- <li class="nav-item" role="presentation">
<button class="nav-link" id="tests-tab" data-bs-toggle="tab" data-bs-target="#tests-content" type="button" role="tab" aria-controls="tests-content" aria-selected="false">
<i class="fas fa-vial"></i> <span class="ds-i18n">Tests</span>
</button>
</li> -->
<li class="nav-item" role="presentation">
<button class="nav-link" id="info-tab" data-bs-toggle="tab" data-bs-target="#info-content" type="button" role="tab" aria-controls="info-content" aria-selected="false">
<i class="fas fa-info-circle"></i> <span class="ds-i18n">Info</span>
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="debug-tab" data-bs-toggle="tab" data-bs-target="#debug-content" type="button" role="tab" aria-controls="debug-content" aria-selected="false">
<i class="fas fa-bug"></i> <span class="ds-i18n">Debug</span>
</button>
</li>
</ul>
<div class="tab-content" id="mainTabsContent">
<div class="tab-pane show active" id="controller-content" role="tabpanel" aria-labelledby="controller-tab">
<!-- Main page content (controller info, calibration, joystick info) -->
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="card text-bg-light" >
<div class="card-header"><i class="fas fa-gamepad"></i> <span class="ds-i18n">Controller Info</span></div>
<dl class="row px-3 py-2" id="fwinfo"></dl>
<span id="infoshowall" class="pb-4 px-4 row">
<button class="btn btn-outline-secondary" onclick="show_info_tab()"><i class="fas fa-plus me-1"></i> <span class="ds-i18n">Show all</span></button>
</span>
</div>
<br>
<div class="d-flex justify-content-end" id="quick-tests-div">
<button type="button" class="btn btn-outline-primary ds-btn mb-3" onclick="show_quick_test_modal()" id="quick-test-btn">
<i class="fas fa-vial" id="quick-test-icon"></i>
<span id="quick-test-text" class="ds-i18n">Quick Test</span>
</button>
</div>
<div class="text-center mx-3" id="controller-svg-container">
<!-- DualSense 5 Controller SVG loaded from template -->
<div id="controller-svg-placeholder"></div>
</div>
</div>
<div class="col-md-6 col-sm-12" style="min-width: 330px;">
<div class="vstack gap-2 p-2">
<button type="button" class="btn btn-primary ds-btn" onclick="calibrate_stick_centers()" id="four-step-center-calib" style="display: none;">
<span class="ds-i18n">Calibrate stick center</span>
</button>
<div class="btn-group w-100" role="group" style="display: none;" id="quick-center-calib-group">
<button type="button" class="btn btn-primary ds-btn flex-grow-1" onclick="executeSelectedCenterCalibration()" id="quick-center-calib">
<span> </span>
<span class="ds-i18n">Calibrate stick center</span>
</button>
<button type="button" class="btn btn-primary ds-btn dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false" style="flex: 0 0 35px;">
<span class="visually-hidden">Toggle dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="setCenterCalibrationMethod('quick', event)">
<i class="fas fa-check me-2" id="check-quick" style="display: none;"></i><span class="ds-i18n">Use quick calibration</span>
</a></li>
<li><a class="dropdown-item" href="#" onclick="setCenterCalibrationMethod('four-step', event)">
<i class="fas fa-check me-2" id="check-four-step"></i><span class="ds-i18n">Use four-step calibration</span>
</a></li>
</ul>
</div>
<div class="btn-group w-100" role="group" id="range-calib-group">
<button type="button" class="btn btn-primary ds-btn flex-grow-1" onclick="executeSelectedRangeCalibration()" id="range-calib">
<span> </span>
<span class="ds-i18n">Calibrate stick range</span>
</button>
<button type="button" class="btn btn-primary ds-btn dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false" style="flex: 0 0 35px;">
<span class="visually-hidden">Toggle dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="setRangeCalibrationMethod('normal', event)">
<i class="fas fa-check me-2" id="check-range-normal"></i><span class="ds-i18n">Use normal mode</span>
</a></li>
<li><a class="dropdown-item" href="#" onclick="setRangeCalibrationMethod('expert', event)">
<i class="fas fa-check me-2" id="check-range-expert" style="display: none;"></i><span class="ds-i18n">Use expert mode</span>
</a></li>
</ul>
</div>
<button type="button" class="btn btn-primary ds-btn" onclick="ds5_finetune()" id="ds5finetune">
<span class="ds-i18n">Finetune stick calibration</span>
</button>
<hr>
<button id="savechanges" type="button" class="btn btn-success ds-btn ds-i18n" onclick="flash_all_changes()">Save changes permanently</button>
<button id="restore-calibration-btn" type="button" class="btn btn-secondary ds-btn ds-i18n" onclick="openCalibrationHistoryModal()">Restore calibration</button>
<button type="button" class="btn btn-danger ds-btn ds-i18n" onclick="reboot_controller()" id="resetBtn">Reboot controller</button>
<div class="card text-bg-light" >
<div class="card-header"><i class="fas fa-crosshairs"></i> <span class="ds-i18n">Joystick Info</span></div>
<div class="vstack px-2">
<center>
<div style="position: relative; display: inline-block;">
<canvas id="stickCanvas" width="300" height="150"></canvas>
<svg
id="circularityCheckIcon" class="bi" width="32" height="32"
style="cursor: pointer; color: #ff4000cb; position: absolute; top: 25px; right: -30px; display: none;"
onclick="show_circularity_warning()"
>
<use xlink:href="#info"/></svg>
</div>
</center>
</div>
<div class="px-2">
<div class="hstack">
<div class="vstack" style="text-align: center;">
<span>LX:</span>
<pre id="lx-lbl" style="min-width: 80px;"></pre>
</div>
<div class="vstack" style="text-align: center;">
<span>LY:</span>
<pre id="ly-lbl" style="min-width: 80px;"></pre>
</div>
<div id="stick-item-rx" class="vstack" style="text-align: center;">
<span>RX:</span>
<pre id="rx-lbl" style="min-width: 80px;"></pre>
</div>
<div id="stick-item-ry" class="vstack" style="text-align: center;">
<span>RY:</span>
<pre id="ry-lbl" style="min-width: 80px;"></pre>
</div>
</div>
</div>
<div class="px-2">
<center>
<div class="btn-group mb-3" role="group" aria-label="Display mode options">
<input type="radio" class="btn-check" name="displayMode" id="normalMode" value="normal" checked>
<label class="btn btn-outline-secondary btn-sm ds-i18n" for="normalMode">Normal</label>
<input type="radio" class="btn-check" name="displayMode" id="centerZoomMode" value="centerZoom">
<label class="btn btn-outline-secondary btn-sm ds-i18n" for="centerZoomMode">10x zoom</label>
<input type="radio" class="btn-check" name="displayMode" id="checkCircularityMode" value="checkCircularity">
<label class="btn btn-outline-secondary btn-sm ds-i18n" for="checkCircularityMode">Check circularity</label>
</div>
</center>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="tab-pane" id="tests-content" role="tabpanel" aria-labelledby="tests-tab">
<div class="card text-bg-light mt-3" style="min-height: 500px;">
<div class="card-header">
<i class="fas fa-vial"></i> <span class="ds-i18n">Tests</span>
</div>
<div class="card-body">
<div class="row">
<div class="col-4">
<div class="list-group" id="tests-list" role="tablist">
<a class="list-group-item list-group-item-action active ds-i18n" id="haptic-test-tab" data-bs-toggle="list" href="#haptic-test-pane">Haptic Motors</a>
</div>
</div>
<div class="col-8">
<div class="bg-white border rounded-3 p-4">
<div class="tab-content">
<div class="tab-pane show active" id="haptic-test-pane" role="tabpanel" aria-labelledby="haptic-test-tab">
<h5 class="ds-i18n">Test the Haptic Motors</h5>
<p class="ds-i18n">Press L2 to test the strong (left) haptic motor</p>
<p class="ds-i18n">Press R2 to test the weak (right) haptic motor</p>
<p class="ds-i18n">The motor strength will match how hard you press the trigger</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> -->
<div class="tab-pane" id="info-content" role="tabpanel" aria-labelledby="info-tab">
<div class="container-fluid py-4">
<div class="row">
<div class="col-lg-12 col-xl-6 py-3">
<div class="card">
<h5 class="card-header"><i class="fas fa-code"></i> <span class="ds-i18n">Software</span></h5>
<div class="card-body">
<dl class="row" id="fwinfoextra-fw"></dl>
</div>
</div>
</div>
<div class="col-lg-12 col-xl-6 py-3">
<div class="card">
<h5 class="card-header"><i class="fas fa-microchip"></i> <span class="ds-i18n">Hardware</span></h5>
<div class="card-body">
<dl class="row" id="fwinfoextra-hw"></dl>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="debug-content" role="tabpanel" aria-labelledby="debug-tab">
<div class="container-fluid py-4">
<div class="row">
<p class="ds-i18n">Sections below are not useful, just some debug infos or manual commands</p>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="card text-bg-light" >
<div class="card-header"><i class="fas fa-bug"></i> <span class="ds-i18n">Debug Info</span></div>
<div class="vstack p-2">
<div class="hstack"><p class="ds-i18n">NVS Status</p><p class="ms-auto ds-i18n" id="d-nvstatus">Unknown</p></div>
</div>
</div>
<br>
</div>
<div class="col-md-6 col-sm-12">
<div class="card text-bg-light" >
<div class="card-header"><i class="fas fa-skull-crossbones"></i> <span class="ds-i18n">Debug buttons</span></div>
<div class="vstack gap-2 p-2">
<div class="hstack gap-2">
<button type="button" class="btn btn-success ds-btn ds-i18n" onclick="refresh_nvstatus()">Query NVS status</button>
<button type="button" class="btn btn-primary ds-btn ds-i18n" onclick="nvsunlock()">NVS unlock</button>
<button type="button" class="btn btn-primary ds-btn ds-i18n" onclick="nvslock()">NVS lock</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Alert Messages Container -->
<div class="container-fluid fixed-bottom " style="z-index: 1040; pointer-events: none; bottom: 70px;">
<div class="container">
<div id="alert-container" class="mb-3" style="pointer-events: auto;">
<!-- Alert messages will be dynamically inserted here -->
</div>
</div>
</div>
<!-- About drift and this utility -->
<div id="aboutdrift" style="position: fixed; bottom: 70px; left: 0; right: 0; z-index: 1030; display: none;">
<div class="container">
<div class="mb-4" style="border: 2px solid #0d6efd; border-radius: 8px; color: #0d6efd; padding: 12px; background-color: white;">
<p class="mb-2">
<i class="fas fa-hand-point-up"></i>
<span class="ds-i18n">This utility cannot fix stick drift.</span>
</p>
<p class="mb-2">
<span class="ds-i18n">Drift is caused by mechanical parts in the joystick being worn out, and they need to be replaced to fix the drift.</span>
<span class="ds-i18n">After they have been replaced, this utility can be used to calibrate the controller to work with the new joysticks.</span></p>
<p class="mb-0">
<i class="fas fa-regular fa-triangle-exclamation"></i>
<span class="ds-i18n">Calibrating without replacing the joysticks may help temporarily, but it may also make the problem worse, with no way to undo it.</span>
</p>
</div>
<div id="lastConnected" class="gap-2">
<span class="text-muted"><i class="fas fa-history"></i> <span class="ds-i18n">Last connected</span>:</span>
<span id="lastConnectedInfo"></span>
<div id="lastConnectedWarning" style="display: none;">
<p class="text-danger" style="margin-top: 8px; margin-bottom: 0;">
<i class="fas fa-regular fa-triangle-exclamation"></i> <span class="ds-i18n">This controller has unsaved changes that will be lost when the controller is rebooted.</span>
</p>
</div>
</div>
</div>
</div>
<!-- Fixed Footer -->
<footer class="fixed-bottom bg-body-tertiary border-top">
<div class="container">
<div class="d-flex flex-column flex-sm-row justify-content-between py-3" id="footbody">
<p class="mb-0"><a target="_blank" href="https://github.com/dualshock-tools/dualshock-tools.github.io/commits/main/"><span class="ds-i18n">Version</span> 2.24</a> (2026-01-13) - <a href="#" class="ds-i18n" onclick="show_donate_modal();">Support this project</a> <span id="authorMsg"></span></p>
<ul class="list-unstyled d-flex mb-0">
<li class="ms-3"><a class="text-dark" href="mailto:ds4@the.al" target="_blank"><svg class="bi" width="24" height="24"><use xlink:href="#mail"/></svg></a></li>
<li class="ms-3"><a class="text-dark" href="https://discord.gg/w2P7Rrs2Yp" target="_blank"><svg class="bi" width="24" height="24"><use xlink:href="#discord"/></svg></a></li>
<li class="ms-3"><a class="text-dark" href="https://github.com/dualshock-tools/" target="_blank"><svg class="bi" width="24" height="24"><use xlink:href="#github"/></svg></a></li>
<li class="ms-3"><a class="text-dark" href="https://the.al/ds_history/"><svg class="bi" width="24" height="24"><use xlink:href="#time-back"/></svg></a></li>
</ul>
</div>
</div>
</footer>
</body>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-FSXPMDXLLS"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-FSXPMDXLLS');
// The gboot() function is now auto-called when the core.js module loads
// No manual initialization needed here
</script>
</html>