#include "GameManager.h" static pascal void Timer(EventLoopTimerRef r, void * d) { #pragma unused(r) VGame * g; UnsignedWide microseconds; float interval; Vector Direction; g = (VGame *)d; microseconds = UpTime(); interval = (10000.0 / (microseconds.lo - g->lastTime.lo)); g->lastTime = microseconds; glClear(GL_DEPTH_BUFFER_BIT); glLoadIdentity(); /* Fill with semi transparent background */ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDepthMask(GL_FALSE); glColor4f(0.0, 0.0, 0.0, (0.04 / (interval > 1.0 ? 1.0 : interval))); glBegin(GL_QUADS); glVertex3f(-10.0, 10.0, -2.0); glVertex3f(10.0, 10.0, -2.0); glVertex3f(10.0, -10.0, -2.0); glVertex3f(-10.0, -10.0, -2.0); glEnd(); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDepthMask(GL_TRUE); g->Rot += (0.01 / interval); OffsetCamera(&g->world, &g->cMovement, interval); switch(g->Direction) { case FORWARDS: ForwardsVector(&g->world, CAMERASPEED, &Direction); break; case BACKWARDS: ForwardsVector(&g->world, -CAMERASPEED, &Direction); break; default: Direction.x = 0; Direction.y = 0; Direction.z = 0; break; } OffsetCamera(&g->world, &Direction, interval); RotateCamera(&g->world, &g->cRotate); gluLookAt(g->world.cameraPos.x, g->world.cameraPos.y, g->world.cameraPos.z, g->world.view.x, g->world.view.y, g->world.view.z, g->world.up.x, g->world.up.y, g->world.up.z); glPushMatrix(); glColor4f(0.5, 0.2, 0.0, 1.0); glRotatef(g->Rot, 0, 0, 1); glBegin(GL_QUADS); /* Top left */ glVertex3f(-0.5, 0.5, -2); /* Top right */ glVertex3f(0.5, 0.5, -2); /* Bottom right */ glVertex3f(0.5, -0.5, -2); /* Bottom left */ glVertex3f(-0.5, -0.5, -2); glEnd(); glPopMatrix(); if(g->w.IsFullScreen) aglSwapBuffers(g->w.FullScreen); else aglSwapBuffers(g->w.Windowed); } static pascal OSStatus MenuSelected(EventHandlerCallRef r, EventRef e, void * d) { #pragma unused(r) VGame * g; HICommand TheCommand; g = (VGame *)d; GetEventParameter(e, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &TheCommand); switch(TheCommand.commandID) { case 'FScn': if(g->w.IsFullScreen) CreateWindowedContext(&g->w); else CreateFullScreenContext(&g->w); return noErr; break; case 'abou': OpenAboutWindow(&g->m); return noErr; break; default: return eventNotHandledErr; } } static pascal OSStatus KeyDown(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) { #pragma unused (nextEvent) VGame * g; char charCode; UInt32 modifiers; g = (VGame *) userData; GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode); GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); switch (charCode) { case 28: /* Left arrow */ if (modifiers & shiftKey) { g->cRotate.y = CAMERASPEED; } else if (modifiers & cmdKey) { g->cRotate.z = CAMERASPEED; } else { g->cMovement.x = -CAMERASPEED; } break; case 29: /* Right arrow */ if (modifiers & shiftKey) { g->cRotate.y = -CAMERASPEED; } else if (modifiers & cmdKey) { g->cRotate.z = -CAMERASPEED; } else { g->cMovement.x = CAMERASPEED; } break; case 30: /* Up arrow */ if (modifiers & shiftKey) { g->cRotate.x = -CAMERASPEED; } else if (modifiers & cmdKey) { g->cMovement.z = -CAMERASPEED; } else { g->cMovement.y = CAMERASPEED; } break; case 31: /* Down arrow */ if (modifiers & shiftKey) { g->cRotate.x = CAMERASPEED; } else if (modifiers & cmdKey) { g->cMovement.z = CAMERASPEED; } else { g->cMovement.y = -CAMERASPEED; } break; case ' ': if(modifiers & shiftKey) g->Direction = BACKWARDS; else g->Direction = FORWARDS; break; } return eventNotHandledErr; } static pascal OSStatus KeyUp(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) { #pragma unused(nextEvent) VGame * g; char charCode; g = (VGame *) userData; GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode); switch (charCode) { case 28: /* Left arrow */ if(g->cRotate.y > 0.0) g->cRotate.y = 0.0; if (g->cRotate.z > 0.0) g->cRotate.z = 0.0; if(g->cMovement.x < 0.0) g->cMovement.x = 0.0; break; case 29: /* Right arrow */ if(g->cRotate.y < 0.0) g->cRotate.y = 0.0; if (g->cRotate.z < 0.0) g->cRotate.z = 0.0; if(g->cMovement.x > 0.0) g->cMovement.x = 0.0; break; case 30: /* Up arrow */ if(g->cRotate.x < 0.0) g->cRotate.x = 0.0; if (g->cMovement.z < 0.0) g->cMovement.z = 0.0; if(g->cMovement.y > 0.0) g->cMovement.y = 0.0; break; case 31: /* Down arrow */ if(g->cRotate.x > 0.0) g->cRotate.x = 0.0; if (g->cMovement.z > 0.0) g->cMovement.z = 0.0; if(g->cMovement.y < 0.0) g->cMovement.y = 0.0; break; case ' ': g->Direction = STATIONARY; break; } return eventNotHandledErr; } static pascal OSStatus AppActivated(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) { #pragma unused(nextEvent, theEvent) VGame * g; g = (VGame *) userData; SetEventLoopTimerNextFireTime(g->timerRef, (kEventDurationSecond / 100000.0)); g->lastTime = UpTime(); return eventNotHandledErr; } static pascal OSStatus AppDeactivated(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) { #pragma unused(nextEvent, theEvent) VGame * g; g = (VGame *) userData; SetEventLoopTimerNextFireTime(g->timerRef, kEventDurationForever); return eventNotHandledErr; } void InitGame(VGame * g) { EventTypeSpec eventType; InitCursor(); InstallEventLoopTimer(GetMainEventLoop(), 0, (kEventDurationSecond / 100000.0), NewEventLoopTimerUPP(Timer), g, &g->timerRef); eventType.eventClass = kEventClassCommand; eventType.eventKind = kEventProcessCommand; InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(MenuSelected), 1, &eventType, g, NULL); eventType.eventClass = kEventClassKeyboard; eventType.eventKind = kEventRawKeyDown; InstallApplicationEventHandler(NewEventHandlerUPP(KeyDown), 1, &eventType, g, NULL); eventType.eventClass = kEventClassKeyboard; eventType.eventKind = kEventRawKeyUp; InstallApplicationEventHandler(NewEventHandlerUPP(KeyUp), 1, &eventType, g, NULL); eventType.eventClass = kEventClassApplication; eventType.eventKind = kEventAppActivated; InstallApplicationEventHandler(NewEventHandlerUPP(AppActivated), 1, &eventType, g, NULL); eventType.eventClass = kEventClassApplication; eventType.eventKind = kEventAppDeactivated; InstallApplicationEventHandler(NewEventHandlerUPP(AppDeactivated), 1, &eventType, g, NULL); InitMenu(&g->m); InitWindow(&g->w); InitWorld(&g->world); g->cMovement.x = 0.0; g->cMovement.y = 0.0; g->cMovement.z = 0.0; g->cRotate.x = 0.0; g->cRotate.y = 0.0; g->cRotate.z = 0.0; g->lastTime = UpTime(); g->w.quitOnClose = true; g->Rot = 0; } void RunGame(VGame * g) { InitGame(g); RunApplicationEventLoop(); CleanUpGame(g); } void CleanUpGame(VGame * g) { RemoveEventLoopTimer(g->timerRef); CleanUpWindow(&g->w); CleanUpMenu(&g->m); CleanUpWorld(&g->world); }