📄 sdl_cgxvideo.c
字号:
// Check if the window needs to be closed or can be resized if( (flags&SDL_FULLSCREEN) || (current && current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))) needcreate=1;// Check if we need to close an already existing videomode... if(current && current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN)) { unsigned long i; D(bug("Destroying image, window & screen!\n")); CGX_DestroyImage(this,current); CGX_DestroyWindow(this,current); DestroyScreen(this); GFX_Display=SDL_Display=LockPubScreen(NULL); bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH); for ( i = 0; i < this->hidden->nvisuals; i++ ) { if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ break; } if ( i == this->hidden->nvisuals ) { SDL_SetError("No matching visual for requested depth"); return NULL; /* should never happen */ } SDL_Visual = this->hidden->visuals[i].visual; D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); } /* Check the combination of flags we were passed */ if ( flags & SDL_FULLSCREEN ) { int i; /* Clear fullscreen flag if not supported */ if ( SDL_windowid ) { flags &= ~SDL_FULLSCREEN; } else if(current && current->flags&SDL_FULLSCREEN ) { if(current->w!=width || current->h!=height || (this->hidden && this->hidden->depth!=bpp)) { D(bug("Deleting previous window...\n")); CGX_DestroyImage(this,current); CGX_DestroyWindow(this,current); DestroyScreen(this); goto buildnewscreen; } } elsebuildnewscreen: { Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,width, CYBRBIDTG_NominalHeight,height, CYBRBIDTG_Depth,bpp, TAG_DONE); GFX_Display=NULL; D(bug("Opening screen...\n")); if(okid!=INVALID_ID) GFX_Display=OpenScreenTags(NULL, SA_Width,width, SA_Height,height, SA_Quiet,TRUE,SA_ShowTitle,FALSE, SA_Depth,bpp, SA_DisplayID,okid, TAG_DONE); if(!GFX_Display) { GFX_Display=SDL_Display; flags &= ~SDL_FULLSCREEN; flags &= ~SDL_DOUBLEBUF; } else { UnlockPubScreen(NULL,SDL_Display); SDL_Display=GFX_Display; D(bug("Screen opened.\n")); if(flags&SDL_DOUBLEBUF) { int ok=0; D(bug("Start of DBuffering allocations...\n")); if(this->hidden->SB[0]=AllocScreenBuffer(SDL_Display,NULL,SB_SCREEN_BITMAP)) { if(this->hidden->SB[1]=AllocScreenBuffer(SDL_Display,NULL,0L)) { extern struct MsgPort *safeport,*dispport; safeport=CreateMsgPort(); dispport=CreateMsgPort(); if(!safeport || !dispport) { if(safeport) { DeleteMsgPort(safeport); safeport=NULL; } if(dispport) { DeleteMsgPort(dispport); dispport=NULL; } FreeScreenBuffer(SDL_Display,this->hidden->SB[0]); FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); } else { extern ULONG safe_sigbit,disp_sigbit; int i; safe_sigbit=1L<< safeport->mp_SigBit; disp_sigbit=1L<< dispport->mp_SigBit; for(i=0;i<2;i++) { this->hidden->SB[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=safeport; this->hidden->SB[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=dispport; } ok=1; D(bug("Dbuffering enabled!\n")); this->hidden->dbuffer=1; current->flags|=SDL_DOUBLEBUF; } } else { FreeScreenBuffer(SDL_Display,this->hidden->SB[1]); this->hidden->SB[0]=NULL; } } if(!ok) flags&=~SDL_DOUBLEBUF; } } if(GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)==bpp) this->hidden->same_format=1; } bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH); D(bug("Setting screen depth to: %ld\n",this->hidden->depth)); for ( i = 0; i < this->hidden->nvisuals; i++ ) if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */ break; if ( i == this->hidden->nvisuals ) { SDL_SetError("No matching visual for requested depth"); return NULL; /* should never happen */ } SDL_Visual = this->hidden->visuals[i].visual; } /* Set up the X11 window */ saved_flags = current->flags; if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL) && bpp == current->format->BitsPerPixel && !needcreate) { if (CGX_ResizeWindow(this, current, width, height, flags) < 0) { current = NULL; goto done; } } else { if (CGX_CreateWindow(this,current,width,height,bpp,flags) < 0) { current = NULL; goto done; } }#if 0 /* Set up the new mode framebuffer */ if ( ((current->w != width) || (current->h != height)) || ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) { current->w = width; current->h = height; current->pitch = SDL_CalculatePitch(current); CGX_ResizeImage(this, current, flags); }#endif current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it done: /* Release the event thread */ SDL_Unlock_EventThread(); /* We're done! */ return(current);}static int CGX_ToggleFullScreen(_THIS, int on){ Uint32 event_thread; /* Don't switch if we don't own the window */ if ( SDL_windowid ) { return(0); } /* Don't lock if we are the event thread */ event_thread = SDL_EventThreadID(); if ( event_thread && (SDL_ThreadID() == event_thread) ) { event_thread = 0; } if ( event_thread ) { SDL_Lock_EventThread(); } if ( on ) { this->screen->flags |= SDL_FULLSCREEN; CGX_EnterFullScreen(this); } else { this->screen->flags &= ~SDL_FULLSCREEN; CGX_LeaveFullScreen(this); } CGX_RefreshDisplay(this); if ( event_thread ) { SDL_Unlock_EventThread(); } SDL_ResetKeyboard(); return(1);}static void SetSingleColor(Uint32 fmt, unsigned char r, unsigned char g, unsigned char b, unsigned char *c){ switch(fmt) { case PIXFMT_BGR15: case PIXFMT_RGB15PC: { Uint16 *t=(Uint16 *)c; *t=(r>>3) | ((g>>3)<<5) | ((b>>3)<<10) ; } break; case PIXFMT_RGB15: case PIXFMT_BGR15PC: { Uint16 *t=(Uint16 *)c; *t=(b>>3) | ((g>>3)<<5) | ((r>>3)<<10) ; } break; case PIXFMT_BGR16PC: case PIXFMT_RGB16: { Uint16 *t=(Uint16 *)c; *t=(b>>3) | ((g>>2)<<5) | ((r>>3)<<11) ; } break; case PIXFMT_BGR16: case PIXFMT_RGB16PC: { Uint16 *t=(Uint16 *)c; *t=(r>>3) | ((g>>2)<<5) | ((b>>3)<<11) ; } break; case PIXFMT_RGB24: c[0]=r; c[1]=g; c[2]=b; c[3]=0; break; case PIXFMT_BGR24: c[0]=b; c[1]=g; c[2]=r; c[3]=0; break; case PIXFMT_ARGB32: c[0]=0; c[1]=r; c[2]=g; c[3]=b; break; case PIXFMT_BGRA32: c[0]=b; c[1]=g; c[2]=r; c[3]=0; break; case PIXFMT_RGBA32: c[0]=r; c[1]=g; c[2]=b; c[3]=0; break; default: D(bug("Error, SetSingleColor with PIXFMT %ld!\n",fmt)); }}/* Update the current mouse state and position */static void CGX_UpdateMouse(_THIS){ /* Lock the event thread, in multi-threading environments */ SDL_Lock_EventThread(); if(currently_fullscreen) { SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX, SDL_Display->MouseY); } else { if( SDL_Display->MouseX>=(SDL_Window->LeftEdge+SDL_Window->BorderLeft) && SDL_Display->MouseX<(SDL_Window->LeftEdge+SDL_Window->Width-SDL_Window->BorderRight) && SDL_Display->MouseY>=(SDL_Window->TopEdge+SDL_Window->BorderLeft) && SDL_Display->MouseY<(SDL_Window->TopEdge+SDL_Window->Height-SDL_Window->BorderBottom) ) { SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX-SDL_Window->LeftEdge-SDL_Window->BorderLeft, SDL_Display->MouseY-SDL_Window->TopEdge-SDL_Window->BorderTop); } else { SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); } } SDL_Unlock_EventThread();}static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors){ int i; /* Check to make sure we have a colormap allocated */ /* It's easy if we have a hidden colormap */ if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen ) { ULONG xcmap[256*3+2]; xcmap[0]=(ncolors<<16); xcmap[0]+=firstcolor;// D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors)); for ( i=0; i<ncolors; i++ ) { xcmap[i*3+1] = colors[i+firstcolor].r<<24; xcmap[i*3+2] = colors[i+firstcolor].g<<24; xcmap[i*3+3] = colors[i+firstcolor].b<<24; } xcmap[ncolors*3+1]=0; LoadRGB32(&GFX_Display->ViewPort,xcmap); } else {// XPixels are not needed on 8bit screen with hwpalette unsigned long pixel; if ( SDL_XPixels == NULL ) { D(bug("SetColors without colormap!")); return(0); } if(this->hidden->depth==8) {// In this case I have to unalloc and realloc the full palette D(bug("Obtaining %ld colors on the screen\n",ncolors)); /* Free existing allocated colors */ for ( pixel=0; pixel<this->screen->format->palette->ncolors; ++pixel ) { if(SDL_XPixels[pixel]>=0) ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]); } /* Try to allocate all the colors */ for ( i=0; i<this->screen->format->palette->ncolors; ++i ) { SDL_XPixels[i]=ObtainBestPenA(GFX_Display->ViewPort.ColorMap,colors[i].r<<24,colors[i].g<<24,colors[i].b<<24,NULL); } } else {#ifndef USE_CGX_WRITELUTPIXEL Uint32 fmt; D(bug("Preparing a conversion pixel table...\n")); fmt=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT); for(i=0;i<ncolors;i++) { SetSingleColor(fmt,colors[firstcolor+i].r,colors[firstcolor+i].g,colors[firstcolor+i].b,(unsigned char *)&SDL_XPixels[firstcolor+i]); }#else// D(bug("Executing XPixel(%lx) remapping: (from %ld, %ld colors) first: r%ld g%ld b%ld\n",SDL_XPixels,firstcolor,ncolors,colors[firstcolor].r,colors[firstcolor].g,colors[firstcolor].b)); for(i=0;i<ncolors;i++) SDL_XPixels[i+firstcolor]=(colors[firstcolor+i].r<<16)+(colors[firstcolor+i].g<<8)+colors[firstcolor+i].b;#endif } }// Actually it cannot fail! return 1;}/* Note: If we are terminated, this could be called in the middle of another SDL video routine -- notably UpdateRects.*/static void CGX_VideoQuit(_THIS){ /* Shutdown everything that's still up */ /* The event thread should be done, so we can touch SDL_Display */ D(bug("CGX_VideoQuit\n")); if ( SDL_Display != NULL ) { /* Clean up OpenGL */ if(this->gl_data->gl_active == 1) { CGX_GL_Quit(this); } /* Start shutting down the windows */ D(bug("Destroying image...\n")); CGX_DestroyImage(this, this->screen); D(bug("Destroying window...\n")); CGX_DestroyWindow(this, this->screen);// Otherwise SDL_VideoQuit will try to free it! SDL_VideoSurface=NULL; CGX_FreeVideoModes(this); /* Free that blank cursor */ if ( SDL_BlankCursor != NULL ) { FreeMem(SDL_BlankCursor,16); SDL_BlankCursor = NULL; } /* Close the X11 graphics connection */ this->hidden->same_format=0; D(bug("Destroying screen...\n")); if ( GFX_Display != NULL ) DestroyScreen(this); /* Close the X11 display connection */ SDL_Display = NULL; /* Unload GL library after X11 shuts down */ } D(bug("Closing libraries...\n")); if( CyberGfxBase) { CloseLibrary(CyberGfxBase); CyberGfxBase=NULL; } if (IntuitionBase) { CloseLibrary((struct Library *)IntuitionBase); IntuitionBase=NULL; } if (GfxBase) { CloseLibrary((struct Library *)GfxBase); GfxBase=NULL; } if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { /* Direct screen access, no memory buffer */ this->screen->pixels = NULL; } D(bug("End of CGX_VideoQuit.\n"));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -