Annotation of previous_trunk/src/dimension/nd_sdl.cpp, revision 1.1

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

unix.superglobalmegacorp.com

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