8#define WIN32_LEAN_AND_MEAN
15#pragma comment(lib, "Ole32.lib")
16#pragma comment(lib, "Shell32.lib")
17#pragma comment(lib, "icu.lib")
20static CRITICAL_SECTION guard_abort_handler;
23 static bool run_once =
false;
25 EnterCriticalSection(&guard_abort_handler);
26 if(run_once ==
false) {
30 ZeroMemory(&si,
sizeof(si));
32 PROCESS_INFORMATION pi;
33 ZeroMemory(&pi,
sizeof(pi));
48 LeaveCriticalSection(&guard_abort_handler);
53 WaitForSingleObject(pi.hProcess, INFINITE);
55 CloseHandle(pi.hProcess);
56 CloseHandle(pi.hThread);
58 LeaveCriticalSection(&guard_abort_handler);
61LONG WINAPI
uef_wrapper(
struct _EXCEPTION_POINTERS* lpTopLevelExceptionFilter) {
63 return EXCEPTION_CONTINUE_SEARCH;
70 const wchar_t* expression,
71 const wchar_t* function,
80 typedef BOOL(WINAPI* tGetPolicy)(LPDWORD lpFlags);
81 typedef BOOL(WINAPI* tSetPolicy)(DWORD dwFlags);
82 const DWORD EXCEPTION_SWALLOWING = 0x1;
84 HMODULE kernel32 = LoadLibraryA(
"kernel32.dll");
86 tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32,
"GetProcessUserModeExceptionPolicy");
87 tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32,
"SetProcessUserModeExceptionPolicy");
88 if(pGetPolicy && pSetPolicy) {
90 if(pGetPolicy(&dwFlags)) {
92 pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
96 BOOL insanity = FALSE;
97 SetUserObjectInformationA(GetCurrentProcess(), UOI_TIMERPROC_EXCEPTION_SUPPRESSION, &insanity,
sizeof(insanity));
100int WINAPI
wWinMain(HINSTANCE , HINSTANCE , LPWSTR ,
int
104 HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
107 InitializeCriticalSection(&guard_abort_handler);
109 if(!IsDebuggerPresent()) {
113 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
118 SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
120 if(SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
124 auto parsed_cmd = CommandLineToArgvW(GetCommandLineW(), &num_params);
126 int headless_speed = 6;
127 bool headless_repeat =
false;
128 bool headless =
false;
134 auto msg = std::string(
"Start Alice.exe using the launcher");
149 auto root = get_root(fs_root);
150 auto common = open_directory(root,
NATIVE(
"common"));
153 if(
auto f = open_file(common,
NATIVE(
"bookmarks.txt")); f) {
155 err.file_name =
"bookmarks.txt";
157 parsers::parse_bookmark_file(gen, err, bookmark_context);
160 err.accumulated_errors +=
"File common/bookmarks.txt could not be opened\n";
167 ret += digits[v & 0x0F];
175 err.accumulated_errors.clear();
176 err.accumulated_warnings.clear();
178 auto inner_game_state = std::make_unique<sys::state>();
181 inner_game_state->load_scenario_data(err, bookmark_context.
bookmark_dates[date_index].date_);
184 if(date_index == 0) {
187 auto time_stamp =
uint64_t(std::time(0));
191 auto content = view_contents(*of);
194 scenario_key = inner_game_state->scenario_checksum;
196 inner_game_state->scenario_checksum = scenario_key;
201 if(!err.accumulated_errors.empty()) {
202 auto assembled_file = std::string(
"You can still play the mod, but it might be unstable\r\nThe following problems were encountered while creating the scenario:\r\n\r\nErrors:\r\n") + err.accumulated_errors +
"\r\n\r\nWarnings:\r\n" + err.accumulated_warnings;
225 for(
int i = 1; i < num_params; ++i) {
232 if(i + 1 < num_params) {
237 if(i + 1 < num_params) {
243 if(i + 1 < num_params) {
256 headless_repeat =
true;
258 if(i + 1 < num_params) {
260 headless_speed = std::atoi(str.c_str());
276 LocalFree(parsed_cmd);
284 game_state.
ui_pause.store(
false, std::memory_order::release);
287 if(headless_repeat) {
288 std::thread update_thread([&]() { game_state.
game_loop(); });
289 while(!game_state.
quit_signaled.load(std::memory_order::acquire)) {
291 std::this_thread::sleep_for(std::chrono::milliseconds(15));
309 update_thread.join();
314 std::thread update_thread([&]() { game_state.
game_loop(); });
317 game_state.
quit_signaled.store(
true, std::memory_order_release);
318 update_thread.join();
#define assert(condition)
native_string to_hex(uint64_t v)
void EnableCrashingOnCrashes()
void signal_abort_handler(int)
LONG WINAPI uef_wrapper(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter)
void invalid_parameter_wrapper(const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t pReserved)
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
void switch_scene(sys::state &state, scene_id ui_scene)
void finish(sys::state &state, bool notify_host)
void init(sys::state &state)
void add_root(file_system &fs, native_string_view root_path)
void write_file(directory const &dir, native_string_view file_name, char const *file_data, uint32_t file_size)
directory get_or_create_settings_directory()
native_string get_full_name(directory const &f)
std::optional< file > open_file(directory const &dir, native_string_view file_name)
std::string native_to_utf8(native_string_view data_in)
file_contents view_contents(file const &f)
directory get_or_create_scenario_directory()
mod_identifier extract_mod_information(uint8_t const *ptr_in, uint64_t file_size)
void write_scenario_file(sys::state &state, native_string_view name, uint32_t count)
void write_save_file(sys::state &state, save_type type, std::string const &name)
bool try_read_scenario_and_save_file(sys::state &state, native_string_view name)
void populate_definitions_map(sys::state &state)
void emit_error_message(std::string const &content, bool fatal)
void create_window(sys::state &game_state, creation_parameters const ¶ms)
std::string native_string
sys::player_name nickname
std::vector< bookmark_definition > bookmark_dates
network_mode_type network_mode
user_settings_s user_settings
std::atomic< bool > ui_pause
std::atomic< int32_t > actual_game_speed
dcon::nation_id local_player_nation
simple_fs::file_system common_fs
game_scene::scene_properties current_scene
std::atomic< bool > quit_signaled
void load_user_settings()
network::network_state network_state