瀏覽代碼

Merge branch 'master' into compiler-improvements-2023-01

gingerBill 2 年之前
父節點
當前提交
15469758de

+ 21 - 72
core/fmt/fmt.odin

@@ -547,7 +547,7 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, new_offset: int, ok:
 	is_digit :: #force_inline proc(r: byte) -> bool { return '0' <= r && r <= '9' }
 
 	new_offset = offset
-	for new_offset <= len(s) {
+	for new_offset < len(s) {
 		c := s[new_offset]
 		if !is_digit(c) {
 			break
@@ -678,7 +678,7 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
 		}
 	} else if fi.zero && fi.width_set {
 		prec = fi.width
-		if neg || fi.plus || fi.space {
+		if neg || fi.plus {
 			// There needs to be space for the "sign"
 			prec -= 1
 		}
@@ -697,7 +697,6 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
 	flags: strconv.Int_Flags
 	if fi.hash && !fi.zero { flags |= {.Prefix} }
 	if fi.plus             { flags |= {.Plus}   }
-	if fi.space            { flags |= {.Space}  }
 	s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags)
 
 	if fi.hash && fi.zero && fi.indent == 0 {
@@ -744,7 +743,7 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i
 		}
 	} else if fi.zero && fi.width_set {
 		prec = fi.width
-		if neg || fi.plus || fi.space {
+		if neg || fi.plus {
 			// There needs to be space for the "sign"
 			prec -= 1
 		}
@@ -763,7 +762,6 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i
 	flags: strconv.Int_Flags
 	if fi.hash && !fi.zero { flags |= {.Prefix} }
 	if fi.plus             { flags |= {.Plus}   }
-	if fi.space            { flags |= {.Space}  }
 	s := strconv.append_bits_128(buf[start:], u, base, is_signed, bit_size, digits, flags)
 
 	if fi.hash && fi.zero && fi.indent == 0 {
@@ -867,79 +865,30 @@ _pad :: proc(fi: ^Info, s: string) {
 	}
 }
 
-fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
-	switch verb {
-	case 'f', 'F', 'g', 'G', 'v':
-		prec: int = 3
-		if fi.prec_set {
-			prec = fi.prec
-		}
-		buf: [386]byte
+_fmt_float_as :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune, float_fmt: byte) {
+	prec := fi.prec if fi.prec_set else 3
+	buf: [386]byte
 
-		str := strconv.append_float(buf[1:], v, 'f', prec, bit_size)
-		b := buf[:len(str)+1]
-		if b[1] == '+' || b[1] == '-' {
-			b = b[1:]
-		} else {
-			b[0] = '+'
-		}
-
-		if fi.space && !fi.plus && b[0] == '+' {
-			b[0] = ' '
-		}
+	// Can return "NaN", "+Inf", "-Inf", "+<value>", "-<value>".
+	str := strconv.append_float(buf[:], v, float_fmt, prec, bit_size)
 
-		if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') {
-			io.write_string(fi.writer, string(b), &fi.n)
-			return
+	if !fi.plus {
+		// Strip sign from "+<value>" but not "+Inf".
+		if str[0] == '+' && str[1] != 'I' {
+			str = str[1:] 
 		}
+	}
 
-		if fi.plus || b[0] != '+' {
-			if fi.zero && fi.width_set && fi.width > len(b) {
-				io.write_byte(fi.writer, b[0], &fi.n)
-				fmt_write_padding(fi, fi.width - len(b))
-				io.write_string(fi.writer, string(b[1:]), &fi.n)
-			} else {
-				_pad(fi, string(b))
-			}
-		} else {
-			_pad(fi, string(b[1:]))
-		}
+	_pad(fi, str)
+}
 
+fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
+	switch verb {
+	case 'f', 'F', 'g', 'G', 'v':
+		_fmt_float_as(fi, v, bit_size, verb, 'f')
 	case 'e', 'E':
-		prec: int = 3
-		if fi.prec_set {
-			prec = fi.prec
-		}
-		buf: [386]byte
-
-		str := strconv.append_float(buf[1:], v, 'e', prec, bit_size)
-		b := buf[:len(str)+1]
-		if b[1] == '+' || b[1] == '-' {
-			b = b[1:]
-		} else {
-			b[0] = '+'
-		}
-
-		if fi.space && !fi.plus && b[0] == '+' {
-			b[0] = ' '
-		}
-
-		if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') {
-			io.write_string(fi.writer, string(b), &fi.n)
-			return
-		}
-
-		if fi.plus || str[0] != '+' {
-			if fi.zero && fi.width_set && fi.width > len(b) {
-				io.write_byte(fi.writer, b[0], &fi.n)
-				fmt_write_padding(fi, fi.width - len(b))
-				io.write_string(fi.writer, string(b[1:]), &fi.n)
-			} else {
-				_pad(fi, string(b))
-			}
-		} else {
-			_pad(fi, string(b[1:]))
-		}
+		// BUG(): "%.3e" returns "3.000e+00"
+		_fmt_float_as(fi, v, bit_size, verb, 'e')
 
 	case 'h', 'H':
 		prev_fi := fi^

+ 4 - 0
core/os/os.odin

@@ -261,3 +261,7 @@ heap_allocator :: proc() -> mem.Allocator {
 		data = nil,
 	}
 }
+
+processor_core_count :: proc() -> int {
+	return _processor_core_count()
+}

+ 13 - 0
core/os/os_darwin.odin

@@ -314,6 +314,7 @@ foreign libc {
 	@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr ---
 
 	@(link_name="strerror") _darwin_string_error :: proc(num : c.int) -> cstring ---
+	@(link_name="sysctlbyname") _sysctlbyname    :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int ---
 
 	@(link_name="exit")    _unix_exit :: proc(status: c.int) -> ! ---
 }
@@ -771,6 +772,18 @@ get_page_size :: proc() -> int {
 	return page_size
 }
 
+@(private)
+_processor_core_count :: proc() -> int {
+	count : int = 0
+	count_size := size_of(count)
+	if _sysctlbyname("hw.logicalcpu", &count, &count_size, nil, 0) == 0 {
+		if count > 0 {
+			return count
+		}
+	}
+
+	return 1
+}
 
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))

