2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 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.
24 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.
26 ===========================================================================
30 #import "../../idlib/precompiled.h"
31 #import "DOOMController.h"
36 #import <Foundation/Foundation.h>
37 #import <Carbon/Carbon.h>
38 #import <AppKit/AppKit.h>
41 #import "macosx_common.h"
42 #import "macosx_local.h"
43 #import "macosx_sys.h"
46 //#import <ucontext.h>
47 #import <mach/thread_status.h>
51 static idStr savepath;
53 extern bool key_overstrikeMode;
55 #define TEST_FPU_EXCEPTIONS \
56 FPU_EXCEPTION_INVALID_OPERATION | \
57 FPU_EXCEPTION_DENORMALIZED_OPERAND | \
58 FPU_EXCEPTION_DIVIDE_BY_ZERO | \
59 /* FPU_EXCEPTION_NUMERIC_OVERFLOW | */ \
60 /* FPU_EXCEPTION_NUMERIC_UNDERFLOW | */ \
61 /* FPU_EXCEPTION_INEXACT_RESULT | */ \
64 #define kRegKey @"RegCode"
66 static const ControlID kRegCode1EditText = { 'RegC', 1 };
70 char prefRegCode1[256];
73 ControlRef regCode1EditText;
76 static OSErr DoRegCodeDialog( char* ioRegCode1 );
79 @interface DOOMController (Private)
81 - (BOOL)checkRegCodes;
85 @implementation DOOMController
90 static bool initialized = NO;
100 #define MAX_ARGC 1024
102 - (void)applicationDidFinishLaunching:(NSNotification *)notification;
105 NSAssert(sizeof(bool) == 1, @"sizeof(bool) should equal 1 byte");
108 Sys_Error( (const char *)[ [ localException reason ] cString ] );
113 - (void)applicationWillHide:(NSNotification *)notification;
118 - (void)applicationWillUnhide:(NSNotification *)notification;
123 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
126 return NSTerminateLater; // we never reach this
132 - (IBAction)paste:(id)sender;
134 int shiftWasDown, insertWasDown;
135 unsigned int currentTime;
137 currentTime = Sys_Milliseconds();
138 // Save the original keyboard state
139 shiftWasDown = keys[K_SHIFT].down;
140 insertWasDown = keys[K_INS].down;
141 // Fake a Shift-Insert keyboard event
142 keys[K_SHIFT].down = true;
143 Posix_QueEvent(currentTime, SE_KEY, K_INS, true, 0, NULL);
144 Posix_QueEvent(currentTime, SE_KEY, K_INS, false, 0, NULL);
145 // Restore the original keyboard state
146 keys[K_SHIFT].down = shiftWasDown;
147 keys[K_INS].down = insertWasDown;
150 extern void CL_Quit_f(void);
151 //extern void SetProgramPath(const char *path);
154 - (IBAction)requestTerminate:(id)sender;
162 static bool hasShownBanner = NO;
164 if (!hasShownBanner) {
165 //cvar_t *showBanner;
167 hasShownBanner = YES;
168 //showBanner = Cvar_Get("cl_showBanner", "1", 0);
169 //if ( showBanner->integer != 0 ) {
171 NSPanel *splashPanel;
172 NSImage *bannerImage;
174 NSImageView *bannerImageView;
176 bannerImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"banner.jpg"]];
177 bannerRect = NSMakeRect(0.0, 0.0, [bannerImage size].width, [bannerImage size].height);
179 splashPanel = [[NSPanel alloc] initWithContentRect:bannerRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
181 bannerImageView = [[NSImageView alloc] initWithFrame:bannerRect];
182 [bannerImageView setImage:bannerImage];
183 [splashPanel setContentView:bannerImageView];
184 [bannerImageView release];
186 [splashPanel center];
187 [splashPanel setHasShadow:YES];
188 [splashPanel orderFront: nil];
189 [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.5]];
192 [bannerImage release];
199 - (void)connectToServer:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error;
201 NSArray *pasteboardTypes;
203 pasteboardTypes = [pasteboard types];
204 if ([pasteboardTypes containsObject:NSStringPboardType]) {
205 NSString *requestedServer;
207 requestedServer = [pasteboard stringForType:NSStringPboardType];
208 if (requestedServer) {
209 Cbuf_AddText( va( "connect %s\n", [requestedServer cString]));
213 *error = @"Unable to connect to server: could not find string on pasteboard";
216 - (void)performCommand:(NSPasteboard *)pasteboard userData:(NSString *)data error:(NSString **)error;
218 NSArray *pasteboardTypes;
220 pasteboardTypes = [pasteboard types];
221 if ([pasteboardTypes containsObject:NSStringPboardType]) {
222 NSString *requestedCommand;
224 requestedCommand = [pasteboard stringForType:NSStringPboardType];
225 if (requestedCommand) {
226 Cbuf_AddText(va("%s\n", [requestedCommand cString]));
230 *error = @"Unable to perform command: could not find string on pasteboard";
233 #endif // commented out all the banners and actions
237 @implementation DOOMController (Private)
241 NSAutoreleasePool *pool;
243 const char *argv[MAX_ARGC];
244 NSProcessInfo *processInfo;
246 unsigned int argumentIndex, argumentCount;
248 //NSFileManager *defaultManager;
251 pool = [[NSAutoreleasePool alloc] init];
253 [NSApp setServicesProvider:self];
255 processInfo = [NSProcessInfo processInfo];
256 arguments = [processInfo arguments];
257 argumentCount = [arguments count];
258 for (argumentIndex = 0; argumentIndex < argumentCount; argumentIndex++) {
259 argv[argc++] = strdup([[arguments objectAtIndex:argumentIndex] cString]);
261 if (![[NSFileManager defaultManager] changeCurrentDirectoryPath:[[NSBundle mainBundle] resourcePath]]) {
262 Sys_Error("Could not access application resources");
264 //cddir = macosx_scanForLibraryDirectory();
268 defaultManager = [NSFileManager defaultManager];
269 if (![defaultManager fileExistsAtPath:@"./base/default.cfg"] && (!cddir || *cddir == '\0' || ![defaultManager fileExistsAtPath:[NSString stringWithFormat:@"%s/baseq3/pak0.pk3", cddir]])) {
272 if (!cddir || *cddir == '\0') {
273 message = [NSString stringWithFormat:@"Could not find DOOM levels."];
274 } else if (![defaultManager fileExistsAtPath:[NSString stringWithFormat:@"%s", cddir]]) {
275 message = [NSString stringWithFormat:@"Could not find DOOM levels: '%s' does not exist.", cddir];
277 message = [NSString stringWithFormat:@"Could not find DOOM levels: '%s' is not a complete DOOM installation.", cddir];
279 switch (NSRunAlertPanel(@"DOOM", @"%@", @"Quit", @"Find...", nil, message)) {
280 case NSAlertDefaultReturn:
284 case NSAlertAlternateReturn:
289 NSOpenPanel *openPanel;
292 openPanel = [NSOpenPanel openPanel];
293 [openPanel setAllowsMultipleSelection:NO];
294 [openPanel setCanChooseDirectories:YES];
295 [openPanel setCanChooseFiles:NO];
296 result = [openPanel runModalForDirectory:nil file:nil];
297 if (result == NSOKButton) {
300 filenames = [openPanel filenames];
301 if ([filenames count] == 1) {
304 cdPath = [filenames objectAtIndex:0];
305 [[NSUserDefaults standardUserDefaults] setObject:cdPath forKey:@"CDPath"];
306 cddir = strdup([cdPath cString]);
314 if (cddir && *cddir != '\0') {
315 SetProgramPath([[[NSString stringWithCString:cddir] stringByAppendingPathComponent:@"/x"] cString]);
319 //Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS );
324 if ( [self checkOS] == FALSE) {
328 if ( [self checkDVD] == FALSE) {
333 // need strncmp, can't use idlib before init
335 // Finder passes the process serial number as only argument after the program path
336 // nuke it if we see it
337 if ( argc > 1 && strncmp( argv[ 1 ], "-psn", 4 ) ) {
338 common->Init( argc-1, &argv[1], NULL );
340 common->Init( 0, NULL, NULL );
345 [NSApp activateIgnoringOtherApps:YES];
349 OTPeriodicTimerReset();
350 OTNodeStart(RootNode);
353 // maintain exceptions in case system calls are turning them off (is that needed)
354 //Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS );
358 // We should think about doing this less frequently than every frame
360 pool = [[NSAutoreleasePool alloc] init];
362 OTNodeStop(RootNode);
369 - (BOOL)checkRegCodes
373 NSUserDefaults *userDefaults;
375 userDefaults = [NSUserDefaults standardUserDefaults];
376 cdKey = [userDefaults stringForKey:kRegKey];
379 if ( cdKey == nil || [cdKey length] == 0 ) {
381 if ( DoRegCodeDialog( regCode ) != noErr ) {
385 [userDefaults setObject:[NSString stringWithCString: regCode] forKey:kRegKey];
386 [userDefaults synchronize];
395 long gestaltOSVersion;
396 err = Gestalt(gestaltSystemVersion, &gestaltOSVersion);
397 if ( err || gestaltOSVersion < 0x1038 ) {
398 NSBundle *thisBundle = [ NSBundle mainBundle ];
399 NSString *messsage = [ thisBundle localizedStringForKey:@"InsufficientOS" value:@"No translation" table:nil ];
400 NSRunAlertPanel(@GAME_NAME, messsage, nil, nil, nil);
418 const char *Sys_EXEPath( void ) {
419 static char exepath[ 1024 ];
420 strncpy( exepath, [ [ [ NSBundle mainBundle ] bundlePath ] cString ], 1024 );
429 const char *Sys_DefaultSavePath(void) {
430 #if defined( ID_DEMO_BUILD )
431 sprintf( savepath, "%s/Library/Application Support/Doom 3 Demo", [NSHomeDirectory() cString] );
433 sprintf( savepath, "%s/Library/Application Support/Doom 3", [NSHomeDirectory() cString] );
435 return savepath.c_str();
443 const char *Sys_DefaultBasePath(void) {
444 static char basepath[ 1024 ];
445 strncpy( basepath, [ [ [ NSBundle mainBundle ] bundlePath ] cString ], 1024 );
446 char *snap = strrchr( basepath, '/' );
458 void Sys_Shutdown( void ) {
469 cpuid_t Sys_GetProcessorId( void ) {
470 cpuid_t cpuid = CPUID_GENERIC;
472 cpuid |= CPUID_ALTIVEC;
473 #elif defined(__i386__)
474 cpuid |= CPUID_INTEL | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | CPUID_SSE3 | CPUID_HTT | CPUID_CMOV | CPUID_FTZ | CPUID_DAZ;
481 Sys_GetProcessorString
484 const char *Sys_GetProcessorString( void ) {
486 return "ppc CPU with AltiVec extensions";
487 #elif defined(__i386__)
488 return "x86 CPU with MMX/SSE/SSE2/SSE3 extensions";
497 Sys_FPU_EnableExceptions
498 http://developer.apple.com/documentation/mac/PPCNumerics/PPCNumerics-154.html
499 http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf
503 #define fegetenvd(x) asm volatile( "mffs %0" : "=f" (x) );
504 #define fesetenvd(x) asm volatile( "mtfsf 255,%0" : : "f" (x) );
506 FE_ENABLE_INEXACT = 0x8,
507 FE_ENABLE_DIVBYZERO = 0x10,
508 FE_ENABLE_UNDERFLOW = 0x20,
509 FE_ENABLE_OVERFLOW = 0x40,
510 FE_ENABLE_INVALID = 0x80,
511 FE_ENABLE_ALL_EXCEPT = 0xF8
522 static int exception_mask = 0;
524 void Sys_FPU_EnableExceptions( int exceptions ) {
526 if ( exceptions & ( FPU_EXCEPTION_INVALID_OPERATION | FPU_EXCEPTION_DENORMALIZED_OPERAND ) ) {
527 // clear the flag before enabling the exception
543 if ( exceptions & FPU_EXCEPTION_DIVIDE_BY_ZERO ) {
549 if ( exceptions & FPU_EXCEPTION_NUMERIC_OVERFLOW ) {
555 if ( exceptions & FPU_EXCEPTION_NUMERIC_UNDERFLOW ) {
561 if ( exceptions & FPU_EXCEPTION_INEXACT_RESULT ) {
569 #elif defined(__ppc__)
572 if ( exceptions & ( FPU_EXCEPTION_INVALID_OPERATION | FPU_EXCEPTION_DENORMALIZED_OPERAND ) ) {
573 exception_mask |= FE_ENABLE_INVALID;
575 if ( exceptions & FPU_EXCEPTION_DIVIDE_BY_ZERO ) {
576 exception_mask |= FE_ENABLE_DIVBYZERO;
578 if ( exceptions & FPU_EXCEPTION_NUMERIC_OVERFLOW ) {
579 exception_mask |= FE_ENABLE_OVERFLOW;
581 if ( exceptions & FPU_EXCEPTION_NUMERIC_UNDERFLOW ) {
582 exception_mask |= FE_ENABLE_UNDERFLOW;
584 if ( exceptions & FPU_EXCEPTION_INEXACT_RESULT ) {
585 exception_mask |= FE_ENABLE_INVALID;
587 Sys_Printf( "Sys_FPUEnableExceptions: 0x%x\n", exception_mask );
588 // clear the exception flags
589 feclearexcept( FE_ALL_EXCEPT );
590 // set the enable flags on the exceptions we want
592 t.i.lo &= ~FE_ENABLE_ALL_EXCEPT;
593 t.i.lo |= exception_mask;
595 Sys_Printf( "done\n" );
604 void Sys_FPE_handler( int signum, siginfo_t *info, void *context ) {
607 ppc_float_state_t *fs;
608 ppc_thread_state_t *ss;
610 fs = &( (struct ucontext *)context )->uc_mcontext->fs;
611 ss = &( (struct ucontext *)context )->uc_mcontext->ss;
613 Sys_Printf( "FPE at 0x%x:\n", info->si_addr );
615 ret = fetestexcept( FE_ALL_EXCEPT );
616 if ( ret & FE_INEXACT ) {
617 Sys_Printf( "FE_INEXACT " );
619 if ( ret & FE_DIVBYZERO ) {
620 Sys_Printf( "FE_DIVBYZERO " );
622 if ( ret & FE_UNDERFLOW ) {
623 Sys_Printf( "FE_UNDERFLOW " );
625 if ( ret & FE_OVERFLOW ) {
626 Sys_Printf( "FE_OVERFLOW " );
628 if ( ret & FE_INVALID ) {
629 Sys_Printf( "FE_INVALID " );
632 // clear the exception flags
633 feclearexcept( FE_ALL_EXCEPT );
635 fs->fpscr &= exception_mask;
645 double Sys_GetClockTicks( void ) {
646 // NOTE that this only affects idTimer atm, which is only used for performance timing during developement
647 #warning FIXME: implement Sys_GetClockTicks
653 Sys_ClockTicksPerSecond
656 double Sys_ClockTicksPerSecond(void) {
657 // Our strategy is to query both Gestalt & IOKit and then take the larger of the two values.
659 long gestaltSpeed, ioKitSpeed = -1;
663 // gestaltProcClkSpeedMHz available in 10.3 needs to be used because CPU speeds have now
664 // exceeded the signed long that Gestalt returns.
667 Gestalt(gestaltSystemVersion, &osVers);
668 if (osVers >= 0x1030)
669 err = Gestalt(gestaltProcClkSpeedMHz, &gestaltSpeed);
672 err = Gestalt(gestaltProcClkSpeed, &gestaltSpeed);
674 gestaltSpeed = gestaltSpeed / 1000000;
679 mach_port_t masterPort;
680 CFMutableDictionaryRef matchDict = nil;
681 io_iterator_t itThis;
682 io_service_t service = nil;
684 if (IOMasterPort(MACH_PORT_NULL, &masterPort))
687 matchDict = IOServiceNameMatching("cpus");
688 if (IOServiceGetMatchingServices(masterPort, matchDict, &itThis))
691 service = IOIteratorNext(itThis);
694 io_service_t ioCpu = NULL;
695 if (IORegistryEntryGetChildEntry(service, kIODeviceTreePlane, &ioCpu))
700 CFDataRef data = (CFDataRef)IORegistryEntryCreateCFProperty(ioCpu, CFSTR("clock-frequency"),kCFAllocatorDefault,0);
702 ioKitSpeed = *((unsigned long*)CFDataGetBytePtr(data)) / 1000000;
704 service = IOIteratorNext(itThis);
707 // Return the larger value
710 return ( ioKitSpeed > gestaltSpeed ? ioKitSpeed : gestaltSpeed ) * 1000000.f;
719 int Sys_GetSystemRam( void ) {
722 if ( Gestalt( gestaltPhysicalRAMSize, &ramSize ) == noErr ) {
723 return ramSize / (1024*1024);
735 int Sys_GetVideoRam( void ) {
738 long vramStorage = 64;
739 const short MAXDISPLAYS = 8;
740 CGDisplayCount displayCount;
741 io_service_t dspPorts[MAXDISPLAYS];
742 CGDirectDisplayID displays[MAXDISPLAYS];
744 CGGetOnlineDisplayList( MAXDISPLAYS, displays, &displayCount );
746 for ( i = 0; i < displayCount; i++ ) {
747 if ( Sys_DisplayToUse() == displays[i] ) {
748 dspPorts[i] = CGDisplayIOServicePort(displays[i]);
749 typeCode = IORegistryEntryCreateCFProperty( dspPorts[i], CFSTR("IOFBMemorySize"), kCFAllocatorDefault, kNilOptions );
750 if( typeCode && CFGetTypeID( typeCode ) == CFNumberGetTypeID() ) {
751 CFNumberGetValue( ( CFNumberRef )typeCode, kCFNumberSInt32Type, &vramStorage );
752 vramStorage /= (1024*1024);
760 bool OSX_GetCPUIdentification( int& cpuId, bool& oldArchitecture )
763 Gestalt(gestaltNativeCPUtype, &cpu);
766 oldArchitecture = cpuId < gestaltCPU970;
770 void OSX_GetVideoCard( int& outVendorId, int& outDeviceId )
773 mach_port_t masterPort;
774 io_iterator_t itThis;
775 io_service_t service;
780 // Get a mach port for us and check for errors
781 err = IOMasterPort(MACH_PORT_NULL, &masterPort);
784 // Grab all the PCI devices out of the registry
785 err = IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOPCIDevice"), &itThis);
789 // Yank everything out of the iterator
790 // We could walk through all devices and try to determine the best card. But for now,
791 // we'll just look at the first card.
794 service = IOIteratorNext(itThis);
797 // Make sure we have a valid service
800 // Get the classcode so we know what we're looking at
801 CFDataRef classCode = (CFDataRef)IORegistryEntryCreateCFProperty(service,CFSTR("class-code"),kCFAllocatorDefault,0);
802 // Only accept devices that are
803 // PCI Spec - 0x00030000 is a display device
804 if((*(UInt32*)CFDataGetBytePtr(classCode) & 0x00ff0000) == 0x00030000)
806 // Get the name of the service (hw)
807 IORegistryEntryGetName(service, dName);
809 CFDataRef vendorID, deviceID;
811 // Get the information for the device we've selected from the list
812 vendorID = (CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("vendor-id"),kCFAllocatorDefault,0);
813 deviceID = (CFDataRef)IORegistryEntryCreateCFProperty(service, CFSTR("device-id"),kCFAllocatorDefault,0);
815 outVendorId = *((long*)CFDataGetBytePtr(vendorID));
816 outDeviceId = *((long*)CFDataGetBytePtr(deviceID));
821 CFRelease(classCode);
823 // Stop after finding the first device
824 if (outVendorId != -1)
837 int main( int argc, const char *argv[] ) {
838 return NSApplicationMain( argc, argv );
844 bool FormatRegCode(const char* inRegCode, char* outRegCode)
846 // Clean up the reg code. Remove spaces. Accept only numbers/letters.
847 char* dst = outRegCode;
848 const char* src = inRegCode;
853 else if (*src != ' ')
859 // Reg codes are 18 characters in length
860 return strlen(outRegCode) == 18;
868 static pascal OSStatus RegCodeHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* inUserData )
870 #pragma unused( inHandler )
872 // FIXME: the CD key API has changed for startup check support and expansion pack key support
876 OSStatus result = eventNotHandledErr;
877 RegCodeInfo* regCodeInfo = (RegCodeInfo*)inUserData;
879 GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof( cmd ), NULL, &cmd );
881 switch ( cmd.commandID ) {
887 char strippedKey[256];
890 strippedKey[0] = doomKey[0] = NULL;
891 GetControlData ( regCodeInfo->regCode1EditText, kControlEntireControl, kControlEditTextTextTag, 256, cntrl, &actualSize );
892 cntrl[actualSize] = NULL;
893 if ( FormatRegCode( cntrl, strippedKey ) ) {
894 strncat( doomKey, strippedKey, 16 );
895 strcat( doomKey, " " );
896 strncat( doomKey, strippedKey + 16, 2 );
897 fValid = session->CheckKey( doomKey );
900 strcpy( regCodeInfo->prefRegCode1, doomKey );
901 session->SetCDKey( doomKey );
904 unsigned char theError[512];
905 unsigned char theExplanation[512];
906 CFStringRef theErrorStr = CFCopyLocalizedString( CFSTR("DVD_KEY_ERROR"), "" );
907 CFStringRef theExplanationStr = CFCopyLocalizedString( CFSTR("DVD_KEY_EXPLANATION"), "" );
908 c2pstrcpy( theError, CFStringGetCStringPtr( theErrorStr, kCFStringEncodingMacRoman ) );
909 c2pstrcpy( theExplanation, CFStringGetCStringPtr( theExplanationStr, kCFStringEncodingMacRoman ) );
911 StandardAlert(kAlertStopAlert, theError, theExplanation, NULL, NULL);
913 // Highlight the invalid reg code
914 ClearKeyboardFocus(regCodeInfo->window);
915 SetKeyboardFocus( regCodeInfo->window, regCodeInfo->regCode1EditText, kControlEditTextPart );
916 ControlEditTextSelectionRec sel = {0, 32000};
917 SetControlData (regCodeInfo->regCode1EditText, kControlEntireControl, kControlEditTextSelectionTag, sizeof(sel), &sel);
921 regCodeInfo->okPressed = true;
922 QuitAppModalLoopForWindow( regCodeInfo->window );
927 case kHICommandCancel:
928 regCodeInfo->okPressed = false;
929 QuitAppModalLoopForWindow( regCodeInfo->window );
943 static OSErr DoRegCodeDialog( char* ioRegCode1 )
946 RegCodeInfo regCodeInfo;
947 memset(®CodeInfo, 0, sizeof(regCodeInfo));
950 CFBundleRef theBundle = CFBundleGetMainBundle();
951 err = CreateNibReferenceWithCFBundle( theBundle, CFSTR("ASLCore"), &aslNib );
952 err = ::CreateWindowFromNib( aslNib, CFSTR("Reg Code Sheet"), ®CodeInfo.window );
956 GetControlByID( regCodeInfo.window, &kRegCode1EditText, ®CodeInfo.regCode1EditText );
957 assert( regCodeInfo.regCode1EditText );
958 SetKeyboardFocus( regCodeInfo.window, regCodeInfo.regCode1EditText, kControlEditTextPart );
959 ControlEditTextSelectionRec sel = {0, 32000};
960 SetControlData (regCodeInfo.regCode1EditText, kControlEntireControl, kControlEditTextSelectionTag, sizeof(sel), &sel);
962 EventTypeSpec cmdEvent = { kEventClassCommand, kEventCommandProcess };
963 EventHandlerUPP handler = NewEventHandlerUPP( RegCodeHandler );
964 InstallWindowEventHandler( regCodeInfo.window, handler, 1, &cmdEvent, ®CodeInfo, NULL );
966 RepositionWindow( regCodeInfo.window, NULL, kWindowAlertPositionOnMainScreen );
967 ShowWindow( regCodeInfo.window );
969 RunAppModalLoopForWindow( regCodeInfo.window );
971 DisposeWindow( regCodeInfo.window );
973 if (regCodeInfo.okPressed) {
974 strcpy(ioRegCode1, regCodeInfo.prefRegCode1);
977 return regCodeInfo.okPressed ? (OSErr)noErr : (OSErr)userCanceledErr;
985 void Sys_AsyncThread( void ) {
989 Sys_TriggerEvent( TRIGGER_EVENT_ONE );
990 pthread_testcancel();
1002 void Sys_FPU_SetDAZ( bool enable ) {
1010 void Sys_FPU_SetFTZ( bool enable ) {
1014 #elif defined(__i386__)
1016 #include <xmmintrin.h>
1023 void Sys_FPU_SetDAZ( bool enable ) {
1025 uint32_t enable_l = (uint32_t) enable;
1027 enable_l = enable_l & 1;
1028 enable_l = enable_l << 6;
1029 dwData = _mm_getcsr(); // store MXCSR to dwData
1030 dwData = dwData & 0xffbf;
1031 dwData = dwData | enable_l;
1032 _mm_setcsr(dwData); // load MXCSR with dwData
1040 void Sys_FPU_SetFTZ( bool enable ) {
1043 uint32_t enable_l = (uint32_t) enable;
1045 enable_l = enable_l & 1;
1046 enable_l = enable_l << 15;
1047 dwData = _mm_getcsr(); // store MXCSR to dwData
1048 dwData = dwData & 0x7fff;
1049 dwData = dwData | enable_l;
1050 _mm_setcsr(dwData); // load MXCSR with dwData