Allow the game to work with renamed .exe

This commit is contained in:
UnknownShadow200 2018-12-28 23:48:19 +11:00
parent 38f5afa605
commit b28404190f
10 changed files with 133 additions and 131 deletions

View File

@ -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;
}

View File

@ -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_) {

View File

@ -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;
}

View File

@ -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;

View File

@ -96,6 +96,7 @@ const ReturnCode ReturnCode_SocketWouldBlock = EWOULDBLOCK;
#endif
#ifdef CC_BUILD_OSX
#include <mach/mach_time.h>
#include <mach-o/dyld.h>
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#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) {

View File

@ -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. */

View File

@ -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

View File

@ -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--------------------------------------------------*

View File

@ -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. */

View File

@ -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);
}
}