.data diceSceneFormat3D db "build\actions\dice-scene-%02u.bmp",0 diceSceneName3D db 128 dup(0) diceReadySnapshot3D db "build\actions\dice-ready.bmp",0 diceMissingSnapshot3D db "build\actions\dice-missing.bmp",0 diceHeldSnapshot3D db "build\actions\dice-held-last.bmp",0 diceReleaseSnapshot3D db "build\actions\dice-release.bmp",0 diceFaceFormat3D db "build\actions\dice-face-%u.bmp",0 .code RunDiceSceneTest3D PROC uses ebx esi edi local oldBank:DWORD,oldRng:DWORD,expected:DWORD,renderRng:DWORD mov eax,bankroll mov oldBank,eax mov eax,rngSeed3D mov oldRng,eax call InitDiceGame cmp diceArtReady3D,1 jne dice_scene_test_fail mov dice3d_val1,3 mov dice3d_val2,6 call RenderDiceGame invoke WriteActionSnapshot3D,OFFSET diceReadySnapshot3D mov dice3d_state,1 xor esi,esi dice_scene_capture: imul eax,esi,40 mov dice3d_timer,eax call RenderDiceGame invoke wsprintfA,OFFSET diceSceneName3D,OFFSET diceSceneFormat3D,esi invoke WriteActionSnapshot3D,OFFSET diceSceneName3D inc esi cmp esi,40 jb dice_scene_capture mov dice3d_timer,239 call RenderDiceGame invoke WriteActionSnapshot3D,OFFSET diceHeldSnapshot3D mov dice3d_timer,240 call RenderDiceGame invoke WriteActionSnapshot3D,OFFSET diceReleaseSnapshot3D ; Every declared result must be on the upward-facing plane, with no RNG ; calls in drawing and no leaked shadow state for other cube callers. mov dice3d_state,2 mov esi,1 dice_scene_faces: mov dice3d_val1,esi mov eax,7 sub eax,esi mov dice3d_val2,eax mov dice3d_sum,7 mov eax,rngSeed3D mov renderRng,eax call RenderDiceGame mov eax,dice3d_val2 cmp cubeFaceValues3D[16],eax jne dice_scene_test_fail mov eax,renderRng cmp rngSeed3D,eax jne dice_scene_test_fail cmp cubeContactShadow3D,0 jne dice_scene_test_fail cmp diceShadowPass3D,0 jne dice_scene_test_fail invoke wsprintfA,OFFSET diceSceneName3D,OFFSET diceFaceFormat3D,esi invoke WriteActionSnapshot3D,OFFSET diceSceneName3D inc esi cmp esi,6 jbe dice_scene_faces ; Both parity choices, four tick sizes, queued mouse/keyboard-style exits. xor esi,esi dice_scene_round: call ClearKeys3D mov mouseClick3D,0 mov engineMode,MODE_DICE mov bankroll,10000 mov dice3d_bet,50 mov eax,esi and eax,1 inc eax mov dice3d_choice,eax call InitDiceGame mov pressedKeys3D[20h],1 call HandleDiceInput cmp dice3d_state,1 jne dice_scene_test_fail cmp bankroll,9950 jne dice_scene_test_fail mov eax,dice3d_val1 add eax,dice3d_val2 and eax,1 inc eax ; Even is choice 1; odd is choice 2. mov expected,9950 cmp eax,dice3d_choice jne @F add expected,100 @@: call DiceEscape3D cmp diceExitQueued3D,1 jne dice_scene_test_fail cmp engineMode,MODE_DICE jne dice_scene_test_fail mov eax,esi and eax,3 inc eax imul eax,17 mov deltaTime3D,eax mov edi,100 dice_scene_tick: call HandleDiceInput cmp dice3d_state,2 je dice_scene_settled dec edi jnz dice_scene_tick jmp dice_scene_test_fail dice_scene_settled: mov eax,expected cmp bankroll,eax jne dice_scene_test_fail cmp engineMode,MODE_WALK jne dice_scene_test_fail call HandleDiceInput mov eax,expected cmp bankroll,eax jne dice_scene_test_fail inc esi cmp esi,300 jb dice_scene_round ; Footer clicks use the same original rules as keyboard commands. call InitDiceGame call ClearKeys3D mov dice3d_choice,1 mov mouseClick3D,1 mov mouseX3D,130 mov mouseY3D,225 call HandleDiceInput cmp dice3d_choice,2 jne dice_scene_test_fail mov mouseClick3D,1 mov mouseX3D,145 mov mouseY3D,205 call HandleDiceInput cmp dice3d_bet,100 jne dice_scene_test_fail mov diceArtReady3D,0 call RenderDiceGame invoke WriteActionSnapshot3D,OFFSET diceMissingSnapshot3D mov diceArtReady3D,1 mov eax,oldBank mov bankroll,eax mov eax,oldRng mov rngSeed3D,eax mov mouseClick3D,0 call ClearKeys3D mov eax,1 ret dice_scene_test_fail: xor eax,eax ret RunDiceSceneTest3D ENDP