Add rooftop elevator, lounge, volumetric city, river and animated traffic. Prune invisible mesh faces, clip CPU surfaces, streamline compositing and add automatic/F8 roof quality profiles with renderer diagnostics. Include dartboard/reticle improvements, tracked fortune orb numerals and fate-session visuals, native regression tests, compatible jukebox IDs and updated shipping executables.
1259 lines
30 KiB
PHP
1259 lines
30 KiB
PHP
; Seated fortune session. All timing, input, dealing and rendering are native MASM.
|
|
BeginFortuneDialog3D PROC uses ebx esi edi
|
|
call StopFortuneWorker3D
|
|
lea esi,screenBuffer
|
|
lea edi,fortuneBackground3D
|
|
mov ecx,SCREEN_SIZE
|
|
rep movsd
|
|
xor ebx,ebx
|
|
lea esi,fortuneSessionPacks3D
|
|
fortune_session_load:
|
|
invoke LoadAnimPack3D,esi,fortuneSessionPaths3D[ebx*4]
|
|
add esi,SIZEOF AnimPack3D
|
|
inc ebx
|
|
cmp ebx,FORTUNE_SESSION_PACK_COUNT
|
|
jb fortune_session_load
|
|
mov engineMode,MODE_FORTUNE
|
|
mov paused3D,0
|
|
mov fortuneSubMode3D,0
|
|
mov fortunePhase3D,0
|
|
mov fortunePhaseTime3D,0
|
|
mov fortuneDealt3D,0
|
|
mov fortuneRevealed3D,0
|
|
mov fortuneCardsDrawn3D,0
|
|
mov fortuneQuestionLength3D,0
|
|
mov fortuneQuestion3D,0
|
|
mov fortuneWorkerState3D,0
|
|
call ResetFortuneFate3D
|
|
mov eax,animationClock3D
|
|
mov fortuneSessionClock3D,eax
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneWelcome3D
|
|
call ClearKeys3D
|
|
mov mouseClick3D,0
|
|
ret
|
|
BeginFortuneDialog3D ENDP
|
|
|
|
; Kept as the public exit/shutdown hook. No inference process is launched.
|
|
StopFortuneWorker3D PROC uses ebx esi
|
|
lea esi,fortuneSessionPacks3D
|
|
mov ebx,FORTUNE_SESSION_PACK_COUNT
|
|
fortune_session_free:
|
|
invoke FreeAnimPack3D,esi
|
|
add esi,SIZEOF AnimPack3D
|
|
dec ebx
|
|
jnz fortune_session_free
|
|
mov fortuneWorkerState3D,0
|
|
call ResetFortuneFate3D
|
|
ret
|
|
StopFortuneWorker3D ENDP
|
|
|
|
PollFortuneWorker3D PROC
|
|
ret
|
|
PollFortuneWorker3D ENDP
|
|
|
|
SetFortuneSpeech3D PROC uses esi edi text:DWORD
|
|
mov esi,text
|
|
lea edi,fortuneSpeech3D
|
|
xor ecx,ecx
|
|
fortune_speech_copy:
|
|
mov al,[esi+ecx]
|
|
mov [edi+ecx],al
|
|
test al,al
|
|
jz fortune_speech_copied
|
|
inc ecx
|
|
cmp ecx,255
|
|
jb fortune_speech_copy
|
|
mov BYTE PTR [edi+255],0
|
|
fortune_speech_copied:
|
|
mov fortuneSpeechLength3D,ecx
|
|
mov fortuneSpeechTime3D,0
|
|
mov fortuneSpeechVisible3D,0
|
|
ret
|
|
SetFortuneSpeech3D ENDP
|
|
|
|
FortuneCardSpeech3D PROC uses ebx esi edi cardSlot:DWORD
|
|
mov eax,cardSlot
|
|
mov ebx,fortuneDrawCards3D[eax*4]
|
|
mov eax,ebx
|
|
xor edx,edx
|
|
mov ecx,22
|
|
div ecx
|
|
mov esi,fortuneCardNames3D[edx*4]
|
|
lea edi,fortuneSpeech3D
|
|
fortune_card_name_copy:
|
|
lodsb
|
|
test al,al
|
|
jz fortune_card_position
|
|
stosb
|
|
jmp fortune_card_name_copy
|
|
fortune_card_position:
|
|
mov al,10
|
|
stosb
|
|
mov esi,OFFSET fortuneUpright3D
|
|
cmp ebx,22
|
|
jb @F
|
|
mov esi,OFFSET fortuneReversed3D
|
|
@@:
|
|
lodsb
|
|
test al,al
|
|
jz fortune_card_placeholder
|
|
stosb
|
|
jmp @B
|
|
fortune_card_placeholder:
|
|
mov al,10
|
|
stosb
|
|
mov esi,OFFSET fortuneUnavailable3D
|
|
fortune_card_placeholder_copy:
|
|
lodsb
|
|
stosb
|
|
test al,al
|
|
jnz fortune_card_placeholder_copy
|
|
sub edi,OFFSET fortuneSpeech3D+1
|
|
mov fortuneSpeechLength3D,edi
|
|
mov fortuneSpeechTime3D,0
|
|
mov fortuneSpeechVisible3D,0
|
|
ret
|
|
FortuneCardSpeech3D ENDP
|
|
|
|
FortuneChar3D PROC character:DWORD
|
|
cmp engineMode,MODE_FORTUNE
|
|
jne fortune_char_done
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_MENU
|
|
jne fortune_char_question
|
|
cmp character,'1'
|
|
je fortune_char_tarot
|
|
cmp character,'2'
|
|
je fortune_char_orb
|
|
ret
|
|
fortune_char_tarot:
|
|
mov fortuneSubMode3D,FORTUNE_SUBMODE_TAROT
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneReady3D
|
|
ret
|
|
fortune_char_orb:
|
|
mov fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
call ResetFortuneFate3D
|
|
mov fortunePhase3D,0
|
|
mov fortunePhaseTime3D,0
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateReady3D
|
|
ret
|
|
fortune_char_question:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
jne @F
|
|
invoke FortuneFateChar3D,character
|
|
ret
|
|
@@:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_TAROT
|
|
jne fortune_char_done
|
|
cmp fortunePhase3D,0
|
|
jne fortune_char_done
|
|
mov eax,character
|
|
cmp eax,8
|
|
je fortune_char_backspace
|
|
cmp eax,32
|
|
jb fortune_char_done
|
|
cmp eax,255
|
|
ja fortune_char_done
|
|
cmp eax,127
|
|
je fortune_char_done
|
|
mov ecx,fortuneQuestionLength3D
|
|
cmp ecx,240
|
|
jae fortune_char_done
|
|
mov fortuneQuestion3D[ecx],al
|
|
inc ecx
|
|
mov fortuneQuestionLength3D,ecx
|
|
mov fortuneQuestion3D[ecx],0
|
|
ret
|
|
fortune_char_backspace:
|
|
mov ecx,fortuneQuestionLength3D
|
|
test ecx,ecx
|
|
jz fortune_char_done
|
|
dec ecx
|
|
mov fortuneQuestionLength3D,ecx
|
|
mov fortuneQuestion3D[ecx],0
|
|
fortune_char_done:
|
|
ret
|
|
FortuneChar3D ENDP
|
|
|
|
SubmitFortuneQuestion3D PROC uses ebx esi
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_TAROT
|
|
jne fortune_submit_done
|
|
cmp fortunePhase3D,0
|
|
jne fortune_submit_done
|
|
cmp fortuneQuestionLength3D,0
|
|
je fortune_submit_done
|
|
xor esi,esi
|
|
fortune_draw_loop:
|
|
invoke RandomRange3D,22
|
|
mov ebx,eax
|
|
xor ecx,ecx
|
|
fortune_check_unique:
|
|
cmp ecx,esi
|
|
jae fortune_apply_orientation
|
|
mov eax,fortuneDrawCards3D[ecx*4]
|
|
xor edx,edx
|
|
push ecx
|
|
mov ecx,22
|
|
div ecx
|
|
pop ecx
|
|
cmp ebx,edx
|
|
je fortune_draw_loop
|
|
inc ecx
|
|
jmp fortune_check_unique
|
|
fortune_apply_orientation:
|
|
invoke RandomRange3D,2
|
|
imul eax,22
|
|
add eax,ebx
|
|
mov fortuneDrawCards3D[esi*4],eax
|
|
inc esi
|
|
cmp esi,3
|
|
jb fortune_draw_loop
|
|
mov fortunePhase3D,1
|
|
mov fortunePhaseTime3D,0
|
|
mov fortuneDealt3D,0
|
|
mov fortuneRevealed3D,0
|
|
mov fortuneCardsDrawn3D,1
|
|
mov eax,animationClock3D
|
|
mov fortuneSessionClock3D,eax
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneShuffle3D
|
|
fortune_submit_done:
|
|
ret
|
|
SubmitFortuneQuestion3D ENDP
|
|
|
|
; Elapsed clock, not render count: repeated renders cannot accelerate a session.
|
|
UpdateFortuneSession3D PROC uses ebx
|
|
mov eax,animationClock3D
|
|
mov edx,eax
|
|
sub eax,fortuneSessionClock3D
|
|
mov fortuneSessionClock3D,edx
|
|
cmp eax,100
|
|
jbe @F
|
|
mov eax,100
|
|
@@:
|
|
add fortuneSpeechTime3D,eax
|
|
add fortunePhaseTime3D,eax
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_TAROT
|
|
jne fortune_update_orb
|
|
mov ebx,fortunePhase3D
|
|
test ebx,ebx
|
|
jz fortune_update_done
|
|
cmp ebx,12
|
|
jae fortune_update_done
|
|
mov eax,fortuneDurations3D[ebx*4]
|
|
cmp fortunePhaseTime3D,eax
|
|
jb fortune_update_done
|
|
inc ebx
|
|
mov fortunePhase3D,ebx
|
|
mov fortunePhaseTime3D,0
|
|
cmp ebx,2
|
|
jb fortune_update_done
|
|
cmp ebx,5
|
|
ja fortune_update_reveal
|
|
mov eax,ebx
|
|
sub eax,2
|
|
mov fortuneDealt3D,eax
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneDeal3D
|
|
jmp fortune_update_done
|
|
fortune_update_reveal:
|
|
cmp ebx,6
|
|
je fortune_explain_one
|
|
cmp ebx,8
|
|
je fortune_explain_two
|
|
cmp ebx,10
|
|
je fortune_explain_three
|
|
cmp ebx,11
|
|
jne fortune_update_done
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneSummary3D
|
|
jmp fortune_update_done
|
|
fortune_explain_one:
|
|
mov fortuneRevealed3D,1
|
|
invoke FortuneCardSpeech3D,0
|
|
jmp fortune_update_done
|
|
fortune_explain_two:
|
|
mov fortuneRevealed3D,2
|
|
invoke FortuneCardSpeech3D,1
|
|
jmp fortune_update_done
|
|
fortune_explain_three:
|
|
mov fortuneRevealed3D,3
|
|
invoke FortuneCardSpeech3D,2
|
|
jmp fortune_update_done
|
|
fortune_update_orb:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
jne fortune_update_done
|
|
cmp fortunePhase3D,1
|
|
jne fortune_orb_swirl
|
|
cmp fortunePhaseTime3D,1400
|
|
jb fortune_update_done
|
|
mov fortunePhase3D,2
|
|
mov fortunePhaseTime3D,0
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateSwirl3D
|
|
jmp fortune_update_done
|
|
fortune_orb_swirl:
|
|
cmp fortunePhase3D,2
|
|
jne fortune_update_done
|
|
cmp fortunePhaseTime3D,5000
|
|
jb fortune_update_done
|
|
mov fortunePhase3D,3
|
|
mov fortunePhaseTime3D,0
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateReveal3D
|
|
fortune_update_done:
|
|
ret
|
|
UpdateFortuneSession3D ENDP
|
|
|
|
HandleFortuneDialog3D PROC
|
|
call UpdateFortuneSession3D
|
|
invoke Pressed3D,1Bh
|
|
test eax,eax
|
|
jnz fortune_handle_exit
|
|
invoke Pressed3D,0Dh
|
|
test eax,eax
|
|
jnz fortune_handle_action
|
|
cmp mouseClick3D,0
|
|
je fortune_handle_done
|
|
mov mouseClick3D,0
|
|
cmp mouseY3D,227
|
|
jb fortune_handle_menu_click
|
|
cmp mouseY3D,239
|
|
ja fortune_handle_done
|
|
cmp mouseX3D,240
|
|
jae fortune_handle_exit
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_MENU
|
|
je fortune_handle_done
|
|
cmp mouseX3D,172
|
|
jae fortune_handle_menu
|
|
cmp mouseX3D,88
|
|
jae fortune_handle_reset
|
|
jmp fortune_handle_action
|
|
fortune_handle_menu_click:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
jne fortune_handle_selection_click
|
|
cmp fortunePhase3D,0
|
|
jne fortune_handle_done
|
|
; Form uses physical pixels; mouse input here uses half-resolution units.
|
|
mov eax,mouseY3D
|
|
sub eax,162
|
|
jb fortune_handle_done
|
|
xor edx,edx
|
|
mov ecx,21
|
|
div ecx
|
|
cmp eax,2
|
|
ja fortune_handle_done
|
|
cmp edx,11
|
|
ja fortune_handle_done
|
|
shl eax,1
|
|
cmp mouseX3D,156
|
|
jb fortune_handle_form_left
|
|
cmp mouseX3D,168
|
|
jb fortune_handle_done
|
|
cmp mouseX3D,312
|
|
ja fortune_handle_done
|
|
inc eax
|
|
jmp fortune_handle_form_focus
|
|
fortune_handle_form_left:
|
|
cmp mouseX3D,8
|
|
jb fortune_handle_done
|
|
fortune_handle_form_focus:
|
|
mov fortuneFateField3D,eax
|
|
ret
|
|
fortune_handle_selection_click:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_MENU
|
|
jne fortune_handle_done
|
|
cmp mouseY3D,196
|
|
jb fortune_handle_done
|
|
cmp mouseY3D,214
|
|
ja fortune_handle_done
|
|
cmp mouseX3D,160
|
|
jae fortune_handle_orb
|
|
fortune_handle_tarot:
|
|
invoke FortuneChar3D,'1'
|
|
ret
|
|
fortune_handle_orb:
|
|
invoke FortuneChar3D,'2'
|
|
ret
|
|
fortune_handle_action:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_MENU
|
|
je fortune_handle_tarot
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
jne @F
|
|
call SubmitFortuneFate3D
|
|
ret
|
|
@@:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_TAROT
|
|
jne fortune_handle_done
|
|
cmp fortunePhase3D,0
|
|
je fortune_handle_submit
|
|
; Continue only after this speech is fully visible. Never skip dealing/flips.
|
|
mov eax,fortuneSpeechLength3D
|
|
imul eax,28
|
|
cmp fortuneSpeechTime3D,eax
|
|
jb fortune_handle_done
|
|
mov eax,fortunePhase3D
|
|
cmp eax,6
|
|
je fortune_handle_advance
|
|
cmp eax,8
|
|
je fortune_handle_advance
|
|
cmp eax,10
|
|
je fortune_handle_advance
|
|
cmp eax,11
|
|
jne fortune_handle_done
|
|
fortune_handle_advance:
|
|
mov eax,fortuneDurations3D[eax*4]
|
|
mov fortunePhaseTime3D,eax
|
|
ret
|
|
fortune_handle_submit:
|
|
call SubmitFortuneQuestion3D
|
|
ret
|
|
fortune_handle_menu:
|
|
mov fortuneSubMode3D,FORTUNE_SUBMODE_MENU
|
|
mov fortunePhase3D,0
|
|
mov fortuneDealt3D,0
|
|
mov fortuneRevealed3D,0
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneWelcome3D
|
|
ret
|
|
fortune_handle_reset:
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
jne @F
|
|
cmp fortunePhase3D,3
|
|
jne fortune_handle_done
|
|
cmp fortunePhaseTime3D,1200
|
|
jb fortune_handle_done
|
|
mov fortunePhase3D,0
|
|
mov fortunePhaseTime3D,0
|
|
mov fortuneFateResult3D,-1
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateReady3D
|
|
ret
|
|
@@:
|
|
cmp fortunePhase3D,12
|
|
jne fortune_handle_done
|
|
mov fortunePhase3D,0
|
|
mov fortuneDealt3D,0
|
|
mov fortuneRevealed3D,0
|
|
mov fortuneQuestionLength3D,0
|
|
mov fortuneQuestion3D,0
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneReady3D
|
|
ret
|
|
fortune_handle_exit:
|
|
call StopFortuneWorker3D
|
|
mov engineMode,MODE_WALK
|
|
call ClearKeys3D
|
|
fortune_handle_done:
|
|
ret
|
|
HandleFortuneDialog3D ENDP
|
|
|
|
FortuneWrap3D PROC uses ebx esi edi source:DWORD,top:DWORD,lines:DWORD,skip:DWORD,ink:DWORD
|
|
local count:DWORD,lastSpace:DWORD,lineNumber:DWORD
|
|
mov esi,source
|
|
mov lineNumber,0
|
|
fortune_wrap_line:
|
|
cmp BYTE PTR [esi],0
|
|
je fortune_wrap_end
|
|
xor ebx,ebx
|
|
mov lastSpace,0
|
|
fortune_wrap_measure:
|
|
mov al,[esi+ebx]
|
|
test al,al
|
|
jz fortune_wrap_measured
|
|
cmp al,10
|
|
je fortune_wrap_measured
|
|
cmp al,32
|
|
jne @F
|
|
mov lastSpace,ebx
|
|
@@:
|
|
inc ebx
|
|
cmp ebx,72
|
|
jb fortune_wrap_measure
|
|
cmp BYTE PTR [esi+ebx],0
|
|
je fortune_wrap_measured
|
|
cmp lastSpace,0
|
|
je fortune_wrap_measured
|
|
mov ebx,lastSpace
|
|
fortune_wrap_measured:
|
|
mov count,ebx
|
|
mov eax,lineNumber
|
|
cmp eax,skip
|
|
jb fortune_wrap_advance
|
|
sub eax,skip
|
|
cmp eax,lines
|
|
jae fortune_wrap_more
|
|
imul eax,11
|
|
add eax,top
|
|
push eax
|
|
lea edi,fortuneLine3D
|
|
mov ecx,ebx
|
|
push esi
|
|
rep movsb
|
|
mov BYTE PTR [edi],0
|
|
pop esi
|
|
pop eax
|
|
mov fortuneCaretY3D,eax
|
|
mov edx,count
|
|
imul edx,8
|
|
add edx,24
|
|
mov fortuneCaretX3D,edx
|
|
invoke DrawBuckshotText3D,24,eax,OFFSET fortuneLine3D,ink
|
|
fortune_wrap_advance:
|
|
add esi,count
|
|
cmp BYTE PTR [esi],10
|
|
je fortune_wrap_skip_separator
|
|
cmp BYTE PTR [esi],32
|
|
jne fortune_wrap_next
|
|
fortune_wrap_skip_separator:
|
|
inc esi
|
|
fortune_wrap_next:
|
|
inc lineNumber
|
|
jmp fortune_wrap_line
|
|
fortune_wrap_more:
|
|
mov eax,1
|
|
ret
|
|
fortune_wrap_end:
|
|
xor eax,eax
|
|
ret
|
|
FortuneWrap3D ENDP
|
|
|
|
; The bubble grows with visible glyphs, rather than allocating a full-screen panel.
|
|
DrawFortuneSpeech3D PROC uses ebx esi edi
|
|
local column:DWORD,row:DWORD,maxColumn:DWORD,visible:DWORD,glyphX:DWORD,glyphY:DWORD
|
|
mov eax,fortuneSpeechTime3D
|
|
xor edx,edx
|
|
mov ecx,28
|
|
div ecx
|
|
cmp eax,fortuneSpeechLength3D
|
|
jbe @F
|
|
mov eax,fortuneSpeechLength3D
|
|
@@:
|
|
mov visible,eax
|
|
mov fortuneSpeechVisible3D,eax
|
|
test eax,eax
|
|
jz fortune_bubble_done
|
|
mov column,0
|
|
mov row,0
|
|
mov maxColumn,0
|
|
xor esi,esi
|
|
fortune_bubble_measure:
|
|
cmp esi,visible
|
|
jae fortune_bubble_box
|
|
cmp fortuneSpeech3D[esi],10
|
|
je fortune_bubble_newline
|
|
inc column
|
|
mov eax,column
|
|
cmp eax,maxColumn
|
|
jbe @F
|
|
mov maxColumn,eax
|
|
@@:
|
|
cmp column,23
|
|
jb fortune_bubble_measure_next
|
|
fortune_bubble_newline:
|
|
mov column,0
|
|
inc row
|
|
fortune_bubble_measure_next:
|
|
inc esi
|
|
jmp fortune_bubble_measure
|
|
fortune_bubble_box:
|
|
mov eax,maxColumn
|
|
imul eax,8
|
|
add eax,20
|
|
mov fortuneSpeechWidth3D,eax
|
|
shr eax,1
|
|
mov ebx,eax
|
|
mov eax,row
|
|
inc eax
|
|
imul eax,12
|
|
add eax,20
|
|
mov fortuneSpeechHeight3D,eax
|
|
shr eax,1
|
|
invoke DrawBoxBorder,208,30,ebx,eax,000A1829h,006E9DB8h,1
|
|
mov column,0
|
|
mov row,0
|
|
xor esi,esi
|
|
fortune_bubble_glyph:
|
|
cmp esi,visible
|
|
jae fortune_bubble_done
|
|
mov al,fortuneSpeech3D[esi]
|
|
cmp al,10
|
|
je fortune_bubble_glyph_newline
|
|
mov fortuneGlyph3D,al
|
|
mov eax,column
|
|
imul eax,8
|
|
add eax,426
|
|
mov glyphX,eax
|
|
mov ebx,row
|
|
imul ebx,12
|
|
add ebx,70
|
|
mov eax,esi
|
|
inc eax
|
|
imul eax,28
|
|
mov edx,fortuneSpeechTime3D
|
|
sub edx,eax
|
|
cmp edx,84
|
|
jae @F
|
|
mov eax,84
|
|
sub eax,edx
|
|
shr eax,5
|
|
sub ebx,eax
|
|
@@:
|
|
mov glyphY,ebx
|
|
invoke DrawBuckshotText3D,glyphX,ebx,OFFSET fortuneGlyph3D,00D2E8F2h
|
|
inc column
|
|
cmp column,23
|
|
jb fortune_bubble_glyph_next
|
|
fortune_bubble_glyph_newline:
|
|
mov column,0
|
|
inc row
|
|
fortune_bubble_glyph_next:
|
|
inc esi
|
|
jmp fortune_bubble_glyph
|
|
fortune_bubble_done:
|
|
ret
|
|
DrawFortuneSpeech3D ENDP
|
|
|
|
DrawFortuneSessionCard3D PROC uses ebx esi edi slot:DWORD
|
|
local px:DWORD,py:DWORD,cw:DWORD,cardHeight:DWORD,face:DWORD,amount:DWORD
|
|
mov esi,slot
|
|
mov eax,esi
|
|
imul eax,100
|
|
add eax,198
|
|
mov px,eax
|
|
mov py,302
|
|
mov cw,72
|
|
mov cardHeight,96
|
|
mov face,44
|
|
cmp esi,fortuneRevealed3D
|
|
jae @F
|
|
mov eax,fortuneDrawCards3D[esi*4]
|
|
mov face,eax
|
|
@@:
|
|
cmp esi,fortuneDealt3D
|
|
jb fortune_card_flip_check
|
|
mov eax,fortunePhase3D
|
|
sub eax,2
|
|
cmp eax,esi
|
|
jne fortune_card_done
|
|
; Release at 40%, then carry the card from the hand to its table slot.
|
|
mov ebx,fortunePhaseTime3D
|
|
sub ebx,400
|
|
js fortune_card_done
|
|
cmp ebx,600
|
|
jbe @F
|
|
mov ebx,600
|
|
@@:
|
|
mov eax,px
|
|
sub eax,220
|
|
imul eax,ebx
|
|
cdq
|
|
mov ecx,600
|
|
idiv ecx
|
|
add eax,220
|
|
mov px,eax
|
|
mov eax,ebx
|
|
imul eax,40
|
|
xor edx,edx
|
|
div ecx
|
|
add eax,262
|
|
mov py,eax
|
|
jmp fortune_card_draw
|
|
fortune_card_flip_check:
|
|
mov eax,fortunePhase3D
|
|
sub eax,5
|
|
js fortune_card_draw
|
|
test eax,1
|
|
jnz fortune_card_draw
|
|
shr eax,1
|
|
cmp eax,esi
|
|
jne fortune_card_draw
|
|
cmp fortunePhase3D,9
|
|
ja fortune_card_draw
|
|
mov ebx,fortunePhaseTime3D
|
|
cmp ebx,400
|
|
jb fortune_card_flip_back
|
|
mov eax,fortuneDrawCards3D[esi*4]
|
|
mov face,eax
|
|
sub ebx,400
|
|
jmp fortune_card_flip_width
|
|
fortune_card_flip_back:
|
|
mov eax,400
|
|
sub eax,ebx
|
|
mov ebx,eax
|
|
fortune_card_flip_width:
|
|
imul ebx,72
|
|
mov eax,ebx
|
|
xor edx,edx
|
|
mov ecx,400
|
|
div ecx
|
|
cmp eax,2
|
|
jae @F
|
|
mov eax,2
|
|
@@:
|
|
mov cw,eax
|
|
mov ebx,72
|
|
sub ebx,eax
|
|
shr ebx,1
|
|
add px,ebx
|
|
fortune_card_draw:
|
|
invoke DrawAnimSprite3D,OFFSET fortuneSessionCards3D,face,px,py,cw,cardHeight
|
|
fortune_card_done:
|
|
ret
|
|
DrawFortuneSessionCard3D ENDP
|
|
|
|
RenderFortuneDialog3D PROC uses ebx esi edi
|
|
lea esi,fortuneBackground3D
|
|
lea edi,screenBuffer
|
|
mov ecx,SCREEN_SIZE
|
|
rep movsd
|
|
invoke DrawAnimSprite3D,OFFSET fortuneSessionRoom3D,0,0,0,640,480
|
|
cmp fortuneSessionRoom3D.pixels,0
|
|
jne @F
|
|
invoke DrawBoxBorder,4,4,312,36,000A1829h,006E9DB8h,1
|
|
invoke DrawBuckshotText3D,24,24,OFFSET fortuneMissing3D,00FFFFFFh
|
|
@@:
|
|
mov ebx,OFFSET fortuneSessionShuffle3D
|
|
xor esi,esi
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
je fortune_render_orb_hands
|
|
mov eax,fortunePhase3D
|
|
cmp eax,1
|
|
jne fortune_render_hand_deal
|
|
mov eax,fortunePhaseTime3D
|
|
xor edx,edx
|
|
mov ecx,25
|
|
div ecx
|
|
and eax,63
|
|
mov esi,eax
|
|
jmp fortune_render_hands
|
|
fortune_render_hand_deal:
|
|
cmp eax,2
|
|
jb fortune_render_hands
|
|
cmp eax,4
|
|
ja fortune_render_hand_gesture
|
|
mov ebx,OFFSET fortuneSessionDeal3D
|
|
mov eax,fortunePhaseTime3D
|
|
xor edx,edx
|
|
mov ecx,32
|
|
div ecx
|
|
cmp eax,31
|
|
jbe @F
|
|
mov eax,31
|
|
@@:
|
|
mov esi,eax
|
|
jmp fortune_render_hands
|
|
fortune_render_hand_gesture:
|
|
mov ebx,OFFSET fortuneSessionGesture3D
|
|
mov eax,fortunePhaseTime3D
|
|
shr eax,5
|
|
and eax,31
|
|
mov esi,eax
|
|
jmp fortune_render_hands
|
|
fortune_render_orb_hands:
|
|
cmp fortunePhase3D,0
|
|
je fortune_render_hands
|
|
mov ebx,OFFSET fortuneSessionOrbHands3D
|
|
mov eax,fortunePhaseTime3D
|
|
shr eax,5
|
|
and eax,31
|
|
mov esi,eax
|
|
fortune_render_hands:
|
|
invoke DrawAnimSprite3D,ebx,esi,134,32,280,250
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_MENU
|
|
je fortune_render_menu
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
je fortune_render_orb
|
|
cmp fortunePhase3D,0
|
|
je fortune_render_input
|
|
invoke DrawAnimSprite3D,OFFSET fortuneSessionCards3D,44,142,300,30,40
|
|
xor esi,esi
|
|
fortune_render_cards:
|
|
invoke DrawFortuneSessionCard3D,esi
|
|
cmp esi,fortuneRevealed3D
|
|
jae @F
|
|
mov eax,esi
|
|
imul eax,100
|
|
add eax,198
|
|
invoke DrawBuckshotText3D,eax,288,fortuneRoleTexts3D[esi*4],00B9D4E7h
|
|
@@:
|
|
inc esi
|
|
cmp esi,3
|
|
jb fortune_render_cards
|
|
fortune_render_input:
|
|
invoke DrawBoxBorder,8,199,304,24,00081322h,0046637Fh,1
|
|
mov fortuneCaretX3D,24
|
|
mov fortuneCaretY3D,402
|
|
invoke FortuneWrap3D,OFFSET fortuneQuestion3D,402,4,0,00E8EFF4h
|
|
cmp fortunePhase3D,0
|
|
jne fortune_render_footer
|
|
test animationClock3D,200h
|
|
jnz fortune_render_footer
|
|
invoke DrawBuckshotText3D,fortuneCaretX3D,fortuneCaretY3D,OFFSET fortuneCaret3D,00FFFFFFh
|
|
jmp fortune_render_footer
|
|
fortune_render_menu:
|
|
invoke DrawBoxBorder,8,196,148,18,000D2136h,005D86A0h,1
|
|
invoke DrawBuckshotText3D,100,404,OFFSET fortuneTarot3D,00D2E8F2h
|
|
invoke DrawBoxBorder,164,196,148,18,000D2136h,005D86A0h,1
|
|
invoke DrawBuckshotText3D,364,404,OFFSET fortuneFate3D,00D2E8F2h
|
|
jmp fortune_render_footer
|
|
fortune_render_orb:
|
|
cmp fortunePhase3D,0
|
|
jne fortune_render_orb_active
|
|
call DrawFortuneFateForm3D
|
|
jmp fortune_render_footer
|
|
fortune_render_orb_active:
|
|
call ResolveFortuneOrb3D
|
|
invoke DrawAnimSprite3D,OFFSET fortuneSessionMist3D,fortuneOrbFrame3D,fortuneOrbX3D,fortuneOrbY3D,128,128
|
|
cmp fortunePhase3D,3
|
|
jne @F
|
|
call DrawFortuneFateResult3D
|
|
@@:
|
|
call DrawFortuneFateIdentity3D
|
|
fortune_render_footer:
|
|
call DrawFortuneSpeech3D
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_MENU
|
|
je fortune_render_exit_button
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_TAROT
|
|
jne fortune_render_fate_button
|
|
invoke DrawBoxBorder,8,227,76,12,000B1E30h,00445F75h,1
|
|
mov esi,OFFSET fortuneAsk3D
|
|
cmp fortunePhase3D,0
|
|
je @F
|
|
mov esi,OFFSET fortuneContinue3D
|
|
@@:
|
|
invoke DrawBuckshotText3D,24,458,esi,00CCE4F4h
|
|
jmp fortune_render_again_button
|
|
fortune_render_fate_button:
|
|
cmp fortunePhase3D,0
|
|
jne fortune_render_again_button
|
|
invoke DrawBoxBorder,8,227,76,12,000B1E30h,00445F75h,1
|
|
invoke DrawBuckshotText3D,24,458,OFFSET fortuneFateStart3D,00CCE4F4h
|
|
fortune_render_again_button:
|
|
invoke DrawBoxBorder,88,227,76,12,000B1E30h,00445F75h,1
|
|
mov esi,OFFSET fortuneAgain3D
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
jne @F
|
|
mov esi,OFFSET fortuneFateEdit3D
|
|
@@:
|
|
invoke DrawBuckshotText3D,192,458,esi,0091A8BCh
|
|
invoke DrawBoxBorder,172,227,64,12,000B1E30h,00445F75h,1
|
|
invoke DrawBuckshotText3D,368,458,OFFSET fortuneMenu3D,00CCE4F4h
|
|
fortune_render_exit_button:
|
|
invoke DrawBoxBorder,240,227,72,12,000B1E30h,00445F75h,1
|
|
invoke DrawBuckshotText3D,516,458,OFFSET fortuneExit3D,00CCE4F4h
|
|
ret
|
|
RenderFortuneDialog3D ENDP
|
|
|
|
ResetFortuneFate3D PROC uses edi
|
|
lea edi,fortuneFateLengths3D
|
|
xor eax,eax
|
|
mov ecx,6
|
|
rep stosd
|
|
lea edi,fortuneFateFields3D
|
|
mov ecx,96
|
|
rep stosd
|
|
mov fortuneFateField3D,0
|
|
mov fortuneFateResult3D,-1
|
|
mov fortuneFateFields3D[256],'9'
|
|
mov fortuneFateFields3D[320],'1'
|
|
mov fortuneFateFields3D[321],'0'
|
|
mov fortuneFateLengths3D[16],1
|
|
mov fortuneFateLengths3D[20],2
|
|
ret
|
|
ResetFortuneFate3D ENDP
|
|
|
|
FortuneFateChar3D PROC uses ebx esi edi character:DWORD
|
|
cmp fortunePhase3D,0
|
|
jne fate_char_done
|
|
mov ebx,fortuneFateField3D
|
|
cmp ebx,6
|
|
jae fate_char_done
|
|
mov eax,character
|
|
cmp eax,9
|
|
je fate_char_next
|
|
mov esi,ebx
|
|
shl esi,6
|
|
lea esi,fortuneFateFields3D[esi]
|
|
mov ecx,fortuneFateLengths3D[ebx*4]
|
|
cmp eax,8
|
|
je fate_char_backspace
|
|
cmp eax,32
|
|
jb fate_char_done
|
|
cmp eax,255
|
|
ja fate_char_done
|
|
cmp eax,127
|
|
je fate_char_done
|
|
cmp ecx,fortuneFateLimits3D[ebx*4]
|
|
jae fate_char_done
|
|
cmp ebx,2
|
|
je fate_char_date
|
|
cmp ebx,4
|
|
jae fate_char_digit
|
|
cmp eax,32
|
|
jne fate_char_store
|
|
test ecx,ecx
|
|
jz fate_char_done
|
|
cmp BYTE PTR [esi+ecx-1],32
|
|
je fate_char_done
|
|
jmp fate_char_store
|
|
fate_char_date:
|
|
cmp eax,'/'
|
|
jne @F
|
|
mov eax,'.'
|
|
@@:
|
|
cmp eax,'.'
|
|
jne fate_char_date_digit
|
|
cmp ecx,2
|
|
je fate_char_store
|
|
cmp ecx,5
|
|
je fate_char_store
|
|
jmp fate_char_done
|
|
fate_char_date_digit:
|
|
cmp eax,'0'
|
|
jb fate_char_done
|
|
cmp eax,'9'
|
|
ja fate_char_done
|
|
cmp ecx,2
|
|
je fate_char_date_dot
|
|
cmp ecx,5
|
|
jne fate_char_store
|
|
fate_char_date_dot:
|
|
mov BYTE PTR [esi+ecx],'.'
|
|
inc ecx
|
|
jmp fate_char_store
|
|
fate_char_digit:
|
|
cmp eax,'0'
|
|
jb fate_char_done
|
|
cmp eax,'9'
|
|
ja fate_char_done
|
|
fate_char_store:
|
|
mov [esi+ecx],al
|
|
inc ecx
|
|
mov fortuneFateLengths3D[ebx*4],ecx
|
|
mov BYTE PTR [esi+ecx],0
|
|
ret
|
|
fate_char_backspace:
|
|
test ecx,ecx
|
|
jz fate_char_done
|
|
dec ecx
|
|
mov fortuneFateLengths3D[ebx*4],ecx
|
|
mov BYTE PTR [esi+ecx],0
|
|
ret
|
|
fate_char_next:
|
|
inc ebx
|
|
cmp ebx,6
|
|
jb @F
|
|
xor ebx,ebx
|
|
@@:
|
|
mov fortuneFateField3D,ebx
|
|
fate_char_done:
|
|
ret
|
|
FortuneFateChar3D ENDP
|
|
|
|
; Validation is calendar-based, including leap years, not a birth-date heuristic.
|
|
ValidateFortuneBirth3D PROC uses ebx esi edi
|
|
local dayValue:DWORD,monthValue:DWORD
|
|
cmp fortuneFateLengths3D[8],10
|
|
jne fate_birth_bad
|
|
lea esi,fortuneFateFields3D[128]
|
|
cmp BYTE PTR [esi+2],'.'
|
|
jne fate_birth_bad
|
|
cmp BYTE PTR [esi+5],'.'
|
|
jne fate_birth_bad
|
|
xor ebx,ebx
|
|
xor edi,edi
|
|
fate_birth_parse:
|
|
movzx eax,BYTE PTR [esi+edi]
|
|
cmp edi,2
|
|
je fate_birth_day
|
|
cmp edi,5
|
|
je fate_birth_month
|
|
sub eax,'0'
|
|
cmp eax,9
|
|
ja fate_birth_bad
|
|
imul ebx,10
|
|
add ebx,eax
|
|
jmp fate_birth_next
|
|
fate_birth_day:
|
|
mov dayValue,ebx
|
|
xor ebx,ebx
|
|
jmp fate_birth_next
|
|
fate_birth_month:
|
|
mov monthValue,ebx
|
|
xor ebx,ebx
|
|
fate_birth_next:
|
|
inc edi
|
|
cmp edi,10
|
|
jb fate_birth_parse
|
|
cmp ebx,1900
|
|
jb fate_birth_bad
|
|
cmp ebx,2099
|
|
ja fate_birth_bad
|
|
mov eax,monthValue
|
|
dec eax
|
|
cmp eax,11
|
|
ja fate_birth_bad
|
|
movzx ecx,fortuneFateMonthDays3D[eax]
|
|
cmp eax,1
|
|
jne fate_birth_check_day
|
|
test ebx,3
|
|
jnz fate_birth_check_day
|
|
cmp ebx,1900
|
|
je fate_birth_check_day
|
|
inc ecx
|
|
fate_birth_check_day:
|
|
cmp dayValue,1
|
|
jb fate_birth_bad
|
|
cmp dayValue,ecx
|
|
ja fate_birth_bad
|
|
mov eax,1
|
|
ret
|
|
fate_birth_bad:
|
|
xor eax,eax
|
|
ret
|
|
ValidateFortuneBirth3D ENDP
|
|
|
|
ParseFortuneFateNumber3D PROC uses ebx esi slot:DWORD
|
|
mov eax,slot
|
|
mov ecx,fortuneFateLengths3D[eax*4]
|
|
test ecx,ecx
|
|
jz fate_number_bad
|
|
cmp ecx,3
|
|
ja fate_number_bad
|
|
shl eax,6
|
|
lea esi,fortuneFateFields3D[eax]
|
|
xor eax,eax
|
|
fate_number_parse:
|
|
movzx ebx,BYTE PTR [esi]
|
|
sub ebx,'0'
|
|
cmp ebx,9
|
|
ja fate_number_bad
|
|
imul eax,10
|
|
add eax,ebx
|
|
inc esi
|
|
loop fate_number_parse
|
|
cmp eax,100
|
|
ja fate_number_bad
|
|
ret
|
|
fate_number_bad:
|
|
mov eax,-1
|
|
ret
|
|
ParseFortuneFateNumber3D ENDP
|
|
|
|
SubmitFortuneFate3D PROC uses ebx
|
|
cmp fortuneSubMode3D,FORTUNE_SUBMODE_ORB
|
|
jne fate_submit_done
|
|
cmp fortunePhase3D,0
|
|
jne fate_submit_done
|
|
xor ebx,ebx
|
|
fate_submit_required:
|
|
cmp fortuneFateLengths3D[ebx*4],0
|
|
je fate_submit_missing
|
|
inc ebx
|
|
cmp ebx,6
|
|
jb fate_submit_required
|
|
call ValidateFortuneBirth3D
|
|
test eax,eax
|
|
jz fate_submit_date
|
|
invoke ParseFortuneFateNumber3D,4
|
|
cmp eax,-1
|
|
je fate_submit_low
|
|
mov fortuneFateLowValue3D,eax
|
|
invoke ParseFortuneFateNumber3D,5
|
|
cmp eax,-1
|
|
je fate_submit_high
|
|
cmp eax,fortuneFateLowValue3D
|
|
jb fate_submit_high
|
|
mov fortuneFateHighValue3D,eax
|
|
sub eax,fortuneFateLowValue3D
|
|
inc eax
|
|
; Exactly one draw, independent of identity. Renders and double clicks never reroll.
|
|
invoke RandomRange3D,eax
|
|
add eax,fortuneFateLowValue3D
|
|
mov fortuneFateResult3D,eax
|
|
mov fortunePhase3D,1
|
|
mov fortunePhaseTime3D,0
|
|
mov eax,animationClock3D
|
|
mov fortuneSessionClock3D,eax
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateRising3D
|
|
fate_submit_done:
|
|
ret
|
|
fate_submit_missing:
|
|
mov fortuneFateField3D,ebx
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateRequired3D
|
|
ret
|
|
fate_submit_date:
|
|
mov fortuneFateField3D,2
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateDateError3D
|
|
ret
|
|
fate_submit_low:
|
|
mov fortuneFateField3D,4
|
|
jmp fate_submit_range
|
|
fate_submit_high:
|
|
mov fortuneFateField3D,5
|
|
fate_submit_range:
|
|
invoke SetFortuneSpeech3D,OFFSET fortuneFateRangeError3D
|
|
ret
|
|
SubmitFortuneFate3D ENDP
|
|
|
|
DrawFortuneFateForm3D PROC uses ebx esi edi
|
|
local px:DWORD,py:DWORD,edgeInk:DWORD
|
|
invoke DrawBoxBorder,8,149,304,74,00081322h,0046637Fh,1
|
|
invoke DrawBuckshotText3D,24,304,OFFSET fortuneFatePlay3D,0086ABBCh
|
|
xor esi,esi
|
|
fate_form_field:
|
|
mov eax,fortuneFateXs3D[esi*4]
|
|
mov px,eax
|
|
shr eax,1
|
|
mov ebx,fortuneFateYs3D[esi*4]
|
|
mov py,ebx
|
|
shr ebx,1
|
|
mov edgeInk,00314D65h
|
|
cmp esi,fortuneFateField3D
|
|
jne @F
|
|
mov edgeInk,0088DDEAh
|
|
@@:
|
|
invoke DrawBoxBorder,eax,ebx,144,11,000B1D30h,edgeInk,1
|
|
mov eax,px
|
|
add eax,8
|
|
mov ebx,py
|
|
sub ebx,9
|
|
invoke DrawBuckshotText3D,eax,ebx,fortuneFateLabels3D[esi*4],00A9C8D8h
|
|
mov edi,esi
|
|
shl edi,6
|
|
add edi,OFFSET fortuneFateFields3D
|
|
mov eax,px
|
|
add eax,8
|
|
mov ebx,py
|
|
add ebx,7
|
|
cmp esi,2
|
|
jne fate_form_value
|
|
cmp fortuneFateLengths3D[8],0
|
|
jne fate_form_value
|
|
invoke DrawBuckshotText3D,eax,ebx,OFFSET fortuneFateHint3D,005A7A95h
|
|
jmp fate_form_caret
|
|
fate_form_value:
|
|
invoke DrawBuckshotText3D,eax,ebx,edi,00E8EFF4h
|
|
fate_form_caret:
|
|
cmp esi,fortuneFateField3D
|
|
jne fate_form_next
|
|
test animationClock3D,200h
|
|
jnz fate_form_next
|
|
mov eax,fortuneFateLengths3D[esi*4]
|
|
shl eax,3
|
|
add eax,px
|
|
add eax,8
|
|
mov ebx,py
|
|
add ebx,7
|
|
invoke DrawBuckshotText3D,eax,ebx,OFFSET fortuneCaret3D,00B8F3FFh
|
|
fate_form_next:
|
|
inc esi
|
|
cmp esi,6
|
|
jb fate_form_field
|
|
ret
|
|
DrawFortuneFateForm3D ENDP
|
|
|
|
DrawFortuneFateIdentity3D PROC uses ebx esi edi
|
|
invoke DrawBoxBorder,8,190,304,33,00081322h,0046637Fh,1
|
|
xor esi,esi
|
|
fate_identity_field:
|
|
mov eax,fortuneFateXs3D[esi*4]
|
|
add eax,8
|
|
mov ebx,esi
|
|
shr ebx,1
|
|
imul ebx,20
|
|
add ebx,388
|
|
mov edi,esi
|
|
shl edi,6
|
|
add edi,OFFSET fortuneFateFields3D
|
|
cmp esi,4
|
|
jb @F
|
|
invoke DrawBuckshotText3D,eax,ebx,fortuneFateLabels3D[esi*4],0086ABBCh
|
|
mov eax,fortuneFateXs3D[esi*4]
|
|
add eax,40
|
|
@@:
|
|
invoke DrawBuckshotText3D,eax,ebx,edi,00E8EFF4h
|
|
inc esi
|
|
cmp esi,6
|
|
jb fate_identity_field
|
|
ret
|
|
DrawFortuneFateIdentity3D ENDP
|
|
|
|
; One resolver supplies the frame, sprite placement and its measured glass centre.
|
|
ResolveFortuneOrb3D PROC uses ebx
|
|
mov eax,fortunePhaseTime3D
|
|
shr eax,6
|
|
and eax,15
|
|
mov fortuneOrbFrame3D,eax
|
|
mov ebx,eax
|
|
mov fortuneOrbX3D,214
|
|
mov fortuneOrbY3D,195
|
|
cmp fortunePhase3D,1
|
|
jne fate_orb_anchor
|
|
mov eax,fortunePhaseTime3D
|
|
cmp eax,1400
|
|
jbe @F
|
|
mov eax,1400
|
|
@@:
|
|
imul eax,135
|
|
xor edx,edx
|
|
mov ecx,1400
|
|
div ecx
|
|
mov ecx,330
|
|
sub ecx,eax
|
|
mov fortuneOrbY3D,ecx
|
|
fate_orb_anchor:
|
|
mov eax,fortuneOrbAnchorX3D[ebx*4]
|
|
add eax,128
|
|
shr eax,8
|
|
add eax,fortuneOrbX3D
|
|
mov fortuneOrbCenterX3D,eax
|
|
mov eax,fortuneOrbAnchorY3D[ebx*4]
|
|
add eax,128
|
|
shr eax,8
|
|
add eax,fortuneOrbY3D
|
|
mov fortuneOrbCenterY3D,eax
|
|
ret
|
|
ResolveFortuneOrb3D ENDP
|
|
|
|
DrawFortuneFateResult3D PROC uses ebx esi edi
|
|
local numberX:DWORD,numberY:DWORD
|
|
cmp fortuneFateResult3D,100
|
|
ja fate_result_done
|
|
invoke FormatNumber,fortuneFateResult3D,OFFSET fortuneFateNumber3D
|
|
lea edi,fortuneFateNumber3D
|
|
xor ebx,ebx
|
|
fate_result_length:
|
|
cmp BYTE PTR [edi+ebx],0
|
|
je fate_result_place
|
|
inc ebx
|
|
jmp fate_result_length
|
|
fate_result_place:
|
|
dec ebx
|
|
imul ebx,20
|
|
add ebx,32
|
|
shr ebx,1
|
|
neg ebx
|
|
add ebx,fortuneOrbCenterX3D
|
|
mov numberX,ebx
|
|
mov eax,fortuneOrbCenterY3D
|
|
sub eax,24
|
|
mov numberY,eax
|
|
; Fade into the mist at a constant size; preserve opacity for later draws.
|
|
push animOpacity3D
|
|
mov eax,fortunePhaseTime3D
|
|
cmp eax,900
|
|
jbe @F
|
|
mov eax,900
|
|
@@:
|
|
imul eax,255
|
|
xor edx,edx
|
|
mov ecx,900
|
|
div ecx
|
|
mov animOpacity3D,eax
|
|
fate_result_digit:
|
|
movzx esi,BYTE PTR [edi]
|
|
test esi,esi
|
|
jz fate_result_restore
|
|
sub esi,'0'
|
|
invoke DrawAnimSprite3D,OFFSET fortuneSessionNumerals3D,esi,numberX,numberY,32,48
|
|
add numberX,20
|
|
inc edi
|
|
jmp fate_result_digit
|
|
fate_result_restore:
|
|
pop animOpacity3D
|
|
fate_result_done:
|
|
ret
|
|
DrawFortuneFateResult3D ENDP
|