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