]> git.jsancho.org Git - lugaru.git/blob - Source/OpenGL_Full_Screen.cpp
Build fixes.
[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>3000)screenwidth=640;
960                 if(screenwidth<0)screenwidth=640;
961                 if(screenheight>3000)screenheight=480;
962                 if(screenheight<0)screenheight=480;
963         }
964
965         
966         if(vblsync){    
967                 GLint swapInt = 1;
968                 aglSetInteger(gaglContext, AGL_SWAP_INTERVAL, &swapInt);
969         }
970         
971         if(kBitsPerPixel!=32&&kBitsPerPixel!=16){
972                 kBitsPerPixel=16;
973         }
974
975         
976         GDHandle hGD, hTargetDevice = NULL;
977         short numDevices = 0;
978         short fNum = 0;
979         short whichDevice = 0; // number of device to try (0 = 1st device)
980
981         InitToolbox ();
982         
983         gpDSpPort = NULL;
984         gaglContext = 0;
985         
986         // check for DSp
987         if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpStartup) 
988                 ReportError ("DSp not installed");
989
990         if (noErr != DSpDebugStr (DSpStartup()))
991                 return NULL;
992 //      DSpSetDebugMode (true);
993 #if defined kUseFades
994         DSpDebugStr (DSpContext_FadeGammaOut (NULL, NULL)); // fade display, remove for debug
995 #endif
996         
997         hGD = DMGetFirstScreenDevice (true); // check number of screens
998         hTargetDevice = hGD; // default to first device                                                 
999         do
1000         {
1001                 if (numDevices == whichDevice)
1002                         hTargetDevice = hGD; // if device number matches                                                
1003                 numDevices++;
1004                 hGD = DMGetNextScreenDevice (hGD, true);
1005         }
1006         while (hGD);
1007
1008 #if defined (kUseAGLFullScreenX)
1009         if (CheckMacOSX ()) // Try AGL full screen on Mac OS X
1010         {
1011                 short depth = kBitsPerPixel, width = kContextWidth, height = kContextHeight; 
1012                 gaglContext = SetupAGLFullScreen (hTargetDevice, &depth, &width, &height); // Setup the OpenGL context
1013                 SetRect (&gRectPort, 0, 0, width, height); // l, t, r, b
1014                 sprintf (gcstrMode, "AGL Full Screen: %d x %d x %d", width, height, depth);
1015         }
1016 #endif
1017         if (!gaglContext) //try DSp
1018         {
1019                 if (NULL != (gpDSpPort = SetupDSpFullScreen (hTargetDevice))) // Setup DSp for OpenGL sets hTargetDeviceto device actually used 
1020                 {
1021                         GetPortBounds (gpDSpPort, &gRectPort);
1022                         sprintf (gcstrMode, "DrawSprocket Full Screen: %d x %d x %d", gRectPort.right - gRectPort.left, gRectPort.bottom - gRectPort.top, (**(**hTargetDevice).gdPMap).pixelSize);
1023                         gaglContext = SetupAGL (hTargetDevice, gpDSpPort);
1024                 }
1025         }
1026         if (gaglContext)
1027         {
1028                 GetFNum("\pMonaco", &fNum);                                                                     // build font
1029                 gFontList = BuildFontGL (gaglContext, fNum, normal, 9);
1030                 //InstallEventLoopTimer (GetCurrentEventLoop(), 0, 0.0001, GetTimerUPP (), 0, &gTimer);
1031         }
1032         
1033         //gMidPoint.h = (gRectPort.left + gRectPort.right)/2;
1034         //gMidPoint.v = (gRectPort.top + gRectPort.bottom)/2;
1035         gMidPoint.h = 200;
1036         gMidPoint.v = 200;
1037         GLint swapInt = 1;
1038         //aglSetInteger(gaglContext, AGL_SWAP_INTERVAL, &swapInt);
1039         
1040 #if defined kUseFades
1041         DSpDebugStr (DSpContext_FadeGammaIn (NULL, NULL));
1042 #endif
1043         
1044         
1045         HideCursor();
1046         
1047         
1048     GLint width = gRectPort.right - gRectPort.left;
1049     GLint height = gRectPort.bottom - gRectPort.top;
1050     screenwidth=width;
1051     screenheight=height;
1052      
1053     game.newdetail=detail;
1054         game.newscreenwidth=screenwidth;
1055         game.newscreenheight=screenheight;
1056      
1057         game.InitGame();
1058         
1059         if (gaglContext)
1060                 return true;
1061         else
1062                 return false;
1063         
1064 }
1065
1066 static Boolean RunningOnCarbonX(void)
1067 {
1068         static Boolean first = true;
1069         static Boolean result = false;
1070
1071         if (first)
1072         {
1073                 UInt32 response;
1074
1075                 first = false;
1076
1077                 result = (Gestalt(gestaltSystemVersion, 
1078                     (SInt32 *) &response) == noErr)
1079                 && (response >= 0x01000);
1080         }
1081     return result;
1082 }
1083
1084 static OSStatus LoadFrameworkBundle(CFStringRef pFrameworkCFStrRef, CFBundleRef *pFrameworkCFBndlRef)
1085 {
1086         OSStatus        err;
1087         FSRef           frameworksFolderRef;
1088         CFURLRef        baseURL;
1089         CFURLRef        bundleURL;
1090         
1091         if (nil == pFrameworkCFBndlRef) return paramErr;
1092         
1093         *pFrameworkCFBndlRef = nil;
1094         
1095         baseURL = nil;
1096         bundleURL = nil;
1097         
1098         err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef);
1099         if (err == noErr) {
1100                 baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef);
1101                 if (baseURL == nil) {
1102                         err = coreFoundationUnknownErr;
1103                 }
1104         }
1105         if (err == noErr) {
1106                 bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, pFrameworkCFStrRef, false);
1107                 if (bundleURL == nil) {
1108                         err = coreFoundationUnknownErr;
1109                 }
1110         }
1111         if (err == noErr) {
1112                 *pFrameworkCFBndlRef = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL);
1113                 if (*pFrameworkCFBndlRef == nil) {
1114                         err = coreFoundationUnknownErr;
1115                 }
1116         }
1117         if (err == noErr) {
1118             if ( ! CFBundleLoadExecutable( *pFrameworkCFBndlRef ) ) {
1119                         err = coreFoundationUnknownErr;
1120             }
1121         }
1122
1123         // Clean up.
1124         
1125         if (err != noErr && *pFrameworkCFBndlRef != nil) {
1126                 CFRelease(*pFrameworkCFBndlRef);
1127                 *pFrameworkCFBndlRef = nil;
1128         }
1129         if (bundleURL != nil) {
1130                 CFRelease(bundleURL);
1131         }       
1132         if (baseURL != nil) {
1133                 CFRelease(baseURL);
1134         }       
1135         
1136         return err;
1137 }
1138
1139
1140
1141 static CFragConnectionID gCFragConnectionID = 0;
1142
1143 typedef pascal OSErr (*CDM_NewDeviceProcPtr)(CursorDevicePtr * ourDevice);
1144
1145 static OSErr MyCursorDeviceNewDevice(CursorDevicePtr * ourDevice)
1146 {
1147         static CDM_NewDeviceProcPtr sCDM_NewDeviceProcPtr = nil;
1148         OSStatus anErr = noErr;
1149
1150         if (nil == ourDevice) return paramErr;
1151
1152         if (!RunningOnCarbonX())
1153         {
1154                 if (!sCDM_NewDeviceProcPtr)
1155                 {
1156                         if (!gCFragConnectionID)
1157                         {
1158                                 Ptr             mainAddr;
1159                                 Str255  errName;
1160
1161                                 anErr = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch,
1162                                          kFindCFrag, &gCFragConnectionID, &mainAddr, errName);
1163                                 if (noErr != anErr) return anErr;
1164                         }
1165
1166                         if (gCFragConnectionID)
1167                         {
1168                                 CFragSymbolClass symClass;
1169
1170                                 anErr = FindSymbol(gCFragConnectionID, "\pCrsrDevNewDevice",
1171                                         (Ptr*) &sCDM_NewDeviceProcPtr, &symClass);
1172                                 if (noErr != anErr) return anErr;
1173                         }
1174                 }
1175                 if (sCDM_NewDeviceProcPtr)
1176                         anErr = (*sCDM_NewDeviceProcPtr)(ourDevice);
1177                 else
1178                         anErr = paramErr;
1179         }
1180
1181         return anErr;
1182 }
1183
1184 typedef pascal OSErr (*CDM_CursorDeviceMoveToProcPtr)(
1185                                                         CursorDevicePtr   ourDevice,
1186                                                         long              absX,
1187                                                         long              absY);
1188
1189 typedef UInt32 (*CGWarpMouseCursorPositionProcPtr)(CGPoint newCursorPosition);
1190 typedef UInt32 (*CGSetLocalEventsSuppressionIntervalProcPtr)(double pSeconds);
1191
1192 static OSErr MyCursorDeviceMoveTo(      CursorDevicePtr   ourDevice,
1193                                                         long              absX,
1194                                                         long              absY)
1195 {
1196         OSStatus anErr = noErr;
1197
1198         if (RunningOnCarbonX())
1199         {
1200                 static CGWarpMouseCursorPositionProcPtr sCGWarpMouseCursorPositionProcPtr = nil;
1201
1202                 if (nil == sCGWarpMouseCursorPositionProcPtr)
1203                 {
1204                         CFBundleRef tCFBundleRef;
1205
1206                         anErr = LoadFrameworkBundle(CFSTR("ApplicationServices.framework"), &tCFBundleRef);
1207
1208                         if (noErr == anErr)
1209                         {
1210                                 CGSetLocalEventsSuppressionIntervalProcPtr tCGSetLocalEventsSuppressionIntervalProcPtr = nil;
1211
1212                                 sCGWarpMouseCursorPositionProcPtr = (CGWarpMouseCursorPositionProcPtr)
1213                                         CFBundleGetFunctionPointerForName( tCFBundleRef, CFSTR("CGWarpMouseCursorPosition") );
1214                                 if (nil == sCGWarpMouseCursorPositionProcPtr)
1215                                         anErr = cfragNoSymbolErr;
1216
1217                                 tCGSetLocalEventsSuppressionIntervalProcPtr = (CGSetLocalEventsSuppressionIntervalProcPtr)
1218                                         CFBundleGetFunctionPointerForName(tCFBundleRef,CFSTR("CGSetLocalEventsSuppressionInterval"));
1219                                 if (nil != tCGSetLocalEventsSuppressionIntervalProcPtr)
1220                                         (*tCGSetLocalEventsSuppressionIntervalProcPtr)(0.0f);
1221                         }
1222                 }
1223
1224                 if (nil != sCGWarpMouseCursorPositionProcPtr)
1225                 {
1226                         CGPoint tCGPoint;
1227
1228                         tCGPoint.x = absX;
1229                         tCGPoint.y = absY;
1230
1231                         (*sCGWarpMouseCursorPositionProcPtr)(tCGPoint);
1232                 }
1233         }
1234         else
1235         {
1236                 static CDM_CursorDeviceMoveToProcPtr sCDM_CursorDeviceMoveToProcPtr = nil;
1237
1238                 if (!ourDevice) return paramErr;
1239
1240                 if (!sCDM_CursorDeviceMoveToProcPtr)
1241                 {
1242                         if (!gCFragConnectionID)
1243                         {
1244                                 Ptr             mainAddr;
1245                                 Str255  errName;
1246
1247                                 anErr = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch,
1248                                          kFindCFrag, &gCFragConnectionID, &mainAddr, errName);
1249                                 if (noErr != anErr) return anErr;
1250                         }
1251
1252                         if (gCFragConnectionID)
1253                         {
1254                                 CFragSymbolClass symClass;
1255
1256                                 anErr = FindSymbol(gCFragConnectionID, "\pCrsrDevMoveTo",
1257                                         (Ptr*) &sCDM_CursorDeviceMoveToProcPtr, &symClass);
1258                                 if (noErr != anErr) return anErr;
1259                         }
1260                 }
1261                 if (sCDM_CursorDeviceMoveToProcPtr)
1262                         anErr = (*sCDM_CursorDeviceMoveToProcPtr)(ourDevice,absX,absY);
1263                 else
1264                         anErr = paramErr;
1265         }
1266
1267         return anErr;
1268 }
1269
1270 static void DoMouse(void)
1271 {
1272         static CursorDevicePtr virtualCursorDevicePtr = nil;
1273         OSStatus anErr = noErr;
1274
1275          HideCursor();
1276
1277         if (nil == virtualCursorDevicePtr)
1278                 anErr = MyCursorDeviceNewDevice(&virtualCursorDevicePtr);
1279
1280         {
1281                 static Point lastMouse = {-1,-1};
1282                 Point globalMouse;
1283
1284                 GetGlobalMouse(&globalMouse);
1285         
1286                 if (EqualPt(lastMouse, globalMouse))
1287                 {
1288                         game.deltah=0;
1289                         game.deltav=0;
1290                 }
1291
1292                 if (!EqualPt(lastMouse, globalMouse))
1293                 {
1294                         static Point virtualMouse = {0,0};
1295                         delta = globalMouse;
1296
1297                         SubPt(lastMouse, &delta);
1298                         GetGlobalMouse(&lastMouse);
1299                         //AddPt(delta, &virtualMouse);
1300                         
1301                         if(mainmenu||(abs(delta.h)<10*realmultiplier*1000&&abs(delta.v)<10*realmultiplier*1000)){
1302                         game.deltah=delta.h*usermousesensitivity;
1303                         game.deltav=delta.v*usermousesensitivity;
1304                         game.mousecoordh=globalMouse.h;
1305                         game.mousecoordv=globalMouse.v;
1306                         }
1307 #if 1
1308                         //printf("\nMouse Moved: {%d,%d}.",globalMouse.h,globalMouse.v);
1309                         //printf("\tdelta: {%d,%d}.",delta.h,delta.v);
1310                         //printf("\tvirtual: {%d,%d}.",virtualMouse.h,virtualMouse.v);
1311 #endif
1312                         if(!mainmenu)
1313                         if(lastMouse.h>gMidPoint.h+100||lastMouse.h<gMidPoint.h-100||lastMouse.v>gMidPoint.v+100||lastMouse.v<gMidPoint.v-100){
1314                                 MyCursorDeviceMoveTo(virtualCursorDevicePtr,gMidPoint.h,gMidPoint.v);
1315                                 lastMouse = gMidPoint;
1316                         }
1317                 }
1318         }
1319 }
1320
1321
1322 // --------------------------------------------------------------------------
1323
1324 void DoMenu (SInt32 menuResult)
1325 {
1326         SInt16 theMenu;
1327         SInt16 theItem;
1328         MenuRef theMenuHandle;
1329                 
1330         theMenu = HiWord(menuResult);
1331         theItem = LoWord(menuResult);
1332         theMenuHandle = GetMenuHandle(theMenu);
1333
1334         switch (theMenu)
1335         {
1336                 case kMenuApple:
1337                         switch (theItem)
1338                         {
1339                                 case kAppleAbout:
1340                                         break;
1341                                 default:
1342                                         break;
1343                         }
1344                         break;
1345                 case kMenuFile:
1346                         switch (theItem)
1347                         {
1348                                 case kFileQuit:
1349                                         game.quit = true;
1350                                         break;
1351                         }
1352                         break;
1353         }
1354         HiliteMenu(0);
1355         DrawMenuBar();
1356 }
1357
1358 // --------------------------------------------------------------------------
1359
1360 void DoKey (SInt8 theKey, SInt8 theCode)
1361 {
1362         #pragma unused (theCode, theKey)
1363     /*if ((theKey == '=') || (theKey == '+'))
1364         gfScale *= 1.1;
1365     if (theKey == '-')
1366         gfScale /= 1.1;*/
1367         // do nothing
1368 }
1369
1370 // --------------------------------------------------------------------------
1371
1372
1373
1374 /*void DoUpdate (void)
1375 {
1376         static float sps=200;
1377         static int count;
1378         static float oldmult;
1379
1380         DoFrameRate();
1381         
1382         count = multiplier*sps;
1383         if(count<2)count=2;
1384         
1385         oldmult=multiplier;
1386         multiplier/=count;
1387         
1388         for(int i=0;i<count;i++){
1389                 game.Tick();
1390         }
1391         multiplier=oldmult;
1392         
1393         game.TickOnce();
1394         
1395         DoMouse();
1396
1397         DrawGL (&gRectPort);
1398 }*/
1399
1400 void DoUpdate (void)
1401 {
1402         static float sps=200;
1403         static int count;
1404         static float oldmult;
1405         
1406         DoFrameRate(1);
1407         
1408         if(multiplier>.6)multiplier=.6;
1409         
1410         game.fps=1/multiplier;
1411
1412         count = multiplier*sps;
1413         if(count<2)count=2;
1414         //if(count>10)count=10;
1415         
1416         realmultiplier=multiplier;
1417         multiplier*=gamespeed;
1418         if(difficulty==1)multiplier*=.9;
1419         if(difficulty==0)multiplier*=.8;
1420         
1421         if(game.loading==4)multiplier*=.00001;
1422
1423         //multiplier*.9;
1424         if(slomo&&!mainmenu)multiplier*=slomospeed;
1425         //if(freeze)multiplier*=0.00001;
1426         oldmult=multiplier;
1427         multiplier/=(float)count;
1428         
1429         DoMouse();
1430         
1431         game.TickOnce();
1432         
1433         for(int i=0;i<count;i++){
1434                 game.Tick();
1435         }
1436         multiplier=oldmult;
1437         
1438         game.TickOnceAfter();
1439         
1440         DrawGL (&gRectPort);
1441 }
1442
1443 // --------------------------------------------------------------------------
1444
1445 Boolean WaitNextEventWrapper (EventMask eventMask, EventRecord *theEvent, unsigned long sleep,RgnHandle mouseRgn)
1446 {
1447         return WaitNextEvent (eventMask, theEvent, sleep, mouseRgn);
1448 }
1449
1450 // --------------------------------------------------------------------------
1451
1452 OSStatus DSpProcessEventWrapper (EventRecord *inEvent, Boolean *outEventWasProcessed)
1453 {
1454         return DSpProcessEvent (inEvent, outEventWasProcessed);
1455 }
1456
1457 // --------------------------------------------------------------------------
1458
1459 void UpdateWrapper (EventRecord *theEvent)
1460 {
1461         WindowRef whichWindow;
1462         GrafPtr pGrafSave;
1463         
1464         whichWindow = (WindowRef) theEvent->message;
1465         GetPort (&pGrafSave);
1466         SetPort((GrafPtr) GetWindowPort(whichWindow));
1467         BeginUpdate(whichWindow);
1468         DoUpdate();
1469         SetPort((GrafPtr) GetWindowPort(whichWindow));
1470         EndUpdate(whichWindow);
1471         SetPort (pGrafSave);
1472 }
1473
1474 // --------------------------------------------------------------------------
1475
1476 pascal void IdleTimer (EventLoopTimerRef inTimer, void* userData)
1477 {
1478         #pragma unused (inTimer, userData)
1479         if(!stillloading)DoUpdate ();
1480 }
1481
1482 // --------------------------------------------------------------------------
1483
1484 EventLoopTimerUPP GetTimerUPP (void)
1485 {
1486         static EventLoopTimerUPP        sTimerUPP = NULL;
1487         
1488         if (sTimerUPP == NULL)
1489                 sTimerUPP = NewEventLoopTimerUPP (IdleTimer);
1490         
1491         return sTimerUPP;
1492 }
1493
1494 // --------------------------------------------------------------------------
1495
1496 pascal OSStatus mDown (EventHandlerCallRef ref, EventRef e,void * thedata) {
1497         EventMouseButton button;
1498         OSStatus status;
1499         
1500         status = GetEventParameter (e, kEventParamMouseButton, typeMouseButton, NULL, 
1501                 sizeof (button), NULL, &button);
1502         
1503         buttons[button-1] = true;               
1504         
1505         return eventNotHandledErr;
1506 }
1507
1508 pascal OSStatus mUp (EventHandlerCallRef ref, EventRef e,void * thedata) {
1509         EventMouseButton button = 0;
1510         OSStatus status;
1511         
1512         status = GetEventParameter (e, kEventParamMouseButton, typeMouseButton, NULL, 
1513                 sizeof (EventMouseButton), NULL, &button);
1514         
1515         buttons[button-1] = false;      
1516         
1517         return eventNotHandledErr;      
1518 }
1519
1520 void InstallHandlers(void){
1521         OSStatus status;
1522         EventTypeSpec spec;
1523         
1524         spec.eventClass = kEventClassMouse;
1525         spec.eventKind = kEventMouseDown;
1526
1527         status = InstallEventHandler (GetApplicationEventTarget(), 
1528                 NewEventHandlerUPP (mDown), 1, &spec, NULL, NULL);
1529         
1530         
1531         spec.eventKind = kEventMouseUp;
1532         
1533         status = InstallEventHandler (GetApplicationEventTarget(), 
1534                 NewEventHandlerUPP (mUp), 1, &spec, NULL, NULL);
1535
1536 }
1537
1538 void NewEvent(void) {
1539         EventRecord e;
1540         OSStatus s;
1541         
1542         
1543         /*ReceiveNextEvent (0, NULL, 1, true, &er);
1544         
1545         s = SendEventToEventTarget (er, GetEventDispatcherTarget());*/
1546         WaitNextEvent (everyEvent, &e, 0, NULL);
1547         
1548         DoUpdate();
1549 }
1550
1551 void DoEvent (void)
1552 {
1553         EventRecord theEvent;
1554         WindowRef whichWindow;
1555         SInt16 whatPart;
1556         Boolean fProcessed;
1557         
1558 // profile
1559 #if __profile__
1560         if (noErr == gProfErr)
1561                 ProfilerSetStatus(TRUE); // turn on profiling
1562 #endif
1563
1564         if (WaitNextEventWrapper (everyEvent, &theEvent, gSleepTime, NULL))
1565         {
1566                 DSpProcessEventWrapper (&theEvent, &fProcessed);
1567                 if (!fProcessed)
1568                 {
1569                         switch (theEvent.what)
1570                         {
1571                                 case mouseDown:
1572                                         whatPart = FindWindow (theEvent.where, &whichWindow);
1573                                         switch (whatPart)
1574                                         {
1575                                                 case inContent:
1576 //                                                      if (GetWindowFromPort (gpDSpPort) != FrontWindow()) 
1577 //                                                              SelectWindow (GetWindowFromPort (gpDSpPort));
1578                                                         break;
1579                                                 case inMenuBar:
1580                                                 {
1581                                                         SInt32 menuResult = MenuSelect (theEvent.where);
1582                                                         if (HiWord (menuResult) != 0)
1583                                                                 DoMenu (menuResult);
1584                                                 }
1585                                                         break;
1586                                                 case inDrag:
1587                                                         {
1588                                                                 // full screen no drag
1589                                                         }
1590                                                         break;
1591                                                 case inGrow:
1592                                                         {
1593                                                                 // full screen no grow
1594                                                         }
1595                                                         break;
1596                                                 case inGoAway:
1597                                                         {
1598                                                                 // full screen no go away
1599                                                         }
1600                                                         break;
1601                                                 case inZoomIn:
1602                                                 case inZoomOut:
1603                                                         {
1604                                                                 // full screen no zoom
1605                                                         }
1606                                                         break;
1607                                                 case inSysWindow:
1608                                                         break;
1609                                         }
1610                                         break;
1611                                 case keyDown:
1612                                 case autoKey:
1613                                 {
1614                                         SInt8 theKey;
1615                                         SInt8 theCode;
1616                                         theKey = theEvent.message & charCodeMask;
1617                                         theCode = (theEvent.message & keyCodeMask) >> 8;
1618                                         if ((theEvent.modifiers & cmdKey) != 0)
1619                                         {
1620                                                 SInt32 menuResult = MenuKey (theKey);
1621                                                 if (HiWord(menuResult) != 0)
1622                                                         DoMenu (menuResult);
1623                                         }
1624                                         else
1625                                                 DoKey (theKey, theCode);
1626                                 }
1627                                         break;
1628                                 case updateEvt:
1629                                 {
1630                                         UpdateWrapper (&theEvent);
1631                                 }
1632                                         break;
1633                                 case diskEvt:
1634                                         break;
1635                                 /*case osEvt:
1636                                         if (theEvent.message & 0x01000000)              //      Suspend/resume event
1637                                         {
1638                                                 if (theEvent.message & 0x00000001)      //      Resume
1639                                                 {
1640                                                         gSleepTime = kForegroundSleep;  
1641                                                         gfFrontProcess = true;
1642                                                 }
1643                                                 else
1644                                                 {
1645                                                         gSleepTime = kBackgroundSleep;  //      Suspend
1646                                                         gfFrontProcess = false;
1647                                                 }
1648                                         }
1649                                         break;*/
1650
1651                                 case kHighLevelEvent:
1652                                         AEProcessAppleEvent (&theEvent);
1653                                         break;
1654                         }
1655                 }
1656         }
1657 // profile
1658 #if __profile__
1659         if (noErr == gProfErr)
1660                 ProfilerSetStatus(FALSE); // turn profiling off again
1661 #endif
1662 }
1663
1664 // --------------------------------------------------------------------------
1665
1666 void CleanUp (void)
1667 {
1668         MenuHandle hMenu;
1669         
1670 // profile
1671 #if __profile__
1672         if (noErr == gProfErr)
1673         {
1674                 ProfilerDump ("\pGL DSp Carbon.prof");
1675                 ProfilerTerm ();
1676         }
1677 #endif
1678
1679         game.Dispose();
1680         
1681 #if defined kUseFades
1682         DSpDebugStr (DSpContext_FadeGammaOut (NULL, NULL)); // fade display, remove for debug
1683 #endif
1684
1685         RemoveEventLoopTimer(gTimer);
1686         gTimer = NULL;
1687
1688         DeleteFontGL (gFontList);
1689         CleanupAGL (gaglContext); // Cleanup the OpenGL context
1690         gaglContext = 0;
1691         if (gpDSpPort)
1692         {
1693                 ShutdownDSp (gpDSpPort); // DSp shutdown
1694                 gpDSpPort = NULL;
1695         }
1696
1697         
1698         hMenu = GetMenuHandle (kMenuFile);
1699         DeleteMenu (kMenuFile);
1700         DisposeMenu (hMenu);
1701
1702         hMenu = GetMenuHandle (kMenuApple);
1703         DeleteMenu (kMenuApple);
1704         DisposeMenu (hMenu);
1705
1706 #if defined kUseFades
1707         DSpDebugStr (DSpContext_FadeGammaIn (NULL, NULL)); // fade display, remove for debug
1708 #endif
1709         DSpShutdown ();
1710         
1711         ShowCursor();
1712 }
1713
1714 // --------------------------------------------------------------------------
1715 #include <iostream>
1716 #include <InternetConfig.h>
1717
1718 /*void openURL()
1719 {
1720 #ifdef Q_WS_MAC
1721         QString url("http://www.wolfire.com/");
1722         ICInstance icInstance
1723         OSType psiSignature = 'Psi ';
1724         OSStatus error = ::ICStart( &icInstance, psiSignature);
1725         if(error=noErr){
1726                 ConstStr255Param hint( 0x0 );
1727                 const char* data = url.latin1();
1728                 long length = url.length();
1729                 long start( 0 );
1730                 long end( length );
1731                 ::ICLaunchURL( icInstance, hint, data, length, &start, &end);
1732                 ICStop( icInstance);
1733         }
1734         #endif
1735 }*/
1736
1737 void LaunchURL(char *url)
1738 {
1739         ICInstance gICInstance;
1740         ICStart (&gICInstance, 0);
1741         long int start,fin;
1742         start=0;
1743         fin=strlen(url);
1744         ICLaunchURL(gICInstance, "\p" ,url, fin, &start, &fin);
1745 }
1746         
1747         
1748         
1749 int main (void)
1750 {
1751         try { 
1752                 if (SetUp ())   {
1753                         InstallHandlers();
1754                         while (!gDone&&!game.quit&&(!game.tryquit||!game.registered)) {
1755                                 NewEvent ();
1756                         }
1757                 }
1758                 CleanUp ();
1759                 if(game.registernow){
1760                         char url[100];
1761                         sprintf(url,"http://www.wolfire.com/register.html");
1762                         LaunchURL(url);
1763                 }
1764                 return 0;
1765         } catch (const std::exception& error) { 
1766                 ofstream opstream("error.txt"); 
1767         opstream << "Caught exception: " << error.what() << std::endl;
1768             opstream.close();
1769         }       
1770 }