Merge branch 'dev-mod-manager' of https://github.com/DavivaD/colobot into dev-mod-manager

pyro-refactor
MrSimbax 2020-07-17 11:49:51 +02:00
commit 4905abe30b
35 changed files with 713 additions and 13 deletions

View File

@ -120,6 +120,12 @@ msgstr ""
msgid "2) Then press the key you want to use instead."
msgstr ""
msgid "Unloaded Mods:"
msgstr ""
msgid "Loaded Mods:"
msgstr ""
msgid "Face type:"
msgstr ""
@ -343,6 +349,18 @@ msgstr ""
msgid "Play\\Start mission!"
msgstr ""
msgid "Workshop\\Open Workshop to search Mods"
msgstr ""
msgid "Open Directory\\Open Mods directory"
msgstr ""
msgid "Load\\Load Mod"
msgstr ""
msgid "Unload\\Unload Mod"
msgstr ""
msgid "Device\\Driver and resolution settings"
msgstr ""
@ -358,6 +376,9 @@ msgstr ""
msgid "Sound\\Music and game sound volume"
msgstr ""
msgid "Mods\\Manage installed mods"
msgstr ""
msgid "Unit"
msgstr ""

View File

@ -844,12 +844,18 @@ msgstr "Seznam uložených misí"
msgid "Load a saved mission"
msgstr "Nahrát uloženou misi"
msgid "Load\\Load Mod"
msgstr ""
msgid "Load\\Load a saved mission"
msgstr "Nahrát\\Nahrát uloženou misi"
msgid "Load\\Loads the selected mission"
msgstr "Nahrát\\Nahraje vybranou misi"
msgid "Loaded Mods:"
msgstr ""
msgid "Loading basic level settings"
msgstr "Načítám základní nastavení mapy"
@ -904,6 +910,9 @@ msgstr "Mise na této planetě:"
msgid "Missions\\Select mission"
msgstr "Mise\\Vyberte misi"
msgid "Mods\\Manage installed mods"
msgstr ""
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
msgstr "Vodorovné převrácení posunu\\Při vodorovném posunu kamery myší pousouvat opačným směrem"
@ -1072,6 +1081,9 @@ msgstr "Otevřít"
msgid "Open (Ctrl+O)"
msgstr "Otevřít (Ctrl+O)"
msgid "Open Directory\\Open Mods directory"
msgstr ""
msgid "Opening brace missing"
msgstr "Chybí levá složená závorka"
@ -1691,6 +1703,12 @@ msgstr "Neznámá zástupná sekvence"
msgid "Unknown function"
msgstr "Neznámá funkce"
msgid "Unload\\Unload Mod"
msgstr ""
msgid "Unloaded Mods:"
msgstr ""
msgid "Up (\\key gup;)"
msgstr "Vzhůru (\\key gup;)"
@ -1766,6 +1784,9 @@ msgstr "Létající detektor"
msgid "Withdraw shield (\\key action;)"
msgstr "Vypnout štít (\\key action;)"
msgid "Workshop\\Open Workshop to search Mods"
msgstr ""
msgid "Worm"
msgstr "Červ"

View File

@ -846,12 +846,18 @@ msgstr "Liste der gespeicherten Missionen"
msgid "Load a saved mission"
msgstr "Gespeicherte Mission laden"
msgid "Load\\Load Mod"
msgstr ""
msgid "Load\\Load a saved mission"
msgstr "Laden\\Eine gespeicherte Mission öffnen"
msgid "Load\\Loads the selected mission"
msgstr "Laden\\Öffnet eine gespeicherte Mission"
msgid "Loaded Mods:"
msgstr ""
msgid "Loading basic level settings"
msgstr "Lade Level-Grundeinstellungen"
@ -920,6 +926,9 @@ msgstr "Liste der Missionen des Planeten:"
msgid "Missions\\Select mission"
msgstr "Missionen\\Aufbruch ins Weltall"
msgid "Mods\\Manage installed mods"
msgstr ""
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
msgstr "Umkehr X\\Umkehr der Kameradrehung X-Achse"
@ -1088,6 +1097,9 @@ msgstr "Öffnen"
msgid "Open (Ctrl+O)"
msgstr "Öffnen (Ctrl+O)"
msgid "Open Directory\\Open Mods directory"
msgstr ""
msgid "Opening brace missing"
msgstr "Es fehlt eine offene geschweifte Klammer\"{\""
@ -1708,6 +1720,12 @@ msgstr ""
msgid "Unknown function"
msgstr "Unbekannte Funktion"
msgid "Unload\\Unload Mod"
msgstr ""
msgid "Unloaded Mods:"
msgstr ""
msgid "Up (\\key gup;)"
msgstr "Steigt (\\key gup;)"
@ -1783,6 +1801,9 @@ msgstr "Schnüffler"
msgid "Withdraw shield (\\key action;)"
msgstr "Schutzschild einholen (\\key action;)"
msgid "Workshop\\Open Workshop to search Mods"
msgstr ""
msgid "Worm"
msgstr "Wurm"

View File

