Skip to content
Permalink
Browse files
Changed screenshot capturing method
Now it's just reading the entire screen and doing all conversions on the GPU instead of just reading texture and processing it manually.
  • Loading branch information
ata4 committed Mar 6, 2018
1 parent 46b4059 commit 6af5b4c86d1d9cc24add3c5c3133cba1b3e89820
Showing with 23 additions and 55 deletions.
  1. +1 −1 core/screen.h
  2. +10 −24 plugin-common/gl_screen.c
  3. +1 −1 plugin-common/gl_screen.h
  4. +4 −20 plugin-mupen64plus/gfx_m64p.c
  5. +2 −2 plugin-mupen64plus/screen.c
  6. +3 −5 plugin-zilmar/gfx_1.3.c
  7. +2 −2 plugin-zilmar/screen.c
@@ -8,7 +8,7 @@
void screen_init(struct rdp_config* config);
void screen_swap(bool blank);
void screen_write(struct rdp_frame_buffer* fb, int32_t output_height);
void screen_read(struct rdp_frame_buffer* fb);
void screen_read(struct rdp_frame_buffer* fb, bool rgb);
void screen_set_fullscreen(bool fullscreen);
bool screen_get_fullscreen(void);
void screen_toggle_fullscreen(void);
@@ -184,33 +184,19 @@ bool gl_screen_write(struct rdp_frame_buffer* fb, int32_t output_height)
return buffer_size_changed;
}

void gl_screen_read(struct rdp_frame_buffer* fb)
void gl_screen_read(struct rdp_frame_buffer* fb, bool rgb)
{
fb->width = tex_width;
fb->height = tex_display_height;
fb->pitch = tex_width;
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);

if (!fb->pixels) {
return;
}

// check if resampling is required
if (tex_display_height == tex_height) {
// size matches, direct copy
glGetTexImage(GL_TEXTURE_2D, 0, TEX_FORMAT, TEX_TYPE, (void*)fb->pixels);
} else {
// do nearest-neighbor resampling
int32_t* tex_buffer = malloc(tex_width * tex_display_height * sizeof(int32_t));
glGetTexImage(GL_TEXTURE_2D, 0, TEX_FORMAT, TEX_TYPE, tex_buffer);

for (int32_t y = 0; y < tex_display_height; y++) {
int32_t iy = y * tex_height / tex_display_height;
uint32_t os = tex_width * iy;
uint32_t od = tex_width * y;
memcpy(fb->pixels + od, tex_buffer + os, tex_width * sizeof(int32_t));
}
fb->width = vp[2];
fb->height = vp[3];
fb->pitch = fb->width;

free(tex_buffer);
if (fb->pixels) {
GLenum format = rgb ? GL_RGB : TEX_FORMAT;
GLenum type = rgb ? GL_UNSIGNED_BYTE : TEX_TYPE;
glReadPixels(vp[0], vp[1], vp[2], vp[3], format, type, fb->pixels);
}
}

@@ -7,6 +7,6 @@

void gl_screen_init(struct rdp_config* config);
bool gl_screen_write(struct rdp_frame_buffer* fb, int32_t output_height);
void gl_screen_read(struct rdp_frame_buffer* fb);
void gl_screen_read(struct rdp_frame_buffer* fb, bool rgb);
void gl_screen_render(int32_t win_width, int32_t win_height, int32_t win_x, int32_t win_y);
void gl_screen_close(void);
@@ -224,31 +224,15 @@ EXPORT void CALL ChangeWindow(void)
EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)
{
struct rdp_frame_buffer fb = { 0 };
screen_read(&fb);
screen_read(&fb, true);

*width = fb.width;
*height = fb.height;

if (!dest) {
return;
if (dest) {
fb.pixels = dest;
screen_read(&fb, true);
}

// convert BGRA to RGB and also flip image vertically
fb.pixels = malloc(fb.width * fb.height * sizeof(int32_t));
screen_read(&fb);

uint8_t* pdst = (uint8_t*)dest;
for (int32_t y = fb.height - 1; y >= 0; y--) {
uint8_t* psrc = (uint8_t*)(fb.pixels + y * fb.width);
for (int32_t x = 0; x < (int32_t)fb.width; x++) {
*pdst++ = psrc[2];
*pdst++ = psrc[1];
*pdst++ = psrc[0];
psrc += 4;
}
}

free(fb.pixels);
}

EXPORT void CALL SetRenderingCallback(void (*callback)(int))
@@ -77,9 +77,9 @@ void screen_write(struct rdp_frame_buffer* buffer, int32_t output_height)
gl_screen_write(buffer, output_height);
}

void screen_read(struct rdp_frame_buffer* buffer)
void screen_read(struct rdp_frame_buffer* buffer, bool rgb)
{
gl_screen_read(buffer);
gl_screen_read(buffer, rgb);
}

void screen_set_fullscreen(bool _fullscreen)
@@ -19,7 +19,7 @@ GFX_INFO gfx;
static void write_screenshot(char* path)
{
struct rdp_frame_buffer fb = { 0 };
screen_read(&fb);
screen_read(&fb, false);

// prepare bitmap headers
BITMAPINFOHEADER ihdr = {0};
@@ -50,10 +50,8 @@ static void write_screenshot(char* path)
fseek(fp, fhdr.bfOffBits, SEEK_SET);

fb.pixels = malloc(ihdr.biSizeImage);
screen_read(&fb);
for (int32_t y = fb.height - 1; y >= 0; y--) {
fwrite(fb.pixels + fb.width * y, fb.width * sizeof(*fb.pixels), 1, fp);
}
screen_read(&fb, false);
fwrite(fb.pixels, ihdr.biSizeImage, 1, fp);
free(fb.pixels);

fclose(fp);
@@ -126,9 +126,9 @@ void screen_write(struct rdp_frame_buffer* buffer, int32_t output_height)
gl_screen_write(buffer, output_height);
}

void screen_read(struct rdp_frame_buffer* buffer)
void screen_read(struct rdp_frame_buffer* buffer, bool rgb)
{
gl_screen_read(buffer);
gl_screen_read(buffer, rgb);
}

void screen_swap(bool blank)

0 comments on commit 6af5b4c

Please sign in to comment.