174 lines
4.2 KiB
Plaintext
174 lines
4.2 KiB
Plaintext
#import "base.kl"
|
|
#import "os_windows.kl"
|
|
#import "kernel32.kl"
|
|
#import "gdi32.kl"
|
|
#import "user32.kl"
|
|
#import "winmm.kl"
|
|
|
|
Vec2I :: struct;; x: S64; y: S64
|
|
Vec2 :: struct;; x: F32; y: F32
|
|
|
|
Windows_Bitmap :: struct
|
|
size: Vec2I
|
|
data: *U32
|
|
hdc: HDC
|
|
dib: HBITMAP
|
|
|
|
Type_ID :: U64
|
|
Type_Info_Kind :: enum
|
|
TYPE_NONE
|
|
TYPE_S64 // FIRST_NUMERIC
|
|
TYPE_S32
|
|
TYPE_S16
|
|
TYPE_S8
|
|
TYPE_INT
|
|
TYPE_CHAR
|
|
TYPE_U64
|
|
TYPE_U32
|
|
TYPE_U16
|
|
TYPE_U8
|
|
TYPE_F32
|
|
TYPE_F64
|
|
TYPE_POINTER
|
|
TYPE_BOOL // LAST_NUMERIC
|
|
TYPE_STRING
|
|
TYPE_VOID
|
|
TYPE_ARRAY
|
|
TYPE_LAMBDA
|
|
TYPE_STRUCT
|
|
TYPE_UNION
|
|
TYPE_ENUM
|
|
TYPE_TYPE
|
|
TYPE_SLICE
|
|
TYPE_TUPLE
|
|
TYPE_ANY
|
|
|
|
Any :: struct
|
|
data: *void
|
|
type: Type_ID
|
|
|
|
Type_Info_Struct_Field :: struct
|
|
name: String
|
|
type: Type_ID
|
|
offset: S32
|
|
|
|
Type_Info :: struct
|
|
kind: Type_Info_Kind
|
|
size: S32
|
|
align: S32
|
|
is_unsigned: Bool
|
|
type_id: Type_ID
|
|
|
|
base_type: Type_ID
|
|
array_size: S32
|
|
struct_member_count: S32
|
|
fields: *Type_Info_Struct_Field
|
|
|
|
type_infos: []*Type_Info
|
|
|
|
|
|
Bitmap :: struct
|
|
size: Vec2I
|
|
data: *U32
|
|
|
|
create_bitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap
|
|
result: Windows_Bitmap = {size = size}
|
|
if bottom_up == false
|
|
result.size.y = -result.size.y
|
|
|
|
bminfo := BITMAPINFO{
|
|
BITMAPINFOHEADER{
|
|
biSize = 40, // @todo!!! size_of(BITMAPINFOHEADER),
|
|
biWidth = size.x->LONG,
|
|
biHeight = size.y->LONG,
|
|
biPlanes = 1,
|
|
biBitCount = 32,
|
|
biCompression = BI_RGB,
|
|
biXPelsPerMeter = 1,
|
|
biYPelsPerMeter = 1,
|
|
}
|
|
}
|
|
|
|
hdc := GetDC(0)
|
|
result.dib = CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, (&result.data)->**void, 0, 0)
|
|
result.hdc = CreateCompatibleDC(hdc)
|
|
return result
|
|
|
|
app_is_running := true
|
|
window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT
|
|
if msg == WM_DESTROY
|
|
PostQuitMessage(0)
|
|
app_is_running = false
|
|
return 0
|
|
else;; return DefWindowProcW(hwnd, msg, wparam, lparam)
|
|
|
|
_gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char
|
|
print_float :: (value: F64)
|
|
buff: [100]char
|
|
_gcvt(value, 10, &buff[0])
|
|
OutputDebugStringA("\n")
|
|
OutputDebugStringA(&buff[0])
|
|
|
|
WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int
|
|
if good_scheduling := false, timeBeginPeriod(1) == TIMERR_NOERROR
|
|
good_scheduling = true
|
|
|
|
arena: Arena
|
|
window_name := string_to_string16(&arena, "Have a wonderful day! 豈 更 車 賈 滑 串 句 龜 ")
|
|
w := WNDCLASSW{
|
|
lpfnWndProc = window_procedure,
|
|
hInstance = hInstance,
|
|
lpszClassName = window_name.str,
|
|
}
|
|
assert(RegisterClassW(&w) != 0)
|
|
|
|
screen_size: Vec2I = {1280, 720}
|
|
window := CreateWindowExW(
|
|
dwExStyle = 0, hWndParent = 0, hMenu = 0, lpParam = 0,
|
|
X = CW_USEDEFAULT, Y = CW_USEDEFAULT, nWidth = screen_size.x->int, nHeight = screen_size.y->int,
|
|
lpClassName = window_name.str,
|
|
lpWindowName = window_name.str,
|
|
dwStyle = WS_OVERLAPPEDWINDOW,
|
|
hInstance = hInstance
|
|
)
|
|
assert(window != 0)
|
|
ShowWindow(window, nShowCmd)
|
|
|
|
window_dc := GetDC(window)
|
|
bitmap := create_bitmap(screen_size)
|
|
|
|
requested_time_per_frame := 1.0 / 60.0
|
|
frame_start_time := time()
|
|
frame_number: S64
|
|
total_time: F64
|
|
for app_is_running
|
|
msg: MSG
|
|
for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0
|
|
TranslateMessage(&msg)
|
|
DispatchMessageW(&msg)
|
|
|
|
for y := 0, y < bitmap.size.y, y+=1
|
|
for x := 0, x < bitmap.size.x, x+=1
|
|
bitmap.data[x + y*bitmap.size.x] = 0xFFFF0000
|
|
|
|
SelectObject(bitmap.hdc, bitmap.dib)
|
|
BitBlt(window_dc, 0, 0, (bitmap.size.x)->int, (bitmap.size.y)->int, bitmap.hdc, 0, 0, SRCCOPY)
|
|
|
|
|
|
frame_time := time() - frame_start_time
|
|
print_float(frame_time)
|
|
if frame_time < requested_time_per_frame
|
|
if good_scheduling
|
|
time_to_sleep := (requested_time_per_frame - frame_time) * 1000
|
|
if time_to_sleep > 0
|
|
time_to_sleep_dword := time_to_sleep->DWORD
|
|
// @check if time_to_sleep_dword truncates down
|
|
Sleep(time_to_sleep_dword)
|
|
|
|
new_frame_time := time()
|
|
for new_frame_time < requested_time_per_frame
|
|
new_frame_time = time() - frame_start_time
|
|
|
|
frame_time = new_frame_time
|
|
frame_number += 1
|
|
total_time += frame_time |