]> Dogcows Code - chaz/yoink/blob - src/GameLayer.cc
8ff3a75a1cd5fecdb85144d2c7625ad5a7664731
[chaz/yoink] / src / GameLayer.cc
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #include "config.h"
13
14 #include <stdexcept>
15
16 #include <moof/log.hh>
17 #include <moof/math.hh>
18 #include <moof/mesh.hh>
19 #include <moof/opengl.hh>
20 #include <moof/settings.hh>
21 #include <moof/video.hh>
22
23 #include "GameLayer.hh"
24
25
26 void GameLayer::loadSceneLoader()
27 {
28 state_.script.import_safe_standard_libraries();
29 moof::log::import(state_.script);
30 moof::mesh::import(state_.script, "yoink");
31 moof::sound::import(state_.script, "yoink");
32
33 std::string path = moof::resource::find_file("scenes/loader.lua");
34 if (path.empty())
35 {
36 throw std::runtime_error("cannot find scene loader script");
37 }
38
39 moof::script::status status = state_.script.do_file(path);
40 if (status != moof::script::success)
41 {
42 std::string str;
43 state_.script[-1].get(str);
44 throw std::runtime_error("script error: " + str);
45 }
46
47 state_.script.globals().push_field("scenes");
48 state_.script.top().get(state_.sceneList);
49 if (state_.sceneList.size() == 0)
50 {
51 throw std::runtime_error("no variable `scenes' in script loader");
52 }
53 }
54
55 void GameLayer::advanceScene(moof::settings& settings)
56 {
57 if (state_.sceneList.size() != 0)
58 {
59 state_.scene = Scene::alloc(state_.sceneList[0]);
60 state_.sceneList.erase(state_.sceneList.begin());
61
62 moof::script::status status = state_.scene->load(settings,
63 state_.script);
64 if (status != moof::script::success)
65 {
66 std::string str;
67 state_.script[-1].get(str);
68 throw std::runtime_error("script error: " + str);
69 }
70
71 moof::script::slot table = state_.script.globals().push_field("Event");
72 if (table.is_table())
73 {
74 state_.script.push("Think");
75 table.push_field("Think");
76 state_.script.registry().set_field();
77 }
78 state_.script.pop();
79
80 table = state_.script.globals().push_field("Event");
81 if (table.is_table())
82 {
83 table.push_field("Draw");
84 state_.script.registry().set_field("Draw");
85 }
86 state_.script.pop();
87 }
88 }
89
90
91 GameLayer::GameLayer()
92 {
93 music_.sample("NightFusionIntro.ogg");
94 music_.loop(true);
95 music_.enqueue("NightFusionLoop.ogg");
96 music_.position(moof::vector3(10.0, 5.0, 0.0));
97
98 punch_sound_.sample("RobotPunch");
99
100 state_.heroine = Heroine::alloc();
101 state_.heroine->animation.startSequence("FlyDiagonallyUp");
102
103 state_.interp.init(0.0, 1.0, 4.0, moof::lerp_scalar::oscillate);
104 }
105
106
107 void GameLayer::did_add_to_view()
108 {
109 bool isMute = false;
110 settings().get("nomusic", isMute);
111 music_.play();
112
113 loadSceneLoader();
114 advanceScene(settings()); // load the first scene
115
116 mHud = Hud::alloc(state_);
117 add_child(mHud);
118
119 mRay.direction.set(1.0, 0.0);
120
121 mLine.a.set(20, 10);
122 mLine.b.set(19, 14);
123
124 mCircle.point.set(22, 5);
125 mCircle.radius = 2;
126
127 mRayTimer.init(boost::bind(&GameLayer::rayTimer, this),
128 1.0, moof::timer::repeat);
129
130 projection();
131 }
132
133
134 void GameLayer::update(moof::scalar t, moof::scalar dt)
135 {
136 if (!state_.scene) return;
137 state_.camera.update(t, dt);
138 state_.heroine->update(t, dt);
139
140 state_.scene->checkForCollision(*state_.heroine);
141
142 moof::vector3 cam= -moof::promote(state_.heroine->state().position, 8);
143 state_.camera.position(cam);
144
145 mRay.point = state_.heroine->state().position;
146
147 state_.script.registry().push_field("Think");
148 if (state_.script[-1].is_function()) state_.script.call();
149 else state_.script.pop();
150
151 moof::view::update(t, dt);
152 }
153
154 void GameLayer::rayTimer()
155 {
156 moof::ray2::contact meh;
157 std::list<moof::ray2::contact> hits;
158 moof::vector2 point;
159
160 bool bam = mLine.intersect_ray(mRay, meh);
161 if (bam)
162 {
163 //meh.normal.normalize();
164 //hits.push_back(meh);
165 mRay.solve(point, meh.distance);
166 moof::log_info << "line: d = " << meh.distance << std::endl;
167 moof::log_info << " P = " << point << std::endl;
168 moof::log_info << " n = " << meh.normal << std::endl;
169 }
170
171 bam = mCircle.intersect_ray(mRay, meh);
172 if (bam)
173 {
174 meh.normal.normalize();
175 hits.push_back(meh);
176 }
177
178 if (state_.scene->castRay(mRay, hits))
179 {
180 hits.front().normal.normalize();
181 mRay.solve(point, hits.front().distance);
182 moof::log_info << "scene: d = " << hits.front().distance << std::endl;
183 moof::log_info << " P = " << point << std::endl;
184 moof::log_info << " n = " << hits.front().normal << std::endl;
185 }
186 }
187
188
189 void GameLayer::draw(moof::scalar alpha) const
190 {
191 if (!state_.scene) return;
192 state_.camera.upload_to_gl(alpha);
193
194 float pos[] = {state_.heroine->state().position[0],
195 state_.heroine->state().position[1], 0.0f, 1.0f};
196 glLightfv(GL_LIGHT0, GL_POSITION, pos);
197
198 // DRAW THE SCENE
199 moof::image::reset_binding();
200
201 glEnableClientState(GL_VERTEX_ARRAY);
202 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
203
204 //state_.scene->draw_if_visible(alpha, state_.camera.frustum());
205
206 size_t meh = 23;
207 state_.script.push(meh);
208 state_.script.pop();
209
210 state_.script.registry().push_field("Draw");
211 if (state_.script[-1].is_function())
212 {
213 moof::script::status result = state_.script.call();
214 if (result != moof::script::success)
215 {
216 std::string str;
217 state_.script[-1].get(str);
218 throw std::runtime_error("script error: " + str);
219 }
220 }
221 else state_.script.pop();
222
223 state_.heroine->draw(alpha);
224
225 mRay.draw();
226 mLine.draw();
227 mCircle.draw();
228
229 moof::view::draw(alpha);
230 }
231
232 bool GameLayer::handle_event(const moof::event& event)
233 {
234 if (moof::view::handle_event(event)) return true;
235
236 switch (event.type)
237 {
238 case SDL_KEYDOWN:
239 if (event.key.keysym.sym == SDLK_SPACE)
240 {
241 state_.heroine->animation.startSequence("Flattened");
242 moof::log_info("thump!");
243 punch_sound_.play();
244 return true;
245 }
246 else if (event.key.keysym.sym == SDLK_m)
247 {
248 music_.toggle();
249 return true;
250 }
251 else if (event.key.keysym.sym == SDLK_PAGEUP)
252 {
253 mRay.direction = moof::rotate_vector_2D(mRay.direction,
254 moof::rad(10.0));
255 return true;
256 }
257 else if (event.key.keysym.sym == SDLK_PAGEDOWN)
258 {
259 mRay.direction = moof::rotate_vector_2D(mRay.direction,
260 moof::rad(-10.0));
261 return true;
262 }
263 else if (event.key.keysym.sym == SDLK_r)
264 {
265 loadSceneLoader();
266 advanceScene(settings());
267 return true;
268 }
269 return state_.heroine->handle_event(event);
270
271 case SDL_KEYUP:
272 if (event.key.keysym.sym == SDLK_ESCAPE)
273 {
274 parent().remove_child(this);
275 return true;
276 }
277 else if (event.key.keysym.sym == SDLK_h)
278 {
279 add_child(mHud);
280 return true;
281 }
282 return state_.heroine->handle_event(event);
283
284 case SDL_MOUSEMOTION:
285 case SDL_MOUSEBUTTONDOWN:
286 state_.camera.handle_event(event);
287 return true;
288
289 case SDL_VIDEORESIZE:
290 projection(event.resize.w, event.resize.h);
291 break;
292 }
293
294 return false;
295 }
296
297
298 void GameLayer::projection()
299 {
300 projection(video().width(), video().height());
301 }
302
303 void GameLayer::projection(moof::scalar width, moof::scalar height)
304 {
305 state_.camera.projection(moof::rad(60.0),
306 width / height,
307 SCALAR(1.0), SCALAR(200.0));
308 }
309
This page took 0.048192 seconds and 3 git commands to generate.