1 #include "game.h"
2 
3 #include "assets/assets.h"
4 #include "building/model.h"
5 #include "building/properties.h"
6 #include "city/view.h"
7 #include "core/config.h"
8 #include "core/hotkey_config.h"
9 #include "core/image.h"
10 #include "core/lang.h"
11 #include "core/locale.h"
12 #include "core/log.h"
13 #include "core/random.h"
14 #include "editor/editor.h"
15 #include "figure/type.h"
16 #include "game/animation.h"
17 #include "game/file.h"
18 #include "game/file_editor.h"
19 #include "game/settings.h"
20 #include "game/speed.h"
21 #include "game/state.h"
22 #include "game/tick.h"
23 #include "graphics/font.h"
24 #include "graphics/video.h"
25 #include "graphics/window.h"
26 #include "scenario/property.h"
27 #include "scenario/scenario.h"
28 #include "sound/city.h"
29 #include "sound/system.h"
30 #include "translation/translation.h"
31 #include "window/editor/map.h"
32 #include "window/logo.h"
33 #include "window/main_menu.h"
34 
errlog(const char * msg)35 static void errlog(const char *msg)
36 {
37     log_error(msg, 0, 0);
38 }
39 
update_encoding(void)40 static encoding_type update_encoding(void)
41 {
42     language_type language = locale_determine_language();
43     encoding_type encoding = encoding_determine(language);
44     log_info("Detected encoding:", 0, encoding);
45     font_set_encoding(encoding);
46     translation_load(language);
47     return encoding;
48 }
49 
game_pre_init(void)50 int game_pre_init(void)
51 {
52     settings_load();
53     config_load();
54     hotkey_config_load();
55     scenario_settings_init();
56     game_state_unpause();
57 
58     if (!lang_load(0)) {
59         errlog("'c3.eng' or 'c3_mm.eng' files not found or too large.");
60         return 0;
61     }
62     update_encoding();
63     random_init();
64     return 1;
65 }
66 
is_unpatched(void)67 static int is_unpatched(void)
68 {
69     const uint8_t *delete_game = lang_get_string(1, 6);
70     const uint8_t *option_menu = lang_get_string(2, 0);
71     const uint8_t *difficulty_option = lang_get_string(2, 6);
72     const uint8_t *help_menu = lang_get_string(3, 0);
73     // Without patch, the difficulty option string does not exist and
74     // getting it "falls through" to the next text group, or, for some
75     // languages (pt_BR): delete game falls through to option menu
76     return difficulty_option == help_menu || delete_game == option_menu;
77 }
78 
game_init(void)79 int game_init(void)
80 {
81     if (!image_init()) {
82         errlog("unable to init graphics");
83         return 0;
84     }
85     if (!image_load_climate(CLIMATE_CENTRAL, 0, 1)) {
86         errlog("unable to load main graphics");
87         return 0;
88     }
89     if (!image_load_enemy(ENEMY_0_BARBARIAN)) {
90         errlog("unable to load enemy graphics");
91         return 0;
92     }
93     int missing_fonts = 0;
94     if (!image_load_fonts(encoding_get())) {
95         errlog("unable to load font graphics");
96         if (encoding_get() == ENCODING_KOREAN) {
97             missing_fonts = 1;
98         } else {
99             return 0;
100         }
101     }
102 
103     if (!model_load()) {
104         errlog("unable to load c3_model.txt");
105         return 0;
106     }
107 
108     assets_init();
109     init_augustus_building_properties();
110     load_custom_messages();
111     sound_system_init();
112     game_state_init();
113     int missing_assets = !assets_get_image_id("Roadblocks", "roadblock"); // If can't find roadblocks asset, extra assets not installed properly
114     window_logo_show(missing_fonts ? MESSAGE_MISSING_FONTS : (is_unpatched() ? MESSAGE_MISSING_PATCH : (missing_assets ? MESSAGE_MISSING_EXTRA_ASSETS : MESSAGE_NONE)));
115     return 1;
116 }
117 
reload_language(int is_editor,int reload_images)118 static int reload_language(int is_editor, int reload_images)
119 {
120     if (!lang_load(is_editor)) {
121         if (is_editor) {
122             errlog("'c3_map.eng' or 'c3_map_mm.eng' files not found or too large.");
123         } else {
124             errlog("'c3.eng' or 'c3_mm.eng' files not found or too large.");
125         }
126         return 0;
127     }
128     encoding_type encoding = update_encoding();
129     if (!is_editor) {
130         load_custom_messages();
131     }
132 
133     if (!image_load_fonts(encoding)) {
134         errlog("unable to load font graphics");
135         return 0;
136     }
137     if (!image_load_climate(scenario_property_climate(), is_editor, reload_images)) {
138         errlog("unable to load main graphics");
139         return 0;
140     }
141     return 1;
142 }
143 
game_init_editor(void)144 int game_init_editor(void)
145 {
146     if (!reload_language(1, 0)) {
147         return 0;
148     }
149 
150     game_file_editor_clear_data();
151     game_file_editor_create_scenario(2);
152 
153     if (city_view_is_sidebar_collapsed()) {
154         city_view_toggle_sidebar();
155     }
156 
157     editor_set_active(1);
158     window_editor_map_show();
159     return 1;
160 }
161 
game_exit_editor(void)162 void game_exit_editor(void)
163 {
164     if (!reload_language(0, 0)) {
165         return;
166     }
167     editor_set_active(0);
168     window_main_menu_show(1);
169 }
170 
game_reload_language(void)171 int game_reload_language(void)
172 {
173     return reload_language(0, 1);
174 }
175 
game_run(void)176 void game_run(void)
177 {
178     game_animation_update();
179     int num_ticks = game_speed_get_elapsed_ticks();
180     for (int i = 0; i < num_ticks; i++) {
181         game_tick_run();
182         game_file_write_mission_saved_game();
183 
184         if (window_is_invalid()) {
185             break;
186         }
187     }
188 }
189 
game_draw(void)190 void game_draw(void)
191 {
192     window_draw(0);
193     sound_city_play();
194 }
195 
game_exit(void)196 void game_exit(void)
197 {
198     video_shutdown();
199     settings_save();
200     config_save();
201     sound_system_shutdown();
202 }
203