Example #1
0
INLINE void render_quad(sdl_info *sdl, texture_info *texture, render_primitive *prim, int x, int y)
{
	SDL_Texture	*texture_id;
	SDL_Rect target_rect;

	target_rect.x = x;
	target_rect.y = y;
	target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0);
	target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0);

	if (texture)
	{
		texture_id = texture->texture_id;

		texture->copyinfo->time -= osd_ticks();
#if 0
		if ((PRIMFLAG_GET_SCREENTEX(prim->flags)) && video_config.filter)
		{
			SDL_SetTextureScaleMode(texture->texture_id,  DRAW2_SCALEMODE_BEST);
		}
		else
		{
			SDL_SetTextureScaleMode(texture->texture_id,  DRAW2_SCALEMODE_NEAREST);
		}
#endif
		SDL_SetTextureBlendMode(texture_id, texture->sdl_blendmode);
		set_coloralphamode(texture_id, &prim->color);
		SDL_RenderCopy(sdl->sdl_renderer,  texture_id, NULL, &target_rect);
		texture->copyinfo->time += osd_ticks();

		texture->copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->rawwidth * texture->rawheight));
		if (sdl->last_blit_pixels)
		{
			texture->copyinfo->time += (sdl->last_blit_time * (INT64) (texture->rawwidth * texture->rawheight)) / (INT64) sdl->last_blit_pixels;
		}
		texture->copyinfo->samples++;
		texture->copyinfo->perf = ( texture->copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->copyinfo->time;
	}
	else
	{
		UINT32 sr = (UINT32)(255.0f * prim->color.r);
		UINT32 sg = (UINT32)(255.0f * prim->color.g);
		UINT32 sb = (UINT32)(255.0f * prim->color.b);
		UINT32 sa = (UINT32)(255.0f * prim->color.a);

		SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)));
		SDL_SetRenderDrawColor(sdl->sdl_renderer, sr, sg, sb, sa);
		SDL_RenderFillRect(sdl->sdl_renderer, &target_rect);
	}
}
Example #2
0
void renderer_sdl2::render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y)
{
	SDL_Rect target_rect;

	target_rect.x = x;
	target_rect.y = y;
	target_rect.w = round_nearest(prim.bounds.x1 - prim.bounds.x0);
	target_rect.h = round_nearest(prim.bounds.y1 - prim.bounds.y0);

	if (texture)
	{
		copy_info_t *copyinfo = texture->m_copyinfo;
		copyinfo->time -= osd_ticks();
		texture->render_quad(prim, x, y);
		copyinfo->time += osd_ticks();

		copyinfo->pixel_count += std::max(STAT_PIXEL_THRESHOLD , (texture->raw_width() * texture->raw_height()));
		if (m_last_blit_pixels)
		{
			copyinfo->time += (m_last_blit_time * (INT64) (texture->raw_width() * texture->raw_height())) / (INT64) m_last_blit_pixels;
		}
		copyinfo->samples++;
		copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time;
	}
	else
	{
		UINT32 sr = (UINT32)(255.0f * prim.color.r);
		UINT32 sg = (UINT32)(255.0f * prim.color.g);
		UINT32 sb = (UINT32)(255.0f * prim.color.b);
		UINT32 sa = (UINT32)(255.0f * prim.color.a);

		SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags)));
		SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa);
		SDL_RenderFillRect(m_sdl_renderer, &target_rect);
	}
}
Example #3
0
static int drawdd_window_draw(win_window_info *window, HDC dc, int update)
{
	dd_info *dd = window->drawdata;
	const render_primitive *prim;
	int usemembuffer = FALSE;
	HRESULT result;

	// if we haven't been created, just punt
	if (dd == NULL)
		return 1;

	// if we're updating, remember to erase the outer stuff
	if (update)
		update_outer_rects(dd);

	// if we have a ddraw object, check the cooperative level
	if (ddraw_test_cooperative(window))
		return 1;

	// get the size; if we're too small, delete the existing surfaces
	if (dd->blitwidth > dd->blitdesc.dwWidth || dd->blitheight > dd->blitdesc.dwHeight)
		ddraw_delete_surfaces(window);

	// if we need to create surfaces, do it now
	if (dd->blit == NULL && ddraw_create_surfaces(window) != 0)
		return 1;

	// select our surface and lock it
	result = IDirectDrawSurface7_Lock(dd->blit, NULL, &dd->blitdesc, DDLOCK_WAIT, NULL);
	if (result == DDERR_SURFACELOST)
	{
		mame_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n");
		ddraw_delete_surfaces(window);
		return 1;
	}
	if (result != DD_OK)
	{
		mame_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result);
		return 1;
	}

	// render to it
	osd_lock_acquire(window->primlist->lock);

	// scan the list of primitives for tricky stuff
	for (prim = window->primlist->head; prim != NULL; prim = prim->next)
		if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE ||
			(prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32))
		{
			usemembuffer = TRUE;
			break;
		}

	// if we're using the memory buffer, draw offscreen first and then copy
	if (usemembuffer)
	{
		int x, y;

		// based on the target format, use one of our standard renderers
		switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000: 	drawdd_rgb888_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);	break;
			case 0x000000ff:	drawdd_bgr888_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);	break;
			case 0xf800:		drawdd_rgb565_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);	break;
			case 0x7c00:		drawdd_rgb555_draw_primitives(window->primlist->head, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);	break;
			default:
				mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}

		// handle copying to both 16bpp and 32bpp destinations
		for (y = 0; y < dd->blitheight; y++)
		{
			if (dd->blitdesc.ddpfPixelFormat.dwRGBBitCount == 32)
			{
				UINT32 *src = (UINT32 *)dd->membuffer + y * dd->blitwidth;
				UINT32 *dst = (UINT32 *)((UINT8 *)dd->blitdesc.lpSurface + y * dd->blitdesc.lPitch);
				for (x = 0; x < dd->blitwidth; x++)
					*dst++ = *src++;
			}
			else if (dd->blitdesc.ddpfPixelFormat.dwRGBBitCount == 16)
			{
				UINT16 *src = (UINT16 *)dd->membuffer + y * dd->blitwidth;
				UINT16 *dst = (UINT16 *)((UINT8 *)dd->blitdesc.lpSurface + y * dd->blitdesc.lPitch);
				for (x = 0; x < dd->blitwidth; x++)
					*dst++ = *src++;
			}
		}

	}

	// otherwise, draw directly
	else
	{
		// based on the target format, use one of our standard renderers
		switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000: 	drawdd_rgb888_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4);	break;
			case 0x000000ff:	drawdd_bgr888_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4);	break;
			case 0xf800:		drawdd_rgb565_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2);	break;
			case 0x7c00:		drawdd_rgb555_nr_draw_primitives(window->primlist->head, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2);	break;
			default:
				mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}
	}
	osd_lock_release(window->primlist->lock);

	// unlock and blit
	result = IDirectDrawSurface7_Unlock(dd->blit, NULL);
	if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result);

	// sync to VBLANK
	if ((video_config.waitvsync || video_config.syncrefresh) && video_get_throttle() && (!window->fullscreen || dd->back == NULL))
	{
		result = IDirectDraw7_WaitForVerticalBlank(dd->ddraw, DDWAITVB_BLOCKBEGIN, NULL);
		if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
	}

	// complete the blitting
	blit_to_primary(window, dd->blitwidth, dd->blitheight);
	return 0;
}
Example #4
0
texture_info::texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags)
{
	// fill in the core data
	m_renderer = renderer;
	m_hash = texture_compute_hash(texsource, flags);
	m_flags = flags;
	m_texinfo = texsource;
	m_texinfo.seqid = -1; // force set data
	m_is_rotated = false;
	m_setup = setup;
	m_sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags));
	m_pitch = 0;

	switch (PRIMFLAG_GET_TEXFORMAT(flags))
	{
		case TEXFORMAT_ARGB32:
			m_format = SDL_TEXFORMAT_ARGB32;
			break;
		case TEXFORMAT_RGB32:
			m_format = texsource.palette ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32;
			break;
		case TEXFORMAT_PALETTE16:
			m_format = SDL_TEXFORMAT_PALETTE16;
			break;
		case TEXFORMAT_PALETTEA16:
			m_format = SDL_TEXFORMAT_PALETTE16A;
			break;
		case TEXFORMAT_YUY16:
			m_format = texsource.palette ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16;
			break;

		default:
			osd_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags));
	}

	if (setup.rotwidth != m_texinfo.width || setup.rotheight != m_texinfo.height
			|| setup.dudx < 0 || setup.dvdy < 0 || (PRIMFLAG_GET_TEXORIENT(flags) != 0))
		m_is_rotated = true;
	else
		m_is_rotated = false;

	//m_sdl_access = SDL_TEXTUREACCESS_STATIC;
	m_sdl_access = SDL_TEXTUREACCESS_STREAMING;

	// Watch out for 0x0 textures ...
	if (!m_setup.rotwidth || !m_setup.rotheight)
		osd_printf_warning("Trying to create texture with zero dim\n");

	// set copy_info

	m_copyinfo = compute_size_type();

	m_texture_id = SDL_CreateTexture(m_renderer->m_sdl_renderer, m_copyinfo->dst_fmt, m_sdl_access,
			m_setup.rotwidth, m_setup.rotheight);

	if (!m_texture_id)
		osd_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", m_setup.rotwidth, m_setup.rotheight,
				m_copyinfo->dstname, SDL_GetError());

	if (m_sdl_access == SDL_TEXTUREACCESS_STATIC)
	{
		if (m_copyinfo->blitter->m_is_passthrough)
			m_pixels = nullptr;
		else
			m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->blitter->m_dest_bpp);
	}
	m_last_access = osd_ticks();

}
Example #5
0
int renderer_sdl2::draw(int update)
{
	texture_info *texture=nullptr;
	float vofs, hofs;
	int blit_pixels = 0;

	if (video_config.novideo)
	{
		return 0;
	}

	auto win = assert_window();
	osd_dim wdim = win->get_size();

	if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
	{
		destroy_all_textures();
		m_width = wdim.width();
		m_height = wdim.height();
		SDL_RenderSetViewport(m_sdl_renderer, nullptr);
		m_blittimer = 3;
		clear_flags(FI_CHANGED);
	}

	//SDL_SelectRenderer(window().sdl_window);

	if (m_blittimer > 0)
	{
		/* SDL Underlays need alpha = 0 ! */
		SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_NONE);
		//SDL_SetRenderDrawColor(0,0,0,255);
		SDL_SetRenderDrawColor(m_sdl_renderer, 0,0,0,0);
		SDL_RenderFillRect(m_sdl_renderer, nullptr);
		m_blittimer--;
	}

	// compute centering parameters
	vofs = hofs = 0.0f;

	if (video_config.centerv || video_config.centerh)
	{
		int ch, cw;

		ch = wdim.height();
		cw = wdim.width();

		if (video_config.centerv)
		{
			vofs = (ch - m_blit_dim.height()) / 2.0f;
		}
		if (video_config.centerh)
		{
			hofs = (cw - m_blit_dim.width()) / 2.0f;
		}
	}

	m_last_hofs = hofs;
	m_last_vofs = vofs;

	win->m_primlist->acquire_lock();

	// now draw
	for (render_primitive &prim : *win->m_primlist)
	{
		Uint8 sr, sg, sb, sa;

		switch (prim.type)
		{
			case render_primitive::LINE:
				sr = (int)(255.0f * prim.color.r);
				sg = (int)(255.0f * prim.color.g);
				sb = (int)(255.0f * prim.color.b);
				sa = (int)(255.0f * prim.color.a);

				SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim.flags)));
				SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa);
				SDL_RenderDrawLine(m_sdl_renderer, prim.bounds.x0 + hofs, prim.bounds.y0 + vofs,
						prim.bounds.x1 + hofs, prim.bounds.y1 + vofs);
				break;
			case render_primitive::QUAD:
				texture = texture_update(prim);
				if (texture)
					blit_pixels += (texture->raw_height() * texture->raw_width());
				render_quad(texture, prim,
						round_nearest(hofs + prim.bounds.x0),
						round_nearest(vofs + prim.bounds.y0));
				break;
			default:
				throw emu_fatalerror("Unexpected render_primitive type\n");
		}
	}

	win->m_primlist->release_lock();

	m_last_blit_pixels = blit_pixels;
	m_last_blit_time = -osd_ticks();
	SDL_RenderPresent(m_sdl_renderer);
	m_last_blit_time += osd_ticks();

	return 0;
}
Example #6
0
void renderer_bgfx::render_textured_quad(int view, render_primitive* prim, bgfx::TransientVertexBuffer* buffer)
{
	ScreenVertex* vertex = (ScreenVertex*)buffer->data;

	UINT32 rgba = u32Color(prim->color.r * 255, prim->color.g * 255, prim->color.b * 255, prim->color.a * 255);

	vertex[0].m_x = prim->bounds.x0;
	vertex[0].m_y = prim->bounds.y0;
	vertex[0].m_z = 0;
	vertex[0].m_rgba = rgba;
	vertex[0].m_u = prim->texcoords.tl.u;
	vertex[0].m_v = prim->texcoords.tl.v;

	vertex[1].m_x = prim->bounds.x1;
	vertex[1].m_y = prim->bounds.y0;
	vertex[1].m_z = 0;
	vertex[1].m_rgba = rgba;
	vertex[1].m_u = prim->texcoords.tr.u;
	vertex[1].m_v = prim->texcoords.tr.v;

	vertex[2].m_x = prim->bounds.x1;
	vertex[2].m_y = prim->bounds.y1;
	vertex[2].m_z = 0;
	vertex[2].m_rgba = rgba;
	vertex[2].m_u = prim->texcoords.br.u;
	vertex[2].m_v = prim->texcoords.br.v;

	vertex[3].m_x = prim->bounds.x1;
	vertex[3].m_y = prim->bounds.y1;
	vertex[3].m_z = 0;
	vertex[3].m_rgba = rgba;
	vertex[3].m_u = prim->texcoords.br.u;
	vertex[3].m_v = prim->texcoords.br.v;

	vertex[4].m_x = prim->bounds.x0;
	vertex[4].m_y = prim->bounds.y1;
	vertex[4].m_z = 0;
	vertex[4].m_rgba = rgba;
	vertex[4].m_u = prim->texcoords.bl.u;
	vertex[4].m_v = prim->texcoords.bl.v;

	vertex[5].m_x = prim->bounds.x0;
	vertex[5].m_y = prim->bounds.y0;
	vertex[5].m_z = 0;
	vertex[5].m_rgba = rgba;
	vertex[5].m_u = prim->texcoords.tl.u;
	vertex[5].m_v = prim->texcoords.tl.v;
	bgfx::setVertexBuffer(buffer);

	uint32_t texture_flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP;
	if (video_config.filter == 0)
	{
		texture_flags |= BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT;
	}

	const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK,
		prim->texture.width, prim->texture.height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);

	bgfx::TextureHandle texture = bgfx::createTexture2D((uint16_t)prim->texture.width, (uint16_t)prim->texture.height, 1, bgfx::TextureFormat::RGBA8, texture_flags, mem);

	bgfx_effect** effects = PRIMFLAG_GET_SCREENTEX(prim->flags) ? m_screen_effect : m_gui_effect;
	UINT32 blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
	bgfx::setTexture(0, effects[blend]->uniform("s_tex")->handle(), texture);
	effects[blend]->submit(view);

	bgfx::destroyTexture(texture);
}
Example #7
0
static texture_info *texture_create(sdl_window_info *window, const render_texinfo *texsource, quad_setup_data *setup, UINT32 flags)
{
	sdl_info *sdl = (sdl_info *) window->dxdata;
	texture_info *texture;

	// allocate a new texture
	texture = (texture_info *) osd_malloc(sizeof(*texture));
	memset(texture, 0, sizeof(*texture));

	// fill in the core data
	texture->hash = texture_compute_hash(texsource, flags);
	texture->flags = flags;
	texture->texinfo = *texsource;
	texture->texinfo.seqid = -1; // force set data
	texture->is_rotated = FALSE;
	texture->setup = *setup;
	texture->sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags));

	switch (PRIMFLAG_GET_TEXFORMAT(flags))
	{
		case TEXFORMAT_ARGB32:
			texture->format = SDL_TEXFORMAT_ARGB32;
			break;
		case TEXFORMAT_RGB32:
            texture->format = texsource->palette ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32;
			break;
		case TEXFORMAT_PALETTE16:
			texture->format = SDL_TEXFORMAT_PALETTE16;
			break;
		case TEXFORMAT_PALETTEA16:
			texture->format = SDL_TEXFORMAT_PALETTE16A;
			break;
		case TEXFORMAT_YUY16:
			texture->format = texsource->palette ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16;
			break;

		default:
			mame_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags));
	}

	texture->rawwidth = texsource->width;
	texture->rawheight = texsource->height;
	if (setup->rotwidth != texture->rawwidth || setup->rotheight != texture->rawheight
			|| setup->dudx < 0 )
		texture->is_rotated = TRUE;
	else
		texture->is_rotated = FALSE;

	//texture->sdl_access = SDL_TEXTUREACCESS_STATIC;
	texture->sdl_access = SDL_TEXTUREACCESS_STREAMING;

	// Watch out for 0x0 textures ...
	if (!texture->setup.rotwidth || !texture->setup.rotheight)
		mame_printf_warning("Trying to create texture with zero dim\n");

	// compute the size
	texture->copyinfo = texture_compute_size_type(sdl->sdl_renderer, texsource, texture, flags);

	texture->texture_id = SDL_CreateTexture(sdl->sdl_renderer, texture->copyinfo->dst_fmt, texture->sdl_access,
			texture->setup.rotwidth, texture->setup.rotheight);

	if (!texture->texture_id)
		mame_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", texture->setup.rotwidth, texture->setup.rotheight,
				texture->copyinfo->dstname, SDL_GetError());

	if ( (texture->copyinfo->func != NULL) && (texture->sdl_access == SDL_TEXTUREACCESS_STATIC))
	{
		texture->pixels = osd_malloc_array(texture->setup.rotwidth * texture->setup.rotheight * texture->copyinfo->dst_bpp);
	 texture->pixels_own=TRUE;
 }
	/* add us to the texture list */
	texture->next = sdl->texlist;
	sdl->texlist = texture;

	texture->last_access = osd_ticks();

	return texture;
}
Example #8
0
static int draw13_window_draw(sdl_window_info *window, UINT32 dc, int update)
{
	sdl_info *sdl = (sdl_info *) window->dxdata;
	render_primitive *prim;
	texture_info *texture=NULL;
	float vofs, hofs;
	int blit_pixels = 0;

	if (video_config.novideo)
	{
		return 0;
	}

    if (sdl->resize_pending)
	{
		SDL_SetWindowSize(window->sdl_window, sdl->resize_width, sdl->resize_height);
		SDL_GetWindowSize(window->sdl_window, &window->width, &window->height);
		sdl->resize_pending = 0;
		SDL_RenderSetViewport(sdl->sdl_renderer, NULL);
	}

    //SDL_SelectRenderer(window->sdl_window);

	if (sdl->blittimer > 0)
	{
		/* SDL Underlays need alpha = 0 ! */
		SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, SDL_BLENDMODE_NONE);
		//SDL_SetRenderDrawColor(0,0,0,255);
		SDL_SetRenderDrawColor(sdl->sdl_renderer, 0,0,0,0);
		SDL_RenderFillRect(sdl->sdl_renderer, NULL);
		sdl->blittimer--;
	}

	// compute centering parameters
	vofs = hofs = 0.0f;

	if (video_config.centerv || video_config.centerh)
	{
		int ch, cw;

		if ((window->fullscreen) && (!video_config.switchres))
		{
			ch = window->monitor->center_height;
			cw = window->monitor->center_width;
		}
		else
		{
			ch = window->height;
			cw = window->width;
		}

		if (video_config.centerv)
		{
			vofs = (ch - window->blitheight) / 2.0f;
		}
		if (video_config.centerh)
		{
			hofs = (cw - window->blitwidth) / 2.0f;
		}
	}

	sdl->last_hofs = hofs;
	sdl->last_vofs = vofs;

	window->primlist->acquire_lock();

	// now draw
	for (prim = window->primlist->first(); prim != NULL; prim = prim->next())
	{
		Uint8 sr, sg, sb, sa;

		switch (prim->type)
		{
			case render_primitive::LINE:
				sr = (int)(255.0f * prim->color.r);
				sg = (int)(255.0f * prim->color.g);
				sb = (int)(255.0f * prim->color.b);
				sa = (int)(255.0f * prim->color.a);

				SDL_SetRenderDrawBlendMode(sdl->sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)));
				SDL_SetRenderDrawColor(sdl->sdl_renderer, sr, sg, sb, sa);
				SDL_RenderDrawLine(sdl->sdl_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs,
						prim->bounds.x1 + hofs, prim->bounds.y1 + vofs);
				break;
			case render_primitive::QUAD:
				texture = texture_update(window, prim);
				if (texture)
					blit_pixels += (texture->rawheight * texture->rawwidth);
				render_quad(sdl, texture, prim,
						round_nearest(hofs + prim->bounds.x0),
						round_nearest(vofs + prim->bounds.y0));
				break;
			default:
				throw emu_fatalerror("Unexpected render_primitive type\n");
		}
	}

	window->primlist->release_lock();

	sdl->last_blit_pixels = blit_pixels;
	sdl->last_blit_time = -osd_ticks();
	SDL_RenderPresent(sdl->sdl_renderer);
	sdl->last_blit_time += osd_ticks();

	return 0;
}
Example #9
0
static void draw_quad(render_primitive *prim) {
    void * texture = (prim->texture.base);

    //void Xe_SetBlendControl(struct XenosDevice *xe, int col_src, int col_op, int col_dst, int alpha_src, int alpha_op, int alpha_dst);
    switch (PRIMFLAG_GET_BLENDMODE(prim->flags)) {
        case BLENDMODE_NONE:
            Xe_SetAlphaTestEnable(g_pVideoDevice,0);
            Xe_SetBlendOp(g_pVideoDevice, XE_BLENDOP_ADD);
            Xe_SetSrcBlend(g_pVideoDevice, XE_BLEND_SRCALPHA);
            Xe_SetDestBlend(g_pVideoDevice, XE_BLEND_INVSRCALPHA);
            break;
        case BLENDMODE_ALPHA:
            Xe_SetAlphaTestEnable(g_pVideoDevice,1);
            Xe_SetBlendOp(g_pVideoDevice, XE_BLENDOP_ADD);
            Xe_SetSrcBlend(g_pVideoDevice, XE_BLEND_SRCALPHA);
            Xe_SetDestBlend(g_pVideoDevice, XE_BLEND_INVSRCALPHA);
            break;
        case BLENDMODE_RGB_MULTIPLY:
            Xe_SetAlphaTestEnable(g_pVideoDevice,1);
            Xe_SetBlendOp(g_pVideoDevice, XE_BLENDOP_ADD);
            Xe_SetSrcBlend(g_pVideoDevice, XE_BLEND_DESTCOLOR);
            Xe_SetDestBlend(g_pVideoDevice, XE_BLEND_ZERO);
            break;
        case BLENDMODE_ADD:
            Xe_SetAlphaTestEnable(g_pVideoDevice,1);
            Xe_SetBlendOp(g_pVideoDevice, XE_BLENDOP_ADD);
            Xe_SetSrcBlend(g_pVideoDevice, XE_BLEND_SRCALPHA);
            Xe_SetDestBlend(g_pVideoDevice, XE_BLEND_ONE);
            break;
    }

    DrawVerticeFormats *vertex = (DrawVerticeFormats *) Xe_VB_Lock(g_pVideoDevice, vb, nb_vertices, 3 * sizeof (DrawVerticeFormats), XE_LOCK_WRITE);
    memset(vertex, 0, 3 * sizeof (DrawVerticeFormats));
    {
        vertex[0].x = prim->bounds.x0 - 0.5f;
        vertex[0].y = prim->bounds.y0 - 0.5f;
        vertex[1].x = prim->bounds.x1 - 0.5f;
        vertex[1].y = prim->bounds.y0 - 0.5f;
        vertex[2].x = prim->bounds.x0 - 0.5f;
        vertex[2].y = prim->bounds.y1 - 0.5f;
        vertex[3].x = prim->bounds.x1 - 0.5f;
        vertex[3].y = prim->bounds.y1 - 0.5f;

        // set the texture coordinates
        if (texture != NULL) {
            vertex[0].u = prim->texcoords.tl.u;
            vertex[0].v = prim->texcoords.tl.v;
            vertex[1].u = prim->texcoords.tr.u;
            vertex[1].v = prim->texcoords.tr.v;
            vertex[2].u = prim->texcoords.bl.u;
            vertex[2].v = prim->texcoords.bl.v;
            vertex[3].u = prim->texcoords.br.u;
            vertex[3].v = prim->texcoords.br.v;
            n++;
        }

        XeColor color;
        color.r = (prim->color.r * 255.0f);
        color.g = (prim->color.g * 255.0f);
        color.b = (prim->color.b * 255.0f);
        color.a = (prim->color.a * 255.0f);

        int i = 0;
        for (i = 0; i < 3; i++) {
            vertex[i].z = 0.0;
            vertex[i].w = 1.0;
        }
    }


    Xe_VB_Unlock(g_pVideoDevice, vb);

    Xe_SetStreamSource(g_pVideoDevice, 0, vb, nb_vertices, sizeof (DrawVerticeFormats));
    Xe_DrawPrimitive(g_pVideoDevice, XE_PRIMTYPE_RECTLIST, 0, 1);

    nb_vertices += 256;
}
Example #10
0
int renderer_dd::draw(const int update)
{
	render_primitive *prim;
	int usemembuffer = FALSE;
	HRESULT result;

	// if we're updating, remember to erase the outer stuff
	if (update)
		update_outer_rects();

	// if we have a ddraw object, check the cooperative level
	if (ddraw_test_cooperative())
		return 1;

	// get the size; if we're too small, delete the existing surfaces
	if (blitwidth > blitdesc.dwWidth || blitheight > blitdesc.dwHeight)
		ddraw_delete_surfaces();

	// if we need to create surfaces, do it now
	if (blit == NULL && ddraw_create_surfaces() != 0)
		return 1;

	// select our surface and lock it
	result = IDirectDrawSurface7_Lock(blit, NULL, &blitdesc, DDLOCK_WAIT, NULL);
	if (result == DDERR_SURFACELOST)
	{
		osd_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n");
		ddraw_delete_surfaces();
		return 1;
	}
	if (result != DD_OK)
	{
		osd_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result);
		return 1;
	}

	// render to it
	window().m_primlist->acquire_lock();

	// scan the list of primitives for tricky stuff
	for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
		if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE ||
			(prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32))
		{
			usemembuffer = TRUE;
			break;
		}

	// if we're using the memory buffer, draw offscreen first and then copy
	if (usemembuffer)
	{
		int x, y;

		// based on the target format, use one of our standard renderers
		switch (blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
			default:
				osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}

		// handle copying to both 16bpp and 32bpp destinations
		for (y = 0; y < blitheight; y++)
		{
			if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 32)
			{
				UINT32 *src = (UINT32 *)membuffer + y * blitwidth;
				UINT32 *dst = (UINT32 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
				for (x = 0; x < blitwidth; x++)
					*dst++ = *src++;
			}
			else if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 16)
			{
				UINT16 *src = (UINT16 *)membuffer + y * blitwidth;
				UINT16 *dst = (UINT16 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
				for (x = 0; x < blitwidth; x++)
					*dst++ = *src++;
			}
		}

	}

	// otherwise, draw directly
	else
	{
		// based on the target format, use one of our standard renderers
		switch (blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
			case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
			case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
			case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
			default:
				osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}
	}
	window().m_primlist->release_lock();

	// unlock and blit
	result = IDirectDrawSurface7_Unlock(blit, NULL);
	if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result);

	// sync to VBLANK
	if ((video_config.waitvsync || video_config.syncrefresh) && window().machine().video().throttled() && (!window().fullscreen() || back == NULL))
	{
		result = IDirectDraw7_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKBEGIN, NULL);
		if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
	}

	// complete the blitting
	blit_to_primary(blitwidth, blitheight);
	return 0;
}