123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 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 3 of the License, or
- (at your option) any later version.
- Doom 3 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- // -*- mode: objc -*-
- #import "../../idlib/precompiled.h"
- #import "DOOMController.h"
- #import <unistd.h>
- #import <pthread.h>
- #import <Foundation/Foundation.h>
- #import <Carbon/Carbon.h>
- #import <AppKit/AppKit.h>
- #import <OpenGL/gl.h>
- #import "macosx_common.h"
- #import "macosx_local.h"
- #import "macosx_sys.h"
- #import <fenv.h>
- #import <mach/thread_status.h>
- #define MAX_KEYS 256
- static idStr savepath;
- extern bool key_overstrikeMode;
- #define TEST_FPU_EXCEPTIONS \
- FPU_EXCEPTION_INVALID_OPERATION | \
- FPU_EXCEPTION_DENORMALIZED_OPERAND | \
- FPU_EXCEPTION_DIVIDE_BY_ZERO | \
- /* FPU_EXCEPTION_NUMERIC_OVERFLOW | */ \
- /* FPU_EXCEPTION_NUMERIC_UNDERFLOW | */ \
- /* FPU_EXCEPTION_INEXACT_RESULT | */ \
- 0
- #define kRegKey @"RegCode"
- static const ControlID kRegCode1EditText = { 'RegC', 1 };
- struct RegCodeInfo
- {
- char prefRegCode1[256];
- bool okPressed;
- WindowRef window;
- ControlRef regCode1EditText;
- };
- static OSErr DoRegCodeDialog( char* ioRegCode1 );
- @interface DOOMController (Private)
- - (void)quakeMain;
- - (BOOL)checkRegCodes;
- - (BOOL)checkOS;
- @end
- @implementation DOOMController
- /*
- + (void)initialize;
- {
- static bool initialized = NO;
- [super initialize];
- if ( initialized ) {
- return;
- }
- initialized = YES;
- }
- */
- #define MAX_ARGC 1024
- - (void)applicationDidFinishLaunching:(NSNotification *)notification;
- {
- NS_DURING {
- NSAssert(sizeof(bool) == 1, @"sizeof(bool) should equal 1 byte");
- [self quakeMain];
- } NS_HANDLER {
- Sys_Error( (const char *)[ [ localException reason ] cString ] );
- } NS_ENDHANDLER;
- Sys_Quit();
- }
- - (void)applicationWillHide:(NSNotification *)notification;
- {
- Sys_ShutdownInput();
- }
- - (void)applicationWillUnhide:(NSNotification *)notification;
- {
- Sys_InitInput();
- }
- - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
- {
- common->Quit();
- return NSTerminateLater; // we never reach this
- }
- #if 0
- // Actions
- - (IBAction)paste:(id)sender;
- {
- int shiftWasDown, insertWasDown;
- unsigned int currentTime;
- currentTime = Sys_Milliseconds();
- // Save the original keyboard state
- shiftWasDown = keys[K_SHIFT].down;
- insertWasDown = keys[K_INS].down;
- // Fake a Shift-Insert keyboard event
- keys[K_SHIFT].down = true;
- Posix_QueEvent(currentTime, SE_KEY, K_INS, true, 0, NULL);
- Posix_QueEvent(currentTime, SE_KEY, K_INS, false, 0, NULL);
- // Restore the original keyboard state
- keys[K_SHIFT].down = shiftWasDown;
- keys[K_INS].down = insertWasDown;
- }
- extern void CL_Quit_f(void);
- //extern void SetProgramPath(const char *path);
- - (IBAction)requestTerminate:(id)sender;
- {
- //osxQuit();
- common->Quit();
- }
- - (void)showBanner;
- {
- static bool hasShownBanner = NO;
- if (!hasShownBanner) {
- //cvar_t *showBanner;
- hasShownBanner = YES;
- //showBanner = Cvar_Get("cl_showBanner", "1", 0);
- //if ( showBanner->integer != 0 ) {
- if ( true ) {
- NSPanel *splashPanel;
- NSImage *bannerImage;
- NSRect bannerRect;
- NSImageView *bannerImageView;
-
- bannerImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"banner.jpg"]];
- bannerRect = NSMakeRect(0.0, 0.0, [bannerImage size].width, [bannerImage size].height);
-
- splashPanel = [[NSPanel alloc] initWithContentRect:bannerRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
-
- bannerImageView = [[NSImageView alloc] initWithFrame:bannerRect];
- [bannerImageView setImage:bannerImage];
- [splashPanel setContentView:bannerImageView];
- [bannerImageView release];
-
- [splashPanel center];
- [splashPanel setHasShadow:YES];
- [splashPanel orderFront: nil];
- [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.5]];
- [splashPanel close];
-
- [bannerImage release];
- }
- }
- }
- // Services
- - (void)connectToServer:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error;
- {
- NSArray *pasteboardTypes;
- pasteboardTypes = [pasteboard types];
- if ([pasteboardTypes containsObject:NSStringPboardType]) {
- NSString *requestedServer;
- requestedServer = [pasteboard stringForType:NSStringPboardType];
- if (requestedServer) {
- Cbuf_AddText( va( "connect %s\n", [requestedServer cString]));
- return;
- }
- }
- *error = @"Unable to connect to server: could not find string on pasteboard";
- }
- - (void)performCommand:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error;
- {
- NSArray *pasteboardTypes;
- pasteboardTypes = [pasteboard types];
- if ([pasteboardTypes containsObject:NSStringPboardType]) {
- NSString *requestedCommand;
- requestedCommand = [pasteboard stringForType:NSStringPboardType];
- if (requestedCommand) {
- Cbuf_AddText(va("%s\n", [requestedCommand cString]));
- return;
- }
- }
- *error = @"Unable to perform command: could not find string on pasteboard";
- }
- #endif // commented out all the banners and actions
- @end
- @implementation DOOMController (Private)
- - (void)quakeMain
- {
- NSAutoreleasePool *pool;
- int argc = 0;
- const char *argv[MAX_ARGC];
- NSProcessInfo *processInfo;
- NSArray *arguments;
- unsigned int argumentIndex, argumentCount;
- //const char *cddir;
- //NSFileManager *defaultManager;
- //bool tryAgain;
- pool = [[NSAutoreleasePool alloc] init];
- [NSApp setServicesProvider:self];
- processInfo = [NSProcessInfo processInfo];
- arguments = [processInfo arguments];
- argumentCount = [arguments count];
- for (argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) {
- argv[argc++] = strdup([[arguments objectAtIndex:argumentIndex] cString]);
- }
- if (![[NSFileManager defaultManager] changeCurrentDirectoryPath:[[NSBundle mainBundle] resourcePath]]) {
- Sys_Error("Could not access application resources");
- }
- //cddir = macosx_scanForLibraryDirectory();
- /*
- do {
- tryAgain = NO;
- defaultManager = [NSFileManager defaultManager];
- if (![defaultManager fileExistsAtPath:@"./base/default.cfg"] && (!cddir || *cddir == '\0' || ![defaultManager fileExistsAtPath:[NSString stringWithFormat:@"%s/baseq3/pak0.pk3", cddir]])) {
- NSString *message;
- if (!cddir || *cddir == '\0') {
- message = [NSString stringWithFormat:@"Could not find DOOM levels."];
- } else if (![defaultManager fileExistsAtPath:[NSString stringWithFormat:@"%s", cddir]]) {
- message = [NSString stringWithFormat:@"Could not find DOOM levels: '%s' does not exist.", cddir];
- } else {
- message = [NSString stringWithFormat:@"Could not find DOOM levels: '%s' is not a complete DOOM installation.", cddir];
- }
- switch (NSRunAlertPanel(@"DOOM", @"%@", @"Quit", @"Find...", nil, message)) {
- case NSAlertDefaultReturn:
- default:
- Sys_Quit();
- break;
- case NSAlertAlternateReturn:
- tryAgain = YES;
- break;
- }
- if (tryAgain) {
- NSOpenPanel *openPanel;
- int result;
- openPanel = [NSOpenPanel openPanel];
- [openPanel setAllowsMultipleSelection:NO];
- [openPanel setCanChooseDirectories:YES];
- [openPanel setCanChooseFiles:NO];
- result = [openPanel runModalForDirectory:nil file:nil];
- if (result == NSOKButton) {
- NSArray *filenames;
- filenames = [openPanel filenames];
- if ([filenames count] == 1) {
- NSString *cdPath;
- cdPath = [filenames objectAtIndex:0];
- [[NSUserDefaults standardUserDefaults] setObject:cdPath forKey:@"CDPath"];
- cddir = strdup([cdPath cString]);
- }
- }
- }
- }
- } while (tryAgain);
- */
- /*
- if (cddir && *cddir != '\0') {
- SetProgramPath([[[NSString stringWithCString:cddir] stringByAppendingPathComponent:@"/x"] cString]);
- }
- */
- //Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS );
- Posix_EarlyInit( );
- #ifndef _DEBUG
- if ( [self checkOS] == FALSE) {
- common->Quit();
- }
-
- if ( [self checkDVD] == FALSE) {
- common->Quit();
- }
- #endif
-
- // need strncmp, can't use idlib before init
- #undef strncmp
- // Finder passes the process serial number as only argument after the program path
- // nuke it if we see it
- // TODO: clean out all the misc. osx arguments the engine doesn't understand.
- if ( false ) {//argc > 1 && strncmp( argv[ 1 ], "-psn", 4 ) ) {
- common->Init( argc-1, &argv[1], NULL );
- } else {
- common->Init( 0, NULL, NULL );
- }
- Posix_LateInit( );
- [NSApp activateIgnoringOtherApps:YES];
- while (1) {
- #ifdef OMNI_TIMER
- OTPeriodicTimerReset();
- OTNodeStart(RootNode);
- #endif
- // maintain exceptions in case system calls are turning them off (is that needed)
- //Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS );
- common->Frame();
- // We should think about doing this less frequently than every frame
- [pool release];
- pool = [[NSAutoreleasePool alloc] init];
- #ifdef OMNI_TIMER
- OTNodeStop(RootNode);
- #endif
- }
- [pool release];
- }
- - (BOOL)checkRegCodes
- {
- BOOL retval;
- NSString *cdKey;
- NSUserDefaults *userDefaults;
-
- userDefaults = [NSUserDefaults standardUserDefaults];
- cdKey = [userDefaults stringForKey:kRegKey];
-
- retval = TRUE;
- if ( cdKey == nil || [cdKey length] == 0 ) {
- char regCode[256];
- if ( DoRegCodeDialog( regCode ) != noErr ) {
- retval = FALSE;
- }
- else {
- [userDefaults setObject:[NSString stringWithCString: regCode] forKey:kRegKey];
- [userDefaults synchronize];
- }
- }
- return retval;
- }
- - (BOOL)checkOS
- {
- OSErr err;
- long gestaltOSVersion;
- err = Gestalt(gestaltSystemVersion, &gestaltOSVersion);
- if ( err || gestaltOSVersion < 0x1038 ) {
- NSBundle *thisBundle = [ NSBundle mainBundle ];
- NSString *messsage = [ thisBundle localizedStringForKey:@"InsufficientOS" value:@"No translation" table:nil ];
- NSRunAlertPanel(@GAME_NAME, messsage, nil, nil, nil);
- return FALSE;
- }
- return TRUE;
- }
- - (BOOL)checkDVD
- {
- return TRUE;
- }
- @end
- /*
- ==============
- Sys_EXEPath
- ==============
- */
- const char *Sys_EXEPath( void ) {
- static char exepath[ 1024 ];
- strncpy( exepath, [ [ [ NSBundle mainBundle ] executablePath ] cString ], 1024 );
- return exepath;
- }
- /*
- ==========
- Sys_DefaultSavePath
- ==========
- */
- const char *Sys_DefaultSavePath(void) {
- #if defined( ID_DEMO_BUILD )
- sprintf( savepath, "%s/Library/Application Support/BlendoGames/Quadrilateral Cowboy Demo", [NSHomeDirectory() cString] );
- #else
- sprintf( savepath, "%s/Library/Application Support/BlendoGames/Quadrilateral Cowboy", [NSHomeDirectory() cString] );
- #endif
- return savepath.c_str();
- }
- /*
- ==========
- Sys_DefaultBasePath
- ==========
- */
- const char *Sys_DefaultBasePath(void) {
- static char basepath[ 1024 ];
- strncpy( basepath, [ [ [ NSBundle mainBundle ] pathForResource:@"base" ofType:nil ] cString ], 1024 );
- char *snap = strrchr( basepath, '/' );
- if ( snap ) {
- *snap = '\0';
- }
- return basepath;
- }
- /*
- ===============
- Sys_Shutdown
- ===============
- */
- void Sys_Shutdown( void ) {
- savepath.Clear();
- Posix_Shutdown();
- }
- /*
- ===============
- Sys_GetProcessorId
- ===============
- */
- cpuid_t Sys_GetProcessorId( void ) {
- cpuid_t cpuid = CPUID_GENERIC;
- #if defined(__ppc__)
- cpuid |= CPUID_ALTIVEC;
- #elif defined(__i386__)
- // cpuid |= CPUID_INTEL | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_SSE3 | CPUID_HTT | CPUID_CMOV | CPUID_FTZ | CPUID_DAZ;
- #endif
- return cpuid;
- }
- /*
- ===============
- Sys_GetProcessorString
- ===============
- */
- const char *Sys_GetProcessorString( void ) {
- #if defined(__ppc__)
- return "ppc CPU with AltiVec extensions";
- #elif defined(__i386__)
- return "x86 CPU with MMX/SSE/SSE2/SSE3 extensions";
- #else
- #error
- return NULL;
- #endif
- }
- /*
- ===============
- Sys_FPU_EnableExceptions
- http://developer.apple.com/documentation/mac/PPCNumerics/PPCNumerics-154.html
- http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf
- ===============
- */
- #define fegetenvd(x) asm volatile( "mffs %0" : "=f" (x) );
- #define fesetenvd(x) asm volatile( "mtfsf 255,%0" : : "f" (x) );
- enum {
- FE_ENABLE_INEXACT = 0x8,
- FE_ENABLE_DIVBYZERO = 0x10,
- FE_ENABLE_UNDERFLOW = 0x20,
- FE_ENABLE_OVERFLOW = 0x40,
- FE_ENABLE_INVALID = 0x80,
- FE_ENABLE_ALL_EXCEPT = 0xF8
- };
- typedef union {
- struct {
- unsigned long hi;
- unsigned long lo;
- } i;
- double d;
- } hexdouble;
- static int exception_mask = 0;
- void Sys_FPU_EnableExceptions( int exceptions ) {
- #if 0
- if ( exceptions & ( FPU_EXCEPTION_INVALID_OPERATION | FPU_EXCEPTION_DENORMALIZED_OPERAND ) ) {
- // clear the flag before enabling the exception
- asm( "mtfsb0 2" );
- asm( "mtfsb0 7" );
- asm( "mtfsb0 8" );
- asm( "mtfsb0 9" );
- asm( "mtfsb0 10" );
- asm( "mtfsb0 11" );
- asm( "mtfsb0 12" );
- asm( "mtfsb0 21" );
- asm( "mtfsb0 22" );
- asm( "mtfsb0 23" );
- // enable
- asm( "mtfsb1 24" );
- } else {
- asm( "mtfsb0 24" );
- }
- if ( exceptions & FPU_EXCEPTION_DIVIDE_BY_ZERO ) {
- asm( "mtfsb0 5" );
- asm( "mtfsb1 27" );
- } else {
- asm( "mtfsb0 27" );
- }
- if ( exceptions & FPU_EXCEPTION_NUMERIC_OVERFLOW ) {
- asm( "mtfsb0 3" );
- asm( "mtfsb1 25" );
- } else {
- asm( "mtfsb0 25" );
- }
- if ( exceptions & FPU_EXCEPTION_NUMERIC_UNDERFLOW ) {
- asm( "mtfsb0 4" );
- asm( "mtfsb1 26" );
- } else {
- asm( "mtfsb0 26" );
- }
- if ( exceptions & FPU_EXCEPTION_INEXACT_RESULT ) {
- asm( "mtfsb0 6" );
- asm( "mtfsb0 13" );
- asm( "mtfsb0 14" );
- asm( "mtfsb1 28" );
- } else {
- asm( "mtfsb0 28" );
- }
- #elif defined(__ppc__)
- hexdouble t;
- exception_mask = 0;
- if ( exceptions & ( FPU_EXCEPTION_INVALID_OPERATION | FPU_EXCEPTION_DENORMALIZED_OPERAND ) ) {
- exception_mask |= FE_ENABLE_INVALID;
- }
- if ( exceptions & FPU_EXCEPTION_DIVIDE_BY_ZERO ) {
- exception_mask |= FE_ENABLE_DIVBYZERO;
- }
- if ( exceptions & FPU_EXCEPTION_NUMERIC_OVERFLOW ) {
- exception_mask |= FE_ENABLE_OVERFLOW;
- }
- if ( exceptions & FPU_EXCEPTION_NUMERIC_UNDERFLOW ) {
- exception_mask |= FE_ENABLE_UNDERFLOW;
- }
- if ( exceptions & FPU_EXCEPTION_INEXACT_RESULT ) {
- exception_mask |= FE_ENABLE_INVALID;
- }
- Sys_Printf( "Sys_FPUEnableExceptions: 0x%x\n", exception_mask );
- // clear the exception flags
- feclearexcept( FE_ALL_EXCEPT );
- // set the enable flags on the exceptions we want
- fegetenvd( t.d );
- t.i.lo &= ~FE_ENABLE_ALL_EXCEPT;
- t.i.lo |= exception_mask;
- fesetenvd( t.d );
- Sys_Printf( "done\n" );
- #endif
- }
- /*
- ===============
- Sys_FPE_handler
- ===============
- */
- void Sys_FPE_handler( int signum, siginfo_t *info, void *context ) {
- #if defined(__ppc__)
- int ret;
- ppc_float_state_t *fs;
- ppc_thread_state_t *ss;
- fs = &( (struct ucontext *)context )->uc_mcontext->fs;
- ss = &( (struct ucontext *)context )->uc_mcontext->ss;
- Sys_Printf( "FPE at 0x%x:\n", info->si_addr );
- ret = fetestexcept( FE_ALL_EXCEPT );
- if ( ret & FE_INEXACT ) {
- Sys_Printf( "FE_INEXACT " );
- }
- if ( ret & FE_DIVBYZERO ) {
- Sys_Printf( "FE_DIVBYZERO " );
- }
- if ( ret & FE_UNDERFLOW ) {
- Sys_Printf( "FE_UNDERFLOW " );
- }
- if ( ret & FE_OVERFLOW ) {
- Sys_Printf( "FE_OVERFLOW " );
- }
- if ( ret & FE_INVALID ) {
- Sys_Printf( "FE_INVALID " );
- }
- Sys_Printf( "\n" );
- // clear the exception flags
- feclearexcept( FE_ALL_EXCEPT );
- // re-arm
- fs->fpscr &= exception_mask;
- ss->srr0 += 4;
- #endif
- }
- /*
- ===============
- Sys_GetClockTicks
- ===============
- */
- double Sys_GetClockTicks( void ) {
- // NOTE that this only affects idTimer atm, which is only used for performance timing during developement
- #warning FIXME: implement Sys_GetClockTicks
- return 0.0;
- }
- /*
- ===============
- Sys_ClockTicksPerSecond
- ===============
- */
- double Sys_ClockTicksPerSecond(void) {
- // Our strategy is to query both Gestalt & IOKit and then take the larger of the two values.
-
- long gestaltSpeed, ioKitSpeed = -1;
-
- // GESTALT
-
- // gestaltProcClkSpeedMHz available in 10.3 needs to be used because CPU speeds have now
- // exceeded the signed long that Gestalt returns.
- long osVers;
- OSErr err;
- Gestalt(gestaltSystemVersion, &osVers);
- if (osVers >= 0x1030)
- err = Gestalt(gestaltProcClkSpeedMHz, &gestaltSpeed);
- else
- {
- err = Gestalt(gestaltProcClkSpeed, &gestaltSpeed);
- if (err == noErr)
- gestaltSpeed = gestaltSpeed / 1000000;
- }
-
- // IO KIT
-
- mach_port_t masterPort;
- CFMutableDictionaryRef matchDict = nil;
- io_iterator_t itThis;
- io_service_t service = nil;
-
- if (IOMasterPort(MACH_PORT_NULL, &masterPort))
- goto bail;
-
- matchDict = IOServiceNameMatching("cpus");
- if (IOServiceGetMatchingServices(masterPort, matchDict, &itThis))
- goto bail;
-
- service = IOIteratorNext(itThis);
- while(service)
- {
- io_service_t ioCpu = NULL;
- if (IORegistryEntryGetChildEntry(service, kIODeviceTreePlane, &ioCpu))
- goto bail;
-
- if (ioCpu)
- {
- CFDataRef data = (CFDataRef)IORegistryEntryCreateCFProperty(ioCpu, CFSTR("clock-frequency"),kCFAllocatorDefault,0);
- if (data)
- ioKitSpeed = *((unsigned long*)CFDataGetBytePtr(data)) / 1000000;
- }
- service = IOIteratorNext(itThis);
- }
-
- // Return the larger value
-
- bail:
- return ( ioKitSpeed > gestaltSpeed ? ioKitSpeed : gestaltSpeed ) * 1000000.f;
- }
- /*
- ================
- Sys_GetSystemRam
- returns in megabytes
- ================
- */
- int Sys_GetSystemRam( void ) {
- long ramSize;
-
- if ( Gestalt( gestaltPhysicalRAMSize, &ramSize ) == noErr ) {
- return ramSize / (1024*1024);
- }
- else
- return 1024;
- }
- /*
- ================
- Sys_GetVideoRam
- returns in megabytes
- ================
- */
- int Sys_GetVideoRam( void ) {
- unsigned int i;
- CFTypeRef typeCode;
- long vramStorage = 64;
- const short MAXDISPLAYS = 8;
- CGDisplayCount displayCount;
- io_service_t dspPorts[MAXDISPLAYS];
- CGDirectDisplayID displays[MAXDISPLAYS];
- CGGetOnlineDisplayList( MAXDISPLAYS, displays, &displayCount );
-
- for ( i = 0; i < displayCount; i++ ) {
- #ifdef USE_SDL
- if ( 0 == displays[i] ) {
- #else
- if ( Sys_DisplayToUse() == displays[i] ) {
- #endif
- dspPorts[i] = CGDisplayIOServicePort(displays[i]);
- typeCode = IORegistryEntryCreateCFProperty( dspPorts[i], CFSTR("IOFBMemorySize"), kCFAllocatorDefault, kNilOptions );
- if( typeCode && CFGetTypeID( typeCode ) == CFNumberGetTypeID() ) {
- CFNumberGetValue( ( CFNumberRef )typeCode, kCFNumberSInt32Type, &vramStorage );
- vramStorage /= (1024*1024);
- }
- }
- }
- return vramStorage;
- }
- bool OSX_GetCPUIdentification( int& cpuId, bool& oldArchitecture )
- {
- long cpu;
- Gestalt(gestaltNativeCPUtype, &cpu);
-
- cpuId = cpu;
- oldArchitecture = cpuId < gestaltCPU970;
- return true;
- }
- void OSX_GetVideoCard( int& outVendorId, int& outDeviceId )
- {
- kern_return_t err;
- mach_port_t masterPort;
- io_iterator_t itThis;
- io_service_t service;
-
- outVendorId = -1;
- outDeviceId = -1;
-
- // Get a mach port for us and check for errors
- err = IOMasterPort(MACH_PORT_NULL, &masterPort);
- if(err)
- return;
- // Grab all the PCI devices out of the registry
- err = IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOPCIDevice"), &itThis);
- if(err)
- return;
-
- // Yank everything out of the iterator
- // We could walk through all devices and try to determine the best card. But for now,
- // we'll just look at the first card.
- while(1)
- {
- service = IOIteratorNext(itThis);
- io_name_t dName;
-
- // Make sure we have a valid service
- if(service)
- {
- // Get the classcode so we know what we're looking at
- CFDataRef classCode = (CFDataRef)IORegistryEntryCreateCFProperty(service,CFSTR("class-code"),kCFAllocatorDefault,0);
- // Only accept devices that are
- // PCI Spec - 0x00030000 is a display device
- if((*(UInt32*)CFDataGetBytePtr(classCode) & 0x00ff0000) == 0x00030000)
- {
- // Get the name of the service (hw)
- IORegistryEntryGetName(service, dName);
-
- CFDataRef vendorID, deviceID;
-
- // Get the information for the device we've selected from the list
- vendorID = (CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("vendor-id"),kCFAllocatorDefault,0);
- deviceID = (CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("device-id"),kCFAllocatorDefault,0);
-
- outVendorId = *((long*)CFDataGetBytePtr(vendorID));
- outDeviceId = *((long*)CFDataGetBytePtr(deviceID));
-
- CFRelease(vendorID);
- CFRelease(deviceID);
- }
- CFRelease(classCode);
-
- // Stop after finding the first device
- if (outVendorId != -1)
- break;
- }
- else
- break;
- }
- }
- /*
- ===============
- main
- ===============
- */
- int main( int argc, const char *argv[] ) {
- return NSApplicationMain( argc, argv );
- }
- #pragma mark -
- bool FormatRegCode(const char* inRegCode, char* outRegCode)
- {
- // Clean up the reg code. Remove spaces. Accept only numbers/letters.
- char* dst = outRegCode;
- const char* src = inRegCode;
- while (*src)
- {
- if (isalnum(*src))
- *dst++ = *src;
- else if (*src != ' ')
- return false;
- src++;
- }
- *dst = 0;
-
- // Reg codes are 18 characters in length
- return strlen(outRegCode) == 18;
- }
- /*
- ===============
- RegCodeHandler
- ===============
- */
- static pascal OSStatus RegCodeHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* inUserData )
- {
- #pragma unused( inHandler )
- #if 1
- // FIXME: the CD key API has changed for startup check support and expansion pack key support
- return noErr;
- #else
- HICommand cmd;
- OSStatus result = eventNotHandledErr;
- RegCodeInfo* regCodeInfo = (RegCodeInfo*)inUserData;
-
- GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof( cmd ), NULL, &cmd );
-
- switch ( cmd.commandID ) {
- case kHICommandOK:
- bool fValid;
- Size actualSize;
- char cntrl[256];
- char doomKey[256];
- char strippedKey[256];
-
- fValid = false;
- strippedKey[0] = doomKey[0] = NULL;
- GetControlData ( regCodeInfo->regCode1EditText, kControlEntireControl, kControlEditTextTextTag, 256, cntrl, &actualSize );
- cntrl[actualSize] = NULL;
- if ( FormatRegCode( cntrl, strippedKey ) ) {
- strncat( doomKey, strippedKey, 16 );
- strcat( doomKey, " " );
- strncat( doomKey, strippedKey + 16, 2 );
- fValid = session->CheckKey( doomKey );
- }
- if ( fValid ) {
- strcpy( regCodeInfo->prefRegCode1, doomKey );
- session->SetCDKey( doomKey );
- }
- else {
- unsigned char theError[512];
- unsigned char theExplanation[512];
- CFStringRef theErrorStr = CFCopyLocalizedString( CFSTR("DVD_KEY_ERROR"), "" );
- CFStringRef theExplanationStr = CFCopyLocalizedString( CFSTR("DVD_KEY_EXPLANATION"), "" );
- c2pstrcpy( theError, CFStringGetCStringPtr( theErrorStr, kCFStringEncodingMacRoman ) );
- c2pstrcpy( theExplanation, CFStringGetCStringPtr( theExplanationStr, kCFStringEncodingMacRoman ) );
-
- StandardAlert(kAlertStopAlert, theError, theExplanation, NULL, NULL);
-
- // Highlight the invalid reg code
- ClearKeyboardFocus(regCodeInfo->window);
- SetKeyboardFocus( regCodeInfo->window, regCodeInfo->regCode1EditText, kControlEditTextPart );
- ControlEditTextSelectionRec sel = {0, 32000};
- SetControlData (regCodeInfo->regCode1EditText, kControlEntireControl, kControlEditTextSelectionTag, sizeof(sel), &sel);
- break;
- }
-
- regCodeInfo->okPressed = true;
- QuitAppModalLoopForWindow( regCodeInfo->window );
- result = noErr;
-
- break;
-
- case kHICommandCancel:
- regCodeInfo->okPressed = false;
- QuitAppModalLoopForWindow( regCodeInfo->window );
- result = noErr;
- break;
-
- }
- return result;
- #endif
- }
- /*
- ===============
- DoRegCodeDialog
- ===============
- */
- static OSErr DoRegCodeDialog( char* ioRegCode1 )
- {
- OSErr err;
- RegCodeInfo regCodeInfo;
- memset(®CodeInfo, 0, sizeof(regCodeInfo));
-
- IBNibRef aslNib;
- CFBundleRef theBundle = CFBundleGetMainBundle();
- err = CreateNibReferenceWithCFBundle( theBundle, CFSTR("ASLCore"), &aslNib );
- err = ::CreateWindowFromNib( aslNib, CFSTR("Reg Code Sheet"), ®CodeInfo.window );
- if (err != noErr)
- return err;
-
- GetControlByID( regCodeInfo.window, &kRegCode1EditText, ®CodeInfo.regCode1EditText );
- assert( regCodeInfo.regCode1EditText );
- SetKeyboardFocus( regCodeInfo.window, regCodeInfo.regCode1EditText, kControlEditTextPart );
- ControlEditTextSelectionRec sel = {0, 32000};
- SetControlData (regCodeInfo.regCode1EditText, kControlEntireControl, kControlEditTextSelectionTag, sizeof(sel), &sel);
-
- EventTypeSpec cmdEvent = { kEventClassCommand, kEventCommandProcess };
- EventHandlerUPP handler = NewEventHandlerUPP( RegCodeHandler );
- InstallWindowEventHandler( regCodeInfo.window, handler, 1, &cmdEvent, ®CodeInfo, NULL );
-
- RepositionWindow( regCodeInfo.window, NULL, kWindowAlertPositionOnMainScreen );
- ShowWindow( regCodeInfo.window );
-
- RunAppModalLoopForWindow( regCodeInfo.window );
-
- DisposeWindow( regCodeInfo.window );
-
- if (regCodeInfo.okPressed) {
- strcpy(ioRegCode1, regCodeInfo.prefRegCode1);
- }
-
- return regCodeInfo.okPressed ? (OSErr)noErr : (OSErr)userCanceledErr;
- }
- /*
- =================
- Sys_AsyncThread
- =================
- */
- void Sys_AsyncThread( void ) {
- while ( 1 ) {
- usleep( 16666 );
- common->Async();
- Sys_TriggerEvent( TRIGGER_EVENT_ONE );
- pthread_testcancel();
- }
- }
- #if defined(__ppc__)
- /*
- ================
- Sys_FPU_SetDAZ
- ================
- */
- void Sys_FPU_SetDAZ( bool enable ) {
- }
- /*
- ================
- Sys_FPU_SetFTZ
- ================
- */
- void Sys_FPU_SetFTZ( bool enable ) {
- }
- #elif defined(__i386__)
- #include <xmmintrin.h>
- /*
- ================
- Sys_FPU_SetDAZ
- ================
- */
- void Sys_FPU_SetDAZ( bool enable ) {
- uint32_t dwData;
- uint32_t enable_l = (uint32_t) enable;
-
- enable_l = enable_l & 1;
- enable_l = enable_l << 6;
- dwData = _mm_getcsr(); // store MXCSR to dwData
- dwData = dwData & 0xffbf;
- dwData = dwData | enable_l;
- _mm_setcsr(dwData); // load MXCSR with dwData
- }
- /*
- ================
- Sys_FPU_SetFTZ
- ================
- */
- void Sys_FPU_SetFTZ( bool enable ) {
-
- uint32_t dwData;
- uint32_t enable_l = (uint32_t) enable;
-
- enable_l = enable_l & 1;
- enable_l = enable_l << 15;
- dwData = _mm_getcsr(); // store MXCSR to dwData
- dwData = dwData & 0x7fff;
- dwData = dwData | enable_l;
- _mm_setcsr(dwData); // load MXCSR with dwData
- }
- #endif
|