#include #include #include #include #include #include #include "controls.h" #include "initexit.h" #include "config.h" #include "screen.h" #include "textures.h" #include "renderframe.h" #include "environment.h" #include "gameinitexit.h" #include "gametime.h" #include "gameframe.h" #include "error.h" #include "network.h" #include "interfaceutil.h" #include "models.h" #include "text.h" #include "GetPID.h" #include "gamesound.h" int gSystemSuspended=false; int gInGame=false; pthread_mutex_t gASMutex; // http://developer.apple.com/qa/qa2001/qa1111.html // Creates an AppleEvent with one text parameter. We leave it up to the AppleScript // to further parse the text parameter into potentially more parameters. static OSStatus CreateMessageEvent( AppleEvent *theEvent, char *parameter ) { OSStatus err; ProcessSerialNumber psn = {0, kCurrentProcess}; err = AEBuildAppleEvent( 'ascr', kASSubroutineEvent, typeProcessSerialNumber, (Ptr) &psn, sizeof(psn), kAutoGenerateReturnID, kAnyTransactionID, theEvent, NULL, "'----':[TEXT(@)]," // One TEXT pointer parameter "'snam':TEXT(@)", // The keyASSubroutineName ('snam') parameter must contain the name of the subroutine that is being called with every letter converted to lowercase. For example, if name of the subroutine in your script is "GetDocumentSize", then the string provided in the keyASSubroutineName parameter should be "getdocumentsize". parameter, "applescriptentry"); // The entry routine whithin the AppleScript return( err ); } /***************************************************** * * ExecuteCompiledAppleScriptEvent( AEDesc *scriptData, AppleEvent *theEvent, AEDesc *resultData ) * * Purpose: Generic routine to execute our AppleScriptEvent, passing parameters to an * AppleScript running inside my application * * Notes: http://developer.apple.com/qa/qa2001/qa1111.html * * Inputs: scriptData - Reference to the AppleScript to be executed * theEvent - text parameter to our AppleScript as an AppleEvent * resultData - result from script * * Returns: OSStatus - error code (0 == no error) */ typedef struct{ int inited; ComponentInstance theComponent; OSAID contextID; } tScriptData; OSStatus ExecuteCompiledAppleScriptEvent( AEDesc *scriptData, AppleEvent *theEvent, AEDesc *resultData,tScriptData *scriptStore) { OSStatus err; ComponentInstance theComponent = NULL; OSAID contextID = kOSANullScript; OSAID resultID = kOSANullScript; int inited=false; if(scriptStore) if(scriptStore->inited) { theComponent=scriptStore->theComponent; contextID=scriptStore->contextID; inited=true; } if(!inited) { theComponent = OpenDefaultComponent( kOSAComponentType, typeAppleScript ); // Open the scripting component if ( theComponent == NULL ) { err = paramErr; goto Bail; } err = OSALoad( theComponent, scriptData, kOSAModeNull, &contextID ); // Compile the script into a new context require_noerr( err, Bail ); } err = OSAExecuteEvent( theComponent, theEvent, contextID, kOSAModeNull, &resultID ); // Run the script if ( resultData != NULL ) // Collect the results - if any { AECreateDesc( typeNull, NULL, 0, resultData ); /*if ( err == errOSAScriptError ) OSAScriptError( theComponent, kOSAErrorMessage, typeChar, resultData ); else*/ if ( (err == noErr) && (resultID != kOSANullScript) ) OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, resultData); } Bail: if ( resultID != kOSANullScript ) OSADispose( theComponent, resultID ); if(!scriptStore) { if ( contextID != kOSANullScript ) OSADispose( theComponent, contextID ); if ( theComponent != NULL ) CloseComponent( theComponent ); } else { scriptStore->inited=true; scriptStore->theComponent=theComponent; scriptStore->contextID=contextID; } return( err ); } /***************************************************** * * RunAppleScript( FSRef *scriptFSRef, char *textParameter ) * * Purpose: Runs an AppleScript with one text parameter as input. * CreateMessageEvent, and therefore RunAppleScript, assumes the AppleScript has a * subroutine entry titled "applescriptentry" and accepts one TEXT parameter. * * Inputs: scriptFSRef - FSRef to our AppleScript * textParameter - text parameter to our AppleScript * * Returns: OSStatus - error code (0 == no error) */ static OSStatus RunAppleScript( FSRef *scriptFSRef, char *textParameter, char *textReply,int textsize,tScriptData *d) { OSStatus err; AppleEvent aeParameter; AEDesc scriptData; short refNum; FSCatalogInfo catalogInfo; Handle h = NULL; pthread_mutex_lock(&gASMutex); refNum = FSOpenResFile( scriptFSRef, fsRdPerm ); // Older (Mac OS 8/9) scripts store their data in the 'scpt' (1) resource if ( refNum != -1 ) { h = Get1IndResource( 'scpt', 1 ); if( h != NULL ) DetachResource( h ); // Detach the handle before closing the resource CloseResFile( refNum ); } if ( h == NULL ) { err = FSGetCatalogInfo( scriptFSRef, kFSCatInfoDataSizes, &catalogInfo, NULL, NULL, NULL ); // Get the size of the script require_noerr( err, Bail ); err = FSOpenFork( scriptFSRef, 0, NULL, fsRdPerm, &refNum ); // Open the data fork read only require_noerr( err, Bail ); h = NewHandle( catalogInfo.dataLogicalSize ); err = FSReadFork( refNum, fsFromStart, 0, catalogInfo.dataLogicalSize, *h, NULL ); // Read the script into our handle (void) FSCloseFork( refNum ); // Close the file reference } err = CreateMessageEvent( &aeParameter, textParameter ); // Create the AppleEvent, and use the Apple event to call the script's subroutine require_noerr( err, Bail ); err = AECreateDesc( typeOSAGenericStorage, *h, GetHandleSize(h), &scriptData ); // Load the compiled script into an AEDesc of type typeOSAGenericStorage require_noerr( err, Bail ); AEDesc result; err = ExecuteCompiledAppleScriptEvent( &scriptData, &aeParameter, &result,d); // "Generic" routine to execute our AppleScript if(textReply) { int size=AEGetDescDataSize(&result); AEGetDescData(&result,textReply,textsize-1); textReply[textsize]='\0'; if(sizenetwork) PauseGame(); } return noErr; } #define kMaxURLSize 256 pascal OSErr myGURL(const AppleEvent *theAE,AppleEvent *reply,long refCon) { DescType type; char theURL[kMaxURLSize]; Size urlSize; HandleError(AEGetParamPtr(theAE,keyDirectObject,typeChar,&type,theURL,kMaxURLSize,&urlSize)); if(type!=typeChar) return paramErr; if(urlSize>=kMaxURLSize) return paramErr; theURL[urlSize]='\0'; //PrintConsoleString("Opening URL \"%s\"....",theURL); if(theURL[strlen(theURL)-1]=='>') theURL[strlen(theURL)-1]='\0'; if(theURL[strlen(theURL)-1]=='/') theURL[strlen(theURL)-1]='\0'; sscanf(theURL,"<%s",theURL); sscanf(theURL,"URL:%s",theURL); sscanf(theURL,"redline://%s",gJoinHost); gJoinFlag=true; gGameEnd=kEndGameNoReplay; return noErr; } void InitAE() { AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,NewAEEventHandlerUPP(&myQUIT),0,false); AEInstallEventHandler(kInternetEventClass,kAEGetURL,NewAEEventHandlerUPP(&myGURL),0,false); } //#define kBetaExpiration (3232976085+4000000) #define kBetaExpiration (0) void* ITunesPollThread(void * arg) { while(1){ ITunesGetStatus(); sleep(1); } } void InitITunesNotifications(); void SystemInit() { long resp; short hit; AlertStdAlertParamRec alertParam={ false,false,nil, "\pExit", nil, nil, kAlertStdAlertOKButton, 0, kWindowDefaultPosition}; HandleError(Gestalt(gestaltSystemVersion,&resp)); if(resp<0x00001020) { StandardAlert(kAlertStopAlert, "\pMac OS 10.2 or higher is required.", "\p", &alertParam, &hit); ExitToShell(); } unsigned long dateTime; GetDateTime(&dateTime); //PrintConsoleString("%u",dateTime); if(kBetaExpiration&&dateTime>kBetaExpiration) { StandardAlert(kAlertStopAlert, "\pThis beta of Redline has expired.", "\p", &alertParam, &hit); ExitToShell(); } InitAE(); ITunesGetStatus(); InitITunesNotifications(); pthread_mutex_init(&gASMutex,0); //pthread_t thread; //pthread_create(&thread,NULL,ITunesPollThread,NULL); // CallOmniEnableFloatExceptions(); } #define kInputBufferSize 16 UInt32 gInputBuffer[kInputBufferSize]; int gInputBufferPos=0; float gLastCursorHideTime; extern int gInterfaceKeys[kInterfaceNumKeys]; UInt32 gLastSwitch=0; int iTunesPress=false; int gSystemInstalling=false; float gInstallStartTime=0; void SystemPoll(int inGame) { EventRecord evt; gInGame=inGame; while(WaitNextEvent(everyEvent,&evt,0,nil)) { switch(evt.what) { case mouseDown: WindowPtr win; switch(FindWindow(evt.where,&win)) { case inDrag: { Rect dragRect={0,0,32767,32767}; DragWindow(win,evt.where,&dragRect); Point pt={0,0}; // LocalToGlobal(&pt); gConfig->windowX=pt.h; gConfig->windowY=pt.v; } break; case inMenuBar: MenuSelect(evt.where); break; case inContent: if(evt.when>gLastSwitch+20) if(gInputBufferPos>24)==suspendResumeMessage) { gSystemSuspended=!(evt.message&resumeFlag); if(!gSystemSuspended) BringToFront(FrontWindow()); if(inGame) { if(gSystemSuspended&&inGame) if((!gGameInfo->network)&&(!gReplay)) PauseGame(); } else if(gSystemSuspended) PauseGame(); else UnPauseGame(); gLastSwitch=evt.when; if(!gPaused) SoundReInit(); } break; case kHighLevelEvent : AEProcessAppleEvent(&evt); break; case keyDown: case autoKey: if(evt.modifiers&cmdKey) switch(evt.message&charCodeMask) { case 'f': if(!ScreenNoWindow()) { float pauseTime=TimeGetSeconds(); gConfig->fullscreen=!gConfig->fullscreen; ScreenReInit(); if(inGame) { gClipEnable=false; RenderFrame(false); gClipEnable=true; if(!gPaused&&!gGameInfo->network) gStartTime+=TimeGetSeconds()-pauseTime; } } break; /* case 'q': if((!inGame)||gInputEscMode==kInputEscModeNormal) Exit(); break;*/ } else if(gInputBufferPosgLastCursorHideTime+1&&!gSystemInstalling) { gLastCursorHideTime=TimeGetSeconds(); //if(gConfig->fullscreen) // HideCursor(); //else // ObscureCursor(); } if(((!gInterfaceType||GetInterfaceKey(kInterfaceKeyCmd))||inGame)&&!gSystemSuspended) { pthread_t thread; if(GetButtonInput(kInputITunesNext)) { if(!iTunesPress) // ITunesNext(NULL); pthread_create(&thread,NULL,ITunesNext,NULL); iTunesPress=true; } else if(GetButtonInput(kInputITunesPrev)) { if(!iTunesPress) // ITunesPrev(NULL); pthread_create(&thread,NULL,ITunesPrev,NULL); iTunesPress=true; } else if(GetButtonInput(kInputITunesPlay)) { if(!iTunesPress) // ITunesPlay(NULL); pthread_create(&thread,NULL,ITunesPlay,NULL); iTunesPress=true; } else iTunesPress=false; } NetworkIdle(); SystemIdle(); } void SystemYieldTime(float till) { while(TimeGetSeconds()>8==gInterfaceKeys[i]) *key=i; if(gInputBuffer[gInputBufferPos]&charCodeMask) return gInputBuffer[gInputBufferPos]&charCodeMask; else return 0xff; } return 0; } char PeekKeyInput(int *key) { if(key) *key=kInterfaceKeyNone; if(gInputBufferPos) { if(key) for(int i=kInterfaceKeyUp;i>8==gInterfaceKeys[i]) *key=i; if(gInputBuffer[gInputBufferPos-1]&charCodeMask) return gInputBuffer[gInputBufferPos-1]&charCodeMask; else return 0xff; } return 0; } float TimeGetSeconds() { static UInt64 startTime=0; if(startTime==0) Microseconds((UnsignedWide*)&startTime); UInt64 w; Microseconds((UnsignedWide*)&w); return (float)((double)(w-startTime)*(double)0.000001); }