mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-17 11:18:31 +01:00
feat(ddrio-p3io): Add ddrio API implementation for DDR P3IO
Also includes EXTIO. Run a SD style cabinet with bemanitools ddrio API.
This commit is contained in:
parent
3a89502498
commit
0961bae99f
@ -104,6 +104,7 @@ include src/main/d3d9exhook/Module.mk
|
||||
include src/main/ddrhook-util/Module.mk
|
||||
include src/main/ddrhook1/Module.mk
|
||||
include src/main/ddrhook2/Module.mk
|
||||
include src/main/ddrio-p3io/Module.mk
|
||||
include src/main/ddrio-mm/Module.mk
|
||||
include src/main/ddrio-smx/Module.mk
|
||||
include src/main/ddrio/Module.mk
|
||||
|
16
src/main/ddrio-p3io/Module.mk
Normal file
16
src/main/ddrio-p3io/Module.mk
Normal file
@ -0,0 +1,16 @@
|
||||
dlls += ddrio-p3io
|
||||
|
||||
ldflags_ddrio-p3io:= \
|
||||
-lsetupapi \
|
||||
|
||||
libs_ddrio-p3io := \
|
||||
cconfig \
|
||||
extio \
|
||||
extiodrv \
|
||||
p3io \
|
||||
p3iodrv \
|
||||
util \
|
||||
|
||||
src_ddrio-p3io := \
|
||||
config.c \
|
||||
ddrio.c \
|
35
src/main/ddrio-p3io/config.c
Normal file
35
src/main/ddrio-p3io/config.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include "cconfig/cconfig-util.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define DDRIO_P3IO_CONFIG_EXTIO_PORT_KEY "ddrio.p3io.extio_port"
|
||||
|
||||
#define DDRIO_P3IO_CONFIG_EXTIO_PORT_VALUE "COM1"
|
||||
|
||||
void ddrio_p3io_config_init(struct cconfig *config)
|
||||
{
|
||||
cconfig_util_set_str(
|
||||
config,
|
||||
DDRIO_P3IO_CONFIG_EXTIO_PORT_KEY,
|
||||
DDRIO_P3IO_CONFIG_EXTIO_PORT_VALUE,
|
||||
"COM port the EXTIO is connected to, default COM1");
|
||||
}
|
||||
|
||||
void ddrio_p3io_config_get(
|
||||
struct ddrio_p3io_config *config_ddrio_p3io, struct cconfig *config)
|
||||
{
|
||||
if (!cconfig_util_get_str(
|
||||
config,
|
||||
DDRIO_P3IO_CONFIG_EXTIO_PORT_KEY,
|
||||
config_ddrio_p3io->extio_port,
|
||||
sizeof(config_ddrio_p3io->extio_port) - 1,
|
||||
DDRIO_P3IO_CONFIG_EXTIO_PORT_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%s'",
|
||||
DDRIO_P3IO_CONFIG_EXTIO_PORT_KEY,
|
||||
DDRIO_P3IO_CONFIG_EXTIO_PORT_VALUE);
|
||||
}
|
||||
}
|
17
src/main/ddrio-p3io/config.h
Normal file
17
src/main/ddrio-p3io/config.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef DDRIO_P3IO_CONFIG_H
|
||||
#define DDRIO_P3IO_CONFIG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "cconfig/cconfig.h"
|
||||
|
||||
struct ddrio_p3io_config {
|
||||
char extio_port[12];
|
||||
};
|
||||
|
||||
void ddrio_p3io_config_init(struct cconfig *config);
|
||||
|
||||
void ddrio_p3io_config_get(
|
||||
struct ddrio_p3io_config *config_ddrio_p3io, struct cconfig *config);
|
||||
|
||||
#endif
|
11
src/main/ddrio-p3io/ddrio-p3io.def
Normal file
11
src/main/ddrio-p3io/ddrio-p3io.def
Normal file
@ -0,0 +1,11 @@
|
||||
LIBRARY ddrio-p3io
|
||||
|
||||
EXPORTS
|
||||
ddr_io_set_loggers
|
||||
ddr_io_fini
|
||||
ddr_io_init
|
||||
ddr_io_read_pad
|
||||
ddr_io_set_lights_extio
|
||||
ddr_io_set_lights_p3io
|
||||
ddr_io_set_lights_hdxs_panel
|
||||
ddr_io_set_lights_hdxs_rgb
|
427
src/main/ddrio-p3io/ddrio.c
Normal file
427
src/main/ddrio-p3io/ddrio.c
Normal file
@ -0,0 +1,427 @@
|
||||
#define LOG_MODULE "ddrio-p3io"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bemanitools/ddrio.h"
|
||||
|
||||
#include "cconfig/cconfig-main.h"
|
||||
|
||||
#include "extiodrv/device.h"
|
||||
#include "extiodrv/extio.h"
|
||||
|
||||
#include "p3iodrv/ddr.h"
|
||||
#include "p3iodrv/device.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/thread.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
static struct ddrio_p3io_config _ddr_io_p3io_config;
|
||||
static HANDLE _ddr_io_p3io_handle;
|
||||
static HANDLE _ddr_io_extio_handle;
|
||||
|
||||
static HRESULT _ddr_io_p3io_scan_and_open(HANDLE *handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
char path[MAX_PATH];
|
||||
|
||||
log_info("Scanning for p3io...");
|
||||
|
||||
hr = p3iodrv_device_scan(path);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Cannot find a connected p3io: %lX", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
log_info("Opening p3io: %s", path);
|
||||
|
||||
hr = p3iodrv_device_open(path, handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Opening p3io failed: %lX", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_p3io_print_version(HANDLE handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
char version[P3IODRV_VERSION_MAX_LEN];
|
||||
|
||||
memset(version, 0, P3IODRV_VERSION_MAX_LEN);
|
||||
|
||||
hr = p3iodrv_device_read_version(handle, version);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Getting p3io version failed: %lX", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
log_info("P3IO version: %s", version);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_ddr_p3io_print_version(HANDLE handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
char str[4];
|
||||
uint32_t major;
|
||||
uint32_t minor;
|
||||
uint32_t patch;
|
||||
|
||||
hr = p3iodrv_ddr_get_version(handle, str, &major, &minor, &patch);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Getting version failed: %lX", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
log_info("DDR version: %s %d.%d.%d", str, major, minor, patch);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_ddr_p3io_print_cabinet_type(HANDLE handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
enum p3io_cab_type type;
|
||||
|
||||
hr = p3iodrv_ddr_get_cab_type(handle, &type);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Getting cab type failed: %lX", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
log_info("Cabinet type: %d", type);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_ddr_p3io_print_dip_switches(HANDLE handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
uint8_t dip_sw;
|
||||
|
||||
hr = p3iodrv_ddr_get_dipsw(handle, &dip_sw);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Getting dip switches failed");
|
||||
return hr;
|
||||
}
|
||||
|
||||
log_info("Dip switches: 0x%X", dip_sw);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_ddr_p3io_print_video_freq(HANDLE handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
enum p3io_video_freq video_freq;
|
||||
|
||||
hr = p3iodrv_ddr_get_video_freq(handle, &video_freq);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Getting video freq failed");
|
||||
return hr;
|
||||
}
|
||||
|
||||
log_info("Video freq: 0x%X", video_freq);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_ddr_p3io_print_debug_info(HANDLE handle)
|
||||
{
|
||||
return _ddr_io_p3io_print_version(handle) &&
|
||||
_ddr_io_ddr_p3io_print_version(handle) &&
|
||||
_ddr_io_ddr_p3io_print_cabinet_type(handle) &&
|
||||
_ddr_io_ddr_p3io_print_dip_switches(handle) &&
|
||||
_ddr_io_ddr_p3io_print_video_freq(handle);
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_p3io_init(HANDLE *handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
log_info("Initializing DDR P3IO...");
|
||||
|
||||
hr = _ddr_io_p3io_scan_and_open(handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = p3iodrv_ddr_init(*handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = _ddr_io_ddr_p3io_print_debug_info(*handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_p3io_close(HANDLE *handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
log_info("Closing p3io...");
|
||||
|
||||
hr = p3iodrv_device_close(handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Closing p3io failed: %lX", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_extio_init(HANDLE *handle)
|
||||
{
|
||||
log_info("Initializing EXTIO...");
|
||||
|
||||
return extiodrv_device_open(_ddr_io_p3io_config.extio_port, handle);
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_extio_close(HANDLE *handle)
|
||||
{
|
||||
log_info("Closing EXTIO...");
|
||||
|
||||
return extiodrv_device_close(handle);
|
||||
}
|
||||
|
||||
static HRESULT _ddr_io_flush_and_reset(HANDLE p3io_handle, HANDLE extio_handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
struct p3io_ddr_jamma jamma;
|
||||
struct p3io_ddr_output output;
|
||||
struct extiodrv_extio_pad_lights pad_lights[2];
|
||||
bool neons;
|
||||
|
||||
log_assert(p3io_handle != INVALID_HANDLE_VALUE);
|
||||
log_assert(extio_handle != INVALID_HANDLE_VALUE);
|
||||
|
||||
log_info("Flushing inputs and outputs");
|
||||
|
||||
memset(&output, 0, sizeof(output));
|
||||
memset(&pad_lights, 0, sizeof(pad_lights));
|
||||
neons = false;
|
||||
|
||||
hr = p3iodrv_ddr_get_jamma(p3io_handle, &jamma);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Reading jamma failed");
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = p3iodrv_ddr_set_outputs(p3io_handle, &output);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Settings outputs failed");
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = extiodrv_extio_transfer(
|
||||
extio_handle, EXTIODRV_EXTIO_SENSOR_READ_MODE_ALL, pad_lights, neons);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("EXTIO transfer failed");
|
||||
return hr;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void ddr_io_set_loggers(
|
||||
log_formatter_t misc,
|
||||
log_formatter_t info,
|
||||
log_formatter_t warning,
|
||||
log_formatter_t fatal)
|
||||
{
|
||||
log_to_external(misc, info, warning, fatal);
|
||||
}
|
||||
|
||||
static void _ddr_io_config_init(struct ddrio_p3io_config *config_ddrio_p3io)
|
||||
{
|
||||
struct cconfig *config;
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
ddrio_p3io_config_init(config);
|
||||
|
||||
if (!cconfig_main_config_init(
|
||||
config,
|
||||
"--ddrio-p3io-config",
|
||||
"ddrio-p3io.conf",
|
||||
"--help",
|
||||
"-h",
|
||||
"ddrio-p3io",
|
||||
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
|
||||
cconfig_finit(config);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ddrio_p3io_config_get(config_ddrio_p3io, config);
|
||||
|
||||
cconfig_finit(config);
|
||||
}
|
||||
|
||||
bool ddr_io_init(
|
||||
thread_create_t thread_create,
|
||||
thread_join_t thread_join,
|
||||
thread_destroy_t thread_destroy)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
_ddr_io_config_init(&_ddr_io_p3io_config);
|
||||
|
||||
hr = _ddr_io_p3io_init(&_ddr_io_p3io_handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = _ddr_io_extio_init(&_ddr_io_extio_handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = _ddr_io_flush_and_reset(_ddr_io_p3io_handle, _ddr_io_extio_handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t ddr_io_read_pad(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
struct p3io_ddr_jamma jamma;
|
||||
|
||||
hr = p3iodrv_ddr_get_jamma(_ddr_io_p3io_handle, &jamma);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Reading jamma failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _byteswap_ulong(*((uint32_t *) &jamma));
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_extio(uint32_t extio_lights)
|
||||
{
|
||||
HRESULT hr;
|
||||
struct extiodrv_extio_pad_lights pad_lights[EXTIO_PAD_LIGHT_MAX_PLAYERS];
|
||||
bool neons;
|
||||
|
||||
pad_lights[0].up = (extio_lights & (1 << LIGHT_P1_UP)) > 0;
|
||||
pad_lights[0].down = (extio_lights & (1 << LIGHT_P1_DOWN)) > 0;
|
||||
pad_lights[0].left = (extio_lights & (1 << LIGHT_P1_LEFT)) > 0;
|
||||
pad_lights[0].right = (extio_lights & (1 << LIGHT_P1_RIGHT)) > 0;
|
||||
|
||||
pad_lights[1].up = (extio_lights & (1 << LIGHT_P2_UP)) > 0;
|
||||
pad_lights[1].down = (extio_lights & (1 << LIGHT_P2_DOWN)) > 0;
|
||||
pad_lights[1].left = (extio_lights & (1 << LIGHT_P2_LEFT)) > 0;
|
||||
pad_lights[1].right = (extio_lights & (1 << LIGHT_P2_RIGHT)) > 0;
|
||||
|
||||
neons = (extio_lights & (1 << LIGHT_NEONS)) > 0;
|
||||
|
||||
hr = extiodrv_extio_transfer(
|
||||
_ddr_io_extio_handle,
|
||||
EXTIODRV_EXTIO_SENSOR_READ_MODE_ALL,
|
||||
pad_lights,
|
||||
neons);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("EXTIO transfer failed: %lX", hr);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_p3io(uint32_t p3io_lights)
|
||||
{
|
||||
HRESULT hr;
|
||||
struct p3io_ddr_output output;
|
||||
|
||||
output.cabinet.top_p1_lower =
|
||||
(p3io_lights & (1 << LIGHT_P1_LOWER_LAMP)) > 0 ? 1 : 0;
|
||||
output.cabinet.top_p1_upper =
|
||||
(p3io_lights & (1 << LIGHT_P1_UPPER_LAMP)) > 0 ? 1 : 0;
|
||||
output.cabinet.top_p2_lower =
|
||||
(p3io_lights & (1 << LIGHT_P2_LOWER_LAMP)) > 0 ? 1 : 0;
|
||||
output.cabinet.top_p2_upper =
|
||||
(p3io_lights & (1 << LIGHT_P2_UPPER_LAMP)) > 0 ? 1 : 0;
|
||||
|
||||
output.cabinet.p1_menu_buttons =
|
||||
(p3io_lights & (1 << LIGHT_P1_MENU)) > 0 ? 1 : 0;
|
||||
output.cabinet.p2_menu_buttons =
|
||||
(p3io_lights & (1 << LIGHT_P2_MENU)) > 0 ? 1 : 0;
|
||||
|
||||
hr = p3iodrv_ddr_set_outputs(_ddr_io_p3io_handle, &output);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Settings outputs failed: %lX", hr);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_panel(uint32_t lights)
|
||||
{
|
||||
// Unused
|
||||
|
||||
(void) lights;
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
// Unused
|
||||
|
||||
(void) idx;
|
||||
(void) r;
|
||||
(void) g;
|
||||
(void) b;
|
||||
}
|
||||
|
||||
void ddr_io_fini(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = _ddr_io_flush_and_reset(_ddr_io_p3io_handle, _ddr_io_extio_handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Flusing IO failed: %lX", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = _ddr_io_p3io_close(&_ddr_io_p3io_handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Closing P3IO failed: %lX", hr);
|
||||
// continue
|
||||
}
|
||||
|
||||
hr = _ddr_io_extio_close(&_ddr_io_extio_handle);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning("Closing EXTIO failed: %lX", hr);
|
||||
// continue
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user