+ 14 - 0
core/os/os_freebsd.odin

@@ -287,6 +287,7 @@ foreign libc {
 	
 	@(link_name="getenv")           _unix_getenv        :: proc(cstring) -> cstring ---
 	@(link_name="realpath")         _unix_realpath      :: proc(path: cstring, resolved_path: rawptr) -> rawptr ---
+	@(link_name="sysctlbyname")     _sysctlbyname       :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int ---
 
 	@(link_name="exit")             _unix_exit          :: proc(status: c.int) -> ! ---
 }
@@ -702,6 +703,19 @@ get_page_size :: proc() -> int {
 	return page_size
 }
 
+@(private)
+_processor_core_count :: proc() -> int {
+	count : int = 0
+	count_size := size_of(count)
+	if _sysctlbyname("hw.logicalcpu", &count, &count_size, nil, 0) == 0 {
+		if count > 0 {
+			return count
+		}
+	}
+
+	return 1
+}
+
 
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))

+ 5 - 0
core/os/os_linux.odin

@@ -404,6 +404,7 @@ foreign libc {
 	@(link_name="__errno_location") __errno_location    :: proc() -> ^int ---
 
 	@(link_name="getpagesize")      _unix_getpagesize   :: proc() -> c.int ---
+	@(link_name="get_nprocs")       _unix_get_nprocs    :: proc() -> c.int ---
 	@(link_name="fdopendir")        _unix_fdopendir     :: proc(fd: Handle) -> Dir ---
 	@(link_name="closedir")         _unix_closedir      :: proc(dirp: Dir) -> c.int ---
 	@(link_name="rewinddir")        _unix_rewinddir     :: proc(dirp: Dir) ---
@@ -878,6 +879,10 @@ get_page_size :: proc() -> int {
 	return page_size
 }
 
+@(private)
+_processor_core_count :: proc() -> int {
+	return int(_unix_get_nprocs())
+}
 
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))

+ 8 - 1
core/os/os_openbsd.odin

