mirror of
https://github.com/xtreme8000/CavEX.git
synced 2025-01-22 09:11:55 -05:00
Screenshot feature
This commit is contained in:
parent
0ab2fe2a0f
commit
0da0139fce
8 changed files with 103 additions and 4 deletions
|
@ -21,6 +21,7 @@
|
||||||
"gui_left": [2, 202],
|
"gui_left": [2, 202],
|
||||||
"gui_right": [3, 203],
|
"gui_right": [3, 203],
|
||||||
"gui_click": [4, 204],
|
"gui_click": [4, 204],
|
||||||
"gui_click_alt": [5, 205]
|
"gui_click_alt": [5, 205],
|
||||||
|
"screenshot": [7],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"gui_left": [65],
|
"gui_left": [65],
|
||||||
"gui_right": [68],
|
"gui_right": [68],
|
||||||
"gui_click": [1000],
|
"gui_click": [1000],
|
||||||
"gui_click_alt": [1001]
|
"gui_click_alt": [1001],
|
||||||
|
"screenshot": [291]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef PLATFORM_WII
|
#ifdef PLATFORM_WII
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
|
@ -42,10 +43,9 @@
|
||||||
|
|
||||||
#include "cNBT/nbt.h"
|
#include "cNBT/nbt.h"
|
||||||
#include "cglm/cglm.h"
|
#include "cglm/cglm.h"
|
||||||
|
#include "lodepng/lodepng.h"
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
time_reset();
|
|
||||||
|
|
||||||
gstate.quit = false;
|
gstate.quit = false;
|
||||||
gstate.camera = (struct camera) {
|
gstate.camera = (struct camera) {
|
||||||
.x = 0, .y = 0, .z = 0, .rx = 0, .ry = 0, .controller = {0, 0, 0}};
|
.x = 0, .y = 0, .z = 0, .rx = 0, .ry = 0, .controller = {0, 0, 0}};
|
||||||
|
@ -183,6 +183,23 @@ int main(void) {
|
||||||
gstate.current_screen->render2D(gstate.current_screen, gfx_width(),
|
gstate.current_screen->render2D(gstate.current_screen, gfx_width(),
|
||||||
gfx_height());
|
gfx_height());
|
||||||
|
|
||||||
|
if(input_pressed(IB_SCREENSHOT)) {
|
||||||
|
size_t width, height;
|
||||||
|
gfx_copy_framebuffer(NULL, &width, &height);
|
||||||
|
|
||||||
|
void* image = malloc(width * height * 4);
|
||||||
|
|
||||||
|
if(image) {
|
||||||
|
gfx_copy_framebuffer(image, &width, &height);
|
||||||
|
|
||||||
|
char name[64];
|
||||||
|
snprintf(name, sizeof(name), "%ld.png", (long)time(NULL));
|
||||||
|
|
||||||
|
lodepng_encode32_file(name, image, width, height);
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
input_poll();
|
input_poll();
|
||||||
gfx_finish(true);
|
gfx_finish(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@ void gfx_clear_buffers(uint8_t r, uint8_t g, uint8_t b);
|
||||||
int gfx_width(void);
|
int gfx_width(void);
|
||||||
int gfx_height(void);
|
int gfx_height(void);
|
||||||
|
|
||||||
|
void gfx_copy_framebuffer(uint8_t* dest, size_t* width, size_t* height);
|
||||||
|
|
||||||
void gfx_matrix_projection(mat4 proj, bool is_perspective);
|
void gfx_matrix_projection(mat4 proj, bool is_perspective);
|
||||||
void gfx_matrix_modelview(mat4 mv);
|
void gfx_matrix_modelview(mat4 mv);
|
||||||
void gfx_matrix_texture(bool enable, mat4 tex);
|
void gfx_matrix_texture(bool enable, mat4 tex);
|
||||||
|
|
|
@ -303,6 +303,7 @@ static const char* input_config_translate(enum input_button key) {
|
||||||
case IB_GUI_RIGHT: return "input.gui_right";
|
case IB_GUI_RIGHT: return "input.gui_right";
|
||||||
case IB_GUI_CLICK: return "input.gui_click";
|
case IB_GUI_CLICK: return "input.gui_click";
|
||||||
case IB_GUI_CLICK_ALT: return "input.gui_click_alt";
|
case IB_GUI_CLICK_ALT: return "input.gui_click_alt";
|
||||||
|
case IB_SCREENSHOT: return "input.screenshot";
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ enum input_button {
|
||||||
IB_GUI_RIGHT,
|
IB_GUI_RIGHT,
|
||||||
IB_GUI_CLICK,
|
IB_GUI_CLICK,
|
||||||
IB_GUI_CLICK_ALT,
|
IB_GUI_CLICK_ALT,
|
||||||
|
IB_SCREENSHOT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum input_category {
|
enum input_category {
|
||||||
|
|
|
@ -206,6 +206,33 @@ void gfx_bind_texture(struct tex_gfx* tex) {
|
||||||
tex_gfx_bind(tex, 0);
|
tex_gfx_bind(tex, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gfx_copy_framebuffer(uint8_t* dest, size_t* width, size_t* height) {
|
||||||
|
assert(width && height);
|
||||||
|
|
||||||
|
*width = gfx_width();
|
||||||
|
*height = gfx_height();
|
||||||
|
|
||||||
|
if(!dest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
void* tmp = malloc(*width * 4);
|
||||||
|
|
||||||
|
if(!tmp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glReadPixels(0, 0, *width, *height, GL_RGBA, GL_UNSIGNED_BYTE, dest);
|
||||||
|
|
||||||
|
// flip image
|
||||||
|
for(size_t y = 0; y < *height / 2; y++) {
|
||||||
|
memcpy(tmp, dest + y * (*width) * 4, *width * 4);
|
||||||
|
memcpy(dest + y * (*width) * 4, dest + (*height - 1 - y) * (*width) * 4,
|
||||||
|
*width * 4);
|
||||||
|
memcpy(dest + (*height - 1 - y) * (*width) * 4, tmp, *width * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
void gfx_mode_world() {
|
void gfx_mode_world() {
|
||||||
gfx_write_buffers(true, true, true);
|
gfx_write_buffers(true, true, true);
|
||||||
gfx_matrix_texture(false, NULL);
|
gfx_matrix_texture(false, NULL);
|
||||||
|
|
|
@ -252,6 +252,55 @@ void gfx_bind_texture(struct tex_gfx* tex) {
|
||||||
tex_gfx_bind(tex, GX_TEXMAP0);
|
tex_gfx_bind(tex, GX_TEXMAP0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gfx_copy_framebuffer(uint8_t* dest, size_t* width, size_t* height) {
|
||||||
|
assert(width && height);
|
||||||
|
|
||||||
|
*width = screenMode->fbWidth;
|
||||||
|
*height = screenMode->efbHeight;
|
||||||
|
|
||||||
|
if(!dest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t length
|
||||||
|
= GX_GetTexBufferSize(*width, *height, GX_TF_RGBA8, GX_FALSE, 0);
|
||||||
|
uint8_t* buffer = memalign(32, length);
|
||||||
|
|
||||||
|
if(!buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GX_SetTexCopySrc(0, 0, *width, *height);
|
||||||
|
GX_SetTexCopyDst(*width, *height, GX_TF_RGBA8, GX_FALSE);
|
||||||
|
GX_CopyTex(buffer, GX_FALSE);
|
||||||
|
GX_PixModeSync();
|
||||||
|
GX_SetDrawDone();
|
||||||
|
DCInvalidateRange(buffer, length);
|
||||||
|
GX_WaitDrawDone();
|
||||||
|
|
||||||
|
uint8_t* src = buffer;
|
||||||
|
|
||||||
|
for(size_t y = 0; y < *height; y += 4) {
|
||||||
|
for(size_t x = 0; x < *width; x += 4) {
|
||||||
|
for(size_t by = 0; by < 4; by++) {
|
||||||
|
for(size_t bx = 0; bx < 4; bx++) {
|
||||||
|
uint8_t* col = dest + (x + bx + (y + by) * (*width)) * 4;
|
||||||
|
col[3] = *(src++);
|
||||||
|
col[0] = *(src++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t by = 0; by < 4; by++) {
|
||||||
|
for(size_t bx = 0; bx < 4; bx++) {
|
||||||
|
uint8_t* col = dest + (x + bx + (y + by) * (*width)) * 4;
|
||||||
|
col[1] = *(src++);
|
||||||
|
col[2] = *(src++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
void gfx_mode_world() {
|
void gfx_mode_world() {
|
||||||
gfx_write_buffers(true, true, true);
|
gfx_write_buffers(true, true, true);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue