]>Карточные игры и библиотека cards.dll

Карточные игры и библиотека cards.dll

Аватар пользователя mabu

Файл cards.dll входил в состав практически любой Windows, начиная с самых ранних Windows и до Windows 7. Но в каждой Windows использовались разные версии библиотеки, как 16‐битные, так и 32‐битные. Кроме того, иногда библиотека мела разные имена, например, cards32.dll. В нашем случае мы рассматриваем только библиотеку, поставляемую с Windows NT линейки 5 (2000, XP и 2003 сервер).

В Windows 10 эта библиотека отсуствует, однако её можно получить из LiveCD образа операционной системы ReactOS. Так как ReactOS является полноценным «клоном» Windows 2003, то разработчики написали cards.dll для этой системы. Достаточно скачать любой дистрибутив с образом системы, а библиотека будет лежать в образе по пути \reactos\system32\cards.dll. ReactOS — операционная система с открытым исходным кодом по лицензии GPL 2.0, поэтому её компоненты можно использовать в своих программах с открытым исходным кодом.

  1. Функции
    1. cdtInit
    2. cdtDrawExt
    3. cdtTerm
  2. Подробное описание
  3. Демонстрационная программа
    1. Исходный код
    2. Результаты
  4. Ссылки

Функции

cards.dll содержит несколько функций, из них нам понядобятся всего три:

cdtInit

Инициализирует необходимые ресурсы для работы и возвращает стандартные размеры изображения карты из колоды.

Код FreeBASIC
Declare Function cdtInit Alias "cdtInit"( _
&t;ByVal Width As Integer Ptr, _
&t;ByVal Height As Integer Ptr _
)As Integer

Параметры

Width
Указатель на переменную, куда будет записана стандартная ширина карты.
Height
Указатель на переменную, куда будет записана стандартная высота карты.

cdtDrawExt

Выводит карту на экран.

Код FreeBASIC
Declare Function cdtDrawExt Alias "cdtDrawExt"( _
&t;ByVal hDC As HDC, _
&t;ByVal X As Integer, _
&t;ByVal Y As Integer, _
&t;ByVal Width As Integer, _
&t;ByVal Height As Integer, _
&t;ByVal Card As Integer, _
&t;ByVal Suit As Integer, _
&t;ByVal Color As DWORD _
)As Integer

Параметры

hDC
Контекст устройства для рисования.
X
Координата X левой стороны карты.
Y
Координата Y верхней стороны карты.
Width
Ширина карты.
Height
Высота карты.
Card
Число от 0 до 68, описывающее тип выводимой карты.
Suit
Значение, описывающее метод вывода карты.
Color
Инвертируемый цвет. Не используется в Windows XP, просто установи этот параметр в 0.

cdtTerm

Завершает работу с библиотекой cards.dll и освобождяет ресурсы памяти.

Код FreeBASIC
Declare Sub cdtTerm Alias "cdtTerm"()

Параметры

Функция не имеет параметров.

Подробное описание

Основная функция, с помощью которой рисуется карта — cdtDrawExt. Как известно, стандартная колода состоит из 52 карт. Карты имеют 4 масти по 13 наименований в каждой. Параметру Card функции cdtDrawExt соответствует число, определяющее достоинство карты. Числа в интервале 0-51 выводят одну из стандартных 52 карт колоды. Так, значение 0 соответствует тузу треф, 1 — тузу бубен, 2 — тузу червей, 3 — тузу пик и т.д. Последнее число 51 соответствует королю пик.

Код FreeBASIC
' Масти карт
Enum Suits
&t;Clubs = 0 ' трефы
&t;Diamond = 1 ' бубны
&t;Hearts = 2 'черви
&t;Spades = 3 ' пики
End Enum

' Номинал карты
Enum Faces
&t;Ace = 0 ' туз
&t;Two = 1 ' двойка
&t;Three = 2 ' тройка
&t;Four = 3 ' четверка
&t;Five = 4 ' пятерка
&t;Six = 5 ' шестерка
&t;Seven = 6 ' семерка
&t;Eight = 7 ' восьмерка
&t;Nine = 8 ' девятка
&t;Ten = 9 ' десятка
&t;Jack = 10 ' валет
&t;Queen = 11 ' дама
&t;King = 12 ' король
End Enum

