Previously it wasnt working but now its working, TRUST ME

This commit is contained in:
Krzosa Karol
2023-04-02 11:23:36 +02:00
parent 9bb355ed93
commit ad5c692506
32 changed files with 4 additions and 3 deletions

42
build/modules/Arena.core Normal file
View File

@@ -0,0 +1,42 @@
OS :: #import "OS$OS.core"
Base :: #import "Base.core"
ArenaDI: U64
ADDITIONAL_COMMIT_SIZE :: 1024*1024
DEFAULT_RESERVE_SIZE :: 1024*1024*1024
DEFAULT_ALIGNMENT :: 8
Arena :: struct
di: U64 // @debug_id
memory: OS.Memory
alignment: U64
len: U64
Init :: (a: *Arena)
a.memory = OS.Reserve(DEFAULT_RESERVE_SIZE)
a.alignment = DEFAULT_ALIGNMENT
a.di = ArenaDI++
FromBuffer :: (buffer: []U8): Arena
a: Arena
a.memory.reserve = Len(buffer)->U64
a.memory.commit = Len(buffer)->U64
a.alignment = DEFAULT_ALIGNMENT
a.di = ArenaDI++
return a
PushSize :: (a: *Arena, size: Base.SizeU): *void
generous_size := size + a.alignment
if a.len + generous_size > a.memory.commit
if a.memory.reserve == 0
Init(a)
result := OS.Commit(&a.memory, generous_size + ADDITIONAL_COMMIT_SIZE)
Assert(result == true)
a.len = Base.AlignUp(a.len, a.alignment)
Assert(a.memory.reserve > a.len + a.memory.commit)
result: *void = a.memory.data + a.len
a.len += size
return result
Release :: (a: *Arena)
OS.Release(&a.memory)

124
build/modules/Base.core Normal file
View File

@@ -0,0 +1,124 @@
#import "Arena.core"
OS :: #import "OS$OS.core"
SizeU :: U64
ClampTopSizeU :: (val: SizeU, max: SizeU): SizeU
if val > max
return max
return val
GetAlignOffset :: (size: SizeU, align: SizeU): SizeU
mask := align - 1
val := size & mask
if val != 0
val = align - val
return val
AlignUp :: (size: SizeU, align: SizeU): SizeU
result := size + GetAlignOffset(size, align)
return result
ZeroMemory :: (p: *void, size: SizeU)
pcast := p->*U8
for i := 0->SizeU, i < size, i++
pcast[i] = 0
//
// Unicode
//
QuestionMark16 :: 0x003f
String32 :: struct;; str: *U32; len: S64
String16 :: struct;; str: *U16; len: S64
Utf8ToUtf32 :: (c: *U8, max_advance: S64): U32, S64
out_str: U32
advance: S64
if (c[0] & 0b10000000) == 0
if max_advance >= 1
c0 := c[0]->U32
out_str = c0
advance = 1
elif (c[0] & 0b11100000) == 0b11000000
if (c[1] & 0b11000000) == 0b10000000 // Continuation byte required
if max_advance >= 2
c0 := c[0]->U32; c1 := c[1]->U32
out_str = (c0 & 0b00011111) << 6 | (c1 & 0b00111111)
advance = 2
elif (c[0] & 0b11110000) == 0b11100000
if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 // Two continuation bytes required
if max_advance >= 3
c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32
out_str = (c0 & 0b00001111) << 12 | (c1 & 0b00111111) << 6 | (c2 & 0b00111111)
advance = 3
elif (c[0] & 0b11111000) == 0b11110000
if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 && (c[3] & 0b11000000) == 0b10000000 // Three continuation bytes required
if max_advance >= 4
c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32; c3 := c[3]->U32
out_str = (c0 & 0b00001111) << 18 | (c1 & 0b00111111) << 12 | (c2 & 0b00111111) << 6 | (c3 & 0b00111111)
advance = 4
return out_str, advance
Utf32ToUtf16 :: (codepoint: U32): [2]U16, S64
str: [2]U16
len := 0
if codepoint < 0x10000
str[0] = codepoint->U16
len = 1
elif codepoint <= 0x10FFFF
code: U32 = (codepoint - 0x10000)
str[0] = (0xD800 | (code >> 10))->U16
str[1] = (0xDC00 | (code & 0x3FF))->U16
len = 2
return str, len
StringToString16 :: (arena: *Arena, in: String): String16
in_str := &in[0]
// @Note(Krzosa): Should be more then enough space
alloc_size := (Len(in)*2)+1
result := String16{str = PushSize(arena, alloc_size->U64)}
for i := 0, i < Len(in)
s32, s32_len := Utf8ToUtf32(in_str + i, Len(in) - i)
if s32_len != 0
i += s32_len
s16, s16_len := Utf32ToUtf16(s32)
if s16_len != 0
for j := 0, j < s16_len, j++
result.str[result.len++] = s16[j]
else
result.str[result.len++] = QuestionMark16
break
else
result.str[result.len++] = QuestionMark16
break
result.str[result.len] = 0
return result
CStringCompare :: (a: *char, b: *char): Bool
i := 0
for , a[i] != 0, i+=1
if a[i] != b[i]
return false
if a[i] != b[i]
return false
return true
TestUnicode :: (arena: *Arena)
string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..."
string_result := StringToString16(arena, string)
print(string_result)
s32, s32_len := Utf8ToUtf32('A', 1)
assert(s32 == 'A', "Invalid decode")
s32_2, s32_len_2 := Utf8ToUtf32('ć', 2)
assert(s32_2 == 0x107, "Invalid decode")
s32_3, s32_len_3 := Utf8ToUtf32('ó', 2)
assert(s32_3 == 0xF3, "Invalid decode")

41
build/modules/GDI32.core Normal file
View File