@ -848,12 +848,18 @@ msgstr "Liste des missions enregistrées"
msgid "Load a saved mission"
msgstr "Chargement d'une mission enregistrée"
msgid "Load\\Load Mod"
msgstr ""
msgid "Load\\Load a saved mission"
msgstr "Charger\\Charger une mission enregistrée"
msgid "Load\\Loads the selected mission"
msgstr "Charger\\Charger la mission sélectionnée"
msgid "Loaded Mods:"
msgstr ""
msgid "Loading basic level settings"
msgstr "Chargement des configurations de base du niveau"
@ -922,6 +928,9 @@ msgstr "Liste des missions du chapitre :"
msgid "Missions\\Select mission"
msgstr "Missions\\La grande aventure"
msgid "Mods\\Manage installed mods"
msgstr ""
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
msgstr "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord"
@ -1090,6 +1099,9 @@ msgstr "Ouvrir"
msgid "Open (Ctrl+O)"
msgstr "Ouvrir (Ctrl+O)"
msgid "Open Directory\\Open Mods directory"
msgstr ""
msgid "Opening brace missing"
msgstr "Début d'un bloc attendu"
@ -1710,6 +1722,12 @@ msgstr "Séquence d'échappement inconnue"
msgid "Unknown function"
msgstr "Routine inconnue"
msgid "Unload\\Unload Mod"
msgstr ""
msgid "Unloaded Mods:"
msgstr ""
msgid "Up (\\key gup;)"
msgstr "Monte (\\key gup;)"
@ -1785,6 +1803,9 @@ msgstr "Robot renifleur volant"
msgid "Withdraw shield (\\key action;)"
msgstr "Refermer le bouclier (\\key action;)"
msgid "Workshop\\Open Workshop to search Mods"
msgstr ""
msgid "Worm"
msgstr "Ver"

View File

@ -843,12 +843,18 @@ msgstr "Lista zapisanych misji"
msgid "Load a saved mission"
msgstr "Wczytaj zapisaną misję"
msgid "Load\\Load Mod"
msgstr ""
msgid "Load\\Load a saved mission"
msgstr "Wczytaj\\Wczytuje zapisaną misję"
msgid "Load\\Loads the selected mission"
msgstr "Wczytaj\\Wczytuje zaznaczoną misję"
msgid "Loaded Mods:"
msgstr ""
msgid "Loading basic level settings"
msgstr "Wczytywanie ustawień poziomu"
@ -903,6 +909,9 @@ msgstr "Misje na tej planecie:"
msgid "Missions\\Select mission"
msgstr "Misje\\Wybierz misję"
msgid "Mods\\Manage installed mods"
msgstr ""
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
msgstr "Odwrócenie myszy X\\Odwrócenie kierunków przewijania w poziomie"
@ -1071,6 +1080,9 @@ msgstr "Otwórz"
msgid "Open (Ctrl+O)"
msgstr "Otwórz (Ctrl+O)"
msgid "Open Directory\\Open Mods directory"
msgstr ""
msgid "Opening brace missing"
msgstr "Brak klamry otwierającej"
@ -1690,6 +1702,12 @@ msgstr ""
msgid "Unknown function"
msgstr "Funkcja nieznana"
msgid "Unload\\Unload Mod"
msgstr ""
msgid "Unloaded Mods:"
msgstr ""
msgid "Up (\\key gup;)"
msgstr "Góra (\\key gup;)"
@ -1765,6 +1783,9 @@ msgstr "Szperacz latający"
msgid "Withdraw shield (\\key action;)"
msgstr "Wyłącz osłonę (\\key action;)"
msgid "Workshop\\Open Workshop to search Mods"
msgstr ""
msgid "Worm"
msgstr "Robal"

View File

@ -852,12 +852,18 @@ msgstr "Список сохраненных миссий"
msgid "Load a saved mission"
msgstr "Загрузить"
msgid "Load\\Load Mod"
msgstr ""
msgid "Load\\Load a saved mission"
msgstr "Загрузить\\Загрузить сохраненную миссию"
msgid "Load\\Loads the selected mission"
msgstr "Загрузить\\Загрузить выбранную миссию"
msgid "Loaded Mods:"
msgstr ""
msgid "Loading basic level settings"
msgstr "Загрузка основных настроек уровня"
@ -926,6 +932,9 @@ msgstr "Миссии на этой планете:"
msgid "Missions\\Select mission"
msgstr "Миссии\\Выбор миссии"
msgid "Mods\\Manage installed mods"
msgstr ""
msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis"
msgstr "Инверсия мыши по оси X\\Инверсия прокрутки по оси Х"
@ -1096,6 +1105,9 @@ msgstr "Открыть"
msgid "Open (Ctrl+O)"
msgstr "Открыть (Ctrl+O)"
msgid "Open Directory\\Open Mods directory"
msgstr ""
msgid "Opening brace missing"
msgstr "Открывающая скобка отсутствует"
@ -1721,6 +1733,12 @@ msgstr ""
msgid "Unknown function"
msgstr "Неизвестная функция"
msgid "Unload\\Unload Mod"
msgstr ""
msgid "Unloaded Mods:"
msgstr ""
msgid "Up (\\key gup;)"
msgstr "Вверх (\\key gup;)"
@ -1796,6 +1814,9 @@ msgstr "Летающий искатель"
msgid "Withdraw shield (\\key action;)"
msgstr "Снять щит (\\key action;)"
msgid "Workshop\\Open Workshop to search Mods"
msgstr ""
msgid "Worm"
msgstr "Червь"

