Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
PlatformDefinesWindows.cpp
Go to the documentation of this file.
1
2
3#if defined(_WIN32)
4
5#if defined(_DEBUG)
6//#include <float.h>
7//unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);
8#endif
9
12#include <ShellScalingApi.h>
13#include <comdef.h>
14
15#ifdef WIN32_LEAN_AND_MEAN
16#undef WIN32_LEAN_AND_MEAN
17// SDL redefines WIN32_LEAN_AND_MEAN
18#include <SDL2/SDL_syswm.h>
19#endif
20
21#include <iostream>
22
23#include <mimalloc-new-delete.h>
24
25extern "C"
26{
27 _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
28 _declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
29}
30
31LRESULT DlgProc([[maybe_unused]] HWND hWnd, [[maybe_unused]] UINT uMsg, [[maybe_unused]] WPARAM wParam, [[maybe_unused]] LPARAM lParam) noexcept
32{
33 return FALSE;
34}
35
36namespace Divide {
37 //https://msdn.microsoft.com/en-us/library/windows/desktop/ms679360%28v=vs.85%29.aspx
38 static std::string GetLastErrorText() noexcept
39 {
40 //Get the error message ID, if any.
41 DWORD errorMessageID = ::GetLastError();
42 if ( errorMessageID == 0 )
43 {
44 return std::string(); //No error message has been recorded
45 }
46
47 LPSTR messageBuffer = nullptr;
48
49 //Ask Win32 to give us the string version of that message ID.
50 //The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be).
51 size_t size = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
52 NULL, errorMessageID, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&messageBuffer, 0, NULL );
53
54 //Copy the error message into a std::string.
55 std::string message( messageBuffer, size );
56
57 //Free the Win32's string's buffer.
58 LocalFree( messageBuffer );
59
60 return message;
61 }
62
63 F32 PlatformDefaultDPI() noexcept
64 {
65 return 96.f;
66 }
67
68 void GetWindowHandle(void* window, WindowHandle& handleOut) noexcept
69 {
70 SDL_SysWMinfo wmInfo = {};
71 SDL_VERSION(&wmInfo.version);
72 SDL_GetWindowWMInfo(static_cast<SDL_Window*>(window), &wmInfo);
73 handleOut._handle = wmInfo.info.win.window;
74 }
75
76 bool DebugBreak(const bool condition) noexcept
77 {
78 if (condition && IsDebuggerPresent())
79 {
80 __debugbreak();
81 return true;
82 }
83
84 return false;
85 }
86
87 void EnforceDPIScaling() noexcept
88 {
89 if (FAILED( SetProcessDpiAwareness( PROCESS_PER_MONITOR_DPI_AWARE ) ))
90 {
91 std::cerr << GetLastErrorText();
92 }
93 }
94
95 bool GetAvailableMemory(SysInfo& info)
96 {
97 MEMORYSTATUSEX status;
98 status.dwLength = sizeof(status);
99 const BOOL infoStatus = GlobalMemoryStatusEx(&status);
100
101 if (infoStatus != FALSE)
102 {
103 info._availableRamInBytes = status.ullAvailPhys;
104 return true;
105 }
106 else
107 {
108 Console::errorfn( GetLastErrorText().c_str() );
109 }
110
111 return false;
112 }
113
114
115 constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
116
117#pragma pack(push,8)
118 typedef struct tagTHREADNAME_INFO
119 {
120 DWORD dwType; // Must be 0x1000.
121 LPCSTR szName; // Pointer to name (in user addr space).
122 DWORD dwThreadID; // Thread ID (-1=caller thread).
123 DWORD dwFlags; // Reserved for future use, must be zero.
124 } THREADNAME_INFO;
125#pragma pack(pop)
126
127 static void SetThreadPriorityInternal(HANDLE thread, const ThreadPriority priority)
128 {
129 if (priority == ThreadPriority::COUNT)
130 {
131 return;
132 }
133
134 switch (priority)
135 {
136 case ThreadPriority::IDLE: ::SetThreadPriority(thread, THREAD_PRIORITY_IDLE); break;
137 case ThreadPriority::BELOW_NORMAL: ::SetThreadPriority(thread, THREAD_PRIORITY_BELOW_NORMAL); break;
138 case ThreadPriority::NORMAL: ::SetThreadPriority(thread, THREAD_PRIORITY_NORMAL); break;
139 case ThreadPriority::ABOVE_NORMAL: ::SetThreadPriority(thread, THREAD_PRIORITY_ABOVE_NORMAL); break;
140 case ThreadPriority::HIGHEST: ::SetThreadPriority(thread, THREAD_PRIORITY_HIGHEST); break;
141 case ThreadPriority::TIME_CRITICAL: ::SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL); break;
143 }
144 }
145
146 void SetThreadPriority(const ThreadPriority priority)
147 {
148 SetThreadPriorityInternal(GetCurrentThread(), priority);
149 }
150
151 static void SetThreadName(const U32 threadID, const std::string_view threadName) noexcept
152 {
153 // DWORD dwThreadID = ::GetThreadId( static_cast<HANDLE>( t.native_handle() ) );
154
155 THREADNAME_INFO info;
156 info.dwType = 0x1000;
157 info.szName = threadName.data();
158 info.dwThreadID = threadID;
159 info.dwFlags = 0;
160
161 __try
162 {
163 RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
164 }
165 __except (EXCEPTION_EXECUTE_HANDLER)
166 {
167 DebugBreak();
168 }
169 }
170
171 void SetThreadName(const std::string_view threadName) noexcept
172 {
173 SetThreadName(GetCurrentThreadId(), threadName);
174 }
175
176 bool CallSystemCmd(const std::string_view cmd, const std::string_view args)
177 {
178 STARTUPINFO si;
179 ZeroMemory(&si, sizeof(si));
180 si.cb = sizeof(si);
181
182 PROCESS_INFORMATION pi;
183 ZeroMemory(&pi, sizeof(pi));
184
185 const string commandLine = Util::StringFormat("\"{}\" {}", cmd, args);
186 char* lpCommandLine = const_cast<char*>(commandLine.c_str());
187
188 const BOOL ret = CreateProcess(nullptr, lpCommandLine, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi);
189
190 CloseHandle(pi.hProcess);
191 CloseHandle(pi.hThread);
192
193 return ret == TRUE;
194 }
195}; //namespace Divide
196
197#endif //defined(_WIN32)
SDL_Window SDL_Window
Definition: DisplayWindow.h:42
#define DIVIDE_UNEXPECTED_CALL()
LRESULT DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) noexcept
Str StringFormat(const char *fmt, Args &&...args)
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
void GetWindowHandle(void *window, WindowHandle &handleOut) noexcept
F32 PlatformDefaultDPI() noexcept
void SetThreadName(std::string_view threadName) noexcept
bool CallSystemCmd(std::string_view cmd, std::string_view args)
void SetThreadPriorityInternal(pthread_t thread, const ThreadPriority priority)
bool DebugBreak(const bool condition) noexcept
void SetThreadPriority(ThreadPriority priority)
void EnforceDPIScaling() noexcept
bool GetAvailableMemory(SysInfo &info)
uint32_t U32
static NO_INLINE void errorfn(const char *format, T &&... args)