1 /*
2 * OpenTyrian: A modern cross-platform port of Tyrian
3 * Copyright (C) 2007-2009 The OpenTyrian Development Team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 #include "config.h"
20 #include "destruct.h"
21 #include "editship.h"
22 #include "episodes.h"
23 #include "file.h"
24 #include "font.h"
25 #include "helptext.h"
26 #include "hg_revision.h"
27 #include "joystick.h"
28 #include "jukebox.h"
29 #include "keyboard.h"
30 #include "loudness.h"
31 #include "mainint.h"
32 #include "mtrand.h"
33 #include "musmast.h"
34 #include "network.h"
35 #include "nortsong.h"
36 #include "opentyr.h"
37 #include "params.h"
38 #include "picload.h"
39 #include "scroller.h"
40 #include "setup.h"
41 #include "sprite.h"
42 #include "tyrian2.h"
43 #include "xmas.h"
44 #include "varz.h"
45 #include "vga256d.h"
46 #include "video.h"
47 #include "video_scale.h"
48
49 #include "SDL.h"
50
51 #include <assert.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <time.h>
55
56 const char *opentyrian_str = "OpenTyrian",
57 *opentyrian_version = HG_REV;
58
59 /* zero-terminated strncpy */
strnztcpy(char * to,const char * from,size_t count)60 char *strnztcpy( char *to, const char *from, size_t count )
61 {
62 to[count] = '\0';
63 return strncpy(to, from, count);
64 }
65
opentyrian_menu(void)66 void opentyrian_menu( void )
67 {
68 typedef enum
69 {
70 MENU_ABOUT = 0,
71 MENU_FULLSCREEN,
72 MENU_SCALER,
73 // MENU_DESTRUCT,
74 MENU_JUKEBOX,
75 MENU_RETURN,
76 MenuOptions_MAX
77 } MenuOptions;
78
79 static const char *menu_items[] =
80 {
81 "About OpenTyrian",
82 "Toggle Fullscreen",
83 "Scaler: None",
84 // "Play Destruct",
85 "Jukebox",
86 "Return to Main Menu",
87 };
88 bool menu_items_disabled[] =
89 {
90 false,
91 !can_init_any_scaler(false) || !can_init_any_scaler(true),
92 false,
93 // false,
94 false,
95 false,
96 };
97
98 assert(COUNTOF(menu_items) == MenuOptions_MAX);
99 assert(COUNTOF(menu_items_disabled) == MenuOptions_MAX);
100
101 fade_black(10);
102 JE_loadPic(VGAScreen, 13, false);
103
104 draw_font_hv(VGAScreen, VGAScreen->w / 2, 5, opentyrian_str, large_font, centered, 15, -3);
105
106 memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
107
108 JE_showVGA();
109
110 play_song(36); // A Field for Mag
111
112 MenuOptions sel = 0;
113
114 uint temp_scaler = scaler;
115
116 bool fade_in = true, quit = false;
117 do
118 {
119 memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
120
121 for (MenuOptions i = 0; i < MenuOptions_MAX; i++)
122 {
123 const char *text = menu_items[i];
124 char buffer[100];
125
126 if (i == MENU_SCALER)
127 {
128 snprintf(buffer, sizeof(buffer), "Scaler: %s", scalers[temp_scaler].name);
129 text = buffer;
130 }
131
132 int y = i != MENU_RETURN ? i * 16 + 32 : 118;
133 draw_font_hv(VGAScreen, VGAScreen->w / 2, y, text, normal_font, centered, 15, menu_items_disabled[i] ? -8 : i != sel ? -4 : -2);
134 }
135
136 JE_showVGA();
137
138 if (fade_in)
139 {
140 fade_in = false;
141 fade_palette(colors, 20, 0, 255);
142 wait_noinput(true, false, false);
143 }
144
145 tempW = 0;
146 JE_textMenuWait(&tempW, false);
147
148 if (newkey)
149 {
150 switch (lastkey_sym)
151 {
152 case SDLK_UP:
153 do
154 {
155 if (sel-- == 0)
156 sel = MenuOptions_MAX - 1;
157 }
158 while (menu_items_disabled[sel]);
159
160 JE_playSampleNum(S_CURSOR);
161 break;
162 case SDLK_DOWN:
163 do
164 {
165 if (++sel >= MenuOptions_MAX)
166 sel = 0;
167 }
168 while (menu_items_disabled[sel]);
169
170 JE_playSampleNum(S_CURSOR);
171 break;
172
173 case SDLK_LEFT:
174 if (sel == MENU_SCALER)
175 {
176 do
177 {
178 if (temp_scaler == 0)
179 temp_scaler = scalers_count;
180 temp_scaler--;
181 }
182 while (!can_init_scaler(temp_scaler, fullscreen_enabled));
183
184 JE_playSampleNum(S_CURSOR);
185 }
186 break;
187 case SDLK_RIGHT:
188 if (sel == MENU_SCALER)
189 {
190 do
191 {
192 temp_scaler++;
193 if (temp_scaler == scalers_count)
194 temp_scaler = 0;
195 }
196 while (!can_init_scaler(temp_scaler, fullscreen_enabled));
197
198 JE_playSampleNum(S_CURSOR);
199 }
200 break;
201
202 case SDLK_RETURN:
203 switch (sel)
204 {
205 case MENU_ABOUT:
206 JE_playSampleNum(S_SELECT);
207
208 scroller_sine(about_text);
209
210 memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
211 JE_showVGA();
212 fade_in = true;
213 break;
214
215 case MENU_FULLSCREEN:
216 JE_playSampleNum(S_SELECT);
217
218 if (!init_scaler(scaler, !fullscreen_enabled) && // try new fullscreen state
219 !init_any_scaler(!fullscreen_enabled) && // try any scaler in new fullscreen state
220 !init_scaler(scaler, fullscreen_enabled)) // revert on fail
221 {
222 exit(EXIT_FAILURE);
223 }
224 set_palette(colors, 0, 255); // for switching between 8 bpp scalers
225 break;
226
227 case MENU_SCALER:
228 JE_playSampleNum(S_SELECT);
229
230 if (scaler != temp_scaler)
231 {
232 if (!init_scaler(temp_scaler, fullscreen_enabled) && // try new scaler
233 !init_scaler(temp_scaler, !fullscreen_enabled) && // try other fullscreen state
234 !init_scaler(scaler, fullscreen_enabled)) // revert on fail
235 {
236 exit(EXIT_FAILURE);
237 }
238 set_palette(colors, 0, 255); // for switching between 8 bpp scalers
239 }
240 break;
241
242 case MENU_JUKEBOX:
243 JE_playSampleNum(S_SELECT);
244
245 fade_black(10);
246 jukebox();
247
248 memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
249 JE_showVGA();
250 fade_in = true;
251 break;
252
253 case MENU_RETURN:
254 quit = true;
255 JE_playSampleNum(S_SPRING);
256 break;
257
258 case MenuOptions_MAX:
259 assert(false);
260 break;
261 }
262 break;
263
264 case SDLK_ESCAPE:
265 quit = true;
266 JE_playSampleNum(S_SPRING);
267 break;
268
269 default:
270 break;
271 }
272 }
273 } while (!quit);
274 }
275
main(int argc,char * argv[])276 int main( int argc, char *argv[] )
277 {
278 mt_srand(time(NULL));
279
280 printf("\nWelcome to... >> %s %s <<\n\n", opentyrian_str, opentyrian_version);
281
282 printf("Copyright (C) 2007-2013 The OpenTyrian Development Team\n\n");
283
284 printf("This program comes with ABSOLUTELY NO WARRANTY.\n");
285 printf("This is free software, and you are welcome to redistribute it\n");
286 printf("under certain conditions. See the file GPL.txt for details.\n\n");
287
288 if (SDL_Init(0))
289 {
290 printf("Failed to initialize SDL: %s\n", SDL_GetError());
291 return -1;
292 }
293
294 JE_loadConfiguration();
295
296 xmas = xmas_time(); // arg handler may override
297
298 JE_paramCheck(argc, argv);
299
300 JE_scanForEpisodes();
301
302 init_video();
303 init_keyboard();
304 init_joysticks();
305 printf("assuming mouse detected\n"); // SDL can't tell us if there isn't one
306
307 if (xmas && (!dir_file_exists(data_dir(), "tyrianc.shp") || !dir_file_exists(data_dir(), "voicesc.snd")))
308 {
309 xmas = false;
310
311 fprintf(stderr, "warning: Christmas is missing.\n");
312 }
313
314 JE_loadPals();
315 JE_loadMainShapeTables(xmas ? "tyrianc.shp" : "tyrian.shp");
316
317 if (xmas && !xmas_prompt())
318 {
319 xmas = false;
320
321 free_main_shape_tables();
322 JE_loadMainShapeTables("tyrian.shp");
323 }
324
325
326 /* Default Options */
327 youAreCheating = false;
328 smoothScroll = true;
329 loadDestruct = false;
330
331 if (!audio_disabled)
332 {
333 printf("initializing SDL audio...\n");
334
335 init_audio();
336
337 load_music();
338
339 JE_loadSndFile("tyrian.snd", xmas ? "voicesc.snd" : "voices.snd");
340 }
341 else
342 {
343 printf("audio disabled\n");
344 }
345
346 if (record_demo)
347 printf("demo recording enabled (input limited to keyboard)\n");
348
349 JE_loadExtraShapes(); /*Editship*/
350
351 JE_loadHelpText();
352 /*debuginfo("Help text complete");*/
353
354 if (isNetworkGame)
355 {
356 #ifdef WITH_NETWORK
357 if (network_init())
358 {
359 network_tyrian_halt(3, false);
360 }
361 #else
362 fprintf(stderr, "OpenTyrian was compiled without networking support.");
363 JE_tyrianHalt(5);
364 #endif
365 }
366
367 #ifdef NDEBUG
368 if (!isNetworkGame)
369 intro_logos();
370 #endif
371
372 for (; ; )
373 {
374 JE_initPlayerData();
375 JE_sortHighScores();
376
377 if (JE_titleScreen(true))
378 break; // user quit from title screen
379
380 if (loadDestruct)
381 {
382 JE_destructGame();
383 loadDestruct = false;
384 }
385 else
386 {
387 JE_main();
388 }
389 }
390
391 JE_tyrianHalt(0);
392
393 return 0;
394 }
395
396