#include "GameManager.h"static pascal void Timer(EventLoopTimerRef r, void * d){	#pragma unused(r)	VGame * g;	UnsignedWide microseconds;	float interval;	Vector front, push;		g = (VGame *)d;		microseconds = UpTime();	interval = (10000.0 / (microseconds.lo - g->lastTime.lo));	g->lastTime = microseconds;		if(g->Status == MENU)	{		glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);				RunInterface(&g->Interface, interval);		DrawInterface(&g->Interface);				if(g->w.IsFullScreen)			aglSwapBuffers(g->w.FullScreen);		else			aglSwapBuffers(g->w.Windowed);		return;	}		g->Frames++;		if(TickCount() - g->FrameTimer > 60)	{		g->FrameTimer = TickCount();		g->FramesPerSecond = g->Frames;		g->Frames = 0;	}		if (!g->Paused)	{  	RunWorld(&g->world, interval);	}		glClear(GL_DEPTH_BUFFER_BIT);	glLoadIdentity();		ForwardsVector(&g->world.Camera, 1.0, &front);	push = front;	if (g->Direction & STOP) {	  StopShip(&g->world.Physics, (SHIPACCELERATION / interval));	} else if (g->Direction & FORWARDS) {  	push.x *= (SHIPACCELERATION / interval);		push.y *= (SHIPACCELERATION / interval);		push.z *= (SHIPACCELERATION / interval);		PushShip(&g->world.Physics, &push);	} else if (g->Direction & BACKWARDS) {  	push.x *= -(SHIPACCELERATION / interval);		push.y *= -(SHIPACCELERATION / interval);		push.z *= -(SHIPACCELERATION / interval);		PushShip(&g->world.Physics, &push);	}	TurnShip(&g->world.Physics, g->Rotation, interval);		DrawWorld(&g->world, interval);		if(g->w.IsFullScreen)		aglSwapBuffers(g->w.FullScreen);	else		aglSwapBuffers(g->w.Windowed);		if(g->world.Finished)		SwitchMode(g, MENU);}static void ResumeGame(VGame * g){	g->lastTime = UpTime();	g->FrameTimer = TickCount();	if (g->Status != MENU && g->w.IsFullScreen) HideCursor();	else ShowCursor();}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);				ShowCursor();				if (g->Status == PLAYING && g->Paused) {					glClear(GL_DEPTH_BUFFER_BIT);					DrawWorld(&g->world, 1.0);					aglSwapBuffers(g->w.Windowed);				}			} else {				CreateFullScreenContext(&g->w);				if (g->Status != MENU) HideCursor();				if (g->Paused) {					glClear(GL_DEPTH_BUFFER_BIT);					DrawWorld(&g->world, 1.0);					aglSwapBuffers(g->w.FullScreen);				}			}						return noErr;			break;		case 'EndG':			if (g->Status == PLAYING) {			  SwitchMode(g, MENU);			}			break;		case kHICommandAbout:			OpenAboutWindow(&g->m);			return noErr;			break;		case kHICommandPreferences:			OpenSettingsWindow(&g->Settings);			return noErr;			break;	}	return eventNotHandledErr;}static pascal OSStatus KeyDown(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) {	#pragma unused (nextEvent)	VGame * g;	VSettings * s;	unsigned char charCode;	UInt32 modifiers;	SInt16 key;		g = (VGame *) userData;	s = GetSettings();	GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode);	GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);	key = KeyWithModifiers(charCode, modifiers);	if (charCode == 27)	{ /* Escape */		if (g->w.IsFullScreen) {			CreateWindowedContext(&g->w);			ShowCursor();			if (g->Status == PLAYING && g->Paused) {				glClear(GL_DEPTH_BUFFER_BIT);				DrawWorld(&g->world, 1.0);				aglSwapBuffers(g->w.Windowed);			}		}	}		if(charCode == 0x9)	{		FindTarget(&g->world);	}		if (g->Status != PLAYING) return eventNotHandledErr;	if (SettingsIsEquivalentKey(s, key, s->Left)) {		g->Rotation &= ~RIGHT;		g->Rotation |= LEFT;	}	if (SettingsIsEquivalentKey(s, key, s->Right)) {		g->Rotation &= ~LEFT;		g->Rotation |= RIGHT;	}	if (SettingsIsEquivalentKey(s, key, s->Up)) {		g->Rotation &= ~DOWN;		g->Rotation |= UP;	}	if (SettingsIsEquivalentKey(s, key, s->Down)) {		g->Rotation &= ~UP;		g->Rotation |= DOWN;	}	if (SettingsIsEquivalentKey(s, key, s->Forward)) {		g->Direction = FORWARDS;	}	if (SettingsIsEquivalentKey(s, key, s->Backward)) {		g->Direction = BACKWARDS;	}	if (SettingsIsEquivalentKey(s, key, s->Brake)) {		g->Direction |= STOP;	}	if (SettingsIsEquivalentKey(s, key, s->Bullet)) {	  AddWeapon(&g->world, WEAPONTYPEBULLET);	}	if (SettingsIsEquivalentKey(s, key, s->Rocket)) {		AddWeapon(&g->world, WEAPONTYPEROCKET);	}	if (SettingsIsEquivalentKey(s, key, s->Pause)) {	  if (g->Paused) {      //SetEventLoopTimerNextFireTime(g->timerRef, (kEventDurationSecond / 120.0));      ResumeGame(g);	  } else {      //SetEventLoopTimerNextFireTime(g->timerRef, kEventDurationForever);      InitCursor();	  }	  g->Paused = !g->Paused;	  g->world.Console.Paused = g->Paused;	}		return eventNotHandledErr;}static pascal OSStatus KeyUp(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) {	#pragma unused(nextEvent)	VGame * g;	VSettings * s;	unsigned char charCode;		g = (VGame *) userData;	s = GetSettings();	GetEventParameter(theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode);	if (g->Status != PLAYING) return eventNotHandledErr;	if (charCode == (s->Left & 0xFF)) {		g->Rotation &= ~LEFT;	}	if (charCode == (s->Right & 0xFF)) {		g->Rotation &= ~RIGHT;	}	if (charCode == (s->Up & 0xFF)) {		g->Rotation &= ~UP;	}	if (charCode == (s->Down & 0xFF)) {		g->Rotation &= ~DOWN;	}	if (charCode == (s->Forward & 0xFF) || charCode == (s->Backward & 0xFF)) {		g->Direction &= ~(FORWARDS | BACKWARDS);	}	if (charCode == (s->Brake & 0xFF)) {		g->Direction &= ~STOP;	}		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 / 120.0));	ResumeGame(g);	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);	ShowCursor();	return eventNotHandledErr;}void InitGame(VGame * g){	EventTypeSpec eventType;		InitCursor();	InstallEventLoopTimer(GetMainEventLoop(), 0, (kEventDurationSecond / 120.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);		SetQDGlobalsRandomSeed(TickCount());		InitSettings(&g->Settings);	InitMenu(&g->m);	InitWindow(&g->w);	InitInterface(&g->Interface, &g->w, g);		g->Status = MENU;	SetOrtho(&g->w);	g->w.quitOnClose = true;	g->lastTime = UpTime();	g->Paused = false;	g->Frames = 0;	g->FramesPerSecond = -1;	g->FrameTimer = TickCount();}void RunGame(VGame * g){	InitGame(g);	RunApplicationEventLoop();	CleanUpGame(g);}void CleanUpGame(VGame * g){	RemoveEventLoopTimer(g->timerRef);	CleanUpWindow(&g->w);	CleanUpMenu(&g->m);	CleanUpSettings(&g->Settings);}void SwitchMode(VGame * g, int Mode){	g->Status = Mode;	if(Mode == MENU)	{		SetOrtho(&g->w);		ShowCursor();		CleanUpWorld(&g->world);		CleanUpConsole(&g->world.Console);	} else if(Mode == PLAYING)	{		SetPerspective(&g->w);		InitWorld(&g->world);		InitConsole(&g->world.Console, &g->world.Player, &g->FramesPerSecond);		g->Direction = STATIONARY;		g->Rotation = STATIONARY;		g->lastTime = UpTime();		g->Paused = false;		g->Frames = 0;		g->FramesPerSecond = -1;		g->FrameTimer = TickCount();	}}