mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +00:00
Save screenshots as PNGs.
This commit is contained in:
parent
19209918a7
commit
c6e3c0ee30
@ -2,42 +2,54 @@
|
|||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "vff.h"
|
#include "vff.h"
|
||||||
|
#include "png.h"
|
||||||
|
|
||||||
|
|
||||||
void CreateScreenshot() {
|
void CreateScreenshot() {
|
||||||
const u32 snap_size = 54 + (SCREEN_SIZE_TOP * 2);
|
const u32 snap_size = SCREEN_SIZE_TOP * 2, snap_width = SCREEN_WIDTH_TOP, snap_height = SCREEN_HEIGHT * 2;
|
||||||
const u8 bmp_header[54] = {
|
u8 *png_data = NULL;
|
||||||
0x42, 0x4D, 0x36, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
|
size_t png_size;
|
||||||
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];
|
char filename[64];
|
||||||
DsTime dstime;
|
DsTime dstime;
|
||||||
|
|
||||||
fvx_rmkdir(OUTPUT_PATH);
|
fvx_rmkdir(OUTPUT_PATH);
|
||||||
get_dstime(&dstime);
|
get_dstime(&dstime);
|
||||||
snprintf(filename, 64, OUTPUT_PATH "/snap_%02X%02X%02X%02X%02X%02X.bmp",
|
snprintf(filename, 64, OUTPUT_PATH "/snap_%02X%02X%02X%02X%02X%02X.png",
|
||||||
dstime.bcd_Y, dstime.bcd_M, dstime.bcd_D,
|
dstime.bcd_Y, dstime.bcd_M, dstime.bcd_D,
|
||||||
dstime.bcd_h, dstime.bcd_m, dstime.bcd_s);
|
dstime.bcd_h, dstime.bcd_m, dstime.bcd_s);
|
||||||
|
|
||||||
u8* buffer = (u8*) malloc(snap_size);
|
u8* buffer = (u8*) malloc(snap_size);
|
||||||
if (!buffer) return;
|
if (!buffer) return;
|
||||||
|
|
||||||
u8* buffer_b = buffer + 54;
|
u8* buffer_t = buffer;
|
||||||
u8* buffer_t = buffer_b + (400 * 240 * 3);
|
u8* buffer_b = buffer + SCREEN_SIZE_TOP;
|
||||||
|
|
||||||
memset(buffer, 0x1F, snap_size); // gray background
|
memset(buffer, 0x1F, snap_size); // gray background
|
||||||
memcpy(buffer, bmp_header, 54);
|
|
||||||
for (u32 x = 0; x < 400; x++)
|
for (u32 x = 0; x < 400; x++) {
|
||||||
for (u32 y = 0; y < 240; y++)
|
for (u32 y = 0; y < 240; y++) {
|
||||||
memcpy(buffer_t + (y*400 + x) * 3, TOP_SCREEN + (x*240 + y) * 3, 3);
|
buffer_t[(y * SCREEN_WIDTH_TOP + x) * 3 + 0] = *(TOP_SCREEN + (((x * 240) + (239 - y)) * 3) + 2);
|
||||||
for (u32 x = 0; x < 320; x++)
|
buffer_t[(y * SCREEN_WIDTH_TOP + x) * 3 + 1] = *(TOP_SCREEN + (((x * 240) + (239 - y)) * 3) + 1);
|
||||||
for (u32 y = 0; y < 240; y++)
|
buffer_t[(y * SCREEN_WIDTH_TOP + x) * 3 + 2] = *(TOP_SCREEN + (((x * 240) + (239 - y)) * 3) + 0);
|
||||||
memcpy(buffer_b + (y*400 + x + 40) * 3, BOT_SCREEN + (x*240 + y) * 3, 3);
|
}
|
||||||
fvx_qwrite(filename, buffer, 0, snap_size, NULL);
|
}
|
||||||
|
|
||||||
|
for (u32 x = 0; x < 320; x++) {
|
||||||
|
for (u32 y = 0; y < 240; y++) {
|
||||||
|
buffer_b[(y * SCREEN_WIDTH_TOP + x + 40) * 3 + 0] = *(BOT_SCREEN + (((x * 240) + (239 - y)) * 3) + 2);
|
||||||
|
buffer_b[(y * SCREEN_WIDTH_TOP + x + 40) * 3 + 1] = *(BOT_SCREEN + (((x * 240) + (239 - y)) * 3) + 1);
|
||||||
|
buffer_b[(y * SCREEN_WIDTH_TOP + x + 40) * 3 + 2] = *(BOT_SCREEN + (((x * 240) + (239 - y)) * 3) + 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
png_data = PNG_Compress(buffer, snap_width, snap_height, &png_size);
|
||||||
|
|
||||||
|
if (png_data && png_size)
|
||||||
|
fvx_qwrite(filename, png_data, 0, png_size, NULL);
|
||||||
|
else
|
||||||
|
ShowPrompt(false, "Failed to write screenshot!");
|
||||||
|
|
||||||
// "snap effect"
|
// "snap effect"
|
||||||
memcpy(buffer_b, BOT_SCREEN, SCREEN_SIZE_BOT);
|
memcpy(buffer_b, BOT_SCREEN, SCREEN_SIZE_BOT);
|
||||||
memcpy(buffer_t, TOP_SCREEN, SCREEN_SIZE_TOP);
|
memcpy(buffer_t, TOP_SCREEN, SCREEN_SIZE_TOP);
|
||||||
@ -45,6 +57,7 @@ void CreateScreenshot() {
|
|||||||
memset(TOP_SCREEN, 0, SCREEN_SIZE_TOP);
|
memset(TOP_SCREEN, 0, SCREEN_SIZE_TOP);
|
||||||
memcpy(BOT_SCREEN, buffer_b, SCREEN_SIZE_BOT);
|
memcpy(BOT_SCREEN, buffer_b, SCREEN_SIZE_BOT);
|
||||||
memcpy(TOP_SCREEN, buffer_t, SCREEN_SIZE_TOP);
|
memcpy(TOP_SCREEN, buffer_t, SCREEN_SIZE_TOP);
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
if (png_data) free(png_data);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,16 @@
|
|||||||
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
||||||
|
static inline void _rgb_swap(u8 *img, size_t sz)
|
||||||
|
{
|
||||||
|
// maybe process in batches of 3 pixels / 12 bytes at a time?
|
||||||
|
for (size_t i = 0; i < sz; i+=3) {
|
||||||
|
u8 c = img[i];
|
||||||
|
img[i] = img[i + 2];
|
||||||
|
img[i + 2] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u8 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h)
|
u8 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h)
|
||||||
{
|
{
|
||||||
u8 *img;
|
u8 *img;
|
||||||
@ -13,18 +23,29 @@ u8 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h)
|
|||||||
size_t w_, h_;
|
size_t w_, h_;
|
||||||
|
|
||||||
res = lodepng_decode24(&img, &w_, &h_, png, png_len);
|
res = lodepng_decode24(&img, &w_, &h_, png, png_len);
|
||||||
if (res)
|
if (res) {
|
||||||
|
if (img) free(img);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// maybe process in batches of 3 pixels / 12 bytes at a time?
|
|
||||||
for (size_t i = 0; i < (w_ * h_ * 3); i += 3) {
|
|
||||||
u8 c = img[i];
|
|
||||||
img[i] = img[i + 2];
|
|
||||||
img[i + 2] = c;
|
|
||||||
}
|
}
|
||||||
|
_rgb_swap(img, w_ * h_ * 3);
|
||||||
if (w) *w = w_;
|
if (w) *w = w_;
|
||||||
if (h) *h = h_;
|
if (h) *h = h_;
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 *PNG_Compress(u8 *fb, u32 w, u32 h, size_t *png_sz)
|
||||||
|
{
|
||||||
|
u32 res;
|
||||||
|
size_t png_size;
|
||||||
|
u8 *img;
|
||||||
|
|
||||||
|
res = lodepng_encode24(&img, &png_size, fb, w, h);
|
||||||
|
if (res) {
|
||||||
|
if (img) free(img);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (png_sz) *png_sz = png_size;
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
@ -7,3 +7,4 @@
|
|||||||
#define PNG_MAGIC 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
|
#define PNG_MAGIC 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
|
||||||
|
|
||||||
u8 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h);
|
u8 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h);
|
||||||
|
u8 *PNG_Compress(u8 *fb, u32 w, u32 h, size_t *png_sz);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user