Skip to content

Instantly share code, notes, and snippets.

@NickelMattera
Last active April 24, 2020 01:28
Show Gist options
  • Save NickelMattera/2a76b95ab41d647be8deb4125b45268b to your computer and use it in GitHub Desktop.
Save NickelMattera/2a76b95ab41d647be8deb4125b45268b to your computer and use it in GitHub Desktop.
#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