From b8f1f6ea73f8e92bc52f6c363203ebe83128b4ba Mon Sep 17 00:00:00 2001 From: akiroz Date: Fri, 18 Mar 2022 23:47:25 +0800 Subject: [PATCH] Fix DllMain init for chuni --- src/main.zig | 74 ++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/src/main.zig b/src/main.zig index 3875404..8b8a8b6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -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;