1 /*
2  * xsystem35.c  SYSTEM35 �ǥ�����
3  *
4  * Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
5  *               1998-                           <masaki-c@is.aist-nara.ac.jp>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21 */
22 /* $Id: xsystem35.c,v 1.77 2003/11/16 15:29:52 chikama Exp $ */
23 
24 #include "config.h"
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <unistd.h>
31 #include <signal.h>
32 #include <sys/types.h>
33 #include <dirent.h>
34 #include <ctype.h>
35 
36 #ifdef ENABLE_GTK
37 #  define GTK_RC_NAME ".gtk/gtkrc"
38 #  include <gtk/gtk.h>
39 #endif
40 
41 #ifdef HAVE_MKDTEMP
42 #include <stdlib.h>
43 #else
44 extern char *mkdtemp (char *template);
45 #endif
46 
47 
48 #include "nact.h"
49 #include "portab.h"
50 #include "xsystem35.h"
51 #include "nact.h"
52 #include "profile.h"
53 #include "randMT.h"
54 #include "counter.h"
55 #include "ags.h"
56 #include "graphicsdevice.h"
57 #include "menu.h"
58 #include "music.h"
59 #include "music_client.h"
60 #include "savedata.h"
61 #include "scenario.h"
62 #include "variable.h"
63 #include "dri.h"
64 #include "ald_manager.h"
65 #include "filecheck.h"
66 #include "joystick.h"
67 #include "s39init.h"
68 
69 #ifdef ENABLE_MMX
70 #include "haveunit.h"
71 #endif
72 
73 static char *gameResorceFile = "xsystem35.gr";
74 static void    sys35_usage(boolean verbose);
75 static void    sys35_init();
76 static void    sys35_remove();
77 static boolean sys35_initGameDataResorce();
78 static void    sys35_ParseOption(int *argc, char **argv);
79 static void    signal_handler(int sig_num);
80 static void    signal_handler_segv(int sig_num);
81 static void    check_profile();
82 static void    init_signalhandler();
83 
84 /* for debugging */
85 static FILE *fpdebuglog;
86 static int debuglv = DEBUGLEVEL;
87 int sys_nextdebuglv;
88 
89 /* game data file name */
90 static char *gamefname[DRIFILETYPEMAX][DRIFILEMAX];
91 
92 /* font name from rcfile */
93 static char *fontname[FONTTYPEMAX];
94 static char *fontname_tt[FONTTYPEMAX];
95 static boolean isjix0213_tt[FONTTYPEMAX];
96 static char fontface[FONTTYPEMAX];
97 
98 #ifdef ENABLE_EDL
99 static fontdev_t fontdev = FONT_GTK;
100 #else
101 static fontdev_t fontdev = FONT_X11;
102 #endif
103 
104 /* antialias on from command line */
105 static boolean font_antialias;
106 static boolean font_noantialias;
107 
108 /* fullscreen on from command line */
109 static boolean fs_on;
110 
111 // for reboot
112 static int saved_argc;
113 static char **saved_argv;
114 
sys35_usage(boolean verbose)115 static void sys35_usage(boolean verbose) {
116 	if (verbose) {
117 		puts("System35 for X Window System [proj. Rainy Moon]");
118 		puts("             (C) Masaki Chikama(Wren) 1997-2002");
119 		puts("                                  Version "VERSION"\n");
120 	}
121 	puts("Usage: xsystem35 [OPTIONS]\n");
122 	puts("OPTIONS");
123 	puts(" -gamefile file : set game resouce file to 'file'");
124 	puts(" -no-shm        : don't use MIT-SHM (use in another display)");
125 	puts(" -devcd device  : set cdrom device name to 'device'");
126 	puts(" -devmidi device: set midi device name to 'device'");
127 	puts(" -devdsp device : set audio device name to 'device'");
128 
129 #ifdef ENABLE_OSS
130 	puts("                :  /dev/dsp : oss type (device name)");
131 #endif
132 #ifdef ENABLE_ALSA
133 #ifdef ENABLE_ALSA05
134 	puts("                :  0:0      : alsa type (card and device)");
135 #endif
136 #ifdef ENABLE_ALSA09
137 	puts("                :  hw:0,0   : alsa hardware");
138 #endif
139 #endif
140 
141 	puts(" -O?            : select output audio device");
142 #ifdef ENABLE_OSS
143 	puts(" -Oo            : OSS mode");
144 #endif
145 #ifdef ENABLE_ALSA
146 	puts(" -Os            : ALSA mode");
147 #endif
148 #ifdef ENABLE_ESD
149 	puts(" -Oe            : Enlightened Sound Daemon mode");
150 #endif
151 	puts(" -O0            : Disable Audio output");
152 
153 	puts(" -M?            : select output midi methos");
154 #ifdef ENABLE_MIDI_EXTPLAYER
155 	puts(" -Me            : External midi player");
156 #endif
157 #ifdef ENABLE_MIDI_RAWMIDI
158 	puts(" -Mr            : Raw Midi device");
159 #endif
160 #ifdef ENABLE_MIDI_SEQMIDI
161 	puts(" -Ms?           : Sequenceer device (?:devicenumber)");
162 #endif
163 	puts(" -M0            : Disable MIDI output");
164 	puts(" -midiplayer cmd: set external midi player to 'cmd'");
165 
166 	puts(" -devmix device : set mixer device name to 'device' (effective only for oss)");
167 	puts(" -devjoy device : set joystic device name to 'device'");
168 	puts("                    if 'device' is set to 'none', don't use the device");
169 	puts(" -savekanji #   : kanji code of filename (0 or 1 ... 0:euc, 1:sjis)");
170 #ifdef DEBUG
171 
172 	puts(" -devfont device: select font device");
173 #if defined(ENABLE_TTF) || defined(ENABLE_FT2)
174 	puts(" -devfont ttf   : FreerType (True Type Font)");
175 #endif
176 #ifdef ENABLE_X11FONT
177 	puts(" -devfont x11   : x11");
178 #endif
179 #ifdef ENABLE_GTKFONT
180 	puts(" -devfont gtk   : gtk");
181 #endif
182 
183 #ifdef ENABLE_EDL
184 #ifdef ENABLE_GTK
185 	puts("                : default is gtk");
186 #else
187 	puts("                : default is ttf");
188 #endif
189 #else
190 	puts("                : default is x11");
191 #endif
192 
193 #if defined(ENABLE_TTF) || defined(ENABLE_SDLTTF) || defined(ENABLE_FT2)
194 	puts(" -ttfont_mincho: set TrueType font for mincho");
195 	puts(" -ttfont_gothic: set TrueType font for mincho");
196 #endif
197 	puts(" -font_mincho  : set X11(gtk) font for mincho");
198 	puts(" -font_gothic  : set X11(gtk) font for mincho");
199 
200 	puts(" -debuglv #     : debug level");
201 	puts("                :  0: critical error message only ");
202 	puts("                :  1: + waring message");
203 	puts("                :  2: + not implemented command message");
204 	puts("                :  5: + implemented command (write to logfile)");
205 	puts("                :  6: + message (write to logfile)");
206 #endif
207 	puts(" -antialias     : always draw antialiased string (for !256 colors game)");
208 	puts(" -noantialias   : nevser use antialiased string (for !256 colors game)");
209 	puts(" -fullscreen    : start with fullscreen");
210 	puts(" -noimagecursor : disable image cursor");
211 	puts(" -version       : show version");
212 	puts(" -h             : show this message");
213 	puts(" --help         : show this message");
214 	exit(1);
215 }
216 
sys_message(char * format,...)217 void sys_message(char *format, ...) {
218 	va_list args;
219 
220 	va_start(args, format);
221 #ifdef DEBUG
222 	if (debuglv >= sys_nextdebuglv) {
223 		if (sys_nextdebuglv >= 5) {
224 			vfprintf(fpdebuglog, format, args);
225 			fflush(fpdebuglog);
226 		} else {
227 			vfprintf(stderr, format, args);
228 		}
229 	}
230 #else
231 	if (debuglv >= sys_nextdebuglv) {
232 		vfprintf(stderr, format, args);
233 	}
234 #endif
235 	va_end(args);
236 
237 }
238 
sys_error(char * format,...)239 void sys_error(char *format, ...) {
240 	va_list args;
241 
242 	va_start(args, format);
243 	vfprintf(stderr, format, args);
244 	va_end(args);
245 	sys35_remove();
246 	exit(1);
247 }
248 
sys_exit(int code)249 void sys_exit(int code) {
250 	sys35_remove();
251 	exit(code);
252 }
253 
check_fontdev(char * devname)254 static int check_fontdev(char *devname) {
255 #ifdef ENABLE_TTF
256 	if (0 == strcmp(devname, "ttf")) {
257 		return FONT_TTF;
258 	}
259 #endif
260 
261 #ifdef ENABLE_FT2
262 	if (0 == strcmp(devname, "ft2")) {
263 		return FONT_FT2;
264 	}
265 	if (0 == strcmp(devname, "ttf")) {
266 		return FONT_FT2;
267 	}
268 #endif
269 
270 #ifdef ENABLE_X11FONT
271 	if (0 == strcmp(devname, "x11")) {
272 		return FONT_X11;
273 	}
274 #endif
275 
276 #ifdef ENABLE_GTKFONT
277 	if (0 == strcmp(devname, "gtk")) {
278 		return FONT_GTK;
279 	}
280 #endif
281 
282 #ifdef ENABLE_SDL
283 #ifdef ENABLE_GTK
284 	return FONT_GTK;
285 #else
286 	return FONT_TTF;
287 #endif
288 #else
289 	return FONT_X11;
290 #endif
291 }
292 
storeDataName(int type,int no,char * src)293 static void storeDataName(int type, int no, char *src) {
294 	gamefname[type][no] = strdup(src);
295 }
296 
storeSaveName(int no,char * src)297 static void storeSaveName(int no, char *src) {
298 	char *home_dir = "";
299 	char *path = NULL;
300 
301 	if (*src == '~') {
302 		home_dir = getenv("HOME");
303 		if (NULL == (path = malloc(strlen(home_dir) + strlen(src) + 1))) {
304 			NOMEMERR();
305 		}
306 		sprintf(path, "%s%s", home_dir, src+1);
307 		save_register_file(path, no);
308 		src = path;
309 	} else {
310 		save_register_file(src, no);
311 	}
312 
313 	if (no == 0) {
314 		char *b = strrchr(src, '/');
315 		if (b == NULL) {
316 			SYSERROR("Illigal save filename %s\n", src);
317 		}
318 		*b = '\0';
319 		save_set_path(src);
320 	}
321 	if (path) free(path);
322 }
323 
324 /* ������Υǡ����ե�����ξ����ǥ��쥯�ȥ꤫����� thanx tajiri@wizard*/
sys35_initGameDataDir(int * cnt)325 static boolean sys35_initGameDataDir(int* cnt)
326 {
327     DIR* dir;
328     struct dirent* d;
329     char s1[256], s2[256];
330     int dno;
331     int i;
332 
333     getcwd(s1,255);
334     if(NULL == (dir= opendir(".")))
335     {
336         SYSERROR("Game Resouce File open failed\n");
337     }
338     while(NULL != (d = readdir(dir))){
339         char *filename = d->d_name;
340         int len = strlen(filename);
341         sprintf(s2,"%s%c%s",s1,'/',filename);
342         if(strcasecmp(filename,"adisk.ald")==0){
343             storeDataName(DRIFILE_SCO, 0, s2);
344             cnt[0] = max(1, cnt[0]);
345         } else if (strcasecmp(filename, "system39.ain") == 0) {
346 		nact->ain.path_to_ain = strdup(filename);
347 	}
348         else if(strcasecmp(filename+len-4,".ald")==0){
349             dno = toupper(*(filename+len-5)) - 'A';
350             if (dno < 0 || dno >= DRIFILEMAX) continue;
351             switch(*(filename+len-6)){
352                 case 'S':
353                 case 's':
354                     storeDataName(DRIFILE_SCO, dno, s2);
355                     cnt[0] = max(dno + 1, cnt[0]);
356                     break;
357                 case 'g':
358                 case 'G':
359                     storeDataName(DRIFILE_CG, dno, s2);
360                     cnt[1] = max(dno + 1, cnt[1]);
361                     break;
362                 case 'W':
363                 case 'w':
364                     storeDataName(DRIFILE_WAVE, dno, s2);
365                     cnt[2] = max(dno + 1, cnt[2]);
366                     break;
367                 case 'M':
368                 case 'm':
369                     storeDataName(DRIFILE_MIDI, dno, s2);
370                     cnt[3] = max(dno + 1, cnt[3]);
371                     break;
372                 case 'D':
373                 case 'd':
374                     storeDataName(DRIFILE_DATA, dno, s2);
375                     cnt[4] = max(dno + 1, cnt[4]);
376                     break;
377                 case 'R':
378                 case 'r':
379                     storeDataName(DRIFILE_RSC, dno, s2);
380                     cnt[5] = max(dno + 1, cnt[5]);
381                     break;
382 
383             }
384         }
385     }
386     for(i=0;i<SAVE_MAXNUMBER;i++){
387         sprintf(s2,"%s/%c%s",s1,'a'+i,"sleep.asd");
388         storeSaveName(i, s2);
389     }
390 
391     if(cnt[0]>0)
392         return TRUE;
393     else
394         return FALSE;
395 }
396 
397 
398 /* ������Υǡ����ե�����ξ�����ɤ߹��� */
sys35_initGameDataResorce()399 static boolean sys35_initGameDataResorce() {
400 	int cnt[] = {0, 0, 0, 0, 0, 0, 0};
401 	int linecnt = 0, dno;
402 	FILE *fp;
403 	char s[256];
404 	char s1[256], s2[256];
405 
406 	if (NULL == (fp = fopen(gameResorceFile, "r"))) {
407 		if(sys35_initGameDataDir(cnt)==TRUE) {
408 			goto initdata;
409 		}
410 		sys35_usage(TRUE);
411 	}
412 	while(fgets(s, 255, fp) != NULL ) {
413 		linecnt++;
414 		if (s[0] == '#') continue;
415 		s2[0] = '\0';
416 		sscanf(s,"%s %s", s1, s2);
417 		if (s2[0] == '\0') continue;
418 		if (0 == strncmp(s1, "Scenario", 8)) {
419 			dno = s1[8] - 'A';
420 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
421 			storeDataName(DRIFILE_SCO, dno, s2);
422 			cnt[0] = max(dno + 1, cnt[0]);
423 		} else if (0 == strncmp(s1, "Graphics", 8)) {
424 			dno = s1[8] - 'A';
425 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
426 			storeDataName(DRIFILE_CG, dno, s2);
427 			cnt[1] = max(dno + 1, cnt[1]);
428 		} else if (0 == strncmp(s1, "Wave", 4)) {
429 			dno = s1[4] - 'A';
430 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
431 			storeDataName(DRIFILE_WAVE, dno, s2);
432 			cnt[2] = max(dno + 1, cnt[2]);
433 		} else if (0 == strncmp(s1, "Midi", 4)) {
434 			dno = s1[4] - 'A';
435 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
436 			storeDataName(DRIFILE_MIDI, dno, s2);
437 			cnt[3] = max(dno + 1, cnt[3]);
438 		} else if (0 == strncmp(s1, "Data", 4)) {
439 			dno = s1[4] - 'A';
440 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
441 			storeDataName(DRIFILE_DATA, dno, s2);
442 			cnt[4] = max(dno + 1, cnt[4]);
443 		} else if (0 == strncmp(s1, "Resource", 8)) {
444 			dno = s1[8] - 'A';
445 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
446 			storeDataName(DRIFILE_RSC, dno, s2);
447 			cnt[5] = max(dno + 1, cnt[5]);
448 		} else if (0 == strncmp(s1, "BGM", 3)) {
449 			dno = s1[3] - 'A';
450 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
451 			storeDataName(DRIFILE_BGM, dno, s2);
452 			cnt[6] = max(dno + 1, cnt[6]);
453 		} else if (0 == strncmp(s1, "Save", 4)) {
454 			dno = s1[4] - 'A';
455 			if (dno < 0 || dno >= DRIFILEMAX) goto errexit;
456 			storeSaveName(dno, s2);
457 		} else if (0 == strncmp(s1, "Ain", 3)) {
458 			nact->ain.path_to_ain = strdup(s2);
459 		} else if (0 == strncmp(s1, "WAIA", 4)) {
460 			nact->files.wai = strdup(s2);
461 		} else if (0 == strncmp(s1, "BGIA", 4)) {
462 			nact->files.bgi = strdup(s2);
463 		} else if (0 == strncmp(s1, "SACT01", 6)) {
464 			nact->files.sact01 = strdup(s2);
465 		} else if (0 == strncmp(s1, "Init", 4)) {
466 			nact->files.init = strdup(s2);
467 		} else if (0 == strncmp(s1, "ALK", 3)) {
468 			dno = s1[4] - '0';
469 			if (dno < 0 || dno >= 10) goto errexit;
470 			nact->files.alk[dno] = strdup(s2);
471 		} else {
472 			goto errexit;
473 		}
474 	}
475 	fclose(fp);
476 initdata:
477 	if (cnt[0] == 0) {
478 		SYSERROR("No Scenario data available\n");
479 	}
480 
481 	if (cnt[0] > 0)
482 		ald_init(DRIFILE_SCO, gamefname[DRIFILE_SCO], cnt[0], TRUE);
483 	if (cnt[1] > 0)
484 		ald_init(DRIFILE_CG,  gamefname[DRIFILE_CG], cnt[1], TRUE);
485 	if (cnt[2] > 0)
486 		ald_init(DRIFILE_WAVE, gamefname[DRIFILE_WAVE], cnt[2], TRUE);
487 	if (cnt[3] > 0)
488 		ald_init(DRIFILE_MIDI, gamefname[DRIFILE_MIDI], cnt[3], TRUE);
489 	if (cnt[4] > 0)
490 		ald_init(DRIFILE_DATA, gamefname[DRIFILE_DATA], cnt[4], TRUE);
491 	if (cnt[5] > 0)
492 		ald_init(DRIFILE_RSC, gamefname[DRIFILE_RSC], cnt[5], TRUE);
493 	if (cnt[6] > 0)
494 		ald_init(DRIFILE_BGM, gamefname[DRIFILE_BGM], cnt[6], TRUE);
495 
496 	return 0;
497 
498  errexit:
499 	SYSERROR("Illigal resouce at line(%d) file<%s>\n",linecnt, gameResorceFile);
500 	return 0;
501 }
502 
sys35_init()503 static void sys35_init() {
504 	int i;
505 
506 	nact_init();
507 
508 	sl_init();
509 
510 	v_initVars();
511 
512 	nact->fontdev = fontdev;
513 
514 	ags_init();
515 
516 	for (i = 0; i < FONTTYPEMAX; i++) {
517 		switch(fontdev) {
518 		case FONT_TTF:
519 		case FONT_FT2:
520 		case FONT_SDLTTF:
521 			if (fontname_tt[i] == NULL) {
522 				nact->ags.font->name[i] = strdup(FONT_DEFAULTNAME_TTF);
523 			} else {
524 				nact->ags.font->name[i] = fontname_tt[i];
525 			}
526 			nact->ags.font->isJISX0213[i] = isjix0213_tt[i];
527 			nact->ags.font->face[i] = fontface[i];
528 			break;
529 
530 		case FONT_X11:
531 		case FONT_GTK:
532 			if (fontname[i] == NULL) {
533 				nact->ags.font->name[i] = strdup(FONT_DEFAULTNAME_X);
534 			} else {
535 				nact->ags.font->name[i] = fontname[i];
536 			}
537 			break;
538 		default:
539 			break;
540 		}
541 	}
542 
543 	ags_fullscreen(fs_on);
544 	nact->noantialias = font_noantialias;
545 	ags_setAntialiasedStringMode(font_antialias);
546 
547 
548 	reset_counter(0);
549 
550 	sgenrand(getpid());
551 
552 #ifdef ENABLE_MMX
553 	nact->mmx_is_ok = ((haveUNIT() & tMMX) ? TRUE : FALSE);
554 #endif
555 
556 	msg_init();
557 	sel_init();
558 
559 	s39ain_init();
560 	s39ini_init();
561 }
562 
sys35_remove()563 static void sys35_remove() {
564 	mus_exit();
565 	ags_remove();
566 	s39ini_remove();
567 	/* joy_close(); */
568 #if DEBUG
569 	if (debuglv >= 3) {
570 		fclose(fpdebuglog);
571 	}
572 #endif
573 	if (0 != strcmp(nact->tmpdir, "/tmp")) {
574 		rmdir(nact->tmpdir);
575 	}
576 }
577 
sys_reset()578 void sys_reset() {
579 	mus_exit();
580 	ags_remove();
581 	s39ini_remove();
582 
583 	if (0 != strcmp(nact->tmpdir, "/tmp")) {
584 		rmdir(nact->tmpdir);
585 	}
586 
587 	execvp(saved_argv[0], saved_argv);
588 	sys_error("exec fail");
589 }
590 
signal_handler(int sig_num)591 static void signal_handler(int sig_num) {
592 	sys35_remove();
593 	exit(1);
594 }
595 
signal_handler_segv(int sig_num)596 static void signal_handler_segv(int sig_num) {
597 	fprintf(stderr, "PID(%d), sigsegv caught @ %03d, %05x\n", (int)getpid(), sl_getPage(), sl_getIndex());
598 	sys35_remove();
599 	exit(1);
600 }
601 
sys35_ParseOption(int * argc,char ** argv)602 static void sys35_ParseOption(int *argc, char **argv) {
603 	int i;
604 	FILE *fp;
605 	for (i = 1; i < *argc; i++) {
606 		if (!strcmp(argv[i], "-h")) {
607 			sys35_usage(TRUE);
608 		}
609 		if (!strcmp(argv[i], "--help")) {
610 			sys35_usage(TRUE);
611 		}
612 	}
613 	for (i = 1; i < *argc; i++) {
614 		if (0 == strcmp(argv[i], "-gamefile")) {
615 			if (i == *argc - 1) {
616 				fprintf(stderr, "xsystem35: The -gamefile option requires file value\n\n");
617 				sys35_usage(FALSE);
618 			}
619 			if (NULL == (fp = fopen(argv[i + 1],"r"))) {
620 				fprintf(stderr, "xsystem35: gamefile '%s' not found\n\n", argv[i + 1]);
621 				sys35_usage(FALSE);
622 			}
623 			fclose(fp);
624 			gameResorceFile = argv[i + 1];
625 		} else if (0 == strcmp(argv[i], "-no-shm")) {
626 			SetNoShmMode();
627 		} else if (0 == strcmp(argv[i], "-devcd")) {
628 			if (argv[i + 1] != NULL) {
629 				cd_set_devicename(argv[i + 1]);
630 			}
631 		} else if (0 == strcmp(argv[i], "-devmidi")) {
632 			if (argv[i + 1] != NULL) {
633 				midi_set_devicename(argv[i + 1]);
634 			}
635 		} else if (0 == strcmp(argv[i], "-midiplayer")) {
636 			if (argv[i + 1] != NULL) {
637 				midi_set_playername(argv[i + 1]);
638 			}
639 		} else if (0 == strncmp(argv[i], "-M", 2)) {
640 			int subdev = 0;
641 			if (argv[i][3] != '\0') {
642 				subdev = (argv[i][3] - '0') << 8;
643 			}
644 			midi_set_output_device(argv[i][2] | subdev);
645 		} else if (0 == strcmp(argv[i], "-devdsp")) {
646 			if (argv[i + 1] != NULL) {
647 				audio_set_pcm_devicename(argv[i + 1]);
648 			}
649 		} else if (0 == strncmp(argv[i], "-O", 2)) {
650 			audio_set_output_device(argv[i][2]);
651 		} else if (0 == strcmp(argv[i], "-devmix")) {
652 			if (argv[i + 1] != NULL) {
653 				audio_set_mixer_devicename(argv[i + 1]);
654 			}
655 		} else if (0 == strcmp(argv[i], "-devjoy")) {
656 			if (argv[i + 1] != NULL) {
657 				joy_set_devicename(argv[i + 1]);
658 			}
659 		} else if (0 == strcmp(argv[i], "-savekanji")) {
660 			if (argv[i + 1] != NULL) {
661 				fc_set_default_kanjicode(argv[i + 1][0] - '0');
662 			}
663 		} else if (0 == strcmp(argv[i], "-fullscreen")) {
664 			fs_on = TRUE;
665 		} else if (0 == strcmp(argv[i], "-antialias")) {
666 			font_antialias = TRUE;
667 		} else if (0 == strcmp(argv[i], "-noantialias")) {
668 			font_noantialias = TRUE;
669 		} else if (0 == strcmp(argv[i], "-devfont")) {
670 			if (argv[i + 1] != NULL) {
671 				fontdev = check_fontdev(argv[i + 1]);
672 			}
673 		} else if (0 == strcmp(argv[i], "-font_gothic")) {
674 			if (argv[i + 1] != NULL) {
675 				fontname[FONT_GOTHIC] = argv[i + 1];
676 			}
677 		} else if (0 == strcmp(argv[i], "-font_mincho")) {
678 			if (argv[i + 1] != NULL) {
679 				fontname[FONT_MINCHO] = argv[i + 1];
680 			}
681 		} else if (0 == strcmp(argv[i], "-ttfont_gothic")) {
682 			if (argv[i + 1] != NULL) {
683 				fontname_tt[FONT_GOTHIC] = argv[i + 1];
684 			}
685 		} else if (0 == strcmp(argv[i], "-ttfont_mincho")) {
686 			if (argv[i + 1] != NULL) {
687 				fontname_tt[FONT_MINCHO] = argv[i + 1];
688 			}
689 		} else if (0 == strcmp(argv[i], "-noimagecursor")) {
690 			nact->noimagecursor = TRUE;
691 		} else if (0 == strcmp(argv[i], "-debuglv")) {
692 			if (argv[i + 1] != NULL) {
693 				debuglv = argv[i + 1][0] - '0';
694 			}
695 		} else if (0 == strcmp(argv[i], "-version")) {
696 			puts(VERSION);
697 			exit(0);
698 		}
699 	}
700 }
701 
check_profile()702 static void check_profile() {
703 	char *param;
704 
705 	/* �ե���ȥǥХ��������� */
706 	param = get_profile("font_device");
707 	if (param) {
708 		fontdev = check_fontdev(param);
709 	}
710 	/* �����å��ե���Ȥ����� */
711 	param = get_profile("font_gothic");
712 	if (param) {
713 		fontname[FONT_GOTHIC] = param;
714 	}
715 	/* ��ī�ե���Ȥ����� */
716 	param = get_profile("font_mincho");
717 	if (param) {
718 		fontname[FONT_MINCHO] = param;
719 	}
720 	/* �����å��ե����(TT)������ */
721 	param = get_profile("ttfont_gothic");
722 	if (param) {
723 		fontname_tt[FONT_GOTHIC] = param;
724 	}
725 	/* ��ī�ե����(TT)������ */
726 	param = get_profile("ttfont_mincho");
727 	if (param) {
728 		fontname_tt[FONT_MINCHO] = param;
729 	}
730 	/* �����å��ե����(TT)�Υ��������� */
731 	param = get_profile("ttfont_gothic_code");
732 	if (param) {
733 		isjix0213_tt[FONT_GOTHIC] = (strcmp("jisx0213",param) == 0 ? TRUE : FALSE);
734 	}
735 	/* ��ī�ե����(TT)�Υ��������� */
736 	param = get_profile("ttfont_mincho_code");
737 	if (param) {
738 		isjix0213_tt[FONT_MINCHO] = (strcmp("jisx0213",param) == 0 ? TRUE : FALSE);
739 	}
740 	/* �����å��ե����(TT)�Υե��������� */
741 	param = get_profile("ttfont_gothic_face");
742 	if (param) {
743 		fontface[FONT_GOTHIC] = *param - '0';
744 	}
745 	/* ��ī�ե����(TT)�Υե��������� */
746 	param = get_profile("ttfont_mincho_face");
747 	if (param) {
748 		fontface[FONT_MINCHO] = *param - '0';
749 	}
750 	/* CD-ROM device name ������ */
751 	param = get_profile("cdrom_device");
752 	if (param) {
753 		cd_set_devicename(param);
754 	}
755 	/* DSP device name ������ */
756 	param = get_profile("dsp_device");
757 	if (param) {
758 		audio_set_pcm_devicename(param);
759 	}
760 	/* mixer device name ������ */
761 	param = get_profile("mixer_device");
762 	if (param) {
763 		audio_set_mixer_devicename(param);
764 	}
765 	/* audio output device ������ */
766 	param = get_profile("audio_output_device");
767 	if (param) {
768 		audio_set_output_device(*param);
769 	}
770 	/* joystick device name ������ */
771 	param = get_profile("joy_device");
772 	if (param) {
773 		joy_set_devicename(param);
774 	}
775 	/* ����MIDI�ץ졼�䡼������ */
776 	param = get_profile("midi_player");
777 	if (param) {
778 		midi_set_playername(param);
779 	}
780 	/* Raw MIDI device name ������ */
781 	param = get_profile("midi_device");
782 	if (param) {
783 		midi_set_devicename(param);
784 	}
785 	/* MIDI output device ������ */
786 	param = get_profile("midi_output_device");
787 	if (param) {
788 		int subdev = 0;
789 		if (*(param+1) != '\0') {
790 			subdev = (*(param + 1) - '0') << 8;
791 		}
792 		midi_set_output_device(*param | subdev);
793 	}
794 	/* no-shm flag */
795 	param = get_profile("no_shm");
796 	if (param) {
797 		if (0 == strcmp(param, "Yes")) {
798 			SetNoShmMode();
799 		}
800 	}
801 	/* qe-kanjicode flag */
802 	param = get_profile("qe-kanjicode");
803 	if (param) {
804 		fc_set_default_kanjicode(*param - '0');
805 	}
806 	/* disable image cursor */
807 	param = get_profile("no_imagecursor");
808 	if (param) {
809 		if (0 == strcmp(param, "Yes")) {
810 			nact->noimagecursor = TRUE;
811 		}
812 	}
813 }
814 
sys_set_signalhandler(int SIG,void (* handler)(int))815 void sys_set_signalhandler(int SIG, void (*handler)(int)) {
816 	struct sigaction act;
817 	sigset_t smask;
818 
819 	sigemptyset(&smask);
820 	sigaddset(&smask, SIG);
821 
822 	act.sa_handler = handler;
823 	act.sa_mask = smask;
824 	act.sa_flags = 0;
825 
826 	sigaction(SIG, &act, NULL);
827 }
828 
init_signalhandler()829 void init_signalhandler() {
830 	sys_set_signalhandler(SIGINT, signal_handler);
831 	sys_set_signalhandler(SIGTERM, signal_handler);
832 	sys_set_signalhandler(SIGPIPE, SIG_IGN);
833 	sys_set_signalhandler(SIGABRT, signal_handler);
834 	sys_set_signalhandler(SIGSEGV, signal_handler_segv);
835 }
836 
main(int argc,char ** argv)837 int main(int argc, char **argv) {
838 	char *homedir = getenv("HOME"), *rc_name, *rc_path;
839 	sys_set_signalhandler(SIGINT, SIG_IGN);
840 
841 	saved_argc = argc;
842 	saved_argv = argv;
843 
844 	load_profile(NULL);
845 	check_profile();
846 	sys35_ParseOption(&argc, argv);
847 
848 #if DEBUG
849 	if (debuglv >= 5) {
850 		if (NULL == (fpdebuglog = fopen(DEBUGLOGFILE, "w"))) {
851 			fpdebuglog = stderr;
852 		}
853 	}
854 #endif
855 	sys35_initGameDataResorce();
856 
857 	init_signalhandler();
858 
859 	nact->tmpdir = strdup("/tmp/xsystem35-XXXXXX");
860 	if (NULL == mkdtemp(nact->tmpdir)) {
861 		free(nact->tmpdir);
862 		nact->tmpdir = strdup("/tmp");
863 	}
864 
865 	mus_init();
866 
867 #ifdef ENABLE_NLS
868         bindtextdomain (PACKAGE, LOCALEDIR);
869         textdomain(PACKAGE);
870 #endif
871 
872 #ifdef ENABLE_GTK
873 	gtk_set_locale();
874 	gtk_init(&argc, &argv);
875 #endif
876 
877 	sys35_init();
878 
879 #ifdef ENABLE_GTK
880 	rc_name = get_profile("gtkrc_path");
881 	if (!rc_name) {
882 		rc_name = GTK_RC_NAME;
883 	}
884 	rc_path = (char *)g_malloc(sizeof(char) * (strlen(homedir) + strlen(rc_name)) + 2);
885 	strcpy(rc_path, homedir);
886 	strcat(rc_path, "/");
887 	strcat(rc_path, rc_name);
888 
889 	gtk_rc_parse(rc_path);
890 	g_free(rc_path);
891 	menu_init();
892 #endif
893 
894 	nact_main();
895 	sys35_remove();
896 
897 	return 0;
898 }
899