diff --git a/build/graphics/casino3d.inc b/build/graphics/casino3d.inc index e3d7728..96f7064 100644 --- a/build/graphics/casino3d.inc +++ b/build/graphics/casino3d.inc @@ -112,6 +112,9 @@ MODE_BLACKJACK equ 2 MODE_ROULETTE equ 3 MODE_SHOP equ 4 MODE_ATM equ 5 +MODE_COIN equ 6 +MODE_DICE equ 7 +MODE_SKULLS equ 8 WS_OVERLAPPEDWINDOW equ 00CF0000h SW_SHOW equ 5 @@ -276,6 +279,75 @@ roulWinningNum dd 0 roulPayout dd 0 roulOutcomeMsg db 64 dup(0) +; --- Native 2.5D Coin Flip Game --- +coin3d_bet dd 50 +coin3d_side dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà +coin3d_state dd 0 ; 0 = Idle, 1 = Flipping, 2 = Result +coin3d_timer dd 0 +coin3d_result dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà +coin3d_streak dd 0 +coin3d_win dd 0 + +coinRxAnimTable db 22, 18, 12, 4, 12, 18, 22, 18, 12, 4 + +textCoinTitle db "ÌÎÍÅÒÊÀ (ÎÐ¨Ë / ÐÅØÊÀ)",0 +textCoinHeads db "ÎШË",0 +textCoinTails db "ÐÅØÊÀ",0 +textCoinStreak db "ÑÅÐÈß: ",0 +textCoinSide1 db "[1] ÎШË",0 +textCoinSide2 db "[2] ÐÅØÊÀ",0 +textCoinFlipping db "ÌÎÍÅÒÀ  ÂÎÇÄÓÕÅ...",0 +textCoinWin db "ÂÛÈÃÐÛØ! +$",0 +textCoinLose db "ÏÐÎÈÃÐÛØ!",0 +textCoinControls1 db "[1/2] ÑÒÎÐÎÍÀ [ÏÐÎÁÅË] ÁÐÎÑÎÊ",0 +textCoinControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",0 + +; --- Native 2.5D Dice Game --- +dice3d_bet dd 50 +dice3d_choice dd 1 ; 1 = ׸ò, 2 = Íå÷åò +dice3d_state dd 0 ; 0 = Idle, 1 = Rolling, 2 = Result +dice3d_timer dd 0 +dice3d_val1 dd 3 +dice3d_val2 dd 4 +dice3d_sum dd 7 +dice3d_win dd 0 + +textDiceTitle db "ÊÎÑÒÈ (CRAPS) - ×¨Ò / ÍÅ×ÅÒ",0 +textDiceEven db "[1] רÒ",0 +textDiceOdd db "[2] ÍÅ×ÅÒ",0 +textDiceTally db "ÊÎÑÒÈ: ",0 +textDicePlus db " + ",0 +textDiceEqual db " = ",0 +textDiceEvenResult db " (רÒ)",0 +textDiceOddResult db " (ÍÅ×ÅÒ)",0 +textDiceRolling db "ÁÐÎÑÎÊ ÊÎÑÒÅÉ...",0 +textDiceWin db "ÂÛÈÃÐÛØ! +$",0 +textDiceLose db "ÏÐÎÈÃÐÛØ!",0 +textDiceControls1 db "[1] ×¨Ò [2] ÍÅ×ÅÒ [ÏÐÎÁÅË] ÁÐÎÑÎÊ",0 +textDiceControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",0 + +; --- Native 2.5D Skulls Game --- +skulls3d_bet dd 50 +skulls3d_state dd 0 ; 0 = Idle, 1 = Show ball, 2 = Shuffle, 3 = Pick, 4 = Reveal +skulls3d_timer dd 0 +skulls3d_ballPos dd 0 ; 0, 1, 2 +skulls3d_choice dd 0 ; 0, 1, 2 +skulls3d_win dd 0 +skulls3d_swapPair0 dd 0 +skulls3d_swapPair1 dd 1 +skulls3d_swapPair2 dd 2 + +textSkullsTitle db "ÍÀϨÐÑÒÊÈ (×ÅÐÅÏÀ È ÊÓÁÊÈ)",0 +textSkullsPhase0 db "ÂÛÁÅÐÈÒÅ ÑÒÀÂÊÓ È ÍÀÆÌÈÒÅ [ÏÐÎÁÅË]",0 +textSkullsPhase1 db "ÇÀÏÎÌÍÈÒÅ, ÃÄÅ ØÀÐÈÊ!",0 +textSkullsPhase2 db "ÊÐÓ×Ó, ÂÅÐ×Ó, ÇÀÏÓÒÀÒÜ ÕÎ×Ó...",0 +textSkullsPhase3 db "ÃÄÅ ØÀÐÈÊ? ÍÀÆÌÈÒÅ [1], [2] ÈËÈ [3]!",0 +textSkullsWin db "ÂÛ ÓÃÀÄÀËÈ! ÄÆÅÊÏÎÒ x3! +$",0 +textSkullsLose db "ÍÅ ÓÃÀÄÀËÈ! ØÀÐÈÊ ÁÛË ÍÅ ÇÄÅÑÜ!",0 +textSkullsAgain db "[ÏÐÎÁÅË] - ÑÛÃÐÀÒÜ ÅÙ¨ ÐÀÇ",0 +textSkullsControls1 db "[1/2/3] ÂÛÁÎÐ ÊÓÁÊÀ [ÏÐÎÁÅË] ÑÒÀÐÒ",0 +textSkullsControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",0 + shopMsg db 128 dup(0) atmMsg db 128 dup(0) @@ -2558,6 +2630,1188 @@ RenderATMGame PROC ret RenderATMGame ENDP +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: COIN FLIP (ÌÎÍÅÒÊÀ) +; ============================================================================== +DrawCoinEllipse PROC uses ebx esi edi cxVal:DWORD, cyVal:DWORD, rxVal:DWORD, ryVal:DWORD, outerColor:DWORD, innerColor:DWORD + local curDY:DWORD, curDX:DWORD, rxSq:DWORD, rySq:DWORD, rxRySq:DWORD, threshSq:DWORD + cmp rxVal, 0 + jle ellipse_done + cmp ryVal, 0 + jle ellipse_done + + mov eax, rxVal + imul eax, eax + mov rxSq, eax + + mov eax, ryVal + imul eax, eax + mov rySq, eax + + mov eax, rxSq + imul eax, rySq + mov rxRySq, eax + + mov eax, rxRySq + shr eax, 2 + imul eax, 3 + mov threshSq, eax + + mov eax, ryVal + neg eax + mov curDY, eax + +ellipse_y_loop: + mov eax, curDY + cmp eax, ryVal + jg ellipse_done + + mov eax, rxVal + neg eax + mov curDX, eax + +ellipse_x_loop: + mov eax, curDX + cmp eax, rxVal + jg next_ellipse_y + + mov eax, curDX + imul eax, eax + imul eax, rySq + mov ebx, curDY + imul ebx, ebx + imul ebx, rxSq + add eax, ebx + cmp eax, rxRySq + jg next_ellipse_x + + mov ecx, innerColor + cmp eax, threshSq + jb @F + mov ecx, outerColor +@@: + mov eax, cxVal + add eax, curDX + mov edx, cyVal + add edx, curDY + invoke DrawPixel, eax, edx, ecx + +next_ellipse_x: + inc curDX + jmp ellipse_x_loop + +next_ellipse_y: + inc curDY + jmp ellipse_y_loop + +ellipse_done: + ret +DrawCoinEllipse ENDP + +InitCoinGame PROC + mov coin3d_state, 0 + mov coin3d_timer, 0 + mov coin3d_win, 0 + cmp coin3d_bet, 10 + jge @F + mov coin3d_bet, 50 +@@: + ret +InitCoinGame ENDP + +HandleCoinInput PROC + cmp coin3d_state, 1 + je coin_input_done + + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_coin_side + mov eax, bankroll + cmp eax, coin3d_bet + jl coin_no_cash + sub eax, coin3d_bet + mov bankroll, eax + mov coin3d_state, 1 + mov coin3d_timer, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp coin_input_done +coin_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp coin_input_done + +check_coin_side: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov coin3d_side, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_coin_bet_adjust + mov coin3d_side, 2 + +check_coin_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz coin_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_coin_bet_down +coin_inc_bet: + cmp coin3d_bet, 500 + jge coin_input_done + cmp coin3d_bet, 250 + jge coin_set_500 + cmp coin3d_bet, 100 + jge coin_set_250 + cmp coin3d_bet, 50 + jge coin_set_100 + cmp coin3d_bet, 25 + jge coin_set_50 + jmp coin_set_25 + +check_coin_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz coin_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz coin_input_done +coin_dec_bet: + cmp coin3d_bet, 25 + jle coin_set_10 + cmp coin3d_bet, 50 + jle coin_set_25 + cmp coin3d_bet, 100 + jle coin_set_50 + cmp coin3d_bet, 250 + jle coin_set_100 + jmp coin_set_250 + +coin_set_500: + mov coin3d_bet, 500 + jmp coin_input_done +coin_set_250: + mov coin3d_bet, 250 + jmp coin_input_done +coin_set_100: + mov coin3d_bet, 100 + jmp coin_input_done +coin_set_50: + mov coin3d_bet, 50 + jmp coin_input_done +coin_set_25: + mov coin3d_bet, 25 + jmp coin_input_done +coin_set_10: + mov coin3d_bet, 10 + jmp coin_input_done + +coin_input_done: + ret +HandleCoinInput ENDP + +RenderCoinGame PROC uses ebx esi edi + local cyVal:DWORD, rxVal:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00140D18h + invoke DrawBoxBorder, 10, 10, 300, 220, 0022142Ah, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000D0812h, 0000FFFFh, 2 + invoke DrawString8x8, 72, 27, OFFSET textCoinTitle, 0000D7FFh + + ; Streak Display + invoke DrawString8x8, 28, 50, OFFSET textCoinStreak, 0000D7FFh + invoke FormatNumber, coin3d_streak, OFFSET hudNumBuffer + invoke DrawString8x8, 84, 50, OFFSET hudNumBuffer, 0050FF50h + + ; Side Panel: [1] ÎÐ¨Ë + mov eax, 00120D16h + mov edx, 00505050h + mov ecx, 00808080h + cmp coin3d_side, 1 + jne @F + mov eax, 001E3520h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 24, 70, 68, 38, eax, edx, 2 + pop ecx + invoke DrawString8x8, 28, 85, OFFSET textCoinSide1, ecx + + ; Side Panel: [2] ÐÅØÊÀ + mov eax, 00120D16h + mov edx, 00505050h + mov ecx, 00808080h + cmp coin3d_side, 2 + jne @F + mov eax, 001E3520h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 228, 70, 68, 38, eax, edx, 2 + pop ecx + invoke DrawString8x8, 232, 85, OFFSET textCoinSide2, ecx + + ; Center coin pedestal arena + invoke DrawBoxBorder, 102, 54, 116, 84, 000F0A12h, 00504030h, 1 + + ; Flipping animation logic + cmp coin3d_state, 1 + jne coin_at_rest + + inc coin3d_timer + + ; Parabolic toss: cy = 96 - (t * (40 - t)) / 16 + mov eax, coin3d_timer + mov ecx, 40 + sub ecx, eax + imul eax, ecx + shr eax, 4 + mov edx, 96 + sub edx, eax + mov cyVal, edx + + ; Width rx from lookup table: (t % 10) + mov eax, coin3d_timer + xor edx, edx + mov ecx, 10 + div ecx + movzx eax, BYTE PTR [coinRxAnimTable + edx] + mov rxVal, eax + + invoke DrawCoinEllipse, 160, cyVal, rxVal, 22, 0000D7FFh, 0000B0E0h + invoke DrawString8x8, 84, 142, OFFSET textCoinFlipping, 0000FFFFh + + cmp coin3d_timer, 40 + jl coin_draw_controls + + ; Flip complete! + mov coin3d_state, 2 + invoke RandomRange3D, 2 + inc eax + mov coin3d_result, eax + + mov eax, coin3d_result + cmp eax, coin3d_side + jne coin_flip_lost + + ; Won! + mov eax, coin3d_bet + shl eax, 1 + mov coin3d_win, eax + add bankroll, eax + inc coin3d_streak + cmp coin3d_streak, 3 + jl @F + invoke PlaySoundA, OFFSET soundJackpot, 0, 1 + jmp coin_draw_controls +@@: + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp coin_draw_controls + +coin_flip_lost: + mov coin3d_streak, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp coin_draw_controls + +coin_at_rest: + ; Draw coin resting at (160, 96) + invoke DrawCoinEllipse, 160, 96, 24, 24, 0000D7FFh, 0000B0E0h + invoke DrawCoinEllipse, 160, 96, 20, 20, 0000FFFFh, 000090D0h + + ; Draw side text inside coin + cmp coin3d_state, 2 + jne coin_show_picked_side + cmp coin3d_result, 1 + jne @F + invoke DrawString8x8, 144, 92, OFFSET textCoinHeads, 00000030h + jmp coin_show_splash +@@: + invoke DrawString8x8, 140, 92, OFFSET textCoinTails, 00000030h + jmp coin_show_splash + +coin_show_picked_side: + cmp coin3d_side, 1 + jne @F + invoke DrawString8x8, 144, 92, OFFSET textCoinHeads, 00000030h + jmp coin_draw_controls +@@: + invoke DrawString8x8, 140, 92, OFFSET textCoinTails, 00000030h + jmp coin_draw_controls + +coin_show_splash: + cmp coin3d_win, 0 + je coin_show_loss + invoke DrawString8x8, 90, 142, OFFSET textCoinWin, 0000FFFFh + invoke FormatNumber, coin3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 178, 142, OFFSET hudNumBuffer, 0000FFFFh + jmp coin_draw_controls + +coin_show_loss: + invoke DrawString8x8, 126, 142, OFFSET textCoinLose, 000000FFh + +coin_draw_controls: + ; Bottom Control Panel + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, coin3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 28, 186, OFFSET textCoinControls1, 00FFFFFFh + invoke DrawString8x8, 28, 202, OFFSET textCoinControls2, 00A0A0A0h + ret +RenderCoinGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: DICE / CRAPS (ÊÎÑÒÈ) +; ============================================================================== +DrawDieCube PROC uses ebx esi edi x:DWORD, y:DWORD, cubeSize:DWORD, valNum:DWORD + local pipColor:DWORD + mov pipColor, 001515C0h + + invoke DrawBoxBorder, x, y, cubeSize, cubeSize, 00F4F6F8h, 00303038h, 2 + + mov eax, x + add eax, cubeSize + mov edx, y + add edx, 2 + invoke DrawBox, eax, edx, 2, cubeSize, 0008140Ah + mov eax, x + add eax, 2 + mov edx, y + add edx, cubeSize + invoke DrawBox, eax, edx, cubeSize, 2, 0008140Ah + + cmp valNum, 1 + je draw_die_center + cmp valNum, 3 + je draw_die_center + cmp valNum, 5 + je draw_die_center + jmp check_die_corners +draw_die_center: + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + +check_die_corners: + cmp valNum, 2 + jl die_render_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 27 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 2, pipColor + + cmp valNum, 4 + jl die_render_done + mov eax, x + add eax, 27 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 9 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 2, pipColor + + cmp valNum, 6 + jl die_render_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 27 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + +die_render_done: + ret +DrawDieCube ENDP + +InitDiceGame PROC + mov dice3d_state, 0 + mov dice3d_timer, 0 + mov dice3d_win, 0 + cmp dice3d_bet, 10 + jge @F + mov dice3d_bet, 50 +@@: + ret +InitDiceGame ENDP + +HandleDiceInput PROC + cmp dice3d_state, 1 + je dice_input_done + + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_dice_choice + mov eax, bankroll + cmp eax, dice3d_bet + jl dice_no_cash + sub eax, dice3d_bet + mov bankroll, eax + mov dice3d_state, 1 + mov dice3d_timer, 0 + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp dice_input_done +dice_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp dice_input_done + +check_dice_choice: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov dice3d_choice, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_dice_bet_adjust + mov dice3d_choice, 2 + +check_dice_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz dice_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_dice_bet_down +dice_inc_bet: + cmp dice3d_bet, 500 + jge dice_input_done + cmp dice3d_bet, 250 + jge dice_set_500 + cmp dice3d_bet, 100 + jge dice_set_250 + cmp dice3d_bet, 50 + jge dice_set_100 + cmp dice3d_bet, 25 + jge dice_set_50 + jmp dice_set_25 + +check_dice_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz dice_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz dice_input_done +dice_dec_bet: + cmp dice3d_bet, 25 + jle dice_set_10 + cmp dice3d_bet, 50 + jle dice_set_25 + cmp dice3d_bet, 100 + jle dice_set_50 + cmp dice3d_bet, 250 + jle dice_set_100 + jmp dice_set_250 + +dice_set_500: + mov dice3d_bet, 500 + jmp dice_input_done +dice_set_250: + mov dice3d_bet, 250 + jmp dice_input_done +dice_set_100: + mov dice3d_bet, 100 + jmp dice_input_done +dice_set_50: + mov dice3d_bet, 50 + jmp dice_input_done +dice_set_25: + mov dice3d_bet, 25 + jmp dice_input_done +dice_set_10: + mov dice3d_bet, 10 + jmp dice_input_done + +dice_input_done: + ret +HandleDiceInput ENDP + +RenderDiceGame PROC uses ebx esi edi + local d1X:DWORD, d1Y:DWORD, d2X:DWORD, d2Y:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 000C2612h + invoke DrawBoxBorder, 10, 10, 300, 220, 0014381Ah, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000A1F0Eh, 0000FFFFh, 2 + invoke DrawString8x8, 52, 27, OFFSET textDiceTitle, 0000D7FFh + + ; Choice Panels + mov eax, 000E2614h + mov edx, 00505050h + mov ecx, 00808080h + cmp dice3d_choice, 1 + jne @F + mov eax, 001C4824h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 24, 55, 76, 36, eax, edx, 2 + pop ecx + invoke DrawString8x8, 34, 68, OFFSET textDiceEven, ecx + + mov eax, 000E2614h + mov edx, 00505050h + mov ecx, 00808080h + cmp dice3d_choice, 2 + jne @F + mov eax, 001C4824h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 220, 55, 76, 36, eax, edx, 2 + pop ecx + invoke DrawString8x8, 226, 68, OFFSET textDiceOdd, ecx + + ; Dice Table Box + invoke DrawBoxBorder, 104, 52, 112, 54, 0009200Dh, 00305030h, 1 + + ; Rolling animation logic + cmp dice3d_state, 1 + jne dice_at_rest + + inc dice3d_timer + + ; Tumbling jitter offsets + mov eax, dice3d_timer + and eax, 3 + sub eax, 1 + + mov edx, 112 + add edx, eax + mov d1X, edx + + mov edx, 60 + sub edx, eax + mov d1Y, edx + + mov edx, 172 + sub edx, eax + mov d2X, edx + + mov edx, 62 + add edx, eax + mov d2Y, edx + + test dice3d_timer, 1 + jz @F + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax +@@: + invoke DrawDieCube, d1X, d1Y, 36, dice3d_val1 + invoke DrawDieCube, d2X, d2Y, 36, dice3d_val2 + + invoke DrawString8x8, 96, 132, OFFSET textDiceRolling, 0000FFFFh + + cmp dice3d_timer, 36 + jl dice_draw_controls + + ; Roll completed! + mov dice3d_state, 2 + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax + + mov eax, dice3d_val1 + add eax, dice3d_val2 + mov dice3d_sum, eax + + test eax, 1 + jz dice_sum_is_even + mov ecx, 2 ; Odd + jmp check_dice_win +dice_sum_is_even: + mov ecx, 1 ; Even + +check_dice_win: + cmp ecx, dice3d_choice + jne dice_roll_lost + + mov eax, dice3d_bet + shl eax, 1 + mov dice3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp dice_draw_controls + +dice_roll_lost: + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp dice_draw_controls + +dice_at_rest: + invoke DrawDieCube, 112, 60, 36, dice3d_val1 + invoke DrawDieCube, 172, 60, 36, dice3d_val2 + + cmp dice3d_state, 2 + jne dice_draw_controls + + ; Score Tally + invoke DrawString8x8, 80, 112, OFFSET textDiceTally, 0000D7FFh + invoke FormatNumber, dice3d_val1, OFFSET hudNumBuffer + invoke DrawString8x8, 136, 112, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 146, 112, OFFSET textDicePlus, 0000D7FFh + invoke FormatNumber, dice3d_val2, OFFSET hudNumBuffer + invoke DrawString8x8, 170, 112, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 180, 112, OFFSET textDiceEqual, 0000D7FFh + invoke FormatNumber, dice3d_sum, OFFSET hudNumBuffer + invoke DrawString8x8, 204, 112, OFFSET hudNumBuffer, 0000FFFFh + + mov eax, dice3d_sum + test eax, 1 + jz @F + invoke DrawString8x8, 222, 112, OFFSET textDiceOddResult, 00FF8080h + jmp dice_show_outcome +@@: + invoke DrawString8x8, 222, 112, OFFSET textDiceEvenResult, 0080FF80h + +dice_show_outcome: + cmp dice3d_win, 0 + je dice_show_loss + invoke DrawString8x8, 90, 132, OFFSET textDiceWin, 0000FFFFh + invoke FormatNumber, dice3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 178, 132, OFFSET hudNumBuffer, 0000FFFFh + jmp dice_draw_controls +dice_show_loss: + invoke DrawString8x8, 126, 132, OFFSET textDiceLose, 000000FFh + +dice_draw_controls: + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, dice3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 28, 186, OFFSET textDiceControls1, 00FFFFFFh + invoke DrawString8x8, 28, 202, OFFSET textDiceControls2, 00A0A0A0h + ret +RenderDiceGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: SKULLS & CUPS (ÍÀϨÐÑÒÊÈ) +; ============================================================================== +DrawCup PROC uses ebx esi edi x:DWORD, y:DWORD, cupNumChar:DWORD + invoke DrawBox, x + 14, y, 16, 4, 0000C8E8h + invoke DrawBoxBorder, x + 8, y + 4, 28, 12, 00221A30h, 0000D7FFh, 2 + invoke DrawBoxBorder, x + 4, y + 16, 36, 16, 00221A30h, 0000D7FFh, 2 + invoke DrawBoxBorder, x + 2, y + 32, 40, 8, 002A2038h, 0000FFFFh, 2 + + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawChar8x8, eax, edx, cupNumChar, 0000FFFFh + ret +DrawCup ENDP + +DrawGoldenBall PROC uses ebx esi edi x:DWORD, y:DWORD + invoke DrawCircle, x, y, 7, 0000A5D8h + invoke DrawCircle, x, y, 6, 0000D7FFh + invoke DrawCircle, x, y, 4, 0000FFFFh + mov eax, x + sub eax, 2 + mov edx, y + sub edx, 2 + invoke DrawCircle, eax, edx, 1, 00FFFFFFh + ret +DrawGoldenBall ENDP + +InitSkullsGame PROC + mov skulls3d_state, 0 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + cmp skulls3d_bet, 10 + jge @F + mov skulls3d_bet, 50 +@@: + ret +InitSkullsGame ENDP + +FinalizeSkullsGuess PROC + mov skulls3d_state, 4 + mov eax, skulls3d_choice + cmp eax, skulls3d_ballPos + jne skulls_guess_lost + + mov eax, skulls3d_bet + imul eax, 3 + mov skulls3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundJackpot, 0, 1 + ret + +skulls_guess_lost: + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + ret +FinalizeSkullsGuess ENDP + +HandleSkullsInput PROC + cmp skulls3d_state, 1 + je skulls_input_done + cmp skulls3d_state, 2 + je skulls_input_done + + cmp skulls3d_state, 0 + jne check_skulls_in_phase3 + + ; Phase 0: Idle / betting + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_skulls_bet_adjust + + mov eax, bankroll + cmp eax, skulls3d_bet + jl skulls_no_cash + sub eax, skulls3d_bet + mov bankroll, eax + + invoke RandomRange3D, 3 + mov skulls3d_ballPos, eax + mov skulls3d_state, 1 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp skulls_input_done + +skulls_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp skulls_input_done + +check_skulls_in_phase3: + cmp skulls3d_state, 3 + jne check_skulls_in_phase4 + + ; Phase 3: Pick cup + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov skulls3d_choice, 0 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz @F + mov skulls3d_choice, 1 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 33h ; '3' + test eax, eax + jz skulls_input_done + mov skulls3d_choice, 2 + call FinalizeSkullsGuess + jmp skulls_input_done + +check_skulls_in_phase4: + ; Phase 4: Play again or adjust bet + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_skulls_bet_adjust + mov skulls3d_state, 0 + jmp skulls_input_done + +check_skulls_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz skulls_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_skulls_bet_down +skulls_inc_bet: + cmp skulls3d_bet, 500 + jge skulls_input_done + cmp skulls3d_bet, 250 + jge skulls_set_500 + cmp skulls3d_bet, 100 + jge skulls_set_250 + cmp skulls3d_bet, 50 + jge skulls_set_100 + cmp skulls3d_bet, 25 + jge skulls_set_50 + jmp skulls_set_25 + +check_skulls_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz skulls_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz skulls_input_done +skulls_dec_bet: + cmp skulls3d_bet, 25 + jle skulls_set_10 + cmp skulls3d_bet, 50 + jle skulls_set_25 + cmp skulls3d_bet, 100 + jle skulls_set_50 + cmp skulls3d_bet, 250 + jle skulls_set_100 + jmp skulls_set_250 + +skulls_set_500: + mov skulls3d_bet, 500 + jmp skulls_input_done +skulls_set_250: + mov skulls3d_bet, 250 + jmp skulls_input_done +skulls_set_100: + mov skulls3d_bet, 100 + jmp skulls_input_done +skulls_set_50: + mov skulls3d_bet, 50 + jmp skulls_input_done +skulls_set_25: + mov skulls3d_bet, 25 + jmp skulls_input_done +skulls_set_10: + mov skulls3d_bet, 10 + jmp skulls_input_done + +skulls_input_done: + ret +HandleSkullsInput ENDP + +RenderSkullsGame PROC uses ebx esi edi + local passTick:DWORD, curPair:DWORD, swapSlotA:DWORD, swapSlotB:DWORD + local xA:DWORD, xB:DWORD, curXA:DWORD, curXB:DWORD, curYA:DWORD, curYB:DWORD + local distX:DWORD, dxVal:DWORD, archY:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00100E18h + invoke DrawBoxBorder, 10, 10, 300, 220, 001A1828h, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000C0A14h, 0000FFFFh, 2 + invoke DrawString8x8, 56, 27, OFFSET textSkullsTitle, 0000D7FFh + + ; Dispatch based on phase + cmp skulls3d_state, 1 + je skulls_render_phase1 + cmp skulls3d_state, 2 + je skulls_render_phase2 + cmp skulls3d_state, 3 + je skulls_render_phase3 + cmp skulls3d_state, 4 + je skulls_render_phase4 + + ; Phase 0: Idle / Betting + invoke DrawCup, 50, 105, '1' + invoke DrawCup, 138, 105, '2' + invoke DrawCup, 226, 105, '3' + invoke DrawString8x8, 24, 48, OFFSET textSkullsPhase0, 0000D7FFh + jmp skulls_draw_controls + +skulls_render_phase1: + inc skulls3d_timer + + ; Draw golden ball under starting cup + mov eax, skulls3d_ballPos + cmp eax, 0 + je p1_ball_0 + cmp eax, 1 + je p1_ball_1 + invoke DrawGoldenBall, 248, 120 + jmp p1_draw_cups +p1_ball_0: + invoke DrawGoldenBall, 72, 120 + jmp p1_draw_cups +p1_ball_1: + invoke DrawGoldenBall, 160, 120 + +p1_draw_cups: + mov edx, 105 + cmp skulls3d_ballPos, 0 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 50, edx, '1' + + mov edx, 105 + cmp skulls3d_ballPos, 1 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 138, edx, '2' + + mov edx, 105 + cmp skulls3d_ballPos, 2 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 226, edx, '3' + + invoke DrawString8x8, 76, 48, OFFSET textSkullsPhase1, 0000FFFFh + + cmp skulls3d_timer, 40 + jl skulls_draw_controls + + ; Start Phase 2 (Shuffle) + mov skulls3d_state, 2 + mov skulls3d_timer, 0 + invoke RandomRange3D, 3 + mov skulls3d_swapPair0, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair1, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair2, eax + jmp skulls_draw_controls + +skulls_render_phase2: + inc skulls3d_timer + + mov eax, skulls3d_timer + cmp eax, 20 + jbe pass_0 + cmp eax, 40 + jbe pass_1 + sub eax, 41 + mov passTick, eax + mov eax, skulls3d_swapPair2 + mov curPair, eax + jmp setup_pass_pair + +pass_0: + dec eax + mov passTick, eax + mov eax, skulls3d_swapPair0 + mov curPair, eax + jmp setup_pass_pair + +pass_1: + sub eax, 21 + mov passTick, eax + mov eax, skulls3d_swapPair1 + mov curPair, eax + +setup_pass_pair: + cmp curPair, 1 + je pair_1 + cmp curPair, 2 + je pair_2 + mov swapSlotA, 0 + mov swapSlotB, 1 + mov xA, 50 + mov xB, 138 + jmp calc_swap_coords +pair_1: + mov swapSlotA, 1 + mov swapSlotB, 2 + mov xA, 138 + mov xB, 226 + jmp calc_swap_coords +pair_2: + mov swapSlotA, 0 + mov swapSlotB, 2 + mov xA, 50 + mov xB, 226 + +calc_swap_coords: + mov eax, xB + sub eax, xA + mov distX, eax + + mov eax, distX + imul eax, passTick + xor edx, edx + mov ecx, 20 + div ecx + mov dxVal, eax + + mov eax, xA + add eax, dxVal + mov curXA, eax + + mov eax, xB + sub eax, dxVal + mov curXB, eax + + mov eax, passTick + mov ecx, 20 + sub ecx, eax + imul eax, ecx + xor edx, edx + mov ecx, 25 + div ecx + mov archY, eax + + mov eax, 105 + sub eax, archY + mov curYA, eax + + mov eax, 105 + add eax, archY + mov curYB, eax + + cmp passTick, 19 + jne @F + mov eax, skulls3d_ballPos + cmp eax, swapSlotA + jne check_ball_b + mov eax, swapSlotB + mov skulls3d_ballPos, eax + jmp ball_swap_done +check_ball_b: + cmp eax, swapSlotB + jne ball_swap_done + mov eax, swapSlotA + mov skulls3d_ballPos, eax +ball_swap_done: + invoke PlaySoundA, OFFSET soundClick, 0, 1 +@@: + cmp curPair, 1 + je draw_stat_0 + cmp curPair, 2 + je draw_stat_1 + invoke DrawCup, 226, 105, '3' + jmp draw_moving_cups +draw_stat_0: + invoke DrawCup, 50, 105, '1' + jmp draw_moving_cups +draw_stat_1: + invoke DrawCup, 138, 105, '2' + +draw_moving_cups: + mov edx, '1' + add edx, swapSlotA + invoke DrawCup, curXA, curYA, edx + + mov edx, '1' + add edx, swapSlotB + invoke DrawCup, curXB, curYB, edx + + invoke DrawString8x8, 40, 48, OFFSET textSkullsPhase2, 0000FFFFh + + cmp skulls3d_timer, 60 + jl skulls_draw_controls + mov skulls3d_state, 3 + mov skulls3d_timer, 0 + jmp skulls_draw_controls + +skulls_render_phase3: + invoke DrawCup, 50, 105, '1' + invoke DrawCup, 138, 105, '2' + invoke DrawCup, 226, 105, '3' + invoke DrawString8x8, 16, 48, OFFSET textSkullsPhase3, 0000FFFFh + jmp skulls_draw_controls + +skulls_render_phase4: + mov eax, skulls3d_ballPos + cmp eax, 0 + je p4_ball_0 + cmp eax, 1 + je p4_ball_1 + invoke DrawGoldenBall, 248, 120 + jmp p4_draw_cups +p4_ball_0: + invoke DrawGoldenBall, 72, 120 + jmp p4_draw_cups +p4_ball_1: + invoke DrawGoldenBall, 160, 120 + +p4_draw_cups: + mov edx, 105 + cmp skulls3d_choice, 0 + je @F + cmp skulls3d_ballPos, 0 + jne draw_cup0 +@@: + mov edx, 70 +draw_cup0: + invoke DrawCup, 50, edx, '1' + + mov edx, 105 + cmp skulls3d_choice, 1 + je @F + cmp skulls3d_ballPos, 1 + jne draw_cup1 +@@: + mov edx, 70 +draw_cup1: + invoke DrawCup, 138, edx, '2' + + mov edx, 105 + cmp skulls3d_choice, 2 + je @F + cmp skulls3d_ballPos, 2 + jne draw_cup2 +@@: + mov edx, 70 +draw_cup2: + invoke DrawCup, 226, edx, '3' + + cmp skulls3d_win, 0 + je p4_splash_lose + invoke DrawString8x8, 24, 48, OFFSET textSkullsWin, 0000FFFFh + invoke FormatNumber, skulls3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 48, OFFSET hudNumBuffer, 0000FFFFh + jmp p4_again_hint +p4_splash_lose: + invoke DrawString8x8, 36, 48, OFFSET textSkullsLose, 000000FFh +p4_again_hint: + invoke DrawString8x8, 56, 138, OFFSET textSkullsAgain, 0000D7FFh + +skulls_draw_controls: + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, skulls3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 24, 186, OFFSET textSkullsControls1, 00FFFFFFh + invoke DrawString8x8, 24, 202, OFFSET textSkullsControls2, 00A0A0A0h + ret +RenderSkullsGame ENDP + ; --- Player Input & Movement Physics --- HandlePlayerInput PROC uses ebx esi edi local speed:DWORD @@ -2974,19 +4228,22 @@ check_target_roulette: check_target_dice: cmp eax, INTERACT_DICE jne check_target_skulls - invoke LaunchClassicGame, OFFSET GameDice, 7, OFFSET szTitleDice + call InitDiceGame + mov engineMode, MODE_DICE ret check_target_skulls: cmp eax, INTERACT_SKULLS jne check_target_coin - invoke LaunchClassicGame, OFFSET GameSkulls, 5, OFFSET szTitleSkulls + call InitSkullsGame + mov engineMode, MODE_SKULLS ret check_target_coin: cmp eax, INTERACT_COIN jne check_target_skill - invoke LaunchClassicGame, OFFSET GameCoin, 6, OFFSET szTitleCoin + call InitCoinGame + mov engineMode, MODE_COIN ret check_target_skill: @@ -3382,6 +4639,14 @@ leave_table: je engine_tick cmp roulState, 1 je engine_tick + cmp coin3d_state, 1 + je engine_tick + cmp dice3d_state, 1 + je engine_tick + cmp skulls3d_state, 1 + je engine_tick + cmp skulls3d_state, 2 + je engine_tick mov engineMode, MODE_WALK engine_tick: cmp paused3D, 0 @@ -3425,9 +4690,29 @@ check_shop_mode: call RenderShopGame jmp present_frame check_atm_mode: + cmp engineMode, MODE_ATM + jne check_coin_mode call HandleATMInput call RenderATMGame jmp present_frame +check_coin_mode: + cmp engineMode, MODE_COIN + jne check_dice_mode + call HandleCoinInput + call RenderCoinGame + jmp present_frame +check_dice_mode: + cmp engineMode, MODE_DICE + jne check_skulls_mode + call HandleDiceInput + call RenderDiceGame + jmp present_frame +check_skulls_mode: + cmp engineMode, MODE_SKULLS + jne present_frame + call HandleSkullsInput + call RenderSkullsGame + jmp present_frame draw_pause: invoke DrawBoxBorder, 65, 75, 190, 85, 00151C21h, 00D8BC6Ah, 2 invoke DrawString8x8, 86, 88, OFFSET textPause3D, 00FFFFFFh diff --git a/build/graphics/poker.exe b/build/graphics/poker.exe index b874ad9..dbed6aa 100644 Binary files a/build/graphics/poker.exe and b/build/graphics/poker.exe differ diff --git a/casino3d.inc b/casino3d.inc index e3d7728..96f7064 100644 --- a/casino3d.inc +++ b/casino3d.inc @@ -112,6 +112,9 @@ MODE_BLACKJACK equ 2 MODE_ROULETTE equ 3 MODE_SHOP equ 4 MODE_ATM equ 5 +MODE_COIN equ 6 +MODE_DICE equ 7 +MODE_SKULLS equ 8 WS_OVERLAPPEDWINDOW equ 00CF0000h SW_SHOW equ 5 @@ -276,6 +279,75 @@ roulWinningNum dd 0 roulPayout dd 0 roulOutcomeMsg db 64 dup(0) +; --- Native 2.5D Coin Flip Game --- +coin3d_bet dd 50 +coin3d_side dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà +coin3d_state dd 0 ; 0 = Idle, 1 = Flipping, 2 = Result +coin3d_timer dd 0 +coin3d_result dd 1 ; 1 = Îð¸ë, 2 = Ðåøêà +coin3d_streak dd 0 +coin3d_win dd 0 + +coinRxAnimTable db 22, 18, 12, 4, 12, 18, 22, 18, 12, 4 + +textCoinTitle db "ÌÎÍÅÒÊÀ (ÎÐ¨Ë / ÐÅØÊÀ)",0 +textCoinHeads db "ÎШË",0 +textCoinTails db "ÐÅØÊÀ",0 +textCoinStreak db "ÑÅÐÈß: ",0 +textCoinSide1 db "[1] ÎШË",0 +textCoinSide2 db "[2] ÐÅØÊÀ",0 +textCoinFlipping db "ÌÎÍÅÒÀ  ÂÎÇÄÓÕÅ...",0 +textCoinWin db "ÂÛÈÃÐÛØ! +$",0 +textCoinLose db "ÏÐÎÈÃÐÛØ!",0 +textCoinControls1 db "[1/2] ÑÒÎÐÎÍÀ [ÏÐÎÁÅË] ÁÐÎÑÎÊ",0 +textCoinControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",0 + +; --- Native 2.5D Dice Game --- +dice3d_bet dd 50 +dice3d_choice dd 1 ; 1 = ׸ò, 2 = Íå÷åò +dice3d_state dd 0 ; 0 = Idle, 1 = Rolling, 2 = Result +dice3d_timer dd 0 +dice3d_val1 dd 3 +dice3d_val2 dd 4 +dice3d_sum dd 7 +dice3d_win dd 0 + +textDiceTitle db "ÊÎÑÒÈ (CRAPS) - ×¨Ò / ÍÅ×ÅÒ",0 +textDiceEven db "[1] רÒ",0 +textDiceOdd db "[2] ÍÅ×ÅÒ",0 +textDiceTally db "ÊÎÑÒÈ: ",0 +textDicePlus db " + ",0 +textDiceEqual db " = ",0 +textDiceEvenResult db " (רÒ)",0 +textDiceOddResult db " (ÍÅ×ÅÒ)",0 +textDiceRolling db "ÁÐÎÑÎÊ ÊÎÑÒÅÉ...",0 +textDiceWin db "ÂÛÈÃÐÛØ! +$",0 +textDiceLose db "ÏÐÎÈÃÐÛØ!",0 +textDiceControls1 db "[1] ×¨Ò [2] ÍÅ×ÅÒ [ÏÐÎÁÅË] ÁÐÎÑÎÊ",0 +textDiceControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",0 + +; --- Native 2.5D Skulls Game --- +skulls3d_bet dd 50 +skulls3d_state dd 0 ; 0 = Idle, 1 = Show ball, 2 = Shuffle, 3 = Pick, 4 = Reveal +skulls3d_timer dd 0 +skulls3d_ballPos dd 0 ; 0, 1, 2 +skulls3d_choice dd 0 ; 0, 1, 2 +skulls3d_win dd 0 +skulls3d_swapPair0 dd 0 +skulls3d_swapPair1 dd 1 +skulls3d_swapPair2 dd 2 + +textSkullsTitle db "ÍÀϨÐÑÒÊÈ (×ÅÐÅÏÀ È ÊÓÁÊÈ)",0 +textSkullsPhase0 db "ÂÛÁÅÐÈÒÅ ÑÒÀÂÊÓ È ÍÀÆÌÈÒÅ [ÏÐÎÁÅË]",0 +textSkullsPhase1 db "ÇÀÏÎÌÍÈÒÅ, ÃÄÅ ØÀÐÈÊ!",0 +textSkullsPhase2 db "ÊÐÓ×Ó, ÂÅÐ×Ó, ÇÀÏÓÒÀÒÜ ÕÎ×Ó...",0 +textSkullsPhase3 db "ÃÄÅ ØÀÐÈÊ? ÍÀÆÌÈÒÅ [1], [2] ÈËÈ [3]!",0 +textSkullsWin db "ÂÛ ÓÃÀÄÀËÈ! ÄÆÅÊÏÎÒ x3! +$",0 +textSkullsLose db "ÍÅ ÓÃÀÄÀËÈ! ØÀÐÈÊ ÁÛË ÍÅ ÇÄÅÑÜ!",0 +textSkullsAgain db "[ÏÐÎÁÅË] - ÑÛÃÐÀÒÜ ÅÙ¨ ÐÀÇ",0 +textSkullsControls1 db "[1/2/3] ÂÛÁÎÐ ÊÓÁÊÀ [ÏÐÎÁÅË] ÑÒÀÐÒ",0 +textSkullsControls2 db "[ÂÂÅÐÕ/ÂÍÈÇ] ÑÒÀÂÊÀ [ESC] ÂÛÕÎÄ",0 + shopMsg db 128 dup(0) atmMsg db 128 dup(0) @@ -2558,6 +2630,1188 @@ RenderATMGame PROC ret RenderATMGame ENDP +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: COIN FLIP (ÌÎÍÅÒÊÀ) +; ============================================================================== +DrawCoinEllipse PROC uses ebx esi edi cxVal:DWORD, cyVal:DWORD, rxVal:DWORD, ryVal:DWORD, outerColor:DWORD, innerColor:DWORD + local curDY:DWORD, curDX:DWORD, rxSq:DWORD, rySq:DWORD, rxRySq:DWORD, threshSq:DWORD + cmp rxVal, 0 + jle ellipse_done + cmp ryVal, 0 + jle ellipse_done + + mov eax, rxVal + imul eax, eax + mov rxSq, eax + + mov eax, ryVal + imul eax, eax + mov rySq, eax + + mov eax, rxSq + imul eax, rySq + mov rxRySq, eax + + mov eax, rxRySq + shr eax, 2 + imul eax, 3 + mov threshSq, eax + + mov eax, ryVal + neg eax + mov curDY, eax + +ellipse_y_loop: + mov eax, curDY + cmp eax, ryVal + jg ellipse_done + + mov eax, rxVal + neg eax + mov curDX, eax + +ellipse_x_loop: + mov eax, curDX + cmp eax, rxVal + jg next_ellipse_y + + mov eax, curDX + imul eax, eax + imul eax, rySq + mov ebx, curDY + imul ebx, ebx + imul ebx, rxSq + add eax, ebx + cmp eax, rxRySq + jg next_ellipse_x + + mov ecx, innerColor + cmp eax, threshSq + jb @F + mov ecx, outerColor +@@: + mov eax, cxVal + add eax, curDX + mov edx, cyVal + add edx, curDY + invoke DrawPixel, eax, edx, ecx + +next_ellipse_x: + inc curDX + jmp ellipse_x_loop + +next_ellipse_y: + inc curDY + jmp ellipse_y_loop + +ellipse_done: + ret +DrawCoinEllipse ENDP + +InitCoinGame PROC + mov coin3d_state, 0 + mov coin3d_timer, 0 + mov coin3d_win, 0 + cmp coin3d_bet, 10 + jge @F + mov coin3d_bet, 50 +@@: + ret +InitCoinGame ENDP + +HandleCoinInput PROC + cmp coin3d_state, 1 + je coin_input_done + + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_coin_side + mov eax, bankroll + cmp eax, coin3d_bet + jl coin_no_cash + sub eax, coin3d_bet + mov bankroll, eax + mov coin3d_state, 1 + mov coin3d_timer, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp coin_input_done +coin_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp coin_input_done + +check_coin_side: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov coin3d_side, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_coin_bet_adjust + mov coin3d_side, 2 + +check_coin_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz coin_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_coin_bet_down +coin_inc_bet: + cmp coin3d_bet, 500 + jge coin_input_done + cmp coin3d_bet, 250 + jge coin_set_500 + cmp coin3d_bet, 100 + jge coin_set_250 + cmp coin3d_bet, 50 + jge coin_set_100 + cmp coin3d_bet, 25 + jge coin_set_50 + jmp coin_set_25 + +check_coin_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz coin_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz coin_input_done +coin_dec_bet: + cmp coin3d_bet, 25 + jle coin_set_10 + cmp coin3d_bet, 50 + jle coin_set_25 + cmp coin3d_bet, 100 + jle coin_set_50 + cmp coin3d_bet, 250 + jle coin_set_100 + jmp coin_set_250 + +coin_set_500: + mov coin3d_bet, 500 + jmp coin_input_done +coin_set_250: + mov coin3d_bet, 250 + jmp coin_input_done +coin_set_100: + mov coin3d_bet, 100 + jmp coin_input_done +coin_set_50: + mov coin3d_bet, 50 + jmp coin_input_done +coin_set_25: + mov coin3d_bet, 25 + jmp coin_input_done +coin_set_10: + mov coin3d_bet, 10 + jmp coin_input_done + +coin_input_done: + ret +HandleCoinInput ENDP + +RenderCoinGame PROC uses ebx esi edi + local cyVal:DWORD, rxVal:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00140D18h + invoke DrawBoxBorder, 10, 10, 300, 220, 0022142Ah, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000D0812h, 0000FFFFh, 2 + invoke DrawString8x8, 72, 27, OFFSET textCoinTitle, 0000D7FFh + + ; Streak Display + invoke DrawString8x8, 28, 50, OFFSET textCoinStreak, 0000D7FFh + invoke FormatNumber, coin3d_streak, OFFSET hudNumBuffer + invoke DrawString8x8, 84, 50, OFFSET hudNumBuffer, 0050FF50h + + ; Side Panel: [1] ÎÐ¨Ë + mov eax, 00120D16h + mov edx, 00505050h + mov ecx, 00808080h + cmp coin3d_side, 1 + jne @F + mov eax, 001E3520h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 24, 70, 68, 38, eax, edx, 2 + pop ecx + invoke DrawString8x8, 28, 85, OFFSET textCoinSide1, ecx + + ; Side Panel: [2] ÐÅØÊÀ + mov eax, 00120D16h + mov edx, 00505050h + mov ecx, 00808080h + cmp coin3d_side, 2 + jne @F + mov eax, 001E3520h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 228, 70, 68, 38, eax, edx, 2 + pop ecx + invoke DrawString8x8, 232, 85, OFFSET textCoinSide2, ecx + + ; Center coin pedestal arena + invoke DrawBoxBorder, 102, 54, 116, 84, 000F0A12h, 00504030h, 1 + + ; Flipping animation logic + cmp coin3d_state, 1 + jne coin_at_rest + + inc coin3d_timer + + ; Parabolic toss: cy = 96 - (t * (40 - t)) / 16 + mov eax, coin3d_timer + mov ecx, 40 + sub ecx, eax + imul eax, ecx + shr eax, 4 + mov edx, 96 + sub edx, eax + mov cyVal, edx + + ; Width rx from lookup table: (t % 10) + mov eax, coin3d_timer + xor edx, edx + mov ecx, 10 + div ecx + movzx eax, BYTE PTR [coinRxAnimTable + edx] + mov rxVal, eax + + invoke DrawCoinEllipse, 160, cyVal, rxVal, 22, 0000D7FFh, 0000B0E0h + invoke DrawString8x8, 84, 142, OFFSET textCoinFlipping, 0000FFFFh + + cmp coin3d_timer, 40 + jl coin_draw_controls + + ; Flip complete! + mov coin3d_state, 2 + invoke RandomRange3D, 2 + inc eax + mov coin3d_result, eax + + mov eax, coin3d_result + cmp eax, coin3d_side + jne coin_flip_lost + + ; Won! + mov eax, coin3d_bet + shl eax, 1 + mov coin3d_win, eax + add bankroll, eax + inc coin3d_streak + cmp coin3d_streak, 3 + jl @F + invoke PlaySoundA, OFFSET soundJackpot, 0, 1 + jmp coin_draw_controls +@@: + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp coin_draw_controls + +coin_flip_lost: + mov coin3d_streak, 0 + mov coin3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp coin_draw_controls + +coin_at_rest: + ; Draw coin resting at (160, 96) + invoke DrawCoinEllipse, 160, 96, 24, 24, 0000D7FFh, 0000B0E0h + invoke DrawCoinEllipse, 160, 96, 20, 20, 0000FFFFh, 000090D0h + + ; Draw side text inside coin + cmp coin3d_state, 2 + jne coin_show_picked_side + cmp coin3d_result, 1 + jne @F + invoke DrawString8x8, 144, 92, OFFSET textCoinHeads, 00000030h + jmp coin_show_splash +@@: + invoke DrawString8x8, 140, 92, OFFSET textCoinTails, 00000030h + jmp coin_show_splash + +coin_show_picked_side: + cmp coin3d_side, 1 + jne @F + invoke DrawString8x8, 144, 92, OFFSET textCoinHeads, 00000030h + jmp coin_draw_controls +@@: + invoke DrawString8x8, 140, 92, OFFSET textCoinTails, 00000030h + jmp coin_draw_controls + +coin_show_splash: + cmp coin3d_win, 0 + je coin_show_loss + invoke DrawString8x8, 90, 142, OFFSET textCoinWin, 0000FFFFh + invoke FormatNumber, coin3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 178, 142, OFFSET hudNumBuffer, 0000FFFFh + jmp coin_draw_controls + +coin_show_loss: + invoke DrawString8x8, 126, 142, OFFSET textCoinLose, 000000FFh + +coin_draw_controls: + ; Bottom Control Panel + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, coin3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 28, 186, OFFSET textCoinControls1, 00FFFFFFh + invoke DrawString8x8, 28, 202, OFFSET textCoinControls2, 00A0A0A0h + ret +RenderCoinGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: DICE / CRAPS (ÊÎÑÒÈ) +; ============================================================================== +DrawDieCube PROC uses ebx esi edi x:DWORD, y:DWORD, cubeSize:DWORD, valNum:DWORD + local pipColor:DWORD + mov pipColor, 001515C0h + + invoke DrawBoxBorder, x, y, cubeSize, cubeSize, 00F4F6F8h, 00303038h, 2 + + mov eax, x + add eax, cubeSize + mov edx, y + add edx, 2 + invoke DrawBox, eax, edx, 2, cubeSize, 0008140Ah + mov eax, x + add eax, 2 + mov edx, y + add edx, cubeSize + invoke DrawBox, eax, edx, cubeSize, 2, 0008140Ah + + cmp valNum, 1 + je draw_die_center + cmp valNum, 3 + je draw_die_center + cmp valNum, 5 + je draw_die_center + jmp check_die_corners +draw_die_center: + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + +check_die_corners: + cmp valNum, 2 + jl die_render_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 27 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 2, pipColor + + cmp valNum, 4 + jl die_render_done + mov eax, x + add eax, 27 + mov edx, y + add edx, 9 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 9 + mov edx, y + add edx, 27 + invoke DrawCircle, eax, edx, 2, pipColor + + cmp valNum, 6 + jl die_render_done + mov eax, x + add eax, 9 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + mov eax, x + add eax, 27 + mov edx, y + add edx, 18 + invoke DrawCircle, eax, edx, 2, pipColor + +die_render_done: + ret +DrawDieCube ENDP + +InitDiceGame PROC + mov dice3d_state, 0 + mov dice3d_timer, 0 + mov dice3d_win, 0 + cmp dice3d_bet, 10 + jge @F + mov dice3d_bet, 50 +@@: + ret +InitDiceGame ENDP + +HandleDiceInput PROC + cmp dice3d_state, 1 + je dice_input_done + + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_dice_choice + mov eax, bankroll + cmp eax, dice3d_bet + jl dice_no_cash + sub eax, dice3d_bet + mov bankroll, eax + mov dice3d_state, 1 + mov dice3d_timer, 0 + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp dice_input_done +dice_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp dice_input_done + +check_dice_choice: + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov dice3d_choice, 1 +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz check_dice_bet_adjust + mov dice3d_choice, 2 + +check_dice_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz dice_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_dice_bet_down +dice_inc_bet: + cmp dice3d_bet, 500 + jge dice_input_done + cmp dice3d_bet, 250 + jge dice_set_500 + cmp dice3d_bet, 100 + jge dice_set_250 + cmp dice3d_bet, 50 + jge dice_set_100 + cmp dice3d_bet, 25 + jge dice_set_50 + jmp dice_set_25 + +check_dice_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz dice_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz dice_input_done +dice_dec_bet: + cmp dice3d_bet, 25 + jle dice_set_10 + cmp dice3d_bet, 50 + jle dice_set_25 + cmp dice3d_bet, 100 + jle dice_set_50 + cmp dice3d_bet, 250 + jle dice_set_100 + jmp dice_set_250 + +dice_set_500: + mov dice3d_bet, 500 + jmp dice_input_done +dice_set_250: + mov dice3d_bet, 250 + jmp dice_input_done +dice_set_100: + mov dice3d_bet, 100 + jmp dice_input_done +dice_set_50: + mov dice3d_bet, 50 + jmp dice_input_done +dice_set_25: + mov dice3d_bet, 25 + jmp dice_input_done +dice_set_10: + mov dice3d_bet, 10 + jmp dice_input_done + +dice_input_done: + ret +HandleDiceInput ENDP + +RenderDiceGame PROC uses ebx esi edi + local d1X:DWORD, d1Y:DWORD, d2X:DWORD, d2Y:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 000C2612h + invoke DrawBoxBorder, 10, 10, 300, 220, 0014381Ah, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000A1F0Eh, 0000FFFFh, 2 + invoke DrawString8x8, 52, 27, OFFSET textDiceTitle, 0000D7FFh + + ; Choice Panels + mov eax, 000E2614h + mov edx, 00505050h + mov ecx, 00808080h + cmp dice3d_choice, 1 + jne @F + mov eax, 001C4824h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 24, 55, 76, 36, eax, edx, 2 + pop ecx + invoke DrawString8x8, 34, 68, OFFSET textDiceEven, ecx + + mov eax, 000E2614h + mov edx, 00505050h + mov ecx, 00808080h + cmp dice3d_choice, 2 + jne @F + mov eax, 001C4824h + mov edx, 0000FFFFh + mov ecx, 0000FFFFh +@@: + push ecx + invoke DrawBoxBorder, 220, 55, 76, 36, eax, edx, 2 + pop ecx + invoke DrawString8x8, 226, 68, OFFSET textDiceOdd, ecx + + ; Dice Table Box + invoke DrawBoxBorder, 104, 52, 112, 54, 0009200Dh, 00305030h, 1 + + ; Rolling animation logic + cmp dice3d_state, 1 + jne dice_at_rest + + inc dice3d_timer + + ; Tumbling jitter offsets + mov eax, dice3d_timer + and eax, 3 + sub eax, 1 + + mov edx, 112 + add edx, eax + mov d1X, edx + + mov edx, 60 + sub edx, eax + mov d1Y, edx + + mov edx, 172 + sub edx, eax + mov d2X, edx + + mov edx, 62 + add edx, eax + mov d2Y, edx + + test dice3d_timer, 1 + jz @F + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax +@@: + invoke DrawDieCube, d1X, d1Y, 36, dice3d_val1 + invoke DrawDieCube, d2X, d2Y, 36, dice3d_val2 + + invoke DrawString8x8, 96, 132, OFFSET textDiceRolling, 0000FFFFh + + cmp dice3d_timer, 36 + jl dice_draw_controls + + ; Roll completed! + mov dice3d_state, 2 + invoke RandomRange3D, 6 + inc eax + mov dice3d_val1, eax + invoke RandomRange3D, 6 + inc eax + mov dice3d_val2, eax + + mov eax, dice3d_val1 + add eax, dice3d_val2 + mov dice3d_sum, eax + + test eax, 1 + jz dice_sum_is_even + mov ecx, 2 ; Odd + jmp check_dice_win +dice_sum_is_even: + mov ecx, 1 ; Even + +check_dice_win: + cmp ecx, dice3d_choice + jne dice_roll_lost + + mov eax, dice3d_bet + shl eax, 1 + mov dice3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp dice_draw_controls + +dice_roll_lost: + mov dice3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + jmp dice_draw_controls + +dice_at_rest: + invoke DrawDieCube, 112, 60, 36, dice3d_val1 + invoke DrawDieCube, 172, 60, 36, dice3d_val2 + + cmp dice3d_state, 2 + jne dice_draw_controls + + ; Score Tally + invoke DrawString8x8, 80, 112, OFFSET textDiceTally, 0000D7FFh + invoke FormatNumber, dice3d_val1, OFFSET hudNumBuffer + invoke DrawString8x8, 136, 112, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 146, 112, OFFSET textDicePlus, 0000D7FFh + invoke FormatNumber, dice3d_val2, OFFSET hudNumBuffer + invoke DrawString8x8, 170, 112, OFFSET hudNumBuffer, 00FFFFFFh + invoke DrawString8x8, 180, 112, OFFSET textDiceEqual, 0000D7FFh + invoke FormatNumber, dice3d_sum, OFFSET hudNumBuffer + invoke DrawString8x8, 204, 112, OFFSET hudNumBuffer, 0000FFFFh + + mov eax, dice3d_sum + test eax, 1 + jz @F + invoke DrawString8x8, 222, 112, OFFSET textDiceOddResult, 00FF8080h + jmp dice_show_outcome +@@: + invoke DrawString8x8, 222, 112, OFFSET textDiceEvenResult, 0080FF80h + +dice_show_outcome: + cmp dice3d_win, 0 + je dice_show_loss + invoke DrawString8x8, 90, 132, OFFSET textDiceWin, 0000FFFFh + invoke FormatNumber, dice3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 178, 132, OFFSET hudNumBuffer, 0000FFFFh + jmp dice_draw_controls +dice_show_loss: + invoke DrawString8x8, 126, 132, OFFSET textDiceLose, 000000FFh + +dice_draw_controls: + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, dice3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 28, 186, OFFSET textDiceControls1, 00FFFFFFh + invoke DrawString8x8, 28, 202, OFFSET textDiceControls2, 00A0A0A0h + ret +RenderDiceGame ENDP + +; ============================================================================== +; IN-ENGINE 2.5D MINI-GAME: SKULLS & CUPS (ÍÀϨÐÑÒÊÈ) +; ============================================================================== +DrawCup PROC uses ebx esi edi x:DWORD, y:DWORD, cupNumChar:DWORD + invoke DrawBox, x + 14, y, 16, 4, 0000C8E8h + invoke DrawBoxBorder, x + 8, y + 4, 28, 12, 00221A30h, 0000D7FFh, 2 + invoke DrawBoxBorder, x + 4, y + 16, 36, 16, 00221A30h, 0000D7FFh, 2 + invoke DrawBoxBorder, x + 2, y + 32, 40, 8, 002A2038h, 0000FFFFh, 2 + + mov eax, x + add eax, 18 + mov edx, y + add edx, 18 + invoke DrawChar8x8, eax, edx, cupNumChar, 0000FFFFh + ret +DrawCup ENDP + +DrawGoldenBall PROC uses ebx esi edi x:DWORD, y:DWORD + invoke DrawCircle, x, y, 7, 0000A5D8h + invoke DrawCircle, x, y, 6, 0000D7FFh + invoke DrawCircle, x, y, 4, 0000FFFFh + mov eax, x + sub eax, 2 + mov edx, y + sub edx, 2 + invoke DrawCircle, eax, edx, 1, 00FFFFFFh + ret +DrawGoldenBall ENDP + +InitSkullsGame PROC + mov skulls3d_state, 0 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + cmp skulls3d_bet, 10 + jge @F + mov skulls3d_bet, 50 +@@: + ret +InitSkullsGame ENDP + +FinalizeSkullsGuess PROC + mov skulls3d_state, 4 + mov eax, skulls3d_choice + cmp eax, skulls3d_ballPos + jne skulls_guess_lost + + mov eax, skulls3d_bet + imul eax, 3 + mov skulls3d_win, eax + add bankroll, eax + invoke PlaySoundA, OFFSET soundJackpot, 0, 1 + ret + +skulls_guess_lost: + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundClick, 0, 1 + ret +FinalizeSkullsGuess ENDP + +HandleSkullsInput PROC + cmp skulls3d_state, 1 + je skulls_input_done + cmp skulls3d_state, 2 + je skulls_input_done + + cmp skulls3d_state, 0 + jne check_skulls_in_phase3 + + ; Phase 0: Idle / betting + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_skulls_bet_adjust + + mov eax, bankroll + cmp eax, skulls3d_bet + jl skulls_no_cash + sub eax, skulls3d_bet + mov bankroll, eax + + invoke RandomRange3D, 3 + mov skulls3d_ballPos, eax + mov skulls3d_state, 1 + mov skulls3d_timer, 0 + mov skulls3d_win, 0 + invoke PlaySoundA, OFFSET soundCoin, 0, 1 + jmp skulls_input_done + +skulls_no_cash: + invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage + mov flashTimer, 60 + jmp skulls_input_done + +check_skulls_in_phase3: + cmp skulls3d_state, 3 + jne check_skulls_in_phase4 + + ; Phase 3: Pick cup + invoke Pressed3D, 31h ; '1' + test eax, eax + jz @F + mov skulls3d_choice, 0 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 32h ; '2' + test eax, eax + jz @F + mov skulls3d_choice, 1 + call FinalizeSkullsGuess + jmp skulls_input_done +@@: + invoke Pressed3D, 33h ; '3' + test eax, eax + jz skulls_input_done + mov skulls3d_choice, 2 + call FinalizeSkullsGuess + jmp skulls_input_done + +check_skulls_in_phase4: + ; Phase 4: Play again or adjust bet + invoke Pressed3D, 20h ; SPACE + test eax, eax + jz check_skulls_bet_adjust + mov skulls3d_state, 0 + jmp skulls_input_done + +check_skulls_bet_adjust: + invoke Pressed3D, 26h ; UP + test eax, eax + jnz skulls_inc_bet + invoke Pressed3D, 57h ; W + test eax, eax + jz check_skulls_bet_down +skulls_inc_bet: + cmp skulls3d_bet, 500 + jge skulls_input_done + cmp skulls3d_bet, 250 + jge skulls_set_500 + cmp skulls3d_bet, 100 + jge skulls_set_250 + cmp skulls3d_bet, 50 + jge skulls_set_100 + cmp skulls3d_bet, 25 + jge skulls_set_50 + jmp skulls_set_25 + +check_skulls_bet_down: + invoke Pressed3D, 28h ; DOWN + test eax, eax + jnz skulls_dec_bet + invoke Pressed3D, 53h ; S + test eax, eax + jz skulls_input_done +skulls_dec_bet: + cmp skulls3d_bet, 25 + jle skulls_set_10 + cmp skulls3d_bet, 50 + jle skulls_set_25 + cmp skulls3d_bet, 100 + jle skulls_set_50 + cmp skulls3d_bet, 250 + jle skulls_set_100 + jmp skulls_set_250 + +skulls_set_500: + mov skulls3d_bet, 500 + jmp skulls_input_done +skulls_set_250: + mov skulls3d_bet, 250 + jmp skulls_input_done +skulls_set_100: + mov skulls3d_bet, 100 + jmp skulls_input_done +skulls_set_50: + mov skulls3d_bet, 50 + jmp skulls_input_done +skulls_set_25: + mov skulls3d_bet, 25 + jmp skulls_input_done +skulls_set_10: + mov skulls3d_bet, 10 + jmp skulls_input_done + +skulls_input_done: + ret +HandleSkullsInput ENDP + +RenderSkullsGame PROC uses ebx esi edi + local passTick:DWORD, curPair:DWORD, swapSlotA:DWORD, swapSlotB:DWORD + local xA:DWORD, xB:DWORD, curXA:DWORD, curXB:DWORD, curYA:DWORD, curYB:DWORD + local distX:DWORD, dxVal:DWORD, archY:DWORD + + ; Background & Bezel + invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00100E18h + invoke DrawBoxBorder, 10, 10, 300, 220, 001A1828h, 0000D7FFh, 3 + + ; Illuminated Marquee Header + invoke DrawBoxBorder, 25, 18, 270, 26, 000C0A14h, 0000FFFFh, 2 + invoke DrawString8x8, 56, 27, OFFSET textSkullsTitle, 0000D7FFh + + ; Dispatch based on phase + cmp skulls3d_state, 1 + je skulls_render_phase1 + cmp skulls3d_state, 2 + je skulls_render_phase2 + cmp skulls3d_state, 3 + je skulls_render_phase3 + cmp skulls3d_state, 4 + je skulls_render_phase4 + + ; Phase 0: Idle / Betting + invoke DrawCup, 50, 105, '1' + invoke DrawCup, 138, 105, '2' + invoke DrawCup, 226, 105, '3' + invoke DrawString8x8, 24, 48, OFFSET textSkullsPhase0, 0000D7FFh + jmp skulls_draw_controls + +skulls_render_phase1: + inc skulls3d_timer + + ; Draw golden ball under starting cup + mov eax, skulls3d_ballPos + cmp eax, 0 + je p1_ball_0 + cmp eax, 1 + je p1_ball_1 + invoke DrawGoldenBall, 248, 120 + jmp p1_draw_cups +p1_ball_0: + invoke DrawGoldenBall, 72, 120 + jmp p1_draw_cups +p1_ball_1: + invoke DrawGoldenBall, 160, 120 + +p1_draw_cups: + mov edx, 105 + cmp skulls3d_ballPos, 0 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 50, edx, '1' + + mov edx, 105 + cmp skulls3d_ballPos, 1 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 138, edx, '2' + + mov edx, 105 + cmp skulls3d_ballPos, 2 + jne @F + mov edx, 70 +@@: + invoke DrawCup, 226, edx, '3' + + invoke DrawString8x8, 76, 48, OFFSET textSkullsPhase1, 0000FFFFh + + cmp skulls3d_timer, 40 + jl skulls_draw_controls + + ; Start Phase 2 (Shuffle) + mov skulls3d_state, 2 + mov skulls3d_timer, 0 + invoke RandomRange3D, 3 + mov skulls3d_swapPair0, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair1, eax + invoke RandomRange3D, 3 + mov skulls3d_swapPair2, eax + jmp skulls_draw_controls + +skulls_render_phase2: + inc skulls3d_timer + + mov eax, skulls3d_timer + cmp eax, 20 + jbe pass_0 + cmp eax, 40 + jbe pass_1 + sub eax, 41 + mov passTick, eax + mov eax, skulls3d_swapPair2 + mov curPair, eax + jmp setup_pass_pair + +pass_0: + dec eax + mov passTick, eax + mov eax, skulls3d_swapPair0 + mov curPair, eax + jmp setup_pass_pair + +pass_1: + sub eax, 21 + mov passTick, eax + mov eax, skulls3d_swapPair1 + mov curPair, eax + +setup_pass_pair: + cmp curPair, 1 + je pair_1 + cmp curPair, 2 + je pair_2 + mov swapSlotA, 0 + mov swapSlotB, 1 + mov xA, 50 + mov xB, 138 + jmp calc_swap_coords +pair_1: + mov swapSlotA, 1 + mov swapSlotB, 2 + mov xA, 138 + mov xB, 226 + jmp calc_swap_coords +pair_2: + mov swapSlotA, 0 + mov swapSlotB, 2 + mov xA, 50 + mov xB, 226 + +calc_swap_coords: + mov eax, xB + sub eax, xA + mov distX, eax + + mov eax, distX + imul eax, passTick + xor edx, edx + mov ecx, 20 + div ecx + mov dxVal, eax + + mov eax, xA + add eax, dxVal + mov curXA, eax + + mov eax, xB + sub eax, dxVal + mov curXB, eax + + mov eax, passTick + mov ecx, 20 + sub ecx, eax + imul eax, ecx + xor edx, edx + mov ecx, 25 + div ecx + mov archY, eax + + mov eax, 105 + sub eax, archY + mov curYA, eax + + mov eax, 105 + add eax, archY + mov curYB, eax + + cmp passTick, 19 + jne @F + mov eax, skulls3d_ballPos + cmp eax, swapSlotA + jne check_ball_b + mov eax, swapSlotB + mov skulls3d_ballPos, eax + jmp ball_swap_done +check_ball_b: + cmp eax, swapSlotB + jne ball_swap_done + mov eax, swapSlotA + mov skulls3d_ballPos, eax +ball_swap_done: + invoke PlaySoundA, OFFSET soundClick, 0, 1 +@@: + cmp curPair, 1 + je draw_stat_0 + cmp curPair, 2 + je draw_stat_1 + invoke DrawCup, 226, 105, '3' + jmp draw_moving_cups +draw_stat_0: + invoke DrawCup, 50, 105, '1' + jmp draw_moving_cups +draw_stat_1: + invoke DrawCup, 138, 105, '2' + +draw_moving_cups: + mov edx, '1' + add edx, swapSlotA + invoke DrawCup, curXA, curYA, edx + + mov edx, '1' + add edx, swapSlotB + invoke DrawCup, curXB, curYB, edx + + invoke DrawString8x8, 40, 48, OFFSET textSkullsPhase2, 0000FFFFh + + cmp skulls3d_timer, 60 + jl skulls_draw_controls + mov skulls3d_state, 3 + mov skulls3d_timer, 0 + jmp skulls_draw_controls + +skulls_render_phase3: + invoke DrawCup, 50, 105, '1' + invoke DrawCup, 138, 105, '2' + invoke DrawCup, 226, 105, '3' + invoke DrawString8x8, 16, 48, OFFSET textSkullsPhase3, 0000FFFFh + jmp skulls_draw_controls + +skulls_render_phase4: + mov eax, skulls3d_ballPos + cmp eax, 0 + je p4_ball_0 + cmp eax, 1 + je p4_ball_1 + invoke DrawGoldenBall, 248, 120 + jmp p4_draw_cups +p4_ball_0: + invoke DrawGoldenBall, 72, 120 + jmp p4_draw_cups +p4_ball_1: + invoke DrawGoldenBall, 160, 120 + +p4_draw_cups: + mov edx, 105 + cmp skulls3d_choice, 0 + je @F + cmp skulls3d_ballPos, 0 + jne draw_cup0 +@@: + mov edx, 70 +draw_cup0: + invoke DrawCup, 50, edx, '1' + + mov edx, 105 + cmp skulls3d_choice, 1 + je @F + cmp skulls3d_ballPos, 1 + jne draw_cup1 +@@: + mov edx, 70 +draw_cup1: + invoke DrawCup, 138, edx, '2' + + mov edx, 105 + cmp skulls3d_choice, 2 + je @F + cmp skulls3d_ballPos, 2 + jne draw_cup2 +@@: + mov edx, 70 +draw_cup2: + invoke DrawCup, 226, edx, '3' + + cmp skulls3d_win, 0 + je p4_splash_lose + invoke DrawString8x8, 24, 48, OFFSET textSkullsWin, 0000FFFFh + invoke FormatNumber, skulls3d_win, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 48, OFFSET hudNumBuffer, 0000FFFFh + jmp p4_again_hint +p4_splash_lose: + invoke DrawString8x8, 36, 48, OFFSET textSkullsLose, 000000FFh +p4_again_hint: + invoke DrawString8x8, 56, 138, OFFSET textSkullsAgain, 0000D7FFh + +skulls_draw_controls: + invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 0000D7FFh, 1 + invoke DrawString8x8, 28, 170, OFFSET textBank3D, 0000D7FFh + invoke FormatNumber, bankroll, OFFSET hudNumBuffer + invoke DrawString8x8, 88, 170, OFFSET hudNumBuffer, 0000FFFFh + + invoke DrawString8x8, 180, 170, OFFSET textBet3D, 0000D7FFh + invoke FormatNumber, skulls3d_bet, OFFSET hudNumBuffer + invoke DrawString8x8, 236, 170, OFFSET hudNumBuffer, 0050FF50h + + invoke DrawString8x8, 24, 186, OFFSET textSkullsControls1, 00FFFFFFh + invoke DrawString8x8, 24, 202, OFFSET textSkullsControls2, 00A0A0A0h + ret +RenderSkullsGame ENDP + ; --- Player Input & Movement Physics --- HandlePlayerInput PROC uses ebx esi edi local speed:DWORD @@ -2974,19 +4228,22 @@ check_target_roulette: check_target_dice: cmp eax, INTERACT_DICE jne check_target_skulls - invoke LaunchClassicGame, OFFSET GameDice, 7, OFFSET szTitleDice + call InitDiceGame + mov engineMode, MODE_DICE ret check_target_skulls: cmp eax, INTERACT_SKULLS jne check_target_coin - invoke LaunchClassicGame, OFFSET GameSkulls, 5, OFFSET szTitleSkulls + call InitSkullsGame + mov engineMode, MODE_SKULLS ret check_target_coin: cmp eax, INTERACT_COIN jne check_target_skill - invoke LaunchClassicGame, OFFSET GameCoin, 6, OFFSET szTitleCoin + call InitCoinGame + mov engineMode, MODE_COIN ret check_target_skill: @@ -3382,6 +4639,14 @@ leave_table: je engine_tick cmp roulState, 1 je engine_tick + cmp coin3d_state, 1 + je engine_tick + cmp dice3d_state, 1 + je engine_tick + cmp skulls3d_state, 1 + je engine_tick + cmp skulls3d_state, 2 + je engine_tick mov engineMode, MODE_WALK engine_tick: cmp paused3D, 0 @@ -3425,9 +4690,29 @@ check_shop_mode: call RenderShopGame jmp present_frame check_atm_mode: + cmp engineMode, MODE_ATM + jne check_coin_mode call HandleATMInput call RenderATMGame jmp present_frame +check_coin_mode: + cmp engineMode, MODE_COIN + jne check_dice_mode + call HandleCoinInput + call RenderCoinGame + jmp present_frame +check_dice_mode: + cmp engineMode, MODE_DICE + jne check_skulls_mode + call HandleDiceInput + call RenderDiceGame + jmp present_frame +check_skulls_mode: + cmp engineMode, MODE_SKULLS + jne present_frame + call HandleSkullsInput + call RenderSkullsGame + jmp present_frame draw_pause: invoke DrawBoxBorder, 65, 75, 190, 85, 00151C21h, 00D8BC6Ah, 2 invoke DrawString8x8, 86, 88, OFFSET textPause3D, 00FFFFFFh diff --git a/poker.exe b/poker.exe index b874ad9..dbed6aa 100644 Binary files a/poker.exe and b/poker.exe differ