From 3f29cea8bf6803b61dab5bd20dc6684181b7e020 Mon Sep 17 00:00:00 2001 From: joel16 Date: Mon, 3 Apr 2023 16:42:26 -0400 Subject: [PATCH] app: Add ability to take .BMP screenshots using the square button --- app/include/screenshot.h | 5 ++ app/source/consoleidinfo.cpp | 4 +- app/source/crt0.cpp | 10 +-- app/source/gui.cpp | 6 +- app/source/hardwareinfo.cpp | 5 +- app/source/main.cpp | 34 +++++---- app/source/screenshot.cpp | 140 +++++++++++++++++++++++++++++++++++ app/source/systeminfo.cpp | 5 +- app/source/utils.cpp | 3 +- libs/include/vlf.h | 2 +- 10 files changed, 179 insertions(+), 35 deletions(-) create mode 100644 app/include/screenshot.h create mode 100644 app/source/screenshot.cpp diff --git a/app/include/screenshot.h b/app/include/screenshot.h new file mode 100644 index 0000000..dba101c --- /dev/null +++ b/app/include/screenshot.h @@ -0,0 +1,5 @@ +#pragma once + +namespace Screenshot { + void Capture(int menu); +} diff --git a/app/source/consoleidinfo.cpp b/app/source/consoleidinfo.cpp index 397c1ec..f2bb459 100644 --- a/app/source/consoleidinfo.cpp +++ b/app/source/consoleidinfo.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include "consoleidinfo.h" diff --git a/app/source/crt0.cpp b/app/source/crt0.cpp index 9a298e2..a8aca29 100644 --- a/app/source/crt0.cpp +++ b/app/source/crt0.cpp @@ -1,15 +1,11 @@ - +#include +#include #include -#include #include -#include -#include -#include - - #include "main.h" #include "kernel.h" +#include "vlf.h" extern unsigned char kernel_prx_start[], intraFont_prx_start[], kumdman_prx_start[], vlf_prx_start[]; extern unsigned int kernel_prx_size, intraFont_prx_size, kumdman_prx_size, vlf_prx_size; diff --git a/app/source/gui.cpp b/app/source/gui.cpp index af566a9..e44406d 100644 --- a/app/source/gui.cpp +++ b/app/source/gui.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include "gui.h" #include "utils.h" diff --git a/app/source/hardwareinfo.cpp b/app/source/hardwareinfo.cpp index bb4aa7f..a42aef8 100644 --- a/app/source/hardwareinfo.cpp +++ b/app/source/hardwareinfo.cpp @@ -1,7 +1,6 @@ +#include +#include #include -#include -#include -#include #include "kernel.h" #include "kumdman.h" diff --git a/app/source/main.cpp b/app/source/main.cpp index 6550608..19e5f74 100644 --- a/app/source/main.cpp +++ b/app/source/main.cpp @@ -1,22 +1,20 @@ //>>> PSP_EVEREST 2 //Copyright(C) 2023, frostegater, Joel16 +#include +#include #include #include #include #include -#include #include -#include -#include -#include -#include #include "consoleidinfo.h" #include "gui.h" #include "hardwareinfo.h" #include "kernel.h" #include "main.h" +#include "screenshot.h" #include "systeminfo.h" #include "translate.h" #include "utils.h" @@ -42,6 +40,7 @@ namespace Menus { static constexpr u8 NUM_DEL_ITEMS_SYSTEM = 7; static constexpr u8 NUM_DEL_ITEMS_CONSOLEID = 8; + static u8 menu = 0; static bool battery_break = false; static u16 bserialdata[2], serialdata[2]; static VlfText text_hardware[NUM_DEL_ITEMS_HARDWARE], text_battery[NUM_DEL_ITEMS_BATTERY], @@ -281,28 +280,43 @@ namespace Menus { GUI::SetBottomDialog(0, 1, Menus::ConsoleIdInfoHandler, 1); GUI::SetFade(); } + + int Capture(void *param) { + Screenshot::Capture(menu); + return VLF_EV_RET_NOTHING; + } + + void HandleScreenshot(int select) { + menu = select; + vlfGuiRemoveEventHandler(Menus::Capture); + vlfGuiAddEventHandler(PSP_CTRL_SQUARE, -1, Menus::Capture, nullptr); + } int MainMenuHandler(int select) { switch(select) { case 0: vlfGuiCancelCentralMenu(); Menus::HardwareInfo(); + Menus::HandleScreenshot(select); break; case 1: vlfGuiCancelCentralMenu(); battery_break = false; + Menus::HandleScreenshot(select); Menus::BatteryInfo(); break; case 2: vlfGuiCancelCentralMenu(); Menus::SystemInfo(); + Menus::HandleScreenshot(select); break; case 3: vlfGuiCancelCentralMenu(); Menus::ConsoleIdInfo(); + Menus::HandleScreenshot(select); break; case 4: @@ -329,11 +343,7 @@ namespace Menus { } } -#if defined (__cplusplus) -extern "C" { -#endif - -int app_main(int argc, char *argv[]) { +extern "C" int app_main(int argc, char *argv[]) { sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, &language); SetupTranslate(); @@ -374,7 +384,3 @@ int app_main(int argc, char *argv[]) { return 0; } - -#if defined (__cplusplus) -} -#endif diff --git a/app/source/screenshot.cpp b/app/source/screenshot.cpp new file mode 100644 index 0000000..d2ae259 --- /dev/null +++ b/app/source/screenshot.cpp @@ -0,0 +1,140 @@ +#include +#include +#include +#include + +namespace Screenshot { + typedef struct __attribute__((packed)) { + char id[2]; + u32 file_size; + u32 reserved; + u32 offset; + u32 head_size; + u32 width; + u32 height; + u16 planes; + u16 bpp; + u32 comp; + u32 bitmap_size; + u32 hres; + u32 vres; + u32 colors; + u32 impcolors; + } BitmapHeader; + + static constexpr int SCREEN_WIDTH = 480; + static constexpr int SCREEN_HEIGHT = 272; + static constexpr u8 BYTES_PER_PIXEL = 3; + + int WriteFile(SceUID fd, void *data, u32 length) { + u32 bytes_written = 0; + + while(bytes_written < length) { + int ret = sceIoWrite(fd, static_cast(data) + bytes_written, length - bytes_written); + if (ret < 0) { + bytes_written = -1; + break; + } + + bytes_written += ret; + } + + return bytes_written; + } + + int WriteBitmap(void *frame_addr, void *tmp_buf, const char *file) { + BitmapHeader *bmp = { 0 }; + void *pixel_data = static_cast(tmp_buf) + sizeof(BitmapHeader); + u8 *line = nullptr, *p = nullptr; + SceUID fd = 0; + + bmp = static_cast(tmp_buf); + memset(bmp, 0, sizeof(BitmapHeader)); + memcpy(bmp->id, "BM", sizeof(bmp->id)); + bmp->file_size = SCREEN_WIDTH * SCREEN_HEIGHT * BYTES_PER_PIXEL + sizeof(BitmapHeader); + bmp->offset = sizeof(BitmapHeader); + bmp->head_size = 0x28; + bmp->width = SCREEN_WIDTH; + bmp->height = SCREEN_HEIGHT; + bmp->planes = 1; + bmp->bpp = 24; + bmp->bitmap_size = SCREEN_WIDTH * SCREEN_HEIGHT * BYTES_PER_PIXEL; + bmp->hres = 2834; + bmp->vres = 2834; + + line = static_cast(pixel_data); + + for(int h = SCREEN_HEIGHT - 1; h >= 0; h--) { + p = static_cast(frame_addr) + (h * 512 * 4); + + for(int i = 0; i < SCREEN_WIDTH; i++) { + line[(i * BYTES_PER_PIXEL) + 2] = p[i * 4]; + line[(i * BYTES_PER_PIXEL) + 1] = p[(i * 4) + 1]; + line[(i * BYTES_PER_PIXEL) + 0] = p[(i * 4) + 2]; + } + + line += SCREEN_WIDTH * BYTES_PER_PIXEL; + } + + fd = sceIoOpen(file, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777); + + if (fd >= 0) { + Screenshot::WriteFile(fd, tmp_buf, bmp->file_size); + sceIoClose(fd); + return 0; + } + + return -1; + } + + void Save(const char *path) { + void *framebuf = malloc(SCREEN_WIDTH * SCREEN_HEIGHT * BYTES_PER_PIXEL + sizeof(BitmapHeader)); + if (!framebuf) { + return; + } + + u32 *vram32 = nullptr; + sceDisplayWaitVblankStart(); + sceDisplayGetFrameBuf(reinterpret_cast(&vram32), nullptr, nullptr, 0); + Screenshot::WriteBitmap(vram32, framebuf, path); + free(framebuf); + } + + bool DirExists(const char *path) { + SceUID dir = sceIoDopen(path); + if (dir >= 0) { + sceIoDclose(dir); + return true; + } + + return false; + } + + void Capture(int menu) { + if (!Screenshot::DirExists("ms0:/PSP/PHOTO/")) { + sceIoMkdir("ms0:/PSP/PHOTO", 0777); + } + + if (!Screenshot::DirExists("ms0:/PSP/PHOTO/PSP-Everest/")) { + sceIoMkdir("ms0:/PSP/PHOTO/PSP-Everest", 0777); + } + + switch (menu) { + case 0: + Screenshot::Save("ms0:/PSP/PHOTO/PSP-Everest/hardware_info.bmp"); + break; + + case 1: + Screenshot::Save("ms0:/PSP/PHOTO/PSP-Everest/battery_info.bmp"); + break; + + case 2: + Screenshot::Save("ms0:/PSP/PHOTO/PSP-Everest/system_info.bmp"); + break; + + case 3: + Screenshot::Save("ms0:/PSP/PHOTO/PSP-Everest/consoleid_info.bmp"); + break; + } + } +} diff --git a/app/source/systeminfo.cpp b/app/source/systeminfo.cpp index 02887f4..65130e6 100644 --- a/app/source/systeminfo.cpp +++ b/app/source/systeminfo.cpp @@ -1,8 +1,7 @@ +#include +#include #include -#include #include -#include -#include #include "main.h" #include "utils.h" diff --git a/app/source/utils.cpp b/app/source/utils.cpp index 390b36d..4c48234 100644 --- a/app/source/utils.cpp +++ b/app/source/utils.cpp @@ -1,9 +1,8 @@ +#include #include #include #include #include -#include -#include #include "main.h" diff --git a/libs/include/vlf.h b/libs/include/vlf.h index cfd73b3..9e8eb0a 100644 --- a/libs/include/vlf.h +++ b/libs/include/vlf.h @@ -494,7 +494,7 @@ void vlfGuiSetTitleBarVisibility(int visible); * * @returns a VlfText item on success, NULL on error. */ -VlfText vlfGuiAddText(int x, int y, char *string); +VlfText vlfGuiAddText(int x, int y, const char *string); /** * Adds a new text item from an unicode string.