mirror of
https://github.com/joel16/VITA-Homebrew-Sorter.git
synced 2024-11-23 03:19:42 +00:00
imGui: Switch to SDL2 renderer backend
This commit is contained in:
parent
3c15a7fff3
commit
bed515818f
@ -28,10 +28,17 @@ add_definitions(
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -ffast-math -mtune=cortex-a9 -mfpu=neon -Wall -Wno-psabi -fno-rtti -std=gnu++17")
|
||||
set(VITA_MKSFOEX_FLAGS "${VITA_MKSFOEX_FLAGS} -d PARENTAL_LEVEL=1")
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(SDL2_image REQUIRED)
|
||||
|
||||
include_directories(
|
||||
${VITASDK}/arm-vita-eabi/include/freetype2/
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${SDL2_IMAGE_INCLUDE_DIRS}
|
||||
libs/imgui
|
||||
libs/imgui/backends
|
||||
libs/sqlite3
|
||||
libs
|
||||
include
|
||||
)
|
||||
|
||||
@ -45,13 +52,18 @@ add_executable(${PROJECT_NAME}
|
||||
libs/imgui/imgui_draw.cpp
|
||||
libs/imgui/imgui_tables.cpp
|
||||
libs/imgui/imgui_widgets.cpp
|
||||
libs/imgui/backends/imgui_impl_sdl2.cpp
|
||||
libs/imgui/backends/imgui_impl_sdlrenderer2.cpp
|
||||
libs/imgui/misc/freetype/imgui_freetype.cpp
|
||||
libs/sqlite3/sqlite3.c
|
||||
source/tabs/loadouts.cpp
|
||||
source/tabs/pages.cpp
|
||||
source/tabs/settings.cpp
|
||||
source/tabs/sort.cpp
|
||||
source/applist.cpp
|
||||
source/config.cpp
|
||||
source/fs.cpp
|
||||
source/gui.cpp
|
||||
source/imgui_impl_vitagl.cpp
|
||||
source/keyboard.cpp
|
||||
source/loadouts.cpp
|
||||
source/log.cpp
|
||||
@ -66,27 +78,11 @@ target_link_libraries(${PROJECT_NAME}
|
||||
freetype
|
||||
png
|
||||
pthread
|
||||
lzma
|
||||
bz2
|
||||
z
|
||||
vitaGL
|
||||
vitashark
|
||||
mathneon
|
||||
SceAppMgr_stub
|
||||
SceAppUtil_stub
|
||||
SceCommonDialog_stub
|
||||
SceCtrl_stub
|
||||
SceDisplay_stub
|
||||
SceGxm_stub
|
||||
SceKernelDmacMgr_stub
|
||||
SDL2_image
|
||||
SDL2::SDL2
|
||||
SceLibJson_stub
|
||||
SceLibKernel_stub
|
||||
ScePower_stub
|
||||
SceShaccCg_stub
|
||||
SceShaccCgExt
|
||||
SceSysmodule_stub
|
||||
SceTouch_stub
|
||||
taihen_stub
|
||||
)
|
||||
|
||||
## Create Vita files
|
||||
|
@ -1,5 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
namespace GUI {
|
||||
SDL_Renderer *GetRenderer(void);
|
||||
SDL_Window *GetWindow(void);
|
||||
int Init(void);
|
||||
void Exit(void);
|
||||
void DisableButtonInit(bool disable);
|
||||
void DisableButtonExit(bool disable);
|
||||
int RenderLoop(void);
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
||||
// confuse your GPU driver.
|
||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
IMGUI_API bool ImGui_ImplVitaGL_Init(void);
|
||||
IMGUI_API void ImGui_ImplVitaGL_Shutdown(void);
|
||||
IMGUI_API void ImGui_ImplVitaGL_NewFrame(void);
|
||||
IMGUI_API void ImGui_ImplVitaGL_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing ImGui state.
|
||||
IMGUI_API bool ImGui_ImplVitaGL_CreateDeviceObjects(void);
|
||||
IMGUI_API void ImGui_ImplVitaGL_DestroyDeviceObjects(void);
|
40
include/tabs.h
Normal file
40
include/tabs.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <psp2/io/dirent.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "applist.h"
|
||||
|
||||
enum IconType {
|
||||
App,
|
||||
DB,
|
||||
Folder,
|
||||
Page,
|
||||
Trash
|
||||
};
|
||||
|
||||
enum SortMode {
|
||||
SortDefault,
|
||||
SortAsc,
|
||||
SortDesc
|
||||
};
|
||||
|
||||
enum State {
|
||||
StateNone,
|
||||
StateConfirmSort,
|
||||
StateConfirmSwap,
|
||||
StateRestore,
|
||||
StateLoadoutRestore,
|
||||
StateWarning,
|
||||
StateDone,
|
||||
StateDelete,
|
||||
StateError
|
||||
};
|
||||
|
||||
namespace Tabs {
|
||||
void Sort(AppEntries &entries, State &state, bool &backupExists);
|
||||
void Pages(AppEntries &entries, State &state, bool &backupExists);
|
||||
void Loadouts(std::vector<SceIoDirent> &loadouts, State &state, int &date_format, std::string &loadout_name);
|
||||
void Settings(void);
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <vitaGL.h>
|
||||
#include <SDL.h>
|
||||
#include <vector>
|
||||
|
||||
typedef struct {
|
||||
GLuint id = 0;
|
||||
SDL_Texture *ptr = nullptr;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
} Tex;
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <psp2/ctrl.h>
|
||||
#include <psp2/system_param.h>
|
||||
|
||||
/// Checks whether a result code indicates success.
|
||||
@ -9,17 +8,11 @@
|
||||
#define R_FAILED(res) ((res)<0)
|
||||
/// Returns the level of a result code.
|
||||
|
||||
extern int SCE_CTRL_ENTER, SCE_CTRL_CANCEL;
|
||||
extern unsigned int pressed;
|
||||
|
||||
constexpr char db_path[] = "ur0:shell/db/app.db";
|
||||
|
||||
namespace Utils {
|
||||
int InitAppUtil(void);
|
||||
int EndAppUtil(void);
|
||||
SceCtrlData ReadControls(void);
|
||||
int GetEnterButton(void);
|
||||
int GetCancelButton(void);
|
||||
int GetDateFormat(void);
|
||||
void GetDateString(char string[24], SceSystemParamDateFormat format, SceDateTime &time);
|
||||
}
|
||||
|
610
source/gui.cpp
610
source/gui.cpp
@ -2,66 +2,26 @@
|
||||
#include <cstdio>
|
||||
#include <psp2/power.h>
|
||||
#include <psp2/kernel/clib.h>
|
||||
#include <vitaGL.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "applist.h"
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include "imgui_impl_vitagl.h"
|
||||
#include "imgui_impl_sdl2.h"
|
||||
#include "imgui_impl_sdlrenderer2.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "log.h"
|
||||
#include "loadouts.h"
|
||||
#include "sqlite3.h"
|
||||
#include "textures.h"
|
||||
#include "tabs.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace Renderer {
|
||||
static void End(bool clear, ImVec4 clear_color) {
|
||||
glViewport(0, 0, static_cast<int>(ImGui::GetIO().DisplaySize.x), static_cast<int>(ImGui::GetIO().DisplaySize.y));
|
||||
|
||||
if (clear) {
|
||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplVitaGL_RenderDrawData(ImGui::GetDrawData());
|
||||
vglSwapBuffers(GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
namespace GUI {
|
||||
enum State {
|
||||
StateNone,
|
||||
StateConfirmSort,
|
||||
StateConfirmSwap,
|
||||
StateRestore,
|
||||
StateLoadoutRestore,
|
||||
StateWarning,
|
||||
StateDone,
|
||||
StateDelete,
|
||||
StateError
|
||||
};
|
||||
|
||||
enum SortMode {
|
||||
SortDefault,
|
||||
SortAsc,
|
||||
SortDesc
|
||||
};
|
||||
|
||||
enum IconType {
|
||||
App,
|
||||
DB,
|
||||
Folder,
|
||||
Page,
|
||||
Trash
|
||||
};
|
||||
|
||||
static bool backupExists = false;
|
||||
static const ImVec2 tex_size = ImVec2(20, 20);
|
||||
static const char *sort_by[] = {"Title", "Title ID"};
|
||||
static const char *sort_folders[] = {"Both", "Apps only", "Folders only"};
|
||||
static int old_page_id = -1;
|
||||
|
||||
static SDL_Window *window;
|
||||
static SDL_Renderer *renderer;
|
||||
|
||||
static void SetupPopup(const char *id) {
|
||||
ImGui::OpenPopup(id);
|
||||
@ -85,23 +45,10 @@ namespace GUI {
|
||||
ImGui::PopStyleVar();
|
||||
};
|
||||
|
||||
static void DisableButtonInit(bool disable) {
|
||||
if (disable) {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
static void DisableButtonExit(bool disable) {
|
||||
if (disable) {
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
}
|
||||
|
||||
static void Prompt(State &state, AppEntries &entries, std::vector<SceIoDirent> &loadouts, const std::string &db_name) {
|
||||
if (state == StateNone)
|
||||
if (state == StateNone) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string title, prompt;
|
||||
|
||||
@ -243,371 +190,153 @@ namespace GUI {
|
||||
GUI::ExitPopup();
|
||||
}
|
||||
|
||||
static void SortTab(AppEntries &entries, State &state) {
|
||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter |
|
||||
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
|
||||
|
||||
if (ImGui::BeginTabItem("Sort/Backup")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
ImGui::PushID("sort_by");
|
||||
ImGui::PushItemWidth(100.f);
|
||||
if (ImGui::BeginCombo("", sort_by[cfg.sort_by])) {
|
||||
for (int i = 0; i < IM_ARRAYSIZE(sort_by); i++) {
|
||||
const bool is_selected = (cfg.sort_by == i);
|
||||
|
||||
if (ImGui::Selectable(sort_by[i], is_selected)) {
|
||||
cfg.sort_by = i;
|
||||
Config::Save(cfg);
|
||||
static void Begin(void) {
|
||||
ImGui_ImplSDLRenderer2_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
static void End(ImGuiIO &io, ImVec4 clear_color, SDL_Renderer *renderer) {
|
||||
ImGui::Render();
|
||||
SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
||||
SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255));
|
||||
SDL_RenderClear(renderer);
|
||||
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData());
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
SDL_Renderer *GetRenderer(void) {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
SDL_Window *GetWindow(void) {
|
||||
return window;
|
||||
}
|
||||
|
||||
int Init(void) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) {
|
||||
Log::Error("SDL_Init failed: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create window with SDL_Renderer graphics context
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
window = SDL_CreateWindow("VITA Customizer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 960, 544, window_flags);
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == nullptr) {
|
||||
Log::Error("SDL_CreateRenderer failed: %s\n", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.IniFilename = nullptr;
|
||||
|
||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||
ImGui_ImplSDLRenderer2_Init(renderer);
|
||||
|
||||
// Build font atlas
|
||||
unsigned char *pixels = nullptr;
|
||||
int width = 0, height = 0, bytes_per_pixel = 0;
|
||||
|
||||
ImFontConfig font_config;
|
||||
font_config.OversampleH = 1;
|
||||
font_config.OversampleV = 1;
|
||||
font_config.PixelSnapH = 1;
|
||||
|
||||
io.Fonts->AddFontFromFileTTF("sa0:/data/font/pvf/jpn0.pvf", 20.0f, std::addressof(font_config), io.Fonts->GetGlyphRangesJapanese());
|
||||
io.Fonts->GetTexDataAsAlpha8(std::addressof(pixels), std::addressof(width), std::addressof(height), std::addressof(bytes_per_pixel));
|
||||
io.Fonts->Build();
|
||||
|
||||
// Set theme/style
|
||||
ImGui::GetStyle().FrameRounding = 4.0f;
|
||||
ImGui::GetStyle().GrabRounding = 4.0f;
|
||||
|
||||
ImVec4 *colors = ImGui::GetStyle().Colors;
|
||||
colors[ImGuiCol_Text] = ImVec4(0.85f, 0.85f, 0.85f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.05f, 0.07f, 0.13f, 1.00f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f);
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
|
||||
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabHovered] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_NavHighlight] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
ImGui_ImplSDLRenderer2_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void DisableButtonInit(bool disable) {
|
||||
if (disable) {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID("sort_folders");
|
||||
ImGui::PushItemWidth(150.f);
|
||||
if (ImGui::BeginCombo("", sort_folders[cfg.sort_folders])) {
|
||||
for (int i = 0; i < IM_ARRAYSIZE(sort_folders); i++) {
|
||||
const bool is_selected = (cfg.sort_folders == i);
|
||||
|
||||
if (ImGui::Selectable(sort_folders[i], is_selected)) {
|
||||
cfg.sort_folders = i;
|
||||
Config::Save(cfg);
|
||||
}
|
||||
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Default", cfg.sort_mode == SortDefault)) {
|
||||
cfg.sort_mode = SortDefault;
|
||||
AppList::Get(entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Asc", cfg.sort_mode == SortAsc)) {
|
||||
cfg.sort_mode = SortAsc;
|
||||
AppList::Get(entries);
|
||||
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAppAsc);
|
||||
std::sort(entries.child_apps.begin(), entries.child_apps.end(), AppList::SortChildAppAsc);
|
||||
AppList::Sort(entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Desc", cfg.sort_mode == SortDesc)) {
|
||||
cfg.sort_mode = SortDesc;
|
||||
AppList::Get(entries);
|
||||
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAppDesc);
|
||||
std::sort(entries.child_apps.begin(), entries.child_apps.end(), AppList::SortChildAppDesc);
|
||||
AppList::Sort(entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
GUI::DisableButtonInit(cfg.sort_mode == SortDefault);
|
||||
if (ImGui::Button("Apply Sort", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 0.0f))) {
|
||||
state = StateConfirmSort;
|
||||
}
|
||||
GUI::DisableButtonExit(cfg.sort_mode == SortDefault);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
GUI::DisableButtonInit(!backupExists);
|
||||
if (ImGui::Button("Restore Backup", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f))) {
|
||||
state = StateRestore;
|
||||
}
|
||||
GUI::DisableButtonExit(!backupExists);
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::BeginTable("AppList", 5, tableFlags)) {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Title");
|
||||
ImGui::TableSetupColumn("Page ID", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Page No", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Pos", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (unsigned int i = 0, counter = 0; i < entries.icons.size(); i++) {
|
||||
if (entries.icons[i].icon0Type == 7) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[Folder].id), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
std::string title = std::to_string(counter) + ") ";
|
||||
title.append(entries.icons[i].title);
|
||||
bool open = ImGui::TreeNodeEx(title.c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageNo);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pos);
|
||||
|
||||
if (open) {
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth;
|
||||
int reserved01 = std::stoi(std::string(entries.icons[i].reserved01));
|
||||
|
||||
for (unsigned int j = 0; j < entries.child_apps.size(); j++) {
|
||||
if (entries.child_apps[j].pageNo == reserved01) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TreeNodeEx(entries.child_apps[j].title, flags);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.child_apps[j].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("-");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.child_apps[j].pos);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
counter++;
|
||||
}
|
||||
else if (entries.icons[i].pageNo >= 0) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[App].id), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
std::string title = std::to_string(counter) + ") ";
|
||||
title.append(entries.icons[i].title);
|
||||
ImGui::Selectable(title.c_str(), false, ImGuiSelectableFlags_SpanAllColumns);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageNo);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pos);
|
||||
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
static void PagesTab(AppEntries &entries, State &state) {
|
||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter;
|
||||
|
||||
if (ImGui::BeginTabItem("Pages")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::Button("Reset", ImVec2(ImGui::GetContentRegionAvail().x * 0.33f, 0.0f))) {
|
||||
AppList::Get(entries);
|
||||
old_page_id = -1;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Apply Changes", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 0.0f))) {
|
||||
state = StateConfirmSwap;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
GUI::DisableButtonInit(!backupExists);
|
||||
if (ImGui::Button("Restore Backup", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f))) {
|
||||
state = StateRestore;
|
||||
}
|
||||
GUI::DisableButtonExit(!backupExists);
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::BeginTable("PagesList", 3, tableFlags)) {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("pageId");
|
||||
ImGui::TableSetupColumn("pageNo");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (unsigned int i = 0; i < entries.pages.size(); i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[Page].id), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.pages[i].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
std::string pageNo = std::to_string(entries.pages[i].pageNo);
|
||||
const bool is_selected = (old_page_id == static_cast<int>(i));
|
||||
if (ImGui::Selectable(pageNo.c_str(), is_selected)) {
|
||||
if (old_page_id == -1) {
|
||||
old_page_id = i;
|
||||
}
|
||||
else {
|
||||
int temp = entries.pages[i].pageNo;
|
||||
entries.pages[i].pageNo = entries.pages[old_page_id].pageNo;
|
||||
entries.pages[old_page_id].pageNo = temp;
|
||||
old_page_id = -1;
|
||||
ImGui::ClearActiveID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadoutsTab(std::vector<SceIoDirent> &loadouts, State &state, int &date_format, std::string &loadout_name) {
|
||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter |
|
||||
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
|
||||
|
||||
if (ImGui::BeginTabItem("Loadouts")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::Button("Backup current loadout", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f))) {
|
||||
if (R_SUCCEEDED(Loadouts::Backup())) {
|
||||
FS::GetDirList("ux0:data/VITAHomebrewSorter/loadouts", loadouts);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::BeginTable("LoadoutList", 4, tableFlags)) {
|
||||
if (loadouts.empty()) {
|
||||
ImGui::Text("No loadouts found");
|
||||
}
|
||||
else {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Title");
|
||||
ImGui::TableSetupColumn("Date", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (unsigned int i = 0; i < loadouts.size(); i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[DB].id), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(loadouts[i].d_name, false)) {
|
||||
loadout_name = loadouts[i].d_name;
|
||||
state = StateLoadoutRestore;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
char date[16];
|
||||
Utils::GetDateString(date, static_cast<SceSystemParamDateFormat>(date_format), loadouts[i].d_stat.st_mtime);
|
||||
ImGui::Text(date);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(i);
|
||||
if (ImGui::ImageButton("", reinterpret_cast<ImTextureID>(icons[Trash].id), tex_size, ImVec2(0, 0), ImVec2(1, 1), ImVec4(0.0f, 0.0f, 0.0f, 1.0f), ImVec4(1.0f, 1.0f, 1.0f, 1.0f))) {
|
||||
loadout_name = loadouts[i].d_name;
|
||||
state = StateDelete;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
static void SettingsTab(void) {
|
||||
if (ImGui::BeginTabItem("Settings")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
ImGui::Indent(5.f);
|
||||
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "Beta features:");
|
||||
ImGui::Indent(15.f);
|
||||
|
||||
if (ImGui::RadioButton("Enabled", cfg.beta_features == true)) {
|
||||
cfg.beta_features = true;
|
||||
Config::Save(cfg);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Disabled", cfg.beta_features == false)) {
|
||||
cfg.beta_features = false;
|
||||
Config::Save(cfg);
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f)); // Spacing
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Indent(5.f);
|
||||
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "App Info:");
|
||||
ImGui::Indent(15.f);
|
||||
std::string version = APP_VERSION;
|
||||
version.erase(0, std::min(version.find_first_not_of('0'), version.size() - 1));
|
||||
ImGui::Text("App version: %s", version.c_str());
|
||||
ImGui::Text("Author: Joel16");
|
||||
ImGui::Text("Assets: PreetiSketch");
|
||||
ImGui::Text("Dear imGui version: %s", ImGui::GetVersion());
|
||||
ImGui::Text("SQLite 3 version: %s", sqlite3_libversion());
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f)); // Spacing
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Indent(5.f);
|
||||
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "Usage:");
|
||||
ImGui::Indent(15.f);
|
||||
std::string usage = std::string("VITA Homebrew Sorter is a basic PS VITA homebrew application that sorts the application database in your LiveArea.")
|
||||
+ " The application sorts apps and games that are inside folders as well. This applications also allows you to backup your current 'loadout' that "
|
||||
+ " you can switch into as you wish. A backup will be made before any changes are applied to the application database."
|
||||
+ " This backup is overwritten each time you use the sort option. You can find the backup in ux0:/data/VITAHomebrewSorter/backups/app.db."
|
||||
+ " \n\nIt is always recommended to restart your vita so that it can refresh your livearea/app.db for any changes (deleted icons, new folders, etc.)"
|
||||
+ " before you run this application.";
|
||||
ImGui::TextWrapped(usage.c_str());
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
void DisableButtonExit(bool disable) {
|
||||
if (disable) {
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
}
|
||||
|
||||
int RenderLoop(void) {
|
||||
bool done = false;
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
backupExists = (FS::FileExists("ux0:/data/VITAHomebrewSorter/backup/app.db") || FS::FileExists("ux0:/data/VITAHomebrewSorter/backup/app.db.bkp"));
|
||||
|
||||
AppEntries entries;
|
||||
@ -624,34 +353,51 @@ namespace GUI {
|
||||
|
||||
std::string loadout_name;
|
||||
State state = StateNone;
|
||||
SceCtrlData pad = { 0 };
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
|
||||
while (!done) {
|
||||
ImGui_ImplVitaGL_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
if (event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) {
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
if (event.cbutton.button == SDL_CONTROLLER_BUTTON_START) {
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GUI::Begin();
|
||||
GUI::SetupWindow();
|
||||
|
||||
if (ImGui::Begin("VITA Homebrew Sorter", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
|
||||
if (ImGui::BeginTabBar("VITA Homebrew Sorter tabs")) {
|
||||
GUI::SortTab(entries, state);
|
||||
GUI::PagesTab(entries, state);
|
||||
Tabs::Sort(entries, state, backupExists);
|
||||
Tabs::Pages(entries, state, backupExists);
|
||||
GUI::DisableButtonInit(!cfg.beta_features);
|
||||
GUI::LoadoutsTab(loadouts, state, date_format, loadout_name);
|
||||
Tabs::Loadouts(loadouts, state, date_format, loadout_name);
|
||||
GUI::DisableButtonExit(!cfg.beta_features);
|
||||
GUI::SettingsTab();
|
||||
Tabs::Settings();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
}
|
||||
|
||||
GUI::ExitWindow();
|
||||
GUI::Prompt(state, entries, loadouts, loadout_name.c_str());
|
||||
Renderer::End(true, ImVec4(0.45f, 0.55f, 0.60f, 1.00f));
|
||||
|
||||
pad = Utils::ReadControls();
|
||||
|
||||
if (pressed & SCE_CTRL_START) {
|
||||
done = true;
|
||||
}
|
||||
GUI::End(io, clear_color, renderer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1,300 +0,0 @@
|
||||
// Implemented features:
|
||||
// [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
|
||||
|
||||
#include <math.h>
|
||||
#include <psp2/kernel/clib.h>
|
||||
#include <psp2/kernel/processmgr.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vitaGL.h>
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_vitagl.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define lerp(value, from_max, to_max) ((((value * 10) * (to_max * 10)) / (from_max * 10)) / 10)
|
||||
|
||||
struct ImGui_ImplVitaGL_Data {
|
||||
GLuint FontTexture = 0;
|
||||
uint64_t g_Time = 0;
|
||||
ImGui_ImplVitaGL_Data(void) {
|
||||
sceClibMemset(this, 0, sizeof(*this));
|
||||
}
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplVitaGL_Data *ImGui_ImplVitaGL_GetBackendData(void) {
|
||||
return ImGui::GetCurrentContext() ? static_cast<ImGui_ImplVitaGL_Data *>(ImGui::GetIO().BackendRendererUserData) : nullptr;
|
||||
}
|
||||
|
||||
bool ImGui_ImplVitaGL_Init(void) {
|
||||
sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplVitaGL_Data *bd = IM_NEW(ImGui_ImplVitaGL_Data)();
|
||||
io.BackendRendererUserData = (void *)bd;
|
||||
io.BackendRendererName = "imgui_impl_vitagl";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_Shutdown(void) {
|
||||
ImGui_ImplVitaGL_Data *bd = ImGui_ImplVitaGL_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplVitaGL_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVitaGL_UpdateGamepads(void) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
// Get gamepad
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
SceCtrlData pad;
|
||||
sceCtrlPeekBufferPositive(0, &pad, 1);
|
||||
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
int rstick_x = (pad.rx - 127) * 256;
|
||||
int rstick_y = (pad.ry - 127) * 256;
|
||||
|
||||
// Update gamepad inputs
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, (pad.buttons & BUTTON_NO)); }
|
||||
#define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(AXIS_NO - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
|
||||
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
|
||||
MAP_BUTTON(ImGuiKey_GamepadStart, SCE_CTRL_ENTER);
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, SCE_CTRL_CANCEL);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, SCE_CTRL_ENTER);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, SCE_CTRL_CANCEL);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SCE_CTRL_SQUARE);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, SCE_CTRL_TRIANGLE);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SCE_CTRL_LEFT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, SCE_CTRL_RIGHT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, SCE_CTRL_UP);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadDown, SCE_CTRL_DOWN);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL1, SCE_CTRL_LTRIGGER);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR1, SCE_CTRL_RTRIGGER);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, rstick_x, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickRight, rstick_x, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickUp, rstick_y, -thumb_dead_zone, -32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickDown, rstick_y, +thumb_dead_zone, +32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_NewFrame(void) {
|
||||
ImGui_ImplVitaGL_Data *bd = ImGui_ImplVitaGL_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplVitaGL_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplVitaGL_CreateDeviceObjects();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w = 0, h = 0;
|
||||
int display_w = 0, display_h = 0;
|
||||
|
||||
GLint viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
w = display_w = viewport[2];
|
||||
h = display_h = viewport[3];
|
||||
|
||||
io.DisplaySize = ImVec2(static_cast<float>(w), static_cast<float>(h));
|
||||
|
||||
if (w > 0 && h > 0)
|
||||
io.DisplayFramebufferScale = ImVec2(static_cast<float>(display_w / w),static_cast<float>(display_h) / h);
|
||||
|
||||
static uint64_t frequency = 1000000;
|
||||
uint64_t current_time = sceKernelGetProcessTimeWide();
|
||||
io.DeltaTime = bd->g_Time > 0 ? static_cast<float>(static_cast<double>((current_time - bd->g_Time)) / frequency) : static_cast<float>(1.0f / 60.0f);
|
||||
bd->g_Time = current_time;
|
||||
|
||||
ImGui_ImplVitaGL_UpdateGamepads();
|
||||
}
|
||||
|
||||
static void ImGui_ImplVitaGL_SetupRenderState(ImDrawData *draw_data, int fb_width, int fb_height) {
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
||||
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
|
||||
// (DO NOT MODIFY THIS FILE! Add the code in your calling function)
|
||||
// GLint last_program;
|
||||
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||
// glUseProgram(0);
|
||||
// ImGui_ImplVitaGL_RenderDrawData(...);
|
||||
// glUseProgram(last_program)
|
||||
// There are potentially many more states you could need to clear/setup that we can't access from default headers.
|
||||
// e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
glViewport(0, 0, static_cast<GLsizei>(fb_width), static_cast<GLsizei>(fb_height));
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
// OpenGL2 Render function.
|
||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
||||
// This is in order to be able to run within an OpenGL engine that doesn't do so.
|
||||
void ImGui_ImplVitaGL_RenderDrawData(ImDrawData *draw_data) {
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = static_cast<int>(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = static_cast<int>(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup GL state
|
||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
//GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model);
|
||||
GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
||||
|
||||
// Setup desired GL state
|
||||
ImGui_ImplVitaGL_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++) {
|
||||
const ImDrawList *cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert *vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx *idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), reinterpret_cast<const GLvoid *>(reinterpret_cast<const char *>(vtx_buffer) + IM_OFFSETOF(ImDrawVert, pos)));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), reinterpret_cast<const GLvoid *>(reinterpret_cast<const char *>(vtx_buffer) + IM_OFFSETOF(ImDrawVert, uv)));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), reinterpret_cast<const GLvoid *>(reinterpret_cast<const char *>(vtx_buffer) + IM_OFFSETOF(ImDrawVert, col)));
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
|
||||
const ImDrawCmd *pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback) {
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplVitaGL_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else {
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||
glScissor(static_cast<int>(clip_min.x), static_cast<int>(static_cast<float>(fb_height) - clip_max.y), static_cast<int>(clip_max.x - clip_min.x), static_cast<int>(clip_max.y - clip_min.y));
|
||||
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, reinterpret_cast<GLuint>(pcmd->GetTexID()));
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(pcmd->ElemCount), sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore modified GL state
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(last_texture));
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
glPolygonMode(GL_FRONT, static_cast<GLenum>(last_polygon_mode[0])); glPolygonMode(GL_BACK, static_cast<GLenum>(last_polygon_mode[1]));
|
||||
glViewport(last_viewport[0], last_viewport[1], static_cast<GLsizei>(last_viewport[2]), static_cast<GLsizei>(last_viewport[3]));
|
||||
glScissor(last_scissor_box[0], last_scissor_box[1], static_cast<GLsizei>(last_scissor_box[2]), static_cast<GLsizei>(last_scissor_box[3]));
|
||||
//glShadeModel(last_shade_model);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
|
||||
}
|
||||
|
||||
bool ImGui_ImplVitaGL_CreateFontsTexture(void) {
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplVitaGL_Data *bd = ImGui_ImplVitaGL_GetBackendData();
|
||||
unsigned char *pixels = nullptr;
|
||||
int width = 0, height = 0;
|
||||
|
||||
ImFontConfig font_config;
|
||||
font_config.OversampleH = 1;
|
||||
font_config.OversampleV = 1;
|
||||
font_config.PixelSnapH = 1;
|
||||
|
||||
io.Fonts->AddFontFromFileTTF("sa0:/data/font/pvf/jpn0.pvf", 20.0f, &font_config, io.Fonts->GetGlyphRangesJapanese());
|
||||
io.Fonts->GetTexDataAsRGBA32(static_cast<unsigned char **>(&pixels), &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
GLint last_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
glGenTextures(1, &bd->FontTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID(reinterpret_cast<ImTextureID>(bd->FontTexture));
|
||||
|
||||
// Restore state
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_DestroyFontsTexture(void) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplVitaGL_Data *bd = ImGui_ImplVitaGL_GetBackendData();
|
||||
|
||||
if (bd->FontTexture) {
|
||||
glDeleteTextures(1, &bd->FontTexture);
|
||||
io.Fonts->SetTexID(0);
|
||||
bd->FontTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplVitaGL_CreateDeviceObjects(void) {
|
||||
return ImGui_ImplVitaGL_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplVitaGL_DestroyDeviceObjects(void) {
|
||||
ImGui_ImplVitaGL_DestroyFontsTexture();
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
#include <locale>
|
||||
#include <psp2/kernel/clib.h>
|
||||
#include <psp2/ime_dialog.h>
|
||||
#include <vitaGL.h>
|
||||
|
||||
#include "gui.h"
|
||||
#include "keyboard.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
@ -87,8 +87,7 @@ namespace Keyboard {
|
||||
bool done = false;
|
||||
|
||||
do {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
SDL_RenderClear(GUI::GetRenderer());
|
||||
|
||||
SceCommonDialogStatus status = Keyboard::Update();
|
||||
|
||||
@ -99,7 +98,7 @@ namespace Keyboard {
|
||||
done = false;
|
||||
}
|
||||
|
||||
vglSwapBuffers(GL_TRUE);
|
||||
SDL_RenderPresent(GUI::GetRenderer());
|
||||
} while(!done);
|
||||
|
||||
return text;
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include <psp2/sysmodule.h>
|
||||
#include <vitaGL.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
#include "gui.h"
|
||||
#include "imgui_impl_vitagl.h"
|
||||
#include "log.h"
|
||||
#include "power.h"
|
||||
#include "textures.h"
|
||||
@ -13,79 +11,9 @@
|
||||
int _newlib_heap_size_user = 192 * 1024 * 1024;
|
||||
|
||||
namespace Services {
|
||||
void SetDefaultTheme(void) {
|
||||
ImGui::GetStyle().FrameRounding = 4.0f;
|
||||
ImGui::GetStyle().GrabRounding = 4.0f;
|
||||
|
||||
ImVec4 *colors = ImGui::GetStyle().Colors;
|
||||
colors[ImGuiCol_Text] = ImVec4(0.85f, 0.85f, 0.85f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.05f, 0.07f, 0.13f, 1.00f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f);
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
|
||||
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabHovered] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_NavHighlight] = ImVec4(0.65f, 0.16f, 0.31f, 1.0f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||
io.IniFilename = nullptr;
|
||||
}
|
||||
|
||||
void Init(void) {
|
||||
// Initalize vitaGL and imGui contexts
|
||||
vglInitExtended(0, 960, 544, 0x800000, SCE_GXM_MULTISAMPLE_4X);
|
||||
vglUseVram(GL_TRUE);
|
||||
ImGui::CreateContext();
|
||||
ImGui_ImplVitaGL_Init();
|
||||
|
||||
// Setup style
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
GUI::Init();
|
||||
Utils::InitAppUtil();
|
||||
SCE_CTRL_ENTER = Utils::GetEnterButton();
|
||||
SCE_CTRL_CANCEL = Utils::GetCancelButton();
|
||||
|
||||
sceSysmoduleLoadModule(SCE_SYSMODULE_JSON);
|
||||
|
||||
if (!FS::DirExists("ux0:data/VITAHomebrewSorter/backup")) {
|
||||
@ -103,20 +31,16 @@ namespace Services {
|
||||
}
|
||||
|
||||
void Exit(void) {
|
||||
// Clean up
|
||||
Textures::Exit();
|
||||
Log::Exit();
|
||||
sceSysmoduleUnloadModule(SCE_SYSMODULE_JSON);
|
||||
Utils::EndAppUtil();
|
||||
ImGui_ImplVitaGL_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
vglEnd();
|
||||
GUI::Exit();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Services::Init();
|
||||
Services::SetDefaultTheme();
|
||||
GUI::RenderLoop();
|
||||
Services::Exit();
|
||||
return 0;
|
||||
|
70
source/tabs/loadouts.cpp
Normal file
70
source/tabs/loadouts.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "fs.h"
|
||||
#include "imgui.h"
|
||||
#include "loadouts.h"
|
||||
#include "tabs.h"
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace Tabs {
|
||||
static const ImVec2 tex_size = ImVec2(20, 20);
|
||||
|
||||
void Loadouts(std::vector<SceIoDirent> &loadouts, State &state, int &date_format, std::string &loadout_name) {
|
||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter |
|
||||
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
|
||||
|
||||
if (ImGui::BeginTabItem("Loadouts")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::Button("Backup current loadout", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f))) {
|
||||
if (R_SUCCEEDED(Loadouts::Backup())) {
|
||||
FS::GetDirList("ux0:data/VITAHomebrewSorter/loadouts", loadouts);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::BeginTable("LoadoutList", 4, tableFlags)) {
|
||||
if (loadouts.empty()) {
|
||||
ImGui::Text("No loadouts found");
|
||||
}
|
||||
else {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Title");
|
||||
ImGui::TableSetupColumn("Date", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (unsigned int i = 0; i < loadouts.size(); i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[DB].ptr), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(loadouts[i].d_name, false)) {
|
||||
loadout_name = loadouts[i].d_name;
|
||||
state = StateLoadoutRestore;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
char date[16];
|
||||
Utils::GetDateString(date, static_cast<SceSystemParamDateFormat>(date_format), loadouts[i].d_stat.st_mtime);
|
||||
ImGui::Text(date);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushID(i);
|
||||
if (ImGui::ImageButton("", reinterpret_cast<ImTextureID>(icons[Trash].ptr), tex_size, ImVec2(0, 0), ImVec2(1, 1), ImVec4(0.0f, 0.0f, 0.0f, 1.0f), ImVec4(1.0f, 1.0f, 1.0f, 1.0f))) {
|
||||
loadout_name = loadouts[i].d_name;
|
||||
state = StateDelete;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
76
source/tabs/pages.cpp
Normal file
76
source/tabs/pages.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "gui.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "tabs.h"
|
||||
#include "textures.h"
|
||||
|
||||
namespace Tabs {
|
||||
static int old_page_id = -1;
|
||||
static const ImVec2 tex_size = ImVec2(20, 20);
|
||||
|
||||
void Pages(AppEntries &entries, State &state, bool &backupExists) {
|
||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter;
|
||||
|
||||
if (ImGui::BeginTabItem("Pages")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::Button("Reset", ImVec2(ImGui::GetContentRegionAvail().x * 0.33f, 0.0f))) {
|
||||
AppList::Get(entries);
|
||||
old_page_id = -1;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Apply Changes", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 0.0f))) {
|
||||
state = StateConfirmSwap;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
GUI::DisableButtonInit(!backupExists);
|
||||
if (ImGui::Button("Restore Backup", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f))) {
|
||||
state = StateRestore;
|
||||
}
|
||||
GUI::DisableButtonExit(!backupExists);
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::BeginTable("PagesList", 3, tableFlags)) {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("pageId");
|
||||
ImGui::TableSetupColumn("pageNo");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (unsigned int i = 0; i < entries.pages.size(); i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[Page].ptr), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.pages[i].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
std::string pageNo = std::to_string(entries.pages[i].pageNo);
|
||||
const bool is_selected = (old_page_id == static_cast<int>(i));
|
||||
if (ImGui::Selectable(pageNo.c_str(), is_selected)) {
|
||||
if (old_page_id == -1) {
|
||||
old_page_id = i;
|
||||
}
|
||||
else {
|
||||
int temp = entries.pages[i].pageNo;
|
||||
entries.pages[i].pageNo = entries.pages[old_page_id].pageNo;
|
||||
entries.pages[old_page_id].pageNo = temp;
|
||||
old_page_id = -1;
|
||||
ImGui::ClearActiveID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
67
source/tabs/settings.cpp
Normal file
67
source/tabs/settings.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include <SDL.h>
|
||||
#include <string>
|
||||
|
||||
#include "config.h"
|
||||
#include "imgui.h"
|
||||
#include "sqlite3.h"
|
||||
|
||||
namespace Tabs {
|
||||
static SDL_version sdlVersion;
|
||||
|
||||
void Settings(void) {
|
||||
if (ImGui::BeginTabItem("Settings")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
ImGui::Indent(5.f);
|
||||
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "Beta features:");
|
||||
ImGui::Indent(15.f);
|
||||
|
||||
if (ImGui::RadioButton("Enabled", cfg.beta_features == true)) {
|
||||
cfg.beta_features = true;
|
||||
Config::Save(cfg);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Disabled", cfg.beta_features == false)) {
|
||||
cfg.beta_features = false;
|
||||
Config::Save(cfg);
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f)); // Spacing
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Indent(5.f);
|
||||
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "App Info:");
|
||||
ImGui::Indent(15.f);
|
||||
std::string version = APP_VERSION;
|
||||
version.erase(0, std::min(version.find_first_not_of('0'), version.size() - 1));
|
||||
ImGui::Text("App version: %s", version.c_str());
|
||||
ImGui::Text("Author: Joel16");
|
||||
ImGui::Text("Assets: PreetiSketch");
|
||||
ImGui::Text("Dear imGui version: %s", ImGui::GetVersion());
|
||||
|
||||
SDL_GetVersion(&sdlVersion);
|
||||
ImGui::Text("SDL2 version: %u.%u.%u", sdlVersion.major, sdlVersion.minor, sdlVersion.patch);
|
||||
|
||||
ImGui::Text("SQLite 3 version: %s", sqlite3_libversion());
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f)); // Spacing
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::Indent(5.f);
|
||||
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "Usage:");
|
||||
ImGui::Indent(15.f);
|
||||
std::string usage = std::string("VITA Homebrew Sorter is a basic PS VITA homebrew application that sorts the application database in your LiveArea.")
|
||||
+ " The application sorts apps and games that are inside folders as well. This applications also allows you to backup your current 'loadout' that "
|
||||
+ " you can switch into as you wish. A backup will be made before any changes are applied to the application database."
|
||||
+ " This backup is overwritten each time you use the sort option. You can find the backup in ux0:/data/VITAHomebrewSorter/backups/app.db."
|
||||
+ " \n\nIt is always recommended to restart your vita so that it can refresh your livearea/app.db for any changes (deleted icons, new folders, etc.)"
|
||||
+ " before you run this application.";
|
||||
ImGui::TextWrapped(usage.c_str());
|
||||
ImGui::Unindent();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
197
source/tabs/sort.cpp
Normal file
197
source/tabs/sort.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "config.h"
|
||||
#include "gui.h"
|
||||
#include "imgui.h"
|
||||
#include "tabs.h"
|
||||
#include "textures.h"
|
||||
|
||||
namespace Tabs {
|
||||
static const ImVec2 tex_size = ImVec2(20, 20);
|
||||
static const char *sort_by[] = {"Title", "Title ID"};
|
||||
static const char *sort_folders[] = {"Both", "Apps only", "Folders only"};
|
||||
|
||||
void Sort(AppEntries &entries, State &state, bool &backupExists) {
|
||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter |
|
||||
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
|
||||
|
||||
if (ImGui::BeginTabItem("Sort/Backup")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
ImGui::PushID("sort_by");
|
||||
ImGui::PushItemWidth(100.f);
|
||||
if (ImGui::BeginCombo("", sort_by[cfg.sort_by])) {
|
||||
for (int i = 0; i < IM_ARRAYSIZE(sort_by); i++) {
|
||||
const bool is_selected = (cfg.sort_by == i);
|
||||
|
||||
if (ImGui::Selectable(sort_by[i], is_selected)) {
|
||||
cfg.sort_by = i;
|
||||
Config::Save(cfg);
|
||||
}
|
||||
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID("sort_folders");
|
||||
ImGui::PushItemWidth(150.f);
|
||||
if (ImGui::BeginCombo("", sort_folders[cfg.sort_folders])) {
|
||||
for (int i = 0; i < IM_ARRAYSIZE(sort_folders); i++) {
|
||||
const bool is_selected = (cfg.sort_folders == i);
|
||||
|
||||
if (ImGui::Selectable(sort_folders[i], is_selected)) {
|
||||
cfg.sort_folders = i;
|
||||
Config::Save(cfg);
|
||||
}
|
||||
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Default", cfg.sort_mode == SortDefault)) {
|
||||
cfg.sort_mode = SortDefault;
|
||||
AppList::Get(entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Asc", cfg.sort_mode == SortAsc)) {
|
||||
cfg.sort_mode = SortAsc;
|
||||
AppList::Get(entries);
|
||||
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAppAsc);
|
||||
std::sort(entries.child_apps.begin(), entries.child_apps.end(), AppList::SortChildAppAsc);
|
||||
AppList::Sort(entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Desc", cfg.sort_mode == SortDesc)) {
|
||||
cfg.sort_mode = SortDesc;
|
||||
AppList::Get(entries);
|
||||
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAppDesc);
|
||||
std::sort(entries.child_apps.begin(), entries.child_apps.end(), AppList::SortChildAppDesc);
|
||||
AppList::Sort(entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
GUI::DisableButtonInit(cfg.sort_mode == SortDefault);
|
||||
if (ImGui::Button("Apply Sort", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 0.0f))) {
|
||||
state = StateConfirmSort;
|
||||
}
|
||||
GUI::DisableButtonExit(cfg.sort_mode == SortDefault);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
GUI::DisableButtonInit(!backupExists);
|
||||
if (ImGui::Button("Restore Backup", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f))) {
|
||||
state = StateRestore;
|
||||
}
|
||||
GUI::DisableButtonExit(!backupExists);
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
if (ImGui::BeginTable("AppList", 5, tableFlags)) {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Title");
|
||||
ImGui::TableSetupColumn("Page ID", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Page No", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Pos", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (unsigned int i = 0, counter = 0; i < entries.icons.size(); i++) {
|
||||
if (entries.icons[i].icon0Type == 7) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[Folder].ptr), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
std::string title = std::to_string(counter) + ") ";
|
||||
title.append(entries.icons[i].title);
|
||||
bool open = ImGui::TreeNodeEx(title.c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageNo);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pos);
|
||||
|
||||
if (open) {
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth;
|
||||
int reserved01 = std::stoi(std::string(entries.icons[i].reserved01));
|
||||
|
||||
for (unsigned int j = 0; j < entries.child_apps.size(); j++) {
|
||||
if (entries.child_apps[j].pageNo == reserved01) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TreeNodeEx(entries.child_apps[j].title, flags);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.child_apps[j].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("-");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.child_apps[j].pos);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
counter++;
|
||||
}
|
||||
else if (entries.icons[i].pageNo >= 0) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(icons[App].ptr), tex_size);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
std::string title = std::to_string(counter) + ") ";
|
||||
title.append(entries.icons[i].title);
|
||||
ImGui::Selectable(title.c_str(), false, ImGuiSelectableFlags_SpanAllColumns);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pageNo);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entries.icons[i].pos);
|
||||
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
#include <memory>
|
||||
#include <png.h>
|
||||
#include <psp2/kernel/clib.h>
|
||||
#include <SDL_image.h>
|
||||
#include <string>
|
||||
|
||||
#include "imgui.h"
|
||||
#include "gui.h"
|
||||
#include "log.h"
|
||||
#include "textures.h"
|
||||
|
||||
@ -11,68 +10,44 @@ std::vector<Tex> icons;
|
||||
|
||||
namespace Textures {
|
||||
constexpr int max_textures = 7;
|
||||
int GL_RGB = 3, GL_RGBA = 4;
|
||||
|
||||
static bool Create(unsigned char *data, GLint format, Tex &texture) {
|
||||
// Create a OpenGL texture identifier
|
||||
glGenTextures(1, &texture.id);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
static bool LoadImage(const std::string &path, Tex &texture) {
|
||||
texture.ptr = IMG_LoadTexture(GUI::GetRenderer(), path.c_str());
|
||||
|
||||
// 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);
|
||||
if (!texture.ptr) {
|
||||
Log::Error("Couldn't load %s: %s\n", path.c_str(), SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Upload pixels into texture
|
||||
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, texture.width, texture.height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||
SDL_QueryTexture(texture.ptr, nullptr, nullptr, &texture.width, &texture.height);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadImagePNG(const std::string &path, Tex &texture) {
|
||||
bool ret = false;
|
||||
png_image image;
|
||||
sceClibMemset(&image, 0, (sizeof image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
if (png_image_begin_read_from_file(&image, path.c_str()) != 0) {
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
std::unique_ptr<png_byte[]> buffer(new png_byte[PNG_IMAGE_SIZE(image)]);
|
||||
|
||||
if (png_image_finish_read(&image, nullptr, buffer.get(), 0, nullptr) != 0) {
|
||||
texture.width = image.width;
|
||||
texture.height = image.height;
|
||||
ret = Textures::Create(buffer.get(), GL_RGBA, texture);
|
||||
png_image_free(&image);
|
||||
void Free(SDL_Texture *texture) {
|
||||
if (texture) {
|
||||
SDL_DestroyTexture(texture);
|
||||
texture = nullptr;
|
||||
}
|
||||
else {
|
||||
Log::Error("png_image_finish_read failed: %s\n", image.message);
|
||||
png_image_free(&image);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log::Error("png_image_begin_read_from_memory failed: %s\n", image.message);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Init(void) {
|
||||
icons.resize(max_textures);
|
||||
|
||||
const std::string paths[max_textures] {
|
||||
"app0:res/app.png",
|
||||
"app0:res/db.png",
|
||||
"app0:res/folder.png",
|
||||
"app0:res/page.png",
|
||||
"app0:res/trash.png",
|
||||
"app0:res/checked.png",
|
||||
"app0:res/unchecked.png",
|
||||
"app0:res/trash.png"
|
||||
"app0:res/unchecked.png"
|
||||
};
|
||||
|
||||
for (int i = 0; i < max_textures; i++) {
|
||||
bool ret = Textures::LoadImagePNG(paths[i], icons[i]);
|
||||
Tex texture;
|
||||
bool ret = Textures::LoadImage(paths[i], texture);
|
||||
IM_ASSERT(ret);
|
||||
|
||||
icons.push_back(texture);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -80,7 +55,7 @@ namespace Textures {
|
||||
|
||||
void Exit(void) {
|
||||
for (int i = 0; i < max_textures; i++) {
|
||||
glDeleteTextures(1, &icons[i].id);
|
||||
Textures::Free(icons[i].ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,7 @@
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
||||
int SCE_CTRL_ENTER = 0, SCE_CTRL_CANCEL = 0;
|
||||
unsigned int pressed = 0;
|
||||
|
||||
namespace Utils {
|
||||
static SceCtrlData pad, old_pad;
|
||||
|
||||
int InitAppUtil(void) {
|
||||
SceAppUtilInitParam init;
|
||||
SceAppUtilBootParam boot;
|
||||
@ -33,11 +28,6 @@ namespace Utils {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, reinterpret_cast<int *>(¶m.enterButtonAssign)))) {
|
||||
Log::Error("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (R_FAILED(ret = sceCommonDialogSetConfigParam(¶m))) {
|
||||
Log::Error("sceCommonDialogSetConfigParam failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
@ -57,42 +47,6 @@ namespace Utils {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SceCtrlData ReadControls(void) {
|
||||
sceClibMemset(&pad, 0, sizeof(SceCtrlData));
|
||||
sceCtrlPeekBufferPositive(0, &pad, 1);
|
||||
pressed = pad.buttons & ~old_pad.buttons;
|
||||
old_pad = pad;
|
||||
return pad;
|
||||
}
|
||||
|
||||
int GetEnterButton(void) {
|
||||
int button = 0, ret = 0;
|
||||
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button))) {
|
||||
Log::Error("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE) {
|
||||
return SCE_CTRL_CIRCLE;
|
||||
}
|
||||
|
||||
return SCE_CTRL_CROSS;
|
||||
}
|
||||
|
||||
int GetCancelButton(void) {
|
||||
int button = 0, ret = 0;
|
||||
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button))) {
|
||||
Log::Error("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (button == SCE_SYSTEM_PARAM_ENTER_BUTTON_CIRCLE) {
|
||||
return SCE_CTRL_CROSS;
|
||||
}
|
||||
|
||||
return SCE_CTRL_CIRCLE;
|
||||
}
|
||||
|
||||
int GetDateFormat(void) {
|
||||
int format = 0, ret = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user