diff --git a/.vscode/settings.json b/.vscode/settings.json index 646f1fa..f3124c4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -50,6 +50,7 @@ "stdexcept": "cpp", "streambuf": "cpp", "typeinfo": "cpp", - "execution": "cpp" + "execution": "cpp", + "stdbool.h": "c" } } \ No newline at end of file diff --git a/source/io/ctrl.c b/source/io/ctrl.c index 83776c8..45dcc35 100644 --- a/source/io/ctrl.c +++ b/source/io/ctrl.c @@ -24,8 +24,10 @@ struct InputRecord { union { struct { - u32 value; bool is_down; + } key; + struct { + u64 value; } axis; struct { u32 x; @@ -36,16 +38,31 @@ struct InputRecord { double timestamp; }; -struct InputResult { +struct InputBuffer { + struct InputRecord records[IO_BUF_SIZE]; size_t count; - struct InputRecord buf[IO_BUF_SIZE]; + pthread_mutex_t mutex; }; +struct InputBuffer NewInputBuffer() +{ + struct InputBuffer buf; + buf.count = 0; + buf.mutex = PTHREAD_MUTEX_INITIALIZER; + return buf; +} + struct Axis { + u8 type; + union { struct { u32 value; - bool is_down; + u32 is_down : 1; + u32 is_up : 1; + } key; + struct { + u64 value; } axis; struct { u32 x; @@ -104,87 +121,126 @@ hashtype hash_ident(u16f id, enum InputType type) return Hash(&obj, sizeof(struct ident)); } -struct ctrl_bkt { - hashtype bind_hash; - size_t index; - hashtype code_hash; - +struct code_bkt { + hashtype hash; + u16 code; struct Axis axis; }; +struct bind_bkt { + hashtype hash; + u16 bind; + struct Axis *axis; +}; + struct Ctrl { - size_t capacity; - size_t filled; - struct ctrl_bkt *bkts; + struct { + size_t capacity; + size_t filled; + struct code_bkt *bkts; + } codes; + + struct { + size_t capacity; + size_t filled; + struct bind_bkt *bkts; + } binds; pthread_mutex_t mutex; }; typedef struct Ctrl Ctrl; -Ctrl NewCtrl(struct ctrl_bkt *bkts_prealloc, size_t capacity) +Ctrl NewCtrl(struct code_bkt *codes, size_t c, struct bind_bkt *binds, size_t b) { + memset(codes, 0, sizeof(struct code_bkt) * c); + memset(binds, 0, sizeof(struct bind_bkt) * b); + Ctrl ctrl; - ctrl.capacity = capacity; - ctrl.filled = 0; - memset(bkts_prealloc, 0, sizeof(struct ctrl_bkt) * capacity); - ctrl.bkts = bkts_prealloc; + ctrl.codes.bkts = codes; + ctrl.binds.bkts = binds; ctrl.mutex = PTHREAD_MUTEX_INITIALIZER; + return ctrl; } -struct ctrl_bkt *get_bkt(Ctrl *ctrl, size_t i) +void CtrlPoll(struct InputBuffer *buf) { - return &ctrl->bkts[i]; + for (size_t i = 0; i < buf->count; i++) { + struct InputRecord *rec = &buf->records[i]; + + switch (rec->type) { + case KEY: + key_update(); + break; + case AXIS: + axis_update(); + break; + case JOYSTICK: + joystick_update(); + break; + } + } } -struct ctrl_bkt *find_bind(Ctrl *ctrl, hashtype bind_hash, hashtype search) +struct ctrl_bkt *get_code_bkt(Ctrl *ctrl, size_t i) { - size_t i = bind_hash % ctrl->capacity; + assert(i < ctrl->codes.capacity); + return &ctrl->codes.bkts[i]; +} - struct ctrl_bkt *next; - for (size_t offset = 0; offset < ctrl->capacity; offset++) { - i = (i + 1) % ctrl->capacity; +struct ctrl_bkt *get_bind_bkt(Ctrl *ctrl, size_t i) +{ + assert(i < ctrl->binds.capacity); + return &ctrl->binds.bkts[i]; +} - next = get_bkt(ctrl, i); - if (next->bind_hash != search) - continue; +struct code_bkt *find_code(Ctrl *ctrl, hashtype hash) +{ + const size_t index = hash % ctrl->codes.capacity; + size_t i = index; + + while (i != index - 1) { + struct code_bkt *bkt = get_code_bkt(ctrl, i); + if (bkt->hash == 0) + return bkt; - return next; + i = (i + 1) % ctrl->codes.capacity; } return nullptr; } -struct ctrl_bkt *find_code(Ctrl *ctrl, size_t *i, hashtype search) +struct ctrl_bkt *find_bind(Ctrl *ctrl, hashtype hash) { - struct ctrl_bkt *next; - for (size_t offset = 0; offset < ctrl->capacity; offset++) { - *i = (*i + 1) % ctrl->capacity; + const size_t index = hash % ctrl->binds.capacity; + size_t i = index; - next = get_bkt(ctrl, *i); - if (next->code_hash != search) - continue; - - return next; + while (i != index - 1) { + struct bind_bkt *bkt = get_bind_bkt(ctrl, i); + if (bkt->hash == 0) + return bkt; + + i = (i + 1) % ctrl->binds.capacity; } return nullptr; } bool CtrlMap(Ctrl *ctrl, u16f bind, u16f code, enum InputType type) { - if (ctrl->filled == ctrl->capacity) + if (ctrl->binds.filled == ctrl->binds.capacity) return false; - hashtype bind_hash = hash_ident(bind, type); - struct ctrl_bkt *bind_bkt = find_bind(ctrl, bind_hash, 0); - bind_bkt->bind_hash = bind_hash; - hashtype code_hash = hash_ident(code, type); - size_t code_i = code_hash % ctrl->capacity; - struct ctrl_bkt *code_bkt = find_code(ctrl, &code_i, 0); - code_bkt->code_hash = code_hash; - - bind_bkt->index = code_i; - ctrl->filled += 1; + struct code_bkt *code_bkt = find_code(ctrl, code_hash); + code_bkt->hash = code_hash; + code_bkt->code = code; + + hashtype bind_hash = hash_ident(bind, type); + struct bind_bkt *bind_bkt = find_bind(ctrl, bind_hash); + bind_bkt->hash = bind_hash; + bind_bkt->bind = bind; + bind_bkt->axis = &code_bkt->axis; + + ctrl->binds.filled += 1; return true; } @@ -199,11 +255,9 @@ struct Axis *find_bind_axis(Ctrl *ctrl, u16f bind, enum InputType type) return &get_bkt(ctrl, bind_bkt->index)->axis; } -struct Axis *CtrlGet(Ctrl *ctrl, u16f code, enum InputType type) +struct Axis *CtrlGet(Ctrl *ctrl, u16f code, u8f type) { - hashtype code_hash = hash_ident(code, type); - size_t code_i = code_hash % ctrl->capacity; - struct ctrl_bkt *code_bkt = find_code(ctrl, &code_i, code_hash); += struct ctrl_bkt *code_bkt = find_code(ctrl, code, type); if (code_bkt == nullptr) return nullptr; @@ -216,12 +270,12 @@ bool CtrlUpdateKey(Ctrl *ctrl, struct InputRecord *record) if (axis == nullptr) return false; - if (record->data.axis.is_down) { + if (record->data.key.is_down) { axis->last_pressed = record->timestamp; } else { axis->last_released = record->timestamp; } - axis->data.axis.is_down = record->data.axis.is_down; + axis->data.axis.value = record->data.key.is_down; return true; } diff --git a/source/io/ctrl.h b/source/io/ctrl.h index f6a8425..d13c3c5 100644 --- a/source/io/ctrl.h +++ b/source/io/ctrl.h @@ -25,8 +25,10 @@ struct InputRecord { union { struct { - u32 value; bool is_down; + } key; + struct { + u64 value; } axis; struct { u32 x; @@ -37,16 +39,23 @@ struct InputRecord { double timestamp; }; -struct InputResult { +struct InputBuffer { + struct InputRecord records[IO_BUF_SIZE]; size_t count; - struct InputRecord buf[IO_BUF_SIZE]; + pthread_mutex_t mutex; }; +struct InputBuffer NewInputBuffer(); + struct Axis { union { struct { u32 value; - bool is_down; + u32 is_down : 1; + u32 is_up : 1; + } key; + struct { + u64 value; } axis; struct { u32 x; @@ -83,8 +92,11 @@ typedef u32 hashtype; struct ctrl_bkt { hashtype bind_hash; + u16 bind; size_t index; + hashtype code_hash; + u16 code; struct Axis axis; }; diff --git a/source/io/input.c b/source/io/input.c index 1d56aad..f017283 100644 --- a/source/io/input.c +++ b/source/io/input.c @@ -7,67 +7,35 @@ #include "ctrl.h" #include "fumotris.h" -#include "gametime.h" #ifdef _WIN32 #include "win.h" #endif -bool dispatch(Ctrl *ctrl, struct InputRecord *record) +#define IO_BUF_SIZE 8 + +struct input_args { + Ctrl *ctrl; + struct InputBuffer *in_buf; +}; + +void *block_input(void *args_ptr) { - switch (record->type) { - case KEY: - return CtrlUpdateKey(ctrl, record); - case AXIS: - return CtrlUpdateAxis(ctrl, record); - case JOYSTICK: - return CtrlUpdateJoystick(ctrl, record); - case WINDOW: - return CtrlUpdateWindow(ctrl, record); - case ESCAPE: - default: - return false; - } -} - -bool write_result(Ctrl *ctrl, struct InputResult *result) -{ - double now = GetTime(); - pthread_mutex_lock(&ctrl->mutex); - - for (size_t i = 0; i < result->count; i++) { - if (result->buf[i].type == ESCAPE) - return false; - result->buf[i].timestamp = now; - - dispatch(ctrl, &result->buf[i]); - } - - pthread_mutex_unlock(&ctrl->mutex); - return true; -} - -void *block_input(void *args) -{ - Ctrl *ctrl = args; - struct InputResult result; + struct input_args *args = args_ptr; + Ctrl *ctrl = args->ctrl; + struct InputBuffer *in_buf = args->in_buf; input_loop: bool success; + #ifdef _WIN32 - success = WindowsBlockInput(&result); + success = WindowsBlockInput(&in_buf); #endif - if (!success) { + if (!success) exit(1); - } - - if (!write_result(ctrl, &result)) { - return nullptr; - } goto input_loop; - return nullptr; } diff --git a/source/io/input.h b/source/io/input.h index 1688a2c..1a75c3b 100644 --- a/source/io/input.h +++ b/source/io/input.h @@ -8,4 +8,10 @@ #include "ctrl.h" #include "fumotris.h" +struct InputBuffer { + struct InputRecord records[IO_BUF_SIZE]; + size_t count; + pthread_mutex_t mutex; +}; + void StartInput(Ctrl *ctrl); \ No newline at end of file diff --git a/source/io/platforms/win.c b/source/io/platforms/win.c index efb36cd..f006dd6 100644 --- a/source/io/platforms/win.c +++ b/source/io/platforms/win.c @@ -21,9 +21,9 @@ bool WindowsInit() return true; } -bool WindowsBlockInput(struct InputResult *result) +bool WindowsBlockInput(struct InputBuffer *buf) { - return WinBlockInput(result); + return WinBlockInput(buf); } bool WindowsWait(double seconds) diff --git a/source/io/platforms/win.h b/source/io/platforms/win.h index 7a89e9a..b539fdd 100644 --- a/source/io/platforms/win.h +++ b/source/io/platforms/win.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -9,6 +10,6 @@ bool WindowsInit(); -bool WindowsBlockInput(struct InputResult *result); +bool WindowsBlockInput(struct InputBuffer *buf); bool WindowsWait(double seconds); \ No newline at end of file diff --git a/source/io/platforms/winhandler.c b/source/io/platforms/winhandler.c index f805b1c..343c9a6 100644 --- a/source/io/platforms/winhandler.c +++ b/source/io/platforms/winhandler.c @@ -7,6 +7,7 @@ #include #include "fumotris.h" +#include "gametime.h" #include "input.h" struct Windows { @@ -45,7 +46,7 @@ void set_key_record(struct InputRecord *record, KEY_EVENT_RECORD win_key) { record->type = KEY; record->id = win_key.wVirtualKeyCode; - record->data.axis.is_down = win_key.bKeyDown; + record->data.key.is_down = win_key.bKeyDown; if (win_key.wVirtualKeyCode == VK_ESCAPE) record->type = ESCAPE; @@ -100,27 +101,31 @@ bool dispatch_record(struct InputRecord *record, INPUT_RECORD win_record) return true; } -bool WinBlockInput(struct InputResult *result) +bool WinBlockInput(struct InputBuffer *buf) { - INPUT_RECORD buf[8]; + size_t win_size = IO_BUF_SIZE - buf->count; + INPUT_RECORD win_buf[win_size]; DWORD count; - if (!ReadConsoleInput(windows.input_handle, buf, 8, &count)) + if (!ReadConsoleInput(windows.input_handle, win_buf, win_size, &count)) return false; + + double now = GetTime(); + pthread_mutex_lock(&buf->mutex); - size_t unused_offset = 0; for (size_t i = 0; i < count; i++) { struct InputRecord record; + record.timestamp = now; - bool include = dispatch_record(&record, buf[i]); - if (record.type == ESCAPE) - return false; + bool include = dispatch_record(&record, win_buf[i]); if (!include) - unused_offset += 1; + continue; - result->buf[i - unused_offset] = record; + buf->records[buf->count] = record; + buf->count += 1; } - result->count = count - unused_offset; + + pthread_mutex_unlock(&buf->mutex); return true; } diff --git a/source/io/platforms/winhandler.h b/source/io/platforms/winhandler.h index 25797d0..7bb4172 100644 --- a/source/io/platforms/winhandler.h +++ b/source/io/platforms/winhandler.h @@ -13,6 +13,6 @@ bool WinInitTimer(); bool WinInitConsole(); -bool WinBlockInput(struct InputResult *result); +bool WinBlockInput(struct InputBuffer *buf); bool WinWait(double seconds); \ No newline at end of file diff --git a/source/main.c b/source/main.c index 4edf4da..e519d90 100644 --- a/source/main.c +++ b/source/main.c @@ -73,39 +73,13 @@ void Loop(Ctrl *ctrl) falling.blks = falling_blks; for (int i = 0; i < 7779997; i++) { + + TetrMapToTermBuf(&board, &term); TetrMapToTermBuf(&falling, &term); size_t size = TermBufToChars(&term, out, out_max); - //puts(out); - puts("\x1b[H"); - - //falling.y += 1; - - for(int j = 0; j < ctrl->capacity; j++) { - printf("val:%u, is_down:%u, x:%u, y:%u, press:%f, relse:%f\n", - ctrl->bkts[j].axis.data.axis.value, ctrl->bkts[j].axis.data.axis.is_down, - ctrl->bkts[j].axis.data.joystick.x, ctrl->bkts[j].axis.data.joystick.y, - ctrl->bkts[j].axis.last_pressed, ctrl->bkts[j].axis.last_released); - } - /* - struct Axis *axis = CtrlGet(ctrl, LEFT, KEY); - struct Axis *right = CtrlGet(ctrl, RIGHT, KEY); - - printf("ctrl:%u\n", axis); - printf("ctrl:%u\n", right); - - printf("%f\n", axis->last_pressed); - - if (axis->data.axis.is_down) { - printf("left"); - falling.x -= 1; - } - - if (right->data.axis.is_down) { - printf("right"); - falling.x += 1; - }*/ + puts(out); WindowsWait(0.1); } @@ -115,8 +89,8 @@ int main() { WindowsInit(); - struct ctrl_bkt bkts[16]; - Ctrl ctrl = NewCtrl(bkts, 16); + struct ctrl_bkt bkts[13]; + Ctrl ctrl = NewCtrl(bkts, 13); for (size_t i = 0; i < 9; i++) { CtrlMap(&ctrl, key_binds[i], key_codes[i], KEY); diff --git a/source/test.cpp b/source/test.cpp deleted file mode 100644 index 15d0df3..0000000 --- a/source/test.cpp +++ /dev/null @@ -1,422 +0,0 @@ -#include -#include -#include -using namespace std; - -void gotoxy(int x, int y); -void setcolor(WORD color); -void setForeGroundAndBackGroundColor(int ForeGroundColor,int BackGroundColor); -void clearscreen(); -void drawpixel( unsigned char x, unsigned char y, unsigned char Color); -void drawpixel2( unsigned char x, unsigned char y, unsigned char Color, char character); -void drawcircle(int x, int y, int a, int b, int color); -void drawline(int x0, int y0, int x1, int y1, int color); -void drawfilledrectangle(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char bkcol); -void drawframe(unsigned x,unsigned y,unsigned sx,unsigned sy,unsigned char col,unsigned char col2,char text_[]); -void drawwindow(unsigned x,unsigned y,unsigned sx,unsigned sy,unsigned char col,unsigned char col2,unsigned char bkcol,char text_[]); - -int main() -{ - gotoxy(1,23); - setcolor(7); - clearscreen(); - - cout<<"click anywhere in console window to write - hello world -\n\n\n\n\n\n\n\n\n\n\n\n\n" - "Press Ctrl+C to Exit"; - - HANDLE hout= GetStdHandle(STD_OUTPUT_HANDLE); - HANDLE hin = GetStdHandle(STD_INPUT_HANDLE); - INPUT_RECORD InputRecord; - DWORD Events; - COORD coord; - CONSOLE_CURSOR_INFO cci; - cci.dwSize = 25; - cci.bVisible = FALSE; - SetConsoleCursorInfo(hout, &cci); - SetConsoleMode(hin, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); - bool EXITGAME = false; - int buttonX=1, buttonY=1; - - drawpixel(buttonX,buttonY ,1); - gotoxy(buttonX+2,buttonY); - setcolor(3); - cout<<"<----- a button \n"; - - - while( !EXITGAME ) - { - - ReadConsoleInput(hin, &InputRecord, 1, &Events); - - - switch ( InputRecord.EventType ){ - case KEY_EVENT: // keyboard input - - - switch (InputRecord.Event.KeyEvent.wVirtualKeyCode) - { - case VK_ESCAPE: - EXITGAME = TRUE; - break; - - case VK_SPACE: - - break; - - - case VK_RETURN: - - break; - - case VK_LEFT: - // left key move player left - cout<<"VK_LEFT = "<= 0) { - ya -= asq * 2; - thresh -= ya; - wy--; - } - - xa += bsq * 2; - wx++; - - if (xa >= ya) - break; - - - drawpixel(x+wx, y-wy, color); - drawpixel(x-wx, y-wy, color); - drawpixel(x+wx, y+wy, color); - drawpixel(x-wx, y+wy, color); - } - - drawpixel(x+a, y, color); - drawpixel(x-a, y, color); - - wx = a; - wy = 0; - xa = bsq * 2 * a; - - ya = 0; - thresh = bsq / 4 - bsq * a; - - for (;;) { - thresh += ya + asq; - - if (thresh >= 0) { - xa -= bsq * 2; - thresh = thresh - xa; - wx--; - } - - ya += asq * 2; - wy++; - - if (ya > xa) - break; - - drawpixel(x+wx, y-wy, color); - drawpixel(x-wx, y-wy, color); - drawpixel(x+wx, y+wy, color); - drawpixel(x-wx, y+wy, color); - } -} - -//***************************************************************************** - -void drawline(int x0, int y0, int x1, int y1, int color){ - int pix = color; - int dy = y1 - y0; - int dx = x1 - x0; - int stepx, stepy; - - if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; } - if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } - dy <<= 1; // dy is now 2*dy - dx <<= 1; // dx is now 2*dx - - drawpixel( x0, y0,pix); - if (dx > dy) { - int fraction = dy - (dx >> 1); // same as 2*dy - dx - while (x0 != x1) { - if (fraction >= 0) { - y0 += stepy; - fraction -= dx; // same as fraction -= 2*dx - } - x0 += stepx; - fraction += dy; // same as fraction -= 2*dy - drawpixel( x0, y0,pix); - } - } else { - int fraction = dx - (dy >> 1); - while (y0 != y1) { - if (fraction >= 0) { - x0 += stepx; - fraction -= dy; - } - y0 += stepy; - fraction += dx; - drawpixel( x0, y0,pix); - } - } -} - -//***************************************************************************** - - -void drawframe(unsigned x,unsigned y,unsigned sx,unsigned sy,unsigned char col,unsigned char col2,char text_[]){ - unsigned i,j,m;{ - - m=(sx-x); //differential - j=m/8; //adjust - j=j-1; //more adjustment - gotoxy(x,y);printf("É"); //Top left corner of drawframe - gotoxy(sx,y);printf("»"); //Top right corner of drawframe - gotoxy(x,sy);printf("È"); //Bottom left corner of drawframe - gotoxy(sx,sy);printf("¼"); //Bottom right corner of drawframe - - for (i=x+1;i