diff --git a/.vscode/settings.json b/.vscode/settings.json index 5a429d0..791c5a6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,8 @@ "limits": "c", "new": "c", "fumocommon.h": "c", - "input.h": "c" + "input.h": "c", + "bit": "cpp" }, "cmake.configureOnOpen": false } \ No newline at end of file diff --git a/a.exe b/a.exe new file mode 100644 index 0000000..66e640c Binary files /dev/null and b/a.exe differ diff --git a/binaryencoder.cpp b/binaryencoder.cpp new file mode 100644 index 0000000..b763e48 --- /dev/null +++ b/binaryencoder.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +class BinaryEncoder { +private: + unsigned char *const buffer; + std::size_t index; + +public: + BinaryEncoder(unsigned char *b) noexcept : buffer(b) {} + + void write(unsigned char val, unsigned char width = 0) + { + if (width == 0) + width = std::bit_width(val); + + const unsigned char bitindex = index % CHAR_BIT; + const std::size_t byteindex = index / CHAR_BIT; + + buffer[byteindex] &= compl(UCHAR_MAX << bitindex); + buffer[byteindex] |= val << bitindex; + + const unsigned char bitsWritten = CHAR_BIT - bitindex; + + if (width <= bitsWritten) { + index += width; + } else { + index += bitsWritten; + this->write(val >> bitsWritten); + } + } +}; + + +int main() { + unsigned char buf[1]; + BinaryEncoder be(buf); + + be.write(0b111u); + be.write(0b100u); + + if (buf[0] == 39) std::puts("miku"); +} \ No newline at end of file diff --git a/binaryencoder.exe b/binaryencoder.exe new file mode 100644 index 0000000..5259061 Binary files /dev/null and b/binaryencoder.exe differ diff --git a/binaryencoder.exe.obj b/binaryencoder.exe.obj new file mode 100644 index 0000000..ebc98b8 Binary files /dev/null and b/binaryencoder.exe.obj differ diff --git a/binaryencoder.pdb b/binaryencoder.pdb new file mode 100644 index 0000000..e3b6161 Binary files /dev/null and b/binaryencoder.pdb differ diff --git a/binaryencoder.zig b/binaryencoder.zig new file mode 100644 index 0000000..41281b0 --- /dev/null +++ b/binaryencoder.zig @@ -0,0 +1,42 @@ +const std = @import("std"); + +const BinaryEncoder = struct { + buf: []u8, + byte_index: usize = 0, + bit_index: u8 = 0, + + pub fn init(buf: []u8) BinaryEncoder { + const be = BinaryEncoder{ .buf = buf }; + @memset(buf, 0); + + return be; + } + + pub fn write(this: *@This(), value: u8, bit_width: u8) void { + const shift_left: u3 = @intCast(this.bit_index); + this.buf[this.byte_index] |= value << shift_left; + + if (this.bit_index + bit_width > 8) { + const shift_right: u3 = @intCast(8 - this.bit_index); + this.buf[this.byte_index + 1] |= value >> shift_right; + + this.bit_index = bit_width - shift_right; + } else if (this.bit_index + bit_width == 8) { + this.bit_index = 0; + this.byte_index += 1; + } else { + this.bit_index += bit_width; + } + } +}; + +pub fn main() !void { + var buf: [16]u8 = undefined; + var be = BinaryEncoder.init(&buf); + + be.write(0b0000000, 7); + be.write(0b11, 2); + + std.debug.print("val: bin:{b} dec:{}\n", .{ buf[0], buf[0] }); + std.debug.print("val: bin:{b} dec:{}\n", .{ buf[1], buf[1] }); +} diff --git a/meow.exe b/meow.exe new file mode 100644 index 0000000..efd39d9 Binary files /dev/null and b/meow.exe differ diff --git a/rewrite/src/controller.zig b/rewrite/src/controller.zig index 0e2fcf2..c48a4f7 100644 --- a/rewrite/src/controller.zig +++ b/rewrite/src/controller.zig @@ -58,20 +58,20 @@ const Controller = struct { }; } - pub fn poll(this: *@This(), records: []input.Record) void { + pub fn poll(this: *@This(), record_buffer: fumo.RingBuffer(input.Record, 16)) void { for (this.pending[0..this.n_pending]) |axis| { axis.is_up = false; axis.is_down = false; } - for (records) |*record| { + for (record_buffer) |*record| { if (this.scancode_map.find(record.scancode)) |*bind| { dispatch(bind, record); } } } - fn dispatch(bind: *Bind, record: *input.Record) void { + fn dispatch(bind: *Bind, record: input.Record) void { bind.axis.data = record.data * bind.multiplier; if (record.is_down) { diff --git a/rewrite/src/fumostd.zig b/rewrite/src/fumostd.zig index 08db86e..87f9149 100644 --- a/rewrite/src/fumostd.zig +++ b/rewrite/src/fumostd.zig @@ -94,6 +94,30 @@ pub fn RingBuffer(comptime T: type, comptime size: comptime_int) type { this.array[this.write_index] = slice[i]; this.write_index = @mod(this.write_index + 1, size); } + + return i; + } + + pub fn read(this: *@This()) struct { []T, []T } { + const contiguous: bool = this.write_index >= this.read_index; + + const upper_1: usize = if (contiguous) this.write_index else size; + const upper_2: usize = if (contiguous) 0 else this.write_index; + + this.read_index = this.write_index; + + return .{ + this.array[this.read_index..upper_1], + this.array[0..upper_2], + }; + } + + pub fn unreadLen(this: @This()) usize { + if (this.write_index >= this.read_index) { + return this.write_index - this.read_index; + } else { + return (size - this.read_index) + this.write_index; + } } }; } diff --git a/rewrite/src/input.zig b/rewrite/src/input.zig index cdfafa7..85451f5 100644 --- a/rewrite/src/input.zig +++ b/rewrite/src/input.zig @@ -4,6 +4,9 @@ const fumo = @import("fumostd.zig"); const IO_BUF_SIZE: usize = 16; const STR_BUF_SIZE: usize = IO_BUF_SIZE * 4; +const RecordBuffer = fumo.RingBuffer(Record, IO_BUF_SIZE); +const StringBuffer = fumo.RingBuffer(u8, STR_BUF_SIZE); + const Record = struct { scancode: usize, data: f64, @@ -14,29 +17,46 @@ const Record = struct { }; const Handle = struct { - record_buffer: fumo.RingBuffer(Record, IO_BUF_SIZE), - string_buffer: fumo.RingBuffer(u8, STR_BUF_SIZE), + records: RecordBuffer, + string: StringBuffer, thread: std.Thread, mutex: std.Thread.Mutex = std.Thread.Mutex{}, + read_signal: std.Thread.Condition = std.Thread.Condition{}, pub fn init() !Handle { const handle = Handle{ - .thread = try std.Thread.spawn(.{}, handle.worker, .{}), + .thread = try std.Thread.spawn(.{}, worker, .{}), }; return handle; } - fn worker(this: @This()) void { + fn worker(this: *@This()) void { + var rec_buf: [IO_BUF_SIZE]Record = undefined; + var str_buf: [STR_BUF_SIZE]u8 = undefined; + + var n_recs: usize = 0; + var n_str: usize = 0; + while (true) { // block platform read in + try platform.ReadInput(&rec_buf, &n_recs, &str_buf, &n_str); this.mutex.lock(); + defer this.mutex.unlock(); - this.record_buffer.write(input); + var w_recs: usize = 0; + var w_str: usize = 0; - this.mutex.unlock(); + while (w_recs < n_recs) : ({ + this.read_signal.wait(&this.mutex); + if (this.records.read_index == this.records.write_index) + continue; + }) { + w_recs += this.records.write(rec_buf[w_recs..n_recs]); + w_str += this.string.write(str_buf[w_str..n_str]); + } } } }; diff --git a/rewrite/src/platform.zig b/rewrite/src/platform.zig new file mode 100644 index 0000000..ae6bc6a --- /dev/null +++ b/rewrite/src/platform.zig @@ -0,0 +1,56 @@ +const std = @import("std"); +const input = @import("input.zig"); + +const windows = @cImport({ + @cInclude("windows.h"); +}); + +const stdin = windows.GetStdHandle(windows.STD_INPUT_HANDLE); + +const PlatformError = error{ReadInputCall}; + +pub fn ReadInput( + out_buf: *[input.IO_BUF_SIZE]input.Record, + n_out: *usize, + str_buf: *[input.STR_BUF_SIZE]u8, + n_str: *usize, +) !void { + var buf: [input.IO_BUF_SIZE]windows.INPUT_RECORD = undefined; + var n_buf: usize = 0; + + const success: bool = windows.ReadConsoleInputW( + stdin, + &buf, + input.IO_BUF_SIZE, + &n_buf, + ); + + if (!success) + return PlatformError.ReadInputCall; + + n_out.* = 0; + + for (buf, out_buf) |rec, *out_rec| {} +} + +fn dispatch(win_rec: windows.INPUT_RECORD) bool { + switch (win_rec.EventType) { + windows.KEY_EVENT => blk: { + out_rec.* = input.Record{ + .scancode = rec.Event.KeyEvent.wVirtualScanCode, + .data = rec.Event.KeyEvent.bKeyDown, + .time = now, + .is_down = rec.Event.KeyEvent.bKeyDown, + }; + + if (rec.Event.KeyEvent.bKeyDown) + n_str.* += ucs2ToUtf8(str_buf + n_out, rec.Event.KeyEvent.uChar.UnicodeChar); + + break :blk true; + }, + + windows.WINDOW_BUFFER_SIZE_EVENT => false, + + else => false, + } +}