예제 #1
0
파일: sound.c 프로젝트: i-willh/imame4all
//============================================================
//	lock_buffer
//============================================================
static int lock_buffer(long offset, long size, void **buffer1, long *length1, void **buffer2, long *length2)
{
    volatile long pstart, pend, lstart, lend;

    if (!buf_locked)
    {
        if (video_get_throttle())
        {
            pstart = stream_playpos;
            pend = (pstart + sdl_xfer_samples);
            lstart = offset;
            lend = lstart+size;
            while (((pstart >= lstart) && (pstart <= lend)) ||
                    ((pend >= lstart) && (pend <= lend)))
            {
                pstart = stream_playpos;
                pend = pstart + sdl_xfer_samples;
            }
        }

        SDL_LockAudio();
        buf_locked++;
    }

    // init lengths
    *length1 = *length2 = 0;

    if ((offset + size) > stream_buffer_size)
    {
        // 2-piece case
        *length1 = stream_buffer_size - offset;
        *buffer1 = &stream_buffer[offset];
        *length2 = size - *length1;
        *buffer2 = stream_buffer;
    }
    else
    {
        // normal 1-piece case
        *length1 = size;
        *buffer1 = &stream_buffer[offset];
    }

    if (LOG_SOUND)
        fprintf(sound_log, "locking %ld bytes at offset %ld (total %d, playpos %d): len1 %ld len2 %ld\n",
                size, offset, stream_buffer_size, stream_playpos, *length1, *length2);

    return 0;
}
예제 #2
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;
}