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:
maksw committed 2026-07-12 00:10:21 +02:00
1 parent 485a6bbfe7
commit 8b254f84f4
74 files changed
+4488 -2503

No files matched your search

+61 -6
View File
@@ -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 */));