Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/cards/cards.c
4388 views
1
/*
2
* Cards dll implementation
3
*
4
* Copyright (C) 2004 Sami Nopanen
5
*
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.
10
*
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.
15
*
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include <stdarg.h>
22
23
#include "windef.h"
24
#include "winbase.h"
25
#include "winuser.h"
26
#include "wingdi.h"
27
28
#include "cards.h"
29
#include "wine/debug.h"
30
31
WINE_DEFAULT_DEBUG_CHANNEL(cards);
32
33
34
void WINAPI cdtTerm(void);
35
36
37
static HINSTANCE hInst;
38
static int cardWidth;
39
static int cardHeight;
40
static HBITMAP cardBitmaps[CARD_MAX + 1];
41
42
43
/***********************************************************************
44
* Initializes the cards.dll library. Loads the card bitmaps from the
45
* resources, and initializes the card size variables.
46
*/
47
BOOL WINAPI cdtInit(int *width, int *height)
48
{
49
BITMAP bm;
50
int i;
51
52
TRACE("(%p, %p)\n", width, height);
53
54
for(i = 0; i <= CARD_MAX; i++)
55
cardBitmaps[i] = 0;
56
57
for(i = 0; i <= CARD_MAX; i++)
58
{
59
cardBitmaps[i] = LoadBitmapA(hInst, MAKEINTRESOURCEA(i));
60
if(cardBitmaps[i] == 0)
61
{
62
cdtTerm();
63
return FALSE;
64
}
65
}
66
67
GetObjectA(cardBitmaps[0], sizeof(BITMAP), &bm);
68
*width = cardWidth = bm.bmWidth;
69
*height = cardHeight = bm.bmHeight;
70
return TRUE;
71
}
72
73
static DWORD do_blt(HDC hdc, int x, int y, int dx, int dy, HDC hMemoryDC, DWORD rasterOp )
74
{
75
if((cardWidth == dx) && (cardHeight == dy))
76
return BitBlt(hdc, x, y, cardWidth, cardHeight, hMemoryDC, 0, 0, rasterOp);
77
return StretchBlt(hdc, x, y, dx, dy, hMemoryDC, 0, 0, cardWidth, cardHeight, rasterOp);
78
}
79
80
/***********************************************************************
81
* Draw a card. Unlike cdtDrawCard, this version allows you to stretch
82
* card bitmaps to the size you specify (dx, dy). See cdtDraw for info
83
* on card, mode and color parameters.
84
*/
85
BOOL WINAPI cdtDrawExt(HDC hdc, int x, int y, int dx, int dy, int card, int mode, DWORD color)
86
{
87
HDC hMemoryDC;
88
HBITMAP hCardBitmap;
89
HGDIOBJ result;
90
DWORD rasterOp = SRCCOPY;
91
BOOL roundCornersFlag;
92
BOOL eraseFlag = FALSE;
93
BOOL drawFlag = TRUE;
94
95
TRACE("(%p, %d, %d, %d, %d, %d, %d, %ld)\n", hdc, x, y, dx, dy, card, mode, color);
96
97
roundCornersFlag = !(mode & MODEFLAG_DONT_ROUND_CORNERS) &&
98
(dx == cardWidth) && (dy == cardHeight);
99
mode &= ~MODEFLAG_DONT_ROUND_CORNERS;
100
101
if((card < 0) || (card > CARD_MAX))
102
{
103
FIXME("Unexpected card: %d\n", card);
104
return FALSE;
105
}
106
107
if((mode < MODE_FACEUP) || (mode > MODE_DECKO))
108
{
109
FIXME("Unexpected mode: %d\n", mode);
110
return FALSE;
111
}
112
113
switch(mode)
114
{
115
case MODE_FACEUP:
116
break;
117
case MODE_FACEDOWN:
118
break;
119
case MODE_HILITE:
120
rasterOp = NOTSRCCOPY;
121
break;
122
case MODE_GHOST:
123
card = CARD_FREE_MASK;
124
eraseFlag = TRUE;
125
rasterOp = SRCAND;
126
break;
127
case MODE_REMOVE:
128
eraseFlag = TRUE;
129
drawFlag = FALSE;
130
break;
131
case MODE_INVISIBLEGHOST:
132
card = CARD_FREE_MASK;
133
rasterOp = SRCAND;
134
break;
135
case MODE_DECKX:
136
card = CARD_BACK_THE_X;
137
break;
138
case MODE_DECKO:
139
card = CARD_BACK_THE_O;
140
break;
141
}
142
143
hMemoryDC = CreateCompatibleDC(hdc);
144
if(hMemoryDC == 0)
145
return FALSE;
146
147
if(eraseFlag)
148
{
149
HBRUSH hBrush;
150
RECT rect;
151
hBrush = CreateSolidBrush(color);
152
SetRect(&rect, x, y, x + cardWidth - 1, y + cardHeight - 1);
153
FillRect(hdc, &rect, hBrush);
154
}
155
156
if(drawFlag)
157
{
158
hCardBitmap = cardBitmaps[card];
159
if(hCardBitmap == 0)
160
return FALSE;
161
162
result = SelectObject(hMemoryDC, hCardBitmap);
163
if((result == 0) || (result == HGDI_ERROR))
164
{
165
DeleteDC(hMemoryDC);
166
return FALSE;
167
}
168
169
SetBkColor(hdc, color);
170
171
if(roundCornersFlag)
172
{
173
/* NOTE: native uses Get/SetPixel for corners, but that really
174
* hurts on X11 since it needs a server round-trip for each pixel.
175
* So we use a clip region instead. */
176
HRGN saved = CreateRectRgn( 0, 0, 0, 0 );
177
HRGN line = CreateRectRgn( x + 2, y, x + dx - 2, y + 1 );
178
HRGN clip = CreateRectRgn( x, y + 2, x + dx, y + dy - 2 );
179
180
CombineRgn( clip, clip, line, RGN_OR );
181
SetRectRgn( line, x + 1, y + 1, x + dx - 1, y + 2 );
182
CombineRgn( clip, clip, line, RGN_OR );
183
SetRectRgn( line, x + 1, y + dy - 2, x + dx - 1, y + dy - 1 );
184
CombineRgn( clip, clip, line, RGN_OR );
185
SetRectRgn( line, x + 2, y + dy - 1, x + dx - 2, y + dy );
186
CombineRgn( clip, clip, line, RGN_OR );
187
DeleteObject( line );
188
189
if (!GetClipRgn( hdc, saved ))
190
{
191
DeleteObject( saved );
192
saved = 0;
193
}
194
ExtSelectClipRgn( hdc, clip, RGN_AND );
195
DeleteObject( clip );
196
197
do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);
198
199
SelectClipRgn( hdc, saved );
200
if (saved) DeleteObject( saved );
201
}
202
else
203
do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);
204
}
205
206
DeleteDC(hMemoryDC);
207
208
return TRUE;
209
}
210
211
212
/***********************************************************************
213
* Draws a card at position x, y in its default size (as returned by
214
* cdtInit.
215
*
216
* Mode controls how the card gets drawn:
217
* MODE_FACEUP ; draw card facing up
218
* MODE_FACEDOWN ; draw card facing down
219
* MODE_HILITE ; draw face up, with NOTSRCCOPY
220
* MODE_GHOST ; draw 'ghost' card
221
* MODE_REMOVE ; draw with background color
222
* MODE_INVISIBLEGHOST ; draw 'ghost' card, without clearing background
223
* MODE_DECKX ; draw X
224
* MODE_DECKO ; draw O
225
*
226
* The card parameter defines the card graphic to be drawn. If we are
227
* drawing fronts of cards, card should have a value from 0 through 51
228
* to represent the card face. If we are drawing card backs, 53 through
229
* 68 represent different card backs.
230
*
231
* When drawing card faces, two lowest bits represent the card suit
232
* (clubs, diamonds, hearts, spades), and the bits above that define the
233
* card value (ace, 2, ..., king). That is,
234
* card = face * 4 + suit.
235
*
236
* Color parameter defines the background color, used when drawing some
237
* card backs.
238
*/
239
BOOL WINAPI cdtDraw(HDC hdc, int x, int y, int card, int mode, DWORD color)
240
{
241
TRACE("(%p, %d, %d, %d, %d, %ld)\n", hdc, x, y, card, mode, color);
242
243
return cdtDrawExt(hdc, x, y, cardWidth, cardHeight, card, mode, color);
244
}
245
246
247
/***********************************************************************
248
* Animates the card backs, e.g. blinking lights on the robot, the sun
249
* donning sunglasses, bats flying across the caste, etc.. Works only
250
* for cards of normal size (as drawn with cdtDraw). To draw frames of
251
* the card back animation, start with frame = 0, and increment the
252
* frame by one, until cdtAnimate returns FALSE (to indicate that we
253
* have gone through all frames of animation).
254
*/
255
BOOL WINAPI cdtAnimate(HDC hdc, int cardback, int x, int y, int frame)
256
{
257
TRACE("(%p, %d, %d, %d, %d)\n", hdc, cardback, x, y, frame);
258
FIXME("Implement me.\n");
259
260
return FALSE;
261
}
262
263
264
/***********************************************************************
265
* Frees resources reserved by cdtInit.
266
*/
267
void WINAPI cdtTerm(void)
268
{
269
int i;
270
271
TRACE("()\n");
272
273
for(i = 0; i <= CARD_MAX; i++)
274
{
275
if(cardBitmaps[i] != 0)
276
DeleteObject(cardBitmaps[i]);
277
cardBitmaps[i] = 0;
278
}
279
}
280
281
282
/***********************************************************************
283
* DllMain.
284
*/
285
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
286
{
287
switch (reason)
288
{
289
case DLL_PROCESS_ATTACH:
290
hInst = inst;
291
DisableThreadLibraryCalls( inst );
292
break;
293
}
294
return TRUE;
295
}
296
297