mirror of
https://gitea.tendokyu.moe/Hay1tsme/segatools.git
synced 2026-06-02 22:27:15 -05:00
diva: add partition and button LED support
This commit is contained in:
parent
ce77d60905
commit
e4bd0543c9
|
|
@ -30,9 +30,28 @@ const struct dll_bind_sym diva_dll_syms[] = {
|
||||||
}, {
|
}, {
|
||||||
.sym = "diva_io_slider_set_leds",
|
.sym = "diva_io_slider_set_leds",
|
||||||
.off = offsetof(struct diva_dll, slider_set_leds),
|
.off = offsetof(struct diva_dll, slider_set_leds),
|
||||||
|
}, {
|
||||||
|
.sym = "diva_io_led_init",
|
||||||
|
.off = offsetof(struct diva_dll, led_init),
|
||||||
|
}, {
|
||||||
|
.sym = "diva_io_led_set_leds",
|
||||||
|
.off = offsetof(struct diva_dll, led_set_leds),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Helper function to determine upon dll_bind failure whether the required functions were found
|
||||||
|
NOTE: relies on symbols order declared above */
|
||||||
|
static HRESULT has_enough_symbols(uint16_t version, uint8_t count)
|
||||||
|
{
|
||||||
|
if ( version < 0x0101 && count == 7 )
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
if ( version >= 0x0101 && count == 9 )
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
struct diva_dll diva_dll;
|
struct diva_dll diva_dll;
|
||||||
|
|
||||||
// Copypasta DLL binding and diagnostic message boilerplate.
|
// Copypasta DLL binding and diagnostic message boilerplate.
|
||||||
|
|
@ -92,16 +111,24 @@ HRESULT diva_dll_init(const struct diva_dll_config *cfg, HINSTANCE self)
|
||||||
}
|
}
|
||||||
|
|
||||||
sym = diva_dll_syms;
|
sym = diva_dll_syms;
|
||||||
|
const struct dll_bind_sym *init_sym = &sym[0];
|
||||||
hr = dll_bind(&diva_dll, src, &sym, _countof(diva_dll_syms));
|
hr = dll_bind(&diva_dll, src, &sym, _countof(diva_dll_syms));
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
if (src != self) {
|
if (src != self) {
|
||||||
dprintf("Diva IO: Custom IO DLL does not provide function "
|
// Might still be ok depending on external dll API version
|
||||||
"\"%s\". Please contact your IO DLL's developer for "
|
int bind_count = sym - init_sym;
|
||||||
"further assistance.\n",
|
if ( has_enough_symbols(diva_dll.api_version, bind_count) == S_OK )
|
||||||
sym->sym);
|
{
|
||||||
|
hr = S_OK;
|
||||||
|
} else {
|
||||||
|
dprintf("Diva IO: Custom IO DLL does not provide function "
|
||||||
|
"\"%s\". Please contact your IO DLL's developer for "
|
||||||
|
"further assistance.\n",
|
||||||
|
sym->sym);
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ struct diva_dll {
|
||||||
void (*slider_start)(diva_io_slider_callback_t callback);
|
void (*slider_start)(diva_io_slider_callback_t callback);
|
||||||
void (*slider_stop)(void);
|
void (*slider_stop)(void);
|
||||||
void (*slider_set_leds)(const uint8_t *rgb);
|
void (*slider_set_leds)(const uint8_t *rgb);
|
||||||
|
HRESULT (*led_init)(void);
|
||||||
|
void (*led_set_leds)(uint8_t board, const uint8_t *rgb);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct diva_dll_config {
|
struct diva_dll_config {
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,5 @@ EXPORTS
|
||||||
diva_io_slider_set_leds
|
diva_io_slider_set_leds
|
||||||
diva_io_slider_start
|
diva_io_slider_start
|
||||||
diva_io_slider_stop
|
diva_io_slider_stop
|
||||||
|
diva_io_led_init
|
||||||
|
diva_io_led_set_leds
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,12 @@ static void diva_jvs_read_coin_counter(
|
||||||
void *ctx,
|
void *ctx,
|
||||||
uint8_t slot_no,
|
uint8_t slot_no,
|
||||||
uint16_t *out);
|
uint16_t *out);
|
||||||
|
static void diva_jvs_write_gpio(void *ctx, uint32_t state);
|
||||||
|
|
||||||
static const struct io3_ops diva_jvs_io3_ops = {
|
static const struct io3_ops diva_jvs_io3_ops = {
|
||||||
.read_switches = diva_jvs_read_switches,
|
.read_switches = diva_jvs_read_switches,
|
||||||
.read_coin_counter = diva_jvs_read_coin_counter,
|
.read_coin_counter = diva_jvs_read_coin_counter,
|
||||||
|
.write_gpio = diva_jvs_write_gpio
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct io3 diva_jvs_io3;
|
static struct io3 diva_jvs_io3;
|
||||||
|
|
@ -107,3 +109,26 @@ static void diva_jvs_read_coin_counter(
|
||||||
|
|
||||||
diva_dll.jvs_read_coin_counter(out);
|
diva_dll.jvs_read_coin_counter(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void diva_jvs_write_gpio(void *ctx, uint32_t state)
|
||||||
|
{
|
||||||
|
assert(diva_dll.led_set_leds != NULL);
|
||||||
|
|
||||||
|
// Since Sega uses an odd ordering for the first part of the bitfield,
|
||||||
|
// let's normalize the data and just send over bytes for the receiver
|
||||||
|
// to interpret as ON/OFF values.
|
||||||
|
uint8_t rgb_out[10] = {
|
||||||
|
state & DIVA_IO_LED_LEFT_PARTITION_RED ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_LEFT_PARTITION_GREEN ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_LEFT_PARTITION_BLUE ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_RIGHT_PARTITION_RED ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_RIGHT_PARTITION_GREEN ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_RIGHT_PARTITION_BLUE ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_BTN_TRIANGLE ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_BTN_CROSS ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_BTN_SQUARE ? 0xFF : 0x00,
|
||||||
|
state & DIVA_IO_LED_BTN_CIRCLE ? 0xFF : 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
diva_dll.led_set_leds(0, rgb_out);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@
|
||||||
|
|
||||||
#include "divaio/divaio.h"
|
#include "divaio/divaio.h"
|
||||||
#include "divaio/config.h"
|
#include "divaio/config.h"
|
||||||
|
|
||||||
#include "util/env.h"
|
#include "util/env.h"
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
static unsigned int __stdcall diva_io_slider_thread_proc(void *ctx);
|
static unsigned int __stdcall diva_io_slider_thread_proc(void *ctx);
|
||||||
|
|
||||||
|
|
@ -19,7 +21,7 @@ static struct diva_io_config diva_io_cfg;
|
||||||
|
|
||||||
uint16_t diva_io_get_api_version(void)
|
uint16_t diva_io_get_api_version(void)
|
||||||
{
|
{
|
||||||
return 0x0100;
|
return 0x0101;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT diva_io_jvs_init(void)
|
HRESULT diva_io_jvs_init(void)
|
||||||
|
|
@ -132,3 +134,26 @@ static unsigned int __stdcall diva_io_slider_thread_proc(void *ctx)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT diva_io_led_init(void)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void diva_io_led_set_leds(uint8_t board, const uint8_t *rgb)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
dprintf("DIVA LED: LEFT PARTITION RED: %02X\n", rgb[0]);
|
||||||
|
dprintf("DIVA LED: LEFT PARTITION GREEN: %02X\n", rgb[1]);
|
||||||
|
dprintf("DIVA LED: LEFT PARTITION BLUE: %02X\n", rgb[2]);
|
||||||
|
dprintf("DIVA LED: RIGHT PARTITION RED: %02X\n", rgb[3]);
|
||||||
|
dprintf("DIVA LED: RIGHT PARTITION GREEN: %02X\n", rgb[4]);
|
||||||
|
dprintf("DIVA LED: RIGHT PARTITION BLUE: %02X\n", rgb[5]);
|
||||||
|
dprintf("DIVA LED: BTN TRIANGLE: %02X\n", rgb[6]);
|
||||||
|
dprintf("DIVA LED: BTN CROSS: %02X\n", rgb[7]);
|
||||||
|
dprintf("DIVA LED: BTN SQUARE: %02X\n", rgb[8]);
|
||||||
|
dprintf("DIVA LED: BTN CIRCLE: %02X\n", rgb[9]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,45 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
DIVA CUSTOM IO API
|
||||||
|
|
||||||
|
Changelog:
|
||||||
|
|
||||||
|
- 0x0100: Initial API version
|
||||||
|
- 0x0101: Add partition and button led support
|
||||||
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DIVA_IO_OPBTN_TEST = 0x01,
|
DIVA_IO_OPBTN_TEST = 0x01,
|
||||||
DIVA_IO_OPBTN_SERVICE = 0x02
|
DIVA_IO_OPBTN_SERVICE = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DIVA_IO_GAMEBTN_CIRCLE = 0x01,
|
DIVA_IO_GAMEBTN_CIRCLE = 0x01,
|
||||||
DIVA_IO_GAMEBTN_CROSS = 0x02,
|
DIVA_IO_GAMEBTN_CROSS = 0x02,
|
||||||
DIVA_IO_GAMEBTN_SQUARE = 0x04,
|
DIVA_IO_GAMEBTN_SQUARE = 0x04,
|
||||||
DIVA_IO_GAMEBTN_TRIANGLE = 0x08,
|
DIVA_IO_GAMEBTN_TRIANGLE = 0x08,
|
||||||
DIVA_IO_GAMEBTN_START = 0x10,
|
DIVA_IO_GAMEBTN_START = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* These are the bitmasks to use when checking which
|
||||||
|
lights are triggered on incoming IO3 GPIO writes. */
|
||||||
|
DIVA_IO_LED_LEFT_PARTITION_RED = 1 << 1,
|
||||||
|
DIVA_IO_LED_LEFT_PARTITION_GREEN = 1 << 0,
|
||||||
|
DIVA_IO_LED_LEFT_PARTITION_BLUE = 1 << 15,
|
||||||
|
DIVA_IO_LED_RIGHT_PARTITION_RED = 1 << 14,
|
||||||
|
DIVA_IO_LED_RIGHT_PARTITION_GREEN = 1 << 13,
|
||||||
|
DIVA_IO_LED_RIGHT_PARTITION_BLUE = 1 << 12,
|
||||||
|
DIVA_IO_LED_BTN_TRIANGLE = 1 << 6,
|
||||||
|
DIVA_IO_LED_BTN_CROSS = 1 << 3,
|
||||||
|
DIVA_IO_LED_BTN_SQUARE = 1 << 5,
|
||||||
|
DIVA_IO_LED_BTN_CIRCLE = 1 << 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get the version of the Project Diva IO API that this DLL supports. This
|
/* Get the version of the Project Diva IO API that this DLL supports. This
|
||||||
|
|
@ -118,3 +142,34 @@ void diva_io_slider_stop(void);
|
||||||
Minimum API version: 0x0100 */
|
Minimum API version: 0x0100 */
|
||||||
|
|
||||||
void diva_io_slider_set_leds(const uint8_t *rgb);
|
void diva_io_slider_set_leds(const uint8_t *rgb);
|
||||||
|
|
||||||
|
/* Initialize LED emulation. This function will be called before any
|
||||||
|
other diva_io_led_*() function calls.
|
||||||
|
|
||||||
|
All subsequent calls may originate from arbitrary threads and some may
|
||||||
|
overlap with each other. Ensuring synchronization inside your IO DLL is
|
||||||
|
your responsibility.
|
||||||
|
|
||||||
|
Minimum API version: 0x0101 */
|
||||||
|
|
||||||
|
HRESULT diva_io_led_init(void);
|
||||||
|
|
||||||
|
/* Update the cabinet button LEDs. rgb is a pointer to an array up to 10 bytes.
|
||||||
|
|
||||||
|
The LEDs are laid out as follows:
|
||||||
|
[0]: LEFT PARTITION RED LED
|
||||||
|
[1]: LEFT PARTITION GREEN LED
|
||||||
|
[2]: LEFT PARTITION BLUE LED
|
||||||
|
[3]: RIGHT PARTITION RED LED
|
||||||
|
[4]: RIGHT PARTITION GREEN LED
|
||||||
|
[5]: RIGHT PARTITION BLUE LED
|
||||||
|
[6]: BTN TRIANGLE LED
|
||||||
|
[7]: BTN CROSS LED
|
||||||
|
[8]: BTN SQUARE LED
|
||||||
|
[9]: BTN CIRCLE LED
|
||||||
|
|
||||||
|
The LED is turned on when the byte is 255 and turned off when the byte is 0.
|
||||||
|
|
||||||
|
Minimum API version: 0x0101 */
|
||||||
|
|
||||||
|
void diva_io_led_set_leds(uint8_t board, const uint8_t *rgb);
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@ static void idz_jvs_read_coin_counter(
|
||||||
|
|
||||||
idz_dll.jvs_read_coin_counter(out);
|
idz_dll.jvs_read_coin_counter(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void idz_jvs_write_gpio(void *ctx, uint32_t state)
|
static void idz_jvs_write_gpio(void *ctx, uint32_t state)
|
||||||
{
|
{
|
||||||
assert(idz_dll.led_set_leds != NULL);
|
assert(idz_dll.led_set_leds != NULL);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user