add doom, disable warnings as errors, massive speedups in the fat32 driver, HAL_KEYBOARD Poll now returns the key and added IsKeyDown used by GetAsyncKeyState, slight upgrade in hal_main drain and pray, more accurate QueryTicks and by that GetTickCount, add GetTickCount64, boot.ini now dictates what executable should init launch, not the kernel, LaunchUserProcess in kmain.c now takes an argument, rearrange syscall numbers, add SysKbIsKeyDown syscall, use include windows.h over manual definitions, add fictional win32 api ClearConsoleScreenBuffer and real FlushConsoleInputBuffer and a clear command to the shell, print exit codes as signed int, StretchDIBits now can stretch, runa.bat now gives 256 MB.
This commit is contained in:
1 parent
cdf7ed4cea
commit
0c7f461c6d
24 files changed
+50236
-1310
No files matched your search
+105
-14
@@ -1,11 +1,20 @@
|
||||
// gdi32.c - Win32 Graphics Device Interface stubs
|
||||
// gdi32.c
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__SSE2__) || defined(_M_X64) || defined(_M_IX86)
|
||||
#include <emmintrin.h>
|
||||
#elif defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM64)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Syscall stubs (from syscall.dll)
|
||||
// ---------------------------------------------------------------------------
|
||||
extern void SysScreenBlit(int x, int y, int w, int h, const uint32_t* pixels);
|
||||
extern void* SysAlloc(size_t size);
|
||||
extern void SysFree(void* ptr, size_t size);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Win32 Base Types
|
||||
@@ -54,9 +63,17 @@ typedef struct tagBITMAPINFO {
|
||||
RGBQUAD bmiColors[1];
|
||||
} BITMAPINFO;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GDI Exports
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Static buffers to persist between function calls
|
||||
static uint32_t* destBuffer = NULL;
|
||||
static int* srcX_map = NULL;
|
||||
static int currentDestCapacity = 0;
|
||||
static int currentXMapCapacity = 0;
|
||||
|
||||
__declspec(dllexport) int StretchDIBits(
|
||||
HDC hdc,
|
||||
int xDest, int yDest, int DestWidth, int DestHeight,
|
||||
@@ -64,20 +81,94 @@ __declspec(dllexport) int StretchDIBits(
|
||||
const void *lpBits, const BITMAPINFO *lpbmi,
|
||||
UINT iUsage, DWORD rop)
|
||||
{
|
||||
(void)hdc; (void)xSrc; (void)ySrc; (void)SrcWidth; (void)SrcHeight;
|
||||
(void)lpbmi; (void)iUsage; (void)rop;
|
||||
(void)hdc; (void)lpbmi; (void)iUsage; (void)rop;
|
||||
|
||||
// Direct mapping to kernel screen blit
|
||||
SysScreenBlit(xDest, yDest, DestWidth, DestHeight, (const uint32_t*)lpBits);
|
||||
// Safety check to prevent division by zero
|
||||
if (DestWidth <= 0 || DestHeight <= 0 || SrcWidth <= 0 || SrcHeight <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle trivial case (1:1 copy) to bypass allocation and scaling overhead
|
||||
if (DestWidth == SrcWidth && DestHeight == SrcHeight && xSrc == 0 && ySrc == 0) {
|
||||
SysScreenBlit(xDest, yDest, DestWidth, DestHeight, (const uint32_t*)lpBits);
|
||||
return DestHeight;
|
||||
}
|
||||
|
||||
const uint32_t* srcPixels = (const uint32_t*)lpBits;
|
||||
|
||||
// Only reallocate if the new size is LARGER than what we already have
|
||||
int requiredPixels = DestWidth * DestHeight;
|
||||
if (requiredPixels > currentDestCapacity) {
|
||||
SysFree(destBuffer, 0);
|
||||
destBuffer = (uint32_t*)SysAlloc(requiredPixels * sizeof(uint32_t));
|
||||
currentDestCapacity = requiredPixels;
|
||||
}
|
||||
|
||||
if (DestWidth > currentXMapCapacity) {
|
||||
SysFree(srcX_map, 0);
|
||||
srcX_map = (int*)SysAlloc(DestWidth * sizeof(int));
|
||||
currentXMapCapacity = DestWidth;
|
||||
}
|
||||
|
||||
for (int dx = 0; dx < DestWidth; ++dx) {
|
||||
// Nearest neighbor coordinate mapping
|
||||
srcX_map[dx] = xSrc + (dx * SrcWidth) / DestWidth;
|
||||
|
||||
// Clamp to safe bounds
|
||||
if (srcX_map[dx] < 0) srcX_map[dx] = 0;
|
||||
if (srcX_map[dx] >= SrcWidth) srcX_map[dx] = SrcWidth - 1;
|
||||
}
|
||||
|
||||
// Process the image row by row
|
||||
for (int dy = 0; dy < DestHeight; ++dy) {
|
||||
// Map destination Y to source Y
|
||||
int sy = ySrc + (dy * SrcHeight) / DestHeight;
|
||||
if (sy < 0) sy = 0;
|
||||
if (sy >= SrcHeight) sy = SrcHeight - 1;
|
||||
|
||||
// Assumes stride == SrcWidth (tightly packed 32bpp)
|
||||
const uint32_t* srcRow = srcPixels + (sy * SrcWidth);
|
||||
uint32_t* dstRow = destBuffer + (dy * DestWidth);
|
||||
|
||||
int dx = 0;
|
||||
|
||||
#if defined(__SSE2__) || defined(_M_X64)
|
||||
// Process 4 pixels (16 bytes) per loop iteration using SSE2
|
||||
for (; dx <= DestWidth - 4; dx += 4) {
|
||||
// Gather 4 source pixels using our precomputed X map.
|
||||
// Note: _mm_set_epi32 takes arguments in reverse order (3, 2, 1, 0)
|
||||
__m128i pixels = _mm_set_epi32(
|
||||
srcRow[srcX_map[dx + 3]],
|
||||
srcRow[srcX_map[dx + 2]],
|
||||
srcRow[srcX_map[dx + 1]],
|
||||
srcRow[srcX_map[dx + 0]]
|
||||
);
|
||||
// Issue a single 128-bit unaligned store
|
||||
_mm_storeu_si128((__m128i*)&dstRow[dx], pixels);
|
||||
}
|
||||
#elif defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM64)
|
||||
// Process 4 pixels per loop iteration using ARM NEON
|
||||
for (; dx <= DestWidth - 4; dx += 4) {
|
||||
// Initialize a vector and populate lanes (avoids stack-memory hop)
|
||||
uint32x4_t pixels = vdupq_n_u32(0);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 0]], pixels, 0);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 1]], pixels, 1);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 2]], pixels, 2);
|
||||
pixels = vsetq_lane_u32(srcRow[srcX_map[dx + 3]], pixels, 3);
|
||||
|
||||
// Issue a single 128-bit store
|
||||
vst1q_u32(&dstRow[dx], pixels);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Epilogue: Handle remaining pixels if DestWidth isn't a multiple of 4
|
||||
for (; dx < DestWidth; ++dx) {
|
||||
dstRow[dx] = srcRow[srcX_map[dx]];
|
||||
}
|
||||
}
|
||||
|
||||
// Direct mapping to kernel screen blit using the stretched buffer
|
||||
SysScreenBlit(xDest, yDest, DestWidth, DestHeight, destBuffer);
|
||||
|
||||
// Return the number of scanlines copied
|
||||
return DestHeight;
|
||||
}
|
||||
|
||||
__declspec(dllexport) BOOL BitBlt(HDC hdcDest, int xDest, int yDest, int w, int h,
|
||||
HDC hdcSrc, int xSrc, int ySrc, DWORD rop) {
|
||||
(void)hdcDest; (void)xDest; (void)yDest; (void)w; (void)h;
|
||||
(void)hdcSrc; (void)xSrc; (void)ySrc; (void)rop;
|
||||
// Stubbed. Applications manipulating pixels directly will use StretchDIBits.
|
||||
return TRUE;
|
||||
}
|
||||
+128
-27
@@ -28,45 +28,59 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Syscall stubs (from syscall.dll, assembled from syscall_stubs.asm)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Memory
|
||||
extern void* SysAlloc(size_t size);
|
||||
extern void SysFree(void* ptr, size_t size);
|
||||
extern void* SysRealloc(void* ptr, size_t newSize);
|
||||
|
||||
extern uint32_t SysOpenFile(const char* path, uint32_t* handleOut);
|
||||
extern uint32_t SysReadFile(uint32_t handle, void* buf, size_t size, size_t* bytesReadOut);
|
||||
extern uint32_t SysWriteFile(uint32_t handle, const void* buf,
|
||||
size_t size, size_t* bytesWrittenOut);
|
||||
extern uint32_t SysCreateFile(const char* path, uint32_t* handleOut);
|
||||
extern uint32_t SysDeleteFile(const char* path);
|
||||
extern uint32_t SysTruncateFile(uint32_t handle, uint64_t newSize);
|
||||
extern uint64_t SysGetFilePos(uint32_t handle);
|
||||
extern uint32_t SysSeekFile(uint32_t handle, uint64_t offset);
|
||||
extern uint64_t SysGetFileSize(uint32_t handle);
|
||||
extern void SysCloseHandle(uint32_t handle);
|
||||
|
||||
// Process & Thread
|
||||
extern void SysExitProcess(int exitCode);
|
||||
extern void SysExitThread(int exitCode);
|
||||
extern uint32_t SysCreateThread(uint64_t entry, uint64_t arg,
|
||||
uint32_t priority, uint32_t* tidOut);
|
||||
extern uint32_t SysGetCurrentTid(void);
|
||||
extern uint32_t SysGetCurrentPid(void);
|
||||
extern uint32_t SysCreateProcess(const char* path, uint32_t* handleOut, const char* cmdline);
|
||||
extern uint32_t SysWaitForProcess(uint32_t handle);
|
||||
extern uint32_t SysCreateThread(uint64_t entry, uint64_t arg, uint32_t priority, uint32_t* tidOut);
|
||||
extern uint32_t SysGetCurrentPid(void);
|
||||
extern uint32_t SysGetCurrentTid(void);
|
||||
extern uint32_t SysGetProcessExitCode(uint32_t handle, int* exitCodeOut);
|
||||
extern char SysKbReadChar(void);
|
||||
extern uint32_t SysKbPoll(void);
|
||||
extern void SysYield(void);
|
||||
extern void SysSleep(uint32_t ms);
|
||||
extern uint32_t SysWaitForProcess(uint32_t handle);
|
||||
|
||||
extern uint64_t SysGetTick(void);
|
||||
extern void SysDebugPrint(const char* str);
|
||||
// File I/O
|
||||
extern void SysCloseHandle(uint32_t handle);
|
||||
extern uint32_t SysCreateFile(const char* path, uint32_t* handleOut);
|
||||
extern uint32_t SysDeleteFile(const char* path);
|
||||
extern uint64_t SysGetFilePos(uint32_t handle);
|
||||
extern uint64_t SysGetFileSize(uint32_t handle);
|
||||
extern uint32_t SysOpenFile(const char* path, uint32_t* handleOut);
|
||||
extern uint32_t SysReadFile(uint32_t handle, void* buf, size_t size, size_t* bytesReadOut);
|
||||
extern uint32_t SysSeekFile(uint32_t handle, uint64_t offset);
|
||||
extern uint32_t SysTruncateFile(uint32_t handle, uint64_t newSize);
|
||||
extern uint32_t SysWriteFile(uint32_t handle, const void* buf, size_t size, size_t* bytesWrittenOut);
|
||||
|
||||
// Console & directory & CWD stubs (syscall.dll)
|
||||
extern void SysWriteConsole(const char* buf, size_t len);
|
||||
// Console & directory & CWD stubs
|
||||
extern uint32_t SysGetCwd(char* buf, size_t size);
|
||||
extern uint32_t SysOpenDir(const char* dirPath, uint32_t* handleOut);
|
||||
extern uint32_t SysReadDir(uint32_t handle, void* entryOut);
|
||||
extern void SysScreenClear(uint32_t color);
|
||||
extern uint32_t SysSetCwd(const char* path);
|
||||
extern uint32_t SysGetCwd(char* buf, size_t size);
|
||||
extern void SysWriteConsole(const char* buf, size_t len);
|
||||
|
||||
// Keyboard syscalls
|
||||
extern uint32_t SysKbGetModifiers(void);
|
||||
extern uint64_t SysKbIsKeyDown(uint8_t scancode, bool extended);
|
||||
extern uint32_t SysKbPoll(void);
|
||||
extern char SysKbReadChar(void);
|
||||
extern unsigned char SysKbReadScancode(void);
|
||||
|
||||
// Mouse syscalls
|
||||
extern void SysMouseGetPos(int* x, int* y);
|
||||
extern uint32_t SysMousePoll(void);
|
||||
extern uint32_t SysMouseRead(int* dx, int* dy, unsigned char* buttons);
|
||||
|
||||
// Misc
|
||||
extern void SysDebugPrint(const char* str);
|
||||
extern void SysYield(void);
|
||||
extern void SysSleep(uint32_t ms);
|
||||
extern uint64_t SysGetTick(void);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Types
|
||||
@@ -74,6 +88,10 @@ extern uint32_t SysGetCwd(char* buf, size_t size);
|
||||
typedef void* HANDLE;
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef short SHORT;
|
||||
typedef long LONG;
|
||||
typedef struct { LONG x; LONG y; } POINT;
|
||||
|
||||
#define MAX_PATH 260
|
||||
#define TRUE 1
|
||||
@@ -156,7 +174,11 @@ __declspec(dllexport) void OutputDebugStringA(const char* str) {
|
||||
// Timer
|
||||
// ---------------------------------------------------------------------------
|
||||
__declspec(dllexport) DWORD GetTickCount(void) {
|
||||
return (DWORD)SysGetTick() * 10;
|
||||
return (DWORD)(SysGetTick() / 1000);
|
||||
}
|
||||
|
||||
__declspec(dllexport) uint64_t GetTickCount64(void) {
|
||||
return SysGetTick() / 1000;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -194,6 +216,85 @@ __declspec(dllexport) void* GetProcessHeap(void) {
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
// --- Win32 API ---
|
||||
|
||||
// Updated GetAsyncKeyState implementation
|
||||
__declspec(dllexport) SHORT GetAsyncKeyState(int vKey) {
|
||||
static const struct { int vk; uint8_t sc; bool ext; } vk_to_sc[] = {
|
||||
// Letters
|
||||
{ 0x41, 0x1E, false }, { 0x42, 0x30, false }, { 0x43, 0x2E, false },
|
||||
{ 0x44, 0x20, false }, { 0x45, 0x12, false }, { 0x46, 0x21, false },
|
||||
{ 0x47, 0x22, false }, { 0x48, 0x23, false }, { 0x49, 0x17, false },
|
||||
{ 0x4A, 0x24, false }, { 0x4B, 0x25, false }, { 0x4C, 0x26, false },
|
||||
{ 0x4D, 0x32, false }, { 0x4E, 0x31, false }, { 0x4F, 0x18, false },
|
||||
{ 0x50, 0x19, false }, { 0x51, 0x10, false }, { 0x52, 0x13, false },
|
||||
{ 0x53, 0x1F, false }, { 0x54, 0x14, false }, { 0x55, 0x16, false },
|
||||
{ 0x56, 0x2F, false }, { 0x57, 0x11, false }, { 0x58, 0x2D, false },
|
||||
{ 0x59, 0x15, false }, { 0x5A, 0x2C, false },
|
||||
|
||||
// Numbers
|
||||
{ 0x31, 0x02, false }, { 0x32, 0x03, false }, { 0x33, 0x04, false },
|
||||
{ 0x34, 0x05, false }, { 0x35, 0x06, false }, { 0x36, 0x07, false },
|
||||
{ 0x37, 0x08, false }, { 0x38, 0x09, false }, { 0x39, 0x0A, false },
|
||||
{ 0x30, 0x0B, false },
|
||||
|
||||
// Arrows (Extended)
|
||||
{ 0x26, 0x48, true }, // VK_UP
|
||||
{ 0x28, 0x50, true }, // VK_DOWN
|
||||
{ 0x25, 0x4B, true }, // VK_LEFT
|
||||
{ 0x27, 0x4D, true }, // VK_RIGHT
|
||||
|
||||
// Controls
|
||||
{ 0x1B, 0x01, false }, // ESC
|
||||
{ 0x0D, 0x1C, false }, // ENTER
|
||||
{ 0x20, 0x39, false }, // SPACE
|
||||
{ 0x11, 0x1D, false }, // CTRL (Generic)
|
||||
{ 0x10, 0x2A, false }, // SHIFT (Generic)
|
||||
{ 0x12, 0x38, false }, // ALT (Generic)
|
||||
{ 0x08, 0x0E, false }, // BACKSPACE
|
||||
{ 0x09, 0x0F, false }, // TAB
|
||||
|
||||
// Function Keys
|
||||
{ 0x70, 0x3B, false }, { 0x71, 0x3C, false }, { 0x72, 0x3D, false },
|
||||
{ 0x73, 0x3E, false }, { 0x74, 0x3F, false }, { 0x75, 0x40, false },
|
||||
{ 0x76, 0x41, false }, { 0x77, 0x42, false }, { 0x78, 0x43, false },
|
||||
{ 0x79, 0x44, false }, { 0x7A, 0x57, false }, { 0x7B, 0x58, false },
|
||||
|
||||
// Symbols
|
||||
{ 0xBD, 0x0C, false }, // MINUS '-'
|
||||
{ 0xBB, 0x0D, false }, // EQUALS '='
|
||||
{ 0xBC, 0x33, false }, // COMMA ','
|
||||
{ 0xBE, 0x34, false }, // PERIOD '.'
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(vk_to_sc)/sizeof(vk_to_sc[0]); ++i) {
|
||||
if (vk_to_sc[i].vk == vKey) {
|
||||
// Check the hardware state array via our HAL helper
|
||||
if (SysKbIsKeyDown(vk_to_sc[i].sc, vk_to_sc[i].ext)) {
|
||||
return (SHORT)0x8000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FlushConsoleInputBuffer: clear the keyboard input buffer
|
||||
__declspec(dllexport) BOOL FlushConsoleInputBuffer(HANDLE hConsoleInput) {
|
||||
(void)hConsoleInput;
|
||||
// Drain the keyboard buffer by reading until empty
|
||||
while (SysKbPoll()) {
|
||||
(void)SysKbReadChar();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// !Made-up! clear console api.
|
||||
__declspec(dllexport) BOOL ClearConsoleScreenBuffer(HANDLE hConsole) {
|
||||
SysScreenClear(0x00000000);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Locale / code-page stubs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user