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

📄 sdl_xbios.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* 8 bits -> list 0 */
	/* 16 bits -> list 1 */
	return(SDL_modelist[(format->BitsPerPixel)>>4]);
}

static void XBIOS_FreeBuffers(_THIS)
{
	int i;

	for (i=0;i<2;i++) {
		if (XBIOS_screensmem[i]!=NULL) {
			Mfree(XBIOS_screensmem[i]);
			XBIOS_screensmem[i]=NULL;
		}
	}

	if (XBIOS_shadowscreen!=NULL) {
		Mfree(XBIOS_shadowscreen);
		XBIOS_shadowscreen=NULL;
	}
}

static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
				int width, int height, int bpp, Uint32 flags)
{
	int mode, new_depth;
	int i;
	xbiosmode_t *new_video_mode;
	Uint32 new_screen_size;
	Uint32 modeflags;

	/* Free current buffers */
	XBIOS_FreeBuffers(this);

	/* Search if the mode exists (width, height, bpp) */
	bpp >>= 4;
	for ( mode=0; SDL_modelist[bpp][mode]; ++mode ) {
		if ( (SDL_modelist[bpp][mode]->w == width) &&
		     (SDL_modelist[bpp][mode]->h == height) ) {

			break;
		}
	}
	if ( SDL_modelist[bpp][mode] == NULL ) {
		SDL_SetError("Couldn't find requested mode in list");
		return(NULL);
	}

	modeflags = (SDL_FULLSCREEN|SDL_HWPALETTE);

	/* Allocate needed buffers: simple/double buffer and shadow surface */
	new_video_mode = XBIOS_videomodes[bpp][mode];
	new_depth = new_video_mode->depth;
	if (new_depth == 4) {
		Atari_C2pInit = Atari_C2pInit4;
		if (atari_cpu060_avail) {
			Atari_C2pConvert = Atari_C2pConvert4_060;
		} else {
			Atari_C2pConvert = Atari_C2pConvert4;
		}
		new_depth=8;
		modeflags |= SDL_SWSURFACE;
	} else if (new_depth == 8) {
		Atari_C2pInit = Atari_C2pInit8;
		if (atari_cpu060_avail) {
			Atari_C2pConvert = Atari_C2pConvert8_060;
		} else {
			Atari_C2pConvert = Atari_C2pConvert8;
		}
		modeflags |= SDL_SWSURFACE;
	} else {
		modeflags |= SDL_HWSURFACE;
	}

	new_screen_size = width * height * ((new_depth)>>3);
	new_screen_size += 256; /* To align on a 256 byte adress */	

	if (new_depth == 8) {
		XBIOS_shadowscreen = Atari_SysMalloc(new_screen_size, MX_PREFTTRAM);

		if (XBIOS_shadowscreen == NULL) {
			SDL_SetError("XBIOS_SetVideoMode: Not enough memory for shadow surface");
			return (NULL);
		}
		memset(XBIOS_shadowscreen, 0, new_screen_size);
	}

	/* Output buffer needs to be twice in size for the software double-line mode */
	XBIOS_doubleline = SDL_FALSE;
	if (new_video_mode->doubleline) {
		new_screen_size <<= 1;
		XBIOS_doubleline = SDL_TRUE;
	}

	XBIOS_screensmem[0] = Atari_SysMalloc(new_screen_size, MX_STRAM);

	if (XBIOS_screensmem[0]==NULL) {
		XBIOS_FreeBuffers(this);
		SDL_SetError("XBIOS_SetVideoMode: Not enough memory for video buffer");
		return (NULL);
	}
	memset(XBIOS_screensmem[0], 0, new_screen_size);

	XBIOS_screens[0]=(void *) (( (long) XBIOS_screensmem[0]+256) & 0xFFFFFF00UL);

	/* Double buffer ? */
	if (flags & SDL_DOUBLEBUF) {
		XBIOS_screensmem[1] = Atari_SysMalloc(new_screen_size, MX_STRAM);

		if (XBIOS_screensmem[1]==NULL) {
			XBIOS_FreeBuffers(this);
			SDL_SetError("XBIOS_SetVideoMode: Not enough memory for double buffer");
			return (NULL);
		}
		memset(XBIOS_screensmem[1], 0, new_screen_size);

		XBIOS_screens[1]=(void *) (( (long) XBIOS_screensmem[1]+256) & 0xFFFFFF00UL);
		modeflags |= SDL_DOUBLEBUF;
	}
	
	/* Allocate the new pixel format for the screen */
	if ( ! SDL_ReallocFormat(current, new_depth, 0, 0, 0, 0) ) {
		XBIOS_FreeBuffers(this);
		SDL_SetError("Couldn't allocate new pixel format for requested mode");
		return(NULL);
	}

	current->flags = modeflags;
	current->w = XBIOS_width = width;
	current->h = XBIOS_height = height;
	current->pitch = (width * new_depth)>>3;

	/* this is for C2P conversion */
	XBIOS_pitch = (new_video_mode->width * new_video_mode->depth)>>3;

	if (new_depth == 8)
		current->pixels = XBIOS_shadowscreen;
	else
		current->pixels = XBIOS_screens[0];

	XBIOS_fbnum = 0;

	/* Now set the video mode */
	Setscreen(-1,XBIOS_screens[0],-1);

	switch(XBIOS_cvdo >> 16) {
		case VDO_ST:
			Setscreen(-1,-1,new_video_mode->number);
			/* Reset palette */
			for (i=0;i<16;i++) {
				int c;

				c = ((i>>1)<<8) | ((i>>1)<<4) | (i>>1);
				if ((i & 1) && (i<15))
					c += (1<<4);
				if (i==14)
					c -= 1<<8;

				TT_palette[i]= c;
			}
			Setpalette(TT_palette);
			break;
		case VDO_STE:
			Setscreen(-1,-1,new_video_mode->number);
			/* Reset palette */
			for (i=0;i<16;i++)
			{
				int c;

				c=((i&1)<<3)|((i>>1)&7);
				TT_palette[i]=(c<<8)|(c<<4)|c;
			}
			Setpalette(TT_palette);
			break;
		case VDO_TT:
			EsetShift(new_video_mode->number);
			break;
		case VDO_F30:
			Vsetmode(new_video_mode->number);
			break;
	}

	Vsync();

	this->UpdateRects = XBIOS_UpdateRects;

	return (current);
}

