Index: src/main.c =================================================================== --- src/main.c (revision 11240) +++ src/main.c (working copy) @@ -26,12 +26,7 @@ #include -#if defined(WZ_OS_WIN) -# include /* For SHGetFolderPath */ -#elif defined(WZ_OS_UNIX) -# include -#endif // WZ_OS_WIN - +#include "lib/framework/directory.h" #include "lib/framework/configfile.h" #include "lib/framework/input.h" #include "lib/framework/physfs_ext.h" @@ -95,7 +90,6 @@ #if defined(WZ_OS_WIN) # define WZ_WRITEDIR "Warzone 2100 Trunk" #elif defined(WZ_OS_MAC) -# include # include # define WZ_WRITEDIR "Warzone 2100 Trunk" #else @@ -353,97 +347,6 @@ return mod_list; } - -/*! - * Retrieves the current working directory and copies it into the provided output buffer - * \param[out] dest the output buffer to put the current working directory in - * \param size the size (in bytes) of \c dest - * \return true on success, false if an error occurred (and dest doesn't contain a valid directory) - */ -static bool getCurrentDir(char * const dest, size_t const size) -{ -#if defined(WZ_OS_UNIX) - if (getcwd(dest, size) == NULL) - { - if (errno == ERANGE) - { - debug(LOG_ERROR, "getPlatformUserDir: The buffer to contain our current directory is too small (%u bytes and more needed)", (unsigned int)size); - } - else - { - debug(LOG_ERROR, "getPlatformUserDir: getcwd failed: %s", strerror(errno)); - } - - return false; - } -#elif defined(WZ_OS_WIN) - const int len = GetCurrentDirectoryA(size, dest); - - if (len == 0) - { - // Retrieve Windows' error number - const int err = GetLastError(); - char* err_string; - - // Retrieve a string describing the error number (uses LocalAlloc() to allocate memory for err_string) - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, (char*)&err_string, 0, NULL); - - // Print an error message with the above description - debug(LOG_ERROR, "getPlatformUserDir: GetCurrentDirectoryA failed (error code: %d): %s", err, err_string); - - // Free our chunk of memory FormatMessageA gave us - LocalFree(err_string); - - return false; - } - else if (len > size) - { - debug(LOG_ERROR, "getPlatformUserDir: The buffer to contain our current directory is too small (%u bytes and %d needed)", (unsigned int)size, len); - - return false; - } -#else -# error "Provide an implementation here to copy the current working directory in 'dest', which is 'size' bytes large." -#endif - - // If we got here everything went well - return true; -} - - -static void getPlatformUserDir(char * const tmpstr, size_t const size) -{ -#if defined(WZ_OS_WIN) - ASSERT(size >= MAX_PATH, "size (%u) is smaller than the required minimum of MAX_PATH (%u)", size, (size_t)MAX_PATH); - if ( SUCCEEDED( SHGetFolderPathA( NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, tmpstr ) ) ) - strlcat(tmpstr, PHYSFS_getDirSeparator(), size); - else -#elif defined(WZ_OS_MAC) - FSRef fsref; - OSErr error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &fsref); - if (!error) - error = FSRefMakePath(&fsref, (UInt8 *) tmpstr, size); - if (!error) - strlcat(tmpstr, PHYSFS_getDirSeparator(), size); - else -#endif - if (PHYSFS_getUserDir()) - { - strlcpy(tmpstr, PHYSFS_getUserDir(), size); // Use PhysFS supplied UserDir (As fallback on Windows / Mac, default on Linux) - } - // If PhysicsFS fails (might happen if environment variable HOME is unset or wrong) then use the current working directory - else if (getCurrentDir(tmpstr, size)) - { - strlcat(tmpstr, PHYSFS_getDirSeparator(), size); - } - else - { - debug(LOG_FATAL, "Can't get UserDir?"); - abort(); -} -} - - static void initialize_ConfigDir(void) { char tmpstr[PATH_MAX] = { '\0' }; @@ -612,11 +515,8 @@ #ifdef WZ_OS_MAC if( !PHYSFS_exists("gamedesc.lev") ) { - CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); char resourcePath[PATH_MAX]; - if( CFURLGetFileSystemRepresentation( resourceURL, true, - (UInt8 *) resourcePath, - PATH_MAX) ) { + if( getMacResourcePath(resourcePath, PATH_MAX) ) { chdir( resourcePath ); registerSearchPath( "data", 7 ); rebuildSearchPath( mod_multiplay, true ); Index: lib/framework/i18n.c =================================================================== --- lib/framework/i18n.c (revision 11240) +++ lib/framework/i18n.c (working copy) @@ -21,13 +21,9 @@ #include #include +#include "directory.h" #include "string_ext.h" -#ifdef WZ_OS_MAC -# include -# include -#endif - /* Always use fallbacks on Windows */ #if defined(WZ_OS_WIN) # undef LOCALEDIR @@ -389,8 +385,8 @@ #ifdef WZ_OS_MAC { char resourcePath[PATH_MAX]; - CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if( CFURLGetFileSystemRepresentation( resourceURL, true, (UInt8 *) resourcePath, PATH_MAX) ) + + if (getMacResourcePath(resourcePath, PATH_MAX)) { sstrcat(resourcePath, "/locale"); textdomainDirectory = bindtextdomain(PACKAGE, resourcePath); Index: lib/framework/Makefile.am =================================================================== --- lib/framework/Makefile.am (revision 11240) +++ lib/framework/Makefile.am (working copy) @@ -38,6 +38,7 @@ crc.h \ cursors.h \ debug.h \ + directory.h \ file.h \ fixedpoint.h \ frame.h \ @@ -79,6 +80,7 @@ cursors32.c \ cursors.c \ debug.c \ + directory.c \ frame.c \ frameresource.c \ i18n.c \ Index: lib/ivis_opengl/textdraw.c =================================================================== --- lib/ivis_opengl/textdraw.c (revision 11240) +++ lib/ivis_opengl/textdraw.c (working copy) @@ -33,9 +33,9 @@ #include "lib/ivis_common/textdraw.h" #include "lib/ivis_common/bitimage.h" +#include "lib/framework/directory.h" + #ifdef WZ_OS_MAC -# include -# include # include #else # include @@ -136,8 +136,8 @@ #ifdef WZ_OS_MAC { char resourcePath[PATH_MAX]; - CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if (CFURLGetFileSystemRepresentation(resourceURL, true, (UInt8 *) resourcePath, PATH_MAX)) + + if (getMacResourcePath(resourcePath, PATH_MAX)) { sstrcat(resourcePath, "/Fonts"); glcAppendCatalog(resourcePath); Index: lib/framework/directory.c =================================================================== --- lib/framework/directory.c (revision 0) +++ lib/framework/directory.c (revision 0) @@ -0,0 +1,136 @@ +/* + This file is part of Warzone 2100. + Copyright (C) 2010 Warzone Project + + Warzone 2100 is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Warzone 2100 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Warzone 2100; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "directory.h" + +#ifdef WZ_OS_MAC +#include +#include +#include +#endif // WZ_OS_MAC + +#if defined(WZ_OS_WIN) +# include /* For SHGetFolderPath */ +#elif defined(WZ_OS_UNIX) +# include +#endif // WZ_OS_WIN + +#include "frame.h" +#include "physfs_ext.h" + +#ifdef WZ_OS_MAC +bool getMacResourcePath(char * resourcePath, size_t size) +{ + CFURLRef resourceURL = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); + bool retVal; + + if (resourceURL == NULL) + { + return false; + } + + retVal = CFURLGetFileSystemRepresentation(resourceURL, true, (UInt8 *) resourcePath, size); + + CFRelease(resourceURL); + + return retVal; +} +#endif // WZ_OS_MAC + +bool getCurrentDir(char * const dest, size_t const size) +{ +#if defined(WZ_OS_UNIX) + if (getcwd(dest, size) == NULL) + { + if (errno == ERANGE) + { + debug(LOG_ERROR, "getCurrentDir: The buffer to contain our current directory is too small (%u bytes and more needed)", (unsigned int)size); + } + else + { + debug(LOG_ERROR, "getCurrentDir: getcwd failed: %s", strerror(errno)); + } + + return false; + } +#elif defined(WZ_OS_WIN) + const int len = GetCurrentDirectoryA(size, dest); + + if (len == 0) + { + // Retrieve Windows' error number + const int err = GetLastError(); + char* err_string; + + // Retrieve a string describing the error number (uses LocalAlloc() to allocate memory for err_string) + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, (char*)&err_string, 0, NULL); + + // Print an error message with the above description + debug(LOG_ERROR, "getCurrentDir: GetCurrentDirectoryA failed (error code: %d): %s", err, err_string); + + // Free our chunk of memory FormatMessageA gave us + LocalFree(err_string); + + return false; + } + else if (len > size) + { + debug(LOG_ERROR, "getCurrentDir: The buffer to contain our current directory is too small (%u bytes and %d needed)", (unsigned int)size, len); + + return false; + } +#else +# error "Provide an implementation here to copy the current working directory in 'dest', which is 'size' bytes large." +#endif + + // If we got here everything went well + return true; +} + + +void getPlatformUserDir(char * const tmpstr, size_t const size) +{ +#if defined(WZ_OS_WIN) + ASSERT(size >= MAX_PATH, "size (%u) is smaller than the required minimum of MAX_PATH (%u)", size, (size_t)MAX_PATH); + if ( SUCCEEDED( SHGetFolderPathA( NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, tmpstr ) ) ) + strlcat(tmpstr, PHYSFS_getDirSeparator(), size); + else +#elif defined(WZ_OS_MAC) + FSRef fsref; + OSErr error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &fsref); + if (!error) + error = FSRefMakePath(&fsref, (UInt8 *) tmpstr, size); + if (!error) + strlcat(tmpstr, PHYSFS_getDirSeparator(), size); + else +#endif + if (PHYSFS_getUserDir()) + { + strlcpy(tmpstr, PHYSFS_getUserDir(), size); // Use PhysFS supplied UserDir (As fallback on Windows / Mac, default on Linux) + } + // If PhysicsFS fails (might happen if environment variable HOME is unset or wrong) then use the current working directory + else if (getCurrentDir(tmpstr, size)) + { + strlcat(tmpstr, PHYSFS_getDirSeparator(), size); + } + else + { + debug(LOG_FATAL, "Can't get UserDir?"); + abort(); + } +} Index: lib/framework/directory.h =================================================================== --- lib/framework/directory.h (revision 0) +++ lib/framework/directory.h (revision 0) @@ -0,0 +1,60 @@ +/* + This file is part of Warzone 2100. + Copyright (C) 2010 Warzone Project + + Warzone 2100 is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Warzone 2100 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Warzone 2100; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +/*! \file directory.h + * \brief Directory handling code. + * \note May include platform specific code. + */ +#ifndef __DIRECTORY_H__ +#define __DIRECTORY_H__ + +#include + +#include "wzglobal.h" +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif //__cplusplus + +#ifdef WZ_OS_MAC +/*! + * Get the application's main bundle path. + * \param resourcePath Buffer to hold the of the ressource path + * in the filesystem's native representation. + * \param size Size of resourcePath + */ +bool getMacResourcePath(char * resourcePath, size_t size); +#endif // WZ_OS_MAC + +/*! + * Retrieves the current working directory and copies it into the provided output buffer + * \param[out] dest the output buffer to put the current working directory in + * \param size the size (in bytes) of \c dest + * \return true on success, false if an error occurred (and dest doesn't contain a valid directory) + */ +bool getCurrentDir(char * const dest, size_t const size); + +void getPlatformUserDir(char * const tmpstr, size_t const size); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif /* __DIRECTORY_H__ */