]> Dogcows Code - chaz/yoink/blob - src/YoinkApp.cc
main loop code fixed to decouple updates and draws
[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 <iostream>
30 #include <string>
31
32 #include <cstdlib> // getenv
33
34 #include <boost/bind.hpp>
35
36 #include "opengl.hh"
37 #include "video.hh"
38 #include "settings.hh"
39
40 #include "math.hh"
41
42 #include "YoinkApp.hh"
43
44 #include "timer.hh"
45
46 #if HAVE_CONFIG_H
47 #include "config.h"
48 #endif
49
50
51 static std::string configFiles()
52 {
53 std::string files;
54
55 char* configFile = getenv("YOINK_CONFIGFILE");
56
57 if (configFile)
58 {
59 // if a config file from the environment variable is specified, we want
60 // to load it first
61 files += configFile;
62 files += ":";
63 }
64
65 files += YOINK_CONFIGFILES;
66
67 return files;
68 }
69
70
71 YoinkApp::YoinkApp(int argc, char* argv[]) :
72 dc::engine(PACKAGE_STRING, argc, argv, configFiles())
73 {
74 std::cout << PACKAGE_STRING << std::endl
75 << "Compiled " << __TIME__ " " __DATE__ << std::endl
76 << "Send requests, patches, and bug reports to <"
77 PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
78
79 char* dataDir = getenv("YOINK_DATADIR");
80
81 if (dataDir)
82 {
83 dc::resource::addSearchPath(dataDir);
84 }
85
86 dc::resource::addSearchPath(YOINK_DATADIR);
87
88 dc::dispatcher::instance().addHandler("video.context_recreated",
89 boost::bind(&YoinkApp::contextRecreated, this, _1), this);
90 setupGL();
91
92 state = 0.0;
93
94 someChar = new Character("RobotTrooper");
95 someChar->getAnimation().startSequence("Run");
96
97 font = new TilemapFont;
98
99 dc::vector2 coeffs[4];
100 coeffs[0] = dc::vector2(0.0, 0.0);
101 coeffs[1] = dc::vector2(0.5, 0.0);
102 coeffs[2] = dc::vector2(0.5, 0.0);
103 coeffs[3] = dc::vector2(1.0, 0.0);
104 interp.init(coeffs, 1.0, dc::interpolator::oscillate);
105
106 dc::scalar coeff[2] = {1.0, 0.0};
107 fadeIn.init(coeff, 0.5f);
108
109 testScene = new dc::scene("Test");
110 }
111
112 YoinkApp::~YoinkApp()
113 {
114 delete someChar;
115 delete font;
116
117 dc::dispatcher::instance().removeHandler(this);
118
119 std::cout << "Goodbye..." << std::endl;
120 }
121
122
123 void YoinkApp::setupGL()
124 {
125 glEnable(GL_TEXTURE_2D);
126 //glEnable(GL_CULL_FACE);
127 glEnable(GL_DEPTH_TEST);
128
129 glShadeModel(GL_SMOOTH);
130
131 //glEnable(GL_BLEND);
132 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
133 glEnable(GL_ALPHA_TEST);
134 glAlphaFunc(GL_GREATER, 0.0);
135
136 glClearColor(0.0, 0.0, 1.0, 1.0);
137
138 glLineWidth(10.0f);
139 }
140
141 void YoinkApp::contextRecreated(const dc::notification& note)
142 {
143 // Whenever the context and a new one created, it probably won't contain our
144 // state so we need to set that up again.
145 setupGL();
146 }
147
148
149 void YoinkApp::update(dc::scalar t, dc::scalar dt)
150 {
151 //dt *= 0.2;
152
153 fadeIn.update(dt);
154
155 someChar->getAnimation().update(t, dt);
156 interp.update(dt);
157
158 prevstate = state;
159 state += dt;
160 }
161
162
163 void YoinkApp::draw(dc::scalar alpha)
164 {
165 dc::vector4 meh;
166 meh.random(0.0, 1.0);
167 static dc::vector4 c1(meh);
168
169 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
170
171 dc::scalar drawstate = cml::lerp(prevstate, state, alpha);
172 dc::scalar sinstate = std::sin(drawstate);
173 dc::scalar cosstate = std::cos(drawstate);
174
175
176 // DRAW THE SCENE
177 testScene->draw(alpha);
178
179
180 someChar->getTilemap().bind();
181 glColor3f(1.0, 1.0, 1.0);
182
183 unsigned heroFrame = someChar->getAnimation().getFrame();
184
185 float coords[8];
186 someChar->getTilemap().getTileCoords(heroFrame, coords);
187
188 glBegin(GL_QUADS);
189 glTexCoord2f(coords[0], coords[1]);
190 glVertex3f(-1.0, 0.0, 0.0);
191 glTexCoord2f(coords[2], coords[3]);
192 glVertex3f(0.0, 0.0, 0.0);
193 glTexCoord2f(coords[4], coords[5]);
194 glVertex3f(0.0, 1.0, 0.0);
195 glTexCoord2f(coords[6], coords[7]);
196 glVertex3f(-1.0, 1.0, 0.0);
197 glEnd();
198
199
200 someChar->getTilemap().getTileCoords(heroFrame, coords,
201 dc::tilemap::reverse);
202
203 glBegin(GL_QUADS);
204 glTexCoord2f(coords[0], coords[1]);
205 glVertex3f(0.0, 0.0, 0.0);
206 glTexCoord2f(coords[2], coords[3]);
207 glVertex3f(1.0, 0.0, 0.0);
208 glTexCoord2f(coords[4], coords[5]);
209 glVertex3f(1.0, 1.0, 0.0);
210 glTexCoord2f(coords[6], coords[7]);
211 glVertex3f(0.0, 1.0, 0.0);
212 glEnd();
213
214 glColor4f(1.0,0.0,0.0,0.5);
215
216 glBindTexture(GL_TEXTURE_2D, 0);
217 glColor4fv(c1.data());
218
219 glRectd(-cosstate, -sinstate, sinstate, cosstate);
220 glRectf(0.0f, 0.0f, sinstate, cosstate);
221
222 font->bind();
223
224 font->getTileCoords('c', coords);
225
226 glBegin(GL_QUADS);
227 glTexCoord2f(coords[0], coords[1]);
228 glVertex3f(-1.0, 0.0, 0.0);
229 glTexCoord2f(coords[2], coords[3]);
230 glVertex3f(0.0, 0.0, 0.0);
231 glTexCoord2f(coords[4], coords[5]);
232 glVertex3f(0.0, 1.0, 0.0);
233 glTexCoord2f(coords[6], coords[7]);
234 glVertex3f(-1.0, 1.0, 0.0);
235 glEnd();
236
237 font->getTileCoords('h', coords);
238
239 glBegin(GL_QUADS);
240 glTexCoord2f(coords[0], coords[1]);
241 glVertex3f(0.0, 0.0, 0.0);
242 glTexCoord2f(coords[2], coords[3]);
243 glVertex3f(1.0, 0.0, 0.0);
244 glTexCoord2f(coords[4], coords[5]);
245 glVertex3f(1.0, 1.0, 0.0);
246 glTexCoord2f(coords[6], coords[7]);
247 glVertex3f(0.0, 1.0, 0.0);
248 glEnd();
249
250 font->getTileCoords('a', coords);
251
252 glBegin(GL_QUADS);
253 glTexCoord2f(coords[0], coords[1]);
254 glVertex3f(-1.0, -1.0, 0.0);
255 glTexCoord2f(coords[2], coords[3]);
256 glVertex3f(0.0, -1.0, 0.0);
257 glTexCoord2f(coords[4], coords[5]);
258 glVertex3f(0.0, 0.0, 0.0);
259 glTexCoord2f(coords[6], coords[7]);
260 glVertex3f(-1.0, 0.0, 0.0);
261 glEnd();
262
263 font->getTileCoords('z', coords);
264
265 glBegin(GL_QUADS);
266 glTexCoord2f(coords[0], coords[1]);
267 glVertex3f(0.0, -1.0, 0.0);
268 glTexCoord2f(coords[2], coords[3]);
269 glVertex3f(1.0, -1.0, 0.0);
270 glTexCoord2f(coords[4], coords[5]);
271 glVertex3f(1.0, 0.0, 0.0);
272 glTexCoord2f(coords[6], coords[7]);
273 glVertex3f(0.0, 0.0, 0.0);
274 glEnd();
275
276 glEnable(GL_BLEND);
277 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
278 glDisable(GL_DEPTH_TEST);
279
280 glBindTexture(GL_TEXTURE_2D, 0);
281 glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
282
283 glBegin(GL_LINES);
284 glVertex2f(0.0f, 0.0f);
285 glVertex2fv(interp.getState(alpha).data());
286 glEnd();
287
288 glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
289 glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
290
291 glDisable(GL_BLEND);
292 glEnable(GL_DEPTH_TEST);
293 }
294
295 void YoinkApp::handleEvent(const dc::event& e)
296 {
297 switch (e.type)
298 {
299 case SDL_KEYDOWN:
300 if (e.key.keysym.sym == SDLK_ESCAPE)
301 {
302 stop();
303 }
304 else if (e.key.keysym.sym == SDLK_f)
305 {
306 getVideo().toggleFull();
307 }
308 else if (e.key.keysym.sym == SDLK_a)
309 {
310 someChar->getAnimation().startSequence("Punch");
311 }
312 break;
313
314 case SDL_QUIT:
315 stop();
316 break;
317
318 case SDL_VIDEORESIZE:
319 glViewport(0, 0, e.resize.w, e.resize.h);
320 break;
321 }
322 }
323
324
325
326 int main(int argc, char* argv[])
327 {
328 YoinkApp app(argc, argv);
329 return app.run();
330 }
331
332 /** vim: set ts=4 sw=4 tw=80: *************************************************/
333
This page took 0.044532 seconds and 4 git commands to generate.