/* We don't actually allow hardware surfaces other than the main one */
static int XBIOS_AllocHWSurface(_THIS, SDL_Surface *surface)
{
	return(-1);
}

static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

static int XBIOS_LockHWSurface(_THIS, SDL_Surface *surface)
{
	return(0);
}

static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
{
	SDL_Surface *surface;

	surface = this->screen;

	if ((surface->format->BitsPerPixel) == 8) {
		void *destscr;
		int destx;
		int i;

		/* Center on destination screen */
		destscr = XBIOS_screens[XBIOS_fbnum];
		destscr += XBIOS_pitch * ((XBIOS_height - surface->h) >> 1);
		destx = (XBIOS_width - surface->w) >> 1;
		destx &= ~15;
		destscr += destx;

		for (i=0;i<numrects;i++) {
			void *source,*destination;
			int x1,x2;

			x1 = rects[i].x & ~15;
			x2 = rects[i].x+rects[i].w;
			if (x2 & 15) {
				x2 = (x2 | 15) +1;
			}

			source = surface->pixels;
			source += surface->pitch * rects[i].y;
			source += x1;

			destination = destscr;
			destination += XBIOS_pitch * rects[i].y;
			destination += x1;

			/* Convert chunky to planar screen */
			Atari_C2pConvert(
				source,
				destination,
				x2-x1,
				rects[i].h,
				XBIOS_doubleline,
				surface->pitch,
				XBIOS_pitch
			);
		}
	}

	Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1);
	Vsync();

	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
		XBIOS_fbnum ^= 1;
		if ((surface->format->BitsPerPixel) > 8) {
			surface->pixels=XBIOS_screens[XBIOS_fbnum];
		}
	}
}

