1 /* --------------------------------------------------------------------
2 EXTREME TUXRACER
3 
4 Copyright (C) 1999-2001 Jasmin F. Patry (Tuxracer)
5 Copyright (C) 2010 Extreme Tux Racer Team
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 ---------------------------------------------------------------------*/
17 
18 #ifdef HAVE_CONFIG_H
19 #include <etr_config.h>
20 #endif
21 
22 #include "tool_frame.h"
23 #include "tools.h"
24 #include "ogl.h"
25 #include "keyframe.h"
26 #include "font.h"
27 #include "textures.h"
28 #include "spx.h"
29 #include "tux.h"
30 #include "winsys.h"
31 
32 static std::size_t curr_frame = 0;
33 static int curr_joint = 0;
34 static int last_joint = 0;
35 static TVector3d ref_position(0, 0, 0);
36 static bool must_render = true;
37 static int framebase = 24;
38 static int jointbase = 16;
39 static bool shift = false;
40 static bool control = false;
41 static bool alt = false;
42 static bool lastframe = 0;
43 static bool keyrun = false;
44 
InitFrameTools()45 void InitFrameTools() {
46 	framebase = (int)((Winsys.resolution.height - 350) / 18);
47 	if (TestFrame.numFrames() < 1) TestFrame.AddFrame();
48 	curr_joint = 0;
49 	last_joint = TestFrame.GetNumJoints() -1;
50 }
51 
SingleFrameKeys(sf::Keyboard::Key key,bool release,int x,int y)52 void SingleFrameKeys(sf::Keyboard::Key key, bool release, int x, int y) {
53 //PrintInt (key);
54 	must_render = true;
55 	int keyfact;
56 	lastframe = TestFrame.numFrames() != 1;
57 	TKeyframe *frame = TestFrame.GetFrame(curr_frame);
58 
59 	// setting the camera change state
60 	if (key == sf::Keyboard::F1) {GluCamera.turnright = !release; return;}
61 	else if (key == sf::Keyboard::F2) { GluCamera.turnleft = !release; return; }
62 	if (key == sf::Keyboard::F3) { GluCamera.nearer = !release; return; }
63 	else if (key == sf::Keyboard::F4) { GluCamera.farther = !release; return; }
64 
65 	// additional keys if needed
66 	if (key == sf::Keyboard::LShift || key == sf::Keyboard::RShift) shift = !release;
67 	if (key == sf::Keyboard::LControl) control = !release;
68 	if (key == sf::Keyboard::LAlt) alt = !release;
69 	if (shift) keyfact = -1;
70 	else keyfact = 1;
71 
72 	if (release) return;
73 
74 	switch (key) {
75 		case sf::Keyboard::Y:
76 		case sf::Keyboard::J:
77 			if (ToolsFinalStage()) {
78 				SaveToolCharacter();
79 				SaveToolFrame();
80 				State::manager.RequestQuit();
81 			}
82 			break;
83 		case sf::Keyboard::N:
84 			if (ToolsFinalStage()) State::manager.RequestQuit();
85 			break;
86 
87 		case sf::Keyboard::Escape:
88 		case sf::Keyboard::Q:
89 			QuitTool();
90 			break;
91 		case sf::Keyboard::S:
92 			SaveToolFrame();
93 			break;
94 		case sf::Keyboard::Tab:
95 			SetToolMode(0);
96 			break;
97 
98 		case sf::Keyboard::A:
99 			TestFrame.AddFrame();
100 			SetFrameChanged(true);
101 			break;
102 		case sf::Keyboard::Insert:
103 			TestFrame.InsertFrame(curr_frame);
104 			SetFrameChanged(true);
105 			break;
106 		case sf::Keyboard::Delete:
107 			curr_frame = TestFrame.DeleteFrame(curr_frame);
108 			SetFrameChanged(true);
109 			break;
110 		case sf::Keyboard::PageDown:
111 			if (curr_frame < TestFrame.numFrames()-1) curr_frame++;
112 			break;
113 		case sf::Keyboard::PageUp:
114 			if (curr_frame > 0) curr_frame--;
115 			break;
116 		case sf::Keyboard::Up:
117 			if (curr_joint > 0) curr_joint--;
118 			break;
119 		case sf::Keyboard::Down:
120 			if (curr_joint < last_joint) curr_joint++;
121 			break;
122 		case sf::Keyboard::Right:
123 			if (curr_joint < 4) frame->val[curr_joint] += 0.05;
124 			else frame->val[curr_joint] += 1;
125 			SetFrameChanged(true);
126 			break;
127 		case sf::Keyboard::Left:
128 			if (curr_joint < 4) frame->val[curr_joint] -= 0.05;
129 			else frame->val[curr_joint] -= 1;
130 			SetFrameChanged(true);
131 			break;
132 		case sf::Keyboard::Num0:
133 			frame->val[curr_joint] = 0.0;
134 			SetFrameChanged(true);
135 			break;
136 		case sf::Keyboard::Space:
137 			if (curr_joint < 4) frame->val[curr_joint] += 0.05 * keyfact;
138 			else frame->val[curr_joint] += 1 * keyfact;
139 			SetFrameChanged(true);
140 			break;
141 
142 		case sf::Keyboard::Return:
143 			TestFrame.InitTest(ref_position, &TestChar);
144 			SetToolMode(2);
145 			must_render = true;
146 			break;
147 
148 		case sf::Keyboard::M :
149 			TestChar.useMaterials = !TestChar.useMaterials;
150 			break;
151 		case sf::Keyboard::H:
152 			TestChar.useHighlighting = !TestChar.useHighlighting;
153 			break;
154 		case sf::Keyboard::C:
155 			if (control) TestFrame.CopyToClipboard(curr_frame);
156 			else TestFrame.ClearFrame(curr_frame);
157 			SetFrameChanged(true);
158 			break;
159 		case sf::Keyboard::V:
160 			if (control) TestFrame.PasteFromClipboard(curr_frame);
161 			SetFrameChanged(true);
162 			break;
163 		case sf::Keyboard::P:
164 			if (curr_frame>0)
165 				TestFrame.CopyFrame(curr_frame-1, curr_frame);
166 			break;
167 		case sf::Keyboard::F10:
168 			Winsys.TakeScreenshot();
169 			break;
170 
171 		case sf::Keyboard::Num1:
172 			GluCamera.angle = 0;
173 			break;
174 		case sf::Keyboard::Num2:
175 			GluCamera.angle = 45;
176 			break;
177 		case sf::Keyboard::Num3:
178 			GluCamera.angle = 90;
179 			break;
180 		case sf::Keyboard::Num4:
181 			GluCamera.angle = 135;
182 			break;
183 		case sf::Keyboard::Num5:
184 			GluCamera.angle = 180;
185 			break;
186 		case sf::Keyboard::Num6:
187 			GluCamera.angle = 225;
188 			break;
189 		case sf::Keyboard::Num7:
190 			GluCamera.angle = 270;
191 			break;
192 		case sf::Keyboard::Num8:
193 			GluCamera.angle = 315;
194 			break;
195 		default:
196 			break;
197 	}
198 }
199 
SingleFrameMouse(int button,int state,int x,int y)200 void SingleFrameMouse(int button, int state, int x, int y) {
201 	must_render = true;
202 	if (ToolsFinalStage()) return;
203 
204 	if (button == 4) {
205 		GluCamera.distance += 0.1;
206 	} else if (button == 5) {
207 		GluCamera.distance -= 0.1;
208 	}
209 }
210 
SingleFrameMotion(int x,int y)211 void SingleFrameMotion(int x, int y) {
212 }
213 
PrintFrameParams(int ytop,TKeyframe * frame)214 void PrintFrameParams(int ytop, TKeyframe *frame) {
215 	int offs = 18;
216 
217 	for (int i=0; i<=last_joint; i++) {
218 		if (i == curr_joint) FT.SetColor(colYellow);
219 		else FT.SetColor(colLGrey);
220 
221 		int x = ITrunc(i, jointbase) * 140 + 20;
222 		int y = IFrac(i, jointbase) * offs + ytop;
223 
224 		FT.DrawString(x, y, TestFrame.GetJointName(i));
225 		if (i < 4) FT.DrawString(x+80, y, Float_StrN(frame->val[i], 2));
226 		else FT.DrawString(x+80, y, Int_StrN((int)frame->val[i]));
227 	}
228 }
229 
RenderSingleFrame(float timestep)230 void RenderSingleFrame(float timestep) {
231 	if (!must_render) return;
232 
233 	// ------------------ 3d scenery ----------------------------------
234 	ScopedRenderMode rm1(TUX);
235 	ClearRenderContext(colDDBackgr);
236 
237 	const std::string& hlname = TestFrame.GetHighlightName(curr_joint);
238 	TestChar.highlight_node = TestChar.GetNodeName(hlname);
239 
240 	glPushMatrix();
241 	SetToolLight();
242 	GluCamera.Update(timestep);
243 
244 	TestFrame.CalcKeyframe(curr_frame, &TestChar, ref_position);
245 	TestChar.Draw();
246 	glPopMatrix();
247 
248 	// ----------------- 2d screen ------------------------------------
249 	Setup2dScene();
250 	ScopedRenderMode rm2(TEXFONT);
251 
252 	if (FrameHasChanged()) DrawChanged();
253 
254 	FT.SetProps("bold", 20, colYellow);
255 	FT.DrawString(-1, 10, "Keyframe mode");
256 
257 	FT.SetProps("normal", 16);
258 	for (std::size_t i=0; i<TestFrame.numFrames(); i++) {
259 		if (i != curr_frame) {
260 			FT.SetColor(colLGrey);
261 			FT.SetFont("normal");
262 		} else {
263 			FT.SetColor(colYellow);
264 			FT.SetFont("bold");
265 		}
266 		int xl = ITrunc((int)i, framebase) * 100 + 20;
267 		int yt = IFrac((int)i, framebase) * 18 + 20;
268 		FT.DrawString(xl, yt, Int_StrN((int)i));
269 	}
270 
271 	FT.SetFont("normal");
272 	FT.SetColor(colLGrey);
273 	PrintFrameParams(Winsys.resolution.height - 330, TestFrame.GetFrame(curr_frame));
274 
275 	if (ToolsFinalStage()) {
276 		FT.SetSize(20);
277 		FT.SetColor(colYellow);
278 		FT.DrawString(-1, Winsys.resolution.height - 50, "Quit program. Save character list (y/n)");
279 	}
280 
281 	Reshape(Winsys.resolution.width, Winsys.resolution.height);
282 	Winsys.SwapBuffers();
283 	must_render = false;
284 }
285 
286 
287 // --------------------------------------------------------------------
288 //				frame sequence
289 // --------------------------------------------------------------------
290 
SequenceKeys(sf::Keyboard::Key key,bool release,int x,int y)291 void SequenceKeys(sf::Keyboard::Key key, bool release, int x, int y) {
292 	if (release) return;
293 	switch (key) {
294 		case sf::Keyboard::Return:
295 			keyrun = true;
296 			break;
297 		case sf::Keyboard::Escape:
298 		case sf::Keyboard::Tab:
299 			SetToolMode(1);
300 			break;
301 		case sf::Keyboard::Q:
302 			QuitTool();
303 			break;
304 		default:
305 			break;
306 	}
307 }
308 
SequenceMouse(int button,int state,int x,int y)309 void SequenceMouse(int button, int state, int x, int y) {}
SequenceMotion(int x,int y)310 void SequenceMotion(int x, int y) {}
311 
RenderSequence(float timestep)312 void RenderSequence(float timestep) {
313 	ScopedRenderMode rm(TUX);
314 	ClearRenderContext(colDDBackgr);
315 
316 	GluCamera.Update(timestep);
317 	if (TestFrame.active) TestFrame.UpdateTest(timestep, &TestChar);
318 	else if (keyrun) {
319 		TestFrame.InitTest(NullVec3, &TestChar);
320 		keyrun = false;
321 	}
322 
323 	glPushMatrix();
324 	TestChar.Draw();
325 	glPopMatrix();
326 
327 	Reshape(Winsys.resolution.width, Winsys.resolution.height);
328 	Winsys.SwapBuffers();
329 }
330