parent
91af3ea0ea
commit
9ffe109cb1
7 changed files with 2032 additions and 6 deletions
@ -0,0 +1,205 @@ |
|||||||
|
/**
|
||||||
|
* Landlord Win32 API Layer |
||||||
|
* |
||||||
|
* C++ is intentionally limited to Win32 windowing and primitive drawing. |
||||||
|
* The game rules and AI live in PHP. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <phpx.h> |
||||||
|
#include <windows.h> |
||||||
|
#include <cstdio> |
||||||
|
#include <cstring> |
||||||
|
#include <cwchar> |
||||||
|
|
||||||
|
using namespace php; |
||||||
|
|
||||||
|
static bool g_quitRequested = false; |
||||||
|
|
||||||
|
struct PaintFrame { |
||||||
|
HDC memDC; |
||||||
|
HBITMAP bitmap; |
||||||
|
HBITMAP oldBitmap; |
||||||
|
}; |
||||||
|
|
||||||
|
static HDC frame_hdc(Int frameHandle) { |
||||||
|
PaintFrame* frame = (PaintFrame*)frameHandle; |
||||||
|
return frame ? frame->memDC : NULL; |
||||||
|
} |
||||||
|
|
||||||
|
LRESULT CALLBACK LandlordWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { |
||||||
|
switch (msg) { |
||||||
|
case WM_CLOSE: |
||||||
|
g_quitRequested = true; |
||||||
|
PostQuitMessage(0); |
||||||
|
return 0; |
||||||
|
case WM_DESTROY: |
||||||
|
g_quitRequested = true; |
||||||
|
PostQuitMessage(0); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
return DefWindowProc(hWnd, msg, wParam, lParam); |
||||||
|
} |
||||||
|
|
||||||
|
Int php_win_create_window(String title, Int width, Int height) { |
||||||
|
SetConsoleOutputCP(65001); |
||||||
|
|
||||||
|
WNDCLASSW wc; |
||||||
|
ZeroMemory(&wc, sizeof(wc)); |
||||||
|
wc.style = CS_HREDRAW | CS_VREDRAW; |
||||||
|
wc.lpfnWndProc = LandlordWndProc; |
||||||
|
wc.hInstance = GetModuleHandle(NULL); |
||||||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW); |
||||||
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); |
||||||
|
wc.lpszClassName = L"LandlordWindow"; |
||||||
|
RegisterClassW(&wc); |
||||||
|
|
||||||
|
int wtitle_len = MultiByteToWideChar(CP_UTF8, 0, title.data(), -1, NULL, 0); |
||||||
|
wchar_t* wtitle = new wchar_t[wtitle_len]; |
||||||
|
MultiByteToWideChar(CP_UTF8, 0, title.data(), -1, wtitle, wtitle_len); |
||||||
|
|
||||||
|
HWND hWnd = CreateWindowExW( |
||||||
|
0, L"LandlordWindow", wtitle, |
||||||
|
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, |
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, |
||||||
|
(int)width, (int)height, |
||||||
|
NULL, NULL, GetModuleHandle(NULL), NULL |
||||||
|
); |
||||||
|
delete[] wtitle; |
||||||
|
return (Int)hWnd; |
||||||
|
} |
||||||
|
|
||||||
|
void php_win_show_window(Int hWnd, Int cmdShow) { |
||||||
|
ShowWindow((HWND)hWnd, (int)cmdShow); |
||||||
|
} |
||||||
|
|
||||||
|
Bool php_win_quit_requested() { |
||||||
|
return g_quitRequested; |
||||||
|
} |
||||||
|
|
||||||
|
void php_win_post_quit(Int exitCode) { |
||||||
|
PostQuitMessage((int)exitCode); |
||||||
|
} |
||||||
|
|
||||||
|
Array php_win_peek_message() { |
||||||
|
MSG msg; |
||||||
|
ZeroMemory(&msg, sizeof(msg)); |
||||||
|
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { |
||||||
|
Array result; |
||||||
|
result.append((Int)msg.hwnd); |
||||||
|
result.append((Int)msg.message); |
||||||
|
result.append((Int)msg.wParam); |
||||||
|
result.append((Int)msg.lParam); |
||||||
|
TranslateMessage(&msg); |
||||||
|
DispatchMessage(&msg); |
||||||
|
return result; |
||||||
|
} |
||||||
|
return Array(); |
||||||
|
} |
||||||
|
|
||||||
|
Int php_win_get_tick_count() { |
||||||
|
return (Int)GetTickCount(); |
||||||
|
} |
||||||
|
|
||||||
|
Int php_win_message_box(Int hWnd, String text, String caption, Int uType) { |
||||||
|
int wtext_len = MultiByteToWideChar(CP_UTF8, 0, text.data(), -1, NULL, 0); |
||||||
|
wchar_t* wtext = new wchar_t[wtext_len]; |
||||||
|
MultiByteToWideChar(CP_UTF8, 0, text.data(), -1, wtext, wtext_len); |
||||||
|
|
||||||
|
int wcaption_len = MultiByteToWideChar(CP_UTF8, 0, caption.data(), -1, NULL, 0); |
||||||
|
wchar_t* wcaption = new wchar_t[wcaption_len]; |
||||||
|
MultiByteToWideChar(CP_UTF8, 0, caption.data(), -1, wcaption, wcaption_len); |
||||||
|
|
||||||
|
int result = MessageBoxW((HWND)hWnd, wtext, wcaption, (UINT)uType); |
||||||
|
|
||||||
|
delete[] wtext; |
||||||
|
delete[] wcaption; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
Int php_win_begin_paint(Int hWnd) { |
||||||
|
HDC hdc = GetDC((HWND)hWnd); |
||||||
|
RECT rc; |
||||||
|
GetClientRect((HWND)hWnd, &rc); |
||||||
|
|
||||||
|
HDC memDC = CreateCompatibleDC(hdc); |
||||||
|
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom); |
||||||
|
HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap); |
||||||
|
|
||||||
|
ReleaseDC((HWND)hWnd, hdc); |
||||||
|
|
||||||
|
PaintFrame* frame = new PaintFrame; |
||||||
|
frame->memDC = memDC; |
||||||
|
frame->bitmap = memBitmap; |
||||||
|
frame->oldBitmap = oldBitmap; |
||||||
|
return (Int)frame; |
||||||
|
} |
||||||
|
|
||||||
|
void php_win_end_paint(Int hWnd, Int hdcHandle) { |
||||||
|
PaintFrame* frame = (PaintFrame*)hdcHandle; |
||||||
|
if (frame == NULL || frame->memDC == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
HDC memDC = frame->memDC; |
||||||
|
RECT rc; |
||||||
|
GetClientRect((HWND)hWnd, &rc); |
||||||
|
|
||||||
|
HDC hdc = GetDC((HWND)hWnd); |
||||||
|
BitBlt(hdc, 0, 0, rc.right, rc.bottom, memDC, 0, 0, SRCCOPY); |
||||||
|
ReleaseDC((HWND)hWnd, hdc); |
||||||
|
|
||||||
|
SelectObject(memDC, frame->oldBitmap); |
||||||
|
DeleteObject(frame->bitmap); |
||||||
|
DeleteDC(memDC); |
||||||
|
delete frame; |
||||||
|
} |
||||||
|
|
||||||
|
void php_win_fill_rect(Int hdc, Int x, Int y, Int w, Int h, Int rgbColor) { |
||||||
|
HDC targetDC = frame_hdc(hdc); |
||||||
|
HBRUSH brush = CreateSolidBrush((COLORREF)rgbColor); |
||||||
|
RECT r = {(int)x, (int)y, (int)(x + w), (int)(y + h)}; |
||||||
|
FillRect(targetDC, &r, brush); |
||||||
|
DeleteObject(brush); |
||||||
|
} |
||||||
|
|
||||||
|
void php_win_fill_ellipse(Int hdc, Int x, Int y, Int w, Int h, Int rgbColor) { |
||||||
|
HDC targetDC = frame_hdc(hdc); |
||||||
|
HBRUSH brush = CreateSolidBrush((COLORREF)rgbColor); |
||||||
|
HBRUSH oldBrush = (HBRUSH)SelectObject(targetDC, brush); |
||||||
|
HPEN pen = CreatePen(PS_SOLID, 1, (COLORREF)rgbColor); |
||||||
|
HPEN oldPen = (HPEN)SelectObject(targetDC, pen); |
||||||
|
Ellipse(targetDC, (int)x, (int)y, (int)(x + w), (int)(y + h)); |
||||||
|
SelectObject(targetDC, oldPen); |
||||||
|
SelectObject(targetDC, oldBrush); |
||||||
|
DeleteObject(pen); |
||||||
|
DeleteObject(brush); |
||||||
|
} |
||||||
|
|
||||||
|
void php_win_draw_line(Int hdc, Int x1, Int y1, Int x2, Int y2, Int rgbColor) { |
||||||
|
HDC targetDC = frame_hdc(hdc); |
||||||
|
HPEN pen = CreatePen(PS_SOLID, 1, (COLORREF)rgbColor); |
||||||
|
HPEN oldPen = (HPEN)SelectObject(targetDC, pen); |
||||||
|
MoveToEx(targetDC, (int)x1, (int)y1, NULL); |
||||||
|
LineTo(targetDC, (int)x2, (int)y2); |
||||||
|
SelectObject(targetDC, oldPen); |
||||||
|
DeleteObject(pen); |
||||||
|
} |
||||||
|
|
||||||
|
void php_win_draw_text(Int hdc, Int x, Int y, String text, Int fontSize, Int rgbColor, Int bold) { |
||||||
|
HDC targetDC = frame_hdc(hdc); |
||||||
|
SetTextColor(targetDC, (COLORREF)rgbColor); |
||||||
|
SetBkMode(targetDC, TRANSPARENT); |
||||||
|
|
||||||
|
int wtext_len = MultiByteToWideChar(CP_UTF8, 0, text.data(), -1, NULL, 0); |
||||||
|
wchar_t* wtext = new wchar_t[wtext_len]; |
||||||
|
MultiByteToWideChar(CP_UTF8, 0, text.data(), -1, wtext, wtext_len); |
||||||
|
|
||||||
|
HFONT hFont = CreateFontW((int)fontSize, 0, 0, 0, |
||||||
|
bold ? FW_BOLD : FW_NORMAL, FALSE, FALSE, FALSE, |
||||||
|
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, |
||||||
|
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Microsoft YaHei UI"); |
||||||
|
HFONT oldFont = (HFONT)SelectObject(targetDC, hFont); |
||||||
|
TextOutW(targetDC, (int)x, (int)y, wtext, (int)wcslen(wtext)); |
||||||
|
SelectObject(targetDC, oldFont); |
||||||
|
DeleteObject(hFont); |
||||||
|
delete[] wtext; |
||||||
|
} |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,258 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
const SW_SHOW = 5; |
||||||
|
const WM_KEYDOWN = 0x0100; |
||||||
|
const WM_LBUTTONDOWN = 0x0201; |
||||||
|
const WM_QUIT = 0x0012; |
||||||
|
const MB_OK = 0x00000000; |
||||||
|
const VK_N = 0x4E; |
||||||
|
|
||||||
|
const WINDOW_WIDTH = 1180; |
||||||
|
const WINDOW_HEIGHT = 760; |
||||||
|
const CARD_W = 68; |
||||||
|
const CARD_H = 96; |
||||||
|
const CARD_GAP = 36; |
||||||
|
|
||||||
|
const BTN_Y = 506; |
||||||
|
const BTN_W = 138; |
||||||
|
const BTN_H = 42; |
||||||
|
const BTN_PLAY_X = 430; |
||||||
|
const BTN_PASS_X = 588; |
||||||
|
const BTN_NEW_X = 746; |
||||||
|
|
||||||
|
function rgb(int $r, int $g, int $b): int |
||||||
|
{ |
||||||
|
return ($r | ($g << 8) | ($b << 16)); |
||||||
|
} |
||||||
|
|
||||||
|
function mouse_x(int $lParam): int |
||||||
|
{ |
||||||
|
$x = $lParam & 0xFFFF; |
||||||
|
return $x >= 0x8000 ? $x - 0x10000 : $x; |
||||||
|
} |
||||||
|
|
||||||
|
function mouse_y(int $lParam): int |
||||||
|
{ |
||||||
|
$y = ($lParam >> 16) & 0xFFFF; |
||||||
|
return $y >= 0x8000 ? $y - 0x10000 : $y; |
||||||
|
} |
||||||
|
|
||||||
|
function in_rect(int $x, int $y, int $rx, int $ry, int $rw, int $rh): bool |
||||||
|
{ |
||||||
|
return $x >= $rx && $x <= $rx + $rw && $y >= $ry && $y <= $ry + $rh; |
||||||
|
} |
||||||
|
|
||||||
|
function card_rank(int $card): int |
||||||
|
{ |
||||||
|
if ($card == 52) { |
||||||
|
return 16; |
||||||
|
} |
||||||
|
if ($card == 53) { |
||||||
|
return 17; |
||||||
|
} |
||||||
|
return intdiv($card, 4) + 3; |
||||||
|
} |
||||||
|
|
||||||
|
function card_suit(int $card): int |
||||||
|
{ |
||||||
|
return $card % 4; |
||||||
|
} |
||||||
|
|
||||||
|
function rank_label(int $rank): string |
||||||
|
{ |
||||||
|
$labels = [ |
||||||
|
3 => '3', 4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', |
||||||
|
10 => '10', 11 => 'J', 12 => 'Q', 13 => 'K', 14 => 'A', 15 => '2', |
||||||
|
16 => '小王', 17 => '大王', |
||||||
|
]; |
||||||
|
return $labels[$rank] ?? '?'; |
||||||
|
} |
||||||
|
|
||||||
|
function card_label(int $card): string |
||||||
|
{ |
||||||
|
$rank = card_rank($card); |
||||||
|
if ($rank >= 16) { |
||||||
|
return 'JOKER'; |
||||||
|
} |
||||||
|
$suits = ['黑', '红', '梅', '方']; |
||||||
|
return rank_label($rank) . $suits[card_suit($card)]; |
||||||
|
} |
||||||
|
|
||||||
|
function card_suit_label(int $card): string |
||||||
|
{ |
||||||
|
$rank = card_rank($card); |
||||||
|
if ($rank >= 16) { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
$suits = ['♠', '♥', '♣', '♦']; |
||||||
|
return $suits[card_suit($card)]; |
||||||
|
} |
||||||
|
|
||||||
|
function sort_cards(array &$cards): void |
||||||
|
{ |
||||||
|
usort($cards, function (int $a, int $b): int { |
||||||
|
$ra = card_rank($a); |
||||||
|
$rb = card_rank($b); |
||||||
|
return $ra == $rb ? card_suit($a) <=> card_suit($b) : $ra <=> $rb; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function rank_counts(array $cards): array |
||||||
|
{ |
||||||
|
$counts = []; |
||||||
|
foreach ($cards as $card) { |
||||||
|
$rank = card_rank($card); |
||||||
|
$counts[$rank] = ($counts[$rank] ?? 0) + 1; |
||||||
|
} |
||||||
|
ksort($counts); |
||||||
|
return $counts; |
||||||
|
} |
||||||
|
|
||||||
|
function is_consecutive(array $ranks): bool |
||||||
|
{ |
||||||
|
sort($ranks); |
||||||
|
for ($i = 1; $i < count($ranks); $i++) { |
||||||
|
if ($ranks[$i] != $ranks[$i - 1] + 1) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function analyze_play(array $cards): array |
||||||
|
{ |
||||||
|
$n = count($cards); |
||||||
|
if ($n == 0) { |
||||||
|
return ['valid' => false, 'type' => 'none', 'main' => 0, 'len' => 0]; |
||||||
|
} |
||||||
|
|
||||||
|
$counts = rank_counts($cards); |
||||||
|
$ranks = array_keys($counts); |
||||||
|
$values = array_values($counts); |
||||||
|
sort($values); |
||||||
|
|
||||||
|
if ($n == 2 && in_array(16, $ranks, true) && in_array(17, $ranks, true)) { |
||||||
|
return ['valid' => true, 'type' => 'rocket', 'main' => 17, 'len' => 2]; |
||||||
|
} |
||||||
|
if ($n == 4 && count($counts) == 1) { |
||||||
|
return ['valid' => true, 'type' => 'bomb', 'main' => $ranks[0], 'len' => 4]; |
||||||
|
} |
||||||
|
if ($n == 6 && $values == [1, 1, 4]) { |
||||||
|
foreach ($counts as $rank => $count) { |
||||||
|
if ($count == 4) { |
||||||
|
return ['valid' => true, 'type' => 'four_two_single', 'main' => $rank, 'len' => 6]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if ($n == 8 && $values == [2, 2, 4]) { |
||||||
|
foreach ($counts as $rank => $count) { |
||||||
|
if ($count == 4) { |
||||||
|
return ['valid' => true, 'type' => 'four_two_pair', 'main' => $rank, 'len' => 8]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if ($n == 1) { |
||||||
|
return ['valid' => true, 'type' => 'single', 'main' => $ranks[0], 'len' => 1]; |
||||||
|
} |
||||||
|
if ($n == 2 && count($counts) == 1) { |
||||||
|
return ['valid' => true, 'type' => 'pair', 'main' => $ranks[0], 'len' => 2]; |
||||||
|
} |
||||||
|
if ($n == 3 && count($counts) == 1) { |
||||||
|
return ['valid' => true, 'type' => 'triple', 'main' => $ranks[0], 'len' => 3]; |
||||||
|
} |
||||||
|
if ($n == 4 && $values == [1, 3]) { |
||||||
|
foreach ($counts as $rank => $count) { |
||||||
|
if ($count == 3) { |
||||||
|
return ['valid' => true, 'type' => 'triple_single', 'main' => $rank, 'len' => 4]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if ($n == 5 && $values == [2, 3]) { |
||||||
|
foreach ($counts as $rank => $count) { |
||||||
|
if ($count == 3) { |
||||||
|
return ['valid' => true, 'type' => 'triple_pair', 'main' => $rank, 'len' => 5]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if ($n >= 5 && count($counts) == $n && max($ranks) < 15 && is_consecutive($ranks)) { |
||||||
|
return ['valid' => true, 'type' => 'straight', 'main' => max($ranks), 'len' => $n]; |
||||||
|
} |
||||||
|
if ($n >= 6 && $n % 2 == 0 && min($values) == 2 && max($values) == 2 && max($ranks) < 15 && is_consecutive($ranks)) { |
||||||
|
return ['valid' => true, 'type' => 'pair_sequence', 'main' => max($ranks), 'len' => $n]; |
||||||
|
} |
||||||
|
if ($n >= 6 && $n % 3 == 0 && min($values) == 3 && max($values) == 3 && max($ranks) < 15 && is_consecutive($ranks)) { |
||||||
|
return ['valid' => true, 'type' => 'airplane', 'main' => max($ranks), 'len' => $n]; |
||||||
|
} |
||||||
|
|
||||||
|
return ['valid' => false, 'type' => 'invalid', 'main' => 0, 'len' => $n]; |
||||||
|
} |
||||||
|
|
||||||
|
function can_beat(array $play, array $last): bool |
||||||
|
{ |
||||||
|
if (!$play['valid']) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (!$last['valid']) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if ($play['type'] == 'rocket') { |
||||||
|
return $last['type'] != 'rocket'; |
||||||
|
} |
||||||
|
if ($play['type'] == 'bomb' && $last['type'] != 'bomb' && $last['type'] != 'rocket') { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return $play['type'] == $last['type'] && $play['len'] == $last['len'] && $play['main'] > $last['main']; |
||||||
|
} |
||||||
|
|
||||||
|
function play_name(array $play): string |
||||||
|
{ |
||||||
|
if (!$play['valid']) { |
||||||
|
return '无'; |
||||||
|
} |
||||||
|
$names = [ |
||||||
|
'single' => '单牌', 'pair' => '对子', 'triple' => '三张', |
||||||
|
'triple_single' => '三带一', 'triple_pair' => '三带一对', |
||||||
|
'four_two_single' => '四带二', |
||||||
|
'four_two_pair' => '四带两对', |
||||||
|
'straight' => '顺子', 'pair_sequence' => '连对', |
||||||
|
'airplane' => '飞机', 'bomb' => '炸弹', 'rocket' => '王炸', |
||||||
|
]; |
||||||
|
return ($names[$play['type']] ?? $play['type']) . ' ' . rank_label($play['main']); |
||||||
|
} |
||||||
|
|
||||||
|
function remove_cards(array &$hand, array $cards): void |
||||||
|
{ |
||||||
|
foreach ($cards as $card) { |
||||||
|
$idx = array_search($card, $hand, true); |
||||||
|
if ($idx !== false) { |
||||||
|
unset($hand[$idx]); |
||||||
|
} |
||||||
|
} |
||||||
|
$hand = array_values($hand); |
||||||
|
} |
||||||
|
|
||||||
|
function hand_strength(array $hand): int |
||||||
|
{ |
||||||
|
$score = 0; |
||||||
|
$counts = rank_counts($hand); |
||||||
|
foreach ($hand as $card) { |
||||||
|
$rank = card_rank($card); |
||||||
|
if ($rank >= 16) { |
||||||
|
$score += 7; |
||||||
|
} elseif ($rank == 15) { |
||||||
|
$score += 4; |
||||||
|
} elseif ($rank >= 13) { |
||||||
|
$score += 2; |
||||||
|
} |
||||||
|
} |
||||||
|
foreach ($counts as $rank => $count) { |
||||||
|
if ($count == 4) { |
||||||
|
$score += 9; |
||||||
|
} elseif ($count == 3) { |
||||||
|
$score += 4; |
||||||
|
} elseif ($count == 2 && $rank >= 12) { |
||||||
|
$score += 2; |
||||||
|
} |
||||||
|
} |
||||||
|
return $score; |
||||||
|
} |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
function win_create_window(string $title, int $width, int $height): int {} |
||||||
|
function win_show_window(int $hWnd, int $cmdShow): void {} |
||||||
|
function win_quit_requested(): bool {} |
||||||
|
function win_post_quit(int $exitCode): void {} |
||||||
|
function win_peek_message(): array {} |
||||||
|
function win_get_tick_count(): int {} |
||||||
|
function win_message_box(int $hWnd, string $text, string $caption, int $uType): int {} |
||||||
|
|
||||||
|
function win_begin_paint(int $hWnd): int {} |
||||||
|
function win_end_paint(int $hWnd, int $hdc): void {} |
||||||
|
function win_fill_rect(int $hdc, int $x, int $y, int $w, int $h, int $rgb): void {} |
||||||
|
function win_fill_ellipse(int $hdc, int $x, int $y, int $w, int $h, int $rgb): void {} |
||||||
|
function win_draw_line(int $hdc, int $x1, int $y1, int $x2, int $y2, int $rgb): void {} |
||||||
|
function win_draw_text(int $hdc, int $x, int $y, string $text, int $fontSize, int $rgb, int $bold): void {} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
name: landlord |
||||||
|
version: 1.0.0 |
||||||
|
mode: bin |
||||||
|
sources: |
||||||
|
- main.php |
||||||
|
- ./php-src |
||||||
|
- ./cpp-src |
||||||
@ -1 +1 @@ |
|||||||
1080 |
1082 |
||||||
Loading…
Reference in new issue