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