Fumofumotris/source/io/platforms/winhandler.c

153 lines
3.8 KiB
C
Raw Normal View History

2024-03-25 05:34:59 +00:00
#include <iso646.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
2024-04-01 22:39:21 +00:00
#include <time.h>
2024-03-25 05:34:59 +00:00
#include "fumotris.h"
2024-03-26 20:11:58 +00:00
#include "gametime.h"
2024-03-25 05:34:59 +00:00
#include "input.h"
struct Windows {
HANDLE input_handle;
HANDLE timer;
};
static struct Windows windows;
bool WinInitInputHandle()
{
windows.input_handle = GetStdHandle(STD_INPUT_HANDLE);
if (windows.input_handle == INVALID_HANDLE_VALUE)
return false;
return true;
}
bool WinInitTimer()
{
windows.timer = CreateWaitableTimer(NULL, TRUE, NULL);
if (!windows.timer)
return false;
return true;
}
bool WinInitConsole()
{
DWORD mode = ENABLE_EXTENDED_FLAGS
| ENABLE_PROCESSED_INPUT
| ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
| ENABLE_VIRTUAL_TERMINAL_PROCESSING;
return SetConsoleMode(windows.input_handle, mode);
}
void set_key_record(struct InputRecord *record, KEY_EVENT_RECORD win_key)
{
record->type = KEY;
record->id = win_key.wVirtualKeyCode;
2024-03-26 20:11:58 +00:00
record->data.key.is_down = win_key.bKeyDown;
2024-03-25 05:34:59 +00:00
if (win_key.wVirtualKeyCode == VK_ESCAPE)
record->type = ESCAPE;
}
bool set_mouse_record(struct InputRecord *record, MOUSE_EVENT_RECORD win_mouse)
{
switch (win_mouse.dwEventFlags) {
case MOUSE_WHEELED:
record->type = AXIS;
record->id = 0;
record->data.axis.value = win_mouse.dwButtonState;
break;
case MOUSE_HWHEELED:
record->type = AXIS;
record->id = 1;
record->data.axis.value = win_mouse.dwButtonState;
break;
case MOUSE_MOVED:
record->type = JOYSTICK;
record->id = 0;
record->data.joystick.x = win_mouse.dwMousePosition.X;
record->data.joystick.y = win_mouse.dwMousePosition.Y;
break;
default:
return false;
}
return true;
}
void set_window_record(struct InputRecord *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 InputRecord *record, INPUT_RECORD win_record)
{
switch (win_record.EventType) {
case KEY_EVENT:
set_key_record(record, win_record.Event.KeyEvent);
return true;
case MOUSE_EVENT:
return set_mouse_record(record, win_record.Event.MouseEvent);
case WINDOW_BUFFER_SIZE_EVENT:
set_window_record(record, win_record.Event.WindowBufferSizeEvent);
return true;
default:
record->type = ESCAPE;
}
return true;
}
2024-03-26 20:11:58 +00:00
bool WinBlockInput(struct InputBuffer *buf)
2024-03-25 05:34:59 +00:00
{
2024-04-01 22:39:21 +00:00
printf("\twin blocked: %u\n", buf);
2024-03-26 20:11:58 +00:00
size_t win_size = IO_BUF_SIZE - buf->count;
2024-04-01 22:39:21 +00:00
printf("\twhar\n");
2024-03-26 20:11:58 +00:00
INPUT_RECORD win_buf[win_size];
2024-03-25 05:34:59 +00:00
DWORD count;
2024-04-01 22:39:21 +00:00
printf("\treading in..\n");
2024-03-26 20:11:58 +00:00
if (!ReadConsoleInput(windows.input_handle, win_buf, win_size, &count))
2024-03-25 05:34:59 +00:00
return false;
2024-04-01 22:39:21 +00:00
printf("\read done\n");
2024-03-26 20:11:58 +00:00
2024-04-01 22:39:21 +00:00
struct timespec now;
timespec_get(&now, TIME_UTC);
2024-03-26 20:11:58 +00:00
pthread_mutex_lock(&buf->mutex);
2024-03-25 05:34:59 +00:00
for (size_t i = 0; i < count; i++) {
struct InputRecord record;
2024-03-26 20:11:58 +00:00
record.timestamp = now;
2024-03-25 05:34:59 +00:00
2024-03-26 20:11:58 +00:00
bool include = dispatch_record(&record, win_buf[i]);
2024-03-25 05:34:59 +00:00
if (!include)
2024-03-26 20:11:58 +00:00
continue;
2024-03-25 05:34:59 +00:00
2024-03-26 20:11:58 +00:00
buf->records[buf->count] = record;
buf->count += 1;
2024-03-25 05:34:59 +00:00
}
2024-03-26 20:11:58 +00:00
pthread_mutex_unlock(&buf->mutex);
2024-03-25 05:34:59 +00:00
return true;
}
bool WinWait(double seconds)
{
LARGE_INTEGER duration;
duration.QuadPart = (u64)(-10000000.0 * seconds);
if (!SetWaitableTimer(windows.timer, &duration, 0, NULL, NULL, FALSE))
return false;
2024-04-01 22:39:21 +00:00
printf("about to wait..\n");
2024-03-25 05:34:59 +00:00
DWORD result = WaitForSingleObject(windows.timer, INFINITE);
2024-04-01 22:39:21 +00:00
printf("waitforsingle\n");
2024-03-25 05:34:59 +00:00
if (result != WAIT_OBJECT_0)
return false;
return true;
}