Annotation of previous/src/dimension/nd_sdl.c, revision 1.1.1.2

1.1       root        1: #include "main.h"
                      2: #include "nd_sdl.h"
                      3: #include "configuration.h"
                      4: #include "dimension.h"
                      5: #include "screen.h"
1.1.1.2 ! root        6: #include "host.h"
        !             7: #include "cycInt.h"
1.1       root        8: 
                      9: /* Because of SDL time (in)accuracy, timing is very approximative */
                     10: const int DISPLAY_VBL_MS = 1000 / 68; // main display at 68Hz, actually this is 71.42 Hz because (int)1000/(int)68Hz=14ms
                     11: const int VIDEO_VBL_MS   = 1000 / 60; // NTSC display at 60Hz, actually this is 62.5 Hz because (int)1000/(int)60Hz=16ms
                     12: const int BLANK_MS       = 2;         // Give some blank time for both
                     13: 
                     14: static volatile bool doRepaint     = true;
                     15: static SDL_Thread*   repaintThread = NULL;
                     16: static SDL_Window*   ndWindow      = NULL;
1.1.1.2 ! root       17: static SDL_Renderer* ndRenderer    = NULL;
        !            18: 
        !            19: SDL_atomic_t blitNDFB;
1.1       root       20: 
1.1.1.2 ! root       21: void blitDimension(SDL_Texture* tex);
1.1       root       22: 
                     23: static int repainter(void* unused) {
1.1.1.2 ! root       24:     SDL_SetThreadPriority(SDL_THREAD_PRIORITY_NORMAL);
        !            25:     
1.1       root       26:     SDL_Texture*  ndTexture  = NULL;
1.1.1.2 ! root       27:     
        !            28:     SDL_Rect r = {0,0,1120,832};
1.1       root       29:     
                     30:     ndRenderer = SDL_CreateRenderer(ndWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1.1.1.2 ! root       31:     
        !            32:     if (!ndRenderer) {
1.1       root       33:         fprintf(stderr,"[ND] Failed to create renderer!\n");
                     34:         exit(-1);
                     35:     }
1.1.1.2 ! root       36:     
1.1       root       37:     SDL_RenderSetLogicalSize(ndRenderer, r.w, r.h);
                     38:     ndTexture = SDL_CreateTexture(ndRenderer, SDL_PIXELFORMAT_UNKNOWN, SDL_TEXTUREACCESS_STREAMING, r.w, r.h);
                     39:     
1.1.1.2 ! root       40:     SDL_AtomicSet(&blitNDFB, 1);
        !            41:     
1.1       root       42:     while(doRepaint) {
1.1.1.2 ! root       43:         if (SDL_AtomicGet(&blitNDFB)) {
1.1       root       44:             blitDimension(ndTexture);
                     45:             SDL_RenderCopy(ndRenderer, ndTexture, NULL, NULL);
                     46:             SDL_RenderPresent(ndRenderer);
                     47:         } else {
1.1.1.2 ! root       48:             host_sleep_ms(100);
1.1       root       49:         }
                     50:     }
                     51: 
                     52:     SDL_DestroyTexture(ndTexture);
                     53:     SDL_DestroyRenderer(ndRenderer);
                     54:     SDL_DestroyWindow(ndWindow);
                     55: 
                     56:     return 0;
                     57: }
                     58: 
1.1.1.2 ! root       59: static bool ndVBLtoggle;
        !            60: void nd_vbl_handler() {
        !            61:     CycInt_AcknowledgeInterrupt();
        !            62:     
        !            63:     host_blank(ND_SLOT, ND_DISPLAY, ndVBLtoggle);
        !            64:     ndVBLtoggle = !ndVBLtoggle;
        !            65:     
        !            66:     CycInt_AddRelativeInterruptUs((1000*1000)/136, 0, INTERRUPT_ND_VBL); // 136Hz with toggle gives 68Hz, blank time is 1/2 frame time
        !            67: }
        !            68: 
        !            69: bool ndVideoVBLtoggle;
        !            70: void nd_video_vbl_handler() {
        !            71:     CycInt_AcknowledgeInterrupt();
        !            72:     
        !            73:     host_blank(ND_SLOT, ND_VIDEO, ndVideoVBLtoggle);
        !            74:     ndVideoVBLtoggle = !ndVideoVBLtoggle;
        !            75:     
        !            76:     CycInt_AddRelativeInterruptUs((1000*1000)/120, 0, INTERRUPT_ND_VIDEO_VBL); // 120Hz with toggle gives 60Hz NTSC, blank time is 1/2 frame time
        !            77: }
        !            78: 
1.1       root       79: void nd_sdl_init() {
                     80:     if(!(repaintThread)) {
                     81:         int x, y, w, h;
                     82:         SDL_GetWindowPosition(sdlWindow, &x, &y);
                     83:         SDL_GetWindowSize(sdlWindow, &w, &h);
1.1.1.2 ! root       84:         ndWindow   = SDL_CreateWindow("NeXTdimension",(x-w)+1, y, 1120, 832, SDL_WINDOW_HIDDEN);
        !            85:         
        !            86:         if (!ndWindow) {
        !            87:             fprintf(stderr,"[ND] Failed to create window!\n");
        !            88:             exit(-1);
        !            89:         }
1.1       root       90:     }
                     91:     
                     92:     if(ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_DUAL) {
                     93:         SDL_ShowWindow(ndWindow);
                     94:     } else {
                     95:         SDL_HideWindow(ndWindow);
                     96:     }
                     97: }
                     98: 
1.1.1.2 ! root       99: void nd_start_interrupts() {
        !           100:     if(!(repaintThread) && ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_DUAL)
        !           101:         repaintThread = SDL_CreateThread(repainter, "[ND] repainter", NULL);
        !           102:     
        !           103:     // if this is a cube and we have an ND configured, install ND VBL handlers
        !           104:     if (ConfigureParams.Dimension.bEnabled && (ConfigureParams.System.nMachineType == NEXT_CUBE030 || ConfigureParams.System.nMachineType == NEXT_CUBE040)) {
        !           105:         CycInt_AddRelativeInterruptUs(1000, 0, INTERRUPT_ND_VBL);
        !           106:         CycInt_AddRelativeInterruptUs(1000, 0, INTERRUPT_ND_VIDEO_VBL);
1.1       root      107:     }
1.1.1.2 ! root      108: }
        !           109: 
        !           110: void nd_sdl_uninit() {
1.1       root      111:     SDL_HideWindow(ndWindow);
                    112: }
                    113: 
1.1.1.2 ! root      114: void nd_sdl_pause(bool pause) {
        !           115:     if (pause) {
        !           116:         SDL_AtomicSet(&blitNDFB, 0);
        !           117:     } else {
        !           118:         SDL_AtomicSet(&blitNDFB, 1);
        !           119:     }
        !           120: }
        !           121: 
1.1       root      122: void nd_sdl_destroy() {
                    123:     doRepaint = false; // stop repaint thread
                    124:     int s;
                    125:     SDL_WaitThread(repaintThread, &s);
                    126:     nd_sdl_uninit();
                    127: }
                    128: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.