window
This commit is contained in:
Julia 2024-04-02 15:06:14 -05:00
parent ed2e5a01f9
commit ef7362c5d9
15 changed files with 213 additions and 161 deletions

View file

@ -14,4 +14,3 @@ typedef uint_fast32_t u32f;
typedef uint64_t u64; typedef uint64_t u64;
typedef uint_fast64_t u64f; typedef uint_fast64_t u64f;

View file

@ -21,11 +21,15 @@ struct TetrMap {
u8 *blks; u8 *blks;
}; };
struct TetrMap NewTetrMap(size_t wid, size_t hgt) struct TetrMap NewTetrMap(u8 *blks, size_t wid, size_t hgt)
{ {
size_t area = wid * hgt;
memset(blks, 0, area);
return (struct TetrMap) { return (struct TetrMap) {
wid, hgt, wid * hgt, wid, hgt, area,
0, 0, 0, 0, 0, 0,
blks
}; };
} }

View file

@ -21,7 +21,7 @@ struct TetrMap {
u8 *blks; u8 *blks;
}; };
struct TetrMap NewTetrMap(size_t wid, size_t hgt); struct TetrMap NewTetrMap(u8 *blks, size_t wid, size_t hgt);
void TetrMapToTermBuf(struct TetrMap *map, struct TermBuf *term); void TetrMapToTermBuf(struct TetrMap *map, struct TermBuf *term);

View file

@ -16,7 +16,6 @@ enum CtrlType {
KEY, KEY,
AXIS, AXIS,
JOYSTICK, JOYSTICK,
WINDOW,
ESCAPE ESCAPE
}; };
@ -122,26 +121,19 @@ struct Ctrl {
}; };
typedef struct Ctrl Ctrl; typedef struct Ctrl Ctrl;
Ctrl NewCtrl(struct bkt *codes, struct Axis *axes, size_t c, struct bkt *binds, size_t b) Ctrl NewCtrl(struct dict *codes, struct dict *binds, struct Axis *axes)
{ {
memset(codes, 0, sizeof(struct bkt) * c); memset(codes->bkts, 0, sizeof(struct bkt) * codes->capacity);
memset(axes, 0, sizeof(struct Axis) * c); memset(binds->bkts, 0, sizeof(struct bkt) * binds->capacity);
memset(binds, 0, sizeof(struct bkt) * b); memset(axes, 0, sizeof(struct Axis) * codes->capacity);
for (size_t i = 0; i < c; i++) { for (size_t i = 0; i < codes->capacity; i++) {
codes[i].axis = &axes[i]; codes->bkts[i].axis = &axes[i];
} }
Ctrl ctrl; Ctrl ctrl;
ctrl.codes = *codes;
ctrl.codes.capacity = c; ctrl.binds = *binds;
ctrl.codes.filled = 0;
ctrl.codes.bkts = codes;
ctrl.binds.capacity = b;
ctrl.binds.filled = 0;
ctrl.binds.bkts = binds;
ctrl.mutex = PTHREAD_MUTEX_INITIALIZER; ctrl.mutex = PTHREAD_MUTEX_INITIALIZER;
return ctrl; return ctrl;
@ -295,7 +287,6 @@ bool CtrlPoll(Ctrl *ctrl, struct RecordBuffer *buf)
update_axis(axis, rec); update_axis(axis, rec);
break; break;
case JOYSTICK: case JOYSTICK:
case WINDOW:
update_joystick(axis, rec); update_joystick(axis, rec);
break; break;
default: default:

View file

@ -16,7 +16,6 @@ enum CtrlType {
KEY, KEY,
AXIS, AXIS,
JOYSTICK, JOYSTICK,
WINDOW,
ESCAPE ESCAPE
}; };
@ -107,17 +106,7 @@ struct Ctrl {
}; };
typedef struct Ctrl Ctrl; typedef struct Ctrl Ctrl;
#define NEW_CTRL(CTRL, CODES, BINDS) \ Ctrl NewCtrl(struct dict *codes, struct dict *binds, struct Axis *axes);
struct bkt NEW_CTRL_CODES[CODES]; \
struct bkt NEW_CTRL_BINDS[BINDS]; \
struct Axis NEW_CTRL_AXES[CODES]; \
CTRL = NewCtrl( \
NEW_CTRL_CODES, \
NEW_CTRL_AXES, CODES, \
NEW_CTRL_BINDS, BINDS \
); \
Ctrl NewCtrl(struct bkt *codes, struct Axis *axes, size_t c, struct bkt *binds, size_t b);
bool CtrlMap(Ctrl *ctrl, u16f code, u16f bind, u8f type); bool CtrlMap(Ctrl *ctrl, u16f code, u16f bind, u8f type);

View file

