This commit is contained in:
Julia 2024-05-26 07:11:53 -05:00
parent 4f89205c65
commit 7c786d1d41
12 changed files with 198 additions and 10 deletions

View file

@ -8,7 +8,8 @@
"limits": "c", "limits": "c",
"new": "c", "new": "c",
"fumocommon.h": "c", "fumocommon.h": "c",
"input.h": "c" "input.h": "c",
"bit": "cpp"
}, },
"cmake.configureOnOpen": false "cmake.configureOnOpen": false
} }

BIN
a.exe Normal file

Binary file not shown.

45
binaryencoder.cpp Normal file
View file

@ -0,0 +1,45 @@
#include <bit>
#include <climits>
#include <cmath>
#include <cstdio>
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");
}

BIN
binaryencoder.exe Normal file

Binary file not shown.

BIN
binaryencoder.exe.obj Normal file

Binary file not shown.

BIN
binaryencoder.pdb Normal file

Binary file not shown.

42
binaryencoder.zig Normal file
View file

@ -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] });
}

BIN
meow.exe Normal file

Binary file not shown.

View file

@ -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| { for (this.pending[0..this.n_pending]) |axis| {
axis.is_up = false; axis.is_up = false;
axis.is_down = false; axis.is_down = false;
} }
for (records) |*record| { for (record_buffer) |*record| {
if (this.scancode_map.find(record.scancode)) |*bind| { if (this.scancode_map.find(record.scancode)) |*bind| {
dispatch(bind, record); 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; bind.axis.data = record.data * bind.multiplier;
if (record.is_down) { if (record.is_down) {

View file

@ -94,6 +94,30 @@ pub fn RingBuffer(comptime T: type, comptime size: comptime_int) type {
this.array[this.write_index] = slice[i]; this.array[this.write_index] = slice[i];
this.write_index = @mod(this.write_index + 1, size); 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;
}
} }
}; };
} }

View file

@ -4,6 +4,9 @@ const fumo = @import("fumostd.zig");
const IO_BUF_SIZE: usize = 16; const IO_BUF_SIZE: usize = 16;
const STR_BUF_SIZE: usize = IO_BUF_SIZE * 4; 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 { const Record = struct {
scancode: usize, scancode: usize,
data: f64, data: f64,
@ -14,29 +17,46 @@ const Record = struct {
}; };
const Handle = struct { const Handle = struct {
record_buffer: fumo.RingBuffer(Record, IO_BUF_SIZE), records: RecordBuffer,
string_buffer: fumo.RingBuffer(u8, STR_BUF_SIZE), string: StringBuffer,
thread: std.Thread, thread: std.Thread,
mutex: std.Thread.Mutex = std.Thread.Mutex{}, mutex: std.Thread.Mutex = std.Thread.Mutex{},
read_signal: std.Thread.Condition = std.Thread.Condition{},
pub fn init() !Handle { pub fn init() !Handle {
const handle = Handle{ const handle = Handle{
.thread = try std.Thread.spawn(.{}, handle.worker, .{}), .thread = try std.Thread.spawn(.{}, worker, .{}),
}; };
return handle; 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) { while (true) {
// block platform read in // block platform read in
try platform.ReadInput(&rec_buf, &n_recs, &str_buf, &n_str);
this.mutex.lock(); 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]);
}
} }
} }
}; };

56
rewrite/src/platform.zig Normal file
View file

@ -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,
}
}