add /IGNORE:4216 to HAL link step, add writing and directory listing to the FAT32 driver, add the concept of current working directory to the VFS, add writing to the VFS, more operations in the shell, rename KeCurrentThread to KeGetCurrentThread and add KeGetCurrentProcess, add STATUS_NO_MORE_FILES, change KeFault* to KePanic, add syscalls for writing to files, add a proper syscall to writing to the console, move Screen.Clear to after memory status debug print, add ObjectTypeDir to OBJECT_TYPE, extend kernel32 by file operations and upgrade user32 (and add gdi32) to match windows a bit more closely, change CreateProcessA to accept the first argument as NULL.

This commit is contained in:
maksw committed 2026-05-04 16:27:49 +02:00
1 parent a5f0acfac8
commit 8c7564d5e1
33 files changed
+2343 -429

No files matched your search

+147 -61
View File
@@ -4,83 +4,169 @@
#include <intrin.h>
#include "bink.h"
void OutputDebugStringA(const char* s);
// ---------------------------------------------------------------------------
// Win32 Boilerplate & API declarations
// ---------------------------------------------------------------------------
typedef void* HWND;
typedef void* HDC;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned int UINT;
typedef long LONG;
typedef int BOOL;
#define BI_RGB 0L
#define DIB_RGB_COLORS 0
#define SRCCOPY 0x00CC0020
#define STD_OUTPUT_HANDLE ((DWORD)-11)
typedef struct _RECT {
LONG left, top, right, bottom;
} RECT;
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
char rgbReserved[32];
} PAINTSTRUCT;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD {
unsigned char rgbBlue, rgbGreen, rgbRed, rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
// Kernel/Win32 Exports
void* GetStdHandle(DWORD nStdHandle);
int WriteConsoleA(void* hConsoleOutput, const void* lpBuffer, unsigned int nNumberOfCharsToWrite, unsigned int* lpNumberOfCharsWritten, void* lpReserved);
_Noreturn void ExitProcess(unsigned int code);
void* HeapAlloc(void* heap, unsigned long flags, size_t size);
void BitBlt(int x, int y, int w, int h, const uint32_t* pixels);
void* CreateFileA(const char* name, unsigned long access,
unsigned long share, void* sa,
unsigned long disp, unsigned long flags,
void* templ);
void* CreateFileA(const char* name, unsigned long access, unsigned long share, void* sa, unsigned long disp, unsigned long flags, void* templ);
unsigned long GetFileSize(void* handle, unsigned long* high);
int ReadFile(void* handle, void* buf, unsigned long toRead,
unsigned long* read, void* overlapped);
int ReadFile(void* handle, void* buf, unsigned long toRead, unsigned long* read, void* overlapped);
BOOL CloseHandle(void* hObject);
// New GDI/User32 Exports
HDC BeginPaint(HWND hwnd, PAINTSTRUCT* lpPaint);
BOOL EndPaint(HWND hwnd, const PAINTSTRUCT* lpPaint);
int StretchDIBits(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight,
int xSrc, int ySrc, int SrcWidth, int SrcHeight,
const void *lpBits, const BITMAPINFO *lpbmi,
UINT iUsage, DWORD rop);
int main() {
OutputDebugStringA("video: starting\n");
void* h = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleA(h, "video: starting\n", 16, 0, 0);
// void* f = CreateFileA("video.bk2", 0, 0, 0, 3, 0, 0);
// if (!f) {
// OutputDebugStringA("video: failed to open video.bk2\n");
// ExitProcess(1);
// }
void* f = CreateFileA("video.bk2", 0, 0, 0, 3, 0, 0);
if (!f) {
WriteConsoleA(h, "video: failed to open video.bk2\n", 32, 0, 0);
ExitProcess(1);
}
// unsigned long s = GetFileSize(f, 0);
// void* buf = HeapAlloc(0, 0, s);
// if (!buf) {
// OutputDebugStringA("video: HeapAlloc failed\n");
// ExitProcess(1);
// }
unsigned long s = GetFileSize(f, 0);
void* buf = HeapAlloc(0, 0, s);
if (!buf) {
WriteConsoleA(h, "video: HeapAlloc failed\n", 24, 0, 0);
ExitProcess(1);
}
// int r = ReadFile(f, buf, s, 0, 0);
// if (!r) {
// OutputDebugStringA("video: ReadFile failed\n");
// ExitProcess(1);
// }
// OutputDebugStringA("video: video.bk2 loaded\n");
int r = ReadFile(f, buf, s, 0, 0);
if (!r) {
WriteConsoleA(h, "video: ReadFile failed\n", 23, 0, 0);
ExitProcess(1);
}
WriteConsoleA(h, "video: video.bk2 loaded\n", 24, 0, 0);
CloseHandle(h);
// HBINK bink = BinkOpen(buf, BINKFROMMEMORY);
// if (!bink) {
// OutputDebugStringA("video: BinkOpen failed: ");
// OutputDebugStringA(BinkGetError());
// OutputDebugStringA("\n");
// ExitProcess(1);
// }
HBINK bink = BinkOpen(buf, BINKFROMMEMORY);
if (!bink) {
WriteConsoleA(h, "video: BinkOpen failed: ", 24, 0, 0);
const char* err = BinkGetError();
WriteConsoleA(h, err, strlen(err), 0, 0);
WriteConsoleA(h, "\n", 1, 0, 0);
ExitProcess(1);
}
// uint32_t width = bink->Width;
// uint32_t height = bink->Height;
uint32_t width = bink->Width;
uint32_t height = bink->Height;
// uint32_t* fb = HeapAlloc(0, 0, width * height * sizeof(uint32_t));
// if (!fb) {
// OutputDebugStringA("video: framebuffer alloc failed\n");
// ExitProcess(1);
// }
uint32_t* fb = HeapAlloc(0, 0, width * height * sizeof(uint32_t));
if (!fb) {
WriteConsoleA(h, "video: framebuffer alloc failed\n", 32, 0, 0);
ExitProcess(1);
}
// while (1) {
// if (BinkWait(bink)) {
// _mm_pause();
// continue;
// }
// Prepare the Win32 BITMAPINFO structure
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -(LONG)height; // Negative means top-down drawing!
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
// BinkDoFrame(bink);
while (1) {
if (BinkWait(bink)) {
_mm_pause();
continue;
}
// if (BinkShouldSkip(bink)) {
// BinkNextFrame(bink);
// BinkDoFrame(bink);
// continue;
// }
BinkDoFrame(bink);
// BinkCopyToBuffer(bink, fb, width * 4, height, 0, 0, BINKSURFACE32);
// BitBlt(0, 0, width, height, fb);
if (BinkShouldSkip(bink)) {
BinkNextFrame(bink);
continue;
}
// if (bink->FrameNum == bink->Frames)
// break;
BinkCopyToBuffer(bink, fb, width * 4, height, 0, 0,
BINKSURFACE32);
// BinkNextFrame(bink);
// }
// Welcome to the GDI pipeline!
PAINTSTRUCT ps;
// Using NULL/0 as the HWND since we don't have a real window handle yet
HDC hdc = BeginPaint((HWND)0, &ps);
// BinkClose(bink);
for (int i = 0; i < 10000000; i++) _mm_pause();
OutputDebugStringA("video: done\n");
ExitProcess(0);
StretchDIBits(
hdc,
0, 0, width, height, // Destination rect
0, 0, width, height, // Source rect
fb,
&bmi,
DIB_RGB_COLORS,
SRCCOPY
);
EndPaint((HWND)0, &ps);
BinkNextFrame(bink);
}
WriteConsoleA(h, "shell: goodbye\n", 15, 0, 0);
return 0;
}