dispatcher alias methods
[chaz/yoink] / src / YoinkApp.cc
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #include <cstdlib> // getenv
30 #include <iostream>
31 #include <string>
32
33 #include <boost/bind.hpp>
34
35 #include <Moof/Exception.hh>
36 #include <Moof/Log.hh>
37 #include <Moof/Math.hh>
38 #include <Moof/OpenGL.hh>
39 #include <Moof/Settings.hh>
40 #include <Moof/Timer.hh>
41 #include <Moof/Video.hh>
42
43 #include "YoinkApp.hh"
44
45 #include <SDL/SDL_sound.h>
46 #include <AL/al.h>
47 #include <AL/alut.h>
48
49 #if HAVE_CONFIG_H
50 #include "config.h"
51 #endif
52
53
54 static std::string configFiles()
55 {
56 std::string files;
57
58 char* configFile = getenv("YOINKRC");
59 char* dataDir = getenv("YOINK_DATADIR");
60
61 if (configFile)
62 {
63 // if a config file from the environment variable is specified, we want
64 // to load it first so it has precedence
65 files += configFile;
66 files += ":";
67 }
68
69 // add the colon-delimited paths from configure
70 files += YOINK_CONFIGFILES;
71
72 if (dataDir)
73 {
74 // if another data directory is set in the environment, look for a
75 // config file there
76 files += ":";
77 files += dataDir;
78 files += "/yoinkrc";
79 }
80
81 // look in the configured data directory last of all
82 files += ":";
83 files += (dataDir ? dataDir : YOINK_DATADIR);
84 files += "/yoinkrc";
85
86 return files;
87 }
88
89 static std::string iconFile()
90 {
91 char* dataDir = getenv("YOINK_DATADIR");
92
93 // first set up the search paths so we can find the icon and other resources
94 if (dataDir)
95 {
96 // look first in the data directory specified by the environment
97 Mf::Resource::addSearchPath(dataDir);
98 }
99
100 // then look in the configured data directory
101 Mf::Resource::addSearchPath(YOINK_DATADIR);
102
103 return Mf::Resource::getPath("yoink.png");
104 }
105
106
107 YoinkApp::YoinkApp(int argc, char* argv[]) :
108 Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile()),
109 music("NightFusion"),
110 punchSound("RobotPunch")
111 {
112 Mf::dispatcher::addHandler("video.context_recreated",
113 boost::bind(&YoinkApp::contextRecreated, this, _1), this);
114 setupGL();
115
116 Mf::Scalar fade[2] = {0.0, 1.0};
117 musicFade.init(fade, 0.0);
118 music.play();
119
120 state = 0.0;
121
122 heroine = Character::alloc("RobotTrooper");
123 heroine->getAnimation().startSequence("Run");
124
125 font = new TilemapFont;
126
127 Mf::Scalar coeffs[4];
128 coeffs[0] = 0.0;
129 coeffs[1] = 1.5;
130 coeffs[2] = -0.5;
131 coeffs[3] = 1.0;
132 interp.init(coeffs, 1.0, Mf::Interpolator::OSCILLATE);
133
134 Mf::Scalar coeff[2] = {1.0, 0.0};
135 fadeIn.init(coeff, 0.1);
136
137 testScene = new Mf::Scene("Test");
138 heroine->treeNode = testScene->getOctree()->insert(heroine);
139 }
140
141 YoinkApp::~YoinkApp()
142 {
143 //delete heroine;
144 delete font;
145 delete testScene;
146
147 Mf::dispatcher::removeHandler(this);
148 }
149
150
151 void YoinkApp::setupGL()
152 {
153 glEnable(GL_TEXTURE_2D);
154
155 //glEnable(GL_CULL_FACE);
156 glEnable(GL_DEPTH_TEST);
157
158 glShadeModel(GL_SMOOTH);
159 //glEnable(GL_POLYGON_SMOOTH);
160
161 //int texSize;
162 //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
163 //std::cout << "texture size: " << texSize << std::endl;
164
165 //glEnable(GL_BLEND);
166 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
167 glEnable(GL_ALPHA_TEST);
168 glAlphaFunc(GL_GREATER, 0.0);
169
170 glClearColor(1.0, 0.0, 0.0, 1.0);
171
172 //glMatrixMode(GL_PROJECTION);
173 //glLoadIdentity();
174 //gluPerspective(60.0, 1.33333, 1.0, 2500.0);
175 camera.setProjection(cml::rad(60.0), 1.33333, 32.0, 2500.0);
176 camera.uploadProjectionToGL();
177
178 //glMatrixMode(GL_MODELVIEW);
179
180 //glLineWidth(10.0f);
181 }
182
183 void YoinkApp::contextRecreated(const Mf::Notification* note)
184 {
185 // Whenever the context and a new one created, it probably won't contain our
186 // state so we need to set that up again.
187 setupGL();
188 }
189
190
191 void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt)
192 {
193 //dt *= 0.2;
194
195 musicFade.update(dt);
196 music.update(t, dt);
197 music.setGain(musicFade.getValue());
198
199 fadeIn.update(dt);
200
201 camera.update(t, dt);
202
203 heroine->update(t, dt);
204 heroine->treeNode = testScene->getOctree()->reinsert(heroine, heroine->treeNode);
205
206 //camera.lookAt(heroine->getSphere().point);
207 camera.setPosition(Mf::Vector3(-heroine->current.position[0], -heroine->current.position[1], -256));
208
209 interp.update(dt);
210 hud.setBar1Progress(interp.getValue());
211 hud.setBar2Progress(1.0 - interp.getValue());
212
213 prevstate = state;
214 state += dt;
215 }
216
217
218 void YoinkApp::draw(Mf::Scalar alpha)
219 {
220 //Mf::Vector4 meh;
221 //meh.random(0.0, 1.0);
222 //static Mf::Vector4 c1(meh);
223
224 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
225
226 //Mf::Scalar drawstate = cml::lerp(prevstate, state, alpha);
227 //Mf::Scalar sinstate = std::sin(drawstate);
228 //Mf::Scalar cosstate = std::cos(drawstate);
229
230
231 glMatrixMode(GL_MODELVIEW);
232 //glLoadIdentity();
233
234 //glRotatef(drawstate*15.0f, 0.0, 1.0, 0.0);
235 //glTranslatef(x, y, z);
236 glLoadMatrix(camera.getModelviewMatrix().data());
237
238 // DRAW THE SCENE
239 Mf::Texture::resetBind();
240 testScene->draw(alpha, camera);
241
242
243
244 //heroine->draw(alpha);
245 heroine->getAabb().draw();
246
247
248 hud.draw();
249
250
251 glEnable(GL_BLEND);
252 glMatrixMode(GL_PROJECTION);
253 glPushMatrix();
254 glLoadIdentity();
255 glMatrixMode(GL_MODELVIEW);
256 glPushMatrix();
257 glLoadIdentity();
258 glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
259 Mf::Texture::resetBind();
260
261 //glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
262 glBegin(GL_QUADS);
263 glVertex3f(-1.0, -1.0, -0.1);
264 glVertex3f(1.0, -1.0, -0.1);
265 glVertex3f(1.0, 1.0, -0.1);
266 glVertex3f(-1.0, 1.0, -0.1);
267 glEnd();
268
269 glDisable(GL_BLEND);
270
271 glMatrixMode(GL_PROJECTION);
272 glPopMatrix();
273 glMatrixMode(GL_MODELVIEW);
274 glPopMatrix();
275
276 /*
277 glLoadIdentity();
278
279 someChar->getTilemap().bind();
280 glColor3f(1.0, 1.0, 1.0);
281
282 Mf::Tilemap::Index heroFrame = someChar->getAnimation().getFrame();
283
284 Mf::Scalar coords[8];
285 someChar->getTilemap().getTileCoords(heroFrame, coords);
286
287 glBegin(GL_QUADS);
288 glTexCoord2f(coords[0], coords[1]);
289 glVertex3f(-1.0, 0.0, 0.0);
290 glTexCoord2f(coords[2], coords[3]);
291 glVertex3f(0.0, 0.0, 0.0);
292 glTexCoord2f(coords[4], coords[5]);
293 glVertex3f(0.0, 1.0, 0.0);
294 glTexCoord2f(coords[6], coords[7]);
295 glVertex3f(-1.0, 1.0, 0.0);
296 glEnd();
297
298
299 someChar->getTilemap().getTileCoords(heroFrame, coords,
300 Mf::Tilemap::REVERSE);
301
302 glBegin(GL_QUADS);
303 glTexCoord2f(coords[0], coords[1]);
304 glVertex3f(0.0, 0.0, 0.0);
305 glTexCoord2f(coords[2], coords[3]);
306 glVertex3f(1.0, 0.0, 0.0);
307 glTexCoord2f(coords[4], coords[5]);
308 glVertex3f(1.0, 1.0, 0.0);
309 glTexCoord2f(coords[6], coords[7]);
310 glVertex3f(0.0, 1.0, 0.0);
311 glEnd();
312
313 glColor4f(1.0,0.0,0.0,0.5);
314
315 glBindTexture(GL_TEXTURE_2D, 0);
316 glColor4v(c1.data());
317
318 glRectd(-cosstate, -sinstate, sinstate, cosstate);
319 glRectf(0.0f, 0.0f, sinstate, cosstate);
320
321 font->bind();
322
323 font->getTileCoords('c', coords);
324
325 glBegin(GL_QUADS);
326 glTexCoord2f(coords[0], coords[1]);
327 glVertex3f(-1.0, 0.0, 0.0);
328 glTexCoord2f(coords[2], coords[3]);
329 glVertex3f(0.0, 0.0, 0.0);
330 glTexCoord2f(coords[4], coords[5]);
331 glVertex3f(0.0, 1.0, 0.0);
332 glTexCoord2f(coords[6], coords[7]);
333 glVertex3f(-1.0, 1.0, 0.0);
334 glEnd();
335
336 font->getTileCoords('h', coords);
337
338 glBegin(GL_QUADS);
339 glTexCoord2f(coords[0], coords[1]);
340 glVertex3f(0.0, 0.0, 0.0);
341 glTexCoord2f(coords[2], coords[3]);
342 glVertex3f(1.0, 0.0, 0.0);
343 glTexCoord2f(coords[4], coords[5]);
344 glVertex3f(1.0, 1.0, 0.0);
345 glTexCoord2f(coords[6], coords[7]);
346 glVertex3f(0.0, 1.0, 0.0);
347 glEnd();
348
349 font->getTileCoords('a', coords);
350
351 glBegin(GL_QUADS);
352 glTexCoord2f(coords[0], coords[1]);
353 glVertex3f(-1.0, -1.0, 0.0);
354 glTexCoord2f(coords[2], coords[3]);
355 glVertex3f(0.0, -1.0, 0.0);
356 glTexCoord2f(coords[4], coords[5]);
357 glVertex3f(0.0, 0.0, 0.0);
358 glTexCoord2f(coords[6], coords[7]);
359 glVertex3f(-1.0, 0.0, 0.0);
360 glEnd();
361
362 font->getTileCoords('z', coords);
363
364 glBegin(GL_QUADS);
365 glTexCoord2f(coords[0], coords[1]);
366 glVertex3(0.0, -1.0, 0.0);
367 glTexCoord2f(coords[2], coords[3]);
368 glVertex3(1.0, -1.0, 0.0);
369 glTexCoord2f(coords[4], coords[5]);
370 glVertex3(1.0, 0.0, 0.0);
371 glTexCoord2f(coords[6], coords[7]);
372 glVertex3(0.0, 0.0, 0.0);
373 glEnd();
374
375 glEnable(GL_BLEND);
376 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
377 glDisable(GL_DEPTH_TEST);
378
379 glBindTexture(GL_TEXTURE_2D, 0);
380 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
381
382 glBegin(GL_LINES);
383 glVertex2f(0.0f, 0.0f);
384 glVertex2v(interp.getState(alpha).data());
385 glEnd();
386
387 glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
388 glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
389
390 glDisable(GL_BLEND);
391 glEnable(GL_DEPTH_TEST);*/
392 }
393
394 void YoinkApp::handleEvent(const Mf::Event& event)
395 {
396 switch (event.type)
397 {
398 case SDL_KEYDOWN:
399 if (event.key.keysym.sym == SDLK_ESCAPE)
400 {
401 stop();
402 break;
403 }
404 else if (event.key.keysym.sym == SDLK_f)
405 {
406 getVideo().toggleFull();
407 break;
408 }
409 else if (event.key.keysym.sym == SDLK_SPACE)
410 {
411 heroine->getAnimation().startSequence("Punch");
412 punchSound.play();
413 break;
414 }
415 else if (event.key.keysym.sym == SDLK_r)
416 {
417 testScene->refresh();
418 break;
419 }
420 else if (event.key.keysym.sym == SDLK_t)
421 {
422 Mf::dispatcher::dispatch("video.context_recreated");
423 break;
424 }
425 else if (event.key.keysym.sym == SDLK_p)
426 {
427 music.togglePlayPause();
428 break;
429 }
430 else if (event.key.keysym.sym == SDLK_l)
431 {
432 getVideo().toggleCursorGrab();
433 getVideo().toggleCursorVisible();
434 break;
435 }
436
437 case SDL_KEYUP:
438 heroine->handleEvent(event);
439
440 case SDL_MOUSEMOTION:
441 case SDL_MOUSEBUTTONDOWN:
442 camera.handleEvent(event);
443 break;
444
445 case SDL_QUIT:
446 stop();
447 break;
448
449 case SDL_VIDEORESIZE:
450 glViewport(0, 0, event.resize.w, event.resize.h);
451 hud.resize(event.resize.w, event.resize.h);
452 camera.setProjection(cml::rad(60.0), double(event.resize.w / event.resize.h), 32.0, 2500.0);
453 camera.uploadProjectionToGL();
454 break;
455 }
456 }
457
458
459
460 int main(int argc, char* argv[])
461 {
462 std::cout << std::endl << PACKAGE_STRING << std::endl
463 << "Compiled " << __TIME__ " " __DATE__ << std::endl
464 << "Send patches and bug reports to <"
465 PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
466
467 #if ! NDEBUG
468 Mf::setLogLevel(Mf::DEBUGGING);
469 #endif
470
471 int status = 0;
472
473 try
474 {
475 YoinkApp app(argc, argv);
476 status = app.run();
477 }
478 catch (Mf::Exception e)
479 {
480 Mf::logError("unhandled exception: <<%s>>", e.what());
481 Mf::logInfo("it's time to crash now :-(");
482 status = 1;
483 }
484
485 std::cout << std::endl << "Goodbye..." << std::endl << std::endl;
486 return status;
487 }
488
489
490 /** vim: set ts=4 sw=4 tw=80: *************************************************/
491
This page took 0.047957 seconds and 4 git commands to generate.