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

ported chipmunk demos
author Extrawurst
date Sat, 04 Dec 2010 02:02:29 +0100
parents
children f2287962b4b7
comparison
equal deleted inserted replaced
15:df4ebc8add66 16:af2f61a96318
1 /++
2 + Authors: Stephan Dilly, www.extrawurst.org
3 +/
4
5 module gameApp;
6
7 import framework;
8
9 import drawSpace;
10
11 import chipmunkd.chipmunk;
12
13 import samples.LogoSmash;
14 import samples.Simple;
15 import samples.PyramidStack;
16 import samples.ChipmunkDemo;
17 import samples.Plink;
18 import samples.Tumble;
19 import samples.PyramidTopple;
20 import samples.Planet;
21 import samples.Query;
22 import samples.OneWay;
23 import samples.Sensors;
24 import samples.Bounce;
25 import samples.Springies;
26 import samples.Joints;
27 import samples.MagnetsElectric;
28 import samples.Player;
29 import samples.Tank;
30 import samples.Pump;
31 import samples.TheoJansen;
32 import samples.UnsafeOps;
33
34 import derelict.opengl.gl;
35 import derelict.opengl.glu;
36 import derelict.sdl.sdl;
37
38 import std.stdio;
39 import core.thread:Sleep;
40
41 extern(System) ulong GetTickCount();
42
43 version = TIME_TRIAL;
44
45 cpVect mousePos;
46 cpVect arrowDirection;
47
48 ///
49 final class GameApp {
50
51 private:
52
53 chipmunkDemo*[] demos;
54 chipmunkDemo* currentDemo;
55 cpSpace* space;
56 int ticks;
57 cpBody* mouseBody;
58 cpConstraint* mouseJoint;
59 cpVect mousePos_last;
60
61 bool key_up = false;
62 bool key_down = false;
63 bool key_left = false;
64 bool key_right = false;
65
66 bool m_running = true;
67
68 drawSpaceOptions options = {
69 0, // drawHash
70 0, // drawBB
71 1, // drawShapes
72 4.0f, // collisionPointSize
73 0.0f, // bodyPointSize
74 1.5f, // lineThickness
75 };
76
77 enum width = 1024;
78 enum height = 780;
79
80 version(TIME_TRIAL)
81 {
82 void time_trial(int index, int count)
83 {
84 currentDemo = demos[index];
85 space = currentDemo.initFunc();
86
87 auto start = .GetTickCount();
88
89 foreach(i; 0..count)
90 currentDemo.updateFunc(i);
91
92 auto end = .GetTickCount();
93 auto duration = (end - start);
94
95 currentDemo.destroyFunc();
96 currentDemo = null;
97
98 writefln("Time(%s) = %s", cast(char)(index + 'a'), duration);
99 }
100 }
101
102 ///
103 public void boot() {
104
105 demos = [
106 &LogoSmash,
107 &Simple,
108 &PyramidStack,
109 &Plink,
110 &Tumble,
111 &PyramidTopple,
112 &Bounce,
113 &Planet,
114 &Springies,
115 &Pump,
116 &TheoJansen,
117 &MagnetsElectric,
118 &UnsafeOps,
119 &Query,
120 &OneWay,
121 &Player,
122 &Sensors,
123 &Joints,
124 &Tank,
125 ];
126
127 cpInitChipmunk();
128
129 cp_collision_slop = 0.2f;
130
131 version(TIME_TRIAL)
132 {
133 Sleep(1);
134 foreach(i; 0..demos.length)
135 {
136 //if(i == 'l' - 'a') continue;
137 time_trial(i, 1000);
138 }
139
140 m_running = false;
141
142 return;
143 }//TIME_TRIAL
144
145 //setup framework
146 framework.startup("chipmunk'd by Stephan Dilly",width,height);
147
148 reshape(width,height);
149
150 glEnableClientState(GL_VERTEX_ARRAY);
151
152 runDemo(demos[0]);
153
154 mouseBody = cpBodyNew(INFINITY, INFINITY);
155 }
156
157 ///
158 void runDemo(chipmunkDemo *demo)
159 {
160 if(currentDemo)
161 currentDemo.destroyFunc();
162
163 currentDemo = demo;
164 ticks = 0;
165 mouseJoint = null;
166
167 //maxArbiters = 0;
168 //maxPoints = 0;
169 //maxConstraints = 0;
170 space = currentDemo.initFunc();
171 }
172
173 ///
174 void reshape(int width, int height)
175 {
176 glViewport(0, 0, width, height);
177
178 double rx = width / 2.0;
179 double ry = height / 2.0;
180
181 glMatrixMode(GL_PROJECTION);
182 glLoadIdentity();
183 glOrtho(-rx, rx, -ry, ry, -1.0, 1.0);
184 glTranslated(0.5, 0.5, 0.0);
185 }
186
187 ///
188 public bool update() {
189
190 if(!m_running) return m_running;
191
192 if(!framework.processEvents(&keyEvent,&mouseMove,&mouseButtonEvent))
193 return false;
194
195 cpVect newPoint = cpvlerp(mousePos_last, mousePos, 0.25f);
196 mouseBody.p = newPoint;
197 mouseBody.v = cpvmult(cpvsub(newPoint, mousePos_last), 60.0f);
198 mousePos_last = newPoint;
199
200 currentDemo.updateFunc(ticks++);
201
202 // render
203
204 glClearColor(1,1,1,1);
205
206 glClear(GL_COLOR_BUFFER_BIT);
207
208 DrawSpace(space,currentDemo.drawOptions ? currentDemo.drawOptions : &options);
209
210 SDL_GL_SwapBuffers();
211
212 return m_running;
213 }
214
215 ///
216 public void shutdown() {
217
218 version(TIME_TRIAL){}else
219 {
220 currentDemo.destroyFunc();
221
222 framework.shutdown();
223 }
224 }
225
226 cpVect mouseToSpace(int x, int y)
227 {
228 GLdouble model[16];
229 glGetDoublev(GL_MODELVIEW_MATRIX, model.ptr);
230
231 GLdouble proj[16];
232 glGetDoublev(GL_PROJECTION_MATRIX, proj.ptr);
233
234 GLint view[4];
235 glGetIntegerv(GL_VIEWPORT, view.ptr);
236
237 GLdouble mx, my, mz;
238 gluUnProject(x, height - y, 0.0f, model.ptr, proj.ptr, view.ptr, &mx, &my, &mz);
239
240 return cpv(mx, my);
241 }
242
243 ///
244 private void mouseMove(int x,int y)
245 {
246 mousePos = mouseToSpace(x,y);
247 }
248
249 ///
250 private void mouseButtonEvent(int x,int y,bool _down)
251 {
252 if(_down){
253 cpVect point = mouseToSpace(x,y);
254
255 cpShape *shape = cpSpacePointQueryFirst(space, point, GRABABLE_MASK_BIT, CP_NO_GROUP);
256 if(shape){
257 cpBody *_body = shape._body;
258 mouseJoint = cpPivotJointNew2(mouseBody, _body, cpvzero, cpBodyWorld2Local(_body, point));
259 mouseJoint.maxForce = 50000.0f;
260 mouseJoint.biasCoef = 0.15f;
261 cpSpaceAddConstraint(space, mouseJoint);
262 }
263 } else if(mouseJoint){
264 cpSpaceRemoveConstraint(space, mouseJoint);
265 cpConstraintFree(mouseJoint);
266 mouseJoint = null;
267 }
268 }
269
270 ///
271 private void set_arrowDirection()
272 {
273 int x = 0, y = 0;
274
275 if(key_up) y += 1;
276 if(key_down) y -= 1;
277 if(key_right) x += 1;
278 if(key_left) x -= 1;
279
280 arrowDirection = cpv(x, y);
281 }
282
283 ///
284 private void keyEvent(int _key,bool _down)
285 {
286 int key = _key;
287
288 if(_down)
289 {
290 int index = key - 'a';
291
292 if(0 <= index && index < demos.length){
293 runDemo(demos[index]);
294 } else if(key == '\r'){
295 runDemo(currentDemo);
296 } else if(key == 47){
297 options.drawHash = !options.drawHash;
298 } else if(key == 92){
299 options.drawBBs = !options.drawBBs;
300 } else if(key == 93){
301 glEnable(GL_LINE_SMOOTH);
302 glEnable(GL_POINT_SMOOTH);
303 glEnable(GL_BLEND);
304 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
305 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
306 glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
307 }
308 else
309 {
310 if(key == SDLK_UP) key_up = true;
311 else if(key == SDLK_DOWN) key_down = true;
312 else if(key == SDLK_LEFT) key_left = true;
313 else if(key == SDLK_RIGHT) key_right = true;
314
315 set_arrowDirection();
316 }
317 }
318 else
319 {
320 if(key == SDLK_UP) key_up = false;
321 else if(key == SDLK_DOWN) key_down = false;
322 else if(key == SDLK_LEFT) key_left = false;
323 else if(key == SDLK_RIGHT) key_right = false;
324
325 set_arrowDirection();
326 }
327 }
328 }
329