Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Harbour/include/GameCard.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ namespace Harbour

std::string m_longDesc = "";

std::string m_thumbnailFilePath = "assets/GameCard/UnknownTitle.png";
std::string m_thumbnailFilePath = "";
std::string m_executablePath = "";
bool m_owned = false;

private:
GLuint m_texture = 0;
bool m_textureNeedsUpdate = true;

ImVec2 m_size = {300, 350};
ImVec2 m_thumbnailSize = {256, 256};
};
Expand Down
5 changes: 3 additions & 2 deletions Harbour/include/utils/FileManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ namespace fs = std::filesystem;

namespace HarbourUtils
{
const fs::path resolvePath(const fs::path &path);
const fs::path resolvePath(const std::string &path);

class FileManager
{
public:
FileManager();
~FileManager();

FileManager *get();

void saveConfigFile(const nlohmann::json &config, const fs::path &path);
nlohmann::json loadConfigFile(const fs::path &path);

Expand Down
12 changes: 8 additions & 4 deletions Harbour/src/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void Harbour::App::init()
#endif

m_window = SDL_CreateWindow("Harbour Ports",
1280, 720, SDL_WINDOW_OPENGL); // Allow SDL_WINDOW_RESIZABLE?
1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); // Allow SDL_WINDOW_RESIZABLE?

SDL_GLContext gl_context = SDL_GL_CreateContext(m_window);
gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress);
Expand All @@ -56,7 +56,9 @@ void Harbour::App::init()
ImGui::CreateContext();

ImGuiIO &io = ImGui::GetIO();
ImFont *font = io.Fonts->AddFontFromFileTTF("assets/Fonts/montserrat/Montserrat-Regular.otf", 16.0f);
auto fontFilePath = HarbourUtils::resolvePath(L"assets/Fonts/montserrat/Montserrat-Regular.otf");

ImFont *font = io.Fonts->AddFontFromFileTTF(fontFilePath.string().c_str(), 16.0f);
if (font == nullptr)
io.Fonts->AddFontDefault();

Expand Down Expand Up @@ -182,7 +184,8 @@ void Harbour::App::drawSplashScreen()
if (!m_splashImg)
{
int width = 0, height = 0;
LoadTextureFromFile("assets/GameCard/UnknownTitle.png", &m_splashImg, &width, &height);
auto filepath = HarbourUtils::resolvePath(L"assets/GameCard/UnknownTitle.png");
LoadTextureFromFile(filepath.string().c_str(), &m_splashImg, &width, &height);
}

ImGui::Image((ImTextureID)(intptr_t)m_splashImg, ImVec2(256, 256));
Expand Down Expand Up @@ -236,6 +239,7 @@ void Harbour::App::initAppClasses()
m_networkManager = std::make_unique<HarbourUtils::NetworkManager>(m_fileManager.get());
m_libraryManager = std::make_unique<HarbourUtils::LibraryManager>(m_fileManager.get());

m_allGames = m_libraryManager->constructLibraryFromJSON("cache/manifest.json");
auto manifestResolvedPath = HarbourUtils::resolvePath(L"cache/manifest.json");
m_allGames = m_libraryManager->constructLibraryFromJSON(manifestResolvedPath.string());
m_initComplete.store(true);
}
17 changes: 13 additions & 4 deletions Harbour/src/GameCard.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#include "GameCard.h"
#include <iostream>
#include "utils/FileManager.h"

Harbour::GameCard::GameCard()
{
this->setThumbnailImg("assets/GameCard/UnknownTitle.png");
}

Harbour::GameCard::GameCard(std::string name, std::string version)
{
std::cout << "A new Game Card was created!" << std::endl;
this->setName(name);
this->setVersion(version);
this->setThumbnailImg("assets/GameCard/UnknownTitle.png");
}

Harbour::GameCard::~GameCard()
Expand Down Expand Up @@ -37,12 +40,16 @@ void Harbour::GameCard::setLongDesc(const std::string &desc)

void Harbour::GameCard::setFilePath(const std::string &path)
{
m_executablePath = path;
auto rPath = HarbourUtils::resolvePath(path);
m_executablePath = rPath.string();
}

void Harbour::GameCard::setThumbnailImg(const std::string &path)
{
m_thumbnailFilePath = path;
auto rPath = HarbourUtils::resolvePath(path);
std::cout << "GameCard with name " << m_name << " just had its thumbnail path set to " << rPath << "when m_texture was: " << m_texture << std::endl;
m_thumbnailFilePath = rPath.string();
m_textureNeedsUpdate = true;
}

