1 /* $Id: main.cpp,v 1.86 2003/07/29 17:14:30 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 "Ball.h"
21 #include "Sound.h"
22 #include "BaseView.h"
23 #include "Player.h"
24 #include "PlayerView.h"
25 #if defined(CHIYO)
26 #include "parts.h"
27 #include "loadparts.h"
28 #endif
29 #include "Network.h"
30 #include "MultiPlay.h"
31 #include "Event.h"
32 #include "Control.h"
33 #include "Launcher.h"
34 #include "HitMark.h"
35 #include "HowtoView.h"
36 #include "RCFile.h"
37 #ifdef LOGGING
38 #include "Logging.h"
39 #endif
40 
41 #include <gtk/gtk.h>
42 #include <locale.h>
43 
44 int LoadData( void *dum );
45 
46 Ball theBall;
47 
48 int theSocket = -1;
49 bool isComm = false;		// Network Play?
50 
51 long wins	= 0;
52 
53 RCFile *theRC = RCFile::GetRCFile();
54 
55 long mode = MODE_OPENING;
56 
57 SDL_mutex *loadMutex;
58 
59 void InitGame();
60 void StartGame();
61 void EndGame();
62 bool PollEvent();
63 
64 #ifdef WIN32
65 #ifdef main
66 #undef main
67 #endif
68 
69 #ifdef __CYGWIN__
70 #include <getopt.h>
71 #else
72 #include "win32/getopt.h"
73 #endif /*__CYGWIN__*/
74 
75 static int win32ver = 0;	//0: win9x, 1: nt4 2: nt5
76 
77 #if !defined(WIN32CONSOLE)
78 #define main theMain
79 #include "win32/GetArgs.h"
80 static int theMain(int argc, char** argv);
WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR CmdLine,int nShow)81 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR CmdLine, int nShow)
82 {
83   int argc;
84   char **argv;
85 
86   GetArgs(&argc, &argv, GetCommandLine());
87   return theMain(argc, argv);
88 }
89 #endif /* WIN32CONSOLE */
90 #endif /* WIN32 */
91 
92 #define PROBE_FILE "Parts/Fnormal/Fnormal-head01.dat"
93 
main(int argc,char ** argv)94 int main(int argc, char** argv) {
95   char *dataDir = NULL;
96 
97   if ( (access( PROBE_FILE, F_OK ) == 0) ) {
98     dataDir = ".";
99   } else {
100 #if !defined(WIN32)
101 #ifdef CANNONSMASH_DATADIR
102     dataDir = CANNONSMASH_DATADIR;
103 #else
104     fprintf( stderr, _("No datafile directory.\n") );
105     exit(1);
106 #endif
107 #else
108     char *path = (char*)alloca(MAX_PATH);
109     *path = '\0';
110     GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
111     int l;
112     for (l = strlen(path); l > 0 && '\\' != path[l]; --l);
113     path[l] = '\0';
114     dataDir = path;
115 #endif
116   }
117 
118   if ( chdir( dataDir ) == -1 ) {
119     fprintf( stderr, _("No datafile directory.\n") );
120     exit(1);
121   }
122 
123   printf( "datadir = %s\n", dataDir );
124 
125     /* initialize i18n */
126 #ifdef WIN32
127     OSVERSIONINFO osver;
128     osver.dwOSVersionInfoSize = sizeof(osver);
129     GetVersionEx(&osver);
130     if (osver.dwPlatformId != VER_PLATFORM_WIN32_NT) {
131 	win32ver = 0;
132     } else if (osver.dwMajorVersion < 5) {
133 	win32ver = 1;
134     } else {
135 	win32ver = 2;
136     }
137 
138     switch (PRIMARYLANGID(GetUserDefaultLangID())) {
139     default: break;
140     case LANG_JAPANESE: putenv("LANGUAGE=ja"); break;
141     case LANG_GERMAN:	putenv("LANGUAGE=de"); break;
142     case LANG_HINDI:	putenv("LANGUAGE=hi"); break;
143     }
144 #endif
145 
146     gtk_set_locale();
147     setlocale(LC_ALL, "");
148     setlocale(LC_NUMERIC, "C");
149 
150     putenv("SDL_MOUSE_RELATIVE=0");
151 
152 #ifdef WIN32
153     char *localedir = (char*)alloca(MAX_PATH);
154     *localedir = '\0';
155 //    GetCurrentDirectory(MAX_PATH, localedir);
156     strncpy(localedir, dataDir, MAX_PATH-1);
157     strcat( localedir, "\\locale" );
158     printf("\nlocale=%s\n", localedir);
159     bindtextdomain ("csmash", localedir);
160     textdomain ("csmash");
161 
162     bind_textdomain_codeset("csmash", "UTF-8");
163 
164     *localedir = '\0';
165 //    GetCurrentDirectory(MAX_PATH, localedir);
166     strncpy(localedir, dataDir, MAX_PATH-1);
167     strcat( localedir, "\\gtk\\gtkrc" );
168     gtk_rc_add_default_file( localedir );
169 #else
170     bindtextdomain(PACKAGE, LOCALEDIR);
171     textdomain(PACKAGE);
172 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
173     bind_textdomain_codeset(PACKAGE, "UTF-8");
174 #endif
175 #endif
176 
177     int c;
178     while (EOF != (c = getopt(argc, argv, "schfS2Op:"))) {
179         switch (c) {
180         case 'h':
181 	    // brief help
182 	    printf("csmash [-s] [ip-address]");
183 	    return 0;
184 	case 's':
185 	    // Server mode
186 	    isComm = true;
187 	    mode = MODE_SELECT;
188 	    theRC->serverName[0] = '\0';
189 	    break;
190 	case 'c':
191 	    // Client mode
192 	    isComm = true;
193 	    mode = MODE_SELECT;
194 	    theRC->serverName[0] = 1;	// :-p
195 	    break;
196 	case 'p':
197 	    // set the csmash_port
198 	    theRC->csmash_port = (short)atoi(optarg);
199 	    if (0 == theRC->csmash_port) theRC->csmash_port = CSMASH_PORT;
200 	    break;
201 	case 'f':
202 	    // Fullscreen mode
203 	    theRC->fullScreen = true;
204 	    break;
205 	case 'S':
206 	    // Simple mode
207 	    theRC->gmode = GMODE_SIMPLE;
208 	    theRC->isTexture = false;
209 	    break;
210 	case '2':
211 	    // Simple mode
212 	    theRC->gmode = GMODE_2D;
213 	    mode = MODE_SELECT;
214 	    break;
215 	}
216     }
217 
218     if (!isComm && argc > optind) {
219       // Client mode
220       isComm = true;
221       mode = MODE_SELECT;
222       strncpy(theRC->serverName, argv[optind], sizeof(theRC->serverName));
223     }
224 
225   struct timeb tb;
226 #ifdef WIN32
227   ftime( &tb );
228 #else
229   struct timeval tv;
230   struct timezone tz;
231   gettimeofday( &tv, &tz );
232   tb.time = tv.tv_sec;
233   tb.millitm = tv.tv_usec/1000;
234 #endif
235 
236   srand(tb.millitm);
237 
238   EndianCheck();
239 
240   loadMutex = SDL_CreateMutex();
241   /* Threading will be disabled until locale becomes thread-safe. */
242   //SDL_CreateThread( LoadData, NULL );
243   LoadData(NULL);
244 
245   if ( mode == MODE_OPENING ) {
246     theRC->ReadRCFile();
247 
248     Launcher *launcher = new Launcher();
249     launcher->Init();
250   } else {
251     ::StartGame();
252     ::EndGame();
253   }
254 
255   return 0;
256 }
257 
258 void
StartGame()259 StartGame() {
260   try {
261     ::InitGame();
262     while ( PollEvent() );
263   } catch ( NetworkError ) {
264     ::EndGame();
265     throw NetworkError();
266   }
267   ::EndGame();
268 }
269 
270 void
InitGame()271 InitGame() {
272 #ifdef HAVE_LIBSDL_MIXER
273 //  theRC->sndMode = SOUND_SDL;
274 
275   if ( theRC->sndMode != SOUND_NONE ) {
276     if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_NOPARACHUTE) < 0 ) {
277       perror( _("SDL initialize failed\n") );
278       exit(1);
279     }
280   } else {
281     if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) {
282       perror( _("SDL initialize failed\n") );
283       exit(1);
284     }
285   }
286 #else
287   if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) {
288     perror( _("SDL initialize failed\n") );
289     exit(1);
290   }
291   theRC->sndMode = SOUND_NONE;
292 #endif
293 
294   if ( mode == MODE_OPENING && (access( OPENINGFILENAME, F_OK ) != 0) ) {
295     mode = MODE_TITLE;
296   }
297 
298 #ifdef LOGGING
299   Logging::GetLogging()->Init();
300 #endif
301 
302   Sound::TheSound()->Init( theRC->sndMode );
303   BaseView::TheView()->Init();
304 
305   SDL_EnableUNICODE(1);
306 
307 #if defined(CHIYO)
308   parts::realizeobjects();
309 #endif
310 
311   Event::TheEvent()->Init();
312 }
313 
EndGame()314 void EndGame()
315 {
316   Control::ClearControl();
317   BaseView::TheView()->QuitGame();
318   Sound::TheSound()->Clear();
319 
320   HitMark::m_textures[0] = 0;
321   HowtoView::m_textures[0] = 0;
322 
323   theSocket = -1;
324   isComm = false;
325 
326   wins = 0;
327   mode = MODE_TITLE;
328 
329 #if defined(CHIYO)
330   parts::unrealizeobjects();
331 #endif
332 
333   SDL_Quit();
334 }
335 
PollEvent()336 bool PollEvent() {
337   SDL_Event event;
338 
339   while ( SDL_PollEvent(&event) ) {
340     // Later, change GLUT-like function to SDL
341     switch ( event.type ) {
342     case SDL_KEYDOWN:
343       Event::KeyboardFunc( event, 0, 0 );
344       break;
345 
346     case SDL_KEYUP:
347       Event::KeyUpFunc( event, 0, 0 );
348       break;
349 
350     case SDL_MOUSEMOTION:
351       Event::MotionFunc( event.motion.x, event.motion.y );
352       break;
353 
354     case SDL_MOUSEBUTTONDOWN:
355     case SDL_MOUSEBUTTONUP:
356       Event::ButtonFunc( event.button.button, event.button.type,
357 			 event.motion.x, event.motion.y );
358       break;
359 
360     case SDL_QUIT:
361       return false;
362 
363     case SDL_SYSWMEVENT:
364       break;
365     }
366   }
367 
368   Event::IdleFunc();
369 
370   return true;
371 }
372 
373 int
LoadData(void * dum)374 LoadData( void *dum ) {
375   SDL_mutexP( loadMutex );
376 
377   if ( theRC->gmode != GMODE_2D )
378     PlayerView::LoadData(NULL);
379 
380   SDL_mutexV( loadMutex );
381 
382   return 0;
383 }
384