KAZIK/src_graphics/scratch.inc

1234 lines
28 KiB
PHP

; Scratch-off state, coating masks, pointer capture and rendering are all MASM.
LoadScratchArt3D PROC
cmp scrReady3D,1
je scratch_art_ok
invoke LoadAnimPack3D,OFFSET scrTicketArt3D,OFFSET scrTicketPath3D
invoke LoadAnimPack3D,OFFSET scrTableArt3D,OFFSET scrTablePath3D
invoke LoadAnimPack3D,OFFSET scrCoinArt3D,OFFSET scrCoinPath3D
invoke LoadAnimPack3D,OFFSET scrFoilArt3D,OFFSET scrFoilPath3D
invoke LoadAnimPack3D,OFFSET scrSymbolsArt3D,OFFSET clpSymbolsPath3D
invoke LoadAnimPack3D,OFFSET scrCounterArt3D,OFFSET scrCounterPath3D
invoke LoadAnimPack3D,OFFSET scrPortraitArt3D,OFFSET scrPortraitPath3D
invoke LoadAnimPack3D,OFFSET scrPortraitMap3D,OFFSET scrPortraitMapPath3D
invoke LoadAnimPack3D,OFFSET scrPayoutArt3D,OFFSET scrPayoutPath3D
invoke ValidateCityPack3D,OFFSET scrPayoutArt3D,96,72,1
invoke ValidateCityPack3D,OFFSET scrTicketArt3D,448,288,4
invoke ValidateCityPack3D,OFFSET scrTableArt3D,640,480,1
invoke ValidateCityPack3D,OFFSET scrCoinArt3D,64,64,4
invoke ValidateCityPack3D,OFFSET scrFoilArt3D,SCR_W,SCR_H,1
invoke ValidateCityPack3D,OFFSET scrSymbolsArt3D,56,56,7
invoke ValidateCityPack3D,OFFSET scrCounterArt3D,224,240,1
invoke ValidateCityPack3D,OFFSET scrPortraitArt3D,540,720,3
invoke ValidateCityPack3D,OFFSET scrPortraitMap3D,540,720,3
cmp scrPortraitArt3D.pixels,0
je scratch_art_fail
cmp scrPortraitMap3D.pixels,0
je scratch_art_fail
cmp scrTicketArt3D.pixels,0
je scratch_art_fail
cmp scrCoinArt3D.pixels,0
je scratch_art_fail
cmp scrSymbolsArt3D.pixels,0
je scratch_art_fail
cmp scrFoilArt3D.pixels,0
je scratch_art_fail
mov scrReady3D,1
scratch_art_ok:
mov eax,1
ret
scratch_art_fail:
call FreeScratchArt3D
xor eax,eax
ret
LoadScratchArt3D ENDP
FreeScratchArt3D PROC
invoke FreeAnimPack3D,OFFSET scrTicketArt3D
invoke FreeAnimPack3D,OFFSET scrTableArt3D
invoke FreeAnimPack3D,OFFSET scrCoinArt3D
invoke FreeAnimPack3D,OFFSET scrFoilArt3D
invoke FreeAnimPack3D,OFFSET scrSymbolsArt3D
invoke FreeAnimPack3D,OFFSET scrCounterArt3D
invoke FreeAnimPack3D,OFFSET scrPortraitArt3D
invoke FreeAnimPack3D,OFFSET scrPortraitMap3D
invoke FreeAnimPack3D,OFFSET scrPayoutArt3D
mov scrReady3D,0
ret
FreeScratchArt3D ENDP
ScratchCancelStroke3D PROC
mov scrLastValid3D,0
cmp scrHeld3D,0
je scratch_cancel_done
mov scrHeld3D,0
invoke ReleaseCapture
scratch_cancel_done:
ret
ScratchCancelStroke3D ENDP
BeginScratch3D PROC
mov scrCatalog3D,0
call LoadScratchArt3D
cmp scrState3D,0
jne @F
call ScratchConfigure3D
@@:
mov engineMode,MODE_SCRATCH
mov paused3D,0
mov scrError3D,0
mov scrNewPixels3D,0
mov scrPointerValid3D,0
call ClearKeys3D
ret
BeginScratch3D ENDP
LeaveScratch3D PROC
cmp scrCatalog3D,0
je @F
mov scrCatalog3D,0
call ClearKeys3D
ret
@@:
call ScratchCancelStroke3D
mov scrDealMs3D,0
mov scrPayoutMs3D,0
mov engineMode,MODE_WALK
mov paused3D,0
call ClearKeys3D
call SaveProgress3D
ret
LeaveScratch3D ENDP
; One mask format serves rectangular, circular and single-area tickets.
ScratchConfigure3D PROC uses ebx esi edi
local rowY:DWORD,pointX:DWORD
mov scrDealMs3D,0
mov scrPayoutMs3D,0
mov scrDustStep3D,0
mov scrScrapeCooldown3D,0
mov scrNewPixels3D,0
mov scrDustIndex3D,0
lea edi,scrDustLife3D
xor eax,eax
mov ecx,SCR_DUST_COUNT
rep stosd
lea edi,scrCounts3D
mov ecx,48
rep stosd
cmp scrType3D,4
jb @F
call ScratchConfigurePortrait3D
ret
@@:
mov scrCellCount3D,9
mov scrCellW3D,SCR_W
mov scrCellH3D,SCR_H
cmp scrType3D,1
jne @F
mov scrCellH3D,34
@@:
cmp scrType3D,2
jne @F
mov scrCellW3D,44
mov scrCellH3D,44
@@:
cmp scrType3D,3
jne @F
mov scrCellCount3D,1
mov scrCellW3D,240
mov scrCellH3D,120
@@:
lea edi,scrMask3D
xor eax,eax
mov ecx,9*SCR_MASK_AREA
rep stosb
lea edi,scrCounts3D
mov ecx,48
rep stosd
xor ebx,ebx
xor esi,esi
scratch_config_cell:
imul edi,esi,SCR_MASK_AREA
add edi,OFFSET scrMask3D
mov rowY,0
scratch_config_row:
mov pointX,0
scratch_config_pixel:
cmp scrType3D,2
jne scratch_config_opaque
mov eax,pointX
sub eax,21
imul eax,eax
mov edx,rowY
sub edx,21
imul edx,edx
add eax,edx
cmp eax,21*21
ja scratch_config_next
scratch_config_opaque:
mov BYTE PTR [edi],255
cmp esi,0
jne scratch_config_next
inc ebx
scratch_config_next:
inc edi
inc pointX
mov eax,pointX
cmp eax,scrCellW3D
jb scratch_config_pixel
inc rowY
mov eax,rowY
cmp eax,scrCellH3D
jb scratch_config_row
inc esi
cmp esi,scrCellCount3D
jb scratch_config_cell
mov scrCellArea3D,ebx
imul eax,ebx,72
xor edx,edx
mov ecx,100
div ecx
mov scrRevealAt3D,eax
ret
ScratchConfigure3D ENDP
ScratchSelectType3D PROC kind:DWORD
cmp scrState3D,1
je scratch_select_done
mov eax,kind
cmp eax,-1
jne @F
mov eax,6
@@:
cmp eax,7
jb @F
xor eax,eax
@@:
cmp eax,scrType3D
je scratch_select_done
mov scrType3D,eax
mov scrState3D,0
mov scrOpened3D,0
mov scrGross3D,0
mov scrError3D,0
mov scrZoom3D,0
call ScratchCancelStroke3D
call ScratchConfigure3D
scratch_select_done:
ret
ScratchSelectType3D ENDP
; A paid ticket is immutable. Losing tickets never accidentally contain a
; triple; winning tickets contain exactly one triple. Shuffle only at purchase.
BuyScratch3D PROC uses ebx esi edi
cmp scrState3D,1
je scratch_buy_done
cmp scrReady3D,1
jne scratch_buy_done
mov ecx,scrPriceIndex3D
cmp ecx,2
ja scratch_buy_done
mov eax,scrPrices3D[ecx*4]
cmp bankroll,eax
jb scratch_buy_poor
mov scrStake3D,eax
sub bankroll,eax
mov scrState3D,1
mov scrGross3D,0
mov scrOpened3D,0
mov scrError3D,0
mov scrPrizeSymbol3D,-1
call ScratchConfigure3D
cmp scrType3D,4
jb @F
call ScratchBuildPortrait3D
mov scrZoom3D,1
jmp scratch_buy_save
@@:
invoke RandomRange3D,1000
push eax
call BackroomsLuck3D
pop edx
cmp eax,-1
je br_scratch_original
imul eax,650
jmp br_scratch_fixed
br_scratch_original:
mov eax,edx
br_scratch_fixed:
cmp eax,600
jb scratch_losing_bag
xor esi,esi
scratch_pick_prize:
cmp eax,scrCutoffs3D[esi*4]
jb scratch_prize_picked
inc esi
jmp scratch_pick_prize
scratch_prize_picked:
mov scrPrizeSymbol3D,esi
mov eax,scrMultipliers3D[esi*4]
imul eax,scrStake3D
mov scrGross3D,eax
mov scrBag3D,esi
mov scrBag3D[4],esi
mov scrBag3D[8],esi
mov edi,3
xor ebx,ebx
scratch_win_fill:
cmp ebx,esi
je @F
mov scrBag3D[edi*4],ebx
inc edi
@@:
inc ebx
cmp ebx,7
jb scratch_win_fill
mov esi,8
jmp scratch_shuffle
scratch_losing_bag:
xor esi,esi
scratch_loss_fill:
mov eax,esi
shr eax,1
mov scrBag3D[esi*4],eax
inc esi
cmp esi,14
jb scratch_loss_fill
mov esi,13
scratch_shuffle:
lea eax,[esi+1]
invoke RandomRange3D,eax
mov ebx,scrBag3D[esi*4]
mov edx,scrBag3D[eax*4]
mov scrBag3D[esi*4],edx
mov scrBag3D[eax*4],ebx
dec esi
jnz scratch_shuffle
lea esi,scrBag3D
lea edi,scrGrid3D
mov ecx,9
rep movsd
call ScratchBuildVariant3D
scratch_buy_save:
call ScratchCancelStroke3D
call ScratchStartDeal3D
call SaveProgress3D
scratch_buy_done:
ret
scratch_buy_poor:
mov scrError3D,1
ret
BuyScratch3D ENDP
ScratchBuildVariant3D PROC uses ebx esi edi
local rowStart:DWORD
cmp scrType3D,1
je scratch_numbers_build
cmp scrType3D,2
jne scratch_variant_done
cmp scrPrizeSymbol3D,-1
je scratch_variant_done
; Preserve the shuffled six distinct nonwinning symbols, put the triple
; in exactly one horizontal row. No diagonal or scattered triple pays.
xor esi,esi
xor edi,edi
scratch_row_collect:
mov eax,scrGrid3D[esi*4]
cmp eax,scrPrizeSymbol3D
je @F
mov scrBag3D[edi*4],eax
inc edi
@@:
inc esi
cmp esi,9
jb scratch_row_collect
invoke RandomRange3D,3
imul eax,3
mov rowStart,eax
xor esi,esi
xor edi,edi
scratch_row_place:
mov eax,esi
sub eax,rowStart
cmp eax,3
jb scratch_row_winner
mov eax,scrBag3D[edi*4]
inc edi
jmp scratch_row_store
scratch_row_winner:
mov eax,scrPrizeSymbol3D
scratch_row_store:
mov scrGrid3D[esi*4],eax
inc esi
cmp esi,9
jb scratch_row_place
ret
scratch_numbers_build:
xor esi,esi
scratch_number_pool:
lea eax,[esi+1]
mov scrBag3D[esi*4],eax
inc esi
cmp esi,30
jb scratch_number_pool
mov esi,29
scratch_number_shuffle:
lea eax,[esi+1]
invoke RandomRange3D,eax
mov ebx,scrBag3D[esi*4]
mov edx,scrBag3D[eax*4]
mov scrBag3D[esi*4],edx
mov scrBag3D[eax*4],ebx
dec esi
jnz scratch_number_shuffle
xor esi,esi
scratch_number_copy:
mov eax,scrBag3D[esi*4]
mov scrGrid3D[esi*4],eax
invoke RandomRange3D,7
mov eax,scrMultipliers3D[eax*4]
imul eax,scrStake3D
mov scrCellPrizes3D[esi*4],eax
inc esi
cmp esi,9
jb scratch_number_copy
cmp scrGross3D,0
je scratch_variant_done
invoke RandomRange3D,6
lea esi,[eax+3]
invoke RandomRange3D,3
mov eax,scrGrid3D[eax*4]
mov scrGrid3D[esi*4],eax
mov eax,scrGross3D
mov scrCellPrizes3D[esi*4],eax
scratch_variant_done:
ret
ScratchBuildVariant3D ENDP
FinishScratch3D PROC
cmp scrState3D,1
jne scratch_finish_done
mov eax,scrCellCount3D
cmp scrOpened3D,eax
jne scratch_finish_done
; Mark paid before invoking persistence; repeated clicks cannot pay twice.
mov scrState3D,2
mov eax,bankroll
add eax,scrGross3D
cmp eax,1000000000
jbe @F
mov eax,1000000000
@@:
mov bankroll,eax
mov ecx, scrGross3D
cmp ecx, scrStake3D
ja scratch_charm_win
je @F
mov eax,scrStake3D
sub eax,scrGross3D
invoke TriggerCharmLossProtection,eax
jmp @F
scratch_charm_win:
mov eax,scrGross3D
sub eax,scrStake3D
invoke TriggerCharmWinBonus,eax
@@:
call ScratchStartPayout3D
call SaveProgress3D
scratch_finish_done:
ret
FinishScratch3D ENDP
; A normal application close settles an already-paid ticket, even if the
; player has since returned to another table. No pending prize is discarded.
SettleScratchOnQuit3D PROC
cmp scrState3D,1
jne scratch_quit_done
mov eax,scrCellCount3D
mov scrOpened3D,eax
call FinishScratch3D
scratch_quit_done:
ret
SettleScratchOnQuit3D ENDP
ScratchCellOrigin3D PROC cell:DWORD
cmp scrType3D,4
jb @F
invoke ScratchPortraitBounds3D,cell
ret
@@:
cmp scrType3D,3
jne @F
mov eax,200
mov edx,176
ret
@@:
mov eax,cell
xor edx,edx
mov ecx,3
div ecx
imul eax,SCR_DY
add eax,SCR_Y
imul edx,SCR_DX
add edx,SCR_X
xchg eax,edx
cmp scrType3D,1
jne @F
add edx,8
@@:
cmp scrType3D,2
jne @F
add eax,30
@@:
ret
ScratchCellOrigin3D ENDP
ScratchErasePixel3D PROC uses ebx esi edi px:DWORD,py:DWORD
cmp scrDealMs3D,0
jne scratch_pixel_done
cmp scrState3D,1
jne scratch_pixel_done
cmp scrType3D,4
jb @F
invoke ScratchErasePortrait3D,px,py
ret
@@:
xor esi,esi
scratch_pixel_find:
invoke ScratchCellOrigin3D,esi
mov ebx,px
sub ebx,eax
cmp ebx,scrCellW3D
jae scratch_pixel_next_cell
mov eax,py
sub eax,edx
cmp eax,scrCellH3D
jb scratch_pixel_found
scratch_pixel_next_cell:
inc esi
cmp esi,scrCellCount3D
jb scratch_pixel_find
ret
scratch_pixel_found:
cmp scrRevealed3D[esi*4],0
jne scratch_pixel_done
imul eax,scrCellW3D
mov edx,eax
add edx,ebx
imul edi,esi,SCR_MASK_AREA
add edx,edi
cmp scrMask3D[edx],0
je scratch_pixel_done
mov scrMask3D[edx],0
inc scrNewPixels3D
inc scrCounts3D[esi*4]
mov eax,scrRevealAt3D
cmp scrCounts3D[esi*4],eax
jb scratch_pixel_done
mov scrRevealed3D[esi*4],1
mov eax,scrCellArea3D
mov scrCounts3D[esi*4],eax
add edi,OFFSET scrMask3D
mov ecx,SCR_MASK_AREA
xor eax,eax
rep stosb
inc scrOpened3D
call FinishScratch3D
scratch_pixel_done:
ret
ScratchErasePixel3D ENDP
; A narrow ellipse matches the scraping rim, rather than a circular eraser.
ScratchStamp3D PROC uses ebx esi brushX:DWORD,brushY:DWORD
mov esi,-4
scratch_stamp_y:
mov ebx,-10
scratch_stamp_x:
mov eax,ebx
imul eax,eax
imul eax,16
mov edx,esi
imul edx,edx
imul edx,100
add eax,edx
cmp eax,1600
ja scratch_stamp_next
mov eax,brushX
add eax,ebx
mov edx,brushY
add edx,esi
invoke ScratchErasePixel3D,eax,edx
scratch_stamp_next:
inc ebx
cmp ebx,10
jle scratch_stamp_x
inc esi
cmp esi,4
jle scratch_stamp_y
ret
ScratchStamp3D ENDP
ScratchStroke3D PROC uses ebx esi edi x0:DWORD,y0:DWORD,x1:DWORD,y1:DWORD
local deltaX:DWORD,deltaY:DWORD,steps:DWORD,px:DWORD
mov eax,x1
sub eax,x0
mov deltaX,eax
cdq
xor eax,edx
sub eax,edx
mov ebx,eax
mov eax,y1
sub eax,y0
mov deltaY,eax
cdq
xor eax,edx
sub eax,edx
cmp eax,ebx
jbe @F
mov ebx,eax
@@:
mov eax,ebx
xor edx,edx
mov ecx,3
div ecx
inc eax
mov steps,eax
xor esi,esi
scratch_stroke_step:
mov eax,deltaX
imul eax,esi
cdq
idiv steps
add eax,x0
mov px,eax
mov eax,deltaY
imul eax,esi
cdq
idiv steps
add eax,y0
invoke ScratchStamp3D,px,eax
inc esi
cmp esi,steps
jbe scratch_stroke_step
ret
ScratchStroke3D ENDP
ScratchApplyPointer3D PROC
cmp scrDealMs3D,0
jne scratch_apply_reset
cmp scrCatalog3D,0
jne scratch_apply_reset
cmp scrHeld3D,1
jne scratch_apply_reset
cmp scrPointerValid3D,1
jne scratch_apply_reset
cmp scrState3D,1
jne scratch_apply_reset
cmp scrLastValid3D,1
je @F
mov eax,scrPointerX3D
mov scrLastX3D,eax
mov eax,scrPointerY3D
mov scrLastY3D,eax
@@:
invoke ScratchStroke3D,scrLastX3D,scrLastY3D,scrPointerX3D,scrPointerY3D
mov eax,scrPointerX3D
mov scrLastX3D,eax
mov eax,scrPointerY3D
mov scrLastY3D,eax
mov scrLastValid3D,1
ret
scratch_apply_reset:
mov scrLastValid3D,0
ret
ScratchApplyPointer3D ENDP
; Return 1 only for messages owned by this scene. Other games retain their
; existing logical pointer coordinates and click behaviour unchanged.
ScratchMouseEvent3D PROC uses ebx hwnd:DWORD,msg:DWORD,wp:DWORD,lp:DWORD
cmp msg,20Ah
jne @F
cmp scrDealMs3D,0
jne scratch_event_yes
cmp scrType3D,4
jb scratch_event_yes
movsx eax,WORD PTR wp[2]
test eax,eax
jz scratch_event_yes
setg al
movzx eax,al
cmp eax,scrZoom3D
je scratch_event_yes
mov scrZoom3D,eax
call ScratchCancelStroke3D
jmp scratch_event_yes
@@:
cmp msg,20h
jne @F
cmp scrPointerValid3D,1
jne scratch_event_no
invoke SetCursor,0
jmp scratch_event_yes
@@:
cmp msg,215h
je scratch_event_lost
cmp msg,8
jne @F
call ScratchCancelStroke3D
mov scrPointerValid3D,0
jmp scratch_event_no
@@:
cmp msg,202h
jne @F
call ScratchCancelStroke3D
jmp scratch_event_yes
@@:
cmp msg,200h
je scratch_event_position
cmp msg,201h
je scratch_event_position
cmp msg,203h
jne scratch_event_no
scratch_event_position:
mov scrPointerValid3D,0
cmp viewWidth3D,0
je scratch_event_invalid
cmp viewHeight3D,0
je scratch_event_invalid
movsx eax,WORD PTR lp
sub eax,viewLeft3D
cmp eax,viewWidth3D
jae scratch_event_invalid
imul eax,640
xor edx,edx
div viewWidth3D
mov scrPointerX3D,eax
movsx eax,WORD PTR lp[2]
sub eax,viewTop3D
cmp eax,viewHeight3D
jae scratch_event_invalid
imul eax,480
xor edx,edx
div viewHeight3D
mov scrPointerY3D,eax
mov scrPointerValid3D,1
cmp msg,200h
je scratch_event_move
mov scrClick3D,1
mov eax,scrPointerX3D
mov scrClickX3D,eax
mov eax,scrPointerY3D
mov scrClickY3D,eax
mov scrHeld3D,1
mov scrLastValid3D,0
invoke SetCapture,hwnd
call ScratchApplyPointer3D
jmp scratch_event_yes
scratch_event_move:
test wp,1
jz @F
; Process every event, including a complete quick gesture between ticks.
call ScratchApplyPointer3D
jmp scratch_event_yes
@@:
call ScratchCancelStroke3D
jmp scratch_event_yes
scratch_event_invalid:
mov scrLastValid3D,0
jmp scratch_event_yes
scratch_event_lost:
mov scrHeld3D,0
mov scrLastValid3D,0
scratch_event_yes:
mov eax,1
ret
scratch_event_no:
xor eax,eax
ret
ScratchMouseEvent3D ENDP
HandleScratch3D PROC uses ebx esi
call ScratchTickVisuals3D
cmp scrCatalog3D,0
je @F
call HandleScratchCatalog3D
ret
@@:
cmp scrClick3D,0
je scratch_keys
mov scrClick3D,0
cmp scrClickY3D,6
jb scratch_keys
cmp scrClickY3D,34
jae scratch_footer_hit
cmp scrClickX3D,504
jb scratch_keys
cmp scrClickX3D,624
jae scratch_keys
call LeaveScratch3D
ret
scratch_footer_hit:
cmp scrClickY3D,46
jb scratch_keys
cmp scrClickY3D,76
jae scratch_footer_buttons
cmp scrClickX3D,348
jb scratch_keys
cmp scrClickX3D,624
jae scratch_keys
call ScratchCancelStroke3D
mov scrCatalog3D,1
mov scrCatalogLocked3D,0
ret
scratch_footer_buttons:
cmp scrClickY3D,436
jb scratch_keys
cmp scrClickY3D,472
jae scratch_keys
cmp scrClickX3D,384
jb scratch_price_hit
cmp scrClickX3D,624
jae scratch_keys
call BuyScratch3D
jmp scratch_keys
scratch_price_hit:
cmp scrType3D,4
jb @F
cmp scrClickX3D,344
jb @F
cmp scrClickX3D,376
jae @F
call ScratchToggleZoom3D
jmp scratch_keys
@@:
cmp scrState3D,1
je scratch_keys
mov eax,scrClickX3D
sub eax,16
js scratch_keys
xor edx,edx
mov ecx,108
div ecx
cmp eax,2
ja scratch_keys
cmp edx,100
jae scratch_keys
mov scrPriceIndex3D,eax
mov scrError3D,0
scratch_keys:
invoke Pressed3D,5Ah
test eax,eax
jz @F
call ScratchToggleZoom3D
@@:
invoke Pressed3D,25h
test eax,eax
jz @F
mov eax,scrType3D
dec eax
invoke ScratchSelectType3D,eax
@@:
invoke Pressed3D,27h
test eax,eax
jz @F
mov eax,scrType3D
inc eax
invoke ScratchSelectType3D,eax
@@:
mov ebx,31h
scratch_price_key:
invoke Pressed3D,ebx
test eax,eax
jz @F
cmp scrState3D,1
je @F
mov eax,ebx
sub eax,31h
mov scrPriceIndex3D,eax
mov scrError3D,0
@@:
inc ebx
cmp ebx,33h
jbe scratch_price_key
invoke Pressed3D,20h
test eax,eax
jz scratch_draw_stroke
call BuyScratch3D
scratch_draw_stroke:
call ScratchApplyPointer3D
cmp scrNewPixels3D,0
je scratch_handle_done
call ScratchSpawnDust3D
mov scrNewPixels3D,0
ret
scratch_handle_done:
ret
HandleScratch3D ENDP
ScratchDrawContent3D PROC uses ebx esi edi cell:DWORD,originX:DWORD,originY:DWORD
local textX:DWORD,textY:DWORD,ink:DWORD
mov esi,cell
cmp scrType3D,1
je scratch_content_number
cmp scrType3D,3
je scratch_content_instant
cmp scrState3D,2
jne @F
mov eax,scrGrid3D[esi*4]
cmp eax,scrPrizeSymbol3D
jne @F
mov eax,originX
shr eax,1
mov textX,eax
mov eax,originY
shr eax,1
mov textY,eax
mov eax,scrCellW3D
shr eax,1
mov edx,scrCellH3D
shr edx,1
invoke DrawBoxBorder,textX,textY,eax,edx,00F2EAD0h,00056837h,1
@@:
mov ebx,38
cmp scrType3D,2
jne @F
mov ebx,30
@@:
mov eax,scrCellW3D
sub eax,ebx
shr eax,1
add eax,originX
mov edx,scrCellH3D
sub edx,ebx
shr edx,1
add edx,originY
invoke DrawAnimSprite3D,OFFSET scrSymbolsArt3D,scrGrid3D[esi*4],eax,edx,ebx,ebx
ret
scratch_content_number:
mov ink,00303B32h
cmp esi,3
jb scratch_content_num_draw
xor edi,edi
scratch_content_match:
mov eax,scrGrid3D[edi*4]
cmp eax,scrGrid3D[esi*4]
jne @F
mov ink,00056837h
@@:
inc edi
cmp edi,3
jb scratch_content_match
scratch_content_num_draw:
mov eax,originX
add eax,36
shr eax,1
mov textX,eax
mov eax,originY
add eax,4
shr eax,1
mov textY,eax
invoke FormatNumber,scrGrid3D[esi*4],OFFSET hudNumBuffer
invoke DrawString8x8,textX,textY,OFFSET hudNumBuffer,ink
cmp esi,3
jb scratch_content_done
invoke FormatNumber,scrCellPrizes3D[esi*4],OFFSET hudNumBuffer
mov eax,originX
add eax,32
mov textX,eax
mov eax,originY
add eax,22
invoke DrawBuckshotText3D,textX,eax,OFFSET hudNumBuffer,ink
ret
scratch_content_instant:
invoke DrawString8x8,128,100,OFFSET scratchAmount3D,00303B32h
invoke FormatNumber,scrGross3D,OFFSET hudNumBuffer
lea edi,hudNumBuffer
xor ecx,ecx
scratch_amount_length:
cmp BYTE PTR [edi+ecx],0
je @F
inc ecx
jmp scratch_amount_length
@@:
imul eax,ecx,4
mov ebx,160
sub ebx,eax
invoke DrawString8x8,ebx,124,OFFSET hudNumBuffer,00056837h
scratch_content_done:
ret
ScratchDrawContent3D ENDP
RenderScratch3D PROC uses ebx esi edi
local cell:DWORD,centerX:DWORD,centerY:DWORD,py:DWORD,px:DWORD,maskAt:DWORD,ink:DWORD
cmp scrReady3D,1
jne scratch_render_missing
; The ticket lies on an overhead writing mat, not in front of a dealer.
cmp scrTableArt3D.pixels,0
je scratch_render_plain
mov esi,scrTableArt3D.pixels
lea edi,screenBuffer
mov ecx,SCREEN_SIZE
rep movsd
jmp scratch_render_paper
scratch_render_plain:
invoke DrawBox,0,0,320,240,001B4839h
scratch_render_paper:
call ScratchSaveBackdrop3D
cmp scrType3D,4
jb @F
call RenderScratchPortrait3D
jmp scratch_render_hud
@@:
invoke DrawAnimSprite3D,OFFSET scrTicketArt3D,scrType3D,96,92,448,288
mov eax,scrType3D
mov esi,scrNames3D[eax*4]
xor ecx,ecx
scratch_title_length:
cmp BYTE PTR [esi+ecx],0
je @F
inc ecx
jmp scratch_title_length
@@:
imul eax,ecx,4
mov ebx,160
sub ebx,eax
invoke DrawString8x8,ebx,65,esi,00E5D29Eh
cmp scrType3D,1
jne @F
invoke DrawBuckshotText3D,144,170,OFFSET scratchLucky3D,00303B32h
invoke DrawBuckshotText3D,144,220,OFFSET scratchYours3D,00303B32h
@@:
mov cell,0
scratch_render_cell:
invoke ScratchCellOrigin3D,cell
mov centerX,eax
mov centerY,edx
cmp scrState3D,0
je scratch_render_coating
invoke ScratchDrawContent3D,cell,centerX,centerY
scratch_render_coating:
mov eax,cell
imul eax,SCR_MASK_AREA
mov maskAt,eax
mov py,0
scratch_coating_row:
mov eax,py
imul eax,scrCellW3D
mov esi,eax
add esi,maskAt
mov eax,centerY
add eax,py
imul eax,640
add eax,centerX
lea edi,screenBuffer[eax*4]
mov px,0
scratch_coating_pixel:
cmp scrMask3D[esi],0
je scratch_coating_next
scratch_coating_opaque:
mov eax,py
xor edx,edx
mov ecx,SCR_H
div ecx
imul ebx,edx,SCR_W
mov eax,px
xor edx,edx
mov ecx,SCR_W
div ecx
lea eax,[ebx+edx]
mov edx,scrFoilArt3D.pixels
mov eax,[edx+eax*4]
mov [edi],eax
scratch_coating_next:
add edi,4
inc esi
inc px
mov eax,scrCellW3D
cmp px,eax
jb scratch_coating_pixel
inc py
mov eax,scrCellH3D
cmp py,eax
jb scratch_coating_row
inc cell
mov eax,scrCellCount3D
cmp cell,eax
jb scratch_render_cell
; Printed odds legend belongs on the paper, not over the scratch surface.
cmp scrType3D,1
je scratch_print_rule
cmp scrType3D,3
je scratch_print_rule
xor esi,esi
scratch_legend:
imul ebx,esi,43
add ebx,176
invoke DrawAnimSprite3D,OFFSET scrSymbolsArt3D,esi,ebx,338,16,16
add ebx,18
invoke FormatNumber,scrMultipliers3D[esi*4],OFFSET hudNumBuffer
invoke DrawBuckshotText3D,ebx,346,OFFSET hudNumBuffer,00303B32h
add ebx,16
invoke DrawBuckshotText3D,ebx,346,OFFSET scrTimes3D,00303B32h
inc esi
cmp esi,7
jb scratch_legend
jmp scratch_render_hud
scratch_print_rule:
mov eax,scrType3D
mov ebx,340
cmp eax,1
jne @F
mov ebx,328
@@:
invoke DrawBuckshotText3D,176,ebx,scrRules3D[eax*4],00303B32h
jmp scratch_render_hud
scratch_render_missing:
invoke DrawBox,0,0,320,240,001B4839h
invoke DrawString8x8,104,112,OFFSET scratchMissing3D,00E99383h
scratch_render_hud:
cmp scrReady3D,1
jne @F
call ScratchDrawDelivery3D
call ScratchDrawPayout3D
cmp scrType3D,4
jb @F
call ScratchPortraitInfo3D
@@:
invoke DrawBox,0,0,320,20,0014191Dh
invoke DrawString8x8,12,6,OFFSET scratchTitle3D,00E5D29Eh
invoke DrawBoxBorder,252,3,60,14,00252D2Ah,0086754Eh,1
invoke DrawString8x8,266,6,OFFSET coinExitText3D,00E5D29Eh
invoke DrawBox,4,23,148,15,0014191Dh
invoke DrawString8x8,8,27,OFFSET coinBankText3D,00E5D29Eh
invoke FormatNumber,bankroll,OFFSET hudNumBuffer
invoke DrawString8x8,56,27,OFFSET hudNumBuffer,00FFFFFFh
invoke DrawBoxBorder,174,23,138,15,00252D2Ah,0086754Eh,1
invoke DrawBuckshotText3D,356,50,OFFSET scratchKind3D,00ADB9BCh
invoke DrawBuckshotText3D,608,57,OFFSET scrNext3D,00E5D29Eh
mov eax,scrType3D
invoke DrawBuckshotText3D,356,62,scrNames3D[eax*4],00E5D29Eh
invoke DrawBox,0,194,320,46,0014191Dh
invoke DrawBuckshotText3D,16,405,OFFSET scratchCost3D,00E5D29Eh
mov eax,scrPriceIndex3D
mov eax,scrPrices3D[eax*4]
cmp scrState3D,0
je @F
mov eax,scrStake3D
@@:
invoke FormatNumber,eax,OFFSET hudNumBuffer
invoke DrawString8x8,56,201,OFFSET hudNumBuffer,00FFFFFFh
cmp scrError3D,0
je scratch_status
invoke DrawString8x8,168,201,OFFSET scratchPoor3D,00E99383h
jmp scratch_buttons
scratch_status:
cmp scrState3D,2
je scratch_result
cmp scrState3D,1
jne scratch_rule
invoke DrawString8x8,168,201,OFFSET scratchWait3D,00E5D29Eh
invoke FormatNumber,scrOpened3D,OFFSET hudNumBuffer
invoke DrawString8x8,232,201,OFFSET hudNumBuffer,00FFFFFFh
jmp scratch_buttons
scratch_rule:
mov eax,scrType3D
invoke DrawBuckshotText3D,328,405,scrRules3D[eax*4],00ADB9BCh
jmp scratch_buttons
scratch_result:
invoke DrawBuckshotText3D,336,405,OFFSET scratchPayout3D,00ADB9BCh
invoke FormatNumber,scrGross3D,OFFSET hudNumBuffer
invoke DrawString8x8,212,201,OFFSET hudNumBuffer,0090D5ADh
call RenderScratchNet3D
scratch_buttons:
cmp scrType3D,4
jb @F
invoke DrawBoxBorder,172,218,16,18,00252D2Ah,0086754Eh,1
mov eax,OFFSET scrZoomIn3D
cmp scrZoom3D,0
je scratch_zoom_label
mov eax,OFFSET scrZoomOut3D
scratch_zoom_label:
invoke DrawString8x8,176,223,eax,00E5D29Eh
@@:
xor esi,esi
scratch_price_button:
mov ink,0086754Eh
cmp scrState3D,1
je @F
cmp esi,scrPriceIndex3D
jne @F
mov ink,00E5D29Eh
@@:
imul ebx,esi,54
add ebx,8
invoke DrawBoxBorder,ebx,218,50,18,00252D2Ah,ink,1
add ebx,9
invoke FormatNumber,scrPrices3D[esi*4],OFFSET hudNumBuffer
invoke DrawString8x8,ebx,223,OFFSET hudNumBuffer,ink
inc esi
cmp esi,3
jb scratch_price_button
invoke DrawBoxBorder,192,218,120,18,00252D2Ah,0086754Eh,1
mov eax,OFFSET scratchBuy3D
cmp scrState3D,2
jne @F
mov eax,OFFSET scratchNext3D
@@:
cmp scrState3D,1
jne @F
mov eax,OFFSET scratchActive3D
@@:
invoke DrawString8x8,224,223,eax,00E5D29Eh
cmp scrReady3D,1
jne scratch_render_done
cmp scrCatalog3D,0
je @F
call RenderScratchCatalog3D
jmp scratch_coin_draw
@@:
call ScratchDrawDust3D
scratch_coin_draw:
cmp scrPointerValid3D,1
jne scratch_render_done
mov eax,scrPointerX3D
sub eax,32
mov centerX,eax
mov eax,scrPointerY3D
sub eax,60
mov centerY,eax
xor eax,eax
cmp scrHeld3D,1
jne @F
mov eax,animationClock3D
shr eax,7
and eax,3
@@:
invoke DrawAnimSprite3D,OFFSET scrCoinArt3D,eax,centerX,centerY,64,64
scratch_render_done:
ret
RenderScratch3D ENDP
ScratchCanWalk3D PROC px:DWORD,py:DWORD
mov eax,px
sub eax,scrStation3D.posX
cdq
xor eax,edx
sub eax,edx
cmp eax,FP_1*19/20
ja scratch_walk_clear
mov eax,py
sub eax,scrStation3D.posY
cdq
xor eax,edx
sub eax,edx
cmp eax,FP_1*2/5
ja scratch_walk_clear
xor eax,eax
ret
scratch_walk_clear:
mov eax,1
ret
ScratchCanWalk3D ENDP
include src_graphics/scratch_portrait.inc
include src_graphics/scratch_ui.inc
include src_graphics/scratch_effects.inc