kgameio.cpp
00001 /* 00002 This file is part of the TDE games library 00003 Copyright (C) 2001 Martin Heni (martin@heni-online.de) 00004 Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de) 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 /* 00021 $Id$ 00022 */ 00023 00024 #include "kgameio.h" 00025 #include "kgameio.moc" 00026 #include "kgame.h" 00027 #include "kplayer.h" 00028 #include "kgamemessage.h" 00029 #include "kmessageio.h" 00030 00031 #include <kdebug.h> 00032 00033 #include <tqwidget.h> 00034 #include <tqbuffer.h> 00035 #include <tqtimer.h> 00036 00037 #include <stdlib.h> 00038 00039 // ----------------------- Generic IO ------------------------- 00040 KGameIO::KGameIO() : TQObject(0,0) 00041 { 00042 kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO) << endl; 00043 mPlayer = 0; 00044 } 00045 00046 KGameIO::KGameIO(KPlayer* player) : TQObject(0,0) 00047 { 00048 kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)" << sizeof(KGameIO) << endl; 00049 mPlayer = 0; 00050 if (player) 00051 { 00052 player->addGameIO(this); 00053 } 00054 } 00055 00056 KGameIO::~KGameIO() 00057 { 00058 kdDebug(11001) << k_funcinfo << ": this=" << this << endl; 00059 // unregister ourselves 00060 if (player()) 00061 { 00062 player()->removeGameIO(this, false); 00063 } 00064 } 00065 00066 void KGameIO::initIO(KPlayer *p) 00067 { 00068 setPlayer(p); 00069 } 00070 00071 void KGameIO::notifyTurn(bool b) 00072 { 00073 if (!player()) 00074 { 00075 kdWarning(11001) << k_funcinfo << ": player() is NULL" << endl; 00076 return; 00077 } 00078 bool sendit=false; 00079 TQByteArray buffer; 00080 TQDataStream stream(buffer, IO_WriteOnly); 00081 emit signalPrepareTurn(stream, b, this, &sendit); 00082 if (sendit) 00083 { 00084 TQDataStream ostream(buffer,IO_ReadOnly); 00085 TQ_UINT32 sender = player()->id(); // force correct sender 00086 kdDebug(11001) << "Prepare turn sendInput" << endl; 00087 sendInput(ostream, true, sender); 00088 } 00089 } 00090 00091 KGame* KGameIO::game() const 00092 { 00093 if (!player()) 00094 { 00095 return 0; 00096 } 00097 return player()->game(); 00098 } 00099 00100 bool KGameIO::sendInput(TQDataStream& s, bool transmit, TQ_UINT32 sender) 00101 { 00102 if (!player()) 00103 { 00104 return false; 00105 } 00106 return player()->forwardInput(s, transmit, sender); 00107 } 00108 00109 void KGameIO::Debug() 00110 { 00111 kdDebug(11001) << "------------------- KGAMEINPUT --------------------" << endl; 00112 kdDebug(11001) << "this: " << this << endl; 00113 kdDebug(11001) << "rtti : " << rtti() << endl; 00114 kdDebug(11001) << "Player: " << player() << endl; 00115 kdDebug(11001) << "---------------------------------------------------" << endl; 00116 } 00117 00118 00119 // ----------------------- Key IO --------------------------- 00120 KGameKeyIO::KGameKeyIO(TQWidget *parent) 00121 : KGameIO() 00122 { 00123 if (parent) 00124 { 00125 kdDebug(11001) << "Key Event filter installed" << endl; 00126 parent->installEventFilter(this); 00127 } 00128 } 00129 00130 KGameKeyIO::~KGameKeyIO() 00131 { 00132 if (parent()) 00133 { 00134 parent()->removeEventFilter(this); 00135 } 00136 } 00137 00138 int KGameKeyIO::rtti() const { return KeyIO; } 00139 00140 bool KGameKeyIO::eventFilter( TQObject *o, TQEvent *e ) 00141 { 00142 if (!player()) 00143 { 00144 return false; 00145 } 00146 00147 // key press/release 00148 if ( e->type() == TQEvent::KeyPress || 00149 e->type() == TQEvent::KeyRelease ) 00150 { 00151 TQKeyEvent *k = (TQKeyEvent*)e; 00152 // kdDebug(11001) << "KGameKeyIO " << this << " key press/release " << k->key() << endl ; 00153 TQByteArray buffer; 00154 TQDataStream stream(buffer,IO_WriteOnly); 00155 bool eatevent=false; 00156 emit signalKeyEvent(this,stream,k,&eatevent); 00157 TQDataStream msg(buffer,IO_ReadOnly); 00158 00159 if (eatevent && sendInput(msg)) 00160 { 00161 return eatevent; 00162 } 00163 return false; // do not eat otherwise 00164 } 00165 return TQObject::eventFilter( o, e ); // standard event processing 00166 } 00167 00168 00169 // ----------------------- Mouse IO --------------------------- 00170 KGameMouseIO::KGameMouseIO(TQWidget *parent,bool trackmouse) 00171 : KGameIO() 00172 { 00173 if (parent) 00174 { 00175 kdDebug(11001) << "Mouse Event filter installed tracking=" << trackmouse << endl; 00176 parent->installEventFilter(this); 00177 parent->setMouseTracking(trackmouse); 00178 } 00179 } 00180 00181 KGameMouseIO::~KGameMouseIO() 00182 { 00183 if (parent()) 00184 { 00185 parent()->removeEventFilter(this); 00186 } 00187 } 00188 00189 int KGameMouseIO::rtti() const 00190 { 00191 return MouseIO; 00192 } 00193 00194 void KGameMouseIO::setMouseTracking(bool b) 00195 { 00196 if (parent()) 00197 { 00198 ((TQWidget*)parent())->setMouseTracking(b); 00199 } 00200 } 00201 00202 bool KGameMouseIO::eventFilter( TQObject *o, TQEvent *e ) 00203 { 00204 if (!player()) 00205 { 00206 return false; 00207 } 00208 // kdDebug(11001) << "KGameMouseIO " << this << endl ; 00209 00210 // mouse action 00211 if ( e->type() == TQEvent::MouseButtonPress || 00212 e->type() == TQEvent::MouseButtonRelease || 00213 e->type() == TQEvent::MouseButtonDblClick || 00214 e->type() == TQEvent::Wheel || 00215 e->type() == TQEvent::MouseMove 00216 ) 00217 { 00218 TQMouseEvent *k = (TQMouseEvent*)e; 00219 // kdDebug(11001) << "KGameMouseIO " << this << endl ; 00220 TQByteArray buffer; 00221 TQDataStream stream(buffer,IO_WriteOnly); 00222 bool eatevent=false; 00223 emit signalMouseEvent(this,stream,k,&eatevent); 00224 // kdDebug(11001) << "################# eatevent=" << eatevent << endl; 00225 TQDataStream msg(buffer,IO_ReadOnly); 00226 if (eatevent && sendInput(msg)) 00227 { 00228 return eatevent; 00229 } 00230 return false; // do not eat otherwise 00231 } 00232 return TQObject::eventFilter( o, e ); // standard event processing 00233 } 00234 00235 00236 // ----------------------- KGameProcesPrivate --------------------------- 00237 class KGameProcessIO::KGameProcessIOPrivate 00238 { 00239 public: 00240 KGameProcessIOPrivate() 00241 { 00242 //mMessageServer = 0; 00243 //mMessageClient = 0; 00244 mProcessIO=0; 00245 } 00246 //KMessageServer *mMessageServer; 00247 //KMessageClient *mMessageClient; 00248 KMessageProcess *mProcessIO; 00249 }; 00250 00251 // ----------------------- Process IO --------------------------- 00252 KGameProcessIO::KGameProcessIO(const TQString& name) 00253 : KGameIO() 00254 { 00255 kdDebug(11001) << k_funcinfo << ": this=" << this << ", sizeof(this)=" << sizeof(KGameProcessIO) << endl; 00256 d = new KGameProcessIOPrivate; 00257 00258 //kdDebug(11001) << "================= KMEssageServer ==================== " << endl; 00259 //d->mMessageServer=new KMessageServer(0,this); 00260 //kdDebug(11001) << "================= KMEssageClient ==================== " << endl; 00261 //d->mMessageClient=new KMessageClient(this); 00262 kdDebug(11001) << "================= KMEssageProcessIO ==================== " << endl; 00263 d->mProcessIO=new KMessageProcess(this,name); 00264 kdDebug(11001) << "================= KMEssage Add client ==================== " << endl; 00265 //d->mMessageServer->addClient(d->mProcessIO); 00266 //kdDebug(11001) << "================= KMEssage SetSErver ==================== " << endl; 00267 //d->mMessageClient->setServer(d->mMessageServer); 00268 kdDebug(11001) << "================= KMEssage: Connect ==================== " << endl; 00269 //connect(d->mMessageClient, TQT_SIGNAL(broadcastReceived(const TQByteArray&, TQ_UINT32)), 00270 // this, TQT_SLOT(clientMessage(const TQByteArray&, TQ_UINT32))); 00271 //connect(d->mMessageClient, TQT_SIGNAL(forwardReceived(const TQByteArray&, TQ_UINT32, const TQValueList <TQ_UINT32> &)), 00272 // this, TQT_SLOT(clientMessage(const TQByteArray&, TQ_UINT32, const TQValueList <TQ_UINT32> &))); 00273 connect(d->mProcessIO, TQT_SIGNAL(received(const TQByteArray&)), 00274 this, TQT_SLOT(receivedMessage(const TQByteArray&))); 00275 //kdDebug(11001) << "Our client is id="<<d->mMessageClient->id() << endl; 00276 } 00277 00278 KGameProcessIO::~KGameProcessIO() 00279 { 00280 kdDebug(11001) << k_funcinfo << ": this=" << this << endl; 00281 kdDebug(11001) << "player="<<player() << endl; 00282 if (player()) 00283 { 00284 player()->removeGameIO(this,false); 00285 } 00286 if (d->mProcessIO) 00287 { 00288 delete d->mProcessIO; 00289 d->mProcessIO=0; 00290 } 00291 delete d; 00292 } 00293 00294 int KGameProcessIO::rtti() const 00295 { 00296 return ProcessIO; 00297 } 00298 00299 void KGameProcessIO::initIO(KPlayer *p) 00300 { 00301 KGameIO::initIO(p); 00302 // Send 'hello' to process 00303 TQByteArray buffer; 00304 TQDataStream stream(buffer, IO_WriteOnly); 00305 TQ_INT16 id = p->userId(); 00306 stream << id; 00307 00308 bool sendit=true; 00309 if (p) 00310 { 00311 emit signalIOAdded(this,stream,p,&sendit); 00312 if (sendit ) 00313 { 00314 TQ_UINT32 sender = p->id(); 00315 kdDebug(11001) << "Sending IOAdded to process player !!!!!!!!!!!!!! " << endl; 00316 sendSystemMessage(stream, KGameMessage::IdIOAdded, 0, sender); 00317 } 00318 } 00319 } 00320 00321 void KGameProcessIO::notifyTurn(bool b) 00322 { 00323 if (!player()) 00324 { 00325 kdWarning(11001) << k_funcinfo << ": player() is NULL" << endl; 00326 return; 00327 } 00328 bool sendit=true; 00329 TQByteArray buffer; 00330 TQDataStream stream(buffer,IO_WriteOnly); 00331 stream << (TQ_INT8)b; 00332 emit signalPrepareTurn(stream,b,this,&sendit); 00333 if (sendit) 00334 { 00335 TQ_UINT32 sender=player()->id(); 00336 kdDebug(11001) << "Sending Turn to process player !!!!!!!!!!!!!! " << endl; 00337 sendSystemMessage(stream, KGameMessage::IdTurn, 0, sender); 00338 } 00339 } 00340 00341 void KGameProcessIO::sendSystemMessage(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) 00342 { 00343 sendAllMessages(stream, msgid, receiver, sender, false); 00344 } 00345 00346 void KGameProcessIO::sendMessage(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender) 00347 { 00348 sendAllMessages(stream, msgid, receiver, sender, true); 00349 } 00350 00351 void KGameProcessIO::sendAllMessages(TQDataStream &stream,int msgid, TQ_UINT32 receiver, TQ_UINT32 sender, bool usermsg) 00352 { 00353 kdDebug(11001) << "==============> KGameProcessIO::sendMessage (usermsg="<<usermsg<<")" << endl; 00354 // if (!player()) return ; 00355 //if (!player()->isActive()) return ; 00356 00357 if (usermsg) 00358 { 00359 msgid+=KGameMessage::IdUser; 00360 } 00361 00362 kdDebug(11001) << "=============* ProcessIO (" << msgid << "," << receiver << "," << sender << ") ===========" << endl; 00363 00364 TQByteArray buffer; 00365 TQDataStream ostream(buffer,IO_WriteOnly); 00366 TQBuffer *device=(TQBuffer *)stream.device(); 00367 TQByteArray data=device->buffer();; 00368 00369 KGameMessage::createHeader(ostream,sender,receiver,msgid); 00370 // ostream.writeRawBytes(data.data()+device->at(),data.size()-device->at()); 00371 ostream.writeRawBytes(data.data(),data.size()); 00372 kdDebug(11001) << " Adding user data from pos="<< device->at() <<" amount= " << data.size() << " byte " << endl; 00373 //if (d->mMessageClient) d->mMessageClient->sendBroadcast(buffer); 00374 if (d->mProcessIO) 00375 { 00376 d->mProcessIO->send(buffer); 00377 } 00378 } 00379 00380 //void KGameProcessIO::clientMessage(const TQByteArray& receiveBuffer, TQ_UINT32 clientID, const TQValueList <TQ_UINT32> &recv) 00381 void KGameProcessIO::receivedMessage(const TQByteArray& receiveBuffer) 00382 { 00383 TQDataStream stream(receiveBuffer,IO_ReadOnly); 00384 int msgid; 00385 TQ_UINT32 sender; 00386 TQ_UINT32 receiver; 00387 KGameMessage::extractHeader(stream,sender,receiver,msgid); 00388 00389 kdDebug(11001) << "************* Got process message sender =" << sender 00390 << " receiver=" << receiver << " msgid=" << msgid << endl; 00391 00392 00393 // Cut out the header part...to not confuse network code 00394 TQBuffer *buf=(TQBuffer *)stream.device(); 00395 TQByteArray newbuffer; 00396 newbuffer.setRawData(buf->buffer().data()+buf->at(),buf->size()-buf->at()); 00397 TQDataStream ostream(newbuffer,IO_ReadOnly); 00398 kdDebug(11001) << "Newbuffer size=" << newbuffer.size() << endl; 00399 00400 00401 00402 // This is a dummy message which allows us the process to talk with its owner 00403 if (msgid==KGameMessage::IdProcessQuery) 00404 { 00405 emit signalProcessQuery(ostream,this); 00406 } 00407 else if (player()) 00408 { 00409 sender = player()->id(); // force correct sender 00410 if (msgid==KGameMessage::IdPlayerInput) 00411 { 00412 sendInput(ostream,true,sender); 00413 } 00414 else 00415 { 00416 player()->forwardMessage(ostream,msgid,receiver,sender); 00417 } 00418 } 00419 else 00420 { 00421 kdDebug(11001) << k_funcinfo << ": Got message from process but no player defined!" << endl; 00422 } 00423 newbuffer.resetRawData(buf->buffer().data()+buf->at(),buf->size()-buf->at()); 00424 } 00425 00426 00427 // ----------------------- Computer IO -------------------------- 00428 class KGameComputerIO::KGameComputerIOPrivate 00429 { 00430 //TODO: maybe these should be KGameProperties!! 00431 public: 00432 KGameComputerIOPrivate() 00433 { 00434 mAdvanceCounter = 0; 00435 mReactionPeriod = 0; 00436 00437 mPauseCounter = 0; 00438 00439 mAdvanceTimer = 0; 00440 } 00441 int mAdvanceCounter; 00442 int mReactionPeriod; 00443 00444 int mPauseCounter; 00445 00446 TQTimer* mAdvanceTimer; 00447 }; 00448 00449 KGameComputerIO::KGameComputerIO() : KGameIO() 00450 { 00451 init(); 00452 } 00453 00454 KGameComputerIO::KGameComputerIO(KPlayer* p) : KGameIO(p) 00455 { 00456 init(); 00457 } 00458 00459 void KGameComputerIO::init() 00460 { 00461 d = new KGameComputerIOPrivate; 00462 } 00463 00464 KGameComputerIO::~KGameComputerIO() 00465 { 00466 if (d->mAdvanceTimer) 00467 { 00468 delete d->mAdvanceTimer; 00469 } 00470 delete d; 00471 } 00472 00473 int KGameComputerIO::rtti() const 00474 { 00475 return ComputerIO; 00476 } 00477 00478 void KGameComputerIO::setReactionPeriod(int calls) 00479 { 00480 d->mReactionPeriod = calls; 00481 } 00482 00483 int KGameComputerIO::reactionPeriod() const 00484 { 00485 return d->mReactionPeriod; 00486 } 00487 00488 void KGameComputerIO::setAdvancePeriod(int ms) 00489 { 00490 stopAdvancePeriod(); 00491 d->mAdvanceTimer = new TQTimer(this); 00492 connect(d->mAdvanceTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(advance())); 00493 d->mAdvanceTimer->start(ms); 00494 } 00495 00496 void KGameComputerIO::stopAdvancePeriod() 00497 { 00498 if (d->mAdvanceTimer) 00499 { 00500 d->mAdvanceTimer->stop(); 00501 delete d->mAdvanceTimer; 00502 } 00503 } 00504 00505 void KGameComputerIO::pause(int calls) 00506 { 00507 d->mPauseCounter = calls; 00508 } 00509 00510 void KGameComputerIO::unpause() 00511 { 00512 pause(0); 00513 } 00514 00515 void KGameComputerIO::advance() 00516 { 00517 if (d->mPauseCounter > 0) 00518 { 00519 d->mPauseCounter--; 00520 return; 00521 } 00522 else if (d->mPauseCounter < 0) 00523 { 00524 return; 00525 } 00526 d->mAdvanceCounter++; 00527 if (d->mAdvanceCounter >= d->mReactionPeriod) 00528 { 00529 d->mAdvanceCounter = 0; 00530 reaction(); 00531 } 00532 } 00533 00534 void KGameComputerIO::reaction() 00535 { 00536 emit signalReaction(); 00537 } 00538 00539