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