]> Dogcows Code - chaz/yoink/blob - src/YoinkApp.cc
a17bf88b1c0ffe84c7ef52a2b966773e434f5ea7
[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::getInstance().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 = CharacterPtr(new Character("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::getInstance().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
246
247 hud.draw();
248
249
250 glEnable(GL_BLEND);
251 glMatrixMode(GL_PROJECTION);
252 glPushMatrix();
253 glLoadIdentity();
254 glMatrixMode(GL_MODELVIEW);
255 glPushMatrix();
256 glLoadIdentity();
257 glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
258 Mf::Texture::resetBind();
259
260 //glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
261 glBegin(GL_QUADS);
262 glVertex3f(-1.0, -1.0, -0.1);
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 glEnd();
267
268 glDisable(GL_BLEND);
269
270 glMatrixMode(GL_PROJECTION);
271 glPopMatrix();
272 glMatrixMode(GL_MODELVIEW);
273 glPopMatrix();
274
275 /*
276 glLoadIdentity();
277
278 someChar->getTilemap().bind();
279 glColor3f(1.0, 1.0, 1.0);
280
281 Mf::Tilemap::Index heroFrame = someChar->getAnimation().getFrame();
282
283 Mf::Scalar coords[8];
284 someChar->getTilemap().getTileCoords(heroFrame, coords);
285
286 glBegin(GL_QUADS);
287 glTexCoord2f(coords[0], coords[1]);
288 glVertex3f(-1.0, 0.0, 0.0);
289 glTexCoord2f(coords[2], coords[3]);
290 glVertex3f(0.0, 0.0, 0.0);
291 glTexCoord2f(coords[4], coords[5]);
292 glVertex3f(0.0, 1.0, 0.0);
293 glTexCoord2f(coords[6], coords[7]);
294 glVertex3f(-1.0, 1.0, 0.0);
295 glEnd();
296
297
298 someChar->getTilemap().getTileCoords(heroFrame, coords,
299 Mf::Tilemap::REVERSE);
300
301 glBegin(GL_QUADS);
302 glTexCoord2f(coords[0], coords[1]);
303 glVertex3f(0.0, 0.0, 0.0);
304 glTexCoord2f(coords[2], coords[3]);
305 glVertex3f(1.0, 0.0, 0.0);
306 glTexCoord2f(coords[4], coords[5]);
307 glVertex3f(1.0, 1.0, 0.0);
308 glTexCoord2f(coords[6], coords[7]);
309 glVertex3f(0.0, 1.0, 0.0);
310 glEnd();
311
312 glColor4f(1.0,0.0,0.0,0.5);
313
314 glBindTexture(GL_TEXTURE_2D, 0);
315 glColor4v(c1.data());
316
317 glRectd(-cosstate, -sinstate, sinstate, cosstate);
318 glRectf(0.0f, 0.0f, sinstate, cosstate);
319
320 font->bind();
321
322 font->getTileCoords('c', coords);
323
324 glBegin(GL_QUADS);
325 glTexCoord2f(coords[0], coords[1]);
326 glVertex3f(-1.0, 0.0, 0.0);
327 glTexCoord2f(coords[2], coords[3]);
328 glVertex3f(0.0, 0.0, 0.0);
329 glTexCoord2f(coords[4], coords[5]);
330 glVertex3f(0.0, 1.0, 0.0);
331 glTexCoord2f(coords[6], coords[7]);
332 glVertex3f(-1.0, 1.0, 0.0);
333 glEnd();
334
335 font->getTileCoords('h', coords);
336
337 glBegin(GL_QUADS);
338 glTexCoord2f(coords[0], coords[1]);
339 glVertex3f(0.0, 0.0, 0.0);
340 glTexCoord2f(coords[2], coords[3]);
341 glVertex3f(1.0, 0.0, 0.0);
342 glTexCoord2f(coords[4], coords[5]);
343 glVertex3f(1.0, 1.0, 0.0);
344 glTexCoord2f(coords[6], coords[7]);
345 glVertex3f(0.0, 1.0, 0.0);
346 glEnd();
347
348 font->getTileCoords('a', coords);
349
350 glBegin(GL_QUADS);
351 glTexCoord2f(coords[0], coords[1]);
352 glVertex3f(-1.0, -1.0, 0.0);
353 glTexCoord2f(coords[2], coords[3]);
354 glVertex3f(0.0, -1.0, 0.0);
355 glTexCoord2f(coords[4], coords[5]);
356 glVertex3f(0.0, 0.0, 0.0);
357 glTexCoord2f(coords[6], coords[7]);
358 glVertex3f(-1.0, 0.0, 0.0);
359 glEnd();
360
361 font->getTileCoords('z', coords);
362
363 glBegin(GL_QUADS);
364 glTexCoord2f(coords[0], coords[1]);
365 glVertex3(0.0, -1.0, 0.0);
366 glTexCoord2f(coords[2], coords[3]);
367 glVertex3(1.0, -1.0, 0.0);
368 glTexCoord2f(coords[4], coords[5]);
369 glVertex3(1.0, 0.0, 0.0);
370 glTexCoord2f(coords[6], coords[7]);
371 glVertex3(0.0, 0.0, 0.0);
372 glEnd();
373
374 glEnable(GL_BLEND);
375 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
376 glDisable(GL_DEPTH_TEST);
377
378 glBindTexture(GL_TEXTURE_2D, 0);
379 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
380
381 glBegin(GL_LINES);
382 glVertex2f(0.0f, 0.0f);
383 glVertex2v(interp.getState(alpha).data());
384 glEnd();
385
386 glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
387 glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
388
389 glDisable(GL_BLEND);
390 glEnable(GL_DEPTH_TEST);*/
391 }
392
393 void YoinkApp::handleEvent(const Mf::Event& event)
394 {
395 switch (event.type)
396 {
397 case SDL_KEYDOWN:
398 if (event.key.keysym.sym == SDLK_ESCAPE)
399 {
400 stop();
401 break;
402 }
403 else if (event.key.keysym.sym == SDLK_f)
404 {
405 getVideo().toggleFull();
406 break;
407 }
408 else if (event.key.keysym.sym == SDLK_SPACE)
409 {
410 heroine->getAnimation().startSequence("Punch");
411 punchSound.play();
412 break;
413 }
414 else if (event.key.keysym.sym == SDLK_r)
415 {
416 testScene->refresh();
417 break;
418 }
419 else if (event.key.keysym.sym == SDLK_t)
420 {
421 Mf::Dispatcher::getInstance().dispatch("video.context_recreated");
422 break;
423 }
424 else if (event.key.keysym.sym == SDLK_p)
425 {
426 music.togglePlayPause();
427 break;
428 }
429 else if (event.key.keysym.sym == SDLK_l)
430 {
431 getVideo().toggleCursorGrab();
432 getVideo().toggleCursorVisible();
433 break;
434 }
435
436 case SDL_KEYUP:
437 heroine->handleEvent(event);
438
439 case SDL_MOUSEMOTION:
440 case SDL_MOUSEBUTTONDOWN:
441 camera.handleEvent(event);
442 break;
443
444 case SDL_QUIT:
445 stop();
446 break;
447
448 case SDL_VIDEORESIZE:
449 glViewport(0, 0, event.resize.w, event.resize.h);
450 hud.resize(event.resize.w, event.resize.h);
451 camera.setProjection(cml::rad(60.0), double(event.resize.w / event.resize.h), 32.0, 2500.0);
452 camera.uploadProjectionToGL();
453 break;
454 }
455 }
456
457
458
459 int main(int argc, char* argv[])
460 {
461 std::cout << std::endl << PACKAGE_STRING << std::endl
462 << "Compiled " << __TIME__ " " __DATE__ << std::endl
463 << "Send patches and bug reports to <"
464 PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
465
466 #if ! NDEBUG
467 Mf::setLogLevel(Mf::DEBUGGING);
468 #endif
469
470 int status = 0;
471
472 //start:
473 try
474 {
475 YoinkApp app(argc, argv);
476 status = app.run();
477 }
478 //catch (Mf::Texture::Exception e)
479 //{
480 //std::cout << "Unhandled exception: " << e.what() << std::endl;
481 //status = 1;
482 //}
483 catch (Mf::Exception e)
484 {
485 //std::cout << "Unhandled exception: " << e.what() << std::endl;
486 Mf::logError("unhandled exception: <<%s>>", e.what());
487 Mf::logInfo("it's time to crash now ;-(");
488 status = 1;
489
490 //std::cout << "Yoink stopped. Do you want to run it again? [yes/No]"
491 //<< std::endl;
492
493 //char answer;
494 //std::cin >> answer;
495
496 //if (answer == 'y' || answer == 'Y') goto start;
497 }
498
499 std::cout << std::endl << "Goodbye..." << std::endl << std::endl;
500 return status;
501 }
502
503
504 /** vim: set ts=4 sw=4 tw=80: *************************************************/
505
This page took 0.052988 seconds and 3 git commands to generate.