1
#if defined(_M_X64) || defined(__x86_64__)
2
#warning "Simutrans is preferably compiled as 32 bit binary!"
12
#include <new.h> // for _set_new_handler
31
#include "boden/boden.h"
32
#include "boden/wasser.h"
35
#include "player/simplay.h"
38
#include "simticker.h"
42
#include "linehandle_t.h"
49
#include "simversion.h"
51
#include "gui/banner.h"
52
#include "gui/pakselector.h"
54
#include "gui/sprachen.h"
55
#include "gui/climates.h"
56
#include "gui/messagebox.h"
57
#include "gui/loadsave_frame.h"
58
#include "gui/load_relief_frame.h"
59
#include "gui/scenario_frame.h"
61
#include "dings/baum.h"
63
#include "utils/simstring.h"
64
#include "utils/searchfolder.h"
66
#include "dataobj/network.h" // must be before any "windows.h" is included via bzlib2.h ...
67
#include "dataobj/loadsave.h"
68
#include "dataobj/umgebung.h"
69
#include "dataobj/tabfile.h"
70
#include "dataobj/einstellungen.h"
71
#include "dataobj/translator.h"
72
#include "dataobj/pakset_info.h"
74
#include "besch/reader/obj_reader.h"
75
#include "besch/sound_besch.h"
77
#include "music/music.h"
78
#include "sound/sound.h"
80
#include "utils/cbuffer_t.h"
82
#include "bauer/vehikelbauer.h"
83
#include "vehicle/simvehikel.h"
84
#include "vehicle/simverkehr.h"
88
/* diagnostic routine:
89
* show the size of several internal structures
91
static void show_sizes()
93
DBG_MESSAGE("Debug", "size of structures");
95
DBG_MESSAGE("sizes", "koord: %d", sizeof(koord));
96
DBG_MESSAGE("sizes", "koord3d: %d", sizeof(koord3d));
97
DBG_MESSAGE("sizes", "ribi_t::ribi: %d", sizeof(ribi_t::ribi));
98
DBG_MESSAGE("sizes", "halthandle_t: %d\n", sizeof(halthandle_t));
100
DBG_MESSAGE("sizes", "ding_t: %d", sizeof(ding_t));
101
DBG_MESSAGE("sizes", "gebaeude_t: %d", sizeof(gebaeude_t));
102
DBG_MESSAGE("sizes", "baum_t: %d", sizeof(baum_t));
103
DBG_MESSAGE("sizes", "weg_t: %d", sizeof(weg_t));
104
DBG_MESSAGE("sizes", "stadtauto_t: %d\n", sizeof(stadtauto_t));
106
DBG_MESSAGE("sizes", "grund_t: %d", sizeof(grund_t));
107
DBG_MESSAGE("sizes", "boden_t: %d", sizeof(boden_t));
108
DBG_MESSAGE("sizes", "wasser_t: %d", sizeof(wasser_t));
109
DBG_MESSAGE("sizes", "planquadrat_t: %d\n", sizeof(planquadrat_t));
111
DBG_MESSAGE("sizes", "ware_t: %d", sizeof(ware_t));
112
DBG_MESSAGE("sizes", "vehikel_t: %d", sizeof(vehikel_t));
113
DBG_MESSAGE("sizes", "haltestelle_t: %d\n", sizeof(haltestelle_t));
115
DBG_MESSAGE("sizes", "karte_t: %d", sizeof(karte_t));
116
DBG_MESSAGE("sizes", "spieler_t: %d\n", sizeof(spieler_t));
122
static void show_times(karte_t *welt, karte_ansicht_t *view)
124
DBG_MESSAGE("test", "testing img ... ");
128
for (i = 0; i < 300000; i++)
129
display_img(10, 50, 50, 1);
130
DBG_MESSAGE("test", "display_img(): %i iterations took %i ms", i, dr_time() - ms);
133
for (i = 0; i < 300000; i++)
134
display_color_img(2000, 120, 100, 0, 1, 1);
135
DBG_MESSAGE("test", "display_color_img(): %i iterations took %i ms", i, dr_time() - ms);
138
for (i = 0; i < 300000; i++)
139
display_color_img(2000, 160, 150, 16, 1, 1);
140
DBG_MESSAGE("test", "display_color_img(): next AI: %i iterations took %i ms", i, dr_time() - ms);
143
for (i = 0; i < 300000; i++)
144
display_color_img(2000, 220, 200, 20, 1, 1);
145
DBG_MESSAGE("test", "display_color_img(), other AI: %i iterations took %i ms", i, dr_time() - ms);
148
for (i = 0; i < 300; i++)
150
DBG_MESSAGE("test", "display_flush_buffer(): %i iterations took %i ms", i, dr_time() - ms);
153
for (i = 0; i < 300000; i++)
154
display_text_proportional_len_clip(100, 120, "Dies ist ein kurzer Textetxt ...", 0, 0, -1);
155
DBG_MESSAGE("test", "display_text_proportional_len_clip(): %i iterations took %i ms", i, dr_time() - ms);
158
for (i = 0; i < 300000; i++)
159
display_fillbox_wh(100, 120, 300, 50, 0, false);
160
DBG_MESSAGE("test", "display_fillbox_wh(): %i iterations took %i ms", i, dr_time() - ms);
163
for (i = 0; i < 200; i++) {
166
DBG_MESSAGE("test", "view->display(true): %i iterations took %i ms", i, dr_time() - ms);
169
for (i = 0; i < 200; i++) {
171
win_display_flush(0.0);
173
DBG_MESSAGE("test", "view->display(true) and flush: %i iterations took %i ms", i, dr_time() - ms);
176
intr_set(welt, view);
177
welt->set_fast_forward(true);
179
for (i = 0; i < 200; i++) {
180
welt->sync_step(200,true,true);
183
DBG_MESSAGE("test", "welt->sync_step/step(200,1,1): %i iterations took %i ms", i, dr_time() - ms);
188
void modal_dialogue( gui_frame_t *gui, long magic, karte_t *welt, bool (*quit)() )
190
if( display_get_width()==0 ) {
191
dbg->error( "modal_dialogue()", "called without a display driver => nothing will be shown!" );
192
// cannot handle this!
197
create_win( (display_get_width()-gui->get_fenstergroesse().x)/2, (display_get_height()-gui->get_fenstergroesse().y)/2, gui, w_info, magic );
200
welt->set_pause( false );
201
welt->reset_interaction();
204
long ms_pause = max( 25, 1000/umgebung_t::fps );
205
uint32 last_step = dr_time()+ms_pause;
207
while( win_is_open(gui) && !umgebung_t::quit_simutrans && !quit() ) {
209
DBG_DEBUG4("zeige_banner", "calling win_poll_event");
212
if( ev.my < werkzeug_t::toolbar_tool[0]->iconsize.y ) {
213
ev.my = werkzeug_t::toolbar_tool[0]->iconsize.y;
215
if( ev.cy < werkzeug_t::toolbar_tool[0]->iconsize.y ) {
216
ev.cy = werkzeug_t::toolbar_tool[0]->iconsize.y;
218
DBG_DEBUG4("zeige_banner", "calling check_pos_win");
220
if( ev.ev_class == EVENT_SYSTEM && ev.ev_code == SYSTEM_QUIT ) {
221
umgebung_t::quit_simutrans = true;
225
} while( dr_time()<last_step );
226
DBG_DEBUG4("zeige_banner", "calling welt->sync_step");
227
welt->sync_step( ms_pause, true, true );
228
DBG_DEBUG4("zeige_banner", "calling welt->step");
229
if( step_count--==0 ) {
233
last_step += ms_pause;
237
display_show_pointer(true);
240
display_fillbox_wh( 0, 0, display_get_width(), display_get_height(), COL_BLACK, true );
241
while( win_is_open(gui) && !umgebung_t::quit_simutrans && !quit() ) {
242
// do not move, do not close it!
244
gui->zeichnen( koord(win_get_posx(gui),win_get_posy(gui)), gui->get_fenstergroesse() );
245
display_poll_event(&ev);
246
// main window resized
250
// main window resized
251
if(ev.ev_class==EVENT_SYSTEM && ev.ev_code==SYSTEM_RESIZE) {
252
// main window resized
253
simgraph_resize( ev.mx, ev.my );
254
display_fillbox_wh( 0, 0, ev.mx, ev.my, COL_BLACK, true );
258
display_fillbox_wh( 0, 0, display_get_width(), display_get_height(), COL_BLACK, true );
261
// just trigger not another following window => wait for button release
262
if (IS_LEFTCLICK(&ev)) {
264
display_get_event(&ev);
265
} while (!IS_LEFTRELEASE(&ev));
270
// some routines for the modal display
271
static bool never_quit() { return false; }
272
static bool empty_objfilename() { return !umgebung_t::objfilename.empty(); }
273
static bool no_language() { return translator::get_language()!=-1; }
280
static void ask_objfilename()
282
pakselector_t* sel = new pakselector_t();
285
destroy_all_win(true); // since eventually the successful load message is still there ....
286
modal_dialogue( sel, magic_none, NULL, empty_objfilename );
296
* Show language selector
298
static void ask_language()
300
if( display_get_width()==0 ) {
301
// only console available ... => choose english for the moment
302
dbg->warning( "ask_language", "No language selected, will use english!" );
303
translator::set_language( "en" );
306
sprachengui_t* sel = new sprachengui_t();
307
destroy_all_win(true); // since eventually the successful load message is still there ....
308
modal_dialogue( sel, magic_none, NULL, no_language );
316
* Dies wird in main mittels set_new_handler gesetzt und von der
317
* Laufzeitumgebung im Falle des Speichermangels bei new() aufgerufen
320
int sim_new_handler(unsigned int)
322
void sim_new_handler()
325
dbg->fatal("sim_new_handler()", "OUT OF MEMORY");
332
static const char *gimme_arg(int argc, char *argv[], const char *arg, int off)
334
for (int i = 1; i < argc; i++) {
335
if (strcmp(argv[i], arg) == 0 && i < argc - off) {
336
return argv[i + off];
343
int simu_main(int argc, char** argv)
345
static const sint16 resolutions[][2] = {
350
{ 704, 560 } // try to force window mode with allegro
353
sint16 disp_width = 0;
354
sint16 disp_height = 0;
355
sint16 fullscreen = false;
357
uint32 quit_month = 0x7FFFFFFFu;
360
_set_new_handler(sim_new_handler);
362
std::set_new_handler(sim_new_handler);
366
// you really want help with this?
367
if (gimme_arg(argc, argv, "-h", 0) ||
368
gimme_arg(argc, argv, "-?", 0) ||
369
gimme_arg(argc, argv, "-help", 0) ||
370
gimme_arg(argc, argv, "--help", 0)) {
373
"---------------------------------------\n"
374
" Simutrans " VERSION_NUMBER "\n"
375
" released " VERSION_DATE "\n"
377
" by the Simutrans team.\n"
379
" Send feedback and questions to:\n"
380
" <markus@pristovsek.de>\n"
382
" Based on Simutrans 0.84.21.2\n"
383
" by Hansj�rg Malthaner et. al.\n"
384
" <hansjoerg.malthaner@gmx.de>\n"
385
"---------------------------------------\n"
386
"command line parameters available: \n"
387
" -addons loads also addons (with -objects)\n"
388
" -async asynchronic images, only for SDL\n"
389
" -debug NUM enables debuging (1..5)\n"
390
" -freeplay play with endless money\n"
391
" -fullscreen starts simutrans in fullscreen mode\n"
392
" -fps COUNT framerate (from 5 to 100)\n"
393
" -h | -help | --help displays this help\n"
394
" -lang CODE starts with specified language\n"
395
" -load FILE[.sve] loads game in file 'save/FILE.sve'\n"
396
" -log enables logging to file 'simu.log'\n"
397
" -noaddons does not load any addon (default)\n"
398
" -nomidi turns off background music\n"
399
" -nosound turns off ambient sounds\n"
400
" -objects DIR_NAME/ load the pakset in specified directory\n"
401
" -res N starts in specified resolution: \n"
402
" 1=640x480, 2=800x600, 3=1024x768, 4=1280x1024\n"
403
" -screensize WxH set screensize to width W and height H\n"
404
" -server [PORT] starts program as server (for network game)\n"
405
" without port specified uses 13353\n"
406
" -server_id NUM ID for server announcements\n"
407
" -server_name NAME name for server announcements\n"
408
" -server_comment TXT comment for server announcements\n"
409
" -singleuser Save everything in program directory (portable version)\n"
411
" -sizes Show current size of some structures\n"
413
" -startyear N start in year N\n"
414
" -timeline enables timeline\n"
415
#if defined DEBUG || defined PROFILE
416
" -times does some simple profiling\n"
417
" -until MONTH quits when MONTH = (month*12+year-1) starts\n"
419
" -use_workdir use current dir as basedir\n"
429
const char* path_sep = PATHSEP;
433
if (1) // since BeOS only supports relative paths ...
435
// use current dir as basedir, else use program_dir
436
if (gimme_arg(argc, argv, "-use_workdir", 0))
439
// save the current directories
440
getcwd(umgebung_t::program_dir, lengthof(umgebung_t::program_dir));
441
strcat( umgebung_t::program_dir, path_sep );
444
// strcpy( umgebung_t::program_dir, argv[0] );
445
// *(strrchr( umgebung_t::program_dir, path_sep[0] )+1) = 0;
446
strcpy(umgebung_t::program_dir, "/usr/share/games/simutrans/");
448
chdir( umgebung_t::program_dir );
450
printf("Use work dir %s\n", umgebung_t::program_dir);
452
// only the pak specifiy conf should overide this!
453
uint16 pak_diagonal_multiplier = umgebung_t::default_einstellungen.get_pak_diagonal_multiplier();
455
// parsing config/simuconf.tab
456
printf("Reading low level config data ...\n");
457
bool found_settings = false;
458
bool found_simuconf = false;
459
bool multiuser = (gimme_arg(argc, argv, "-singleuser", 0) == NULL);
462
char path_to_simuconf[24];
463
// was config/simuconf.tab
464
sprintf(path_to_simuconf, "config%csimuconf.tab", path_sep[0]);
465
if(simuconf.open(path_to_simuconf)) {
467
tabfileobj_t contents;
468
simuconf.read(contents);
469
// use different save directories
470
multiuser = !(contents.get_int("singleuser_install", !multiuser)==1 || !multiuser);
471
found_simuconf = true;
478
umgebung_t::user_dir = dr_query_homedir();
481
// save in program directory
482
umgebung_t::user_dir = umgebung_t::program_dir;
484
chdir( umgebung_t::user_dir );
486
// now read last setting (might be overwritten by the tab-files)
488
if(file.rd_open("settings.xml")) {
489
if( file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL ) ) {
490
// too new => remove it
492
remove( "settings.xml" );
495
found_settings = true;
496
umgebung_t::rdwr(&file);
497
umgebung_t::default_einstellungen.rdwr(&file);
499
// reset to false (otherwise these settings will persist)
500
umgebung_t::default_einstellungen.set_freeplay( false );
501
umgebung_t::default_einstellungen.set_allow_player_change( true );
502
umgebung_t::announce_server = 0;
506
// continue parsing ...
507
chdir( umgebung_t::program_dir );
508
if( found_simuconf ) {
509
if(simuconf.open(path_to_simuconf)) {
510
printf("parse_simuconf() at config/simuconf.tab: ");
511
umgebung_t::default_einstellungen.parse_simuconf( simuconf, disp_width, disp_height, fullscreen, umgebung_t::objfilename );
515
// if set for multiuser, then parses the users config (if there)
516
// retrieve everything (but we must do this again once more ... )
518
const string obj_conf = string(umgebung_t::user_dir) + "simuconf.tab";
519
if (simuconf.open(obj_conf.c_str())) {
520
printf("parse_simuconf() at %s: ", obj_conf.c_str() );
521
umgebung_t::default_einstellungen.parse_simuconf( simuconf, disp_width, disp_height, fullscreen, umgebung_t::objfilename );
525
// unmgebung: overide previous settings
526
if( (gimme_arg(argc, argv, "-freeplay", 0) != NULL) ) {
527
umgebung_t::default_einstellungen.set_freeplay( true );
529
if( gimme_arg(argc, argv, "-debug", 0) != NULL ) {
530
const char *s = gimme_arg(argc, argv, "-debug", 1);
532
if(s!=NULL && s[0]>='0' && s[0]<='9' ) {
535
umgebung_t::verbose_debug = level;
538
// now set the desired objectfilename (overide all previous settings)
539
if (gimme_arg(argc, argv, "-objects", 1)) {
540
umgebung_t::objfilename = gimme_arg(argc, argv, "-objects", 1);
541
// append slash / replace trailing backslash if necessary
542
uint16 len = umgebung_t::objfilename.length();
544
if (umgebung_t::objfilename[len-1]=='\\') {
545
umgebung_t::objfilename.erase(len-1);
546
umgebung_t::objfilename += "/";
548
else if (umgebung_t::objfilename[len-1]!='/') {
549
umgebung_t::objfilename += "/";
555
const char *version = "Simutrans version " VERSION_NUMBER " from " VERSION_DATE " r" QUOTEME(REVISION) "\n";
557
const char *version = "Simutrans version " VERSION_NUMBER " from " VERSION_DATE "\n";
559
if (gimme_arg(argc, argv, "-log", 0)) {
560
chdir( umgebung_t::user_dir );
561
char temp_log_name[256];
562
const char *logname = "simu.log";
563
if( gimme_arg(argc, argv, "-server", 0) ) {
564
const char *p = gimme_arg(argc, argv, "-server", 1);
565
int portadress = p ? atoi( p ) : 13353;
566
sprintf( temp_log_name, "simu-server%d.log", portadress==0 ? 13353 : portadress );
567
logname = temp_log_name;
569
init_logging( logname, true, gimme_arg(argc, argv, "-log", 0 ) != NULL, version );
570
} else if (gimme_arg(argc, argv, "-debug", 0) != NULL) {
571
init_logging( "stderr", true, gimme_arg(argc, argv, "-debug", 0 ) != NULL, version );
573
init_logging(NULL, false, false, version);
576
// starting a server?
577
if( gimme_arg(argc, argv, "-server", 0) ) {
578
const char *p = gimme_arg(argc, argv, "-server", 1);
579
int portadress = p ? atoi( p ) : 13353;
580
if( portadress==0 ) {
583
// will fail fatal on the opening routine ...
584
dbg->message( "simmain()", "Server started on port %i", portadress );
585
umgebung_t::networkmode = network_init_server( portadress );
586
if( umgebung_t::networkmode ) {
587
umgebung_t::server = portadress;
591
// no announce for clients ...
592
umgebung_t::announce_server = 0;
595
DBG_MESSAGE( "simmain::main()", "Version: " VERSION_NUMBER " Date: " VERSION_DATE);
596
DBG_MESSAGE( "Debuglevel","%i", umgebung_t::verbose_debug );
597
DBG_MESSAGE( "program_dir", umgebung_t::program_dir );
598
DBG_MESSAGE( "home_dir", umgebung_t::user_dir );
600
if (gimme_arg(argc, argv, "-sizes", 0) != NULL) {
601
// show the size of some structures ...
606
// prepare skins first
607
obj_reader_t::init();
608
chdir( umgebung_t::program_dir );
610
// likely only the programm without graphics was downloaded
611
if (gimme_arg(argc, argv, "-res", 0) != NULL) {
612
const char* res_str = gimme_arg(argc, argv, "-res", 1);
613
const int res = *res_str - '1';
622
fullscreen = (res<=4);
623
disp_width = resolutions[res][0];
624
disp_height = resolutions[res][1];
629
"invalid resolution, argument must be 1,2,3 or 4\n"
630
"1=640x480, 2=800x600, 3=1024x768, 4=1280x1024, 5=windowed\n"
636
fullscreen |= (gimme_arg(argc, argv, "-fullscreen", 0) != NULL);
638
if(gimme_arg(argc, argv, "-screensize", 0) != NULL) {
639
const char* res_str = gimme_arg(argc, argv, "-screensize", 1);
642
if (res_str != NULL) {
643
n = sscanf(res_str, "%hdx%hd", &disp_width, &disp_height);
648
"invalid argument for -screensize option\n"
649
"argument must be of format like 800x600\n"
656
parameter[0] = gimme_arg(argc, argv, "-net", 0)==NULL;
657
parameter[1] = gimme_arg(argc, argv, "-async", 0)==NULL;
658
dr_os_init(parameter);
660
// get optimal resolution ...
661
if( disp_width==0 || disp_height==0 ) {
662
int scr_x = dr_query_screen_width();
663
int scr_y = dr_query_screen_height();
669
disp_width = min( 704, scr_x );
670
disp_height = min( 560, scr_y );
674
printf("Preparing display ...\n");
675
DBG_MESSAGE("simmain", "simgraph_init disp_width=%d, disp_height=%d, fullscreen=%d", disp_width, disp_height, fullscreen);
676
simgraph_init(disp_width, disp_height, fullscreen);
677
DBG_MESSAGE("simmain", ".. results in disp_width=%d, disp_height=%d", display_get_width(), display_get_height());
679
// if no object files given, we ask the user
680
if( umgebung_t::objfilename.empty() ) {
683
if( umgebung_t::objfilename.empty() ) {
684
// nothing to be loaded => exit
685
fprintf(stderr, "*** No pak set found ***\n\nMost likely, you have no pak set installed.\nPlease download and install also graphics (pak).\n");
686
dr_fatal_notify( "*** No pak set found ***\n\nMost likely, you have no pak set installed.\nPlease download and install also graphcis (pak).\n", 0 );
693
// now find the pak specific tab file ...
694
const string obj_conf = umgebung_t::objfilename + path_to_simuconf;
696
if (simuconf.open(obj_conf.c_str())) {
698
printf("parse_simuconf() at %s: ", obj_conf.c_str());
699
umgebung_t::default_einstellungen.parse_simuconf( simuconf, idummy, idummy, idummy, dummy );
700
pak_diagonal_multiplier = umgebung_t::default_einstellungen.get_pak_diagonal_multiplier();
703
// and parse again parse the user settings
704
if(umgebung_t::user_dir!=umgebung_t::program_dir) {
705
const string obj_conf = string(umgebung_t::user_dir) + "simuconf.tab";
706
if (simuconf.open(obj_conf.c_str())) {
708
printf("parse_simuconf() at %s: ", obj_conf.c_str());
709
umgebung_t::default_einstellungen.parse_simuconf( simuconf, idummy, idummy, idummy, dummy );
712
if( gimme_arg(argc, argv, "-objects", 1) != NULL ) {
713
if(gimme_arg(argc, argv, "-addons", 0) != NULL) {
714
umgebung_t::default_einstellungen.set_with_private_paks( true );
716
if(gimme_arg(argc, argv, "-noaddons", 0) != NULL) {
717
umgebung_t::default_einstellungen.set_with_private_paks( false );
722
// not possible for single user
723
umgebung_t::default_einstellungen.set_with_private_paks( false );
726
// now (re)set the correct length from the pak
727
umgebung_t::default_einstellungen.set_pak_diagonal_multiplier( pak_diagonal_multiplier );
728
vehikel_basis_t::set_diagonal_multiplier( pak_diagonal_multiplier, pak_diagonal_multiplier );
730
convoihandle_t::init( 1024 );
731
linehandle_t::init( 1024 );
732
halthandle_t::init( 1024 );
734
// just check before loading objects
735
if (!gimme_arg(argc, argv, "-nosound", 0) && dr_init_sound()) {
736
printf("Reading compatibility sound data ...\n");
737
sound_besch_t::init();
740
sound_set_mute(true);
743
// Adam - Moved away loading from simmain and placed into translator for better modularisation
744
if( !translator::load(umgebung_t::objfilename) ) {
745
// installation error: likely only program started
746
dbg->fatal("simmain::main()", "Unable to load any language files\n*** PLEASE INSTALL PROPER BASE FILES ***\n");
750
// use requested language (if available)
751
if( gimme_arg(argc, argv, "-lang", 1) ) {
752
const char *iso = gimme_arg(argc, argv, "-lang", 1);
753
if( strlen(iso)>=2 ) {
754
translator::set_language( iso );
756
if( translator::get_language()==-1 ) {
757
dbg->fatal("simmain", "Illegal language defintion \"%s\"", iso );
759
umgebung_t::language_iso = translator::get_lang()->iso_base;
761
else if( found_settings ) {
762
translator::set_language( umgebung_t::language_iso );
765
// Hajo: simgraph init loads default fonts, now we need to load
766
// the real fonts for the current language
767
sprachengui_t::init_font_from_lang();
768
chdir(umgebung_t::program_dir);
770
printf("Reading city configuration ...\n");
771
stadt_t::cityrules_init(umgebung_t::objfilename);
773
printf("Reading speedbonus configuration ...\n");
774
vehikelbauer_t::speedbonus_init(umgebung_t::objfilename);
776
printf("Reading menu configuration ...\n");
777
werkzeug_t::init_menu();
780
printf("Reading object data from %s...\n", umgebung_t::objfilename.c_str());
781
obj_reader_t::load(umgebung_t::objfilename.c_str(), translator::translate("Loading paks ...") );
782
if( umgebung_t::default_einstellungen.get_with_private_paks() ) {
783
// try to read addons from private directory
784
chdir( umgebung_t::user_dir );
785
if(!obj_reader_t::load(umgebung_t::objfilename.c_str(), translator::translate("Loading addon paks ..."))) {
786
fprintf(stderr, "reading addon object data failed (disabling).\n");
787
umgebung_t::default_einstellungen.set_with_private_paks( false );
789
chdir( umgebung_t::program_dir );
791
obj_reader_t::laden_abschliessen();
792
pakset_info_t::calculate_checksum();
793
pakset_info_t::debug();
795
// set overtaking offsets
796
vehikel_basis_t::set_overtaking_offsets( umgebung_t::drive_on_left );
798
printf("Reading menu configuration ...\n");
799
werkzeug_t::read_menu(umgebung_t::objfilename);
801
if( translator::get_language()==-1 ) {
805
bool new_world = true;
806
std::string loadgame;
808
if (gimme_arg(argc, argv, "-load", 0) != NULL) {
810
chdir( umgebung_t::user_dir );
812
* Added automatic adding of extension
814
const char *name = gimme_arg(argc, argv, "-load", 1);
815
if( strstr(name,"net:")==name ) {
819
buf.printf( SAVE_PATH_X "%s", searchfolder_t::complete(name, "sve").c_str() );
821
printf( "loading savegame \"%s\"\n", name );
826
// recover last server game
827
if( new_world && umgebung_t::server ) {
828
chdir( umgebung_t::user_dir );
830
static char servername[128];
831
sprintf( servername, "server%d-network.sve", umgebung_t::server );
832
// try recover with the latest savegame
833
if( file.rd_open(servername) ) {
834
// compare pakset (objfilename has trailing path separator, pak_extension not)
835
if( strncmp( file.get_pak_extension(), umgebung_t::objfilename.c_str(), strlen(file.get_pak_extension() ) )==0 ) {
836
// same pak directory - load this
837
loadgame = servername;
844
// still nothing to be loaded => search for demo games
846
chdir( umgebung_t::program_dir );
848
sprintf(buffer, "%s%sdemo.sve", (const char*)umgebung_t::program_dir, umgebung_t::objfilename.c_str());
849
// access did not work!
850
FILE *f=fopen(buffer,"rb");
852
// there is a demo game to load
855
DBG_MESSAGE("simmain","loadgame file found at %s",buffer);
859
if (gimme_arg(argc, argv, "-timeline", 0) != NULL) {
860
const char* ref_str = gimme_arg(argc, argv, "-timeline", 1);
861
if (ref_str != NULL) {
862
umgebung_t::default_einstellungen.set_use_timeline( atoi(ref_str) );
866
if (gimme_arg(argc, argv, "-startyear", 0) != NULL) {
867
const char * ref_str = gimme_arg(argc, argv, "-startyear", 1); //1930
868
if (ref_str != NULL) {
869
umgebung_t::default_einstellungen.set_starting_year( clamp(atoi(ref_str),1,2999) );
873
// now always writing in user dir (which points the the program dir in multiuser mode)
874
chdir( umgebung_t::user_dir );
876
// init midi before loading sounds
878
printf("Reading midi data ...\n");
879
if(!midi_init(umgebung_t::user_dir)) {
880
if(!midi_init(umgebung_t::program_dir)) {
881
printf("Midi disabled ...\n");
884
if(gimme_arg(argc, argv, "-nomidi", 0)) {
889
printf("Midi disabled ...\n");
893
// restore previous sound settings ...
894
sound_set_shuffle_midi( umgebung_t::shuffle_midi!=0 );
895
sound_set_mute( umgebung_t::mute_sound || sound_get_mute() );
896
midi_set_mute( umgebung_t::mute_midi || midi_get_mute() );
897
sound_set_global_volume( umgebung_t::global_volume );
898
sound_set_midi_volume( umgebung_t::midi_volume );
899
if(!midi_get_mute()) {
900
// not muted => play first song
904
karte_t *welt = new karte_t();
905
karte_ansicht_t *view = new karte_ansicht_t(welt);
906
welt->set_ansicht( view );
908
// some messages about old vehicle may appear ...
909
welt->get_message()->set_message_flags(0, 0, 0, 0);
911
// set the frame per second
912
const char *ref_str = gimme_arg(argc, argv, "-fps", 1);
913
if (ref_str != NULL) {
914
int want_refresh = atoi(ref_str);
915
umgebung_t::fps = want_refresh < 5 ? 5 : (want_refresh > 100 ? 100 : want_refresh);
918
// query server stuff
919
ref_str = gimme_arg(argc, argv, "-server_id", 1);
920
if (ref_str != NULL) {
921
umgebung_t::announce_server = atoi(ref_str);
924
ref_str = gimme_arg(argc, argv, "-server_comment", 1);
925
if (ref_str != NULL) {
926
umgebung_t::server_name = ref_str;
929
ref_str = gimme_arg(argc, argv, "-server_comment", 1);
930
if (ref_str != NULL) {
931
umgebung_t::server_comment = ref_str;
934
chdir(umgebung_t::user_dir);
936
// reset random counter to true randomness
937
setsimrand(dr_time(), dr_time());
938
clear_random_mode( 7 ); // allow all
940
if(loadgame=="" || !welt->laden(loadgame.c_str())) {
941
// create a default map
942
DBG_MESSAGE("init with default map","(failing will be a pak error!)");
943
// no autosave on initial map during the first six month ...
946
sint32 old_autosave = umgebung_t::autosave;
947
umgebung_t::autosave = false;
948
einstellungen_t sets;
949
sets.copy_city_road( umgebung_t::default_einstellungen );
950
sets.set_default_climates();
951
sets.set_use_timeline( 1 );
952
sets.set_groesse(64,64);
953
sets.set_anzahl_staedte(1);
954
sets.set_land_industry_chains(1);
955
sets.set_tourist_attractions(1);
956
sets.set_verkehr_level(7);
959
intr_set(welt, view);
961
werkzeug_t::toolbar_tool[0]->init(welt,welt->get_active_player());
962
welt->set_fast_forward(true);
963
welt->sync_step(5000,true,false);
967
umgebung_t::autosave = old_autosave;
970
// just init view (world was loaded from file)
971
intr_set(welt, view);
973
werkzeug_t::toolbar_tool[0]->init(welt,welt->get_active_player());
976
welt->set_fast_forward(false);
977
#if defined DEBUG || defined PROFILE
979
if (gimme_arg(argc, argv, "-times", 0) != NULL) {
980
show_times(welt, view);
983
// finish after a certain month? (must be entered decimal, i.e. 12*year+month
984
if( gimme_arg(argc, argv, "-until", 0) != NULL ) {
985
quit_month = atoi( gimme_arg(argc, argv, "-until", 1) );
986
welt->set_fast_forward(true);
991
if( !umgebung_t::networkmode && !umgebung_t::server ) {
992
#ifdef display_in_main
993
DBG_MESSAGE("simmain", "calling view->display");
995
DBG_MESSAGE("simmain", "calling intr_refresh_display");
996
intr_refresh_display(true);
1005
#ifdef USE_SOFTPOINTER
1006
// Hajo: give user a mouse to work with
1007
if (skinverwaltung_t::mouse_cursor != NULL) {
1008
// we must use our softpointer (only Allegro!)
1009
display_set_pointer(skinverwaltung_t::mouse_cursor->get_bild_nr(0));
1012
DBG_MESSAGE("simmain", "calling display_show_pointer");
1013
display_show_pointer(true);
1019
// Hajo: simgraph init loads default fonts, now we need to load
1020
// the real fonts for the current language
1021
DBG_MESSAGE("simmain", "sprachengui_t::init_font_from_lang");
1022
sprachengui_t::init_font_from_lang();
1024
destroy_all_win(true);
1025
if( !umgebung_t::server ) {
1026
welt->get_message()->clear();
1028
while( !umgebung_t::quit_simutrans ) {
1032
if( !umgebung_t::networkmode && new_world ) {
1033
DBG_MESSAGE("simmain", "show banner");
1034
printf( "Show banner ... \n" );
1035
ticker::add_msg("Welcome to Simutrans, a game created by Hj. Malthaner and the Simutrans community.", koord::invalid, PLAYER_FLAG + 1);
1036
modal_dialogue( new banner_t(welt), magic_none, welt, never_quit );
1037
// only show new world, if no other dialoge is active ...
1038
new_world = win_get_open_count()==0;
1039
DBG_MESSAGE("simmain", "banner closed");
1041
if( umgebung_t::quit_simutrans ) {
1045
// to purge all previous old messages
1046
DBG_MESSAGE("simmain", "set_message_flags");
1047
welt->get_message()->set_message_flags(umgebung_t::message_flags[0], umgebung_t::message_flags[1], umgebung_t::message_flags[2], umgebung_t::message_flags[3]);
1049
if( !umgebung_t::networkmode && !umgebung_t::server ) {
1050
welt->set_pause( false );
1055
modal_dialogue( new welt_gui_t(welt, &umgebung_t::default_einstellungen), magic_welt_gui_t, welt, never_quit );
1056
if( umgebung_t::quit_simutrans ) {
1062
climate_gui_t *cg = new climate_gui_t(&umgebung_t::default_einstellungen);
1065
view->display(true);
1067
create_win((disp_width - cg->get_fenstergroesse().x-10), 40, cg, w_info, magic_climate );
1069
// we want to center wg (width 260) between sg (width 220) and cg (176)
1070
welt_gui_t *wg = new welt_gui_t(welt, &umgebung_t::default_einstellungen);
1071
create_win((disp_width - 220 - cg->get_fenstergroesse().x -10 -10- 260)/2 + 220 + 10, (disp_height - 300) / 2, wg, w_do_not_delete, magic_welt_gui_t );
1074
// disable pause to allow for screen updates
1075
welt->set_pause( false );
1076
welt->set_fast_forward(false);
1078
INT_CHECK("simmain 803");
1079
DBG_DEBUG4("wait_for_new_world", "calling win_poll_event");
1080
win_poll_event(&ev);
1081
INT_CHECK("simmain 805");
1082
DBG_DEBUG4("wait_for_new_world", "calling check_pos_win");
1084
if( ev.ev_class == EVENT_SYSTEM && ev.ev_code == SYSTEM_QUIT ) {
1085
umgebung_t::quit_simutrans = true;
1087
INT_CHECK("simmain 807");
1088
if( umgebung_t::networkmode ) {
1089
static int count = 0;
1090
if( ((count++)&7)==0 ) {
1091
static uint32 last_step = dr_time();
1092
uint32 next_step = dr_time();
1093
DBG_DEBUG4("wait_for_new_world", "calling welt->sync_step");
1094
welt->sync_step( next_step-last_step, true, true );
1095
DBG_DEBUG4("wait_for_new_world", "calling win_poll_event");
1097
DBG_DEBUG4("wait_for_new_world", "calling welt->step");
1098
last_step = next_step;
1099
DBG_DEBUG4("wait_for_new_world", "back from welt->step");
1103
welt->reset_interaction();
1104
DBG_DEBUG4("wait_for_new_world", "end of loop");
1107
!wg->get_scenario() &&
1108
!wg->get_load_heightfield() &&
1112
!umgebung_t::quit_simutrans
1115
if (IS_LEFTCLICK(&ev)) {
1117
DBG_DEBUG4("wait_for_new_world", "calling display_get_event");
1118
display_get_event(&ev);
1119
} while (!IS_LEFTRELEASE(&ev));
1122
DBG_DEBUG4("wait_for_new_world", "calling destroy_all_win");
1123
destroy_all_win(true);
1124
welt->get_message()->clear();
1127
if(wg->get_scenario()) {
1129
sprintf( path, "%s%sscenario/", umgebung_t::program_dir, umgebung_t::objfilename.c_str() );
1132
create_win( new scenario_frame_t(welt), w_info, magic_load_t );
1133
chdir( umgebung_t::user_dir );
1135
// Neue Karte erzeugen
1136
else if (wg->get_start()) {
1137
// since not autodelete
1138
DBG_DEBUG4("wait_for_new_world", "delete wg");
1141
create_win(200, 100, new news_img("Erzeuge neue Karte.\n", skinverwaltung_t::neueweltsymbol->get_bild_nr(0)), w_info, magic_none);
1143
DBG_DEBUG4("wait_for_new_world", "calling intr_refresh_display");
1144
intr_refresh_display(true);
1146
umgebung_t::default_einstellungen.heightfield = "";
1147
DBG_DEBUG4("wait_for_new_world", "calling welt->init");
1148
welt->init(&umgebung_t::default_einstellungen,0);
1152
if(file.wr_open("default.sve",loadsave_t::binary,"settings only",SAVEGAME_VER_NR)) {
1153
// save default setting
1154
umgebung_t::default_einstellungen.rdwr(&file);
1157
DBG_DEBUG4("wait_for_new_world", "calling destroy_all_win");
1158
destroy_all_win(true);
1159
DBG_DEBUG4("wait_for_new_world", "calling welt->step_month");
1160
welt->step_month( umgebung_t::default_einstellungen.get_starting_month() );
1161
welt->set_pause(false);
1162
DBG_DEBUG4("wait_for_new_world", "new world created");
1164
else if(wg->get_load()) {
1166
create_win( new loadsave_frame_t(welt, true), w_info, magic_load_t);
1168
else if(wg->get_load_heightfield()) {
1170
welt->load_heightfield(&umgebung_t::default_einstellungen);
1171
welt->step_month( umgebung_t::default_einstellungen.get_starting_month() );
1175
if (wg->get_quit() || umgebung_t::quit_simutrans ) {
1180
DBG_DEBUG4("wait_for_new_world", "the end");
1183
printf( "Running world, pause=%i, fast forward=%i ... \n", welt->is_paused(), welt->is_fast_forward() );
1184
loadgame = ""; // only first time
1187
welt->interactive(quit_month);
1190
welt->get_message()->get_message_flags(&umgebung_t::message_flags[0], &umgebung_t::message_flags[1], &umgebung_t::message_flags[2], &umgebung_t::message_flags[3]);
1191
welt->set_fast_forward(false);
1192
welt->set_pause(false);
1193
setsimrand(dr_time(), dr_time());
1195
printf( "World finished ...\n" );
1201
chdir( umgebung_t::user_dir );
1202
if(file.wr_open("settings.xml",loadsave_t::xml,"settings only/",SAVEGAME_VER_NR)) {
1203
umgebung_t::rdwr(&file);
1204
umgebung_t::default_einstellungen.rdwr(&file);
1208
welt->destroy(); // some compiler aparently do not like accessing welt during destroy
1215
network_core_shutdown();
1222
// free all list memories (not working, since there seems to be unitialized list still waiting for automated destruction)
1223
freelist_t::free_all_nodes();