62 #include "newgrf_config.h" |
62 #include "newgrf_config.h" |
63 #include "newgrf_house.h" |
63 #include "newgrf_house.h" |
64 #include "newgrf_commons.h" |
64 #include "newgrf_commons.h" |
65 #include "player_face.h" |
65 #include "player_face.h" |
66 #include "group.h" |
66 #include "group.h" |
67 #include "blitter/blitter.hpp" |
67 #include "blitter/factory.hpp" |
68 |
68 |
69 #include "bridge_map.h" |
69 #include "bridge_map.h" |
70 #include "clear_map.h" |
70 #include "clear_map.h" |
71 #include "rail_map.h" |
71 #include "rail_map.h" |
72 #include "road_map.h" |
72 #include "road_map.h" |
84 |
84 |
85 extern void SetDifficultyLevel(int mode, GameOptions *gm_opt); |
85 extern void SetDifficultyLevel(int mode, GameOptions *gm_opt); |
86 extern Player* DoStartupNewPlayer(bool is_ai); |
86 extern Player* DoStartupNewPlayer(bool is_ai); |
87 extern void ShowOSErrorBox(const char *buf); |
87 extern void ShowOSErrorBox(const char *buf); |
88 |
88 |
89 const char *_default_blitter = "8bpp-optimzed"; |
89 const char *_default_blitter = "8bpp-optimized"; |
90 |
90 |
91 /* TODO: usrerror() for errors which are not of an internal nature but |
91 /* TODO: usrerror() for errors which are not of an internal nature but |
92 * caused by the user, i.e. missing files or fatal configuration errors. |
92 * caused by the user, i.e. missing files or fatal configuration errors. |
93 * Post-0.4.0 since Celestar doesn't want this in SVN before. --pasky */ |
93 * Post-0.4.0 since Celestar doesn't want this in SVN before. --pasky */ |
94 |
94 |
324 |
322 |
325 /* Setup main window */ |
323 /* Setup main window */ |
326 ResetWindowSystem(); |
324 ResetWindowSystem(); |
327 SetupColorsAndInitialWindow(); |
325 SetupColorsAndInitialWindow(); |
328 |
326 |
329 /* Generate a world. */ |
327 /* Load the default opening screen savegame */ |
330 snprintf(filename, lengthof(filename), "%sopntitle.dat", _paths.data_dir); |
328 if (SaveOrLoad("opntitle.dat", SL_LOAD, DATA_DIR) != SL_OK) { |
331 #if defined SECOND_DATA_DIR |
|
332 if (SaveOrLoad(filename, SL_LOAD) != SL_OK) { |
|
333 snprintf(filename, lengthof(filename), "%sopntitle.dat", _paths.second_data_dir); |
|
334 } |
|
335 #endif |
|
336 if (SaveOrLoad(filename, SL_LOAD) != SL_OK) { |
|
337 GenerateWorld(GW_EMPTY, 64, 64); // if failed loading, make empty world. |
329 GenerateWorld(GW_EMPTY, 64, 64); // if failed loading, make empty world. |
338 WaitTillGeneratedWorld(); |
330 WaitTillGeneratedWorld(); |
339 } |
331 } |
340 |
332 |
341 _pause_game = 0; |
333 _pause_game = 0; |
400 #if defined(ENABLE_NETWORK) |
392 #if defined(ENABLE_NETWORK) |
401 case 'D': |
393 case 'D': |
402 strcpy(musicdriver, "null"); |
394 strcpy(musicdriver, "null"); |
403 strcpy(sounddriver, "null"); |
395 strcpy(sounddriver, "null"); |
404 strcpy(videodriver, "dedicated"); |
396 strcpy(videodriver, "dedicated"); |
|
397 strcpy(blitter, "null"); |
405 dedicated = true; |
398 dedicated = true; |
406 if (mgo.opt != NULL) { |
399 if (mgo.opt != NULL) { |
407 /* Use the existing method for parsing (openttd -n). |
400 /* Use the existing method for parsing (openttd -n). |
408 * However, we do ignore the #player part. */ |
401 * However, we do ignore the #player part. */ |
409 const char *temp = NULL; |
402 const char *temp = NULL; |
472 if (StrEmpty(blitter)) ttd_strlcpy(blitter, _default_blitter, sizeof(blitter)); |
465 if (StrEmpty(blitter)) ttd_strlcpy(blitter, _default_blitter, sizeof(blitter)); |
473 if (resolution[0] != 0) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; } |
466 if (resolution[0] != 0) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; } |
474 if (startyear != INVALID_YEAR) _patches_newgame.starting_year = startyear; |
467 if (startyear != INVALID_YEAR) _patches_newgame.starting_year = startyear; |
475 if (generation_seed != GENERATE_NEW_SEED) _patches_newgame.generation_seed = generation_seed; |
468 if (generation_seed != GENERATE_NEW_SEED) _patches_newgame.generation_seed = generation_seed; |
476 |
469 |
|
470 /* The width and height must be at least 1 pixel, this |
|
471 * way all internal drawing routines work correctly. */ |
|
472 if (_cur_resolution[0] == 0) _cur_resolution[0] = 1; |
|
473 if (_cur_resolution[1] == 0) _cur_resolution[1] = 1; |
|
474 |
477 #if defined(ENABLE_NETWORK) |
475 #if defined(ENABLE_NETWORK) |
478 if (dedicated_host) snprintf(_network_server_bind_ip_host, NETWORK_HOSTNAME_LENGTH, "%s", dedicated_host); |
476 if (dedicated_host) snprintf(_network_server_bind_ip_host, NETWORK_HOSTNAME_LENGTH, "%s", dedicated_host); |
479 if (dedicated_port) _network_server_port = dedicated_port; |
477 if (dedicated_port) _network_server_port = dedicated_port; |
480 if (_dedicated_forks && !dedicated) _dedicated_forks = false; |
478 if (_dedicated_forks && !dedicated) _dedicated_forks = false; |
481 #endif /* ENABLE_NETWORK */ |
479 #endif /* ENABLE_NETWORK */ |
752 SetupColorsAndInitialWindow(); |
750 SetupColorsAndInitialWindow(); |
753 |
751 |
754 ResetGRFConfig(true); |
752 ResetGRFConfig(true); |
755 |
753 |
756 /* Load game */ |
754 /* Load game */ |
757 if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode) != SL_OK) { |
755 if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, SCENARIO_DIR) != SL_OK) { |
758 LoadIntroGame(); |
756 LoadIntroGame(); |
759 ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0); |
757 ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0); |
760 } |
758 } |
761 |
759 |
762 _opt_ptr = &_opt; |
760 _opt_ptr = &_opt; |
774 DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE); |
772 DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE); |
775 |
773 |
776 MarkWholeScreenDirty(); |
774 MarkWholeScreenDirty(); |
777 } |
775 } |
778 |
776 |
779 bool SafeSaveOrLoad(const char *filename, int mode, int newgm) |
777 /** Load the specified savegame but on error do different things. |
|
778 * If loading fails due to corrupt savegame, bad version, etc. go back to |
|
779 * a previous correct state. In the menu for example load the intro game again. |
|
780 * @param filename file to be loaded |
|
781 * @param mode mode of loading, either SL_LOAD or SL_OLD_LOAD |
|
782 * @param newgm switch to this mode of loading fails due to some unknown error |
|
783 * @param subdir default directory to look for filename, set to 0 if not needed */ |
|
784 bool SafeSaveOrLoad(const char *filename, int mode, int newgm, Subdirectory subdir) |
780 { |
785 { |
781 byte ogm = _game_mode; |
786 byte ogm = _game_mode; |
782 |
787 |
783 _game_mode = newgm; |
788 _game_mode = newgm; |
784 switch (SaveOrLoad(filename, mode)) { |
789 assert(mode == SL_LOAD || mode == SL_OLD_LOAD); |
|
790 switch (SaveOrLoad(filename, mode, subdir)) { |
785 case SL_OK: return true; |
791 case SL_OK: return true; |
786 |
792 |
787 case SL_REINIT: |
793 case SL_REINIT: |
788 switch (ogm) { |
794 switch (ogm) { |
789 case GM_MENU: LoadIntroGame(); break; |
795 case GM_MENU: LoadIntroGame(); break; |
852 |
858 |
853 case SM_LOAD: { /* Load game, Play Scenario */ |
859 case SM_LOAD: { /* Load game, Play Scenario */ |
854 _opt_ptr = &_opt; |
860 _opt_ptr = &_opt; |
855 ResetGRFConfig(true); |
861 ResetGRFConfig(true); |
856 |
862 |
857 if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL)) { |
863 if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, NO_DIRECTORY)) { |
858 LoadIntroGame(); |
864 LoadIntroGame(); |
859 ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0); |
865 ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0); |
860 } else { |
866 } else { |
861 /* Update the local player for a loaded game. It is either always |
867 /* Update the local player for a loaded game. It is either always |
862 * player #1 (eg 0) or in the case of a dedicated server a spectator */ |
868 * player #1 (eg 0) or in the case of a dedicated server a spectator */ |
886 GenerateWorld(GW_HEIGHTMAP, 1 << _patches.map_x, 1 << _patches.map_y); |
892 GenerateWorld(GW_HEIGHTMAP, 1 << _patches.map_x, 1 << _patches.map_y); |
887 MarkWholeScreenDirty(); |
893 MarkWholeScreenDirty(); |
888 break; |
894 break; |
889 |
895 |
890 case SM_LOAD_SCENARIO: { /* Load scenario from scenario editor */ |
896 case SM_LOAD_SCENARIO: { /* Load scenario from scenario editor */ |
891 if (SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR)) { |
897 if (SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR, NO_DIRECTORY)) { |
892 _opt_ptr = &_opt; |
898 _opt_ptr = &_opt; |
893 |
899 |
894 SetLocalPlayer(OWNER_NONE); |
900 SetLocalPlayer(OWNER_NONE); |
895 _patches_newgame.starting_year = _cur_year; |
901 _patches_newgame.starting_year = _cur_year; |
896 } else { |
902 } else { |
902 case SM_MENU: /* Switch to game intro menu */ |
908 case SM_MENU: /* Switch to game intro menu */ |
903 LoadIntroGame(); |
909 LoadIntroGame(); |
904 break; |
910 break; |
905 |
911 |
906 case SM_SAVE: /* Save game */ |
912 case SM_SAVE: /* Save game */ |
907 if (SaveOrLoad(_file_to_saveload.name, SL_SAVE) != SL_OK) { |
913 if (SaveOrLoad(_file_to_saveload.name, SL_SAVE, NO_DIRECTORY) != SL_OK) { |
908 ShowErrorMessage(INVALID_STRING_ID, STR_4007_GAME_SAVE_FAILED, 0, 0); |
914 ShowErrorMessage(INVALID_STRING_ID, STR_4007_GAME_SAVE_FAILED, 0, 0); |
909 } else { |
915 } else { |
910 DeleteWindowById(WC_SAVELOAD, 0); |
916 DeleteWindowById(WC_SAVELOAD, 0); |
911 } |
917 } |
912 break; |
918 break; |
959 NewsLoop(); |
965 NewsLoop(); |
960 _current_player = p; |
966 _current_player = p; |
961 } |
967 } |
962 } |
968 } |
963 |
969 |
|
970 /** Create an autosave. The default name is "autosave#.sav". However with |
|
971 * the patch setting 'keep_all_autosave' the name defaults to company-name + date */ |
964 static void DoAutosave() |
972 static void DoAutosave() |
965 { |
973 { |
966 char buf[200]; |
974 char buf[MAX_PATH]; |
967 |
975 |
968 #if defined(PSP) |
976 #if defined(PSP) |
969 /* Autosaving in networking is too time expensive for the PSP */ |
977 /* Autosaving in networking is too time expensive for the PSP */ |
970 if (_networking) |
978 if (_networking) |
971 return; |
979 return; |
972 #endif /* PSP */ |
980 #endif /* PSP */ |
973 |
981 |
974 if (_patches.keep_all_autosave && _local_player != PLAYER_SPECTATOR) { |
982 if (_patches.keep_all_autosave && _local_player != PLAYER_SPECTATOR) { |
975 const Player *p = GetPlayer(_local_player); |
983 const Player *p = GetPlayer(_local_player); |
976 char* s = buf; |
|
977 |
|
978 s += snprintf(buf, lengthof(buf), "%s%s", _paths.autosave_dir, PATHSEP); |
|
979 |
984 |
980 SetDParam(0, p->name_1); |
985 SetDParam(0, p->name_1); |
981 SetDParam(1, p->name_2); |
986 SetDParam(1, p->name_2); |
982 SetDParam(2, _date); |
987 SetDParam(2, _date); |
983 s = GetString(s, STR_4004, lastof(buf)); |
988 GetString(buf, STR_4004, lastof(buf)); |
984 strecpy(s, ".sav", lastof(buf)); |
989 ttd_strlcpy(buf, ".sav", sizeof(buf)); |
985 } else { // generate a savegame name and number according to _patches.max_num_autosaves |
990 } else { |
986 snprintf(buf, lengthof(buf), "%s%sautosave%d.sav", _paths.autosave_dir, PATHSEP, _autosave_ctr); |
991 /* generate a savegame name and number according to _patches.max_num_autosaves */ |
987 |
992 snprintf(buf, sizeof(buf), "autosave%d.sav", _autosave_ctr); |
988 _autosave_ctr++; |
993 |
989 if (_autosave_ctr >= _patches.max_num_autosaves) { |
994 if (++_autosave_ctr >= _patches.max_num_autosaves) _autosave_ctr = 0; |
990 /* we reached the limit for numbers of autosaves. We will start over */ |
|
991 _autosave_ctr = 0; |
|
992 } |
|
993 } |
995 } |
994 |
996 |
995 DEBUG(sl, 2, "Autosaving to '%s'", buf); |
997 DEBUG(sl, 2, "Autosaving to '%s'", buf); |
996 if (SaveOrLoad(buf, SL_SAVE) != SL_OK) |
998 if (SaveOrLoad(buf, SL_SAVE, AUTOSAVE_DIR) != SL_OK) |
997 ShowErrorMessage(INVALID_STRING_ID, STR_AUTOSAVE_FAILED, 0, 0); |
999 ShowErrorMessage(INVALID_STRING_ID, STR_AUTOSAVE_FAILED, 0, 0); |
998 } |
1000 } |
999 |
1001 |
1000 static void ScrollMainViewport(int x, int y) |
1002 static void ScrollMainViewport(int x, int y) |
1001 { |
1003 { |
1298 WP(w,vp_d).scrollpos_y = _saved_scrollpos_y; |
1300 WP(w,vp_d).scrollpos_y = _saved_scrollpos_y; |
1299 WP(w,vp_d).dest_scrollpos_x = _saved_scrollpos_x; |
1301 WP(w,vp_d).dest_scrollpos_x = _saved_scrollpos_x; |
1300 WP(w,vp_d).dest_scrollpos_y = _saved_scrollpos_y; |
1302 WP(w,vp_d).dest_scrollpos_y = _saved_scrollpos_y; |
1301 |
1303 |
1302 vp = w->viewport; |
1304 vp = w->viewport; |
1303 vp->zoom = _saved_scrollpos_zoom; |
1305 vp->zoom = (ZoomLevel)min(_saved_scrollpos_zoom, ZOOM_LVL_MAX); |
1304 vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); |
1306 vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); |
1305 vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); |
1307 vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); |
1306 |
1308 |
1307 /* in version 4.1 of the savegame, is_active was introduced to determine |
1309 /* in version 4.1 of the savegame, is_active was introduced to determine |
1308 * if a player does exist, rather then checking name_1 */ |
1310 * if a player does exist, rather then checking name_1 */ |