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: