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