/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. This file is part of Quake III Arena source code. Quake III Arena source code 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. Quake III Arena source code 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 Foobar; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ #import "../client/client.h" #import "macosx_local.h" #import "dlfcn.h" #import "Q3Controller.h" #import #import #import #import #import #import #import #import #import #import #ifdef OMNI_TIMER #import "macosx_timers.h" #endif qboolean stdin_active = qfalse; //=========================================================================== int main(int argc, const char *argv[]) { #ifdef DEDICATED Q3Controller *controller; stdin_active = qtrue; controller = [[Q3Controller alloc] init]; [controller quakeMain]; return 0; #else return NSApplicationMain(argc, argv); #endif } //=========================================================================== /* ================= Sys_UnloadDll ================= */ void Sys_UnloadDll( void *dllHandle ) { if ( !dllHandle ) { return; } dlclose( dllHandle ); } /* ================= Sys_LoadDll Used to load a dylib instead of a virtual machine ================= */ extern char *FS_BuildOSPath(const char *base, const char *game, const char *qpath); void * QDECL Sys_LoadDll(const char *name, char *fqpath , intptr_t (QDECL **entryPoint)(int, ...), intptr_t (QDECL *systemcalls)(intptr_t, ...)) { void *libHandle; void (*dllEntry) (intptr_t (*syscallptr)(intptr_t, ...)); char curpath[MAX_OSPATH]; char fname[MAX_OSPATH]; char *basepath; char *homepath; char *pwdpath; char *gamedir; char *fn; const char *err = NULL; *fqpath = 0; // bk001206 - let's have some paranoia assert(name); getcwd(curpath, sizeof(curpath)); snprintf(fname, sizeof(fname), "%s.dylib", name); pwdpath = Sys_Cwd(); basepath = Cvar_VariableString("fs_basepath"); homepath = Cvar_VariableString("fs_homepath"); gamedir = Cvar_VariableString("fs_game"); fn = FS_BuildOSPath(pwdpath, gamedir, fname); Com_DPrintf("Sys_LoadDll(%s)... \n", fn); libHandle = dlopen(fn, RTLD_NOW); if(!libHandle) { fn = FS_BuildOSPath(homepath, gamedir, fname); Com_DPrintf("Sys_LoadDll(%s)... \n", fn); libHandle = dlopen(fn, RTLD_NOW); if(!libHandle) { fn = FS_BuildOSPath(basepath, gamedir, fname); Com_DPrintf("Sys_LoadDll(%s)... \n", fn); libHandle = dlopen(fn, RTLD_NOW); if(!libHandle) { Com_DPrintf("Sys_LoadDll(%s) failed dlopen() completely!\n", name); return NULL; } else { Com_DPrintf("Sys_LoadDll(%s): succeeded ...\n", fn); } } else { Com_DPrintf("Sys_LoadDll(%s): succeeded ...\n", fn); } } else { Com_DPrintf("Sys_LoadDll(%s): succeeded ...\n", fn); } dllEntry = dlsym(libHandle, "dllEntry"); *entryPoint = dlsym(libHandle, "vmMain"); if(!*entryPoint || !dllEntry) { err = dlerror(); dlclose(libHandle); err = dlerror(); if(err != NULL) Com_DPrintf("Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err); return NULL; } dllEntry(systemcalls); if(libHandle) Q_strncpyz(fqpath, fn, MAX_QPATH); return libHandle; } //=========================================================================== qboolean Sys_DetectAltivec( void ) { qboolean altivec = qfalse; #if idppc_altivec long feat = 0; OSErr err = Gestalt(gestaltPowerPCProcessorFeatures, &feat); if ((err==noErr) && ((1 << gestaltPowerPCHasVectorInstructions) & feat)) { altivec = qtrue; } #endif return altivec; } char *Sys_GetClipboardData(void) // FIXME { NSPasteboard *pasteboard; NSArray *pasteboardTypes; pasteboard = [NSPasteboard generalPasteboard]; pasteboardTypes = [pasteboard types]; if ([pasteboardTypes containsObject:NSStringPboardType]) { NSString *clipboardString; clipboardString = [pasteboard stringForType:NSStringPboardType]; if (clipboardString && [clipboardString length] > 0) { return strdup([clipboardString cString]); } } return NULL; } char *Sys_GetWholeClipboard ( void ) { return NULL; } void Sys_SetClipboard (const char *contents) { } /* ================== Sys_FunctionCheckSum ================== */ int Sys_FunctionCheckSum(void *f1) { return 0; } /* ================== Sys_MonkeyShouldBeSpanked ================== */ int Sys_MonkeyShouldBeSpanked( void ) { return 0; } //=========================================================================== void Sys_BeginProfiling(void) { } void Sys_EndProfiling(void) { } //=========================================================================== /* ================ Sys_Init The cvar and file system has been setup, so configurations are loaded ================ */ void Sys_Init(void) { #ifdef OMNI_TIMER InitializeTimers(); OTStackPushRoot(rootNode); #endif NET_Init(); Sys_InitInput(); } /* ================= Sys_Shutdown ================= */ void Sys_Shutdown(void) { Com_Printf( "----- Sys_Shutdown -----\n" ); Sys_EndProfiling(); Sys_ShutdownInput(); Com_Printf( "------------------------\n" ); } void Sys_Error(const char *error, ...) { va_list argptr; NSString *formattedString; Sys_Shutdown(); va_start(argptr,error); formattedString = [[NSString alloc] initWithFormat:[NSString stringWithCString:error] arguments:argptr]; va_end(argptr); NSLog(@"Sys_Error: %@", formattedString); NSRunAlertPanel(@"Quake 3 Error", formattedString, nil, nil, nil); Sys_Quit(); } void Sys_Quit(void) { Sys_Shutdown(); [NSApp terminate:nil]; } /* ================ Sys_Print This is called for all console output, even if the game is running full screen and the dedicated console window is hidden. ================ */ char *ansiColors[8] = { "\033[30m" , /* ANSI Black */ "\033[31m" , /* ANSI Red */ "\033[32m" , /* ANSI Green */ "\033[33m" , /* ANSI Yellow */ "\033[34m" , /* ANSI Blue */ "\033[36m" , /* ANSI Cyan */ "\033[35m" , /* ANSI Magenta */ "\033[37m" }; /* ANSI White */ void Sys_Print(const char *text) { #if 0 /* Okay, this is a stupid hack, but what the hell, I was bored. ;) */ const char *scan = text; int index; /* Make sure terminal mode is reset at the start of the line... */ fputs("\033[0m", stdout); while(*scan) { /* See if we have a color control code. If so, snarf the character, print what we have so far, print the ANSI Terminal color code, skip over the color control code and continue */ if(Q_IsColorString(scan)) { index = ColorIndex(scan[1]); /* Flush current message */ if(scan != text) { fwrite(text, scan - text, 1, stdout); } /* Write ANSI color code */ fputs(ansiColors[index], stdout); /* Reset search */ text = scan+2; scan = text; continue; } scan++; } /* Flush whatever's left */ fputs(text, stdout); /* Make sure terminal mode is reset at the end of the line too... */ fputs("\033[0m", stdout); #else fputs(text, stdout); #endif } /* ================ Sys_CheckCD Return true if the proper CD is in the drive ================ */ qboolean Sys_CheckCD( void ) { return qtrue; } //=================================================================== void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) { } void Sys_EndStreamedFile( fileHandle_t f ) { } int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) { return FS_Read( buffer, size * count, f ); } void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) { FS_Seek( f, offset, origin ); } void OutputDebugString(char * s) { #ifdef DEBUG fprintf(stderr, "%s", s); #endif } /* ================== Sys_LowPhysicalMemory() ================== */ #define MEM_THRESHOLD 96*1024*1024 qboolean Sys_LowPhysicalMemory() { return NSRealMemoryAvailable() <= MEM_THRESHOLD; } static unsigned int _Sys_ProcessorCount = 0; unsigned int Sys_ProcessorCount() { if (!_Sys_ProcessorCount) { int name[] = {CTL_HW, HW_NCPU}; size_t size; size = sizeof(_Sys_ProcessorCount); if (sysctl(name, 2, &_Sys_ProcessorCount, &size, NULL, 0) < 0) { perror("sysctl"); _Sys_ProcessorCount = 1; } else { Com_Printf("System processor count is %d\n", _Sys_ProcessorCount); } } return _Sys_ProcessorCount; }