View File

@ -581,6 +581,8 @@ set(BASE_SOURCES
ui/screen/screen_setup_game.h
ui/screen/screen_setup_graphics.cpp
ui/screen/screen_setup_graphics.h
ui/screen/screen_setup_mods.cpp
ui/screen/screen_setup_mods.h
ui/screen/screen_setup_sound.cpp
ui/screen/screen_setup_sound.h
ui/screen/screen_welcome.cpp

View File

@ -726,6 +726,26 @@ bool CApplication::Create()
return true;
}
void CApplication::Reload()
{
m_sound->Create();
m_engine->ReloadAllTextures();
CThread musicLoadThread([this]()
{
SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp();
m_systemUtils->GetCurrentTimeStamp(musicLoadStart);
m_sound->CacheAll();
SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp();
m_systemUtils->GetCurrentTimeStamp(musicLoadEnd);
float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC);
GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime);
},
"Sound loading thread");
musicLoadThread.Start();
m_controller->GetRobotMain()->UpdateCustomLevelList();
}
bool CApplication::CreateVideoSurface()
{
Uint32 videoFlags = SDL_WINDOW_OPENGL;

View File

@ -170,6 +170,8 @@ public:
ParseArgsStatus ParseArguments(int argc, char *argv[]);
//! Initializes the application
bool Create();
//! Reloads the application
void Reload();
//! Main event loop
int Run();
//! Returns the code to be returned at main() exit

View File

@ -72,7 +72,28 @@ void CPathManager::AddModAutoloadDir(const std::string &modAutoloadDirPath)
void CPathManager::AddMod(const std::string &modPath)
{
m_mods.push_back(modPath);
std::string::size_type enabled;
enabled = modPath.find('~');
if (enabled == std::string::npos)
{
GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str());
CResourceManager::AddLocation(modPath, true);
}
else
{
GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str());
}
}
void CPathManager::RemoveMod(const std::string &modPath)
{
std::string::size_type enabled;
enabled = modPath.find('~');
if (enabled == std::string::npos)
{
GetLogger()->Info("Unloading mod: '%s'\n", modPath.c_str());
CResourceManager::RemoveLocation(modPath);
}
}
const std::string& CPathManager::GetDataPath()
@ -154,15 +175,33 @@ void CPathManager::InitPaths()
GetLogger()->Trace("Searching for mods in '%s'...\n", modAutoloadDir.c_str());
for (const std::string& modPath : FindModsInDir(modAutoloadDir))
{
GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str());
CResourceManager::AddLocation(modPath);
std::string::size_type enabled;
enabled = modPath.find('~');
if (enabled == std::string::npos)
{
GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str());
CResourceManager::AddLocation(modPath);
}
else
{
GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str());
}
}
}
for (const std::string& modPath : m_mods)
{
GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str());
CResourceManager::AddLocation(modPath);
std::string::size_type enabled;
enabled = modPath.find('~');
if (enabled == std::string::npos)
{
GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str());
CResourceManager::AddLocation(modPath);
}
else
{
GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str());
}
}
CResourceManager::SetSaveLocation(m_savePath);

View File

@ -39,6 +39,7 @@ public:
void SetSavePath(const std::string &savePath);
void AddModAutoloadDir(const std::string &modAutoloadDirPath);
void AddMod(const std::string &modPath);
void RemoveMod(const std::string &modPath);
const std::string& GetDataPath();
const std::string& GetLangPath();

View File

@ -201,6 +201,7 @@ void InitializeEventTypeTexts()
EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPp] = "EVENT_INTERFACE_SETUPp";
EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPc] = "EVENT_INTERFACE_SETUPc";
EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPs] = "EVENT_INTERFACE_SETUPs";
EVENT_TYPE_TEXT[EVENT_INTERFACE_SETUPm] = "EVENT_INTERFACE_SETUPm";
EVENT_TYPE_TEXT[EVENT_INTERFACE_DEVICE] = "EVENT_INTERFACE_DEVICE";
EVENT_TYPE_TEXT[EVENT_INTERFACE_RESOL] = "EVENT_INTERFACE_RESOL";
@ -272,6 +273,13 @@ void InitializeEventTypeTexts()
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT]= "EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT]= "EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT";
EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_UNLOADED] = "EVENT_INTERFACE_MODS_UNLOADED";
EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_LOADED] = "EVENT_INTERFACE_MODS_LOADED";
EVENT_TYPE_TEXT[EVENT_INTERFACE_WORKSHOP] = "EVENT_INTERFACE_WORKSHOP";
EVENT_TYPE_TEXT[EVENT_INTERFACE_MODS_DIR] = "EVENT_INTERFACE_MODS_DIR";
EVENT_TYPE_TEXT[EVENT_INTERFACE_LOAD] = "EVENT_INTERFACE_LOAD";
EVENT_TYPE_TEXT[EVENT_INTERFACE_UNLOAD] = "EVENT_INTERFACE_UNLOAD";
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTl] = "EVENT_INTERFACE_GLINTl";
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTr] = "EVENT_INTERFACE_GLINTr";
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTu] = "EVENT_INTERFACE_GLINTu";

View File

@ -236,6 +236,7 @@ enum EventType
EVENT_INTERFACE_SETUPp = 432,
EVENT_INTERFACE_SETUPc = 433,
EVENT_INTERFACE_SETUPs = 434,
EVENT_INTERFACE_SETUPm = 435,
EVENT_INTERFACE_DEVICE = 440,
EVENT_INTERFACE_RESOL = 441,
@ -311,6 +312,13 @@ enum EventType
EVENT_INTERFACE_JOYSTICK_CAM_Y_INVERT = 573,
EVENT_INTERFACE_JOYSTICK_CAM_Z_INVERT = 574,
EVENT_INTERFACE_MODS_UNLOADED = 580,
EVENT_INTERFACE_MODS_LOADED = 581,
EVENT_INTERFACE_WORKSHOP = 582,
EVENT_INTERFACE_MODS_DIR = 583,
EVENT_INTERFACE_LOAD = 584,
EVENT_INTERFACE_UNLOAD = 585,
EVENT_INTERFACE_GLINTl = 590,
EVENT_INTERFACE_GLINTr = 591,
EVENT_INTERFACE_GLINTu = 592,

View File

@ -92,6 +92,9 @@ void InitializeRestext()
stringsText[RT_SETUP_KEY1] = TR("1) First click on the key you want to redefine.");
stringsText[RT_SETUP_KEY2] = TR("2) Then press the key you want to use instead.");
stringsText[RT_MODS_UNLOADED] = TR("Unloaded Mods:");
stringsText[RT_MODS_LOADED] = TR("Loaded Mods:");
stringsText[RT_PERSO_FACE] = TR("Face type:");
stringsText[RT_PERSO_GLASSES] = TR("Eyeglasses:");
stringsText[RT_PERSO_HAIR] = TR("Hair color:");
@ -182,11 +185,16 @@ void InitializeRestext()
stringsEvent[EVENT_INTERFACE_QUIT] = TR("Quit\\Quit Colobot: Gold Edition");
stringsEvent[EVENT_INTERFACE_BACK] = TR("<< Back \\Back to the previous screen");
stringsEvent[EVENT_INTERFACE_PLAY] = TR("Play\\Start mission!");
stringsEvent[EVENT_INTERFACE_WORKSHOP] = TR("Workshop\\Open Workshop to search Mods");
stringsEvent[EVENT_INTERFACE_MODS_DIR] = TR("Open Directory\\Open Mods directory");
stringsEvent[EVENT_INTERFACE_LOAD] = TR("Load\\Load Mod");
stringsEvent[EVENT_INTERFACE_UNLOAD] = TR("Unload\\Unload Mod");
stringsEvent[EVENT_INTERFACE_SETUPd] = TR("Device\\Driver and resolution settings");
stringsEvent[EVENT_INTERFACE_SETUPg] = TR("Graphics\\Graphics settings");
stringsEvent[EVENT_INTERFACE_SETUPp] = TR("Game\\Game settings");
stringsEvent[EVENT_INTERFACE_SETUPc] = TR("Controls\\Keyboard, joystick and mouse settings");
stringsEvent[EVENT_INTERFACE_SETUPs] = TR("Sound\\Music and game sound volume");
stringsEvent[EVENT_INTERFACE_SETUPm] = TR("Mods\\Manage installed mods");
stringsEvent[EVENT_INTERFACE_DEVICE] = TR("Unit");
stringsEvent[EVENT_INTERFACE_RESOL] = TR("Resolution");
stringsEvent[EVENT_INTERFACE_FULL] = TR("Full screen\\Full screen or window mode");

View File

@ -86,6 +86,9 @@ enum ResTextType
RT_SETUP_KEY1 = 82,
RT_SETUP_KEY2 = 83,
RT_MODS_UNLOADED = 85,
RT_MODS_LOADED = 86,
RT_PERSO_FACE = 90,
RT_PERSO_GLASSES = 91,
RT_PERSO_HAIR = 92,

View File

@ -215,3 +215,13 @@ std::string CSystemUtils::GetEnvVar(const std::string& name)
{
return "";
}
void CSystemUtils::OpenPath(std::string path)
{
assert(false);
}
void CSystemUtils::OpenWebsite(std::string website)
{
assert(false);
}

View File

@ -145,6 +145,12 @@ public:
//! Returns the environment variable with the given name or an empty string if it does not exist
virtual std::string GetEnvVar(const std::string &name);
//! Opens a path with default file browser
virtual void OpenPath(std::string path);
//! Opens a website with default web browser
virtual void OpenWebsite(std::string website);
//! Sleep for given amount of microseconds
virtual void Usleep(int usecs) = 0;

View File

