📄 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;
}
}
else
buildnewscreen:
{
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 + -