Annotation of frontvm/hardware/screen.c, revision 1.1.1.2

1.1       root        1: /*
                      2:   Hatari - screen.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at your
                      5:   option any later version. Read the file gpl.txt for details.
                      6: */
                      7: 
                      8: #include <SDL.h>
                      9: 
                     10: #include "main.h"
                     11: #include "configuration.h"
1.1.1.2 ! root       12: #include "../m68000.h"
1.1       root       13: #include "memAlloc.h"
                     14: #include "misc.h"
                     15: #include "screen.h"
                     16: #include "screenConvert.h"
                     17: #include "scalebit.h"
                     18: 
1.1.1.2 ! root       19: unsigned long VideoBase;                        /* Base address in ST Ram for screen(read on each VBL) */
        !            20: unsigned char *VideoRaster;                      /* Pointer to Video raster, after VideoBase in PC address space. Use to copy data on HBL */
        !            21: 
1.1       root       22: int len_main_palette;
                     23: unsigned short MainPalette[256];
                     24: unsigned short CtrlPalette[16];
                     25: 
                     26: SCREENDRAW ScreenDraw;                   /* Set up with details of drawing functions  */
                     27: unsigned char *pScreenBitmap=NULL;                /* Screen pixels in PC RGB format, allocated with 'CreateDIBSection' */
                     28: unsigned char *pPCScreenDest;                     /* Destination PC buffer */
                     29: int STScreenStartHorizLine,STScreenEndHorizLine;  /* Start/End lines to be converted */
                     30: int PCScreenBytesPerLine, STScreenWidthBytes, STScreenLeftSkipBytes;
                     31: BOOL bInFullScreen=FALSE;                         /* TRUE if in full screen */
                     32: BOOL bFullScreenHold = FALSE;                     /* TRUE if hold display while full screen */
                     33: BOOL bScreenContentsChanged;                      /* TRUE if buffer changed and requires blitting */
                     34: BOOL bTooSlowSoSkipAFlip = FALSE;
                     35: int nDroppedFrames=0;                             /* Number of dropped frames during emulation run */
                     36: int prevChosenDisplayMode = -1;
                     37: 
                     38: int STScreenLineOffset[SCREEN_HEIGHT_HBL];        /* Offsets for ST screen lines eg, 0,160,320... */
                     39: unsigned long MainRGBPalette[256];
                     40: unsigned long CtrlRGBPalette[16];
                     41: 
                     42: SDL_Surface *sdlscrn;                             /* The SDL screen surface */
                     43: BOOL bGrabMouse = FALSE;                          /* Grab the mouse cursor in the window */
                     44: 
                     45: 
                     46: /*-----------------------------------------------------------------------*/
                     47: /*
                     48:   Set window size
                     49: */
                     50: void Screen_SetWindowRes()
                     51: {
                     52:   prevChosenDisplayMode = ConfigureParams.Screen.ChosenDisplayMode;
                     53:   switch (ConfigureParams.Screen.ChosenDisplayMode) {
                     54:          case DISPLAYMODE_HICOL_1X:
                     55:                sdlscrn=SDL_SetVideoMode(320, 200, 16, SDL_DOUBLEBUF | SDL_ANYFORMAT);
                     56:                break;
                     57:          default:
                     58:                sdlscrn=SDL_SetVideoMode(640, 400, 16, SDL_DOUBLEBUF | SDL_ANYFORMAT);
                     59:                break;
                     60:   }
                     61:   if ((sdlscrn == NULL) || (sdlscrn->format->BytesPerPixel < 2))
                     62:   {
                     63:     fprintf(stderr, "Could not set video mode:\n %s\n", SDL_GetError() );
                     64:     SDL_Quit();
                     65:     exit(-2);
                     66:   }
                     67:   pScreenBitmap=sdlscrn->pixels;
                     68: 
                     69:   if(!bGrabMouse)
                     70:   {
                     71:     SDL_WM_GrabInput(SDL_GRAB_OFF);  /* Un-grab mouse pointer in windowed mode */
                     72:   }
                     73:   Screen_SetDrawModes();        /* Set draw modes(store which modes to use!) */
                     74: }
                     75: 
                     76: /*-----------------------------------------------------------------------*/
                     77: /*
                     78:   Init Screen bitmap and buffers/tables needed for ST to PC screen conversion
                     79: */
                     80: void Screen_Init(void)
                     81: {
                     82:   Screen_SetWindowRes();
                     83: 
                     84:   Screen_SetScreenLineOffsets();                  /* Store offset to each horizontal line */
                     85: 
                     86:   /* Configure some SDL stuff: */
                     87:   SDL_WM_SetCaption(PROG_NAME, "Frontier");
                     88:   SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
                     89:   SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE);
                     90:   SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
                     91:   SDL_ShowCursor(SDL_DISABLE);
                     92: }
                     93: 
                     94: 
                     95: /*-----------------------------------------------------------------------*/
                     96: /*
                     97:   Free screen bitmap and allocated resources
                     98: */
                     99: void Screen_UnInit(void)
                    100: {
                    101: }
                    102: 
                    103: 
                    104: /*-----------------------------------------------------------------------*/
                    105: /*
                    106:   Reset screen
                    107: */
                    108: void Screen_Reset(void)
                    109: {
                    110: }
                    111: 
                    112: /*-----------------------------------------------------------------------*/
                    113: /*
                    114:   Store Y offset for each horizontal line in our source ST screen for each reference in assembler(no multiply)
                    115: */
                    116: void Screen_SetScreenLineOffsets(void)
                    117: {
                    118:   int i;
                    119: 
                    120:   for(i=0; i<SCREEN_HEIGHT_HBL; i++)
                    121:     STScreenLineOffset[i] = i * SCREENBYTES_LINE;
                    122: }
                    123: 
                    124: 
                    125: /*-----------------------------------------------------------------------*/
                    126: 
                    127: /*-----------------------------------------------------------------------*/
                    128: /*
                    129:   Enter Full screen mode
                    130: */
                    131: 
                    132: static SDL_Surface *set_new_sdl_fsmode() {
                    133:   SDL_Surface *newsdlscrn;
                    134: 
                    135:     newsdlscrn = SDL_SetVideoMode(sdlscrn->w, sdlscrn->h,
                    136:                ScreenDraw.BitDepth, SDL_DOUBLEBUF | SDL_ANYFORMAT | SDL_FULLSCREEN);
                    137:   return newsdlscrn;
                    138: }
                    139: 
                    140: void Screen_EnterFullScreen(void)
                    141: {
                    142:   SDL_Surface *newsdlscrn;
                    143: 
                    144:   if (!bInFullScreen)
                    145:   {
                    146:     Main_PauseEmulation();        /* Hold things... */
                    147:     SDL_Delay(20);                /* To give sound time to clear! */
                    148: 
                    149:     newsdlscrn = set_new_sdl_fsmode();
                    150:     Screen_SetDrawModes();        /* Set draw modes(store which modes to use!) */
                    151: 
                    152:     if( newsdlscrn==NULL )
                    153:     {
                    154:       fprintf(stderr, "Could not set video mode:\n %s\n", SDL_GetError() );
                    155:     }
                    156:     else
                    157:     {
                    158:       sdlscrn = newsdlscrn;
                    159:       pScreenBitmap = newsdlscrn->pixels;
                    160:       bInFullScreen = TRUE;
                    161: 
                    162:       Screen_ClearScreen();         /* Black out screen bitmap as will be invalid when return */
                    163:     }
                    164:     Main_UnPauseEmulation();        /* And off we go... */
                    165: 
                    166:     SDL_WM_GrabInput(SDL_GRAB_ON);  /* Grab mouse pointer in fullscreen */
                    167:   }
                    168: }
                    169: 
                    170: 
                    171: /*-----------------------------------------------------------------------*/
                    172: /*
                    173:   Return from Full screen mode back to a window
                    174: */
                    175: void Screen_ReturnFromFullScreen(void)
                    176: {
                    177:   if (bInFullScreen)
                    178:   {
                    179:     Main_PauseEmulation();        /* Hold things... */
                    180:     SDL_Delay(20);                /* To give sound time to clear! */
                    181: 
                    182:     bInFullScreen = FALSE;
                    183: 
                    184:     Screen_SetWindowRes();
                    185:     Screen_SetDrawModes();
                    186: 
                    187:     Main_UnPauseEmulation();          /* And off we go... */
                    188:   }
                    189: }
                    190: 
                    191: 
                    192: /*-----------------------------------------------------------------------*/
                    193: /*
                    194:   Clear Window display memory
                    195: */
                    196: void Screen_ClearScreen(void)
                    197: {
                    198:   SDL_FillRect(sdlscrn,NULL, SDL_MapRGB(sdlscrn->format, 0, 0, 0) );
                    199: }
                    200: 
                    201: /*-----------------------------------------------------------------------*/
                    202: /*
                    203: */
                    204: void Screen_SetDrawModes(void)
                    205: {
                    206:   /* Clear out */
                    207:   Memory_Clear(&ScreenDraw,sizeof(SCREENDRAW));
                    208: 
                    209:   ScreenDraw.pDrawFunction = screendrawfuncs[sdlscrn->format->BytesPerPixel][ConfigureParams.Screen.ChosenDisplayMode];
                    210:   /* Assign full-screen draw modes from chosen option under dialog */
                    211:   switch (ConfigureParams.Screen.ChosenDisplayMode) {
                    212: 
                    213:        case DISPLAYMODE_HICOL_1X:
                    214:                ScreenDraw.Width = 320;
                    215:                ScreenDraw.Height = 200;
                    216:                ScreenDraw.BitDepth = sdlscrn->format->BitsPerPixel;
                    217:                ScreenDraw.VertPixelsPerLine = 1;
                    218:                ScreenDraw.PCStartHorizLine = 0;
                    219:                ScreenDraw.MouseScale = 1;
                    220:                break;
                    221:        case DISPLAYMODE_HICOL_2X:
                    222:        default:
                    223:                ScreenDraw.Width = 640;
                    224:                ScreenDraw.Height = 480;
                    225:                ScreenDraw.BitDepth = sdlscrn->format->BitsPerPixel;
                    226:                ScreenDraw.VertPixelsPerLine = 2;
                    227:                ScreenDraw.PCStartHorizLine = 0;
                    228:                ScreenDraw.MouseScale = 2;
                    229:                break;
                    230:   }
                    231: }
                    232: 
                    233: 
                    234: /*-----------------------------------------------------------------------*/
                    235: /*
                    236:   Set details for ST screen conversion(Window version)
                    237: */
                    238: void Screen_SetWindowConvertDetails(void)
                    239: {
                    240:   pPCScreenDest = pScreenBitmap;                /* Destination PC screen */
                    241: 
                    242:   STScreenStartHorizLine = 0;                   /* Full height */
                    243: 
                    244:     /* Always draw to WHOLE screen including ALL borders */
                    245:     STScreenLeftSkipBytes = 0;                  /* Number of bytes to skip on ST screen for left(border) */
                    246:     STScreenWidthBytes = SCREENBYTES_LINE;      /* Number of horizontal bytes in our ST screen */
                    247: 
                    248:     STScreenEndHorizLine = SCREEN_HEIGHT_HBL;
                    249: 
                    250:       PCScreenBytesPerLine = sdlscrn->pitch;
                    251: }
                    252: 
                    253: /*-----------------------------------------------------------------------*/
                    254: /*
                    255:   Set details for ST screen conversion (Full-Screen version)
                    256: */
                    257: void Screen_SetFullScreenConvertDetails(void)
                    258: {
                    259:   /* Only draw what can fit into full-screen and centre on Y */
                    260:   STScreenLeftSkipBytes = 0;
                    261:   STScreenWidthBytes = SCREENBYTES_LINE;
                    262: 
                    263:   STScreenStartHorizLine = 0;
                    264:   STScreenEndHorizLine = SCREEN_HEIGHT_HBL;
                    265: 
                    266:   PCScreenBytesPerLine = sdlscrn->pitch;
                    267:   pPCScreenDest = (unsigned char *)sdlscrn->pixels;  /* Destination PC screen */
                    268:   /* And offset on X */
                    269:  // pPCScreenDest += ScreenDraw.PCStartXOffset;
                    270:   //pPCScreenDest += ScreenDraw.PCStartHorizLine * PCScreenBytesPerLine;
                    271: 
                    272:   /* Is non-interlaced? May need to double up on Y */
                    273:     bScrDoubleY = TRUE;
                    274: }
                    275: 
                    276: 
                    277: /*-----------------------------------------------------------------------*/
                    278: /*
                    279:   Lock full-screen for drawing
                    280: */
                    281: BOOL Screen_Lock(void)
                    282: {
                    283:   if(SDL_MUSTLOCK(sdlscrn))
                    284:   {
                    285:     if(SDL_LockSurface(sdlscrn))
                    286:     {
                    287:       Screen_ReturnFromFullScreen();   /* All OK? If not need to jump back to a window */
                    288:       return(FALSE);
                    289:     }
                    290:   }
                    291: 
                    292:   return(TRUE);
                    293: }
                    294: 
                    295: /*-----------------------------------------------------------------------*/
                    296: /*
                    297:   UnLock full-screen
                    298: */
                    299: void Screen_UnLock(void)
                    300: {
                    301:   if( SDL_MUSTLOCK(sdlscrn) )
                    302:     SDL_UnlockSurface(sdlscrn);
                    303: }
                    304: 
                    305: 
                    306: /*-----------------------------------------------------------------------*/
                    307: /*
                    308:   Draw ST screen to window/full-screen framebuffer
                    309: */
                    310: void Screen_DrawFrame(BOOL bForceFlip)
                    311: {
                    312:   void *pDrawFunction;
                    313: 
                    314:   if ((!ConfigureParams.Screen.bFullScreen) &&
                    315:       (prevChosenDisplayMode != ConfigureParams.Screen.ChosenDisplayMode))
                    316:          Screen_SetWindowRes ();
                    317: 
                    318:   //if (!bScreenContentsChanged) return;
                    319:   if (bTooSlowSoSkipAFlip) {
                    320:          bTooSlowSoSkipAFlip = FALSE;
                    321:          return;
                    322:   }
                    323:   
                    324:   /* Lock screen ready for drawing */
                    325:   if (Screen_Lock()) {
                    326:     bScreenContentsChanged = FALSE;
                    327:     /* Set details */
                    328:     if (bInFullScreen) 
                    329:            Screen_SetFullScreenConvertDetails();
                    330:     else
                    331:            Screen_SetWindowConvertDetails();
                    332:     /* Call drawing for full-screen */
                    333:       pDrawFunction = ScreenDraw.pDrawFunction;
                    334:     
                    335:     /* build RGB palettes */
                    336:     BuildRGBPalette (MainRGBPalette, MainPalette, len_main_palette);
                    337:     BuildRGBPalette (CtrlRGBPalette, CtrlPalette, 16);
                    338:       
                    339:     if (pDrawFunction)
                    340:       CALL_VAR(pDrawFunction)
                    341: 
                    342:     /* Unlock screen */
                    343:     Screen_UnLock();
                    344: 
                    345:     SDL_Flip(sdlscrn);
                    346:   }
                    347: }
                    348: 
                    349: /*-----------------------------------------------------------------------*/
                    350: /*
                    351:   Draw ST screen to window/full-screen
                    352:   This is now called from the 68k program's vblank handler,
                    353:   since we need the vblank to update palettes appropriately
                    354:   before drawing the screen (for frontier)
                    355: */
                    356: void Screen_Draw(unsigned long _dummy)
                    357: {
                    358:   /* Are we holding screen? Ie let user choose options while in full-screen mode using GDI */
                    359:   if (bInFullScreen && bFullScreenHold)
                    360:   {
                    361:     return;
                    362:   }
                    363: 
                    364:   if (!bQuitProgram)
                    365:   {
                    366:     if(VideoBase)
                    367:     {
                    368:       Screen_DrawFrame(FALSE);
                    369:     }
                    370:   }
                    371: 
                    372: }

unix.superglobalmegacorp.com

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