@ -150,6 +150,28 @@ std::string CSystemUtilsLinux::GetEnvVar(const std::string& name)
return "";
}
void CSystemUtilsLinux::OpenPath(std::string path)
{
int result;
result = system(("xdg-open \""+path+"\"").c_str());
if (result == -1)
{
GetLogger()->Error("Failed to open path: %s\n", path.c_str());
}
}
void CSystemUtilsLinux::OpenWebsite(std::string website)
{
int result;
result = system(("xdg-open \""+website+"\"").c_str());
if (result == -1)
{
GetLogger()->Error("Failed to open website: %s\n", website.c_str());
}
}
void CSystemUtilsLinux::Usleep(int usec)
{
usleep(usec);

View File

@ -48,6 +48,9 @@ public:
std::string GetEnvVar(const std::string& name) override;
void OpenPath(std::string path) override;
void OpenWebsite(std::string website) override;
void Usleep(int usec) override;
private:

View File

@ -119,6 +119,28 @@ std::string CSystemUtilsMacOSX::GetEnvVar(const std::string& str)
return std::string();
}
void CSystemUtilsLinux::OpenPath(std::string path)
{
int result;
result = system(("open \""+path+"\"").c_str()); // TODO: Test on macOS
if (result == -1)
{
GetLogger()->Error("Failed to open path: %s\n", path.c_str());
}
}
void CSystemUtilsLinux::OpenWebsite(std::string website)
{
int result;
result = system(("open \""+website+"\"").c_str()); // TODO: Test on macOS
if (result == -1)
{
GetLogger()->Error("Failed to open website: %s\n", website.c_str());
}
}
void CSystemUtilsMacOSX::Usleep(int usec)
{
usleep(usec);

View File

@ -38,6 +38,9 @@ public:
std::string GetEnvVar(const std::string& name) override;
void OpenPath(std::string path) override;
void OpenWebsite(std::string website) override;
void Usleep(int usec) override;
private:

View File

@ -44,6 +44,16 @@ long long int CSystemUtilsOther::TimeStampExactDiff(SystemTimeStamp* before, Sys
return (after->sdlTicks - before->sdlTicks) * 1000000ll;
}
void CSystemUtilsOther::OpenPath(std::string path)
{
// TODO
}
void CSystemUtilsOther::OpenWebsite(std::string website)
{
// TODO
}
void CSystemUtilsOther::Usleep(int usec)
{
SDL_Delay(usec / 1000); // close enough

View File

@ -50,6 +50,9 @@ public:
void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
void OpenPath(std::string path) override;
void OpenWebsite(std::string website) override;
void Usleep(int usec) override;
};

View File

@ -152,6 +152,28 @@ std::string CSystemUtilsWindows::GetEnvVar(const std::string& name)
}
}
void CSystemUtilsWindows::OpenPath(std::string path)
{
int result;
result = system(("explorer \""+path+"\"").c_str()); // TODO: Test on macOS
if (result == -1)
{
GetLogger()->Error("Failed to open path: %s\n", path.c_str());
}
}
void CSystemUtilsWindows::OpenWebsite(std::string website)
{
int result;
result = system(("rundll32 url.dll,FileProtocolHandler \""+website+"\"").c_str()); // TODO: Test on macOS
if (result == -1)
{
GetLogger()->Error("Failed to open website: %s\n", website.c_str());
}
}
void CSystemUtilsWindows::Usleep(int usec)
{
LARGE_INTEGER ft;

View File

@ -46,6 +46,9 @@ public:
std::string GetEnvVar(const std::string& name) override;
void OpenPath(std::string path) override;
void OpenWebsite(std::string website) override;
void Usleep(int usec) override;
public:

View File

@ -1189,6 +1189,10 @@ public:
void EnablePauseBlur();
void DisablePauseBlur();
//! Reloads all textures
/** This additionally sends EVENT_RELOAD_TEXTURES to reload all textures not maintained by CEngine **/
void ReloadAllTextures();
protected:
//! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
/** Instead of calling this directly, send EVENT_RESOLUTION_CHANGED event **/
@ -1287,10 +1291,6 @@ protected:
};
static void WriteScreenShotThread(std::unique_ptr<WriteScreenShotData> data);
//! Reloads all textures
/** This additionally sends EVENT_RELOAD_TEXTURES to reload all textures not maintained by CEngine **/
void ReloadAllTextures();
protected:
CApplication* m_app;
CSystemUtils* m_systemUtils;

View File

@ -262,6 +262,8 @@ void CText::FlushCache()
m_lastCachedFont = nullptr;
m_lastFontType = FONT_COMMON;
m_lastFontSize = 0;
Create();
}
int CText::GetTabSize()

View File

@ -326,11 +326,13 @@ std::string PhaseToString(Phase phase)
if (phase == PHASE_SETUPp) return "PHASE_SETUPp";
if (phase == PHASE_SETUPc) return "PHASE_SETUPc";
if (phase == PHASE_SETUPs) return "PHASE_SETUPs";
if (phase == PHASE_SETUPm) return "PHASE_SETUPm";
if (phase == PHASE_SETUPds) return "PHASE_SETUPds";
if (phase == PHASE_SETUPgs) return "PHASE_SETUPgs";
if (phase == PHASE_SETUPps) return "PHASE_SETUPps";
if (phase == PHASE_SETUPcs) return "PHASE_SETUPcs";
if (phase == PHASE_SETUPss) return "PHASE_SETUPss";
if (phase == PHASE_SETUPms) return "PHASE_SETUPms";
if (phase == PHASE_WRITEs) return "PHASE_WRITEs";
if (phase == PHASE_READ) return "PHASE_READ";
if (phase == PHASE_READs) return "PHASE_READs";
@ -343,7 +345,7 @@ std::string PhaseToString(Phase phase)
bool IsInSimulationConfigPhase(Phase phase)
{
return (phase >= PHASE_SETUPds && phase <= PHASE_SETUPss) || phase == PHASE_READs || phase == PHASE_WRITEs;
return (phase >= PHASE_SETUPds && phase <= PHASE_SETUPms) || phase == PHASE_READs || phase == PHASE_WRITEs;
}
bool IsPhaseWithWorld(Phase phase)
@ -3911,6 +3913,7 @@ void CRobotMain::ChangeColor()
m_phase != PHASE_SETUPps &&
m_phase != PHASE_SETUPcs &&
m_phase != PHASE_SETUPss &&
m_phase != PHASE_SETUPms &&
m_phase != PHASE_WIN &&
m_phase != PHASE_LOST &&
m_phase != PHASE_APPERANCE ) return;

