Mercurial > repos > blastem
comparison render_sdl.c @ 1541:f8ef74e7c800
Merged nuklear_ui into default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 25 Mar 2018 12:01:49 -0700 |
parents | c59adc305e46 |
children | ce1f93be0104 |
comparison
equal
deleted
inserted
replaced
1533:78b7fc03c7c6 | 1541:f8ef74e7c800 |
---|---|
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <math.h> | 9 #include <math.h> |
10 #include "render.h" | 10 #include "render.h" |
11 #include "render_sdl.h" | |
11 #include "blastem.h" | 12 #include "blastem.h" |
12 #include "genesis.h" | 13 #include "genesis.h" |
13 #include "io.h" | 14 #include "io.h" |
14 #include "util.h" | 15 #include "util.h" |
15 #include "ppm.h" | 16 #include "ppm.h" |
521 SDL_JoystickEventState(SDL_ENABLE); | 522 SDL_JoystickEventState(SDL_ENABLE); |
522 | 523 |
523 atexit(render_quit); | 524 atexit(render_quit); |
524 } | 525 } |
525 | 526 |
527 SDL_Window *render_get_window(void) | |
528 { | |
529 return main_window; | |
530 } | |
531 | |
526 void render_set_video_standard(vid_std std) | 532 void render_set_video_standard(vid_std std) |
527 { | 533 { |
528 video_standard = std; | 534 video_standard = std; |
529 } | 535 } |
530 | 536 |
586 #define FPS_INTERVAL 10000 | 592 #define FPS_INTERVAL 10000 |
587 #else | 593 #else |
588 #define FPS_INTERVAL 1000 | 594 #define FPS_INTERVAL 1000 |
589 #endif | 595 #endif |
590 | 596 |
591 static uint32_t last_width; | 597 static uint32_t last_width, last_height; |
598 static uint8_t interlaced; | |
592 void render_framebuffer_updated(uint8_t which, int width) | 599 void render_framebuffer_updated(uint8_t which, int width) |
593 { | 600 { |
594 static uint8_t last; | 601 static uint8_t last; |
595 last_width = width; | 602 last_width = width; |
596 uint32_t height = which <= FRAMEBUFFER_EVEN | 603 uint32_t height = which <= FRAMEBUFFER_EVEN |
612 free(screenshot_path); | 619 free(screenshot_path); |
613 screenshot_path = NULL; | 620 screenshot_path = NULL; |
614 shot_height = video_standard == VID_NTSC ? 243 : 294; | 621 shot_height = video_standard == VID_NTSC ? 243 : 294; |
615 shot_width = width; | 622 shot_width = width; |
616 } | 623 } |
624 interlaced = last != which; | |
617 width -= overscan_left[video_standard] + overscan_right[video_standard]; | 625 width -= overscan_left[video_standard] + overscan_right[video_standard]; |
618 #ifndef DISABLE_OPENGL | 626 #ifndef DISABLE_OPENGL |
619 if (render_gl && which <= FRAMEBUFFER_EVEN) { | 627 if (render_gl && which <= FRAMEBUFFER_EVEN) { |
620 glBindTexture(GL_TEXTURE_2D, textures[which]); | 628 glBindTexture(GL_TEXTURE_2D, textures[which]); |
621 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]); | 629 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, GL_BGRA, GL_UNSIGNED_BYTE, texture_buf + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]); |
622 | |
623 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
624 glClear(GL_COLOR_BUFFER_BIT); | |
625 | |
626 glUseProgram(program); | |
627 glActiveTexture(GL_TEXTURE0); | |
628 glBindTexture(GL_TEXTURE_2D, textures[0]); | |
629 glUniform1i(un_textures[0], 0); | |
630 | |
631 glActiveTexture(GL_TEXTURE1); | |
632 glBindTexture(GL_TEXTURE_2D, textures[last != which ? 1 : scanlines ? 2 : 0]); | |
633 glUniform1i(un_textures[1], 1); | |
634 | |
635 glUniform1f(un_width, width); | |
636 glUniform1f(un_height, height); | |
637 | |
638 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); | |
639 glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | |
640 glEnableVertexAttribArray(at_pos); | |
641 | |
642 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); | |
643 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | |
644 | |
645 glDisableVertexAttribArray(at_pos); | |
646 | |
647 SDL_GL_SwapWindow(main_window); | |
648 | 630 |
649 if (screenshot_file) { | 631 if (screenshot_file) { |
650 //properly supporting interlaced modes here is non-trivial, so only save the odd field for now | 632 //properly supporting interlaced modes here is non-trivial, so only save the odd field for now |
651 #ifndef DISABLE_ZLIB | 633 #ifndef DISABLE_ZLIB |
652 if (!strcasecmp(ext, "png")) { | 634 if (!strcasecmp(ext, "png")) { |
696 #ifndef DISABLE_ZLIB | 678 #ifndef DISABLE_ZLIB |
697 } | 679 } |
698 #endif | 680 #endif |
699 } | 681 } |
700 SDL_UnlockTexture(sdl_textures[which]); | 682 SDL_UnlockTexture(sdl_textures[which]); |
701 SDL_Rect src_clip = { | 683 #ifndef DISABLE_OPENGL |
702 .x = overscan_left[video_standard], | 684 } |
703 .y = overscan_top[video_standard], | 685 #endif |
704 .w = width, | 686 last_height = height; |
705 .h = height | 687 render_update_display(); |
706 }; | |
707 SDL_SetRenderDrawColor(main_renderer, 0, 0, 0, 255); | |
708 SDL_RenderClear(main_renderer); | |
709 SDL_RenderCopy(main_renderer, sdl_textures[which], &src_clip, &main_clip); | |
710 SDL_RenderPresent(main_renderer); | |
711 #ifndef DISABLE_OPENGL | |
712 } | |
713 #endif | |
714 if (screenshot_file) { | 688 if (screenshot_file) { |
715 fclose(screenshot_file); | 689 fclose(screenshot_file); |
716 } | 690 } |
717 if (which <= FRAMEBUFFER_EVEN) { | 691 if (which <= FRAMEBUFFER_EVEN) { |
718 last = which; | 692 last = which; |
733 } | 707 } |
734 start = last_frame; | 708 start = last_frame; |
735 frame_counter = 0; | 709 frame_counter = 0; |
736 } | 710 } |
737 } | 711 } |
712 } | |
713 | |
714 static ui_render_fun render_ui; | |
715 void render_set_ui_render_fun(ui_render_fun fun) | |
716 { | |
717 render_ui = fun; | |
718 } | |
719 | |
720 void render_update_display() | |
721 { | |
722 #ifndef DISABLE_OPENGL | |
723 if (render_gl) { | |
724 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
725 glClear(GL_COLOR_BUFFER_BIT); | |
726 | |
727 glUseProgram(program); | |
728 glActiveTexture(GL_TEXTURE0); | |
729 glBindTexture(GL_TEXTURE_2D, textures[0]); | |
730 glUniform1i(un_textures[0], 0); | |
731 | |
732 glActiveTexture(GL_TEXTURE1); | |
733 glBindTexture(GL_TEXTURE_2D, textures[interlaced ? 1 : scanlines ? 2 : 0]); | |
734 glUniform1i(un_textures[1], 1); | |
735 | |
736 glUniform1f(un_width, render_emulated_width()); | |
737 glUniform1f(un_height, last_height); | |
738 | |
739 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); | |
740 glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | |
741 glEnableVertexAttribArray(at_pos); | |
742 | |
743 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); | |
744 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | |
745 | |
746 glDisableVertexAttribArray(at_pos); | |
747 | |
748 if (render_ui) { | |
749 render_ui(); | |
750 } | |
751 | |
752 SDL_GL_SwapWindow(main_window); | |
753 } else { | |
754 #endif | |
755 SDL_Rect src_clip = { | |
756 .x = overscan_left[video_standard], | |
757 .y = overscan_top[video_standard], | |
758 .w = render_emulated_width(), | |
759 .h = last_height | |
760 }; | |
761 SDL_SetRenderDrawColor(main_renderer, 0, 0, 0, 255); | |
762 SDL_RenderClear(main_renderer); | |
763 SDL_RenderCopy(main_renderer, sdl_textures[FRAMEBUFFER_ODD], &src_clip, &main_clip); | |
764 if (render_ui) { | |
765 render_ui(); | |
766 } | |
767 SDL_RenderPresent(main_renderer); | |
768 #ifndef DISABLE_OPENGL | |
769 } | |
770 #endif | |
738 if (!events_processed) { | 771 if (!events_processed) { |
739 process_events(); | 772 process_events(); |
740 } | 773 } |
741 events_processed = 0; | 774 events_processed = 0; |
742 } | 775 } |
987 void render_set_drag_drop_handler(drop_handler handler) | 1020 void render_set_drag_drop_handler(drop_handler handler) |
988 { | 1021 { |
989 drag_drop_handler = handler; | 1022 drag_drop_handler = handler; |
990 } | 1023 } |
991 | 1024 |
1025 static ui_render_fun on_context_destroyed, on_context_created; | |
1026 void render_set_gl_context_handlers(ui_render_fun destroy, ui_render_fun create) | |
1027 { | |
1028 on_context_destroyed = destroy; | |
1029 on_context_created = create; | |
1030 } | |
1031 | |
1032 static event_handler custom_event_handler; | |
1033 void render_set_event_handler(event_handler handler) | |
1034 { | |
1035 custom_event_handler = handler; | |
1036 } | |
1037 | |
992 static int32_t handle_event(SDL_Event *event) | 1038 static int32_t handle_event(SDL_Event *event) |
993 { | 1039 { |
1040 if (custom_event_handler) { | |
1041 custom_event_handler(event); | |
1042 } | |
994 switch (event->type) { | 1043 switch (event->type) { |
995 case SDL_KEYDOWN: | 1044 case SDL_KEYDOWN: |
996 handle_keydown(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]); | 1045 handle_keydown(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]); |
997 break; | 1046 break; |
998 case SDL_KEYUP: | 1047 case SDL_KEYUP: |
1051 main_width = event->window.data1; | 1100 main_width = event->window.data1; |
1052 main_height = event->window.data2; | 1101 main_height = event->window.data2; |
1053 update_aspect(); | 1102 update_aspect(); |
1054 #ifndef DISABLE_OPENGL | 1103 #ifndef DISABLE_OPENGL |
1055 if (render_gl) { | 1104 if (render_gl) { |
1105 if (on_context_destroyed) { | |
1106 on_context_destroyed(); | |
1107 } | |
1056 SDL_GL_DeleteContext(main_context); | 1108 SDL_GL_DeleteContext(main_context); |
1057 main_context = SDL_GL_CreateContext(main_window); | 1109 main_context = SDL_GL_CreateContext(main_window); |
1058 gl_setup(); | 1110 gl_setup(); |
1111 if (on_context_created) { | |
1112 on_context_created(); | |
1113 } | |
1059 } | 1114 } |
1060 #endif | 1115 #endif |
1061 break; | 1116 break; |
1062 } | 1117 } |
1063 break; | 1118 break; |
1188 void render_infobox(char *title, char *message) | 1243 void render_infobox(char *title, char *message) |
1189 { | 1244 { |
1190 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title, message, NULL); | 1245 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title, message, NULL); |
1191 } | 1246 } |
1192 | 1247 |
1248 uint32_t render_elapsed_ms(void) | |
1249 { | |
1250 return SDL_GetTicks(); | |
1251 } | |
1252 | |
1253 void render_sleep_ms(uint32_t delay) | |
1254 { | |
1255 return SDL_Delay(delay); | |
1256 } | |
1257 | |
1258 uint8_t render_has_gl(void) | |
1259 { | |
1260 return render_gl; | |
1261 } |