Annotation of previous_trunk/src/dimension/nd_sdl.cpp, revision 1.1.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.