@@ -0,0 +1,41 @@
#import "KERNEL32.core"
#link "gdi32"
RBGQUAD :: struct;; rgbBlue: BYTE; rgbGreen: BYTE; rgbRed: BYTE; rgbReserved: BYTE
BITMAPINFOHEADER :: struct;; biSize: DWORD; biWidth: LONG; biHeight: LONG; biPlanes: WORD; biBitCount: WORD; biCompression: DWORD; biSizeImage: DWORD; biXPelsPerMeter: LONG; biYPelsPerMeter: LONG; biClrUsed: DWORD; biClrImportant: DWORD
BITMAPINFO :: struct;; bmiHeader: BITMAPINFOHEADER; bmiColors: [1]RBGQUAD
HGDIOBJ :: HANDLE
BI_RGB :: 0x0000
BI_RLE8 :: 0x0001
BI_RLE4 :: 0x0002
BI_BITFIELDS :: 0x0003
BI_JPEG :: 0x0004
BI_PNG :: 0x0005
BI_CMYK :: 0x000B
BI_CMYKRLE8 :: 0x000C
BI_CMYKRLE4 :: 0x000
DIB_RGB_COLORS :: 0x00
SRCCOPY :: 0x00CC0020 /* dest = source */
SRCPAINT :: 0x00EE0086 /* dest = source OR dest */
SRCAND :: 0x008800C6 /* dest = source AND dest */
SRCINVERT :: 0x00660046 /* dest = source XOR dest */
SRCERASE :: 0x00440328 /* dest = source AND (NOT dest ) */
NOTSRCCOPY :: 0x00330008 /* dest = (NOT source) */
NOTSRCERASE :: 0x001100A6 /* dest = (NOT src) AND (NOT dest) */
MERGECOPY :: 0x00C000CA /* dest = (source AND pattern) */
MERGEPAINT :: 0x00BB0226 /* dest = (NOT source) OR dest */
PATCOPY :: 0x00F00021 /* dest = pattern */
PATPAINT :: 0x00FB0A09 /* dest = DPSnoo */
PATINVERT :: 0x005A0049 /* dest = pattern XOR dest */
DSTINVERT :: 0x00550009 /* dest = (NOT dest) */
BLACKNESS :: 0x00000042 /* dest = BLACK */
WHITENESS :: 0x00FF0062 /* dest = WHITE */
CreateDIBSection :: #foreign (hdc: HDC, pbmi: *BITMAPINFO, usage: UINT, ppvBits: **VOID, hSection: HANDLE, offset: DWORD): HBITMAP
CreateCompatibleDC :: #foreign (hdc: HDC): HDC
SelectObject :: #foreign (hdc: HDC, h: HGDIOBJ): HGDIOBJ
BitBlt :: #foreign (hdc: HDC, x: int, y: int, cx: int, cy: int, hdcSrc: HDC, x1: int, y1: int, ro: DWORD): BOOL
DeleteDC :: #foreign (hdc: HDC): BOOL
DeleteObject :: #foreign (ho : HGDIOBJ): BOOL

130
build/modules/KERNEL32.core Normal file
View File

@@ -0,0 +1,130 @@
#link "kernel32"
DWORD :: U32
LPCSTR :: *char
LPSTR :: *char
LPCWSTR :: *U16
HWND :: *void
HMENU :: *void
HINSTANCE :: *void
HBITMAP :: *void
HDC :: *void
LPVOID :: *void
SIZE_T :: U64
BOOL :: int
HMODULE :: HANDLE
HANDLE :: *void
VOID :: void
HICON :: HANDLE
HCURSOR :: HANDLE
HBRUSH :: HANDLE
LPDWORD :: *DWORD
LRESULT :: S64
WPARAM :: U64
LPARAM :: S64
BYTE :: U8 // @todo? unsigned char
WORD :: S16 // short
LONG :: S32 // @todo long
UINT :: U32 // @todo uint
ATOM :: WORD
LARGE_INTEGER :: S64
PLARGE_INTEGER :: *LARGE_INTEGER
LPOVERLAPPED :: *OVERLAPPED
LONG_PTR :: *S64
ULONG_PTR :: *U64
MEM_COMMIT :: 0x00001000
MEM_RESERVE :: 0x00002000
MEM_RESET :: 0x00080000
MEM_RESET_UNDO :: 0x1000000
MEM_DECOMMIT :: 0x00004000
MEM_RELEASE :: 0x00008000
PAGE_NOACCESS :: 1
PAGE_READONLY :: 2
PAGE_READWRITE :: 4
PAGE_WRITECOPY :: 8
PAGE_EXECUTE :: 0x10; PAGE_EXECUTE_READ :: 0x20; PAGE_EXECUTE_READWRITE :: 0x40; PAGE_EXECUTE_WRITECOPY :: 0x80
VirtualAlloc :: #foreign (lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD): LPVOID
VirtualFree :: #foreign (lpAddress: LPVOID, dwSize: SIZE_T, dwFreeType: DWORD): BOOL
HEAP_ZERO_MEMORY :: 0x8; HEAP_NO_SERIALIZE :: 0x1; HEAP_GENERATE_EXCEPTIONS :: 0x4
GetProcessHeap :: #foreign (): HANDLE
HeapAlloc :: #foreign (hHeap: HANDLE, dwFlags: DWORD, dwByte: SIZE_T): LPVOID
HeapFree :: #foreign (hHeap: HANDLE, dwFlags: DWORD, lpMe: LPVOID): BOOL
STD_INPUT_HANDLE :: 4294967286//(-10)->DWORD
STD_OUTPUT_HANDLE :: 4294967285//(-11)->DWORD
//STD_ERROR_HANDLE :: (-12)->DWORD
GetStdHandle :: #foreign (nStdHandle: DWORD): HANDLE
WriteConsoleA :: #foreign (hConsoleOutput: HANDLE,lpBuffer: *VOID,nNumberOfCharsToWrite: DWORD,lpNumberOfCharsWritten: LPDWORD,lpReserve: LPVOID): BOOL
WriteConsoleW :: #foreign (hConsoleOutput: HANDLE,lpBuffer: *VOID,nNumberOfCharsToWrite: DWORD,lpNumberOfCharsWritten: LPDWORD,lpReserve: LPVOID): BOOL
__debugbreak :: #foreign ()
GetModuleHandleA :: #foreign (lpModuleName: LPCSTR): HMODULE
ExitProcess :: #foreign (uExitCode: UINT)
GetLastError :: #foreign (): DWORD
QueryPerformanceFrequency :: #foreign (lpFrequency: *LARGE_INTEGER): BOOL
QueryPerformanceCounter :: #foreign (lpFrequency: *LARGE_INTEGER): BOOL
Sleep :: #foreign (dwMilliseconds: DWORD)
OutputDebugStringA :: #foreign (lpOutputString: LPCSTR)
CreateFileW :: #foreign (lpFileName: LPCWSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE): HANDLE
ReadFile :: #foreign (hFile: HANDLE, lpBuffer: LPVOID, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: LPDWORD, lpOverlapped: LPOVERLAPPED): BOOL
CloseHandle :: #foreign (hObject: HANDLE): BOOL
GetFileSizeEx :: #foreign (hFile: HANDLE, lpFileSize: PLARGE_INTEGER)
OVERLAPPED :: struct
Internal: ULONG_PTR
InternalHigh: ULONG_PTR
Pointer: PVOID
hEvent: HANDLE
LPSECURITY_ATTRIBUTES :: *SECURITY_ATTRIBUTES
SECURITY_ATTRIBUTES :: struct
nLength: DWORD
lpSecurityDescriptor: LPVOID
bInheritHandle: BOOL
GENERIC_READ :: 0x80000000
GENERIC_WRITE :: 0x40000000
GENERIC_EXECUTE :: 0x20000000
GENERIC_ALL :: 0x10000000
CREATE_NEW :: 1
CREATE_ALWAYS :: 2
OPEN_EXISTING :: 3
OPEN_ALWAYS :: 4
TRUNCATE_EXISTING :: 5
FILE_SHARE_READ :: 0x00000001
FILE_SHARE_WRITE :: 0x00000002
FILE_SHARE_DELETE :: 0x00000004
// INVALID_HANDLE_VALUE :: ((-1)->LONG_PTR)->HANDLE
INVALID_HANDLE_VALUE :: (~(0->U64))
FILE_ATTRIBUTE_READONLY :: 0x00000001
FILE_ATTRIBUTE_HIDDEN :: 0x00000002
FILE_ATTRIBUTE_SYSTEM :: 0x00000004
FILE_ATTRIBUTE_DIRECTORY :: 0x00000010
FILE_ATTRIBUTE_ARCHIVE :: 0x00000020
FILE_ATTRIBUTE_DEVICE :: 0x00000040
FILE_ATTRIBUTE_NORMAL :: 0x00000080
FILE_ATTRIBUTE_TEMPORARY :: 0x00000100
FILE_ATTRIBUTE_SPARSE_FILE :: 0x00000200
FILE_ATTRIBUTE_REPARSE_POINT :: 0x00000400
FILE_ATTRIBUTE_COMPRESSED :: 0x00000800
FILE_ATTRIBUTE_OFFLINE :: 0x00001000
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED :: 0x00002000
FILE_ATTRIBUTE_ENCRYPTED :: 0x00004000
FILE_ATTRIBUTE_INTEGRITY_STREAM :: 0x00008000
FILE_ATTRIBUTE_VIRTUAL :: 0x00010000
FILE_ATTRIBUTE_NO_SCRUB_DATA :: 0x00020000
FILE_ATTRIBUTE_EA :: 0x00040000
FILE_ATTRIBUTE_PINNED :: 0x00080000
FILE_ATTRIBUTE_UNPINNED :: 0x00100000
FILE_ATTRIBUTE_RECALL_ON_OPEN :: 0x00040000
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS :: 0x00400000

