|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.