PSP2: Add GUI framework and use for file chooser

This commit is contained in:
Jeffrey Pfau 2015-07-28 00:59:28 -07:00
parent cddae84a43
commit ade9402578
12 changed files with 342 additions and 10 deletions

View File

@ -27,6 +27,7 @@ file(GLOB GBA_CHEATS_SRC ${CMAKE_SOURCE_DIR}/src/gba/cheats/*.c)
file(GLOB GBA_RR_SRC ${CMAKE_SOURCE_DIR}/src/gba/rr/*.c)
file(GLOB GBA_SV_SRC ${CMAKE_SOURCE_DIR}/src/gba/supervisor/*.c)
file(GLOB UTIL_SRC ${CMAKE_SOURCE_DIR}/src/util/*.[cSs])
file(GLOB GUI_SRC ${CMAKE_SOURCE_DIR}/src/util/gui/*.c)
file(GLOB RENDERER_SRC ${CMAKE_SOURCE_DIR}/src/gba/renderers/*.c)
file(GLOB SIO_SRC ${CMAKE_SOURCE_DIR}/src/gba/sio/lockstep.c)
file(GLOB THIRD_PARTY_SRC ${CMAKE_SOURCE_DIR}/src/third-party/inih/*.c)
@ -355,6 +356,7 @@ set(CORE_SRC
${DEBUGGER_SRC}
${RENDERER_SRC}
${SIO_SRC}
${GUI_SRC}
${UTIL_SRC}
${VFS_SRC}
${OS_SRC}

BIN
res/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,8 +1,10 @@
file(GLOB PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/psp2/*.c)
set(PLATFORM_LIBRARY -lvita2d -lSceCtrl_stub -lSceRtc_stub -lSceGxm_stub -lSceDisplay_stub -lSceAudio_stub -lm_stub)
execute_process(COMMAND ${DEVKITARM}/bin/arm-none-eabi-objcopy -I binary -O elf32-littlearm -B arm font.png ${CMAKE_BINARY_DIR}/font.o WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/res)
add_executable(${BINARY_NAME}.elf ${PLATFORM_SRC})
set(PLATFORM_LIBRARY -lvita2d -lSceCtrl_stub -lSceRtc_stub -lSceGxm_stub -lSceDisplay_stub -lSceAudio_stub -lpng -lz -lm_stub)
add_executable(${BINARY_NAME}.elf ${PLATFORM_SRC} ${CMAKE_BINARY_DIR}/font.o)
target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${PLATFORM_LIBRARY})
set_target_properties(${BINARY_NAME}.elf PROPERTIES OUTPUT_NAME ${BINARY_NAME}.elf)
add_custom_command(TARGET ${BINARY_NAME}.elf POST_BUILD COMMAND ${FIXUP} -q -S ${BINARY_NAME}.elf ${BINARY_NAME}.velf MAIN_DEPENDENCY ${BINARY_NAME}.elf)

View File

@ -0,0 +1,60 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "util/gui/font.h"
#include <vita2d.h>
#define GLYPH_HEIGHT 11
#define GLYPH_WIDTH 14
#define FONT_TRACKING 10
#define CELL_HEIGHT 16
#define CELL_WIDTH 16
extern const uint8_t _binary_font_png_start[];
struct GUIFont {
vita2d_texture* tex;
};
struct GUIFont* GUIFontCreate(void) {
struct GUIFont* font = malloc(sizeof(struct GUIFont));
if (!font) {
return 0;
}
font->tex = vita2d_load_PNG_buffer(_binary_font_png_start);
return font;
}
void GUIFontDestroy(struct GUIFont* font) {
vita2d_free_texture(font->tex);
free(font);
}
int GUIFontHeight(const struct GUIFont* font) {
UNUSED(font);
return GLYPH_HEIGHT;
}
void GUIFontPrintf(const struct GUIFont* font, int x, int y, enum GUITextAlignment align, uint32_t color, const char* text, ...) {
UNUSED(align); // TODO
char buffer[256];
va_list args;
va_start(args, text);
int len = vsnprintf(buffer, sizeof(buffer), text, args);
va_end(args);
int i;
for (i = 0; i < len; ++i) {
char c = buffer[i];
if (c > 0x7F) {
c = 0;
}
vita2d_draw_texture_tint_part(font->tex, x, y - GLYPH_HEIGHT,
(c & 15) * CELL_WIDTH + ((CELL_WIDTH - GLYPH_WIDTH) >> 1),
(c >> 4) * CELL_HEIGHT + ((CELL_HEIGHT - GLYPH_HEIGHT) >> 1),
GLYPH_WIDTH, GLYPH_HEIGHT, color);
x += FONT_TRACKING;
}
}

View File

@ -5,19 +5,83 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "psp2-context.h"
#include "util/gui.h"
#include "util/gui/font.h"
#include "util/gui/file-select.h"
#include <psp2/ctrl.h>
#include <psp2/kernel/processmgr.h>
#include <psp2/moduleinfo.h>
#include <vita2d.h>
PSP2_MODULE_INFO(0, 0, "mGBA");
static void _drawStart(void) {
vita2d_start_drawing();
vita2d_clear_screen();
}
static void _drawEnd(void) {
vita2d_end_drawing();
vita2d_swap_buffers();
}
static int _pollInput(void) {
SceCtrlData pad;
sceCtrlPeekBufferPositive(0, &pad, 1);
int input = 0;
if (pad.buttons & PSP2_CTRL_TRIANGLE) {
input |= 1 << GUI_INPUT_CANCEL;
}
if (pad.buttons & PSP2_CTRL_CIRCLE) {
input |= 1 << GUI_INPUT_BACK;
}
if (pad.buttons & PSP2_CTRL_CROSS) {
input |= 1 << GUI_INPUT_SELECT;
}
if (pad.buttons & PSP2_CTRL_UP) {
input |= 1 << GUI_INPUT_UP;
}
if (pad.buttons & PSP2_CTRL_DOWN) {
input |= 1 << GUI_INPUT_DOWN;
}
if (pad.buttons & PSP2_CTRL_LEFT) {
input |= 1 << GUI_INPUT_LEFT;
}
if (pad.buttons & PSP2_CTRL_RIGHT) {
input |= 1 << GUI_INPUT_RIGHT;
}
return input;
}
int main() {
printf("%s initializing", projectName);
vita2d_init();
struct GUIFont* font = GUIFontCreate();
GBAPSP2Setup();
GBAPSP2LoadROM("cache0:/VitaDefilerClient/Documents/GBA/rom.gba");
GBAPSP2Runloop();
GBAPSP2UnloadROM();
struct GUIParams params = {
PSP2_HORIZONTAL_PIXELS, PSP2_VERTICAL_PIXELS,
font, _drawStart, _drawEnd, _pollInput
};
while (true) {
char path[256];
if (!selectFile(&params, "cache0:", path, sizeof(path), "gba")) {
break;
}
GBAPSP2LoadROM(path);
GBAPSP2Runloop();
GBAPSP2UnloadROM();
}
GBAPSP2Teardown();
GUIFontDestroy(font);
vita2d_fini();
sceKernelExitProcess(0);
return 0;
}

View File

@ -0,0 +1,14 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef PSP2_COMMON_H
#define PSP2_COMMON_H
#include "util/common.h"
#define PSP2_HORIZONTAL_PIXELS 960
#define PSP2_VERTICAL_PIXELS 544
#endif

View File

@ -39,8 +39,6 @@ static Thread audioThread;
static bool fullscreen = false;
#define PSP2_HORIZONTAL_PIXELS 960
#define PSP2_VERTICAL_PIXELS 544
#define PSP2_INPUT 0x50535032
#define PSP2_SAMPLES 64
#define PSP2_AUDIO_BUFFER_SIZE (PSP2_SAMPLES * 19)
@ -100,7 +98,6 @@ void GBAPSP2Setup() {
desc = (struct GBAAxis) { GBA_KEY_RIGHT, GBA_KEY_LEFT, 192, 64 };
GBAInputBindAxis(&inputMap, PSP2_INPUT, 1, &desc);
vita2d_init();
tex = vita2d_create_empty_texture_format(256, 256, SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR);
renderer.outputBuffer = vita2d_texture_get_datap(tex);
@ -251,7 +248,6 @@ void GBAPSP2Teardown(void) {
GBAInputMapDeinit(&inputMap);
vita2d_free_texture(tex);
vita2d_fini();
}
void GBAPSP2Draw(void) {

View File

@ -6,7 +6,7 @@
#ifndef PSP2_CONTEXT_H
#define PSP2_CONTEXT_H
#include "util/common.h"
#include "psp2-common.h"
void GBAPSP2Setup(void);
void GBAPSP2Teardown(void);

35
src/util/gui.h Normal file
View File

@ -0,0 +1,35 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GUI_H
#define GUI_H
#include "util/common.h"
struct GUIFont;
enum GUIInput {
GUI_INPUT_NONE = -1,
GUI_INPUT_SELECT = 0,
GUI_INPUT_BACK,
GUI_INPUT_CANCEL,
GUI_INPUT_UP,
GUI_INPUT_DOWN,
GUI_INPUT_LEFT,
GUI_INPUT_RIGHT,
};
struct GUIParams {
int width;
int height;
const struct GUIFont* font;
void (*drawStart)(void);
void (*drawEnd)(void);
int (*pollInput)(void);
};
#endif

121
src/util/gui/file-select.c Normal file
View File

@ -0,0 +1,121 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "file-select.h"
#include "util/gui/font.h"
#include "util/vector.h"
#include "util/vfs.h"
DECLARE_VECTOR(FileList, char*);
DEFINE_VECTOR(FileList, char*);
void _cleanFiles(struct FileList* currentFiles) {
size_t size = FileListSize(currentFiles);
size_t i;
for (i = 0; i < size; ++i) {
free(*FileListGetPointer(currentFiles, i));
}
FileListClear(currentFiles);
}
void _upDirectory(char* currentPath) {
char* end = strrchr(currentPath, '/');
if (!end) {
return;
}
end[0] = '\0';
if (end[1]) {
return;
}
// TODO: What if there was a trailing slash?
}
bool _refreshDirectory(const char* currentPath, struct FileList* currentFiles) {
_cleanFiles(currentFiles);
struct VDir* dir = VDirOpen(currentPath);
if (!dir) {
return false;
}
struct VDirEntry* de;
while ((de = dir->listNext(dir))) {
if (de->name(de)[0] == '.') {
continue;
}
*FileListAppend(currentFiles) = strdup(de->name(de));
}
dir->close(dir);
return true;
}
bool selectFile(const struct GUIParams* params, const char* basePath, char* outPath, size_t outLen, const char* suffix) {
char currentPath[256];
strncpy(currentPath, basePath, sizeof(currentPath));
int oldInput = -1;
size_t fileIndex = 0;
struct FileList currentFiles;
FileListInit(&currentFiles, 0);
_refreshDirectory(currentPath, &currentFiles);
while (true) {
int input = params->pollInput();
int newInput = input & (oldInput ^ input);
oldInput = input;
if (newInput & (1 << GUI_INPUT_UP) && fileIndex > 0) {
--fileIndex;
}
if (newInput & (1 << GUI_INPUT_DOWN) && fileIndex < FileListSize(&currentFiles) - 1) {
++fileIndex;
}
if (newInput & (1 << GUI_INPUT_CANCEL)) {
_cleanFiles(&currentFiles);
FileListDeinit(&currentFiles);
return false;
}
if (newInput & (1 << GUI_INPUT_SELECT)) {
snprintf(currentPath, sizeof(currentPath), "%s%c%s", currentPath, '/', *FileListGetPointer(&currentFiles, fileIndex));
if (!_refreshDirectory(currentPath, &currentFiles)) {
strncpy(outPath, currentPath, outLen);
return true;
}
fileIndex = 0;
}
if (newInput & (1 << GUI_INPUT_BACK)) {
if (strncmp(currentPath, basePath, sizeof(currentPath)) == 0) {
_cleanFiles(&currentFiles);
FileListDeinit(&currentFiles);
return false;
}
_upDirectory(currentPath);
_refreshDirectory(currentPath, &currentFiles);
fileIndex = 0;
}
params->drawStart();
int y = GUIFontHeight(params->font);
GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, "Current directory: %s", currentPath);
y += 2 * GUIFontHeight(params->font);
size_t i;
for (i = 0; i < FileListSize(&currentFiles); ++i) {
int color = 0xE0A0A0A0;
char bullet = ' ';
if (i == fileIndex) {
color = 0xFFFFFFFF;
bullet = '>';
}
GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, *FileListGetPointer(&currentFiles, i));
y += GUIFontHeight(params->font);
if (y + GUIFontHeight(params->font) > params->height) {
break;
}
}
y += GUIFontHeight(params->font) * 2;
params->drawEnd();
}
}

View File

@ -0,0 +1,13 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GUI_FILE_CHOOSER_H
#define GUI_FILE_CHOOSER_H
#include "util/gui.h"
bool selectFile(const struct GUIParams*, const char* basePath, char* outPath, size_t outLen, const char* suffix);
#endif

25
src/util/gui/font.h Normal file
View File

@ -0,0 +1,25 @@
/* Copyright (c) 2013-2015 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GUI_FONT_H
#define GUI_FONT_H
#include "util/common.h"
struct GUIFont;
struct GUIFont* GUIFontCreate(void);
void GUIFontDestroy(struct GUIFont*);
enum GUITextAlignment {
GUI_TEXT_LEFT = 0,
GUI_TEXT_CENTER,
GUI_TEXT_RIGHT
};
int GUIFontHeight(const struct GUIFont*);
void GUIFontPrintf(const struct GUIFont*, int x, int y, enum GUITextAlignment, uint32_t color, const char* text, ...);
#endif