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