config: Implement config mechanism to save list visited diretory + some other options/toggles

This commit is contained in:
Joel16 2020-09-16 22:50:50 -04:00
parent a2140f2044
commit aaa411454d
7 changed files with 188 additions and 16 deletions

View File

@ -65,6 +65,7 @@ add_executable(${PROJECT_NAME}
libs/libnsbmp/libnsbmp.c
libs/libnsgif/libnsgif.c
libs/libnsgif/lzw.c
source/config.cpp
source/fs.cpp
source/gui.cpp
source/keyboard.cpp
@ -76,6 +77,7 @@ add_executable(${PROJECT_NAME}
# Library to link to (drop the prefix). This will mostly be stubs.
target_link_libraries(${PROJECT_NAME}
jansson
tiff
webp
turbojpeg

20
include/config.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef _VITALBUM_CONFIG_H_
#define _VITALBUM_CONFIG_H_
#include <string>
typedef struct {
int sort = 0;
bool dev_options = false;
bool image_filename = false;
std::string cwd;
} config_t;
extern config_t config;
namespace Config {
int Save(config_t config);
int Load(void);
}
#endif

View File

@ -6,7 +6,8 @@
#include <string>
namespace FS {
extern std::string CWD;
bool FileExists(const std::string &path);
bool DirExists(const std::string &path);
int GetFileSize(const std::string &path, SceOff *size);
std::string GetFileExt(const std::string &filename);
SceOff GetDirList(const std::string &path, SceIoDirent **entriesp);
@ -14,6 +15,7 @@ namespace FS {
SceOff ChangeDirPrev(SceIoDirent **entries);
const std::string BuildPath(SceIoDirent *entry);
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size);
int WriteFile(const std::string &path, const void *data, SceSize size);
}
#endif

105
source/config.cpp Normal file
View File

@ -0,0 +1,105 @@
#include <jansson.h>
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#include "config.h"
#include "fs.h"
#include "utils.h"
#define CONFIG_VERSION 1
config_t config;
namespace Config {
static const char *config_file = "{\n\t\"config_ver\": %d,\n\t\"sort\": %d,\n\t\"dev_options\": %d,\n\t\"image_filename\": %d,\n\t\"last_dir\": \"%s\"\n}";
static int config_version_holder = 0;
int Save(config_t config) {
int ret = 0;
char *buf = new char[1024];
SceSize len = std::snprintf(buf, 1024, config_file, CONFIG_VERSION, config.sort, config.dev_options, config.image_filename, config.cwd.c_str());
if (R_FAILED(ret = FS::WriteFile("ux0:data/VITAlbum/config.json", buf, len))) {
delete[] buf;
return ret;
}
delete[] buf;
return 0;
}
static void SetDefault(config_t *config) {
config->sort = 0;
config->dev_options = false;
config->image_filename = false;
config->cwd = "ux0:";
}
int Load(void) {
int ret = 0;
if (!FS::DirExists("ux0:data"))
sceIoMkdir("ux0:data", 0777);
if (!FS::DirExists("ux0:data/VITAlbum"))
sceIoMkdir("ux0:data/VITAlbum", 0777);
if (!FS::FileExists("ux0:data/VITAlbum/config.json")) {
Config::SetDefault(&config);
return Config::Save(config);
}
SceUID file = 0;
if (R_FAILED(ret = file = sceIoOpen("ux0:data/VITAlbum/config.json", SCE_O_RDONLY, 0)))
return ret;
SceOff size = sceIoLseek(file, 0, SEEK_END);
char *buffer = new char[size + 1];
if (R_FAILED(ret = sceIoPread(file, buffer, size + 1, SCE_SEEK_SET))) {
delete[] buffer;
sceIoClose(file);
return ret;
}
if (R_FAILED(ret = sceIoClose(file))) {
delete[] buffer;
return ret;
}
json_t *root;
json_error_t error;
root = json_loads(buffer, 0, &error);
delete[] buffer;
if (!root)
return -1;
json_t *config_ver = json_object_get(root, "config_ver");
config_version_holder = json_integer_value(config_ver);
json_t *sort = json_object_get(root, "sort");
config.sort = json_integer_value(sort);
json_t *dev_options = json_object_get(root, "dev_options");
config.dev_options = json_integer_value(dev_options);
json_t *image_filename = json_object_get(root, "image_filename");
config.image_filename = json_integer_value(image_filename);
json_t *last_dir = json_object_get(root, "last_dir");
config.cwd = json_string_value(last_dir);
if (!FS::DirExists(config.cwd))
config.cwd = "ux0:";
// Delete config file if config file is updated. This will rarely happen.
if (config_version_holder < CONFIG_VERSION) {
sceIoRemove("ux0:data/VITAlbum/config.json");
Config::SetDefault(&config);
return Config::Save(config);
}
json_decref(root);
return 0;
}
}

View File

@ -6,11 +6,32 @@
#include <cstring>
#include <filesystem>
#include "config.h"
#include "fs.h"
#include "utils.h"
namespace FS {
std::string CWD;
bool FileExists(const std::string &path) {
SceUID file = 0;
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), SCE_O_RDONLY, 0777))) {
sceIoClose(file);
return true;
}
return false;
}
bool DirExists(const std::string &path) {
SceUID dir = 0;
if (R_SUCCEEDED(dir = sceIoDopen(path.c_str()))) {
sceIoDclose(dir);
return true;
}
return false;
}
int GetFileSize(const std::string &path, SceOff *size) {
int ret = 0;
@ -103,23 +124,24 @@ namespace FS {
// Free entries and change the current working directory.
delete[] *entries;
CWD = path;
config.cwd = path;
Config::Save(config);
*entries = new_entries;
return num_entries;
}
static int ChangeDirUp(char path[256]) {
if (CWD.length() <= 1 && CWD.c_str()[0] == '/')
if (config.cwd.length() <= 1 && config.cwd.c_str()[0] == '/')
return -1;
// Remove upmost directory
bool copy = false;
int len = 0;
for (ssize_t i = CWD.length(); i >= 0; i--) {
if (CWD.c_str()[i] == '/')
for (ssize_t i = config.cwd.length(); i >= 0; i--) {
if (config.cwd.c_str()[i] == '/')
copy = true;
if (copy) {
path[i] = CWD.c_str()[i];
path[i] = config.cwd.c_str()[i];
len++;
}
}
@ -133,7 +155,7 @@ namespace FS {
}
SceOff ChangeDirNext(const std::string &path, SceIoDirent **entries) {
std::string new_path = CWD;
std::string new_path = config.cwd;
new_path.append("/");
new_path.append(path);
return FS::ChangeDir(new_path, entries);
@ -148,15 +170,15 @@ namespace FS {
}
const std::string BuildPath(SceIoDirent *entry) {
std::string path = CWD;
std::string path = config.cwd;
path.append("/");
path.append(entry->d_name);
return path;
}
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size) {
SceUID file = 0;
int ret = 0;
SceUID file = 0;
if (R_FAILED(ret = file = sceIoOpen(path.c_str(), SCE_O_RDONLY, 0)))
return ret;
@ -172,4 +194,22 @@ namespace FS {
return 0;
}
int WriteFile(const std::string &path, const void *data, SceSize size) {
int ret = 0, bytes_written = 0;
SceUID file = 0;
if (R_FAILED(ret = file = sceIoOpen(path.c_str(), SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777)))
return ret;
if (R_FAILED(ret = bytes_written = sceIoWrite(file, data, size))) {
sceIoClose(file);
return ret;
}
if (R_FAILED(ret = sceIoClose(file)))
return ret;
return bytes_written;
}
}

View File

@ -1,6 +1,7 @@
#include <imgui_vita.h>
#include <vitaGL.h>
#include "config.h"
#include "fs.h"
#include "keyboard.h"
#include "textures.h"
@ -158,10 +159,9 @@ namespace GUI {
void MainMenu(void) {
bool window = true, properties_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
FS::CWD = "ux0:";
SceIoDirent *entries;
SceOff entry_count = FS::GetDirList(FS::CWD, &entries);
SceOff entry_count = FS::GetDirList(config.cwd, &entries);
SceOff selected = 0;
Tex texture; // Common image formats
@ -174,7 +174,7 @@ namespace GUI {
Renderer::SetupWindow();
if (ImGui::Begin("VITAlbum", &window, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
ImGui::TextColored(ImVec4(1.00f, 1.00f, 1.00f, 1.00f), FS::CWD.c_str());
ImGui::TextColored(ImVec4(1.00f, 1.00f, 1.00f, 1.00f), config.cwd.c_str());
ImGui::BeginChild("##FS::GetDirList");
for (SceOff i = 0; i < entry_count; i++) {
@ -265,13 +265,13 @@ namespace GUI {
case GUI_STATE_IMAGE_PREVIEW:
GUI::ImageWindow(&entries[selected], &texture);
if (properties_window)
GUI::PropertiesWindow(&properties_window, FS::CWD, &entries[selected], &texture);
GUI::PropertiesWindow(&properties_window, config.cwd, &entries[selected], &texture);
break;
case GUI_STATE_GIF_PREVIEW:
GUI::GifWindow(&entries[selected], textures);
if (properties_window)
GUI::PropertiesWindow(&properties_window, FS::CWD, &entries[selected], &textures[0]);
GUI::PropertiesWindow(&properties_window, config.cwd, &entries[selected], &textures[0]);
break;
default:

View File

@ -1,6 +1,7 @@
#include <imgui_vita.h>
#include <vitaGL.h>
#include "config.h"
#include "gui.h"
//#include "log.h"
#include "textures.h"
@ -82,6 +83,8 @@ namespace Services {
Utils::InitAppUtil();
SCE_CTRL_ENTER = Utils::GetEnterButton();
SCE_CTRL_CANCEL = Utils::GetCancelButton();
Config::Load();
}
void Exit(void) {