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;
|
||||
}
|
||||
Reference in new issue
Block a user