bool Harbour::GameCard::startGame()
Expand Down Expand Up @@ -83,17 +90,19 @@ void Harbour::GameCard::draw()

void Harbour::GameCard::drawThumbnail()
{
if (!m_texture)
if (m_textureNeedsUpdate)
{
// From ImGui docs by ocornut
int my_image_width = 0;
int my_image_height = 0;
bool ret = LoadTextureFromFile(m_thumbnailFilePath.c_str(), &m_texture, &my_image_width, &my_image_height);
IM_ASSERT(ret);
if (ret)
m_textureNeedsUpdate = false;
}

float widthOffset = ImGui::GetCursorPosX() + (m_size.x - m_thumbnailSize.x) / 2;
ImGui::SetCursorPos(ImVec2(widthOffset, ImGui::GetCursorPosY()));

ImGui::Image((ImTextureID)(intptr_t)m_texture, ImVec2(256, 256)); // ImVec2(my_image_width, my_image_height)
ImGui::Image((ImTextureID)(intptr_t)m_texture, m_thumbnailSize); // ImVec2(my_image_width, my_image_height)
}
4 changes: 2 additions & 2 deletions Harbour/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// main.cpp
#define SDL_MAIN_HANDLED


#include "App.h"

int main() {
int main(int argc, char **argv)
{
Harbour::App app = {};

app.run();
Expand Down
57 changes: 46 additions & 11 deletions Harbour/src/utils/FileManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
#include <exception>
#include <archive.h>

#if defined(__APPLE__)
#include <mach-o/dyld.h>
#include <sys/syslimits.h>
#include <stdlib.h>
#endif

HarbourUtils::FileManager::FileManager()
{
this->directoryExists("cache/downloads", true); // Creates cache/downloads/ folder for downloaded archives to be put in
Expand All @@ -14,19 +20,16 @@ HarbourUtils::FileManager::~FileManager()
{
}

HarbourUtils::FileManager *HarbourUtils::FileManager::get()
{
return this;
}

void HarbourUtils::FileManager::saveConfigFile(const nlohmann::json &config, const fs::path &path)
{
if (!path.parent_path().empty() && !fs::exists(path.parent_path()))
fs::path rPath = HarbourUtils::resolvePath(path);

if (!rPath.parent_path().empty() && !fs::exists(rPath.parent_path()))
{
fs::create_directories(path.parent_path());
fs::create_directories(rPath.parent_path());
}

std::ofstream stream(path, std::ios::out | std::ios::trunc);
std::ofstream stream(rPath, std::ios::out | std::ios::trunc);
if (stream.is_open())
{
stream << config.dump(4);
Expand All @@ -40,9 +43,10 @@ void HarbourUtils::FileManager::saveConfigFile(const nlohmann::json &config, con

nlohmann::json HarbourUtils::FileManager::loadConfigFile(const fs::path &path)
{
fs::path rPath = HarbourUtils::resolvePath(path);
try
{
std::ifstream stream(path);
std::ifstream stream(rPath);
if (stream.is_open())
{
nlohmann::json config;
Expand Down Expand Up @@ -73,15 +77,18 @@ bool HarbourUtils::FileManager::fileExists(const fs::path &path)

bool HarbourUtils::FileManager::directoryExists(const fs::path &path, bool createIfMissing)
{
if (fs::exists(path) && fs::is_directory(path))
fs::path rPath = HarbourUtils::resolvePath(path);

if (fs::exists(rPath) && fs::is_directory(rPath))
{
return true;
}
else
{
if (createIfMissing)
{
fs::create_directories(path);
fs::create_directories(rPath);
return true;
}
return false;
}
Expand All @@ -96,6 +103,34 @@ bool HarbourUtils::FileManager::unzipArchive(const fs::path &path, const fs::pat
return true;
}

const fs::path HarbourUtils::resolvePath(const fs::path &path)
{
// Assisted by Gemini 3.1 Pro Extended because I am still learning macOS specific fixes
#if defined(__APPLE__)
char appPath[PATH_MAX];
uint32_t size = sizeof(appPath);

if (_NSGetExecutablePath(appPath, &size) == 0)
{
char realPath[PATH_MAX];
if (realpath(appPath, realPath) != nullptr)
{
fs::path resolvedPath(realPath);
return resolvedPath.parent_path() / path; // just the directory the app is actually in
}
}
#endif
return fs::weakly_canonical(path);
}

const fs::path HarbourUtils::resolvePath(const std::string &pathStr)
{

fs::path path = fs::path(pathStr);
fs::path resolvedPath = resolvePath(path);
return resolvedPath;
}

/**
* Placeholder code
#include <archive.h>
Expand Down
28 changes: 21 additions & 7 deletions Harbour/src/utils/LoadImage.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
#define STB_IMAGE_IMPLEMENTATION

#include "utils/LoadImage.h"
#include <iostream>

// Simple helper function to load an image into a OpenGL texture with common settings
bool LoadTextureFromMemory(const void* data, size_t data_size, GLuint* out_texture, int* out_width, int* out_height)
bool LoadTextureFromMemory(const void *data, size_t data_size, GLuint *out_texture, int *out_width, int *out_height)
{
// Load from file
int image_width = 0;
int image_height = 0;
unsigned char* image_data = stbi_load_from_memory((const unsigned char*)data, (int)data_size, &image_width, &image_height, NULL, 4);
unsigned char *image_data = stbi_load_from_memory((const unsigned char *)data, (int)data_size, &image_width, &image_height, NULL, 4);
if (image_data == NULL)
return false;

// Create a OpenGL texture identifier
GLuint image_texture;
glGenTextures(1, &image_texture);
GLuint image_texture = (out_texture != nullptr) ? *out_texture : 0;
if (image_texture == 0)
glGenTextures(1, &image_texture); // only generate if it's never been generated before

glBindTexture(GL_TEXTURE_2D, image_texture);

std::cout << "[LoadTextureFromMemory] GLUint for this image is: " << image_texture << std::endl;
// Setup filtering parameters for display
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Expand All @@ -34,20 +38,30 @@ bool LoadTextureFromMemory(const void* data, size_t data_size, GLuint* out_textu
}

// Open and read a file, then forward to LoadTextureFromMemory()
bool LoadTextureFromFile(const char* file_name, GLuint* out_texture, int* out_width, int* out_height)
bool LoadTextureFromFile(const char *file_name, GLuint *out_texture, int *out_width, int *out_height)
{
FILE* f = fopen(file_name, "rb");
FILE *f = fopen(file_name, "rb");
std::cout << "Opening image file at: " << file_name << std::endl;

if (f == NULL)
{
std::cout << "f is NULL" << std::endl;
return false;
}

fseek(f, 0, SEEK_END);
size_t file_size = (size_t)ftell(f);
if (file_size == -1)
return false;
fseek(f, 0, SEEK_SET);
void* file_data = IM_ALLOC(file_size);
void *file_data = IM_ALLOC(file_size);
fread(file_data, 1, file_size, f);
fclose(f);
std::cout << "File " << file_name << " was successfully read and closed" << std::endl;

bool ret = LoadTextureFromMemory(file_data, file_size, out_texture, out_width, out_height);

std::cout << "LoadTextureFromMemory succeeded" << std::endl;
IM_FREE(file_data);
return ret;
}
7 changes: 4 additions & 3 deletions Harbour/src/utils/NetworkManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ HarbourUtils::NetworkManager *HarbourUtils::NetworkManager::get()

void HarbourUtils::NetworkManager::checkForManifestUpdate()
{
nlohmann::json etags = m_fileManager->loadConfigFile("cache/etags.json");
auto cachePath = HarbourUtils::resolvePath(L"cache/etags.json");
nlohmann::json etags = m_fileManager->loadConfigFile(cachePath);

cpr::Header headers = {
{"Expect", ""}};
Expand Down Expand Up @@ -53,12 +54,12 @@ void HarbourUtils::NetworkManager::checkForManifestUpdate()
if (!manifestETag.empty())
{
etags["manifest"] = manifestETag;
m_fileManager->saveConfigFile(etags, "cache/etags.json");
m_fileManager->saveConfigFile(etags, cachePath);
}

nlohmann::json manifest = nlohmann::json::parse(r.text);

m_fileManager->saveConfigFile(manifest, "cache/manifest.json");
m_fileManager->saveConfigFile(manifest, HarbourUtils::resolvePath(L"cache/manifest.json"));
}

void HarbourUtils::NetworkManager::checkForSelfUpdate()
Expand Down
Loading