Mercurial > repos > blastem
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(); |