replace the VHD/diskpart disk image pipeline with a directory-based vvfat root, we'll see when it breaks, fix /O2, add an all_tests, generalize the fat32 driver into a fat 16+32 driver, change policy on volume drivers, collapse KCPU's fields into a single atomic KE_CPU_STATE state machine, move scheduler ticking to per-CPU LAPIC timers, gate verbose SMP topology logging behind selftest diagnostics and add SMP pool-checkpoint validation around AP admission, add checked intrusive list helpers behind a new KE_DEBUG_LIST_CHECKS flag, add ObInitializeObjectHeader/ObTryReferenceObject, add waitable display clock objects and a SYS_OPEN_DISPLAY_CLOCK syscall for vsync-style waits, refactor kernel input into a per-queue KE_INPUT_CONTEXT with its own key/mouse ring buffers and DPC-driven key repeat, add KeInputQueuePeekEvent/ReadEvent/WaitKey and a SYS_QUERY_GLOBAL_INPUT_STATE syscall, split the kernel pool allocator out of mm_virt, new video files!
This commit is contained in:
1 parent
485a6bbfe7
commit
8b254f84f4
74 files changed
+4488
-2503
No files matched your search
@@ -274,17 +274,25 @@ static const KeyMap g_keymap[] = {
|
||||
|
||||
static bool g_prev_key[KEYMAP_COUNT];
|
||||
|
||||
// Returns whether one NTLite input key is currently held.
|
||||
static bool ntlite_key_down(INPUT_KEY key)
|
||||
// Returns whether one key bit is set in a global input snapshot.
|
||||
static bool ntlite_snapshot_key_down(const SYS_GLOBAL_INPUT_STATE* state, INPUT_KEY key)
|
||||
{
|
||||
bool down = false;
|
||||
return SysIsKeyDown(key, &down) == NTLSTATUS_SUCCESS && down;
|
||||
if (!state || key >= 256u) return false;
|
||||
return (state->KeyDown[key >> 3] & (uint8_t)(1u << (key & 7u))) != 0;
|
||||
}
|
||||
|
||||
static void poll_input(void)
|
||||
{
|
||||
SYS_GLOBAL_INPUT_STATE input;
|
||||
memset(&input, 0, sizeof(input));
|
||||
input.Size = sizeof(input);
|
||||
input.Flags = SYS_GLOBAL_INPUT_STATE_FLAG_NONE;
|
||||
|
||||
if (SysQueryGlobalInputState(&input) != NTLSTATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < (int)KEYMAP_COUNT; i++) {
|
||||
bool cur_down = ntlite_key_down(g_keymap[i].inputKey);
|
||||
bool cur_down = ntlite_snapshot_key_down(&input, g_keymap[i].inputKey);
|
||||
bool prev_down = g_prev_key[i];
|
||||
|
||||
if (cur_down && !prev_down) doom_key_down(g_keymap[i].key);
|
||||
@@ -304,6 +312,7 @@ static void poll_input(void)
|
||||
#define DISP_H (DOOM_H * SCALE)
|
||||
|
||||
static uint32_t g_surface_handle;
|
||||
static uint32_t g_display_clock_handle;
|
||||
static uint32_t* g_surface_pixels;
|
||||
static uint32_t g_surface_pitch_pixels;
|
||||
|
||||
@@ -335,6 +344,22 @@ static void init_surface(void)
|
||||
g_surface_pitch_pixels = pitchBytes / sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static void init_display_clock(void)
|
||||
{
|
||||
SYS_OPEN_DISPLAY_CLOCK_REQUEST req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.Size = sizeof(req);
|
||||
req.Flags = SYS_DISPLAY_CLOCK_FLAG_NONE;
|
||||
req.PeriodMilliseconds = 1;
|
||||
req.HandleOut = &g_display_clock_handle;
|
||||
|
||||
uint32_t s = SysOpenDisplayClock(&req);
|
||||
if (s != NTLSTATUS_SUCCESS) {
|
||||
g_display_clock_handle = 0;
|
||||
doom_print_wrapper("doom: display clock unavailable, using sleep pacing\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void render_frame(const uint8_t* rgba)
|
||||
{
|
||||
const uint32_t* src = (const uint32_t*)rgba;
|
||||
@@ -409,6 +434,30 @@ static int build_argv_from_command_line(const char* cmdline, char* storage, size
|
||||
return argc;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timing
|
||||
// ---------------------------------------------------------------------------
|
||||
static int doom_now_tic(void)
|
||||
{
|
||||
return I_GetTime();
|
||||
}
|
||||
|
||||
// Waits until Doom has a new simulation tic to render.
|
||||
static int wait_for_next_doom_tic(int lastTic)
|
||||
{
|
||||
for (;;) {
|
||||
int now = doom_now_tic();
|
||||
if (now != lastTic)
|
||||
return now;
|
||||
|
||||
if (g_display_clock_handle) {
|
||||
(void)SysWaitSingle(g_display_clock_handle, SYS_WAIT_FLAG_NONE, SYS_WAIT_TIMEOUT_INFINITE);
|
||||
} else {
|
||||
SysSleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// main
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -447,12 +496,18 @@ int main(void)
|
||||
const char* argv[32];
|
||||
int argc = build_argv_from_command_line(cmdline, argvStorage, sizeof(argvStorage), argv, 32);
|
||||
init_surface();
|
||||
init_display_clock();
|
||||
doom_init(argc, argv, 0);
|
||||
|
||||
do { SYS_WRITE_CONSOLE_REQUEST req = { SYS_SV_LITERAL("doom: entering game loop\n") }; SysWriteConsole(&req); } while (0);
|
||||
|
||||
// Core execution loop
|
||||
// Core execution loop. Doom advances at TICRATE, so rendering duplicate
|
||||
// frames as fast as possible only amplifies scheduler and input jitter.
|
||||
int lastFrameTic = doom_now_tic();
|
||||
while (1) {
|
||||
int frameTic = wait_for_next_doom_tic(lastFrameTic);
|
||||
lastFrameTic = frameTic;
|
||||
|
||||
poll_input();
|
||||
doom_update();
|
||||
render_frame((const uint8_t*)doom_get_framebuffer(4 /* RGBA */));
|
||||
|
||||
Reference in new issue
Block a user