Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can DirectDraw game access a backbuffer without locking it?

I'm modding an old Windows DirectDraw game. I've created a DirectDraw proxy. It logs every IDirectDraw and IDirectDrawSurface call. The backbuffer looks like this after one BltFast call:

enter image description here

And like this before the next BltFast call:

enter image description here

These pictures are dumped by Locking-copying-Unlocking the backbuffer before and after any BltFast call. There are no other IDirectDraw(Surface) calls between these two BltFast calls, especially no Lock/Unlock calls. How is this possible?

like image 347
cubuspl42 Avatar asked Jun 17 '14 20:06

cubuspl42


1 Answers

As far as I can tell, it looks like the game might be drawing in multiple stages, and you are catching it in-between. IE, the game calls blit once to render its background, then again (possibly multiple times) to render interactive 'sprites'. (However, the order could well be reversed, meaning that the second frame you capture is actually the first layer of the next loop.)

As far as the backbufer goes, I was able to find this in MSDNs documentation for DirectDraw: https://msdn.microsoft.com/en-us/library/windows/desktop/gg426183(v=vs.85).aspx

BltFast always attempts an asynchronous blit if it is supported by the hardware.

So it could be a race, possibly, but I would imagine that any attempt to lock would block until this completes.

And also... https://msdn.microsoft.com/en-us/library/windows/desktop/gg426208%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Do not call DirectDraw bitblt functions to bitblt from a locked region of a surface. If you do, the bitblt returns either DDERR_SURFACEBUSY or DDERR_LOCKEDSURFACES. GDI blit functions also silently fail when used on a locked video memory surface.

This implies that bitblt itself has locking semantics. Given that GDI is not allowed to access a surface that is explicitly locked, it's also likely that it cannot access a surface in the middle of an asynchronous blit operation.

So to specifically answer your question, it appears GDI might be able to access a surface without locking it.

Of course, there's all kinds of weird things that can be done in the name of performance, so who knows what other kind of hacks they might have done?

I will say though, that I am not an expert by any means at DirectDraw, and am operating under the assumption that the backbuffer is just like any other surface.

like image 130
Meta Avatar answered Sep 30 '22 01:09

Meta