Skip to content

Commit

Permalink
refactor: Improve startup creation of dirs
Browse files Browse the repository at this point in the history
- Amiberry/conf was always created on startup, as part of the get_config_directory process.
We should be able to skip that at that step, and only create it if it's missing after loading the amiberry.conf file, since the path might be different there.
- Added one more location check for the whdboot dir on startup, under /usr/local/share/amiberry/whdboot
- if that is also not found, added a final fallback option, to recreate the whole structure from scratch, and attempt to download the missing files from the repositories. This last part is identical as if pressing the Update WHDBoot XML button.
- Also look in /usr/local/share/amiberry/roms for the bundled ROM files, if not found earlier
  • Loading branch information
midwan committed Jan 29, 2025
1 parent d7d082f commit 1c34827
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 118 deletions.
115 changes: 3 additions & 112 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@
#include "fsdb_host.h"
#include "keyboard.h"

static const char __ver[40] = "$VER: Amiberry-Lite 5.8.2 (2025-01-24)";
// Special version string so that AmigaOS can detect it
static constexpr char __ver[40] = "$VER: Amiberry-Lite 5.8.2 (2025-01-29)";

long int version = 256 * 65536L * UAEMAJOR + 65536L * UAEMINOR + UAESUBREV;

extern int console_logging;
Expand Down Expand Up @@ -1337,117 +1339,6 @@ long get_file_size(const std::string& filename)
return rc == 0 ? static_cast<long>(stat_buf.st_size) : -1;
}

bool file_exists(const std::string& file)
{
#ifdef USE_OLDGCC
namespace fs = std::experimental::filesystem;
#else
namespace fs = std::filesystem;
#endif
fs::path f { file };
return (fs::exists(f));
}

bool download_file(const std::string& source, const std::string& destination, bool keep_backup)
{
// homebrew installs in different locations on OSX Intel vs OSX Apple Silicon
#if defined (__MACH__) && defined (__arm64__)
std::string wget_path = "/opt/homebrew/bin/wget";
if (!file_exists(wget_path))
{
write_log("Could not locate wget in /opt/homebrew/ - Please use homebrew to install it!\n");
return false;
}
#elif defined(__MACH__)
std::string wget_path = "/usr/local/bin/wget";
if (!file_exists(wget_path))
{
write_log("Could not locate wget in /usr/local/bin/ - Please use homebrew to install it!\n");
return false;
}
#else
std::string wget_path = "wget";
#endif
std::string download_command = wget_path + " -np -nv -O ";
auto tmp = destination;
tmp = tmp.append(".tmp");

download_command.append(tmp);
download_command.append(" ");
download_command.append(source);
download_command.append(" 2>&1");

// Cleanup if the tmp destination already exists
if (file_exists(tmp))
{
write_log("Existing file found, removing %s\n", tmp.c_str());
if (std::remove(tmp.c_str()) < 0)
{
write_log(strerror(errno));
write_log("\n");
}
}

try
{
char buffer[MAX_DPATH];
const auto output = popen(download_command.c_str(), "r");
if (!output)
{
write_log("Failed while trying to run wget! Make sure it exists in your system...\n");
return false;
}

while (fgets(buffer, sizeof buffer, output))
{
write_log(buffer);
write_log("\n");
}
pclose(output);
}
catch (...)
{
write_log("An exception was thrown while trying to execute wget!\n");
return false;
}

if (file_exists(tmp))
{
if (file_exists(destination) && keep_backup)
{
write_log("Backup requested, renaming destination file %s to .bak\n", destination.c_str());
const std::string new_filename = destination.substr(0, destination.find_last_of('.')).append(".bak");
if (std::rename(destination.c_str(), new_filename.c_str()) < 0)
{
write_log(strerror(errno));
write_log("\n");
}
}

write_log("Renaming downloaded temporary file %s to final destination\n", tmp.c_str());
if (std::rename(tmp.c_str(), destination.c_str()) < 0)
{
write_log(strerror(errno));
write_log("\n");
}
return true;
}

return false;
}

void download_rtb(const std::string& filename)
{
const std::string destination_filename = "save-data/Kickstarts/" + filename;
const std::string destination = prefix_with_whdboot_path(destination_filename);
if (!file_exists(destination))
{
write_log("Downloading %s ...\n", destination.c_str());
const std::string url = "https://github.com/BlitterStudio/amiberry/blob/master/whdboot/save-data/Kickstarts/" + filename + "?raw=true";
download_file(url, destination, false);
}
}

