diff --git a/source/datastructures/ringbuffer.c b/source/datastructures/ringbuffer.c new file mode 100644 index 0000000..fb90b00 --- /dev/null +++ b/source/datastructures/ringbuffer.c @@ -0,0 +1,35 @@ +#pragma once +#include "ringbuffer.h" +#include + +struct rbuf_generic { + struct RingBufferHead head; + u8 arr[]; +}; + +inline void *rbuf_start(RingBufferT T, struct rbuf_generic *rbuf, size_t i) +{ + size_t wrap_i = (rbuf->head.start + i) % T->LEN; + return rbuf->arr + wrap_i * T->SIZE; +} + +inline void *rbuf_tail(RingBufferT T, struct rbuf_generic *rbuf, size_t i) +{ + size_t wrap_i = (rbuf->head.start + rbuf->head.len + i) % T->LEN; + return rbuf->arr + i * T->SIZE; +} + +void RingBufferTransfer(RingBufferT T, RingBuffer *dest, RingBuffer *tmp) +{ + struct rbuf_generic *write = dest; + struct rbuf_generic *read = tmp; + + size_t copy_max = min_size(T->LEN - write->head.len, read->head.len); + + for (size_t i = 0; i < copy_max; i++) { + memcpy(rbuf_tail(T, write, i), rbuf_start(T, read, i), T->LEN); + } + + write->head.start += copy_max; + read->head.len -= copy_max; +} \ No newline at end of file diff --git a/source/datastructures/ringbuffer.h b/source/datastructures/ringbuffer.h new file mode 100644 index 0000000..6f5af8c --- /dev/null +++ b/source/datastructures/ringbuffer.h @@ -0,0 +1,24 @@ +#pragma once +#include +#include +#include +#include +#include + +#include "fumotris.h" + +typedef void *RingBuffer; + +typedef const struct RingBufferT { + size_t LEN; + size_t SIZE; +} *const RingBufferT; + +struct RingBufferHead { + u8f len; + u8f start; +}; + +void RingBufferTransfer(RingBufferT T, RingBuffer *dest, RingBuffer *tmp); + +#define INIT_RING_BUF_T(len, type) &(struct RingBufferT) { len, sizeof(type) } \ No newline at end of file diff --git a/source/io/ctrl.h b/source/io/ctrl.h index 4740c56..e64d4e8 100644 --- a/source/io/ctrl.h +++ b/source/io/ctrl.h @@ -47,8 +47,8 @@ struct ctrl_axis_vec { }; struct Controller { - struct RecordBuffer recs; - struct StringBuffer str; + struct InputRecordBuf recs; + struct InputStringBuf str; struct { struct InputAxis *axes[IO_BUF_SIZE]; diff --git a/source/io/input.c b/source/io/input.c index 7e89d9b..ffd3223 100644 --- a/source/io/input.c +++ b/source/io/input.c @@ -3,44 +3,12 @@ #include "platform.h" -void InputBufferTransfer(struct RecordBuffer *dest, struct RecordBuffer *src) -{ - size_t copy_max = min_size(IO_BUF_SIZE - dest->len, src->len); - - for (size_t i = 0; i < copy_max; i++) { - size_t dest_i = (dest->start + dest->len + i) % IO_BUF_SIZE; - size_t src_i = (src->start + i) % IO_BUF_SIZE; - - dest->buf[dest_i] = src->buf[src_i]; - } - - dest->start += copy_max; - if (copy_max < src->len) - src->len -= copy_max; -} - -void StringBufferTransfer(struct StringBuffer *dest, struct StringBuffer *src) -{ - size_t copy_max = min_size(STR_BUF_SIZE - dest->len, src->len); - - for (size_t i = 0; i < copy_max; i++) { - size_t dest_i = (dest->start + dest->len + i) % STR_BUF_SIZE; - size_t src_i = (src->start + i) % STR_BUF_SIZE; - - dest->buf[dest_i] = src->buf[src_i]; - } - - dest->start += copy_max; - if (copy_max < src->len) - src->len -= copy_max; -} - void *input_thread_loop(void *arg) { struct InputThreadHandle *hand = arg; - struct RecordBuffer tmp_in = { .len = 0, .start = 0 }; - struct StringBuffer tmp_str = { .len = 0, .start = 0 }; + struct InputRecordBuf tmp_in = { .head.len = 0, .head.start = 0 }; + struct InputStringBuf tmp_str = { .head.len = 0, .head.start = 0 }; while (!hand->is_terminating) { if (!PlatformReadInput(&tmp_in, &tmp_str)) @@ -49,13 +17,13 @@ void *input_thread_loop(void *arg) if (hand->err = pthread_mutex_lock(&hand->mutex)) return nullptr; - while (tmp_in.len == IO_BUF_SIZE) { + while (tmp_in.head.len == IO_BUF_SIZE) { if (hand->err = pthread_cond_wait(&hand->consume, &hand->mutex)) return nullptr; } - InputBufferTransfer(hand->in, &tmp_in); - StringBufferTransfer(hand->str, &tmp_str); + RingBufferTransfer(IO_BUF_T, hand->in, &tmp_in); + RingBufferTransfer(STR_BUF_T, hand->str, &tmp_str); if (hand->err = pthread_mutex_unlock(&hand->mutex)) return nullptr; @@ -66,8 +34,8 @@ void *input_thread_loop(void *arg) bool BeginInputThread( struct InputThreadHandle *hand, - struct RecordBuffer *in, - struct StringBuffer *str + struct InputRecordBuf *in, + struct InputStringBuf *str ) { *hand = (struct InputThreadHandle) { .in = in, diff --git a/source/io/input.h b/source/io/input.h index a86e8e9..9869bec 100644 --- a/source/io/input.h +++ b/source/io/input.h @@ -8,6 +8,7 @@ #include "fumotris.h" #include "gametime.h" +#include "ringbuffer.h" #define IO_BUF_SIZE 16 #define STR_BUF_SIZE (IO_BUF_SIZE * 4) @@ -67,21 +68,22 @@ struct InputRecord { }; }; -struct RecordBuffer { +RingBufferT IO_BUF_T = INIT_RING_BUF_T(IO_BUF_SIZE, struct InputRecord); +RingBufferT STR_BUF_T = INIT_RING_BUF_T(STR_BUF_SIZE, char); + +struct InputRecordBuf { + struct RingBufferHead head; struct InputRecord buf[IO_BUF_SIZE]; - u8f len; - u8f start; }; -struct StringBuffer { +struct InputStringBuf { + struct RingBufferHead head; char buf[STR_BUF_SIZE]; - u8f len; - u8f start; }; struct InputThreadHandle { - struct RecordBuffer *in; - struct StringBuffer *str; + struct InputRecordBuf *in; + struct InputStringBuf *str; pthread_t thread; pthread_mutex_t mutex; @@ -91,12 +93,10 @@ struct InputThreadHandle { bool is_terminating; }; -void InputBufferTransfer(struct RecordBuffer *tmp, struct RecordBuffer *dest); - bool BeginInputThread( struct InputThreadHandle *hand, - struct RecordBuffer *in, - struct StringBuffer *str + struct InputRecordBuf *in, + struct InputStringBuf *str ); bool EndInputThread(struct InputThreadHandle *hand); \ No newline at end of file diff --git a/source/io/platforms/platform.h b/source/io/platforms/platform.h index 2aee8e3..0938bf1 100644 --- a/source/io/platforms/platform.h +++ b/source/io/platforms/platform.h @@ -16,7 +16,7 @@ bool PlatformInit(); bool PlatformGetRefreshRate(u16f *out); -bool PlatformReadInput(struct RecordBuffer *in, struct StringBuffer *str); +bool PlatformReadInput(struct InputRecordBuf *in, struct InputStringBuf *str); bool PlatformStopInput(); diff --git a/source/io/platforms/win.c b/source/io/platforms/win.c index 75b1d21..aa0b62f 100644 --- a/source/io/platforms/win.c +++ b/source/io/platforms/win.c @@ -121,7 +121,7 @@ bool PlatformGetRefreshRate(u16f *out) bool dispatch_rec( struct InputRecord *out, - struct StringBuffer *str, + struct InputStringBuf *str, struct win_rec *rec ) { u8f type = rec->type | (rec->is_mouse & rec->mouse.flags); @@ -149,7 +149,7 @@ bool dispatch_rec( return false; } -bool PlatformReadInput(struct RecordBuffer *in, struct StringBuffer *str) +bool PlatformReadInput(struct InputRecordBuf *in, struct InputStringBuf *str) { DWORD max_records = IO_BUF_SIZE - in->len; struct win_rec win_buf[max_records];