1 /* $Id: MultiPlay.cpp,v 1.74 2003/11/19 17:02:24 nan Exp $ */
2
3 // Copyright (C) 2000-2003 $B?@Fn(B $B5H9((B(Kanna Yoshihiro)
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 #include "ttinc.h"
20 #include "MultiPlay.h"
21 #include "Ball.h"
22 #include "Player.h"
23 #include "Event.h"
24 #include "BaseView.h"
25 #include "RCFile.h"
26 #include "Network.h"
27 #include "MultiPlayerSelect.h"
28 #include "NetPenAttack.h"
29 #include "NetPenDrive.h"
30 #include "NetShakeCut.h"
31
32 #ifdef LOGGING
33 #include "Logging.h"
34 #endif
35
36 #if !defined(WIN32)
37 #include <netinet/tcp.h>
38 #endif
39
40 #if defined(WIN32)
41
42 typedef int socklen_t; /* mimic Penguin's typedef */
43
44 #else /* ! WIN32 */
45
46 #if !defined(__FreeBSD__)
47 #define closesocket(FD) close(FD)
48 #endif
49
50 #endif
51
52 extern long mode;
53 extern Ball theBall;
54 extern RCFile *theRC;
55 extern int theSocket;
56 extern long timeAdj;
57
58 extern void QuitGame();
59
60 int one=1;
61
62 SDL_mutex *networkMutex;
63
64 void
StartServer()65 MultiPlay::StartServer() {
66 }
67
68 void
StartClient()69 MultiPlay::StartClient() {
70 //Event::TheEvent()->SendBall();
71 }
72
MultiPlay()73 MultiPlay::MultiPlay() {
74 }
75
~MultiPlay()76 MultiPlay::~MultiPlay() {
77 }
78
79 bool
Init()80 MultiPlay::Init() {
81 #ifdef LOGGING
82 Logging::GetLogging()->StartLog();
83 #endif
84
85 theRC->gameLevel = LEVEL_HARD;
86 theRC->gameMode = GAME_11PTS;
87
88 // Init timer again
89 struct timeb tb;
90 getcurrenttime(&tb);
91
92 Event::m_lastTime = tb;
93
94 m_View = (PlayGameView *)View::CreateView( VIEW_PLAYGAME );
95
96 m_View->Init( this );
97
98 BaseView::TheView()->AddView( m_View );
99
100 return true;
101 }
102
103 void
Create(long player,long com)104 MultiPlay::Create( long player, long com ) {
105 long side;
106
107 Control::ClearControl();
108
109 m_theControl = new MultiPlay();
110 m_theControl->Init();
111
112 theBall.Warp( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1000 );
113
114 if ( !(theRC->serverName[0]) )
115 side = 1; // server side
116 else
117 side = -1; // client side
118
119 m_thePlayer = Player::Create( player, side, 0 );
120 m_comPlayer = Player::Create( com, -side, 0 );
121
122 networkMutex = SDL_CreateMutex();
123
124 if ( side == 1 ) {
125 ((MultiPlay *)m_theControl)->StartServer();
126 } else {
127 ((MultiPlay *)m_theControl)->StartClient();
128 }
129
130 m_thePlayer->Init();
131 m_comPlayer->Init();
132 }
133
134 bool
Move(SDL_keysym * KeyHistory,long * MouseXHistory,long * MouseYHistory,unsigned long * MouseBHistory,int Histptr)135 MultiPlay::Move( SDL_keysym *KeyHistory, long *MouseXHistory,
136 long *MouseYHistory, unsigned long *MouseBHistory,
137 int Histptr ) {
138 bool reDraw = false;
139
140 theBall.Move();
141 reDraw |= m_thePlayer->Move( KeyHistory, MouseXHistory,
142 MouseYHistory, MouseBHistory, Histptr );
143 reDraw |= m_comPlayer->Move( NULL, NULL, NULL, NULL, 0 );
144
145 return reDraw;
146 }
147
148 bool
LookAt(double & srcX,double & srcY,double & srcZ,double & destX,double & destY,double & destZ)149 MultiPlay::LookAt( double &srcX, double &srcY, double &srcZ,
150 double &destX, double &destY, double &destZ ) {
151 if (m_thePlayer) {
152 srcX = m_thePlayer->GetX() + m_thePlayer->GetEyeX();
153 srcY = m_thePlayer->GetY() + m_thePlayer->GetEyeY();
154 srcZ = m_thePlayer->GetZ() + m_thePlayer->GetEyeZ();
155 destX = m_thePlayer->GetLookAtX();
156 destY = m_thePlayer->GetLookAtY();
157 destZ = m_thePlayer->GetLookAtZ();
158 }
159
160 return true;
161 }
162
163
164 void
SendTime(char * buf)165 MultiPlay::SendTime( char *buf ) {
166 char v;
167 long sec, count;
168
169 sec = Event::m_lastTime.time;
170 count = Event::m_lastTime.millitm/10;
171
172 count += timeAdj;
173
174 while ( count >= 100 ) {
175 count -= 100;
176 sec++;
177 }
178 while ( count < 0 ) {
179 count += 100;
180 sec--;
181 }
182
183 memcpy( buf, (char *)&sec, 4 );
184 v = (char)(count);
185 memcpy( &(buf[4]), (char *)&v, 1 );
186 }
187
188 void
EndGame()189 MultiPlay::EndGame() {
190 QuitGame();
191 //mode = MODE_TITLE;
192 }
193
194
195 int
WaitForData(void * dum)196 MultiPlay::WaitForData( void *dum ) {
197 fd_set rdfds;
198
199 while (1) {
200 FD_ZERO( &rdfds );
201 FD_SET( (unsigned int)theSocket, &rdfds );
202
203 if ( select( theSocket+1, &rdfds, NULL, NULL, NULL ) > 0 ) {
204 bool ret;
205 long side;
206 if ( !(theRC->serverName[0]) )
207 side = -1;
208 else
209 side = 1;
210
211 if ( m_comPlayer )
212 side = m_comPlayer->GetSide();
213
214 SDL_mutexP( networkMutex );
215 ret = Event::TheEvent()->GetExternalData( side );
216 SDL_mutexV( networkMutex );
217
218 if ( !ret ) {
219 break;
220 }
221 } else {
222 printf( "Select failed\n" );
223 break;
224 }
225 }
226
227 return 0;
228 }
229
230
ExternalData()231 ExternalData::ExternalData() {
232 side = 1;
233 dataType = 0;
234 sec = 0;
235 count = 0;
236 memset( data, 0, 256 );
237 next = NULL;
238 }
239
ExternalData(long s)240 ExternalData::ExternalData( long s ) {
241 side = s;
242 dataType = 0;
243 sec = 0;
244 count = 0;
245 memset( data, 0, 256 );
246 next = NULL;
247 }
248
~ExternalData()249 ExternalData::~ExternalData() {
250 }
251
252 void
ReadTime(int sd,long * sec,char * count)253 ExternalData::ReadTime( int sd, long *sec, char *count ) {
254 char buf[256];
255 long len = 0;
256 long ctmp;
257
258 while (1) {
259 if ( (len+=recv( sd, buf+len, 5-len, 0 )) == 5 )
260 break;
261 }
262 memcpy( sec, &buf[0], 4 );
263 memcpy( count, &buf[4], 1 );
264
265 ctmp = *count;
266 ctmp -= timeAdj;
267
268 while ( ctmp >= 100 ) {
269 ctmp -= 100;
270 (*sec)++;
271 }
272 while ( ctmp < 0 ) {
273 ctmp += 100;
274 (*sec)--;
275 }
276 *count = (char)ctmp;
277 }
278
279 ExternalData *
ReadData(long s)280 ExternalData::ReadData( long s ) {
281 char buf[256];
282 ExternalData *extNow;
283
284 ReadHeader( theSocket, buf );
285
286 if ( !strncmp( buf, "PV", 2 ) ) {
287 extNow = new ExternalPVData(s);
288 extNow->Read( theSocket );
289 } else if ( !strncmp( buf, "PS", 2 ) ) {
290 extNow = new ExternalPSData(s);
291 extNow->Read( theSocket );
292 } else if ( !strncmp( buf, "BV", 2 ) ) {
293 extNow = new ExternalBVData(s);
294 extNow->Read( theSocket );
295 } else if ( !strncmp( buf, "PT", 2 ) ) {
296 extNow = new ExternalPTData(s);
297 extNow->Read( theSocket );
298 } else if ( !strncmp( buf, "QT", 2 ) ) {
299 QuitGame();
300 //mode = MODE_TITLE;
301 return NULL;
302 } else {
303 printf( "Comm Error!!\n" );
304 return NULL;
305 }
306
307 return extNow;
308 }
309
310
ExternalPVData()311 ExternalPVData::ExternalPVData() : ExternalData() {
312 dataType = DATA_PV;
313 }
314
ExternalPVData(long s)315 ExternalPVData::ExternalPVData( long s ) : ExternalData(s) {
316 dataType = DATA_PV;
317 }
318
319 bool
Apply(Player * targetPlayer,bool & fThePlayer,bool & fComPlayer,bool & fTheBall)320 ExternalPVData::Apply( Player *targetPlayer, bool &fThePlayer,
321 bool &fComPlayer, bool &fTheBall ) {
322 targetPlayer->Warp( data );
323 if ( targetPlayer == Control::GetThePlayer() )
324 fThePlayer = true;
325 else if ( targetPlayer == Control::GetComPlayer() )
326 fComPlayer = true;
327
328 #ifdef LOGGING
329 Logging::GetLogging()->LogRecvPVMessage( this );
330 #endif
331
332 return true;
333 }
334
335 bool
Read(long sock)336 ExternalPVData::Read( long sock ) {
337 ReadTime( sock, &sec, &count );
338
339 long len = 0;
340 while (1) {
341 if ( (len+=recv( sock, data+len, 48-len, 0 )) == 48 )
342 break;
343 }
344
345 #ifdef LOGGING
346 char buf[256];
347 Logging::GetLogging()->LogTime( LOG_COMCOMPLAYER );
348 sprintf( buf, "Recv PV: %d.%3d\n", (int)sec, (int)count );
349 Logging::GetLogging()->Log( LOG_COMCOMPLAYER, buf );
350 #endif
351
352 return true;
353 }
354
355
ExternalPSData()356 ExternalPSData::ExternalPSData() : ExternalData() {
357 dataType = DATA_PS;
358 }
359
ExternalPSData(long s)360 ExternalPSData::ExternalPSData( long s ) : ExternalData(s) {
361 dataType = DATA_PS;
362 }
363
364 bool
Apply(Player * targetPlayer,bool & fThePlayer,bool & fComPlayer,bool & fTheBall)365 ExternalPSData::Apply( Player *targetPlayer, bool &fThePlayer,
366 bool &fComPlayer, bool &fTheBall ) {
367 targetPlayer->ExternalSwing( data );
368 if ( targetPlayer == Control::GetThePlayer() )
369 fThePlayer = true;
370 else if ( targetPlayer == Control::GetComPlayer() )
371 fComPlayer = true;
372
373 #ifdef LOGGING
374 Logging::GetLogging()->LogRecvPSMessage( this );
375 #endif
376
377 return true;
378 }
379
380 bool
Read(long sock)381 ExternalPSData::Read( long sock ) {
382 ReadTime( sock, &sec, &count );
383
384 long len = 0;
385 while (1) {
386 if ( (len+=recv( sock, data+len, 24-len, 0 )) == 24 )
387 break;
388 }
389
390 #ifdef LOGGING
391 char buf[256];
392 Logging::GetLogging()->LogTime( LOG_COMCOMPLAYER );
393 sprintf( buf, "Recv PS: %d.%3d\n", (int)sec, (int)count );
394 Logging::GetLogging()->Log( LOG_COMCOMPLAYER, buf );
395 #endif
396
397 return true;
398 }
399
400
ExternalBVData()401 ExternalBVData::ExternalBVData() : ExternalData() {
402 dataType = DATA_BV;
403 }
404
ExternalBVData(long s)405 ExternalBVData::ExternalBVData( long s ) : ExternalData(s) {
406 dataType = DATA_BV;
407 }
408
409 bool
Apply(Player * targetPlayer,bool & fThePlayer,bool & fComPlayer,bool & fTheBall)410 ExternalBVData::Apply( Player *targetPlayer, bool &fThePlayer,
411 bool &fComPlayer, bool &fTheBall ) {
412 theBall.Warp( data );
413 fTheBall = true;
414
415 #ifdef LOGGING
416 Logging::GetLogging()->LogRecvBVMessage( this );
417 #endif
418
419 return true;
420 }
421
422 bool
Read(long sock)423 ExternalBVData::Read( long sock ) {
424 ReadTime( sock, &sec, &count );
425
426 long len = 0;
427 while (1) {
428 if ( (len+=recv( sock, data+len, 60-len, 0 )) == 60 )
429 break;
430 }
431
432 #ifdef LOGGING
433 char buf[256];
434 Logging::GetLogging()->LogTime( LOG_COMBALL );
435 sprintf( buf, "Recv BV: %d.%3d\n", (int)sec, (int)count );
436 Logging::GetLogging()->Log( LOG_COMBALL, buf );
437 #endif
438
439 return true;
440 }
441
442
ExternalPTData()443 ExternalPTData::ExternalPTData() : ExternalData() {
444 dataType = DATA_PT;
445 }
446
ExternalPTData(long s)447 ExternalPTData::ExternalPTData( long s ) : ExternalData(s) {
448 dataType = DATA_PT;
449 }
450
451 bool
Apply(Player * targetPlayer,bool & fThePlayer,bool & fComPlayer,bool & fTheBall)452 ExternalPTData::Apply( Player *targetPlayer, bool &fThePlayer,
453 bool &fComPlayer, bool &fTheBall ) {
454 ((MultiPlayerSelect *)Control::TheControl())->ReadPT( data );
455
456 #ifdef LOGGING
457 Logging::GetLogging()->LogRecvPTMessage( this );
458 #endif
459
460 return true;
461 }
462
463 bool
Read(long sock)464 ExternalPTData::Read( long sock ) {
465 //ReadTime( sock, &sec, &count );
466
467 long len = 0;
468 while (1) {
469 if ( (len+=recv( sock, data+len, 5-len, 0 )) == 5 )
470 break;
471 }
472
473 #ifdef LOGGING
474 char buf[256];
475 Logging::GetLogging()->LogTime( LOG_COMMISC );
476 sprintf( buf, "Recv PT: \n" );
477 Logging::GetLogging()->Log( LOG_COMMISC, buf );
478 #endif
479
480 return true;
481 }
482