volatile is valid everywhere const is valid.
[wine/wine-kai.git] / dlls / cards / cards.c
blobc9db204a3cb91decada744c524d91f3b05e9a89b
1 /*
2 * Cards dll implementation
4 * Copyright (C) 2004 Sami Nopanen
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "wingdi.h"
30 #include "cards.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(cards);
36 void WINAPI cdtTerm(void);
39 static HINSTANCE hInst;
40 static int cardWidth;
41 static int cardHeight;
42 static HBITMAP cardBitmaps[CARD_MAX + 1];
45 /***********************************************************************
46 * Initializes the cards.dll library. Loads the card bitmaps from the
47 * resources, and initializes the card size variables.
49 BOOL WINAPI cdtInit(int *width, int *height)
51 BITMAP bm;
52 int i;
54 TRACE("(%p, %p)\n", width, height);
56 for(i = 0; i <= CARD_MAX; i++)
57 cardBitmaps[i] = 0;
59 for(i = 0; i <= CARD_MAX; i++)
61 cardBitmaps[i] = LoadBitmapA(hInst, MAKEINTRESOURCEA(i));
62 if(cardBitmaps[i] == 0)
64 cdtTerm();
65 return FALSE;
69 GetObjectA(cardBitmaps[0], sizeof(BITMAP), &bm);
70 *width = cardWidth = bm.bmWidth;
71 *height = cardHeight = bm.bmHeight;
72 return TRUE;
75 static DWORD do_blt(HDC hdc, int x, int y, int dx, int dy, HDC hMemoryDC, DWORD rasterOp )
77 if((cardWidth == dx) && (cardHeight == dy))
78 return BitBlt(hdc, x, y, cardWidth, cardHeight, hMemoryDC, 0, 0, rasterOp);
79 return StretchBlt(hdc, x, y, dx, dy, hMemoryDC, 0, 0, cardWidth, cardHeight, rasterOp);
82 /***********************************************************************
83 * Draw a card. Unlike cdtDrawCard, this version allows you to stretch
84 * card bitmaps to the size you specify (dx, dy). See cdtDraw for info
85 * on card, mode and color parameters.
87 BOOL WINAPI cdtDrawExt(HDC hdc, int x, int y, int dx, int dy, int card, int mode, DWORD color)
89 HDC hMemoryDC;
90 HBITMAP hCardBitmap;
91 HGDIOBJ result;
92 DWORD rasterOp = SRCCOPY;
93 BOOL roundCornersFlag;
94 BOOL eraseFlag = FALSE;
95 BOOL drawFlag = TRUE;
97 TRACE("(%p, %d, %d, %d, %d, %d, %d, %ld)\n", hdc, x, y, dx, dy, card, mode, color);
99 roundCornersFlag = !(mode & MODEFLAG_DONT_ROUND_CORNERS) &&
100 (dx == cardWidth) && (dy == cardHeight);
101 mode &= ~MODEFLAG_DONT_ROUND_CORNERS;
103 if((card < 0) || (card > CARD_MAX))
105 FIXME("Unexpected card: %d\n", card);
106 return FALSE;
109 if((mode < MODE_FACEUP) || (mode > MODE_DECKO))
111 FIXME("Unexpected mode: %d\n", mode);
112 return FALSE;
115 switch(mode)
117 case MODE_FACEUP:
118 break;
119 case MODE_FACEDOWN:
120 break;
121 case MODE_HILITE:
122 rasterOp = NOTSRCCOPY;
123 break;
124 case MODE_GHOST:
125 card = CARD_FREE_MASK;
126 eraseFlag = TRUE;
127 rasterOp = SRCAND;
128 break;
129 case MODE_REMOVE:
130 eraseFlag = TRUE;
131 drawFlag = FALSE;
132 break;
133 case MODE_INVISIBLEGHOST:
134 card = CARD_FREE_MASK;
135 rasterOp = SRCAND;
136 break;
137 case MODE_DECKX:
138 card = CARD_BACK_THE_X;
139 break;
140 case MODE_DECKO:
141 card = CARD_BACK_THE_O;
142 break;
145 hMemoryDC = CreateCompatibleDC(hdc);
146 if(hMemoryDC == 0)
147 return FALSE;
149 if(eraseFlag)
151 HBRUSH hBrush;
152 RECT rect;
153 hBrush = CreateSolidBrush(color);
154 rect.left = x;
155 rect.top = y;
156 rect.right = x + cardWidth - 1;
157 rect.bottom = y + cardHeight - 1;
158 FillRect(hdc, &rect, hBrush);
161 if(drawFlag)
163 hCardBitmap = cardBitmaps[card];
164 if(hCardBitmap == 0)
165 return FALSE;
167 result = SelectObject(hMemoryDC, hCardBitmap);
168 if((result == 0) || (result == HGDI_ERROR))
170 DeleteDC(hMemoryDC);
171 return FALSE;
174 SetBkColor(hdc, color);
176 if(roundCornersFlag)
178 COLORREF savedPixels[12];
180 savedPixels[0] = GetPixel(hdc, x, y);
181 savedPixels[1] = GetPixel(hdc, x + 1, y);
182 savedPixels[2] = GetPixel(hdc, x, y + 1);
183 savedPixels[3] = GetPixel(hdc, x + dx - 1, y);
184 savedPixels[4] = GetPixel(hdc, x + dx - 2, y);
185 savedPixels[5] = GetPixel(hdc, x + dx - 1, y + 1);
186 savedPixels[6] = GetPixel(hdc, x, y + dy - 1);
187 savedPixels[7] = GetPixel(hdc, x + 1, y + dy - 1);
188 savedPixels[8] = GetPixel(hdc, x, y + dy - 2);
189 savedPixels[9] = GetPixel(hdc, x + dx - 1, y + dy - 1);
190 savedPixels[10] = GetPixel(hdc, x + dx - 2, y + dy - 1);
191 savedPixels[11] = GetPixel(hdc, x + dx - 1, y + dy - 2);
193 do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);
195 SetPixel(hdc, x, y, savedPixels[0]);
196 SetPixel(hdc, x + 1, y, savedPixels[1]);
197 SetPixel(hdc, x, y + 1, savedPixels[2]);
198 SetPixel(hdc, x + dx - 1, y, savedPixels[3]);
199 SetPixel(hdc, x + dx - 2, y, savedPixels[4]);
200 SetPixel(hdc, x + dx - 1, y + 1, savedPixels[5]);
201 SetPixel(hdc, x, y + dy - 1, savedPixels[6]);
202 SetPixel(hdc, x + 1, y + dy - 1, savedPixels[7]);
203 SetPixel(hdc, x, y + dy - 2, savedPixels[8]);
204 SetPixel(hdc, x + dx - 1, y + dy - 1, savedPixels[9]);
205 SetPixel(hdc, x + dx - 2, y + dy - 1, savedPixels[10]);
206 SetPixel(hdc, x + dx - 1, y + dy - 2, savedPixels[11]);
208 else
209 do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);
212 DeleteDC(hMemoryDC);
214 return TRUE;
218 /***********************************************************************
219 * Draws a card at position x, y in its default size (as returned by
220 * cdtInit.
222 * Mode controls how the card gets drawn:
223 * MODE_FACEUP ; draw card facing up
224 * MODE_FACEDOWN ; draw card facing down
225 * MODE_HILITE ; draw face up, with NOTSRCCOPY
226 * MODE_GHOST ; draw 'ghost' card
227 * MODE_REMOVE ; draw with background color
228 * MODE_INVISIBLEGHOST ; draw 'ghost' card, without clearing background
229 * MODE_DECKX ; draw X
230 * MODE_DECKO ; draw O
232 * The card parameter defines the card graphic to be drawn. If we are
233 * drawing fronts of cards, card should have a value from 0 through 51
234 * to represent the card face. If we are drawing card backs, 53 through
235 * 68 represent different card backs.
237 * When drawing card faces, two lowest bits represent the card suit
238 * (clubs, diamonds, hearts, spades), and the bits above that define the
239 * card value (ace, 2, ..., king). That is,
240 * card = face * 4 + suit.
242 * Color parameter defines the background color, used when drawing some
243 * card backs.
245 BOOL WINAPI cdtDraw(HDC hdc, int x, int y, int card, int mode, DWORD color)
247 TRACE("(%p, %d, %d, %d, %d, %ld)\n", hdc, x, y, card, mode, color);
249 return cdtDrawExt(hdc, x, y, cardWidth, cardHeight, card, mode, color);
253 /***********************************************************************
254 * Animates the card backs, e.g. blinking lights on the robot, the sun
255 * donning sunglasses, bats flying across the caste, etc.. Works only
256 * for cards of normal size (as drawn with cdtDraw). To draw frames of
257 * the card back animation, start with frame = 0, and increment the
258 * frame by one, until cdtAnimate returns FALSE (to indicate that we
259 * have gone through all frames of animation).
261 BOOL WINAPI cdtAnimate(HDC hdc, int cardback, int x, int y, int frame)
263 TRACE("(%p, %d, %d, %d, %d)\n", hdc, cardback, x, y, frame);
264 FIXME("Implement me.\n");
266 return FALSE;
270 /***********************************************************************
271 * Frees resources reserved by cdtInitialize.
273 void WINAPI cdtTerm()
275 int i;
277 TRACE("()\n");
279 for(i = 0; i <= CARD_MAX; i++)
281 if(cardBitmaps[i] != 0)
282 DeleteObject(cardBitmaps[i]);
283 cardBitmaps[i] = 0;
288 /***********************************************************************
289 * DllMain.
291 BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
293 switch (reason)
295 case DLL_PROCESS_ATTACH:
296 hInst = inst;
297 DisableThreadLibraryCalls( inst );
298 break;
299 case DLL_PROCESS_DETACH:
300 break;
302 return TRUE;