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:
maksw committed 2026-05-11 10:10:21 +02:00
1 parent cdf7ed4cea
commit 0c7f461c6d
24 files changed
+50236 -1310

No files matched your search

+105 -14
View File
@@ -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;
}