1 /***************************************************************************
2                           main.cpp  -  description
3                              -------------------
4     begin                : Fri Jun 2 2000
5     copyright            : (C) 2000 by Simon White
6     email                : s_a_white@email.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 /***************************************************************************
18  *  $Log: main.cpp,v $
19  *  Revision 1.32  2004/02/26 18:19:22  s_a_white
20  *  Updates for VC7 (use real libstdc++ headers instead of draft ones).
21  *
22  *  Revision 1.31  2004/02/12 05:58:03  s_a_white
23  *  Update argurements and help menu handling.
24  *
25  *  Revision 1.30  2003/06/27 21:09:37  s_a_white
26  *  Constified some of the interfaces.
27  *
28  *  Revision 1.29  2003/02/22 09:41:17  s_a_white
29  *  Removed endl, was in wrong location.
30  *
31  *  Revision 1.28  2003/02/20 18:50:43  s_a_white
32  *  sid2crc support.
33  *
34  *  Revision 1.27  2002/03/11 18:02:56  s_a_white
35  *  Display errors like sidplay1.
36  *
37  *  Revision 1.26  2002/01/30 00:33:00  s_a_white
38  *  Error message now multiline.
39  *
40  *  Revision 1.25  2001/12/07 18:22:33  s_a_white
41  *  Player quit fixes.
42  *
43  *  Revision 1.24  2001/12/05 22:22:48  s_a_white
44  *  Added playerFast flag.
45  *
46  *  Revision 1.23  2001/12/01 20:15:49  s_a_white
47  *  Player changed to ConsolePlayer.
48  *
49  *  Revision 1.22  2001/11/27 19:10:12  s_a_white
50  *  Restructured
51  *
52  *  Revision 1.21  2001/11/21 18:55:25  s_a_white
53  *  Sidplay2 0.8 new frontend interface.
54  *
55  *  Revision 1.19  2001/09/01 11:48:42  s_a_white
56  *  Help moved from cerr to cout.
57  *
58  *  Revision 1.18  2001/09/01 11:24:22  s_a_white
59  *  Renamed configure to config.
60  *
61  *  Revision 1.17  2001/08/20 18:29:55  s_a_white
62  *  SID Model now obtained from info structure.
63  *
64  *  Revision 1.16  2001/07/25 17:11:32  s_a_white
65  *  Support new libsidplay2 configuration interface.
66  *
67  *  Revision 1.15  2001/07/14 12:38:19  s_a_white
68  *  Added sid loop counter, to exit multi-sid tunes.  Added -b to set start
69  *  of song.  0xffff songs now get reported as sys.  Support for sidbuilder
70  *  classes.  !TODO! must tidy this file, it's getting too big.
71  *
72  *  Revision 1.14  2001/04/23 17:08:33  s_a_white
73  *  Added extended video flag -v<n|p>[f].
74  *
75  *  Revision 1.13  2001/04/21 13:28:31  s_a_white
76  *  Updated help information.
77  *
78  *  Revision 1.12  2001/04/21 10:28:22  s_a_white
79  *  Fix -w flag to take an optional filename.
80  *
81  *  Revision 1.11  2001/03/27 19:35:33  s_a_white
82  *  Moved default record length for wav files from main.cpp to IniConfig.cpp.
83  *
84  *  Revision 1.10  2001/03/27 19:00:49  s_a_white
85  *  Default record and play lengths can now be set in the sidplay2.ini file.
86  *
87  *  Revision 1.9  2001/03/27 17:14:39  s_a_white
88  *  Time length can be made INFINITE by using -t0 on the command line.
89  *
90  *  Revision 1.8  2001/03/26 18:14:20  s_a_white
91  *  Removed debug code.
92  *
93  *  Revision 1.7  2001/03/21 22:54:55  s_a_white
94  *  Support for ini config file and libsidutils tools.
95  *
96  *  Revision 1.6  2001/03/04 12:58:56  s_a_white
97  *  Defualt environment changed to real.  Verbose info now printed correctly.
98  *
99  *  Revision 1.5  2001/03/01 23:47:00  s_a_white
100  *  Support for sample mode to be selected at runtime.
101  *
102  *  Revision 1.4  2001/02/08 20:58:01  s_a_white
103  *  Help screen bug fix for default precision and optimisation, which were
104  *  printed as characters.
105  *
106  *  Revision 1.3  2001/01/23 22:54:24  s_a_white
107  *  Prevents timer overwriting paused message.
108  *
109  *  Revision 1.2  2001/01/23 21:25:15  s_a_white
110  *  Only way to load a tune now is by passing in a sidtune object.  This is
111  *  required for songlength database support.
112  *
113  *  Revision 1.1  2001/01/08 16:41:42  s_a_white
114  *  App and Library Seperation
115  *
116  *  Revision 1.20  2000/12/11 18:52:12  s_a_white
117  *  Conversion to AC99
118  *
119  ***************************************************************************/
120 
121 #include <stdlib.h>
122 #include <iostream>
123 using std::cerr;
124 using std::endl;
125 #include <signal.h>
126 #include "player.h"
127 #include "keyboard.h"
128 
129 
130 // Function prototypes
131 static void sighandler (int signum);
132 static ConsolePlayer *g_player;
133 
134 int main(int argc, char *argv[])
135 {
136     ConsolePlayer player(argv[0]);
137     g_player = &player;
138 
139     {// Decode the command line args
140         int ret = player.args (argc - 1, const_cast<const char**>(argv + 1));
141         if (ret < 0)
142             goto main_error;
143         else if (!ret)
144             goto main_exit;
145     }
146 
147 main_restart:
148     if (!player.open ())
149         goto main_error;
150 
151     // Install signal error handlers
152     if ((signal (SIGINT,  &sighandler) == SIG_ERR)
153      || (signal (SIGABRT, &sighandler) == SIG_ERR)
154      || (signal (SIGTERM, &sighandler) == SIG_ERR))
155     {
main(int argc,char * argv[])156         displayError(argv[0], ERR_SIGHANDLER);
157         goto main_error;
158     }
159 
160 #ifdef HAVE_UNIX
161     // Configure terminal to allow direct access to key events
162     keyboard_enable_raw ();
163 #endif // HAVE_UNIX
164 
165     // Play loop
166     FOREVER
167     {
168         if (!player.play ())
169             break;
170     }
171 
172 #ifdef HAVE_UNIX
173     keyboard_disable_raw ();
174 #endif
175 
176     // Restore default signal error handlers
177     if ((signal (SIGINT,  SIG_DFL) == SIG_ERR)
178      || (signal (SIGABRT, SIG_DFL) == SIG_ERR)
179      || (signal (SIGTERM, SIG_DFL) == SIG_ERR))
180     {
181         displayError(argv[0], ERR_SIGHANDLER);
182         goto main_error;
183     }
184 
185     if ((player.state() & ~playerFast) == playerRestart)
186         goto main_restart;
187 main_exit:
188     player.close ();
189     return EXIT_SUCCESS;
190 
191 main_error:
192     player.close ();
193     return EXIT_FAILURE;
194 }
195 
196 
197 void sighandler (int signum)
198 {
199     switch (signum)
200     {
201     case SIGINT:
202     case SIGABRT:
203     case SIGTERM:
204         // Exit now!
205         g_player->stop ();
206     break;
207     default: break;
208     }
209 }
210 
211 
212 void displayError (const char *arg0, uint num)
213 {
214     cerr << arg0 << ": ";
215 
216     switch (num)
217     {
218     case ERR_SYNTAX:
219         cerr << "command line syntax error" << endl
220              << "Try `" << arg0 << " --help' for more information." << endl;
221     break;
222 
223     case ERR_NOT_ENOUGH_MEMORY:
224         cerr << "ERROR: Not enough memory." << endl;
225     break;
226 
227     case ERR_SIGHANDLER:
228         cerr << "ERROR: Could not install signal handler." << endl;
229     break;
230 
231     case ERR_FILE_OPEN:
232         cerr << "ERROR: Could not open file for binary input." << endl;
233     break;
234 
235     default: break;
236     }
237 }
238