; Native regression: real production procedures, isolated output paths. .data artifactTestPath3D db "build\artifacts\profile.dat",0 artifactTestDir3D db "build\artifacts",0 artifactTestPreview3D db "build\artifacts\preview.dat",0 artifactTestLegacy3D db "build\artifacts\legacy.dat",0 artifactTestProfileName3D db "profile.dat",0 artifactTestLegacyName3D db "legacy.dat",0 artifactTestBmp3D db "build\artifacts\shop.bmp",0 artifactTestRewardBmp3D db "build\artifacts\rewards.bmp",0 artifactTestHeader3D db 42h,4Dh dd 1228854 dw 0,0 dd 54,40,640,-480 dw 1,32 dd 0,1228800,0,0,0,0 .code ArtifactTestCapture3D PROC uses ebx path:DWORD local io:DWORD invoke CreateFileA,path,40000000h,0,0,2,80h,0 mov ebx,eax invoke WriteFile,ebx,OFFSET artifactTestHeader3D,54,ADDR io,0 invoke WriteFile,ebx,OFFSET screenBuffer,SCREEN_SIZE*4,ADDR io,0 invoke CloseHandle,ebx ret ArtifactTestCapture3D ENDP RunArtifactTest3D PROC uses ebx esi edi local savedBank:DWORD,oldPath[260]:BYTE,io:DWORD mov obsActive3D,0 mov tournamentMode,0 mov nativeProfileActive3D,0 mov arrivalConfirmed3D,0 call ResetArtifacts3D mov bankroll,10000 invoke BuyMerchantCharm3D,0 cmp bankroll,9100 jne artifact_fail_1 cmp charmCloverUses,3 jne artifact_fail_1 invoke TriggerCharmLossProtection,100 cmp bankroll,9150 jne artifact_fail_1 cmp charmCloverUses,2 jne artifact_fail_1 invoke TriggerCharmLossProtection,0 cmp charmCloverUses,2 jne artifact_fail_1 mov charmHorseshoeUses,5 invoke TriggerCharmWinBonus,1000 cmp eax,350 jne artifact_fail_2 cmp bankroll,9500 jne artifact_fail_2 mov charmDevilUses,2 invoke ToggleArtifact3D,3 cmp charmEnabledMask3D,12 jne artifact_fail_2 invoke TriggerCharmWinBonus,100 cmp eax,100 jne artifact_fail_2 cmp charmDevilUses,1 jne artifact_fail_2 invoke TriggerCharmLossProtection,100 cmp eax,0 jne artifact_fail_2 cmp charmDevilUses,0 jne artifact_fail_2 mov charmEnabledMask3D,7 mov bankroll,999999999 invoke TriggerCharmWinBonus,1000000000 cmp eax,1 jne artifact_fail_3 cmp bankroll,1000000000 jne artifact_fail_3 mov eax,charmHorseshoeUses mov ebx,eax invoke TriggerCharmWinBonus,100 cmp charmHorseshoeUses,ebx jne artifact_fail_3 mov charmSkullUses,1 mov obsActive3D,1 invoke TriggerCharmBulletProtection test eax,eax jnz artifact_fail_4 cmp charmSkullUses,1 jne artifact_fail_4 mov obsActive3D,0 mov tournamentMode,1 invoke TriggerCharmLossProtection,100 test eax,eax jnz artifact_fail_4 invoke TriggerCharmBulletProtection test eax,eax jnz artifact_fail_4 mov towerBulletUses3D,1 invoke TriggerCharmBulletProtection cmp eax,1 jne artifact_fail_4 cmp charmSkullUses,1 jne artifact_fail_4 cmp towerBulletUses3D,0 jne artifact_fail_4 mov tournamentMode,0 mov charmCloverUses,98 mov bankroll,10000 invoke BuyMerchantCharm3D,0 cmp bankroll,10000 jne artifact_fail_5 cmp charmCloverUses,98 jne artifact_fail_5 mov charmCloverUses,0 mov bankroll,0 invoke BuyMerchantCharm3D,0 cmp charmCloverUses,0 jne artifact_fail_5 ; Reward cannot be claimed twice; reset starts a fresh run without touching bank. mov bankroll,10000 mov towerStage,1 mov towerFloorState,TOWER_STATE_BRIEFING call ResetTowerRelics3D call PrepareTowerReward3D invoke ChooseTowerRelic3D,0 invoke ChooseTowerRelic3D,0 cmp towerHeartUses3D,1 jne artifact_fail_6 mov tournamentMode,1 mov towerFloorState,TOWER_STATE_IN_GAME invoke TowerReportRoundOutcome,2 cmp towerFloorState,TOWER_STATE_BRIEFING jne artifact_fail_6 cmp towerHeartUses3D,0 jne artifact_fail_6 ; Duplicate report cannot kill a saved attempt. invoke TowerReportRoundOutcome,2 cmp towerFloorState,TOWER_STATE_BRIEFING jne artifact_fail_6 mov towerFloorState,TOWER_STATE_IN_GAME invoke TowerReportRoundOutcome,1 cmp towerRewardPending3D,1 jne artifact_fail_6 invoke ChooseTowerRelic3D,1 cmp towerSealStage3D,2 jne artifact_fail_6 cmp towerSealUses3D,2 jne artifact_fail_6 mov towerStage,2 mov towerFloorState,TOWER_STATE_IN_GAME invoke TowerReportRoundOutcome,2 cmp towerSealUses3D,1 jne artifact_fail_6 cmp towerFloorState,TOWER_STATE_BRIEFING jne artifact_fail_6 call ResetTowerRelics3D cmp towerSealUses3D,0 jne artifact_fail_6 cmp bankroll,10000 jne artifact_fail_6 ; Exact net loss refunded, not arbitrary prize or a second stake payout. mov towerPurseUses3D,1 mov towerHeartUses3D,1 mov towerEntryBank3D,10000 mov bankroll,9900 mov towerFloorState,TOWER_STATE_IN_GAME invoke TowerReportRoundOutcome,2 cmp bankroll,10000 jne artifact_fail_6 cmp towerPurseUses3D,0 jne artifact_fail_6 mov towerStage,6 mov towerFloorState,TOWER_STATE_IN_GAME invoke TowerReportRoundOutcome,1 mov eax,bankroll mov savedBank,eax invoke TowerReportRoundOutcome,1 mov eax,savedBank cmp bankroll,eax jne artifact_fail_6 cmp towerHeartUses3D,0 jne artifact_fail_6 ; Bust protection removes the real last card, without drawing a replacement. mov towerBustUses3D,1 mov cbPlayerCount3D,3 mov cbPlayer3D,8 mov cbPlayer3D[4],7 mov cbPlayer3D[8],6 call TryTowerBustSave3D cmp eax,1 jne artifact_fail_7 cmp cbPlayerCount3D,2 jne artifact_fail_7 cmp cbPlayerScore3D,19 jne artifact_fail_7 mov towerEye3D,1 mov bs3d_shellIndex,0 mov bs3d_shellCount,2 mov bs3d_shells,1 call UpdateTowerEye3D cmp bs3d_known,1 jne artifact_fail_7 mov tournamentMode,0 call ResetTowerRelics3D ; Both legacy checksum and versioned extension must validate. mov DWORD PTR [saveBuffer+280],32465241h mov DWORD PTR [saveBuffer+284],3 mov DWORD PTR [saveBuffer+288],5 mov DWORD PTR [saveBuffer+292],1 mov DWORD PTR [saveBuffer+296],2 mov DWORD PTR [saveBuffer+300],7 mov DWORD PTR [saveBuffer+304],2 invoke ArtifactSaveSignature3D,OFFSET saveBuffer mov DWORD PTR [saveBuffer+308],eax invoke ValidateArtifactSave3D,OFFSET saveBuffer cmp eax,1 jne artifact_fail_8 inc DWORD PTR [saveBuffer+284] invoke ValidateArtifactSave3D,OFFSET saveBuffer test eax,eax jnz artifact_fail_8 ; Real profile write/reload uses test paths, never runtime/profiles. invoke CreateDirectoryA,OFFSET artifactTestDir3D,0 mov nativeProfilesDirPtr3D,OFFSET artifactTestDir3D mov nativeProfileActive3D,1 invoke CopyCString,OFFSET saveFileName,OFFSET artifactTestProfileName3D mov charmCloverUses,3 mov charmHorseshoeUses,5 mov charmSkullUses,1 mov charmDevilUses,2 mov charmEnabledMask3D,7 mov bankroll,12345 call SaveGraphicProfile3D invoke ValidateGraphicProfile3D,OFFSET artifactTestPath3D cmp eax,1 jne artifact_fail_9 call ResetArtifacts3D mov bankroll,0 call LoadSave cmp bankroll,12345 jne artifact_fail_9 cmp charmCloverUses,3 jne artifact_fail_9 cmp charmDevilUses,2 jne artifact_fail_9 cmp charmEnabledMask3D,7 jne artifact_fail_9 ; A signed 280-byte legacy file imports with an empty artifact inventory. invoke CreateFileA,OFFSET artifactTestLegacy3D,40000000h,0,0,2,80h,0 mov ebx,eax invoke WriteFile,ebx,OFFSET saveBuffer,SAVE_LEGACY_SIZE,ADDR io,0 invoke CloseHandle,ebx invoke ValidateGraphicProfile3D,OFFSET artifactTestLegacy3D cmp eax,1 jne artifact_fail_9 invoke CopyCString,OFFSET saveFileName,OFFSET artifactTestLegacyName3D call LoadSave cmp charmCloverUses,0 jne artifact_fail_9 cmp bankroll,12345 jne artifact_fail_9 ; Preview format roundtrip, disabled effects and checksum rejection. mov nativeProfileActive3D,0 invoke CopyCString,OFFSET savePath3D,OFFSET artifactTestPreview3D mov arrivalConfirmed3D,1 mov bankroll,54321 mov charmCloverUses,9 mov charmHorseshoeUses,8 mov charmSkullUses,7 mov charmDevilUses,6 mov charmEnabledMask3D,4 call SaveProgress3D mov arrivalConfirmed3D,0 call ResetArtifacts3D call LoadProgress3D cmp bankroll,54321 jne artifact_fail_10 cmp charmCloverUses,9 jne artifact_fail_10 cmp charmDevilUses,6 jne artifact_fail_10 cmp charmEnabledMask3D,4 jne artifact_fail_10 invoke TriggerCharmWinBonus,100 test eax,eax jnz artifact_fail_10 cmp charmHorseshoeUses,8 jne artifact_fail_10 inc saveData3D[16] invoke CreateFileA,OFFSET artifactTestPreview3D,40000000h,0,0,2,80h,0 mov ebx,eax invoke WriteFile,ebx,OFFSET saveData3D,40,ADDR io,0 invoke CloseHandle,ebx call LoadProgress3D cmp bankroll,10000 jne artifact_fail_10 cmp charmCloverUses,0 jne artifact_fail_10 call ResetProfileDefaults cmp charmSkullUses,0 jne artifact_fail_10 ; Production Buckshot settlement pays net-profit bonus and cannot repeat it. mov bankroll,9900 mov charmEnabledMask3D,7 mov charmHorseshoeUses,2 mov bs3d_bet,100 mov bs3d_state,BS_SHOT mov bs3d_afterAnim,BS_WIN call FinishBuckshotAction3D cmp bankroll,10270 jne artifact_fail_11 cmp charmHorseshoeUses,1 jne artifact_fail_11 call FinishBuckshotAction3D cmp bankroll,10270 jne artifact_fail_11 mov bankroll,9900 mov charmCloverUses,2 mov bs3d_state,BS_SHOT mov bs3d_afterAnim,BS_LOSE call FinishBuckshotAction3D cmp bankroll,9950 jne artifact_fail_11 cmp charmCloverUses,1 jne artifact_fail_11 ; Keyboard purchase requires two presses; selection cancels confirmation. mov bankroll,10000 call ResetArtifacts3D mov merchantTab3D,1 mov merchantCharmSelected3D,0 mov artifactBuyArmed3D,0 call ClearKeys3D mov pressedKeys3D[0Dh],1 call HandleArtifactShop3D cmp bankroll,10000 jne artifact_fail_12 cmp artifactBuyArmed3D,1 jne artifact_fail_12 mov pressedKeys3D[0Dh],1 call HandleArtifactShop3D cmp bankroll,9100 jne artifact_fail_12 cmp charmCloverUses,3 jne artifact_fail_12 mov artifactBuyArmed3D,1 mov pressedKeys3D[28h],1 call HandleArtifactShop3D cmp artifactBuyArmed3D,0 jne artifact_fail_12 cmp merchantCharmSelected3D,1 jne artifact_fail_12 mov pressedKeys3D[09h],1 call HandleArtifactShop3D cmp merchantTab3D,0 jne artifact_fail_12 ; Fresh run clears every relic, stale offer and entry bankroll. mov towerHeartUses3D,5 mov towerSealUses3D,2 mov towerSealStage3D,6 mov towerBulletUses3D,2 mov towerBustUses3D,2 mov towerEye3D,1 mov towerPurseUses3D,2 call ResetTowerRelics3D mov eax,towerHeartUses3D or eax,towerSealUses3D or eax,towerSealStage3D or eax,towerBulletUses3D or eax,towerBustUses3D or eax,towerEye3D or eax,towerPurseUses3D or eax,towerEntryBank3D or eax,towerRewardPending3D test eax,eax jnz artifact_fail_12 ; Leaving each native table must end the run, not leak tournament mode to hall. mov tournamentMode,1 mov towerHeartUses3D,1 mov dice3d_state,0 call DiceEscape3D cmp tournamentMode,0 jne artifact_fail_13 cmp towerHeartUses3D,0 jne artifact_fail_13 mov tournamentMode,1 mov towerEye3D,1 mov roulState,0 call WheelEscape3D cmp tournamentMode,0 jne artifact_fail_13 cmp towerEye3D,0 jne artifact_fail_13 mov tournamentMode,1 mov towerBustUses3D,1 mov engineMode,MODE_BLACKJACK mov cbState3D,CB_IDLE call LeaveCardTable3D cmp tournamentMode,0 jne artifact_fail_13 cmp towerBustUses3D,0 jne artifact_fail_13 mov tournamentMode,1 mov towerPurseUses3D,1 mov bankroll,9950 mov coin3d_bet,50 mov coin3d_state,COIN_TOSS mov coin3d_choice,1 mov coin3d_result,1 call CoinEscape3D cmp bankroll,10050 jne artifact_fail_13 cmp tournamentMode,0 jne artifact_fail_13 cmp towerPurseUses3D,0 jne artifact_fail_13 call CoinSettle3D cmp bankroll,10050 jne artifact_fail_13 ; Situational offers follow the upcoming floor, not the one just cleared. mov towerStage,2 mov towerFloorState,TOWER_STATE_CLEAR call PrepareTowerReward3D cmp towerRewardOffers3D[4],3 jne artifact_fail_14 mov towerStage,3 call PrepareTowerReward3D cmp towerRewardOffers3D[4],2 jne artifact_fail_14 mov towerStage,5 call PrepareTowerReward3D cmp towerRewardOffers3D[4],4 jne artifact_fail_14 invoke ChooseTowerRelic3D,1 cmp towerEye3D,1 jne artifact_fail_14 call ResetTowerRelics3D ; Render shipping UI; captures inspected by the Python runner. mov merchantTab3D,1 mov merchantCharmSelected3D,0 mov merchantMessage3D,0 call RenderMerchant3D invoke ArtifactTestCapture3D,OFFSET artifactTestBmp3D mov towerStage,3 mov engineMode,MODE_HELL_TOWER mov towerFloorState,TOWER_STATE_BRIEFING call PrepareTowerReward3D call RenderHellTower3D invoke ArtifactTestCapture3D,OFFSET artifactTestRewardBmp3D xor eax,eax ret artifact_fail_1: mov eax,101 ret artifact_fail_2: mov eax,102 ret artifact_fail_3: mov eax,103 ret artifact_fail_4: mov eax,104 ret artifact_fail_5: mov eax,105 ret artifact_fail_6: mov eax,106 ret artifact_fail_7: mov eax,107 ret artifact_fail_8: mov eax,108 ret artifact_fail_9: mov eax,109 ret artifact_fail_10: mov eax,110 ret artifact_fail_11: mov eax,111 ret artifact_fail_12: mov eax,112 ret artifact_fail_13: mov eax,113 ret artifact_fail_14: mov eax,114 ret RunArtifactTest3D ENDP