View File

@ -61,11 +61,13 @@ enum Phase
PHASE_SETUPp,
PHASE_SETUPc,
PHASE_SETUPs,
PHASE_SETUPm,
PHASE_SETUPds,
PHASE_SETUPgs,
PHASE_SETUPps,
PHASE_SETUPcs,
PHASE_SETUPss,
PHASE_SETUPms,
PHASE_WRITEs,
PHASE_READ,
PHASE_READs,

View File

@ -107,6 +107,7 @@ bool CMainDialog::EventProcess(const Event &event)
if ( CScreenSetup::GetTab() == PHASE_SETUPp ) m_main->ChangePhase(PHASE_SETUPps);
if ( CScreenSetup::GetTab() == PHASE_SETUPc ) m_main->ChangePhase(PHASE_SETUPcs);
if ( CScreenSetup::GetTab() == PHASE_SETUPs ) m_main->ChangePhase(PHASE_SETUPss);
if ( CScreenSetup::GetTab() == PHASE_SETUPm ) m_main->ChangePhase(PHASE_SETUPss);
}
if ( pressedButton == EVENT_INTERFACE_WRITE )

View File

@ -55,6 +55,7 @@
#include "ui/screen/screen_setup_display.h"
#include "ui/screen/screen_setup_game.h"
#include "ui/screen/screen_setup_graphics.h"
#include "ui/screen/screen_setup_mods.h"
#include "ui/screen/screen_setup_sound.h"
#include "ui/screen/screen_welcome.h"
@ -84,6 +85,7 @@ CMainUserInterface::CMainUserInterface()
m_screenSetupDisplay = MakeUnique<CScreenSetupDisplay>();
m_screenSetupGame = MakeUnique<CScreenSetupGame>();
m_screenSetupGraphics = MakeUnique<CScreenSetupGraphics>();
m_screenSetupMods = MakeUnique<CScreenSetupMods>();
m_screenSetupSound = MakeUnique<CScreenSetupSound>();
m_screenMainMenu = MakeUnique<CScreenMainMenu>();
m_screenPlayerSelect = MakeUnique<CScreenPlayerSelect>(m_dialog.get());
@ -144,6 +146,7 @@ CScreenSetup* CMainUserInterface::GetSetupScreen(Phase phase)
if(phase == PHASE_SETUPp) return m_screenSetupGame.get();
if(phase == PHASE_SETUPc) return m_screenSetupControls.get();
if(phase == PHASE_SETUPs) return m_screenSetupSound.get();
if(phase == PHASE_SETUPm) return m_screenSetupMods.get();
assert(false);
return nullptr;
}
@ -184,14 +187,14 @@ void CMainUserInterface::ChangePhase(Phase phase)
m_screenLevelList->SetLevelCategory(m_main->GetLevelCategory());
m_currentScreen = m_screenLevelList.get();
}
if (m_phase >= PHASE_SETUPd && m_phase <= PHASE_SETUPs)
if (m_phase >= PHASE_SETUPd && m_phase <= PHASE_SETUPm)
{
CScreenSetup* screenSetup = GetSetupScreen(m_phase);
screenSetup->SetInSimulation(false);
screenSetup->SetActive();
m_currentScreen = screenSetup;
}
if (m_phase >= PHASE_SETUPds && m_phase <= PHASE_SETUPss)
if (m_phase >= PHASE_SETUPds && m_phase <= PHASE_SETUPms)
{
CScreenSetup* screenSetup = GetSetupScreen(static_cast<Phase>(m_phase - PHASE_SETUPds + PHASE_SETUPd));
screenSetup->SetInSimulation(true);
@ -347,6 +350,7 @@ void CMainUserInterface::GlintMove()
m_phase == PHASE_SETUPp ||
m_phase == PHASE_SETUPc ||
m_phase == PHASE_SETUPs ||
m_phase == PHASE_SETUPm ||
m_phase == PHASE_SETUPds ||
m_phase == PHASE_SETUPgs ||
m_phase == PHASE_SETUPps ||
@ -536,6 +540,7 @@ void CMainUserInterface::FrameParticle(float rTime)
m_phase == PHASE_SETUPp ||
m_phase == PHASE_SETUPc ||
m_phase == PHASE_SETUPs ||
m_phase == PHASE_SETUPm ||
m_phase == PHASE_READ )
{
pParti = partiPosBig;

View File

@ -57,6 +57,7 @@ class CScreenSetupControls;
class CScreenSetupDisplay;
class CScreenSetupGame;
class CScreenSetupGraphics;
class CScreenSetupMods;
class CScreenSetupSound;
class CScreenWelcome;
@ -120,6 +121,7 @@ protected:
std::unique_ptr<CScreenSetupDisplay> m_screenSetupDisplay;
std::unique_ptr<CScreenSetupGame> m_screenSetupGame;
std::unique_ptr<CScreenSetupGraphics> m_screenSetupGraphics;
std::unique_ptr<CScreenSetupMods> m_screenSetupMods;
std::unique_ptr<CScreenSetupSound> m_screenSetupSound;
std::unique_ptr<CScreenWelcome> m_screenWelcome;

View File

@ -83,7 +83,7 @@ void CScreenSetup::CreateInterface()
ddim.y = 0.05f;
pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray
ddim.x = 0.78f/5-0.01f;
ddim.x = 0.65f/5-0.01f;
ddim.y = 0.06f;
pos.x = 0.115f;
pos.y = 0.76f;
@ -116,6 +116,12 @@ void CScreenSetup::CreateInterface()
pb->SetState(STATE_CARD);
pb->SetState(STATE_CHECK, (m_tab == PHASE_SETUPs));
pos.x += ddim.x+0.01f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPm);
pb->SetState(STATE_SHADOW);
pb->SetState(STATE_CARD);
pb->SetState(STATE_CHECK, (m_tab == PHASE_SETUPm));
pos.x = 0.10f;
ddim.x = 0.80f;
pos.y = 0.34f;
@ -148,6 +154,10 @@ bool CScreenSetup::EventProcess(const Event &event)
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == nullptr ) return false;
CButton* pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_SETUPm));
if ( pb == nullptr ) return false;
pb->SetState(STATE_ENABLE);
if ( event.type == pw->GetEventTypeClose() ||
event.type == EVENT_INTERFACE_BACK ||
(event.type == EVENT_KEY_DOWN && event.GetData<KeyEventData>()->key == KEY(ESCAPE)) )
@ -179,6 +189,10 @@ bool CScreenSetup::EventProcess(const Event &event)
m_main->ChangePhase(PHASE_SETUPs);
return false;
case EVENT_INTERFACE_SETUPm:
m_main->ChangePhase(PHASE_SETUPm);
return false;
default:
break;
}
@ -188,6 +202,10 @@ bool CScreenSetup::EventProcess(const Event &event)
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == nullptr ) return false;
CButton* pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_SETUPm));
if ( pb == nullptr ) return false;
pb->ClearState(STATE_ENABLE);
if ( event.type == pw->GetEventTypeClose() ||
event.type == EVENT_INTERFACE_BACK ||
(event.type == EVENT_KEY_DOWN && event.GetData<KeyEventData>()->key == KEY(ESCAPE)) )
@ -221,6 +239,9 @@ bool CScreenSetup::EventProcess(const Event &event)
m_main->ChangePhase(PHASE_SETUPss);
return false;
case EVENT_INTERFACE_SETUPm:
assert(false); // should never get here
default:
break;
}

