493e6157cad7bdc2347f820cb26a1c1d406bbc39
[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/Math.hh>
36 #include <Moof/OpenGL.hh>
37 #include <Moof/Settings.hh>
38 #include <Moof/Timer.hh>
39 #include <Moof/Video.hh>
40
41 #include "YoinkApp.hh"
42
43 #if HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47
48 static std::string configFiles()
49 {
50 std::string files;
51
52 char* configFile = getenv("YOINKRC");
53 char* dataDir = getenv("YOINK_DATADIR");
54
55 if (configFile)
56 {
57 // if a config file from the environment variable is specified, we want
58 // to load it first so it has precedence
59 files += configFile;
60 files += ":";
61 }
62
63 // add the colon-delimited paths from configure
64 files += YOINK_CONFIGFILES;
65
66 if (dataDir)
67 {
68 // if another data directory is set in the environment, look for a
69 // config file there
70 files += ":";
71 files += dataDir;
72 files += "/yoinkrc";
73 }
74
75 // look in the configured data directory last of all
76 files += ":";
77 files += (dataDir ? dataDir : YOINK_DATADIR);
78 files += "/yoinkrc";
79
80 return files;
81 }
82
83 static std::string iconFile()
84 {
85 char* dataDir = getenv("YOINK_DATADIR");
86
87 // first set up the search paths so we can find the icon and other resources
88 if (dataDir)
89 {
90 // look first in the data directory specified by the environment
91 Mf::Resource::addSearchPath(dataDir);
92 }
93
94 // then look in the configured data directory
95 Mf::Resource::addSearchPath(YOINK_DATADIR);
96
97 return Mf::Resource::getPathToResource("yoink.png");
98 }
99
100
101 YoinkApp::YoinkApp(int argc, char* argv[]) :
102 Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile())
103 {
104 Mf::Dispatcher::instance().addHandler("video.context_recreated",
105 boost::bind(&YoinkApp::contextRecreated, this, _1), this);
106 setupGL();
107
108 state = 0.0;
109
110 someChar = new Character("RobotTrooper");
111 someChar->getAnimation().startSequence("Run");
112
113 font = new TilemapFont;
114
115 Mf::Vector2 coeffs[4];
116 coeffs[0] = Mf::Vector2(0.0, 0.0);
117 coeffs[1] = Mf::Vector2(0.5, 0.0);
118 coeffs[2] = Mf::Vector2(0.5, 0.0);
119 coeffs[3] = Mf::Vector2(1.0, 0.0);
120 interp.init(coeffs, 1.0, Mf::Interpolator::OSCILLATE);
121
122 Mf::Scalar coeff[2] = {1.0, 0.0};
123 fadeIn.init(coeff, 0.5f);
124
125 testScene = new Mf::Scene("Test");
126
127 x = y = z = 0.0;
128 }
129
130 YoinkApp::~YoinkApp()
131 {
132 delete someChar;
133 delete font;
134 delete testScene;
135
136 Mf::Dispatcher::instance().removeHandler(this);
137 }
138
139
140 void YoinkApp::setupGL()
141 {
142 glEnable(GL_TEXTURE_2D);
143
144 //glEnable(GL_CULL_FACE);
145 glEnable(GL_DEPTH_TEST);
146
147 glShadeModel(GL_SMOOTH);
148 //glEnable(GL_POLYGON_SMOOTH);
149
150 //int texSize;
151 //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
152 //std::cout << "texture size: " << texSize << std::endl;
153
154 //glEnable(GL_BLEND);
155 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
156 glEnable(GL_ALPHA_TEST);
157 glAlphaFunc(GL_GREATER, 0.0);
158
159 glClearColor(1.0, 0.0, 0.0, 1.0);
160
161 //glMatrixMode(GL_PROJECTION);
162 //glLoadIdentity();
163 //gluPerspective(60.0, 1.33333, 1.0, 2500.0);
164 camera.setProjection(cml::rad(60.0), 1.33333, 32.0, 2500.0);
165 camera.uploadProjectionToGL();
166
167 //glMatrixMode(GL_MODELVIEW);
168
169 //glLineWidth(10.0f);
170 }
171
172 void YoinkApp::contextRecreated(const Mf::Notification& note)
173 {
174 // Whenever the context and a new one created, it probably won't contain our
175 // state so we need to set that up again.
176 setupGL();
177 }
178
179
180 void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt)
181 {
182 //dt *= 0.2;
183
184 fadeIn.update(dt);
185
186 camera.update(t, dt);
187
188 someChar->getAnimation().update(t, dt);
189 interp.update(dt);
190
191 prevstate = state;
192 state += dt;
193 }
194
195
196 void YoinkApp::draw(Mf::Scalar alpha)
197 {
198 //Mf::Vector4 meh;
199 //meh.random(0.0, 1.0);
200 //static Mf::Vector4 c1(meh);
201
202 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
203
204 //Mf::Scalar drawstate = cml::lerp(prevstate, state, alpha);
205 //Mf::Scalar sinstate = std::sin(drawstate);
206 //Mf::Scalar cosstate = std::cos(drawstate);
207
208
209
210 glMatrixMode(GL_MODELVIEW);
211 //glLoadIdentity();
212
213 glBindTexture(GL_TEXTURE_2D, 0);
214 //glRotatef(drawstate*15.0f, 0.0, 1.0, 0.0);
215 //glTranslatef(x, y, z);
216 glLoadMatrix(camera.getModelviewMatrix().data());
217
218 // DRAW THE SCENE
219 testScene->draw(alpha, camera);
220
221
222 /*
223 glLoadIdentity();
224
225 someChar->getTilemap().bind();
226 glColor3f(1.0, 1.0, 1.0);
227
228 Mf::Tilemap::Index heroFrame = someChar->getAnimation().getFrame();
229
230 Mf::Scalar coords[8];
231 someChar->getTilemap().getTileCoords(heroFrame, coords);
232
233 glBegin(GL_QUADS);
234 glTexCoord2f(coords[0], coords[1]);
235 glVertex3f(-1.0, 0.0, 0.0);
236 glTexCoord2f(coords[2], coords[3]);
237 glVertex3f(0.0, 0.0, 0.0);
238 glTexCoord2f(coords[4], coords[5]);
239 glVertex3f(0.0, 1.0, 0.0);
240 glTexCoord2f(coords[6], coords[7]);
241 glVertex3f(-1.0, 1.0, 0.0);
242 glEnd();
243
244
245 someChar->getTilemap().getTileCoords(heroFrame, coords,
246 Mf::Tilemap::REVERSE);
247
248 glBegin(GL_QUADS);
249 glTexCoord2f(coords[0], coords[1]);
250 glVertex3f(0.0, 0.0, 0.0);
251 glTexCoord2f(coords[2], coords[3]);
252 glVertex3f(1.0, 0.0, 0.0);
253 glTexCoord2f(coords[4], coords[5]);
254 glVertex3f(1.0, 1.0, 0.0);
255 glTexCoord2f(coords[6], coords[7]);
256 glVertex3f(0.0, 1.0, 0.0);
257 glEnd();
258
259 glColor4f(1.0,0.0,0.0,0.5);
260
261 glBindTexture(GL_TEXTURE_2D, 0);
262 glColor4v(c1.data());
263
264 glRectd(-cosstate, -sinstate, sinstate, cosstate);
265 glRectf(0.0f, 0.0f, sinstate, cosstate);
266
267 font->bind();
268
269 font->getTileCoords('c', coords);
270
271 glBegin(GL_QUADS);
272 glTexCoord2f(coords[0], coords[1]);
273 glVertex3f(-1.0, 0.0, 0.0);
274 glTexCoord2f(coords[2], coords[3]);
275 glVertex3f(0.0, 0.0, 0.0);
276 glTexCoord2f(coords[4], coords[5]);
277 glVertex3f(0.0, 1.0, 0.0);
278 glTexCoord2f(coords[6], coords[7]);
279 glVertex3f(-1.0, 1.0, 0.0);
280 glEnd();
281
282 font->getTileCoords('h', coords);
283
284 glBegin(GL_QUADS);
285 glTexCoord2f(coords[0], coords[1]);
286 glVertex3f(0.0, 0.0, 0.0);
287 glTexCoord2f(coords[2], coords[3]);
288 glVertex3f(1.0, 0.0, 0.0);
289 glTexCoord2f(coords[4], coords[5]);
290 glVertex3f(1.0, 1.0, 0.0);
291 glTexCoord2f(coords[6], coords[7]);
292 glVertex3f(0.0, 1.0, 0.0);
293 glEnd();
294
295 font->getTileCoords('a', coords);
296
297 glBegin(GL_QUADS);
298 glTexCoord2f(coords[0], coords[1]);
299 glVertex3f(-1.0, -1.0, 0.0);
300 glTexCoord2f(coords[2], coords[3]);
301 glVertex3f(0.0, -1.0, 0.0);
302 glTexCoord2f(coords[4], coords[5]);
303 glVertex3f(0.0, 0.0, 0.0);
304 glTexCoord2f(coords[6], coords[7]);
305 glVertex3f(-1.0, 0.0, 0.0);
306 glEnd();
307
308 font->getTileCoords('z', coords);
309
310 glBegin(GL_QUADS);
311 glTexCoord2f(coords[0], coords[1]);
312 glVertex3(0.0, -1.0, 0.0);
313 glTexCoord2f(coords[2], coords[3]);
314 glVertex3(1.0, -1.0, 0.0);
315 glTexCoord2f(coords[4], coords[5]);
316 glVertex3(1.0, 0.0, 0.0);
317 glTexCoord2f(coords[6], coords[7]);
318 glVertex3(0.0, 0.0, 0.0);
319 glEnd();
320
321 glEnable(GL_BLEND);
322 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
323 glDisable(GL_DEPTH_TEST);
324
325 glBindTexture(GL_TEXTURE_2D, 0);
326 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
327
328 glBegin(GL_LINES);
329 glVertex2f(0.0f, 0.0f);
330 glVertex2v(interp.getState(alpha).data());
331 glEnd();
332
333 glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
334 glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
335
336 glDisable(GL_BLEND);
337 glEnable(GL_DEPTH_TEST);*/
338 }
339
340 void YoinkApp::handleEvent(const Mf::Event& event)
341 {
342 switch (event.type)
343 {
344 case SDL_KEYDOWN:
345 if (event.key.keysym.sym == SDLK_ESCAPE)
346 {
347 stop();
348 }
349 else if (event.key.keysym.sym == SDLK_f)
350 {
351 getVideo().toggleFull();
352 }
353 else if (event.key.keysym.sym == SDLK_a)
354 {
355 someChar->getAnimation().startSequence("Punch");
356 }
357 else if (event.key.keysym.sym == SDLK_r)
358 {
359 testScene->refresh();
360 }
361 else if (event.key.keysym.sym == SDLK_l)
362 {
363 getVideo().toggleCursorGrab();
364 getVideo().toggleCursorVisible();
365 }
366 //else if (event.key.keysym.sym == SDLK_RIGHT)
367 //{
368 //x -= 50.0;
369 //}
370 //else if (event.key.keysym.sym == SDLK_LEFT)
371 //{
372 //x += 50.0;
373 //}
374 //else if (event.key.keysym.sym == SDLK_UP)
375 //{
376 //y -= 50.0;
377 //}
378 //else if (event.key.keysym.sym == SDLK_DOWN)
379 //{
380 //y += 50.0;
381 //}
382 //else if (event.key.keysym.sym == SDLK_PAGEUP)
383 //{
384 //z += 50.0;
385 //}
386 //else if (event.key.keysym.sym == SDLK_PAGEDOWN)
387 //{
388 //z -= 50.0;
389 //}
390
391 case SDL_MOUSEMOTION:
392 case SDL_MOUSEBUTTONDOWN:
393 camera.adjustFromInput(event);
394 break;
395
396 case SDL_QUIT:
397 stop();
398 break;
399
400 case SDL_VIDEORESIZE:
401 glViewport(0, 0, event.resize.w, event.resize.h);
402 camera.setProjection(cml::rad(60.0), double(event.resize.w / event.resize.h), 32.0, 2500.0);
403 camera.uploadProjectionToGL();
404 break;
405 }
406 }
407
408
409
410 int main(int argc, char* argv[])
411 {
412 std::cout << PACKAGE_STRING << std::endl
413 << "Compiled " << __TIME__ " " __DATE__ << std::endl
414 << "Send requests, patches, and bug reports to <"
415 PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
416
417 int status = 0;
418
419 try
420 {
421 YoinkApp app(argc, argv);
422 status = app.run();
423 }
424 catch (Mf::Engine::Exception e)
425 {
426 std::cerr << "Unhandled exception: " << e.what() << std::endl;
427 status = 1;
428 }
429
430 std::cout << "Goodbye..." << std::endl;
431 return status;
432 }
433
434
435 /** vim: set ts=4 sw=4 tw=80: *************************************************/
436
This page took 0.047393 seconds and 3 git commands to generate.