mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-09-15 11:55:10 -05:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdf493d2fb | ||
|
|
bec007d52a | ||
|
|
a177913bd6 | ||
|
|
0fdde8b32d | ||
|
|
09b3a6c24a | ||
|
|
f8b2f5f40d |
@@ -2,6 +2,15 @@
|
||||
Note for CI/CD: Ensure the version formatting in the sections is kept identical to the versions
|
||||
given in tags. The pipeline will pick this up and cuts out the relevant section for release notes.
|
||||
|
||||
## 5.47
|
||||
### Features
|
||||
N/A
|
||||
|
||||
### Fixes
|
||||
* fix(ddr/p3ioemu): Handle unknown 2B command to fix DDR X IO errors
|
||||
* fix(ddr/p3io): Crash on all supported DDR games due to incorrect p3io message size validation
|
||||
* fix(geninput): Sony DualShock 4 not working
|
||||
|
||||
## 5.46
|
||||
### Features
|
||||
* feat(ddrio): Wrapper/shim library to drive another ddrio in a dedicated IO thread. Improves performance for highly IO
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Bemanitools 5
|
||||
|
||||
Version: `5.46`
|
||||
Version: `5.47`
|
||||
|
||||
[Changelog](CHANGELOG.md)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ void dev_list_init(struct dev_list *devs, const GUID *class_guid)
|
||||
devs->infolist = SetupDiGetClassDevs(
|
||||
devs->class_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
|
||||
if (devs->infolist == NULL) {
|
||||
if (devs->infolist == INVALID_HANDLE_VALUE) {
|
||||
log_fatal(
|
||||
"SetupDiGetClassDevs failed: %08x", (unsigned int) GetLastError());
|
||||
}
|
||||
|
||||
@@ -48,7 +48,12 @@ arrays_fail:
|
||||
hid_meta_out_fini_caps(meta);
|
||||
|
||||
caps_fail:
|
||||
return false;
|
||||
/**
|
||||
* Still allow the device to be used as input.
|
||||
* Useful for devices like the Sony DUALSHOCK 4, where it indicates it can receive outputs
|
||||
* but it errors out when trying to initialize an output report.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -99,9 +104,11 @@ hid_meta_out_init_caps(struct hid_meta_out *meta, PHIDP_PREPARSED_DATA ppd)
|
||||
|
||||
caps_val_fail:
|
||||
free(meta->caps_val);
|
||||
meta->caps_val = NULL;
|
||||
|
||||
caps_btn_fail:
|
||||
free(meta->caps_btn);
|
||||
meta->caps_btn = NULL;
|
||||
|
||||
caps_tlc_fail:
|
||||
return false;
|
||||
@@ -114,7 +121,6 @@ static bool hid_meta_out_init_arrays(struct hid_meta_out *meta)
|
||||
bool *report_presence;
|
||||
unsigned int nreports;
|
||||
unsigned int i;
|
||||
uint8_t *bytes;
|
||||
size_t nbytes;
|
||||
size_t count;
|
||||
|
||||
@@ -174,7 +180,6 @@ static bool hid_meta_out_init_arrays(struct hid_meta_out *meta)
|
||||
for (i = 0; i < 0x100; i++) {
|
||||
if (report_presence[i]) {
|
||||
nbytes = meta->caps_tlc.OutputReportByteLength;
|
||||
bytes = xmalloc(meta->caps_tlc.OutputReportByteLength);
|
||||
|
||||
if (!hid_report_out_init(
|
||||
&meta->reports[meta->nreports],
|
||||
@@ -198,14 +203,22 @@ static bool hid_meta_out_init_arrays(struct hid_meta_out *meta)
|
||||
return true;
|
||||
|
||||
r_init_fail:
|
||||
free(bytes);
|
||||
|
||||
for (i = meta->nreports; i > 0; i--) {
|
||||
hid_report_out_fini(&meta->reports[i - 1]);
|
||||
}
|
||||
|
||||
free(report_presence);
|
||||
|
||||
// Clear out all output/light data
|
||||
meta->nreports = 0;
|
||||
free(meta->reports);
|
||||
meta->reports = NULL;
|
||||
|
||||
meta->nlights = 0;
|
||||
meta->nbuttons = 0;
|
||||
// Failed out before allocating memory
|
||||
meta->lights = NULL;
|
||||
meta->priv_lights = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -433,5 +446,8 @@ static void hid_meta_out_fini_arrays(struct hid_meta_out *meta)
|
||||
static void hid_meta_out_fini_caps(struct hid_meta_out *meta)
|
||||
{
|
||||
free(meta->caps_btn);
|
||||
meta->caps_btn = NULL;
|
||||
|
||||
free(meta->caps_val);
|
||||
meta->caps_val = NULL;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ static HANDLE mm_open_device(void)
|
||||
dev_info = SetupDiGetClassDevsW(
|
||||
&hid_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
|
||||
if (dev_info == NULL) {
|
||||
if (dev_info == INVALID_HANDLE_VALUE) {
|
||||
log_fatal("SetupDiGetClassDevs failed");
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ void p3io_resp_hdr_init(
|
||||
{
|
||||
log_assert(resp_hdr != NULL);
|
||||
log_assert(req_hdr != NULL);
|
||||
log_assert(nbytes < P3IO_MAX_MESSAGE_SIZE);
|
||||
log_assert(nbytes <= P3IO_MAX_MESSAGE_SIZE);
|
||||
|
||||
/* Length byte in this packet format counts everything from the length
|
||||
byte onwards. The length byte itself occurs at the start of the frame. */
|
||||
|
||||
@@ -161,6 +161,11 @@ struct p3io_req_rs232_write {
|
||||
uint8_t bytes[128];
|
||||
};
|
||||
|
||||
struct p3io_req_unknown_generic {
|
||||
struct p3io_hdr hdr;
|
||||
uint8_t unknown;
|
||||
};
|
||||
|
||||
struct p3io_req_raw {
|
||||
uint8_t data[P3IO_MAX_MESSAGE_SIZE];
|
||||
};
|
||||
@@ -182,6 +187,7 @@ union p3io_req_any {
|
||||
struct p3io_req_rs232_open_close rs232_open_close;
|
||||
struct p3io_req_rs232_read rs232_read;
|
||||
struct p3io_req_rs232_write rs232_write;
|
||||
struct p3io_req_unknown_generic unknown_generic;
|
||||
struct p3io_req_raw raw;
|
||||
};
|
||||
|
||||
@@ -266,6 +272,11 @@ struct p3io_resp_rs232_write {
|
||||
uint8_t nbytes;
|
||||
};
|
||||
|
||||
struct p3io_resp_unknown_generic {
|
||||
struct p3io_hdr hdr;
|
||||
uint8_t unknown;
|
||||
};
|
||||
|
||||
struct p3io_resp_raw {
|
||||
uint8_t data[P3IO_MAX_MESSAGE_SIZE];
|
||||
};
|
||||
@@ -286,6 +297,7 @@ union p3io_resp_any {
|
||||
struct p3io_resp_rs232_open_close rs232_open_close;
|
||||
struct p3io_resp_rs232_read rs232_read;
|
||||
struct p3io_resp_rs232_write rs232_write;
|
||||
struct p3io_resp_unknown_generic unknown_generic;
|
||||
struct p3io_resp_raw raw;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ static void p3io_cmd_get_video_freq(
|
||||
const struct p3io_req_get_video_freq *req,
|
||||
struct p3io_resp_get_video_freq *resp);
|
||||
static void
|
||||
p3io_cmd_unknown_2b(const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp);
|
||||
static void
|
||||
p3io_cmd_init(const struct p3io_req_init *req, struct p3io_resp_init *resp);
|
||||
static void p3io_cmd_get_coinstock(
|
||||
const struct p3io_req_coin_stock *req, struct p3io_resp_coin_stock *resp);
|
||||
@@ -56,7 +58,7 @@ static void p3io_cmd_set_coin_counter(
|
||||
const struct p3io_req_set_coin_counter *req,
|
||||
struct p3io_resp_set_coin_counter *resp);
|
||||
static void
|
||||
p3io_cmd_unknown(const union p3io_req_any *req, struct p3io_resp_raw *resp);
|
||||
p3io_cmd_unknown(const struct p3io_req_unknown_generic *req, struct p3io_resp_unknown_generic *resp);
|
||||
|
||||
void p3io_emu_init(const struct p3io_ops *ops, void *ctx)
|
||||
{
|
||||
@@ -268,6 +270,11 @@ static HRESULT p3io_cmd_dispatch(const union p3io_req_any *req)
|
||||
|
||||
break;
|
||||
|
||||
case P3IO_CMD_UNKNOWN_2B:
|
||||
p3io_cmd_unknown_2b(&req->unknown_2b, &resp.unknown_2b);
|
||||
|
||||
break;
|
||||
|
||||
case P3IO_CMD_INIT:
|
||||
p3io_cmd_init(&req->init, &resp.init);
|
||||
|
||||
@@ -301,7 +308,7 @@ static HRESULT p3io_cmd_dispatch(const union p3io_req_any *req)
|
||||
break;
|
||||
|
||||
default:
|
||||
p3io_cmd_unknown(req, &resp.raw);
|
||||
p3io_cmd_unknown(&req->unknown_generic, &resp.unknown_generic);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -511,6 +518,16 @@ static void p3io_cmd_get_video_freq(
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
p3io_cmd_unknown_2b(const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp)
|
||||
{
|
||||
log_misc("Unknown 2b");
|
||||
|
||||
p3io_resp_hdr_init(&resp->hdr, sizeof(*resp), &req->hdr);
|
||||
|
||||
resp->unknown = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
p3io_cmd_init(const struct p3io_req_init *req, struct p3io_resp_init *resp)
|
||||
{
|
||||
@@ -557,15 +574,16 @@ static void p3io_cmd_set_coin_counter(
|
||||
}
|
||||
|
||||
static void
|
||||
p3io_cmd_unknown(const union p3io_req_any *req, struct p3io_resp_raw *resp)
|
||||
p3io_cmd_unknown(const struct p3io_req_unknown_generic *req, struct p3io_resp_unknown_generic *resp)
|
||||
{
|
||||
log_warning("Unsupported P3IO command: %02x", req->hdr.cmd);
|
||||
log_warning("Unsupported P3IO command, sending default response (might not work/crash though): %02x",
|
||||
req->hdr.cmd);
|
||||
|
||||
p3io_resp_hdr_init(
|
||||
(struct p3io_hdr *) &resp->data, sizeof(*resp), &req->hdr);
|
||||
p3io_resp_hdr_init(&resp->hdr, sizeof(*resp), &req->hdr);
|
||||
|
||||
// Not always applicable/correct as there are several commands not
|
||||
// responding with any data, but fine for the majority of (unsupported)
|
||||
// commands
|
||||
resp->data[sizeof(struct p3io_hdr) + 0] = 0;
|
||||
// Remark: This might also lead to unpredictable behaviour or crashes
|
||||
resp->unknown = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user