View File

@@ -0,0 +1,60 @@
/*
Any :: struct
data: *void
type: Type
Type_Info_Kind :: enum
S64 // FIRST_NUMERIC
S32
S16
S8
INT
CHAR
U64
U32
U16
U8
F32
F64
POINTER
BOOL // LAST_NUMERIC
STRING
VOID
ARRAY
LAMBDA
STRUCT
UNION
ENUM
TYPE
SLICE
TUPLE
Type_Info_Struct_Member :: struct
name: String
type: Type
offset: S64
Type_Info :: struct
kind: Type_Info_Kind
size: S64
align: S64
is_unsigned: Bool
type: Type
base_type: Type
array_size: S64
struct_members: *Type_Info_Struct_Member
struct_member_count: S64
lambda_arguments: *Type_Info
lambda_argument_count: S64
lambda_return: Type
type_infos_len: S64 #foreign
type_infos : *Type_Info #foreign
GetTypeInfo :: (type: Type): *Type_Info
id := type->S64
if id >= type_infos_len
return 0
return type_infos + id
*/

17
build/modules/LibC.core Normal file
View File

@@ -0,0 +1,17 @@
size_t :: U64 // @todo(Krzosa): Need this type
long :: #strict int // @todo(Krzosa): Need this type
malloc :: #foreign (size: size_t): *void
realloc :: #foreign (ptr: *void, size: size_t): *void
free :: #foreign (ptr: *void)
FILE :: #strict U64 // Doesnt matter the type just handle
fopen :: #foreign (file: *char, mode: *char): *FILE
fclose :: #foreign (file: *FILE): int
fseek :: #foreign (public_stream: *FILE, offset: long, whence: int): int
ftell :: #foreign (public_stream: *FILE): long
fread :: #foreign (buffer: *void, element_size: size_t, element_count: size_t, stream: *FILE): size_t
SEEK_CUR :: 1
SEEK_END :: 2
SEEK_SET :: 0

View File

@@ -0,0 +1,34 @@
sqrtf :: #foreign (value: F32): F32
cosf :: #foreign (value: F32): F32
sinf :: #foreign (value: F32): F32
floorf :: #foreign (value: F32): F32
roundf :: #foreign (value: F32): F32
ceilf :: #foreign (value: F32): F32
Floor :: floorf
Round :: roundf
Ceil :: ceilf
SquareRoot :: sqrtf
Cos :: cosf
Sin :: sinf
Clamp :: (min: F32, value: F32, max: F32): F32
if value > max;; return max
if value < min;; return min
return value
ClampBottom :: (min: F32, value: F32): F32
if value < min;; return min
return value
Absolute :: (val: F32): F32
if val < 0;; return -val
return val
Min :: (a: F32, b: F32): F32
if a > b ;; return b
return a
Max :: (a: F32, b: F32): F32
if a > b ;; return a
return b

View File

