diff --git a/core/screen.h b/core/screen.h index 533167f..2f59aee 100644 --- a/core/screen.h +++ b/core/screen.h @@ -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); diff --git a/plugin-common/gl_screen.c b/plugin-common/gl_screen.c index f3fc725..90aa320 100644 --- a/plugin-common/gl_screen.c +++ b/plugin-common/gl_screen.c @@ -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); } } diff --git a/plugin-common/gl_screen.h b/plugin-common/gl_screen.h index 2c20254..94d7283 100644 --- a/plugin-common/gl_screen.h +++ b/plugin-common/gl_screen.h @@ -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); diff --git a/plugin-mupen64plus/gfx_m64p.c b/plugin-mupen64plus/gfx_m64p.c index a4cf876..739f9ae 100644 --- a/plugin-mupen64plus/gfx_m64p.c +++ b/plugin-mupen64plus/gfx_m64p.c @@ -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)) diff --git a/plugin-mupen64plus/screen.c b/plugin-mupen64plus/screen.c index 94528b2..6632f65 100644 --- a/plugin-mupen64plus/screen.c +++ b/plugin-mupen64plus/screen.c @@ -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) diff --git a/plugin-zilmar/gfx_1.3.c b/plugin-zilmar/gfx_1.3.c index 88577f5..2ecc63d 100644 --- a/plugin-zilmar/gfx_1.3.c +++ b/plugin-zilmar/gfx_1.3.c @@ -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); diff --git a/plugin-zilmar/screen.c b/plugin-zilmar/screen.c index 203d2d3..b0d43bf 100644 --- a/plugin-zilmar/screen.c +++ b/plugin-zilmar/screen.c @@ -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)