segatools/chuniio/chuniio.c

178 lines
3.9 KiB
C
Raw Normal View History

2019-05-03 02:12:06 +00:00
#include <windows.h>
#include <process.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
2019-05-03 02:12:06 +00:00
#include "chuniio/chuniio.h"
2019-11-17 18:11:49 +00:00
#include "chuniio/config.h"
#include "chuniio/ledoutput.h"
2019-05-03 02:12:06 +00:00
#include "util/dprintf.h"
2019-05-03 02:12:06 +00:00
static unsigned int __stdcall chuni_io_slider_thread_proc(void *ctx);
static bool chuni_io_coin;
static uint16_t chuni_io_coins;
static uint8_t chuni_io_hand_pos;
static HANDLE chuni_io_slider_thread;
static bool chuni_io_slider_stop_flag;
2019-11-17 18:11:49 +00:00
static struct chuni_io_config chuni_io_cfg;
2019-05-03 02:12:06 +00:00
uint16_t chuni_io_get_api_version(void)
{
return 0x0102;
}
2019-11-03 18:01:03 +00:00
HRESULT chuni_io_jvs_init(void)
2019-05-03 02:12:06 +00:00
{
2019-11-17 18:11:49 +00:00
chuni_io_config_load(&chuni_io_cfg, L".\\segatools.ini");
led_init_mutex = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
NULL); // unnamed mutex
if (led_init_mutex == NULL)
{
return E_FAIL;
}
2019-05-03 02:12:06 +00:00
return S_OK;
}
void chuni_io_jvs_read_coin_counter(uint16_t *out)
2019-05-03 02:12:06 +00:00
{
if (out == NULL) {
return;
}
if (GetAsyncKeyState(chuni_io_cfg.vk_coin) & 0x8000) {
2019-05-03 02:12:06 +00:00
if (!chuni_io_coin) {
chuni_io_coin = true;
chuni_io_coins++;
}
} else {
chuni_io_coin = false;
}
*out = chuni_io_coins;
2019-05-03 02:12:06 +00:00
}
void chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams)
{
size_t i;
if (GetAsyncKeyState(chuni_io_cfg.vk_test) & 0x8000) {
*opbtn |= CHUNI_IO_OPBTN_TEST;
2019-05-03 02:12:06 +00:00
}
if (GetAsyncKeyState(chuni_io_cfg.vk_service) & 0x8000) {
*opbtn |= CHUNI_IO_OPBTN_SERVICE;
2019-05-03 02:12:06 +00:00
}
if (chuni_io_cfg.vk_ir_emu) {
// Use emulated AIR
if (GetAsyncKeyState(chuni_io_cfg.vk_ir_emu)) {
if (chuni_io_hand_pos < 6) {
chuni_io_hand_pos++;
}
} else {
if (chuni_io_hand_pos > 0) {
chuni_io_hand_pos--;
}
}
for (i = 0 ; i < 6 ; i++) {
if (chuni_io_hand_pos > i) {
*beams |= (1 << i);
}
}
} else {
// Use actual AIR
// IR format is beams[5:0] = {b5,b6,b3,b4,b1,b2};
for (i = 0 ; i < 3 ; i++) {
if (GetAsyncKeyState(chuni_io_cfg.vk_ir[i*2]) & 0x8000)
*beams |= (1 << (i*2+1));
if (GetAsyncKeyState(chuni_io_cfg.vk_ir[i*2+1]) & 0x8000)
*beams |= (1 << (i*2));
2019-05-03 02:12:06 +00:00
}
}
}
2019-11-03 18:01:03 +00:00
HRESULT chuni_io_slider_init(void)
{
return led_output_init(&chuni_io_cfg); // because of slider LEDs
2019-11-03 18:01:03 +00:00
}
2019-05-03 02:12:06 +00:00
void chuni_io_slider_start(chuni_io_slider_callback_t callback)
{
BOOL status;
2019-05-03 02:12:06 +00:00
if (chuni_io_slider_thread != NULL) {
return;
}
chuni_io_slider_thread = (HANDLE) _beginthreadex(
NULL,
0,
chuni_io_slider_thread_proc,
callback,
0,
NULL);
}
void chuni_io_slider_stop(void)
{
if (chuni_io_slider_thread == NULL) {
return;
}
chuni_io_slider_stop_flag = true;
WaitForSingleObject(chuni_io_slider_thread, INFINITE);
CloseHandle(chuni_io_slider_thread);
chuni_io_slider_thread = NULL;
chuni_io_slider_stop_flag = false;
}
void chuni_io_slider_set_leds(const uint8_t *rgb)
{
led_output_update(2, rgb);
2019-05-03 02:12:06 +00:00
}
static unsigned int __stdcall chuni_io_slider_thread_proc(void *ctx)
{
chuni_io_slider_callback_t callback;
uint8_t pressure[32];
size_t i;
callback = ctx;
while (!chuni_io_slider_stop_flag) {
2019-11-17 18:11:49 +00:00
for (i = 0 ; i < _countof(pressure) ; i++) {
if (GetAsyncKeyState(chuni_io_cfg.vk_cell[i]) & 0x8000) {
pressure[i] = 128;
2019-05-03 02:12:06 +00:00
} else {
2019-11-17 18:11:49 +00:00
pressure[i] = 0;
2019-05-03 02:12:06 +00:00
}
}
callback(pressure);
Sleep(1);
}
return 0;
}
HRESULT chuni_io_led_init(void)
{
return led_output_init(&chuni_io_cfg);
}
void chuni_io_led_set_colors(uint8_t board, uint8_t *rgb)
{
led_output_update(board, rgb);
}