@@ -269,6 +269,7 @@ foreign libc {
 	@(link_name="mkdir")	_unix_mkdir	:: proc(path: cstring, mode: mode_t) -> c.int ---
 
 	@(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int ---
+	@(link_name="sysconf") _sysconf :: proc(name: c.int) -> c.long ---
 	@(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir ---
 	@(link_name="closedir")	_unix_closedir	:: proc(dirp: Dir) -> c.int ---
 	@(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) ---
@@ -704,6 +705,12 @@ get_page_size :: proc() -> int {
 	return page_size
 }
 
+_SC_NPROCESSORS_ONLN :: 503
+
+@(private)
+_processor_core_count :: proc() -> int {
+	return int(_sysconf(_SC_NPROCESSORS_ONLN))
+}
 
 _alloc_command_line_arguments :: proc() -> []string {
 	res := make([]string, len(runtime.args__))
@@ -711,4 +718,4 @@ _alloc_command_line_arguments :: proc() -> []string {
 		res[i] = string(arg)
 	}
 	return res
-}
+}

+ 4 - 1
core/os/os_wasi.odin

@@ -89,7 +89,10 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
 current_thread_id :: proc "contextless" () -> int {
 	return 0
 }
-
+@(private)
+_processor_core_count :: proc() -> int {
+	return 1
+}
 
 file_size :: proc(fd: Handle) -> (i64, Errno) {
 	stat, err := wasi.fd_filestat_get(wasi.fd_t(fd))

+ 23 - 1
core/os/os_windows.odin

@@ -3,6 +3,7 @@ package os
 
 import win32 "core:sys/windows"
 import "core:runtime"
+import "core:intrinsics"
 
 Handle    :: distinct uintptr
 File_Time :: distinct u64
@@ -126,7 +127,28 @@ get_page_size :: proc() -> int {
 	return page_size
 }
 
+@(private)
+_processor_core_count :: proc() -> int {
+	length : win32.DWORD = 0
+	result := win32.GetLogicalProcessorInformation(nil, &length)
 
+	thread_count := 0
+	if !result && win32.GetLastError() == 122 && length > 0 {
+		processors := make([]win32.SYSTEM_LOGICAL_PROCESSOR_INFORMATION, length, context.temp_allocator)
+
+		result = win32.GetLogicalProcessorInformation(&processors[0], &length)
+		if result {
+			for processor in processors {
+				if processor.Relationship == .RelationProcessorCore {
+					thread := intrinsics.count_ones(processor.ProcessorMask)
+					thread_count += int(thread)
+				}
+			}
+		}
+	}
+
+	return thread_count
+}
 
 exit :: proc "contextless" (code: int) -> ! {
 	runtime._cleanup_runtime_contextless()
@@ -214,4 +236,4 @@ is_windows_10 :: proc() -> bool {
 is_windows_11 :: proc() -> bool {
 	osvi := get_windows_version_w()
 	return (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber >= WINDOWS_11_BUILD_CUTOFF)
-}
+}

+ 0 - 5
core/strconv/integers.odin

@@ -3,7 +3,6 @@ package strconv
 Int_Flag :: enum {
 	Prefix,
 	Plus,
-	Space,
 }
 Int_Flags :: bit_set[Int_Flag]
 
@@ -73,8 +72,6 @@ append_bits :: proc(buf: []byte, x: u64, base: int, is_signed: bool, bit_size: i
 		i-=1; a[i] = '-'
 	case .Plus in flags:
 		i-=1; a[i] = '+'
-	case .Space in flags:
-		i-=1; a[i] = ' '
 	}
 
 	out := a[i:]
@@ -157,8 +154,6 @@ append_bits_128 :: proc(buf: []byte, x: u128, base: int, is_signed: bool, bit_si
 		i-=1; a[i] = '-'
 	case .Plus in flags:
 		i-=1; a[i] = '+'
-	case .Space in flags:
-		i-=1; a[i] = ' '
 	}
 
 	out := a[i:]

+ 38 - 0
core/sys/windows/dwmapi.odin

@@ -3,7 +3,45 @@ package sys_windows
 
 foreign import dwmapi "system:Dwmapi.lib"
 
+DWMWINDOWATTRIBUTE :: enum {
+	DWMWA_NCRENDERING_ENABLED,
+	DWMWA_NCRENDERING_POLICY,
+	DWMWA_TRANSITIONS_FORCEDISABLED,
+	DWMWA_ALLOW_NCPAINT,
+	DWMWA_CAPTION_BUTTON_BOUNDS,
+	DWMWA_NONCLIENT_RTL_LAYOUT,
+	DWMWA_FORCE_ICONIC_REPRESENTATION,
+	DWMWA_FLIP3D_POLICY,
+	DWMWA_EXTENDED_FRAME_BOUNDS,
+	DWMWA_HAS_ICONIC_BITMAP,
+	DWMWA_DISALLOW_PEEK,
+	DWMWA_EXCLUDED_FROM_PEEK,
+	DWMWA_CLOAK,
+	DWMWA_CLOAKED,
+	DWMWA_FREEZE_REPRESENTATION,
+	DWMWA_PASSIVE_UPDATE_MODE,
+	DWMWA_USE_HOSTBACKDROPBRUSH,
+	DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
+	DWMWA_WINDOW_CORNER_PREFERENCE = 33,
+	DWMWA_BORDER_COLOR,
+	DWMWA_CAPTION_COLOR,
+	DWMWA_TEXT_COLOR,
+	DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
+	DWMWA_SYSTEMBACKDROP_TYPE,
+  	DWMWA_LAST,
+}
+
+DWMNCRENDERINGPOLICY :: enum {
+	DWMNCRP_USEWINDOWSTYLE,
+	DWMNCRP_DISABLED,
+	DWMNCRP_ENABLED,
+	DWMNCRP_LAST,
+}
+
 @(default_calling_convention="stdcall")
 foreign dwmapi {
 	DwmFlush :: proc() -> HRESULT ---
+	DwmIsCompositionEnabled :: proc(pfEnabled: ^BOOL) -> HRESULT ---
+	DwmExtendFrameIntoClientArea :: proc(hWnd: HWND, pMarInset: PMARGINS) -> HRESULT ---
+	DwmSetWindowAttribute :: proc(hWnd: HWND, dwAttribute: DWORD, pvAttribute: LPCVOID, cbAttribute: DWORD) -> HRESULT ---
 }

+ 2 - 0
core/sys/windows/gdi32.odin

@@ -79,6 +79,8 @@ foreign gdi32 {
 	TextOutW :: proc(hdc: HDC, x, y: c_int, lpString: LPCWSTR, c: c_int) -> BOOL ---
 	GetTextExtentPoint32W :: proc(hdc: HDC, lpString: LPCWSTR, c: c_int, psizl: LPSIZE) -> BOOL ---
 	GetTextMetricsW :: proc(hdc: HDC, lptm: LPTEXTMETRICW) -> BOOL ---
+
+	CreateSolidBrush :: proc(color: COLORREF) -> HBRUSH ---
 }
 
 RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {

+ 48 - 0
core/sys/windows/kernel32.odin

@@ -370,6 +370,8 @@ foreign kernel32 {
 		lpTotalNumberOfBytes: PULARGE_INTEGER,
 		lpTotalNumberOfFreeBytes: PULARGE_INTEGER,
 	) -> BOOL ---
+
+	GetLogicalProcessorInformation :: proc(buffer: ^SYSTEM_LOGICAL_PROCESSOR_INFORMATION, returnedLength: PDWORD) -> BOOL ---
 }
 
 
@@ -999,3 +1001,49 @@ foreign kernel32 {
 	ConvertThreadToFiber :: proc(lpParameter: LPVOID) -> LPVOID ---
 	SwitchToFiber :: proc(lpFiber: LPVOID) ---
 }
+
+LOGICAL_PROCESSOR_RELATIONSHIP :: enum c_int {
+	RelationProcessorCore,
+	RelationNumaNode,
+	RelationCache,
+	RelationProcessorPackage,
+	RelationGroup,
+	RelationProcessorDie,
+	RelationNumaNodeEx,
+	RelationProcessorModule,
+	RelationAll = 0xffff,
+}
+
+PROCESSOR_CACHE_TYPE :: enum c_int {
+	CacheUnified,
+	CacheInstruction,
+	CacheData,
+	CacheTrace,
+}
+
+CACHE_DESCRIPTOR :: struct {
+	Level: BYTE,
+	Associativity: BYTE,
+	LineSize: WORD,
+	Size: DWORD,
+	Type: PROCESSOR_CACHE_TYPE,
+}
+
+ProcessorCore :: struct {
+	Flags: BYTE,
+}
+NumaNode :: struct {
+	NodeNumber: DWORD,
+}
+DUMMYUNIONNAME_u :: struct #raw_union {
+	Core: ProcessorCore,
+	Node: NumaNode,
+	Cache: CACHE_DESCRIPTOR,
+	Reserved: [2]ULONGLONG,
+}
+
+SYSTEM_LOGICAL_PROCESSOR_INFORMATION :: struct {
+	ProcessorMask: ULONG_PTR,
+	Relationship: LOGICAL_PROCESSOR_RELATIONSHIP,
+	DummyUnion: DUMMYUNIONNAME_u,
+}

+ 33 - 0
core/sys/windows/shell32.odin

@@ -22,4 +22,37 @@ foreign shell32 {
 	) -> c_int ---
 	SHFileOperationW :: proc(lpFileOp: LPSHFILEOPSTRUCTW) -> c_int ---
 	SHGetFolderPathW :: proc(hwnd: HWND, csidl: c_int, hToken: HANDLE, dwFlags: DWORD, pszPath: LPWSTR) -> HRESULT ---
+	SHAppBarMessage :: proc(dwMessage: DWORD, pData: PAPPBARDATA) -> UINT_PTR --- 
 }
+
+APPBARDATA :: struct {
+	cbSize: DWORD,
+	hWnd: HWND,
+	uCallbackMessage: UINT,
+	uEdge: UINT,
+	rc: RECT,
+	lParam: LPARAM,
+}
+PAPPBARDATA :: ^APPBARDATA
+ 
+ABM_NEW              :: 0x00000000
+ABM_REMOVE           :: 0x00000001
+ABM_QUERYPOS         :: 0x00000002
+ABM_SETPOS           :: 0x00000003
+ABM_GETSTATE         :: 0x00000004
+ABM_GETTASKBARPOS    :: 0x00000005
+ABM_ACTIVATE         :: 0x00000006 
+ABM_GETAUTOHIDEBAR   :: 0x00000007
+ABM_SETAUTOHIDEBAR   :: 0x00000008 
+ABM_WINDOWPOSCHANGED :: 0x0000009
+ABM_SETSTATE         :: 0x0000000a
+ABN_STATECHANGE      :: 0x0000000
+ABN_POSCHANGED       :: 0x0000001
+ABN_FULLSCREENAPP    :: 0x0000002
+ABN_WINDOWARRANGE    :: 0x0000003
+ABS_AUTOHIDE         :: 0x0000001
+ABS_ALWAYSONTOP      :: 0x0000002
+ABE_LEFT             :: 0
+ABE_TOP              :: 1
+ABE_RIGHT            :: 2
+ABE_BOTTOM           :: 3

+ 1 - 0
core/sys/windows/types.odin

@@ -38,6 +38,7 @@ HHOOK :: distinct HANDLE
 HKEY :: distinct HANDLE
 HDESK :: distinct HANDLE
 HFONT :: distinct HANDLE
+HRGN :: distinct HANDLE
 BOOL :: distinct b32
 BYTE :: distinct u8
 BOOLEAN :: distinct b8

+ 37 - 0
core/sys/windows/user32.odin

@@ -123,6 +123,8 @@ foreign user32 {
 
 	GetKeyState :: proc(nVirtKey: c_int) -> SHORT ---
 	GetAsyncKeyState :: proc(vKey: c_int) -> SHORT ---
+	
+	GetKeyboardState :: proc(lpKeyState: PBYTE) -> BOOL ---
 
 	MapVirtualKeyW :: proc(uCode: UINT, uMapType: UINT) -> UINT ---
 
@@ -203,6 +205,17 @@ foreign user32 {
 	GetRawInputDeviceList :: proc(pRawInputDeviceList: PRAWINPUTDEVICELIST, puiNumDevices: PUINT, cbSize: UINT) -> UINT ---
 	GetRegisteredRawInputDevices :: proc(pRawInputDevices: PRAWINPUTDEVICE, puiNumDevices: PUINT, cbSize: UINT) -> UINT ---
 	RegisterRawInputDevices :: proc(pRawInputDevices: PCRAWINPUTDEVICE, uiNumDevices: UINT, cbSize: UINT) -> BOOL ---
+
+	SetLayeredWindowAttributes  :: proc(hWnd: HWND, crKey: COLORREF, bAlpha: BYTE, dwFlags: DWORD) -> BOOL ---
+
+	FillRect :: proc(hDC: HDC, lprc: ^RECT, hbr: HBRUSH) -> int ---
+	EqualRect :: proc(lprc1: ^RECT, lprc2: ^RECT) -> BOOL ---
+
+	GetWindowInfo :: proc(hwnd: HWND, pwi: PWINDOWINFO) -> BOOL ---
+	GetWindowPlacement :: proc(hWnd: HWND, lpwndpl: ^WINDOWPLACEMENT) -> BOOL ---
+	SetWindowRgn :: proc(hWnd: HWND, hRgn: HRGN, bRedraw: BOOL) -> int ---
+	CreateRectRgnIndirect :: proc(lprect: ^RECT) -> HRGN ---
+	GetSystemMetricsForDpi :: proc(nIndex: int, dpi: UINT) -> int ---
 }
 
 CreateWindowW :: #force_inline proc "stdcall" (
@@ -433,3 +446,27 @@ RI_MOUSE_BUTTON_5_DOWN :: 0x0100
 RI_MOUSE_BUTTON_5_UP :: 0x0200
 RI_MOUSE_WHEEL :: 0x0400
 RI_MOUSE_HWHEEL :: 0x0800
+
+WINDOWPLACEMENT :: struct {
+	length: UINT,
+	flags: UINT,
+	showCmd: UINT,
+	ptMinPosition: POINT,
+  	ptMaxPosition: POINT,
+  	rcNormalPosition: RECT,
+  	rcDevice: RECT,
+}
+
+WINDOWINFO :: struct {
+	cbSize: DWORD,
+	rcWindow: RECT,
+	rcClient: RECT,
+	dwStyle: DWORD,
+	dwExStyle: DWORD,
+	dwWindowStatus: DWORD,
+	cxWindowBorders: UINT,
+	cyWindowBorders: UINT,
+	atomWindowType: ATOM,
+	wCreatorVersion: WORD,
+}
+PWINDOWINFO :: ^WINDOWINFO

+ 12 - 0
core/sys/windows/ux_theme.odin

@@ -0,0 +1,12 @@
+// +build windows
+package sys_windows
+
+foreign import uxtheme "system:UxTheme.lib"
+
+MARGINS :: distinct [4]int
+PMARGINS :: ^MARGINS
+
+@(default_calling_convention="stdcall")
+foreign uxtheme {
+    IsThemeActive :: proc() -> BOOL ---
+}

+ 19 - 0
src/build_settings.cpp

@@ -1536,6 +1536,25 @@ gb_internal bool init_build_paths(String init_filename) {
 			output_name = remove_extension_from_path(output_name);
 			output_name = copy_string(ha, string_trim_whitespace(output_name));
 			output_path = path_from_string(ha, output_name);
+			
+			// Note(Dragos): This is a fix for empty filenames
+			// Turn the trailing folder into the file name
+			if (output_path.name.len == 0) {
+				isize len = output_path.basename.len;
+				while (len > 1 && output_path.basename[len - 1] != '/') {
+					len -= 1;
+				}
+				// We reached the slash
+				String old_basename = output_path.basename;
+				output_path.basename.len = len - 1; // Remove the slash
+				output_path.name = substring(old_basename, len, old_basename.len);
+				output_path.basename = copy_string(ha, output_path.basename);
+				output_path.name = copy_string(ha, output_path.name);
+				// The old basename is wrong. Delete it
+				gb_free(ha, old_basename.text);
+				
+				
+			}
 
 			// Replace extension.
 			if (output_path.ext.len > 0) {

+ 3 - 0
src/path.cpp

@@ -107,7 +107,9 @@ gb_internal String path_to_string(gbAllocator a, Path path) {
 
 	isize i = 0;
 	gb_memmove(str+i, path.basename.text, path.basename.len); i += path.basename.len;
+	
 	gb_memmove(str+i, "/", 1);                                i += 1;
+	
 	gb_memmove(str+i, path.name.text,     path.name.len);     i += path.name.len;
 	if (path.ext.len > 0) {
 		gb_memmove(str+i, ".", 1);                            i += 1;
@@ -150,6 +152,7 @@ gb_internal Path path_from_string(gbAllocator a, String const &path) {
 		return res;
 	}
 
+	// Note(Dragos): Is the copy_string required if it's a substring?
 	isize name_start = (res.basename.len > 0) ? res.basename.len + 1 : res.basename.len;
 	res.name         = substring(fullpath, name_start, fullpath.len);
 	res.name         = remove_extension_from_path(res.name);

+ 4 - 4
src/threading.cpp

@@ -699,7 +699,7 @@ extern "C" int __ulock_wake(uint32_t operation, void *addr, uint64_t wake_value)
 gb_internal void futex_signal(Futex *f) {
 	for (;;) {
 		int ret = __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, 0);
-		if (ret == 0) {
+		if (ret >= 0) {
 			return;
 		}
 		if (ret == -EINTR || ret == -EFAULT) {
@@ -732,14 +732,14 @@ gb_internal void futex_broadcast(Futex *f) {
 gb_internal void futex_wait(Futex *f, Footex val) {
 	for (;;) {
 		int ret = __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, val, 0);
-		if (ret == 0) {
+		if (ret >= 0) {
 			if (*f != val) {
 				return;
 			}
 			continue;
 		}
-		if (ret == -EINTR || ret == -EFAULT) {
-			-continue;
+		if (ret == -EINTR || ret == -EFAULT) {continue;
+			ret = -ret;
 		}
 		if (ret == -ENOENT) {
 			return;

二進制
vendor/cgltf/lib/cgltf.lib


二進制
vendor/stb/lib/darwin/stb_image.a


二進制
vendor/stb/lib/darwin/stb_image_resize.a


二進制
vendor/stb/lib/darwin/stb_image_write.a


二進制
vendor/stb/lib/darwin/stb_rect_pack.a


二進制
vendor/stb/lib/darwin/stb_truetype.a


二進制
vendor/stb/lib/darwin/stb_vorbis.a


+ 31 - 1
vendor/stb/src/Makefile

@@ -1,4 +1,12 @@
-all:
+OS=$(shell uname)
+
+ifeq ($(OS), Darwin)
+all: darwin
+else
+all: unix
+endif
+
+unix:
 	mkdir -p ../lib
 	$(CC) -c -O2 -Os -fPIC stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c
 	$(AR) rcs ../lib/stb_image.a        stb_image.o
@@ -14,3 +22,25 @@ all:
 	#$(CC) -fPIC -shared -Wl,-soname=stb_rect_pack.so     -o ../lib/stb_rect_pack.so    stb_rect_packl.o
 	#$(CC) -fPIC -shared -Wl,-soname=stb_vorbis.so        -o ../lib/stb_vorbis.so       stb_vorbisl.o
 	rm *.o
+
+darwin:
+	mkdir -p ../lib
+	$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_image.c -o stb_image-x86_64.o -mmacosx-version-min=10.12
+	$(CC) -arch arm64  -c -O2 -Os -fPIC stb_image.c -o stb_image-arm64.o -mmacosx-version-min=10.12
+	lipo -create stb_image-x86_64.o stb_image-arm64.o -output ../lib/darwin/stb_image.a
+	$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_image_write.c -o stb_image_write-x86_64.o -mmacosx-version-min=10.12
+	$(CC) -arch arm64  -c -O2 -Os -fPIC stb_image_write.c -o stb_image_write-arm64.o -mmacosx-version-min=10.12
+	lipo -create stb_image_write-x86_64.o stb_image_write-arm64.o -output ../lib/darwin/stb_image_write.a
+	$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_image_resize.c -o stb_image_resize-x86_64.o -mmacosx-version-min=10.12
+	$(CC) -arch arm64  -c -O2 -Os -fPIC stb_image_resize.c -o stb_image_resize-arm64.o -mmacosx-version-min=10.12
+	lipo -create stb_image_resize-x86_64.o stb_image_resize-arm64.o -output ../lib/darwin/stb_image_resize.a
+	$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_truetype.c -o stb_truetype-x86_64.o -mmacosx-version-min=10.12
+	$(CC) -arch arm64  -c -O2 -Os -fPIC stb_truetype.c -o stb_truetype-arm64.o -mmacosx-version-min=10.12
+	lipo -create stb_truetype-x86_64.o stb_truetype-arm64.o -output ../lib/darwin/stb_truetype.a
+	$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_rect_pack.c -o stb_rect_pack-x86_64.o -mmacosx-version-min=10.12
+	$(CC) -arch arm64  -c -O2 -Os -fPIC stb_rect_pack.c -o stb_rect_pack-arm64.o -mmacosx-version-min=10.12
+	lipo -create stb_rect_pack-x86_64.o stb_rect_pack-arm64.o -output ../lib/darwin/stb_rect_pack.a
+	$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_vorbis.c -o stb_vorbis-x86_64.o -mmacosx-version-min=10.12
+	$(CC) -arch arm64  -c -O2 -Os -fPIC stb_vorbis.c -o stb_vorbis-arm64.o -mmacosx-version-min=10.12
+	lipo -create stb_vorbis-x86_64.o stb_vorbis-arm64.o -output ../lib/darwin/stb_vorbis.a
+	rm *.o