⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_cgxvideo.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 3 页
字号:
// 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 + -