Fix DllMain init for chuni

This commit is contained in:
akiroz 2022-03-18 23:47:25 +08:00
parent d8793be61e
commit b8f1f6ea73
No known key found for this signature in database
GPG Key ID: 8A5957C4A2F68ACC

View File

@ -56,6 +56,7 @@ var slider_active = false;
var slider_thread: ?std.Thread = null;
var input_thread: ?std.Thread = null;
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var usb_out_op = std.Thread.Mutex{};
var usb_out = std.mem.zeroes([80*3]u8);
var usb_in: ?[]u8 = null;
@ -63,7 +64,6 @@ var tasoller: ?*anyopaque = null;
// Test program
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
usb_in = try gpa.allocator().alloc(u8, 0x24);
var i: u32 = 0;
try tasoller_init();
@ -142,6 +142,11 @@ fn tasoller_init() !void {
// Init magic bytes
std.mem.copy(u8, usb_out[0..3], &[_]u8{0x42, 0x4C, 0x00});
input_thread = std.Thread.spawn(.{}, input_thread_proc, .{}) catch |err| {
std.log.err("[chuniio] Spawn input thread: {any}", .{err});
return error.AccessError;
};
}
// Poll input regardless of slider start/stop
@ -149,7 +154,7 @@ fn input_thread_proc() void {
std.log.info("[chuniio] Input thread started", .{});
while(true) {
var len: u32 = 0;
if(WinUsb_ReadPipe(tasoller, 0x84, @ptrCast(*u8, usb_in.?.ptr), usb_in.?.len, &len, null) == 0) {
if(WinUsb_ReadPipe(tasoller, 0x84, @ptrCast(*u8, usb_in.?.ptr), @intCast(u32, usb_in.?.len), &len, null) == 0) {
std.log.warn("[chuniio] WinUsb_ReadPipe: {any}", .{GetLastError()});
}
}
@ -179,11 +184,10 @@ export fn chuni_io_get_api_version() c_ushort {
pub export fn DllMain(hDllHandle: HANDLE, dwReason: DWORD, lpreserved: LPVOID) BOOL {
_ = hDllHandle;
_ = lpreserved;
if(dwReason != DLL_PROCESS_ATTACH) return win32.zig.TRUE;
std.log.info("[chuniio] Initializing", .{});
const cfg_file = ".\\segatools.ini";
std.log.info("[chuniio] Loading config from {s}", .{cfg_file});
cfg = .{
.test_key = @intCast(i32, GetPrivateProfileIntA("io3", "test", 0x31, cfg_file)),
.serv_key = @intCast(i32, GetPrivateProfileIntA("io3", "service", 0x32, cfg_file)),
@ -191,46 +195,47 @@ pub export fn DllMain(hDllHandle: HANDLE, dwReason: DWORD, lpreserved: LPVOID) B
.chusan = @intCast(i32, GetPrivateProfileIntA("chuniio", "chusan", 0, cfg_file)),
};
if(cfg.?.chusan == 0) {
std.log.info("[chuniio] Mode: chuni", .{});
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
usb_in = gpa.allocator().alloc(u8, 0x24) catch |err| {
std.log.err("[chuniio] alloc: {any}", .{err});
return win32.zig.FALSE;
};
} else {
std.log.info("[chuniio] Mode: chusan", .{});
const szName = W("Global\\ChuniioTasoller");
const hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, null, PAGE_READWRITE, 0, 0x24, szName) orelse {
std.log.err("[chuniio] CreateFileMapping: {any}", .{GetLastError()});
return win32.zig.FALSE;
};
const pBuf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0x24) orelse {
std.log.err("[chuniio] MapViewOfFile: {any}", .{GetLastError()});
return win32.zig.FALSE;
};
usb_in = @ptrCast([*]u8, pBuf)[0..0x24];
}
// Chuni mode must not init at DllMain
if(cfg.?.chusan == 0) return win32.zig.TRUE;
std.log.info("[chuniio] Initializing mode: chusan", .{});
const szName = W("Global\\ChuniioTasoller");
const hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, null, PAGE_READWRITE, 0, 0x24, szName) orelse {
std.log.err("[chuniio] CreateFileMapping: {any}", .{GetLastError()});
return win32.zig.FALSE;
};
const pBuf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0x24) orelse {
std.log.err("[chuniio] MapViewOfFile: {any}", .{GetLastError()});
return win32.zig.FALSE;
};
usb_in = @ptrCast([*]u8, pBuf)[0..0x24];
if(builtin.cpu.arch == .i386) {
tasoller_init() catch {
return win32.zig.FALSE;
};
input_thread = std.Thread.spawn(.{}, input_thread_proc, .{}) catch |err| {
std.log.err("[chuniio] Spawn input thread: {any}", .{err});
return win32.zig.FALSE;
};
}
return win32.zig.TRUE;
}
export fn chuni_io_jvs_init() HRESULT {
if(cfg.?.chusan == 1) return S_OK;
std.log.info("[chuniio] Initializing mode: chuni", .{});
usb_in = gpa.allocator().alloc(u8, 0x24) catch |err| {
std.log.err("[chuniio] alloc: {any}", .{err});
return E_FAIL;
};
tasoller_init() catch {
return E_FAIL;
};
return S_OK;
}
export fn chuni_io_jvs_poll(opbtn: ?[*]u8, beams: ?[*]u8) void {
if(cfg.?.chusan != 0 and builtin.cpu.arch != .x86_64) return;
if(cfg.?.chusan == 1 and builtin.cpu.arch != .x86_64) return;
if(opbtn == null or beams == null) return;
if(GetAsyncKeyState(cfg.?.test_key) != 0 or (usb_in.?[3] & (1 << 7)) != 0) opbtn.?.* |= (1 << 0);
if(GetAsyncKeyState(cfg.?.test_key) != 0 or (usb_in.?[3] & (1 << 6)) != 0) opbtn.?.* |= (1 << 1);
@ -240,8 +245,9 @@ export fn chuni_io_jvs_poll(opbtn: ?[*]u8, beams: ?[*]u8) void {
var coin_conter: c_ushort = 0;
var coin_prev_depressed = false;
export fn chuni_io_jvs_read_coin_counter(total: ?*c_ushort) void {
if(cfg.?.chusan != 0 and builtin.cpu.arch != .x86_64) return;
if(cfg.?.chusan == 1 and builtin.cpu.arch != .x86_64) return;
if(total == null) return;
const coin_depressed = GetAsyncKeyState(cfg.?.coin_key) != 0;
if(coin_depressed and !coin_prev_depressed) coin_conter += 1;
coin_prev_depressed = coin_depressed;
@ -253,7 +259,7 @@ export fn chuni_io_slider_init() HRESULT {
}
export fn chuni_io_slider_start(callback: chuni_io_slider_callback_t) void {
if(cfg.?.chusan != 0 and builtin.cpu.arch != .i386) return;
if(cfg.?.chusan == 1 and builtin.cpu.arch != .i386) return;
if(callback == null) return;
thread_op.lock();
@ -268,7 +274,7 @@ export fn chuni_io_slider_start(callback: chuni_io_slider_callback_t) void {
}
export fn chuni_io_slider_stop() void {
if(cfg.?.chusan != 0 and builtin.cpu.arch != .i386) return;
if(cfg.?.chusan == 1 and builtin.cpu.arch != .i386) return;
thread_op.lock();
defer thread_op.unlock();
@ -280,7 +286,7 @@ export fn chuni_io_slider_stop() void {
}
export fn chuni_io_slider_set_leds(rgb: ?[*]u8) void {
if(cfg.?.chusan != 0 and builtin.cpu.arch != .i386) return;
if(cfg.?.chusan == 1 and builtin.cpu.arch != .i386) return;
if(rgb == null) return;
var n: u32 = 0;