diff --git a/arm9/source/common/hid.c b/arm9/source/common/hid.c index af67123..7360dfd 100644 --- a/arm9/source/common/hid.c +++ b/arm9/source/common/hid.c @@ -1,7 +1,8 @@ #include "hid.h" #include "i2c.h" #include "timer.h" -#include "power.h" +#include "power.h" // for brightness slider +#include "screenshot.h" // for screenshots u32 InputWait(u32 timeout_sec) { static u64 delay = 0; @@ -42,8 +43,11 @@ u32 InputWait(u32 timeout_sec) { // make sure the key is pressed u32 t_pressed = 0; 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; + } } } diff --git a/arm9/source/common/screenshot.c b/arm9/source/common/screenshot.c new file mode 100644 index 0000000..79cd1d2 --- /dev/null +++ b/arm9/source/common/screenshot.c @@ -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); +} diff --git a/arm9/source/common/screenshot.h b/arm9/source/common/screenshot.h new file mode 100644 index 0000000..b094f5c --- /dev/null +++ b/arm9/source/common/screenshot.h @@ -0,0 +1,3 @@ +#pragma once + +void CreateScreenshot(); diff --git a/arm9/source/filesys/fsutil.c b/arm9/source/filesys/fsutil.c index a1a4ee3..e75537e 100644 --- a/arm9/source/filesys/fsutil.c +++ b/arm9/source/filesys/fsutil.c @@ -851,41 +851,3 @@ bool FileSelector(char* result, const char* text, const char* path, const char* free(buffer); 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); -} diff --git a/arm9/source/filesys/fsutil.h b/arm9/source/filesys/fsutil.h index 34a48ae..8578f3a 100644 --- a/arm9/source/filesys/fsutil.h +++ b/arm9/source/filesys/fsutil.h @@ -85,6 +85,3 @@ bool PathAttr(const char* path, u8 attr, u8 mask); /** Select a file **/ bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags); - -/** Create a screenshot of the current framebuffer **/ -void CreateScreenshot(); diff --git a/arm9/source/godmode.c b/arm9/source/godmode.c index 493ea12..52b7671 100644 --- a/arm9/source/godmode.c +++ b/arm9/source/godmode.c @@ -434,7 +434,7 @@ u32 FileGraphicsViewer(const char* path) { ClearScreenF(true, true, COLOR_STD_BG); DrawBitmap(ALT_SCREEN, -1, -1, w, h, bitmap); ShowString("Press to continue"); - InputWait(0); + while(!(InputWait(0) & (BUTTON_A | BUTTON_B))); ClearScreenF(true, true, COLOR_STD_BG); } else ret = 1; @@ -639,8 +639,7 @@ u32 FileHexViewer(const char* path) { // handle user input u32 pad_state = InputWait(0); - if ((pad_state & BUTTON_R1) && (pad_state & BUTTON_L1)) CreateScreenshot(); - else if (!edit_mode) { // standard viewer mode + if (!edit_mode) { // standard viewer mode u32 step_ud = (pad_state & BUTTON_R1) ? (0x1000 - (0x1000 % cols)) : cols; u32 step_lr = (pad_state & BUTTON_R1) ? (0x10000 - (0x10000 % cols)) : total_shown; 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; mark_next = 0; } else if (switched && (pad_state & BUTTON_L1)) { // switched L -> screenshot - CreateScreenshot(); - ClearScreenF(true, true, COLOR_STD_BG); + // this is handled in hid.h } else if (*current_path && (pad_state & BUTTON_L1) && (curr_entry->type != T_DOTDOT)) { // unswitched L - mark/unmark single entry if (mark_next < -1) mark_next = -1; diff --git a/arm9/source/utils/gameutil.c b/arm9/source/utils/gameutil.c index 04992dc..8f0bc10 100644 --- a/arm9/source/utils/gameutil.c +++ b/arm9/source/utils/gameutil.c @@ -1684,7 +1684,7 @@ u32 ShowSmdhTitleInfo(Smdh* smdh) { WordWrapString(desc_s, lwrap); WordWrapString(pub, lwrap); 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); return 0; } @@ -1698,7 +1698,7 @@ u32 ShowTwlIconTitleInfo(TwlIconData* twl_icon) { return 1; WordWrapString(desc, lwrap); 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); return 0; } @@ -1708,7 +1708,7 @@ u32 ShowGbaFileTitleInfo(const char* path) { if ((fvx_qread(path, &agb, 0, sizeof(AgbHeader), NULL) != FR_OK) || (ValidateAgbHeader(&agb) != 0)) return 1; 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); return 0; diff --git a/arm9/source/utils/scripting.c b/arm9/source/utils/scripting.c index 49fce5a..033487b 100644 --- a/arm9/source/utils/scripting.c +++ b/arm9/source/utils/scripting.c @@ -1461,38 +1461,35 @@ bool MemTextViewer(const char* text, u32 len, u32 start, bool as_script) { // handle user input u32 pad_state = InputWait(0); - if ((pad_state & BUTTON_R1) && (pad_state & BUTTON_L1)) CreateScreenshot(); - else { // standard viewer mode - char* line0_next = line0; - u32 step_ud = (pad_state & BUTTON_R1) ? TV_NLIN_DISP : 1; - u32 step_lr = (pad_state & BUTTON_R1) ? TV_LLEN_DISP : 1; - bool switched = (pad_state & BUTTON_R1); - if (pad_state & BUTTON_DOWN) line0_next = line_seek(text, len, ww, line0, step_ud); - else if (pad_state & BUTTON_UP) line0_next = line_seek(text, len, ww, line0, -step_ud); - else if (pad_state & BUTTON_RIGHT) off_disp += step_lr; - else if (pad_state & BUTTON_LEFT) off_disp -= step_lr; - else if (switched && (pad_state & BUTTON_X)) { - u64 lnext64 = ShowNumberPrompt(lcurr, "Current line: %i\nEnter new line below.", lcurr); - if (lnext64 && (lnext64 != (u64) -1)) line0_next = line_seek(text, len, 0, line0, (int) lnext64 - lcurr); - ShowString(instr); - } else if (switched && (pad_state & BUTTON_Y)) { - ww = ww ? 0 : TV_LLEN_DISP; - line0_next = line_seek(text, len, ww, line0, 0); - } else if (pad_state & (BUTTON_B|BUTTON_START)) break; - - // check for problems, apply changes - if (!ww && (line0_next > llast_nww)) line0_next = llast_nww; - else if (ww && (line0_next > llast_ww)) line0_next = llast_ww; - if (line0_next < line0) { // fix line number for decrease - do if (*(--line0) == '\n') lcurr--; - while (line0 > line0_next); - } else { // fix line number for increase / same - for (; line0_next > line0; line0++) - if (*line0 == '\n') lcurr++; - } - if (off_disp + TV_LLEN_DISP > llen_max) off_disp = llen_max - TV_LLEN_DISP; - if ((off_disp < 0) || ww) off_disp = 0; + char* line0_next = line0; + u32 step_ud = (pad_state & BUTTON_R1) ? TV_NLIN_DISP : 1; + u32 step_lr = (pad_state & BUTTON_R1) ? TV_LLEN_DISP : 1; + bool switched = (pad_state & BUTTON_R1); + if (pad_state & BUTTON_DOWN) line0_next = line_seek(text, len, ww, line0, step_ud); + else if (pad_state & BUTTON_UP) line0_next = line_seek(text, len, ww, line0, -step_ud); + else if (pad_state & BUTTON_RIGHT) off_disp += step_lr; + else if (pad_state & BUTTON_LEFT) off_disp -= step_lr; + else if (switched && (pad_state & BUTTON_X)) { + u64 lnext64 = ShowNumberPrompt(lcurr, "Current line: %i\nEnter new line below.", lcurr); + if (lnext64 && (lnext64 != (u64) -1)) line0_next = line_seek(text, len, 0, line0, (int) lnext64 - lcurr); + ShowString(instr); + } else if (switched && (pad_state & BUTTON_Y)) { + ww = ww ? 0 : TV_LLEN_DISP; + line0_next = line_seek(text, len, ww, line0, 0); + } else if (pad_state & (BUTTON_B|BUTTON_START)) break; + + // check for problems, apply changes + if (!ww && (line0_next > llast_nww)) line0_next = llast_nww; + else if (ww && (line0_next > llast_ww)) line0_next = llast_ww; + if (line0_next < line0) { // fix line number for decrease + do if (*(--line0) == '\n') lcurr--; + while (line0 > line0_next); + } else { // fix line number for increase / same + for (; line0_next > line0; line0++) + if (*line0 == '\n') lcurr++; } + if (off_disp + TV_LLEN_DISP > llen_max) off_disp = llen_max - TV_LLEN_DISP; + if ((off_disp < 0) || ww) off_disp = 0; } // clear screens