diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e890bce..2d19f32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,8 +32,8 @@ jobs: shell: bash run: | mv build_debug/wibo build/wibo_debug - wget -q https://cdn.discordapp.com/attachments/727918646525165659/1129759991696457728/GC_WII_COMPILERS.zip - unzip -q GC_WII_COMPILERS.zip + wget -q https://files.decomp.dev/compilers_latest.zip + unzip -q compilers_latest.zip set -x build/wibo_debug Wii/1.7/mwcceppc.exe -nodefaults -c test/test.c -Itest -o test_debug.o file test_debug.o diff --git a/LICENSE b/LICENSE index 366edae..b51b1a5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Ash Wolf +Copyright (c) 2022-2024 Ash Wolf & Decompals Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index aa37e0a..17bcd46 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -119,6 +119,7 @@ namespace kernel32 { } uint32_t WIN_FUNC GetLastError() { + DEBUG_LOG("GetLastError() -> %u\n", wibo::lastError); return wibo::lastError; } @@ -225,6 +226,20 @@ namespace kernel32 { // to prevent from doubling up on the target executable name // (it appears as lpApplicationName, and as the first token in lpCommandLine) arg = strtok(NULL, " "); + + if (arg) { + // Trim all quotation marks from the start and the end of the string + while(*arg == '\"') { + arg++; + } + + char* end = arg + strlen(arg) - 1; + while(end > arg && *end == '\"') { + *end = '\0'; + end--; + } + } + argv[current_arg_index++] = arg; } @@ -276,6 +291,7 @@ namespace kernel32 { } int WIN_FUNC GetSystemDefaultLangID() { + DEBUG_LOG("STUB GetSystemDefaultLangID\n"); return 0; } @@ -679,14 +695,21 @@ namespace kernel32 { std::string pattern; }; - bool findNextFile(FindFirstFileHandle *handle) { + bool findNextFile(FindFirstFileHandle* handle) { + // Check if iterator is valid before using it + if (!handle || handle->it == std::filesystem::directory_iterator()) { + return false; + } + + // Look for a matching file with the pattern while (handle->it != std::filesystem::directory_iterator()) { std::filesystem::path path = *handle->it; - if (fnmatch(handle->pattern.c_str(), path.filename().c_str(), 0) == 0) { + if (!handle->pattern.empty() && fnmatch(handle->pattern.c_str(), path.filename().c_str(), 0) == 0) { return true; } handle->it++; } + return false; } @@ -724,15 +747,20 @@ namespace kernel32 { return (void *) 1; } - auto *handle = new FindFirstFileHandle(); + // If the parent path is empty then we assume the parent path is the current directory. + auto parent_path = path.parent_path(); + if (parent_path == "") { + parent_path = "."; + } - if (!std::filesystem::exists(path.parent_path())) { + if (!std::filesystem::exists(parent_path)) { wibo::lastError = ERROR_PATH_NOT_FOUND; - delete handle; return INVALID_HANDLE_VALUE; } - std::filesystem::directory_iterator it(path.parent_path()); + auto *handle = new FindFirstFileHandle(); + + std::filesystem::directory_iterator it(parent_path); handle->it = it; handle->pattern = path.filename().string(); @@ -769,6 +797,7 @@ namespace kernel32 { } int WIN_FUNC FindNextFileA(void *hFindFile, WIN32_FIND_DATA *lpFindFileData) { + DEBUG_LOG("FindNextFileA(%p, %p)\n", hFindFile, lpFindFileData); // Special value from FindFirstFileA if (hFindFile == (void *) 1) { wibo::lastError = ERROR_NO_MORE_FILES; @@ -1128,19 +1157,36 @@ namespace kernel32 { void WIN_FUNC GetSystemTime(SYSTEMTIME *lpSystemTime) { DEBUG_LOG("GetSystemTime\n"); - lpSystemTime->wYear = 0; - lpSystemTime->wMonth = 0; - lpSystemTime->wDayOfWeek = 0; - lpSystemTime->wDay = 0; - lpSystemTime->wHour = 0; - lpSystemTime->wMinute = 0; - lpSystemTime->wSecond = 0; + + time_t t = time(NULL); + struct tm *tm = gmtime(&t); + assert(tm != NULL); + + lpSystemTime->wYear = tm->tm_year + 1900; + lpSystemTime->wMonth = tm->tm_mon + 1; + lpSystemTime->wDayOfWeek = tm->tm_wday; + lpSystemTime->wDay = tm->tm_mday; + lpSystemTime->wHour = tm->tm_hour; + lpSystemTime->wMinute = tm->tm_min; + lpSystemTime->wSecond = tm->tm_sec; lpSystemTime->wMilliseconds = 0; } void WIN_FUNC GetLocalTime(SYSTEMTIME *lpSystemTime) { DEBUG_LOG("GetLocalTime\n"); - GetSystemTime(lpSystemTime); + + time_t t = time(NULL); + struct tm *tm = localtime(&t); + assert(tm != NULL); + + lpSystemTime->wYear = tm->tm_year + 1900; + lpSystemTime->wMonth = tm->tm_mon + 1; + lpSystemTime->wDayOfWeek = tm->tm_wday; + lpSystemTime->wDay = tm->tm_mday; + lpSystemTime->wHour = tm->tm_hour; + lpSystemTime->wMinute = tm->tm_min; + lpSystemTime->wSecond = tm->tm_sec; + lpSystemTime->wMilliseconds = 0; } int WIN_FUNC SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, FILETIME *lpFileTime) { @@ -1257,7 +1303,7 @@ namespace kernel32 { } unsigned int WIN_FUNC SetConsoleCtrlHandler(void *HandlerRoutine, unsigned int Add) { - DEBUG_LOG("SetConsoleCtrlHandler\n"); + DEBUG_LOG("STUB SetConsoleCtrlHandler\n"); // This is a function that gets called when doing ^C // We might want to call this later (being mindful that it'll be stdcall I think) @@ -1280,6 +1326,7 @@ namespace kernel32 { }; unsigned int WIN_FUNC GetConsoleScreenBufferInfo(void *hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO *lpConsoleScreenBufferInfo) { + DEBUG_LOG("GetConsoleScreenBufferInfo(%p, %p)\n", hConsoleOutput, lpConsoleScreenBufferInfo); // Tell a lie // mwcc doesn't care about anything else lpConsoleScreenBufferInfo->dwSize_x = 80; @@ -1346,7 +1393,7 @@ namespace kernel32 { } unsigned int WIN_FUNC GetCurrentDirectoryA(unsigned int uSize, char *lpBuffer) { - DEBUG_LOG("GetCurrentDirectoryA(%u, %p)\n", uSize, lpBuffer); + DEBUG_LOG("GetCurrentDirectoryA(%u, %p)", uSize, lpBuffer); std::filesystem::path cwd = std::filesystem::current_path(); std::string path = files::pathToWindows(cwd); @@ -1354,9 +1401,11 @@ namespace kernel32 { // If the buffer is too small, return the required buffer size. // (Add 1 to include the NUL terminator) if (path.size() + 1 > uSize) { + DEBUG_LOG(" !! Buffer too small: %i, %i\n", path.size() + 1, uSize); return path.size() + 1; } + DEBUG_LOG(" -> %s\n", path.c_str()); strcpy(lpBuffer, path.c_str()); return path.size(); } @@ -1764,6 +1813,7 @@ namespace kernel32 { return 1; // sure.. we have that feature... + DEBUG_LOG(" IsProcessorFeaturePresent: we don't know about feature %u, lying...\n", processorFeature); return 1; } @@ -1912,7 +1962,39 @@ namespace kernel32 { if (LCType == 4098) { // LOCALE_SENGCOUNTRY return "Country"; } - assert(false); + if (LCType == 0x1) { // LOCALE_ILANGUAGE + return "0001"; + } + if (LCType == 0x15) { // LOCALE_SINTLSYMBOL + return "Currency"; + } + if (LCType == 0x14) { // LOCALE_SCURRENCY + return "sCurrency"; + } + if (LCType == 0x16) { // LOCALE_SMONDECIMALSEP + return "."; + } + if (LCType == 0x17) { // LOCALE_SMONTHOUSANDSEP + return ","; + } + if (LCType == 0x18) { // LOCALE_SMONGROUPING + return ";"; + } + if (LCType == 0x50) { // LOCALE_SPOSITIVESIGN + return ""; + } + if (LCType == 0x51) { // LOCALE_SNEGATIVESIGN + return "-"; + } + if (LCType == 0x1A) { // LOCALE_IINTLCURRDIGITS + return "2"; + } + if (LCType == 0x19) { // LOCALE_ICURRDIGITS + return "2"; + } + + DEBUG_LOG("STUB: LCType 0x%X not implemented\n", LCType); + return ""; } int WIN_FUNC GetLocaleInfoA(unsigned int Locale, int LCType, LPSTR lpLCData, int cchData) { diff --git a/files.cpp b/files.cpp index a684ae3..2701d30 100644 --- a/files.cpp +++ b/files.cpp @@ -32,7 +32,6 @@ namespace files { return path; } - path = path.lexically_normal(); std::filesystem::path newPath = "."; bool followingExisting = true; for (const auto& component : path) {