// In case of error, print the error code and close the application
void check_error_sdl(const bool check, const char* message)
{
Expand Down
192 changes: 186 additions & 6 deletions src/osdep/amiberry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3786,6 +3786,117 @@ bool directory_exists(std::string directory, const std::string& sub_dir)
return my_existsdir(directory.c_str());
}

bool file_exists(const std::string& file)
{
#ifdef USE_OLDGCC
namespace fs = std::experimental::filesystem;
#else
namespace fs = std::filesystem;
#endif
fs::path f{ file };
return (fs::exists(f));
}

bool download_file(const std::string& source, const std::string& destination, bool keep_backup)
{
// homebrew installs in different locations on OSX Intel vs OSX Apple Silicon
#if defined (__MACH__) && defined (__arm64__)
std::string wget_path = "/opt/homebrew/bin/wget";
if (!file_exists(wget_path))
{
write_log("Could not locate wget in /opt/homebrew/ - Please use homebrew to install it!\n");
return false;
}
#elif defined(__MACH__)
std::string wget_path = "/usr/local/bin/wget";
if (!file_exists(wget_path))
{
write_log("Could not locate wget in /usr/local/bin/ - Please use homebrew to install it!\n");
return false;
}
#else
std::string wget_path = "wget";
#endif
std::string download_command = wget_path + " -np -nv -O ";
auto tmp = destination;
tmp = tmp.append(".tmp");

download_command.append(tmp);
download_command.append(" ");
download_command.append(source);
download_command.append(" 2>&1");

// Cleanup if the tmp destination already exists
if (file_exists(tmp))
{
write_log("Existing file found, removing %s\n", tmp.c_str());
if (std::remove(tmp.c_str()) < 0)
{
write_log(strerror(errno));
write_log("\n");
}
}

try
{
char buffer[MAX_DPATH];
const auto output = popen(download_command.c_str(), "r");
if (!output)
{
write_log("Failed while trying to run wget! Make sure it exists in your system...\n");
return false;
}

while (fgets(buffer, sizeof buffer, output))
{
write_log(buffer);
write_log("\n");
}
pclose(output);
}
catch (...)
{
write_log("An exception was thrown while trying to execute wget!\n");
return false;
}

if (file_exists(tmp))
{
if (file_exists(destination) && keep_backup)
{
write_log("Backup requested, renaming destination file %s to .bak\n", destination.c_str());
const std::string new_filename = destination.substr(0, destination.find_last_of('.')).append(".bak");
if (std::rename(destination.c_str(), new_filename.c_str()) < 0)
{
write_log(strerror(errno));
write_log("\n");
}
}

write_log("Renaming downloaded temporary file %s to final destination\n", tmp.c_str());
if (std::rename(tmp.c_str(), destination.c_str()) < 0)
{
write_log(strerror(errno));
write_log("\n");
}
return true;
}

return false;
}

void download_rtb(const std::string& filename)
{
const std::string destination_filename = "save-data/Kickstarts/" + filename;
const std::string destination = get_whdbootpath().append(destination_filename);
if (!file_exists(destination))
{
write_log("Downloading %s ...\n", destination.c_str());
const std::string url = "https://github.com/BlitterStudio/amiberry/blob/master/whdboot/save-data/Kickstarts/" + filename + "?raw=true";
download_file(url, destination, false);
}
}

