Compare commits

...

2 Commits

5 changed files with 181 additions and 32 deletions

View File

@@ -37,8 +37,6 @@ GNU General Public License for more details.
#include "com_model.h"
#include "com_strings.h"
#include "crtlib.h"
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
#include "fscallback.h"
#include "cvar.h"
#include "con_nprint.h"
#include "crclib.h"

View File

@@ -36,6 +36,8 @@ GNU General Public License for more details.
#include "enginefeatures.h"
#include "render_api.h" // decallist_t
#include "tests.h"
#include "library.h"
#include "platform/platform.h"
host_parm_t host; // host parms
static jmp_buf return_from_main_buf;
@@ -861,6 +863,118 @@ static void Host_DetermineExecutableName( char *out, size_t size )
#endif
}
static qboolean Host_CollectX86Libraries( ECommonLibraryType lib_type,
const char *win_path, const char *lin_path, const char *osx_path,
char *found, size_t found_size )
{
string native_path;
qboolean has_any = false;
found[0] = 0;
COM_GetCommonLibraryPath( lib_type, native_path, sizeof( native_path ));
if( Platform_LibraryExists( native_path, true ))
return 0;
#if !( XASH_WIN32 && XASH_X86 )
if( !COM_StringEmpty( win_path ) && FS_FileExists( win_path, true ))
{
Q_strncat( found, "Windows (x86)", found_size );
has_any = true;
}
#endif
#if !( XASH_LINUX && !XASH_ANDROID && XASH_X86 )
if( !COM_StringEmpty( lin_path ) && FS_FileExists( lin_path, true ))
{
if( has_any )
Q_strncat( found, ", ", found_size );
Q_strncat( found, "GNU/Linux (x86)", found_size );
has_any = true;
}
#endif
#if !( XASH_APPLE && XASH_X86 )
if( !COM_StringEmpty( osx_path ) && FS_FileExists( osx_path, true ))
{
if( has_any )
Q_strncat( found, ", ", found_size );
Q_strncat( found, "macOS (x86)", found_size );
has_any = true;
}
#endif
return has_any;
}
static void Host_CheckGameLibraries( void )
{
// on Android, game libraries are loaded from APKs and are invisible to FS_FileExists,
// so the check cannot work there; iOS is handled via Platform_LibraryExists -> IOS_LibraryExists
#if !defined( XASH_INTERNAL_GAMELIBS ) && !XASH_ANDROID
struct
{
const char *name;
ECommonLibraryType type;
const char *override; // host.gamedll / host.clientlib / host.menulib
} libs[3] = {
{ "client", LIBRARY_CLIENT, host.clientlib },
{ "server", LIBRARY_SERVER, host.gamedll },
{ "menu", LIBRARY_GAMEUI, host.menulib },
};
char details[MAX_VA_STRING];
details[0] = 0;
for( int i = 0; i < ARRAYSIZE( libs ); i++ )
{
string found;
qboolean ret;
// if the user explicitly set a library path, trust them and skip the check
if( !COM_StringEmpty( libs[i].override ))
continue;
if( libs[i].type == LIBRARY_SERVER )
{
// missing server library is only critical when singleplayer is available
// mirrors silent mode in SV_InitGame
if( GI->gamemode != GAME_SINGLEPLAYER_ONLY )
continue;
ret = Host_CollectX86Libraries( libs[i].type,
GI->game_dll, GI->game_dll_linux, GI->game_dll_osx,
found, sizeof( found ));
}
else
{
string win, lin, osx;
Q_snprintf( win, sizeof( win ), "%s/%s.dll", GI->dll_path, libs[i].name );
Q_snprintf( lin, sizeof( lin ), "%s/%s.so", GI->dll_path, libs[i].name );
Q_snprintf( osx, sizeof( osx ), "%s/%s.dylib", GI->dll_path, libs[i].name );
ret = Host_CollectX86Libraries( libs[i].type,
win, lin, osx, found, sizeof( found ));
}
if( ret )
{
size_t len = Q_strlen( details );
Q_snprintf( details + len, sizeof( details ) - len, "- %s: %s\n", libs[i].name, found );
}
}
if( COM_StringEmpty( details ))
return;
Sys_Warn( "No native game libraries found for current platform (%s-%s),\n"
"but found libraries for other platforms:\n"
"%s"
"The game may fail to load or work incorrectly.\n"
"Consider using a mod version built for this platform.",
Q_buildos(), Q_buildarch(), details );
#endif // XASH_INTERNAL_GAMELIBS
}
/*
=================
Host_InitCommon
@@ -998,6 +1112,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
#endif
FS_LoadGameInfo();
Host_CheckGameLibraries();
Cvar_PostFSInit();
Image_CheckPaletteQ1 ();

View File

@@ -13,63 +13,83 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <string.h>
#include <unistd.h>
#include <SDL.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include "crtlib.h"
#include "library.h"
#include "platform/ios/lib_ios.h"
#include "common.h"
#define EXT_LENGTH 5
const char *g_szLibrarySuffix;
static void *IOS_LoadLibraryInternal( const char *dllname )
{
void *pHandle;
string errorstring = "";
char path[MAX_SYSPATH];
Q_snprintf( path, MAX_SYSPATH, "%s%s", SDL_GetBasePath(), dllname );
Q_snprintf( path, sizeof( path ), "%s%s", SDL_GetBasePath(), dllname );
pHandle = dlopen( path, RTLD_LAZY );
if( !pHandle )
{
COM_PushLibraryError(errorstring);
COM_PushLibraryError(dlerror());
}
COM_PushLibraryError(dlerror( ));
return pHandle;
}
const char *g_szLibrarySuffix;
static qboolean IOS_LibraryExistsInternal( const char *name )
{
struct stat buf;
char path[MAX_SYSPATH];
Q_snprintf( path, sizeof( path ), "%s%s", SDL_GetBasePath(), name );
return stat( path, &buf ) == 0;
}
static const char *IOS_GetLibraryPostfix( void )
{
if( g_szLibrarySuffix )
return g_szLibrarySuffix;
return Q_strcmp( host.default_gamedir, FS_Gamedir( )) ? FS_Gamedir( ) : "";
}
static void IOS_PrepareGameLibraryPath( const char *dllname, char *out, size_t outsize )
{
string strippedname;
Q_strncpy( strippedname, dllname, sizeof( strippedname ));
COM_StripExtension( strippedname );
Q_snprintf( out, outsize, "%s_%s.dylib", strippedname, IOS_GetLibraryPostfix( ));
}
void *IOS_LoadLibrary( const char *dllname )
{
//Immediately load if the library is filesystem_stdio.dylib or we will crash when accessing gamedir
if ( !Q_strcmp( dllname, "filesystem_stdio.dylib" ) )
{
// filesystem_stdio is a special case, as engine won't work correctly without it
// but it's always located at known path
if( !Q_strcmp( dllname, "filesystem_stdio.dylib" ))
return IOS_LoadLibraryInternal( dllname );
}
string name;
string strippedname;
const char *postfix = g_szLibrarySuffix;
char *pHandle;
if( !postfix )
{
if ( Q_strcmp(FS_Gamedir(), host.default_gamedir ) )
{
postfix = FS_Gamedir( );
}
else postfix = "";
}
Q_strncpy( strippedname, dllname, sizeof( strippedname ) );
COM_StripExtension(strippedname);
Q_snprintf( name, MAX_STRING, "%s_%s.dylib", strippedname, postfix );
IOS_PrepareGameLibraryPath( dllname, name, sizeof( name ));
pHandle = IOS_LoadLibraryInternal( name );
if( pHandle )
return pHandle;
if( !pHandle )
pHandle = IOS_LoadLibraryInternal( dllname );
return IOS_LoadLibraryInternal( dllname );
return pHandle;
}
qboolean IOS_LibraryExists( const char *dllname )
{
string name;
IOS_PrepareGameLibraryPath( dllname, name, sizeof( name ));
return IOS_LibraryExistsInternal( name ) || IOS_LibraryExistsInternal( dllname );
}

View File

@@ -20,6 +20,7 @@ GNU General Public License for more details.
#define Platform_POSIX_LoadLibrary( x ) IOS_LoadLibrary(( x ))
void *IOS_LoadLibrary( const char *dllname );
qboolean IOS_LibraryExists( const char *name );
#endif // IOS_LIB_H
#endif // TARGET_OS_IPHONE

View File

@@ -18,6 +18,8 @@ GNU General Public License for more details.
#define PLATFORM_H
#include <errno.h>
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
#include "fscallback.h"
#include "common.h"
#include "system.h"
#include "defaults.h"
@@ -43,6 +45,7 @@ qboolean Platform_DebuggerPresent( void );
int IOS_GetArgs( char ***argv );
const char *IOS_GetDocsDir( void );
void IOS_LaunchDialog( void );
#include "platform/ios/lib_ios.h"
#endif // TARGET_OS_IOS
#if XASH_WIN32 || XASH_LINUX
@@ -207,6 +210,18 @@ static inline void Sys_RestoreCrashHandler( void )
}
#endif
static inline qboolean Platform_LibraryExists( const char *name, qboolean gamedironly )
{
#if XASH_IOS
return IOS_LibraryExists( name );
#elif XASH_ANDROID
// sorry, unimplemented
return false;
#else
return g_fsapi.FileExists( name, gamedironly );
#endif
}
/*
==============================================================================