@@ -0,0 +1,32 @@
Vec2I :: struct;; x: S64; y: S64
Vec2 :: struct;; x: F32; y: F32
"*" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x*b.x, a.y*b.y}
"*" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x*b, a.y*b}
"*" :: (a: F32, b: Vec2) : Vec2 ;; return {a*b.x, a*b.y}
"-" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x-b.x, a.y-b.y}
"-" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x-b, a.y-b}
"-" :: (a: F32, b: Vec2) : Vec2 ;; return {a-b.x, a-b.y}
"+" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x+b.x, a.y+b.y}
"+" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x+b, a.y+b}
"+" :: (a: F32, b: Vec2) : Vec2 ;; return {a+b.x, a+b.y}
"/" :: (a: Vec2, b: Vec2): Vec2 ;; return {a.x/b.x, a.y/b.y}
"/" :: (a: Vec2, b: F32) : Vec2 ;; return {a.x/b, a.y/b}
"/" :: (a: F32, b: Vec2) : Vec2 ;; return {a/b.x, a/b.y}
"*" :: (a: Vec2I, b: Vec2I): Vec2I ;; return {a.x*b.x, a.y*b.y}
"*" :: (a: Vec2I, b: S64) : Vec2I ;; return {a.x*b, a.y*b}
"*" :: (a: S64, b: Vec2I) : Vec2I ;; return {a*b.x, a*b.y}
"-" :: (a: Vec2I, b: Vec2I): Vec2I ;; return {a.x-b.x, a.y-b.y}
"-" :: (a: Vec2I, b: S64) : Vec2I ;; return {a.x-b, a.y-b}
"-" :: (a: S64, b: Vec2I) : Vec2I ;; return {a-b.x, a-b.y}
"+" :: (a: Vec2I, b: Vec2I): Vec2I ;; return {a.x+b.x, a.y+b.y}
"+" :: (a: Vec2I, b: S64) : Vec2I ;; return {a.x+b, a.y+b}
"+" :: (a: S64, b: Vec2I) : Vec2I ;; return {a+b.x, a+b.y}
"/" :: (a: Vec2I, b: Vec2I): Vec2I ;; return {a.x/b.x, a.y/b.y}
"/" :: (a: Vec2I, b: S64) : Vec2I ;; return {a.x/b, a.y/b}
"/" :: (a: S64, b: Vec2I) : Vec2I ;; return {a/b.x, a/b.y}
FloorVec2ToVec2I :: (a: Vec2): Vec2I ;; return {floorf(a.x)->S64, floorf(a.y)->S64}
CastVec2ToVec2I :: (a: Vec2): Vec2I ;; return {a.x->S64, a.y->S64}

View File

@@ -0,0 +1,46 @@
#import "MathF32.core"
Vec3 :: struct ;; x: F32; y: F32; z: F32
Length :: (a: Vec3): F32 ;; return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z)
Negate :: (a: Vec3): Vec3 ;; return {-a.x, -a.y, -a.z}
Dot :: (a: Vec3, b: Vec3): F32 ;; return a.x*b.x + a.y*b.y + a.z*b.z
"*" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x*b.x, a.y*b.y, a.z*b.z}
"*" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x*b, a.y*b, a.z*b}
"*" :: (a: F32, b: Vec3) : Vec3 ;; return {a*b.x, a*b.y, a*b.z}
"-" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x-b.x, a.y-b.y, a.z-b.z}
"-" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x-b, a.y-b, a.z-b}
"-" :: (a: F32, b: Vec3) : Vec3 ;; return {a-b.x, a-b.y, a-b.z}
"+" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x+b.x, a.y+b.y, a.z+b.z}
"+" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x+b, a.y+b, a.z+b}
"+" :: (a: F32, b: Vec3) : Vec3 ;; return {a+b.x, a+b.y, a+b.z}
"/" :: (a: Vec3, b: Vec3): Vec3 ;; return {a.x/b.x, a.y/b.y, a.z/b.z}
"/" :: (a: Vec3, b: F32) : Vec3 ;; return {a.x/b, a.y/b, a.z/b}
"/" :: (a: F32, b: Vec3) : Vec3 ;; return {a/b.x, a/b.y, a/b.z}
Cross :: (a: Vec3, b: Vec3): Vec3
result := Vec3{
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x,
}
return result
Normalize :: (a: Vec3): Vec3
length := Length(a)
result := a / length
return result
Reflect :: (a: Vec3, normal: Vec3): Vec3
an := Dot(a, normal)*2
result := a - a * an
return result
ConvertToARGB :: (a: Vec3): U32
a.x = Clamp(0, a.x, 1)
a.y = Clamp(0, a.y, 1)
a.z = Clamp(0, a.z, 1)
r := (a.x * 255)->U32 << 16
g := (a.y * 255)->U32 << 8
b := (a.z * 255)->U32 << 0
result := r | g | b
return result

View File

@@ -0,0 +1,64 @@
/*
Library for making games/graphical applications
* The api is very simple, very few function calls
* You retrieve information about the state of application from "Mu" struct
* Data is available in many different formats to avoid format conversions in user code
API and name inspired by one of Per Vognsen streams
https://www.youtube.com/watch?v=NG_mUhc8LRw&list=PLU94OURih-CjrtFuazwZ5GYzTrupOMDL7&index=19
All of his channel is recommended watch for programmers.
*/
Mu: MU
MU :: struct
screen: *U32
window: MUWindow
key: [Key.Count]KeyState
mouse: Mouse
frame_count: U64
time: MUTime
quit: Bool
frame_arena: Arena
os: Platform
MUWindow :: struct
x: S64
y: S64
sizef: Vec2
size: Vec2I
resizable: Bool
MUTime :: struct
total : F64
delta : F64 // @modifiable
start : F64
frame_start: F64
KeyState :: struct
down: Bool
Key :: enum
None
Up;Down;Left;Right;Escape;Control;Backspace;Alt;Shift;Tab
F1;F2;F3;F4;F5;F6;F7;F8;F9;F10
F11;F12;A;B;C;D;E;F;G;H
I;J;K;L;M;N;O;P;Q;R
S;T;U;V;W;X;Y;Z;K0;K1
K2;K3;K4;K5;K6;K7;K8;K9
Count
Mouse :: struct
left: KeyState
right: KeyState
middle: KeyState
wheel: S64
#import "Base.core"
#import "MathF32.core"
#import "MathVec2.core"
#import "Arena.core"
#load "$os_multimedia.core"

View File

