Esempio n. 1
0
int win_perform_blit(const struct win_blit_params *blit, int update)
{
	int srcdepth = (blit->srcdepth + 7) / 8;
	int dstdepth = (blit->dstdepth + 7) / 8;
	struct rectangle temprect;
#ifndef _WIN64
	blitter_func blitter;
#endif
	int srcx, srcy;
	DWORD dw;

	// if we have a vector dirty array, alter the plan
	if (blit->vecdirty && !update)
		if (blit_vectors(blit))
			return 1;

	// determine the starting source X/Y
	temprect.min_x = blit->srcxoffs;
	temprect.min_y = blit->srcyoffs;
	temprect.max_x = blit->srcxoffs + blit->srcwidth - 1;
	temprect.max_y = blit->srcyoffs + blit->srcheight - 1;
	win_disorient_rect(&temprect);

	if (blit->swapxy != blit_swapxy)
	{
		blit_srcwidth = blit->srcheight;
		blit_srcheight = blit->srcwidth;
	}
	else
	{
		blit_srcwidth = blit->srcwidth;
		blit_srcheight = blit->srcheight;
	}

	if (!blit->swapxy)
	{
		srcx = blit->flipx ? (temprect.max_x + 1) : temprect.min_x;
		srcy = blit->flipy ? (temprect.max_y + 1) : temprect.min_y;
	}
	else
	{
		srcx = blit->flipy ? (temprect.max_x + 1) : temprect.min_x;
		srcy = blit->flipx ? (temprect.max_y + 1) : temprect.min_y;
	}

	// if anything important has changed, fix it
	if (blit->srcwidth != active_blitter_params.srcwidth ||
		blit->srcdepth != active_blitter_params.srcdepth ||
		blit->srcpitch != active_blitter_params.srcpitch ||
		blit->dstdepth != active_blitter_params.dstdepth ||
		blit->dstpitch != active_blitter_params.dstpitch ||
		blit->dstyskip != active_blitter_params.dstyskip ||
		blit->dstxscale != active_blitter_params.dstxscale ||
		blit->dstyscale != active_blitter_params.dstyscale ||
		blit->dsteffect != active_blitter_params.dsteffect ||
		blit->flipx != active_blitter_params.flipx ||
		blit->flipy != active_blitter_params.flipy ||
		blit->swapxy != active_blitter_params.swapxy)
	{
		// allocate memory for the blitter code and mark it as executable to avoid an access violation
		if (active_fast_blitter == NULL) active_fast_blitter = VirtualAlloc(NULL, MAX_BLITTER_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		else VirtualProtect(active_fast_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE_READWRITE, &dw);
		if (active_update_blitter == NULL) active_update_blitter = VirtualAlloc(NULL, MAX_BLITTER_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		else VirtualProtect(active_update_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE_READWRITE, &dw);

		generate_blitter(blit);

		// protect memory from external undesired changes
		VirtualProtect(active_fast_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE, &dw);
		VirtualProtect(active_update_blitter, MAX_BLITTER_SIZE, PAGE_EXECUTE, &dw);
		
		active_blitter_params = *blit;
	}

	// copy data to the globals
	asmblit_srcdata = (UINT8 *)blit->srcdata + blit->srcpitch * srcy + srcdepth * srcx;
	asmblit_srcheight = blit_srcheight;
	asmblit_srclookup = blit->srclookup;

	asmblit_dstdata = (UINT8 *)blit->dstdata + blit->dstpitch * blit->dstyoffs + dstdepth * blit->dstxoffs;
	asmblit_dstpitch = blit->dstpitch;

#ifndef _WIN64
	// pick the blitter
	blitter = update ? (blitter_func)active_update_blitter : (blitter_func)active_fast_blitter;
	(*blitter)();
#else
	if ((blit->dstdepth == 15) || (blit->dstdepth == 16))
	{
		int c, c2, s;
		const UINT8 * src = asmblit_srcdata;
		UINT8 * dst = asmblit_dstdata;

		for (c = 0; c < asmblit_srcheight; c++)
		{
			for (c2 = 0; c2 < blit->srcwidth; c2++)
			{
				const UINT16 col = blit->srclookup[((UINT16*)src)[c2]];
				for (s = 0; s < blit->dstxscale; ++s)
					((UINT16*)dst)[c2 * blit->dstxscale + s] = col;
			}
			for(s = 0; s < blit->dstyscale; ++s)
				memcpy(dst + blit->dstpitch*(s+1), dst, blit->dstpitch);
			src += blit->srcpitch;
			dst += blit->dstpitch * blit->dstyscale;
		}
	}
	else if (blit->dstdepth == 32)
	{
		int c, c2, s;
		const UINT8 * src = asmblit_srcdata;
		UINT8 * dst = asmblit_dstdata;

		for (c = 0; c < asmblit_srcheight; c++)
		{
			for (c2 = 0; c2 < blit->srcwidth; c2++)
			{
				const UINT32 col = blit->srclookup[((UINT16*)src)[c2]];
				for (s = 0; s < blit->dstxscale; ++s)
					((UINT32*)dst)[c2 * blit->dstxscale + s] = col;
			}
			for (s = 0; s < blit->dstyscale; ++s)
				memcpy(dst + blit->dstpitch*(s + 1), dst, blit->dstpitch);
			src += blit->srcpitch;
			dst += blit->dstpitch * blit->dstyscale;
		}
	}
#endif

	return 1;
}
Esempio n. 2
0
int win_perform_blit(const struct win_blit_params *blit, int update)
{
	int srcdepth = (blit->srcdepth + 7) / 8;
	int dstdepth = (blit->dstdepth + 7) / 8;
	struct rectangle temprect;
	blitter_func blitter;
	int srcx, srcy;

	// if we have a vector dirty array, alter the plan
	if (blit->vecdirty && !update)
		if (blit_vectors(blit))
			return 1;

	// determine the starting source X/Y
	temprect.min_x = blit->srcxoffs;
	temprect.min_y = blit->srcyoffs;
	temprect.max_x = blit->srcxoffs + blit->srcwidth - 1;
	temprect.max_y = blit->srcyoffs + blit->srcheight - 1;

	if (blit->swapxy || blit->flipx || blit->flipy)
		win_disorient_rect(&temprect);

	if (!blit->swapxy)
	{
		srcx = blit->flipx ? (temprect.max_x + 1) : temprect.min_x;
		srcy = blit->flipy ? (temprect.max_y + 1) : temprect.min_y;
	}
	else
	{
		srcx = blit->flipy ? (temprect.max_x + 1) : temprect.min_x;
		srcy = blit->flipx ? (temprect.max_y + 1) : temprect.min_y;
	}

	// if anything important has changed, fix it
	if (blit->srcwidth != active_blitter_params.srcwidth ||
		blit->srcdepth != active_blitter_params.srcdepth ||
		blit->srcpitch != active_blitter_params.srcpitch ||
		blit->dstdepth != active_blitter_params.dstdepth ||
		blit->dstpitch != active_blitter_params.dstpitch ||
		blit->dstyskip != active_blitter_params.dstyskip ||
		blit->dstxscale != active_blitter_params.dstxscale ||
		blit->dstyscale != active_blitter_params.dstyscale ||
		blit->dsteffect != active_blitter_params.dsteffect ||
		blit->flipx != active_blitter_params.flipx ||
		blit->flipy != active_blitter_params.flipy ||
		blit->swapxy != active_blitter_params.swapxy)
	{
		generate_blitter(blit);
		active_blitter_params = *blit;
	}

	// copy data to the globals
	asmblit_srcdata = (UINT8 *)blit->srcdata + blit->srcpitch * srcy + srcdepth * srcx;
	asmblit_srcheight = blit->srcheight;
	asmblit_srclookup = blit->srclookup;

	asmblit_dstdata = (UINT8 *)blit->dstdata + blit->dstpitch * blit->dstyoffs + dstdepth * blit->dstxoffs;
	asmblit_dstpitch = blit->dstpitch;

	// pick the blitter
	blitter = update ? (blitter_func)active_update_blitter : (blitter_func)active_fast_blitter;
	(*blitter)();
	return 1;
}