1 /*=============================================================================
2 Blobby Volley 2
3 Copyright (C) 2006 Jonathan Sieber (jonathan_sieber@yahoo.de)
4 Copyright (C) 2006 Daniel Knobe (daniel-knobe@web.de)
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 =============================================================================*/
20 
21 /* header include */
22 #include "ReplayState.h"
23 
24 /* includes */
25 #include <sstream>
26 
27 #include "IMGUI.h"
28 #include "ReplayPlayer.h"
29 #include "DuelMatch.h"
30 #include "SoundManager.h"
31 #include "TextManager.h"
32 #include "SpeedController.h"
33 #include "IUserConfigReader.h"
34 #include "ReplaySelectionState.h"
35 #include "InputManager.h"
36 
37 /* implementation */
38 
39 extern const std::string DUMMY_RULES_NAME;
40 
ReplayState()41 ReplayState::ReplayState()
42 {
43 	IMGUI::getSingleton().resetSelection();
44 
45 	mPositionJump = -1;
46 	mPaused = false;
47 
48 	mSpeedValue = 8;
49 	mSpeedTimer = 0;
50 }
51 
~ReplayState()52 ReplayState::~ReplayState()
53 {
54 
55 }
56 
loadReplay(const std::string & file)57 void ReplayState::loadReplay(const std::string& file)
58 {
59 	mReplayPlayer.reset( new ReplayPlayer() );
60 
61 	//try
62 	//{
63 		mReplayPlayer->load(std::string("replays/" + file + ".bvr"));
64 		mMatch.reset(new DuelMatch(false, DUMMY_RULES_NAME));
65 
66 		SoundManager::getSingleton().playSound(
67 				"sounds/pfiff.wav", ROUND_START_SOUND_VOLUME);
68 
69 		mMatch->setPlayers(mReplayPlayer->getPlayerName(LEFT_PLAYER), mReplayPlayer->getPlayerName(RIGHT_PLAYER));
70 
71 		mMatch->getPlayer(LEFT_PLAYER).setStaticColor(mReplayPlayer->getBlobColor(LEFT_PLAYER));
72 		mMatch->getPlayer(RIGHT_PLAYER).setStaticColor(mReplayPlayer->getBlobColor(RIGHT_PLAYER));
73 
74 		SpeedController::getMainInstance()->setGameSpeed(
75 				(float)IUserConfigReader::createUserConfigReader("config.xml")->getInteger("gamefps")
76 			);
77 
78 	//}
79 	/*catch (ChecksumException& e)
80 	{
81 		delete mReplayRecorder;
82 		mReplayRecorder = 0;
83 		mChecksumError = true;
84 	}
85 	catch (VersionMismatchException& e)
86 	{
87 		delete mReplayRecorder;
88 		mReplayRecorder = 0;
89 		mVersionError = true;
90 	}*/
91 	/// \todo reintroduce error handling
92 }
93 
step_impl()94 void ReplayState::step_impl()
95 {
96 	IMGUI& imgui = IMGUI::getSingleton();
97 
98 	// only draw cursor when mouse moved or clicked in the last second
99 	if(mLastMousePosition != InputManager::getSingleton()->position() || InputManager::getSingleton()->click())
100 	{
101 		/// \todo we must do this framerate independent
102 		mMouseShowTimer = 75;
103 	}
104 
105 	if(mMouseShowTimer > 0)
106 	{
107 		imgui.doCursor();
108 		mMouseShowTimer--;
109 	}
110 
111 	mLastMousePosition = InputManager::getSingleton()->position();
112 
113 
114 	if(mPositionJump != -1)
115 	{
116 		if(mReplayPlayer->gotoPlayingPosition(mPositionJump, mMatch.get()))
117 			mPositionJump = -1;
118 	}
119 	 else if(!mPaused)
120 	{
121 		while( mSpeedTimer >= 8)
122 		{
123 			mPaused = !mReplayPlayer->play(mMatch.get());
124 			mSpeedTimer -= 8;
125 			presentGame();
126 		}
127 		mSpeedTimer += mSpeedValue;
128 
129 	}
130 
131 	mMatch->getClock().setTime( mReplayPlayer->getReplayPosition() / mReplayPlayer->getGameSpeed() );
132 
133 	// draw the progress bar
134 	Vector2 prog_pos = Vector2(50, 600-22);
135 	imgui.doOverlay(GEN_ID, prog_pos, Vector2(750, 600-3), Color(0,0,0));
136 	imgui.doOverlay(GEN_ID, prog_pos, Vector2(700*mReplayPlayer->getPlayProgress()+50, 600-3), Color(0,255,0));
137 
138 	PlayerSide side = NO_PLAYER;
139 	if (mReplayPlayer->endOfFile())
140 	{
141 		int diff = mMatch->getScore(LEFT_PLAYER) - mMatch->getScore(RIGHT_PLAYER);
142 		if (diff > 0)
143 		{
144 			side = LEFT_PLAYER;
145 		}
146 		else if (diff < 0)
147 		{
148 			side = RIGHT_PLAYER;
149 		}
150 	}
151 
152 	// play/pause button
153 	imgui.doOverlay(GEN_ID, Vector2(350, 535.0), Vector2(450, 575.0));
154 	bool pause_click = imgui.doImageButton(GEN_ID, Vector2(400, 555), Vector2(24, 24), mPaused ? "gfx/btn_play.bmp" : "gfx/btn_pause.bmp");
155 	bool fast_click = imgui.doImageButton(GEN_ID, Vector2(430, 555), Vector2(24, 24),  "gfx/btn_fast.bmp");
156 	bool slow_click = imgui.doImageButton(GEN_ID, Vector2(370, 555), Vector2(24, 24),  "gfx/btn_slow.bmp");
157 
158 	// handle these image buttons. IMGUI is not capable of doing this.
159 	if(side == NO_PLAYER)
160 	{
161 		// control replay position
162 		Vector2 mousepos = InputManager::getSingleton()->position();
163 		if (mousepos.x + 5 > prog_pos.x && mousepos.y > prog_pos.y &&
164 			mousepos.x < prog_pos.x + 700 && mousepos.y < prog_pos.y + 24.0)
165 		{
166 
167 			if (InputManager::getSingleton()->click())
168 			{
169 				float pos = (mousepos.x - prog_pos.x) / 700.0;
170 				mPositionJump = pos * mReplayPlayer->getReplayLength();
171 			}
172 		}
173 
174 		if (pause_click)
175 		{
176 			if(mPaused)
177 			{
178 				if(mReplayPlayer->endOfFile())
179 					mPositionJump = 0;
180 			}
181 			mPaused = !mPaused;
182 		}
183 
184 		if (fast_click)
185 		{
186 			mSpeedValue *= 2;
187 			if(mSpeedValue > 64)
188 				mSpeedValue = 64;
189 		}
190 
191 		if (slow_click)
192 		{
193 			mSpeedValue /= 2;
194 			if(mSpeedValue < 1)
195 				mSpeedValue = 1;
196 		}
197 
198 		if ((InputManager::getSingleton()->exit()))
199 		{
200 			switchState(new ReplaySelectionState());
201 			return;
202 		}
203 	}
204 	else
205 	{
206 		displayWinningPlayerScreen(side);
207 
208 		if (imgui.doButton(GEN_ID, Vector2(290, 350), TextManager::LBL_OK))
209 		{
210 			switchState(new ReplaySelectionState());
211 			return;
212 		}
213 		if (imgui.doButton(GEN_ID, Vector2(400, 350), TextManager::RP_SHOW_AGAIN))
214 		{
215 			// we don't have to reset the match, cause we don't use lua rules
216 			// we just have to jump to the beginning
217 			SoundManager::getSingleton().playSound(
218 					"sounds/pfiff.wav", ROUND_START_SOUND_VOLUME);
219 
220 			// do we really need this?
221 			// maybe, users want to replay the game on the current speed
222 			SpeedController::getMainInstance()->setGameSpeed(
223 					(float)IUserConfigReader::createUserConfigReader("config.xml")->getInteger("gamefps")
224 				);
225 
226 			mPaused = false;
227 			mPositionJump = 0;
228 		}
229 		imgui.doCursor();
230 	}
231 
232 	// show the game ui
233 	presentGameUI();
234 }
235 
getStateName() const236 const char* ReplayState::getStateName() const
237 {
238 	return "ReplayState";
239 }
240 
241