KAZIK/src_graphics/native_slots.inc

645 lines
16 KiB
PHP

FreeNativeSlots3D PROC
invoke FreeAnimPack3D, OFFSET slotCabinetPack3D
invoke FreeAnimPack3D, OFFSET slotSymbolsPack3D
ret
FreeNativeSlots3D ENDP
InitNativeSlots3D PROC
invoke LoadAnimPack3D, OFFSET slotCabinetPack3D, OFFSET slotCabinetPath3D
test eax,eax
jz slot_init_fail
cmp slotCabinetPack3D.imageWidth,640
jne slot_init_fail
cmp slotCabinetPack3D.height,480
jne slot_init_fail
cmp slotCabinetPack3D.frames,1
jne slot_init_fail
invoke LoadAnimPack3D, OFFSET slotSymbolsPack3D, OFFSET slotSymbolsPath3D
test eax,eax
jz slot_init_fail
cmp slotSymbolsPack3D.imageWidth,64
jne slot_init_fail
cmp slotSymbolsPack3D.height,64
jne slot_init_fail
cmp slotSymbolsPack3D.frames,8
jne slot_init_fail
mov slotSpinState,SLOT_READY
mov slotSpinTimer,0
mov slotWinAmount,0
mov slotStake3D,0
mov slotLeaveAfter3D,0
mov slotPaytable3D,0
mov slotError3D,0
mov slotEffects3D,0
mov slotBetIndex3D,1
mov slotBet,50
mov cardExitActive3D,0
mov paused3D,0
call ClearKeys3D
mov eax,1
ret
slot_init_fail:
call FreeNativeSlots3D
xor eax,eax
ret
InitNativeSlots3D ENDP
; Results are sampled once at stake debit. Rendering never consumes RNG or pays.
StartNativeSlots3D PROC uses ebx esi
cmp slotSpinState,SLOT_SPIN
je slot_start_done
cmp slotPaytable3D,0
jne slot_start_done
cmp slotCabinetPack3D.pixels,0
je slot_start_done
cmp slotSymbolsPack3D.pixels,0
je slot_start_done
mov eax,slotBet
test eax,eax
jz slot_start_done
cmp eax,10000
ja slot_start_done
cmp eax,bankroll
ja slot_start_money
sub bankroll,eax
mov slotStake3D,eax
mov slotSpinState,SLOT_SPIN
mov slotSpinTimer,0
mov slotWinAmount,0
mov slotLeaveAfter3D,0
mov slotError3D,0
mov slotEffects3D,0
call BackroomsLuck3D
mov brSlotLuck3D,eax
xor esi,esi
slot_start_reel:
mov eax,slotStops3D[esi*4]
mov slotStartStops3D[esi*4],eax
invoke RandomRange3D,20
cmp brSlotLuck3D,-1
je br_slot_target
mov eax,0
cmp brSlotLuck3D,1
je br_slot_target
; Distinct symbols, with no refund pair, for the unlucky 10%.
mov eax,esi
inc eax
br_slot_target:
mov slotTargets3D[esi*4],eax
mov edx,slotStrip3D[eax*4]
mov slotReel1[esi*4],edx
sub eax,slotStartStops3D[esi*4]
jns @F
add eax,20
@@:
add eax,slotCycles3D[esi*4]
shl eax,6
mov slotTravel3D[esi*4],eax
inc esi
cmp esi,3
jb slot_start_reel
call SaveProgress3D
invoke PlayCasinoSound3D, OFFSET soundSlotSpin,0,1
ret
slot_start_money:
mov slotError3D,1
slot_start_done:
ret
StartNativeSlots3D ENDP
; Gross multipliers. A cherry pair pays 2x, any other pair returns the stake.
SlotMultiplier3D PROC first:DWORD,second:DWORD,third:DWORD
mov eax,first
cmp eax,7
ja slot_multiplier_zero
cmp second,7
ja slot_multiplier_zero
cmp third,7
ja slot_multiplier_zero
cmp eax,second
jne slot_multiplier_other_pair
cmp eax,third
jne slot_multiplier_pair
mov eax,slotTriple3D[eax*4]
ret
slot_multiplier_other_pair:
cmp eax,third
je slot_multiplier_pair
mov eax,second
cmp eax,third
jne slot_multiplier_zero
slot_multiplier_pair:
cmp eax,1
jne @F
mov eax,2
ret
@@:
mov eax,1
ret
slot_multiplier_zero:
xor eax,eax
ret
SlotMultiplier3D ENDP
SettleNativeSlots3D PROC uses esi
cmp slotSpinState,SLOT_SPIN
jne slot_settle_done
invoke SlotMultiplier3D,slotReel1,slotReel2,slotReel3
mul slotStake3D
mov ecx,1000000000
sub ecx,bankroll
cmp eax,ecx
jbe @F
mov eax,ecx
@@:
mov slotWinAmount,eax
add bankroll,eax
jc slot_settle_cap
cmp bankroll,1000000000
jbe @F
slot_settle_cap:
mov bankroll,1000000000
@@:
xor esi,esi
slot_settle_stops:
mov eax,slotTargets3D[esi*4]
mov slotStops3D[esi*4],eax
inc esi
cmp esi,3
jb slot_settle_stops
mov slotSpinTimer,3000
mov slotSpinState,SLOT_RESULT
mov slotEffects3D,0
xor eax,eax
mov ecx,slotWinAmount
cmp ecx,slotStake3D
seta al
invoke NpcRecordRound3D,4,eax
call SaveProgress3D
mov eax,slotWinAmount
cmp eax,slotStake3D
jb slot_settle_loss
jne @F
invoke PlayCasinoSound3D,0,0,0
jmp slot_settle_exit
@@:
invoke PlayCasinoSound3D,OFFSET soundRoundWin,0,1
mov eax,slotWinAmount
sub eax,slotStake3D
invoke TriggerCharmWinBonus,eax
jmp slot_settle_exit
slot_settle_loss:
mov eax,slotStake3D
sub eax,slotWinAmount
invoke TriggerCharmLossProtection,eax
test eax, eax
jnz slot_settle_exit
invoke PlayCasinoSound3D,OFFSET soundRoundLose,0,1
slot_settle_exit:
cmp slotLeaveAfter3D,0
je slot_settle_done
call SlotEscape3D
slot_settle_done:
ret
SettleNativeSlots3D ENDP
; Escape queues a safe exit during a paid spin; it never opens the pause menu.
SlotEscape3D PROC
mov paused3D,0
cmp slotPaytable3D,0
je @F
mov slotPaytable3D,0
call ClearKeys3D
ret
@@:
cmp slotSpinState,SLOT_SPIN
jne slot_exit_hall
mov slotLeaveAfter3D,1
call ClearKeys3D
ret
slot_exit_hall:
mov slotLeaveAfter3D,0
mov paused3D,0
mov engineMode,MODE_WALK
call ClearKeys3D
invoke PlayCasinoSound3D,0,0,0
ret
SlotEscape3D ENDP
; A monotonic quadratic ease-out maps elapsed milliseconds to strip pixels.
SlotReelPosition3D PROC uses ebx index:DWORD
mov ebx,index
cmp ebx,2
ja slot_position_zero
mov eax,slotStops3D[ebx*4]
shl eax,6
cmp slotSpinState,SLOT_SPIN
jne slot_position_done
mov eax,slotSpinTimer
cmp eax,slotDurations3D[ebx*4]
jae slot_position_end
shl eax,10
xor edx,edx
div slotDurations3D[ebx*4]
mov ecx,2048
sub ecx,eax
imul eax,ecx
mul slotTravel3D[ebx*4]
shrd eax,edx,20
mov edx,slotStartStops3D[ebx*4]
shl edx,6
add eax,edx
ret
slot_position_end:
mov eax,slotStartStops3D[ebx*4]
shl eax,6
add eax,slotTravel3D[ebx*4]
slot_position_done:
ret
slot_position_zero:
xor eax,eax
ret
SlotReelPosition3D ENDP
SlotExitMouse3D PROC
cmp mouseClick3D,0
je slot_exit_mouse_done
mov mouseClick3D,0
cmp mouseY3D,3
jb slot_exit_mouse_done
cmp mouseY3D,17
jae slot_exit_mouse_done
cmp mouseX3D,252
jb slot_exit_mouse_done
cmp mouseX3D,312
jae slot_exit_mouse_done
call SlotEscape3D
slot_exit_mouse_done:
ret
SlotExitMouse3D ENDP
HandleNativeSlots3D PROC uses ebx
cmp slotSpinState,SLOT_SPIN
jne slot_handle_idle
; Process the header before settlement so the final spin tick cannot eat it.
call SlotExitMouse3D
mov eax,deltaTime3D
cmp eax,250
jbe @F
mov eax,250
@@:
add slotSpinTimer,eax
cmp slotSpinTimer,3000
jb slot_handle_exit_mouse
call SettleNativeSlots3D
ret
slot_handle_idle:
mov eax,deltaTime3D
add slotEffects3D,eax
cmp slotEffects3D,2000
jbe @F
mov slotEffects3D,2000
@@:
cmp slotPaytable3D,0
je slot_handle_controls
invoke Pressed3D,0Dh
test eax,eax
jnz slot_close_paytable
invoke Pressed3D,20h
test eax,eax
jnz slot_close_paytable
invoke Pressed3D,50h
test eax,eax
jnz slot_close_paytable
cmp mouseClick3D,0
je slot_handle_done
mov mouseClick3D,0
cmp mouseY3D,202
jb slot_handle_done
cmp mouseY3D,220
jae slot_handle_done
cmp mouseX3D,112
jb slot_handle_done
cmp mouseX3D,208
jae slot_handle_done
slot_close_paytable:
mov slotPaytable3D,0
ret
slot_handle_controls:
cmp mouseClick3D,0
je slot_handle_keys
cmp mouseY3D,222
jb slot_handle_keys
cmp mouseY3D,238
jae slot_handle_keys
mov mouseClick3D,0
mov eax,mouseX3D
cmp eax,11
jb slot_handle_keys
cmp eax,29
jb slot_bet_down
cmp eax,35
jb slot_handle_keys
cmp eax,53
jb slot_bet_up
cmp eax,120
jb slot_handle_keys
cmp eax,190
jb slot_handle_start
cmp eax,202
jb slot_handle_keys
cmp eax,272
jae slot_handle_keys
mov slotPaytable3D,1
ret
slot_handle_keys:
invoke Pressed3D,50h
test eax,eax
jz @F
mov slotPaytable3D,1
ret
@@:
invoke Pressed3D,57h
test eax,eax
jnz slot_bet_up
invoke Pressed3D,26h
test eax,eax
jnz slot_bet_up
invoke Pressed3D,53h
test eax,eax
jnz slot_bet_down
invoke Pressed3D,28h
test eax,eax
jnz slot_bet_down
invoke Pressed3D,20h
test eax,eax
jnz slot_handle_start
invoke Pressed3D,0Dh
test eax,eax
jz slot_handle_exit_mouse
slot_handle_start:
call StartNativeSlots3D
ret
slot_bet_up:
cmp slotBetIndex3D,6
jae slot_handle_done
inc slotBetIndex3D
jmp slot_bet_changed
slot_bet_down:
cmp slotBetIndex3D,0
je slot_handle_done
dec slotBetIndex3D
slot_bet_changed:
mov ecx,slotBetIndex3D
mov eax,slotBetValues3D[ecx*4]
mov slotBet,eax
mov slotError3D,0
ret
slot_handle_exit_mouse:
call SlotExitMouse3D
slot_handle_done:
ret
HandleNativeSlots3D ENDP
; Clip the 64x64 alpha-tested symbol to its own reel window, not the cabinet.
DrawSlotSymbol3D PROC uses ebx esi edi symbol:DWORD,x:DWORD,y:DWORD
local row:DWORD,lastRow:DWORD,source:DWORD
cmp symbol,7
ja slot_symbol_done
mov eax,slotSymbolsPack3D.pixels
test eax,eax
jz slot_symbol_done
mov ecx,symbol
shl ecx,14
add eax,ecx
mov source,eax
mov eax,y
cmp eax,SLOT_TOP
jge @F
mov eax,SLOT_TOP
@@:
mov row,eax
mov eax,y
add eax,64
cmp eax,SLOT_BOTTOM
jle @F
mov eax,SLOT_BOTTOM
@@:
mov lastRow,eax
slot_symbol_row:
mov eax,row
cmp eax,lastRow
jge slot_symbol_done
mov ecx,eax
sub ecx,y
shl ecx,8
mov esi,source
add esi,ecx
imul eax,640*4
mov ecx,x
lea edi,screenBuffer[eax+ecx*4]
mov ecx,64
slot_symbol_column:
lodsd
test eax,0FF000000h
jz @F
and eax,00FFFFFFh
mov [edi],eax
@@:
add edi,4
dec ecx
jnz slot_symbol_column
inc row
jmp slot_symbol_row
slot_symbol_done:
ret
DrawSlotSymbol3D ENDP
DrawSlotReel3D PROC uses ebx esi edi index:DWORD
local offsetPx:DWORD,baseStop:DWORD,symbolY:DWORD,symbolX:DWORD
invoke SlotReelPosition3D,index
xor edx,edx
mov ecx,64
div ecx
mov offsetPx,edx
xor edx,edx
mov ecx,20
div ecx
mov baseStop,edx
mov ebx,index
mov eax,slotWindows3D[ebx*4]
add eax,12
mov symbolX,eax
mov eax,160
sub eax,offsetPx
sub eax,64
mov symbolY,eax
mov esi,baseStop
add esi,19
xor edi,edi
slot_reel_symbol:
mov eax,esi
xor edx,edx
mov ecx,20
div ecx
mov eax,slotStrip3D[edx*4]
invoke DrawSlotSymbol3D,eax,symbolX,symbolY
add symbolY,64
inc esi
inc edi
cmp edi,4
jb slot_reel_symbol
ret
DrawSlotReel3D ENDP
RenderNativeSlots3D PROC uses ebx esi edi
; The validated cabinet is opaque and already framebuffer-sized.
mov esi,slotCabinetPack3D.pixels
test esi,esi
jz slot_render_done
lea edi,screenBuffer
mov ecx,SCREEN_SIZE
rep movsd
xor esi,esi
slot_render_reels:
invoke DrawSlotReel3D,esi
inc esi
cmp esi,3
jb slot_render_reels
; The payline is fixed at the center of the three physical drums.
invoke DrawBox,86,94,4,3,00E9CE71h
invoke DrawBox,232,94,4,3,00E9CE71h
cmp slotSpinState,SLOT_RESULT
jne slot_render_header
mov eax,slotWinAmount
cmp eax,slotStake3D
jbe slot_render_header
mov eax,slotEffects3D
xor edx,edx
mov ecx,200
div ecx
test eax,1
jnz slot_render_header
invoke DrawBox,90,94,142,1,00E9CE71h
slot_render_header:
invoke DrawBox,0,0,320,19,00151D20h
invoke DrawString8x8,8,6,OFFSET slotTitle3D,00E8D7ADh
invoke DrawString8x8,54,6,OFFSET textBank3D,00A8DDB9h
invoke FormatNumber,bankroll,OFFSET hudNumBuffer
invoke DrawString8x8,103,6,OFFSET hudNumBuffer,00F4F3E8h
invoke DrawBoxBorder,252,3,60,14,002C3637h,00687672h,1
invoke DrawString8x8,258,6,OFFSET cardExitButton3D,00E9D8B0h
mov ebx,OFFSET slotReadyText3D
cmp slotSpinState,SLOT_SPIN
jne @F
mov ebx,OFFSET slotRollingText3D
@@:
cmp slotSpinState,SLOT_RESULT
jne @F
mov ebx,OFFSET slotLoseText3D
mov eax,slotWinAmount
cmp eax,slotStake3D
jb @F
mov ebx,OFFSET slotRefundText3D
je @F
mov ebx,OFFSET slotWinText3D
@@:
cmp slotError3D,0
je @F
mov ebx,OFFSET slotNoMoney3D
@@:
cmp slotLeaveAfter3D,0
je @F
mov ebx,OFFSET slotExitText3D
@@:
; Keep the message on the generated inset plate, with fixed-size numerals.
invoke DrawBox,98,147,126,12,00151D20h
invoke DrawString8x8,104,149,ebx,00E8D7ADh
cmp slotSpinState,SLOT_RESULT
jne slot_render_controls
cmp ebx,OFFSET slotWinText3D
je @F
cmp ebx,OFFSET slotRefundText3D
jne slot_render_controls
@@:
invoke FormatNumber,slotWinAmount,OFFSET hudNumBuffer
invoke DrawString8x8,164,149,OFFSET hudNumBuffer,00A8DDB9h
slot_render_controls:
invoke DrawBox,0,198,320,42,00151D20h
invoke DrawString8x8,11,201,OFFSET slotBetText3D,00E8D7ADh
invoke FormatNumber,slotBet,OFFSET hudNumBuffer
invoke DrawString8x8,75,201,OFFSET hudNumBuffer,00F4F3E8h
cmp slotSpinState,SLOT_RESULT
jne @F
invoke DrawSlotTotals3D,slotWinAmount,slotStake3D,120
@@:
mov ebx,1
cmp slotSpinState,SLOT_SPIN
jne @F
xor ebx,ebx
@@:
mov edi,006D7470h
test ebx,ebx
jz @F
mov edi,00EEE5CDh
@@:
invoke DrawBoxBorder,11,222,18,16,0025372Ch,edi,1
invoke DrawBoxBorder,35,222,18,16,0025372Ch,edi,1
invoke DrawString8x8,16,226,OFFSET tableMinusText3D,edi
invoke DrawString8x8,40,226,OFFSET tablePlusText3D,edi
invoke DrawTableButton3D,120,OFFSET slotSpinText3D,ebx
invoke DrawTableButton3D,202,OFFSET slotPayText3D,ebx
cmp slotPaytable3D,0
je slot_render_done
invoke DrawBoxBorder,30,23,260,198,00151D20h,00D1B16Eh,1
invoke DrawString8x8,76,31,OFFSET slotPayTitle3D,00E8D7ADh
invoke DrawString8x8,42,48,OFFSET slotTripleText3D,00A8DDB9h
xor esi,esi
slot_render_pay_row:
mov edi,esi
imul edi,12
add edi,62
mov eax,slotSymbolNames3D[esi*4]
invoke DrawString8x8,62,edi,eax,00F4F3E8h
invoke FormatNumber,slotTriple3D[esi*4],OFFSET hudNumBuffer
invoke DrawString8x8,212,edi,OFFSET strMultiplier3D,00E8D7ADh
invoke DrawString8x8,220,edi,OFFSET hudNumBuffer,00E8D7ADh
inc esi
cmp esi,8
jb slot_render_pay_row
invoke DrawString8x8,62,160,OFFSET slotPairText3D,00A8DDB9h
invoke DrawString8x8,62,173,OFFSET slotCherryPair3D,00A8DDB9h
invoke DrawString8x8,42,188,OFFSET slotPayNote3D,00A8DDB9h
invoke DrawBoxBorder,112,204,96,15,003B6C59h,00E9D8B0h,1
invoke DrawString8x8,128,207,OFFSET slotCloseText3D,00E9D8B0h
slot_render_done:
ret
RenderNativeSlots3D ENDP
; Gross is the actual credited sum, including any returned stake.
DrawSlotTotals3D PROC uses ebx esi edi gross:DWORD,stake:DWORD,x:DWORD
mov ebx,x
lea edi,[ebx+72]
invoke DrawString8x8,ebx,201,OFFSET slotWinText3D,00E8D7ADh
invoke FormatNumber,gross,OFFSET hudNumBuffer
invoke DrawString8x8,edi,201,OFFSET hudNumBuffer,00F4F3E8h
invoke DrawString8x8,ebx,211,OFFSET slotNetText3D,00E8D7ADh
mov eax,gross
sub eax,stake
mov esi,00D0D4D0h
lea ebx,slotNetBuffer3D
test eax,eax
jz totals_format
mov BYTE PTR [ebx],'+'
mov esi,00A8DDB9h
jns @F
mov BYTE PTR [ebx],'-'
mov esi,00EE9988h
neg eax
@@:
inc ebx
totals_format:
invoke FormatNumber,eax,ebx
invoke DrawString8x8,edi,211,OFFSET slotNetBuffer3D,esi
ret
DrawSlotTotals3D ENDP