win: winmain, manifest, icon, and some improvements

This commit is contained in:
Ondrej Novak 2025-02-08 12:42:55 +01:00
parent f70b29abab
commit 7bea57e587
23 changed files with 203 additions and 140 deletions

View file

@ -3,28 +3,30 @@
#include "../platform.h"
#include <iostream>
#include <string>
#include <sstream>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wchar.h>
#include <shellapi.h>
void show_help(const char *arg0) {
printf(
void show_help(std::ostream &out, const char *arg0) {
out <<
"Brany Skeldalu (Gates of Skeldal) portable game player\n"
"Copyright (c) 2025 Ondrej Novak. All rights reserved.\n\n"
"This work is licensed under the terms of the MIT license.\n"
"For a copy, see <https://opensource.org/licenses/MIT>.\n"
"\n"
"Usage:"
);
printf("%s [-f <file>] [-a <file>] [-l <lang>] [-s <dir>] [-h]\n\n", arg0);
printf("-f <file> path to configuration file\n"
"Usage:";
out << arg0 << " [-f <file>] [-a <file>] [-l <lang>] [-s <dir>] [-h]\n\n";
out << "-f <file> path to configuration file\n"
"-a <adv> path for adventure file (.adv)\n"
"-l <lang> set language (cz|en)"
"-l <lang> set language (cz|en)\n"
"-s <directory> generate string-tables (for localization) and exit\n"
"-h this help\n");
exit(0);
"-h this help\n";
}
void show_help_short() {
printf("Use -h for help\n");
void show_help_short(std::ostream &out) {
out << "Use -h for help\n";
}
@ -33,26 +35,43 @@ int main(int argc, char **argv) {
std::string adv_config_file;
std::string gen_stringtable_path;
std::string lang;
std::ostringstream console;
for (int optchr = -1; (optchr = getopt(argc, argv, "hf:a:s:l:")) != -1; ) {
switch (optchr) {
case 'f': config_name = optarg;break;
case 'a': adv_config_file = optarg;break;
case 'h': show_help(argv[0]);break;
case 'h': show_help(console, argv[0]);break;
case 'l': lang = optarg;break;
case 's': gen_stringtable_path = optarg;break;
default: show_help_short();
return 1;
default: show_help_short(console);break;
}
}
if (!check_file_exists(config_name.c_str())) {
console << "ERROR: A configuration file was not found:\n\n" << config_name << "\n\n";
show_help(console, argv[0]);
}
SKELDAL_CONFIG cfg;
cfg.short_help = show_help_short;
cfg.short_help = []{};
cfg.show_error = [](const char *txt) {
std::cerr << "ERROR: " << txt << std::endl;
char buff[MAX_PATH];
GetModuleFileNameA(NULL,buff,MAX_PATH);
MessageBoxA(NULL,txt,buff, MB_OK|MB_ICONEXCLAMATION|MB_SYSTEMMODAL|MB_APPLMODAL);
ExitProcess(1);
};
cfg.adventure_path = adv_config_file.empty()?NULL:adv_config_file.c_str();
cfg.config_path = config_name.c_str();
cfg.lang_path = lang.empty()?NULL:lang.c_str();
{
std::string msg = console.str();
if (!msg.empty()) {
cfg.show_error(msg.c_str());
return 1;
}
}
try {
if (!gen_stringtable_path.empty()) {
@ -63,7 +82,7 @@ int main(int argc, char **argv) {
}
} catch (const std::exception &e) {
std::cerr << "ERROR: " << e.what() << std::endl;
cfg.show_error(e.what());
return 1;
}
@ -71,3 +90,19 @@ int main(int argc, char **argv) {
}
int WinMain(HINSTANCE,HINSTANCE ,LPSTR, INT) {
int argc;
LPWSTR *szArglist = CommandLineToArgvW(GetCommandLineW(), &argc);
char **argv = (char **)alloca(sizeof(char *) * argc);
for (int i = 0; i < argc; ++i) {
DWORD need = WideCharToMultiByte(CP_UTF8,0,szArglist[i],wcslen(szArglist[i]),NULL,NULL,NULL,FALSE)+1;
argv[i] = (char *)alloca(sizeof(char) * need);
WideCharToMultiByte(CP_UTF8,0,szArglist[i],wcslen(szArglist[i]),argv[i],need,NULL,FALSE);
argv[i][need-1] = 0;
}
GlobalFree(szArglist);
return main(argc, argv);
}