diff --git a/src/Formats.c b/src/Formats.c index 451cbbc4b..4f82c1f28 100644 --- a/src/Formats.c +++ b/src/Formats.c @@ -329,7 +329,7 @@ static ReturnCode Nbt_ReadString(struct Stream* stream, String* str) { if (len > Array_Elems(buffer)) return CW_ERR_STRING_LEN; if ((res = Stream_Read(stream, buffer, len))) return res; - String_DecodeUtf8(str, buffer, len); + Convert_DecodeUtf8(str, buffer, len); return 0; } diff --git a/src/LScreens.c b/src/LScreens.c index 9451d9b13..9d2bf20bd 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -1445,7 +1445,7 @@ static void UpdatesScreen_DevD3D9(void* w, int x, int y) { UpdatesScreen_Get(f static void UpdatesScreen_DevOpenGL(void* w, int x, int y) { UpdatesScreen_Get(false, false); } static void UpdatesScreen_Init(struct LScreen* s_) { - const static String exeName = String_FromConst(GAME_EXE_NAME); + String path; char pathBuffer[FILENAME_SIZE]; struct UpdatesScreen* s = (struct UpdatesScreen*)s_; TimeMS buildTime; ReturnCode res; @@ -1477,13 +1477,15 @@ static void UpdatesScreen_Init(struct LScreen* s_) { UpdatesScreen_FormatBoth(s); } CheckUpdateTask_Run(); + + String_InitArray(path, pathBuffer); + res = Platform_GetExePath(&path); + if (res) { Logger_Warn(res, "getting .exe path"); return; } - res = File_GetModifiedTime(&exeName, &buildTime); - if (res) { - Logger_Warn(res, "getting build time"); - } else { - UpdatesScreen_Format(&s->LblYour, "Your build: ", buildTime); - } + res = File_GetModifiedTime(&path, &buildTime); + if (res) { Logger_Warn(res, "getting build time"); return; } + + UpdatesScreen_Format(&s->LblYour, "Your build: ", buildTime); } static void UpdatesScreen_Reposition(struct LScreen* s_) { diff --git a/src/Launcher.c b/src/Launcher.c index 2441eedb6..b5efa2fc9 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -514,7 +514,7 @@ void Launcher_MarkAllDirty(void) { *#########################################################################################################################*/ static TimeMS lastJoin; bool Launcher_StartGame(const String* user, const String* mppass, const String* ip, const String* port, const String* server) { - const static String exe = String_FromConst(GAME_EXE_NAME); + String path; char pathBuffer[FILENAME_SIZE]; String args; char argsBuffer[512]; TimeMS now; ReturnCode res; @@ -525,7 +525,6 @@ bool Launcher_StartGame(const String* user, const String* mppass, const String* /* Make sure if the client has changed some settings in the meantime, we keep the changes */ Options_Load(); - Launcher_ShouldExit = Options_GetBool(OPT_AUTO_CLOSE_LAUNCHER, false); /* Save resume info */ if (server->length) { @@ -537,22 +536,23 @@ bool Launcher_StartGame(const String* user, const String* mppass, const String* Options_Save(); } + String_InitArray(path, pathBuffer); + res = Platform_GetExePath(&path); + if (res) { Logger_Warn(res, "getting .exe path"); return false; } + String_InitArray(args, argsBuffer); String_AppendString(&args, user); if (mppass->length) String_Format3(&args, " %s %s %s", mppass, ip, port); - res = Platform_StartProcess(&exe, &args); + res = Platform_StartProcess(&path, &args); #ifdef CC_BUILD_WINDOWS /* TODO: Check this*/ /* HRESULT when user clicks 'cancel' to 'are you sure you want to run ClassiCube.exe' */ if (res == 0x80004005) return; #endif + if (res) { Logger_Warn(res, "starting game"); return false; } - if (res) { - Logger_Warn(res, "starting game"); - Launcher_ShouldExit = false; - return false; - } + Launcher_ShouldExit = Options_GetBool(OPT_AUTO_CLOSE_LAUNCHER, false); return true; } diff --git a/src/Launcher.h b/src/Launcher.h index 3c0da1059..b69ffb459 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -6,11 +6,6 @@ Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 */ struct LScreen; -#ifdef CC_BUILD_WIN -#define GAME_EXE_NAME "ClassiCube.exe" -#else -#define GAME_EXE_NAME "./ClassiCube" -#endif /* Currently active screen/menu. */ extern struct LScreen* Launcher_Screen; diff --git a/src/Platform.c b/src/Platform.c index 58cc4e1da..17f6bcb88 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -96,6 +96,7 @@ const ReturnCode ReturnCode_SocketWouldBlock = EWOULDBLOCK; #endif #ifdef CC_BUILD_OSX #include +#include #include #include #endif @@ -560,7 +561,7 @@ ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallba if (src[0] == '.' && src[1] == '.' && src[2] == '\0') continue; len = String_CalcLen(src, UInt16_MaxValue); - String_DecodeUtf8(&path, src, len); + Convert_DecodeUtf8(&path, src, len); /* TODO: fallback to stat when this fails */ if (entry->d_type == DT_DIR) { @@ -1293,7 +1294,7 @@ ReturnCode Socket_Poll(SocketHandle socket, int mode, bool* success) { FD_ZERO(&set); FD_SET(socket, &set); - if (selectMode == SOCKET_POLL_READ) { + if (mode == SOCKET_POLL_READ) { selectCount = select(socket + 1, &set, NULL, NULL, &time); } else { selectCount = select(socket + 1, NULL, &set, NULL, &time); @@ -1712,18 +1713,10 @@ static void Platform_InitStopwatch(void) { } else { sw_freqDiv = 10; } } -void Platform_SetWorkingDir(void) { - TCHAR dirName[FILENAME_SIZE + 1]; - DWORD len = GetModuleFileName(NULL, dirName, FILENAME_SIZE); - if (!len) return; - - /* get rid of filename at end of directory */ - for (; len > 0; len--) { - if (dirName[len] == '/' || dirName[len] == '\\') break; - } - - dirName[len] = '\0'; - SetCurrentDirectory(dirName); +ReturnCode Platform_SetCurrentDirectory(const String* path) { + TCHAR str[300]; + Platform_ConvertString(str, path); + return SetCurrentDirectory(str) ? 0 : GetLastError(); } void Platform_Exit(ReturnCode code) { ExitProcess(code); } @@ -1793,6 +1786,19 @@ ReturnCode Platform_Decrypt(const uint8_t* data, int len, uint8_t** dec, int* de return 0; } +ReturnCode Platform_GetExePath(String* path) { + TCHAR chars[FILENAME_SIZE + 1]; + DWORD len = GetModuleFileName(NULL, chars, FILENAME_SIZE); + if (!len) return GetLastError(); + +#ifdef UNICODE + Convert_DecodeUtf16(path, chars, len * 2); +#else + Convert_DecodeAscii(path, chars, len); +#endif + return 0; +} + ReturnCode Platform_StartProcess(const String* path, const String* args) { String file, argv; char argvBuffer[300]; TCHAR str[300], raw[300]; @@ -1875,6 +1881,12 @@ void Platform_Free(void) { pthread_mutex_destroy(&audio_lock); } +ReturnCode Platform_SetCurrentDirectory(const String* path) { + char str[600]; + Platform_ConvertString(str, path); + return chdir(str) == -1 ? errno : 0; +} + void Platform_Exit(ReturnCode code) { exit(code); } int Platform_GetCommandLineArgs(int argc, STRING_REF const char** argv, String* args) { @@ -1976,13 +1988,13 @@ ReturnCode Platform_StartOpen(const String* args) { } static void Platform_InitStopwatch(void) { sw_freqDiv = 1000; } -void Platform_SetWorkingDir(void) { - char path[FILENAME_SIZE + 1] = { 0 }; - int len = readlink("/proc/self/exe", path, FILENAME_SIZE); - if (len <= 0) return; +ReturnCode Platform_GetExePath(String* path) { + char str[600]; + int len = readlink("/proc/self/exe", str, 600); + if (len == -1) return errno; - Platform_TrimFilename(path, len); - chdir(path); + Convert_DecodeUtf8(path, str, len); + return 0; } #endif #ifdef CC_BUILD_SOLARIS @@ -1993,13 +2005,13 @@ ReturnCode Platform_StartOpen(const String* args) { } static void Platform_InitStopwatch(void) { sw_freqDiv = 1000; } -void Platform_SetWorkingDir(void) { - char path[FILENAME_SIZE + 1] = { 0 }; - int len = readlink("/proc/self/path/a.out", path, FILENAME_SIZE); - if (len <= 0) return; +ReturnCode Platform_GetExePath(String* path) { + char str[600]; + int len = readlink("/proc/self/path/a.out", str, 600); + if (len == -1) return errno; - Platform_TrimFilename(path, len); - chdir(path); + Convert_DecodeUtf8(path, str, len); + return 0; } #endif #ifdef CC_BUILD_OSX @@ -2007,28 +2019,13 @@ ReturnCode Platform_StartOpen(const String* args) { const static String path = String_FromConst("/usr/bin/open"); return Platform_StartProcess(&path, args); } -void Platform_SetWorkingDir(void) { - char path[1024]; - CFBundleRef bundle; - CFURLRef bundleUrl; - CFStringRef cfPath; - int len; +ReturnCode Platform_GetExePath(String* path) { + char str[600]; + int len = 600; - bundle = CFBundleGetMainBundle(); - if (!bundle) return; - bundleUrl = CFBundleCopyBundleURL(bundle); - if (!bundleUrl) return; - - cfPath = CFURLCopyFileSystemPath(bundleUrl, kCFURLPOSIXPathStyle); - if (!cfPath) return; - CFStringGetCString(cfPath, path, Array_Elems(path), kCFStringEncodingUTF8); - - CFRelease(bundleUrl); - CFRelease(cfPath); - - len = String_CalcLen(path, Array_Elems(path)); - Platform_TrimFilename(path, len); - chdir(path); + if (_NSGetExecutablePath(str, &len) != 0) return ReturnCode_InvalidArg; + Convert_DecodeUtf8(path, str, len); + return 0; } static void Platform_InitDisplay(void) { diff --git a/src/Platform.h b/src/Platform.h index ff0606cc3..986aa8a32 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -55,8 +55,9 @@ CC_API int Platform_ConvertString(void* data, const String* src); void Platform_Init(void); /* Frees the platform specific state. */ void Platform_Free(void); -/* Sets current directory to the directory the executable is in. */ -void Platform_SetWorkingDir(void); +/* Sets current/working directory to the given directory. */ +/* This is the 'base directory' relative paths are based on. */ +ReturnCode Platform_SetCurrentDirectory(const String* path); /* Exits the process with the given return code .*/ void Platform_Exit(ReturnCode code); @@ -69,6 +70,8 @@ ReturnCode Platform_Encrypt(const uint8_t* data, int len, uint8_t** enc, int* en /* NOTE: Should only be implemented when platform natively supports it. */ ReturnCode Platform_Decrypt(const uint8_t* data, int len, uint8_t** dec, int* decLen); +/* Returns the full path of the application's executable. */ +ReturnCode Platform_GetExePath(String* path); /* Starts the given program with the given arguments. */ ReturnCode Platform_StartProcess(const String* path, const String* args); /* Starts the platform-specific program to open the given url or filename. */ diff --git a/src/Program.c b/src/Program.c index 3e21e38b9..e27b69ca3 100644 --- a/src/Program.c +++ b/src/Program.c @@ -65,13 +65,30 @@ static void Program_RunGame(void) { Game_Run(width, height, &title); } +static void Program_SetCurrentDirectory(void) { + String path; char pathBuffer[FILENAME_SIZE]; + int i; + ReturnCode res; + String_InitArray(path, pathBuffer); + + res = Platform_GetExePath(&path); + if (res) { Logger_Warn(res, "getting exe path"); return; } + + /* get rid of filename at end of directory */ + for (i = path.length - 1; i >= 0; i--, path.length--) { + if (path.buffer[i] == '/' || path.buffer[i] == '\\') break; + } + res = Platform_SetCurrentDirectory(&path); + if (res) { Logger_Warn(res, "setting current directory"); return; } +} + int main(int argc, char** argv) { String args[GAME_MAX_CMDARGS]; int argsCount; uint8_t ip[4]; uint16_t port; - Platform_SetWorkingDir(); + Program_SetCurrentDirectory(); Logger_Hook(); Platform_Init(); #ifdef CC_TEST_VORBIS diff --git a/src/String.c b/src/String.c index fba646710..7efcd6c92 100644 --- a/src/String.c +++ b/src/String.c @@ -526,19 +526,6 @@ bool Convert_TryUnicodeToCP437(Codepoint cp, char* c) { *c = '?'; return false; } -void String_DecodeUtf8(String* str, uint8_t* data, uint32_t len) { - Codepoint cp; - int read; - - while (len) { - read = Convert_Utf8ToUnicode(&cp, data, len); - if (!read) break; - - String_Append(str, Convert_UnicodeToCP437(cp)); - data += read; len -= read; - } -} - int Convert_Utf8ToUnicode(Codepoint* cp, const uint8_t* data, uint32_t len) { *cp = '\0'; if (!len) return 0; @@ -582,6 +569,34 @@ int Convert_UnicodeToUtf8(Codepoint cp, uint8_t* data) { } } +void Convert_DecodeUtf16(String* value, Codepoint* chars, int numBytes) { + int i; char c; + + for (i = 0; i < (numBytes >> 1); i++) { + if (Convert_TryUnicodeToCP437(chars[i], &c)) String_Append(value, c); + } +} + +void Convert_DecodeUtf8(String* value, uint8_t* chars, int numBytes) { + int len; Codepoint cp; char c; + + for (; numBytes > 0; numBytes -= len) { + len = Convert_Utf8ToUnicode(&cp, chars, numBytes); + if (!len) return; + + if (Convert_TryUnicodeToCP437(cp, &c)) String_Append(value, c); + chars += len; + } +} + +void Convert_DecodeAscii(String* value, uint8_t* chars, int numBytes) { + int i; char c; + + for (i = 0; i < numBytes; i++) { + if (Convert_TryUnicodeToCP437(chars[i], &c)) String_Append(value, c); + } +} + /*########################################################################################################################* *--------------------------------------------------Numerical conversions--------------------------------------------------* diff --git a/src/String.h b/src/String.h index 1922e24e7..3fd38cc36 100644 --- a/src/String.h +++ b/src/String.h @@ -155,14 +155,22 @@ Codepoint Convert_CP437ToUnicode(char c); char Convert_UnicodeToCP437(Codepoint cp); /* Attempts to convert a unicode character to its code page 437 equivalent. */ bool Convert_TryUnicodeToCP437(Codepoint cp, char* c); -/* Appends all characters from UTF8 encoded data to the given string. */ -void String_DecodeUtf8(String* str, uint8_t* data, uint32_t len); /* Decodes a unicode character from UTF8, returning number of bytes read. */ /* Returns 0 if not enough input data to read the character. */ int Convert_Utf8ToUnicode(Codepoint* cp, const uint8_t* data, uint32_t len); /* Encodes a unicode character in UTF8, returning number of bytes written. */ int Convert_UnicodeToUtf8(Codepoint cp, uint8_t* data); +/* Attempts to append all characters from UTF16 encoded data to the given string. */ +/* Characters not in code page 437 are omitted. */ +void Convert_DecodeUtf16(String* str, Codepoint* chars, int numBytes); +/* Attempts to append all characters from UTF8 encoded data to the given string. */ +/* Characters not in code page 437 are omitted. */ +void Convert_DecodeUtf8(String* str, uint8_t* chars, int numBytes); +/* Attempts to append all characters from ASCII encoded data to the given string. */ +/* Characters not in code page 437 are omitted. */ +void Convert_DecodeAscii(String* str, uint8_t* chars, int numBytes); + /* Attempts to convert the given string into an unsigned 8 bit integer. */ CC_API bool Convert_ParseUInt8(const String* str, uint8_t* value); /* Attempts to convert the given string into an signed 16 bit integer. */ diff --git a/src/Window.c b/src/Window.c index c7d76244a..7acd063fe 100644 --- a/src/Window.c +++ b/src/Window.c @@ -12,34 +12,6 @@ Size2D Window_ClientSize; static bool win_cursorVisible = true; bool Window_GetCursorVisible(void) { return win_cursorVisible; } -static void Window_DecodeUtf16(String* value, Codepoint* chars, int numBytes) { - int i; char c; - - for (i = 0; i < (numBytes >> 1); i++) { - if (Convert_TryUnicodeToCP437(chars[i], &c)) String_Append(value, c); - } -} - -static void Window_DecodeUtf8(String* value, uint8_t* chars, int numBytes) { - int len; Codepoint cp; char c; - - for (; numBytes > 0; numBytes -= len) { - len = Convert_Utf8ToUnicode(&cp, chars, numBytes); - if (!len) return; - - if (Convert_TryUnicodeToCP437(cp, &c)) String_Append(value, c); - chars += len; - } -} - -static void Window_DecodeAscii(String* value, uint8_t* chars, int numBytes) { - int i; char c; - - for (i = 0; i < numBytes; i++) { - if (Convert_TryUnicodeToCP437(chars[i], &c)) String_Append(value, c); - } -} - void Window_CreateSimple(int width, int height) { struct DisplayDevice* device = &DisplayDevice_Default; struct GraphicsMode mode; @@ -434,9 +406,9 @@ void Window_GetClipboardText(String* value) { /* ignore trailing NULL at end */ /* TODO: Verify it's always there */ if (isUnicode) { - Window_DecodeUtf16(value, (Codepoint*)src, size - 2); + Convert_DecodeUtf16(value, (Codepoint*)src, size - 2); } else { - Window_DecodeAscii(value, (uint8_t*)src, size - 1); + Convert_DecodeAscii(value, (uint8_t*)src, size - 1); } GlobalUnlock(hGlobal); @@ -1311,7 +1283,7 @@ void Window_ProcessEvents(void) { if (data && items && prop_type == xa_utf8_string) { clipboard_paste_text.length = 0; - Window_DecodeUtf8(&clipboard_paste_text, data, items); + Convert_DecodeUtf8(&clipboard_paste_text, data, items); } if (data) XFree(data); } @@ -1895,7 +1867,6 @@ OSStatus Window_ProcessKeyboardEvent(EventHandlerCallRef inCaller, EventRef inEv UInt32 kind, code; Key key; char charCode, raw; - bool repeat; OSStatus res; kind = GetEventKind(inEvent); @@ -1941,17 +1912,11 @@ OSStatus Window_ProcessKeyboardEvent(EventHandlerCallRef inCaller, EventRef inEv NULL, sizeof(UInt32), NULL, &code); if (res) Logger_Abort2(res, "Getting key modifiers"); - /* TODO: Is this even needed */ - repeat = Key_KeyRepeat; - Key_KeyRepeat = false; - - Key_SetPressed(KEY_LCTRL, (code & 0x1000) != 0); - Key_SetPressed(KEY_LALT, (code & 0x0800) != 0); - Key_SetPressed(KEY_LSHIFT, (code & 0x0200) != 0); - Key_SetPressed(KEY_LWIN, (code & 0x0100) != 0); - Key_SetPressed(KEY_CAPSLOCK, (code & 0x0400) != 0); - - Key_KeyRepeat = repeat; + Key_SetPressed(KEY_LCTRL, (code & 0x1000) != 0); + Key_SetPressed(KEY_LALT, (code & 0x0800) != 0); + Key_SetPressed(KEY_LSHIFT, (code & 0x0200) != 0); + Key_SetPressed(KEY_LWIN, (code & 0x0100) != 0); + Key_SetPressed(KEY_CAPSLOCK, (code & 0x0400) != 0); return 0; } return eventNotHandledErr; @@ -2203,11 +2168,11 @@ void Window_GetClipboardText(String* value) { if (!(err = PasteboardCopyItemFlavorData(pbRef, itemID, FMT_UTF16, &outData))) { ptr = CFDataGetBytePtr(outData); len = CFDataGetLength(outData); - if (ptr) Window_DecodeUtf16(value, (Codepoint*)ptr, len); + if (ptr) Convert_DecodeUtf16(value, (Codepoint*)ptr, len); } else if (!(err = PasteboardCopyItemFlavorData(pbRef, itemID, FMT_UTF8, &outData))) { ptr = CFDataGetBytePtr(outData); len = CFDataGetLength(outData); - if (ptr) Window_DecodeUtf8(value, (uint8_t*)ptr, len); + if (ptr) Convert_DecodeUtf8(value, (uint8_t*)ptr, len); } }