@ -12,17 +12,9 @@
#include "win.h" #include "win.h"
#endif #endif
struct input_args {
Ctrl *ctrl;
struct RecordBuffer *buf;
};
void *block_input(void *args_ptr) void *block_input(void *args_ptr)
{ {
struct input_args *args = args_ptr; struct RecordBuffer *buf = args_ptr;
Ctrl *ctrl = args->ctrl;
struct RecordBuffer *buf = args->buf;
free(args_ptr);
while (true) { while (true) {
bool success; bool success;
@ -42,11 +34,7 @@ void *block_input(void *args_ptr)
void StartInput(Ctrl *ctrl, struct RecordBuffer *buf) void StartInput(Ctrl *ctrl, struct RecordBuffer *buf)
{ {
struct input_args *args = malloc(sizeof(struct input_args)); pthread_create(&ctrl->thread, nullptr, block_input, buf);
args->ctrl = ctrl;
args->buf = buf;
pthread_create(&ctrl->thread, nullptr, block_input, args);
} }
void JoinInput(Ctrl *ctrl) void JoinInput(Ctrl *ctrl)

16
source/io/instance.c Normal file
View file

@ -0,0 +1,16 @@
#include <iso646.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fumotris.h"
struct Window {
size_t x;
size_t y;
u16f fps;
};

17
source/io/instance.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include <iso646.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fumotris.h"
struct Window {
size_t x;
size_t y;
u16f fps;
};

View file

@ -5,9 +5,10 @@
#include <stdlib.h> #include <stdlib.h>
#include "input.h" #include "input.h"
#include "instance.h"
#include "winhandler.h" #include "winhandler.h"
bool WindowsInit() bool WindowsInit(struct Window *window)
{ {
if (!WinInitInputHandle()) if (!WinInitInputHandle())
return false; return false;
@ -18,6 +19,8 @@ bool WindowsInit()
if (!WinInitConsole()) if (!WinInitConsole())
return false; return false;
return true; return true;
} }

View file

@ -10,26 +10,37 @@
#include "fumotris.h" #include "fumotris.h"
#include "gametime.h" #include "gametime.h"
#include "input.h" #include "input.h"
#include "instance.h"
struct Windows { struct Windows {
HANDLE input_handle; HANDLE input_handle;
HANDLE timer; HANDLE draw_handles[2];
}; };
static struct Windows windows; static struct Windows windows;
bool WinInitInputHandle() bool WinInitHandles()
{ {
windows.input_handle = GetStdHandle(STD_INPUT_HANDLE); windows.input_handle = GetStdHandle(STD_INPUT_HANDLE);
if (windows.input_handle == INVALID_HANDLE_VALUE) if (windows.input_handle == INVALID_HANDLE_VALUE)
return false; return false;
return true;
}
bool WinInitTimer() windows.draw_handles[0] = CreateWaitableTimer(
{ NULL, // Timer attributes
windows.timer = CreateWaitableTimer(NULL, TRUE, NULL); TRUE, // Manual reset
if (!windows.timer) NULL // Name
);
if (!windows.draw_handles[0])
return false; return false;
windows.draw_handles[1] = CreateEvent(
NULL, // Event attributes
FALSE, // Manual reset
FALSE, // Initial state
NULL // Name
);
if (!windows.draw_handles[1])
return false;
return true; return true;
} }
@ -43,6 +54,20 @@ bool WinInitConsole()
return SetConsoleMode(windows.input_handle, mode); return SetConsoleMode(windows.input_handle, mode);
} }
bool WinGetRefreshRate(struct Window *window)
{
LPDEVMODE mode;
if(!EnumDisplaySettingsA(
NULL, // Device name (null for current)
ENUM_CURRENT_SETTINGS, // Mode
&mode // Out
))
return false;
window->fps = mode->dmDisplayFrequency;
return true;
}
void set_key_record(struct CtrlRecord *record, KEY_EVENT_RECORD win_key) void set_key_record(struct CtrlRecord *record, KEY_EVENT_RECORD win_key)
{ {
record->type = KEY; record->type = KEY;
@ -78,24 +103,17 @@ bool set_mouse_record(struct CtrlRecord *record, MOUSE_EVENT_RECORD win_mouse)
return true; return true;
} }
void set_window_record(struct CtrlRecord *record, WINDOW_BUFFER_SIZE_RECORD win_resize)
{
record->type = WINDOW;
record->data.joystick.x = win_resize.dwSize.X;
record->data.joystick.y = win_resize.dwSize.Y;
}
bool dispatch_record(struct CtrlRecord *record, INPUT_RECORD win_record) bool dispatch_record(struct CtrlRecord *record, INPUT_RECORD win_record)
{ {
switch (win_record.EventType) { switch (win_record.EventType) {
case KEY_EVENT: case KEY_EVENT:
set_key_record(record, win_record.Event.KeyEvent); set_key_record(record, win_record.Event.KeyEvent);
return true; break;
case MOUSE_EVENT: case MOUSE_EVENT:
return set_mouse_record(record, win_record.Event.MouseEvent); return set_mouse_record(record, win_record.Event.MouseEvent);
case WINDOW_BUFFER_SIZE_EVENT: case WINDOW_BUFFER_SIZE_EVENT:
set_window_record(record, win_record.Event.WindowBufferSizeEvent); set_window_record(record, win_record.Event.WindowBufferSizeEvent);
return true; break;
default: default:
record->type = ESCAPE; record->type = ESCAPE;
} }
@ -108,7 +126,12 @@ bool WinBlockInput(struct RecordBuffer *buf)
INPUT_RECORD win_buf[win_size]; INPUT_RECORD win_buf[win_size];
DWORD count; DWORD count;
if (!ReadConsoleInput(windows.input_handle, win_buf, win_size, &count)) if (!ReadConsoleInput(
windows.input_handle, // Input handle
win_buf, // Record buffer
win_size, // Record buffer length
&count // Out number of records
))
return false; return false;
struct timespec now; struct timespec now;
@ -132,14 +155,28 @@ bool WinBlockInput(struct RecordBuffer *buf)
return true; return true;
} }
bool WinWait(double seconds) bool WinWait(struct timespec duration)
{ {
LARGE_INTEGER duration; LARGE_INTEGER duration;
duration.QuadPart = (u64)(-10000000.0 * seconds); duration.QuadPart = (u64)(-10000000.0 * seconds);
if (!SetWaitableTimer(windows.timer, &duration, 0, NULL, NULL, FALSE))
if (!SetWaitableTimer(
windows.draw_handles[0], // Timer
&duration, // Duration
0, // Period
NULL, // Completion coroutine
NULL, // Completion coroutine arg
FALSE // Resume
))
return false; return false;
DWORD result = WaitForSingleObject(windows.timer, INFINITE); DWORD result = WaitForMultipleObjects(
2, // Handle count
windows.draw_handles, // Handles
FALSE, // Wait for all
INFINITE // Timeout
);
if (result != WAIT_OBJECT_0) if (result != WAIT_OBJECT_0)
return false; return false;

View file

@ -7,9 +7,7 @@
#include "fumotris.h" #include "fumotris.h"
bool WinInitInputHandle(); bool WinInitHandles();
bool WinInitTimer();
bool WinInitConsole(); bool WinInitConsole();

View file

@ -15,69 +15,89 @@
#include "win.h" #include "win.h"
#endif #endif
const size_t code_count = 12; const u8 I[16] = {
const enum CtrlCode codes[12] = {
LEFT,
RIGHT,
SOFT_DROP,
HARD_DROP,
ROTATE_CCW,
ROTATE_CW,
ROTATE_180,
SWAP,
ESC,
VSCROLL,
HSCROLL,
MOUSE
};
const u16f binds[12] = {
0x25,
0x27,
0x28,
0x20,
'Z',
'X',
'A',
'C',
0x1B,
0,
1,
0
};
u8 I[16] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0 0, 0, 0, 0
}; };
const u8 O[4] = {
1, 1,
1, 1
};
const u8 T[9] = {
0, 1, 0,
1, 1, 1,
0, 0, 0
};
const u8 S[9] = {
0, 1, 1,
1, 1, 0,
0, 0, 0
};
const u8 Z[9] = {
1, 1, 0,
0, 1, 1,
0, 0, 0
};
const u8 J[9] = {
1, 0, 0,
1, 1, 1,
0, 0, 0
};
const u8 L[9] = {
0, 0, 1,
1, 1, 1,
0, 0, 0
};
struct CtrlBind {
enum CtrlCode code;
u16 bind;
u8 type;
};
const size_t code_count = 12;
const struct CtrlBind ctrl_binds[12] = {
{ LEFT, 0x25, KEY },
{ RIGHT, 0x27, KEY },
{ SOFT_DROP, 0x28, KEY },
{ HARD_DROP, 0x20, KEY },
{ ROTATE_CCW, 'Z', KEY },
{ ROTATE_CW, 'X', KEY },
{ ROTATE_180, 'A', KEY },
{ SWAP, 'C', KEY },
{ ESC, 0x1B, KEY },
{ VSCROLL, 0, AXIS },
{ HSCROLL, 1, AXIS },
{ MOUSE, 0, JOYSTICK }
};
void Update(Ctrl *ctrl)
{
}
void Loop(Ctrl *ctrl, struct RecordBuffer *in_buf) void Loop(Ctrl *ctrl, struct RecordBuffer *in_buf)
{ {
struct TermBuf term = NewTermBuf(20, 20); struct CharBlk4 term_blks[20 * 20];
struct CharBlk4 term_blks[term.area]; struct TermBuf term = NewTermBuf(term_blks, 20, 20);
memset(term_blks, 0, sizeof(struct CharBlk4) * term.area);
term.blks = term_blks;
size_t out_max = TermMaxChars(&term); size_t out_max = TermMaxChars(&term);
char out[out_max]; char out[out_max];
memset(out, 0, out_max);
struct TetrMap board = NewTetrMap(10, 20); u8 board_blks[10 * 20];
u8 board_blks[board.area]; struct TetrMap board = NewTetrMap(board_blks, 10, 20);
memset(board_blks, 0, board.area);
board.blks = board_blks;
struct TetrMap falling = NewTetrMap(4, 4); u8 falling_blks[4 * 4];
u8 falling_blks[falling.area]; struct TetrMap falling = NewTetrMap(falling_blks, 4, 4);
memcpy(falling_blks, I, falling.area); memcpy(falling_blks, I, falling.area);
falling.blks = falling_blks;
for (int i = 0; i < 7779997; i++) { for (int i = 0; i < 7779997; i++) {
CtrlPoll(ctrl, in_buf); CtrlPoll(ctrl, in_buf);
@ -88,27 +108,36 @@ void Loop(Ctrl *ctrl, struct RecordBuffer *in_buf)
TermBufToChars(&term, out, out_max); TermBufToChars(&term, out, out_max);
puts(out); puts(out);
WindowsWait(0.5); WindowsWait(1.0/30);
} }
} }
int main() int main()
{ {
WindowsInit(); #ifdef _WIN32
if(!WindowsInit())
exit(1);
#endif
Ctrl ctrl; struct bkt code_bkts[code_count];
NEW_CTRL(ctrl, 13, 13); struct dict codes = {
.capacity = code_count,
.filled = 0,
.bkts = code_bkts
};
struct bkt bind_bkts[code_count];
struct dict binds = {
.capacity = code_count,
.filled = 0,
.bkts = bind_bkts
};
struct Axis axes[code_count];
Ctrl ctrl = NewCtrl(&codes, &binds, axes);
for (size_t i = 0; i < code_count; i++) { for (size_t i = 0; i < code_count; i++) {
CtrlMap(&ctrl, key_binds[i], key_codes[i], KEY); const struct CtrlBind *bind = &ctrl_binds[i];
CtrlMap(&ctrl, bind->code, bind->bind, bind->type);
} }
for (size_t i = 0; i < 2; i++) {
CtrlMap(&ctrl, axis_codes[i], axis_binds[i], AXIS);
}
CtrlMap(&ctrl, 0, MOUSE, JOYSTICK);
CtrlMap(&ctrl, 0, 0, WINDOW);
printf("set controls\n");
struct RecordBuffer in_buf = { struct RecordBuffer in_buf = {
.count = 0, .count = 0,
@ -117,7 +146,6 @@ int main()
StartInput(&ctrl, &in_buf); StartInput(&ctrl, &in_buf);
Loop(&ctrl, &in_buf); Loop(&ctrl, &in_buf);
JoinInput(&ctrl); JoinInput(&ctrl);
return 0; return 0;

View file

@ -21,10 +21,13 @@ struct TermBuf {
struct CharBlk4 *blks; struct CharBlk4 *blks;
}; };
struct TermBuf NewTermBuf(size_t wid, size_t hgt) struct TermBuf NewTermBuf(struct CharBlk4 *blks, size_t wid, size_t hgt)
{ {
size_t area = wid * hgt;
memset(blks, 0, sizeof(struct CharBlk4) * area);
return (struct TermBuf) { return (struct TermBuf) {
wid, hgt, wid * hgt wid, hgt, area, blks
}; };
} }
@ -105,24 +108,3 @@ size_t TermBufToChars(struct TermBuf *term, char *buf, size_t max_chars)
buf[filled] = 0; buf[filled] = 0;
return filled; return filled;
} }
/*int main()
{
struct TermBuf term;
term.wid = 20;
term.hgt = 10;
term.area = 20 * 10;
struct CharBlk4 blks[term.area];
memset(&blks, 0, sizeof(struct CharBlk4) * term.area);
term.blks = blks;
size_t out_max = TermMaxChars(&term);
char out[out_max];
memset(out, 0, out_max);
TermBufToChars(&term, out, out_max);
puts(out);
return 0;
}*/

View file

@ -22,7 +22,7 @@ struct TermBuf {
struct CharBlk4 *blks; struct CharBlk4 *blks;
}; };
struct TermBuf NewTermBuf(size_t wid, size_t hgt); struct TermBuf NewTermBuf(struct CharBlk4 *blks, size_t wid, size_t hgt);
size_t TermMaxChars(struct TermBuf *term); size_t TermMaxChars(struct TermBuf *term);

BIN
test.exe

Binary file not shown.