Mercurial > repos > blastem
comparison render_sdl.c @ 1474:c5c022c7aa54 nuklear_ui
Initial work on Nuklear-based UI
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 21 Nov 2017 19:07:43 -0800 |
parents | 8a3d3bb2cd08 |
children | 0646ae0987c3 |
comparison
equal
deleted
inserted
replaced
1473:152a60c6787e | 1474:c5c022c7aa54 |
---|---|
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" |
520 SDL_JoystickEventState(SDL_ENABLE); | 521 SDL_JoystickEventState(SDL_ENABLE); |
521 | 522 |
522 atexit(render_quit); | 523 atexit(render_quit); |
523 } | 524 } |
524 | 525 |
526 SDL_Window *render_get_window(void) | |
527 { | |
528 return main_window; | |
529 } | |
530 | |
525 void render_set_video_standard(vid_std std) | 531 void render_set_video_standard(vid_std std) |
526 { | 532 { |
527 video_standard = std; | 533 video_standard = std; |
528 } | 534 } |
529 | 535 |
585 #define FPS_INTERVAL 10000 | 591 #define FPS_INTERVAL 10000 |
586 #else | 592 #else |
587 #define FPS_INTERVAL 1000 | 593 #define FPS_INTERVAL 1000 |
588 #endif | 594 #endif |
589 | 595 |
590 static uint32_t last_width; | 596 static uint32_t last_width, last_height; |
597 static uint8_t interlaced; | |
591 void render_framebuffer_updated(uint8_t which, int width) | 598 void render_framebuffer_updated(uint8_t which, int width) |
592 { | 599 { |
593 static uint8_t last; | 600 static uint8_t last; |
594 last_width = width; | 601 last_width = width; |
595 uint32_t height = which <= FRAMEBUFFER_EVEN | 602 uint32_t height = which <= FRAMEBUFFER_EVEN |
607 free(screenshot_path); | 614 free(screenshot_path); |
608 screenshot_path = NULL; | 615 screenshot_path = NULL; |
609 shot_height = video_standard == VID_NTSC ? 243 : 294; | 616 shot_height = video_standard == VID_NTSC ? 243 : 294; |
610 shot_width = width; | 617 shot_width = width; |
611 } | 618 } |
619 interlaced = last != which; | |
612 width -= overscan_left[video_standard] + overscan_right[video_standard]; | 620 width -= overscan_left[video_standard] + overscan_right[video_standard]; |
613 #ifndef DISABLE_OPENGL | 621 #ifndef DISABLE_OPENGL |
614 if (render_gl && which <= FRAMEBUFFER_EVEN) { | 622 if (render_gl && which <= FRAMEBUFFER_EVEN) { |
615 glBindTexture(GL_TEXTURE_2D, textures[which]); | 623 glBindTexture(GL_TEXTURE_2D, textures[which]); |
616 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]); | 624 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]); |
617 | |
618 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
619 glClear(GL_COLOR_BUFFER_BIT); | |
620 | |
621 glUseProgram(program); | |
622 glActiveTexture(GL_TEXTURE0); | |
623 glBindTexture(GL_TEXTURE_2D, textures[0]); | |
624 glUniform1i(un_textures[0], 0); | |
625 | |
626 glActiveTexture(GL_TEXTURE1); | |
627 glBindTexture(GL_TEXTURE_2D, textures[last != which ? 1 : scanlines ? 2 : 0]); | |
628 glUniform1i(un_textures[1], 1); | |
629 | |
630 glUniform1f(un_width, width); | |
631 glUniform1f(un_height, height); | |
632 | |
633 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); | |
634 glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | |
635 glEnableVertexAttribArray(at_pos); | |
636 | |
637 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); | |
638 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | |
639 | |
640 glDisableVertexAttribArray(at_pos); | |
641 | |
642 SDL_GL_SwapWindow(main_window); | |
643 | 625 |
644 if (screenshot_file) { | 626 if (screenshot_file) { |
645 //properly supporting interlaced modes here is non-trivial, so only save the odd field for now | 627 //properly supporting interlaced modes here is non-trivial, so only save the odd field for now |
646 save_ppm(screenshot_file, texture_buf, shot_width, shot_height, LINEBUF_SIZE*sizeof(uint32_t)); | 628 save_ppm(screenshot_file, texture_buf, shot_width, shot_height, LINEBUF_SIZE*sizeof(uint32_t)); |
647 } | 629 } |
671 shot_pitch *= 2; | 653 shot_pitch *= 2; |
672 } | 654 } |
673 save_ppm(screenshot_file, locked_pixels, shot_width, shot_height, shot_pitch); | 655 save_ppm(screenshot_file, locked_pixels, shot_width, shot_height, shot_pitch); |
674 } | 656 } |
675 SDL_UnlockTexture(sdl_textures[which]); | 657 SDL_UnlockTexture(sdl_textures[which]); |
676 SDL_Rect src_clip = { | 658 #ifndef DISABLE_OPENGL |
677 .x = overscan_left[video_standard], | 659 } |
678 .y = overscan_top[video_standard], | 660 #endif |
679 .w = width, | 661 last_height = height; |
680 .h = height | 662 render_update_display(); |
681 }; | |
682 SDL_SetRenderDrawColor(main_renderer, 0, 0, 0, 255); | |
683 SDL_RenderClear(main_renderer); | |
684 SDL_RenderCopy(main_renderer, sdl_textures[which], &src_clip, &main_clip); | |
685 SDL_RenderPresent(main_renderer); | |
686 #ifndef DISABLE_OPENGL | |
687 } | |
688 #endif | |
689 if (screenshot_file) { | 663 if (screenshot_file) { |
690 fclose(screenshot_file); | 664 fclose(screenshot_file); |
691 } | 665 } |
692 if (which <= FRAMEBUFFER_EVEN) { | 666 if (which <= FRAMEBUFFER_EVEN) { |
693 last = which; | 667 last = which; |
708 } | 682 } |
709 start = last_frame; | 683 start = last_frame; |
710 frame_counter = 0; | 684 frame_counter = 0; |
711 } | 685 } |
712 } | 686 } |
687 } | |
688 | |
689 static ui_render_fun render_ui; | |
690 void render_set_ui_render_fun(ui_render_fun fun) | |
691 { | |
692 render_ui = fun; | |
693 } | |
694 | |
695 void render_update_display() | |
696 { | |
697 #ifndef DISABLE_OPENGL | |
698 if (render_gl) { | |
699 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
700 glClear(GL_COLOR_BUFFER_BIT); | |
701 | |
702 glUseProgram(program); | |
703 glActiveTexture(GL_TEXTURE0); | |
704 glBindTexture(GL_TEXTURE_2D, textures[0]); | |
705 glUniform1i(un_textures[0], 0); | |
706 | |
707 glActiveTexture(GL_TEXTURE1); | |
708 glBindTexture(GL_TEXTURE_2D, textures[interlaced ? 1 : scanlines ? 2 : 0]); | |
709 glUniform1i(un_textures[1], 1); | |
710 | |
711 glUniform1f(un_width, render_emulated_width()); | |
712 glUniform1f(un_height, last_height); | |
713 | |
714 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); | |
715 glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | |
716 glEnableVertexAttribArray(at_pos); | |
717 | |
718 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); | |
719 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | |
720 | |
721 glDisableVertexAttribArray(at_pos); | |
722 | |
723 if (render_ui) { | |
724 render_ui(); | |
725 } | |
726 | |
727 SDL_GL_SwapWindow(main_window); | |
728 } else { | |
729 #endif | |
730 SDL_Rect src_clip = { | |
731 .x = overscan_left[video_standard], | |
732 .y = overscan_top[video_standard], | |
733 .w = render_emulated_width(), | |
734 .h = last_height | |
735 }; | |
736 SDL_SetRenderDrawColor(main_renderer, 0, 0, 0, 255); | |
737 SDL_RenderClear(main_renderer); | |
738 SDL_RenderCopy(main_renderer, sdl_textures[FRAMEBUFFER_ODD], &src_clip, &main_clip); | |
739 if (render_ui) { | |
740 render_ui(); | |
741 } | |
742 SDL_RenderPresent(main_renderer); | |
743 #ifndef DISABLE_OPENGL | |
744 } | |
745 #endif | |
713 if (!events_processed) { | 746 if (!events_processed) { |
714 process_events(); | 747 process_events(); |
715 } | 748 } |
716 events_processed = 0; | 749 events_processed = 0; |
717 } | 750 } |
962 void render_set_drag_drop_handler(drop_handler handler) | 995 void render_set_drag_drop_handler(drop_handler handler) |
963 { | 996 { |
964 drag_drop_handler = handler; | 997 drag_drop_handler = handler; |
965 } | 998 } |
966 | 999 |
1000 static event_handler custom_event_handler; | |
1001 void render_set_event_handler(event_handler handler) | |
1002 { | |
1003 custom_event_handler = handler; | |
1004 } | |
1005 | |
967 static int32_t handle_event(SDL_Event *event) | 1006 static int32_t handle_event(SDL_Event *event) |
968 { | 1007 { |
1008 if (custom_event_handler) { | |
1009 custom_event_handler(event); | |
1010 } | |
969 switch (event->type) { | 1011 switch (event->type) { |
970 case SDL_KEYDOWN: | 1012 case SDL_KEYDOWN: |
971 handle_keydown(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]); | 1013 handle_keydown(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]); |
972 break; | 1014 break; |
973 case SDL_KEYUP: | 1015 case SDL_KEYUP: |