diff trunk/tests/ChipmunkDemos/gameApp.d @ 16:af2f61a96318

ported chipmunk demos
author Extrawurst
date Sat, 04 Dec 2010 02:02:29 +0100
parents
children f2287962b4b7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trunk/tests/ChipmunkDemos/gameApp.d	Sat Dec 04 02:02:29 2010 +0100
@@ -0,0 +1,329 @@
+/++
+ +	Authors: Stephan Dilly, www.extrawurst.org
+ +/
+
+module gameApp;
+
+import framework;
+
+import drawSpace;
+
+import chipmunkd.chipmunk;
+
+import samples.LogoSmash;
+import samples.Simple;
+import samples.PyramidStack;
+import samples.ChipmunkDemo;
+import samples.Plink;
+import samples.Tumble;
+import samples.PyramidTopple;
+import samples.Planet;
+import samples.Query;
+import samples.OneWay;
+import samples.Sensors;
+import samples.Bounce;
+import samples.Springies;
+import samples.Joints;
+import samples.MagnetsElectric;
+import samples.Player;
+import samples.Tank;
+import samples.Pump;
+import samples.TheoJansen;
+import samples.UnsafeOps;
+
+import derelict.opengl.gl;
+import derelict.opengl.glu;
+import derelict.sdl.sdl;
+
+import std.stdio;
+import core.thread:Sleep;
+
+extern(System) ulong GetTickCount();
+
+version = TIME_TRIAL;
+
+cpVect			mousePos;
+cpVect			arrowDirection;
+
+///
+final class GameApp {
+
+private:
+
+	chipmunkDemo*[] demos;
+	chipmunkDemo*	currentDemo;
+	cpSpace*		space;
+	int				ticks;
+	cpBody*			mouseBody;
+	cpConstraint*	mouseJoint;
+	cpVect			mousePos_last;
+	
+	bool key_up = false;
+	bool key_down = false;
+	bool key_left = false;
+	bool key_right = false;
+	
+	bool 	m_running = true;
+	
+	drawSpaceOptions options = {
+		0,		// drawHash
+		0,		// drawBB
+		1,		// drawShapes
+		4.0f,	// collisionPointSize
+		0.0f,	// bodyPointSize
+		1.5f,	// lineThickness
+	};
+	
+	enum width = 1024;
+	enum height = 780;
+	
+version(TIME_TRIAL)
+{
+	void time_trial(int index, int count)
+	{
+		currentDemo = demos[index];
+		space = currentDemo.initFunc();
+		
+		auto start = .GetTickCount();
+		
+		foreach(i; 0..count)
+			currentDemo.updateFunc(i);
+		
+		auto end = .GetTickCount();
+		auto duration = (end - start);
+		
+		currentDemo.destroyFunc();
+		currentDemo = null;
+		
+		writefln("Time(%s) = %s", cast(char)(index + 'a'), duration);
+	}
+}
+
+	///
+	public void boot() {
+
+		demos = [
+			&LogoSmash,
+			&Simple,
+			&PyramidStack,
+			&Plink,
+			&Tumble,
+			&PyramidTopple,
+			&Bounce,
+			&Planet,
+			&Springies,
+			&Pump,
+			&TheoJansen,
+			&MagnetsElectric,
+			&UnsafeOps,
+			&Query,
+			&OneWay,
+			&Player,
+			&Sensors,
+			&Joints,
+			&Tank,
+		];
+			
+		cpInitChipmunk();
+		
+		cp_collision_slop = 0.2f;
+		
+version(TIME_TRIAL)
+{
+		Sleep(1);
+		foreach(i; 0..demos.length)
+		{
+			//if(i == 'l' - 'a') continue;
+			time_trial(i, 1000);
+		}
+	
+		m_running = false;
+		
+		return;
+}//TIME_TRIAL
+		
+		//setup framework
+		framework.startup("chipmunk'd by Stephan Dilly",width,height);
+
+		reshape(width,height);
+				
+		glEnableClientState(GL_VERTEX_ARRAY);
+		
+		runDemo(demos[0]);
+		
+		mouseBody = cpBodyNew(INFINITY, INFINITY);
+	}
+		
+	///
+	void runDemo(chipmunkDemo *demo)
+	{
+		if(currentDemo)
+			currentDemo.destroyFunc();
+		
+		currentDemo = demo;
+		ticks = 0;
+		mouseJoint = null;
+		
+		//maxArbiters = 0;
+		//maxPoints = 0;
+		//maxConstraints = 0;
+		space = currentDemo.initFunc();
+	}
+					 
+	///
+	void reshape(int width, int height)
+	{
+		glViewport(0, 0, width, height);
+		
+		double rx = width / 2.0;
+		double ry = height / 2.0;
+		
+		glMatrixMode(GL_PROJECTION);
+		glLoadIdentity();
+		glOrtho(-rx, rx, -ry, ry, -1.0, 1.0);
+		glTranslated(0.5, 0.5, 0.0);
+	}
+
+	///
+	public bool update() {
+
+		if(!m_running) return m_running;
+		
+		if(!framework.processEvents(&keyEvent,&mouseMove,&mouseButtonEvent))
+			return false;
+					 
+		cpVect newPoint = cpvlerp(mousePos_last, mousePos, 0.25f);
+		mouseBody.p = newPoint;
+		mouseBody.v = cpvmult(cpvsub(newPoint, mousePos_last), 60.0f);
+		mousePos_last = newPoint;
+	
+		currentDemo.updateFunc(ticks++);
+		
+		// render
+		
+		glClearColor(1,1,1,1);
+
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		DrawSpace(space,currentDemo.drawOptions ? currentDemo.drawOptions : &options);
+
+		SDL_GL_SwapBuffers();
+					 
+		return m_running;
+	}
+
+	///
+	public void shutdown() {
+		
+version(TIME_TRIAL){}else
+{
+		currentDemo.destroyFunc();
+					 
+		framework.shutdown();
+}
+	}
+
+	cpVect mouseToSpace(int x, int y)
+	{
+		GLdouble model[16];
+		glGetDoublev(GL_MODELVIEW_MATRIX, model.ptr);
+	
+		GLdouble proj[16];
+		glGetDoublev(GL_PROJECTION_MATRIX, proj.ptr);
+	
+		GLint view[4];
+		glGetIntegerv(GL_VIEWPORT, view.ptr);
+	
+		GLdouble mx, my, mz;
+		gluUnProject(x, height - y, 0.0f, model.ptr, proj.ptr, view.ptr, &mx, &my, &mz);
+	
+		return cpv(mx, my);
+	}
+	
+	///
+	private void mouseMove(int x,int y)
+	{
+		mousePos = mouseToSpace(x,y);
+	}
+	
+	///
+	private void mouseButtonEvent(int x,int y,bool _down)
+	{	
+		if(_down){
+			cpVect point = mouseToSpace(x,y);
+		
+			cpShape *shape = cpSpacePointQueryFirst(space, point, GRABABLE_MASK_BIT, CP_NO_GROUP);
+			if(shape){
+				cpBody *_body = shape._body;
+				mouseJoint = cpPivotJointNew2(mouseBody, _body, cpvzero, cpBodyWorld2Local(_body, point));
+				mouseJoint.maxForce = 50000.0f;
+				mouseJoint.biasCoef = 0.15f;
+				cpSpaceAddConstraint(space, mouseJoint);
+			}
+		} else if(mouseJoint){
+			cpSpaceRemoveConstraint(space, mouseJoint);
+			cpConstraintFree(mouseJoint);
+			mouseJoint = null;
+		}
+	}
+	
+	///
+	private void set_arrowDirection()
+	{
+		int x = 0, y = 0;
+	
+		if(key_up) y += 1;
+		if(key_down) y -= 1;
+		if(key_right) x += 1;
+		if(key_left) x -= 1;
+	
+		arrowDirection = cpv(x, y);
+	}
+	
+	///
+	private void keyEvent(int _key,bool _down)
+	{				 
+		int key = _key;
+		
+		if(_down)
+		{
+			int index = key - 'a';
+			
+			if(0 <= index && index < demos.length){
+				runDemo(demos[index]);
+			} else if(key == '\r'){
+				runDemo(currentDemo);
+			} else if(key == 47){
+				options.drawHash = !options.drawHash;
+			} else if(key == 92){
+				options.drawBBs = !options.drawBBs;
+			} else if(key == 93){
+				glEnable(GL_LINE_SMOOTH);
+				glEnable(GL_POINT_SMOOTH);
+				glEnable(GL_BLEND);
+				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+				glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
+				glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
+			}
+			else
+			{
+				if(key == SDLK_UP) key_up = true;
+				else if(key == SDLK_DOWN) key_down = true;
+				else if(key == SDLK_LEFT) key_left = true;
+				else if(key == SDLK_RIGHT) key_right = true;
+	
+				set_arrowDirection();
+			}
+		}
+		else
+		{
+			if(key == SDLK_UP) key_up = false;
+			else if(key == SDLK_DOWN) key_down = false;
+			else if(key == SDLK_LEFT) key_left = false;
+			else if(key == SDLK_RIGHT) key_right = false;
+			
+			set_arrowDirection();
+		}
+	}
+}
+