@@ -0,0 +1,65 @@
#import "KERNEL32.core"
#import "Base.core"
PAGE_SIZE :: 4096
Memory :: struct
commit : SizeU
reserve: SizeU
data : *U8
ProcessHeap: HANDLE
Allocate :: (size: U64): *void
if ProcessHeap == 0
ProcessHeap = GetProcessHeap()
return HeapAlloc(ProcessHeap, 0, size)
Reserve :: (size: SizeU): Memory
result := Memory{reserve=AlignUp(size, PAGE_SIZE)}
result.data = VirtualAlloc(
flProtect = PAGE_READWRITE,
dwSize = result.reserve,
flAllocationType = MEM_RESERVE,
lpAddress = 0)->*U8
return result
Commit :: (m: *Memory, size: SizeU): Bool
commit_size := AlignUp(size, PAGE_SIZE)
total_commit := m.commit + commit_size
clamped_commit := ClampTopSizeU(total_commit, m.reserve)
adjusted_commit := clamped_commit - m.commit
if adjusted_commit != 0
result := VirtualAlloc(
lpAddress = (m.data + m.commit)->*void,
dwSize = adjusted_commit,
flAllocationType = MEM_COMMIT,
flProtect = PAGE_READWRITE,
)
Assert(result != 0)
m.commit += adjusted_commit
return true
return false
Release :: (m: *Memory)
result := VirtualFree(m.data->*void, 0, MEM_RELEASE)
if result != 0
m.data = 0
m.commit = 0
m.reserve = 0
WriteConsole :: (string: String16)
handle := GetStdHandle(STD_OUTPUT_HANDLE)
WriteConsoleW(handle, string.str->*void, string.len->DWORD, 0, 0)
PerformanceFrequency: F64
PerformanceFrequency_S64: S64
Time :: (): F64
query: LARGE_INTEGER
if PerformanceFrequency_S64 == 0
err := QueryPerformanceFrequency(&PerformanceFrequency_S64)
Assert(err != 0)
PerformanceFrequency = PerformanceFrequency_S64->F64
err := QueryPerformanceCounter(&query)
Assert(err != 0)
result := query->F64 / PerformanceFrequency
return result

200
build/modules/USER32.core Normal file
View File