View File

@ -0,0 +1,291 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2019, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#include "ui/screen/screen_setup_mods.h"
#include "app/app.h"
#include "app/pathman.h"
#include "common/system/system.h"
#include "common/restext.h"
#include "common/config.h"
#include "common/logger.h"
#include "common/settings.h"
#include "common/resources/resourcemanager.h"
#include "level/parser/parser.h"
#include "ui/controls/button.h"
#include "ui/controls/edit.h"
#include "ui/controls/interface.h"
#include "ui/controls/label.h"
#include "ui/controls/list.h"
#include "ui/controls/window.h"
#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
using namespace boost::filesystem;
namespace Ui
{
CScreenSetupMods::CScreenSetupMods()
{
}
void CScreenSetupMods::SetActive()
{
m_tab = PHASE_SETUPm;
}
void CScreenSetupMods::CreateInterface()
{
CWindow* pw;
CLabel* pl;
CButton* pb;
CList* pli;
Math::Point pos, ddim;
std::string name;
CScreenSetup::CreateInterface();
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == nullptr ) return;
// Displays a list of unloaded mods:
pos.x = ox+sx*3;
pos.y = oy+sy*9;
ddim.x = dim.x*6;
ddim.y = dim.y*1;
GetResource(RES_TEXT, RT_MODS_UNLOADED, name);
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name);
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pos.y = oy+sy*3.75f;
ddim.x = dim.x*6.5f;
ddim.y = dim.y*6.05f;
pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_MODS_UNLOADED);
pli->SetState(STATE_SHADOW);
UpdateUnloadedModList();
// Displays a list of loaded mods:
pos.x = ox+sx*9.5f;
pos.y = oy+sy*9;
ddim.x = dim.x*6;
ddim.y = dim.y*1;
GetResource(RES_TEXT, RT_MODS_LOADED, name);
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name);
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pos.y = oy+sy*3.75f;
ddim.x = dim.x*6.5f;
ddim.y = dim.y*6.05f;
pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_MODS_LOADED);
pli->SetState(STATE_SHADOW);
UpdateLoadedModList();
pos = pli->GetPos();
ddim = pli->GetDim();
pos.x = ox+sx*8.2f;
pos.y = oy+sy*2;
ddim.x = dim.x*1;
ddim.y = dim.y*1;
pb = pw->CreateButton(pos, ddim, 40, EVENT_INTERFACE_WORKSHOP);
pb->SetState(STATE_SHADOW);
pos.x += dim.x*1.3f;
pb = pw->CreateButton(pos, ddim, 57, EVENT_INTERFACE_MODS_DIR);
pb->SetState(STATE_SHADOW);
pos.x += dim.x*1.3f;
ddim.x = dim.x*2.5f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_LOAD);
pb->SetState(STATE_SHADOW);
pb->ClearState(STATE_ENABLE);
pos.x += dim.x*2.8f;
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_UNLOAD);
pb->SetState(STATE_SHADOW);
pb->ClearState(STATE_ENABLE);
}
bool CScreenSetupMods::EventProcess(const Event &event)
{
CWindow* pw;
CButton* pb;
CList* pl;
std::string modName, modPath, website = "https://www.moddb.com/games/colobot-gold-edition";
auto systemUtils = CSystemUtils::Create(); // platform-specific utils
if (!CScreenSetup::EventProcess(event)) return false;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == nullptr ) return false;
if (event.type == EVENT_INTERFACE_LOAD)
{
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MODS_UNLOADED));
if ( pl == nullptr ) return false;
modName = pl->GetItemName(pl->GetSelect());
LoadMod(modName);
m_app->Reload();
m_main->ChangePhase(PHASE_SETUPm);
}
if (event.type == EVENT_INTERFACE_UNLOAD)
{
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MODS_LOADED));
if ( pl == nullptr ) return false;
modName = pl->GetItemName(pl->GetSelect());
UnloadMod(modName);
m_app->Reload();
m_main->ChangePhase(PHASE_SETUPm);
}
if (event.type == EVENT_INTERFACE_MODS_DIR)
{
modPath = CResourceManager::GetSaveLocation() + "/" + "mods";
systemUtils->OpenPath(modPath);
}
switch (event.type)
{
case EVENT_INTERFACE_MODS_UNLOADED:
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MODS_LOADED));
if ( pl == nullptr ) break;
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_UNLOAD));
if ( pb == nullptr ) break;
pl->SetSelect(-1);
pb->ClearState(STATE_ENABLE);
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_LOAD));
if ( pb == nullptr ) break;
pb->SetState(STATE_ENABLE);
break;
case EVENT_INTERFACE_MODS_LOADED:
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MODS_UNLOADED));
if ( pl == nullptr ) break;
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_LOAD));
if ( pb == nullptr ) break;
pl->SetSelect(-1);
pb->ClearState(STATE_ENABLE);
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_UNLOAD));
if ( pb == nullptr ) break;
pb->SetState(STATE_ENABLE);
break;
case EVENT_INTERFACE_WORKSHOP:
systemUtils->OpenWebsite(website);
break;
default:
return true;
}
return false;
}
void CScreenSetupMods::UnloadMod(std::string modName)
{
std::string modPath, modPathRaw, disabled = "~";
modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/";
modPath = modPathRaw.c_str();
m_pathManager->RemoveMod(modPath+modName);
boost::filesystem::rename(modPath+modName, modPath+disabled+modName);
}
void CScreenSetupMods::LoadMod(std::string modName)
{
std::string modPath, modPathRaw, disabled = "~";
modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/";
modPath = modPathRaw.c_str();
boost::filesystem::rename(modPath+disabled+modName, modPath+modName);
m_pathManager->AddMod(modPath+modName);
}
void CScreenSetupMods::UpdateUnloadedModList()
{
CWindow* pw;
CList* pl;
int i = 0;
std::string modPath, modPathRaw;
directory_iterator end_itr;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == nullptr ) return;
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MODS_UNLOADED));
if ( pl == nullptr ) return;
pl->Flush();
modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/";
modPath = modPathRaw.c_str();
for (directory_iterator itr(modPath); itr != end_itr; ++itr)
{
std::string modName = itr->path().string();
boost::erase_all(modName, modPath);
std::string::size_type enabled;
enabled = modName.find('~');
if (enabled != std::string::npos)
{
modName.erase(0,1);
pl->SetItemName(i++, modName);
}
}
pl->ShowSelect(false); // shows the selected columns
}
void CScreenSetupMods::UpdateLoadedModList()
{
CWindow* pw;
CList* pl;
int i = 0;
std::string modPath, modPathRaw;
directory_iterator end_itr;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == nullptr ) return;
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_MODS_LOADED));
if ( pl == nullptr ) return;
pl->Flush();
modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/";
modPath = modPathRaw.c_str();
for (directory_iterator itr(modPath); itr != end_itr; ++itr)
{
std::string modName = itr->path().string();
boost::erase_all(modName, modPath);
std::string::size_type enabled;
enabled = modName.find('~');
if (enabled == std::string::npos)
pl->SetItemName(i++, modName);
}
pl->ShowSelect(false); // shows the selected columns
}
} // namespace Ui

View File

@ -0,0 +1,52 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2019, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include "ui/screen/screen_setup.h"
#include <vector>
class CPathManager;
namespace Ui
{
class CScreenSetupMods : public CScreenSetup
{
public:
CScreenSetupMods();
void SetActive() override;
void CreateInterface() override;
bool EventProcess(const Event &event) override;
protected:
void UnloadMod(std::string ModName);
void LoadMod(std::string ModName);
void UpdateUnloadedModList();
void UpdateLoadedModList();
protected:
CPathManager* m_pathManager;
std::vector<std::string> m_unloadedModList;
std::vector<std::string> m_loadedModList;
};
} // namespace Ui