diff --git a/misc/UWP/Platform_UWP.cpp b/misc/UWP/Platform_UWP.cpp new file mode 100644 index 000000000..9cb860ef4 --- /dev/null +++ b/misc/UWP/Platform_UWP.cpp @@ -0,0 +1,797 @@ +#include "../../src/Core.h" +#include "../../src/_PlatformBase.h" +#include "../../src/Stream.h" +#include "../../src/SystemFonts.h" +#include "../../src/Funcs.h" +#include "../../src/Utils.h" +#include "../../src/Errors.h" + +#define WIN32_LEAN_AND_MEAN +#define NOSERVICE +#define NOMCX +#define NOIME +#ifndef UNICODE +#define UNICODE +#define _UNICODE +#endif +#include +#include +#include +#include +#include + +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Devices::Input; +using namespace Windows::Graphics::Display; +using namespace Windows::Foundation; +using namespace Windows::System; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; +using namespace Windows::Security::Cryptography; +using namespace Windows::Security::Cryptography::DataProtection; +using namespace Platform; + +static HANDLE heap; +const cc_result ReturnCode_FileShareViolation = ERROR_SHARING_VIOLATION; +const cc_result ReturnCode_FileNotFound = ERROR_FILE_NOT_FOUND; +const cc_result ReturnCode_DirectoryExists = ERROR_ALREADY_EXISTS; +const cc_result ReturnCode_SocketInProgess = WSAEINPROGRESS; +const cc_result ReturnCode_SocketWouldBlock = WSAEWOULDBLOCK; +const cc_result ReturnCode_SocketDropped = WSAECONNRESET; + +const char* Platform_AppNameSuffix = ""; +cc_bool Platform_ReadonlyFilesystem; +cc_bool Platform_SingleProcess; +#define UWP_STRING(str) ((wchar_t*)(str)->uni) + +/*########################################################################################################################* +*---------------------------------------------------------Memory----------------------------------------------------------* +*#########################################################################################################################*/ +void* Mem_Set(void* dst, cc_uint8 value, unsigned numBytes) { return memset( dst, value, numBytes); } +void* Mem_Copy(void* dst, const void* src, unsigned numBytes) { return memcpy( dst, src, numBytes); } +void* Mem_Move(void* dst, const void* src, unsigned numBytes) { return memmove(dst, src, numBytes); } + +void* Mem_TryAlloc(cc_uint32 numElems, cc_uint32 elemsSize) { + cc_uint32 size = CalcMemSize(numElems, elemsSize); + return size ? HeapAlloc(heap, 0, size) : NULL; +} + +void* Mem_TryAllocCleared(cc_uint32 numElems, cc_uint32 elemsSize) { + cc_uint32 size = CalcMemSize(numElems, elemsSize); + return size ? HeapAlloc(heap, HEAP_ZERO_MEMORY, size) : NULL; +} + +void* Mem_TryRealloc(void* mem, cc_uint32 numElems, cc_uint32 elemsSize) { + cc_uint32 size = CalcMemSize(numElems, elemsSize); + return size ? HeapReAlloc(heap, 0, mem, size) : NULL; +} + +void Mem_Free(void* mem) { + if (mem) HeapFree(heap, 0, mem); +} + + +/*########################################################################################################################* +*------------------------------------------------------Logging/Time-------------------------------------------------------* +*#########################################################################################################################*/ +/* TODO: check this is actually accurate */ +static cc_uint64 sw_freqMul = 1, sw_freqDiv = 1; +cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { + if (end < beg) return 0; + return ((end - beg) * sw_freqMul) / sw_freqDiv; +} + +static HANDLE conHandle; +static BOOL hasDebugger; + +void Platform_Log(const char* msg, int len) { + char tmp[2048 + 1]; + DWORD wrote; + + if (conHandle) { + WriteFile(conHandle, msg, len, &wrote, NULL); + WriteFile(conHandle, "\n", 1, &wrote, NULL); + } + + if (!hasDebugger) return; + len = min(len, 2048); + Mem_Copy(tmp, msg, len); tmp[len] = '\0'; + + OutputDebugStringA(tmp); + OutputDebugStringA("\n"); +} + +#define FILETIME_EPOCH 50491123200ULL +#define FILETIME_UNIX_EPOCH 11644473600ULL +#define FileTime_TotalSecs(time) ((time / 10000000) + FILETIME_EPOCH) +#define FileTime_UnixTime(time) ((time / 10000000) - FILETIME_UNIX_EPOCH) + +TimeMS DateTime_CurrentUTC(void) { + FILETIME ft; + cc_uint64 raw; + + GetSystemTimeAsFileTime(&ft); + /* in 100 nanosecond units, since Jan 1 1601 */ + raw = ft.dwLowDateTime | ((cc_uint64)ft.dwHighDateTime << 32); + return FileTime_TotalSecs(raw); +} + +void DateTime_CurrentLocal(struct cc_datetime* t) { + SYSTEMTIME localTime; + GetLocalTime(&localTime); + + t->year = localTime.wYear; + t->month = localTime.wMonth; + t->day = localTime.wDay; + t->hour = localTime.wHour; + t->minute = localTime.wMinute; + t->second = localTime.wSecond; +} + +static cc_bool sw_highRes; +cc_uint64 Stopwatch_Measure(void) { + LARGE_INTEGER t; + FILETIME ft; + + if (sw_highRes) { + QueryPerformanceCounter(&t); + return (cc_uint64)t.QuadPart; + } else { + GetSystemTimeAsFileTime(&ft); + return (cc_uint64)ft.dwLowDateTime | ((cc_uint64)ft.dwHighDateTime << 32); + } +} + + +/*########################################################################################################################* +*-----------------------------------------------------Directory/File------------------------------------------------------* +*#########################################################################################################################*/ +void Directory_GetCachePath(cc_string* path) { } + +void Platform_EncodePath(cc_filepath* dst, const cc_string* src) { + Platform_EncodeString(dst, src); +} + +cc_result Directory_Create(const cc_filepath* path) { + if (CreateDirectoryW(UWP_STRING(path), NULL)) return 0; + return GetLastError(); +} + +int File_Exists(const cc_filepath* path) { + DWORD attribs = GetFileAttributesW(UWP_STRING(path)); + + return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY); +} + +static cc_result Directory_EnumCore(const cc_string* dirPath, const cc_string* file, DWORD attribs, + void* obj, Directory_EnumCallback callback) { + cc_string path; char pathBuffer[MAX_PATH + 10]; + int is_dir; + + /* ignore . and .. entry */ + if (file->length == 1 && file->buffer[0] == '.') return 0; + if (file->length == 2 && file->buffer[0] == '.' && file->buffer[1] == '.') return 0; + + String_InitArray(path, pathBuffer); + String_Format2(&path, "%s/%s", dirPath, file); + + is_dir = attribs & FILE_ATTRIBUTE_DIRECTORY; + callback(&path, obj, is_dir); + return 0; +} + +cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) { + cc_string path; char pathBuffer[MAX_PATH + 10]; + WIN32_FIND_DATAW eW; + int i, ansi = false; + cc_filepath str; + HANDLE find; + cc_result res; + + /* Need to append \* to search for files in directory */ + String_InitArray(path, pathBuffer); + String_Format1(&path, "%s\\*", dirPath); + Platform_EncodePath(&str, &path); + + find = FindFirstFileW(UWP_STRING(&str), &eW); + if (!find || find == INVALID_HANDLE_VALUE) + return GetLastError(); + + do { + path.length = 0; + for (i = 0; i < MAX_PATH && eW.cFileName[i]; i++) { + /* TODO: UTF16 to codepoint conversion */ + String_Append(&path, Convert_CodepointToCP437(eW.cFileName[i])); + } + if ((res = Directory_EnumCore(dirPath, &path, eW.dwFileAttributes, obj, callback))) return res; + } while (FindNextFileW(find, &eW)); + + res = GetLastError(); /* return code from FindNextFile */ + FindClose(find); + return res == ERROR_NO_MORE_FILES ? 0 : res; +} + +static cc_result DoFile(cc_file* file, const cc_filepath* path, DWORD access, DWORD createMode) { + *file = CreateFile2(UWP_STRING(path), access, FILE_SHARE_READ, createMode, NULL); + if (*file && *file != INVALID_HANDLE_VALUE) return 0; + return GetLastError(); +} + +cc_result File_Open(cc_file* file, const cc_filepath* path) { + return DoFile(file, path, GENERIC_READ, OPEN_EXISTING); +} +cc_result File_Create(cc_file* file, const cc_filepath* path) { + return DoFile(file, path, GENERIC_WRITE | GENERIC_READ, CREATE_ALWAYS); +} +cc_result File_OpenOrCreate(cc_file* file, const cc_filepath* path) { + return DoFile(file, path, GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS); +} + +cc_result File_Read(cc_file file, void* data, cc_uint32 count, cc_uint32* bytesRead) { + /* NOTE: the (DWORD*) cast assumes that sizeof(long) is 4 */ + BOOL success = ReadFile(file, data, count, (DWORD*)bytesRead, NULL); + return success ? 0 : GetLastError(); +} + +cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32* bytesWrote) { + /* NOTE: the (DWORD*) cast assumes that sizeof(long) is 4 */ + BOOL success = WriteFile(file, data, count, (DWORD*)bytesWrote, NULL); + return success ? 0 : GetLastError(); +} + +cc_result File_Close(cc_file file) { + return CloseHandle(file) ? 0 : GetLastError(); +} + +cc_result File_Seek(cc_file file, int offset, int seekType) { + static cc_uint8 modes[] = { FILE_BEGIN, FILE_CURRENT, FILE_END }; + DWORD pos = SetFilePointer(file, offset, NULL, modes[seekType]); + return pos != INVALID_SET_FILE_POINTER ? 0 : GetLastError(); +} + +cc_result File_Position(cc_file file, cc_uint32* pos) { + *pos = SetFilePointer(file, 0, NULL, FILE_CURRENT); + return *pos != INVALID_SET_FILE_POINTER ? 0 : GetLastError(); +} + +cc_result File_Length(cc_file file, cc_uint32* len) { + LARGE_INTEGER raw; + if (!GetFileSizeEx(file, &raw)) return GetLastError(); + + *len = raw.QuadPart; + return 0; +} + + +/*########################################################################################################################* +*--------------------------------------------------------Threading--------------------------------------------------------* +*#############################################################################################################p############*/ +void Thread_Sleep(cc_uint32 milliseconds) { Sleep(milliseconds); } +static DWORD WINAPI ExecThread(void* param) { + Thread_StartFunc func = (Thread_StartFunc)param; + func(); + return 0; +} + +void Thread_Run(void** handle, Thread_StartFunc func, int stackSize, const char* name) { + DWORD threadID; + HANDLE thread = CreateThread(NULL, 0, ExecThread, (void*)func, CREATE_SUSPENDED, &threadID); + if (!thread) Logger_Abort2(GetLastError(), "Creating thread"); + + *handle = thread; + ResumeThread(thread); +} + +void Thread_Detach(void* handle) { + if (!CloseHandle((HANDLE)handle)) { + Logger_Abort2(GetLastError(), "Freeing thread handle"); + } +} + +void Thread_Join(void* handle) { + WaitForSingleObject((HANDLE)handle, INFINITE); + Thread_Detach(handle); +} + +void* Mutex_Create(const char* name) { + CRITICAL_SECTION* ptr = (CRITICAL_SECTION*)Mem_Alloc(1, sizeof(CRITICAL_SECTION), "mutex"); + InitializeCriticalSection(ptr); + return ptr; +} + +void Mutex_Free(void* handle) { + DeleteCriticalSection((CRITICAL_SECTION*)handle); + Mem_Free(handle); +} +void Mutex_Lock(void* handle) { EnterCriticalSection((CRITICAL_SECTION*)handle); } +void Mutex_Unlock(void* handle) { LeaveCriticalSection((CRITICAL_SECTION*)handle); } + +void* Waitable_Create(const char* name) { + void* handle = CreateEventA(NULL, false, false, NULL); + if (!handle) { + Logger_Abort2(GetLastError(), "Creating waitable"); + } + return handle; +} + +void Waitable_Free(void* handle) { + if (!CloseHandle((HANDLE)handle)) { + Logger_Abort2(GetLastError(), "Freeing waitable"); + } +} + +void Waitable_Signal(void* handle) { SetEvent((HANDLE)handle); } +void Waitable_Wait(void* handle) { + WaitForSingleObject((HANDLE)handle, INFINITE); +} + +void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) { + WaitForSingleObject((HANDLE)handle, milliseconds); +} + + +/*########################################################################################################################* +*---------------------------------------------------------Socket----------------------------------------------------------* +*#########################################################################################################################*/ +/* Sanity check to ensure cc_sockaddr struct is large enough to contain all socket addresses supported by this platform */ +static char sockaddr_size_check[sizeof(SOCKADDR_STORAGE) < CC_SOCKETADDR_MAXSIZE ? 1 : -1]; + +static cc_result ParseHostNew(char* host, int port, cc_sockaddr* addrs, int* numValidAddrs) { + char portRaw[32]; cc_string portStr; + struct addrinfo hints = { 0 }; + struct addrinfo* result; + struct addrinfo* cur; + int res, i = 0; + + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + String_InitArray(portStr, portRaw); + String_AppendInt(&portStr, port); + portRaw[portStr.length] = '\0'; + + res = getaddrinfo(host, portRaw, &hints, &result); + if (res == WSAHOST_NOT_FOUND) return SOCK_ERR_UNKNOWN_HOST; + if (res) return res; + + /* Prefer IPv4 addresses first */ + for (cur = result; cur && i < SOCKET_MAX_ADDRS; cur = cur->ai_next) + { + if (cur->ai_family != AF_INET) continue; + SocketAddr_Set(&addrs[i], cur->ai_addr, cur->ai_addrlen); i++; + } + + for (cur = result; cur && i < SOCKET_MAX_ADDRS; cur = cur->ai_next) + { + if (cur->ai_family == AF_INET) continue; + SocketAddr_Set(&addrs[i], cur->ai_addr, cur->ai_addrlen); i++; + } + + freeaddrinfo(result); + *numValidAddrs = i; + return i == 0 ? ERR_INVALID_ARGUMENT : 0; +} + +cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) { + SOCKADDR_IN* addr4 = (SOCKADDR_IN* )addrs[0].data; + SOCKADDR_IN6* addr6 = (SOCKADDR_IN6*)addrs[0].data; + cc_winstring str; + INT size; + + *numValidAddrs = 0; + Platform_EncodeString(&str, address); + + size = sizeof(*addr4); + if (!WSAStringToAddressW(UWP_STRING(&str), AF_INET, NULL, (SOCKADDR*)addr4, &size)) { + addr4->sin_port = htons(port); + + addrs[0].size = size; + *numValidAddrs = 1; + return 0; + } + + size = sizeof(*addr6); + if (!WSAStringToAddressW(UWP_STRING(&str), AF_INET6, NULL, (SOCKADDR*)addr6, &size)) { + addr6->sin6_port = htons(port); + + addrs[0].size = size; + *numValidAddrs = 1; + return 0; + } + + return ParseHostNew(str.ansi, port, addrs, numValidAddrs); +} + +cc_result Socket_Create(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) { + SOCKADDR* raw_addr = (SOCKADDR*)addr->data; + + *s = socket(raw_addr->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (*s == -1) return WSAGetLastError(); + + if (nonblocking) { + u_long blockingMode = -1; /* non-blocking mode */ + ioctlsocket(*s, FIONBIO, &blockingMode); + } + return 0; +} + +cc_result Socket_Connect(cc_socket s, cc_sockaddr* addr) { + SOCKADDR* raw_addr = (SOCKADDR*)addr->data; + + int res = connect(s, raw_addr, addr->size); + return res == -1 ? WSAGetLastError() : 0; +} + +cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* modified) { + int recvCount = recv(s, (char*)data, count, 0); + if (recvCount != -1) { *modified = recvCount; return 0; } + *modified = 0; return WSAGetLastError(); +} + +cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified) { + int sentCount = send(s, (const char*)data, count, 0); + if (sentCount != -1) { *modified = sentCount; return 0; } + *modified = 0; return WSAGetLastError(); +} + +void Socket_Close(cc_socket s) { + shutdown(s, SD_BOTH); + closesocket(s); +} + +static cc_result Socket_Poll(cc_socket s, int mode, cc_bool* success) { + fd_set set; + struct timeval time = { 0 }; + int selectCount; + + set.fd_count = 1; + set.fd_array[0] = s; + + if (mode == SOCKET_POLL_READ) { + selectCount = select(1, &set, NULL, NULL, &time); + } else { + selectCount = select(1, NULL, &set, NULL, &time); + } + + if (selectCount == -1) { *success = false; return WSAGetLastError(); } + + *success = set.fd_count != 0; return 0; +} + +cc_result Socket_CheckReadable(cc_socket s, cc_bool* readable) { + return Socket_Poll(s, SOCKET_POLL_READ, readable); +} + +cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) { + int resultSize = sizeof(cc_result); + cc_result res = Socket_Poll(s, SOCKET_POLL_WRITE, writable); + if (res || *writable) return res; + + /* https://stackoverflow.com/questions/29479953/so-error-value-after-successful-socket-operation */ + getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&res, &resultSize); + return res; +} + + +/*########################################################################################################################* +*-----------------------------------------------------Process/Module------------------------------------------------------* +*#########################################################################################################################*/ +cc_bool Process_OpenSupported = true; + +static cc_result Process_RawGetExePath(cc_winstring* path, int* len) { + *len = GetModuleFileNameW(NULL, UWP_STRING(path), NATIVE_STR_LEN); + path->uni[*len] = '\0'; + if (*len) return 0; + + return GetLastError(); +} + +cc_result Process_StartGame2(const cc_string* args, int numArgs) { + union STARTUPINFO_union { + STARTUPINFOW wide; + STARTUPINFOA ansi; + } si = { 0 }; // less compiler warnings this way + + cc_winstring path; + cc_string argv; char argvBuffer[NATIVE_STR_LEN]; + PROCESS_INFORMATION pi = { 0 }; + cc_winstring raw; + cc_result res; + int len, i; + + if (Platform_SingleProcess) return SetGameArgs(args, numArgs); + if ((res = Process_RawGetExePath(&path, &len))) return res; + si.wide.cb = sizeof(STARTUPINFOW); + + String_InitArray(argv, argvBuffer); + /* Game doesn't actually care about argv[0] */ + String_AppendConst(&argv, "cc"); + for (i = 0; i < numArgs; i++) + { + if (String_IndexOf(&args[i], ' ') >= 0) { + String_Format1(&argv, " \"%s\"", &args[i]); + } else { + String_Format1(&argv, " %s", &args[i]); + } + } + Platform_EncodeString(&raw, &argv); + + if (!CreateProcessW(UWP_STRING(&path), UWP_STRING(&raw), NULL, NULL, + false, 0, NULL, NULL, &si.wide, &pi)) return GetLastError(); + + /* Don't leak memory for process return code */ + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return 0; +} + +void Process_Exit(cc_result code) { ExitProcess(code); } +cc_result Process_StartOpen(const cc_string* args) { + cc_winstring raw; + Platform_EncodeString(&raw, args); + + auto str = ref new String(UWP_STRING(&raw)); + auto uri = ref new Uri(str); + + auto options = ref new Windows::System::LauncherOptions(); + options->TreatAsUntrusted = true; + Windows::System::Launcher::LaunchUriAsync(uri, options); + return 0; +} + + +/*########################################################################################################################* +*--------------------------------------------------------Updater----------------------------------------------------------* +*#########################################################################################################################*/ +#define UPDATE_TMP TEXT("CC_prev.exe") +#define UPDATE_SRC TEXT(UPDATE_FILE) +cc_bool Updater_Supported = true; + +#if defined _M_IX86 +const struct UpdaterInfo Updater_Info = { + "&eDirect3D 9 is recommended", 2, + { + { "Direct3D9", "ClassiCube.exe" }, + { "OpenGL", "ClassiCube.opengl.exe" } + } +}; +#elif defined _M_X64 +const struct UpdaterInfo Updater_Info = { + "&eDirect3D 9 is recommended", 2, + { + { "Direct3D9", "ClassiCube.64.exe" }, + { "OpenGL", "ClassiCube.64-opengl.exe" } + } +}; +#elif defined _M_ARM64 +const struct UpdaterInfo Updater_Info = { "", 1, { { "Direct3D11", "cc-arm64-d3d11.exe" } } }; +#elif defined _M_ARM +const struct UpdaterInfo Updater_Info = { "", 1, { { "Direct3D11", "cc-arm32-d3d11.exe" } } }; +#else +const struct UpdaterInfo Updater_Info = { "&eCompile latest source code to update", 0 }; +#endif + +cc_bool Updater_Clean(void) { + return DeleteFile(UPDATE_TMP) || GetLastError() == ERROR_FILE_NOT_FOUND; +} + +cc_result Updater_Start(const char** action) { + cc_winstring path; + cc_result res; + int len; + + *action = "Getting executable path"; + if ((res = Process_RawGetExePath(&path, &len))) return res; + + *action = "Moving executable to CC_prev.exe"; + if (!path.uni[0]) return ERR_NOT_SUPPORTED; /* MoveFileA returns ERROR_ACCESS_DENIED on Win 9x anyways */ + if (!MoveFileExW(UWP_STRING(&path), UPDATE_TMP, MOVEFILE_REPLACE_EXISTING)) return GetLastError(); + + *action = "Replacing executable"; + if (!MoveFileExW(UPDATE_SRC, UWP_STRING(&path), MOVEFILE_REPLACE_EXISTING)) return GetLastError(); + + *action = "Restarting game"; + return Process_StartGame2(NULL, 0); +} + +cc_result Updater_GetBuildTime(cc_uint64* timestamp) { + cc_winstring path; + cc_file file; + FILETIME ft; + cc_uint64 raw; + cc_result res; + int len; + + if ((res = Process_RawGetExePath(&path, &len))) return res; + if ((res = File_Open(&file, &path))) return res; + + if (GetFileTime(file, NULL, NULL, &ft)) { + raw = ft.dwLowDateTime | ((cc_uint64)ft.dwHighDateTime << 32); + *timestamp = FileTime_UnixTime(raw); + } else { + res = GetLastError(); + } + + File_Close(file); + return res; +} + +/* Don't need special execute permission on windows */ +cc_result Updater_MarkExecutable(void) { return 0; } +cc_result Updater_SetNewBuildTime(cc_uint64 timestamp) { + static const cc_string path = String_FromConst(UPDATE_FILE); + cc_filepath str; + cc_file file; + FILETIME ft; + cc_uint64 raw; + cc_result res; + + Platform_EncodePath(&str, &path); + res = File_OpenOrCreate(&file, &str); + if (res) return res; + + raw = 10000000 * (timestamp + FILETIME_UNIX_EPOCH); + ft.dwLowDateTime = (cc_uint32)raw; + ft.dwHighDateTime = (cc_uint32)(raw >> 32); + + if (!SetFileTime(file, NULL, NULL, &ft)) res = GetLastError(); + File_Close(file); + return res; +} + + +/*########################################################################################################################* +*-------------------------------------------------------Dynamic lib-------------------------------------------------------* +*#########################################################################################################################*/ +const cc_string DynamicLib_Ext = String_FromConst(".dll"); +static cc_result dynamicErr; +static cc_bool loadingPlugin; + +void* DynamicLib_Load2(const cc_string* path) { + return NULL; +} + +void* DynamicLib_Get2(void* lib, const char* name) { + return NULL; +} + +cc_bool DynamicLib_DescribeError(cc_string* dst) { + return false; +} + + +/*########################################################################################################################* +*--------------------------------------------------------Platform---------------------------------------------------------* +*#########################################################################################################################*/ +void Platform_EncodeString(cc_winstring* dst, const cc_string* src) { + cc_unichar* uni; + char* ansi; + int i; + if (src->length > FILENAME_SIZE) Logger_Abort("String too long to expand"); + + uni = dst->uni; + for (i = 0; i < src->length; i++) + { + *uni++ = Convert_CP437ToUnicode(src->buffer[i]); + } + *uni = '\0'; + + ansi = dst->ansi; + for (i = 0; i < src->length; i++) + { + *ansi++ = (char)dst->uni[i]; + } + *ansi = '\0'; +} + +static void Platform_InitStopwatch(void) { + LARGE_INTEGER freq; + sw_highRes = QueryPerformanceFrequency(&freq); + + if (sw_highRes) { + sw_freqMul = 1000 * 1000; + sw_freqDiv = freq.QuadPart; + } else { sw_freqDiv = 10; } +} + +void Platform_Init(void) { + WSADATA wsaData; + cc_result res; + + Platform_InitStopwatch(); + heap = GetProcessHeap(); + + hasDebugger = IsDebuggerPresent(); + AttachConsole(-1); /* ATTACH_PARENT_PROCESS */ + + conHandle = GetStdHandle(STD_OUTPUT_HANDLE); + if (conHandle == INVALID_HANDLE_VALUE) conHandle = NULL; + + res = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (res) Logger_SysWarn(res, "starting WSA"); +} + +void Platform_Free(void) { + WSACleanup(); + HeapDestroy(heap); +} + +cc_bool Platform_DescribeError(cc_result res, cc_string* dst) { + WCHAR chars[NATIVE_STR_LEN]; + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; + + res = FormatMessageW(flags, NULL, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + chars, NATIVE_STR_LEN, NULL); + if (!res) return false; + + String_AppendUtf16(dst, chars, res * 2); + return true; +} + + +/*########################################################################################################################* +*-------------------------------------------------------Encryption--------------------------------------------------------* +*#########################################################################################################################*/ +cc_result Platform_Encrypt(const void* data, int len, cc_string* dst) { + return 200; +} + +cc_result Platform_Decrypt(const void* data, int len, cc_string* dst) { + return 200; +} + +cc_result Platform_GetEntropy(void* data, int len) { + return ERR_NOT_SUPPORTED; +} + + +/*########################################################################################################################* +*-----------------------------------------------------Configuration-------------------------------------------------------* +*#########################################################################################################################*/ +static cc_string Platform_NextArg(STRING_REF cc_string* args) { + cc_string arg; + int end; + + /* get rid of leading spaces before arg */ + while (args->length && args->buffer[0] == ' ') { + *args = String_UNSAFE_SubstringAt(args, 1); + } + + if (args->length && args->buffer[0] == '"') { + /* "xy za" is used for arg with spaces */ + *args = String_UNSAFE_SubstringAt(args, 1); + end = String_IndexOf(args, '"'); + } else { + end = String_IndexOf(args, ' '); + } + + if (end == -1) { + arg = *args; + args->length = 0; + } else { + arg = String_UNSAFE_Substring(args, 0, end); + *args = String_UNSAFE_SubstringAt(args, end + 1); + } + return arg; +} + +int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* args) { + cc_string cmdArgs = String_FromReadonly(GetCommandLineA()); + int i; + Platform_NextArg(&cmdArgs); /* skip exe path */ + if (gameHasArgs) return GetGameArgs(args); + + for (i = 0; i < GAME_MAX_CMDARGS; i++) + { + args[i] = Platform_NextArg(&cmdArgs); + + if (!args[i].length) break; + } + return i; +} + +cc_result Platform_SetDefaultCurrentDirectory(int argc, char** argv) { + return 0; +} diff --git a/misc/UWP/Source.cpp b/misc/UWP/Source.cpp deleted file mode 100644 index 0b700660a..000000000 --- a/misc/UWP/Source.cpp +++ /dev/null @@ -1,76 +0,0 @@ -using namespace Windows::ApplicationModel; -using namespace Windows::ApplicationModel::Core; -using namespace Windows::ApplicationModel::Activation; -using namespace Windows::Devices::Input; -using namespace Windows::Graphics::Display; -using namespace Windows::Foundation; -using namespace Windows::System; -using namespace Windows::UI::Core; -using namespace Windows::UI::Input; -using namespace Platform; - -void Launch_Browser(void) { - wchar_t* tmp = L"https://google.com"; - auto str = ref new String(tmp); - auto uri = ref new Uri(str); - - auto options = ref new Windows::System::LauncherOptions(); - options->TreatAsUntrusted = true; - Windows::System::Launcher::LaunchUriAsync(uri, options); -} - -void OpenFileDialog(void) { - auto picker = ref new Windows::Storage::Pickers::FileOpenPicker(); - picker->FileTypeFilter->Append(ref new String(L".jpg")); - picker->FileTypeFilter->Append(ref new String(L".jpeg")); - picker->FileTypeFilter->Append(ref new String(L".png")); - - //Windows::Storage::StorageFile file = picker->PickSingleFileAsync(); -} - -ref class CCApp sealed : IFrameworkView -{ -public: - virtual void Initialize(CoreApplicationView^ view) - { - } - - virtual void Load(String^ EntryPoint) - { - } - - virtual void Uninitialize() - { - } - - virtual void Run() - { - CoreWindow^ window = CoreWindow::GetForCurrentThread(); - window->Activate(); - Launch_Browser(); - - CoreDispatcher^ dispatcher = window->Dispatcher; - dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit); - } - - virtual void SetWindow(CoreWindow^ win) - { - } -}; - -ref class CCAppSource sealed : IFrameworkViewSource -{ -public: - virtual IFrameworkView^ CreateView() - { - return ref new CCApp(); - } -}; - -[MTAThread] -int main(Array^ args) -{ - //init_apartment(); - auto source = ref new CCAppSource(); - CoreApplication::Run(source); -} \ No newline at end of file diff --git a/misc/UWP/Window_UWP.cpp b/misc/UWP/Window_UWP.cpp new file mode 100644 index 000000000..ad7a9c9a6 --- /dev/null +++ b/misc/UWP/Window_UWP.cpp @@ -0,0 +1,247 @@ +#include "../../src/Core.h" +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Devices::Input; +using namespace Windows::Graphics::Display; +using namespace Windows::Foundation; +using namespace Windows::System; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; +using namespace Platform; + +#include "../../src/_WindowBase.h" +#include "../../src/String.h" +#include "../../src/Funcs.h" +#include "../../src/Bitmap.h" +#include "../../src/Options.h" +#include "../../src/Errors.h" + + +/*########################################################################################################################* +*--------------------------------------------------Public implementation--------------------------------------------------* +*#########################################################################################################################*/ +void Window_PreInit(void) { + DisplayInfo.CursorVisible = true; +} + +void Window_Init(void) { + Input.Sources = INPUT_SOURCE_NORMAL; + + DisplayInfo.Width = 640; + DisplayInfo.Height = 480; + DisplayInfo.Depth = 32; + DisplayInfo.ScaleX = 1.0f; + DisplayInfo.ScaleY = 1.0f; +} + +void Window_Free(void) { } + +void Window_Create2D(int width, int height) { } +void Window_Create3D(int width, int height) { } + +void Window_Destroy(void) { +} + +void Window_SetTitle(const cc_string* title) { +} + +void Clipboard_GetText(cc_string* value) { +} + +void Clipboard_SetText(const cc_string* value) { +} + +int Window_GetWindowState(void) { + return WINDOW_STATE_NORMAL; +} + +cc_result Window_EnterFullscreen(void) { + return ERR_NOT_SUPPORTED; +} + +cc_result Window_ExitFullscreen(void) { + return ERR_NOT_SUPPORTED; +} + +int Window_IsObscured(void) { return 0; } + +void Window_Show(void) { +} + +void Window_SetSize(int width, int height) { +} + +void Window_RequestClose(void) { + Event_RaiseVoid(&WindowEvents.Closing); +} + +void Window_ProcessEvents(float delta) { +} + +void Gamepads_Init(void) { + +} + +void Gamepads_Process(float delta) { } + +static void Cursor_GetRawPos(int* x, int* y) { + *x = 0; + *y = 0; +} + +void Cursor_SetPosition(int x, int y) { +} + +static void Cursor_DoSetVisible(cc_bool visible) { +} + +static void ShowDialogCore(const char* title, const char* msg) { +} + +static cc_result OpenSaveFileDialog(const cc_string* filters, FileDialogCallback callback, cc_bool load, + const char* const* fileExts, const cc_string* defaultName) { + return ERR_NOT_SUPPORTED; +} + +cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) { + const char* const* fileExts = args->filters; + cc_string filters; char buffer[NATIVE_STR_LEN]; + int i; + + /* Filter tokens are \0 separated - e.g. "Maps (*.cw;*.dat)\0*.cw;*.dat\0 */ + String_InitArray(filters, buffer); + String_Format1(&filters, "%c (", args->description); + for (i = 0; fileExts[i]; i++) + { + if (i) String_Append(&filters, ';'); + String_Format1(&filters, "*%c", fileExts[i]); + } + String_Append(&filters, ')'); + String_Append(&filters, '\0'); + + for (i = 0; fileExts[i]; i++) + { + if (i) String_Append(&filters, ';'); + String_Format1(&filters, "*%c", fileExts[i]); + } + String_Append(&filters, '\0'); + + return OpenSaveFileDialog(&filters, args->Callback, true, fileExts, &String_Empty); +} + +cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) { + const char* const* titles = args->titles; + const char* const* fileExts = args->filters; + cc_string filters; char buffer[NATIVE_STR_LEN]; + int i; + + /* Filter tokens are \0 separated - e.g. "Map (*.cw)\0*.cw\0 */ + String_InitArray(filters, buffer); + for (i = 0; fileExts[i]; i++) + { + String_Format2(&filters, "%c (*%c)", titles[i], fileExts[i]); + String_Append(&filters, '\0'); + String_Format1(&filters, "*%c", fileExts[i]); + String_Append(&filters, '\0'); + } + return OpenSaveFileDialog(&filters, args->Callback, false, fileExts, &args->defaultName); +} + +void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) { + bmp->scan0 = (BitmapCol*)Mem_Alloc(width * height, BITMAPCOLOR_SIZE, "bitmap"); + bmp->width = width; + bmp->height = height; +} + +void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) { +} + +void Window_FreeFramebuffer(struct Bitmap* bmp) { + Mem_Free(bmp->scan0); +} + +static cc_bool rawMouseInited, rawMouseSupported; +static void InitRawMouse(void) { + +} + +void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) { } +void OnscreenKeyboard_SetText(const cc_string* text) { } +void OnscreenKeyboard_Close(void) { } + +void Window_EnableRawMouse(void) { + DefaultEnableRawMouse(); + if (!rawMouseInited) InitRawMouse(); + + rawMouseInited = true; +} + +void Window_UpdateRawMouse(void) { + if (rawMouseSupported) { + /* handled in WM_INPUT messages */ + CentreMousePosition(); + } else { + DefaultUpdateRawMouse(); + } +} + +void Window_DisableRawMouse(void) { + DefaultDisableRawMouse(); +} + + +void OpenFileDialog(void) { + auto picker = ref new Windows::Storage::Pickers::FileOpenPicker(); + picker->FileTypeFilter->Append(ref new String(L".jpg")); + picker->FileTypeFilter->Append(ref new String(L".jpeg")); + picker->FileTypeFilter->Append(ref new String(L".png")); + + //Windows::Storage::StorageFile file = picker->PickSingleFileAsync(); +} + +ref class CCApp sealed : IFrameworkView +{ +public: + virtual void Initialize(CoreApplicationView^ view) + { + } + + virtual void Load(String^ EntryPoint) + { + } + + virtual void Uninitialize() + { + } + + virtual void Run() + { + CoreWindow^ window = CoreWindow::GetForCurrentThread(); + window->Activate(); + + CoreDispatcher^ dispatcher = window->Dispatcher; + dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit); + } + + virtual void SetWindow(CoreWindow^ win) + { + } +}; + +ref class CCAppSource sealed : IFrameworkViewSource +{ +public: + virtual IFrameworkView^ CreateView() + { + return ref new CCApp(); + } +}; + +[MTAThread] +int main(Array^ args) +{ + //init_apartment(); + auto source = ref new CCAppSource(); + CoreApplication::Run(source); +} \ No newline at end of file diff --git a/src/Chat.c b/src/Chat.c index 0c0f7236d..83227f5f5 100644 --- a/src/Chat.c +++ b/src/Chat.c @@ -121,7 +121,7 @@ static cc_bool CreateLogsDirectory(void) { return false; } -static void OpenChatLog(struct DateTime* now) { +static void OpenChatLog(struct cc_datetime* now) { cc_result res; int i; if (Platform_ReadonlyFilesystem || !CreateLogsDirectory()) return; @@ -154,7 +154,7 @@ static void OpenChatLog(struct DateTime* now) { static void AppendChatLog(const cc_string* text) { cc_string str; char strBuffer[DRAWER2D_MAX_TEXT_LENGTH]; - struct DateTime now; + struct cc_datetime now; cc_result res; if (!logName.length || !Chat_Logging) return; diff --git a/src/Core.h b/src/Core.h index 06cd51d54..cffa41cd2 100644 --- a/src/Core.h +++ b/src/Core.h @@ -183,6 +183,14 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_NOSOUNDS #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN #define DEFAULT_SSL_BACKEND CC_SSL_BACKEND_BEARSSL +#elif defined __WRL_NO_DEFAULT_LIB__ + #undef CC_BUILD_FREETYPE + #define CC_BUILD_WIN + #define CC_BUILD_UWP + #define CC_BUILD_NOMUSIC + #define CC_BUILD_NOSOUNDS + #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN + #define DEFAULT_GFX_BACKEND CC_GFX_BACKEND_SOFTGPU #elif defined _WIN32 #define CC_BUILD_WIN #define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN diff --git a/src/Game.c b/src/Game.c index 7e0cceb66..028f7e668 100644 --- a/src/Game.c +++ b/src/Game.c @@ -586,7 +586,7 @@ static void PerformScheduledTasks(double time) { void Game_TakeScreenshot(void) { cc_string filename; char fileBuffer[STRING_SIZE]; cc_string path; char pathBuffer[FILENAME_SIZE]; - struct DateTime now; + struct cc_datetime now; cc_result res; #ifdef CC_BUILD_WEB cc_filepath str; diff --git a/src/LScreens.c b/src/LScreens.c index d963dafe6..d8041a1f4 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -1659,11 +1659,10 @@ static void UpdatesScreen_FormatBoth(struct UpdatesScreen* s) { } static void UpdatesScreen_UpdateHeader(struct UpdatesScreen* s, cc_string* str) { - const char* message; - if ( s->release) message = "&eFetching latest release "; - if (!s->release) message = "&eFetching latest dev build "; + const char* message = s->release ? "release " : "dev build "; - String_Format2(str, "%c%c", message, Updater_Info.builds[s->buildIndex].name); + String_Format2(str, "&eFetching latest %c%c", + message, Updater_Info.builds[s->buildIndex].name); } static void UpdatesScreen_DoFetch(struct UpdatesScreen* s) { diff --git a/src/Logger.c b/src/Logger.c index f76042d2d..9231c270c 100644 --- a/src/Logger.c +++ b/src/Logger.c @@ -18,11 +18,15 @@ #include #include + #ifndef CC_BUILD_UWP /* Compatibility version so compiling works on older Windows SDKs */ #include "../misc/windows/min-imagehlp.h" #define CC_KERN32_FUNC extern /* main use is Platform_Windows.c */ #include "../misc/windows/min-kernel32.h" + #endif + static HANDLE curProcess = CUR_PROCESS_HANDLE; + static cc_uintptr spRegister; #elif defined CC_BUILD_OPENBSD || defined CC_BUILD_HAIKU || defined CC_BUILD_SERENITY #include /* These operating systems don't provide sys/ucontext.h */ @@ -205,7 +209,12 @@ static void PrintFrame(cc_string* str, cc_uintptr addr, cc_uintptr symAddr, cons } } -#if defined CC_BUILD_WIN +#if defined CC_BUILD_UWP +static void DumpFrame(cc_string* trace, void* addr) { + cc_uintptr addr_ = (cc_uintptr)addr; + String_Format1(trace, "%x", &addr_); +} +#elif defined CC_BUILD_WIN struct SymbolAndName { IMAGEHLP_SYMBOL symbol; char name[256]; }; static void DumpFrame(HANDLE process, cc_string* trace, cc_uintptr addr) { @@ -291,7 +300,11 @@ static void DumpFrame(cc_string* trace, void* addr) { /*########################################################################################################################* *-------------------------------------------------------Backtracing-------------------------------------------------------* *#########################################################################################################################*/ -#if defined CC_BUILD_WIN +#if defined CC_BUILD_UWP +void Logger_Backtrace(cc_string* trace, void* ctx) { + String_AppendConst(trace, "-- backtrace unimplemented --"); +} +#elif defined CC_BUILD_WIN static PVOID WINAPI FunctionTableAccessCallback(HANDLE process, _DWORD_PTR addr) { if (!_SymFunctionTableAccess) return NULL; @@ -316,7 +329,6 @@ static BOOL WINAPI ReadMemCallback(HANDLE process, _DWORD_PTR baseAddress, PVOID *numBytesRead = (DWORD)numRead; /* DWORD always 32 bits */ return ok; } -static cc_uintptr spRegister; static int GetFrames(CONTEXT* ctx, cc_uintptr* addrs, int max) { STACKFRAME frame = { 0 }; @@ -923,7 +935,10 @@ static void DumpRegisters(void* ctx) { /*########################################################################################################################* *------------------------------------------------Module/Memory map handling-----------------------------------------------* *#########################################################################################################################*/ -#if defined CC_BUILD_WIN +#if defined CC_BUILD_UWP +static void DumpMisc(void) { } + +#elif defined CC_BUILD_WIN static void DumpStack(void) { static const cc_string stack = String_FromConst("-- stack --\r\n"); cc_string str; char strBuffer[128]; @@ -1121,6 +1136,7 @@ static LONG WINAPI UnhandledFilter(struct _EXCEPTION_POINTERS* info) { void Logger_Hook(void) { OSVERSIONINFOA osInfo; SetUnhandledExceptionFilter(UnhandledFilter); +#if !defined CC_BUILD_UWP ImageHlp_LoadDynamicFuncs(); /* Windows 9x requires process IDs instead - see old DBGHELP docs */ @@ -1132,6 +1148,7 @@ void Logger_Hook(void) { if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { curProcess = (HANDLE)((cc_uintptr)GetCurrentProcessId()); } +#endif } #elif defined CC_BUILD_POSIX static const char* SignalDescribe(int type) { @@ -1200,7 +1217,11 @@ void Logger_Hook(void) { /*########################################################################################################################* *-------------------------------------------------Deliberate crash logging------------------------------------------------* *#########################################################################################################################*/ -#if defined CC_BUILD_WIN +#if defined CC_BUILD_UWP +void Logger_Abort2(cc_result result, const char* raw_msg) { + AbortCommon(result, raw_msg, NULL); +} +#elif defined CC_BUILD_WIN #if __GNUC__ /* Don't want compiler doing anything fancy with registers */ void __attribute__((optimize("O0"))) Logger_Abort2(cc_result result, const char* raw_msg) { @@ -1270,7 +1291,7 @@ void Logger_Log(const cc_string* msg) { static void LogCrashHeader(void) { cc_string msg; char msgBuffer[96]; - struct DateTime now; + struct cc_datetime now; String_InitArray(msg, msgBuffer); String_AppendConst(&msg, _NL "----------------------------------------" _NL); diff --git a/src/Platform.h b/src/Platform.h index 97d4fafcf..c435ec0d5 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -19,15 +19,14 @@ Copyright 2014-2023 ClassiCube | Licensed under BSD-3 /* Suffix added to app name sent to the server */ extern const char* Platform_AppNameSuffix; -#ifdef CC_BUILD_WIN +#if defined CC_BUILD_WIN typedef struct cc_winstring_ { cc_unichar uni[NATIVE_STR_LEN]; /* String represented using UTF16 format */ char ansi[NATIVE_STR_LEN]; /* String lossily represented using ANSI format */ } cc_winstring; + /* Encodes a string into the platform native string format */ void Platform_EncodeString(cc_winstring* dst, const cc_string* src); - -cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, void* lib); #endif #ifdef CC_BUILD_WIN @@ -200,12 +199,12 @@ cc_bool Platform_DescribeError(cc_result res, cc_string* dst); *#########################################################################################################################*/ /* Number of seconds since 01/01/0001 to start of unix time. */ #define UNIX_EPOCH_SECONDS 62135596800ULL -struct DateTime; +struct cc_datetime; /* Returns the current UTC time, as number of seconds since 1/1/0001 */ CC_API TimeMS DateTime_CurrentUTC(void); /* Returns the current local Time. */ -CC_API void DateTime_CurrentLocal(struct DateTime* t); +CC_API void DateTime_CurrentLocal(struct cc_datetime* t); /* Takes a platform-specific stopwatch measurement. */ /* NOTE: The value returned is platform-specific - do NOT try to interpret the value. */ CC_API cc_uint64 Stopwatch_Measure(void); diff --git a/src/Platform_32x.c b/src/Platform_32x.c index d18eb4d4d..f14d8cfda 100644 --- a/src/Platform_32x.c +++ b/src/Platform_32x.c @@ -77,8 +77,8 @@ TimeMS DateTime_CurrentUTC(void) { return 0; } -void DateTime_CurrentLocal(struct DateTime* t) { - Mem_Set(t, 0, sizeof(struct DateTime)); +void DateTime_CurrentLocal(struct cc_datetime* t) { + Mem_Set(t, 0, sizeof(struct cc_datetime)); } diff --git a/src/Platform_3DS.c b/src/Platform_3DS.c index 9a2e9b844..f5e31d337 100644 --- a/src/Platform_3DS.c +++ b/src/Platform_3DS.c @@ -61,7 +61,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct timeval cur; struct tm loc_time; gettimeofday(&cur, NULL); diff --git a/src/Platform_Dreamcast.c b/src/Platform_Dreamcast.c index e7fcd2c8c..be3ffab8d 100644 --- a/src/Platform_Dreamcast.c +++ b/src/Platform_Dreamcast.c @@ -99,7 +99,7 @@ TimeMS DateTime_CurrentUTC(void) { return curSecs + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { uint32 secs, ms; time_t total_secs; struct tm loc_time; diff --git a/src/Platform_GCWii.c b/src/Platform_GCWii.c index 359895e9f..9af8d0560 100644 --- a/src/Platform_GCWii.c +++ b/src/Platform_GCWii.c @@ -85,7 +85,7 @@ TimeMS DateTime_CurrentUTC(void) { return secs + UNIX_EPOCH_SECONDS + GCWII_EPOCH_ADJUST; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct timeval cur; struct tm loc_time; gettimeofday(&cur, NULL); diff --git a/src/Platform_MSDOS.c b/src/Platform_MSDOS.c index 6b699a726..4a77f9bb4 100644 --- a/src/Platform_MSDOS.c +++ b/src/Platform_MSDOS.c @@ -79,7 +79,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct timeval cur; struct tm loc_time; gettimeofday(&cur, NULL); diff --git a/src/Platform_MacClassic.c b/src/Platform_MacClassic.c index ba05f1bb2..39497435f 100644 --- a/src/Platform_MacClassic.c +++ b/src/Platform_MacClassic.c @@ -125,7 +125,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)secs + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct tm loc_time; time_t secs = gettod(); localtime_r(&secs, &loc_time); diff --git a/src/Platform_N64.c b/src/Platform_N64.c index 81342a693..e103be75d 100644 --- a/src/Platform_N64.c +++ b/src/Platform_N64.c @@ -55,7 +55,7 @@ TimeMS DateTime_CurrentUTC(void) { return 0; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { rtc_time_t curTime = { 0 }; rtc_get(&curTime); diff --git a/src/Platform_NDS.c b/src/Platform_NDS.c index 736d8ca6c..f8f24f286 100644 --- a/src/Platform_NDS.c +++ b/src/Platform_NDS.c @@ -95,7 +95,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct timeval cur; struct tm loc_time; gettimeofday(&cur, NULL); diff --git a/src/Platform_PS1.c b/src/Platform_PS1.c index c117d0f6b..a749fda08 100644 --- a/src/Platform_PS1.c +++ b/src/Platform_PS1.c @@ -54,8 +54,8 @@ TimeMS DateTime_CurrentUTC(void) { return 0; } -void DateTime_CurrentLocal(struct DateTime* t) { - Mem_Set(t, 0, sizeof(struct DateTime)); +void DateTime_CurrentLocal(struct cc_datetime* t) { + Mem_Set(t, 0, sizeof(struct cc_datetime)); } diff --git a/src/Platform_PS2.c b/src/Platform_PS2.c index b98420651..fe5b3df1e 100644 --- a/src/Platform_PS2.c +++ b/src/Platform_PS2.c @@ -100,7 +100,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)rtc_sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { time_t rtc_sec = CurrentUnixTime(); struct tm loc_time; localtime_r(&rtc_sec, &loc_time); diff --git a/src/Platform_PS3.c b/src/Platform_PS3.c index 23826e877..d8aaa0f8c 100644 --- a/src/Platform_PS3.c +++ b/src/Platform_PS3.c @@ -60,7 +60,7 @@ TimeMS DateTime_CurrentUTC(void) { return sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct timeval cur; struct tm loc_time; gettimeofday(&cur, NULL); diff --git a/src/Platform_PSP.c b/src/Platform_PSP.c index caf572106..74179e22d 100644 --- a/src/Platform_PSP.c +++ b/src/Platform_PSP.c @@ -63,7 +63,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { ScePspDateTime curTime; sceRtcGetCurrentClockLocalTime(&curTime); diff --git a/src/Platform_PSVita.c b/src/Platform_PSVita.c index 28f668898..4d4d51da0 100644 --- a/src/Platform_PSVita.c +++ b/src/Platform_PSVita.c @@ -46,7 +46,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { SceDateTime curTime; sceRtcGetCurrentClockLocalTime(&curTime); diff --git a/src/Platform_Posix.c b/src/Platform_Posix.c index fa7b6b3f3..8907ae1c2 100644 --- a/src/Platform_Posix.c +++ b/src/Platform_Posix.c @@ -121,7 +121,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct timeval cur; struct tm loc_time; gettimeofday(&cur, NULL); diff --git a/src/Platform_Saturn.c b/src/Platform_Saturn.c index 48609dd4a..a90960e3f 100644 --- a/src/Platform_Saturn.c +++ b/src/Platform_Saturn.c @@ -84,8 +84,8 @@ TimeMS DateTime_CurrentUTC(void) { return 0; } -void DateTime_CurrentLocal(struct DateTime* t) { - Mem_Set(t, 0, sizeof(struct DateTime)); +void DateTime_CurrentLocal(struct cc_datetime* t) { + Mem_Set(t, 0, sizeof(struct cc_datetime)); } diff --git a/src/Platform_Switch.c b/src/Platform_Switch.c index e20cacb1b..30ec8167b 100644 --- a/src/Platform_Switch.c +++ b/src/Platform_Switch.c @@ -92,7 +92,7 @@ TimeMS DateTime_CurrentUTC(void) { return timestamp + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { u64 timestamp = 0; TimeCalendarTime calTime = { 0 }; timeGetCurrentTime(TimeType_Default, ×tamp); diff --git a/src/Platform_Web.c b/src/Platform_Web.c index 46a96f7e0..430b63f64 100644 --- a/src/Platform_Web.c +++ b/src/Platform_Web.c @@ -93,8 +93,8 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; } -extern void interop_GetLocalTime(struct DateTime* t); -void DateTime_CurrentLocal(struct DateTime* t) { +extern void interop_GetLocalTime(struct cc_datetime* t); +void DateTime_CurrentLocal(struct cc_datetime* t) { interop_GetLocalTime(t); } diff --git a/src/Platform_WiiU.c b/src/Platform_WiiU.c index 4175c7730..eb8a2b57e 100644 --- a/src/Platform_WiiU.c +++ b/src/Platform_WiiU.c @@ -68,7 +68,7 @@ TimeMS DateTime_CurrentUTC(void) { return secs + UNIX_EPOCH_SECONDS + WIIU_EPOCH_ADJUST; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct OSCalendarTime loc_time; OSTicksToCalendarTime(OSGetTime(), &loc_time); diff --git a/src/Platform_Windows.c b/src/Platform_Windows.c index c20f045e5..318c44ae5 100644 --- a/src/Platform_Windows.c +++ b/src/Platform_Windows.c @@ -147,7 +147,7 @@ TimeMS DateTime_CurrentUTC(void) { return FileTime_TotalSecs(raw); } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { SYSTEMTIME localTime; GetLocalTime(&localTime); @@ -943,12 +943,11 @@ void Platform_Free(void) { HeapDestroy(heap); } -cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, void* lib) { +cc_bool Platform_DescribeError(cc_result res, cc_string* dst) { WCHAR chars[NATIVE_STR_LEN]; DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; - if (lib) flags |= FORMAT_MESSAGE_FROM_HMODULE; - res = FormatMessageW(flags, lib, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + res = FormatMessageW(flags, NULL, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), chars, NATIVE_STR_LEN, NULL); if (!res) return false; @@ -956,10 +955,6 @@ cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, void* lib) { return true; } -cc_bool Platform_DescribeError(cc_result res, cc_string* dst) { - return Platform_DescribeErrorExt(res, dst, NULL); -} - /*########################################################################################################################* *-------------------------------------------------------Encryption--------------------------------------------------------* diff --git a/src/Platform_Xbox.c b/src/Platform_Xbox.c index 92470dd32..d064ce2db 100644 --- a/src/Platform_Xbox.c +++ b/src/Platform_Xbox.c @@ -54,7 +54,7 @@ TimeMS DateTime_CurrentUTC(void) { return FileTime_TotalSecs(ft.QuadPart); } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { SYSTEMTIME localTime; GetLocalTime(&localTime); diff --git a/src/Platform_Xbox360.c b/src/Platform_Xbox360.c index f669840a8..bbcf97ece 100644 --- a/src/Platform_Xbox360.c +++ b/src/Platform_Xbox360.c @@ -52,7 +52,7 @@ TimeMS DateTime_CurrentUTC(void) { return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; } -void DateTime_CurrentLocal(struct DateTime* t) { +void DateTime_CurrentLocal(struct cc_datetime* t) { struct timeval cur; struct tm loc_time; gettimeofday(&cur, NULL); diff --git a/src/Resources.c b/src/Resources.c index b176587d5..b434abf85 100644 --- a/src/Resources.c +++ b/src/Resources.c @@ -92,7 +92,7 @@ static cc_result ZipEntry_ExtractData(struct ResourceZipEntry* e, struct Stream* *------------------------------------------------------Zip entry writer---------------------------------------------------* *#########################################################################################################################*/ static void GetCurrentZipDate(int* modTime, int* modDate) { - struct DateTime now; + struct cc_datetime now; DateTime_CurrentLocal(&now); *modTime = (now.second / 2) | (now.minute << 5) | (now.hour << 11); diff --git a/src/Utils.h b/src/Utils.h index c50696d42..8127a1308 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -13,7 +13,7 @@ struct StringsBuffer; /* Represents a particular instance in time in some timezone. Not necessarily UTC time. */ /* NOTE: TimeMS and DateTime_CurrentUTC() should almost always be used instead. */ /* This struct should only be used when actually needed. (e.g. log message time) */ -struct DateTime { +struct cc_datetime { int year; /* Year, ranges from 0 to 65535 */ int month; /* Month, ranges from 1 to 12 */ int day; /* Day, ranges from 1 to 31 */