Previously it wasnt working but now its working, TRUST ME
This commit is contained in:
42
build/modules/Arena.core
Normal file
42
build/modules/Arena.core
Normal 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
124
build/modules/Base.core
Normal 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
41
build/modules/GDI32.core
Normal 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
130
build/modules/KERNEL32.core
Normal 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
|
||||
60
build/modules/Language.core
Normal file
60
build/modules/Language.core
Normal 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
17
build/modules/LibC.core
Normal 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
|
||||
34
build/modules/MathF32.core
Normal file
34
build/modules/MathF32.core
Normal 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
|
||||
32
build/modules/MathVec2.core
Normal file
32
build/modules/MathVec2.core
Normal 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}
|
||||
46
build/modules/MathVec3.core
Normal file
46
build/modules/MathVec3.core
Normal 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
|
||||
64
build/modules/Multimedia.core
Normal file
64
build/modules/Multimedia.core
Normal 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"
|
||||
65
build/modules/OSWin32.core
Normal file
65
build/modules/OSWin32.core
Normal 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
200
build/modules/USER32.core
Normal 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
6
build/modules/WINMM.core
Normal file
@@ -0,0 +1,6 @@
|
||||
#import "KERNEL32.core"
|
||||
#link "winmm"
|
||||
|
||||
MMRESULT :: UINT
|
||||
TIMERR_NOERROR :: 0
|
||||
timeBeginPeriod :: #foreign (uPeriod: UINT): MMRESULT
|
||||
355
build/modules/win32_multimedia.core
Normal file
355
build/modules/win32_multimedia.core
Normal 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*/
|
||||
Reference in New Issue
Block a user