KAZIK/src_graphics/native_clover.inc
Artvasil09 881a0061dc Add native NPC visitors with contracts, Clover slots, Pyramid, and party table scenes
Implement 32x32 BFS visitor navigation and daily contracts system with companion .npc journals; add native assembly scenes for Clover slots, Pyramid cards, Blackjack Party and Russian Party; package animation and sprite packs; add comprehensive offline test suites and rebuild shipping binaries.
2026-10-13 09:47:33 +03:00

685 lines
16 KiB
PHP

FreeNativeClover3D PROC
invoke FreeAnimPack3D,OFFSET clpCabinet3D
invoke FreeAnimPack3D,OFFSET clpSymbols3D
ret
FreeNativeClover3D ENDP
InitNativeClover3D PROC
invoke LoadAnimPack3D,OFFSET clpCabinet3D,OFFSET clpCabinetPath3D
test eax,eax
jz clp_init_fail
cmp clpCabinet3D.imageWidth,640
jne clp_init_fail
cmp clpCabinet3D.height,480
jne clp_init_fail
cmp clpCabinet3D.frames,1
jne clp_init_fail
invoke LoadAnimPack3D,OFFSET clpSymbols3D,OFFSET clpSymbolsPath3D
test eax,eax
jz clp_init_fail
cmp clpSymbols3D.imageWidth,CLP_CELL
jne clp_init_fail
cmp clpSymbols3D.height,CLP_CELL
jne clp_init_fail
cmp clpSymbols3D.frames,7
jne clp_init_fail
mov clpState3D,SLOT_READY
mov clpTimer3D,0
mov clpStake3D,0
mov clpGross3D,0
mov clpTotal3D,0
mov clpCount3D,0
mov clpWinMask3D,0
mov clpSelected3D,0
mov clpPaytable3D,0
mov clpLeave3D,0
mov clpError3D,0
mov clpBet3D,50
mov clpBetIndex3D,1
mov paused3D,0
mov cardExitActive3D,0
call ClearKeys3D
mov eax,1
ret
clp_init_fail:
call FreeNativeClover3D
xor eax,eax
ret
InitNativeClover3D ENDP
; Tape contents and final board are frozen at the single stake debit.
StartNativeClover3D PROC uses ebx esi edi
cmp clpState3D,SLOT_SPIN
je clp_start_done
cmp clpPaytable3D,0
jne clp_start_done
cmp clpCabinet3D.pixels,0
je clp_start_done
cmp clpSymbols3D.pixels,0
je clp_start_done
mov eax,clpBet3D
test eax,eax
jz clp_start_done
cmp eax,10000
ja clp_start_done
cmp eax,bankroll
ja clp_start_money
sub bankroll,eax
mov clpStake3D,eax
mov clpState3D,SLOT_SPIN
mov clpTimer3D,0
mov clpGross3D,0
mov clpCount3D,0
mov clpTotal3D,0
mov clpWinMask3D,0
mov clpSelected3D,0
mov clpLeave3D,0
mov clpError3D,0
xor esi,esi
clp_start_column:
mov ebx,esi
shl ebx,8
xor edi,edi
clp_start_tape:
invoke RandomRange3D,7
mov clpTape3D[ebx+edi*4],eax
inc edi
cmp edi,64
jb clp_start_tape
xor edi,edi
clp_start_rows:
mov ecx,edi
imul ecx,5
add ecx,esi
mov eax,clpGrid3D[ecx*4]
mov clpTape3D[ebx+edi*4],eax
invoke RandomRange3D,7
mov clpGrid3D[ecx*4],eax
mov edx,clpSteps3D[esi*4]
add edx,edi
mov clpTape3D[ebx+edx*4],eax
inc edi
cmp edi,3
jb clp_start_rows
inc esi
cmp esi,5
jb clp_start_column
call SaveProgress3D
invoke PlayCasinoSound3D,OFFSET soundSlotSpin,0,1
clp_start_done:
ret
clp_start_money:
mov clpError3D,1
ret
StartNativeClover3D ENDP
; Reuse the original pure assembly evaluator, never the console game or payer.
CloverEvaluate3D PROC uses ebx esi edi
mov clpTotal3D,0
mov clpCount3D,0
mov clpWinMask3D,0
mov clpJackpot3D,0
xor esi,esi
clp_eval_validate:
cmp clpGrid3D[esi*4],6
ja clp_eval_done
inc esi
cmp esi,15
jb clp_eval_validate
lea esi,clpGrid3D
lea edi,slotGrid
mov ecx,15
rep movsd
call EvaluateSlotCombos
mov eax,slotBestMultiplier
mov clpTotal3D,eax
mov eax,slotWinMask
mov clpWinMask3D,eax
mov eax,slotJackpotHit
mov clpJackpot3D,eax
mov eax,slotComboCount
mov clpCount3D,eax
lea esi,slotComboNames
lea edi,clpNames3D
mov ecx,eax
rep movsd
lea esi,slotComboMults
lea edi,clpMults3D
mov ecx,clpCount3D
rep movsd
lea esi,slotComboMasks
lea edi,clpMasks3D
mov ecx,clpCount3D
rep movsd
clp_eval_done:
xor eax,eax
ret
CloverEvaluate3D ENDP
SettleNativeClover3D PROC
cmp clpState3D,SLOT_SPIN
jne clp_settle_done
call CloverEvaluate3D
mov eax,clpTotal3D
mul clpStake3D
mov ecx,1000000000
sub ecx,bankroll
cmp eax,ecx
jbe @F
mov eax,ecx
@@:
mov clpGross3D,eax
add bankroll,eax
mov clpState3D,SLOT_RESULT
mov clpTimer3D,3400
xor eax,eax
mov ecx,clpGross3D
cmp ecx,clpStake3D
seta al
invoke NpcRecordRound3D,4,eax
call SaveProgress3D
mov eax,clpGross3D
cmp eax,clpStake3D
jb clp_settle_loss
jne @F
invoke PlayCasinoSound3D,0,0,0
jmp clp_settle_leave
@@:
invoke PlayCasinoSound3D,OFFSET soundRoundWin,0,1
jmp clp_settle_leave
clp_settle_loss:
invoke PlayCasinoSound3D,OFFSET soundRoundLose,0,1
clp_settle_leave:
cmp clpLeave3D,0
je clp_settle_done
call CloverEscape3D
clp_settle_done:
ret
SettleNativeClover3D ENDP
CloverEscape3D PROC
mov paused3D,0
cmp clpPaytable3D,0
je @F
mov clpPaytable3D,0
call ClearKeys3D
ret
@@:
cmp clpState3D,SLOT_SPIN
jne clp_escape_hall
mov clpLeave3D,1
call ClearKeys3D
ret
clp_escape_hall:
mov clpLeave3D,0
mov engineMode,MODE_WALK
call ClearKeys3D
invoke PlayCasinoSound3D,0,0,0
ret
CloverEscape3D ENDP
CloverReelPosition3D PROC uses ebx index:DWORD
mov ebx,index
xor eax,eax
cmp ebx,4
ja clp_pos_done
cmp clpState3D,SLOT_SPIN
jne clp_pos_end
mov eax,clpTimer3D
cmp eax,clpDurations3D[ebx*4]
jae clp_pos_end
shl eax,10
xor edx,edx
div clpDurations3D[ebx*4]
mov ecx,2048
sub ecx,eax
imul eax,ecx
mov ecx,clpSteps3D[ebx*4]
imul ecx,CLP_CELL
mul ecx
shrd eax,edx,20
ret
clp_pos_end:
mov eax,clpSteps3D[ebx*4]
imul eax,CLP_CELL
clp_pos_done:
ret
CloverReelPosition3D ENDP
HandleNativeClover3D PROC uses ebx
cmp mouseClick3D,0
je clp_handle_tick
mov mouseClick3D,0
mov eax,mouseY3D
cmp eax,3
jb clp_handle_tick
cmp eax,17
jae clp_handle_mouse_controls
cmp mouseX3D,252
jb clp_handle_tick
cmp mouseX3D,312
jae clp_handle_tick
call CloverEscape3D
cmp clpState3D,SLOT_SPIN
je clp_handle_tick
ret
clp_handle_mouse_controls:
cmp clpState3D,SLOT_SPIN
je clp_handle_tick
cmp clpPaytable3D,0
je @F
cmp eax,202
jb clp_handle_tick
cmp eax,220
jae clp_handle_tick
cmp mouseX3D,112
jb clp_handle_tick
cmp mouseX3D,208
jae clp_handle_tick
mov clpPaytable3D,0
ret
@@:
cmp eax,170
jb clp_handle_tick
cmp eax,185
jae clp_handle_mouse_footer
cmp mouseX3D,232
jb clp_handle_tick
cmp mouseX3D,250
jb clp_handle_previous
cmp mouseX3D,292
jb clp_handle_tick
cmp mouseX3D,310
jb clp_handle_next
jmp clp_handle_tick
clp_handle_mouse_footer:
cmp eax,222
jb clp_handle_tick
cmp eax,238
jae clp_handle_tick
mov eax,mouseX3D
cmp eax,11
jb clp_handle_tick
cmp eax,29
jb clp_handle_down
cmp eax,35
jb clp_handle_tick
cmp eax,53
jb clp_handle_up
cmp eax,120
jb clp_handle_tick
cmp eax,190
jb clp_handle_start
cmp eax,202
jb clp_handle_tick
cmp eax,272
jb clp_handle_paytable
clp_handle_tick:
cmp clpState3D,SLOT_SPIN
jne clp_handle_keys
mov eax,deltaTime3D
cmp eax,250
jbe @F
mov eax,250
@@:
add clpTimer3D,eax
cmp clpTimer3D,3400
jb clp_handle_done
call SettleNativeClover3D
ret
clp_handle_keys:
invoke Pressed3D,50h
test eax,eax
jnz clp_handle_paytable
cmp clpPaytable3D,0
je clp_handle_game_keys
invoke Pressed3D,20h
test eax,eax
jnz clp_handle_paytable
invoke Pressed3D,0Dh
test eax,eax
jnz clp_handle_paytable
ret
clp_handle_game_keys:
invoke Pressed3D,25h
test eax,eax
jnz clp_handle_previous
invoke Pressed3D,27h
test eax,eax
jnz clp_handle_next
invoke Pressed3D,57h
test eax,eax
jnz clp_handle_up
invoke Pressed3D,26h
test eax,eax
jnz clp_handle_up
invoke Pressed3D,53h
test eax,eax
jnz clp_handle_down
invoke Pressed3D,28h
test eax,eax
jnz clp_handle_down
invoke Pressed3D,20h
test eax,eax
jnz clp_handle_start
invoke Pressed3D,0Dh
test eax,eax
jz clp_handle_done
clp_handle_start:
call StartNativeClover3D
ret
clp_handle_paytable:
xor clpPaytable3D,1
ret
clp_handle_previous:
cmp clpCount3D,0
je clp_handle_done
cmp clpSelected3D,0
jne @F
mov eax,clpCount3D
mov clpSelected3D,eax
@@:
dec clpSelected3D
ret
clp_handle_next:
cmp clpCount3D,0
je clp_handle_done
inc clpSelected3D
mov eax,clpSelected3D
cmp eax,clpCount3D
jb clp_handle_done
mov clpSelected3D,0
ret
clp_handle_up:
cmp clpBetIndex3D,6
jae clp_handle_done
inc clpBetIndex3D
jmp clp_handle_bet
clp_handle_down:
cmp clpBetIndex3D,0
je clp_handle_done
dec clpBetIndex3D
clp_handle_bet:
mov ecx,clpBetIndex3D
mov eax,slotBetValues3D[ecx*4]
mov clpBet3D,eax
mov clpError3D,0
clp_handle_done:
ret
HandleNativeClover3D ENDP
DrawCloverSymbol3D PROC uses ebx esi edi symbol:DWORD,x:DWORD,y:DWORD
local row:DWORD,lastRow:DWORD,source:DWORD
cmp symbol,6
ja clp_symbol_done
mov eax,clpSymbols3D.pixels
test eax,eax
jz clp_symbol_done
mov ecx,symbol
imul ecx,CLP_CELL*CLP_CELL*4
add eax,ecx
mov source,eax
mov eax,y
cmp eax,CLP_TOP
jge @F
mov eax,CLP_TOP
@@:
mov row,eax
mov eax,y
add eax,CLP_CELL
cmp eax,CLP_BOTTOM
jle @F
mov eax,CLP_BOTTOM
@@:
mov lastRow,eax
clp_symbol_row:
mov eax,row
cmp eax,lastRow
jge clp_symbol_done
mov ecx,eax
sub ecx,y
imul ecx,CLP_CELL*4
mov esi,source
add esi,ecx
imul eax,640*4
mov ecx,x
lea edi,screenBuffer[eax+ecx*4]
mov ecx,CLP_CELL
clp_symbol_column:
lodsd
test eax,0FF000000h
jz @F
and eax,00FFFFFFh
mov [edi],eax
@@:
add edi,4
dec ecx
jnz clp_symbol_column
inc row
jmp clp_symbol_row
clp_symbol_done:
ret
DrawCloverSymbol3D ENDP
DrawCloverReel3D PROC uses ebx esi edi index:DWORD
local symbolY:DWORD,baseStop:DWORD,columnX:DWORD
mov ebx,index
mov eax,clpColumns3D[ebx*4]
mov columnX,eax
cmp clpState3D,SLOT_SPIN
jne clp_reel_static
invoke CloverReelPosition3D,ebx
xor edx,edx
mov ecx,CLP_CELL
div ecx
mov baseStop,eax
mov eax,CLP_TOP
sub eax,edx
mov symbolY,eax
shl ebx,8
xor esi,esi
clp_reel_tape:
mov ecx,baseStop
add ecx,esi
mov eax,clpTape3D[ebx+ecx*4]
invoke DrawCloverSymbol3D,eax,columnX,symbolY
add symbolY,CLP_CELL
inc esi
cmp esi,4
jb clp_reel_tape
ret
clp_reel_static:
mov symbolY,CLP_TOP
xor esi,esi
clp_reel_rows:
mov ecx,esi
imul ecx,5
add ecx,ebx
mov eax,clpGrid3D[ecx*4]
invoke DrawCloverSymbol3D,eax,columnX,symbolY
add symbolY,CLP_CELL
inc esi
cmp esi,3
jb clp_reel_rows
ret
DrawCloverReel3D ENDP
CloverComboText3D PROC index:DWORD
mov ecx,index
cmp ecx,clpCount3D
jae clp_combo_none
mov edx,clpNames3D[ecx*4]
xor ecx,ecx
clp_combo_lookup:
cmp edx,clpLegacyNames3D[ecx*4]
je clp_combo_found
inc ecx
cmp ecx,11
jb clp_combo_lookup
clp_combo_none:
mov eax,OFFSET clpNoCombo3D
ret
clp_combo_found:
mov eax,clpShapeNames3D[ecx*4]
ret
CloverComboText3D ENDP
RenderNativeClover3D PROC uses ebx esi edi
local cellX:DWORD,cellY:DWORD,selectedMask:DWORD
mov esi,clpCabinet3D.pixels
test esi,esi
jz clp_render_done
lea edi,screenBuffer
mov ecx,SCREEN_SIZE
rep movsd
xor esi,esi
clp_render_reels:
mov ebx,clpColumns3D[esi*4]
shr ebx,1
invoke DrawBoxBorder,ebx,63,28,84,000D1816h,00405A46h,1
invoke DrawCloverReel3D,esi
inc esi
cmp esi,5
jb clp_render_reels
cmp clpState3D,SLOT_RESULT
jne clp_render_header
mov ecx,clpSelected3D
cmp ecx,clpCount3D
jae clp_render_header
mov eax,clpMasks3D[ecx*4]
mov selectedMask,eax
xor esi,esi
clp_render_highlight:
mov eax,1
mov ecx,esi
shl eax,cl
test selectedMask,eax
jz clp_render_next_cell
mov eax,esi
xor edx,edx
mov ecx,5
div ecx
imul eax,28
add eax,63
mov cellY,eax
mov ebx,clpColumns3D[edx*4]
shr ebx,1
mov cellX,ebx
; Border strips do not paint over the transparent symbol interior.
invoke DrawBox,ebx,cellY,28,1,00E9CE71h
mov eax,cellY
add eax,27
invoke DrawBox,ebx,eax,28,1,00E9CE71h
invoke DrawBox,ebx,cellY,1,28,00E9CE71h
add ebx,27
invoke DrawBox,ebx,cellY,1,28,00E9CE71h
clp_render_next_cell:
inc esi
cmp esi,15
jb clp_render_highlight
clp_render_header:
invoke DrawBox,0,0,320,19,00151D20h
invoke DrawString8x8,8,6,OFFSET clpTitle3D,00E8D7ADh
invoke DrawString8x8,108,6,OFFSET textBank3D,00A8DDB9h
invoke FormatNumber,bankroll,OFFSET hudNumBuffer
invoke DrawString8x8,157,6,OFFSET hudNumBuffer,00F4F3E8h
invoke DrawBoxBorder,252,3,60,14,002C3637h,00687672h,1
invoke DrawString8x8,258,6,OFFSET cardExitButton3D,00E9D8B0h
invoke DrawBox,63,160,194,26,00151D20h
mov ebx,OFFSET slotReadyText3D
cmp clpState3D,SLOT_SPIN
jne @F
mov ebx,OFFSET slotRollingText3D
@@:
cmp clpState3D,SLOT_RESULT
jne @F
mov ebx,OFFSET clpNoCombo3D
cmp clpCount3D,0
je @F
mov ebx,OFFSET clpTotalText3D
@@:
cmp clpError3D,0
je @F
mov ebx,OFFSET slotNoMoney3D
@@:
cmp clpLeave3D,0
je @F
mov ebx,OFFSET slotExitText3D
@@:
invoke DrawString8x8,72,163,ebx,00E8D7ADh
cmp clpState3D,SLOT_RESULT
jne clp_render_footer
cmp clpCount3D,0
je clp_render_footer
invoke DrawString8x8,208,163,OFFSET strMultiplier3D,00A8DDB9h
invoke FormatNumber,clpTotal3D,OFFSET hudNumBuffer
invoke DrawString8x8,216,163,OFFSET hudNumBuffer,00A8DDB9h
invoke CloverComboText3D,clpSelected3D
invoke DrawString8x8,72,175,eax,00F4F3E8h
mov ecx,clpSelected3D
invoke FormatNumber,clpMults3D[ecx*4],OFFSET hudNumBuffer
invoke DrawString8x8,208,175,OFFSET strMultiplier3D,00E9CE71h
invoke DrawString8x8,216,175,OFFSET hudNumBuffer,00E9CE71h
invoke DrawBoxBorder,232,170,18,15,0025372Ch,00E9CE71h,1
invoke DrawBoxBorder,292,170,18,15,0025372Ch,00E9CE71h,1
invoke DrawString8x8,237,174,OFFSET clpLeft3D,00E9CE71h
invoke DrawString8x8,297,174,OFFSET clpRight3D,00E9CE71h
mov eax,clpSelected3D
inc eax
invoke FormatNumber,eax,OFFSET hudNumBuffer
invoke DrawString8x8,252,174,OFFSET hudNumBuffer,00F4F3E8h
invoke DrawString8x8,268,174,OFFSET clpSlash3D,00F4F3E8h
invoke FormatNumber,clpCount3D,OFFSET hudNumBuffer
invoke DrawString8x8,276,174,OFFSET hudNumBuffer,00F4F3E8h
clp_render_footer:
invoke DrawBox,0,198,320,42,00151D20h
invoke DrawString8x8,11,201,OFFSET slotBetText3D,00E8D7ADh
invoke FormatNumber,clpBet3D,OFFSET hudNumBuffer
invoke DrawString8x8,75,201,OFFSET hudNumBuffer,00F4F3E8h
cmp clpState3D,SLOT_RESULT
jne @F
invoke DrawSlotTotals3D,clpGross3D,clpStake3D,120
@@:
mov ebx,1
cmp clpState3D,SLOT_SPIN
jne @F
xor ebx,ebx
@@:
invoke DrawBoxBorder,11,222,18,16,0025372Ch,00EEE5CDh,1
invoke DrawBoxBorder,35,222,18,16,0025372Ch,00EEE5CDh,1
invoke DrawString8x8,16,226,OFFSET tableMinusText3D,00EEE5CDh
invoke DrawString8x8,40,226,OFFSET tablePlusText3D,00EEE5CDh
invoke DrawTableButton3D,120,OFFSET slotSpinText3D,ebx
invoke DrawTableButton3D,202,OFFSET slotPayText3D,ebx
cmp clpPaytable3D,0
je clp_render_done
invoke DrawBoxBorder,18,22,284,200,00151D20h,00D1B16Eh,1
invoke DrawString8x8,76,29,OFFSET slotPayTitle3D,00E8D7ADh
invoke DrawString8x8,28,44,OFFSET clpSymbolsText3D,00A8DDB9h
invoke DrawString8x8,164,44,OFFSET clpShapesText3D,00A8DDB9h
xor esi,esi
clp_render_pay_row:
mov edi,esi
imul edi,11
add edi,58
mov eax,clpShapeNames3D[esi*4]
invoke DrawString8x8,156,edi,eax,00F4F3E8h
invoke FormatNumber,clpShapeFactors3D[esi*4],OFFSET hudNumBuffer
invoke DrawString8x8,280,edi,OFFSET hudNumBuffer,00E8D7ADh
cmp esi,7
jae clp_render_pay_next
mov eax,clpSymbolNames3D[esi*4]
invoke DrawString8x8,28,edi,eax,00F4F3E8h
invoke FormatNumber,slotSymbolValues[esi*4],OFFSET hudNumBuffer
invoke DrawString8x8,132,edi,OFFSET hudNumBuffer,00E8D7ADh
clp_render_pay_next:
inc esi
cmp esi,11
jb clp_render_pay_row
invoke DrawString8x8,28,181,OFFSET clpOverlapText3D,00A8DDB9h
invoke DrawString8x8,28,193,OFFSET slotPayNote3D,00A8DDB9h
invoke DrawBoxBorder,112,204,96,15,003B6C59h,00E9D8B0h,1
invoke DrawString8x8,128,207,OFFSET slotCloseText3D,00E9D8B0h
clp_render_done:
ret
RenderNativeClover3D ENDP