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