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.
--- Jonathan Wilson jonwil@tpgi.com.au wrote:
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"
If you want to send the cards spec, rc, headers and a copy of this letter in a zip to me we can still create a stub dll that others can work on and implement for ReactOS. If someone does develop it in our tree then I am sure Alexandre will accept the patch as he didnt seem to have any problem with the idea of implementing that dll. Just the method you used. I have not been able to get your GUID generation program to build right in the ReactOS build system as the w32api headers are incompleate and our system kind of sucks atm. Once this is fixed we can merge that also.
Thanks Steven
__________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com