|
|
1.1 ! root 1: #include "main.h" ! 2: #include "nd_sdl.h" ! 3: #include "configuration.h" ! 4: #include "dimension.h" ! 5: #include "screen.h" ! 6: ! 7: /* Because of SDL time (in)accuracy, timing is very approximative */ ! 8: const int DISPLAY_VBL_MS = 1000 / 68; // main display at 68Hz, actually this is 71.42 Hz because (int)1000/(int)68Hz=14ms ! 9: const int VIDEO_VBL_MS = 1000 / 60; // NTSC display at 60Hz, actually this is 62.5 Hz because (int)1000/(int)60Hz=16ms ! 10: const int BLANK_MS = 2; // Give some blank time for both ! 11: ! 12: extern Uint32 nd_display_blank_start(); ! 13: extern Uint32 nd_display_blank_end(); ! 14: extern Uint32 nd_video_vbl(Uint32 interval, void* param); ! 15: ! 16: static SDL_TimerID videoVBL = NULL; ! 17: static volatile bool doRepaint = true; ! 18: static SDL_Thread* repaintThread = NULL; ! 19: static SDL_Window* ndWindow = NULL; ! 20: ! 21: extern void blitDimension(SDL_Texture* tex); ! 22: ! 23: static int repainter(void* unused) { ! 24: SDL_Texture* ndTexture = NULL; ! 25: SDL_Renderer* ndRenderer = NULL; ! 26: ! 27: ndRenderer = SDL_CreateRenderer(ndWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); ! 28: if (!ndWindow || !ndRenderer) { ! 29: fprintf(stderr,"[ND] Failed to create renderer!\n"); ! 30: exit(-1); ! 31: } ! 32: SDL_Rect r = {0,0,1120,832}; ! 33: SDL_RenderSetLogicalSize(ndRenderer, r.w, r.h); ! 34: ndTexture = SDL_CreateTexture(ndRenderer, SDL_PIXELFORMAT_UNKNOWN, SDL_TEXTUREACCESS_STREAMING, r.w, r.h); ! 35: ! 36: while(doRepaint) { ! 37: if(ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_DUAL) { ! 38: blitDimension(ndTexture); ! 39: SDL_RenderCopy(ndRenderer, ndTexture, NULL, NULL); ! 40: SDL_RenderPresent(ndRenderer); ! 41: } else { ! 42: SDL_Delay(VIDEO_VBL_MS - BLANK_MS); ! 43: } ! 44: // if this is a cube, then do ND blank emulation. ! 45: if(ConfigureParams.System.nMachineType == NEXT_CUBE030 || ConfigureParams.System.nMachineType == NEXT_CUBE040) { ! 46: nd_display_blank_start(); ! 47: SDL_Delay(BLANK_MS); ! 48: nd_display_blank_end(); ! 49: } ! 50: } ! 51: ! 52: SDL_DestroyTexture(ndTexture); ! 53: SDL_DestroyRenderer(ndRenderer); ! 54: SDL_DestroyWindow(ndWindow); ! 55: ! 56: return 0; ! 57: } ! 58: ! 59: void nd_sdl_init() { ! 60: if(!(repaintThread)) { ! 61: int x, y, w, h; ! 62: SDL_GetWindowPosition(sdlWindow, &x, &y); ! 63: SDL_GetWindowSize(sdlWindow, &w, &h); ! 64: ndWindow = SDL_CreateWindow("NeXT Dimension",(x-w)+1, y, 1120, 832, SDL_WINDOW_HIDDEN); ! 65: repaintThread = SDL_CreateThread(repainter, "[ND] repainter", NULL); ! 66: } ! 67: if(videoVBL) SDL_RemoveTimer(videoVBL); ! 68: // NTSC video at 60Hz ! 69: videoVBL = SDL_AddTimer(VIDEO_VBL_MS, nd_video_vbl, NULL); ! 70: ! 71: if(ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_DUAL) { ! 72: SDL_ShowWindow(ndWindow); ! 73: } else { ! 74: SDL_HideWindow(ndWindow); ! 75: } ! 76: } ! 77: ! 78: void nd_sdl_uninit() { ! 79: if(videoVBL) { ! 80: SDL_RemoveTimer(videoVBL); ! 81: videoVBL = NULL; ! 82: } ! 83: SDL_HideWindow(ndWindow); ! 84: } ! 85: ! 86: void nd_sdl_destroy() { ! 87: doRepaint = false; // stop repaint thread ! 88: int s; ! 89: SDL_WaitThread(repaintThread, &s); ! 90: nd_sdl_uninit(); ! 91: } ! 92: ! 93: //----- SDL abstractions for ND implementation ! 94: ! 95: void lock(lock_t* lock) { ! 96: SDL_AtomicLock(lock); ! 97: } ! 98: ! 99: int trylock(lock_t* lock) { ! 100: return SDL_AtomicTryLock(lock); ! 101: } ! 102: ! 103: void unlock(lock_t* lock) { ! 104: SDL_AtomicUnlock(lock); ! 105: } ! 106: ! 107: void checklock(lock_t* lock) { ! 108: SDL_AtomicLock(lock); ! 109: SDL_AtomicUnlock(lock); ! 110: } ! 111: ! 112: Uint32 time_ms() { ! 113: return SDL_GetTicks(); ! 114: } ! 115: ! 116: void sleep_ms(Uint32 ms) { ! 117: SDL_Delay(ms); ! 118: } ! 119: ! 120: thread_t* thread_create(thread_func_t func, void* data) { ! 121: return SDL_CreateThread(func, "[ND] Thread", data); ! 122: } ! 123: ! 124: int thread_wait(thread_t* thread) { ! 125: int status; ! 126: SDL_WaitThread(thread, &status); ! 127: return status; ! 128: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.