Allow screenshots (almost) everywhere

This commit is contained in:
d0k3 2018-03-07 01:15:12 +01:00
parent 0ddb5c49d5
commit 67e19ad574
8 changed files with 93 additions and 82 deletions

View File

@ -1,7 +1,8 @@
#include "hid.h" #include "hid.h"
#include "i2c.h" #include "i2c.h"
#include "timer.h" #include "timer.h"
#include "power.h" #include "power.h" // for brightness slider
#include "screenshot.h" // for screenshots
u32 InputWait(u32 timeout_sec) { u32 InputWait(u32 timeout_sec) {
static u64 delay = 0; static u64 delay = 0;
@ -42,9 +43,12 @@ u32 InputWait(u32 timeout_sec) {
// make sure the key is pressed // make sure the key is pressed
u32 t_pressed = 0; u32 t_pressed = 0;
for(; (t_pressed < 0x13000) && (pad_state == HID_STATE); t_pressed++); for(; (t_pressed < 0x13000) && (pad_state == HID_STATE); t_pressed++);
if (t_pressed >= 0x13000) if (t_pressed >= 0x13000) {
if ((pad_state & BUTTON_ANY) == (BUTTON_R1 | BUTTON_L1))
CreateScreenshot(); // screenshot handling
return pad_state; return pad_state;
} }
}
} }
bool CheckButton(u32 button) { bool CheckButton(u32 button) {

View File

@ -0,0 +1,50 @@
#include "common.h"
#include "ui.h"
#include "vff.h"
void CreateScreenshot() {
const u32 snap_size = 54 + (SCREEN_SIZE_TOP * 2);
const u8 bmp_header[54] = {
0x42, 0x4D, 0x36, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCA, 0x08, 0x00, 0x12, 0x0B, 0x00, 0x00, 0x12, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char filename[64];
static u32 n = 0;
fvx_rmkdir(OUTPUT_PATH);
for (; n < 1000; n++) {
snprintf(filename, 64, OUTPUT_PATH "/snap%03i.bmp", (int) n);
if (fvx_stat(filename, NULL) != FR_OK) break;
}
if (n >= 1000) return;
u8* buffer = (u8*) malloc(snap_size);
if (!buffer) return;
u8* buffer_b = buffer + 54;
u8* buffer_t = buffer_b + (400 * 240 * 3);
memset(buffer, 0x1F, snap_size); // gray background
memcpy(buffer, bmp_header, 54);
for (u32 x = 0; x < 400; x++)
for (u32 y = 0; y < 240; y++)
memcpy(buffer_t + (y*400 + x) * 3, TOP_SCREEN + (x*240 + y) * 3, 3);
for (u32 x = 0; x < 320; x++)
for (u32 y = 0; y < 240; y++)
memcpy(buffer_b + (y*400 + x + 40) * 3, BOT_SCREEN + (x*240 + y) * 3, 3);
fvx_qwrite(filename, buffer, 0, snap_size, NULL);
// "snap effect"
memcpy(buffer_b, BOT_SCREEN, SCREEN_SIZE_BOT);
memcpy(buffer_t, TOP_SCREEN, SCREEN_SIZE_TOP);
memset(BOT_SCREEN, 0, SCREEN_SIZE_BOT);
memset(TOP_SCREEN, 0, SCREEN_SIZE_TOP);
memcpy(BOT_SCREEN, buffer_b, SCREEN_SIZE_BOT);
memcpy(TOP_SCREEN, buffer_t, SCREEN_SIZE_TOP);
free(buffer);
}

View File

@ -0,0 +1,3 @@
#pragma once
void CreateScreenshot();

View File

@ -851,41 +851,3 @@ bool FileSelector(char* result, const char* text, const char* path, const char*
free(buffer); free(buffer);
return ret; return ret;
} }
void CreateScreenshot() {
const u32 snap_size = 54 + (400 * 240 * 3 * 2);
const u8 bmp_header[54] = {
0x42, 0x4D, 0x36, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCA, 0x08, 0x00, 0x12, 0x0B, 0x00, 0x00, 0x12, 0x0B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char filename[64];
static u32 n = 0;
fvx_rmkdir(OUTPUT_PATH);
for (; n < 1000; n++) {
snprintf(filename, 64, OUTPUT_PATH "/snap%03i.bmp", (int) n);
if (fa_stat(filename, NULL) != FR_OK) break;
}
if (n >= 1000) return;
u8* buffer = (u8*) malloc(snap_size);
if (!buffer) return;
u8* buffer_b = buffer + 54;
u8* buffer_t = buffer_b + (400 * 240 * 3);
memset(buffer, 0x1F, snap_size); // gray background
memcpy(buffer, bmp_header, 54);
for (u32 x = 0; x < 400; x++)
for (u32 y = 0; y < 240; y++)
memcpy(buffer_t + (y*400 + x) * 3, TOP_SCREEN + (x*240 + y) * 3, 3);
for (u32 x = 0; x < 320; x++)
for (u32 y = 0; y < 240; y++)
memcpy(buffer_b + (y*400 + x + 40) * 3, BOT_SCREEN + (x*240 + y) * 3, 3);
FileSetData(filename, buffer, snap_size, 0, true);
free(buffer);
}

View File

@ -85,6 +85,3 @@ bool PathAttr(const char* path, u8 attr, u8 mask);
/** Select a file **/ /** Select a file **/
bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags); bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags);
/** Create a screenshot of the current framebuffer **/
void CreateScreenshot();

View File

@ -434,7 +434,7 @@ u32 FileGraphicsViewer(const char* path) {
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
DrawBitmap(ALT_SCREEN, -1, -1, w, h, bitmap); DrawBitmap(ALT_SCREEN, -1, -1, w, h, bitmap);
ShowString("Press <A> to continue"); ShowString("Press <A> to continue");
InputWait(0); while(!(InputWait(0) & (BUTTON_A | BUTTON_B)));
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
} else ret = 1; } else ret = 1;
@ -639,8 +639,7 @@ u32 FileHexViewer(const char* path) {
// handle user input // handle user input
u32 pad_state = InputWait(0); u32 pad_state = InputWait(0);
if ((pad_state & BUTTON_R1) && (pad_state & BUTTON_L1)) CreateScreenshot(); if (!edit_mode) { // standard viewer mode
else if (!edit_mode) { // standard viewer mode
u32 step_ud = (pad_state & BUTTON_R1) ? (0x1000 - (0x1000 % cols)) : cols; u32 step_ud = (pad_state & BUTTON_R1) ? (0x1000 - (0x1000 % cols)) : cols;
u32 step_lr = (pad_state & BUTTON_R1) ? (0x10000 - (0x10000 % cols)) : total_shown; u32 step_lr = (pad_state & BUTTON_R1) ? (0x10000 - (0x10000 % cols)) : total_shown;
if (pad_state & BUTTON_DOWN) offset += step_ud; if (pad_state & BUTTON_DOWN) offset += step_ud;
@ -2244,8 +2243,7 @@ u32 GodMode(int entrypoint) {
for (u32 c = 1; c < current_dir->n_entries; c++) current_dir->entry[c].marked = 0; for (u32 c = 1; c < current_dir->n_entries; c++) current_dir->entry[c].marked = 0;
mark_next = 0; mark_next = 0;
} else if (switched && (pad_state & BUTTON_L1)) { // switched L -> screenshot } else if (switched && (pad_state & BUTTON_L1)) { // switched L -> screenshot
CreateScreenshot(); // this is handled in hid.h
ClearScreenF(true, true, COLOR_STD_BG);
} else if (*current_path && (pad_state & BUTTON_L1) && (curr_entry->type != T_DOTDOT)) { } else if (*current_path && (pad_state & BUTTON_L1) && (curr_entry->type != T_DOTDOT)) {
// unswitched L - mark/unmark single entry // unswitched L - mark/unmark single entry
if (mark_next < -1) mark_next = -1; if (mark_next < -1) mark_next = -1;

View File

@ -1684,7 +1684,7 @@ u32 ShowSmdhTitleInfo(Smdh* smdh) {
WordWrapString(desc_s, lwrap); WordWrapString(desc_s, lwrap);
WordWrapString(pub, lwrap); WordWrapString(pub, lwrap);
ShowIconString(icon, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG, "%s\n%s\n%s", desc_l, desc_s, pub); ShowIconString(icon, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG, "%s\n%s\n%s", desc_l, desc_s, pub);
InputWait(0); while(!(InputWait(0) & (BUTTON_A | BUTTON_B)));
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, false, COLOR_STD_BG);
return 0; return 0;
} }
@ -1698,7 +1698,7 @@ u32 ShowTwlIconTitleInfo(TwlIconData* twl_icon) {
return 1; return 1;
WordWrapString(desc, lwrap); WordWrapString(desc, lwrap);
ShowIconString(icon, TWLICON_DIM_ICON, TWLICON_DIM_ICON, "%s", desc); ShowIconString(icon, TWLICON_DIM_ICON, TWLICON_DIM_ICON, "%s", desc);
InputWait(0); while(!(InputWait(0) & (BUTTON_A | BUTTON_B)));
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, false, COLOR_STD_BG);
return 0; return 0;
} }
@ -1708,7 +1708,7 @@ u32 ShowGbaFileTitleInfo(const char* path) {
if ((fvx_qread(path, &agb, 0, sizeof(AgbHeader), NULL) != FR_OK) || if ((fvx_qread(path, &agb, 0, sizeof(AgbHeader), NULL) != FR_OK) ||
(ValidateAgbHeader(&agb) != 0)) return 1; (ValidateAgbHeader(&agb) != 0)) return 1;
ShowString("%.12s (AGB-%.4s)\n%s", agb.game_title, agb.game_code, AGB_DESTSTR(agb.game_code)); ShowString("%.12s (AGB-%.4s)\n%s", agb.game_title, agb.game_code, AGB_DESTSTR(agb.game_code));
InputWait(0); while(!(InputWait(0) & (BUTTON_A | BUTTON_B)));
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, false, COLOR_STD_BG);
return 0; return 0;

View File

@ -1461,8 +1461,6 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) {
// handle user input // handle user input
u32 pad_state = InputWait(0); u32 pad_state = InputWait(0);
if ((pad_state & BUTTON_R1) && (pad_state & BUTTON_L1)) CreateScreenshot();
else { // standard viewer mode
char* line0_next = line0; char* line0_next = line0;
u32 step_ud = (pad_state & BUTTON_R1) ? TV_NLIN_DISP : 1; u32 step_ud = (pad_state & BUTTON_R1) ? TV_NLIN_DISP : 1;
u32 step_lr = (pad_state & BUTTON_R1) ? TV_LLEN_DISP : 1; u32 step_lr = (pad_state & BUTTON_R1) ? TV_LLEN_DISP : 1;
@ -1493,7 +1491,6 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) {
if (off_disp + TV_LLEN_DISP > llen_max) off_disp = llen_max - TV_LLEN_DISP; if (off_disp + TV_LLEN_DISP > llen_max) off_disp = llen_max - TV_LLEN_DISP;
if ((off_disp < 0) || ww) off_disp = 0; if ((off_disp < 0) || ww) off_disp = 0;
} }
}
// clear screens // clear screens
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);