#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);}