Чтобы получить номер нужной карты, надо знать волшебную формулу:

Код FreeBASIC
Сard = Faces * 4 + Suits

Например, нужно получить номер пиковой дамы. Подставляем в формулу нужные значения:

Код FreeBASIC
Card = Faces.Queen * 4 + Suits.Diamond

Таким образом, пиковой даме соответствует номер 47 = (11 * 4 + 3).

Остальные числа от 52 до 68 выводят различные виды рубашек, а также несколько специальных картинок: X или O. Перечёркнутая красным крестом карта означает конец игры, зелёная O указывает, что ты можешь перемешать колоду для продолжения игры. Параметр Suit позволяет выводить различные состояния карты. Например, ты присвоил параметру Card значение от 0 до 51 (нормальный вид). В этом случае при значении 0 в параметре Suit выведется стандартный вид карты. Передавая значение 2, выведется эта же карта в инвертированном виде, показывая пользователю, что карта выбрана. Если же необходимо показать рубашку карты (обратную сторону), то используй значение 1 в параметре Suit при значениях Card в интервале от 53 до 68.

Код FreeBASIC
' Картинки для рубашки
Enum Backs
&t;Crosshatch = 53 ' Сетка
&t;Sky = 54 ' Небо
&t;Mineral = 55 ' Минерал
&t;Fish = 56 ' Рыба
&t;Frog = 57 ' Лягушка
&t;Flower = 58 ' Цветок
&t;Island = 59 ' Остров с пальмами
&t;Sqiares = 60 ' Квадраты
&t;Magenta = 61 ' Фиолетовый узор
&t;Sanddunes = 62 ' Песчаные дюны
&t;Space = 63 ' Астронавт
&t;Lines = 64 ' Линии
&t;Cars = 65 ' Машинки
&t;Unused = 66 ' Неиспользуемая карта
&t;X = 67 ' Символ X
&t;O = 68 ' Символ О
End Enum

Демонстрационная программа

Программа создаёт окно и выводит на него бубнового валета, инвертированного бубнового валета и рубашку «Небо».

Исходный код

Собранный воедино заголовочный файл «cards.bi».

Код FreeBASIC
' Функции работы с картами
Declare Function cdtInit Alias "cdtInit"(ByVal Width As Integer Ptr, ByVal Height As Integer Ptr)As Integer
Declare Function cdtDrawExt Alias "cdtDrawExt"(ByVal hDC As HDC, ByVal X As Integer, ByVal Y As Integer, ByVal dX As Integer, ByVal dY As Integer, ByVal Card As Integer, ByVal Suit As Integer, ByVal Color As DWORD)As Integer
Declare Sub cdtTerm Alias "cdtTerm"()

' Картинки для рубашки
Enum Backs
&t;Crosshatch = 53 ' Сетка
&t;Sky = 54 ' Небо
&t;Mineral = 55 ' Минерал
&t;Fish = 56 ' Рыба
&t;Frog = 57 ' Лягушка
&t;Flower = 58 ' Цветок
&t;Island = 59 ' Остров с пальмами
&t;Sqiares = 60 ' Квадраты
&t;Magenta = 61 ' Фиолетовый узор
&t;Sanddunes = 62 ' Песчаные дюны
&t;Space = 63 ' Астронавт
&t;Lines = 64 ' Линии
&t;Cars = 65 ' Машинки
&t;Unused = 66 ' Неиспользуемая карта
&t;X = 67 ' Символ X
&t;O = 68 ' Символ О
End Enum

' Масти карт
Enum Suits
&t;Clubs = 0 ' трефы
&t;Diamond = 1 ' бубны
&t;Hearts = 2 'черви
&t;Spades = 3 ' пики
End Enum

' Номинал карты
Enum Faces
&t;Ace = 0 ' туз
&t;Two = 1 ' двойка
&t;Three = 2 ' тройка
&t;Four = 3 ' четверка
&t;Five = 4 ' пятерка
&t;Six = 5 ' шестерка
&t;Seven = 6 ' семерка
&t;Eight = 7 ' восьмерка
&t;Nine = 8 ' девятка
&t;Ten = 9 ' десятка
&t;Jack = 10 ' валет
&t;Queen = 11 ' дама
&t;King = 12 ' король
End Enum

' Тип отображения карты
Enum Views
&t;Normal = 0 ' Карта в нормальном виде
&t;Back = 1 ' Рубашка карты
&t;Invert = 2 ' Инвертированная карта
End Enum

Файл «cards.bas».

Код FreeBASIC
#define unicode
#include once "windows.bi"
#include once "cards.bi"

Const MainWindowClassName = "Карты"
Const MainWindowTitle = "Демонстрация вывода карт"

Declare Function WndProc(ByVal hWnd As HWND, ByVal wMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM)As LRESULT

' Размеры карты по умолчанию
Dim Shared mintWidth As Integer
Dim Shared mintHeight As Integer

' Инициализация библиотеки
cdtInit(@mintWidth, @mintHeight)

' Регистрация класса окна и создание

Dim hInstance As HMODULE = GetModuleHandle(0)
Dim wcls As WNDCLASS = Any
With wcls
&t;.style = CS_HREDRAW Or CS_VREDRAW
&t;.lpfnWndProc = @WndProc
&t;.cbClsExtra = 0
&t;.cbWndExtra = 0
&t;.hInstance = hInstance
&t;.hIcon = 0
&t;.hCursor = LoadCursor(0, IDC_ARROW)
&t;.hbrBackground = Cast(HBRUSH, COLOR_BTNFACE + 1)
&t;.lpszMenuName = 0
&t;.lpszClassName = @MainWindowClassName
End With

If RegisterClass(@wcls) = FALSE Then
&t;MessageBox(0, "Не могу зарегистрировать класс окна", @MainWindowTitle, MB_ICONERROR)
&t;End(1)
End If

Dim hWndMain As HWND = CreateWindowEx(0, @MainWindowClassName, @MainWindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL)

ShowWindow(hWndMain, SW_NORMAL)
UpdateWindow(hWndMain)

Dim wMsg As MSG = Any
Dim bRet As Integer = GetMessage(@wMsg, NULL, 0, 0)
Do While bRet <> 0
&t;If bRet = -1 Then
&t;&t;' Ошибка
&t;&t;Exit Do
&t;Else
&t;&t;TranslateMessage(@wMsg)
&t;&t;DispatchMessage(@wMsg)
&t;End If
&t;bRet = GetMessage(@wMsg, NULL, 0, 0)
Loop

' Очистка
cdtTerm()

End(wMsg.wParam)


Function WndProc(ByVal hWin As HWND, ByVal wMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM)As LRESULT
&t;Select Case wMsg
&t;&t;Case WM_PAINT
&t;&t;&t;Dim pnt As PAINTSTRUCT
&t;&t;&t;Dim hDC As HDC
&t;&t;&t;hDC = BeginPaint(hWin, @pnt)
&t;&t;&t;' Рисуем бубнового валета
&t;&t;&t;cdtDrawExt(hDC, 10, 10, mintWidth, mintHeight, Faces.Jack * 4 + Suits.Diamond, Views.Normal, 0)
&t;&t;&t;' Рисуем инвертированного бубнового валета
&t;&t;&t;cdtDrawExt(hDC, 100, 10, mintWidth, mintHeight, Faces.Jack * 4 + Suits.Diamond, Views.Invert, 0)
&t;&t;&t;' Рисуем рубашку «Небо»
&t;&t;&t;cdtDrawExt(hDC, 200, 10, mintWidth, mintHeight, Backs.Sky, Views.Back, 0)
&t;&t;&t;EndPaint(hWin, @pnt)

&t;&t;Case WM_DESTROY
&t;&t;&t;PostQuitMessage(0)

&t;&t;Case Else
&t;&t;&t;Return DefWindowProc(hWin, wMsg, wParam, lParam)
&t;&t;End Select

&t;Return 0
End Function

Компиляция

Код Batch
"%ProgramFiles%\FreeBASIC\fbc.exe" -s gui -l cards cards.bas

Также для успешной компиляции файл cards.dll необходимо скопировать из «c:\windows\system32\» и положить рядом с исходным кодом.

Результаты

Результат работы программы в Windows 2003 со стандартной библиотекой:

Изображение бубнового валета в Windows 2003

Результат работы программы в Windows 2003 с библиотекой из операционной системы ReactOS:

Изображение бубнового валета в ReactOS

Ссылки

Поделись ссылочкой в социальных сетях