]> Dogcows Code - chaz/yoink/blob - src/YoinkApp.cc
d36f6da3ef8f52f9f8e61d82c85a4f5cb6f655b4
[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 #if HAVE_CONFIG_H
46 #include "config.h"
47 #endif
48
49
50 static std::string configFiles()
51 {
52 std::string files;
53
54 char* configFile = getenv("YOINKRC");
55 char* dataDir = getenv("YOINK_DATADIR");
56
57 if (configFile)
58 {
59 // if a config file from the environment variable is specified, we want
60 // to load it first so it has precedence
61 files += configFile;
62 files += ":";
63 }
64
65 // add the colon-delimited paths from configure
66 files += YOINK_CONFIGFILES;
67
68 if (dataDir)
69 {
70 // if another data directory is set in the environment, look for a
71 // config file there
72 files += ":";
73 files += dataDir;
74 files += "/yoinkrc";
75 }
76
77 // look in the configured data directory last of all
78 files += ":";
79 files += (dataDir ? dataDir : YOINK_DATADIR);
80 files += "/yoinkrc";
81
82 return files;
83 }
84
85 static std::string iconFile()
86 {
87 char* dataDir = getenv("YOINK_DATADIR");
88
89 // first set up the search paths so we can find the icon and other resources
90 if (dataDir)
91 {
92 // look first in the data directory specified by the environment
93 Mf::Resource::addSearchPath(dataDir);
94 }
95
96 // then look in the configured data directory
97 Mf::Resource::addSearchPath(YOINK_DATADIR);
98
99 return Mf::Resource::getPath("yoink.png");
100 }
101
102
103 YoinkApp::YoinkApp(int argc, char* argv[]) :
104 Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile()),
105 music("NightFusionIntro"),
106 punchSound("RobotPunch")
107 {
108 Mf::dispatcher::addHandler("video.context_recreated",
109 boost::bind(&YoinkApp::contextRecreated, this, _1), this);
110 setupGL();
111
112 music.setLooping(true);
113 music.enqueue("NightFusionLoop");
114 music.stream();
115
116 heroine = Character::alloc("RobotTrooper");
117 heroine->getAnimation().startSequence("Run");
118
119 font = new TilemapFont;
120
121 Mf::Scalar coeffs[4];
122 coeffs[0] = 0.0;
123 coeffs[1] = 1.5;
124 coeffs[2] = -0.5;
125 coeffs[3] = 1.0;
126 interp.init(coeffs, 1.0, Mf::Interpolator::OSCILLATE);
127
128 Mf::Scalar coeff[2] = {1.0, 0.0};
129 fadeIn.init(coeff, 0.1);
130
131 testScene = Mf::Scene::alloc("Test");
132 heroine->treeNode = testScene->getOctree()->insert(heroine);
133 }
134
135 YoinkApp::~YoinkApp()
136 {
137 //delete heroine;
138 delete font;
139
140 Mf::dispatcher::removeHandler(this);
141 }
142
143
144 void YoinkApp::setupGL()
145 {
146 glEnable(GL_TEXTURE_2D);
147
148 //glEnable(GL_CULL_FACE);
149 glEnable(GL_DEPTH_TEST);
150
151 glShadeModel(GL_SMOOTH);
152 //glEnable(GL_POLYGON_SMOOTH);
153
154 //int texSize;
155 //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
156 //std::cout << "texture size: " << texSize << std::endl;
157
158 //glEnable(GL_BLEND);
159 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
160 glEnable(GL_ALPHA_TEST);
161 glAlphaFunc(GL_GREATER, 0.0);
162
163 glClearColor(1.0, 0.0, 0.0, 1.0);
164
165 //glMatrixMode(GL_PROJECTION);
166 //glLoadIdentity();
167 //gluPerspective(60.0, 1.33333, 1.0, 2500.0);
168 camera.setProjection(cml::rad(60.0), 1.33333, 32.0, 2500.0);
169 camera.uploadProjectionToGL();
170
171 //glMatrixMode(GL_MODELVIEW);
172
173 //glLineWidth(10.0f);
174 }
175
176 void YoinkApp::contextRecreated(const Mf::Notification* note)
177 {
178 // Whenever the context and a new one created, it probably won't contain our
179 // state so we need to set that up again.
180 setupGL();
181 }
182
183
184 void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt)
185 {
186 //dt *= 0.5;
187
188 music.update(t, dt);
189 fadeIn.update(dt);
190 camera.update(t, dt);
191 heroine->update(t, dt);
192
193 // reinsert heroine
194 heroine->treeNode = testScene->getOctree()->reinsert(heroine, heroine->treeNode);
195 testScene->getOctree()->print(heroine->treeNode);
196
197 //camera.lookAt(heroine->getSphere().point);
198 camera.setPosition(Mf::Vector3(-heroine->current.position[0], -heroine->current.position[1], -256));
199
200 interp.update(dt);
201 hud.setBar1Progress(interp.getValue());
202 hud.setBar2Progress(1.0 - interp.getValue());
203 }
204
205
206 void YoinkApp::draw(Mf::Scalar alpha)
207 {
208 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
209
210 glMatrixMode(GL_MODELVIEW);
211 glLoadMatrix(camera.getModelviewMatrix().data());
212
213 // DRAW THE SCENE
214 Mf::Texture::resetBind();
215 testScene->draw(alpha, camera);
216
217 //heroine->draw(alpha);
218 heroine->getAabb().draw();
219
220 hud.draw();
221
222 // DRAW FADE
223 glEnable(GL_BLEND);
224 glMatrixMode(GL_PROJECTION);
225 glPushMatrix();
226 glLoadIdentity();
227 glMatrixMode(GL_MODELVIEW);
228 glPushMatrix();
229 glLoadIdentity();
230 glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
231 Mf::Texture::resetBind();
232
233 //glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
234 glBegin(GL_QUADS);
235 glVertex3f(-1.0, -1.0, -0.1);
236 glVertex3f(1.0, -1.0, -0.1);
237 glVertex3f(1.0, 1.0, -0.1);
238 glVertex3f(-1.0, 1.0, -0.1);
239 glEnd();
240
241 glDisable(GL_BLEND);
242
243 glMatrixMode(GL_PROJECTION);
244 glPopMatrix();
245 glMatrixMode(GL_MODELVIEW);
246 glPopMatrix();
247 }
248
249 void YoinkApp::handleEvent(const Mf::Event& event)
250 {
251 switch (event.type)
252 {
253 case SDL_KEYDOWN:
254 if (event.key.keysym.sym == SDLK_ESCAPE)
255 {
256 stop();
257 break;
258 }
259 else if (event.key.keysym.sym == SDLK_f)
260 {
261 getVideo().toggleFull();
262 break;
263 }
264 else if (event.key.keysym.sym == SDLK_SPACE)
265 {
266 heroine->getAnimation().startSequence("Punch");
267 punchSound.play();
268 break;
269 }
270 else if (event.key.keysym.sym == SDLK_r)
271 {
272 testScene->refresh();
273 break;
274 }
275 else if (event.key.keysym.sym == SDLK_t)
276 {
277 Mf::dispatcher::dispatch("video.context_recreated");
278 break;
279 }
280 else if (event.key.keysym.sym == SDLK_p)
281 {
282 music.toggle();
283 break;
284 }
285 else if (event.key.keysym.sym == SDLK_l)
286 {
287 getVideo().toggleCursorGrab();
288 getVideo().toggleCursorVisible();
289 break;
290 }
291
292 case SDL_KEYUP:
293 heroine->handleEvent(event);
294
295 case SDL_MOUSEMOTION:
296 case SDL_MOUSEBUTTONDOWN:
297 camera.handleEvent(event);
298 break;
299
300 case SDL_QUIT:
301 stop();
302 break;
303
304 case SDL_VIDEORESIZE:
305 glViewport(0, 0, event.resize.w, event.resize.h);
306 hud.resize(event.resize.w, event.resize.h);
307 camera.setProjection(cml::rad(60.0), double(event.resize.w / event.resize.h), 32.0, 2500.0);
308 camera.uploadProjectionToGL();
309 break;
310 }
311 }
312
313
314
315 int main(int argc, char* argv[])
316 {
317 std::cout << std::endl << PACKAGE_STRING << std::endl
318 << "Compiled " << __TIME__ " " __DATE__ << std::endl
319 << "Send patches and bug reports to <"
320 PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
321
322 #if YOINK_LOGLEVEL >= 4
323 Mf::setLogLevel(Mf::LOG_DEBUG);
324 #elif YOINK_LOGLEVEL >= 3
325 Mf::setLogLevel(Mf::LOG_INFO);
326 #elif YOINK_LOGLEVEL >= 2
327 Mf::setLogLevel(Mf::LOG_WARNING);
328 #elif YOINK_LOGLEVEL >= 1
329 Mf::setLogLevel(Mf::LOG_ERROR);
330 #elif YOINK_LOGLEVEL
331 Mf::setLogLevel(Mf::LOG_NONE);
332 #endif
333
334 int status = 0;
335
336 try
337 {
338 YoinkApp app(argc, argv);
339 status = app.run();
340 }
341 catch (Mf::Exception e)
342 {
343 Mf::logError("unhandled exception: <<%s>>", e.what());
344 Mf::logInfo("it's time to crash now :-(");
345 status = 1;
346 }
347
348 std::cout << std::endl << "Goodbye..." << std::endl << std::endl;
349 return status;
350 }
351
352
353 /** vim: set ts=4 sw=4 tw=80: *************************************************/
354
This page took 0.049849 seconds and 3 git commands to generate.