]> Dogcows Code - chaz/yoink/blob - src/GameLayer.cc
3f5a7a869fb2dd8d13e6da4671d82f78d474f47d
[chaz/yoink] / src / GameLayer.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 <Moof/Engine.hh>
30 #include <Moof/Exception.hh>
31 #include <Moof/Log.hh>
32 #include <Moof/Math.hh>
33 #include <Moof/OpenGL.hh>
34 #include <Moof/Settings.hh>
35 #include <Moof/Video.hh>
36
37 #include "GameLayer.hh"
38 #include "Hud.hh"
39
40 #if HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44
45
46 Mf::Scalar GameLayer::getZCoord(const Mf::Vector2& position) const
47 {
48 Mf::Scalar z;
49
50 mState.script.getGlobalTable().pushField("GetZCoord");
51 mState.script.push(position[0]);
52 mState.script.push(position[1]);
53 mState.script.call(2, 1);
54 mState.script.getTop().get(z);
55 mState.script.pop();
56
57 return z;
58 }
59
60 void GameLayer::loadSceneLoader()
61 {
62 mState.script.importStandardLibraries();
63 importLogPrintFunction(mState.script);
64
65 std::string loaderPath = Scene::getPath("loader");
66 if (loaderPath == "")
67 {
68 throw Mf::Exception(Mf::ErrorCode::RESOURCE_NOT_FOUND, "loader");
69 }
70
71 Mf::Script::Result status = mState.script.doFile(loaderPath);
72 if (status != Mf::Script::SUCCESS)
73 {
74 std::string str;
75 mState.script[-1].get(str);
76
77 throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str);
78 }
79
80 mState.script.getGlobalTable().pushField("scenes");
81 mState.script.getTop().get(mState.sceneList);
82 if (mState.sceneList.size() == 0)
83 {
84 throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR,
85 "no variable `scenes' within loader");
86 }
87 }
88
89 void GameLayer::advanceScene()
90 {
91 if (mState.sceneList.size() != 0)
92 {
93 mState.scene = Scene::alloc(mState.sceneList[0]);
94 mState.sceneList.erase(mState.sceneList.begin());
95
96 Mf::Script::Result status = mState.scene->load(mState.script);
97 if (status != Mf::Script::SUCCESS)
98 {
99 std::string str;
100 mState.script[-1].get(str);
101
102 throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str);
103 }
104 }
105 }
106
107
108 GameLayer::GameLayer() :
109 mMusic("NightFusionIntro"),
110 mPunchSound("Thump")
111 {
112 mMusic.setLooping(true);
113 mMusic.enqueue("NightFusionLoop");
114
115 bool isMute = false;
116 Mf::Settings::getInstance().get("nomusic", isMute);
117 if (!isMute) mMusic.play();
118
119 //mMusic.setPosition(Mf::Vector3(10.0, 5.0, 0.0));
120
121 loadSceneLoader();
122 advanceScene(); // load the first scene
123
124 mState.heroine = Heroine::alloc();
125 mState.heroine->animation.startSequence("FlyDiagonallyUp");
126
127 Mf::Scalar a[6] = {0.0, 1.5, -0.5, 3.0, -2.0, 1.0};
128 mState.interp.init(a, 2.0, Mf::Interpolator::OSCILLATE);
129
130 setProjection();
131 }
132
133
134 void GameLayer::pushed(Mf::Engine& engine)
135 {
136 engine.push(Hud::alloc(mState));
137
138 mRay.direction.set(1.0, 0.0);
139
140 mLine.a.set(20, 10);
141 mLine.b.set(19, 14);
142
143 mSphere.point.set(22, 5);
144 mSphere.radius = 2;
145
146 mRayTimer.init(boost::bind(&GameLayer::rayTimer, this), 1.0, Mf::Timer::REPEAT);
147 }
148
149
150 void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
151 {
152 mState.camera.update(t, dt);
153 mState.heroine->update(t, dt);
154
155 mState.scene->checkForCollision(*mState.heroine);
156
157 mState.camera.setPosition(Mf::Vector3(-mState.heroine->getState().position[0],
158 -mState.heroine->getState().position[1], -9));
159 //mState.camera.lookAt(Mf::promote(mState.heroine->getState().position));
160
161 mRay.point = mState.heroine->getState().position;
162 }
163
164
165 void GameLayer::rayTimer()
166 {
167 Mf::Ray<2>::Intersection meh;
168 std::list<Mf::Ray<2>::Intersection> hits;
169 Mf::Vector2 point;
170
171 bool bam = mLine.intersectRay(mRay, meh);
172 if (bam)
173 {
174 meh.normal.normalize();
175 hits.push_back(meh);
176 }
177
178 bam = mSphere.intersectRay(mRay, meh);
179 if (bam)
180 {
181 meh.normal.normalize();
182 hits.push_back(meh);
183 }
184
185 if (mState.scene->castRay(mRay, hits))
186 {
187 hits.front().normal.normalize();
188 mRay.solve(point, hits.front().distance);
189 Mf::logDebug << "scene: d = " << hits.front().distance << std::endl;
190 Mf::logDebug << " P = " << point << std::endl;
191 Mf::logDebug << " n = " << hits.front().normal << std::endl;
192 }
193 }
194
195
196 void GameLayer::draw(Mf::Engine& engine, Mf::Scalar alpha) const
197 {
198 mState.camera.uploadToGL(alpha);
199
200 // DRAW THE SCENE
201 Mf::Texture::resetBind();
202
203 glEnableClientState(GL_VERTEX_ARRAY);
204 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
205
206 mState.scene->drawIfVisible(alpha, mState.camera.getFrustum());
207
208 mState.heroine->setZCoord(getZCoord(mState.heroine->getState().position));
209 mState.heroine->draw(alpha);
210
211 mRay.draw();
212 mLine.draw();
213 mSphere.draw();
214 }
215
216 bool GameLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event)
217 {
218 switch (event.type)
219 {
220 case SDL_KEYDOWN:
221 if (event.key.keysym.sym == SDLK_SPACE)
222 {
223 mState.heroine->animation.startSequence("Flattened");
224 Mf::logInfo("thump!");
225 mPunchSound.play();
226 return true;
227 }
228 else if (event.key.keysym.sym == SDLK_m)
229 {
230 mMusic.toggle();
231 return true;
232 }
233 else if (event.key.keysym.sym == SDLK_PAGEUP)
234 {
235 mRay.direction = cml::rotate_vector_2D(mRay.direction,
236 cml::rad(10.0));
237 return true;
238 }
239 else if (event.key.keysym.sym == SDLK_PAGEDOWN)
240 {
241 mRay.direction = cml::rotate_vector_2D(mRay.direction,
242 cml::rad(-10.0));
243 return true;
244 }
245 return mState.heroine->handleEvent(event);
246
247 case SDL_KEYUP:
248 if (event.key.keysym.sym == SDLK_ESCAPE)
249 {
250 engine.pop(this);
251 return true;
252 }
253 else if (event.key.keysym.sym == SDLK_h)
254 {
255 engine.push(Hud::alloc(mState));
256 return true;
257 }
258 return mState.heroine->handleEvent(event);
259
260 case SDL_MOUSEMOTION:
261 case SDL_MOUSEBUTTONDOWN:
262 mState.camera.handleEvent(event);
263 return true;
264
265 case SDL_VIDEORESIZE:
266 setProjection(event.resize.w, event.resize.h);
267 break;
268 }
269
270 return false;
271 }
272
273
274 void GameLayer::setProjection()
275 {
276 Mf::VideoP video = Mf::Engine::getInstance().getVideo();
277 setProjection(video->getWidth(), video->getHeight());
278 }
279
280 void GameLayer::setProjection(Mf::Scalar width, Mf::Scalar height)
281 {
282 mState.camera.setProjection(cml::rad(60.0), width / height, 1.0, 200.0);
283 }
284
285
286 /** vim: set ts=4 sw=4 tw=80: *************************************************/
287
This page took 0.047387 seconds and 3 git commands to generate.