how cards.dll works

Jonathan Wilson jonwil at tpgi.com.au
Mon Jul 28 06:53:12 CDT 2003


After finding out that certain things I did when coding cards.dll (such as 
studying the complete code in a disassembler) mean that any code I write 
for it a potential "derivitave work", I have come up with a descrition that 
is (hopefully) detailed enough to enable someone else with windows GDI 
programming experience to write cards.dll for wine but (hopefully) not 
detailed enough to be considered a "derivitive work"

The folowing files can be made available to whoever ends up working on 
cards.dll:
1.cards.spec, a ready made spec file for the dll
2.cards.rc, a RC file containing the card bitmaps (which are licenced under 
a licence that gave permission to use them) and also the card back bitmaps 
that were sent to me before (to whoever ends up working on this, feel free 
to modify the images if you dont like them :)
3.makefile.in ready made for the dll
and 4.cards.h which contains the publicly documented interface to cards.dll 
(which I pulled from various info documents found on the net)
IANAL but I dont think that any of these could be claimed to be covered by 
that "derivitave work" thing, if they are, please do tell me.

This document explains the workings of cards.dll (version 5.00.2134.1 from 
windows XP SP1)

Cards.dll exports 7 different functions.
These are:
cdtInit
cdtTerm
cdtAnimate
cdtDraw
cdtDrawExt
DllMain
and WEP

cdtInit takes 2 int * variables. It should return TRUE if the initalization 
was sucessfull and FALSE if it was not.
It is a place to do any initalization you require (depending on for example 
if you want to preload the resource bitmaps or whatever).
It should return the x and y size of the card bitmaps in the 2 variables. 
For the cards I am using, the x size is 71 and the y size is 96 (which just 
happened to match up with the size of microsofts cards which is good)

the main purpose of DllMain is to store the HINSTANCE of the cards.dll to 
use later when the bitmaps are loaded

WEP is a holdover from when cards.dll was a 16 bit dll and doesnt actually 
need to be implemented (since its never called by 32 bit windows)

cdtTerm is where you undo anything you did in cdtInit (such as unloading 
any preloaded resources)
It takes no parameters and returns nothing.

cdtAnimate is supposed to handle animations for the card backs but since 
the backs we are using dont animate, it can just return TRUE
(hence why the resource file I wrote returns the windows XP version number 
since XP doesnt have animated backs either)
As for parameters, it takes a HDC, an x and y position and a frame number 
(each individual microsoft back has a specific number of frames and 
applictions tend to hard-code these values)

cdtDraw basicly calls cdtDrawExt passing the default size of the card 
bitmaps as the x and y size parameters

The real work is done in cdtDrawExt
This function takes:
a HDC (for the screen window to draw the card on)
an X positon and a Y position to draw the card at
a card number (cards.h lists the different values)
a mode number (again cards.h lists the different values)
and a RGB background color
What the function does depends on the value of the mode.
If the upper bit of md (which is an int) is set, then it shouldnt save and 
resore the corner pixels (as explained below)

modes greater than 7 should (as far as I can tell) do nothing.
mode 0 is "draw face card"
mode 1 is "draw back"
mode 2 is "draw highlighted face card"
mode 3 is "draw empty card spot"
mode 4 is "erase card"
mode 5 is "draw empty card spot but doesnt paint background"
mode 6 is "draw red X card"
and mode 7 is "draw green O card"

all modes use the same "drawing logic" except for mode 4 which doesnt draw 
any bitmap.

You need a resource ID and a raster OP to do the drawing
For modes 0 and 2, the resource ID uses this formula
resource id equals ((((card number shl 2) mod 0dh) plus ((card number and 
3) times 0dh)) plus 1)
For mode 1, the resource ID is just the card number
For modes 3 and 5, the resource ID is 53 (the resource ID of the empty card 
spot graphic, also the contant hb in cards.h)
For mode 1, the resource ID is just the card number
For mode 6, the resource ID is 67 (the resource ID of the card with the red 
X on a green background graphic, also the contant xb in cards.h)
For mode 7, the resource ID is 68 (the resource ID of the card with the 
green O on a green background graphic, also the contant ob in cards.h)
and mode 4 doesnt use any ID since it doesnt draw anything.

For the raster OP, all modes use SRCCOPY except for:
mode 2 which uses NOTSRCCOPY
and modes 3 and 5 which use SRCAND

Also, if the mode is 0, the background color is set to white (0xFFFFFF) 
before drawing. And after drawing, if the card is a red card (resource IDs 
0x0E to ox17 and 0x1B to 0x24), it paints over the boarders of the card 
using PatBlt and the BLACKNESS rasterop.

If the mode is 3 or 4, it creates a solid brush using the background color, 
uses SetBrushOrgEx to set the brush origin to the screen DC origin and then 
uses PatBlt to paint over the area of the card using PATCOPY.

If the mode has the top bit clear (as explained above) and the size matches 
with the default card size, before drawing, it saves the corner pixels of 
the cards (the card bitmaps I am using have one pixel in each corner) and 
then restore them after drawing.

To do the actual drawing, you need to load the bitmap resource into memory 
and load the resulting HBITMAP into a memory DC.
You also need to set the background color of the screen DC to whatever was 
passed in (unless its mode 0, in which case its 0xFFFFFF as explained 
above). And then, you need to copy the data from the memory DC to the 
screen DC using either BitBlt or StretchBlt as appropriate.

Remeber to free all the GDI resources (bitmaps, memory DCs etc) that you used.
And also to restore the background color to whatever it was
before you changed it.
If the function is a sucess, you return TRUE.
If the function is a failure (e.g. a GDI function call fails), you return 
FALSE.

Hoepfully someone can use this information to implement cards.dll in a way 
that is legally safe.





More information about the wine-devel mailing list