Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "client-game-logic.h"
00036
00037 #include "datahash/datahash_util.h"
00038 #include "gamepad/gamepad.h"
00039 #include "map-dynamics/map-dynamics.h"
00040 #include "model-loader/model-loader.h"
00041 #include "threadsafe/smart_mutex.h"
00042
00043
00044
00045 namespace aesop {
00046
00047
00048
00050
00051
00052
00054
00055
00069 class ClibGameLogic : public ClientGameLogic {
00070 public:
00071
00072 ClibGameLogic(void) throw();
00073 ~ClibGameLogic(void) throw() { }
00074
00075
00076 void initialize(void) { }
00077
00078
00079 void setHost(IN ClientGameLogicHost * host) { m_host = host; }
00080 bool localPlayerJoined(IN int playerId);
00081 void localPlayerLeft(IN int playerId);
00082 void notifyInput(IN int playerId,
00083 IN const event_t& event);
00084 void tick(IN float dt);
00085 void appendGameData(IN xdrbuf::Output * outbuf);
00086
00087 private:
00088
00089 struct local_player_rec_t {
00090
00091 local_player_rec_t(void) throw() { this->clear(); }
00092 void clear(void) throw() {
00093 m_target = 0;
00094 }
00095
00096
00097 long m_target;
00098 };
00099
00100 typedef std::map<int, smart_ptr<local_player_rec_t> > local_map_t;
00101
00102
00103 local_player_rec_t * getLocal(IN int playerId);
00104 bool getMapAndPlacement(IN int playerId,
00105 OUT MapDynamics ** dyn,
00106 OUT placement_t& placement);
00107
00108
00109 ClientGameLogicHost * m_host;
00110 local_map_t m_locals;
00111 float m_msg[7];
00112 int m_msgPlayerId;
00113 bool m_haveMessage;
00114 };
00115
00116
00117
00118 ClibGameLogic::ClibGameLogic(void)
00119 throw()
00120 {
00121 m_host = NULL;
00122 m_haveMessage = false;
00123 }
00124
00125
00126
00128
00129
00130
00132
00133 bool
00134 ClibGameLogic::localPlayerJoined
00135 (
00136 IN int playerId
00137 )
00138 {
00139 ASSERT(playerId > 0, "Bad player id: %d", playerId);
00140
00141 if (!this->getLocal(playerId)) {
00142
00143 smart_ptr<local_player_rec_t> lpr = new local_player_rec_t;
00144 ASSERT(lpr, "out of memory");
00145
00146 m_locals[playerId] = lpr;
00147 }
00148
00149
00150 return true;
00151 }
00152
00153
00154
00155 void
00156 ClibGameLogic::localPlayerLeft
00157 (
00158 IN int playerId
00159 )
00160 {
00161 ASSERT(playerId > 0, "Bad player id: %d", playerId);
00162
00163
00164 local_map_t::iterator i = m_locals.find(playerId);
00165 if (m_locals.end() != i) {
00166 m_locals.erase(i);
00167 }
00168 }
00169
00170
00171
00172 void
00173 ClibGameLogic::notifyInput
00174 (
00175 IN int playerId,
00176 IN const event_t& event
00177 )
00178 {
00179 ASSERT(playerId > 0, "Bad player id: %d", playerId);
00180
00181 DPRINTF("Game logic received input event");
00182
00183
00184
00185
00186
00187
00188 if (eDevice_Gamepad == event.device) {
00189 if (eEvent_Press == event.event) {
00190 if (event.item >= 0) {
00191 DPRINTF(" Some gamepad thing was pressed!");
00192
00193
00194 MapDynamics * dyn;
00195 placement_t placement;
00196 if (!this->getMapAndPlacement(playerId, &dyn, placement)) {
00197 DPRINTF("Ignoring event: Player not in map");
00198 return;
00199 }
00200
00201
00202
00203
00204 m_msg[0] = placement.position.x;
00205 m_msg[1] = placement.position.y;
00206 m_msg[2] = placement.position.z;
00207 m_msg[3] = placement.rotation.x;
00208 m_msg[4] = placement.rotation.y;
00209 m_msg[5] = placement.rotation.z;
00210 m_msg[6] = placement.rotation.w;
00211 m_msgPlayerId = playerId;
00212 m_haveMessage = true;
00213 }
00214 }
00215 }
00216 }
00217
00218
00219
00220 void
00221 ClibGameLogic::tick
00222 (
00223 IN float dt
00224 )
00225 {
00226 ASSERT(dt >= 0, "bad dt: %f", dt);
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 }
00256
00257
00258
00259 void
00260 ClibGameLogic::appendGameData
00261 (
00262 IN xdrbuf::Output * outbuf
00263 )
00264 {
00265 ASSERT(outbuf, "null");
00266
00267
00268
00269
00270
00271
00272
00273 if (m_haveMessage) {
00274 m_haveMessage = false;
00275
00276 outbuf->openPacklet('s');
00277 int32_t l = m_msgPlayerId;
00278 outbuf->addInt32Packlet('p', &l, 1);
00279 outbuf->addFloatPacklet('o', m_msg, 7);
00280 outbuf->closePacklet('s');
00281 }
00282
00283
00284 std::string animState;
00285 for (local_map_t::iterator i = m_locals.begin(); i != m_locals.end();
00286 ++i) {
00287 int playerId = i->first;
00288
00289
00290 smart_ptr<Instance> instance =
00291 m_host->getPlayerInstance(playerId);
00292 if (!instance) {
00293
00294 continue;
00295 }
00296
00297
00298 smart_ptr<glut::Renderable> model = getModel(instance);
00299 if (!model) {
00300
00301 continue;
00302 }
00303
00304 if (!model->isAnimateable()) {
00305
00306 continue;
00307 }
00308 model->getAnimationState(animState);
00309
00310
00311 outbuf->openPacklet('a');
00312 int32_t pid32 = playerId;
00313 outbuf->addInt32Packlet('p', &pid32, 1);
00314 int nLen = animState.length();
00315 outbuf->addStringPacklet('s', animState.c_str(), nLen);
00316 outbuf->closePacklet('a');
00317 }
00318 }
00319
00320
00321
00323
00324
00325
00327
00328 ClibGameLogic::local_player_rec_t *
00329 ClibGameLogic::getLocal
00330 (
00331 IN int playerId
00332 )
00333 {
00334 ASSERT(playerId > 0, "bad player id: %d", playerId);
00335
00336 local_map_t::iterator i = m_locals.find(playerId);
00337 if (m_locals.end() == i)
00338 return NULL;
00339
00340 ASSERT(i->second, "null local player record in map");
00341 return i->second;
00342 }
00343
00344
00345
00346 bool
00347 ClibGameLogic::getMapAndPlacement
00348 (
00349 IN int playerId,
00350 OUT MapDynamics ** dyn,
00351 OUT placement_t& placement
00352 )
00353 {
00354 ASSERT(playerId > 0, "Bad player id: %d", playerId);
00355 ASSERT(dyn, "null pointer to pointer!");
00356 ASSERT(m_host, "null");
00357 placement.clear();
00358
00359
00360 *dyn = m_host->getMapForPlayer(playerId);
00361 if (!*dyn)
00362 return false;
00363
00364
00365 if (!m_host->getPlacement(playerId, placement))
00366 return false;
00367
00368
00369 return true;
00370 }
00371
00372
00373
00375
00376
00377
00379
00380 smart_ptr<ClientGameLogic>
00381 createClientGameLogic
00382 (
00383 void
00384 )
00385 {
00386 smart_ptr<ClibGameLogic> rp = new ClibGameLogic;
00387 ASSERT(rp, "out of memory");
00388
00389 rp->initialize();
00390
00391 return rp;
00392 }
00393
00394
00395 };
00396