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 }