fix the return value of LdrLoadImage, make use of __declspec(dllexport), speed up blitting, add dummy TEB, redesign the syscall interface, fix stack alignent so movaps doesn't crash, implement a shitload of win32, implement a simple shell, add bink as video.exe 😎, minor kmain.c cleanup, HAL now supports power-off events, implemented \b in hal_screen.c, fix many deadlocks, add wait for exit event for processes, completely new error codes, small readme changes.

This commit is contained in:
maksw committed 2026-05-03 13:43:29 +02:00
1 parent c13dd99150
commit 7f4052f41c
33 files changed
+6396 -735

No files matched your search

+992 -91
View File
File diff suppressed because it is too large. Load diff
+81 -2
View File
@@ -1,2 +1,81 @@
// ole32.c - stub; no COM at this stage.
static void stub(void) { }
// ole32.c - Win32 COM / OLE stubs
// No COM infrastructure at this stage; all functions fail gracefully.
#include <stdint.h>
#include <stddef.h>
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
typedef long HRESULT;
typedef void* IUnknown;
#define S_OK ((HRESULT)0x00000000L)
#define E_NOTIMPL ((HRESULT)0x80004001L)
#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
#define COINIT_MULTITHREADED 0x0
// GUID - 16-byte COM interface identifier.
typedef struct {
unsigned int Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
// PROPVARIANT - variant type used by shell / media APIs.
typedef struct {
unsigned short vt;
unsigned short wReserved1, wReserved2, wReserved3;
union {
long long hVal;
double dblVal;
void* punkVal;
unsigned char bVal;
unsigned int ulVal;
// ... (only common fields; full union is ~16 bytes)
unsigned char padding[16];
};
} PROPVARIANT;
extern void SysFree(void* ptr, size_t size);
// ---------------------------------------------------------------------------
// COM initialisation
// ---------------------------------------------------------------------------
__declspec(dllexport) HRESULT CoInitializeEx(void* reserved, unsigned long coInit) {
(void)reserved; (void)coInit;
return S_OK; // Pretend success; no actual apartment is created.
}
__declspec(dllexport) void CoUninitialize(void) {
// No-op.
}
// ---------------------------------------------------------------------------
// Object creation
// ---------------------------------------------------------------------------
__declspec(dllexport) HRESULT CoCreateInstance(const GUID* clsid, IUnknown* outer,
unsigned long ctx, const GUID* iid,
void** ppv) {
(void)clsid; (void)outer; (void)ctx; (void)iid;
if (ppv) *ppv = (void*)0;
return E_NOTIMPL;
}
// ---------------------------------------------------------------------------
// Memory
// ---------------------------------------------------------------------------
__declspec(dllexport) void CoTaskMemFree(void* pv) {
if (pv) SysFree(pv, 0);
}
// ---------------------------------------------------------------------------
// PROPVARIANT
// ---------------------------------------------------------------------------
__declspec(dllexport) HRESULT PropVariantClear(PROPVARIANT* pvar) {
if (!pvar) return E_NOTIMPL;
// Zero the entire structure; no deep release needed for stub types.
unsigned char* p = (unsigned char*)pvar;
for (size_t i = 0; i < sizeof(*pvar); i++) p[i] = 0;
return S_OK;
}
+79 -8
View File
@@ -1,20 +1,91 @@
// user32.c - minimal user32 stubs (no window manager yet)
// user32.c - Win32 user interface stubs (no window manager yet)
#include <stdint.h>
#include <stddef.h>
// Screen blit is the only graphical primitive available at this stage.
// ---------------------------------------------------------------------------
// Syscall stubs (from syscall.dll)
// ---------------------------------------------------------------------------
extern void SysScreenBlit(int x, int y, int w, int h, const uint32_t* pixels);
// syscall.dll
extern void SysYield(void);
extern void SysDebugPrint(const char* str);
extern uint32_t SysKbPoll(void);
void BitBlt(int x, int y, int w, int h, const uint32_t* pixels) {
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
typedef void* HWND;
#define IDOK 1
#define IDCANCEL 2
// ---------------------------------------------------------------------------
// Keyboard
// ---------------------------------------------------------------------------
// GetAsyncKeyState: returns non-zero if a key is available in the input
// buffer. We have no per-key state, so the vKey argument is ignored and
// the high bit (key-down) is set whenever SysKbPoll reports data waiting.
__declspec(dllexport) short GetAsyncKeyState(int vKey) {
(void)vKey;
// High bit (0x8000 / INT16_MIN) = key is down.
// Low bit = key pressed since last call; we have no per-key history to
// track, so it is left clear.
return SysKbPoll() ? (short)(-32768) : 0;
}
// ---------------------------------------------------------------------------
// Screen output
// ---------------------------------------------------------------------------
// BitBlt is the only graphical primitive available at this stage.
__declspec(dllexport) void BitBlt(int x, int y, int w, int h, const uint32_t* pixels) {
SysScreenBlit(x, y, w, h, pixels);
}
// Message loop stubs - always return 0.
int GetMessage(void* msg, void* hwnd, unsigned int min, unsigned int max) {
// ---------------------------------------------------------------------------
// Message loop (stubs - always return 0 / no messages)
// ---------------------------------------------------------------------------
__declspec(dllexport) int GetMessage(void* msg, HWND hwnd,
unsigned int min, unsigned int max) {
(void)msg; (void)hwnd; (void)min; (void)max;
SysYield();
return 0;
}
int DispatchMessage(const void* msg) { (void)msg; return 0; }
__declspec(dllexport) int DispatchMessage(const void* msg) { (void)msg; return 0; }
// ---------------------------------------------------------------------------
// Window queries (stubs - no WM exists yet, all return NULL / 0)
// ---------------------------------------------------------------------------
__declspec(dllexport) HWND GetDesktopWindow(void) { return (HWND)0; }
__declspec(dllexport) HWND GetActiveWindow(void) { return (HWND)0; }
__declspec(dllexport) HWND GetTopWindow(HWND hwnd){ (void)hwnd; return (HWND)0; }
__declspec(dllexport) HWND GetWindow(HWND hwnd, unsigned int cmd) {
(void)hwnd; (void)cmd; return (HWND)0;
}
__declspec(dllexport) long GetWindowLongA(HWND hwnd, int index) {
(void)hwnd; (void)index; return 0;
}
__declspec(dllexport) intptr_t GetWindowLongPtrA(HWND hwnd, int index) {
(void)hwnd; (void)index; return 0;
}
__declspec(dllexport) unsigned long GetWindowThreadProcessId(HWND hwnd, unsigned long* pid) {
(void)hwnd;
if (pid) *pid = 1;
return 1; // Thread ID
}
// ---------------------------------------------------------------------------
// Dialogs
// ---------------------------------------------------------------------------
__declspec(dllexport) int MessageBoxA(HWND hwnd, const char* text,
const char* caption, unsigned int type) {
(void)hwnd; (void)text; (void)caption; (void)type;
// No UI available, console
SysDebugPrint(text);
return IDOK;
}
+128 -2
View File
@@ -1,2 +1,128 @@
// winmm.c - stub; no multimedia at this stage.
static void stub(void) { }
// winmm.c - Win32 multimedia: waveform audio, timer
// Stubs only; no audio hardware access at this stage.
#include <stdint.h>
#include <stddef.h>
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
typedef unsigned int MMRESULT;
typedef void* HWAVEOUT;
#define MMSYSERR_NOERROR 0
#define MMSYSERR_NOTSUPPORTED 8
#define WAVERR_STILLPLAYING 33
// WAVEFORMATEX - standard PCM audio format descriptor.
typedef struct {
unsigned short wFormatTag;
unsigned short nChannels;
unsigned int nSamplesPerSec;
unsigned int nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short wBitsPerSample;
unsigned short cbSize;
} WAVEFORMATEX;
// WAVEHDR - buffer header submitted to waveOutWrite.
typedef struct _WAVEHDR {
char* lpData;
unsigned int dwBufferLength;
unsigned int dwBytesRecorded;
uintptr_t dwUser;
unsigned int dwFlags;
unsigned int dwLoops;
struct _WAVEHDR* lpNext;
uintptr_t reserved;
} WAVEHDR;
// MMTIME - used by waveOutGetPosition.
typedef struct {
unsigned int wType;
union {
unsigned int ms;
unsigned int sample;
unsigned int cb;
unsigned int ticks;
} u;
} MMTIME;
// ---------------------------------------------------------------------------
// Timer
// ---------------------------------------------------------------------------
// timeGetTime is the lightweight alternative to GetTickCount; both return
// milliseconds since system start. We forward to the kernel tick counter.
extern uint64_t SysGetTick(void);
__declspec(dllexport) unsigned long timeGetTime(void) {
return (unsigned long)SysGetTick();
}
// ---------------------------------------------------------------------------
// Waveform audio (stubs - no audio hardware at this stage)
// ---------------------------------------------------------------------------
__declspec(dllexport) MMRESULT waveOutOpen(HWAVEOUT* phwo, unsigned int deviceId,
const WAVEFORMATEX* fmt, uintptr_t callback,
uintptr_t callbackInstance, unsigned long flags) {
(void)deviceId; (void)fmt; (void)callback; (void)callbackInstance; (void)flags;
if (phwo) *phwo = (void*)0;
return MMSYSERR_NOTSUPPORTED;
}
__declspec(dllexport) MMRESULT waveOutClose(HWAVEOUT hwo) {
(void)hwo; return MMSYSERR_NOERROR;
}
__declspec(dllexport) MMRESULT waveOutPrepareHeader(HWAVEOUT hwo, WAVEHDR* hdr,
unsigned int size) {
(void)hwo; (void)hdr; (void)size; return MMSYSERR_NOERROR;
}
__declspec(dllexport) MMRESULT waveOutUnprepareHeader(HWAVEOUT hwo, WAVEHDR* hdr,
unsigned int size) {
(void)hwo; (void)hdr; (void)size; return MMSYSERR_NOERROR;
}
__declspec(dllexport) MMRESULT waveOutWrite(HWAVEOUT hwo, WAVEHDR* hdr, unsigned int size) {
(void)hwo; (void)hdr; (void)size; return MMSYSERR_NOTSUPPORTED;
}
__declspec(dllexport) MMRESULT waveOutPause(HWAVEOUT hwo) {
(void)hwo; return MMSYSERR_NOERROR;
}
__declspec(dllexport) MMRESULT waveOutRestart(HWAVEOUT hwo) {
(void)hwo; return MMSYSERR_NOERROR;
}
__declspec(dllexport) MMRESULT waveOutReset(HWAVEOUT hwo) {
(void)hwo; return MMSYSERR_NOERROR;
}
__declspec(dllexport) MMRESULT waveOutSetVolume(HWAVEOUT hwo, unsigned long volume) {
(void)hwo; (void)volume; return MMSYSERR_NOTSUPPORTED;
}
__declspec(dllexport) MMRESULT waveOutGetPosition(HWAVEOUT hwo, MMTIME* mmt,
unsigned int size) {
(void)hwo; (void)size;
if (mmt) { mmt->wType = 0; mmt->u.ms = 0; }
return MMSYSERR_NOERROR;
}
// ---------------------------------------------------------------------------
// Timer resolution control
// No hardware timer reprogramming at this stage; pretend success so callers
// that wrap their audio/game loop in timeBeginPeriod(1) don't bail out.
// ---------------------------------------------------------------------------
__declspec(dllexport) MMRESULT timeBeginPeriod(unsigned int uPeriod) {
(void)uPeriod;
return MMSYSERR_NOERROR;
}
__declspec(dllexport) MMRESULT timeEndPeriod(unsigned int uPeriod) {
(void)uPeriod;
return MMSYSERR_NOERROR;
}