Last active
April 24, 2020 01:28
-
-
Save NickelMattera/2a76b95ab41d647be8deb4125b45268b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <switch.h> | |
#define INNER_HEAP_SIZE 0x80000 | |
extern "C" { | |
extern u32 __start__; | |
u32 __nx_applet_type = AppletType_None; | |
size_t nx_inner_heap_size = INNER_HEAP_SIZE; | |
char nx_inner_heap[INNER_HEAP_SIZE]; | |
void __libnx_initheap(void) | |
{ | |
void* addr = nx_inner_heap; | |
size_t size = nx_inner_heap_size; | |
extern char* fake_heap_start; | |
extern char* fake_heap_end; | |
fake_heap_start = (char*)addr; | |
fake_heap_end = (char*)addr + size; | |
} | |
void __attribute__((weak)) __appInit(void) | |
{ | |
Result rc; | |
rc = smInitialize(); | |
if (R_FAILED(rc)) | |
fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM)); | |
rc = capsscInitialize(); | |
if (R_FAILED(rc)) | |
fatalThrow(0xFEE15BAD); | |
rc = fsInitialize(); | |
if (R_FAILED(rc)) | |
fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS)); | |
rc = hiddbgInitialize(); | |
if (R_FAILED(rc)) | |
fatalThrow(MAKERESULT(Module_Libnx, LibnxError_InitFail_HID)); | |
fsdevMountSdmc(); | |
} | |
void __attribute__((weak)) userAppExit(void); | |
void __attribute__((weak)) __appExit(void) | |
{ | |
hiddbgExit(); | |
fsdevUnmountAll(); | |
fsExit(); | |
capsscExit(); | |
smExit(); | |
} | |
} | |
Result capsscOpenRawScreenShotReadStream(u64 *out_size, u64 *out_width, u64 *out_height, ViLayerStack layer_stack, u64 timeout) { | |
const struct { | |
ViLayerStack layer_stack; | |
u64 timeout; | |
} in = {layer_stack, timeout}; | |
struct { | |
u64 size; | |
u64 width; | |
u64 height; | |
} out; | |
Result rc = serviceDispatchInOut(capsscGetServiceSession(), 1201, in, out); | |
if (R_SUCCEEDED(rc)) { | |
if (out_size) | |
*out_size = out.size; | |
if (out_width) | |
*out_width = out.width; | |
if (out_height) | |
*out_height = out.height; | |
} | |
return rc; | |
} | |
Result capsscCloseRawScreenShotReadStream() { | |
return serviceDispatch(capsscGetServiceSession(), 1202); | |
} | |
Result capsscReadRawScreenShotReadStream(u64 offset, u64 *bytes_read, void *buffer, size_t buffer_size) { | |
return serviceDispatchInOut(capsscGetServiceSession(), 1203, offset, *bytes_read, | |
.buffer_attrs = {SfBufferAttr_Out | SfBufferAttr_HipcMapAlias}, | |
.buffers = {{buffer, buffer_size}}, ); | |
} | |
struct bmp_t { | |
u16 magic; | |
u32 size; | |
u32 rsvd; | |
u32 data_off; | |
u32 hdr_size; | |
u32 width; | |
u32 height; | |
u16 planes; | |
u16 pxl_bits; | |
u32 comp; | |
u32 img_size; | |
u32 res_h; | |
u32 res_v; | |
u64 rsvd2; | |
} __attribute__((packed)); | |
constexpr const u64 divider = 40; | |
int main(int argc, char * argv[]) { | |
u64 width = 0; | |
u64 height = 0; | |
HiddbgHdlsStateList hdlStates; | |
while(true) { | |
Result rc; | |
rc = hiddbgDumpHdlsStates(&hdlStates); | |
if (R_FAILED(rc)) | |
continue; | |
bool captured = false; | |
for (int i = 0; i < hdlStates.total_entries; i++) { | |
if (hdlStates.entries[i].state.buttons & KEY_CAPTURE) { | |
captured = true; | |
break; | |
} | |
} | |
if (!captured) { | |
continue; | |
} | |
rc = capsscOpenRawScreenShotReadStream(nullptr, &width, &height, ViLayerStack_Default, 100000000); | |
if (R_FAILED(rc)) | |
continue; | |
u32 inLineSize = width * 4; | |
u32 outLineSize = width * 3; | |
u32 outSize = outLineSize * height; | |
u32 fileSize = outSize + 0x36; | |
u32 inBufferSize = inLineSize * divider; | |
u32 outBufferSize = outLineSize * divider; | |
u8 in_buffer[inBufferSize]; | |
u8 out_buffer[outBufferSize]; | |
char filename[0x20]; | |
u64 tick = armGetSystemTick(); | |
snprintf(filename, 0x20, "/%ld.bmp", tick); | |
FILE * output = fopen(filename, "w+a"); | |
if (output == nullptr) { | |
continue; | |
} | |
bmp_t bmp = { | |
.magic = 0x4D42, | |
.size = fileSize, | |
.rsvd = 0, | |
.data_off = 0x36, | |
.hdr_size = 40, | |
.width = (u32) width, | |
.height = (u32) height, | |
.planes = 1, | |
.pxl_bits = 24, | |
.comp = 0, | |
.img_size = outSize, | |
.res_h = 2834, | |
.res_v = 2834, | |
.rsvd2 = 0, | |
}; | |
fwrite(&bmp, 54, 1, output); | |
rc = 0; | |
u64 written = 0; | |
for (int y = (height / divider) - 1; y >= 0; y--) { | |
rc = capsscReadRawScreenShotReadStream(y * sizeof(in_buffer), &written, in_buffer, sizeof(in_buffer)); | |
if (R_FAILED(rc)) | |
break; | |
for (int div_y = (divider - 1); div_y >= 0; div_y--) { | |
u8 *out = out_buffer + (div_y * outLineSize); | |
u8 *in = in_buffer + ((divider - div_y - 1) * inLineSize); | |
for (u32 x = 0; x < width; x++) { | |
out[0] = in[2]; | |
out[1] = in[1]; | |
out[2] = in[0]; | |
in += 4; | |
out += 3; | |
} | |
} | |
fwrite(out_buffer, 1, sizeof(out_buffer), output); | |
} | |
capsscCloseRawScreenShotReadStream(); | |
fflush(output); | |
fclose(output); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment