comparison render_sdl.c @ 1263:5f65a16c23ff

Implement raw screenshot functionality requested in ticket:10
author Michael Pavone <pavone@retrodev.com>
date Sat, 04 Mar 2017 11:50:14 -0800
parents 1148567ab355
children 3772bb926be5
comparison
equal deleted inserted replaced
1262:462d9770d467 1263:5f65a16c23ff
10 #include "render.h" 10 #include "render.h"
11 #include "blastem.h" 11 #include "blastem.h"
12 #include "genesis.h" 12 #include "genesis.h"
13 #include "io.h" 13 #include "io.h"
14 #include "util.h" 14 #include "util.h"
15 #include "ppm.h"
15 16
16 #ifndef DISABLE_OPENGL 17 #ifndef DISABLE_OPENGL
17 #include <GL/glew.h> 18 #include <GL/glew.h>
18 #endif 19 #endif
19 20
486 caption = title; 487 caption = title;
487 free(fps_caption); 488 free(fps_caption);
488 fps_caption = NULL; 489 fps_caption = NULL;
489 } 490 }
490 491
492 static char *screenshot_path;
493 void render_save_screenshot(char *path)
494 {
495 if (screenshot_path) {
496 free(screenshot_path);
497 }
498 screenshot_path = path;
499 }
500
491 uint32_t *locked_pixels; 501 uint32_t *locked_pixels;
492 uint32_t locked_pitch; 502 uint32_t locked_pitch;
493 uint32_t *render_get_framebuffer(uint8_t which, int *pitch) 503 uint32_t *render_get_framebuffer(uint8_t which, int *pitch)
494 { 504 {
495 #ifndef DISABLE_OPENGL 505 #ifndef DISABLE_OPENGL
536 { 546 {
537 static uint8_t last; 547 static uint8_t last;
538 uint32_t height = which <= FRAMEBUFFER_EVEN 548 uint32_t height = which <= FRAMEBUFFER_EVEN
539 ? (video_standard == VID_NTSC ? 243 : 294) - (overscan_top[video_standard] + overscan_bot[video_standard]) 549 ? (video_standard == VID_NTSC ? 243 : 294) - (overscan_top[video_standard] + overscan_bot[video_standard])
540 : 240; 550 : 240;
551 FILE *screenshot_file = NULL;
552 uint32_t shot_height;
553 if (screenshot_path && which == FRAMEBUFFER_ODD) {
554 screenshot_file = fopen(screenshot_path, "wb");
555 if (screenshot_file) {
556 info_message("Saving screenshot to %s\n", screenshot_path);
557 } else {
558 warning("Failed to open screenshot file %s for writing\n", screenshot_path);
559 }
560 free(screenshot_path);
561 screenshot_path = NULL;
562 shot_height = video_standard == VID_NTSC ? 243 : 294;
563 }
541 #ifndef DISABLE_OPENGL 564 #ifndef DISABLE_OPENGL
542 if (render_gl && which <= FRAMEBUFFER_EVEN) { 565 if (render_gl && which <= FRAMEBUFFER_EVEN) {
543 glBindTexture(GL_TEXTURE_2D, textures[which]); 566 glBindTexture(GL_TEXTURE_2D, textures[which]);
544 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, height, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf + 320 * overscan_top[video_standard]); 567 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, height, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf + 320 * overscan_top[video_standard]);
545 568
566 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); 589 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0);
567 590
568 glDisableVertexAttribArray(at_pos); 591 glDisableVertexAttribArray(at_pos);
569 592
570 SDL_GL_SwapWindow(main_window); 593 SDL_GL_SwapWindow(main_window);
594
595 if (screenshot_file) {
596 //properly supporting interlaced modes here is non-trivial, so only save the odd field for now
597 save_ppm(screenshot_file, texture_buf, width, shot_height, 320*sizeof(uint32_t));
598 }
571 } else { 599 } else {
572 #endif 600 #endif
573 if (which <= FRAMEBUFFER_EVEN && last != which) { 601 if (which <= FRAMEBUFFER_EVEN && last != which) {
574 uint8_t *cur_dst = (uint8_t *)locked_pixels; 602 uint8_t *cur_dst = (uint8_t *)locked_pixels;
575 uint8_t *cur_saved = (uint8_t *)texture_buf; 603 uint8_t *cur_saved = (uint8_t *)texture_buf;
584 cur_dst += locked_pitch * 2; 612 cur_dst += locked_pitch * 2;
585 cur_saved += locked_pitch; 613 cur_saved += locked_pitch;
586 } 614 }
587 height = 480; 615 height = 480;
588 } 616 }
617 if (screenshot_file) {
618 uint32_t shot_pitch = locked_pitch;
619 if (which == FRAMEBUFFER_EVEN) {
620 shot_height *= 2;
621 } else {
622 shot_pitch *= 2;
623 }
624 save_ppm(screenshot_file, locked_pixels, width, shot_height, shot_pitch);
625 }
589 SDL_UnlockTexture(sdl_textures[which]); 626 SDL_UnlockTexture(sdl_textures[which]);
590 SDL_Rect src_clip = { 627 SDL_Rect src_clip = {
591 .x = 0, 628 .x = 0,
592 .y = overscan_top[video_standard], 629 .y = overscan_top[video_standard],
593 .w = width, 630 .w = width,
596 SDL_RenderCopy(main_renderer, sdl_textures[which], &src_clip, &main_clip); 633 SDL_RenderCopy(main_renderer, sdl_textures[which], &src_clip, &main_clip);
597 SDL_RenderPresent(main_renderer); 634 SDL_RenderPresent(main_renderer);
598 #ifndef DISABLE_OPENGL 635 #ifndef DISABLE_OPENGL
599 } 636 }
600 #endif 637 #endif
638 if (screenshot_file) {
639 fclose(screenshot_file);
640 }
601 if (which <= FRAMEBUFFER_EVEN) { 641 if (which <= FRAMEBUFFER_EVEN) {
602 last = which; 642 last = which;
603 static uint32_t frame_counter, start; 643 static uint32_t frame_counter, start;
604 frame_counter++; 644 frame_counter++;
605 last_frame= SDL_GetTicks(); 645 last_frame= SDL_GetTicks();