Browse Source

Fixed UTF-8 encoding of APPDATA and CWD on Windows.

rude 15 years ago
parent
commit
a3f6a55593

+ 24 - 0
platform/msvc2008/common/common.vcproj

@@ -318,6 +318,30 @@
 			RelativePath="..\..\..\src\common\types.h"
 			>
 		</File>
+		<File
+			RelativePath="..\..\..\src\common\utf8.cpp"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ObjectFile="$(IntDir)\common\"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCLCompilerTool"
+					ObjectFile="$(IntDir)\common\"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\..\..\src\common\utf8.h"
+			>
+		</File>
 		<File
 			RelativePath="..\..\..\src\common\Vector.cpp"
 			>

+ 24 - 0
platform/msvc2008/love.vcproj

@@ -3537,6 +3537,30 @@
 				RelativePath="..\..\src\common\types.h"
 				>
 			</File>
+			<File
+				RelativePath="..\..\src\common\utf8.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)\common\"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)\common\"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\src\common\utf8.h"
+				>
+			</File>
 			<File
 				RelativePath="..\..\src\common\Vector.cpp"
 				>

+ 60 - 0
src/common/utf8.cpp

@@ -0,0 +1,60 @@
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#include "utf8.h"
+
+#ifdef LOVE_WINDOWS
+
+namespace love
+{
+	std::string to_utf8(LPCWSTR wstr)
+	{
+		size_t wide_len = wcslen(wstr)+1;
+
+		// Get size in UTF-8.
+		int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, 0, 0, 0, 0);
+
+		char * utf8_str = new char[utf8_size];
+
+		// Convert to UTF-8.
+		int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0);
+
+		if(!ok)
+		{
+			delete [] utf8_str;
+		}
+
+		return ok ? std::string(utf8_str) : std::string();
+	}
+
+	void replace_char(std::string & str, char find, char replace)
+	{
+		int length = str.length();
+
+		for(int i = 0; i<length; i++)
+		{
+			if(str[i] == find)
+				str[i] = replace;
+		}
+	}
+
+} // love
+
+#endif // LOVE_WINDOWS

+ 47 - 0
src/common/utf8.h

@@ -0,0 +1,47 @@
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#include "config.h"
+
+#ifdef LOVE_WINDOWS
+
+#include <string>
+#include <windows.h>
+
+namespace love
+{
+	/**
+	* Convert the wide string to a UTF-8 encoded string.
+	* @param wstr The wide-char string.
+	* @return A UTF-8 string.
+	**/
+	std::string to_utf8(LPCWSTR wstr);
+
+	/**
+	* Replace all occurences of 'find' with 'replace' in a string.
+	* @param str The string to modify.
+	* @param find The character to match.
+	* @param replace The character to replace matches.
+	**/
+	void replace_char(std::string & str, char find, char replace);
+
+} // love
+
+#endif // LOVE_WINDOWS

+ 40 - 17
src/modules/filesystem/physfs/Filesystem.cpp

@@ -18,10 +18,11 @@
 * 3. This notice may not be removed or altered from any source distribution.
 **/
 
-#include "Filesystem.h"
+#include <common/config.h>
+
+#include <common/utf8.h>
 
-// Physfs
-//#include <physfs.h> // this gets included by virtue of Filesystem.h including File.h
+#include "Filesystem.h"
 
 namespace love
 {
@@ -153,14 +154,26 @@ namespace physfs
 
 	const char * Filesystem::getWorkingDirectory()
 	{
-		#ifdef LOVE_WINDOWS
-				_getcwd(cwdbuffer, LOVE_MAX_PATH);
-		#else
-				char * temp = getcwd(cwdbuffer, LOVE_MAX_PATH);
-				if(temp == 0)
-					return 0;
-		#endif
-				return cwdbuffer;
+		if(cwd.empty())
+		{
+#ifdef LOVE_WINDOWS
+
+			WCHAR w_cwd[LOVE_MAX_PATH];
+			_wgetcwd(w_cwd, LOVE_MAX_PATH);
+			cwd = to_utf8(w_cwd);
+			replace_char(cwd, '\\', '/');
+#else
+			cwd = new char[LOVE_MAX_PATH];
+
+			if(!getcwd(cwd, LOVE_MAX_PATH))
+			{
+				delete [] cwd;
+				cwd = 0;
+			}
+#endif
+		}
+
+		return cwd.c_str();
 	}
 
 	const char * Filesystem::getUserDirectory()
@@ -170,12 +183,22 @@ namespace physfs
 
 	const char * Filesystem::getAppdataDirectory()
 	{
-#ifdef WINDOWS
-		return getenv("APPDATA");
-#elif defined(LOVE_MACOSX)
-		std::string udir = getUserDirectory();
-		udir.append("/Library/Application Support");
-		return udir.c_str();
+#ifdef LOVE_WINDOWS
+		if(appdata.empty())
+		{
+			wchar_t * w_appdata = _wgetenv(TEXT("APPDATA"));
+			appdata = to_utf8(w_appdata);
+			replace_char(appdata, '\\', '/');
+		}
+		return appdata.c_str();
+#elif defined(LOVE_MACOSX
+		if(appdata.empty())
+		{
+			std::string udir = getUserDirectory();
+			udir.append("/Library/Application Support");
+			appdata = udir;
+		}
+		return appdata.c_str();
 #else
 		return getUserDirectory();
 #endif

+ 6 - 2
src/modules/filesystem/physfs/Filesystem.h

@@ -36,6 +36,7 @@
 // Using this instead of boost::filesystem which totally
 // cramped our style.
 #ifdef LOVE_WINDOWS
+#	include <windows.h>
 #	include <direct.h>
 #else
 #	include <sys/param.h>
@@ -74,8 +75,11 @@ namespace physfs
 		// Pointer used for file reads.
 		char * buffer;
 		
-		// Buffer used for getcwd in Linux.
-		char cwdbuffer[LOVE_MAX_PATH];
+		// Contains the current working directory (UTF8).
+		std::string cwd;
+
+		// %APPDATA% on Windows.
+		std::string appdata;
 
 		// This name will be used to create the folder
 		// in the appdata/userdata folder.