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 "ReplayPlayer.h"
23 
24 /* includes */
25 #include <cassert>
26 
27 #include "IReplayLoader.h"
28 #include "DuelMatch.h"
29 
30 /* implementation */
ReplayPlayer()31 ReplayPlayer::ReplayPlayer()
32 {
33 }
34 
~ReplayPlayer()35 ReplayPlayer::~ReplayPlayer()
36 {
37 }
38 
endOfFile() const39 bool ReplayPlayer::endOfFile() const
40 {
41 	return (mPosition >= mLength);
42 }
43 
load(const std::string & filename)44 void ReplayPlayer::load(const std::string& filename)
45 {
46 	loader.reset(IReplayLoader::createReplayLoader(filename));
47 
48 	mPlayerNames[LEFT_PLAYER] = loader->getPlayerName(LEFT_PLAYER);
49 	mPlayerNames[RIGHT_PLAYER] = loader->getPlayerName(RIGHT_PLAYER);
50 
51 	mPosition = 0;
52 	mLength = loader->getLength();
53 }
54 
getPlayerName(const PlayerSide side) const55 std::string ReplayPlayer::getPlayerName(const PlayerSide side) const
56 {
57 	return mPlayerNames[side];
58 }
59 
getBlobColor(const PlayerSide side) const60 Color ReplayPlayer::getBlobColor(const PlayerSide side) const
61 {
62 	return loader->getBlobColor(side);
63 }
64 
getGameSpeed() const65 int ReplayPlayer::getGameSpeed() const
66 {
67 	return loader->getSpeed();
68 }
69 
getPlayProgress() const70 float ReplayPlayer::getPlayProgress() const
71 {
72 	return (float)mPosition / mLength;
73 }
74 
getReplayPosition() const75 int ReplayPlayer::getReplayPosition() const
76 {
77 	return mPosition;
78 }
79 
getReplayLength() const80 int ReplayPlayer::getReplayLength() const
81 {
82 	return mLength;
83 }
84 
play(DuelMatch * virtual_match)85 bool ReplayPlayer::play(DuelMatch* virtual_match)
86 {
87 	mPosition++;
88 	if( mPosition < mLength )
89 	{
90 
91 		PlayerInput left;
92 		PlayerInput right;
93 		loader->getInputAt(mPosition, virtual_match->getInputSource( LEFT_PLAYER ).get(), virtual_match->getInputSource( RIGHT_PLAYER ).get() );
94 		virtual_match->step();
95 
96 		int point;
97 		if(loader->isSavePoint(mPosition, point))
98 		{
99 			ReplaySavePoint reference;
100 			loader->readSavePoint(point, reference);
101 			virtual_match->setState(reference.state);
102 		}
103 
104 
105 		// everything was as expected
106 		return true;
107 	}
108 
109 	// error or end of file
110 	return false;
111 }
112 
gotoPlayingPosition(int rep_position,DuelMatch * virtual_match)113 bool ReplayPlayer::gotoPlayingPosition(int rep_position, DuelMatch* virtual_match)
114 {
115 	/// \todo add validity check for rep_position
116 	/// \todo replay clock does not work!
117 
118 	// find next safepoint
119 	int save_position = -1;
120 	int savepoint = loader->getSavePoint(rep_position, save_position);
121 	// save position contains game step at which the save point is
122 	// savepoint is index of save point in array
123 
124 	// now compare safepoint and actual position
125 	// if we have to forward and save_position is nearer than current position, jump
126 	if( (rep_position < mPosition || save_position > mPosition) && savepoint >= 0)
127 	{
128 		// can't use mPosition
129 		// set match to safepoint
130 		ReplaySavePoint state;
131 		loader->readSavePoint(savepoint, state);
132 
133 		// set position and update match
134 		mPosition = save_position;
135 		virtual_match->setState(state.state);
136 	}
137 	// otherwise, use current position
138 
139 	// this is legacy code which will make fast forwarding possible even
140 	// when we have no safepoint and have to go back
141 	if(rep_position < mPosition)
142 	{
143 		// reset the match and simulate from start!
144 		virtual_match->reset();
145 		mPosition = 0;
146 	}
147 
148 	// in the end, simulate the remaining steps
149 	// maximum: 100 steps
150 	for(int i = 0; i < 100; ++i)
151 	{
152 		// check if we have to do another step
153 		if(endOfFile() || rep_position == mPosition)
154 			return true;
155 
156 		// do one play step
157 		play(virtual_match);
158 
159 	}
160 
161 	return false;
162 }
163