@@ -0,0 +1,200 @@
#import "KERNEL32.core"
#link "user32"
WNDPROC :: (hwnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM): LRESULT
WNDCLASSW :: struct;; style: UINT; lpfnWndProc: WNDPROC; cbClsExtra: int; cbWndExtra: int; hInstance: HINSTANCE; hIcon: HICON; hCursor: HCURSOR; hbrBackground: HBRUSH; lpszMenuName: LPCWSTR; lpszClassName: LPCWSTR
MSG :: struct;; hwnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM; time: DWORD; pt: POINT; lPrivate: DWORD
POINT :: struct;; x: LONG; y: LONG
LPMSG :: *MSG
RECT :: struct;; left: LONG; top: LONG; right: LONG; bottom: LONG
LPRECT :: *RECT
PostQuitMessage :: #foreign (nExitCode: int)
DefWindowProcW :: #foreign (hwnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM): LRESULT
GetDC :: #foreign (hWnd: HWND): HDC
CreateWindowA :: #foreign (dwExStyle: DWORD, lpClassName: *char, lpWindowName: *char, dwStyle: DWORD, X: int, Y: int, nWidth: int, nHeight: int, hWndParent: HWND, hMenu: HMENU, hInstance: HINSTANCE, lpParam: *void): HWND
CreateWindowExW :: #foreign (dwExStyle: DWORD, lpClassName: LPCWSTR, lpWindowName: LPCWSTR, dwStyle: DWORD, X: int, Y: int, nWidth: int, nHeight: int, hWndParent: HWND, hMenu: HMENU, hInstance: HINSTANCE, lpParam: LPVOID): HWND
RegisterClassW :: #foreign (lpWndClass: *WNDCLASSW): ATOM
ShowWindow :: #foreign (hWnd: HWND, nCmdShow: int): BOOL
PeekMessageW :: #foreign (lpMsg: LPMSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMs: UINT):BOOL
TranslateMessage :: #foreign (lpMsg: *MSG): BOOL
DispatchMessageW :: #foreign (lpMsg: *MSG): LRESULT
SetProcessDPIAware:: #foreign (): BOOL
GetDpiForWindow :: #foreign (hwnd: HWND): UINT
AdjustWindowRectExForDpi :: #foreign (lpRect: *RECT, dwStyle: DWORD, bMenu: BOOL, dwExStyle: DWORD, dpi: UINT): BOOL
AdjustWindowRectEx :: #foreign (lpRect: *RECT, dwStyle: DWORD, bMenu: BOOL, dwExStyle: DWORD): BOOL
SetWindowPos :: #foreign (hWnd: HWND, hWndInsertAfter: HWND, X: int, Y: int, cx: int, cy: int, uFlags: UINT): BOOL
GetClientRect :: #foreign (hWnd: HWND, lpRect: LPRECT): BOOL
CW_USEDEFAULT :: -2147483648//0x80000000
WS_CAPTION :: 0x00C00000
WS_CHILD :: 0x40000000
WS_CHILDWINDOW :: 0x40000000
WS_CLIPCHILDREN :: 0x02000000
WS_CLIPSIBLINGS :: 0x04000000
WS_DISABLED :: 0x08000000
WS_DLGFRAME :: 0x00400000
WS_GROUP :: 0x00020000
WS_HSCROLL :: 0x00100000
WS_ICONIC :: 0x20000000
WS_MAXIMIZE :: 0x01000000
WS_MAXIMIZEBOX :: 0x00010000
WS_MINIMIZE :: 0x20000000
WS_MINIMIZEBOX :: 0x00020000
WS_OVERLAPPED :: 0x00000000
WS_POPUP :: 0x80000000
WS_SIZEBOX :: 0x00040000
WS_SYSMENU :: 0x00080000
WS_TABSTOP :: 0x00010000
WS_THICKFRAME :: 0x00040000
WS_TILED :: 0x00000000
WS_VISIBLE :: 0x10000000
WS_VSCROLL :: 0x00200000
WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
PM_NOREMOVE :: 0
PM_REMOVE :: 0x0001
PM_NOYIELD :: 0x0002
SW_HIDE :: 0
SW_NORMAL :: 1
SW_SHOWMINIMIZED :: 2
SW_SHOWMAXIMIZED :: 3
SW_SHOWNOACTIVATE :: 4
SW_SHOW :: 5
SW_MINIMIZE :: 6
SW_SHOWMINNOACTIVE :: 7
SW_SHOWNA :: 8
SW_RESTORE :: 9
SW_SHOWDEFAULT :: 10
SW_FORCEMINIMIZE :: 11
HWND_TOP :: 0
HWND_BOTTOM :: 1
// HWND_NOTOPMOST :: -2 // Probably relies on overflow ?
// HWND_TOPMOST :: -1 // Probably relies on overflow ?
SWP_ASYNCWINDOWPOS :: 0x4000
SWP_DEFERERASE :: 0x2000
SWP_DRAWFRAME :: 0x0020
SWP_FRAMECHANGED :: 0x0020
SWP_HIDEWINDOW :: 0x0080
SWP_NOACTIVATE :: 0x0010
SWP_NOCOPYBITS :: 0x0100
SWP_NOMOVE :: 0x0002
SWP_NOOWNERZORDER :: 0x0200
SWP_NOREDRAW :: 0x0008
SWP_NOREPOSITION :: 0x0200
SWP_NOSENDCHANGING :: 0x0400
SWP_NOSIZE :: 0x0001
SWP_NOZORDER :: 0x0004
SWP_SHOWWINDOW :: 0x0040
WM_NULL :: 0x0000; WM_CREATE :: 0x0001; WM_DESTROY :: 0x0002; WM_MOVE :: 0x0003; WM_SIZE :: 0x0005
WM_ACTIVATE :: 0x0006; WA_INACTIVE :: 0; WA_ACTIVE :: 1; WA_CLICKACTIVE :: 2
WM_SETFOCUS :: 0x0007; WM_KILLFOCUS :: 0x0008; WM_ENABLE :: 0x000A; WM_SETREDRAW :: 0x000B; WM_SETTEXT :: 0x000C; WM_GETTEXT :: 0x000D; WM_GETTEXTLENGTH :: 0x000E; WM_PAINT :: 0x000F; WM_CLOSE :: 0x0010
WM_KEYFIRST :: 0x0100
WM_KEYDOWN :: 0x0100
WM_KEYUP :: 0x0101
WM_CHAR :: 0x0102
WM_DEADCHAR :: 0x0103
WM_SYSKEYDOWN :: 0x0104
WM_SYSKEYUP :: 0x0105
WM_SYSCHAR :: 0x0106
WM_SYSDEADCHAR :: 0x0107
WM_MOUSEFIRST :: 0x0200
WM_MOUSEMOVE :: 0x0200
WM_LBUTTONDOWN :: 0x0201
WM_LBUTTONUP :: 0x0202
WM_LBUTTONDBLCLK :: 0x0203
WM_RBUTTONDOWN :: 0x0204
WM_RBUTTONUP :: 0x0205
WM_RBUTTONDBLCLK :: 0x0206
WM_MBUTTONDOWN :: 0x0207
WM_MBUTTONUP :: 0x0208
WM_MBUTTONDBLCLK :: 0x0209
WM_MOUSEWHEEL :: 0x020A
VK_BACK :: 0x08
VK_TAB :: 0x09
VK_CLEAR :: 0x0C
VK_RETURN :: 0x0D
VK_SHIFT :: 0x10
VK_CONTROL :: 0x11
VK_MENU :: 0x12
VK_PAUSE :: 0x13
VK_CAPITAL :: 0x14
VK_KANA :: 0x15
VK_HANGEUL :: 0x15 /* old name - should be here for compatibility */
VK_HANGUL :: 0x15
VK_IME_ON :: 0x16
VK_JUNJA :: 0x17
VK_FINAL :: 0x18
VK_HANJA :: 0x19
VK_KANJI :: 0x19
VK_IME_OFF :: 0x1A
VK_ESCAPE :: 0x1B
VK_CONVERT :: 0x1C
VK_NONCONVERT :: 0x1D
VK_ACCEPT :: 0x1E
VK_MODECHANGE :: 0x1F
VK_SPACE :: 0x20
VK_PRIOR :: 0x21
VK_NEXT :: 0x22
VK_END :: 0x23
VK_HOME :: 0x24
VK_LEFT :: 0x25
VK_UP :: 0x26
VK_RIGHT :: 0x27
VK_DOWN :: 0x28
VK_SELECT :: 0x29
VK_PRINT :: 0x2A
VK_EXECUTE :: 0x2B
VK_SNAPSHOT :: 0x2C
VK_INSERT :: 0x2D
VK_DELETE :: 0x2E
VK_HELP :: 0x2F
/*
* VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
* 0x3A - 0x40 : unassigned
* VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
*/
VK_LWIN :: 0x5B
VK_RWIN :: 0x5C
VK_APPS :: 0x5D
VK_SLEEP :: 0x5F
VK_NUMPAD0 :: 0x60
VK_NUMPAD1 :: 0x61
VK_NUMPAD2 :: 0x62
VK_NUMPAD3 :: 0x63
VK_NUMPAD4 :: 0x64
VK_NUMPAD5 :: 0x65
VK_NUMPAD6 :: 0x66
VK_NUMPAD7 :: 0x67
VK_NUMPAD8 :: 0x68
VK_NUMPAD9 :: 0x69
VK_MULTIPLY :: 0x6A
VK_ADD :: 0x6B
VK_SEPARATOR :: 0x6C
VK_SUBTRACT :: 0x6D
VK_DECIMAL :: 0x6E
VK_DIVIDE :: 0x6F
VK_F1 :: 0x70
VK_F2 :: 0x71
VK_F3 :: 0x72
VK_F4 :: 0x73
VK_F5 :: 0x74
VK_F6 :: 0x75
VK_F7 :: 0x76
VK_F8 :: 0x77
VK_F9 :: 0x78
VK_F10 :: 0x79
VK_F11 :: 0x7A
VK_F12 :: 0x7B

6
build/modules/WINMM.core Normal file
View File

@@ -0,0 +1,6 @@
#import "KERNEL32.core"
#link "winmm"
MMRESULT :: UINT
TIMERR_NOERROR :: 0
timeBeginPeriod :: #foreign (uPeriod: UINT): MMRESULT

View File

