]> git.jsancho.org Git - lugaru.git/blob - Source/OpenGL_Full_Screen.cpp
873cf00bc6e529cdebdcc6aa612a1b89b67b7e5e
[lugaru.git] / Source / OpenGL_Full_Screen.cpp
1 #include "Game.h"
2 #include "nommgr.h"
3
4 extern bool buttons[3];
5 extern float multiplier;
6 extern float screenwidth,screenheight;
7 extern float sps;
8 extern float realmultiplier;
9 extern int slomo;
10 extern bool ismotionblur;
11 extern float usermousesensitivity;
12 extern int detail;
13 extern bool floatjump;
14 extern bool cellophane;
15 extern int terraindetail;
16 extern int texdetail;
17 extern int bloodtoggle;
18 extern bool osx;
19 extern bool autoslomo;
20 extern bool foliage;
21 extern bool musictoggle;
22 extern bool trilinear;
23 extern float gamespeed;
24 extern int difficulty;
25 extern bool damageeffects;
26 extern int numplayers;
27 extern bool decals;
28 extern bool invertmouse;
29 extern bool texttoggle;
30 extern bool ambientsound;
31 extern bool mousejump;
32 extern bool freeze;
33 extern Person player[maxplayers];
34 extern bool vblsync;
35 extern bool stillloading;
36 extern bool showpoints;
37 extern bool alwaysblur;
38 extern bool immediate;
39 extern bool velocityblur;
40 extern bool debugmode;
41 extern int mainmenu;
42 extern int kBitsPerPixel;
43 extern float slomospeed;
44 extern float slomofreq;
45 extern float oldgamespeed;
46
47  #define kUseAGLFullScreenX 1
48  #define kUseFades 1
49  
50 // system includes ----------------------------------------------------------
51
52 #ifdef __APPLE_CC__
53     #include "Carbon Include.h"
54     #include <Carbon/Carbon.h>
55     
56     #include <DrawSprocket/DrawSprocket.h>
57         #include <AGL/agl.h>
58         #include <AGL/aglRenderers.h>
59         #include <OpenGL/gl.h>
60         #include <OpenGL/glu.h>
61 #else
62     #include <DrawSprocket.h>
63     
64     #include <Devices.h>
65     #include <Dialogs.h>
66     #include <DriverServices.h>
67     #include <Events.h>
68     #include <Gestalt.h>
69     #include <LowMem.h>
70     #include <Sound.h>
71     #include <TextEdit.h>
72     #include <ToolUtils.h>
73     #include <Windows.h>
74
75     // profile
76     #include <Profiler.h>
77
78         #include "agl.h"
79     #include "gamegl.h"
80         #include "glu.h"
81 #endif
82
83 #include <math.h>
84 #include <stdio.h>
85 #include <string.h>
86 #include <Folders.h>
87 #include <fstream.h>
88  
89 // project includes ---------------------------------------------------------
90
91 #include "aglString.h"
92 #include "MacInput.h"
93
94 // functions (internal/private) ---------------------------------------------
95
96 static UInt32 CheckMacOSX (void);
97 void CToPStr (StringPtr outString, const char *inString);
98 void ReportError (char * strError);
99 OSStatus DSpDebugStr (OSStatus error);
100 GLenum aglDebugStr (void);
101 GLenum glDebugStr (void);
102
103 CGrafPtr SetupDSpFullScreen (GDHandle hGD);
104 void ShutdownDSp (CGrafPtr pDSpPort);
105
106 AGLContext SetupAGL (GDHandle hGD, AGLDrawable win);
107 AGLContext SetupAGLFullScreen (GDHandle display, short * pDepth, short * pWidth, short * pHeight);
108 void CleanupAGL (AGLContext ctx);
109 void DrawGL (Rect * pRectPort);
110
111 void InitToolbox(void);
112 void CreateGLWindow (void);
113 Boolean SetUp (void);
114 void DoMenu (SInt32 menuResult);
115 void DoKey (SInt8 theKey, SInt8 theCode);
116 void DoUpdate (void);
117
118 pascal void IdleTimer (EventLoopTimerRef inTimer, void* userData);
119 EventLoopTimerUPP GetTimerUPP (void);
120 static Boolean RunningOnCarbonX(void);
121
122 void DoEvent (void);
123 void CleanUp (void);
124
125 // profile wrappers
126 Boolean WaitNextEventWrapper (EventMask eventMask, EventRecord *theEvent, unsigned long sleep,RgnHandle mouseRgn);
127 OSStatus DSpProcessEventWrapper (EventRecord *inEvent, Boolean *outEventWasProcessed);
128 void UpdateWrapper (EventRecord *theEvent);
129
130 // statics/globals (internal only) ------------------------------------------
131
132 Point delta;
133
134 // Menu defs
135 enum 
136 {
137         kMenuApple = 128,
138         kMenuFile = 129,
139         
140         kAppleAbout = 1,
141         kFileQuit = 1
142 };
143
144 enum 
145 {
146         kForegroundSleep = 10,
147         kBackgroundSleep = 10000
148 };
149 EventLoopTimerRef gTimer = NULL;
150
151 int kContextWidth;
152 int kContextHeight;
153
154 const RGBColor rgbBlack = { 0x0000, 0x0000, 0x0000 };
155
156 NumVersion gVersionDSp;
157 DSpContextAttributes gContextAttributes;
158 DSpContextReference gContext = 0;
159 extern AGLContext gaglContext;
160 GLuint gFontList;
161 char gcstrMode [256] = "";
162
163 AGLDrawable gpDSpPort = NULL; // will be NULL for full screen under X
164 Rect gRectPort = {0, 0, 0, 0};
165
166 UInt32 gSleepTime = kForegroundSleep;
167 Boolean gDone = false, gfFrontProcess = true;
168
169 Game game;
170
171 // profile
172 #if __profile__
173 OSErr gProfErr = noErr;
174 #endif
175
176 #pragma mark -
177
178 //-----------------------------------------------------------------------------------------------------------------------
179
180 // are we running on Mac OS X
181 // returns 0 if < Mac OS X or version number of Mac OS X (10.0 for GM)
182
183 static UInt32 CheckMacOSX (void)
184 {
185         UInt32 response;
186     
187         if ((Gestalt(gestaltSystemVersion, (SInt32 *) &response) == noErr) && (response >= 0x01000))
188                 return response;
189         else
190                 return 0;
191 }
192
193 //-----------------------------------------------------------------------------------------------------------------------
194
195 // Copy C string to Pascal string
196
197 void CToPStr (StringPtr outString, const char *inString)
198 {       
199         unsigned char x = 0;
200         do
201                 *(((char*)outString) + x + 1) = *(inString + x++);
202         while ((*(inString + x) != 0)  && (x < 256));
203         *((char*)outString) = (char) x;                                                                 
204 }
205
206 // --------------------------------------------------------------------------
207
208 void ReportError (char * strError)
209 {
210         char errMsgCStr [256];
211         Str255 strErr;
212
213         sprintf (errMsgCStr, "%s", strError); 
214
215         // out as debug string
216         CToPStr (strErr, errMsgCStr);
217         DebugStr (strErr);
218 }
219
220 //-----------------------------------------------------------------------------------------------------------------------
221
222 OSStatus DSpDebugStr (OSStatus error)
223 {
224         switch (error)
225         {
226                 case noErr:
227                         break;
228                 case kDSpNotInitializedErr:
229                         ReportError ("DSp Error: Not initialized");
230                         break;
231                 case kDSpSystemSWTooOldErr:
232                         ReportError ("DSp Error: system Software too old");
233                         break;
234                 case kDSpInvalidContextErr:
235                         ReportError ("DSp Error: Invalid context");
236                         break;
237                 case kDSpInvalidAttributesErr:
238                         ReportError ("DSp Error: Invalid attributes");
239                         break;
240                 case kDSpContextAlreadyReservedErr:
241                         ReportError ("DSp Error: Context already reserved");
242                         break;
243                 case kDSpContextNotReservedErr:
244                         ReportError ("DSp Error: Context not reserved");
245                         break;
246                 case kDSpContextNotFoundErr:
247                         ReportError ("DSp Error: Context not found");
248                         break;
249                 case kDSpFrameRateNotReadyErr:
250                         ReportError ("DSp Error: Frame rate not ready");
251                         break;
252                 case kDSpConfirmSwitchWarning:
253 //                      ReportError ("DSp Warning: Must confirm switch"); // removed since it is just a warning, add back for debugging
254                         return 0; // don't want to fail on this warning
255                         break;
256                 case kDSpInternalErr:
257                         ReportError ("DSp Error: Internal error");
258                         break;
259                 case kDSpStereoContextErr:
260                         ReportError ("DSp Error: Stereo context");
261                         break;
262         }
263         return error;
264 }
265
266 //-----------------------------------------------------------------------------------------------------------------------
267
268 // if error dump agl errors to debugger string, return error
269
270 GLenum aglDebugStr (void)
271 {
272         GLenum err = aglGetError();
273         if (AGL_NO_ERROR != err)
274                 ReportError ((char *)aglErrorString(err));
275         return err;
276 }
277
278 //-----------------------------------------------------------------------------------------------------------------------
279
280 // if error dump agl errors to debugger string, return error
281
282 GLenum glDebugStr (void)
283 {
284         GLenum err = glGetError();
285         if (GL_NO_ERROR != err)
286                 ReportError ((char *)gluErrorString(err));
287         return err;
288 }
289
290 #pragma mark -
291 //-----------------------------------------------------------------------------------------------------------------------
292
293 // Set up DSp screen on graphics device requested
294 // side effect: sets both gpDSpWindow and gpPort
295
296 CGrafPtr SetupDSpFullScreen (GDHandle hGD)
297 {
298         DSpContextAttributes foundAttributes;
299         DisplayIDType displayID = NULL;
300         
301         if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpGetVersion) 
302         {
303                 ReportError ("DrawSprocket not installed.");
304                 return NULL;
305         }
306         else
307                 gVersionDSp = DSpGetVersion ();
308
309         if ((gVersionDSp.majorRev == 0x01) && (gVersionDSp.minorAndBugRev < 0x99))
310         {
311                 // this version of DrawSprocket is not completely functional on Mac OS X
312                 if (CheckMacOSX ())
313                 {
314                         ReportError ("DrawSprocket 1.99 or greate required on Mac OS X, please update to at least Mac OS X 10.1.");
315                         return NULL;
316                 }
317         }
318                         
319         // Note: DSp < 1.7.3 REQUIRES the back buffer attributes even if only one buffer is required
320         memset(&gContextAttributes, 0, sizeof (DSpContextAttributes));
321         gContextAttributes.displayWidth                 = kContextWidth;
322         gContextAttributes.displayHeight                = kContextHeight;
323         gContextAttributes.colorNeeds                   = kDSpColorNeeds_Require;
324         gContextAttributes.displayBestDepth             = kBitsPerPixel;
325         gContextAttributes.backBufferBestDepth  = kBitsPerPixel;
326         gContextAttributes.displayDepthMask             = kDSpDepthMask_All;
327         gContextAttributes.backBufferDepthMask  = kDSpDepthMask_All;
328         gContextAttributes.pageCount                    = 1;                                                            // only the front buffer is needed
329         
330         screenwidth=kContextWidth;
331         screenheight=kContextHeight;
332         
333         DMGetDisplayIDByGDevice (hGD, &displayID, true);
334         
335         if (noErr != DSpDebugStr (DSpFindBestContextOnDisplayID (&gContextAttributes, &gContext, displayID)))
336         {
337                 ReportError ("DSpFindBestContext() had an error.");
338                 return NULL;
339         }
340
341         if (noErr != DSpDebugStr (DSpContext_GetAttributes (gContext, &foundAttributes))) // see what we actually found
342         {
343                 ReportError ("DSpContext_GetAttributes() had an error.");
344                 return NULL;
345         }
346
347         // reset width and height to full screen and handle our own centering
348         // HWA will not correctly center less than full screen size contexts
349         gContextAttributes.displayWidth         = foundAttributes.displayWidth;
350         gContextAttributes.displayHeight        = foundAttributes.displayHeight;
351         gContextAttributes.pageCount            = 1;                                                                    // only the front buffer is needed
352         gContextAttributes.contextOptions       = 0 | kDSpContextOption_DontSyncVBL;    // no page flipping and no VBL sync needed
353
354         DSpSetBlankingColor(&rgbBlack);
355
356         if (noErr !=  DSpDebugStr (DSpContext_Reserve ( gContext, &gContextAttributes))) // reserve our context
357         {
358                 ReportError ("DSpContext_Reserve() had an error.");
359                 return NULL;
360         }
361  
362         HideCursor ();
363
364         if (noErr != DSpDebugStr (DSpContext_SetState (gContext, kDSpContextState_Active))) // activate our context
365         {
366                 ReportError ("DSpContext_SetState() had an error.");
367                 return NULL;
368         }
369
370
371         if ((CheckMacOSX ()) && !((gVersionDSp.majorRev > 0x01) || ((gVersionDSp.majorRev == 0x01) && (gVersionDSp.minorAndBugRev >= 0x99))))// DSp should be supported in version after 1.98
372         {
373                 ReportError ("Mac OS X with DSp < 1.99 does not support DrawSprocket for OpenGL full screen");
374                 return NULL;
375         }
376         else if (CheckMacOSX ()) // DSp should be supported in versions 1.99 and later
377         {
378                 CGrafPtr pPort;
379                 // use DSp's front buffer on Mac OS X
380                 if (noErr != DSpDebugStr (DSpContext_GetFrontBuffer (gContext, &pPort)))
381                 {
382                         ReportError ("DSpContext_GetFrontBuffer() had an error.");
383                         return NULL;
384                 }
385                 // there is a problem in Mac OS X 10.0 GM CoreGraphics that may not size the port pixmap correctly
386                 // this will check the vertical sizes and offset if required to fix the problem
387                 // this will not center ports that are smaller then a particular resolution
388                 {
389                         long deltaV, deltaH;
390                         Rect portBounds;
391                         PixMapHandle hPix = GetPortPixMap (pPort);
392                         Rect pixBounds = (**hPix).bounds;
393                         GetPortBounds (pPort, &portBounds);
394                         deltaV = (portBounds.bottom - portBounds.top) - (pixBounds.bottom - pixBounds.top) +
395                                  (portBounds.bottom - portBounds.top - kContextHeight) / 2;
396                         deltaH = -(portBounds.right - portBounds.left - kContextWidth) / 2;
397                         if (deltaV || deltaH)
398                         {
399                                 GrafPtr pPortSave;
400                                 GetPort (&pPortSave);
401                                 SetPort ((GrafPtr)pPort);
402                                 // set origin to account for CG offset and if requested drawable smaller than screen rez
403                                 SetOrigin (deltaH, deltaV);
404                                 SetPort (pPortSave);
405                         }
406                 }
407                 return pPort;
408         }
409         else // Mac OS 9 or less
410         {
411                 WindowPtr pWindow;
412                 Rect rectWin;
413                 RGBColor rgbSave;
414                 GrafPtr pGrafSave;
415                 // create a new window in our context 
416                 // note: OpenGL is expecting a window so it can enumerate the devices it spans, 
417                 // center window in our context's gdevice
418                 rectWin.top  = (short) ((**hGD).gdRect.top + ((**hGD).gdRect.bottom - (**hGD).gdRect.top) / 2);         // h center
419                 rectWin.top  -= (short) (kContextHeight / 2);
420                 rectWin.left  = (short) ((**hGD).gdRect.left + ((**hGD).gdRect.right - (**hGD).gdRect.left) / 2);       // v center
421                 rectWin.left  -= (short) (kContextWidth / 2);
422                 rectWin.right = (short) (rectWin.left + kContextWidth);
423                 rectWin.bottom = (short) (rectWin.top + kContextHeight);
424                 
425                 pWindow = NewCWindow (NULL, &rectWin, "\p", 0, plainDBox, (WindowPtr)-1, 0, 0);
426
427                 // paint back ground black before fade in to avoid white background flash
428                 ShowWindow(pWindow);
429                 GetPort (&pGrafSave);
430                 SetPortWindowPort (pWindow);
431                 GetForeColor (&rgbSave);
432                 RGBForeColor (&rgbBlack);
433                 {
434                         Rect paintRect;
435                         GetWindowPortBounds (pWindow, &paintRect);
436                         PaintRect (&paintRect);
437                 }
438                 RGBForeColor (&rgbSave);                // ensure color is reset for proper blitting
439                 SetPort (pGrafSave);
440                 return (GetWindowPort (pWindow));
441         }
442 }
443
444 //-----------------------------------------------------------------------------------------------------------------------
445
446 // clean up DSp
447
448 void ShutdownDSp (CGrafPtr pDSpPort)
449 {
450         if ((NULL != pDSpPort) && !CheckMacOSX ())
451                 DisposeWindow (GetWindowFromPort (pDSpPort));
452         DSpContext_SetState( gContext, kDSpContextState_Inactive);
453         DSpContext_Release (gContext);
454 }
455
456 #pragma mark -
457 //-----------------------------------------------------------------------------------------------------------------------
458
459 // OpenGL Setup
460
461
462 AGLContext SetupAGL (GDHandle hGD, AGLDrawable drawable)
463 {
464         GLint                   attrib[64];
465         
466         AGLPixelFormat  fmt;
467         AGLContext      ctx;
468
469 // different possible pixel format choices for different renderers 
470 // basics requirements are RGBA and double buffer
471 // OpenGLz will select acclerated context if available
472
473         short i = 0;
474         attrib [i++] = AGL_RGBA; // red green blue and alpha
475         attrib [i++] = AGL_DOUBLEBUFFER; // double buffered
476         attrib [i++] = AGL_DEPTH_SIZE; 
477         attrib [i++] = 8; 
478         attrib [i++] = AGL_ACCELERATED; // HWA pixel format only
479         attrib [i++] = AGL_NONE;
480
481         if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL
482         {
483                 ReportError ("OpenGL not installed");
484                 return NULL;
485         }       
486
487         if (hGD)
488                 fmt = aglChoosePixelFormat (&hGD, 1, attrib); // get an appropriate pixel format
489         else
490                 fmt = aglChoosePixelFormat(NULL, 0, attrib); // get an appropriate pixel format
491         aglDebugStr ();
492         if (NULL == fmt) 
493         {
494                 ReportError("Could not find valid pixel format");
495                 return NULL;
496         }
497
498         ctx = aglCreateContext (fmt, NULL); // Create an AGL context
499         aglDebugStr ();
500         if (NULL == ctx)
501         {
502                 ReportError ("Could not create context");
503                 return NULL;
504         }
505
506         if (!aglSetDrawable (ctx, drawable)) // attach the window to the context
507         {
508                 ReportError ("SetDrawable failed");
509                 aglDebugStr ();
510                 return NULL;
511         }
512
513
514         if (!aglSetCurrentContext (ctx)) // make the context the current context
515         {
516                 aglDebugStr ();
517                 aglSetDrawable (ctx, NULL);
518                 return NULL;
519         }
520
521         aglDestroyPixelFormat(fmt); // pixel format is no longer needed
522
523         return ctx;
524 }
525
526 //-----------------------------------------------------------------------------------------------------------------------
527
528 // OpenGL Setup
529
530 AGLContext SetupAGLFullScreen (GDHandle display, short * pDepth, short * pWidth, short * pHeight)
531 {
532         //GLint                 attrib[64];
533         GLint attrib[] ={AGL_RGBA, AGL_DOUBLEBUFFER,AGL_DEPTH_SIZE, 16, AGL_FULLSCREEN,AGL_ALL_RENDERERS, AGL_NONE};
534
535         AGLPixelFormat  fmt;
536         AGLContext      ctx;
537
538
539         if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL
540         {
541                 ReportError ("OpenGL not installed");
542                 return NULL;
543         }       
544
545         fmt = aglChoosePixelFormat(&display, 1, attrib); // this may fail if looking for acclerated across multiple monitors
546         if (NULL == fmt) 
547         {
548                 ReportError("Could not find valid pixel format");
549                 aglDebugStr ();
550                 return NULL;
551         }
552
553         ctx = aglCreateContext (fmt, NULL); // Create an AGL context
554         if (NULL == ctx)
555         {
556                 ReportError ("Could not create context");
557                 aglDebugStr ();
558                 return NULL;
559         }
560
561         if (!aglSetFullScreen (ctx, *pWidth, *pHeight, 60, 0))
562         {
563                 ReportError ("SetFullScreen failed");
564                 aglDebugStr ();
565                 return NULL;
566         }
567
568         if (!aglSetCurrentContext (ctx)) // make the context the current context
569         {
570                 ReportError ("SetCurrentContext failed");
571                 aglDebugStr ();
572                 aglSetDrawable (ctx, NULL); // turn off full screen
573                 return NULL;
574         }
575
576         aglDestroyPixelFormat(fmt); // pixel format is no longer needed
577
578         return ctx;
579 }
580
581 //-----------------------------------------------------------------------------------------------------------------------
582
583 // OpenGL Cleanup
584
585 void CleanupAGL(AGLContext ctx)
586 {
587         aglSetDrawable (ctx, NULL);
588         aglSetCurrentContext (NULL);
589         aglDestroyContext (ctx);
590 }
591
592 //-----------------------------------------------------------------------------------------------------------------------
593
594 // OpenGL Drawing
595
596 void DrawGL (Rect * pRectPort)
597 {
598         if (gaglContext == 0)
599                 return;
600         aglSetCurrentContext (gaglContext); // ensure our context is current prior to drawing
601         
602     {
603         GLint width = pRectPort->right - pRectPort->left;
604         GLint height = pRectPort->bottom - pRectPort->top;
605         screenwidth=width;
606         screenheight=height;
607        /* glViewport ((width - (width * 1)) / 2, (height - (height * 1)) / 2,
608                     width * 1, height * 1);*/
609      }
610     
611         game.DrawGLScene();
612         
613         
614         //glDebugStr ();
615
616         // draw info
617         /*{
618                 GLint matrixMode;
619         glViewport (0, 0, pRectPort->right - pRectPort->left, pRectPort->bottom - pRectPort->top);
620                 glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
621                 glMatrixMode (GL_PROJECTION);
622                 glPushMatrix();
623                         glLoadIdentity ();
624                         glMatrixMode (GL_MODELVIEW);
625                         glPushMatrix();
626                                 glLoadIdentity ();
627                                 glScalef (2.0 / (pRectPort->right - pRectPort->left), -2.0 /  (pRectPort->bottom - pRectPort->top), 1.0);
628                                 glTranslatef (-(pRectPort->right - pRectPort->left) / 2.0, -(pRectPort->bottom - pRectPort->top) / 2.0, 0.0);
629                                 glColor3f (1.0, 1.0, 1.0);
630                                 glRasterPos3d (10, 12, 0); 
631                                 DrawFrameRate (gFontList);
632                                 glRasterPos3d (10, 24, 0); 
633                                 DrawCStringGL (gcstrMode, gFontList);
634                                 glRasterPos3d (10, (pRectPort->bottom - pRectPort->top) - 15, 0); 
635                                 DrawCStringGL ((char*) glGetString (GL_VENDOR), gFontList);
636                                 glRasterPos3d (10, (pRectPort->bottom - pRectPort->top) - 3, 0); 
637                                 DrawCStringGL ((char*) glGetString (GL_RENDERER), gFontList);
638                                 static char aChar[256] = "";
639                                 sprintf (aChar, "     Mac OS X: %d",  RunningOnCarbonX());
640                                 DrawCStringGL (aChar, gFontList);
641                         glPopMatrix();
642                         glMatrixMode (GL_PROJECTION);
643                 glPopMatrix();
644                 glMatrixMode (matrixMode);
645         }*/
646         //glDebugStr ();
647         //aglSwapBuffers(gaglContext); // send swap command
648 }
649
650 #pragma mark -
651 //-----------------------------------------------------------------------------------------------------------------------
652
653 static pascal OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, SInt32 refcon )
654 {
655         #pragma unused (appleEvt, reply, refcon)
656         //gDone =  true;
657         game.tryquit=1;
658         return false;
659 }
660
661 //-----------------------------------------------------------------------------------------------------------------------
662
663 void InitToolbox(void)
664 {
665         OSErr err;
666         long response;
667         MenuHandle menu;
668         
669         InitCursor();
670         
671 // profile
672 #if __profile__
673 //      prototype:
674 //              ProfilerInit (collection method, time base, num funcs, stack depth)
675         // default call
676         gProfErr = ProfilerInit (collectDetailed, bestTimeBase, 20, 10); // set up profiling
677         // something that you may need to do (may need more memory)
678 //      gProfErr = ProfilerInit (collectSummary, bestTimeBase, 1000, 100); // set up profiling
679 // Note: application will likely run slower, but still should be useful info
680         if (noErr == gProfErr)
681                 ProfilerSetStatus(FALSE);
682 #endif
683         
684         // Init Menus
685         menu = NewMenu (kMenuApple, "\p\024");                  // new  apple menu
686         InsertMenu (menu, 0);                                                   // add menu to end
687
688         menu = NewMenu (kMenuFile, "\pFile");                   // new menu
689         InsertMenu (menu, 0);                                                   // add menu to end
690
691         // insert application menus here
692         
693         // add quit if not under Mac OS X
694         err = Gestalt (gestaltMenuMgrAttr, &response);
695         if ((err == noErr) && !(response & gestaltMenuMgrAquaLayoutMask))
696                         AppendMenu (menu, "\pQuit/Q");                                  // add quit
697
698         DrawMenuBar();
699         err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false );
700         if (err != noErr)
701                 ExitToShell();
702 }
703
704 // --------------------------------------------------------------------------
705
706 static Point gMidPoint;
707
708 Boolean SetUp (void)
709 {
710         char string[10];
711         
712         SetQDGlobalsRandomSeed(TickCount());
713         
714         osx = 0;
715         if(CheckMacOSX ())osx = 1;
716         ifstream ipstream(":Data:config.txt");
717         detail=1;
718         ismotionblur=0;
719         usermousesensitivity=1;
720         kContextWidth=640;
721         kContextHeight=480;
722         kBitsPerPixel = 32;
723         floatjump=0;
724         cellophane=0;
725         texdetail=4;
726         autoslomo=1;
727         decals=1;
728         invertmouse=0;
729         bloodtoggle=0;
730         terraindetail=2;
731         foliage=1;
732         musictoggle=1;
733         trilinear=1;
734         gamespeed=1;
735         difficulty=1;
736         damageeffects=0;
737         texttoggle=1;
738         alwaysblur=0;
739         showpoints=0;
740         immediate=0;
741         velocityblur=0;
742         slomospeed=0.25;
743         slomofreq=8012;
744         
745         game.crouchkey=MAC_SHIFT_KEY;
746     game.jumpkey=MAC_SPACE_KEY;
747     game.leftkey=MAC_A_KEY;
748     game.forwardkey=MAC_W_KEY;
749     game.backkey=MAC_S_KEY;
750     game.rightkey=MAC_D_KEY;
751     game.drawkey=MAC_E_KEY;
752     game.throwkey=MAC_Q_KEY;
753     game.attackkey=MAC_MOUSEBUTTON1;
754     game.chatkey=MAC_T_KEY;
755     numplayers=1;
756     ambientsound=1;
757     vblsync=0;
758     debugmode=0;
759     if(!ipstream) {
760         ofstream opstream(":Data:config.txt"); 
761         opstream << "Screenwidth:\n";
762         opstream << kContextWidth;
763         opstream << "\nScreenheight:\n";
764             opstream << kContextHeight;
765             opstream << "\nMouse sensitivity:\n";
766             opstream << usermousesensitivity;
767             opstream << "\nBlur(0,1):\n";
768             opstream << ismotionblur;
769                 opstream << "\nOverall Detail(0,1,2) higher=better:\n";
770             opstream << detail;
771             opstream << "\nFloating jump:\n";
772             opstream << floatjump;
773             opstream << "\nMouse jump:\n";
774             opstream << mousejump;
775             opstream << "\nAmbient sound:\n";
776             opstream << ambientsound;
777                 opstream << "\nBlood (0,1,2):\n";
778         opstream << bloodtoggle;
779         opstream << "\nAuto slomo:\n";
780         opstream << autoslomo;
781             opstream << "\nFoliage:\n";
782         opstream << foliage;
783         opstream << "\nMusic:\n";
784         opstream << musictoggle;
785         opstream << "\nTrilinear:\n";
786         opstream << trilinear;
787             opstream << "\nDecals(shadows,blood puddles,etc):\n";
788         opstream << decals;
789             opstream << "\nInvert mouse:\n";
790         opstream << invertmouse;
791             opstream << "\nGamespeed:\n";
792         opstream << gamespeed;
793         opstream << "\nDifficulty(0,1,2) higher=harder:\n";
794         opstream << difficulty;
795         opstream << "\nDamage effects(blackout, doublevision):\n";
796         opstream << damageeffects;
797             opstream << "\nText:\n";
798         opstream << texttoggle;
799             opstream << "\nDebug:\n";
800         opstream << debugmode;
801             opstream << "\nVBL Sync:\n";
802         opstream << vblsync;
803         opstream << "\nShow Points:\n";
804         opstream << showpoints;
805         opstream << "\nAlways Blur:\n";
806         opstream << alwaysblur;
807             opstream << "\nImmediate mode (turn on on G5):\n";
808         opstream << immediate;
809             opstream << "\nVelocity blur:\n";
810         opstream << velocityblur;
811             opstream << "\nForward key:\n";
812             opstream << KeyToChar(game.forwardkey);
813             opstream << "\nBack key:\n";
814             opstream << KeyToChar(game.backkey);
815             opstream << "\nLeft key:\n";
816             opstream << KeyToChar(game.leftkey);
817             opstream << "\nRight key:\n";
818             opstream << KeyToChar(game.rightkey);
819             opstream << "\nJump key:\n";
820             opstream << KeyToChar(game.jumpkey);
821             opstream << "\nCrouch key:\n";
822             opstream << KeyToChar(game.crouchkey);
823             opstream << "\nDraw key:\n";
824             opstream << KeyToChar(game.drawkey);
825             opstream << "\nThrow key:\n";
826             opstream << KeyToChar(game.throwkey);
827             opstream << "\nAttack key:\n";
828             opstream << KeyToChar(game.attackkey);
829             opstream << "\nChat key:\n";
830             opstream << KeyToChar(game.chatkey);
831             opstream.close();
832     }
833     if(ipstream){
834                 ipstream.ignore(256,'\n');
835             ipstream >> kContextWidth;
836             ipstream.ignore(256,'\n');
837             ipstream.ignore(256,'\n');
838             ipstream >> kContextHeight;
839             ipstream.ignore(256,'\n');
840             ipstream.ignore(256,'\n');
841             ipstream >> usermousesensitivity;
842             ipstream.ignore(256,'\n');
843             ipstream.ignore(256,'\n');
844             ipstream >> ismotionblur;
845             ipstream.ignore(256,'\n');
846             ipstream.ignore(256,'\n');
847             ipstream >> detail;
848             if(detail!=0)kBitsPerPixel=32;
849             else kBitsPerPixel=16;
850             ipstream.ignore(256,'\n');
851             ipstream.ignore(256,'\n');
852             ipstream >> floatjump;
853             ipstream.ignore(256,'\n');
854             ipstream.ignore(256,'\n');
855             ipstream >> mousejump;
856             ipstream.ignore(256,'\n');
857             ipstream.ignore(256,'\n');
858             ipstream >> ambientsound;
859             ipstream.ignore(256,'\n');
860             ipstream.ignore(256,'\n');
861             ipstream >> bloodtoggle;
862             ipstream.ignore(256,'\n');
863             ipstream.ignore(256,'\n');
864             ipstream >> autoslomo;
865             ipstream.ignore(256,'\n');
866             ipstream.ignore(256,'\n');
867             ipstream >> foliage;
868             ipstream.ignore(256,'\n');
869             ipstream.ignore(256,'\n');
870             ipstream >> musictoggle;
871             ipstream.ignore(256,'\n');
872             ipstream.ignore(256,'\n');
873             ipstream >> trilinear;
874             ipstream.ignore(256,'\n');
875             ipstream.ignore(256,'\n');
876             ipstream >> decals;
877             ipstream.ignore(256,'\n');
878             ipstream.ignore(256,'\n');
879             ipstream >> invertmouse;
880             ipstream.ignore(256,'\n');
881             ipstream.ignore(256,'\n');
882             ipstream >> gamespeed;
883             oldgamespeed=gamespeed;
884             if(oldgamespeed==0){
885                 gamespeed=1;
886                 oldgamespeed=1;
887             }
888             ipstream.ignore(256,'\n');
889             ipstream.ignore(256,'\n');
890             ipstream >> difficulty;
891             ipstream.ignore(256,'\n');
892             ipstream.ignore(256,'\n');
893             ipstream >> damageeffects;
894             ipstream.ignore(256,'\n');
895             ipstream.ignore(256,'\n');
896             ipstream >> texttoggle;
897             ipstream.ignore(256,'\n');
898             ipstream.ignore(256,'\n');
899             ipstream >> debugmode;
900             ipstream.ignore(256,'\n');
901             ipstream.ignore(256,'\n');
902             ipstream >> vblsync;
903             ipstream.ignore(256,'\n');
904             ipstream.ignore(256,'\n');
905             ipstream >> showpoints;
906             ipstream.ignore(256,'\n');
907             ipstream.ignore(256,'\n');
908             ipstream >> alwaysblur;
909             ipstream.ignore(256,'\n');
910             ipstream.ignore(256,'\n');
911             ipstream >> immediate;
912             ipstream.ignore(256,'\n');
913             ipstream.ignore(256,'\n');
914             ipstream >> velocityblur;
915             ipstream.ignore(256,'\n');
916             ipstream.ignore(256,'\n'); 
917             ipstream >> string;
918             game.forwardkey=CharToKey(string);
919             ipstream.ignore(256,'\n');
920             ipstream.ignore(256,'\n');
921             ipstream >> string;
922             game.backkey=CharToKey(string);
923             ipstream.ignore(256,'\n');
924             ipstream.ignore(256,'\n');
925             ipstream >> string;
926             game.leftkey=CharToKey(string);
927             ipstream.ignore(256,'\n');
928             ipstream.ignore(256,'\n');
929             ipstream >> string;
930             game.rightkey=CharToKey(string);
931             ipstream.ignore(256,'\n');
932             ipstream.ignore(256,'\n');
933             ipstream >> string;
934             game.jumpkey=CharToKey(string);
935             ipstream.ignore(256,'\n');
936             ipstream.ignore(256,'\n');
937             ipstream >> string;
938             game.crouchkey=CharToKey(string);
939             ipstream.ignore(256,'\n');
940             ipstream.ignore(256,'\n');
941             ipstream >> string;
942             game.drawkey=CharToKey(string);
943              ipstream.ignore(256,'\n');
944             ipstream.ignore(256,'\n');
945             ipstream >> string;
946             game.throwkey=CharToKey(string);
947               ipstream.ignore(256,'\n');
948             ipstream.ignore(256,'\n');
949             ipstream >> string;
950             game.attackkey=CharToKey(string);
951              ipstream.ignore(256,'\n');
952             ipstream.ignore(256,'\n');
953             ipstream >> string;
954             game.chatkey=CharToKey(string);
955             ipstream.close();
956             
957             if(detail>2)detail=2;
958             if(detail<0)detail=0;
959                 if(screenwidth<0)screenwidth=640;
960                 if(screenheight<0)screenheight=480;
961 #if !USE_SDL  // we'll take anything that works.
962             if(screenwidth>3000)screenwidth=640;
963                 if(screenheight>3000)screenheight=480;
964 #endif
965         }
966
967         
968         if(vblsync){    
969                 GLint swapInt = 1;
970                 aglSetInteger(gaglContext, AGL_SWAP_INTERVAL, &swapInt);
971         }
972         
973         if(kBitsPerPixel!=32&&kBitsPerPixel!=16){
974                 kBitsPerPixel=16;
975         }
976
977         
978         GDHandle hGD, hTargetDevice = NULL;
979         short numDevices = 0;
980         short fNum = 0;
981         short whichDevice = 0; // number of device to try (0 = 1st device)
982
983         InitToolbox ();
984         
985         gpDSpPort = NULL;
986         gaglContext = 0;
987         
988         // check for DSp
989         if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpStartup) 
990                 ReportError ("DSp not installed");
991
992         if (noErr != DSpDebugStr (DSpStartup()))
993                 return NULL;
994 //      DSpSetDebugMode (true);
995 #if defined kUseFades
996         DSpDebugStr (DSpContext_FadeGammaOut (NULL, NULL)); // fade display, remove for debug
997 #endif
998         
999         hGD = DMGetFirstScreenDevice (true); // check number of screens
1000         hTargetDevice = hGD; // default to first device                                                 
1001         do
1002         {
1003                 if (numDevices == whichDevice)
1004                         hTargetDevice = hGD; // if device number matches                                                
1005                 numDevices++;
1006                 hGD = DMGetNextScreenDevice (hGD, true);
1007         }
1008         while (hGD);
1009
1010 #if defined (kUseAGLFullScreenX)
1011         if (CheckMacOSX ()) // Try AGL full screen on Mac OS X
1012         {
1013                 short depth = kBitsPerPixel, width = kContextWidth, height = kContextHeight; 
1014                 gaglContext = SetupAGLFullScreen (hTargetDevice, &depth, &width, &height); // Setup the OpenGL context
1015                 SetRect (&gRectPort, 0, 0, width, height); // l, t, r, b
1016                 sprintf (gcstrMode, "AGL Full Screen: %d x %d x %d", width, height, depth);
1017         }
1018 #endif
1019         if (!gaglContext) //try DSp
1020         {
1021                 if (NULL != (gpDSpPort = SetupDSpFullScreen (hTargetDevice))) // Setup DSp for OpenGL sets hTargetDeviceto device actually used 
1022                 {
1023                         GetPortBounds (gpDSpPort, &gRectPort);
1024                         sprintf (gcstrMode, "DrawSprocket Full Screen: %d x %d x %d", gRectPort.right - gRectPort.left, gRectPort.bottom - gRectPort.top, (**(**hTargetDevice).gdPMap).pixelSize);
1025                         gaglContext = SetupAGL (hTargetDevice, gpDSpPort);
1026                 }
1027         }
1028         if (gaglContext)
1029         {
1030                 GetFNum("\pMonaco", &fNum);                                                                     // build font
1031                 gFontList = BuildFontGL (gaglContext, fNum, normal, 9);
1032                 //InstallEventLoopTimer (GetCurrentEventLoop(), 0, 0.0001, GetTimerUPP (), 0, &gTimer);
1033         }
1034         
1035         //gMidPoint.h = (gRectPort.left + gRectPort.right)/2;
1036         //gMidPoint.v = (gRectPort.top + gRectPort.bottom)/2;
1037         gMidPoint.h = 200;
1038         gMidPoint.v = 200;
1039         GLint swapInt = 1;
1040         //aglSetInteger(gaglContext, AGL_SWAP_INTERVAL, &swapInt);
1041         
1042 #if defined kUseFades
1043         DSpDebugStr (DSpContext_FadeGammaIn (NULL, NULL));
1044 #endif
1045         
1046         
1047         HideCursor();
1048         
1049         
1050     GLint width = gRectPort.right - gRectPort.left;
1051     GLint height = gRectPort.bottom - gRectPort.top;
1052     screenwidth=width;
1053     screenheight=height;
1054      
1055     game.newdetail=detail;
1056         game.newscreenwidth=screenwidth;
1057         game.newscreenheight=screenheight;
1058      
1059         game.InitGame();
1060         
1061         if (gaglContext)
1062                 return true;
1063         else
1064                 return false;
1065         
1066 }
1067
1068 static Boolean RunningOnCarbonX(void)
1069 {
1070         static Boolean first = true;
1071         static Boolean result = false;
1072
1073         if (first)
1074         {
1075                 UInt32 response;
1076
1077                 first = false;
1078
1079                 result = (Gestalt(gestaltSystemVersion, 
1080                     (SInt32 *) &response) == noErr)
1081                 && (response >= 0x01000);
1082         }
1083     return result;
1084 }
1085
1086 static OSStatus LoadFrameworkBundle(CFStringRef pFrameworkCFStrRef, CFBundleRef *pFrameworkCFBndlRef)
1087 {
1088         OSStatus        err;
1089         FSRef           frameworksFolderRef;
1090         CFURLRef        baseURL;
1091         CFURLRef        bundleURL;
1092         
1093         if (nil == pFrameworkCFBndlRef) return paramErr;
1094         
1095         *pFrameworkCFBndlRef = nil;
1096         
1097         baseURL = nil;
1098         bundleURL = nil;
1099         
1100         err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef);
1101         if (err == noErr) {
1102                 baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef);
1103                 if (baseURL == nil) {
1104                         err = coreFoundationUnknownErr;
1105                 }
1106         }
1107         if (err == noErr) {
1108                 bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, pFrameworkCFStrRef, false);
1109                 if (bundleURL == nil) {
1110                         err = coreFoundationUnknownErr;
1111                 }
1112         }
1113         if (err == noErr) {
1114                 *pFrameworkCFBndlRef = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL);
1115                 if (*pFrameworkCFBndlRef == nil) {
1116                         err = coreFoundationUnknownErr;
1117                 }
1118         }
1119         if (err == noErr) {
1120             if ( ! CFBundleLoadExecutable( *pFrameworkCFBndlRef ) ) {
1121                         err = coreFoundationUnknownErr;
1122             }
1123         }
1124
1125         // Clean up.
1126         
1127         if (err != noErr && *pFrameworkCFBndlRef != nil) {
1128                 CFRelease(*pFrameworkCFBndlRef);
1129                 *pFrameworkCFBndlRef = nil;
1130         }
1131         if (bundleURL != nil) {
1132                 CFRelease(bundleURL);
1133         }       
1134         if (baseURL != nil) {
1135                 CFRelease(baseURL);
1136         }       
1137         
1138         return err;
1139 }
1140
1141
1142
1143 static CFragConnectionID gCFragConnectionID = 0;
1144
1145 typedef pascal OSErr (*CDM_NewDeviceProcPtr)(CursorDevicePtr * ourDevice);
1146
1147 static OSErr MyCursorDeviceNewDevice(CursorDevicePtr * ourDevice)
1148 {
1149         static CDM_NewDeviceProcPtr sCDM_NewDeviceProcPtr = nil;
1150         OSStatus anErr = noErr;
1151
1152         if (nil == ourDevice) return paramErr;
1153
1154         if (!RunningOnCarbonX())
1155         {
1156                 if (!sCDM_NewDeviceProcPtr)
1157                 {
1158                         if (!gCFragConnectionID)
1159                         {
1160                                 Ptr             mainAddr;
1161                                 Str255  errName;
1162
1163                                 anErr = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch,
1164                                          kFindCFrag, &gCFragConnectionID, &mainAddr, errName);
1165                                 if (noErr != anErr) return anErr;
1166                         }
1167
1168                         if (gCFragConnectionID)
1169                         {
1170                                 CFragSymbolClass symClass;
1171
1172                                 anErr = FindSymbol(gCFragConnectionID, "\pCrsrDevNewDevice",
1173                                         (Ptr*) &sCDM_NewDeviceProcPtr, &symClass);
1174                                 if (noErr != anErr) return anErr;
1175                         }
1176                 }
1177                 if (sCDM_NewDeviceProcPtr)
1178                         anErr = (*sCDM_NewDeviceProcPtr)(ourDevice);
1179                 else
1180                         anErr = paramErr;
1181         }
1182
1183         return anErr;
1184 }
1185
1186 typedef pascal OSErr (*CDM_CursorDeviceMoveToProcPtr)(
1187                                                         CursorDevicePtr   ourDevice,
1188                                                         long              absX,
1189                                                         long              absY);
1190
1191 typedef UInt32 (*CGWarpMouseCursorPositionProcPtr)(CGPoint newCursorPosition);
1192 typedef UInt32 (*CGSetLocalEventsSuppressionIntervalProcPtr)(double pSeconds);
1193
1194 static OSErr MyCursorDeviceMoveTo(      CursorDevicePtr   ourDevice,
1195                                                         long              absX,
1196                                                         long              absY)
1197 {
1198         OSStatus anErr = noErr;
1199
1200         if (RunningOnCarbonX())
1201         {
1202                 static CGWarpMouseCursorPositionProcPtr sCGWarpMouseCursorPositionProcPtr = nil;
1203
1204                 if (nil == sCGWarpMouseCursorPositionProcPtr)
1205                 {
1206                         CFBundleRef tCFBundleRef;
1207
1208                         anErr = LoadFrameworkBundle(CFSTR("ApplicationServices.framework"), &tCFBundleRef);
1209
1210                         if (noErr == anErr)
1211                         {
1212                                 CGSetLocalEventsSuppressionIntervalProcPtr tCGSetLocalEventsSuppressionIntervalProcPtr = nil;
1213
1214                                 sCGWarpMouseCursorPositionProcPtr = (CGWarpMouseCursorPositionProcPtr)
1215                                         CFBundleGetFunctionPointerForName( tCFBundleRef, CFSTR("CGWarpMouseCursorPosition") );
1216                                 if (nil == sCGWarpMouseCursorPositionProcPtr)
1217                                         anErr = cfragNoSymbolErr;
1218
1219                                 tCGSetLocalEventsSuppressionIntervalProcPtr = (CGSetLocalEventsSuppressionIntervalProcPtr)
1220                                         CFBundleGetFunctionPointerForName(tCFBundleRef,CFSTR("CGSetLocalEventsSuppressionInterval"));
1221                                 if (nil != tCGSetLocalEventsSuppressionIntervalProcPtr)
1222                                         (*tCGSetLocalEventsSuppressionIntervalProcPtr)(0.0f);
1223                         }
1224                 }
1225
1226                 if (nil != sCGWarpMouseCursorPositionProcPtr)
1227                 {
1228                         CGPoint tCGPoint;
1229
1230                         tCGPoint.x = absX;
1231                         tCGPoint.y = absY;
1232
1233                         (*sCGWarpMouseCursorPositionProcPtr)(tCGPoint);
1234                 }
1235         }
1236         else
1237         {
1238                 static CDM_CursorDeviceMoveToProcPtr sCDM_CursorDeviceMoveToProcPtr = nil;
1239
1240                 if (!ourDevice) return paramErr;
1241
1242                 if (!sCDM_CursorDeviceMoveToProcPtr)
1243                 {
1244                         if (!gCFragConnectionID)
1245                         {
1246                                 Ptr             mainAddr;
1247                                 Str255  errName;
1248
1249                                 anErr = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch,
1250                                          kFindCFrag, &gCFragConnectionID, &mainAddr, errName);
1251                                 if (noErr != anErr) return anErr;
1252                         }
1253
1254                         if (gCFragConnectionID)
1255                         {
1256                                 CFragSymbolClass symClass;
1257
1258                                 anErr = FindSymbol(gCFragConnectionID, "\pCrsrDevMoveTo",
1259                                         (Ptr*) &sCDM_CursorDeviceMoveToProcPtr, &symClass);
1260                                 if (noErr != anErr) return anErr;
1261                         }
1262                 }
1263                 if (sCDM_CursorDeviceMoveToProcPtr)
1264                         anErr = (*sCDM_CursorDeviceMoveToProcPtr)(ourDevice,absX,absY);
1265                 else
1266                         anErr = paramErr;
1267         }
1268
1269         return anErr;
1270 }
1271
1272 static void DoMouse(void)
1273 {
1274         static CursorDevicePtr virtualCursorDevicePtr = nil;
1275         OSStatus anErr = noErr;
1276
1277          HideCursor();
1278
1279         if (nil == virtualCursorDevicePtr)
1280                 anErr = MyCursorDeviceNewDevice(&virtualCursorDevicePtr);
1281
1282         {
1283                 static Point lastMouse = {-1,-1};
1284                 Point globalMouse;
1285
1286                 GetGlobalMouse(&globalMouse);
1287         
1288                 if (EqualPt(lastMouse, globalMouse))
1289                 {
1290                         game.deltah=0;
1291                         game.deltav=0;
1292                 }
1293
1294                 if (!EqualPt(lastMouse, globalMouse))
1295                 {
1296                         static Point virtualMouse = {0,0};
1297                         delta = globalMouse;
1298
1299                         SubPt(lastMouse, &delta);
1300                         GetGlobalMouse(&lastMouse);
1301                         //AddPt(delta, &virtualMouse);
1302                         
1303                         if(mainmenu||(abs(delta.h)<10*realmultiplier*1000&&abs(delta.v)<10*realmultiplier*1000)){
1304                         game.deltah=delta.h*usermousesensitivity;
1305                         game.deltav=delta.v*usermousesensitivity;
1306                         game.mousecoordh=globalMouse.h;
1307                         game.mousecoordv=globalMouse.v;
1308                         }
1309 #if 1
1310                         //printf("\nMouse Moved: {%d,%d}.",globalMouse.h,globalMouse.v);
1311                         //printf("\tdelta: {%d,%d}.",delta.h,delta.v);
1312                         //printf("\tvirtual: {%d,%d}.",virtualMouse.h,virtualMouse.v);
1313 #endif
1314                         if(!mainmenu)
1315                         if(lastMouse.h>gMidPoint.h+100||lastMouse.h<gMidPoint.h-100||lastMouse.v>gMidPoint.v+100||lastMouse.v<gMidPoint.v-100){
1316                                 MyCursorDeviceMoveTo(virtualCursorDevicePtr,gMidPoint.h,gMidPoint.v);
1317                                 lastMouse = gMidPoint;
1318                         }
1319                 }
1320         }
1321 }
1322
1323
1324 // --------------------------------------------------------------------------
1325
1326 void DoMenu (SInt32 menuResult)
1327 {
1328         SInt16 theMenu;
1329         SInt16 theItem;
1330         MenuRef theMenuHandle;
1331                 
1332         theMenu = HiWord(menuResult);
1333         theItem = LoWord(menuResult);
1334         theMenuHandle = GetMenuHandle(theMenu);
1335
1336         switch (theMenu)
1337         {
1338                 case kMenuApple:
1339                         switch (theItem)
1340                         {
1341                                 case kAppleAbout:
1342                                         break;
1343                                 default:
1344                                         break;
1345                         }
1346                         break;
1347                 case kMenuFile:
1348                         switch (theItem)
1349                         {
1350                                 case kFileQuit:
1351                                         game.quit = true;
1352                                         break;
1353                         }
1354                         break;
1355         }
1356         HiliteMenu(0);
1357         DrawMenuBar();
1358 }
1359
1360 // --------------------------------------------------------------------------
1361
1362 void DoKey (SInt8 theKey, SInt8 theCode)
1363 {
1364         #pragma unused (theCode, theKey)
1365     /*if ((theKey == '=') || (theKey == '+'))
1366         gfScale *= 1.1;
1367     if (theKey == '-')
1368         gfScale /= 1.1;*/
1369         // do nothing
1370 }
1371
1372 // --------------------------------------------------------------------------
1373
1374
1375
1376 /*void DoUpdate (void)
1377 {
1378         static float sps=200;
1379         static int count;
1380         static float oldmult;
1381
1382         DoFrameRate();
1383         
1384         count = multiplier*sps;
1385         if(count<2)count=2;
1386         
1387         oldmult=multiplier;
1388         multiplier/=count;
1389         
1390         for(int i=0;i<count;i++){
1391                 game.Tick();
1392         }
1393         multiplier=oldmult;
1394         
1395         game.TickOnce();
1396         
1397         DoMouse();
1398
1399         DrawGL (&gRectPort);
1400 }*/
1401
1402 void DoUpdate (void)
1403 {
1404         static float sps=200;
1405         static int count;
1406         static float oldmult;
1407         
1408         DoFrameRate(1);
1409         
1410         if(multiplier>.6)multiplier=.6;
1411         
1412         game.fps=1/multiplier;
1413
1414         count = multiplier*sps;
1415         if(count<2)count=2;
1416         //if(count>10)count=10;
1417         
1418         realmultiplier=multiplier;
1419         multiplier*=gamespeed;
1420         if(difficulty==1)multiplier*=.9;
1421         if(difficulty==0)multiplier*=.8;
1422         
1423         if(game.loading==4)multiplier*=.00001;
1424
1425         //multiplier*.9;
1426         if(slomo&&!mainmenu)multiplier*=slomospeed;
1427         //if(freeze)multiplier*=0.00001;
1428         oldmult=multiplier;
1429         multiplier/=(float)count;
1430         
1431         DoMouse();
1432         
1433         game.TickOnce();
1434         
1435         for(int i=0;i<count;i++){
1436                 game.Tick();
1437         }
1438         multiplier=oldmult;
1439         
1440         game.TickOnceAfter();
1441         
1442         DrawGL (&gRectPort);
1443 }
1444
1445 // --------------------------------------------------------------------------
1446
1447 Boolean WaitNextEventWrapper (EventMask eventMask, EventRecord *theEvent, unsigned long sleep,RgnHandle mouseRgn)
1448 {
1449         return WaitNextEvent (eventMask, theEvent, sleep, mouseRgn);
1450 }
1451
1452 // --------------------------------------------------------------------------
1453
1454 OSStatus DSpProcessEventWrapper (EventRecord *inEvent, Boolean *outEventWasProcessed)
1455 {
1456         return DSpProcessEvent (inEvent, outEventWasProcessed);
1457 }
1458
1459 // --------------------------------------------------------------------------
1460
1461 void UpdateWrapper (EventRecord *theEvent)
1462 {
1463         WindowRef whichWindow;
1464         GrafPtr pGrafSave;
1465         
1466         whichWindow = (WindowRef) theEvent->message;
1467         GetPort (&pGrafSave);
1468         SetPort((GrafPtr) GetWindowPort(whichWindow));
1469         BeginUpdate(whichWindow);
1470         DoUpdate();
1471         SetPort((GrafPtr) GetWindowPort(whichWindow));
1472         EndUpdate(whichWindow);
1473         SetPort (pGrafSave);
1474 }
1475
1476 // --------------------------------------------------------------------------
1477
1478 pascal void IdleTimer (EventLoopTimerRef inTimer, void* userData)
1479 {
1480         #pragma unused (inTimer, userData)
1481         if(!stillloading)DoUpdate ();
1482 }
1483
1484 // --------------------------------------------------------------------------
1485
1486 EventLoopTimerUPP GetTimerUPP (void)
1487 {
1488         static EventLoopTimerUPP        sTimerUPP = NULL;
1489         
1490         if (sTimerUPP == NULL)
1491                 sTimerUPP = NewEventLoopTimerUPP (IdleTimer);
1492         
1493         return sTimerUPP;
1494 }
1495
1496 // --------------------------------------------------------------------------
1497
1498 pascal OSStatus mDown (EventHandlerCallRef ref, EventRef e,void * thedata) {
1499         EventMouseButton button;
1500         OSStatus status;
1501         
1502         status = GetEventParameter (e, kEventParamMouseButton, typeMouseButton, NULL, 
1503                 sizeof (button), NULL, &button);
1504         
1505         buttons[button-1] = true;               
1506         
1507         return eventNotHandledErr;
1508 }
1509
1510 pascal OSStatus mUp (EventHandlerCallRef ref, EventRef e,void * thedata) {
1511         EventMouseButton button = 0;
1512         OSStatus status;
1513         
1514         status = GetEventParameter (e, kEventParamMouseButton, typeMouseButton, NULL, 
1515                 sizeof (EventMouseButton), NULL, &button);
1516         
1517         buttons[button-1] = false;      
1518         
1519         return eventNotHandledErr;      
1520 }
1521
1522 void InstallHandlers(void){
1523         OSStatus status;
1524         EventTypeSpec spec;
1525         
1526         spec.eventClass = kEventClassMouse;
1527         spec.eventKind = kEventMouseDown;
1528
1529         status = InstallEventHandler (GetApplicationEventTarget(), 
1530                 NewEventHandlerUPP (mDown), 1, &spec, NULL, NULL);
1531         
1532         
1533         spec.eventKind = kEventMouseUp;
1534         
1535         status = InstallEventHandler (GetApplicationEventTarget(), 
1536                 NewEventHandlerUPP (mUp), 1, &spec, NULL, NULL);
1537
1538 }
1539
1540 void NewEvent(void) {
1541         EventRecord e;
1542         OSStatus s;
1543         
1544         
1545         /*ReceiveNextEvent (0, NULL, 1, true, &er);
1546         
1547         s = SendEventToEventTarget (er, GetEventDispatcherTarget());*/
1548         WaitNextEvent (everyEvent, &e, 0, NULL);
1549         
1550         DoUpdate();
1551 }
1552
1553 void DoEvent (void)
1554 {
1555         EventRecord theEvent;
1556         WindowRef whichWindow;
1557         SInt16 whatPart;
1558         Boolean fProcessed;
1559         
1560 // profile
1561 #if __profile__
1562         if (noErr == gProfErr)
1563                 ProfilerSetStatus(TRUE); // turn on profiling
1564 #endif
1565
1566         if (WaitNextEventWrapper (everyEvent, &theEvent, gSleepTime, NULL))
1567         {
1568                 DSpProcessEventWrapper (&theEvent, &fProcessed);
1569                 if (!fProcessed)
1570                 {
1571                         switch (theEvent.what)
1572                         {
1573                                 case mouseDown:
1574                                         whatPart = FindWindow (theEvent.where, &whichWindow);
1575                                         switch (whatPart)
1576                                         {
1577                                                 case inContent:
1578 //                                                      if (GetWindowFromPort (gpDSpPort) != FrontWindow()) 
1579 //                                                              SelectWindow (GetWindowFromPort (gpDSpPort));
1580                                                         break;
1581                                                 case inMenuBar:
1582                                                 {
1583                                                         SInt32 menuResult = MenuSelect (theEvent.where);
1584                                                         if (HiWord (menuResult) != 0)
1585                                                                 DoMenu (menuResult);
1586                                                 }
1587                                                         break;
1588                                                 case inDrag:
1589                                                         {
1590                                                                 // full screen no drag
1591                                                         }
1592                                                         break;
1593                                                 case inGrow:
1594                                                         {
1595                                                                 // full screen no grow
1596                                                         }
1597                                                         break;
1598                                                 case inGoAway:
1599                                                         {
1600                                                                 // full screen no go away
1601                                                         }
1602                                                         break;
1603                                                 case inZoomIn:
1604                                                 case inZoomOut:
1605                                                         {
1606                                                                 // full screen no zoom
1607                                                         }
1608                                                         break;
1609                                                 case inSysWindow:
1610                                                         break;
1611                                         }
1612                                         break;
1613                                 case keyDown:
1614                                 case autoKey:
1615                                 {
1616                                         SInt8 theKey;
1617                                         SInt8 theCode;
1618                                         theKey = theEvent.message & charCodeMask;
1619                                         theCode = (theEvent.message & keyCodeMask) >> 8;
1620                                         if ((theEvent.modifiers & cmdKey) != 0)
1621                                         {
1622                                                 SInt32 menuResult = MenuKey (theKey);
1623                                                 if (HiWord(menuResult) != 0)
1624                                                         DoMenu (menuResult);
1625                                         }
1626                                         else
1627                                                 DoKey (theKey, theCode);
1628                                 }
1629                                         break;
1630                                 case updateEvt:
1631                                 {
1632                                         UpdateWrapper (&theEvent);
1633                                 }
1634                                         break;
1635                                 case diskEvt:
1636                                         break;
1637                                 /*case osEvt:
1638                                         if (theEvent.message & 0x01000000)              //      Suspend/resume event
1639                                         {
1640                                                 if (theEvent.message & 0x00000001)      //      Resume
1641                                                 {
1642                                                         gSleepTime = kForegroundSleep;  
1643                                                         gfFrontProcess = true;
1644                                                 }
1645                                                 else
1646                                                 {
1647                                                         gSleepTime = kBackgroundSleep;  //      Suspend
1648                                                         gfFrontProcess = false;
1649                                                 }
1650                                         }
1651                                         break;*/
1652
1653                                 case kHighLevelEvent:
1654                                         AEProcessAppleEvent (&theEvent);
1655                                         break;
1656                         }
1657                 }
1658         }
1659 // profile
1660 #if __profile__
1661         if (noErr == gProfErr)
1662                 ProfilerSetStatus(FALSE); // turn profiling off again
1663 #endif
1664 }
1665
1666 // --------------------------------------------------------------------------
1667
1668 void CleanUp (void)
1669 {
1670         MenuHandle hMenu;
1671         
1672 // profile
1673 #if __profile__
1674         if (noErr == gProfErr)
1675         {
1676                 ProfilerDump ("\pGL DSp Carbon.prof");
1677                 ProfilerTerm ();
1678         }
1679 #endif
1680
1681         game.Dispose();
1682         
1683 #if defined kUseFades
1684         DSpDebugStr (DSpContext_FadeGammaOut (NULL, NULL)); // fade display, remove for debug
1685 #endif
1686
1687         RemoveEventLoopTimer(gTimer);
1688         gTimer = NULL;
1689
1690         DeleteFontGL (gFontList);
1691         CleanupAGL (gaglContext); // Cleanup the OpenGL context
1692         gaglContext = 0;
1693         if (gpDSpPort)
1694         {
1695                 ShutdownDSp (gpDSpPort); // DSp shutdown
1696                 gpDSpPort = NULL;
1697         }
1698
1699         
1700         hMenu = GetMenuHandle (kMenuFile);
1701         DeleteMenu (kMenuFile);
1702         DisposeMenu (hMenu);
1703
1704         hMenu = GetMenuHandle (kMenuApple);
1705         DeleteMenu (kMenuApple);
1706         DisposeMenu (hMenu);
1707
1708 #if defined kUseFades
1709         DSpDebugStr (DSpContext_FadeGammaIn (NULL, NULL)); // fade display, remove for debug
1710 #endif
1711         DSpShutdown ();
1712         
1713         ShowCursor();
1714 }
1715
1716 // --------------------------------------------------------------------------
1717 #include <iostream>
1718 #include <InternetConfig.h>
1719
1720 /*void openURL()
1721 {
1722 #ifdef Q_WS_MAC
1723         QString url("http://www.wolfire.com/");
1724         ICInstance icInstance
1725         OSType psiSignature = 'Psi ';
1726         OSStatus error = ::ICStart( &icInstance, psiSignature);
1727         if(error=noErr){
1728                 ConstStr255Param hint( 0x0 );
1729                 const char* data = url.latin1();
1730                 long length = url.length();
1731                 long start( 0 );
1732                 long end( length );
1733                 ::ICLaunchURL( icInstance, hint, data, length, &start, &end);
1734                 ICStop( icInstance);
1735         }
1736         #endif
1737 }*/
1738
1739 void LaunchURL(char *url)
1740 {
1741         ICInstance gICInstance;
1742         ICStart (&gICInstance, 0);
1743         long int start,fin;
1744         start=0;
1745         fin=strlen(url);
1746         ICLaunchURL(gICInstance, "\p" ,url, fin, &start, &fin);
1747 }
1748         
1749         
1750         
1751 int main (void)
1752 {
1753         try { 
1754                 if (SetUp ())   {
1755                         InstallHandlers();
1756                         while (!gDone&&!game.quit&&(!game.tryquit||!game.registered)) {
1757                                 NewEvent ();
1758                         }
1759                 }
1760                 CleanUp ();
1761                 if(game.registernow){
1762                         char url[100];
1763                         sprintf(url,"http://www.wolfire.com/register.html");
1764                         LaunchURL(url);
1765                 }
1766                 return 0;
1767         } catch (const std::exception& error) { 
1768                 ofstream opstream("error.txt"); 
1769         opstream << "Caught exception: " << error.what() << std::endl;
1770             opstream.close();
1771         }       
1772 }