mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2024-11-24 14:50:10 +01:00
sdvx: Allow setting digital amp level from sdvxio
For SDVX 1-4: passes amp values through as-is For SDVX5: ignores the amp volume control (as the game uses windows volume controls, which will work without any hooks)
This commit is contained in:
parent
69ef963451
commit
9246e7f9e0
@ -37,7 +37,12 @@ static bool aciodrv_kfca_watchdog_start(uint8_t node_id)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool aciodrv_kfca_amp(uint8_t node_id)
|
bool aciodrv_kfca_amp(
|
||||||
|
uint8_t node_id,
|
||||||
|
uint8_t primary,
|
||||||
|
uint8_t headphone,
|
||||||
|
uint8_t unused,
|
||||||
|
uint8_t subwoofer)
|
||||||
{
|
{
|
||||||
struct ac_io_message msg;
|
struct ac_io_message msg;
|
||||||
|
|
||||||
@ -45,12 +50,10 @@ static bool aciodrv_kfca_amp(uint8_t node_id)
|
|||||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_AMP_CONTROL);
|
msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_AMP_CONTROL);
|
||||||
msg.cmd.nbytes = 4;
|
msg.cmd.nbytes = 4;
|
||||||
|
|
||||||
// yes this sets the amp to 100% volume
|
msg.cmd.raw[0] = primary;
|
||||||
// TODO: expose this to sdvxio instead at some point
|
msg.cmd.raw[1] = headphone;
|
||||||
msg.cmd.raw[0] = 0;
|
msg.cmd.raw[2] = unused;
|
||||||
msg.cmd.raw[1] = 0;
|
msg.cmd.raw[3] = subwoofer;
|
||||||
msg.cmd.raw[2] = 0;
|
|
||||||
msg.cmd.raw[3] = 0;
|
|
||||||
|
|
||||||
if (!aciodrv_send_and_recv(
|
if (!aciodrv_send_and_recv(
|
||||||
&msg, offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
&msg, offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||||
@ -69,7 +72,7 @@ bool aciodrv_kfca_init(uint8_t node_id)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aciodrv_kfca_amp(node_id)) {
|
if (!aciodrv_kfca_amp(node_id, 0, 0, 0, 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,4 +30,22 @@ bool aciodrv_kfca_poll(
|
|||||||
const struct ac_io_kfca_poll_out *pout,
|
const struct ac_io_kfca_poll_out *pout,
|
||||||
struct ac_io_kfca_poll_in *pin);
|
struct ac_io_kfca_poll_in *pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the KFCA digital amp level
|
||||||
|
*
|
||||||
|
* @param node_id Id of the node to query (0 based).
|
||||||
|
* @param primary primary volume (96-0)
|
||||||
|
* @param headphone headphone volume (96-0)
|
||||||
|
* @param unused unknown volume (96-0) (unused)
|
||||||
|
* @param subwoofer subwoofer volume (96-0)
|
||||||
|
* @return True on success, false on error.
|
||||||
|
* @note Note 96 (or 100?) is lowest volume level, 0 is highest
|
||||||
|
*/
|
||||||
|
bool aciodrv_kfca_amp(
|
||||||
|
uint8_t node_id,
|
||||||
|
uint8_t primary,
|
||||||
|
uint8_t headphone,
|
||||||
|
uint8_t unused,
|
||||||
|
uint8_t subwoofer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,4 +98,8 @@ uint16_t sdvx_io_get_input_gpio(uint8_t gpio_bank);
|
|||||||
|
|
||||||
uint16_t sdvx_io_get_spinner_pos(uint8_t spinner_no);
|
uint16_t sdvx_io_get_spinner_pos(uint8_t spinner_no);
|
||||||
|
|
||||||
|
/* Sets the volume of the digital amps if possible */
|
||||||
|
|
||||||
|
bool sdvx_io_set_amp_volume(uint8_t primary, uint8_t headphone, uint8_t subwoofer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
static void kfca_send_version(const struct ac_io_message *req);
|
static void kfca_send_version(const struct ac_io_message *req);
|
||||||
static void kfca_report_status(const struct ac_io_message *req, uint8_t status);
|
static void kfca_report_status(const struct ac_io_message *req, uint8_t status);
|
||||||
static void kfca_report_0128(const struct ac_io_message *req);
|
static void kfca_amp_control(const struct ac_io_message *req);
|
||||||
static void kfca_poll(const struct ac_io_message *req);
|
static void kfca_poll(const struct ac_io_message *req);
|
||||||
static void kfca_poll_thunk(void *ctx_ptr, struct ac_io_message *resp);
|
static void kfca_poll_thunk(void *ctx_ptr, struct ac_io_message *resp);
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ void kfca_dispatch_request(const struct ac_io_message *req)
|
|||||||
|
|
||||||
case AC_IO_CMD_KFCA_AMP_CONTROL:
|
case AC_IO_CMD_KFCA_AMP_CONTROL:
|
||||||
log_misc("AC_IO_CMD_KFCA_AMP_CONTROL(%d)", req->addr);
|
log_misc("AC_IO_CMD_KFCA_AMP_CONTROL(%d)", req->addr);
|
||||||
kfca_report_0128(req);
|
kfca_amp_control(req);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ static void kfca_report_status(const struct ac_io_message *req, uint8_t status)
|
|||||||
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
|
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kfca_report_0128(const struct ac_io_message *req)
|
static void kfca_amp_control(const struct ac_io_message *req)
|
||||||
{
|
{
|
||||||
struct ac_io_message resp;
|
struct ac_io_message resp;
|
||||||
|
|
||||||
@ -120,6 +120,12 @@ static void kfca_report_0128(const struct ac_io_message *req)
|
|||||||
resp.cmd.nbytes = req->cmd.nbytes;
|
resp.cmd.nbytes = req->cmd.nbytes;
|
||||||
memcpy(resp.cmd.raw, req->cmd.raw, req->cmd.nbytes);
|
memcpy(resp.cmd.raw, req->cmd.raw, req->cmd.nbytes);
|
||||||
|
|
||||||
|
// bytes 0-4: main, headphone, unused, subwoofer
|
||||||
|
|
||||||
|
if (!sdvx_io_set_amp_volume(req->cmd.raw[0], req->cmd.raw[1], req->cmd.raw[3])) {
|
||||||
|
log_warning("Unable to set amp volume?");
|
||||||
|
}
|
||||||
|
|
||||||
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
|
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,8 +104,12 @@ kfca_amp_control(struct ac_io_emu *emu, const struct ac_io_message *req)
|
|||||||
resp.cmd.nbytes = req->cmd.nbytes;
|
resp.cmd.nbytes = req->cmd.nbytes;
|
||||||
memcpy(resp.cmd.raw, req->cmd.raw, req->cmd.nbytes);
|
memcpy(resp.cmd.raw, req->cmd.raw, req->cmd.nbytes);
|
||||||
|
|
||||||
// log_misc("sz %d: %d, %d, %d, %d", req->cmd.nbytes, req->cmd.raw[0],
|
// so SDVX5 sets the amps to 0 aka ALL MAX and uses Windows instead
|
||||||
// req->cmd.raw[1], req->cmd.raw[2], req->cmd.raw[3]);
|
// let's leave it to the individual sdvxio to set on init instead
|
||||||
|
// this way if any sdvxio's want to use Windows APIs for SDVX1-4 comapt.
|
||||||
|
// they can do so without doubly affecting the volume
|
||||||
|
|
||||||
|
// sdvx_io_set_amp_volume(0, 0, 0, 0);
|
||||||
|
|
||||||
ac_io_emu_response_push(emu, &resp, 0);
|
ac_io_emu_response_push(emu, &resp, 0);
|
||||||
}
|
}
|
||||||
|
@ -11,3 +11,4 @@ EXPORTS
|
|||||||
sdvx_io_set_loggers
|
sdvx_io_set_loggers
|
||||||
sdvx_io_set_pwm_light
|
sdvx_io_set_pwm_light
|
||||||
sdvx_io_write_output
|
sdvx_io_write_output
|
||||||
|
sdvx_io_set_amp_volume
|
||||||
|
@ -31,6 +31,7 @@ static uint16_t sdvx_io_analog[2];
|
|||||||
|
|
||||||
static bool running;
|
static bool running;
|
||||||
static bool processing_io;
|
static bool processing_io;
|
||||||
|
static int16_t kfca_node_id;
|
||||||
|
|
||||||
struct ac_io_kfca_poll_out pout_staging;
|
struct ac_io_kfca_poll_out pout_staging;
|
||||||
struct ac_io_kfca_poll_out pout_ready;
|
struct ac_io_kfca_poll_out pout_ready;
|
||||||
@ -86,7 +87,7 @@ bool sdvx_io_init(
|
|||||||
uint8_t node_count = aciodrv_device_get_node_count();
|
uint8_t node_count = aciodrv_device_get_node_count();
|
||||||
log_info("Enumerated %d nodes", node_count);
|
log_info("Enumerated %d nodes", node_count);
|
||||||
|
|
||||||
int16_t kfca_node_id = -1;
|
kfca_node_id = -1;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < node_count; i++) {
|
for (uint8_t i = 0; i < node_count; i++) {
|
||||||
char product[4];
|
char product[4];
|
||||||
@ -109,7 +110,11 @@ bool sdvx_io_init(
|
|||||||
|
|
||||||
if (kfca_node_id != -1) {
|
if (kfca_node_id != -1) {
|
||||||
log_warning("Using KFCA on node: %d", kfca_node_id);
|
log_warning("Using KFCA on node: %d", kfca_node_id);
|
||||||
aciodrv_kfca_init(kfca_node_id);
|
|
||||||
|
if (!aciodrv_kfca_init(kfca_node_id)) {
|
||||||
|
log_warning("Unable to start KFCA on node: %d", kfca_node_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
log_warning("sdvxio-kfca now running");
|
log_warning("sdvxio-kfca now running");
|
||||||
@ -155,7 +160,7 @@ bool sdvx_io_read_input(void)
|
|||||||
}
|
}
|
||||||
processing_io = true;
|
processing_io = true;
|
||||||
|
|
||||||
if (!aciodrv_kfca_poll(0, &pout_ready, &pin)) {
|
if (!aciodrv_kfca_poll(kfca_node_id, &pout_ready, &pin)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,3 +204,19 @@ uint16_t sdvx_io_get_spinner_pos(uint8_t spinner_no)
|
|||||||
}
|
}
|
||||||
return sdvx_io_analog[spinner_no];
|
return sdvx_io_analog[spinner_no];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sdvx_io_set_amp_volume(
|
||||||
|
uint8_t primary,
|
||||||
|
uint8_t headphone,
|
||||||
|
uint8_t subwoofer)
|
||||||
|
{
|
||||||
|
if (!running) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aciodrv_kfca_amp(kfca_node_id, primary, 96, headphone, subwoofer)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -88,3 +88,8 @@ uint16_t sdvx_io_get_spinner_pos(uint8_t spinner_no)
|
|||||||
{
|
{
|
||||||
return mapper_read_analog(spinner_no) * 4;
|
return mapper_read_analog(spinner_no) * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sdvx_io_set_amp_volume(uint8_t primary, uint8_t headphone, uint8_t subwoofer)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -11,3 +11,4 @@ EXPORTS
|
|||||||
sdvx_io_set_loggers
|
sdvx_io_set_loggers
|
||||||
sdvx_io_set_pwm_light
|
sdvx_io_set_pwm_light
|
||||||
sdvx_io_write_output
|
sdvx_io_write_output
|
||||||
|
sdvx_io_set_amp_volume
|
||||||
|
Loading…
Reference in New Issue
Block a user