Files
mtgodot-poc/src/port/common/Win32Crt.h
T

145 lines
6.4 KiB
C++

#pragma once
// The Win32/MSVC-CRT functions and macros that 40250 logic code calls, with MSVC semantics.
// Added on demand as ported units need them; each one keeps the Windows behavior (including
// the legacy `_snprintf` truncation contract), not the nearest POSIX spelling.
#include "Win32Types.h"
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#if !defined(_WIN32)
#include <alloca.h>
#include <strings.h>
// The x87 precision-control call has no equivalent on ARM; the script never needs x87 state there.
#define _PC_24 0
#define _MCW_PC 0
inline unsigned _controlfp(unsigned, unsigned) { return 0; }
#define _alloca alloca
#include "Win32MinMax.h"
// mmsystem.h
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
#endif
#define ZeroMemory(dst, len) std::memset((dst), 0, (len))
#define FillMemory(dst, len, fill) std::memset((dst), (fill), (len))
#define CopyMemory(dst, src, len) std::memcpy((dst), (src), (len))
#define MoveMemory(dst, src, len) std::memmove((dst), (src), (len))
inline int _stricmp(const char* a, const char* b) { return strcasecmp(a, b); }
inline int stricmp(const char* a, const char* b) { return strcasecmp(a, b); }
inline int _strnicmp(const char* a, const char* b, size_t n) { return strncasecmp(a, b, n); }
inline int strnicmp(const char* a, const char* b, size_t n) { return strncasecmp(a, b, n); }
inline int _strcmpi(const char* a, const char* b) { return strcasecmp(a, b); }
inline int strcmpi(const char* a, const char* b) { return strcasecmp(a, b); }
char* _strlwr(char* s);
char* _strupr(char* s);
// EterBase/StdAfx.h maps `atoi` to `_atoi64` (and `fileno` to `_fileno`) for MSVC >= 1400.
inline INT64 _atoi64(const char* s) { return std::strtoll(s, nullptr, 10); }
#define _fileno fileno
// MSVC `_snprintf`/`_vsnprintf`: when the output is longer than `count`, `count` bytes are written
// with no terminator and -1 is returned; exactly `count` bytes are written unterminated and
// `count` is returned; otherwise the output is terminated and its length returned.
int _vsnprintf(char* buf, size_t count, const char* fmt, va_list ap);
int _snprintf(char* buf, size_t count, const char* fmt, ...)
#if defined(__GNUC__)
__attribute__((format(printf, 3, 4)))
#endif
;
// kernel32 file-system calls (ANSI). CreateDirectory ignores the security attributes; _access takes
// the MSVC modes 0 (exists), 2 (write), 4 (read), 6 (read/write). _unlink is the <io.h> one.
BOOL CreateDirectory(LPCSTR path, void* security_attributes);
BOOL DeleteFile(LPCSTR path);
BOOL CopyFile(LPCSTR existing_path, LPCSTR new_path, BOOL fail_if_exists);
int _access(const char* path, int mode);
int _unlink(const char* path);
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define FILE_ATTRIBUTE_NORMAL 0x00000080
struct WIN32_FIND_DATA { DWORD dwFileAttributes; char cFileName[MAX_PATH]; };
#define INVALID_HANDLE_VALUE (reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1)))
HANDLE FindFirstFile(const char* pattern, WIN32_FIND_DATA* data);
BOOL FindNextFile(HANDLE handle, WIN32_FIND_DATA* data);
BOOL FindClose(HANDLE handle);
void Sleep(DWORD milliseconds);
// kernel32 synchronization objects used by EterLib (FileLoaderThread): a counting semaphore and a
// _beginthreadex thread, both waitable with WaitForSingleObject and freed with CloseHandle.
// Only the unnamed, default-security forms exist; thread priority is accepted and ignored.
#define WAIT_OBJECT_0 0x00000000L
#define WAIT_TIMEOUT 0x00000102L
#define WAIT_FAILED 0xFFFFFFFF
#define THREAD_PRIORITY_NORMAL 0
HANDLE CreateSemaphore(void* security_attributes, LONG initial_count, LONG maximum_count, LPCSTR name);
BOOL ReleaseSemaphore(HANDLE semaphore, LONG release_count, LONG* previous_count);
DWORD WaitForSingleObject(HANDLE handle, DWORD milliseconds);
BOOL CloseHandle(HANDLE handle);
BOOL SetThreadPriority(HANDLE thread, int priority);
uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (*start_address)(void*), void* arglist,
unsigned initflag, unsigned* thrdaddr);
// MSVC <stdlib.h> __min / __max
#ifndef __min
#define __min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef __max
#define __max(a, b) (((a) > (b)) ? (a) : (b))
#endif
// user32 MessageBox (ANSI): no dialog on these hosts; writes caption and text to stderr, returns IDOK.
#define MB_OK 0x00000000L
#define MB_ICONHAND 0x00000010L
#define MB_ICONSTOP MB_ICONHAND
#define MB_TOPMOST 0x00040000L
#define IDOK 1
int MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
// user32 ReleaseDC: the host owns the window and hands out no DC, so there is none to release.
inline int ReleaseDC(HWND, HDC) { return 1; }
// winmm `timeGetTime`: milliseconds since system start, wrapping at 2^32.
DWORD timeGetTime();
DWORD GetTickCount();
// winbase.h: #define GetCurrentTime() GetTickCount()
#define GetCurrentTime() GetTickCount()
// Recursive, like the Win32 critical section. Storage holds a std::recursive_mutex.
struct CRITICAL_SECTION
{
alignas(16) unsigned char storage[128];
};
typedef CRITICAL_SECTION* LPCRITICAL_SECTION;
void InitializeCriticalSection(LPCRITICAL_SECTION cs);
void DeleteCriticalSection(LPCRITICAL_SECTION cs);
void EnterCriticalSection(LPCRITICAL_SECTION cs);
void LeaveCriticalSection(LPCRITICAL_SECTION cs);
// stringapiset.h. WCHAR is 32-bit here, so wide strings hold UTF-32 code points. CP_UTF8 is converted
// directly; CP_ACP (= 1252) and the other ANSI code pages use Microsoft's tables (codepage/codepage.h).
#define CP_ACP 0
#define CP_UTF8 65001
#define MB_PRECOMPOSED 0x00000001
#define MB_ERR_INVALID_CHARS 0x00000008
#define WC_NO_BEST_FIT_CHARS 0x00000400
int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte,
LPWSTR lpWideCharStr, int cchWideChar);
int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar,
LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
// winnls.h / winuser.h DBCS stepping. Lead bytes follow the double-byte code pages 932, 936, 949 and 950;
// every other code page (1252, UTF-8, ...) steps one byte at a time, as Windows does for single-byte pages.
BOOL IsDBCSLeadByteEx(UINT CodePage, BYTE TestChar);
LPSTR CharNextExA(WORD CodePage, LPCSTR lpCurrentChar, DWORD dwFlags);
LPSTR CharPrevExA(WORD CodePage, LPCSTR lpStart, LPCSTR lpCurrentChar, DWORD dwFlags);
#endif // !_WIN32