- Billiards: add native Russian Pyramid & American Eight-Ball pool with physics prediction, controls, and regression tests - Scratch Tickets: add dedicated counter, mat presentation, elliptical coin scraping, 4 ticket types, and payout effects - First-Person Dice: add native dice scene, hand anchor frames, throwing animation, and table perspective - City Wake & Weather: add arrival cutscene, alley geometry, weather/rain effects, and lighter/rocker animation - World Dressing: add hall paintings, furniture packs, hall lighting, and scene regression tests - Build & Tooling: update build.bat for modern MSVC toolchain, update launcher hash, and refresh shipping binaries
224 lines
6.5 KiB
PHP
224 lines
6.5 KiB
PHP
.data
|
|
worldUnlitPath3D db "build\actions\world-hall-unlit.bmp",0
|
|
worldLitPath3D db "build\actions\world-hall-lit.bmp",0
|
|
worldFrontPath3D db "build\actions\world-wall-front.bmp",0
|
|
worldAnglePath3D db "build\actions\world-wall-angle.bmp",0
|
|
worldStreetPaths3D dd OFFSET worldStreetEarlyPath3D,OFFSET worldStreetMiddlePath3D,OFFSET worldStreetLatePath3D
|
|
worldStreetEarlyPath3D db "build\actions\world-street-early.bmp",0
|
|
worldStreetMiddlePath3D db "build\actions\world-street-middle.bmp",0
|
|
worldStreetLatePath3D db "build\actions\world-street-late.bmp",0
|
|
.code
|
|
WorldDressingTestFrame3D PROC
|
|
call UpdateCamera3D
|
|
call RenderCeilingAndFloor
|
|
call RenderWalls
|
|
call PrepareCityDepth3D
|
|
call RenderSprites
|
|
call RenderHall3D
|
|
ret
|
|
WorldDressingTestFrame3D ENDP
|
|
|
|
TestWorldDressing3D PROC uses ebx esi edi
|
|
local oldBank:DWORD,oldSeed:DWORD,mapSum:DWORD,oldPixel:DWORD,oldCell:DWORD,lightSum:DWORD
|
|
mov hallTestStage3D,7720
|
|
mov eax,bankroll
|
|
mov oldBank,eax
|
|
mov eax,rngSeed3D
|
|
mov oldSeed,eax
|
|
cmp worldDressingArt3D.pixels,0
|
|
je world_test_dressing_fail
|
|
cmp worldDressingArt3D.frames,3
|
|
jne world_test_dressing_fail
|
|
invoke ResolveCitySurface3D,116
|
|
cmp ecx,128
|
|
jne world_test_dressing_fail
|
|
cmp edx,128
|
|
jne world_test_dressing_fail
|
|
mov ebx,worldDressingArt3D.pixels
|
|
add ebx,128*128*4
|
|
cmp eax,ebx
|
|
jne world_test_dressing_fail
|
|
mov eax,worldDressingArt3D.pixels
|
|
mov oldPixel,eax
|
|
mov worldDressingArt3D.pixels,0
|
|
invoke ResolveDressingSurface3D,115
|
|
mov ebx,eax
|
|
mov eax,oldPixel
|
|
mov worldDressingArt3D.pixels,eax
|
|
test ebx,ebx
|
|
jnz world_test_dressing_fail
|
|
call InitHall3D
|
|
cmp viewEye3D,HALL_STANDING_EYE
|
|
jne world_test_dressing_fail
|
|
mov mapSum,0
|
|
xor esi,esi
|
|
world_test_map_sum:
|
|
movzx eax,casinoMap[esi]
|
|
add mapSum,eax
|
|
inc esi
|
|
cmp esi,1024
|
|
jb world_test_map_sum
|
|
; A temporary solid tile must block the baked light ray and is always restored.
|
|
invoke HallLightVisible3D,132,148,132,164
|
|
cmp eax,1
|
|
jne world_test_dressing_fail
|
|
movzx eax,casinoMap[19*32+16]
|
|
mov oldCell,eax
|
|
mov casinoMap[19*32+16],1
|
|
invoke HallLightVisible3D,132,148,132,164
|
|
mov ebx,eax
|
|
mov eax,oldCell
|
|
mov casinoMap[19*32+16],al
|
|
test ebx,ebx
|
|
jnz world_test_dressing_fail
|
|
cmp hallLightMap3D[19*256*8+14*8],80
|
|
jb world_test_dressing_fail
|
|
cmp hallContactMap3D[19*256*8+13*8],40
|
|
jne world_test_dressing_fail
|
|
mov lightSum,0
|
|
xor esi,esi
|
|
world_test_light_sum:
|
|
movzx eax,hallLightMap3D[esi]
|
|
add lightSum,eax
|
|
inc esi
|
|
cmp esi,65536
|
|
jb world_test_light_sum
|
|
call BuildHallLighting3D
|
|
xor ebx,ebx
|
|
xor esi,esi
|
|
world_test_rebake:
|
|
movzx eax,hallLightMap3D[esi]
|
|
add ebx,eax
|
|
inc esi
|
|
cmp esi,65536
|
|
jb world_test_rebake
|
|
cmp ebx,lightSum
|
|
jne world_test_dressing_fail
|
|
mov hallTestStage3D,7721
|
|
; Props retain one-time dimensions and floor anchors when assets are reloaded.
|
|
call LoadWorldDressing3D
|
|
xor esi,esi
|
|
world_test_street_scale:
|
|
imul ebx,esi,SIZEOF CityProp3D
|
|
cmp cityObjects3D[ebx].asset,OFFSET hallStreetLife3D
|
|
jne world_test_scale_next
|
|
cmp cityObjects3D[ebx].frame,32
|
|
jb world_test_scale_next
|
|
cmp cityObjects3D[ebx].frame,37
|
|
je world_test_dressing_fail
|
|
cmp cityObjects3D[ebx].worldH,FP_1
|
|
ja world_test_dressing_fail
|
|
cmp cityObjects3D[ebx].posX,10*FP_1
|
|
jb world_test_scale_next
|
|
cmp cityObjects3D[ebx].posX,28*FP_1+FP_HALF
|
|
jae world_test_scale_next
|
|
mov eax,cityObjects3D[ebx].posY
|
|
cmp eax,12*FP_1
|
|
jb world_test_scale_next
|
|
cmp eax,13*FP_1
|
|
jae world_test_scale_next
|
|
cmp cityObjects3D[ebx].groundZ,FP_1*3/50
|
|
jne world_test_dressing_fail
|
|
world_test_scale_next:
|
|
inc esi
|
|
cmp esi,CITY_PROP_COUNT
|
|
jb world_test_street_scale
|
|
; Outdoor, basement and disabled lighting must not alter a single pixel.
|
|
lea edi,screenBuffer
|
|
mov eax,00123456h
|
|
mov ecx,SCREEN_SIZE
|
|
rep stosd
|
|
mov outdoorRender3D,1
|
|
call ApplyHallLighting3D
|
|
mov outdoorRender3D,0
|
|
mov hallLevel3D,1
|
|
call ApplyHallLighting3D
|
|
mov hallLevel3D,0
|
|
mov hallLighting3D,0
|
|
call ApplyHallLighting3D
|
|
mov hallLighting3D,1
|
|
lea esi,screenBuffer
|
|
mov ecx,SCREEN_SIZE
|
|
world_test_unchanged:
|
|
lodsd
|
|
cmp eax,00123456h
|
|
jne world_test_dressing_fail
|
|
loop world_test_unchanged
|
|
mov hallTestStage3D,7722
|
|
invoke StreetGroundHeight3D,14*FP_1,FP_1*1265/100
|
|
cmp eax,FP_1*3/50
|
|
jne world_test_dressing_fail
|
|
invoke StreetGroundHeight3D,14*FP_1,14*FP_1
|
|
test eax,eax
|
|
jnz world_test_dressing_fail
|
|
invoke StreetGroundHeight3D,35*FP_1,FP_1*1265/100
|
|
test eax,eax
|
|
jnz world_test_dressing_fail
|
|
mov engineMode,MODE_WALK
|
|
mov playerX,14*FP_1
|
|
mov playerY,22*FP_1
|
|
mov playerAngle,384
|
|
mov viewHorizon3D,240
|
|
mov hallLighting3D,0
|
|
call WorldDressingTestFrame3D
|
|
invoke WriteActionSnapshot3D,OFFSET worldUnlitPath3D
|
|
mov hallLighting3D,1
|
|
call WorldDressingTestFrame3D
|
|
invoke WriteActionSnapshot3D,OFFSET worldLitPath3D
|
|
mov playerX,27*FP_1
|
|
mov playerY,18*FP_1
|
|
mov playerAngle,0
|
|
call WorldDressingTestFrame3D
|
|
invoke WriteActionSnapshot3D,OFFSET worldFrontPath3D
|
|
mov playerY,19*FP_1
|
|
mov playerAngle,496
|
|
call WorldDressingTestFrame3D
|
|
invoke WriteActionSnapshot3D,OFFSET worldAnglePath3D
|
|
mov hallTestStage3D,7723
|
|
mov arrivalState3D,ARRIVAL_WALK
|
|
mov cityPhase3D,CITY_STREET
|
|
xor esi,esi
|
|
world_test_street_frame:
|
|
imul eax,esi,2800
|
|
add eax,800
|
|
mov cityTime3D,eax
|
|
add eax,CITY_PRE_ALLEY_MS+6300
|
|
mov cityClock3D,eax
|
|
call RenderCityArrival3D
|
|
xor edi,edi
|
|
world_test_feet:
|
|
imul ebx,edi,SIZEOF CityProp3D
|
|
invoke StreetGroundHeight3D,cityObjects3D[ebx].posX,cityObjects3D[ebx].posY
|
|
cmp cityObjects3D[ebx].groundZ,eax
|
|
jne world_test_dressing_fail
|
|
inc edi
|
|
cmp edi,CITY_PROP_COUNT
|
|
jb world_test_feet
|
|
invoke WriteActionSnapshot3D,worldStreetPaths3D[esi*4]
|
|
inc esi
|
|
cmp esi,3
|
|
jb world_test_street_frame
|
|
; Rendering is cosmetic: casino geometry, balance and gameplay RNG are untouched.
|
|
xor esi,esi
|
|
xor ebx,ebx
|
|
world_test_map_compare:
|
|
movzx eax,casinoMap[esi]
|
|
add ebx,eax
|
|
inc esi
|
|
cmp esi,1024
|
|
jb world_test_map_compare
|
|
cmp ebx,mapSum
|
|
jne world_test_dressing_fail
|
|
mov eax,oldBank
|
|
cmp bankroll,eax
|
|
jne world_test_dressing_fail
|
|
mov eax,oldSeed
|
|
cmp rngSeed3D,eax
|
|
jne world_test_dressing_fail
|
|
call InitHall3D
|
|
mov eax,1
|
|
ret
|
|
world_test_dressing_fail:
|
|
xor eax,eax
|
|
ret
|
|
TestWorldDressing3D ENDP
|