// this is where the required assets are stored, like fonts, icons, etc.
std::string get_data_directory(bool portable_mode)
{
Expand Down Expand Up @@ -4042,12 +4153,12 @@ void create_missing_amiberry_folders()
// copy default controller files, if they exist in AMIBERRY_DATADIR/controllers
if (my_existsdir(default_controller_path.c_str()))
{
const std::string command = "cp -r " + default_controller_path + "* " + controllers_path;
const std::string command = "cp -R " + default_controller_path + "* " + controllers_path;
system(command.c_str());
}
else if (my_existsdir("/usr/share/amiberry-lite/controllers/"))
{
const std::string command = "cp -r /usr/share/amiberry-lite/controllers/* " + controllers_path;
const std::string command = "cp -R /usr/share/amiberry-lite/controllers/* " + controllers_path;
system(command.c_str());
}
}
Expand All @@ -4062,14 +4173,78 @@ void create_missing_amiberry_folders()
// copy default whdboot files, if they exist in AMIBERRY_DATADIR/whdboot
if (my_existsdir(default_whdboot_path.c_str()))
{
const std::string command = "cp -r " + default_whdboot_path + "* " + whdboot_path;
const std::string command = "cp -R " + default_whdboot_path + "* " + whdboot_path;
system(command.c_str());
}
else if (my_existsdir("/usr/share/amiberry-lite/whdboot/"))
{
const std::string command = "cp -r /usr/share/amiberry-lite/whdboot/* " + whdboot_path;
const std::string command = "cp -R /usr/share/amiberry-lite/whdboot/* " + whdboot_path;
system(command.c_str());
}
else if (my_existsdir("/usr/local/share/amiberry-lite/whdboot/"))
{
const std::string command = "cp -R /usr/local/share/amiberry-lite/whdboot/* " + whdboot_path;
system(command.c_str());
}
else
{
write_log("No WHDLoad boot files found in %s, %s, or %s\n", default_whdboot_path.c_str(), "/usr/share/amiberry-lite/whdboot/", "/usr/local/share/amiberry-lite/whdboot/");
write_log("Attempting to download them from the internet...\n");

std::string directory_name = whdboot_path + "save-data";
if (!my_existsdir(directory_name.c_str()))
my_mkdir(directory_name.c_str());

directory_name = whdboot_path + "save-data/Autoboots";
if (!my_existsdir(directory_name.c_str()))
my_mkdir(directory_name.c_str());

directory_name = whdboot_path + "save-data/Debugs";
if (!my_existsdir(directory_name.c_str()))
my_mkdir(directory_name.c_str());

directory_name = whdboot_path + "save-data/Kickstarts";
if (!my_existsdir(directory_name.c_str()))
my_mkdir(directory_name.c_str());

directory_name = whdboot_path + "save-data/Savegames";
if (!my_existsdir(directory_name.c_str()))
my_mkdir(directory_name.c_str());

directory_name = whdboot_path + "game-data";
if (!my_existsdir(directory_name.c_str()))
my_mkdir(directory_name.c_str());

// download WHDLoad executable
std:: string destination = get_whdbootpath().append("WHDLoad");
write_log("Downloading %s ...\n", destination.c_str());
download_file("https://github.com/BlitterStudio/amiberry-lite/blob/master/whdboot/WHDLoad?raw=true", destination, false);

// download JST executable
destination = get_whdbootpath().append("JST");
write_log("Downloading %s ...\n", destination.c_str());
download_file("https://github.com/BlitterStudio/amiberry-lite/blob/master/whdboot/JST?raw=true", destination, false);

// download AmiQuit executable
destination = get_whdbootpath().append("AmiQuit");
write_log("Downloading %s ...\n", destination.c_str());
download_file("https://github.com/BlitterStudio/amiberry-lite/blob/master/whdboot/AmiQuit?raw=true", destination, false);

// download boot-data.zip
destination = get_whdbootpath().append("boot-data.zip");
write_log("Downloading %s ...\n", destination.c_str());
download_file("https://github.com/BlitterStudio/amiberry-lite/blob/master/whdboot/boot-data.zip?raw=true", destination, false);

// download kickstart RTB files for maximum compatibility
download_rtb("kick33180.A500.RTB");
download_rtb("kick34005.A500.RTB");
download_rtb("kick40063.A600.RTB");
download_rtb("kick40068.A1200.RTB");
download_rtb("kick40068.A4000.RTB");

destination = get_whdbootpath().append("game-data/whdload_db.xml");
download_file("https://github.com/HoraceAndTheSpider/Amiberry-XML-Builder/blob/master/whdload_db.xml?raw=true", destination, true);
}
}
if (!my_existsdir(whdload_arch_path.c_str()))
my_mkdir(whdload_arch_path.c_str());
Expand All @@ -4090,12 +4265,17 @@ void create_missing_amiberry_folders()
// copy default kickstart files, if they exist in AMIBERRY_DATADIR/roms
if (my_existsdir(default_roms_path.c_str()))
{
const std::string command = "cp -r " + default_roms_path + "* " + rom_path;
const std::string command = "cp -R " + default_roms_path + "* " + rom_path;
system(command.c_str());
}
else if (my_existsdir("/usr/share/amiberry-lite/roms/"))
{
const std::string command = "cp -r /usr/share/amiberry-lite/roms/* " + rom_path;
const std::string command = "cp -R /usr/share/amiberry-lite/roms/* " + rom_path;
system(command.c_str());
}
else if (my_existsdir("/usr/local/share/amiberry-lite/roms/"))
{
const std::string command = "cp -R /usr/local/share/amiberry-lite/roms/* " + rom_path;
system(command.c_str());
}
}
Expand Down

0 comments on commit 1c34827

Please sign in to comment.