Merged branch utf8.
[neverball] / putt / main.c
1 /*
2  * Copyright (C) 2003 Robert Kooima
3  *
4  * NEVERPUTT is  free software; you can redistribute  it and/or modify
5  * it under the  terms of the GNU General  Public License as published
6  * by the Free  Software Foundation; either version 2  of the License,
7  * or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
11  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
12  * General Public License for more details.
13  */
14
15 /*---------------------------------------------------------------------------*/
16
17 #include <SDL.h>
18 #include <SDL_ttf.h>
19 #include <SDL_mixer.h>
20 #include <SDL_image.h>
21 #include <time.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <locale.h>
26
27 #include "glext.h"
28 #include "audio.h"
29 #include "image.h"
30 #include "state.h"
31 #include "config.h"
32 #include "course.h"
33 #include "hole.h"
34 #include "game.h"
35 #include "gui.h"
36 #include "text.h"
37
38 #include "st_conf.h"
39 #include "st_all.h"
40
41 #define TITLE "Neverputt"
42
43 /*---------------------------------------------------------------------------*/
44
45 static int shot(void)
46 {
47     static char filename[MAXSTR];
48     static int  num = 0;
49
50     sprintf(filename, "screen%02d.png", num++);
51
52     image_snap(filename);
53
54     return 1;
55 }
56
57 /*---------------------------------------------------------------------------*/
58
59 static void toggle_wire(void)
60 {
61     static int wire = 0;
62
63     if (wire)
64     {
65         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
66         glEnable(GL_TEXTURE_2D);
67         glEnable(GL_LIGHTING);
68         wire = 0;
69     }
70     else
71     {
72         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
73         glDisable(GL_TEXTURE_2D);
74         glDisable(GL_LIGHTING);
75         wire = 1;
76     }
77 }
78 /*---------------------------------------------------------------------------*/
79
80 static int loop(void)
81 {
82     SDL_Event e;
83     int d = 1;
84     int c;
85
86     while (d && SDL_PollEvent(&e))
87     {
88         if (e.type == SDL_QUIT)
89             return 0;
90
91         switch (e.type)
92         {
93         case SDL_MOUSEMOTION:
94             st_point(+e.motion.x,
95                      -e.motion.y + config_get_d(CONFIG_HEIGHT),
96                      +e.motion.xrel,
97                      -e.motion.yrel);
98             break;
99
100         case SDL_MOUSEBUTTONDOWN:
101             d = st_click((e.button.button == SDL_BUTTON_LEFT) ? -1 : 1, 1);
102             break;
103
104         case SDL_MOUSEBUTTONUP:
105             d = st_click((e.button.button == SDL_BUTTON_LEFT) ? -1 : 1, 0);
106             break;
107
108         case SDL_KEYDOWN:
109
110             c = e.key.keysym.sym;
111
112             if (config_tst_d(CONFIG_KEY_FORWARD, c))
113                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), -JOY_MAX);
114
115             else if (config_tst_d(CONFIG_KEY_BACKWARD, c))
116                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), +JOY_MAX);
117
118             else if (config_tst_d(CONFIG_KEY_LEFT, c))
119                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), -JOY_MAX);
120
121             else if (config_tst_d(CONFIG_KEY_RIGHT, c))
122                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), +JOY_MAX);
123
124             else switch (c)
125             {
126             case SDLK_F10: d = shot();                break;
127             case SDLK_F9:  config_tgl_d(CONFIG_FPS);  break;
128             case SDLK_F8:  config_tgl_d(CONFIG_NICE); break;
129             case SDLK_F7:  toggle_wire();             break;
130
131             case SDLK_RETURN:
132                 d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_A), 1);
133                 break;
134             case SDLK_ESCAPE:
135                 d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_EXIT), 1);
136                 break;
137
138             default:
139                 d = st_keybd(e.key.keysym.sym, 1);
140             }
141             break;
142
143         case SDL_KEYUP:
144
145             c = e.key.keysym.sym;
146
147             /* gui_stick needs a non-null value, so we use 1 instead of 0. */
148
149             if (config_tst_d(CONFIG_KEY_FORWARD, c))
150                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), 1);
151
152             else if (config_tst_d(CONFIG_KEY_BACKWARD, c))
153                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), 1);
154
155             else if (config_tst_d(CONFIG_KEY_LEFT, c))
156                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), 1);
157
158             else if (config_tst_d(CONFIG_KEY_RIGHT, c))
159                 st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), 1);
160
161             else switch (c)
162             {
163             case SDLK_RETURN:
164                 d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_A), 0);
165                 break;
166             case SDLK_ESCAPE:
167                 d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_EXIT), 0);
168                 break;
169
170             default:
171                 d = st_keybd(e.key.keysym.sym, 0);
172             }
173
174         case SDL_ACTIVEEVENT:
175             if (e.active.state == SDL_APPINPUTFOCUS)
176             {
177                 if (e.active.gain == 0)
178                     goto_pause(&st_over, 0);
179             }
180             break;
181
182         case SDL_JOYAXISMOTION:
183             st_stick(e.jaxis.axis, e.jaxis.value);
184             break;
185
186         case SDL_JOYBUTTONDOWN:
187             d = st_buttn(e.jbutton.button, 1);
188             break;
189
190         case SDL_JOYBUTTONUP:
191             d = st_buttn(e.jbutton.button, 0);
192             break;
193         }
194     }
195     return d;
196 }
197
198 int main(int argc, char *argv[])
199 {
200     int camera = 0;
201     SDL_Surface *icon;
202     SDL_Joystick *joy = NULL;
203
204     srand((int) time(NULL));
205
206     lang_init("neverball", CONFIG_LOCALE);
207
208     if (config_data_path((argc > 1 ? argv[1] : NULL), COURSE_FILE))
209     {
210         if (config_user_path(NULL))
211         {
212             if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) == 0)
213             {
214                 config_init();
215                 config_load();
216
217                 /* Cache Neverball's camera setting. */
218
219                 camera = config_get_d(CONFIG_CAMERA);
220
221                 /* Initialize the joystick. */
222
223                 if (SDL_NumJoysticks() > 0)
224                 {
225                     joy = SDL_JoystickOpen(config_get_d(CONFIG_JOYSTICK_DEVICE));
226                     if (joy)
227                     {
228                         SDL_JoystickEventState(SDL_ENABLE);
229                         set_joystick(joy);
230                     }
231                 }
232
233                 /* Initialize the audio. */
234
235                 audio_bind(AUD_BIRDIE,  1, "snd/birdie.ogg");
236                 audio_bind(AUD_BOGEY,   1, "snd/bogey.ogg");
237                 audio_bind(AUD_BUMP,    1, "snd/bink.wav");
238                 audio_bind(AUD_DOUBLE,  1, "snd/double.ogg");
239                 audio_bind(AUD_EAGLE,   1, "snd/eagle.ogg");
240                 audio_bind(AUD_JUMP,    2, "snd/jump.ogg");
241                 audio_bind(AUD_MENU,    2, "snd/menu.wav");
242                 audio_bind(AUD_ONE,     1, "snd/one.ogg");
243                 audio_bind(AUD_PAR,     1, "snd/par.ogg");
244                 audio_bind(AUD_PENALTY, 1, "snd/penalty.ogg");
245                 audio_bind(AUD_PLAYER1, 1, "snd/player1.ogg");
246                 audio_bind(AUD_PLAYER2, 1, "snd/player2.ogg");
247                 audio_bind(AUD_PLAYER3, 1, "snd/player3.ogg");
248                 audio_bind(AUD_PLAYER4, 1, "snd/player4.ogg");
249                 audio_bind(AUD_SWITCH,  2, "snd/switch.wav");
250                 audio_bind(AUD_SUCCESS, 1, "snd/success.ogg");
251
252                 audio_init();
253
254                 /* Require 16-bit double buffer with 16-bit depth buffer. */
255
256                 SDL_GL_SetAttribute(SDL_GL_RED_SIZE,     5);
257                 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,   5);
258                 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,    5);
259                 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,  16);
260                 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
261
262 #ifndef __APPLE__
263                 icon = IMG_Load(config_data("icon/neverputt.png"));
264
265                 if (icon)
266                 {
267                     SDL_WM_SetIcon(icon, NULL);
268                     SDL_FreeSurface(icon);
269                 }
270 #endif /* __APPLE__ */
271
272                 /* Initialize the video. */
273
274                 if (config_mode(config_get_d(CONFIG_FULLSCREEN),
275                                 config_get_d(CONFIG_WIDTH),
276                                 config_get_d(CONFIG_HEIGHT)))
277                 {
278                     int t1, t0 = SDL_GetTicks();
279
280                     SDL_WM_SetCaption(TITLE, TITLE);
281
282                     /* Run the main game loop. */
283
284                     init_state(&st_null);
285                     goto_state(&st_title);
286
287                     while (loop())
288                         if ((t1 = SDL_GetTicks()) > t0)
289                         {
290                             st_timer((t1 - t0) / 1000.f);
291                             st_paint();
292                             SDL_GL_SwapBuffers();
293
294                             t0 = t1;
295
296                             if (config_get_d(CONFIG_NICE))
297                                 SDL_Delay(1);
298                         }
299                 }
300                 else fprintf(stderr, "%s: %s\n", argv[0], SDL_GetError());
301
302                 /* Restore Neverball's camera setting. */
303
304                 config_set_d(CONFIG_CAMERA, camera);
305                 config_save();
306
307                 SDL_Quit();
308             }
309             else fprintf(stderr, "%s: %s\n", argv[0], SDL_GetError());
310         }
311         else fprintf(stderr, L_("Failure to establish config directory\n"));
312     }
313     else fprintf(stderr, L_("Failure to establish game data directory\n"));
314
315     return 0;
316 }
317
318 /*---------------------------------------------------------------------------*/
319