2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 extern bool buttons[3];
26 extern float multiplier;
27 extern float screenwidth,screenheight;
29 extern float realmultiplier;
31 extern bool ismotionblur;
32 extern float usermousesensitivity;
34 extern bool floatjump;
35 extern bool cellophane;
36 extern int terraindetail;
38 extern int bloodtoggle;
40 extern bool autoslomo;
42 extern bool musictoggle;
43 extern bool trilinear;
44 extern float gamespeed;
45 extern int difficulty;
46 extern bool damageeffects;
47 extern int numplayers;
49 extern bool invertmouse;
50 extern bool texttoggle;
51 extern bool ambientsound;
52 extern bool mousejump;
54 extern Person player[maxplayers];
56 extern bool stillloading;
57 extern bool showpoints;
58 extern bool alwaysblur;
59 extern bool immediate;
60 extern bool velocityblur;
61 extern bool debugmode;
63 extern int kBitsPerPixel;
64 extern float slomospeed;
65 extern float slomofreq;
66 extern float oldgamespeed;
68 #define kUseAGLFullScreenX 1
71 // system includes ----------------------------------------------------------
74 #include "Carbon Include.h"
75 #include <Carbon/Carbon.h>
77 #include <DrawSprocket/DrawSprocket.h>
79 #include <AGL/aglRenderers.h>
80 #include <OpenGL/gl.h>
81 #include <OpenGL/glu.h>
83 #include <DrawSprocket.h>
87 #include <DriverServices.h>
93 #include <ToolUtils.h>
110 // project includes ---------------------------------------------------------
112 #include "aglString.h"
113 #include "MacInput.h"
115 // functions (internal/private) ---------------------------------------------
117 static UInt32 CheckMacOSX (void);
118 void CToPStr (StringPtr outString, const char *inString);
119 void ReportError (char * strError);
120 OSStatus DSpDebugStr (OSStatus error);
121 GLenum aglDebugStr (void);
122 GLenum glDebugStr (void);
124 CGrafPtr SetupDSpFullScreen (GDHandle hGD);
125 void ShutdownDSp (CGrafPtr pDSpPort);
127 AGLContext SetupAGL (GDHandle hGD, AGLDrawable win);
128 AGLContext SetupAGLFullScreen (GDHandle display, short * pDepth, short * pWidth, short * pHeight);
129 void CleanupAGL (AGLContext ctx);
130 void DrawGL (Rect * pRectPort);
132 void InitToolbox(void);
133 void CreateGLWindow (void);
134 Boolean SetUp (void);
135 void DoMenu (SInt32 menuResult);
136 void DoKey (SInt8 theKey, SInt8 theCode);
137 void DoUpdate (void);
139 pascal void IdleTimer (EventLoopTimerRef inTimer, void* userData);
140 EventLoopTimerUPP GetTimerUPP (void);
141 static Boolean RunningOnCarbonX(void);
147 Boolean WaitNextEventWrapper (EventMask eventMask, EventRecord *theEvent, unsigned long sleep,RgnHandle mouseRgn);
148 OSStatus DSpProcessEventWrapper (EventRecord *inEvent, Boolean *outEventWasProcessed);
149 void UpdateWrapper (EventRecord *theEvent);
151 // statics/globals (internal only) ------------------------------------------
167 kForegroundSleep = 10,
168 kBackgroundSleep = 10000
170 EventLoopTimerRef gTimer = NULL;
175 const RGBColor rgbBlack = { 0x0000, 0x0000, 0x0000 };
177 NumVersion gVersionDSp;
178 DSpContextAttributes gContextAttributes;
179 DSpContextReference gContext = 0;
180 extern AGLContext gaglContext;
182 char gcstrMode [256] = "";
184 AGLDrawable gpDSpPort = NULL; // will be NULL for full screen under X
185 Rect gRectPort = {0, 0, 0, 0};
187 UInt32 gSleepTime = kForegroundSleep;
188 Boolean gDone = false, gfFrontProcess = true;
194 OSErr gProfErr = noErr;
199 //-----------------------------------------------------------------------------------------------------------------------
201 // are we running on Mac OS X
202 // returns 0 if < Mac OS X or version number of Mac OS X (10.0 for GM)
204 static UInt32 CheckMacOSX (void)
208 if ((Gestalt(gestaltSystemVersion, (SInt32 *) &response) == noErr) && (response >= 0x01000))
214 //-----------------------------------------------------------------------------------------------------------------------
216 // Copy C string to Pascal string
218 void CToPStr (StringPtr outString, const char *inString)
222 *(((char*)outString) + x + 1) = *(inString + x++);
223 while ((*(inString + x) != 0) && (x < 256));
224 *((char*)outString) = (char) x;
227 // --------------------------------------------------------------------------
229 void ReportError (char * strError)
231 char errMsgCStr [256];
234 sprintf (errMsgCStr, "%s", strError);
236 // out as debug string
237 CToPStr (strErr, errMsgCStr);
241 //-----------------------------------------------------------------------------------------------------------------------
243 OSStatus DSpDebugStr (OSStatus error)
249 case kDSpNotInitializedErr:
250 ReportError ("DSp Error: Not initialized");
252 case kDSpSystemSWTooOldErr:
253 ReportError ("DSp Error: system Software too old");
255 case kDSpInvalidContextErr:
256 ReportError ("DSp Error: Invalid context");
258 case kDSpInvalidAttributesErr:
259 ReportError ("DSp Error: Invalid attributes");
261 case kDSpContextAlreadyReservedErr:
262 ReportError ("DSp Error: Context already reserved");
264 case kDSpContextNotReservedErr:
265 ReportError ("DSp Error: Context not reserved");
267 case kDSpContextNotFoundErr:
268 ReportError ("DSp Error: Context not found");
270 case kDSpFrameRateNotReadyErr:
271 ReportError ("DSp Error: Frame rate not ready");
273 case kDSpConfirmSwitchWarning:
274 // ReportError ("DSp Warning: Must confirm switch"); // removed since it is just a warning, add back for debugging
275 return 0; // don't want to fail on this warning
277 case kDSpInternalErr:
278 ReportError ("DSp Error: Internal error");
280 case kDSpStereoContextErr:
281 ReportError ("DSp Error: Stereo context");
287 //-----------------------------------------------------------------------------------------------------------------------
289 // if error dump agl errors to debugger string, return error
291 GLenum aglDebugStr (void)
293 GLenum err = aglGetError();
294 if (AGL_NO_ERROR != err)
295 ReportError ((char *)aglErrorString(err));
299 //-----------------------------------------------------------------------------------------------------------------------
301 // if error dump agl errors to debugger string, return error
303 GLenum glDebugStr (void)
305 GLenum err = glGetError();
306 if (GL_NO_ERROR != err)
307 ReportError ((char *)gluErrorString(err));
312 //-----------------------------------------------------------------------------------------------------------------------
314 // Set up DSp screen on graphics device requested
315 // side effect: sets both gpDSpWindow and gpPort
317 CGrafPtr SetupDSpFullScreen (GDHandle hGD)
319 DSpContextAttributes foundAttributes;
320 DisplayIDType displayID = NULL;
322 if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpGetVersion)
324 ReportError ("DrawSprocket not installed.");
328 gVersionDSp = DSpGetVersion ();
330 if ((gVersionDSp.majorRev == 0x01) && (gVersionDSp.minorAndBugRev < 0x99))
332 // this version of DrawSprocket is not completely functional on Mac OS X
335 ReportError ("DrawSprocket 1.99 or greate required on Mac OS X, please update to at least Mac OS X 10.1.");
340 // Note: DSp < 1.7.3 REQUIRES the back buffer attributes even if only one buffer is required
341 memset(&gContextAttributes, 0, sizeof (DSpContextAttributes));
342 gContextAttributes.displayWidth = kContextWidth;
343 gContextAttributes.displayHeight = kContextHeight;
344 gContextAttributes.colorNeeds = kDSpColorNeeds_Require;
345 gContextAttributes.displayBestDepth = kBitsPerPixel;
346 gContextAttributes.backBufferBestDepth = kBitsPerPixel;
347 gContextAttributes.displayDepthMask = kDSpDepthMask_All;
348 gContextAttributes.backBufferDepthMask = kDSpDepthMask_All;
349 gContextAttributes.pageCount = 1; // only the front buffer is needed
351 screenwidth=kContextWidth;
352 screenheight=kContextHeight;
354 DMGetDisplayIDByGDevice (hGD, &displayID, true);
356 if (noErr != DSpDebugStr (DSpFindBestContextOnDisplayID (&gContextAttributes, &gContext, displayID)))
358 ReportError ("DSpFindBestContext() had an error.");
362 if (noErr != DSpDebugStr (DSpContext_GetAttributes (gContext, &foundAttributes))) // see what we actually found
364 ReportError ("DSpContext_GetAttributes() had an error.");
368 // reset width and height to full screen and handle our own centering
369 // HWA will not correctly center less than full screen size contexts
370 gContextAttributes.displayWidth = foundAttributes.displayWidth;
371 gContextAttributes.displayHeight = foundAttributes.displayHeight;
372 gContextAttributes.pageCount = 1; // only the front buffer is needed
373 gContextAttributes.contextOptions = 0 | kDSpContextOption_DontSyncVBL; // no page flipping and no VBL sync needed
375 DSpSetBlankingColor(&rgbBlack);
377 if (noErr != DSpDebugStr (DSpContext_Reserve ( gContext, &gContextAttributes))) // reserve our context
379 ReportError ("DSpContext_Reserve() had an error.");
385 if (noErr != DSpDebugStr (DSpContext_SetState (gContext, kDSpContextState_Active))) // activate our context
387 ReportError ("DSpContext_SetState() had an error.");
392 if ((CheckMacOSX ()) && !((gVersionDSp.majorRev > 0x01) || ((gVersionDSp.majorRev == 0x01) && (gVersionDSp.minorAndBugRev >= 0x99))))// DSp should be supported in version after 1.98
394 ReportError ("Mac OS X with DSp < 1.99 does not support DrawSprocket for OpenGL full screen");
397 else if (CheckMacOSX ()) // DSp should be supported in versions 1.99 and later
400 // use DSp's front buffer on Mac OS X
401 if (noErr != DSpDebugStr (DSpContext_GetFrontBuffer (gContext, &pPort)))
403 ReportError ("DSpContext_GetFrontBuffer() had an error.");
406 // there is a problem in Mac OS X 10.0 GM CoreGraphics that may not size the port pixmap correctly
407 // this will check the vertical sizes and offset if required to fix the problem
408 // this will not center ports that are smaller then a particular resolution
412 PixMapHandle hPix = GetPortPixMap (pPort);
413 Rect pixBounds = (**hPix).bounds;
414 GetPortBounds (pPort, &portBounds);
415 deltaV = (portBounds.bottom - portBounds.top) - (pixBounds.bottom - pixBounds.top) +
416 (portBounds.bottom - portBounds.top - kContextHeight) / 2;
417 deltaH = -(portBounds.right - portBounds.left - kContextWidth) / 2;
418 if (deltaV || deltaH)
421 GetPort (&pPortSave);
422 SetPort ((GrafPtr)pPort);
423 // set origin to account for CG offset and if requested drawable smaller than screen rez
424 SetOrigin (deltaH, deltaV);
430 else // Mac OS 9 or less
436 // create a new window in our context
437 // note: OpenGL is expecting a window so it can enumerate the devices it spans,
438 // center window in our context's gdevice
439 rectWin.top = (short) ((**hGD).gdRect.top + ((**hGD).gdRect.bottom - (**hGD).gdRect.top) / 2); // h center
440 rectWin.top -= (short) (kContextHeight / 2);
441 rectWin.left = (short) ((**hGD).gdRect.left + ((**hGD).gdRect.right - (**hGD).gdRect.left) / 2); // v center
442 rectWin.left -= (short) (kContextWidth / 2);
443 rectWin.right = (short) (rectWin.left + kContextWidth);
444 rectWin.bottom = (short) (rectWin.top + kContextHeight);
446 pWindow = NewCWindow (NULL, &rectWin, "\p", 0, plainDBox, (WindowPtr)-1, 0, 0);
448 // paint back ground black before fade in to avoid white background flash
450 GetPort (&pGrafSave);
451 SetPortWindowPort (pWindow);
452 GetForeColor (&rgbSave);
453 RGBForeColor (&rgbBlack);
456 GetWindowPortBounds (pWindow, &paintRect);
457 PaintRect (&paintRect);
459 RGBForeColor (&rgbSave); // ensure color is reset for proper blitting
461 return (GetWindowPort (pWindow));
465 //-----------------------------------------------------------------------------------------------------------------------
469 void ShutdownDSp (CGrafPtr pDSpPort)
471 if ((NULL != pDSpPort) && !CheckMacOSX ())
472 DisposeWindow (GetWindowFromPort (pDSpPort));
473 DSpContext_SetState( gContext, kDSpContextState_Inactive);
474 DSpContext_Release (gContext);
478 //-----------------------------------------------------------------------------------------------------------------------
483 AGLContext SetupAGL (GDHandle hGD, AGLDrawable drawable)
490 // different possible pixel format choices for different renderers
491 // basics requirements are RGBA and double buffer
492 // OpenGLz will select acclerated context if available
495 attrib [i++] = AGL_RGBA; // red green blue and alpha
496 attrib [i++] = AGL_DOUBLEBUFFER; // double buffered
497 attrib [i++] = AGL_DEPTH_SIZE;
499 attrib [i++] = AGL_ACCELERATED; // HWA pixel format only
500 attrib [i++] = AGL_NONE;
502 if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL
504 ReportError ("OpenGL not installed");
509 fmt = aglChoosePixelFormat (&hGD, 1, attrib); // get an appropriate pixel format
511 fmt = aglChoosePixelFormat(NULL, 0, attrib); // get an appropriate pixel format
515 ReportError("Could not find valid pixel format");
519 ctx = aglCreateContext (fmt, NULL); // Create an AGL context
523 ReportError ("Could not create context");
527 if (!aglSetDrawable (ctx, drawable)) // attach the window to the context
529 ReportError ("SetDrawable failed");
535 if (!aglSetCurrentContext (ctx)) // make the context the current context
538 aglSetDrawable (ctx, NULL);
542 aglDestroyPixelFormat(fmt); // pixel format is no longer needed
547 //-----------------------------------------------------------------------------------------------------------------------
551 AGLContext SetupAGLFullScreen (GDHandle display, short * pDepth, short * pWidth, short * pHeight)
554 GLint attrib[] ={AGL_RGBA, AGL_DOUBLEBUFFER,AGL_DEPTH_SIZE, 16, AGL_FULLSCREEN,AGL_ALL_RENDERERS, AGL_NONE};
560 if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL
562 ReportError ("OpenGL not installed");
566 fmt = aglChoosePixelFormat(&display, 1, attrib); // this may fail if looking for acclerated across multiple monitors
569 ReportError("Could not find valid pixel format");
574 ctx = aglCreateContext (fmt, NULL); // Create an AGL context
577 ReportError ("Could not create context");
582 if (!aglSetFullScreen (ctx, *pWidth, *pHeight, 60, 0))
584 ReportError ("SetFullScreen failed");
589 if (!aglSetCurrentContext (ctx)) // make the context the current context
591 ReportError ("SetCurrentContext failed");
593 aglSetDrawable (ctx, NULL); // turn off full screen
597 aglDestroyPixelFormat(fmt); // pixel format is no longer needed
602 //-----------------------------------------------------------------------------------------------------------------------
606 void CleanupAGL(AGLContext ctx)
608 aglSetDrawable (ctx, NULL);
609 aglSetCurrentContext (NULL);
610 aglDestroyContext (ctx);
613 //-----------------------------------------------------------------------------------------------------------------------
617 void DrawGL (Rect * pRectPort)
619 if (gaglContext == 0)
621 aglSetCurrentContext (gaglContext); // ensure our context is current prior to drawing
624 GLint width = pRectPort->right - pRectPort->left;
625 GLint height = pRectPort->bottom - pRectPort->top;
628 /* glViewport ((width - (width * 1)) / 2, (height - (height * 1)) / 2,
629 width * 1, height * 1);*/
640 glViewport (0, 0, pRectPort->right - pRectPort->left, pRectPort->bottom - pRectPort->top);
641 glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
642 glMatrixMode (GL_PROJECTION);
645 glMatrixMode (GL_MODELVIEW);
648 glScalef (2.0 / (pRectPort->right - pRectPort->left), -2.0 / (pRectPort->bottom - pRectPort->top), 1.0);
649 glTranslatef (-(pRectPort->right - pRectPort->left) / 2.0, -(pRectPort->bottom - pRectPort->top) / 2.0, 0.0);
650 glColor3f (1.0, 1.0, 1.0);
651 glRasterPos3d (10, 12, 0);
652 DrawFrameRate (gFontList);
653 glRasterPos3d (10, 24, 0);
654 DrawCStringGL (gcstrMode, gFontList);
655 glRasterPos3d (10, (pRectPort->bottom - pRectPort->top) - 15, 0);
656 DrawCStringGL ((char*) glGetString (GL_VENDOR), gFontList);
657 glRasterPos3d (10, (pRectPort->bottom - pRectPort->top) - 3, 0);
658 DrawCStringGL ((char*) glGetString (GL_RENDERER), gFontList);
659 static char aChar[256] = "";
660 sprintf (aChar, " Mac OS X: %d", RunningOnCarbonX());
661 DrawCStringGL (aChar, gFontList);
663 glMatrixMode (GL_PROJECTION);
665 glMatrixMode (matrixMode);
668 //aglSwapBuffers(gaglContext); // send swap command
672 //-----------------------------------------------------------------------------------------------------------------------
674 static pascal OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, SInt32 refcon )
676 #pragma unused (appleEvt, reply, refcon)
682 //-----------------------------------------------------------------------------------------------------------------------
684 void InitToolbox(void)
695 // ProfilerInit (collection method, time base, num funcs, stack depth)
697 gProfErr = ProfilerInit (collectDetailed, bestTimeBase, 20, 10); // set up profiling
698 // something that you may need to do (may need more memory)
699 // gProfErr = ProfilerInit (collectSummary, bestTimeBase, 1000, 100); // set up profiling
700 // Note: application will likely run slower, but still should be useful info
701 if (noErr == gProfErr)
702 ProfilerSetStatus(FALSE);
706 menu = NewMenu (kMenuApple, "\p\024"); // new apple menu
707 InsertMenu (menu, 0); // add menu to end
709 menu = NewMenu (kMenuFile, "\pFile"); // new menu
710 InsertMenu (menu, 0); // add menu to end
712 // insert application menus here
714 // add quit if not under Mac OS X
715 err = Gestalt (gestaltMenuMgrAttr, &response);
716 if ((err == noErr) && !(response & gestaltMenuMgrAquaLayoutMask))
717 AppendMenu (menu, "\pQuit/Q"); // add quit
720 err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false );
725 // --------------------------------------------------------------------------
727 static Point gMidPoint;
733 SetQDGlobalsRandomSeed(TickCount());
736 if(CheckMacOSX ())osx = 1;
737 ifstream ipstream(":Data:config.txt");
740 usermousesensitivity=1;
766 game.crouchkey=MAC_SHIFT_KEY;
767 game.jumpkey=MAC_SPACE_KEY;
768 game.leftkey=MAC_A_KEY;
769 game.forwardkey=MAC_W_KEY;
770 game.backkey=MAC_S_KEY;
771 game.rightkey=MAC_D_KEY;
772 game.drawkey=MAC_E_KEY;
773 game.throwkey=MAC_Q_KEY;
774 game.attackkey=MAC_MOUSEBUTTON1;
775 game.chatkey=MAC_T_KEY;
781 ofstream opstream(":Data:config.txt");
782 opstream << "Screenwidth:\n";
783 opstream << kContextWidth;
784 opstream << "\nScreenheight:\n";
785 opstream << kContextHeight;
786 opstream << "\nMouse sensitivity:\n";
787 opstream << usermousesensitivity;
788 opstream << "\nBlur(0,1):\n";
789 opstream << ismotionblur;
790 opstream << "\nOverall Detail(0,1,2) higher=better:\n";
792 opstream << "\nFloating jump:\n";
793 opstream << floatjump;
794 opstream << "\nMouse jump:\n";
795 opstream << mousejump;
796 opstream << "\nAmbient sound:\n";
797 opstream << ambientsound;
798 opstream << "\nBlood (0,1,2):\n";
799 opstream << bloodtoggle;
800 opstream << "\nAuto slomo:\n";
801 opstream << autoslomo;
802 opstream << "\nFoliage:\n";
804 opstream << "\nMusic:\n";
805 opstream << musictoggle;
806 opstream << "\nTrilinear:\n";
807 opstream << trilinear;
808 opstream << "\nDecals(shadows,blood puddles,etc):\n";
810 opstream << "\nInvert mouse:\n";
811 opstream << invertmouse;
812 opstream << "\nGamespeed:\n";
813 opstream << gamespeed;
814 opstream << "\nDifficulty(0,1,2) higher=harder:\n";
815 opstream << difficulty;
816 opstream << "\nDamage effects(blackout, doublevision):\n";
817 opstream << damageeffects;
818 opstream << "\nText:\n";
819 opstream << texttoggle;
820 opstream << "\nDebug:\n";
821 opstream << debugmode;
822 opstream << "\nVBL Sync:\n";
824 opstream << "\nShow Points:\n";
825 opstream << showpoints;
826 opstream << "\nAlways Blur:\n";
827 opstream << alwaysblur;
828 opstream << "\nImmediate mode (turn on on G5):\n";
829 opstream << immediate;
830 opstream << "\nVelocity blur:\n";
831 opstream << velocityblur;
832 opstream << "\nForward key:\n";
833 opstream << KeyToChar(game.forwardkey);
834 opstream << "\nBack key:\n";
835 opstream << KeyToChar(game.backkey);
836 opstream << "\nLeft key:\n";
837 opstream << KeyToChar(game.leftkey);
838 opstream << "\nRight key:\n";
839 opstream << KeyToChar(game.rightkey);
840 opstream << "\nJump key:\n";
841 opstream << KeyToChar(game.jumpkey);
842 opstream << "\nCrouch key:\n";
843 opstream << KeyToChar(game.crouchkey);
844 opstream << "\nDraw key:\n";
845 opstream << KeyToChar(game.drawkey);
846 opstream << "\nThrow key:\n";
847 opstream << KeyToChar(game.throwkey);
848 opstream << "\nAttack key:\n";
849 opstream << KeyToChar(game.attackkey);
850 opstream << "\nChat key:\n";
851 opstream << KeyToChar(game.chatkey);
855 ipstream.ignore(256,'\n');
856 ipstream >> kContextWidth;
857 ipstream.ignore(256,'\n');
858 ipstream.ignore(256,'\n');
859 ipstream >> kContextHeight;
860 ipstream.ignore(256,'\n');
861 ipstream.ignore(256,'\n');
862 ipstream >> usermousesensitivity;
863 ipstream.ignore(256,'\n');
864 ipstream.ignore(256,'\n');
865 ipstream >> ismotionblur;
866 ipstream.ignore(256,'\n');
867 ipstream.ignore(256,'\n');
869 if(detail!=0)kBitsPerPixel=32;
870 else kBitsPerPixel=16;
871 ipstream.ignore(256,'\n');
872 ipstream.ignore(256,'\n');
873 ipstream >> floatjump;
874 ipstream.ignore(256,'\n');
875 ipstream.ignore(256,'\n');
876 ipstream >> mousejump;
877 ipstream.ignore(256,'\n');
878 ipstream.ignore(256,'\n');
879 ipstream >> ambientsound;
880 ipstream.ignore(256,'\n');
881 ipstream.ignore(256,'\n');
882 ipstream >> bloodtoggle;
883 ipstream.ignore(256,'\n');
884 ipstream.ignore(256,'\n');
885 ipstream >> autoslomo;
886 ipstream.ignore(256,'\n');
887 ipstream.ignore(256,'\n');
889 ipstream.ignore(256,'\n');
890 ipstream.ignore(256,'\n');
891 ipstream >> musictoggle;
892 ipstream.ignore(256,'\n');
893 ipstream.ignore(256,'\n');
894 ipstream >> trilinear;
895 ipstream.ignore(256,'\n');
896 ipstream.ignore(256,'\n');
898 ipstream.ignore(256,'\n');
899 ipstream.ignore(256,'\n');
900 ipstream >> invertmouse;
901 ipstream.ignore(256,'\n');
902 ipstream.ignore(256,'\n');
903 ipstream >> gamespeed;
904 oldgamespeed=gamespeed;
909 ipstream.ignore(256,'\n');
910 ipstream.ignore(256,'\n');
911 ipstream >> difficulty;
912 ipstream.ignore(256,'\n');
913 ipstream.ignore(256,'\n');
914 ipstream >> damageeffects;
915 ipstream.ignore(256,'\n');
916 ipstream.ignore(256,'\n');
917 ipstream >> texttoggle;
918 ipstream.ignore(256,'\n');
919 ipstream.ignore(256,'\n');
920 ipstream >> debugmode;
921 ipstream.ignore(256,'\n');
922 ipstream.ignore(256,'\n');
924 ipstream.ignore(256,'\n');
925 ipstream.ignore(256,'\n');
926 ipstream >> showpoints;
927 ipstream.ignore(256,'\n');
928 ipstream.ignore(256,'\n');
929 ipstream >> alwaysblur;
930 ipstream.ignore(256,'\n');
931 ipstream.ignore(256,'\n');
932 ipstream >> immediate;
933 ipstream.ignore(256,'\n');
934 ipstream.ignore(256,'\n');
935 ipstream >> velocityblur;
936 ipstream.ignore(256,'\n');
937 ipstream.ignore(256,'\n');
939 game.forwardkey=CharToKey(string);
940 ipstream.ignore(256,'\n');
941 ipstream.ignore(256,'\n');
943 game.backkey=CharToKey(string);
944 ipstream.ignore(256,'\n');
945 ipstream.ignore(256,'\n');
947 game.leftkey=CharToKey(string);
948 ipstream.ignore(256,'\n');
949 ipstream.ignore(256,'\n');
951 game.rightkey=CharToKey(string);
952 ipstream.ignore(256,'\n');
953 ipstream.ignore(256,'\n');
955 game.jumpkey=CharToKey(string);
956 ipstream.ignore(256,'\n');
957 ipstream.ignore(256,'\n');
959 game.crouchkey=CharToKey(string);
960 ipstream.ignore(256,'\n');
961 ipstream.ignore(256,'\n');
963 game.drawkey=CharToKey(string);
964 ipstream.ignore(256,'\n');
965 ipstream.ignore(256,'\n');
967 game.throwkey=CharToKey(string);
968 ipstream.ignore(256,'\n');
969 ipstream.ignore(256,'\n');
971 game.attackkey=CharToKey(string);
972 ipstream.ignore(256,'\n');
973 ipstream.ignore(256,'\n');
975 game.chatkey=CharToKey(string);
978 if(detail>2)detail=2;
979 if(detail<0)detail=0;
980 if(screenwidth<0)screenwidth=640;
981 if(screenheight<0)screenheight=480;
982 #if !USE_SDL // we'll take anything that works.
983 if(screenwidth>3000)screenwidth=640;
984 if(screenheight>3000)screenheight=480;
991 aglSetInteger(gaglContext, AGL_SWAP_INTERVAL, &swapInt);
994 if(kBitsPerPixel!=32&&kBitsPerPixel!=16){
999 GDHandle hGD, hTargetDevice = NULL;
1000 short numDevices = 0;
1002 short whichDevice = 0; // number of device to try (0 = 1st device)
1010 if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpStartup)
1011 ReportError ("DSp not installed");
1013 if (noErr != DSpDebugStr (DSpStartup()))
1015 // DSpSetDebugMode (true);
1016 #if defined kUseFades
1017 DSpDebugStr (DSpContext_FadeGammaOut (NULL, NULL)); // fade display, remove for debug
1020 hGD = DMGetFirstScreenDevice (true); // check number of screens
1021 hTargetDevice = hGD; // default to first device
1024 if (numDevices == whichDevice)
1025 hTargetDevice = hGD; // if device number matches
1027 hGD = DMGetNextScreenDevice (hGD, true);
1031 #if defined (kUseAGLFullScreenX)
1032 if (CheckMacOSX ()) // Try AGL full screen on Mac OS X
1034 short depth = kBitsPerPixel, width = kContextWidth, height = kContextHeight;
1035 gaglContext = SetupAGLFullScreen (hTargetDevice, &depth, &width, &height); // Setup the OpenGL context
1036 SetRect (&gRectPort, 0, 0, width, height); // l, t, r, b
1037 sprintf (gcstrMode, "AGL Full Screen: %d x %d x %d", width, height, depth);
1040 if (!gaglContext) //try DSp
1042 if (NULL != (gpDSpPort = SetupDSpFullScreen (hTargetDevice))) // Setup DSp for OpenGL sets hTargetDeviceto device actually used
1044 GetPortBounds (gpDSpPort, &gRectPort);
1045 sprintf (gcstrMode, "DrawSprocket Full Screen: %d x %d x %d", gRectPort.right - gRectPort.left, gRectPort.bottom - gRectPort.top, (**(**hTargetDevice).gdPMap).pixelSize);
1046 gaglContext = SetupAGL (hTargetDevice, gpDSpPort);
1051 GetFNum("\pMonaco", &fNum); // build font
1052 gFontList = BuildFontGL (gaglContext, fNum, normal, 9);
1053 //InstallEventLoopTimer (GetCurrentEventLoop(), 0, 0.0001, GetTimerUPP (), 0, &gTimer);
1056 //gMidPoint.h = (gRectPort.left + gRectPort.right)/2;
1057 //gMidPoint.v = (gRectPort.top + gRectPort.bottom)/2;
1061 //aglSetInteger(gaglContext, AGL_SWAP_INTERVAL, &swapInt);
1063 #if defined kUseFades
1064 DSpDebugStr (DSpContext_FadeGammaIn (NULL, NULL));
1071 GLint width = gRectPort.right - gRectPort.left;
1072 GLint height = gRectPort.bottom - gRectPort.top;
1074 screenheight=height;
1076 game.newdetail=detail;
1077 game.newscreenwidth=screenwidth;
1078 game.newscreenheight=screenheight;
1089 static Boolean RunningOnCarbonX(void)
1091 static Boolean first = true;
1092 static Boolean result = false;
1100 result = (Gestalt(gestaltSystemVersion,
1101 (SInt32 *) &response) == noErr)
1102 && (response >= 0x01000);
1107 static OSStatus LoadFrameworkBundle(CFStringRef pFrameworkCFStrRef, CFBundleRef *pFrameworkCFBndlRef)
1110 FSRef frameworksFolderRef;
1114 if (nil == pFrameworkCFBndlRef) return paramErr;
1116 *pFrameworkCFBndlRef = nil;
1121 err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef);
1123 baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef);
1124 if (baseURL == nil) {
1125 err = coreFoundationUnknownErr;
1129 bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, pFrameworkCFStrRef, false);
1130 if (bundleURL == nil) {
1131 err = coreFoundationUnknownErr;
1135 *pFrameworkCFBndlRef = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL);
1136 if (*pFrameworkCFBndlRef == nil) {
1137 err = coreFoundationUnknownErr;
1141 if ( ! CFBundleLoadExecutable( *pFrameworkCFBndlRef ) ) {
1142 err = coreFoundationUnknownErr;
1148 if (err != noErr && *pFrameworkCFBndlRef != nil) {
1149 CFRelease(*pFrameworkCFBndlRef);
1150 *pFrameworkCFBndlRef = nil;
1152 if (bundleURL != nil) {
1153 CFRelease(bundleURL);
1155 if (baseURL != nil) {
1164 static CFragConnectionID gCFragConnectionID = 0;
1166 typedef pascal OSErr (*CDM_NewDeviceProcPtr)(CursorDevicePtr * ourDevice);
1168 static OSErr MyCursorDeviceNewDevice(CursorDevicePtr * ourDevice)
1170 static CDM_NewDeviceProcPtr sCDM_NewDeviceProcPtr = nil;
1171 OSStatus anErr = noErr;
1173 if (nil == ourDevice) return paramErr;
1175 if (!RunningOnCarbonX())
1177 if (!sCDM_NewDeviceProcPtr)
1179 if (!gCFragConnectionID)
1184 anErr = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch,
1185 kFindCFrag, &gCFragConnectionID, &mainAddr, errName);
1186 if (noErr != anErr) return anErr;
1189 if (gCFragConnectionID)
1191 CFragSymbolClass symClass;
1193 anErr = FindSymbol(gCFragConnectionID, "\pCrsrDevNewDevice",
1194 (Ptr*) &sCDM_NewDeviceProcPtr, &symClass);
1195 if (noErr != anErr) return anErr;
1198 if (sCDM_NewDeviceProcPtr)
1199 anErr = (*sCDM_NewDeviceProcPtr)(ourDevice);
1207 typedef pascal OSErr (*CDM_CursorDeviceMoveToProcPtr)(
1208 CursorDevicePtr ourDevice,
1212 typedef UInt32 (*CGWarpMouseCursorPositionProcPtr)(CGPoint newCursorPosition);
1213 typedef UInt32 (*CGSetLocalEventsSuppressionIntervalProcPtr)(double pSeconds);
1215 static OSErr MyCursorDeviceMoveTo( CursorDevicePtr ourDevice,
1219 OSStatus anErr = noErr;
1221 if (RunningOnCarbonX())
1223 static CGWarpMouseCursorPositionProcPtr sCGWarpMouseCursorPositionProcPtr = nil;
1225 if (nil == sCGWarpMouseCursorPositionProcPtr)
1227 CFBundleRef tCFBundleRef;
1229 anErr = LoadFrameworkBundle(CFSTR("ApplicationServices.framework"), &tCFBundleRef);
1233 CGSetLocalEventsSuppressionIntervalProcPtr tCGSetLocalEventsSuppressionIntervalProcPtr = nil;
1235 sCGWarpMouseCursorPositionProcPtr = (CGWarpMouseCursorPositionProcPtr)
1236 CFBundleGetFunctionPointerForName( tCFBundleRef, CFSTR("CGWarpMouseCursorPosition") );
1237 if (nil == sCGWarpMouseCursorPositionProcPtr)
1238 anErr = cfragNoSymbolErr;
1240 tCGSetLocalEventsSuppressionIntervalProcPtr = (CGSetLocalEventsSuppressionIntervalProcPtr)
1241 CFBundleGetFunctionPointerForName(tCFBundleRef,CFSTR("CGSetLocalEventsSuppressionInterval"));
1242 if (nil != tCGSetLocalEventsSuppressionIntervalProcPtr)
1243 (*tCGSetLocalEventsSuppressionIntervalProcPtr)(0.0f);
1247 if (nil != sCGWarpMouseCursorPositionProcPtr)
1254 (*sCGWarpMouseCursorPositionProcPtr)(tCGPoint);
1259 static CDM_CursorDeviceMoveToProcPtr sCDM_CursorDeviceMoveToProcPtr = nil;
1261 if (!ourDevice) return paramErr;
1263 if (!sCDM_CursorDeviceMoveToProcPtr)
1265 if (!gCFragConnectionID)
1270 anErr = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch,
1271 kFindCFrag, &gCFragConnectionID, &mainAddr, errName);
1272 if (noErr != anErr) return anErr;
1275 if (gCFragConnectionID)
1277 CFragSymbolClass symClass;
1279 anErr = FindSymbol(gCFragConnectionID, "\pCrsrDevMoveTo",
1280 (Ptr*) &sCDM_CursorDeviceMoveToProcPtr, &symClass);
1281 if (noErr != anErr) return anErr;
1284 if (sCDM_CursorDeviceMoveToProcPtr)
1285 anErr = (*sCDM_CursorDeviceMoveToProcPtr)(ourDevice,absX,absY);
1293 static void DoMouse(void)
1295 static CursorDevicePtr virtualCursorDevicePtr = nil;
1296 OSStatus anErr = noErr;
1300 if (nil == virtualCursorDevicePtr)
1301 anErr = MyCursorDeviceNewDevice(&virtualCursorDevicePtr);
1304 static Point lastMouse = {-1,-1};
1307 GetGlobalMouse(&globalMouse);
1309 if (EqualPt(lastMouse, globalMouse))
1315 if (!EqualPt(lastMouse, globalMouse))
1317 static Point virtualMouse = {0,0};
1318 delta = globalMouse;
1320 SubPt(lastMouse, &delta);
1321 GetGlobalMouse(&lastMouse);
1322 //AddPt(delta, &virtualMouse);
1324 if(mainmenu||(abs(delta.h)<10*realmultiplier*1000&&abs(delta.v)<10*realmultiplier*1000)){
1325 game.deltah=delta.h*usermousesensitivity;
1326 game.deltav=delta.v*usermousesensitivity;
1327 game.mousecoordh=globalMouse.h;
1328 game.mousecoordv=globalMouse.v;
1331 //printf("\nMouse Moved: {%d,%d}.",globalMouse.h,globalMouse.v);
1332 //printf("\tdelta: {%d,%d}.",delta.h,delta.v);
1333 //printf("\tvirtual: {%d,%d}.",virtualMouse.h,virtualMouse.v);
1336 if(lastMouse.h>gMidPoint.h+100||lastMouse.h<gMidPoint.h-100||lastMouse.v>gMidPoint.v+100||lastMouse.v<gMidPoint.v-100){
1337 MyCursorDeviceMoveTo(virtualCursorDevicePtr,gMidPoint.h,gMidPoint.v);
1338 lastMouse = gMidPoint;
1345 // --------------------------------------------------------------------------
1347 void DoMenu (SInt32 menuResult)
1351 MenuRef theMenuHandle;
1353 theMenu = HiWord(menuResult);
1354 theItem = LoWord(menuResult);
1355 theMenuHandle = GetMenuHandle(theMenu);
1381 // --------------------------------------------------------------------------
1383 void DoKey (SInt8 theKey, SInt8 theCode)
1385 #pragma unused (theCode, theKey)
1386 /*if ((theKey == '=') || (theKey == '+'))
1393 // --------------------------------------------------------------------------
1397 /*void DoUpdate (void)
1399 static float sps=200;
1401 static float oldmult;
1405 count = multiplier*sps;
1411 for(int i=0;i<count;i++){
1420 DrawGL (&gRectPort);
1423 void DoUpdate (void)
1425 static float sps=200;
1427 static float oldmult;
1431 if(multiplier>.6)multiplier=.6;
1433 game.fps=1/multiplier;
1435 count = multiplier*sps;
1437 //if(count>10)count=10;
1439 realmultiplier=multiplier;
1440 multiplier*=gamespeed;
1441 if(difficulty==1)multiplier*=.9;
1442 if(difficulty==0)multiplier*=.8;
1444 if(game.loading==4)multiplier*=.00001;
1447 if(slomo&&!mainmenu)multiplier*=slomospeed;
1448 //if(freeze)multiplier*=0.00001;
1450 multiplier/=(float)count;
1456 for(int i=0;i<count;i++){
1461 game.TickOnceAfter();
1463 DrawGL (&gRectPort);
1466 // --------------------------------------------------------------------------
1468 Boolean WaitNextEventWrapper (EventMask eventMask, EventRecord *theEvent, unsigned long sleep,RgnHandle mouseRgn)
1470 return WaitNextEvent (eventMask, theEvent, sleep, mouseRgn);
1473 // --------------------------------------------------------------------------
1475 OSStatus DSpProcessEventWrapper (EventRecord *inEvent, Boolean *outEventWasProcessed)
1477 return DSpProcessEvent (inEvent, outEventWasProcessed);
1480 // --------------------------------------------------------------------------
1482 void UpdateWrapper (EventRecord *theEvent)
1484 WindowRef whichWindow;
1487 whichWindow = (WindowRef) theEvent->message;
1488 GetPort (&pGrafSave);
1489 SetPort((GrafPtr) GetWindowPort(whichWindow));
1490 BeginUpdate(whichWindow);
1492 SetPort((GrafPtr) GetWindowPort(whichWindow));
1493 EndUpdate(whichWindow);
1494 SetPort (pGrafSave);
1497 // --------------------------------------------------------------------------
1499 pascal void IdleTimer (EventLoopTimerRef inTimer, void* userData)
1501 #pragma unused (inTimer, userData)
1502 if(!stillloading)DoUpdate ();
1505 // --------------------------------------------------------------------------
1507 EventLoopTimerUPP GetTimerUPP (void)
1509 static EventLoopTimerUPP sTimerUPP = NULL;
1511 if (sTimerUPP == NULL)
1512 sTimerUPP = NewEventLoopTimerUPP (IdleTimer);
1517 // --------------------------------------------------------------------------
1519 pascal OSStatus mDown (EventHandlerCallRef ref, EventRef e,void * thedata) {
1520 EventMouseButton button;
1523 status = GetEventParameter (e, kEventParamMouseButton, typeMouseButton, NULL,
1524 sizeof (button), NULL, &button);
1526 buttons[button-1] = true;
1528 return eventNotHandledErr;
1531 pascal OSStatus mUp (EventHandlerCallRef ref, EventRef e,void * thedata) {
1532 EventMouseButton button = 0;
1535 status = GetEventParameter (e, kEventParamMouseButton, typeMouseButton, NULL,
1536 sizeof (EventMouseButton), NULL, &button);
1538 buttons[button-1] = false;
1540 return eventNotHandledErr;
1543 void InstallHandlers(void){
1547 spec.eventClass = kEventClassMouse;
1548 spec.eventKind = kEventMouseDown;
1550 status = InstallEventHandler (GetApplicationEventTarget(),
1551 NewEventHandlerUPP (mDown), 1, &spec, NULL, NULL);
1554 spec.eventKind = kEventMouseUp;
1556 status = InstallEventHandler (GetApplicationEventTarget(),
1557 NewEventHandlerUPP (mUp), 1, &spec, NULL, NULL);
1561 void NewEvent(void) {
1566 /*ReceiveNextEvent (0, NULL, 1, true, &er);
1568 s = SendEventToEventTarget (er, GetEventDispatcherTarget());*/
1569 WaitNextEvent (everyEvent, &e, 0, NULL);
1576 EventRecord theEvent;
1577 WindowRef whichWindow;
1583 if (noErr == gProfErr)
1584 ProfilerSetStatus(TRUE); // turn on profiling
1587 if (WaitNextEventWrapper (everyEvent, &theEvent, gSleepTime, NULL))
1589 DSpProcessEventWrapper (&theEvent, &fProcessed);
1592 switch (theEvent.what)
1595 whatPart = FindWindow (theEvent.where, &whichWindow);
1599 // if (GetWindowFromPort (gpDSpPort) != FrontWindow())
1600 // SelectWindow (GetWindowFromPort (gpDSpPort));
1604 SInt32 menuResult = MenuSelect (theEvent.where);
1605 if (HiWord (menuResult) != 0)
1606 DoMenu (menuResult);
1611 // full screen no drag
1616 // full screen no grow
1621 // full screen no go away
1627 // full screen no zoom
1639 theKey = theEvent.message & charCodeMask;
1640 theCode = (theEvent.message & keyCodeMask) >> 8;
1641 if ((theEvent.modifiers & cmdKey) != 0)
1643 SInt32 menuResult = MenuKey (theKey);
1644 if (HiWord(menuResult) != 0)
1645 DoMenu (menuResult);
1648 DoKey (theKey, theCode);
1653 UpdateWrapper (&theEvent);
1659 if (theEvent.message & 0x01000000) // Suspend/resume event
1661 if (theEvent.message & 0x00000001) // Resume
1663 gSleepTime = kForegroundSleep;
1664 gfFrontProcess = true;
1668 gSleepTime = kBackgroundSleep; // Suspend
1669 gfFrontProcess = false;
1674 case kHighLevelEvent:
1675 AEProcessAppleEvent (&theEvent);
1682 if (noErr == gProfErr)
1683 ProfilerSetStatus(FALSE); // turn profiling off again
1687 // --------------------------------------------------------------------------
1695 if (noErr == gProfErr)
1697 ProfilerDump ("\pGL DSp Carbon.prof");
1704 #if defined kUseFades
1705 DSpDebugStr (DSpContext_FadeGammaOut (NULL, NULL)); // fade display, remove for debug
1708 RemoveEventLoopTimer(gTimer);
1711 DeleteFontGL (gFontList);
1712 CleanupAGL (gaglContext); // Cleanup the OpenGL context
1716 ShutdownDSp (gpDSpPort); // DSp shutdown
1721 hMenu = GetMenuHandle (kMenuFile);
1722 DeleteMenu (kMenuFile);
1723 DisposeMenu (hMenu);
1725 hMenu = GetMenuHandle (kMenuApple);
1726 DeleteMenu (kMenuApple);
1727 DisposeMenu (hMenu);
1729 #if defined kUseFades
1730 DSpDebugStr (DSpContext_FadeGammaIn (NULL, NULL)); // fade display, remove for debug
1737 // --------------------------------------------------------------------------
1739 #include <InternetConfig.h>
1744 QString url("http://www.wolfire.com/");
1745 ICInstance icInstance
1746 OSType psiSignature = 'Psi ';
1747 OSStatus error = ::ICStart( &icInstance, psiSignature);
1749 ConstStr255Param hint( 0x0 );
1750 const char* data = url.latin1();
1751 long length = url.length();
1754 ::ICLaunchURL( icInstance, hint, data, length, &start, &end);
1755 ICStop( icInstance);
1760 void LaunchURL(char *url)
1762 ICInstance gICInstance;
1763 ICStart (&gICInstance, 0);
1767 ICLaunchURL(gICInstance, "\p" ,url, fin, &start, &fin);
1777 while (!gDone&&!game.quit&&(!game.tryquit||!game.registered)) {
1782 if(game.registernow){
1784 sprintf(url,"http://www.wolfire.com/register.html");
1788 } catch (const std::exception& error) {
1789 ofstream opstream("error.txt");
1790 opstream << "Caught exception: " << error.what() << std::endl;