1 /* $Id: Event.cpp,v 1.84 2003/11/19 17:26:58 nan Exp $ */
2 
3 // Copyright (C) 2000-2003  ���� �ȹ�(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 "Event.h"
21 #include "Control.h"
22 #include "BaseView.h"
23 #include "BaseView2D.h"
24 #include "SoloPlay.h"
25 #include "PracticePlay.h"
26 #include "MultiPlay.h"
27 #include "Network.h"
28 #include "PlayerSelect.h"
29 #include "MultiPlayerSelect.h"
30 #include "Title.h"
31 #include "Opening.h"
32 #include "Howto.h"
33 #include "TrainingSelect.h"
34 #include "Training.h"
35 #include "PracticeSelect.h"
36 #include "RCFile.h"
37 
38 #ifdef LOGGING
39 #include "Logging.h"
40 #endif
41 
42 extern RCFile *theRC;
43 
44 extern Ball theBall;
45 extern long mode;
46 
47 extern void Timer( int value );
48 struct timeb Event::m_lastTime = {0, 0, 0, 0};	// ľ����TimerEvent���ƤФ줿�Ȥ��λ���
49 
50 Event* Event::m_theEvent = NULL;
51 
52 extern int theSocket;
53 
54 extern long wins;
55 
56 extern bool isComm;
57 
58 extern SDL_mutex *networkMutex;
59 extern long timeAdj;
60 
61 long _perfCount;
62 long perfs;
63 
64 long _backTrackCount = 0;
65 double backTracks = 0;
66 
67 void CopyPlayerData( Player& dest, Player* src );
68 
69 void QuitGame();
70 
Event()71 Event::Event() {
72   memset( &(m_KeyHistory[0]), 0, sizeof(SDL_keysym) );
73   m_MouseXHistory[0] = BaseView::GetWinWidth()/2;
74   m_MouseYHistory[0] = BaseView::GetWinHeight()/2;
75   m_MouseBHistory[0] = 0;
76   m_Histptr = 0;
77 
78   m_External = NULL;
79 
80   m_mouseButton = 0;
81 }
82 
~Event()83 Event::~Event() {
84 }
85 
86 Event*
TheEvent()87 Event::TheEvent() {
88   if ( !m_theEvent )
89     m_theEvent = new Event();
90   return m_theEvent;
91 }
92 
93 bool
Init()94 Event::Init() {
95   if (isComm)
96     m_External = new ExternalNullData();
97 
98   switch ( mode ){
99   case MODE_SOLOPLAY:
100     SoloPlay::Create( 0, RAND(2) );
101     break;
102   case MODE_MULTIPLAY:
103     MultiPlay::Create( 0, RAND(2) );
104     break;
105   case MODE_HOWTO:
106     Howto::Create();
107     break;
108   case MODE_SELECT:
109     PlayerSelect::Create();
110     break;
111   case MODE_MULTIPLAYSELECT:
112     MultiPlayerSelect::Create();
113     break;
114   case MODE_TITLE:
115     Title::Create();
116     break;
117   case MODE_OPENING:
118     Opening::Create();
119     break;
120   }
121 
122   theBall.Init();
123 
124   return true;
125 }
126 
127 void
IdleFunc()128 Event::IdleFunc() {
129   struct timeb tb;
130 
131   long diffsec, diffmsec;
132   long diffcount = 0;
133   bool reDraw = false;
134 
135 #ifndef WIN32
136   struct timeval tv;
137   struct timezone tz;
138 #endif
139 
140 #ifdef WIN32
141   ftime( &tb );
142 #else
143   gettimeofday( &tv, &tz );
144   tb.time = tv.tv_sec;
145   tb.millitm = tv.tv_usec/1000;
146 #endif
147 
148   if ( m_lastTime.time == 0 ){
149     m_lastTime = tb;
150     _perfCount = 0;
151     perfs = 0;
152 
153     ClearBacktrack();
154 
155     return;
156   }
157 
158   diffsec = tb.time - m_lastTime.time;
159   diffmsec = tb.millitm + diffsec*1000 - m_lastTime.millitm;
160 
161   diffcount = diffmsec / 10;
162   if ( diffcount == 0 ) {
163 //    usleep( (10-diffmsec)*1000 );
164     return;
165   }
166 
167   perfs +=diffcount;
168   _perfCount++;
169 
170 #ifdef SCREENSHOT
171   diffcount = 3;
172 #endif
173 
174   for ( int i = 0 ; i < diffcount ; i++ ) {
175     // While pause, never move objects. (Solo Play)
176     if ( Control::TheControl()->IsPlaying() &&
177 	 ((PlayGame *)Control::TheControl())->IsPause() &&
178 	 isComm == false ) {
179       reDraw = true;
180     } else {
181       reDraw |= Event::TheEvent()->Move();
182     }
183 
184     m_lastTime.millitm += 10;
185     if ( m_lastTime.millitm > 1000 ) {
186       m_lastTime.time++;
187       m_lastTime.millitm -= 1000;
188     }
189   }
190 
191   if ( mode == MODE_MULTIPLAY ) {
192     long preMode = mode;
193     Event::TheEvent()->ReadData();
194     Event::TheEvent()->IsModeChanged( preMode );
195   } else if ( mode == MODE_MULTIPLAYSELECT ) {
196     Event::TheEvent()->ReadSelectData();
197   }
198 
199   if ( mode != MODE_OPENING && mode != MODE_TITLE &&
200        !(Control::TheControl()->IsPlaying() &&
201 	 ((PlayGame *)Control::TheControl())->IsPause()) )
202     SDL_WarpMouse((unsigned short)Event::TheEvent()->m_MouseXHistory[Event::TheEvent()->m_Histptr],
203 		  (unsigned short)Event::TheEvent()->m_MouseYHistory[Event::TheEvent()->m_Histptr] );
204 
205   if ( reDraw )
206     BaseView::TheView()->RedrawAll();
207 }
208 
209 bool
Move()210 Event::Move() {
211   long preMode = mode;
212   bool reDraw = false;
213 
214   reDraw |= Control::TheControl()->Move( m_KeyHistory, m_MouseXHistory,
215 					 m_MouseYHistory, m_MouseBHistory,
216 					 m_Histptr );
217 
218   reDraw |= IsModeChanged( preMode );
219   Record();
220 
221   return reDraw;
222 }
223 
224 bool
IsModeChanged(long preMode)225 Event::IsModeChanged( long preMode ) {
226   if ( mode != preMode ) {	// mode change
227     long p, q;
228 
229     switch ( mode ) {
230     case MODE_SOLOPLAY:
231       p = ((PlayerSelect *)Control::TheControl())->GetPlayerNum();
232       q = ((PlayerSelect *)Control::TheControl())->GetOpponentNum();
233 
234       SoloPlay::Create( p, q );
235       break;
236     case MODE_MULTIPLAY:
237       p = ((PlayerSelect *)Control::TheControl())->GetPlayerNum();
238       q = ((PlayerSelect *)Control::TheControl())->GetOpponentNum();
239       MultiPlay::Create( p, q );
240       break;
241     case MODE_SELECT:
242       PlayerSelect::Create();
243       break;
244     case MODE_MULTIPLAYSELECT:
245       MultiPlayerSelect::Create();
246       break;
247     case MODE_TITLE:
248       Title::Create();
249       break;
250     case MODE_OPENING:
251       Opening::Create();
252       break;
253     case MODE_HOWTO:
254       Howto::Create();
255       break;
256     case MODE_TRAININGSELECT:
257       TrainingSelect::Create();
258       break;
259     case MODE_TRAINING:
260       p = ((TrainingSelect *)Control::TheControl())->GetPlayerNum();
261       Training::Create( p, p );
262       break;
263     case MODE_PRACTICESELECT:
264       PracticeSelect::Create();
265       break;
266     case MODE_PRACTICE:
267       p = ((PlayerSelect *)Control::TheControl())->GetPlayerNum();
268       q = ((PlayerSelect *)Control::TheControl())->GetOpponentNum();
269       PracticePlay::Create( p, q );
270       break;
271     }
272 
273     ClearBacktrack();
274 
275     return true;
276   }
277 
278   return false;
279 }
280 
281 void
Record()282 Event::Record() {
283   long x, y;
284   SDL_keysym key;
285   long btn;
286 
287   x = m_MouseXHistory[m_Histptr];
288   y = m_MouseYHistory[m_Histptr];
289   key = m_KeyHistory[m_Histptr];
290   btn = m_MouseBHistory[m_Histptr];
291 
292   m_Histptr++;
293 
294   if ( m_Histptr == MAX_HISTORY )
295     m_Histptr = 0;
296 
297 #ifdef LOGGING
298   long sec = m_BacktrackBuffer[m_Histptr].sec;
299   long cnt = m_BacktrackBuffer[m_Histptr].count;
300   char buf[1024];
301 
302   if ( mode == MODE_MULTIPLAY )
303     cnt += timeAdj;
304 
305   while ( cnt < 0 ) {
306     sec--;
307     cnt += 100;
308   }
309   while ( cnt >= 100 ) {
310     sec++;
311     cnt -= 100;
312   }
313 
314   sprintf( buf, "%d.%2d %d - %d  x = %4.2f y = %4.2f z = %4.2f st = %d\n",
315 	   sec, cnt,
316 	   m_BacktrackBuffer[m_Histptr].score1,
317 	   m_BacktrackBuffer[m_Histptr].score2,
318 	   m_BacktrackBuffer[m_Histptr].theBall.GetX(),
319 	   m_BacktrackBuffer[m_Histptr].theBall.GetY(),
320 	   m_BacktrackBuffer[m_Histptr].theBall.GetZ(),
321 	   m_BacktrackBuffer[m_Histptr].theBall.GetStatus() );
322   Logging::GetLogging()->Log( LOG_ACTBALL, buf );
323 
324   Player *prevPlayer, *player;
325   if ( m_Histptr == 0 )
326     prevPlayer = &m_BacktrackBuffer[MAX_HISTORY-1].thePlayer;
327   else
328     prevPlayer = &m_BacktrackBuffer[m_Histptr-1].thePlayer;
329   player = &m_BacktrackBuffer[m_Histptr].thePlayer;
330 
331   if ( prevPlayer->GetVX() != player->GetVX() ||
332        prevPlayer->GetVY() != player->GetVY() ||
333        prevPlayer->GetSwing() != player->GetSwing() ) {
334     sprintf( buf, "%d.%2d: ", sec, cnt );
335     Logging::GetLogging()->Log( LOG_ACTTHEPLAYER, buf );
336 
337     snprintf( buf, sizeof(buf),
338 	      "playerType=%1d side=%2d x=%4.2f y=%4.2f z=%4.2f "
339 	      "vx=%4.2f vy=%4.2f vz=%4.2f status=%2d "
340 	      "swing=%2d swingType=%1d swingSide=%2d afterSwing=%2d "
341 	      "swingError=%1d targetX=%4.2f targetY=%4.2f "
342 	      "eyeX=%4.2f eyeY=%4.2f eyeZ=%4.2f "
343 	      "lookAtX=%4.2f lookAtY=%4.2f lookAtZ=%4.2f "
344 	      "pow=%1d spin=%3.2f stamina=%2.0f dragX=%2d dragY=%2d\n",
345 	      (int)player->GetPlayerType(), (int)player->GetSide(),
346 	      player->GetX(), player->GetY(), player->GetZ(),
347 	      player->GetVX(), player->GetVY(), player->GetVZ(),
348 	      (int)player->GetStatus(), (int)player->GetSwing(),
349 	      (int)player->GetSwingType(), (int)player->GetSwingSide(),
350 	      (int)player->GetAfterSwing(), (int)player->GetSwingError(),
351 	      player->GetTargetX(), player->GetTargetY(),
352 	      player->GetEyeX(), player->GetEyeY(), player->GetEyeZ(),
353 	      player->GetLookAtX(), player->GetLookAtY(), player->GetLookAtZ(),
354 	      (int)player->GetPower(), player->GetSpin(), player->GetStamina(),
355 	      (int)player->GetDragX(), (int)player->GetDragY() );
356     Logging::GetLogging()->Log( LOG_ACTTHEPLAYER, buf );
357   }
358 
359   if ( m_Histptr == 0 )
360     prevPlayer = &m_BacktrackBuffer[MAX_HISTORY-1].comPlayer;
361   else
362     prevPlayer = &m_BacktrackBuffer[m_Histptr-1].comPlayer;
363   player = &m_BacktrackBuffer[m_Histptr].comPlayer;
364 
365   if ( prevPlayer->GetVX() != player->GetVX() ||
366        prevPlayer->GetVY() != player->GetVY() ||
367        prevPlayer->GetSwing() != player->GetSwing() ) {
368     sprintf( buf, "%d.%2d: ", sec, cnt );
369     Logging::GetLogging()->Log( LOG_ACTCOMPLAYER, buf );
370 
371     snprintf( buf, sizeof(buf),
372 	      "playerType=%1d side=%2d x=%4.2f y=%4.2f z=%4.2f "
373 	      "vx=%4.2f vy=%4.2f vz=%4.2f status=%2d "
374 	      "swing=%2d swingType=%1d swingSide=%2d afterSwing=%2d "
375 	      "swingError=%1d targetX=%4.2f targetY=%4.2f "
376 	      "eyeX=%4.2f eyeY=%4.2f eyeZ=%4.2f "
377 	      "lookAtX=%4.2f lookAtY=%4.2f lookAtZ=%4.2f "
378 	      "pow=%1d spin=%3.2f stamina=%2.0f dragX=%2d dragY=%2d\n",
379 	      (int)player->GetPlayerType(), (int)player->GetSide(),
380 	      player->GetX(), player->GetY(), player->GetZ(),
381 	      player->GetVX(), player->GetVY(), player->GetVZ(),
382 	      (int)player->GetStatus(), (int)player->GetSwing(),
383 	      (int)player->GetSwingType(), (int)player->GetSwingSide(),
384 	      (int)player->GetAfterSwing(), (int)player->GetSwingError(),
385 	      player->GetTargetX(), player->GetTargetY(),
386 	      player->GetEyeX(), player->GetEyeY(), player->GetEyeZ(),
387 	      player->GetLookAtX(), player->GetLookAtY(), player->GetLookAtZ(),
388 	      (int)player->GetPower(), player->GetSpin(), player->GetStamina(),
389 	      (int)player->GetDragX(), (int)player->GetDragY() );
390     Logging::GetLogging()->Log( LOG_ACTCOMPLAYER, buf );
391   }
392 #endif
393 
394   if ( (mode == MODE_SOLOPLAY || mode == MODE_PRACTICE) &&
395        Control::TheControl() &&
396        ((SoloPlay *)Control::TheControl())->GetSmashPtr() >= 0 )
397     return;
398 
399   // Warp Mouse Pointer
400   SetNextMousePointer( x, y );
401 
402   memset( &(m_KeyHistory[m_Histptr]), 0, sizeof(SDL_keysym) );
403   m_MouseXHistory[m_Histptr] = x;
404   m_MouseYHistory[m_Histptr] = y;
405   m_MouseBHistory[m_Histptr] = btn;
406 
407   m_BacktrackBuffer[m_Histptr].sec = m_lastTime.time;
408   m_BacktrackBuffer[m_Histptr].count = m_lastTime.millitm/10;
409 
410   m_BacktrackBuffer[m_Histptr].theBall = theBall;
411   CopyPlayerData( m_BacktrackBuffer[m_Histptr].thePlayer,
412 		  Control::GetThePlayer() );
413   CopyPlayerData( m_BacktrackBuffer[m_Histptr].comPlayer,
414 		  Control::GetComPlayer() );
415 
416   if ( mode == MODE_SOLOPLAY || mode == MODE_MULTIPLAY ||
417        mode == MODE_PRACTICE ) {
418     m_BacktrackBuffer[m_Histptr].score1 =
419       ((PlayGame *)Control::TheControl())->GetScore(1);
420     m_BacktrackBuffer[m_Histptr].score2 =
421       ((PlayGame *)Control::TheControl())->GetScore(-1);
422   }
423 
424   return;
425 }
426 
HotKey_ToggleFullScreen(void)427 void HotKey_ToggleFullScreen(void)
428 {
429   SDL_Surface *screen = SDL_GetVideoSurface();
430   if ( SDL_WM_ToggleFullScreen(screen) ) {
431     theRC->fullScreen = (screen->flags & SDL_FULLSCREEN) ? 1 : 0;
432     fprintf(stderr, _("Toggled fullscreen mode - now %s\n"),
433             theRC->fullScreen  ? _("fullscreen") : _("windowed"));
434   } else {
435     fprintf(stderr, _("Unable to toggle fullscreen mode\n"));
436   }
437 }
438 
439 void
KeyboardFunc(SDL_Event key,int x,int y)440 Event::KeyboardFunc( SDL_Event key, int x, int y ) {
441   if ( (key.key.keysym.sym == SDLK_RETURN) &&
442        (key.key.keysym.mod & KMOD_ALT) ) {
443     HotKey_ToggleFullScreen();
444     return;
445   }
446   if ( key.key.keysym.unicode == 'Q' ) {
447     if ( mode == MODE_SOLOPLAY || mode == MODE_PRACTICE ||
448 	 mode == MODE_SELECT || mode == MODE_HOWTO ||
449 	 mode == MODE_TRAININGSELECT || mode == MODE_TRAINING ||
450 	 mode == MODE_PRACTICESELECT ) {
451     } else
452       QuitGame();
453   } else if ( key.key.keysym.unicode == SDLK_ESCAPE &&
454 	      Control::TheControl()->IsPlaying() ) {
455     if ( ((PlayGame *)Control::TheControl())->IsPause() ) {
456       SDL_WM_GrabInput( SDL_GRAB_ON );
457       SDL_ShowCursor(SDL_DISABLE);
458       ((PlayGame *)Control::TheControl())->SetPause( false );
459     } else {
460       SDL_WM_GrabInput( SDL_GRAB_OFF );
461       SDL_ShowCursor(SDL_ENABLE);
462       ((PlayGame *)Control::TheControl())->SetPause( true );
463     }
464   }
465 
466   Event::TheEvent()->m_KeyHistory[Event::TheEvent()->m_Histptr] = key.key.keysym;
467 }
468 
469 void
KeyUpFunc(SDL_Event key,int x,int y)470 Event::KeyUpFunc( SDL_Event key, int x, int y ) {
471   // �ѻߤ��Ƥ�褤
472 #if 0
473   if ( key.key.keysym.unicode == 'Q' ) {
474     QuitGame();
475   }
476 #endif
477 }
478 
479 void
MotionFunc(int x,int y)480 Event::MotionFunc( int x, int y ) {
481   Event *e = Event::TheEvent();
482   e->m_MouseXHistory[e->m_Histptr] = x;
483   e->m_MouseYHistory[e->m_Histptr] = y;
484 }
485 
486 void
ButtonFunc(int button,int state,int x,int y)487 Event::ButtonFunc( int button, int state, int x, int y ) {
488   Event *e = Event::TheEvent();
489   if ( state == SDL_MOUSEBUTTONDOWN ) {
490     switch ( button ) {
491     case 1:
492       e->m_MouseBHistory[e->m_Histptr] |= BUTTON_LEFT;
493       e->m_mouseButton |= BUTTON_LEFT;
494       break;
495     case 2:
496       e->m_MouseBHistory[e->m_Histptr] |= BUTTON_MIDDLE;
497       e->m_mouseButton |= BUTTON_MIDDLE;
498       break;
499     case 3:
500       e->m_MouseBHistory[e->m_Histptr] |= BUTTON_RIGHT;
501       e->m_mouseButton |= BUTTON_RIGHT;
502       break;
503     }
504   } else {	// Relase Button
505     switch ( button ) {
506     case 1:
507       e->m_MouseBHistory[e->m_Histptr] &= ~BUTTON_LEFT;
508       e->m_mouseButton &= ~BUTTON_LEFT;
509       break;
510     case 2:
511       e->m_MouseBHistory[e->m_Histptr] &= ~BUTTON_MIDDLE;
512       e->m_mouseButton &= ~BUTTON_MIDDLE;
513       break;
514     case 3:
515       e->m_MouseBHistory[e->m_Histptr] &= ~BUTTON_RIGHT;
516       e->m_mouseButton &= ~BUTTON_RIGHT;
517       break;
518     }
519   }
520 
521   e->m_MouseXHistory[e->m_Histptr] = x;
522   e->m_MouseYHistory[e->m_Histptr] = y;
523 }
524 
525 void
CopyPlayerData(Player & dest,Player * src)526 CopyPlayerData( Player& dest, Player* src ) {
527   if ( !src )
528     return;
529 
530   dest = *src;
531 }
532 
533 bool
GetExternalData(ExternalData * & ext,long side)534 Event::GetExternalData( ExternalData *&ext, long side ) {
535   ExternalData *extNow;
536 
537   if ( !(extNow = ExternalData::ReadData( side )) )
538     return false;
539 
540   if ( ext->isNull() || ext->sec > extNow->sec ||
541 	      (ext->sec == extNow->sec && ext->count > extNow->count) ) {
542     extNow->next = ext;
543     ext = extNow;
544   } else {
545     ExternalData *extTmp = ext;
546     while ( !extTmp->next->isNull() &&
547 	    (extTmp->next->sec < extNow->sec ||
548 	    (extTmp->next->sec == extNow->sec &&
549 	     extTmp->next->count < extNow->count) ) ) {
550       extTmp = extTmp->next;
551     }
552 
553     extNow->next = extTmp->next;
554     extTmp->next = extNow;
555   }
556 
557   return true;
558 }
559 
560 bool
SendPlayer(Player * player)561 Event::SendPlayer( Player *player ) {
562   char buf[256];
563 
564   if ( m_backtrack || mode != MODE_MULTIPLAY )
565     return false;
566 
567   strncpy( buf, "PV", 2 );
568   ((MultiPlay *)Control::TheControl())->SendTime( &(buf[2]) );
569 
570   player->SendLocation( &(buf[7]) );
571 
572   send( theSocket, buf, 55, 0 );
573 
574   return true;
575 }
576 
577 bool
SendBall()578 Event::SendBall() {
579   char buf[256];
580 
581   if ( m_backtrack || mode != MODE_MULTIPLAY )
582     return false;
583 
584   strncpy( buf, "BV", 2 );
585   ((MultiPlay *)Control::TheControl())->SendTime( &(buf[2]) );
586 
587   theBall.Send( &(buf[7]) );
588 
589   send( theSocket, buf, 67, 0 );
590 
591   return true;
592 }
593 
594 bool
SendPlayerAndBall(Player * player)595 Event::SendPlayerAndBall( Player *player ) {
596   char buf[256];
597 
598   if ( m_backtrack || mode != MODE_MULTIPLAY )
599     return false;
600 
601   strncpy( buf, "PV", 2 );
602   ((MultiPlay *)Control::TheControl())->SendTime( &(buf[2]) );
603 
604   player->SendLocation( &(buf[7]) );
605 
606   strncpy( &(buf[55]), "BV", 2 );
607   ((MultiPlay *)Control::TheControl())->SendTime( &(buf[57]) );
608 
609   theBall.Send( &(buf[62]) );
610 
611   send( theSocket, buf, 122, 0 );
612 
613   return true;
614 }
615 
616 bool
BackTrack(long Histptr)617 Event::BackTrack( long Histptr ) {
618   theBall = m_BacktrackBuffer[Histptr].theBall;
619   Control::GetThePlayer()->Reset( &m_BacktrackBuffer[Histptr].thePlayer );
620   Control::GetComPlayer()->Reset( &m_BacktrackBuffer[Histptr].comPlayer );
621 
622   if ( mode == MODE_SOLOPLAY || mode == MODE_MULTIPLAY ||
623        mode == MODE_PRACTICE) {
624     ((PlayGame *)Control::TheControl())->
625       ChangeScore( m_BacktrackBuffer[Histptr].score1,
626 		   m_BacktrackBuffer[Histptr].score2 );
627   }
628 
629   m_Histptr = Histptr;
630   return true;
631 }
632 
633 void
ReadData()634 Event::ReadData() {
635   fd_set rdfds;
636   struct timeval to;
637 
638   // Caution!! exchanged with WaitForData()
639 
640   SDL_mutexP( networkMutex );
641 
642   // externalData����Ƭ�ޤ�backtrack����.
643   long btCount = 0;
644   ExternalData *externalOld;
645   long btHistptr;
646   while ( !(m_External->isNull()) ) {	// �Ť���������ΤƤ�.
647     btCount = (m_lastTime.time-m_External->sec)*100 +
648       (m_lastTime.millitm/10-m_External->count);
649     if ( btCount > MAX_HISTORY ) {
650       externalOld = m_External;
651       m_External = m_External->next;
652       delete externalOld;
653       continue;
654     }
655     if ( btCount <= MAX_HISTORY )
656       break;
657   }
658 
659   if ( !(m_External->isNull()) && btCount > 0 ) {
660     backTracks += btCount;
661     _backTrackCount++;
662 
663     btHistptr = m_Histptr - btCount;
664     if ( btHistptr < 0 )
665       btHistptr += MAX_HISTORY;
666 
667     long mtime = m_lastTime.millitm - btCount*10;
668     while ( mtime < 0 ) {
669       mtime += 1000;
670       m_lastTime.time--;
671     }
672     m_lastTime.millitm = (unsigned short)mtime;
673 
674     bool fTheBall, fThePlayer, fComPlayer;
675     fTheBall = fThePlayer = fComPlayer = false;
676 
677     BackTrack( btHistptr );
678 
679     // Ŭ�Ѥ��� -> �ʤ���btCount�����֤�
680     while (1) {
681       if ( fTheBall )
682 	theBall.Move();
683 
684       if ( fThePlayer )
685 	Control::GetThePlayer()->Move( m_KeyHistory, m_MouseXHistory,
686 				       m_MouseYHistory, m_MouseBHistory,
687 				       m_Histptr );
688 
689       if ( fComPlayer )
690 	Control::GetComPlayer()->Move( NULL, NULL, NULL, NULL, 0 );
691 
692       while ( !(m_External->isNull()) &&
693 	      m_External->sec == m_lastTime.time &&
694 	      m_External->count == m_lastTime.millitm/10 ) {
695 	Player *targetPlayer;
696 	if ( m_External->side == Control::GetThePlayer()->GetSide() )
697 	  targetPlayer = Control::GetThePlayer();
698 	else if ( m_External->side == Control::GetComPlayer()->GetSide() )
699 	  targetPlayer = Control::GetComPlayer();
700 	else {
701 	  xerror("%s(%d) ExternalData", __FILE__, __LINE__);
702 	  exit(1);
703 	}
704 
705 	m_External->Apply( targetPlayer, fThePlayer, fComPlayer, fTheBall );
706 
707 	externalOld = m_External;
708 	m_External = m_External->next;
709 	delete externalOld;
710       }
711 
712       m_Histptr++;
713       if ( m_Histptr == MAX_HISTORY )
714 	m_Histptr = 0;
715 
716       if ( fTheBall ) {
717 	m_BacktrackBuffer[m_Histptr].theBall = theBall;
718 	if ( mode == MODE_SOLOPLAY || mode == MODE_MULTIPLAY ||
719 	     mode == MODE_PRACTICE ) {
720 	  m_BacktrackBuffer[m_Histptr].score1 =
721 	    ((PlayGame *)Control::TheControl())->GetScore(1);
722 	  m_BacktrackBuffer[m_Histptr].score2 =
723 	    ((PlayGame *)Control::TheControl())->GetScore(-1);
724 	}
725       }
726       if ( fThePlayer )
727 	CopyPlayerData( m_BacktrackBuffer[m_Histptr].thePlayer,
728 			Control::GetThePlayer() );
729       if ( fComPlayer )
730 	CopyPlayerData( m_BacktrackBuffer[m_Histptr].comPlayer,
731 			Control::GetComPlayer() );
732 
733       m_lastTime.millitm += 10;
734       if ( m_lastTime.millitm >= 1000 ) {
735 	m_lastTime.millitm -= 1000;
736 	m_lastTime.time++;
737       }
738 
739       btCount--;
740       if ( btCount <= 0 )
741 	break;
742     }
743 
744     if (!fTheBall) {
745       theBall = m_BacktrackBuffer[m_Histptr].theBall;
746       ((PlayGame *)Control::TheControl())->
747 	ChangeScore( m_BacktrackBuffer[m_Histptr].score1,
748 		     m_BacktrackBuffer[m_Histptr].score2 );
749     }
750     if (!fThePlayer)
751       Control::GetThePlayer()->Reset(&m_BacktrackBuffer[m_Histptr].thePlayer);
752     if (!fComPlayer)
753       Control::GetComPlayer()->Reset(&m_BacktrackBuffer[m_Histptr].comPlayer);
754   }
755 
756   SDL_mutexV( networkMutex );
757 }
758 
759 void
ReadSelectData()760 Event::ReadSelectData() {
761   fd_set rdfds;
762   struct timeval to;
763   bool dum;
764   ExternalData *externalOld;
765 
766   SDL_mutexP( networkMutex );
767 
768   while ( !(m_External->isNull()) ) {
769     if ( m_External->dataType != DATA_PT )  // Selection is already finished
770       break;
771 
772     m_External->Apply( NULL, dum, dum, dum );
773 
774     externalOld = m_External;
775     m_External = m_External->next;
776     delete externalOld;
777   }
778 
779   SDL_mutexV( networkMutex );
780 }
781 
782 void
ClearBacktrack()783 Event::ClearBacktrack() {
784   Ball aBall;
785 
786   for ( int i = 0 ; i < MAX_HISTORY ; i++ ) {
787     Event::TheEvent()->m_MouseXHistory[i] = 0;
788     Event::TheEvent()->m_MouseYHistory[i] = 0;
789     Event::TheEvent()->m_MouseBHistory[i] = 0;
790     Event::TheEvent()->m_BacktrackBuffer[i].sec = m_lastTime.time;
791     Event::TheEvent()->m_BacktrackBuffer[i].count = m_lastTime.millitm/10;
792     Event::TheEvent()->m_BacktrackBuffer[i].theBall = aBall;
793     CopyPlayerData( Event::TheEvent()->m_BacktrackBuffer[i].thePlayer,
794 		    Control::GetThePlayer() );
795     CopyPlayerData( Event::TheEvent()->m_BacktrackBuffer[i].comPlayer,
796 		    Control::GetComPlayer() );
797 
798     Event::TheEvent()->m_BacktrackBuffer[i].score1 = 0;
799     Event::TheEvent()->m_BacktrackBuffer[i].score2 = 0;
800   }
801 }
802 
803 void
QuitGame()804 QuitGame() {
805 #ifdef LOGGING
806   Event::TheEvent()->Event::RemainingLog();
807 #endif
808 
809   printf( _("Avg = %f\n"), (double)perfs/_perfCount );
810   if (_backTrackCount) printf( _("BackTrack = %f\n"), backTracks/_backTrackCount);
811 
812   Event::TheEvent()->m_lastTime.time = 0;
813   _perfCount = 0;
814   perfs = 0;
815   backTracks = 0;
816   _backTrackCount = 0;
817 
818   SDL_WM_GrabInput( SDL_GRAB_OFF );
819 
820   SDL_Event e;
821   e.type = SDL_QUIT;
822   SDL_PushEvent( &e );
823 }
824 
825 void
SetNextMousePointer(long & x,long & y)826 Event::SetNextMousePointer( long &x, long &y ) {
827   if ( mode == MODE_TITLE ) {
828     return;
829   } else if ( mode == MODE_SELECT || mode == MODE_TRAININGSELECT ||
830 	      mode == MODE_PRACTICESELECT || mode == MODE_MULTIPLAYSELECT ) {
831     x = BaseView::GetWinWidth()/2 + (x-BaseView::GetWinWidth()/2)*15/16;
832   } else {
833     x = BaseView::GetWinWidth()/2 + (x-BaseView::GetWinWidth()/2)*15/16;
834     y = BaseView::GetWinHeight()/2 + (y-BaseView::GetWinHeight()/2)*15/16;
835   }
836 }
837 
838 #ifdef LOGGING
839 void
GetAdjustedTime(long & sec,long & cnt)840 Event::GetAdjustedTime( long &sec, long &cnt ) {
841   if ( isComm )
842     //cnt += ((MultiPlay *)Control::TheControl())->GetTimeAdj();
843     cnt += timeAdj;
844   while ( cnt < 0 ) {
845     sec--;
846     cnt += 100;
847   }
848   while ( cnt >= 100 ) {
849     sec++;
850     cnt -= 100;
851   }
852 }
853 
854 void
RemainingLog()855 Event::RemainingLog() {
856   Logging::GetLogging()->Log( LOG_ACTBALL, "Quit Game\n" );
857   for ( int i = 0 ; i < MAX_HISTORY ; i++ ) {
858     m_Histptr++;
859     if ( m_Histptr == MAX_HISTORY )
860       m_Histptr = 0;
861     struct Backtrack *bt = &(m_BacktrackBuffer[m_Histptr]);
862     long sec = bt->sec;
863     long cnt = bt->count;
864     char buf[1024];
865 
866     if ( isComm )
867       //cnt += ((MultiPlay *)Control::TheControl())->GetTimeAdj();
868       cnt += timeAdj;
869     while ( cnt < 0 ) {
870       sec--;
871       cnt += 100;
872     }
873     while ( cnt >= 100 ) {
874       sec++;
875       cnt -= 100;
876     }
877 
878     sprintf( buf, "sec = %d msec = %d %d - %d  x = %4.2f y = %4.2f z = %4.2f st = %d %d\n",
879              sec, cnt,
880              bt->score1, bt->score2,
881              bt->theBall.GetX(),
882              bt->theBall.GetY(),
883              bt->theBall.GetZ(),
884              bt->theBall.GetStatus(), m_Histptr );
885     Logging::GetLogging()->Log( LOG_ACTBALL, buf );
886   }
887 }
888 
889 #endif
890 
891 bool
GetExternalData(long side)892 Event::GetExternalData( long side ) {
893   return GetExternalData( m_External, side );
894 }
895