static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface)
{
	if ((surface->format->BitsPerPixel) == 8) {
		void *destscr;
		int destx;
			
		/* Center on destination screen */
		destscr = XBIOS_screens[XBIOS_fbnum];
		destscr += XBIOS_pitch * ((XBIOS_height - surface->h) >> 1);
		destx = (XBIOS_width - surface->w) >> 1;
		destx &= ~15;
		destscr += destx;

		/* Convert chunky to planar screen */
		Atari_C2pConvert(
			surface->pixels,
			destscr,
			surface->w,
			surface->h,
			XBIOS_doubleline,
			surface->pitch,
			XBIOS_pitch
		);
	}

	Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1);
	Vsync();

	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
		XBIOS_fbnum ^= 1;
		if ((surface->format->BitsPerPixel) > 8) {
			surface->pixels=XBIOS_screens[XBIOS_fbnum];
		}
	}

	return(0);
}

static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
	int		i;
	int		r,v,b;

	switch( XBIOS_cvdo >> 16) {
		case VDO_ST:
		case VDO_STE:
		 	for (i=0;i<ncolors;i++)
			{
				r = colors[i].r;	
				v = colors[i].g;
				b = colors[i].b;

				TT_palette[firstcolor+i]=((r*30)+(v*59)+(b*11))/100;
			}
			Atari_C2pConvert4_pal(TT_palette); /* convert the lighting */
			break;
		case VDO_TT:
			for(i = 0; i < ncolors; i++)
			{
				r = colors[i].r;	
				v = colors[i].g;
				b = colors[i].b;
					
				TT_palette[i]=((r>>4)<<8)|((v>>4)<<4)|(b>>4);
			}
			EsetPalette(firstcolor,ncolors,TT_palette);
			break;
		case VDO_F30:
			for(i = 0; i < ncolors; i++)
			{
				r = colors[i].r;	
				v = colors[i].g;
				b = colors[i].b;

				F30_palette[i]=(r<<16)|(v<<8)|b;
			}
			VsetRGB(firstcolor,ncolors,F30_palette);
			break;
	}

	return(1);
}

/* Note:  If we are terminated, this could be called in the middle of
   another SDL video routine -- notably UpdateRects.
*/
static void XBIOS_VideoQuit(_THIS)
{
	int i,j;

	Atari_ShutdownEvents();

	/* Restore video mode and palette */
	switch(XBIOS_cvdo >> 16) {
		case VDO_ST:
		case VDO_STE:
			Setscreen(-1,XBIOS_oldvbase,XBIOS_oldvmode);
			if (XBIOS_oldnumcol) {
				Setpalette(XBIOS_oldpalette);
			}
			break;
		case VDO_TT:
			Setscreen(-1,XBIOS_oldvbase,-1);
			EsetShift(XBIOS_oldvmode);
			if (XBIOS_oldnumcol) {
				EsetPalette(0, XBIOS_oldnumcol, XBIOS_oldpalette);
			}
			break;
		case VDO_F30:
			Setscreen(-1, XBIOS_oldvbase, -1);
			Vsetmode(XBIOS_oldvmode);
			if (XBIOS_oldnumcol) {
				VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
			}
			break;
	}
	Vsync();

	if (XBIOS_oldpalette) {
		free(XBIOS_oldpalette);
		XBIOS_oldpalette=NULL;
	}
	XBIOS_FreeBuffers(this);

	/* Free mode list */
	for (j=0;j<NUM_MODELISTS;j++) {
		for (i=0;i<SDL_NUMMODES;i++) {
			if (SDL_modelist[j][i]!=NULL) {
				free(SDL_modelist[j][i]);
				SDL_modelist[j][i]=NULL;
			}
		}
	}

	this->screen->pixels = NULL;	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -