feat(ui): embed classic game terminal into 2.5D arcade bezel without OS borders

This commit is contained in:
Игорь Федосеев 2026-09-24 22:46:27 +03:00
parent 3ae4323379
commit e6bf8d8edb
6 changed files with 314 additions and 22 deletions

View file

@ -207,6 +207,7 @@ szTitleShop db "[KAZIK 3D CASINO] -
szTitleATM db "[KAZIK 3D CASINO] - ÁÀÍÊÎÌÀÒ",0
szTitleTerminal db "[KAZIK 3D CASINO] - ÒÅÐÌÈÍÀË ÈÃÐÎÊÀ",0
szTitleObserver db "[KAZIK 3D CASINO] - ÐÅÆÈÌ ÍÀÁËÞÄÀÒÅËß (ÈÈ)",0
textCabinetFooter db "[ ÂÛÕÎÄ: ÂÂÅÄÈÒÅ 0 / ÂÛÁÅÐÈÒÅ 'N' ÄËß ÂÎÇÂÐÀÒÀ Â ÇÀË ]",0
msgDancerTipped db "Âû áðîñèëè $100 òàíöîâùèöå! ÓÄÀ×À ÀÊÒÈÂÈÐÎÂÀÍÀ!",0
msgNeedMoney db "Íåäîñòàòî÷íî äåíåã â êîøåëüêå!",0
@ -2684,15 +2685,55 @@ interaction_done:
ret
CheckInteractions ENDP
; --- LaunchClassicGame: Îòêðûòèå îòäåëüíîãî îêíà äëÿ êëàññè÷åñêîé âåðñèè èãðû ---
; --- RenderCabinetBezel: Îòðèñîâêà àðêàäíîãî áåçåëÿ òåðìèíàëà íà 3D ýêðàíå ---
RenderCabinetBezel PROC uses ebx esi edi, pTitle:DWORD
; Çàòåìíÿåì 3D-çàë â áóôåðå êàäðà (äåëèì ÿðêîñòü ïîïîëàì)
mov ecx, SCREEN_SIZE
xor esi, esi
dim_bezel_loop:
mov eax, [screenBuffer + esi*4]
shr eax, 1
and eax, 007F7F7Fh
mov [screenBuffer + esi*4], eax
inc esi
loop dim_bezel_loop
; Âíåøíÿÿ çîëîòàÿ ðàìêà òåðìèíàëà
invoke DrawBoxBorder, 10, 14, 300, 212, 000C0E14h, 00D8BC6Ah, 2
; Øàïêà òåðìèíàëà ñ íàçâàíèåì èãðû
invoke DrawBox, 12, 16, 296, 16, 00221A10h
invoke DrawString8x8, 20, 20, pTitle, 00F5E2B0h
; Ïîäâàëüíàÿ ïëàøêà ñ ïîäñêàçêîé ïî âûõîäó
invoke DrawBox, 12, 210, 296, 14, 00141416h
invoke DrawString8x8, 20, 213, OFFSET textCabinetFooter, 00AAAAAAh
; Âûâîäèì êàäð áåçåëÿ â îêíî
call Present3D
ret
RenderCabinetBezel ENDP
; --- LaunchClassicGame: Âñòðàèâàíèå èãðû â UI òåðìèíàëà êàçèíî ---
LaunchClassicGame PROC uses ebx esi edi, pGameProc:DWORD, gameId:DWORD, pTitle:DWORD
LOCAL rc3D[16]:BYTE
LOCAL rcClient[16]:BYTE
LOCAL ptScreen[8]:BYTE
LOCAL fontInfo[84]:BYTE
LOCAL conWnd:DWORD
LOCAL conW:DWORD, conH:DWORD, conX:DWORD, conY:DWORD
LOCAL viewW:DWORD, viewH:DWORD
LOCAL offsetX:DWORD, offsetY:DWORD
mov eax, gameId
mov currentGameId, eax
; 1. Ðèñóåì çîëîòîé áåçåëü òåðìèíàëà íà 3D ýêðàíå
cmp pTitle, 0
je @F
invoke RenderCabinetBezel, pTitle
@@:
; 2. Âûäåëÿåì êîíñîëü
invoke AllocConsole
test eax, eax
jz launch_ret
@ -2712,25 +2753,125 @@ LaunchClassicGame PROC uses ebx esi edi, pGameProc:DWORD, gameId:DWORD, pTitle:D
call EnableAnsi
call ConfigureConsoleSize
; 3. Íàñòðàèâàåì øðèôò Consolas Bold 16pt
lea edi, fontInfo
xor eax, eax
mov ecx, 21
rep stosd
mov dword ptr fontInfo[0], 84 ; cbSize
mov word ptr fontInfo[8], 0 ; dwFontSize.X
mov word ptr fontInfo[10], 16 ; dwFontSize.Y
mov dword ptr fontInfo[16], 700 ; FontWeight = FW_BOLD
mov word ptr fontInfo[20], 'C'
mov word ptr fontInfo[22], 'o'
mov word ptr fontInfo[24], 'n'
mov word ptr fontInfo[26], 's'
mov word ptr fontInfo[28], 'o'
mov word ptr fontInfo[30], 'l'
mov word ptr fontInfo[32], 'a'
mov word ptr fontInfo[34], 's'
mov word ptr fontInfo[36], 0
lea eax, fontInfo
invoke SetCurrentConsoleFontEx, hOut, 0, eax
; 4. Ïîëó÷àåì äåñêðèïòîð îêíà êîíñîëè
invoke GetConsoleWindow
mov conWnd, eax
test eax, eax
jz run_game_body
; 5. Ñíèìàåì ñèñòåìíóþ ðàìêó Windows è çàãîëîâîê ñ êíîïêàìè çàêðûòèÿ/ñâîðà÷èâàíèÿ
invoke GetWindowLongA, conWnd, -16 ; GWL_STYLE
and eax, NOT (00C00000h or 00040000h or 00080000h or 00010000h or 00020000h)
or eax, 80000000h ; WS_POPUP
invoke SetWindowLongA, conWnd, -16, eax
; Ñâÿçûâàåì êàê äî÷åðíåå/ïðèíàäëåæàùåå îêíî ê îêíó èãðû
cmp h3DWnd, 0
je show_con_fallback
invoke SetWindowLongA, conWnd, -8, h3DWnd ; GWL_HWNDPARENT
lea eax, rc3D
invoke GetWindowRect, h3DWnd, eax
mov eax, dword ptr rc3D[0]
add eax, 40
; 6. Âû÷èñëÿåì òî÷íûå êîîðäèíàòû äëÿ ïîñàäêè ýêðàíà âíóòðü áåçåëÿ
lea eax, rcClient
invoke GetClientRect, h3DWnd, eax
mov esi, dword ptr rcClient[8] ; øèðèíà êëèåíòñêîé îáëàñòè
mov edi, dword ptr rcClient[12] ; âûñîòà êëèåíòñêîé îáëàñòè
test esi, esi
jz show_con_fallback
test edi, edi
jz show_con_fallback
; Ðàñ÷åò âüþïîðòà 4:3 òî÷íî êàê â Present3D
mov viewW, esi
mov eax, esi
imul eax, 3
shr eax, 2
cmp eax, edi
jle calc_view_h
mov eax, edi
imul eax, 4
xor edx, edx
mov ecx, 3
div ecx
mov viewW, eax
mov eax, edi
calc_view_h:
mov viewH, eax
mov ebx, esi
sub ebx, viewW
shr ebx, 1
mov offsetX, ebx
mov ebx, edi
sub ebx, viewH
shr ebx, 1
mov offsetY, ebx
; Ýêðàííûå êîîðäèíàòû ëåâîãî âåðõíåãî óãëà êëèåíòñêîé îáëàñòè
mov dword ptr ptScreen[0], 0
mov dword ptr ptScreen[4], 0
lea eax, ptScreen
invoke ClientToScreen, h3DWnd, eax
; conW = viewW * 280 / 320 (âíóòðåííåå îêíî áåçåëÿ)
mov eax, viewW
imul eax, 280
xor edx, edx
mov ecx, 320
div ecx
mov conW, eax
; conH = viewH * 168 / 240
mov eax, viewH
imul eax, 168
xor edx, edx
mov ecx, 240
div ecx
mov conH, eax
; conX = ptScreen.x + offsetX + (viewW * 20 / 320)
mov eax, viewW
imul eax, 20
xor edx, edx
mov ecx, 320
div ecx
add eax, offsetX
add eax, dword ptr ptScreen[0]
mov conX, eax
mov eax, dword ptr rc3D[4]
add eax, 40
; conY = ptScreen.y + offsetY + (viewH * 38 / 240)
mov eax, viewH
imul eax, 38
xor edx, edx
mov ecx, 240
div ecx
add eax, offsetY
add eax, dword ptr ptScreen[4]
mov conY, eax
mov conW, 960
mov conH, 680
invoke SetWindowPos, conWnd, 0, conX, conY, conW, conH, 40h ; SWP_SHOWWINDOW
; Ïîçèöèîíèðóåì áåçðàìî÷íûé ýêðàí òî÷íî âíóòðü çîëîòîé ðàìêè áåçåëÿ
invoke SetWindowPos, conWnd, 0, conX, conY, conW, conH, 20h or 40h ; SWP_FRAMECHANGED | SWP_SHOWWINDOW
jmp set_con_focus
show_con_fallback:
@ -2740,12 +2881,15 @@ set_con_focus:
invoke SetFocus, conWnd
run_game_body:
; Çàïóñê îðèãèíàëüíîé èãðû!
call pGameProc
; Çàêðûâàåì êîíñîëü
invoke FreeConsole
mov hOut, 0
mov hIn, 0
; Âîçâðàùàåì ôîêóñ â îêíî 3D èãðû
cmp h3DWnd, 0
je cleanup_game_input
invoke SetForegroundWindow, h3DWnd

View file

@ -79,6 +79,8 @@ SetConsoleTitleA PROTO :DWORD
GetWindowRect PROTO :DWORD, :DWORD
SetWindowPos PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
SetFocus PROTO :DWORD
ClientToScreen PROTO :DWORD, :DWORD
SetCurrentConsoleFontEx PROTO :DWORD, :DWORD, :DWORD
mciSendStringA PROTO :DWORD, :DWORD, :DWORD, :DWORD
waveOutSetVolume PROTO :DWORD, :DWORD
AnimFrameDelay PROTO :DWORD

Binary file not shown.

View file

@ -207,6 +207,7 @@ szTitleShop db "[KAZIK 3D CASINO] -
szTitleATM db "[KAZIK 3D CASINO] - ÁÀÍÊÎÌÀÒ",0
szTitleTerminal db "[KAZIK 3D CASINO] - ÒÅÐÌÈÍÀË ÈÃÐÎÊÀ",0
szTitleObserver db "[KAZIK 3D CASINO] - ÐÅÆÈÌ ÍÀÁËÞÄÀÒÅËß (ÈÈ)",0
textCabinetFooter db "[ ÂÛÕÎÄ: ÂÂÅÄÈÒÅ 0 / ÂÛÁÅÐÈÒÅ 'N' ÄËß ÂÎÇÂÐÀÒÀ Â ÇÀË ]",0
msgDancerTipped db "Âû áðîñèëè $100 òàíöîâùèöå! ÓÄÀ×À ÀÊÒÈÂÈÐÎÂÀÍÀ!",0
msgNeedMoney db "Íåäîñòàòî÷íî äåíåã â êîøåëüêå!",0
@ -2684,15 +2685,55 @@ interaction_done:
ret
CheckInteractions ENDP
; --- LaunchClassicGame: Îòêðûòèå îòäåëüíîãî îêíà äëÿ êëàññè÷åñêîé âåðñèè èãðû ---
; --- RenderCabinetBezel: Îòðèñîâêà àðêàäíîãî áåçåëÿ òåðìèíàëà íà 3D ýêðàíå ---
RenderCabinetBezel PROC uses ebx esi edi, pTitle:DWORD
; Çàòåìíÿåì 3D-çàë â áóôåðå êàäðà (äåëèì ÿðêîñòü ïîïîëàì)
mov ecx, SCREEN_SIZE
xor esi, esi
dim_bezel_loop:
mov eax, [screenBuffer + esi*4]
shr eax, 1
and eax, 007F7F7Fh
mov [screenBuffer + esi*4], eax
inc esi
loop dim_bezel_loop
; Âíåøíÿÿ çîëîòàÿ ðàìêà òåðìèíàëà
invoke DrawBoxBorder, 10, 14, 300, 212, 000C0E14h, 00D8BC6Ah, 2
; Øàïêà òåðìèíàëà ñ íàçâàíèåì èãðû
invoke DrawBox, 12, 16, 296, 16, 00221A10h
invoke DrawString8x8, 20, 20, pTitle, 00F5E2B0h
; Ïîäâàëüíàÿ ïëàøêà ñ ïîäñêàçêîé ïî âûõîäó
invoke DrawBox, 12, 210, 296, 14, 00141416h
invoke DrawString8x8, 20, 213, OFFSET textCabinetFooter, 00AAAAAAh
; Âûâîäèì êàäð áåçåëÿ â îêíî
call Present3D
ret
RenderCabinetBezel ENDP
; --- LaunchClassicGame: Âñòðàèâàíèå èãðû â UI òåðìèíàëà êàçèíî ---
LaunchClassicGame PROC uses ebx esi edi, pGameProc:DWORD, gameId:DWORD, pTitle:DWORD
LOCAL rc3D[16]:BYTE
LOCAL rcClient[16]:BYTE
LOCAL ptScreen[8]:BYTE
LOCAL fontInfo[84]:BYTE
LOCAL conWnd:DWORD
LOCAL conW:DWORD, conH:DWORD, conX:DWORD, conY:DWORD
LOCAL viewW:DWORD, viewH:DWORD
LOCAL offsetX:DWORD, offsetY:DWORD
mov eax, gameId
mov currentGameId, eax
; 1. Ðèñóåì çîëîòîé áåçåëü òåðìèíàëà íà 3D ýêðàíå
cmp pTitle, 0
je @F
invoke RenderCabinetBezel, pTitle
@@:
; 2. Âûäåëÿåì êîíñîëü
invoke AllocConsole
test eax, eax
jz launch_ret
@ -2712,25 +2753,125 @@ LaunchClassicGame PROC uses ebx esi edi, pGameProc:DWORD, gameId:DWORD, pTitle:D
call EnableAnsi
call ConfigureConsoleSize
; 3. Íàñòðàèâàåì øðèôò Consolas Bold 16pt
lea edi, fontInfo
xor eax, eax
mov ecx, 21
rep stosd
mov dword ptr fontInfo[0], 84 ; cbSize
mov word ptr fontInfo[8], 0 ; dwFontSize.X
mov word ptr fontInfo[10], 16 ; dwFontSize.Y
mov dword ptr fontInfo[16], 700 ; FontWeight = FW_BOLD
mov word ptr fontInfo[20], 'C'
mov word ptr fontInfo[22], 'o'
mov word ptr fontInfo[24], 'n'
mov word ptr fontInfo[26], 's'
mov word ptr fontInfo[28], 'o'
mov word ptr fontInfo[30], 'l'
mov word ptr fontInfo[32], 'a'
mov word ptr fontInfo[34], 's'
mov word ptr fontInfo[36], 0
lea eax, fontInfo
invoke SetCurrentConsoleFontEx, hOut, 0, eax
; 4. Ïîëó÷àåì äåñêðèïòîð îêíà êîíñîëè
invoke GetConsoleWindow
mov conWnd, eax
test eax, eax
jz run_game_body
; 5. Ñíèìàåì ñèñòåìíóþ ðàìêó Windows è çàãîëîâîê ñ êíîïêàìè çàêðûòèÿ/ñâîðà÷èâàíèÿ
invoke GetWindowLongA, conWnd, -16 ; GWL_STYLE
and eax, NOT (00C00000h or 00040000h or 00080000h or 00010000h or 00020000h)
or eax, 80000000h ; WS_POPUP
invoke SetWindowLongA, conWnd, -16, eax
; Ñâÿçûâàåì êàê äî÷åðíåå/ïðèíàäëåæàùåå îêíî ê îêíó èãðû
cmp h3DWnd, 0
je show_con_fallback
invoke SetWindowLongA, conWnd, -8, h3DWnd ; GWL_HWNDPARENT
lea eax, rc3D
invoke GetWindowRect, h3DWnd, eax
mov eax, dword ptr rc3D[0]
add eax, 40
; 6. Âû÷èñëÿåì òî÷íûå êîîðäèíàòû äëÿ ïîñàäêè ýêðàíà âíóòðü áåçåëÿ
lea eax, rcClient
invoke GetClientRect, h3DWnd, eax
mov esi, dword ptr rcClient[8] ; øèðèíà êëèåíòñêîé îáëàñòè
mov edi, dword ptr rcClient[12] ; âûñîòà êëèåíòñêîé îáëàñòè
test esi, esi
jz show_con_fallback
test edi, edi
jz show_con_fallback
; Ðàñ÷åò âüþïîðòà 4:3 òî÷íî êàê â Present3D
mov viewW, esi
mov eax, esi
imul eax, 3
shr eax, 2
cmp eax, edi
jle calc_view_h
mov eax, edi
imul eax, 4
xor edx, edx
mov ecx, 3
div ecx
mov viewW, eax
mov eax, edi
calc_view_h:
mov viewH, eax
mov ebx, esi
sub ebx, viewW
shr ebx, 1
mov offsetX, ebx
mov ebx, edi
sub ebx, viewH
shr ebx, 1
mov offsetY, ebx
; Ýêðàííûå êîîðäèíàòû ëåâîãî âåðõíåãî óãëà êëèåíòñêîé îáëàñòè
mov dword ptr ptScreen[0], 0
mov dword ptr ptScreen[4], 0
lea eax, ptScreen
invoke ClientToScreen, h3DWnd, eax
; conW = viewW * 280 / 320 (âíóòðåííåå îêíî áåçåëÿ)
mov eax, viewW
imul eax, 280
xor edx, edx
mov ecx, 320
div ecx
mov conW, eax
; conH = viewH * 168 / 240
mov eax, viewH
imul eax, 168
xor edx, edx
mov ecx, 240
div ecx
mov conH, eax
; conX = ptScreen.x + offsetX + (viewW * 20 / 320)
mov eax, viewW
imul eax, 20
xor edx, edx
mov ecx, 320
div ecx
add eax, offsetX
add eax, dword ptr ptScreen[0]
mov conX, eax
mov eax, dword ptr rc3D[4]
add eax, 40
; conY = ptScreen.y + offsetY + (viewH * 38 / 240)
mov eax, viewH
imul eax, 38
xor edx, edx
mov ecx, 240
div ecx
add eax, offsetY
add eax, dword ptr ptScreen[4]
mov conY, eax
mov conW, 960
mov conH, 680
invoke SetWindowPos, conWnd, 0, conX, conY, conW, conH, 40h ; SWP_SHOWWINDOW
; Ïîçèöèîíèðóåì áåçðàìî÷íûé ýêðàí òî÷íî âíóòðü çîëîòîé ðàìêè áåçåëÿ
invoke SetWindowPos, conWnd, 0, conX, conY, conW, conH, 20h or 40h ; SWP_FRAMECHANGED | SWP_SHOWWINDOW
jmp set_con_focus
show_con_fallback:
@ -2740,12 +2881,15 @@ set_con_focus:
invoke SetFocus, conWnd
run_game_body:
; Çàïóñê îðèãèíàëüíîé èãðû!
call pGameProc
; Çàêðûâàåì êîíñîëü
invoke FreeConsole
mov hOut, 0
mov hIn, 0
; Âîçâðàùàåì ôîêóñ â îêíî 3D èãðû
cmp h3DWnd, 0
je cleanup_game_input
invoke SetForegroundWindow, h3DWnd

View file

@ -79,6 +79,8 @@ SetConsoleTitleA PROTO :DWORD
GetWindowRect PROTO :DWORD, :DWORD
SetWindowPos PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
SetFocus PROTO :DWORD
ClientToScreen PROTO :DWORD, :DWORD
SetCurrentConsoleFontEx PROTO :DWORD, :DWORD, :DWORD
mciSendStringA PROTO :DWORD, :DWORD, :DWORD, :DWORD
waveOutSetVolume PROTO :DWORD, :DWORD
AnimFrameDelay PROTO :DWORD

BIN
poker.exe

Binary file not shown.