@@ -0,0 +1,355 @@
#import "KERNEL32.core"
#import "GDI32.core"
#import "USER32.core"
#import "WINMM.core"
#import "OS$OS.core"
Platform :: struct
bitmap: WIN32_Bitmap
window_dc: HDC
window: HWND
good_scheduling: Bool
WIN32_Bitmap :: struct
size: Vec2I
data: *U32
hdc: HDC
dib: HBITMAP
compatible_dc: HDC
IsValidBitmap :: (b: *WIN32_Bitmap): Bool
result := b.data != 0
return result
CreateBitmap :: (for_dc: HDC, size: Vec2I, bottom_up: Bool = true): WIN32_Bitmap
result: WIN32_Bitmap = {size = size}
if bottom_up == false
result.size.y = -result.size.y
header_size: U32 = SizeOf(BITMAPINFOHEADER)
Assert(header_size == 40)
bminfo := BITMAPINFO{
BITMAPINFOHEADER{
biSize = header_size,
biWidth = size.x->LONG,
biHeight = size.y->LONG,
biPlanes = 1,
biBitCount = 32,
biCompression = BI_RGB,
biXPelsPerMeter = 1,
biYPelsPerMeter = 1,
}
}
result.dib = CreateDIBSection(for_dc, &bminfo, DIB_RGB_COLORS, (&result.data)->**void, 0, 0)
result.hdc = CreateCompatibleDC(for_dc)
result.compatible_dc = for_dc
return result
DestroyBitmap :: (b: *WIN32_Bitmap)
if IsValidBitmap(b)
DeleteDC(b.hdc)
DeleteObject(b.dib)
ZeroMemory(b, SizeOf(WIN32_Bitmap))
DrawBitmapInCompatibleDC :: (b: *WIN32_Bitmap)
if IsValidBitmap(b)
SelectObject(b.hdc, b.dib)
BitBlt(b.compatible_dc, 0, 0, b.size.x->int, b.size.y->int, b.hdc, 0, 0, SRCCOPY)
GetWindowStyle :: (resizable: Bool): DWORD
style: DWORD = WS_SYSMENU | WS_OVERLAPPED | WS_CAPTION
if resizable ;; style |= WS_MAXIMIZEBOX | WS_THICKFRAME | WS_MINIMIZEBOX
return style
GetWindowSize :: (window: HWND): Vec2I
result: Vec2I
window_rect: RECT
GetClientRect(window, &window_rect)
result.x = (window_rect.right - window_rect.left)->S64
result.y = (window_rect.bottom - window_rect.top)->S64
return result
GetWindowPos :: (window: HWND): Vec2I
pos: Point
ClientToScreen(window, &pos)
return {pos.x, pos.y}
AdjustWindowRect :: (window: HWND, style: DWORD, rect: *RECT): void
FALSE :: 0
// if window == 0
// dpi := GetDpiForWindow(window)
// AdjustWindowRectExForDpi(rect, style, FALSE, 0, dpi)
// else
AdjustWindowRectEx(rect, style, FALSE, 0)
SetWindowSize :: (window: HWND, style: DWORD, size: Vec2I): void
rect := RECT{ 0, 0, size.x->LONG, size.y->LONG }
AdjustWindowRect(window, style, &rect)
SetWindowPos(window, HWND_TOP, 0, 0, (rect.right - rect.left)->int, (rect.bottom - rect.top)->int, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER)
SetWindowPosition :: (window: HWND, style: DWORD, pos: Vec2I): void
rect := RECT{ pos.x->LONG, pos.y->LONG, pos.x->LONG, pos.y->LONG }
AdjustWindowRect(window, style, &rect)
SetWindowPos(window, 0, rect.left, rect.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE)
StartMultimedia :: (
x: S64 = 1280, y: S64 = 720,
title: String = "Hello people!",
window_resizable: Bool = false,
target_ms: F64 = 0.0166666
)
Mu.time.delta = target_ms
if timeBeginPeriod(1) == TIMERR_NOERROR
Mu.os.good_scheduling = true
dpi_aware := SetProcessDPIAware()
Assert(dpi_aware != 0)
Mu.time.start = Time()
hInstance := GetModuleHandleA(0)
window_name := StringToString16(&Mu.frame_arena, title)
w := WNDCLASSW{
lpfnWndProc = WindowProc,
hInstance = hInstance,
lpszClassName = window_name.str,
// style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW,
}
Assert(RegisterClassW(&w) != 0)
style: DWORD = GetWindowStyle(window_resizable)
Mu.os.window = CreateWindowExW(
dwExStyle = 0, hWndParent = 0, hMenu = 0, lpParam = 0,
X = CW_USEDEFAULT, Y = CW_USEDEFAULT, nWidth = x->int, nHeight = y->int,
lpClassName = window_name.str,
lpWindowName = window_name.str,
dwStyle = style,
hInstance = hInstance
)
Assert(Mu.os.window != 0)
SetWindowSize(Mu.os.window, style, {x,y})
ShowWindow(Mu.os.window, SW_SHOW)
size := GetWindowSize(Mu.os.window)
Assert(size.x == x && size.y == y)
Mu.os.window_dc = GetDC(Mu.os.window)
Mu.os.bitmap = CreateBitmap(Mu.os.window_dc, size)
Mu.window.resizable = window_resizable
Mu.screen = Mu.os.bitmap.data
Mu.window.x = size.x
Mu.window.y = size.y
Mu.window.size = size
Mu.window.sizef.x = Mu.window.x->F32
Mu.window.sizef.y = Mu.window.y->F32
UpdateMultimedia :: (): Bool
DrawBitmapInCompatibleDC(&Mu.os.bitmap)
msg: MSG
for PeekMessageW(&msg, Mu.os.window, 0, 0, PM_REMOVE) == 1
TranslateMessage(&msg)
DispatchMessageW(&msg)
size := GetWindowSize(Mu.os.window)
if size.x != Mu.window.x || size.y != Mu.window.y
DestroyBitmap(&Mu.os.bitmap)
Mu.os.bitmap = CreateBitmap(Mu.os.window_dc, size)
Mu.screen = Mu.os.bitmap.data
Mu.window.x = size.x
Mu.window.y = size.y
Mu.window.sizef.x = Mu.window.x->F32
Mu.window.sizef.y = Mu.window.y->F32
Mu.window.size = size
Mu.frame_count += 1
frame_time := Time() - Mu.time.frame_start
Mu.time.total += frame_time
if frame_time < Mu.time.delta
if Mu.os.good_scheduling
time_to_sleep := (Mu.time.delta - 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 < Mu.time.delta
new_frame_time = Time() - Mu.time.frame_start
Mu.time.frame_start = Time()
return !Mu.quit
WindowProc :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT
result: LRESULT
if msg == WM_DESTROY
// @todo: Add destroy window
PostQuitMessage(0)
return 0
elif msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN
key := MapVKToKey(wparam)
Mu.key[key].down = true
elif msg == WM_KEYUP || msg == WM_SYSKEYUP
key := MapVKToKey(wparam)
Mu.key[key].down = false
elif msg == WM_LBUTTONDOWN ;; Mu.mouse.left.down = true
elif msg == WM_LBUTTONUP ;; Mu.mouse.left.down = false
elif msg == WM_RBUTTONDOWN ;; Mu.mouse.right.down = true
elif msg == WM_RBUTTONUP ;; Mu.mouse.right.down = false
elif msg == WM_MBUTTONDOWN ;; Mu.mouse.middle.down = true
elif msg == WM_MBUTTONUP ;; Mu.mouse.middle.down = false
elif msg == WM_MOUSEWHEEL
if wparam->int > 0
Mu.mouse.wheel = 1
else
Mu.mouse.wheel = -1
// Case(WM_CHAR){
// Utf32Result utf32 = Utf16ToUtf32((u16 *)&wparam, 1);
// if(!utf32.error){
// int index = OS->input_count;
// OS->input_count = ClampTop(OS->input_count + 1, (int)(ArrayCount(OS->input) - 1));
// OS->input[index] = utf32.out_str;
// }
// }Break;
else;; result = DefWindowProcW(hwnd, msg, wparam, lparam)
return result
/*#
mapping = [
["Up", "VK_UP"],
["Down", "VK_DOWN"],
["Left", "VK_LEFT"],
["Right", "VK_RIGHT"],
["Escape", "VK_ESCAPE"],
["Control", "VK_CONTROL"],
["Backspace", "VK_BACK"],
["Alt", "VK_MENU"],
["Shift", "VK_SHIFT"],
["Tab", "VK_TAB"],
["F1", "VK_F1"],
["F2", "VK_F2"],
["F3", "VK_F3"],
["F4", "VK_F4"],
["F5", "VK_F5"],
["F6", "VK_F6"],
["F7", "VK_F7"],
["F8", "VK_F8"],
["F9", "VK_F9"],
["F10", "VK_F10"],
["F11", "VK_F11"],
["F12", "VK_F12"],
["A", "'A'"],
["B", "'B'"],
["C", "'C'"],
["D", "'D'"],
["E", "'E'"],
["F", "'F'"],
["G", "'G'"],
["H", "'H'"],
["I", "'I'"],
["J", "'J'"],
["K", "'K'"],
["L", "'L'"],
["M", "'M'"],
["N", "'N'"],
["O", "'O'"],
["P", "'P'"],
["Q", "'Q'"],
["R", "'R'"],
["S", "'S'"],
["T", "'T'"],
["U", "'U'"],
["V", "'V'"],
["W", "'W'"],
["X", "'X'"],
["Y", "'Y'"],
["Z", "'Z'"],
["K0", "'0'"],
["K1", "'1'"],
["K2", "'2'"],
["K3", "'3'"],
["K4", "'4'"],
["K5", "'5'"],
["K6", "'6'"],
["K7", "'7'"],
["K8", "'8'"],
["K9", "'9'"],
]
print("MapVKToKey :: (vk: WPARAM): Key")
el = ""
for val,map in mapping:
print(f" {el}if vk == {map} ;; return Key.{val}")
el = "el"
print(" return Key.None")
*/
MapVKToKey :: (vk: WPARAM): Key
if vk == VK_UP ;; return Key.Up
elif vk == VK_DOWN ;; return Key.Down
elif vk == VK_LEFT ;; return Key.Left
elif vk == VK_RIGHT ;; return Key.Right
elif vk == VK_ESCAPE ;; return Key.Escape
elif vk == VK_CONTROL ;; return Key.Control
elif vk == VK_BACK ;; return Key.Backspace
elif vk == VK_MENU ;; return Key.Alt
elif vk == VK_SHIFT ;; return Key.Shift
elif vk == VK_TAB ;; return Key.Tab
elif vk == VK_F1 ;; return Key.F1
elif vk == VK_F2 ;; return Key.F2
elif vk == VK_F3 ;; return Key.F3
elif vk == VK_F4 ;; return Key.F4
elif vk == VK_F5 ;; return Key.F5
elif vk == VK_F6 ;; return Key.F6
elif vk == VK_F7 ;; return Key.F7
elif vk == VK_F8 ;; return Key.F8
elif vk == VK_F9 ;; return Key.F9
elif vk == VK_F10 ;; return Key.F10
elif vk == VK_F11 ;; return Key.F11
elif vk == VK_F12 ;; return Key.F12
elif vk == 'A' ;; return Key.A
elif vk == 'B' ;; return Key.B
elif vk == 'C' ;; return Key.C
elif vk == 'D' ;; return Key.D
elif vk == 'E' ;; return Key.E
elif vk == 'F' ;; return Key.F
elif vk == 'G' ;; return Key.G
elif vk == 'H' ;; return Key.H
elif vk == 'I' ;; return Key.I
elif vk == 'J' ;; return Key.J
elif vk == 'K' ;; return Key.K
elif vk == 'L' ;; return Key.L
elif vk == 'M' ;; return Key.M
elif vk == 'N' ;; return Key.N
elif vk == 'O' ;; return Key.O
elif vk == 'P' ;; return Key.P
elif vk == 'Q' ;; return Key.Q
elif vk == 'R' ;; return Key.R
elif vk == 'S' ;; return Key.S
elif vk == 'T' ;; return Key.T
elif vk == 'U' ;; return Key.U
elif vk == 'V' ;; return Key.V
elif vk == 'W' ;; return Key.W
elif vk == 'X' ;; return Key.X
elif vk == 'Y' ;; return Key.Y
elif vk == 'Z' ;; return Key.Z
elif vk == '0' ;; return Key.K0
elif vk == '1' ;; return Key.K1
elif vk == '2' ;; return Key.K2
elif vk == '3' ;; return Key.K3
elif vk == '4' ;; return Key.K4
elif vk == '5' ;; return Key.K5
elif vk == '6' ;; return Key.K6
elif vk == '7' ;; return Key.K7
elif vk == '8' ;; return Key.K8
elif vk == '9' ;; return Key.K9
return Key.None
/*END*/