#include "GameManager.h"static pascal void Timer(EventLoopTimerRef r, void * d){	#pragma unused(r)	VGame * g;	UnsignedWide microseconds;	float interval;		g = (VGame *)d;		microseconds = UpTime();	interval = (10000.0 / (microseconds.lo - g->lastTime.lo));	g->lastTime = microseconds;		if (!g->Paused) {  	RunWorld(&g->world, interval);	  	  g->Rot += (0.01 / interval);	}		glClear(GL_DEPTH_BUFFER_BIT);	glLoadIdentity();		DrawWorld(&g->world, &g->cRotate, &g->cMovement, interval);		/* Temporary stuff */		glPushMatrix();		glColor4f(0.5, 0.2, 0.0, 1.0);		glRotatef(g->Rot, 0, 0, 1);		glPushMatrix();			glTranslatef(0, 0, -5);			gluSphere(g->Sphere, 1, 10, 10);		glPopMatrix();				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();		glPushMatrix();		glLoadIdentity();		glDisable(GL_DEPTH_TEST);			DrawCrossHair(&g->world);		glEnable(GL_DEPTH_TEST);	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':			gluDeleteQuadric(g->Sphere);						if(g->w.IsFullScreen)				CreateWindowedContext(&g->w);			else				CreateFullScreenContext(&g->w);						g->Sphere = gluNewQuadric();						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;	Vector Forwards = {0, 0, 0};		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->Rotation = LEFT;				g->cRotate = g->world.up;        g->cRotate.x *= ROTATESPEED;        g->cRotate.y *= ROTATESPEED;        g->cRotate.z *= ROTATESPEED;			} else if (modifiers & cmdKey) {				g->Rotation = ROLLLEFT;				ForwardsVector(&g->world, -ROTATESPEED, &g->cRotate);			} else {				g->Direction = LEFT;				ForwardsVector(&g->world, -CAMERASPEED, &Forwards);				CrossProduct(&Forwards, &g->world.up, &g->cMovement);			}			break;		case 29: /* Right arrow */			if (modifiers & shiftKey) {				g->Rotation = RIGHT;				g->cRotate = g->world.up;        g->cRotate.x *= -ROTATESPEED;        g->cRotate.y *= -ROTATESPEED;        g->cRotate.z *= -ROTATESPEED;			} else if (modifiers & cmdKey) {				g->Rotation = ROLLRIGHT;				ForwardsVector(&g->world, ROTATESPEED, &g->cRotate);			} else {				g->Direction = RIGHT;				ForwardsVector(&g->world, CAMERASPEED, &Forwards);				CrossProduct(&Forwards, &g->world.up, &g->cMovement);			}			break;		case 30: /* Up arrow */			if (modifiers & shiftKey) {				g->Rotation = UP;				ForwardsVector(&g->world, 1, &Forwards);				CrossProduct(&Forwards, &g->world.up, &g->cRotate);				NormalizeVector(&g->cRotate);				g->cRotate.x *= ROTATESPEED;				g->cRotate.y *= ROTATESPEED;				g->cRotate.z *= ROTATESPEED;			} else {				g->Direction = UP;				g->cMovement = g->world.up;				g->cMovement.x *= CAMERASPEED;				g->cMovement.y *= CAMERASPEED;				g->cMovement.z *= CAMERASPEED;			}			break;		case 31: /* Down arrow */			if (modifiers & shiftKey) {				g->Rotation = DOWN;				ForwardsVector(&g->world, 1, &Forwards);				CrossProduct(&Forwards, &g->world.up, &g->cRotate);				NormalizeVector(&g->cRotate);				g->cRotate.x *= -ROTATESPEED;				g->cRotate.y *= -ROTATESPEED;				g->cRotate.z *= -ROTATESPEED;			} else {				g->Direction = DOWN;				g->cMovement = g->world.up;				g->cMovement.x *= -CAMERASPEED;				g->cMovement.y *= -CAMERASPEED;				g->cMovement.z *= -CAMERASPEED;			}			break;		case ' ':			if(modifiers & shiftKey)			{				g->Direction = BACKWARDS;				ForwardsVector(&g->world, -CAMERASPEED, &g->cMovement);			}			else			{				g->Direction = FORWARDS;				ForwardsVector(&g->world, CAMERASPEED, &g->cMovement);			}			break;		case 'f':		case 'F':		  {		    VWeapon * theWeapon;		    Vector front;		      		  theWeapon = (VWeapon *) NewPtr(sizeof(VWeapon));  		  if (theWeapon != NULL) {  		    InitWeapon(theWeapon, WEAPONTYPEBULLET);  		    theWeapon->next = g->world.Weapons;  		    g->world.Weapons = theWeapon;  		    SubtractVector(&g->world.cameraPos, &g->world.view, &front);  		    NormalizeVector(&front);  		    StartWeapon(theWeapon, &g->world.cameraPos, NULL, &front, &g->world.up);  		  }  		}		  break;		case 'r':		case 'R':		  {		    VWeapon * theWeapon;		    Vector front;		      		  theWeapon = (VWeapon *) NewPtr(sizeof(VWeapon));  		  if (theWeapon != NULL) {  		    InitWeapon(theWeapon, WEAPONTYPEROCKET);  		    theWeapon->next = g->world.Weapons;  		    g->world.Weapons = theWeapon;  		    SubtractVector(&g->world.cameraPos, &g->world.view, &front);  		    NormalizeVector(&front);  		    if (g->world.Objects != NULL) {  		      /* Temporary; Target first object in the object list */  		      StartWeapon(theWeapon, &g->world.cameraPos, &g->world.Objects->Position, &front, &g->world.up);  		    } else {  		      /* No particular target */  		      StartWeapon(theWeapon, &g->world.cameraPos, &front, &front, &g->world.up);  		    }  		  }  		}		  break;		case 'p':		  if (g->Paused) {        SetEventLoopTimerNextFireTime(g->timerRef, (kEventDurationSecond / 300.0));        g->lastTime = UpTime();	    } else {        //SetEventLoopTimerNextFireTime(g->timerRef, kEventDurationForever);	    }	    g->Paused = !g->Paused;		  break;		case ']':		  if (g->Paused) {		    g->Paused = 0;		    g->lastTime = UpTime();		    g->lastTime.lo -= 100000;		    Timer(NULL, g);		    g->Paused = 1;		  }		  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->Rotation == LEFT || g->Rotation == ROLLLEFT)			{				g->cRotate.x = 0.0;				g->cRotate.y = 0.0;				g->cRotate.z = 0.0;			}			if (g->cRotate.z > 0.0)				g->cRotate.z = 0.0;			if(g->Direction == LEFT)			{				g->cMovement.x = 0.0;				g->cMovement.y = 0.0;				g->cMovement.z = 0.0;			}			break;		case 29: /* Right arrow */			if(g->Rotation == RIGHT || g->Rotation == ROLLRIGHT)			{				g->cRotate.x = 0.0;				g->cRotate.y = 0.0;				g->cRotate.z = 0.0;			}			if(g->Direction == RIGHT)			{				g->cMovement.x = 0.0;				g->cMovement.y = 0.0;				g->cMovement.z = 0.0;			}			break;		case 30: /* Up arrow */			if(g->Rotation == UP)			{				g->cRotate.x = 0.0;				g->cRotate.y = 0.0;				g->cRotate.z = 0.0;				g->Rotation = STATIONARY;			}			if (g->cMovement.z < 0.0)				g->cMovement.z = 0.0;			if(g->Direction == UP)			{				g->cMovement.x = 0.0;				g->cMovement.y = 0.0;				g->cMovement.z = 0.0;			}			break;		case 31: /* Down arrow */			if(g->Rotation == DOWN)			{				g->cRotate.x = 0.0;				g->cRotate.y = 0.0;				g->cRotate.z = 0.0;				g->Rotation = STATIONARY;			}			if (g->cMovement.z > 0.0)				g->cMovement.z = 0.0;			if(g->Direction == DOWN)			{				g->cMovement.x = 0.0;				g->cMovement.y = 0.0;				g->cMovement.z = 0.0;			}			break;		case ' ':			if(g->Direction == FORWARDS || g->Direction == BACKWARDS)			{				g->cMovement.x = 0.0;				g->cMovement.y = 0.0;				g->cMovement.z = 0.0;			}			break;	}		return eventNotHandledErr;}static pascal OSStatus AppActivated(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) {	#pragma unused(nextEvent, theEvent)	VGame * g;		g = (VGame *) userData;	if (!g->Paused) SetEventLoopTimerNextFireTime(g->timerRef, (kEventDurationSecond / 300.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 / 300.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->Direction = STATIONARY;	g->Rotation = STATIONARY;		g->lastTime = UpTime();	g->Sphere = gluNewQuadric();		g->w.quitOnClose = true;	g->Rot = 0;		g->Paused = 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);}