-
Version 2.16 beta 9 (2025-09-11) - Support this project
+
Version 2.16 beta 10 (2025-09-17) - Support this project
diff --git a/js/controller-manager.js b/js/controller-manager.js
index 725cd7f..0573825 100644
--- a/js/controller-manager.js
+++ b/js/controller-manager.js
@@ -158,9 +158,8 @@ class ControllerManager {
* Flash/save changes to the controller
*/
async flash(progressCallback = null) {
- const result = await this.currentController.flash(progressCallback);
this.setHasChangesToWrite(false);
- return result;
+ return this.currentController.flash(progressCallback);
}
/**
@@ -197,7 +196,7 @@ class ControllerManager {
async calibrateSticksBegin() {
const res = await this.currentController.calibrateSticksBegin();
if (!res.ok) {
- throw new Error(this.l("Stick calibration failed"), { cause: res.error });
+ throw new Error(`${this.l("Stick calibration failed")}. ${res.error?.message}`, { cause: res.error });
}
}
@@ -229,9 +228,9 @@ class ControllerManager {
* Begin stick range calibration (for UI-driven calibration)
*/
async calibrateRangeBegin() {
- const ret = await this.currentController.calibrateRangeBegin();
- if (!ret.ok) {
- throw new Error(this.l("Range calibration failed"), { cause: ret.error } );
+ const res = await this.currentController.calibrateRangeBegin();
+ if (!res.ok) {
+ throw new Error(`${this.l("Stick calibration failed")}. ${res.error?.message}`, { cause: res.error });
}
}
diff --git a/js/controllers/ds4-controller.js b/js/controllers/ds4-controller.js
index 582699a..6e6f7e7 100644
--- a/js/controllers/ds4-controller.js
+++ b/js/controllers/ds4-controller.js
@@ -10,6 +10,8 @@ import {
la
} from '../utils.js';
+const NOT_GENUINE_SONY_CONTROLLER_MSG = "Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.";
+
// DS4 Button mapping configuration
const DS4_BUTTON_MAP = [
{ name: 'up', byte: 4, mask: 0x0 }, // Dpad handled separately
@@ -175,10 +177,14 @@ class DS4Controller extends BaseController {
// Assert
const data = await this.receiveFeatureReport(0x91);
const data2 = await this.receiveFeatureReport(0x92);
- const [d1, d2] = [data, data2].map(v => v.getUint32(0, false));
+ const [d1, d2] = [data, data2].map(v => v.buffer.byteLength == 4 ? v.getUint32(0, false) : undefined);
if(d1 != 0x91010201 || d2 != 0x920102ff) {
la("ds4_calibrate_range_begin_failed", {"d1": d1, "d2": d2});
- return { ok: false, code: 1, d1, d2 };
+ return {
+ ok: false,
+ error: new Error(this.l(NOT_GENUINE_SONY_CONTROLLER_MSG)),
+ code: 1, d1, d2
+ };
}
return { ok: true };
} catch(error) {
@@ -219,10 +225,14 @@ class DS4Controller extends BaseController {
// Assert
const data = await this.receiveFeatureReport(0x91);
const data2 = await this.receiveFeatureReport(0x92);
- const [d1, d2] = [data, data2].map(v => v.getUint32(0, false));
+ const [d1, d2] = [data, data2].map(v => v.buffer.byteLength == 4 ? v.getUint32(0, false) : undefined);
if(d1 != 0x91010101 || d2 != 0x920101ff) {
la("ds4_calibrate_sticks_begin_failed", {"d1": d1, "d2": d2});
- return { ok: false, code: 1, d1, d2 };
+ return {
+ ok: false,
+ error: new Error(this.l(NOT_GENUINE_SONY_CONTROLLER_MSG)),
+ code: 1, d1, d2,
+ };
}
return { ok: true };
diff --git a/js/core.js b/js/core.js
index e3ddccc..b9b7cfd 100644
--- a/js/core.js
+++ b/js/core.js
@@ -298,6 +298,8 @@ async function disconnect() {
}
app.gj = 0;
app.disable_btn = 0;
+ update_disable_btn();
+
await controller.disconnect();
controller = null; // Tear everything down
close_all_modals();
@@ -724,9 +726,14 @@ function handleNvStatusUpdate(nv) {
}
async function flash_all_changes() {
- // For DS5 Edge controllers, pass the progress callback
- const progressCallback = controller.getModel() == "DS5_Edge" ? set_edge_progress : null;
+ const isEdge = controller.getModel() == "DS5_Edge";
+ const progressCallback = isEdge ? set_edge_progress : null;
+ const edgeProgressModal = isEdge ? bootstrap.Modal.getOrCreateInstance('#edgeProgressModal') : null;
+ edgeProgressModal?.show();
+
const result = await controller.flash(progressCallback);
+ edgeProgressModal?.hide();
+
if (result?.success) {
if(result.isHtml) {
show_popup(result.message, result.isHtml);