KAZIK/casino3d.inc

5484 lines
142 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; ==============================================================================
; CASINO 2.5D - MASM32 SOFTWARE RAYCASTER (CP1251)
; Graphical migration; this is not id Software's Doom engine.
; ==============================================================================
includelib gdi32.lib
includelib winmm.lib
CreateWindowExA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
RegisterClassExA PROTO :DWORD
DefWindowProcA PROTO :DWORD,:DWORD,:DWORD,:DWORD
ShowWindow PROTO :DWORD,:DWORD
UpdateWindow PROTO :DWORD
GetDC PROTO :DWORD
ReleaseDC PROTO :DWORD,:DWORD
StretchDIBits PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
PeekMessageA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
TranslateMessage PROTO :DWORD
DispatchMessageA PROTO :DWORD
PostQuitMessage PROTO :DWORD
DestroyWindow PROTO :DWORD
SetWindowTextA PROTO :DWORD,:DWORD
SetForegroundWindow PROTO :DWORD
GetConsoleWindow PROTO
GetSystemMetrics PROTO :DWORD
CreateFileA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
ReadFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
CloseHandle PROTO :DWORD
GetAsyncKeyState PROTO :DWORD
PlaySoundA PROTO :DWORD,:DWORD,:DWORD
GetModuleFileNameA PROTO :DWORD,:DWORD,:DWORD
CopyFileA PROTO :DWORD,:DWORD,:DWORD
lstrcmpiA PROTO :DWORD,:DWORD
GetFileSize PROTO :DWORD,:DWORD
Sleep PROTO :DWORD
CreateThread PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
CreateEventA PROTO :DWORD,:DWORD,:DWORD,:DWORD
SetEvent PROTO :DWORD
WaitForSingleObject PROTO :DWORD,:DWORD
timeBeginPeriod PROTO :DWORD
timeEndPeriod PROTO :DWORD
timeGetTime PROTO
GetCursorPos PROTO :DWORD
SetCursorPos PROTO :DWORD,:DWORD
ShowCursor PROTO :DWORD
ClientToScreen PROTO :DWORD,:DWORD
C3D_POINT STRUCT
x dd ?
y dd ?
C3D_POINT ENDS
C3D_MSG STRUCT
hwnd dd ?
message dd ?
wParam dd ?
lParam dd ?
time dd ?
pt C3D_POINT <>
C3D_MSG ENDS
C3D_WNDCLASSEX STRUCT
cbSize dd ?
style dd ?
lpfnWndProc dd ?
cbClsExtra dd ?
cbWndExtra dd ?
hInstance dd ?
hIcon dd ?
hCursor dd ?
hbrBackground dd ?
lpszMenuName dd ?
lpszClassName dd ?
hIconSm dd ?
C3D_WNDCLASSEX ENDS
C3D_BITMAPINFOHEADER STRUCT
biSize dd ?
biWidth dd ?
biHeight dd ?
biPlanes dw ?
biBitCount dw ?
biCompression dd ?
biSizeImage dd ?
biXPelsPerMeter dd ?
biYPelsPerMeter dd ?
biClrUsed dd ?
biClrImportant dd ?
C3D_BITMAPINFOHEADER ENDS
C3D_BITMAPINFO STRUCT
bmiHeader C3D_BITMAPINFOHEADER <>
bmiColors dd ?
C3D_BITMAPINFO ENDS
SpriteObject STRUCT
posX dd ?
posY dd ?
baseTexId dd ?
frameCount dd ?
curFrame dd ?
animTimer dd ?
animSpeed dd ?
interactId dd ?
promptPtr dd ?
distSq dd ?
SpriteObject ENDS
SCREEN_W equ 640
SCREEN_H equ 480
HALF_W equ 320
HALF_H equ 240
SCREEN_SIZE equ (SCREEN_W * SCREEN_H)
WIN_SCALE equ 1
WINDOW_W equ (SCREEN_W * WIN_SCALE)
WINDOW_H equ (SCREEN_H * WIN_SCALE)
FP_1 equ 65536
FP_HALF equ 32768
CHROMA_KEY equ 00FF00FFh
MODE_WALK equ 0
MODE_SLOTS equ 1
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
MODE_SKILL equ 9
WS_OVERLAPPEDWINDOW equ 00CF0000h
SW_SHOW equ 5
SW_HIDE equ 0
PM_REMOVE equ 1
WM_DESTROY equ 0002h
WM_CLOSE equ 0010h
WM_QUIT equ 0012h
CS_HREDRAW equ 2
CS_VREDRAW equ 1
DIB_RGB_COLORS equ 0
SRCCOPY equ 00CC0020h
INVALID_FILE_HANDLE equ -1
include casino3d_data.inc
include font8x8.inc
include src_graphics\platform_data.inc
include src_graphics\casino_actions_data.inc
include src_graphics\audio_data.inc
include src_graphics\startup_data.inc
include src_graphics\card_tables_data.inc
include src_graphics\native_durak_data.inc
include src_graphics\scene_animation_data.inc
include src_graphics\arrival_data.inc
include src_graphics\city_arrival_data.inc
include src_graphics\merchant_data.inc
include src_graphics\hall_data.inc
include src_graphics\npc_mind_data.inc
include src_graphics\npc_life_data.inc
include src_graphics\native_wheel_data.inc
include src_graphics\billiards_data.inc
include src_graphics\buckshot_data.inc
include src_graphics\russian_view_data.inc
include src_graphics\unavailable_data.inc
include src_graphics\native_slots_data.inc
include src_graphics\native_clover_data.inc
include src_graphics\native_coin_data.inc
.data
ALIGN 4
h3DInst dd 0
h3DWnd dd 0
h3DDC dd 0
hCasinoConsole dd 0
ALIGN 4
hRaycastThread dd 0
hRaycastStartEvent dd 0
hRaycastDoneEvent dd 0
bRaycastQuit dd 0
raycastThreadId dd 0
ALIGN 4
mouseLocked3D dd 0
bmi3D C3D_BITMAPINFO <>
msg3D C3D_MSG <>
wc3D C3D_WNDCLASSEX <>
sz3DClassName db "Casino3DRetroClass",0
sz3DWindowTitle db 192,241,241,229,236,225,235,229,240,32,202,224,231,232,237,238,32,45,32,50,46,53,68,0
szTexturesRelPath db "assets\textures\casino3d-hd.bin",0
szTexturesFullPath db 260 dup(0)
playerX dd (16 * FP_1 + FP_HALF)
playerY dd (16 * FP_1 + FP_HALF)
playerAngle dd 384
playerDirX dd 0
playerDirY dd -FP_1
playerPlaneX dd (FP_1 * 66 / 100)
playerPlaneY dd 0
engineMode dd 0
interactTargetId dd 0
interactPromptPtr dd 0
dancerLuckBuff dd 0
flashTimer dd 0
flashMessage db 128 dup(0)
promptDancer db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> $100",0
promptBlackjack db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (21)",0
promptPoker db 91,69,93,32,207,206,202,197,208,32,40,210,197,213,192,209,209,202,200,201,32,213,206,203,196,197,204,41,0
promptDurak db "[E] <20><><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>",0
promptCasinoRoulette db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
promptClassicSlot db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> 777",0
promptCloverSlot db "[E] <20><><EFBFBD><EFBFBD><EFBFBD> CLOVERPIT (5x3)",0
promptDice db 91,69,93,32,200,195,208,192,32,194,32,202,206,209,210,200,0
promptSkulls db "[E] <20><>Ϩ<EFBFBD><CFA8><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)",0
promptCoin db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28>Ш<EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>)",0
promptSkillCheck db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
promptBuckshot db 91,69,93,32,193,192,202,216,206,210,32,208,211,203,197,210,202,192,0
promptRussianRoulette db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (VIP)",0
promptOnlineRR db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (NET)",0
promptUmamusume db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
promptHellTower db "[E] <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> (10 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)",0
promptShop db "[E] <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
promptATM db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
promptPlayerTerminal db "[E] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
promptObserver db "[E] <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><>)",0
szTitleBlackjack db 202,192,199,200,202,32,51,68,32,45,32,193,203,221,202,196,198,197,202,32,40,50,49,41,0
szTitlePoker db 202,192,199,200,202,32,51,68,32,45,32,207,206,202,197,208,32,40,210,197,213,192,209,209,202,200,201,32,213,206,203,196
db 197,204,41,0
szTitleDurak db 202,192,199,200,202,32,51,68,32,45,32,207,197,208,197,194,206,196,205,206,201,32,196,211,208,192,202,0
szTitleCasinoRoulette db 202,192,199,200,202,32,51,68,32,45,32,197,194,208,206,207,197,201,209,202,192,223,32,208,211,203,197,210,202,192,0
szTitleClassicSlot db 202,192,199,200,202,32,51,68,32,45,32,192,194,210,206,204,192,210,32,55,55,55,0
szTitleCloverSlot db 202,192,199,200,202,32,51,68,32,45,32,202,203,197,194,197,208,205,192,223,32,223,204,192,32,40,53,120,51,41,0
szTitleDice db 202,192,199,200,202,32,51,68,32,45,32,200,195,208,192,32,194,32,202,206,209,210,200,0
szTitleSkulls db 202,192,199,200,202,32,51,68,32,45,32,205,192,207,168,208,209,210,202,200,0
szTitleCoin db 202,192,199,200,202,32,51,68,32,45,32,204,206,205,197,210,202,192,32,40,206,208,168,203,47,208,197,216,202,192,41,0
szTitleSkillCheck db 202,192,199,200,202,32,51,68,32,45,32,207,208,206,194,197,208,202,192,32,205,192,194,219,202,192,0
szTitleBuckshot db 202,192,199,200,202,32,51,68,32,45,32,193,192,202,216,206,210,32,208,211,203,197,210,202,192,0
szTitleRussianRoulette db 202,192,199,200,202,32,51,68,32,45,32,208,211,209,209,202,192,223,32,208,211,203,197,210,202,192,0
szTitleOnlineRR db 202,192,199,200,202,32,51,68,32,45,32,209,197,210,197,194,192,223,32,208,211,209,209,202,192,223,32,208,211,203,197,210
db 202,192,0
szTitleUmamusume db 202,192,199,200,202,32,51,68,32,45,32,195,206,205,202,200,32,211,204,192,204,211,209,211,204,197,0
szTitleHellTower db 202,192,199,200,202,32,51,68,32,45,32,192,196,209,202,192,223,32,193,192,216,205,223,0
szTitleShop db 202,192,199,200,202,32,51,68,32,45,32,202,192,208,210,219,32,200,32,210,192,203,200,209,204,192,205,219,0
szTitleATM db 202,192,199,200,202,32,51,68,32,45,32,193,192,205,202,206,204,192,210,0
szTitleTerminal db 202,192,199,200,202,32,51,68,32,45,32,203,206,202,192,203,220,205,219,197,32,207,208,206,212,200,203,200,0
szTitleObserver db 202,192,199,200,202,32,51,68,32,45,32,205,192,193,203,222,196,192,210,197,203,220,32,40,200,200,41,0
textCabinetFooter db "[ <20><><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 / <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 'N' <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD> ]",0
msgDancerTipped db "<22><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> $100 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
msgNeedMoney db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
statusHUDFormat db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: $",0
targetHUDFormat db " <20><><EFBFBD><EFBFBD>: $",0
luckHUDFormat db " <20><><EFBFBD><EFBFBD><EFBFBD>: +",0
controlsHUD db "WASD/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | E: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ESC: <20><><EFBFBD><EFBFBD>",0
NUM_SPRITES equ 22
INTERACT_NONE equ 0
INTERACT_BLACKJACK equ 1
INTERACT_POKER equ 2
INTERACT_SLOTS_777 equ 3
INTERACT_ROULETTE equ 4
INTERACT_SKULLS equ 5
INTERACT_SHOP equ 6
INTERACT_ATM equ 7
INTERACT_DANCER equ 8
INTERACT_HELL_TOWER equ 9
INTERACT_DURAK equ 10
INTERACT_BUCKSHOT equ 11
INTERACT_COIN equ 12
INTERACT_DICE equ 13
INTERACT_SLOTS_CLOVER equ 14
INTERACT_UMAMUSUME equ 15
INTERACT_OBSERVER equ 16
INTERACT_TERMINAL equ 17
INTERACT_ONLINE_RR equ 18
INTERACT_RUSSIAN_ROULETTE equ 19
INTERACT_SKILL_CHECK equ 20
ALIGN 4
casinoSprites SpriteObject NUM_SPRITES dup(<>)
sortedSprites dd NUM_SPRITES dup(0)
rowDistTable dd 120 dup(0)
rngSeed3D dd 12345678h
slotBet dd 50
slotReel1 dd 0
slotReel2 dd 1
slotReel3 dd 2
slotSpinState dd 0
slotSpinTimer dd 0
slotWinAmount dd 0
slotWinMsg db 64 dup(0)
bjState dd 0
bjBet dd 100
bjPlayerCards dd 10 dup(0)
bjPlayerCardCount dd 0
bjPlayerScore dd 0
bjDealerCards dd 10 dup(0)
bjDealerCardCount dd 0
bjDealerScore dd 0
bjDealerHideHole dd 1
bjOutcomeMsg db 64 dup(0)
roulState dd 0
roulBetType dd 1
roulBetAmount dd 100
roulWheelAngle dd 0
roulBallAngle dd 0
roulSpinTimer dd 0
roulWinningNum dd 0
roulPayout dd 0
roulOutcomeMsg db 64 dup(0)
coinRxAnimTable db 26, 22, 16, 6, 16, 22, 26, 22, 16, 6
; --- Native 2.5D Coin Flip ---
coin3d_bet dd 50
coin3d_choice dd 1 ; 1 = <20><><EFBFBD><EFBFBD>, 2 = <20><><EFBFBD><EFBFBD><EFBFBD>
coin3d_state dd 0 ; 0 = Idle, 1 = Flipping, 2 = Result
coin3d_timer dd 0
coin3d_result dd 1 ; 1 = <20><><EFBFBD><EFBFBD>, 2 = <20><><EFBFBD><EFBFBD><EFBFBD>
coin3d_streak dd 0
coin3d_win dd 0
textCoinTitle db "* * * <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> * * *",0
textCoinHeads db "<22>Ш<EFBFBD>",0
textCoinTails db "<22><><EFBFBD><EFBFBD><EFBFBD>",0
textCoinSide1 db "[1] <20>Ш<EFBFBD>",0
textCoinSide2 db "[2] <20><><EFBFBD><EFBFBD><EFBFBD>",0
textCoinFlipping db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><>˨<EFBFBD><CBA8>...",0
textCoinWin db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: +$",0
textCoinLose db "<22><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
textCoinStreakFmt db "<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>: x",0
textCoinSelected db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
textCoinKey1 db "[1] <20>Ш<EFBFBD>",0
textCoinKey2 db "[2] <20><><EFBFBD><EFBFBD><EFBFBD>",0
textCoinKeySpace db "[SPACE]",0
; --- Native 2.5D Dice Game ---
dice3d_bet dd 50
dice3d_choice dd 1 ; 1 = ׸<>, 2 = <20><><EFBFBD><EFBFBD><EFBFBD>
dice3d_state dd 0 ; 0 = Idle, 1 = Rolling, 2 = Result
dice3d_timer dd 0
dice3d_val1 dd 4
dice3d_val2 dd 6
dice3d_sum dd 10
dice3d_win dd 0
textDiceTitle db 200,195,208,192,32,194,32,202,206,209,210,200,0
textDiceEven db "[1] ר<>",0
textDiceOdd db "[2] <20><><EFBFBD><EFBFBD><EFBFBD>",0
textDiceEvenNums db "2 4 6 ...",0
textDiceOddNums db "3 5 7 ...",0
textDiceSumHdr db "<22><><EFBFBD><EFBFBD><EFBFBD>: ",0
textDicePlus db " + ",0
textDiceEqual db " = ",0
textDiceEvenResult db " (ר<>)",0
textDiceOddResult db " (<28><><EFBFBD><EFBFBD><EFBFBD>)",0
textDiceRolling db "<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>...",0
textDiceWin db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: +$",0
textDiceWinMult db "! (x2)",0
textDiceLose db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
textDiceKey1 db "[1] ר<>",0
textDiceKey2 db "[2] <20><><EFBFBD><EFBFBD><EFBFBD>",0
textDiceKeySpace db "[SPACE]",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 1 ; 0, 1, 2
skulls3d_choice dd 1 ; 0, 1, 2
skulls3d_win dd 0
skulls3d_swapPair0 dd 0
skulls3d_swapPair1 dd 1
skulls3d_swapPair2 dd 2
skulls3d_cup0 dd 0
skulls3d_cup1 dd 1
skulls3d_cup2 dd 2
textSkullsTitle db "* * * <20> <20> <20> <20> <20> <20> <20> <20> <20> * * *",0
textSkullsPhase0 db "<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD> [<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>]",0
textSkullsPhase1 db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>...",0
textSkullsPhase2 db "<22><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>...",0
textSkullsPhase3 db "<22><><EFBFBD> <20><><EFBFBD>? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: [1], [2] <20><><EFBFBD> [3]!",0
textSkullsWin db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: +$",0
textSkullsWinMult db "! (x3) <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
textSkullsLose db "<22><><EFBFBD><EFBFBD>! <20><><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>!",0
textSkullsAgain db "[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>] - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>٨ <20><><EFBFBD>",0
textSkullsKey1 db "[1]",0
textSkullsKey2 db "[2]",0
textSkullsKey3 db "[3]",0
textSkullsKeySpace db "[SPACE] <20><><EFBFBD><EFBFBD><EFBFBD>",0
; --- Native 2.5D Skill Check (Dead by Daylight Survivor Check) ---
skill3d_bet dd 50
skill3d_state dd 0 ; 0=Ready, 1=Active, 2=Hit Result, 3=Miss Result, 4=Escaped, 5=Defeated
skill3d_timer dd 0
skill3d_needle dd 55 ; Needle X (52..268)
skill3d_speed dd 4
skill3d_dir dd 1 ; 1=Right, -1=Left
skill3d_zone_start dd 140
skill3d_zone_width dd 48
skill3d_great_start dd 176
skill3d_great_width dd 12
skill3d_hits dd 0
skill3d_misses dd 0
skill3d_last_result dd 0
skill3d_win_amount dd 0
textSkillTitle db 61,61,61,32,207,208,206,194,197,208,202,192,32,205,192,194,219,202,192,32,61,61,61,0
textSkillHitsHdr db "<22><><EFBFBD>: ",0
textSkillMissHdr db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ",0
textSkillReadyMsg db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>] <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
textSkillPrompt db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>] <20> <20><><EFBFBD><EFBFBD>!",0
textSkillHitMsg db "<22><><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
textSkillGreatMsg db 206,210,203,200,215,205,206,33,32,43,193,206,205,211,209,33,0
textSkillMissMsg db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
textSkillEscape db "<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: +$",0
textSkillLost db "<22><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!",0
textSkillKeySpace db "[SPACE] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
textSkillKeyBet db "[<5B><><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>]",0
; --- Shared UI Strings ---
textKeyEsc db "[ESC]",0
textBankPrompt db "<22><><EFBFBD><EFBFBD>: $",0
textBetPrompt db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: $",0
textBetHint db " [W/S]",0
shopMsg db 128 dup(0)
atmMsg db 128 dup(0)
strWin db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! +$",0
strLose db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
strJackpot db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! +$",0
strPush db 205,200,215,220,223,0
strDealerBust db "<22><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>! +$",0
strPlayerBust db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (>21)! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",0
sym7 db " 777 ",0
symBar db " BAR ",0
symBell db 32,199,194,206,205,0
symCherry db 194,200,216,205,223,0
symClover db 202,203,197,194,197,208,0
symGem db 192,203,204,192,199,0
symCrown db 202,206,208,206,205,192,0
cardRankStr db "A ",0,"2 ",0,"3 ",0,"4 ",0,"5 ",0,"6 ",0,"7 ",0,"8 ",0,"9 ",0,"10",0,"J ",0,"Q ",0,"K ",0
.data?
ALIGN 4
screenBuffer dd SCREEN_SIZE dup(?)
ALIGN 4
zBuffer dd SCREEN_W dup(?)
ALIGN 4
texturesBuffer dd (104 * 128 * 128) dup(?)
hudNumBuffer db 32 dup(?)
.code
; --- 3D Window Procedure ---
Casino3DWndProc PROC hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
invoke WindowEvents3D, hwnd, uMsg, wParam, lParam
ret
Casino3DWndProc ENDP
; --- Random Generator ---
RandomRange3D PROC maxVal:DWORD
mov eax, rngSeed3D
imul eax, 1103515245
add eax, 12345
mov rngSeed3D, eax
shr eax, 16
and eax, 7FFFh
xor edx, edx
div maxVal
mov eax, edx
ret
RandomRange3D ENDP
; --- Copy String ---
CopyString3D PROC src:DWORD, dst:DWORD
push esi
push edi
mov esi, src
mov edi, dst
@@:
mov al, [esi]
mov [edi], al
test al, al
jz @F
inc esi
inc edi
jmp @B
@@:
pop edi
pop esi
ret
CopyString3D ENDP
; --- Format Number to Decimal String ---
FormatNumber PROC num:DWORD, buf:DWORD
push ebx
push esi
push edi
mov eax, num
mov edi, buf
test eax, eax
jns fn_pos
mov BYTE PTR [edi], '-'
inc edi
neg eax
fn_pos:
mov ebx, 10
push 0
fn_div:
xor edx, edx
div ebx
add dl, '0'
push edx
test eax, eax
jnz fn_div
fn_pop:
pop eax
test al, al
jz fn_done
mov [edi], al
inc edi
jmp fn_pop
fn_done:
mov BYTE PTR [edi], 0
pop edi
pop esi
pop ebx
ret
FormatNumber ENDP
; --- Fast 2D Drawing Primitives ---
DrawBox PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
DrawPixel PROC x:DWORD, y:DWORD, color:DWORD
invoke DrawBox, x, y, 1, 1, color
ret
DrawPixel ENDP
DrawBox PROC x:DWORD, y:DWORD, w:DWORD, h:DWORD, color:DWORD
shl x, 1
shl y, 1
shl w, 1
shl h, 1
push ebx
push esi
push edi
mov edi, y
box_row_loop:
mov eax, y
add eax, h
cmp edi, eax
jge box_done
cmp edi, 0
jl next_box_row
cmp edi, SCREEN_H
jge box_done
mov esi, x
box_col_loop:
mov eax, x
add eax, w
cmp esi, eax
jge next_box_row
cmp esi, 0
jl next_box_col
cmp esi, SCREEN_W
jge next_box_row
mov ecx, edi
imul ecx, SCREEN_W
add ecx, esi
mov edx, color
mov [screenBuffer + ecx*4], edx
next_box_col:
inc esi
jmp box_col_loop
next_box_row:
inc edi
jmp box_row_loop
box_done:
pop edi
pop esi
pop ebx
ret
DrawBox ENDP
DrawBoxBorder PROC uses ebx x:DWORD, y:DWORD, w:DWORD, h:DWORD, fillColor:DWORD, borderColor:DWORD, bWidth:DWORD
invoke DrawBox, x, y, w, h, borderColor
mov eax, x
add eax, bWidth
mov edx, y
add edx, bWidth
mov ecx, w
sub ecx, bWidth
sub ecx, bWidth
mov ebx, h
sub ebx, bWidth
sub ebx, bWidth
invoke DrawBox, eax, edx, ecx, ebx, fillColor
ret
DrawBoxBorder ENDP
DrawCircle PROC cxVal:DWORD, cyVal:DWORD, radius:DWORD, color:DWORD
push ebx
push esi
push edi
mov eax, radius
neg eax
mov edi, eax
circ_y:
cmp edi, radius
jg circ_done
mov eax, radius
neg eax
mov esi, eax
circ_x:
cmp esi, radius
jg next_circ_y
mov eax, esi
imul eax, eax
mov ebx, edi
imul ebx, ebx
add eax, ebx
mov edx, radius
imul edx, edx
cmp eax, edx
jg next_circ_x
mov eax, cxVal
add eax, esi
mov ecx, cyVal
add ecx, edi
invoke DrawPixel, eax, ecx, color
next_circ_x:
inc esi
jmp circ_x
next_circ_y:
inc edi
jmp circ_y
circ_done:
pop edi
pop esi
pop ebx
ret
DrawCircle ENDP
DrawChar8x8 PROC uses ebx esi edi x:DWORD, y:DWORD, chVal:DWORD, color:DWORD
local column:DWORD
mov eax, chVal
and eax, 255
lea esi, [font8x8 + eax*8]
xor edi, edi
glyph_row:
movzx ebx, BYTE PTR [esi+edi]
mov column, 0
glyph_col:
test ebx, 80h
jz glyph_next
mov eax, x
add eax, column
mov edx, y
add edx, edi
invoke DrawPixel, eax, edx, color
glyph_next:
shl ebx, 1
inc column
cmp column, 8
jl glyph_col
inc edi
cmp edi, 8
jl glyph_row
ret
DrawChar8x8 ENDP
DrawString8x8 PROC x:DWORD, y:DWORD, strPtr:DWORD, color:DWORD
push ebx
push esi
mov esi, strPtr
mov ebx, x
str_loop:
movzx eax, BYTE PTR [esi]
test al, al
jz str_done
invoke DrawChar8x8, ebx, y, eax, color
add ebx, 8
inc esi
jmp str_loop
str_done:
pop esi
pop ebx
ret
DrawString8x8 ENDP
; --- True 3D Perspective Floor & Ceiling Rendering ---
; --- DDA Raycasting Walls ---
RenderWallsRange PROC colStart:DWORD, colLimit:DWORD
local col:DWORD
local originalStart:DWORD
local camX:DWORD
local rayDirX:DWORD
local rayDirY:DWORD
local mapX:DWORD
local mapY:DWORD
local deltaDistX:DWORD
local deltaDistY:DWORD
local stepX:DWORD
local stepY:DWORD
local sideDistX:DWORD
local sideDistY:DWORD
local side:DWORD
local perpWallDist:DWORD
local lineH:DWORD
local drawStart:DWORD
local drawEnd:DWORD
local wallHit:DWORD
local texX:DWORD
local texXHD:DWORD
local pixelMaterial:DWORD
local texId:DWORD
local shade:DWORD
push ebx
push esi
push edi
mov eax, playerAngle
and eax, 511
mov ebx, [tableCos + eax*4]
mov playerDirX, ebx
mov ebx, [tableSin + eax*4]
mov playerDirY, ebx
mov eax, ebx
imul eax, -66
cdq
mov ecx, 100
idiv ecx
mov playerPlaneX, eax
mov eax, playerDirX
imul eax, 66
cdq
idiv ecx
mov playerPlaneY, eax
mov eax, colStart
mov col, eax
col_loop:
mov eax, colLimit
cmp col, eax
jge walls_done
mov eax, col
shl eax, 1
sub eax, SCREEN_W
imul eax, FP_1
cdq
mov ecx, SCREEN_W
idiv ecx
mov camX, eax
mov eax, playerPlaneX
imul camX
shrd eax, edx, 16
add eax, playerDirX
mov rayDirX, eax
mov eax, playerPlaneY
imul camX
shrd eax, edx, 16
add eax, playerDirY
mov rayDirY, eax
mov eax, playerX
sar eax, 16
mov mapX, eax
mov eax, playerY
sar eax, 16
mov mapY, eax
mov eax, rayDirX
test eax, eax
jnz calc_delta_x
mov deltaDistX, 7FFFFFFFh
jmp calc_delta_y
calc_delta_x:
test eax, eax
jns @F
neg eax
@@:
mov ebx, eax
cmp ebx, 4
jbe delta_x_clamp
xor eax, eax
mov edx, 1
div ebx
mov deltaDistX, eax
jmp calc_delta_y
delta_x_clamp:
mov deltaDistX, 7FFFFFFFh
calc_delta_y:
mov eax, rayDirY
test eax, eax
jnz calc_delta_y_ok
mov deltaDistY, 7FFFFFFFh
jmp check_step
calc_delta_y_ok:
test eax, eax
jns @F
neg eax
@@:
mov ebx, eax
cmp ebx, 4
jbe delta_y_clamp
xor eax, eax
mov edx, 1
div ebx
mov deltaDistY, eax
jmp check_step
delta_y_clamp:
mov deltaDistY, 7FFFFFFFh
check_step:
cmp rayDirX, 0
jge step_x_pos
mov stepX, -1
mov eax, playerX
mov edx, mapX
shl edx, 16
sub eax, edx
imul deltaDistX
shrd eax, edx, 16
mov sideDistX, eax
jmp check_step_y
step_x_pos:
mov stepX, 1
mov eax, mapX
inc eax
shl eax, 16
sub eax, playerX
imul deltaDistX
shrd eax, edx, 16
mov sideDistX, eax
check_step_y:
cmp rayDirY, 0
jge step_y_pos
mov stepY, -1
mov eax, playerY
mov edx, mapY
shl edx, 16
sub eax, edx
imul deltaDistY
shrd eax, edx, 16
mov sideDistY, eax
jmp dda_start
step_y_pos:
mov stepY, 1
mov eax, mapY
inc eax
shl eax, 16
sub eax, playerY
imul deltaDistY
shrd eax, edx, 16
mov sideDistY, eax
dda_start:
xor ecx, ecx
dda_step_loop:
inc ecx
cmp ecx, 64
jge wall_map_boundary
mov eax, sideDistX
cmp eax, sideDistY
jge step_in_y
mov eax, deltaDistX
add sideDistX, eax
mov eax, stepX
add mapX, eax
mov side, 0
jmp check_tile
step_in_y:
mov eax, deltaDistY
add sideDistY, eax
mov eax, stepY
add mapY, eax
mov side, 1
check_tile:
cmp mapX, 0
jl wall_map_boundary
cmp mapX, MAP_WIDTH
jge wall_map_boundary
cmp mapY, 0
jl wall_map_boundary
cmp mapY, MAP_HEIGHT
jge wall_map_boundary
mov eax, mapY
shl eax, 5
add eax, mapX
mov edx, worldMap3D
movzx eax, BYTE PTR [edx + eax]
test eax, eax
jnz hit_wall
jmp dda_step_loop
wall_map_boundary:
cmp outdoorRender3D, 0
je hit_wall
mov eax, col
mov zBuffer[eax*4], 7FFFFFFFh
jmp next_col
hit_wall:
cmp side, 0
jne perp_y
mov eax, sideDistX
sub eax, deltaDistX
mov perpWallDist, eax
jmp perp_done
perp_y:
mov eax, sideDistY
sub eax, deltaDistY
mov perpWallDist, eax
perp_done:
cmp perpWallDist, 2048
jge @F
mov perpWallDist, 2048
@@:
mov eax, col
mov edx, perpWallDist
mov [zBuffer + eax*4], edx
; Unit projection is shared by indoor room height and outdoor storeys.
mov eax, SCREEN_H
imul eax, FP_1
cdq
idiv perpWallDist
mov lineH, eax
mov eax, lineH
imul viewEye3D
shrd eax, edx, 16
add eax, viewHorizon3D
mov drawEnd, eax
mov ebx, lineH
mov eax, viewCeiling3D
cmp outdoorRender3D, 0
je @F
mov eax, CITY_STOREY_HEIGHT
@@:
imul ebx
shrd eax, edx, 16
mov ebx, eax
mov lineH, ebx
mov eax, drawEnd
sub eax, ebx
mov drawStart, eax
cmp outdoorRender3D, 0
je wall_store_original_start
; Floor height is independent of storey height.
mov eax, drawEnd
sub eax, lineH
mov drawStart, eax
mov eax, mapY
shl eax, 5
add eax, mapX
mov edx, worldMap3D
movzx eax, BYTE PTR [edx+eax]
wall_exterior_tall:
; Roof projection and texture sampling use the same storey count.
mov eax, lineH
imul eax, CITY_BUILDING_STOREYS-1
sub drawStart, eax
mov eax, lineH
imul eax, CITY_BUILDING_STOREYS
mov lineH, eax
wall_store_original_start:
mov eax, drawStart
mov originalStart, eax
cmp side, 0
jne hit_side_y
mov eax, perpWallDist
imul rayDirY
shrd eax, edx, 16
add eax, playerY
mov wallHit, eax
jmp calc_tex_x
hit_side_y:
mov eax, perpWallDist
imul rayDirX
shrd eax, edx, 16
add eax, playerX
mov wallHit, eax
calc_tex_x:
; MASK WITH 0FFFFh to prevent texture scrambling!
mov eax, wallHit
and eax, 0FFFFh
mov texXHD, eax
shr eax, 9
and eax, 127
mov texX, eax
cmp side, 0
jne @F
cmp rayDirX, 0
jle @F
mov eax, 127
sub eax, texX
mov texX, eax
xor texXHD, 0FFFFh
@@:
cmp side, 1
jne select_tex
cmp rayDirY, 0
jge select_tex
mov eax, 127
sub eax, texX
mov texX, eax
xor texXHD, 0FFFFh
select_tex:
mov eax, mapY
shl eax, 5
add eax, mapX
mov edx, worldMap3D
movzx eax, BYTE PTR [edx + eax]
mov texId, eax
cmp texId, 0
jne @F
mov texId, 1
@@:
mov eax, perpWallDist
shr eax, 13
mov edx, 256
sub edx, eax
cmp edx, 75
jge @F
mov edx, 75
@@:
cmp side, 1
jne @F
imul edx, 3
shr edx, 2
@@:
mov shade, edx
cmp drawStart, 0
jge @F
mov drawStart, 0
@@:
cmp drawEnd, SCREEN_H
jl @F
mov drawEnd, SCREEN_H - 1
@@:
mov eax, lineH
cmp eax, 1
jge @F
mov eax, 1
mov lineH, eax
@@:
mov eax, 128 * FP_1
cdq
idiv lineH
mov esi, eax ; stepY
mov eax, drawStart
sub eax, originalStart
imul eax, esi
mov edi, eax ; texPos
mov ecx, drawStart
draw_stripe_loop:
cmp ecx, drawEnd
jg next_col
mov eax, edi
shr eax, 16
and eax, 127
mov edx, texId
cmp outdoorRender3D, 0
je wall_sample_material
imul eax, CITY_BUILDING_STOREYS
cmp eax, 128*(CITY_BUILDING_STOREYS-1)
jae wall_lower_storey
push eax
shr eax, 7
add eax, mapX
add eax, mapY
xor edx, edx
mov ebx, 3
div ebx
add edx, 65
pop eax
and eax, 127
jmp wall_sample_material
wall_lower_storey:
sub eax, 128*(CITY_BUILDING_STOREYS-1)
wall_sample_material:
mov pixelMaterial, edx
cmp outdoorRender3D, 0
je wall_sample_indoor_hd
cmp hallCityDetail3D.pixels, 0
je wall_sample_standard
cmp edx, 57
jb wall_sample_standard
cmp edx, 72
ja wall_sample_standard
cmp perpWallDist, 6*FP_1
ja wall_sample_standard
; Preserve subtexel detail near facades; retain the 128px mip at distance.
push edx
mov eax, edi
shr eax, 15
imul eax, CITY_BUILDING_STOREYS
and eax, 255
shl eax, 8
mov ebx, texXHD
shr ebx, 8
add eax, ebx
pop edx
sub edx, 57
shl edx, 16
add eax, edx
mov ebx, hallCityDetail3D.pixels
mov eax, [ebx+eax*4]
jmp wall_shade_pixel
wall_sample_indoor_hd:
cmp edx, 80
jb wall_sample_standard
cmp edx, 103
ja wall_sample_standard
mov ebx, hallRoomHD3D.pixels
cmp edx, 92
jb wall_sample_room_hd
mov ebx, hallArchitectureHD3D.pixels
sub edx, 12
wall_sample_room_hd:
test ebx, ebx
jz wall_sample_standard_restore
sub edx, 80
shl edx, 18
add ebx, edx
mov eax, edi
shr eax, 15
and eax, 255
shl eax, 8
mov edx, texXHD
shr edx, 8
add eax, edx
mov eax, [ebx+eax*4]
jmp wall_shade_pixel
wall_sample_standard_restore:
mov edx, texId
mov eax, edi
shr eax, 16
and eax, 127
wall_sample_standard:
shl eax, 7
add eax, texX
shl edx, 14
add eax, edx
mov eax, [texturesBuffer + eax*4]
; Shade wall pixel
wall_shade_pixel:
mov ebx, shade
cmp outdoorRender3D, 0
je wall_ambient_shade
push eax
push ecx
invoke IsCityEmissive3D, eax, pixelMaterial
pop ecx
test eax, eax
pop eax
jz wall_ambient_shade
mov ebx, 256
wall_ambient_shade:
cmp hallLevel3D, 0
je @F
imul ebx, 7
shr ebx, 3
@@:
movzx edx, al
imul edx, ebx
shr edx, 8
push edx
movzx edx, ah
imul edx, ebx
shr edx, 8
shl edx, 8
shr eax, 16
movzx eax, al
imul eax, ebx
shr eax, 8
shl eax, 16
or eax, edx
pop edx
or eax, edx
mov edx, ecx
imul edx, SCREEN_W
add edx, col
mov [screenBuffer + edx*4], eax
add edi, esi
inc ecx
jmp draw_stripe_loop
next_col:
inc col
jmp col_loop
walls_done:
pop edi
pop esi
pop ebx
ret
RenderWallsRange ENDP
; --- Raycasting Background Worker Thread ---
RaycastWorkerProc PROC uses ebx esi edi lpParam:DWORD
worker_loop:
invoke WaitForSingleObject, hRaycastStartEvent, 0FFFFFFFFh
cmp bRaycastQuit, 1
je worker_exit
invoke RenderWallsRange, 320, 640
invoke SetEvent, hRaycastDoneEvent
jmp worker_loop
worker_exit:
xor eax, eax
ret
RaycastWorkerProc ENDP
; --- Multi-Threaded DDA Raycasting Walls Dispatcher ---
RenderWalls PROC
push ebx
push esi
push edi
mov eax, playerAngle
and eax, 511
mov ebx, [tableCos + eax*4]
mov playerDirX, ebx
mov ebx, [tableSin + eax*4]
mov playerDirY, ebx
mov eax, ebx
imul eax, -66
cdq
mov ecx, 100
idiv ecx
mov playerPlaneX, eax
mov eax, playerDirX
imul eax, 66
cdq
idiv ecx
mov playerPlaneY, eax
cmp hRaycastStartEvent, 0
je single_thread_fallback
; Signal background worker to render columns [320..640)
invoke SetEvent, hRaycastStartEvent
; Main thread processes columns [0..320) in parallel
invoke RenderWallsRange, 0, 320
; Synchronize with worker completion
invoke WaitForSingleObject, hRaycastDoneEvent, 0FFFFFFFFh
jmp walls_finished
single_thread_fallback:
invoke RenderWallsRange, 0, SCREEN_W
walls_finished:
pop edi
pop esi
pop ebx
ret
RenderWalls ENDP
; --- Render 3D Billboard Sprites ---
; --- HUD & Minimap Radar ---
RenderHUD PROC uses ebx esi edi
invoke DrawBox, 0, 0, 320, 16, 0014191Dh
invoke DrawString8x8, 8, 4, OFFSET textBank3D, 00D8BC6Ah
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 64, 4, OFFSET hudNumBuffer, 00FFFFFFh
invoke DrawString8x8, 176, 4, OFFSET textWindowKeys3D, 00A8B6BBh
invoke DrawBox, 0, 226, 320, 14, 0014191Dh
invoke DrawString8x8, 12, 230, OFFSET textWalkKeys3D, 00A8B6BBh
invoke DrawBox, 159, 118, 2, 5, 00E7DFC8h
invoke DrawBox, 157, 120, 6, 1, 00E7DFC8h
cmp interactPromptPtr, 0
je @F
invoke DrawBoxBorder, 4, 199, 312, 18, 0014191Dh, 00D8BC6Ah, 1
invoke DrawString8x8, 10, 204, interactPromptPtr, 00F5E2B0h
@@:
cmp flashTimer, 0
je hud_finished
dec flashTimer
invoke DrawBox, 4, 22, 312, 16, 0014191Dh
invoke DrawString8x8, 10, 26, OFFSET flashMessage, 00FFFFFFh
hud_finished:
ret
RenderHUD ENDP
RenderMinimap PROC uses ebx esi edi
local radarX:DWORD
local radarY:DWORD
local radarSize:DWORD
mov radarX, 320 - 48
mov radarY, 20
mov radarSize, 44
invoke DrawBoxBorder, radarX, radarY, radarSize, radarSize, 00101510h, 00FFD700h, 1
; Draw Sprites on radar
cmp hallLevel3D, 0
jne draw_player_radar
xor esi, esi
radar_spr_loop:
cmp esi, NUM_SPRITES
jge draw_player_radar
mov eax, esi
imul eax, SIZEOF SpriteObject
mov eax, [casinoSprites + eax].posX
sar eax, 16
imul eax, radarSize
shr eax, 5
add eax, radarX
mov ebx, eax
mov eax, esi
imul eax, SIZEOF SpriteObject
mov eax, [casinoSprites + eax].posY
sar eax, 16
imul eax, radarSize
shr eax, 5
add eax, radarY
invoke DrawPixel, ebx, eax, 00FFAA00h
inc esi
jmp radar_spr_loop
draw_player_radar:
mov eax, playerX
sar eax, 16
imul eax, radarSize
shr eax, 5
add eax, radarX
mov ebx, eax
mov eax, playerY
sar eax, 16
imul eax, radarSize
shr eax, 5
add eax, radarY
invoke DrawCircle, ebx, eax, 2, 00FF2020h
ret
RenderMinimap ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: SLOTS 777
; ==============================================================================
HandleSlotsInput PROC
cmp slotSpinState, 1
je slots_input_done
invoke Pressed3D, 20h ; SPACE -> Spin
test ah, 80h
jz check_bet_adjust
mov eax, bankroll
cmp eax, slotBet
jl @F
sub eax, slotBet
mov bankroll, eax
mov slotSpinState, 1
mov slotSpinTimer, 0
mov slotWinAmount, 0
invoke PlayCasinoSound3D, OFFSET soundSlotSpin, 0, 1
jmp slots_input_done
@@:
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
mov flashTimer, 60
check_bet_adjust:
invoke Pressed3D, 26h ; UP / W
test ah, 80h
jnz inc_bet
invoke Pressed3D, 57h
test ah, 80h
jz check_bet_down
inc_bet:
cmp slotBet, 500
jge slots_input_done
cmp slotBet, 100
jge @F
cmp slotBet, 50
jge set_100
mov slotBet, 50
jmp slots_input_done
set_100:
mov slotBet, 100
jmp slots_input_done
@@:
mov slotBet, 500
jmp slots_input_done
check_bet_down:
invoke Pressed3D, 28h ; DOWN / S
test ah, 80h
jnz dec_bet
invoke Pressed3D, 53h
test ah, 80h
jz slots_input_done
dec_bet:
cmp slotBet, 50
jle set_10
cmp slotBet, 100
jle set_50
mov slotBet, 100
jmp slots_input_done
set_50:
mov slotBet, 50
jmp slots_input_done
set_10:
mov slotBet, 10
slots_input_done:
ret
HandleSlotsInput ENDP
RenderSlotsGame PROC uses ebx esi edi
; Cabinet Background (Dark Cherry Wood & Gold)
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A10h
invoke DrawBoxBorder, 10, 10, 300, 220, 00251015h, 00FFD700h, 3
; Illuminated Top Marquee
invoke DrawBoxBorder, 25, 20, 270, 32, 000A0505h, 00FFFF00h, 2
invoke DrawString8x8, 55, 32, OFFSET textSlots3D, 00FFD700h
; Spinning Animation Logic
cmp slotSpinState, 1
jne draw_reels
inc slotSpinTimer
cmp slotSpinTimer, 22
jge @F
invoke RandomRange3D, 7
mov slotReel1, eax
@@:
cmp slotSpinTimer, 36
jge @F
invoke RandomRange3D, 7
mov slotReel2, eax
@@:
cmp slotSpinTimer, 50
jge @F
invoke RandomRange3D, 7
mov slotReel3, eax
@@:
cmp slotSpinTimer, 50
jl draw_reels
; Spin finished! Check outcome!
mov slotSpinState, 0
mov eax, slotReel1
cmp eax, slotReel2
jne check_pairs
cmp eax, slotReel3
jne check_pairs
; 3 Matching!
cmp eax, 0 ; 777!
jne @F
mov eax, slotBet
imul eax, 25
mov slotWinAmount, eax
add bankroll, eax
invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1
jmp draw_reels
@@:
cmp eax, 6 ; CROWN!
jne @F
mov eax, slotBet
imul eax, 50
mov slotWinAmount, eax
add bankroll, eax
invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1
jmp draw_reels
@@:
mov eax, slotBet
imul eax, 10
mov slotWinAmount, eax
add bankroll, eax
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
jmp draw_reels
check_pairs:
mov eax, slotReel1
cmp eax, slotReel2
je pair_win
mov eax, slotReel2
cmp eax, slotReel3
je pair_win
mov eax, slotReel1
cmp eax, slotReel3
je pair_win
jmp draw_reels
pair_win:
mov eax, slotBet
imul eax, 2
mov slotWinAmount, eax
add bankroll, eax
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
draw_reels:
; Reels Window
invoke DrawBoxBorder, 30, 62, 260, 95, 000F0F12h, 0000A5FFh, 2
; Reel 1 (45..105)
invoke DrawBoxBorder, 45, 68, 65, 82, 00F0F0F5h, 00505050h, 2
mov eax, slotReel1
call DrawReelSymbolAt1
; Reel 2 (128..188)
invoke DrawBoxBorder, 128, 68, 65, 82, 00F0F0F5h, 00505050h, 2
mov eax, slotReel2
call DrawReelSymbolAt2
; Reel 3 (210..270)
invoke DrawBoxBorder, 210, 68, 65, 82, 00F0F0F5h, 00505050h, 2
mov eax, slotReel3
call DrawReelSymbolAt3
; Bottom Control Panel
invoke DrawBoxBorder, 20, 165, 280, 58, 00151515h, 00FFD700h, 1
invoke DrawString8x8, 28, 172, OFFSET textBank3D, 00FFD700h
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 00FFFF00h
invoke DrawString8x8, 175, 172, OFFSET textBet3D, 00FFD700h
invoke FormatNumber, slotBet, OFFSET hudNumBuffer
invoke DrawString8x8, 240, 172, OFFSET hudNumBuffer, 0050FF50h
cmp slotWinAmount, 0
jle draw_slot_ctrls
invoke DrawString8x8, 28, 187, OFFSET strWin, 00FFFF00h
invoke FormatNumber, slotWinAmount, OFFSET hudNumBuffer
invoke DrawString8x8, 110, 187, OFFSET hudNumBuffer, 00FFFF00h
draw_slot_ctrls:
invoke DrawString8x8, 28, 204, OFFSET textSlotsKeys3D, 00A0A0A0h
ret
RenderSlotsGame ENDP
DrawReelSymbolAt1 PROC
cmp eax, 0
jne @F
invoke DrawString8x8, 52, 105, OFFSET sym7, 00FF2020h
ret
@@:
cmp eax, 1
jne @F
invoke DrawString8x8, 52, 105, OFFSET symBar, 00FFAA00h
ret
@@:
cmp eax, 2
jne @F
invoke DrawString8x8, 52, 105, OFFSET symBell, 00FFD700h
ret
@@:
cmp eax, 3
jne @F
invoke DrawString8x8, 48, 105, OFFSET symCherry, 000000D0h
ret
@@:
cmp eax, 4
jne @F
invoke DrawString8x8, 48, 105, OFFSET symClover, 0000A000h
ret
@@:
cmp eax, 5
jne @F
invoke DrawString8x8, 52, 105, OFFSET symGem, 00FFFF00h
ret
@@:
invoke DrawString8x8, 52, 105, OFFSET symCrown, 00FFD700h
ret
DrawReelSymbolAt1 ENDP
DrawReelSymbolAt2 PROC
cmp eax, 0
jne @F
invoke DrawString8x8, 135, 105, OFFSET sym7, 00FF2020h
ret
@@:
cmp eax, 1
jne @F
invoke DrawString8x8, 135, 105, OFFSET symBar, 00FFAA00h
ret
@@:
cmp eax, 2
jne @F
invoke DrawString8x8, 135, 105, OFFSET symBell, 00FFD700h
ret
@@:
cmp eax, 3
jne @F
invoke DrawString8x8, 131, 105, OFFSET symCherry, 000000D0h
ret
@@:
cmp eax, 4
jne @F
invoke DrawString8x8, 131, 105, OFFSET symClover, 0000A000h
ret
@@:
cmp eax, 5
jne @F
invoke DrawString8x8, 135, 105, OFFSET symGem, 00FFFF00h
ret
@@:
invoke DrawString8x8, 135, 105, OFFSET symCrown, 00FFD700h
ret
DrawReelSymbolAt2 ENDP
DrawReelSymbolAt3 PROC
cmp eax, 0
jne @F
invoke DrawString8x8, 218, 105, OFFSET sym7, 00FF2020h
ret
@@:
cmp eax, 1
jne @F
invoke DrawString8x8, 218, 105, OFFSET symBar, 00FFAA00h
ret
@@:
cmp eax, 2
jne @F
invoke DrawString8x8, 218, 105, OFFSET symBell, 00FFD700h
ret
@@:
cmp eax, 3
jne @F
invoke DrawString8x8, 214, 105, OFFSET symCherry, 000000D0h
ret
@@:
cmp eax, 4
jne @F
invoke DrawString8x8, 214, 105, OFFSET symClover, 0000A000h
ret
@@:
cmp eax, 5
jne @F
invoke DrawString8x8, 218, 105, OFFSET symGem, 00FFFF00h
ret
@@:
invoke DrawString8x8, 218, 105, OFFSET symCrown, 00FFD700h
ret
DrawReelSymbolAt3 ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: BLACKJACK (21)
; ==============================================================================
HandleBlackjackInput PROC uses ebx
cmp bjState, 0 ; Need Deal
jne check_bj_player_turn
invoke Pressed3D, 20h ; SPACE -> Deal
test ah, 80h
jz check_bj_bet_change
mov eax, bankroll
cmp eax, bjBet
jl bj_need_cash
sub eax, bjBet
mov bankroll, eax
; Deal 2 cards to player, 2 cards to dealer
mov bjPlayerCardCount, 0
mov bjDealerCardCount, 0
mov bjDealerHideHole, 1
; Player Card 1
invoke RandomRange3D, 13
inc eax
mov ebx, bjPlayerCardCount
mov [bjPlayerCards + ebx*4], eax
inc bjPlayerCardCount
; Dealer Card 1
invoke RandomRange3D, 13
inc eax
mov ebx, bjDealerCardCount
mov [bjDealerCards + ebx*4], eax
inc bjDealerCardCount
; Player Card 2
invoke RandomRange3D, 13
inc eax
mov ebx, bjPlayerCardCount
mov [bjPlayerCards + ebx*4], eax
inc bjPlayerCardCount
; Dealer Card 2 (Hole card)
invoke RandomRange3D, 13
inc eax
mov ebx, bjDealerCardCount
mov [bjDealerCards + ebx*4], eax
inc bjDealerCardCount
invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1
; Calc Player Score
call CalcPlayerBJScore
cmp bjPlayerScore, 21
jne set_bj_turn
; Instant Blackjack!
mov bjDealerHideHole, 0
mov eax, bjBet
imul eax, 5
shr eax, 1
add bankroll, eax
invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
mov bjState, 2
ret
set_bj_turn:
mov bjState, 1
mov BYTE PTR [bjOutcomeMsg], 0
ret
bj_need_cash:
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
mov flashTimer, 60
ret
check_bj_player_turn:
cmp bjState, 1
jne check_bj_round_over
invoke Pressed3D, 48h ; 'H' -> Hit
test ah, 80h
jz check_bj_stand
invoke RandomRange3D, 13
inc eax
mov ebx, bjPlayerCardCount
cmp ebx, 8
jge @F
mov [bjPlayerCards + ebx*4], eax
inc bjPlayerCardCount
@@:
invoke PlayCasinoSound3D, OFFSET soundCards, 0, 1
call CalcPlayerBJScore
cmp bjPlayerScore, 21
jle bj_input_done
; Bust!
invoke CopyString3D, OFFSET strPlayerBust, OFFSET bjOutcomeMsg
mov bjDealerHideHole, 0
mov bjState, 2
ret
check_bj_stand:
invoke Pressed3D, 53h ; 'S' -> Stand
test ah, 80h
jz bj_input_done
; Dealer Turn
mov bjDealerHideHole, 0
dealer_loop:
call CalcDealerBJScore
cmp bjDealerScore, 17
jge dealer_finished
invoke RandomRange3D, 13
inc eax
mov ebx, bjDealerCardCount
cmp ebx, 8
jge dealer_finished
mov [bjDealerCards + ebx*4], eax
inc bjDealerCardCount
jmp dealer_loop
dealer_finished:
cmp bjDealerScore, 21
jle compare_scores
; Dealer Bust!
mov eax, bjBet
shl eax, 1
add bankroll, eax
invoke CopyString3D, OFFSET strDealerBust, OFFSET bjOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
mov bjState, 2
ret
compare_scores:
mov eax, bjPlayerScore
cmp eax, bjDealerScore
jle check_dealer_won
; Player Won!
mov eax, bjBet
shl eax, 1
add bankroll, eax
invoke CopyString3D, OFFSET strWin, OFFSET bjOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
mov bjState, 2
ret
check_dealer_won:
cmp eax, bjDealerScore
jl dealer_wins
; Push (Tie)
mov eax, bjBet
add bankroll, eax
invoke CopyString3D, OFFSET strPush, OFFSET bjOutcomeMsg
mov bjState, 2
ret
dealer_wins:
invoke CopyString3D, OFFSET strLose, OFFSET bjOutcomeMsg
mov bjState, 2
ret
check_bj_round_over:
invoke Pressed3D, 20h ; SPACE -> Next Hand
test ah, 80h
jz bj_input_done
mov bjState, 0
ret
check_bj_bet_change:
invoke Pressed3D, 26h ; UP
test ah, 80h
jz @F
cmp bjBet, 500
jge bj_input_done
add bjBet, 50
ret
@@:
invoke Pressed3D, 28h ; DOWN
test ah, 80h
jz bj_input_done
cmp bjBet, 50
jle bj_input_done
sub bjBet, 50
bj_input_done:
ret
HandleBlackjackInput ENDP
CalcPlayerBJScore PROC uses ebx esi
xor eax, eax
xor ebx, ebx
xor esi, esi
calc_p_loop:
cmp esi, bjPlayerCardCount
jge calc_p_done
mov edx, [bjPlayerCards + esi*4]
cmp edx, 10
jle @F
mov edx, 10
@@:
cmp edx, 1
jne add_p_val
inc ebx ; count Aces
add eax, 11
jmp next_p_card
add_p_val:
add eax, edx
next_p_card:
inc esi
jmp calc_p_loop
calc_p_done:
; Soft Ace reduction
reduce_p_ace:
cmp eax, 21
jle store_p_score
test ebx, ebx
jz store_p_score
sub eax, 10
dec ebx
jmp reduce_p_ace
store_p_score:
mov bjPlayerScore, eax
ret
CalcPlayerBJScore ENDP
CalcDealerBJScore PROC uses ebx esi
xor eax, eax
xor ebx, ebx
xor esi, esi
calc_d_loop:
cmp esi, bjDealerCardCount
jge calc_d_done
mov edx, [bjDealerCards + esi*4]
cmp edx, 10
jle @F
mov edx, 10
@@:
cmp edx, 1
jne add_d_val
inc ebx
add eax, 11
jmp next_d_card
add_d_val:
add eax, edx
next_d_card:
inc esi
jmp calc_d_loop
calc_d_done:
reduce_d_ace:
cmp eax, 21
jle store_d_score
test ebx, ebx
jz store_d_score
sub eax, 10
dec ebx
jmp reduce_d_ace
store_d_score:
mov bjDealerScore, eax
ret
CalcDealerBJScore ENDP
RenderBlackjackGame PROC uses ebx esi edi
; Emerald Felt Table Background
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 000A3015h
invoke DrawBoxBorder, 10, 10, 300, 220, 000D4018h, 00FFD700h, 3
; Dealer Area Top
invoke DrawString8x8, 25, 20, OFFSET textBJ3D, 00FFD700h
invoke DrawString8x8, 25, 35, OFFSET textDealer3D, 00FFFFFFh
invoke FormatNumber, bjDealerScore, OFFSET hudNumBuffer
invoke DrawString8x8, 120, 35, OFFSET hudNumBuffer, 00FFFF00h
; Dealer Cards
xor esi, esi
draw_dealer_cards:
cmp esi, bjDealerCardCount
jge draw_player_bj_area
mov eax, esi
imul eax, 45
add eax, 25
mov ebx, eax
cmp esi, 1
jne draw_dealer_face
cmp bjDealerHideHole, 1
jne draw_dealer_face
; Face Down Card
mov eax, selectedBack3D
mov eax, cardBackColors3D[eax*4]
invoke DrawBoxBorder, ebx, 48, 38, 52, eax, 00FFFFFFh, 2
jmp next_dealer_card_draw
draw_dealer_face:
invoke DrawBoxBorder, ebx, 48, 38, 52, 00F0F0F5h, 00000000h, 2
mov eax, [bjDealerCards + esi*4]
dec eax
imul eax, 3
lea edx, [cardRankStr + eax]
mov eax, ebx
add eax, 8
invoke DrawString8x8, eax, 68, edx, 00000000h
next_dealer_card_draw:
inc esi
jmp draw_dealer_cards
draw_player_bj_area:
; Player Area Bottom
invoke DrawString8x8, 25, 110, OFFSET textPlayer3D, 00FFFFFFh
invoke FormatNumber, bjPlayerScore, OFFSET hudNumBuffer
invoke DrawString8x8, 120, 110, OFFSET hudNumBuffer, 0050FF50h
; Player Cards
xor esi, esi
draw_player_cards:
cmp esi, bjPlayerCardCount
jge draw_bj_footer
mov eax, esi
imul eax, 45
add eax, 25
mov ebx, eax
invoke DrawBoxBorder, ebx, 124, 38, 52, 00F0F0F5h, 00000000h, 2
mov eax, [bjPlayerCards + esi*4]
dec eax
imul eax, 3
lea edx, [cardRankStr + eax]
mov eax, ebx
add eax, 8
invoke DrawString8x8, eax, 144, edx, 00000000h
inc esi
jmp draw_player_cards
draw_bj_footer:
; Footer Status & Controls
invoke DrawBoxBorder, 20, 182, 280, 42, 00102010h, 00FFD700h, 1
cmp BYTE PTR [bjOutcomeMsg], 0
je draw_bj_controls
invoke DrawString8x8, 28, 188, OFFSET bjOutcomeMsg, 00FFFF00h
invoke DrawString8x8, 28, 204, OFFSET textNext3D, 00A0A0A0h
ret
draw_bj_controls:
invoke DrawString8x8, 28, 188, OFFSET textBJKeys3D, 00FFFFFFh
invoke DrawString8x8, 28, 204, OFFSET textDeal3D, 00A0A0A0h
ret
RenderBlackjackGame ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: ROULETTE
; ==============================================================================
HandleRouletteInput PROC uses ebx
cmp roulState, 1
je roul_input_done
invoke Pressed3D, 31h ; '1' -> RED
test ah, 80h
jz @F
mov roulBetType, 1
@@:
invoke Pressed3D, 32h ; '2' -> BLACK
test ah, 80h
jz @F
mov roulBetType, 2
@@:
invoke Pressed3D, 33h ; '3' -> ZERO (0)
test ah, 80h
jz @F
mov roulBetType, 3
@@:
invoke Pressed3D, 34h ; '4' -> EVEN
test ah, 80h
jz @F
mov roulBetType, 4
@@:
invoke Pressed3D, 35h ; '5' -> ODD
test ah, 80h
jz check_roul_spin
mov roulBetType, 5
check_roul_spin:
invoke Pressed3D, 20h ; SPACE -> Spin
test ah, 80h
jz roul_input_done
mov eax, bankroll
cmp eax, roulBetAmount
jl roul_no_cash
sub eax, roulBetAmount
mov bankroll, eax
mov roulState, 1
mov roulSpinTimer, 50
mov roulPayout, 0
invoke PlayCasinoSound3D, OFFSET soundRoulette, 0, 1
ret
roul_no_cash:
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
mov flashTimer, 60
roul_input_done:
ret
HandleRouletteInput ENDP
RenderRouletteGame PROC uses ebx esi edi
; Table felt background
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00151525h
invoke DrawBoxBorder, 10, 10, 300, 220, 00201525h, 00FFD700h, 3
; 2.5D Rotating Wheel on Left
invoke DrawCircle, 85, 110, 65, 00102550h
invoke DrawCircle, 85, 110, 60, 00FFD700h
invoke DrawCircle, 85, 110, 52, 00101010h
invoke DrawCircle, 85, 110, 22, 00FFD700h ; Center brass turret
; Spinning Wheel / Ball Logic
cmp roulState, 1
jne draw_roul_ball
dec roulSpinTimer
add roulWheelAngle, 8
sub roulBallAngle, 14
cmp roulSpinTimer, 0
jg draw_roul_ball
; Wheel stopped! Determine result!
mov roulState, 2
invoke RandomRange3D, 37
mov roulWinningNum, eax
; Check bet
cmp roulBetType, 1 ; RED
jne check_ro_black
call IsNumberRed
test eax, eax
jz ro_lost
mov eax, roulBetAmount
shl eax, 1
mov roulPayout, eax
add bankroll, eax
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
jmp draw_roul_ball
check_ro_black:
cmp roulBetType, 2 ; BLACK
jne check_ro_zero
cmp roulWinningNum, 0
je ro_lost
call IsNumberRed
test eax, eax
jnz ro_lost
mov eax, roulBetAmount
shl eax, 1
mov roulPayout, eax
add bankroll, eax
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
jmp draw_roul_ball
check_ro_zero:
cmp roulBetType, 3 ; ZERO
jne check_ro_even
cmp roulWinningNum, 0
jne ro_lost
mov eax, roulBetAmount
imul eax, 36
mov roulPayout, eax
add bankroll, eax
invoke CopyString3D, OFFSET strJackpot, OFFSET roulOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundJackpot, 0, 1
jmp draw_roul_ball
check_ro_even:
cmp roulBetType, 4 ; EVEN
jne check_ro_odd
mov eax, roulWinningNum
test eax, eax
jz ro_lost
test al, 1
jnz ro_lost
mov eax, roulBetAmount
shl eax, 1
mov roulPayout, eax
add bankroll, eax
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
jmp draw_roul_ball
check_ro_odd:
mov eax, roulWinningNum
test eax, eax
jz ro_lost
test al, 1
jz ro_lost
mov eax, roulBetAmount
shl eax, 1
mov roulPayout, eax
add bankroll, eax
invoke CopyString3D, OFFSET strWin, OFFSET roulOutcomeMsg
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
jmp draw_roul_ball
ro_lost:
invoke CopyString3D, OFFSET strLose, OFFSET roulOutcomeMsg
draw_roul_ball:
; Draw White Ball on Rim
mov eax, roulBallAngle
and eax, 511
mov ebx, [tableCos + eax*4]
imul ebx, 42
sar ebx, 16
add ebx, 85
mov eax, roulBallAngle
and eax, 511
mov edx, [tableSin + eax*4]
imul edx, 42
sar edx, 16
add edx, 110
invoke DrawCircle, ebx, edx, 3, 00FFFFFFh
; Right Betting Board
invoke DrawBoxBorder, 175, 25, 125, 28, 001010C0h, 00FFFFFFh, 2 ; [1] RED
invoke DrawString8x8, 190, 35, OFFSET textRed3D, 00FFFFFFh
invoke DrawBoxBorder, 175, 60, 125, 28, 00151515h, 00FFFFFFh, 2 ; [2] BLACK
invoke DrawString8x8, 190, 70, OFFSET textBlack3D, 00FFFFFFh
invoke DrawBoxBorder, 175, 95, 125, 28, 00106010h, 00FFFFFFh, 2 ; [3] ZERO
invoke DrawString8x8, 190, 105, OFFSET textZero3D, 00FFFFFFh
invoke DrawBoxBorder, 175, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [4] EVEN
invoke DrawString8x8, 185, 139, OFFSET textEven3D, 00FFFFFFh
invoke DrawBoxBorder, 240, 130, 60, 26, 00302020h, 00FFFFFFh, 1 ; [5] ODD
invoke DrawString8x8, 250, 139, OFFSET textOdd3D, 00FFFFFFh
; Highlight Active Bet
cmp roulBetType, 1
jne @F
invoke DrawBoxBorder, 173, 23, 129, 32, 0, 00FFFF00h, 2
@@:
cmp roulBetType, 2
jne @F
invoke DrawBoxBorder, 173, 58, 129, 32, 0, 00FFFF00h, 2
@@:
cmp roulBetType, 3
jne @F
invoke DrawBoxBorder, 173, 93, 129, 32, 0, 00FFFF00h, 2
@@:
cmp roulBetType, 4
jne @F
invoke DrawBoxBorder, 173, 128, 64, 30, 0, 00FFFF00h, 2
@@:
cmp roulBetType, 5
jne draw_ro_footer
invoke DrawBoxBorder, 238, 128, 64, 30, 0, 00FFFF00h, 2
draw_ro_footer:
invoke DrawBoxBorder, 20, 180, 280, 42, 00101015h, 00FFD700h, 1
cmp roulState, 2
jne @F
invoke DrawString8x8, 28, 186, OFFSET textResult3D, 00FFD700h
invoke FormatNumber, roulWinningNum, OFFSET hudNumBuffer
invoke DrawString8x8, 85, 186, OFFSET hudNumBuffer, 00FFFF00h
invoke DrawString8x8, 130, 186, OFFSET roulOutcomeMsg, 0050FF50h
@@:
invoke DrawString8x8, 28, 202, OFFSET textSpin3D, 00A0A0A0h
ret
RenderRouletteGame ENDP
IsNumberRed PROC
mov eax, roulWinningNum
cmp eax, 1
je red_yes
cmp eax, 3
je red_yes
cmp eax, 5
je red_yes
cmp eax, 7
je red_yes
cmp eax, 9
je red_yes
cmp eax, 12
je red_yes
cmp eax, 14
je red_yes
cmp eax, 16
je red_yes
cmp eax, 18
je red_yes
cmp eax, 19
je red_yes
cmp eax, 21
je red_yes
cmp eax, 23
je red_yes
cmp eax, 25
je red_yes
cmp eax, 27
je red_yes
cmp eax, 30
je red_yes
cmp eax, 32
je red_yes
cmp eax, 34
je red_yes
cmp eax, 36
je red_yes
xor eax, eax
ret
red_yes:
mov eax, 1
ret
IsNumberRed ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: BAR & SHOP
; ==============================================================================
HandleShopInput PROC uses ebx esi
xor esi, esi
shop_choice:
inc esi
lea eax, [esi+30h]
invoke Pressed3D, eax
test eax, eax
jnz shop_chosen
cmp esi, 3
jb shop_choice
ret
shop_chosen:
bt ownedBacks3D, esi
jc shop_equip
mov ebx, 1500
cmp esi, 1
jne @F
mov ebx, 1000
@@:
cmp bankroll, ebx
jb shop_no_money
sub bankroll, ebx
bts ownedBacks3D, esi
shop_equip:
mov selectedBack3D, esi
invoke CopyString3D, OFFSET textBought3D, OFFSET shopMsg
call SaveProgress3D
ret
shop_no_money:
invoke CopyString3D, OFFSET textNoCash3D, OFFSET shopMsg
ret
HandleShopInput ENDP
RenderShopGame PROC
invoke DrawBox, 0, 0, SCREEN_W, SCREEN_H, 00150A0Ah
invoke DrawBoxBorder, 10, 10, 300, 220, 00251515h, 00FFD700h, 3
invoke DrawString8x8, 25, 20, OFFSET textShop3D, 00FFD700h
invoke DrawBoxBorder, 20, 40, 280, 32, 001A1010h, 00FFFFFFh, 1
invoke DrawString8x8, 28, 46, OFFSET textItem1_3D, 00FFFF00h
invoke DrawString8x8, 28, 58, OFFSET textShopHint3D, 00A0A0A0h
invoke DrawBoxBorder, 20, 80, 280, 32, 001A1010h, 00FFFFFFh, 1
invoke DrawString8x8, 28, 86, OFFSET textItem2_3D, 00FFFF00h
invoke DrawString8x8, 28, 98, OFFSET textShopHint3D, 00A0A0A0h
invoke DrawBoxBorder, 20, 120, 280, 32, 001A1010h, 00FFFFFFh, 1
invoke DrawString8x8, 28, 126, OFFSET textItem3_3D, 00FFFF00h
invoke DrawString8x8, 28, 138, OFFSET textShopHint3D, 00A0A0A0h
invoke DrawBoxBorder, 20, 165, 280, 55, 00100A0Ah, 00FFD700h, 1
invoke DrawString8x8, 28, 172, OFFSET textBank3D, 00FFD700h
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 110, 172, OFFSET hudNumBuffer, 00FFFF00h
cmp BYTE PTR [shopMsg], 0
je @F
invoke DrawString8x8, 28, 188, OFFSET shopMsg, 0050FF50h
@@:
invoke DrawString8x8, 28, 204, OFFSET textBack3D, 00A0A0A0h
ret
RenderShopGame ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: ATM TERMINAL
; ==============================================================================
HandleATMInput PROC
ret
HandleATMInput ENDP
RenderATMGame PROC
invoke DrawBox, 0, 0, 320, 240, 00172120h
invoke DrawString8x8, 24, 30, OFFSET textATM3D, 00D8BC6Ah
invoke DrawString8x8, 24, 70, OFFSET textBank3D, 00FFFFFFh
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 96, 70, OFFSET hudNumBuffer, 0089DAB2h
invoke DrawString8x8, 24, 115, OFFSET textATMNote3D, 00B7C8C1h
invoke DrawString8x8, 24, 140, OFFSET textATMNote2_3D, 00B7C8C1h
invoke DrawString8x8, 24, 208, OFFSET textBack3D, 00D8BC6Ah
ret
RenderATMGame ENDP
; ==============================================================================
; ==============================================================================
; ==============================================================================
; SHARED RICH UI PROCEDURES
; ==============================================================================
DrawKeycap3D PROC uses ebx esi edi, x:DWORD, y:DWORD, strPtr:DWORD, isActive:DWORD
local keyW:DWORD
mov esi, strPtr
xor ecx, ecx
keycap_len:
mov al, [esi+ecx]
test al, al
jz keycap_len_done
inc ecx
jmp keycap_len
keycap_len_done:
shl ecx, 3
add ecx, 8
mov keyW, ecx
; Drop shadow
mov eax, y
add eax, 2
invoke DrawBox, x, eax, keyW, 13, 0008080Ch
; Border and Fill
cmp isActive, 0
je keycap_inactive
mov eax, 00FFFF00h ; Bright Yellow active border
mov edx, 001B4B22h ; Casino Green active fill
mov ebx, 00FFFF00h ; Bright Yellow active text
jmp keycap_draw_box
keycap_inactive:
mov eax, 00606870h ; Slate inactive border
mov edx, 001A1C22h ; Charcoal inactive fill
mov ebx, 00D0D8E0h ; Silver inactive text
keycap_draw_box:
push ebx
invoke DrawBoxBorder, x, y, keyW, 13, edx, eax, 1
pop ebx
; Text label
mov eax, x
add eax, 4
mov edx, y
add edx, 3
invoke DrawString8x8, eax, edx, strPtr, ebx
mov eax, keyW
add eax, 4
ret
DrawKeycap3D ENDP
DrawChipStack PROC uses ebx esi edi, x:DWORD, y:DWORD, chipCount:DWORD
mov edi, chipCount
xor esi, esi
chip_loop:
cmp esi, edi
jge chip_done
mov eax, esi
shl eax, 2
mov edx, y
sub edx, eax
; Shadow
mov eax, x
add eax, 2
mov ecx, edx
add ecx, 5
invoke DrawBox, eax, ecx, 20, 2, 00061004h
; Red Clay Chip body with white rim
invoke DrawBoxBorder, x, edx, 24, 6, 00B81515h, 00FFFFFFh, 1
; White stripe inlays
mov eax, x
add eax, 4
mov ecx, edx
add ecx, 1
invoke DrawBox, eax, ecx, 3, 4, 00FFFFFFh
mov eax, x
add eax, 17
mov ecx, edx
add ecx, 1
invoke DrawBox, eax, ecx, 3, 4, 00FFFFFFh
inc esi
jmp chip_loop
chip_done:
ret
DrawChipStack ENDP
DrawDetailedCoin PROC uses ebx esi edi, cxVal:DWORD, cyVal:DWORD, rxVal:DWORD, ryVal:DWORD, outerColor:DWORD, innerColor:DWORD, reliefType:DWORD
local rxSq:DWORD
local rySq:DWORD
local rxRySq:DWORD
local threshSq:DWORD
local curDy:DWORD
local curDx:DWORD
local curX:DWORD
local curY:DWORD
mov eax, rxVal
cmp eax, 0
jle coin_draw_done
mov eax, ryVal
cmp eax, 0
jle coin_draw_done
mov eax, rxVal
imul eax, rxVal
mov rxSq, eax
mov eax, ryVal
imul eax, ryVal
mov rySq, eax
imul eax, rxSq
mov rxRySq, eax
; 3/4 threshold for rim bevel
mov ecx, 3
imul eax, ecx
shr eax, 2
mov threshSq, eax
; Scan rows
mov eax, ryVal
neg eax
mov curDy, eax
coin_row_loop:
mov eax, curDy
cmp eax, ryVal
jg coin_relief_check
mov edx, cyVal
add edx, curDy
mov curY, edx
; Scan columns
mov eax, rxVal
neg eax
mov curDx, eax
coin_col_loop:
mov eax, curDx
cmp eax, rxVal
jg coin_col_next_row
mov ecx, cxVal
add ecx, curDx
mov curX, ecx
; val = dx*dx*rySq + dy*dy*rxSq
mov eax, curDx
imul eax, curDx
imul eax, rySq
mov ebx, eax
mov eax, curDy
imul eax, curDy
imul eax, rxSq
add eax, ebx
cmp eax, rxRySq
ja coin_pixel_outside
cmp eax, threshSq
jb coin_draw_inner
invoke DrawPixel, curX, curY, outerColor
jmp coin_pixel_outside
coin_draw_inner:
invoke DrawPixel, curX, curY, innerColor
coin_pixel_outside:
inc curDx
jmp coin_col_loop
coin_col_next_row:
inc curDy
jmp coin_row_loop
coin_relief_check:
cmp rxVal, 14
jl coin_draw_done
cmp reliefType, 1
je coin_draw_eagle
cmp reliefType, 2
je coin_draw_numeral
jmp coin_draw_done
coin_draw_eagle:
; Imperial Eagle relief (Dark Gold 009A7A00h / Bright 00FFD700h)
mov eax, cxVal
sub eax, 3
mov edx, cyVal
sub edx, 14
invoke DrawBox, eax, edx, 7, 2, 009A7A00h
mov eax, cxVal
sub eax, 4
mov edx, cyVal
sub edx, 12
invoke DrawBox, eax, edx, 9, 2, 009A7A00h
mov eax, cxVal
sub eax, 2
mov edx, cyVal
sub edx, 9
invoke DrawBox, eax, edx, 5, 12, 009A7A00h
mov eax, cxVal
sub eax, 1
mov edx, cyVal
sub edx, 8
invoke DrawBox, eax, edx, 3, 10, 00FFD700h
mov eax, cxVal
sub eax, 10
mov edx, cyVal
sub edx, 8
invoke DrawBox, eax, edx, 7, 3, 009A7A00h
mov eax, cxVal
sub eax, 13
mov edx, cyVal
sub edx, 5
invoke DrawBox, eax, edx, 10, 3, 009A7A00h
mov eax, cxVal
sub eax, 11
mov edx, cyVal
sub edx, 2
invoke DrawBox, eax, edx, 7, 3, 009A7A00h
mov eax, cxVal
add eax, 4
mov edx, cyVal
sub edx, 8
invoke DrawBox, eax, edx, 7, 3, 009A7A00h
mov eax, cxVal
add eax, 4
mov edx, cyVal
sub edx, 5
invoke DrawBox, eax, edx, 10, 3, 009A7A00h
mov eax, cxVal
add eax, 5
mov edx, cyVal
sub edx, 2
invoke DrawBox, eax, edx, 7, 3, 009A7A00h
mov eax, cxVal
sub eax, 4
mov edx, cyVal
add edx, 4
invoke DrawBox, eax, edx, 9, 3, 009A7A00h
mov eax, cxVal
sub eax, 3
mov edx, cyVal
add edx, 7
invoke DrawBox, eax, edx, 7, 3, 009A7A00h
jmp coin_draw_done
coin_draw_numeral:
; Roman numeral 'I' & laurel
mov eax, cxVal
sub eax, 5
mov edx, cyVal
sub edx, 10
invoke DrawBox, eax, edx, 11, 3, 009A7A00h
mov eax, cxVal
sub eax, 2
mov edx, cyVal
sub edx, 7
invoke DrawBox, eax, edx, 5, 14, 009A7A00h
mov eax, cxVal
sub eax, 1
mov edx, cyVal
sub edx, 6
invoke DrawBox, eax, edx, 3, 12, 00FFD700h
mov eax, cxVal
sub eax, 6
mov edx, cyVal
add edx, 7
invoke DrawBox, eax, edx, 13, 3, 009A7A00h
; Laurel dots
mov eax, cxVal
sub eax, 12
mov edx, cyVal
sub edx, 8
invoke DrawBox, eax, edx, 2, 2, 009A7A00h
mov eax, cxVal
add eax, 11
mov edx, cyVal
sub edx, 8
invoke DrawBox, eax, edx, 2, 2, 009A7A00h
mov eax, cxVal
sub eax, 12
mov edx, cyVal
invoke DrawBox, eax, edx, 2, 2, 009A7A00h
mov eax, cxVal
add eax, 11
mov edx, cyVal
invoke DrawBox, eax, edx, 2, 2, 009A7A00h
mov eax, cxVal
sub eax, 12
mov edx, cyVal
add edx, 8
invoke DrawBox, eax, edx, 2, 2, 009A7A00h
mov eax, cxVal
add eax, 11
mov edx, cyVal
add edx, 8
invoke DrawBox, eax, edx, 2, 2, 009A7A00h
coin_draw_done:
ret
DrawDetailedCoin ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: COIN FLIP
; ==============================================================================
InitCoinGame PROC
call InitNativeCoin3D
ret
InitCoinGame ENDP
HandleCoinInput PROC
call HandleNativeCoin3D
ret
; Retained legacy frame-count prototype, excluded from the executable.
IF 0
cmp coin3d_state, 0
je coin_handle_idle
cmp coin3d_state, 1
je coin_handle_flipping
cmp coin3d_state, 2
je coin_handle_result
ret
coin_handle_idle:
invoke Pressed3D, 26h ; UP
test eax, eax
jnz coin_bet_up
invoke Pressed3D, 57h ; 'W'
test eax, eax
jnz coin_bet_up
invoke Pressed3D, 28h ; DOWN
test eax, eax
jnz coin_bet_down
invoke Pressed3D, 53h ; 'S'
test eax, eax
jnz coin_bet_down
invoke Pressed3D, 31h ; '1'
test eax, eax
jnz coin_pick_1
invoke Pressed3D, 32h ; '2'
test eax, eax
jnz coin_pick_2
invoke Pressed3D, 20h ; SPACE
test eax, eax
jnz coin_start_flip
ret
coin_bet_up:
mov eax, coin3d_bet
add eax, 50
cmp eax, bankroll
jle @F
mov eax, bankroll
@@:
cmp eax, 5000
jle @F
mov eax, 5000
@@:
mov coin3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
coin_bet_down:
mov eax, coin3d_bet
sub eax, 50
cmp eax, 50
jge @F
mov eax, 50
@@:
mov coin3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
coin_pick_1:
mov coin3d_choice, 1
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
coin_pick_2:
mov coin3d_choice, 2
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
coin_start_flip:
mov eax, coin3d_bet
cmp eax, bankroll
jle @F
mov eax, bankroll
mov coin3d_bet, eax
test eax, eax
jz coin_done
@@:
mov eax, coin3d_bet
sub bankroll, eax
mov coin3d_state, 1
mov coin3d_timer, 40
invoke PlayCasinoSound3D, OFFSET soundCoin, 0, 1
ret
coin_handle_flipping:
dec coin3d_timer
cmp coin3d_timer, 0
jg coin_done
invoke RandomRange3D, 2
inc eax
mov coin3d_result, eax
mov edx, coin3d_choice
cmp eax, edx
jne coin_flip_lost
; Won!
inc coin3d_streak
mov eax, coin3d_bet
shl eax, 1
add bankroll, eax
mov coin3d_win, eax
mov coin3d_state, 2
invoke PlayCasinoSound3D, OFFSET soundCoinDing, 0, 1
ret
coin_flip_lost:
mov coin3d_streak, 0
mov coin3d_win, 0
mov coin3d_state, 2
invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1
ret
coin_handle_result:
invoke Pressed3D, 20h
test eax, eax
jz coin_done
mov coin3d_state, 0
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
coin_done:
ret
ENDIF
HandleCoinInput ENDP
RenderCoinGame PROC uses ebx esi edi
local cyVal:DWORD
local rxVal:DWORD
local kx:DWORD
call RenderNativeCoin3D
ret
IF 0
; Background & Cabinet border
invoke DrawBox, 0, 0, 320, 240, 00140906h
invoke DrawBoxBorder, 6, 6, 308, 228, 0022150Fh, 00482E1Bh, 3
; Header
invoke DrawBoxBorder, 20, 12, 280, 26, 001C100Ah, 00FFD700h, 2
invoke DrawString8x8, 44, 21, OFFSET textCoinTitle, 00FFFF00h
; Corner rivets
invoke DrawBox, 12, 12, 3, 3, 00FFD700h
invoke DrawBox, 306, 12, 3, 3, 00FFD700h
invoke DrawBox, 12, 226, 3, 3, 00FFD700h
invoke DrawBox, 306, 226, 3, 3, 00FFD700h
; Status meters
invoke DrawBoxBorder, 20, 44, 110, 18, 000E1A0Ah, 00224B1Ah, 1
invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawBoxBorder, 190, 44, 110, 18, 001A100Ah, 003A2814h, 1
invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h
invoke FormatNumber, coin3d_bet, OFFSET hudNumBuffer
invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h
; Left: Heads
cmp coin3d_choice, 1
jne coin_left_inactive
invoke DrawBoxBorder, 20, 72, 76, 68, 00101828h, 00FFFF00h, 2
invoke DrawString8x8, 30, 78, OFFSET textCoinSide1, 00FFFF00h
invoke DrawDetailedCoin, 58, 106, 14, 14, 00D0A000h, 00FFD700h, 1
invoke DrawString8x8, 24, 126, OFFSET textCoinSelected, 003CFF3Ch
jmp coin_right_side
coin_left_inactive:
invoke DrawBoxBorder, 20, 72, 76, 68, 000A101Ch, 00404855h, 1
invoke DrawString8x8, 30, 78, OFFSET textCoinSide1, 00D0D8E0h
invoke DrawDetailedCoin, 58, 106, 14, 14, 009A7A00h, 00D0A000h, 1
coin_right_side:
; Right: Tails
cmp coin3d_choice, 2
jne coin_right_inactive
invoke DrawBoxBorder, 224, 72, 76, 68, 00101828h, 00FFFF00h, 2
invoke DrawString8x8, 234, 78, OFFSET textCoinSide2, 00FFFF00h
invoke DrawDetailedCoin, 262, 106, 14, 14, 00D0A000h, 00FFD700h, 2
invoke DrawString8x8, 228, 126, OFFSET textCoinSelected, 003CFF3Ch
jmp coin_center_area
coin_right_inactive:
invoke DrawBoxBorder, 224, 72, 76, 68, 000A101Ch, 00404855h, 1
invoke DrawString8x8, 234, 78, OFFSET textCoinSide2, 00D0D8E0h
invoke DrawDetailedCoin, 262, 106, 14, 14, 009A7A00h, 00D0A000h, 2
coin_center_area:
; Center spotlight
invoke DrawCircle, 160, 110, 48, 00121620h
invoke DrawCircle, 160, 110, 44, 00FFD700h
invoke DrawCircle, 160, 110, 42, 000E141Eh
cmp coin3d_state, 1
je coin_render_flipping
cmp coin3d_state, 2
je coin_render_result
; Idle coin
invoke DrawDetailedCoin, 160, 110, 26, 26, 00D0A000h, 00FFD700h, coin3d_choice
jmp coin_render_keys
coin_render_flipping:
mov eax, coin3d_timer
and eax, 7
movzx eax, byte ptr [coinRxAnimTable + eax]
mov rxVal, eax
invoke DrawDetailedCoin, 160, 110, rxVal, 26, 00D0A000h, 00FFD700h, 0
invoke DrawString8x8, 88, 160, OFFSET textCoinFlipping, 00FFFF00h
jmp coin_render_keys
coin_render_result:
invoke DrawDetailedCoin, 160, 110, 26, 26, 00D0A000h, 00FFD700h, coin3d_result
mov eax, coin3d_result
cmp eax, coin3d_choice
jne coin_render_loss_msg
; Win banner
invoke DrawBoxBorder, 44, 154, 232, 22, 000E141Eh, 003CFF3Ch, 1
invoke DrawString8x8, 64, 161, OFFSET textCoinWin, 003CFF3Ch
invoke FormatNumber, coin3d_win, OFFSET hudNumBuffer
invoke DrawString8x8, 152, 161, OFFSET hudNumBuffer, 003CFF3Ch
jmp coin_render_keys
coin_render_loss_msg:
invoke DrawBoxBorder, 44, 154, 232, 22, 000E141Eh, 00C81414h, 1
invoke DrawString8x8, 114, 161, OFFSET textCoinLose, 00FF6464h
coin_render_keys:
mov kx, 16
xor eax, eax
cmp coin3d_choice, 1
sete al
invoke DrawKeycap3D, kx, 192, OFFSET textCoinKey1, eax
add kx, eax
xor eax, eax
cmp coin3d_choice, 2
sete al
invoke DrawKeycap3D, kx, 192, OFFSET textCoinKey2, eax
add kx, eax
invoke DrawKeycap3D, kx, 192, OFFSET textCoinKeySpace, 1
add kx, eax
invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0
ret
ENDIF
RenderCoinGame ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: CRAPS / DICE
; ==============================================================================
DrawCrapsDie PROC uses ebx esi edi, x:DWORD, y:DWORD, sizeVal:DWORD, valNum:DWORD
; Drop shadow
mov eax, x
add eax, 3
mov edx, y
add edx, sizeVal
invoke DrawBox, eax, edx, sizeVal, 3, 00081403h
mov eax, x
add eax, sizeVal
mov edx, y
add edx, 3
invoke DrawBox, eax, edx, 3, sizeVal, 00081403h
; Ivory body & bevel
invoke DrawBoxBorder, x, y, sizeVal, sizeVal, 00FAF4F0h, 00403535h, 1
mov eax, x
inc eax
mov edx, y
inc edx
mov ecx, sizeVal
sub ecx, 2
invoke DrawBox, eax, edx, ecx, 1, 00FFFFFFh
invoke DrawBox, eax, edx, 1, ecx, 00FFFFFFh
; Ruby pips (00C81515h)
mov eax, valNum
test al, 1
jz @F
; Center pip
mov eax, x
add eax, 18
mov edx, y
add edx, 18
invoke DrawCircle, eax, edx, 3, 00C81515h
dec eax
dec edx
invoke DrawPixel, eax, edx, 00FFFFFFh
@@:
cmp valNum, 2
jl die_pips_done
mov eax, x
add eax, 9
mov edx, y
add edx, 9
invoke DrawCircle, eax, edx, 3, 00C81515h
mov eax, x
add eax, 27
mov edx, y
add edx, 27
invoke DrawCircle, eax, edx, 3, 00C81515h
cmp valNum, 4
jl die_pips_done
mov eax, x
add eax, 27
mov edx, y
add edx, 9
invoke DrawCircle, eax, edx, 3, 00C81515h
mov eax, x
add eax, 9
mov edx, y
add edx, 27
invoke DrawCircle, eax, edx, 3, 00C81515h
cmp valNum, 6
jl die_pips_done
mov eax, x
add eax, 9
mov edx, y
add edx, 18
invoke DrawCircle, eax, edx, 3, 00C81515h
mov eax, x
add eax, 27
mov edx, y
add edx, 18
invoke DrawCircle, eax, edx, 3, 00C81515h
die_pips_done:
ret
DrawCrapsDie ENDP
InitDiceGame PROC
mov dice3d_state, 0
mov dice3d_timer, 0
mov dice3d_win, 0
ret
InitDiceGame ENDP
HandleDiceInput PROC
cmp dice3d_state, 0
je dice_handle_idle
cmp dice3d_state, 1
je dice_handle_rolling
cmp dice3d_state, 2
je dice_handle_result
ret
dice_handle_idle:
invoke Pressed3D, 26h ; UP
test eax, eax
jnz dice_bet_up
invoke Pressed3D, 57h ; 'W'
test eax, eax
jnz dice_bet_up
invoke Pressed3D, 28h ; DOWN
test eax, eax
jnz dice_bet_down
invoke Pressed3D, 53h ; 'S'
test eax, eax
jnz dice_bet_down
invoke Pressed3D, 31h ; '1'
test eax, eax
jnz dice_pick_1
invoke Pressed3D, 32h ; '2'
test eax, eax
jnz dice_pick_2
invoke Pressed3D, 20h ; SPACE
test eax, eax
jnz dice_start_roll
ret
dice_bet_up:
mov eax, dice3d_bet
add eax, 50
cmp eax, bankroll
jle @F
mov eax, bankroll
@@:
cmp eax, 5000
jle @F
mov eax, 5000
@@:
mov dice3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
dice_bet_down:
mov eax, dice3d_bet
sub eax, 50
cmp eax, 50
jge @F
mov eax, 50
@@:
mov dice3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
dice_pick_1:
mov dice3d_choice, 1
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
dice_pick_2:
mov dice3d_choice, 2
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
dice_start_roll:
mov eax, dice3d_bet
cmp eax, bankroll
jle @F
mov eax, bankroll
mov dice3d_bet, eax
test eax, eax
jz dice_done
@@:
mov eax, dice3d_bet
test eax, eax
jle dice_done
sub bankroll, eax
mov dice3d_state, 1
mov dice3d_timer, 0
invoke RandomRange3D, 6
inc eax
mov dice3d_val1, eax
invoke RandomRange3D, 6
inc eax
mov dice3d_val2, eax
invoke PlayCasinoSound3D, OFFSET soundDiceRoll, 0, 1
call SaveProgress3D
ret
dice_handle_rolling:
mov eax, deltaTime3D
add dice3d_timer, eax
cmp dice3d_timer, 1600
jb dice_done
mov dice3d_timer, 1600
mov eax, dice3d_val2
mov edx, dice3d_val1
add edx, eax
mov dice3d_sum, edx
; Parity check
mov eax, edx
and eax, 1
jnz dice_sum_is_odd
; Even
mov eax, 1
jmp dice_check_win
dice_sum_is_odd:
mov eax, 2
dice_check_win:
cmp eax, dice3d_choice
jne dice_roll_lost
; Won!
mov eax, dice3d_bet
shl eax, 1
add bankroll, eax
mov dice3d_win, eax
mov dice3d_state, 2
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
invoke NpcRecordRound3D,8,1
call SaveProgress3D
ret
dice_roll_lost:
mov dice3d_win, 0
mov dice3d_state, 2
invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1
invoke NpcRecordRound3D,8,0
call SaveProgress3D
ret
dice_handle_result:
invoke Pressed3D, 20h
test eax, eax
jz dice_done
mov dice3d_state, 0
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
dice_done:
ret
HandleDiceInput ENDP
RenderDiceGame PROC uses ebx esi edi
local kx:DWORD
; Mahogany frame & Deep Felt Green table
invoke DrawBox, 0, 0, 320, 240, 00140906h
invoke DrawBoxBorder, 6, 6, 308, 228, 000A3816h, 00FFD700h, 2
; Header
invoke DrawBoxBorder, 20, 12, 280, 26, 00072E13h, 00FFD700h, 2
invoke DrawString8x8, 116, 21, OFFSET textDiceTitle, 00FFFF00h
; Status
invoke DrawBoxBorder, 20, 44, 110, 18, 00072E13h, 001B4B22h, 1
invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawBoxBorder, 190, 44, 110, 18, 00072E13h, 001B4B22h, 1
invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h
invoke FormatNumber, dice3d_bet, OFFSET hudNumBuffer
invoke DrawString8x8, 258, 49, OFFSET hudNumBuffer, 00FFD700h
; [1] ר<>
cmp dice3d_choice, 1
jne dice_even_inactive
invoke DrawBoxBorder, 16, 70, 88, 48, 00072E13h, 00FFFF00h, 2
invoke DrawString8x8, 30, 76, OFFSET textDiceEven, 00FFFF00h
invoke DrawString8x8, 22, 90, OFFSET textDiceEvenNums, 00FFD700h
invoke DrawString8x8, 26, 104, OFFSET textCoinSelected, 003CFF3Ch
jmp dice_odd_side
dice_even_inactive:
invoke DrawBoxBorder, 16, 70, 88, 48, 00072E13h, 001B4B22h, 1
invoke DrawString8x8, 30, 76, OFFSET textDiceEven, 00D0D8E0h
invoke DrawString8x8, 22, 90, OFFSET textDiceEvenNums, 0080B090h
dice_odd_side:
; [2] <20><><EFBFBD><EFBFBD><EFBFBD>
cmp dice3d_choice, 2
jne dice_odd_inactive
invoke DrawBoxBorder, 216, 70, 88, 48, 00072E13h, 00FFFF00h, 2
invoke DrawString8x8, 226, 76, OFFSET textDiceOdd, 00FFFF00h
invoke DrawString8x8, 224, 90, OFFSET textDiceOddNums, 00FFD700h
invoke DrawString8x8, 226, 104, OFFSET textCoinSelected, 003CFF3Ch
jmp dice_center_cubes
dice_odd_inactive:
invoke DrawBoxBorder, 216, 70, 88, 48, 00072E13h, 001B4B22h, 1
invoke DrawString8x8, 226, 76, OFFSET textDiceOdd, 00D0D8E0h
invoke DrawString8x8, 224, 90, OFFSET textDiceOddNums, 0080B090h
dice_center_cubes:
call RenderDiceThrow3D
cmp dice3d_state, 1
je dice_render_rolling
cmp dice3d_state, 2
je dice_render_result
jmp dice_render_keys
dice_render_rolling:
invoke DrawString8x8, 76, 138, OFFSET textDiceRolling, 00FFFF00h
jmp dice_render_keys
dice_render_result:
invoke DrawBoxBorder, 36, 130, 248, 36, 00072E13h, 00FFD700h, 1
invoke DrawString8x8, 44, 135, OFFSET textDiceSumHdr, 00FFD700h
invoke FormatNumber, dice3d_val1, OFFSET hudNumBuffer
invoke DrawString8x8, 92, 135, OFFSET hudNumBuffer, 00FFFF00h
invoke DrawString8x8, 110, 135, OFFSET textDicePlus, 00FFD700h
invoke FormatNumber, dice3d_val2, OFFSET hudNumBuffer
invoke DrawString8x8, 126, 135, OFFSET hudNumBuffer, 00FFFF00h
invoke DrawString8x8, 144, 135, OFFSET textDiceEqual, 00FFD700h
invoke FormatNumber, dice3d_sum, OFFSET hudNumBuffer
invoke DrawString8x8, 168, 135, OFFSET hudNumBuffer, 00FFFF00h
mov eax, dice3d_sum
and eax, 1
jnz dice_render_odd_res
invoke DrawString8x8, 186, 135, OFFSET textDiceEvenResult, 003CFF3Ch
jmp dice_render_outcome
dice_render_odd_res:
invoke DrawString8x8, 186, 135, OFFSET textDiceOddResult, 003CFF3Ch
dice_render_outcome:
mov eax, dice3d_win
test eax, eax
jz dice_render_loss_outcome
invoke DrawString8x8, 68, 150, OFFSET textDiceWin, 003CFF3Ch
invoke FormatNumber, dice3d_win, OFFSET hudNumBuffer
invoke DrawString8x8, 156, 150, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawString8x8, 188, 150, OFFSET textDiceWinMult, 003CFF3Ch
jmp dice_render_keys
dice_render_loss_outcome:
invoke DrawString8x8, 116, 150, OFFSET textDiceLose, 00FF6464h
dice_render_keys:
mov kx, 16
xor eax, eax
cmp dice3d_choice, 1
sete al
invoke DrawKeycap3D, kx, 192, OFFSET textDiceKey1, eax
add kx, eax
xor eax, eax
cmp dice3d_choice, 2
sete al
invoke DrawKeycap3D, kx, 192, OFFSET textDiceKey2, eax
add kx, eax
invoke DrawKeycap3D, kx, 192, OFFSET textDiceKeySpace, 1
add kx, eax
invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0
ret
RenderDiceGame ENDP
; ==============================================================================
; IN-ENGINE 2.5D MINI-GAME: SKULLS & CUPS (<28><>Ϩ<EFBFBD><CFA8><EFBFBD><EFBFBD><EFBFBD>)
; ==============================================================================
DrawGlowingOrb PROC uses ebx esi edi, cxVal:DWORD, cyVal:DWORD
invoke DrawCircle, cxVal, cyVal, 14, 002E1E08h
invoke DrawCircle, cxVal, cyVal, 11, 00583A10h
invoke DrawCircle, cxVal, cyVal, 8, 008A581Ah
invoke DrawCircle, cxVal, cyVal, 6, 00D0B000h
invoke DrawCircle, cxVal, cyVal, 4, 00FFE000h
mov eax, cxVal
dec eax
mov edx, cyVal
dec edx
invoke DrawCircle, eax, edx, 2, 00FFFF80h
dec eax
dec edx
invoke DrawPixel, eax, edx, 00FFFFFFh
ret
DrawGlowingOrb ENDP
DrawGothicCup PROC uses ebx esi edi, x:DWORD, y:DWORD, cupId:DWORD, isLifted:DWORD, hasBall:DWORD
local liftY:DWORD
mov eax, y
cmp isLifted, 0
je @F
sub eax, 36
@@:
mov liftY, eax
; Drop shadow
cmp isLifted, 0
jne cup_shadow_lifted
mov eax, x
add eax, 6
mov edx, y
add edx, 42
invoke DrawBox, eax, edx, 36, 4, 0010040Ah
jmp cup_ball_check
cup_shadow_lifted:
mov eax, x
add eax, 10
mov edx, y
add edx, 42
invoke DrawBox, eax, edx, 28, 2, 001A0612h
cup_ball_check:
cmp isLifted, 0
je cup_body_draw
cmp hasBall, 0
je cup_body_draw
mov eax, x
add eax, 24
mov edx, y
add edx, 26
invoke DrawGlowingOrb, eax, edx
cup_body_draw:
; Base pedestal
mov eax, x
add eax, 6
mov edx, liftY
add edx, 36
invoke DrawBoxBorder, eax, edx, 36, 6, 00301A22h, 00D0B000h, 1
; Stem
mov eax, x
add eax, 18
mov edx, liftY
add edx, 28
invoke DrawBox, eax, edx, 12, 8, 00452533h
mov eax, x
add eax, 22
invoke DrawBox, eax, edx, 4, 8, 006E4055h
; Goblet Bowl
mov eax, x
add eax, 8
mov edx, liftY
add edx, 8
invoke DrawBoxBorder, eax, edx, 32, 20, 00401E2Dh, 00FFD700h, 1
mov eax, x
add eax, 14
mov edx, liftY
add edx, 10
invoke DrawBox, eax, edx, 6, 16, 00703550h
mov eax, x
add eax, 17
invoke DrawBox, eax, edx, 3, 16, 00A05078h
; Golden Rim
mov eax, x
add eax, 4
mov edx, liftY
add edx, 2
invoke DrawBoxBorder, eax, edx, 40, 7, 00200A15h, 00FFFF00h, 1
mov eax, x
add eax, 12
mov edx, liftY
add edx, 4
invoke DrawBox, eax, edx, 16, 2, 00FFFF00h
; Skull face emblem
mov eax, x
add eax, 21
mov edx, liftY
add edx, 12
invoke DrawBox, eax, edx, 6, 5, 00FFD700h
mov eax, x
add eax, 22
mov edx, liftY
add edx, 17
invoke DrawBox, eax, edx, 4, 3, 00FFD700h
mov eax, x
add eax, 22
mov edx, liftY
add edx, 14
invoke DrawPixel, eax, edx, 00200A15h
mov eax, x
add eax, 24
invoke DrawPixel, eax, edx, 00200A15h
; Cup number label
mov eax, x
add eax, 21
mov edx, liftY
add edx, 24
mov ecx, cupId
add ecx, '1'
invoke DrawChar8x8, eax, edx, ecx, 00FFFF00h
ret
DrawGothicCup ENDP
InitSkullsGame PROC
mov skulls3d_state, 0
mov skulls3d_timer, 0
mov skulls3d_win, 0
mov skulls3d_choice, 1
mov skulls3d_cup0, 0
mov skulls3d_cup1, 1
mov skulls3d_cup2, 2
invoke RandomRange3D, 3
mov skulls3d_ballPos, eax
ret
InitSkullsGame ENDP
FinalizeSkullsGuess PROC uses ebx
cmp skulls3d_state,3
jne skulls_guess_done
mov eax, skulls3d_choice
cmp eax, skulls3d_ballPos
jne skulls_guess_wrong
; Correct! 3x payout
mov eax, skulls3d_bet
imul eax, 3
add bankroll, eax
mov skulls3d_win, eax
mov skulls3d_state, 4
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
invoke NpcRecordRound3D,9,1
call SaveProgress3D
ret
skulls_guess_wrong:
mov skulls3d_win, 0
mov skulls3d_state, 4
invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1
invoke NpcRecordRound3D,9,0
call SaveProgress3D
skulls_guess_done:
ret
FinalizeSkullsGuess ENDP
HandleSkullsInput PROC
cmp skulls3d_state, 0
je skulls_handle_idle
cmp skulls3d_state, 1
je skulls_handle_show
cmp skulls3d_state, 2
je skulls_handle_shuffle
cmp skulls3d_state, 3
je skulls_handle_pick
cmp skulls3d_state, 4
je skulls_handle_reveal
ret
skulls_handle_idle:
invoke Pressed3D, 26h ; UP
test eax, eax
jnz skulls_bet_up
invoke Pressed3D, 57h ; 'W'
test eax, eax
jnz skulls_bet_up
invoke Pressed3D, 28h ; DOWN
test eax, eax
jnz skulls_bet_down
invoke Pressed3D, 53h ; 'S'
test eax, eax
jnz skulls_bet_down
invoke Pressed3D, 20h ; SPACE
test eax, eax
jnz skulls_start_game
ret
skulls_bet_up:
mov eax, skulls3d_bet
add eax, 50
cmp eax, bankroll
jle @F
mov eax, bankroll
@@:
cmp eax, 5000
jle @F
mov eax, 5000
@@:
mov skulls3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
skulls_bet_down:
mov eax, skulls3d_bet
sub eax, 50
cmp eax, 50
jge @F
mov eax, 50
@@:
mov skulls3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
skulls_start_game:
mov eax, skulls3d_bet
cmp eax, bankroll
jle @F
mov eax, bankroll
mov skulls3d_bet, eax
test eax, eax
jz skulls_input_done
@@:
mov eax, skulls3d_bet
sub bankroll, eax
invoke RandomRange3D, 3
mov skulls3d_ballPos, eax
mov skulls3d_cup0, 0
mov skulls3d_cup1, 1
mov skulls3d_cup2, 2
; Pre-generate 3 dynamic swap pairs
invoke RandomRange3D, 3
mov skulls3d_swapPair0, eax
invoke RandomRange3D, 3
mov skulls3d_swapPair1, eax
invoke RandomRange3D, 3
mov skulls3d_swapPair2, eax
mov skulls3d_state, 1
mov skulls3d_timer, 0
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
skulls_handle_show:
inc skulls3d_timer
cmp skulls3d_timer, 45
jl skulls_input_done
; Transition to Phase 2: Active Shuffle Animation
mov skulls3d_state, 2
mov skulls3d_timer, 0
invoke PlayCasinoSound3D, OFFSET soundShuffle, 0, 1
ret
skulls_handle_shuffle:
inc skulls3d_timer
cmp skulls3d_timer, 60
jl skulls_input_done
; Transition to Phase 3: Pick cup
mov skulls3d_state, 3
mov skulls3d_timer, 0
ret
skulls_handle_pick:
invoke Pressed3D, 31h ; '1'
test eax, eax
jnz skulls_pick_1
invoke Pressed3D, 32h ; '2'
test eax, eax
jnz skulls_pick_2
invoke Pressed3D, 33h ; '3'
test eax, eax
jnz skulls_pick_3
ret
skulls_pick_1:
mov skulls3d_choice, 0
call FinalizeSkullsGuess
ret
skulls_pick_2:
mov skulls3d_choice, 1
call FinalizeSkullsGuess
ret
skulls_pick_3:
mov skulls3d_choice, 2
call FinalizeSkullsGuess
ret
skulls_handle_reveal:
invoke Pressed3D, 20h
test eax, eax
jz skulls_input_done
mov skulls3d_state, 0
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
skulls_input_done:
ret
HandleSkullsInput ENDP
RenderSkullsGame PROC uses ebx esi edi
local kx:DWORD
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
; Mahogany & Gothic Purple table
invoke DrawBox, 0, 0, 320, 240, 00140906h
invoke DrawBoxBorder, 6, 6, 308, 228, 00300F22h, 00FFD700h, 2
; Header
invoke DrawBoxBorder, 20, 12, 280, 26, 001A0812h, 00FFD700h, 2
invoke DrawString8x8, 44, 21, OFFSET textSkullsTitle, 00FFFF00h
; Status
invoke DrawBoxBorder, 20, 44, 110, 18, 001A0812h, 00452033h, 1
invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawBoxBorder, 190, 44, 110, 18, 001A0812h, 00452033h, 1
invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h
invoke FormatNumber, skulls3d_bet, OFFSET hudNumBuffer
invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h
; Phase Prompts
cmp skulls3d_state, 0
jne @F
invoke DrawString8x8, 56, 62, OFFSET textSkullsPhase0, 00FFD700h
jmp skulls_draw_idle_cups
@@:
cmp skulls3d_state, 1
jne @F
invoke DrawString8x8, 56, 62, OFFSET textSkullsPhase1, 00FFFF00h
jmp skulls_draw_phase1_cups
@@:
cmp skulls3d_state, 2
jne @F
invoke DrawString8x8, 44, 62, OFFSET textSkullsPhase2, 00FFFF00h
jmp skulls_draw_animated_cups
@@:
cmp skulls3d_state, 3
jne @F
invoke DrawString8x8, 28, 62, OFFSET textSkullsPhase3, 00FFFF00h
jmp skulls_draw_idle_cups
@@:
; Phase 4: Reveal outcome
mov eax, skulls3d_win
test eax, eax
jz skulls_reveal_loss_text
invoke DrawString8x8, 40, 62, OFFSET textSkullsWin, 003CFF3Ch
invoke FormatNumber, skulls3d_win, OFFSET hudNumBuffer
invoke DrawString8x8, 136, 62, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawString8x8, 168, 62, OFFSET textSkullsWinMult, 003CFF3Ch
jmp skulls_draw_reveal_cups
skulls_reveal_loss_text:
invoke DrawString8x8, 40, 62, OFFSET textSkullsLose, 00FF6464h
jmp skulls_draw_reveal_cups
skulls_draw_idle_cups:
; Draw resting cups at static slots: Slot 0 (X=36), Slot 1 (X=136), Slot 2 (X=236)
invoke DrawGothicCup, 36, 114, skulls3d_cup0, 0, 0
invoke DrawGothicCup, 136, 114, skulls3d_cup1, 0, 0
invoke DrawGothicCup, 236, 114, skulls3d_cup2, 0, 0
jmp skulls_render_controls
skulls_draw_phase1_cups:
; Draw with golden ball showing under starting cup
mov ebx, 0
mov edx, 0
cmp skulls3d_ballPos, 0
jne @F
mov ebx, 1
mov edx, 1
@@:
invoke DrawGothicCup, 36, 114, skulls3d_cup0, ebx, edx
mov ebx, 0
mov edx, 0
cmp skulls3d_ballPos, 1
jne @F
mov ebx, 1
mov edx, 1
@@:
invoke DrawGothicCup, 136, 114, skulls3d_cup1, ebx, edx
mov ebx, 0
mov edx, 0
cmp skulls3d_ballPos, 2
jne @F
mov ebx, 1
mov edx, 1
@@:
invoke DrawGothicCup, 236, 114, skulls3d_cup2, ebx, edx
jmp skulls_render_controls
skulls_draw_animated_cups:
; 60 frames = 3 passes of 20 frames
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
pass_0:
dec eax
mov passTick, eax
mov eax, skulls3d_swapPair0
mov curPair, eax
jmp setup_pass
pass_1:
sub eax, 21
mov passTick, eax
mov eax, skulls3d_swapPair1
mov curPair, eax
setup_pass:
; curPair determines swap pair:
; 0: swap slot 0 (X=36) and slot 1 (X=136)
; 1: swap slot 1 (X=136) and slot 2 (X=236)
; 2: swap slot 0 (X=36) and slot 2 (X=236)
cmp curPair, 1
je pair_1
cmp curPair, 2
je pair_2
mov swapSlotA, 0
mov swapSlotB, 1
mov xA, 36
mov xB, 136
jmp calc_coords
pair_1:
mov swapSlotA, 1
mov swapSlotB, 2
mov xA, 136
mov xB, 236
jmp calc_coords
pair_2:
mov swapSlotA, 0
mov swapSlotB, 2
mov xA, 36
mov xB, 236
calc_coords:
; distX = xB - xA
mov eax, xB
sub eax, xA
mov distX, eax
; dxVal = (distX * passTick) / 20
mov eax, distX
imul eax, passTick
xor edx, edx
mov ecx, 20
div ecx
mov dxVal, eax
; curXA = xA + dxVal
mov eax, xA
add eax, dxVal
mov curXA, eax
; curXB = xB - dxVal
mov eax, xB
sub eax, dxVal
mov curXB, eax
; archY = (passTick * (20 - passTick)) / 10
mov eax, passTick
mov ecx, 20
sub ecx, eax
imul eax, ecx
xor edx, edx
mov ecx, 10
div ecx
mov archY, eax
; Cup A hops UP: 114 - archY
mov eax, 114
sub eax, archY
mov curYA, eax
; Cup B hops DOWN: 114 + archY
mov eax, 114
add eax, archY
mov curYB, eax
; Check if pass ended (frame 19): swap ball position and cups
cmp passTick, 19
jne draw_active_shuffle
; Swap ball position if involved
mov eax, skulls3d_ballPos
cmp eax, swapSlotA
jne check_ball_b
mov edx, swapSlotB
mov skulls3d_ballPos, edx
jmp swap_slot_identities
check_ball_b:
cmp eax, swapSlotB
jne swap_slot_identities
mov edx, swapSlotA
mov skulls3d_ballPos, edx
swap_slot_identities:
cmp curPair, 1
je swap_ids_1_2
cmp curPair, 2
je swap_ids_0_2
; swap 0 and 1
mov eax, skulls3d_cup0
xchg eax, skulls3d_cup1
mov skulls3d_cup0, eax
jmp swap_sound_tick
swap_ids_1_2:
mov eax, skulls3d_cup1
xchg eax, skulls3d_cup2
mov skulls3d_cup1, eax
jmp swap_sound_tick
swap_ids_0_2:
mov eax, skulls3d_cup0
xchg eax, skulls3d_cup2
mov skulls3d_cup0, eax
swap_sound_tick:
invoke PlayCasinoSound3D, OFFSET soundShuffle, 0, 1
draw_active_shuffle:
; Draw stationary cup
cmp curPair, 1
je draw_stat_cup0
cmp curPair, 2
je draw_stat_cup1
; Stationary cup is slot 2 (X=236)
invoke DrawGothicCup, 236, 114, skulls3d_cup2, 0, 0
jmp draw_moving_cups
draw_stat_cup0:
; Stationary cup is slot 0 (X=36)
invoke DrawGothicCup, 36, 114, skulls3d_cup0, 0, 0
jmp draw_moving_cups
draw_stat_cup1:
; Stationary cup is slot 1 (X=136)
invoke DrawGothicCup, 136, 114, skulls3d_cup1, 0, 0
draw_moving_cups:
; Moving Cup A and Moving Cup B
cmp curPair, 1
je ids_pair_1
cmp curPair, 2
je ids_pair_2
mov eax, skulls3d_cup0
mov ebx, skulls3d_cup1
jmp draw_the_pair
ids_pair_1:
mov eax, skulls3d_cup1
mov ebx, skulls3d_cup2
jmp draw_the_pair
ids_pair_2:
mov eax, skulls3d_cup0
mov ebx, skulls3d_cup2
draw_the_pair:
push ebx
invoke DrawGothicCup, curXA, curYA, eax, 0, 0
pop ebx
invoke DrawGothicCup, curXB, curYB, ebx, 0, 0
jmp skulls_render_controls
skulls_draw_reveal_cups:
; Reveal Phase: lift chosen cup and lift actual ball cup if different
; Slot 0
mov ebx, 0
mov edx, 0
cmp skulls3d_choice, 0
je slot0_is_lifted
cmp skulls3d_ballPos, 0
jne @F
slot0_is_lifted:
mov ebx, 1
cmp skulls3d_ballPos, 0
sete dl
@@:
invoke DrawGothicCup, 36, 114, skulls3d_cup0, ebx, edx
; Slot 1
mov ebx, 0
mov edx, 0
cmp skulls3d_choice, 1
je slot1_is_lifted
cmp skulls3d_ballPos, 1
jne @F
slot1_is_lifted:
mov ebx, 1
cmp skulls3d_ballPos, 1
sete dl
@@:
invoke DrawGothicCup, 136, 114, skulls3d_cup1, ebx, edx
; Slot 2
mov ebx, 0
mov edx, 0
cmp skulls3d_choice, 2
je slot2_is_lifted
cmp skulls3d_ballPos, 2
jne @F
slot2_is_lifted:
mov ebx, 1
cmp skulls3d_ballPos, 2
sete dl
@@:
invoke DrawGothicCup, 236, 114, skulls3d_cup2, ebx, edx
skulls_render_controls:
; Cup selection slot labels [1], [2], [3]
invoke DrawString8x8, 54, 168, OFFSET textSkullsKey1, 00D0D8E0h
invoke DrawString8x8, 150, 168, OFFSET textSkullsKey2, 00D0D8E0h
invoke DrawString8x8, 250, 168, OFFSET textSkullsKey3, 00D0D8E0h
; Keycaps
mov kx, 16
xor eax, eax
cmp skulls3d_state, 3
je key1_active
cmp skulls3d_choice, 0
sete al
jmp draw_key1
key1_active:
mov eax, 1
draw_key1:
invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey1, eax
add kx, eax
xor eax, eax
cmp skulls3d_state, 3
je key2_active
cmp skulls3d_choice, 1
sete al
jmp draw_key2
key2_active:
mov eax, 1
draw_key2:
invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey2, eax
add kx, eax
xor eax, eax
cmp skulls3d_state, 3
je key3_active
cmp skulls3d_choice, 2
sete al
jmp draw_key3
key3_active:
mov eax, 1
draw_key3:
invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKey3, eax
add kx, eax
xor eax, eax
cmp skulls3d_state, 0
je start_active
cmp skulls3d_state, 4
je start_active
jmp draw_start_key
start_active:
mov eax, 1
draw_start_key:
invoke DrawKeycap3D, kx, 192, OFFSET textSkullsKeySpace, eax
add kx, eax
invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0
ret
RenderSkullsGame ENDP
InitSkillGame PROC
mov skill3d_state, 0
mov skill3d_timer, 0
mov skill3d_hits, 0
mov skill3d_misses, 0
mov skill3d_needle, 55
mov skill3d_speed, 4
mov skill3d_dir, 1
mov skill3d_last_result, 0
mov skill3d_win_amount, 0
; Randomize initial zone: 80 + RandomRange(90) -> 80..170
invoke RandomRange3D, 90
add eax, 80
mov skill3d_zone_start, eax
; Great zone: start + 20 + RandomRange(12)
invoke RandomRange3D, 12
add eax, skill3d_zone_start
add eax, 20
mov skill3d_great_start, eax
ret
InitSkillGame ENDP
HandleSkillInput PROC uses ebx esi
mov eax, skill3d_state
cmp eax, 0
je skill_handle_ready
cmp eax, 1
je skill_handle_active
cmp eax, 2
je skill_handle_round_wait
cmp eax, 3
je skill_handle_round_wait
cmp eax, 4
je skill_handle_end_wait
cmp eax, 5
je skill_handle_end_wait
ret
skill_handle_ready:
invoke Pressed3D, 26h ; UP
test eax, eax
jnz skill_bet_up
invoke Pressed3D, 57h ; 'W'
test eax, eax
jnz skill_bet_up
invoke Pressed3D, 28h ; DOWN
test eax, eax
jnz skill_bet_down
invoke Pressed3D, 53h ; 'S'
test eax, eax
jnz skill_bet_down
jmp skill_check_start
skill_bet_up:
mov eax, skill3d_bet
add eax, 50
cmp eax, bankroll
jle @F
mov eax, bankroll
@@:
cmp eax, 5000
jle @F
mov eax, 5000
@@:
mov skill3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
skill_bet_down:
mov eax, skill3d_bet
sub eax, 50
cmp eax, 50
jge @F
mov eax, 50
@@:
mov skill3d_bet, eax
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
skill_check_start:
invoke Pressed3D, 20h ; SPACE
test eax, eax
jz skill_input_done
; Deduct bet on game start if beginning of run
mov eax, skill3d_hits
or eax, skill3d_misses
jnz @F
mov eax, skill3d_bet
cmp eax, bankroll
jle skill_has_funds
mov eax, bankroll
mov skill3d_bet, eax
test eax, eax
jz skill_input_done
skill_has_funds:
mov eax, skill3d_bet
sub bankroll, eax
@@:
mov skill3d_state, 1
mov skill3d_needle, 55
mov skill3d_dir, 1
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
skill_handle_active:
; Move needle smoothly
mov eax, skill3d_needle
mov edx, skill3d_speed
cmp skill3d_dir, 1
je skill_move_right
sub eax, edx
cmp eax, 52
jge skill_update_needle
mov eax, 52
mov skill3d_dir, 1
jmp skill_update_needle
skill_move_right:
add eax, edx
cmp eax, 268
jle skill_update_needle
mov eax, 268
mov skill3d_dir, -1
skill_update_needle:
mov skill3d_needle, eax
; Check SPACE pressed (Reaction Hit Attempt!)
invoke Pressed3D, 20h
test eax, eax
jz skill_input_done
; Is needle in Great Sweet Spot?
mov eax, skill3d_needle
mov edx, skill3d_great_start
cmp eax, edx
jl check_success_zone
add edx, skill3d_great_width
cmp eax, edx
jg check_success_zone
; GREAT HIT!
mov skill3d_last_result, 2
add skill3d_hits, 2
mov skill3d_state, 2
mov skill3d_timer, 40
invoke PlayCasinoSound3D, OFFSET soundSkillPerfect, 0, 1
jmp skill_check_finish_round
check_success_zone:
mov eax, skill3d_needle
mov edx, skill3d_zone_start
cmp eax, edx
jl skill_was_miss
add edx, skill3d_zone_width
cmp eax, edx
jg skill_was_miss
; NORMAL HIT!
mov skill3d_last_result, 1
inc skill3d_hits
mov skill3d_state, 2
mov skill3d_timer, 40
invoke PlayCasinoSound3D, OFFSET soundSkillHit, 0, 1
jmp skill_check_finish_round
skill_was_miss:
; MISS!
mov skill3d_last_result, 0
inc skill3d_misses
mov skill3d_state, 3
mov skill3d_timer, 45
invoke PlayCasinoSound3D, OFFSET soundSkillMiss, 0, 1
skill_check_finish_round:
cmp skill3d_hits, 5
jge skill_game_escaped
cmp skill3d_misses, 3
jge skill_game_lost
ret
skill_game_escaped:
mov skill3d_state, 4
mov skill3d_timer, 0
; Payout: 3x total return (+$2x bet profit)
mov eax, skill3d_bet
imul eax, 3
add bankroll, eax
mov eax, skill3d_bet
shl eax, 1
mov skill3d_win_amount, eax
invoke NpcRecordRound3D,10,1
call SaveProgress3D
invoke PlayCasinoSound3D, OFFSET soundRoundWin, 0, 1
ret
skill_game_lost:
mov skill3d_state, 5
mov skill3d_timer, 0
invoke NpcRecordRound3D,10,0
call SaveProgress3D
invoke PlayCasinoSound3D, OFFSET soundLose, 0, 1
ret
skill_handle_round_wait:
dec skill3d_timer
cmp skill3d_timer, 0
jg skill_input_done
; Next round setup
invoke RandomRange3D, 90
add eax, 80
mov skill3d_zone_start, eax
invoke RandomRange3D, 12
add eax, skill3d_zone_start
add eax, 20
mov skill3d_great_start, eax
mov eax, skill3d_hits
shr eax, 1
add eax, 4
mov skill3d_speed, eax
mov skill3d_state, 1
ret
skill_handle_end_wait:
invoke Pressed3D, 20h
test eax, eax
jz skill_input_done
call InitSkillGame
ret
skill_input_done:
ret
HandleSkillInput ENDP
RenderSkillGame PROC uses ebx esi edi
local kx:DWORD
local tx:DWORD
; Industrial Steel bezel
invoke DrawBox, 0, 0, 320, 240, 00121416h
invoke DrawBoxBorder, 6, 6, 308, 228, 001A1D20h, 00FFD700h, 2
; Header
invoke DrawBoxBorder, 20, 12, 280, 26, 00121418h, 00FFD700h, 2
invoke DrawString8x8, 40, 21, OFFSET textSkillTitle, 00FFFF00h
; Status
invoke DrawBoxBorder, 20, 44, 110, 18, 00121418h, 002A3540h, 1
invoke DrawString8x8, 24, 49, OFFSET textBankPrompt, 003CFF3Ch
invoke FormatNumber, bankroll, OFFSET hudNumBuffer
invoke DrawString8x8, 72, 49, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawBoxBorder, 190, 44, 110, 18, 00121418h, 002A3540h, 1
invoke DrawString8x8, 194, 49, OFFSET textBetPrompt, 00FFD700h
invoke FormatNumber, skill3d_bet, OFFSET hudNumBuffer
invoke DrawString8x8, 254, 49, OFFSET hudNumBuffer, 00FFD700h
; Survivor Progress
invoke DrawString8x8, 24, 70, OFFSET textSkillHitsHdr, 003CFF3Ch
invoke FormatNumber, skill3d_hits, OFFSET hudNumBuffer
invoke DrawString8x8, 64, 70, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawString8x8, 180, 70, OFFSET textSkillMissHdr, 00FF6464h
invoke FormatNumber, skill3d_misses, OFFSET hudNumBuffer
invoke DrawString8x8, 240, 70, OFFSET hudNumBuffer, 00FF6464h
; Dial Frame (Track: X=50..270, Y=102..134)
invoke DrawBoxBorder, 50, 102, 220, 32, 000F1114h, 00404855h, 2
; Calibrated ticks
mov tx, 60
skill_ticks_loop:
cmp tx, 260
jge skill_draw_zones
invoke DrawBox, tx, 104, 1, 6, 00303845h
invoke DrawBox, tx, 126, 1, 6, 00303845h
add tx, 12
jmp skill_ticks_loop
skill_draw_zones:
; Normal Success Zone (Green)
invoke DrawBoxBorder, skill3d_zone_start, 106, skill3d_zone_width, 24, 00155020h, 003CFF3Ch, 1
; Great Zone (Gold)
invoke DrawBoxBorder, skill3d_great_start, 106, skill3d_great_width, 24, 00FFD700h, 00FFFF00h, 1
; Pointer / Needle at skill3d_needle
mov eax, skill3d_needle
dec eax
invoke DrawBox, eax, 98, 3, 40, 00FFFFFFh
mov eax, skill3d_needle
sub eax, 2
invoke DrawBox, eax, 96, 5, 2, 00FF3030h
invoke DrawBox, eax, 138, 5, 2, 00FF3030h
; Center prompts / outcome
cmp skill3d_state, 0
jne @F
invoke DrawString8x8, 52, 150, OFFSET textSkillReadyMsg, 00FFD700h
invoke DrawString8x8, 76, 166, OFFSET textSkillPrompt, 00D0D8E0h
jmp skill_render_keys
@@:
cmp skill3d_state, 1
jne @F
invoke DrawString8x8, 76, 150, OFFSET textSkillPrompt, 00FFFF00h
jmp skill_render_keys
@@:
cmp skill3d_state, 2
jne @F
cmp skill3d_last_result, 2
jne skill_normal_hit_text
invoke DrawString8x8, 36, 150, OFFSET textSkillGreatMsg, 00FFFF00h
jmp skill_render_keys
skill_normal_hit_text:
invoke DrawString8x8, 64, 150, OFFSET textSkillHitMsg, 003CFF3Ch
jmp skill_render_keys
@@:
cmp skill3d_state, 3
jne @F
invoke DrawString8x8, 88, 150, OFFSET textSkillMissMsg, 00FF6464h
jmp skill_render_keys
@@:
cmp skill3d_state, 4
jne @F
invoke DrawString8x8, 48, 150, OFFSET textSkillEscape, 003CFF3Ch
invoke FormatNumber, skill3d_win_amount, OFFSET hudNumBuffer
invoke DrawString8x8, 240, 150, OFFSET hudNumBuffer, 003CFF3Ch
invoke DrawString8x8, 64, 166, OFFSET textSkullsAgain, 00FFD700h
jmp skill_render_keys
@@:
invoke DrawString8x8, 44, 150, OFFSET textSkillLost, 00FF6464h
invoke DrawString8x8, 64, 166, OFFSET textSkullsAgain, 00FFD700h
skill_render_keys:
mov kx, 16
invoke DrawKeycap3D, kx, 192, OFFSET textSkillKeySpace, 1
add kx, eax
invoke DrawKeycap3D, kx, 192, OFFSET textSkillKeyBet, 0
add kx, eax
invoke DrawKeycap3D, kx, 192, OFFSET textKeyEsc, 0
ret
RenderSkillGame ENDP
; --- Mouse Lock & Unlock Routines for Free Camera Look ---
LockMouse3D PROC
LOCAL rcClient[16]:BYTE
LOCAL ptCenter:C3D_POINT
cmp mouseLocked3D, 1
je lock_done
mov mouseLocked3D, 1
invoke ShowCursor, 0
lea eax, rcClient
invoke GetClientRect, h3DWnd, eax
mov eax, dword ptr rcClient[8]
shr eax, 1
mov ptCenter.x, eax
mov eax, dword ptr rcClient[12]
shr eax, 1
mov ptCenter.y, eax
lea eax, ptCenter
invoke ClientToScreen, h3DWnd, eax
invoke SetCursorPos, ptCenter.x, ptCenter.y
lock_done:
ret
LockMouse3D ENDP
UnlockMouse3D PROC
cmp mouseLocked3D, 0
je unlock_done
mov mouseLocked3D, 0
invoke ShowCursor, 1
unlock_done:
ret
UnlockMouse3D ENDP
UpdateMouseLockState PROC
cmp engineMode, MODE_WALK
jne unlock_it
cmp paused3D, 0
jne unlock_it
invoke GetForegroundWindow
cmp eax, h3DWnd
jne unlock_it
invoke IsIconic, h3DWnd
test eax, eax
jnz unlock_it
call LockMouse3D
ret
unlock_it:
call UnlockMouse3D
ret
UpdateMouseLockState ENDP
HandlePlayerInput PROC uses ebx esi edi
local speed:DWORD
local nextX:DWORD
local nextY:DWORD
local rcClient[16]:BYTE
local ptCenter:C3D_POINT
local ptCursor:C3D_POINT
; --- Mouse Look Camera Rotation ---
cmp mouseLocked3D, 1
jne skip_mouse_look
lea eax, rcClient
invoke GetClientRect, h3DWnd, eax
mov eax, dword ptr rcClient[8]
shr eax, 1
mov ptCenter.x, eax
mov eax, dword ptr rcClient[12]
shr eax, 1
mov ptCenter.y, eax
lea eax, ptCenter
invoke ClientToScreen, h3DWnd, eax
lea eax, ptCursor
invoke GetCursorPos, eax
mov eax, ptCursor.x
sub eax, ptCenter.x
test eax, eax
jz mouse_recenter
cmp eax, 64
jle @F
mov eax, 64
@@:
cmp eax, -64
jge @F
mov eax, -64
@@:
add playerAngle, eax
mouse_recenter:
invoke SetCursorPos, ptCenter.x, ptCenter.y
skip_mouse_look:
mov eax, deltaTime3D
imul eax, 200
mov speed, eax
cmp keys3D[10h], 0
je @F
shl speed, 1
@@:
mov eax, deltaTime3D
shr eax, 2
inc eax
cmp keys3D[41h], 0
jne input_turn_left
cmp keys3D[25h], 0
je input_right
input_turn_left:
sub playerAngle, eax
input_right:
cmp keys3D[44h], 0
jne input_turn_right
cmp keys3D[27h], 0
je input_forward
input_turn_right:
add playerAngle, eax
input_forward:
and playerAngle, 511
call UpdateCamera3D
xor edi, edi
cmp keys3D[57h], 0
jne input_go_forward
cmp keys3D[26h], 0
je input_back
input_go_forward:
inc edi
input_back:
cmp keys3D[53h], 0
jne input_go_back
cmp keys3D[28h], 0
je input_move
input_go_back:
dec edi
input_move:
test edi, edi
jz input_action
imul edi, speed
mov eax, playerDirX
imul edi
shrd eax, edx, 16
add eax, playerX
mov nextX, eax
mov eax, playerDirY
imul edi
shrd eax, edx, 16
add eax, playerY
mov nextY, eax
invoke CanWalk3D, nextX, playerY
test eax, eax
jz @F
mov eax, nextX
mov playerX, eax
@@:
invoke CanWalk3D, playerX, nextY
test eax, eax
jz input_action
mov eax, nextY
mov playerY, eax
input_action:
invoke Pressed3D, 45h
test eax, eax
jz @F
call Trigger3DInteraction
@@:
ret
HandlePlayerInput ENDP
CheckInteractions PROC uses ebx esi edi
local nearest:DWORD
mov nearest, 262144
mov interactTargetId, 0
mov interactPromptPtr, 0
xor esi, esi
interaction_scan:
cmp esi, NUM_SPRITES
jge interaction_done
imul edi, esi, SIZEOF SpriteObject
cmp [casinoSprites+edi].interactId, 0
je interaction_next
mov eax, [casinoSprites+edi].posX
sub eax, playerX
sar eax, 8
mov ebx, eax
imul eax, eax
mov ecx, eax
mov eax, [casinoSprites+edi].posY
sub eax, playerY
sar eax, 8
mov edx, eax
imul eax, eax
add ecx, eax
cmp ecx, nearest
jae interaction_next
; Only target objects in front of the camera.
mov eax, playerDirX
sar eax, 8
imul eax, ebx
mov ebx, playerDirY
sar ebx, 8
imul ebx, edx
add eax, ebx
cmp eax, 18000
jl interaction_next
mov nearest, ecx
mov eax, [casinoSprites+edi].interactId
mov interactTargetId, eax
mov eax, [casinoSprites+edi].promptPtr
mov interactPromptPtr, eax
interaction_next:
inc esi
jmp interaction_scan
interaction_done:
call CheckHallInteractions3D
ret
CheckInteractions ENDP
; (Legacy console arcade bezel bridge removed)
Trigger3DInteraction PROC
call TriggerHallInteraction3D
test eax, eax
jnz trigger_done
mov eax, interactTargetId
test eax, eax
jz trigger_done
cmp eax, INTERACT_DANCER
jne check_target_bj
cmp bankroll, 100
jl dancer_no_cash
sub bankroll, 100
inc dancerLuckBuff
invoke CopyString3D, OFFSET textTips3D, OFFSET flashMessage
mov flashTimer, 100
invoke PlayCasinoSound3D, OFFSET soundClick, 0, 1
ret
dancer_no_cash:
invoke CopyString3D, OFFSET msgNeedMoney, OFFSET flashMessage
mov flashTimer, 60
ret
check_target_bj:
cmp eax, INTERACT_BLACKJACK
jne check_target_poker
call InitNativeBlackjack3D
mov engineMode, MODE_BLACKJACK
ret
check_target_poker:
cmp eax, INTERACT_POKER
jne check_target_durak
call InitNativePoker3D
test eax, eax
jz target_unported
mov engineMode, MODE_POKER
ret
check_target_durak:
cmp eax, INTERACT_DURAK
jne check_target_slots777
call InitNativeDurak3D
mov engineMode, MODE_DURAK
ret
check_target_slots777:
cmp eax, INTERACT_SLOTS_777
jne check_target_slots_clover
call InitNativeSlots3D
test eax,eax
jz target_unported
mov engineMode,MODE_SLOTS
ret
check_target_slots_clover:
cmp eax, INTERACT_SLOTS_CLOVER
jne check_target_roulette
call InitNativeClover3D
test eax,eax
jz target_unported
mov engineMode,MODE_CLOVER
ret
check_target_roulette:
cmp eax, INTERACT_ROULETTE
jne check_target_dice
call InitNativeWheel3D
mov engineMode, MODE_ROULETTE
ret
check_target_dice:
cmp eax, INTERACT_DICE
jne check_target_skulls
call InitDiceGame
mov engineMode, MODE_DICE
ret
check_target_skulls:
cmp eax, INTERACT_SKULLS
jne check_target_coin
call InitSkullsGame
mov engineMode, MODE_SKULLS
ret
check_target_coin:
cmp eax, INTERACT_COIN
jne check_target_skill
call InitCoinGame
mov engineMode, MODE_COIN
ret
check_target_skill:
cmp eax, INTERACT_SKILL_CHECK
jne check_target_buckshot
call InitSkillGame
mov engineMode, MODE_SKILL
ret
check_target_buckshot:
cmp eax, INTERACT_BUCKSHOT
jne check_target_rr
call InitBuckshot3D
mov engineMode, MODE_BUCKSHOT
ret
check_target_rr:
cmp eax, INTERACT_RUSSIAN_ROULETTE
jne check_target_online_rr
call InitRussianGame3D
test eax, eax
jz @F
mov engineMode, MODE_RUSSIAN
@@:
ret
check_target_online_rr:
cmp eax, INTERACT_ONLINE_RR
jne check_target_umamusume
call BeginUnavailable3D
ret
check_target_umamusume:
cmp eax, INTERACT_UMAMUSUME
jne check_target_hell
call BeginUnavailable3D
ret
check_target_hell:
cmp eax, INTERACT_HELL_TOWER
jne check_target_shop
call BeginUnavailable3D
ret
check_target_shop:
cmp eax, INTERACT_SHOP
jne check_target_atm
call BeginMerchant3D
ret
check_target_atm:
cmp eax, INTERACT_ATM
jne check_target_terminal
mov engineMode, MODE_ATM
ret
check_target_terminal:
cmp eax, INTERACT_TERMINAL
jne check_target_observer
call BeginUnavailable3D
ret
check_target_observer:
cmp eax, INTERACT_OBSERVER
jne target_unported
call BeginUnavailable3D
ret
target_unported:
call BeginUnavailable3D
trigger_done:
ret
Trigger3DInteraction ENDP
; --- Engine Initialization ---
Init3DEngine PROC
local screenCX:DWORD
local screenCY:DWORD
local posX:DWORD
local posY:DWORD
local bytesRead:DWORD
push ebx
push esi
push edi
invoke timeBeginPeriod, 1
call LoadDisplaySettings3D
call Create3DWindow
test eax, eax
jz init_failed
call LoadTextures3D
test eax, eax
jz init_failed
call InitializeCasinoSprites3D
; Initialize raycasting worker thread and sync events
invoke CreateEventA, 0, 0, 0, 0
mov hRaycastStartEvent, eax
invoke CreateEventA, 0, 0, 0, 0
mov hRaycastDoneEvent, eax
mov bRaycastQuit, 0
invoke CreateThread, 0, 65536, OFFSET RaycastWorkerProc, 0, 0, ADDR raycastThreadId
mov hRaycastThread, eax
call InitHall3D
call BeginStartup3D
call RenderStartup3D
invoke ShowWindow, h3DWnd, SW_SHOW
invoke UpdateWindow, h3DWnd
invoke SetForegroundWindow, h3DWnd
mov eax, 1
jmp init_return
init_failed:
xor eax, eax
init_return:
pop edi
pop esi
pop ebx
ret
Init3DEngine ENDP
InitializeCasinoSprites3D PROC
init_sprites_table:
; Sprite 0: VIP Dancer 1 (Stage Left)
mov casinoSprites[0*SIZEOF SpriteObject].posX, (13 * FP_1 + FP_HALF)
mov casinoSprites[0*SIZEOF SpriteObject].posY, (4 * FP_1)
mov casinoSprites[0*SIZEOF SpriteObject].baseTexId, 10
mov casinoSprites[0*SIZEOF SpriteObject].frameCount, 12
mov casinoSprites[0*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[0*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[0*SIZEOF SpriteObject].animSpeed, 5
mov casinoSprites[0*SIZEOF SpriteObject].interactId, INTERACT_DANCER
mov casinoSprites[0*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
; Sprite 1: VIP Dancer 2 (Center Stage Star)
mov casinoSprites[1*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF)
mov casinoSprites[1*SIZEOF SpriteObject].posY, (3 * FP_1 + FP_HALF)
mov casinoSprites[1*SIZEOF SpriteObject].baseTexId, 10
mov casinoSprites[1*SIZEOF SpriteObject].frameCount, 12
mov casinoSprites[1*SIZEOF SpriteObject].curFrame, 2
mov casinoSprites[1*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[1*SIZEOF SpriteObject].animSpeed, 5
mov casinoSprites[1*SIZEOF SpriteObject].interactId, INTERACT_DANCER
mov casinoSprites[1*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
; Sprite 2: VIP Dancer 3 (Stage Right)
mov casinoSprites[2*SIZEOF SpriteObject].posX, (19 * FP_1 + FP_HALF)
mov casinoSprites[2*SIZEOF SpriteObject].posY, (4 * FP_1)
mov casinoSprites[2*SIZEOF SpriteObject].baseTexId, 10
mov casinoSprites[2*SIZEOF SpriteObject].frameCount, 12
mov casinoSprites[2*SIZEOF SpriteObject].curFrame, 1
mov casinoSprites[2*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[2*SIZEOF SpriteObject].animSpeed, 5
mov casinoSprites[2*SIZEOF SpriteObject].interactId, INTERACT_DANCER
mov casinoSprites[2*SIZEOF SpriteObject].promptPtr, OFFSET promptDancer
; Sprite 3: VIP Blackjack (Front Center Left)
mov casinoSprites[3*SIZEOF SpriteObject].posX, (12 * FP_1 + FP_HALF)
mov casinoSprites[3*SIZEOF SpriteObject].posY, (8 * FP_1)
mov casinoSprites[3*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[3*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[3*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[3*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[3*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[3*SIZEOF SpriteObject].interactId, INTERACT_BLACKJACK
mov casinoSprites[3*SIZEOF SpriteObject].promptPtr, OFFSET promptBlackjack
; Sprite 4: European Roulette Table (Front Center)
mov casinoSprites[4*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF)
mov casinoSprites[4*SIZEOF SpriteObject].posY, (10 * FP_1)
mov casinoSprites[4*SIZEOF SpriteObject].baseTexId, 31
mov casinoSprites[4*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[4*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[4*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[4*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[4*SIZEOF SpriteObject].interactId, INTERACT_ROULETTE
mov casinoSprites[4*SIZEOF SpriteObject].promptPtr, OFFSET promptCasinoRoulette
; Sprite 5: Texas Hold'em Poker Table (Front Center Right)
mov casinoSprites[5*SIZEOF SpriteObject].posX, (20 * FP_1 + FP_HALF)
mov casinoSprites[5*SIZEOF SpriteObject].posY, (8 * FP_1)
mov casinoSprites[5*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[5*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[5*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[5*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[5*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[5*SIZEOF SpriteObject].interactId, INTERACT_POKER
mov casinoSprites[5*SIZEOF SpriteObject].promptPtr, OFFSET promptPoker
; Sprite 6: Podkidnoy Durak Card Table
mov casinoSprites[6*SIZEOF SpriteObject].posX, (24 * FP_1 + FP_HALF)
mov casinoSprites[6*SIZEOF SpriteObject].posY, (8 * FP_1)
mov casinoSprites[6*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[6*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[6*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[6*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[6*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[6*SIZEOF SpriteObject].interactId, INTERACT_DURAK
mov casinoSprites[6*SIZEOF SpriteObject].promptPtr, OFFSET promptDurak
; Sprite 7: Classic Slots 777 (West Arcade 1)
mov casinoSprites[7*SIZEOF SpriteObject].posX, (6 * FP_1)
mov casinoSprites[7*SIZEOF SpriteObject].posY, (8 * FP_1)
mov casinoSprites[7*SIZEOF SpriteObject].baseTexId, 24
mov casinoSprites[7*SIZEOF SpriteObject].frameCount, 3
mov casinoSprites[7*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[7*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[7*SIZEOF SpriteObject].animSpeed, 8
mov casinoSprites[7*SIZEOF SpriteObject].interactId, INTERACT_SLOTS_777
mov casinoSprites[7*SIZEOF SpriteObject].promptPtr, OFFSET promptClassicSlot
; Sprite 8: CloverPit Slots 5x3 (West Arcade 2)
mov casinoSprites[8*SIZEOF SpriteObject].posX, (6 * FP_1)
mov casinoSprites[8*SIZEOF SpriteObject].posY, (11 * FP_1)
mov casinoSprites[8*SIZEOF SpriteObject].baseTexId, 24
mov casinoSprites[8*SIZEOF SpriteObject].frameCount, 3
mov casinoSprites[8*SIZEOF SpriteObject].curFrame, 1
mov casinoSprites[8*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[8*SIZEOF SpriteObject].animSpeed, 8
mov casinoSprites[8*SIZEOF SpriteObject].interactId, INTERACT_SLOTS_CLOVER
mov casinoSprites[8*SIZEOF SpriteObject].promptPtr, OFFSET promptCloverSlot
; Sprite 9: Craps & Dice Table (West Arcade 3)
mov casinoSprites[9*SIZEOF SpriteObject].posX, (6 * FP_1)
mov casinoSprites[9*SIZEOF SpriteObject].posY, (14 * FP_1)
mov casinoSprites[9*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[9*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[9*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[9*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[9*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[9*SIZEOF SpriteObject].interactId, INTERACT_DICE
mov casinoSprites[9*SIZEOF SpriteObject].promptPtr, OFFSET promptDice
; Sprite 10: Skulls & Cups Table
mov casinoSprites[10*SIZEOF SpriteObject].posX, (10 * FP_1)
mov casinoSprites[10*SIZEOF SpriteObject].posY, (15 * FP_1)
mov casinoSprites[10*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[10*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[10*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[10*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[10*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[10*SIZEOF SpriteObject].interactId, INTERACT_SKULLS
mov casinoSprites[10*SIZEOF SpriteObject].promptPtr, OFFSET promptSkulls
; Sprite 11: Coin Toss Stand
mov casinoSprites[11*SIZEOF SpriteObject].posX, (14 * FP_1)
mov casinoSprites[11*SIZEOF SpriteObject].posY, (15 * FP_1)
mov casinoSprites[11*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[11*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[11*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[11*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[11*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[11*SIZEOF SpriteObject].interactId, INTERACT_COIN
mov casinoSprites[11*SIZEOF SpriteObject].promptPtr, OFFSET promptCoin
; Sprite 12: Skill Check Stand
mov casinoSprites[12*SIZEOF SpriteObject].posX, (18 * FP_1)
mov casinoSprites[12*SIZEOF SpriteObject].posY, (15 * FP_1)
mov casinoSprites[12*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[12*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[12*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[12*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[12*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[12*SIZEOF SpriteObject].interactId, INTERACT_SKILL_CHECK
mov casinoSprites[12*SIZEOF SpriteObject].promptPtr, OFFSET promptSkillCheck
; Sprite 13: Umamusume Derby Lounge
mov casinoSprites[13*SIZEOF SpriteObject].posX, (22 * FP_1)
mov casinoSprites[13*SIZEOF SpriteObject].posY, (15 * FP_1)
mov casinoSprites[13*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[13*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[13*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[13*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[13*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[13*SIZEOF SpriteObject].interactId, INTERACT_UMAMUSUME
mov casinoSprites[13*SIZEOF SpriteObject].promptPtr, OFFSET promptUmamusume
; Sprite 14: Boutique & Shop (East Wing)
mov casinoSprites[14*SIZEOF SpriteObject].posX, (26 * FP_1)
mov casinoSprites[14*SIZEOF SpriteObject].posY, (12 * FP_1)
mov casinoSprites[14*SIZEOF SpriteObject].baseTexId, 32
mov casinoSprites[14*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[14*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[14*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[14*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[14*SIZEOF SpriteObject].interactId, INTERACT_SHOP
mov casinoSprites[14*SIZEOF SpriteObject].promptPtr, OFFSET promptShop
; Sprite 15: Cashier & ATM (East Wing)
mov casinoSprites[15*SIZEOF SpriteObject].posX, (26 * FP_1)
mov casinoSprites[15*SIZEOF SpriteObject].posY, (16 * FP_1)
mov casinoSprites[15*SIZEOF SpriteObject].baseTexId, 33
mov casinoSprites[15*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[15*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[15*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[15*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[15*SIZEOF SpriteObject].interactId, INTERACT_ATM
mov casinoSprites[15*SIZEOF SpriteObject].promptPtr, OFFSET promptATM
; Sprite 16: Player Terminal (East Wing)
mov casinoSprites[16*SIZEOF SpriteObject].posX, (26 * FP_1)
mov casinoSprites[16*SIZEOF SpriteObject].posY, (20 * FP_1)
mov casinoSprites[16*SIZEOF SpriteObject].baseTexId, 33
mov casinoSprites[16*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[16*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[16*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[16*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[16*SIZEOF SpriteObject].interactId, INTERACT_TERMINAL
mov casinoSprites[16*SIZEOF SpriteObject].promptPtr, OFFSET promptPlayerTerminal
; Sprite 17: Buckshot Roulette (South-West)
mov casinoSprites[17*SIZEOF SpriteObject].posX, (12 * FP_1)
mov casinoSprites[17*SIZEOF SpriteObject].posY, (22 * FP_1)
mov casinoSprites[17*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[17*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[17*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[17*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[17*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[17*SIZEOF SpriteObject].interactId, INTERACT_BUCKSHOT
mov casinoSprites[17*SIZEOF SpriteObject].promptPtr, OFFSET promptBuckshot
; Sprite 18: Observer Lounge (South-East)
mov casinoSprites[18*SIZEOF SpriteObject].posX, (20 * FP_1)
mov casinoSprites[18*SIZEOF SpriteObject].posY, (22 * FP_1)
mov casinoSprites[18*SIZEOF SpriteObject].baseTexId, 30
mov casinoSprites[18*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[18*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[18*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[18*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[18*SIZEOF SpriteObject].interactId, INTERACT_OBSERVER
mov casinoSprites[18*SIZEOF SpriteObject].promptPtr, OFFSET promptObserver
; Sprite 19: Russian Roulette (Backroom Entrance)
mov casinoSprites[19*SIZEOF SpriteObject].posX, (16 * FP_1)
mov casinoSprites[19*SIZEOF SpriteObject].posY, (25 * FP_1)
mov casinoSprites[19*SIZEOF SpriteObject].baseTexId, 34
mov casinoSprites[19*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[19*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[19*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[19*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[19*SIZEOF SpriteObject].interactId, INTERACT_RUSSIAN_ROULETTE
mov casinoSprites[19*SIZEOF SpriteObject].promptPtr, OFFSET promptRussianRoulette
; Sprite 20: Online Russian Roulette (Backroom Secret Terminal)
mov casinoSprites[20*SIZEOF SpriteObject].posX, (18 * FP_1)
mov casinoSprites[20*SIZEOF SpriteObject].posY, (25 * FP_1)
mov casinoSprites[20*SIZEOF SpriteObject].baseTexId, 34
mov casinoSprites[20*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[20*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[20*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[20*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[20*SIZEOF SpriteObject].interactId, INTERACT_ONLINE_RR
mov casinoSprites[20*SIZEOF SpriteObject].promptPtr, OFFSET promptOnlineRR
; Sprite 21: Hell Tower Portal (South Wing Deep End)
mov casinoSprites[21*SIZEOF SpriteObject].posX, (16 * FP_1 + FP_HALF)
mov casinoSprites[21*SIZEOF SpriteObject].posY, (29 * FP_1)
mov casinoSprites[21*SIZEOF SpriteObject].baseTexId, 4
mov casinoSprites[21*SIZEOF SpriteObject].frameCount, 1
mov casinoSprites[21*SIZEOF SpriteObject].curFrame, 0
mov casinoSprites[21*SIZEOF SpriteObject].animTimer, 0
mov casinoSprites[21*SIZEOF SpriteObject].animSpeed, 1
mov casinoSprites[21*SIZEOF SpriteObject].interactId, INTERACT_HELL_TOWER
mov casinoSprites[21*SIZEOF SpriteObject].promptPtr, OFFSET promptHellTower
ret
InitializeCasinoSprites3D ENDP
include src_graphics\audio_code.inc
include src_graphics\dice_animation.inc
include src_graphics\russian_roulette.inc
include src_graphics\startup_code.inc
include src_graphics\card_table_assets.inc
include src_graphics\poker_evaluator.inc
include src_graphics\native_poker.inc
include src_graphics\native_blackjack.inc
include src_graphics\native_durak.inc
include src_graphics\card_tables_render.inc
include src_graphics\durak_render.inc
include src_graphics\card_table_input.inc
include src_graphics\scene_animation.inc
include src_graphics\native_slots.inc
include src_graphics\native_clover.inc
include src_graphics\native_coin.inc
include src_graphics\graphic_profiles.inc
include src_graphics\city_arrival_scene.inc
include src_graphics\arrival_scene.inc
include src_graphics\merchant_scene.inc
include src_graphics\hall_scene.inc
include src_graphics\npc_mind.inc
include src_graphics\npc_life.inc
include src_graphics\npc_contracts.inc
include src_graphics\native_wheel.inc
include src_graphics\billiards.inc
include src_graphics\buckshot.inc
include src_graphics\russian_table.inc
include src_graphics\unavailable.inc
; --- Main Loop of the 3D Casino Engine ---
StartCasino3D PROC uses ebx esi edi
call Init3DEngine
test eax, eax
jz engine_shutdown
invoke timeGetTime
mov rngSeed3D, eax
mov previousTick3D, eax
engine_loop:
invoke PeekMessageA, OFFSET msg3D, 0, 0, 0, PM_REMOVE
test eax, eax
jz dispatch_frame
cmp msg3D.message, WM_QUIT
je engine_shutdown
invoke TranslateMessage, OFFSET msg3D
invoke DispatchMessageA, OFFSET msg3D
jmp engine_loop
dispatch_frame:
invoke timeGetTime
mov frameStart3D, eax
sub eax, previousTick3D
cmp eax, 50
jbe @F
mov eax, 50
@@:
mov deltaTime3D, eax
mov eax, frameStart3D
mov previousTick3D, eax
invoke GetForegroundWindow
cmp eax, h3DWnd
jne engine_idle
invoke IsIconic, h3DWnd
test eax, eax
jnz engine_idle
invoke Pressed3D, 7Ah
test eax, eax
jz @F
call ToggleFullscreen3D
@@:
invoke Pressed3D, 1Bh
test eax, eax
jz engine_tick
cmp engineMode, MODE_INTRO
jne @F
call FinishStartup3D
jmp engine_tick
@@:
cmp engineMode, MODE_ARRIVAL
jne @F
call ArrivalEscape3D
jmp engine_tick
@@:
cmp engineMode, MODE_WALK
jne leave_table
xor paused3D, 1
jmp engine_tick
leave_table:
call CardTableEscape3D
test eax, eax
jnz engine_tick
call TableBusy3D
test eax, eax
jz leave_idle_table
xor paused3D, 1
call ClearKeys3D
jmp engine_tick
leave_idle_table:
mov paused3D, 0
mov engineMode, MODE_WALK
call ClearKeys3D
invoke PlayCasinoSound3D, 0, 0, 0
engine_tick:
call UpdateMouseLockState
cmp paused3D, 0
jne draw_pause
mov eax, deltaTime3D
add animationClock3D, eax
cmp engineMode, MODE_INTRO
jne check_arrival_mode
call HandleStartupInput3D
cmp engineMode, MODE_INTRO
jne check_arrival_mode
call RenderStartup3D
jmp present_frame
check_arrival_mode:
cmp engineMode, MODE_ARRIVAL
jne check_walk_mode
call HandleArrival3D
cmp engineMode, MODE_WALK
je check_walk_mode
call RenderArrival3D
jmp present_frame
check_walk_mode:
cmp engineMode, MODE_WALK
jne check_slots_mode
call UpdateHall3D
call UpdateCamera3D
call CheckInteractions
call HandlePlayerInput
call UpdateCamera3D
call RenderCeilingAndFloor
call RenderWalls
call PrepareCityDepth3D
call RenderSprites
call RenderHall3D
call RenderHUD
call RenderMinimap
jmp present_frame
check_slots_mode:
cmp engineMode,MODE_CLOVER
jne @F
call HandleNativeClover3D
call RenderNativeClover3D
jmp present_frame
@@:
cmp engineMode,MODE_NPC_DIALOG
jne @F
call HandleNpcDialog3D
call RenderNpcDialog3D
jmp present_frame
@@:
cmp engineMode, MODE_UNAVAILABLE
jne @F
call HandleUnavailable3D
call RenderUnavailable3D
jmp present_frame
@@:
cmp engineMode, MODE_POOL
jne @F
call HandlePool3D
call RenderPool3D
jmp present_frame
@@:
cmp engineMode, MODE_BAR
jne @F
call HandleBar3D
call RenderBar3D
jmp present_frame
@@:
cmp engineMode, MODE_STAIRS
jne @F
call HandleStairs3D
call RenderStairs3D
jmp present_frame
@@:
cmp engineMode, MODE_SLOTS
jne check_bj_mode
call HandleNativeSlots3D
cmp engineMode,MODE_WALK
je check_walk_mode
call RenderNativeSlots3D
jmp present_frame
check_bj_mode:
cmp engineMode, MODE_BLACKJACK
jne check_poker_mode
call HandleNativeBlackjack3D
cmp engineMode, MODE_WALK
je check_walk_mode
call RenderNativeBlackjack3D
jmp present_frame
check_poker_mode:
cmp engineMode, MODE_POKER
jne check_durak_mode
call HandleNativePoker3D
cmp engineMode, MODE_WALK
je check_walk_mode
call RenderNativePoker3D
jmp present_frame
check_durak_mode:
cmp engineMode, MODE_DURAK
jne check_roul_mode
call HandleNativeDurak3D
cmp engineMode, MODE_WALK
je check_walk_mode
call RenderNativeDurak3D
jmp present_frame
check_roul_mode:
cmp engineMode, MODE_ROULETTE
jne check_shop_mode
call HandleNativeWheel3D
call RenderNativeWheel3D
jmp present_frame
check_shop_mode:
cmp engineMode, MODE_SHOP
jne check_atm_mode
call HandleMerchant3D
call RenderMerchant3D
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 check_skill_mode
call HandleSkullsInput
call RenderSkullsGame
jmp present_frame
check_skill_mode:
cmp engineMode, MODE_SKILL
jne check_buckshot_mode
call HandleSkillInput
call RenderSkillGame
jmp present_frame
check_buckshot_mode:
cmp engineMode, MODE_BUCKSHOT
jne check_russian_mode
call HandleBuckshot3D
call RenderBuckshot3D
jmp present_frame
check_russian_mode:
cmp engineMode, MODE_RUSSIAN
jne present_frame
call HandleRussianInput3D
call RenderRussianGame3D
jmp present_frame
draw_pause:
invoke DrawBoxBorder, 28, 36, 264, 168, 00151C21h, 00D8BC6Ah, 2
invoke DrawString8x8, 44, 48, OFFSET textPause3D, 00FFFFFFh
cmp displayFill3D, 0
je @F
invoke DrawString8x8, 44, 72, OFFSET textDisplayFill3D, 00D8BC6Ah
jmp pause_draw_quality
@@:
invoke DrawString8x8, 44, 72, OFFSET textDisplayFit3D, 00D8BC6Ah
pause_draw_quality:
invoke DrawString8x8, 44, 92, OFFSET textLowSpec3D, 00D8BC6Ah
mov eax, settingsLowSpec
cmp eax, 0
jne @F
mov edx, OFFSET textLowSpecOff3D
jmp pause_draw_quality_value
@@:
cmp eax, 1
jne @F
mov edx, OFFSET textLowSpecEco3D
jmp pause_draw_quality_value
@@:
mov edx, OFFSET textLowSpecQuiet3D
pause_draw_quality_value:
invoke DrawString8x8, 208, 92, edx, 00FFFFFFh
invoke DrawString8x8, 44, 112, OFFSET textVolumeKeys3D, 00D8BC6Ah
invoke DrawString8x8, 44, 130, OFFSET textSoundLevel3D, 00BBBBBBh
invoke FormatNumber, settingsVolume, OFFSET hudNumBuffer
invoke DrawString8x8, 124, 130, OFFSET hudNumBuffer, 00FFFFFFh
invoke DrawString8x8, 44, 150, OFFSET textFullscreenKey3D, 00A0A0A0h
invoke DrawString8x8, 44, 170, OFFSET textResume3D, 00D8BC6Ah
invoke DrawString8x8, 44, 188, OFFSET textQuit3D, 00BBBBBBh
invoke Pressed3D, 31h
test eax, eax
jz @F
xor displayFill3D, 1
call SaveDisplaySettings3D
@@:
invoke Pressed3D, 32h
test eax, eax
jz @F
inc settingsLowSpec
cmp settingsLowSpec, 3
jb pause_low_spec_saved
mov settingsLowSpec, 0
pause_low_spec_saved:
call SaveProgress3D
@@:
invoke Pressed3D, 0BBh
test eax, eax
jz @F
cmp settingsVolume, 10
jae @F
inc settingsVolume
call ApplySoundVolume
call SaveProgress3D
@@:
invoke Pressed3D, 0BDh
test eax, eax
jz @F
mov eax, settingsVolume
test eax, eax
jz @F
dec settingsVolume
call ApplySoundVolume
call SaveProgress3D
@@:
invoke Pressed3D, 51h
test eax, eax
jz @F
call SaveProgress3D
jmp engine_shutdown
present_frame:
mov eax, engineMode
cmp eax, lastPersistMode3D
je @F
cmp eax, MODE_WALK
jne @F
call SaveProgress3D
@@:
mov eax, engineMode
mov lastPersistMode3D, eax
call Present3D
mov mouseClick3D, 0
lea edi, pressedKeys3D
xor eax, eax
mov ecx, 64
rep stosd
invoke timeGetTime
sub eax, frameStart3D
mov ecx, 16
cmp settingsLowSpec, 1
jne @F
mov ecx, 24
@@:
cmp settingsLowSpec, 2
jne @F
mov ecx, 33
@@:
cmp eax, ecx
jae engine_loop
sub ecx, eax
invoke Sleep, ecx
jmp engine_loop
engine_idle:
call UnlockMouse3D
invoke Sleep, 50
jmp engine_loop
engine_shutdown:
call UnlockMouse3D
cmp hRaycastThread, 0
je @F
mov bRaycastQuit, 1
invoke SetEvent, hRaycastStartEvent
invoke WaitForSingleObject, hRaycastThread, 1000
invoke CloseHandle, hRaycastThread
invoke CloseHandle, hRaycastStartEvent
invoke CloseHandle, hRaycastDoneEvent
mov hRaycastThread, 0
mov hRaycastStartEvent, 0
mov hRaycastDoneEvent, 0
@@:
call SaveProgress3D
invoke PlayCasinoSound3D, 0, 0, 0
call FreeRussianAssets3D
call FreeStartupAssets3D
call FreeCardTableAssets3D
call FreeBuckshotAssets3D
call FreeNativeSlots3D
call FreeNativeClover3D
call FreePyramidAssets3D
call FreeArrivalAssets3D
cmp h3DDC, 0
je @F
invoke ReleaseDC, h3DWnd, h3DDC
mov h3DDC, 0
@@:
cmp h3DWnd, 0
je @F
invoke DestroyWindow, h3DWnd
mov h3DWnd, 0
@@:
invoke timeEndPeriod, 1
ret
StartCasino3D ENDP
include src_graphics\platform_code.inc
IFDEF CASINO_ACTION_TEST
include tools\tests\casino_actions_test.inc
ENDIF