feat: add playable bowling match mode and calibrate rooftop character scaling
- Add playable ten-frame bowling against bot with two timing gates (direction/power) and fixed-step physics - Add lane match interaction, shaded ball surface, pin collisions, bonus balls, and live score sheet - Scale rooftop terrace visitor sprites to eye level according to the taller rooftop standing eye height - Resolve mode and interaction ID conflicts with Hell FPS (MODE_BOWLING=30, INTERACT_BOWL_PLAY=56) - Update launcher hash, installer package, and expansion regression test suites
This commit is contained in:
parent
ef5ebff353
commit
3150d217b5
28 changed files with 1700 additions and 12 deletions
BIN
bin/poker.exe
BIN
bin/poker.exe
Binary file not shown.
|
|
@ -8,7 +8,7 @@ namespace AssemblerCasinoLauncher
|
|||
{
|
||||
static class Program
|
||||
{
|
||||
const string ExpectedPokerSha256 = "D25606FE934E0D447DC4791218F8213BB1A21B0F2F7C8AFC0B61D419C03E92C0";
|
||||
const string ExpectedPokerSha256 = "2357F5876DA47FD6CD7FAE7216C71FCEDE6CCA79C1591E2BA6CFD2F3DB61694E";
|
||||
|
||||
[STAThread]
|
||||
static void Main()
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace PokerGameSetup
|
|||
sealed class InstallerForm : Form
|
||||
{
|
||||
const string Marker = "<<POKER_GAME_GUI_PAYLOAD_ZIP>>";
|
||||
const string ExpectedPayloadSha256 = "1A2AC9A543AAF354EAD5BFA4716A8677143E27D994D55120AAF4ACF8296AAA6B";
|
||||
const string ExpectedPayloadSha256 = "D44B44805C80AA6107F2F0226D0B98F0C7B085031911CB97FB89729F9B2510E6";
|
||||
readonly Color bg = Color.FromArgb(15, 12, 10);
|
||||
readonly Color panel = Color.FromArgb(28, 22, 18);
|
||||
readonly Color gold = Color.FromArgb(236, 186, 75);
|
||||
|
|
|
|||
Binary file not shown.
13
casino3d.inc
13
casino3d.inc
|
|
@ -5367,6 +5367,11 @@ pause_interior_walk:
|
|||
xor paused3D, 1
|
||||
jmp engine_tick
|
||||
leave_table:
|
||||
cmp engineMode,MODE_BOWLING
|
||||
jne @F
|
||||
call LeaveBowlingPlay3D
|
||||
jmp engine_tick
|
||||
@@:
|
||||
cmp engineMode,MODE_FORTUNE
|
||||
jne @F
|
||||
call StopFortuneWorker3D
|
||||
|
|
@ -5474,6 +5479,14 @@ engine_backrooms:
|
|||
call RenderBackrooms3D
|
||||
jmp present_frame
|
||||
check_slots_mode:
|
||||
cmp engineMode,MODE_BOWLING
|
||||
jne @F
|
||||
call HandleBowlingPlay3D
|
||||
cmp engineMode,MODE_WALK
|
||||
je check_walk_mode
|
||||
call RenderBowlingPlay3D
|
||||
jmp present_frame
|
||||
@@:
|
||||
cmp engineMode,MODE_JACKBOX
|
||||
jne check_jackbox_done
|
||||
call HandleJackbox3D
|
||||
|
|
|
|||
BIN
dist/Assembler Casino.exe
vendored
BIN
dist/Assembler Casino.exe
vendored
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
# Bowling Lounge
|
||||
|
||||
The bowling lounge is a walkable room, not a player-controlled bowling minigame.
|
||||
The bowling lounge is a walkable room with playable ten-frame bowling against a bot.
|
||||
Enter through the wide opening in the north wall of the main casino, near the
|
||||
slot-machine side of the hall. Walk through to enter or leave; no interaction
|
||||
button or timed stair/elevator animation is used.
|
||||
|
|
@ -19,7 +19,36 @@ All room geometry, rendering, input, scoring and visitor simulation run in MASM.
|
|||
Furniture is built from fixed world-space surfaces, not rotating room billboards.
|
||||
Human sprites retain the game's existing 2.5D presentation.
|
||||
|
||||
## Simulation
|
||||
## Player Game
|
||||
|
||||
Approach a free lane's foul line and press E on the play prompt. Occupied visitor
|
||||
lanes stay unavailable. There is no entry fee or bankroll change. The camera and
|
||||
room position are restored on exit; leaving abandons the current lane match.
|
||||
|
||||
The throw has two separate timing gates, both accepting either left mouse click
|
||||
or a fresh Space press. First stop the oscillating direction arrow on its curved
|
||||
horizontal scale. Then stop the vertical power indicator. The second press
|
||||
commits the launch. Holding Space cannot accidentally consume both stages.
|
||||
The arrow and meter update from elapsed time, not frame count. The ball follows
|
||||
the committed parameters without additional random error.
|
||||
|
||||
Player and bot alternate complete frames. A second ball uses the remaining rack;
|
||||
strikes, spares and tenth-frame bonuses use the shared native bowling scorer.
|
||||
The lane monitor shows the two scores and current phase. Tab toggles a cumulative
|
||||
ten-frame score sheet; unresolved bonuses stay blank rather than inventing a total.
|
||||
The sheet pauses the current throw. Escape or the Exit command returns to the room.
|
||||
After a completed match, click or Space starts a fresh match.
|
||||
|
||||
The player game uses an arcade, not regulation-grade, collision approximation:
|
||||
16-ms fixed steps, a rolling ball disc, ten pin discs, transferred pin impulses
|
||||
and pin friction. Gutters latch once entered. Pins knocked by the ball can knock
|
||||
other pins; removed pins cannot be scored again. The opponent uses the identical
|
||||
solver, with private lane RNG choosing only its launch aim and power. The camera
|
||||
follows the rolling ball; the bot uses a full-body shared-cast throwing animation.
|
||||
The blue ball is a native shaded sphere with a procedural marble surface and
|
||||
rotating finger-hole details, not a new neural or image runtime.
|
||||
|
||||
## Visitor Simulation
|
||||
|
||||
Each occupied lane owns a timer, rack mask, two players, frame counters and roll
|
||||
history. The sequence is pick-up, approach/release, ball travel, pin impact,
|
||||
|
|
@ -55,6 +84,10 @@ Run the offline packer with Python, then build the MASM executable normally.
|
|||
checks entrance visibility, walkable access, both room transitions, lane/furniture
|
||||
collision, sitting/restoration, 600 simulated seconds of lane lifecycles, perfect
|
||||
game/all-spare/open-frame score vectors, and captures room/throw screenshots.
|
||||
The additional `bowling_play_test.inc` covers LMB/Space input through native window
|
||||
events, stage separation, deterministic impacts at two frame deltas, gutters,
|
||||
empty/remaining racks, alternating turns, spare feedback, perfect games and the
|
||||
tenth-frame bonuses, unresolved score cells, scene captures and exit restoration.
|
||||
The complete hall suite includes the same bowling checks alongside existing
|
||||
stairs, doors, rooftop, fortune-room, bar and cabaret regressions. `--parity`
|
||||
compares the tested procedures with the shipping assembly object.
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ casino visitor pauses movement while standing up from a chair.
|
|||
The canvas height is 1.3 world units (192:224 aspect), calibrated against the
|
||||
hall's 1.05-unit standing eye height. The former 1.95-unit canvas made visitors
|
||||
oversized compared with the camera, staff and furniture.
|
||||
The rooftop uses a 1.65-unit standing eye height. Its visitor canvas, width and
|
||||
foot anchor are scaled by the rooftop/hall standing-eye ratio (about 1.57),
|
||||
independently of sitting or leaning. Indoor visitor sizes remain unchanged.
|
||||
|
||||
Walking uses replacement `person-*-walk-source-v2.png` sheets with contact and
|
||||
passing poses in front, rear and right profile. The left profile is mirrored.
|
||||
|
|
@ -72,6 +75,8 @@ wide contact and narrow passing foot spans. Distinct pixel hashes alone did not
|
|||
catch the old sheets' repeated leading-leg poses.
|
||||
The full hall regression includes room navigation, roof, bars, doors and stairs.
|
||||
Shipping/tested assembly parity is checked separately.
|
||||
`roof_character_scale_test.inc` checks all eight rooftop visitors in standing and
|
||||
walking states against that ratio and captures their native grounded silhouettes.
|
||||
|
||||
The older guest and bowling source packs are retained as historical assets;
|
||||
the visitor renderers no longer load or use them.
|
||||
|
|
|
|||
BIN
poker.exe
BIN
poker.exe
Binary file not shown.
BIN
poker.obj
BIN
poker.obj
Binary file not shown.
|
|
@ -1,10 +1,22 @@
|
|||
; Native room, automatic lane simulation and full-body visitors; no AI service.
|
||||
InitBowling3D PROC uses esi edi
|
||||
mov bpActive3D,0
|
||||
call InitBowlingBallSurface3D
|
||||
mov bwClock3D,-1
|
||||
mov bwMonitorClock3D,-1
|
||||
mov bwSeat3D,0
|
||||
xor esi,esi
|
||||
bw_init_lane:
|
||||
mov bwBusy3D[esi*4],0
|
||||
cmp esi,0
|
||||
je bw_init_busy
|
||||
cmp esi,3
|
||||
je bw_init_busy
|
||||
cmp esi,6
|
||||
jne bw_init_state
|
||||
bw_init_busy:
|
||||
mov bwBusy3D[esi*4],1
|
||||
bw_init_state:
|
||||
mov bwState3D[esi*4],0
|
||||
imul eax,esi,349
|
||||
mov bwTime3D[esi*4],eax
|
||||
|
|
@ -50,6 +62,13 @@ FreeBowling3D ENDP
|
|||
|
||||
ResolveBowlingSurface3D PROC material:DWORD
|
||||
mov eax,material
|
||||
cmp eax,253
|
||||
jne @F
|
||||
mov eax,OFFSET bpBallSurface3D
|
||||
mov ecx,64
|
||||
mov edx,64
|
||||
ret
|
||||
@@:
|
||||
cmp eax,252
|
||||
jne @F
|
||||
mov eax,OFFSET bwSignPixels3D
|
||||
|
|
@ -185,6 +204,22 @@ CheckBowlingInteractions3D PROC uses esi edi
|
|||
mov interactPromptPtr,OFFSET bwStandPrompt3D
|
||||
ret
|
||||
bw_check_seats:
|
||||
xor edi,edi
|
||||
bw_check_play:
|
||||
cmp bwBusy3D[edi*4],0
|
||||
jne bw_check_play_next
|
||||
imul eax,edi,BW_LANE_STEP
|
||||
add eax,3*FP_1
|
||||
mov interactTargetId,0
|
||||
invoke HallTarget3D,eax,FP_1*237/10,INTERACT_BOWL_PLAY,OFFSET bpPlayPrompt
|
||||
cmp interactTargetId,INTERACT_BOWL_PLAY
|
||||
jne bw_check_play_next
|
||||
mov bpTarget3D,edi
|
||||
ret
|
||||
bw_check_play_next:
|
||||
inc edi
|
||||
cmp edi,BW_LANES
|
||||
jb bw_check_play
|
||||
lea esi,bwSeats3D
|
||||
xor edi,edi
|
||||
bw_check_seat:
|
||||
|
|
@ -212,6 +247,11 @@ CheckBowlingInteractions3D ENDP
|
|||
TryBowlingInteraction3D PROC uses esi
|
||||
cmp hallLevel3D,HALL_BOWLING
|
||||
jne bw_try_none
|
||||
cmp interactTargetId,INTERACT_BOWL_PLAY
|
||||
jne @F
|
||||
invoke BeginBowlingPlay3D,bpTarget3D
|
||||
ret
|
||||
@@:
|
||||
cmp interactTargetId,INTERACT_BOWL_SEAT
|
||||
jne bw_try_none
|
||||
cmp bwSeat3D,0
|
||||
|
|
@ -252,3 +292,4 @@ TryBowlingInteraction3D ENDP
|
|||
|
||||
include src_graphics\bowling_simulation.inc
|
||||
include src_graphics\bowling_render.inc
|
||||
include src_graphics\bowling_play.inc
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ HALL_BOWLING equ 5
|
|||
INTERACT_BOWL_SEAT equ 53
|
||||
INTERACT_BOWL_WATCH equ 54
|
||||
BW_MATERIAL equ 230
|
||||
BW_LAST_MATERIAL equ 252
|
||||
BW_LAST_MATERIAL equ 253
|
||||
BW_LANES equ 8
|
||||
BW_LANE_STEP equ FP_1*19/10
|
||||
InitBowling3D PROTO
|
||||
|
|
@ -96,3 +96,4 @@ bwMonitors3D dd BW_LANES*128*64 dup(?)
|
|||
bwSignPixels3D dd 128*64 dup(?)
|
||||
.code
|
||||
include src_graphics\bowling_layout.inc
|
||||
include src_graphics\bowling_play_data.inc
|
||||
|
|
|
|||
507
src_graphics/bowling_play.inc
Normal file
507
src_graphics/bowling_play.inc
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
; Two timing gates commit one immutable launch; the same solver serves both players.
|
||||
BeginBowlingPlay3D PROC uses esi lane:DWORD
|
||||
cmp bpActive3D,0
|
||||
jne bp_begin_no
|
||||
mov esi,lane
|
||||
cmp esi,BW_LANES
|
||||
jae bp_begin_no
|
||||
cmp bwBusy3D[esi*4],0
|
||||
jne bp_begin_no
|
||||
mov eax,playerX
|
||||
mov bpHomeX3D,eax
|
||||
mov eax,playerY
|
||||
mov bpHomeY3D,eax
|
||||
mov eax,playerAngle
|
||||
mov bpHomeAngle3D,eax
|
||||
mov bpLane3D,esi
|
||||
imul eax,esi,BW_LANE_STEP
|
||||
add eax,3*FP_1
|
||||
mov bpCentre3D,eax
|
||||
mov bpActive3D,1
|
||||
mov bwBusy3D[esi*4],2
|
||||
mov engineMode,MODE_BOWLING
|
||||
mov paused3D,0
|
||||
mov bwSeat3D,0
|
||||
call ResetBowlingPlay3D
|
||||
mov eax,1
|
||||
ret
|
||||
bp_begin_no:
|
||||
xor eax,eax
|
||||
ret
|
||||
BeginBowlingPlay3D ENDP
|
||||
|
||||
ResetBowlingPlay3D PROC uses ebx esi edi
|
||||
mov esi,bpLane3D
|
||||
lea ebx,[esi*8]
|
||||
mov bwFrames3D[ebx],0
|
||||
mov bwFrames3D[ebx+4],0
|
||||
mov bwRollCount3D[ebx],0
|
||||
mov bwRollCount3D[ebx+4],0
|
||||
mov bwScores3D[ebx],0
|
||||
mov bwScores3D[ebx+4],0
|
||||
imul eax,esi,192
|
||||
lea edi,bwRolls3D[eax]
|
||||
xor eax,eax
|
||||
mov ecx,48
|
||||
rep stosd
|
||||
mov bwTurn3D[esi*4],0
|
||||
mov bwBall3D[esi*4],0
|
||||
mov bwRack3D[esi*4],1023
|
||||
mov bwState3D[esi*4],0
|
||||
mov bwHit3D[esi*4],0
|
||||
mov bwTime3D[esi*4],0
|
||||
mov bpState3D,BP_DIRECTION
|
||||
mov bpTime3D,0
|
||||
call BowlingPlayStartAim3D
|
||||
mov bpScoreOpen3D,0
|
||||
mov bpLast3D,0
|
||||
mov bpLastKind3D,0
|
||||
call BowlingPlayRack3D
|
||||
call ClearKeys3D
|
||||
mov mouseClick3D,0
|
||||
ret
|
||||
ResetBowlingPlay3D ENDP
|
||||
|
||||
; Randomize only the visible starting phase, never the committed trajectory.
|
||||
BowlingPlayStartAim3D PROC
|
||||
mov eax,bwRng3D
|
||||
imul eax,1664525
|
||||
add eax,1013904223
|
||||
mov bwRng3D,eax
|
||||
shr eax,16
|
||||
and eax,2047
|
||||
mov bpClock3D,eax
|
||||
ret
|
||||
BowlingPlayStartAim3D ENDP
|
||||
|
||||
LeaveBowlingPlay3D PROC uses esi
|
||||
cmp bpActive3D,0
|
||||
je bp_leave_done
|
||||
mov esi,bpLane3D
|
||||
mov bwBusy3D[esi*4],0
|
||||
mov bwRack3D[esi*4],1023
|
||||
mov bwHit3D[esi*4],0
|
||||
mov bwState3D[esi*4],0
|
||||
mov bpActive3D,0
|
||||
mov bpScoreOpen3D,0
|
||||
mov eax,bpHomeX3D
|
||||
mov playerX,eax
|
||||
mov eax,bpHomeY3D
|
||||
mov playerY,eax
|
||||
mov eax,bpHomeAngle3D
|
||||
mov playerAngle,eax
|
||||
mov engineMode,MODE_WALK
|
||||
call BowlingEye3D
|
||||
call UpdateCamera3D
|
||||
call ClearKeys3D
|
||||
mov mouseClick3D,0
|
||||
mov bwMonitorClock3D,-1
|
||||
bp_leave_done:
|
||||
ret
|
||||
LeaveBowlingPlay3D ENDP
|
||||
|
||||
BowlingPlayRack3D PROC uses esi
|
||||
xor esi,esi
|
||||
bp_rack_pin:
|
||||
mov eax,bwPinX3D[esi*4]
|
||||
mov bpPinX3D[esi*4],eax
|
||||
mov eax,bwPinY3D[esi*4]
|
||||
mov bpPinY3D[esi*4],eax
|
||||
mov bpPinVX3D[esi*4],0
|
||||
mov bpPinVY3D[esi*4],0
|
||||
inc esi
|
||||
cmp esi,10
|
||||
jb bp_rack_pin
|
||||
mov bpHitMask3D,0
|
||||
mov bpGutter3D,0
|
||||
mov bpAccumulator3D,0
|
||||
mov bpBallX3D,0
|
||||
mov bpBallY3D,FP_1*225/10
|
||||
ret
|
||||
BowlingPlayRack3D ENDP
|
||||
|
||||
BowlingPlayLaunch3D PROC
|
||||
mov bpState3D,BP_RELEASE
|
||||
mov bpTime3D,0
|
||||
mov bpAccumulator3D,0
|
||||
mov eax,bpLockedPower3D
|
||||
imul eax,6*FP_1
|
||||
cdq
|
||||
mov ecx,100
|
||||
idiv ecx
|
||||
add eax,3*FP_1
|
||||
imul eax,16
|
||||
cdq
|
||||
mov ecx,1000
|
||||
idiv ecx
|
||||
mov ecx,eax
|
||||
neg eax
|
||||
mov bpBallVY3D,eax
|
||||
mov eax,bpLockedAim3D
|
||||
imul ecx
|
||||
mov ecx,18*FP_1
|
||||
idiv ecx
|
||||
mov bpBallVX3D,eax
|
||||
ret
|
||||
BowlingPlayLaunch3D ENDP
|
||||
|
||||
BowlingPlayHit3D PROC uses esi pin:DWORD,vx:DWORD,vy:DWORD
|
||||
mov esi,pin
|
||||
mov ecx,esi
|
||||
mov eax,1
|
||||
shl eax,cl
|
||||
test bpHitMask3D,eax
|
||||
jnz bp_hit_done
|
||||
or bpHitMask3D,eax
|
||||
mov eax,vx
|
||||
mov bpPinVX3D[esi*4],eax
|
||||
mov eax,vy
|
||||
mov bpPinVY3D[esi*4],eax
|
||||
bp_hit_done:
|
||||
ret
|
||||
BowlingPlayHit3D ENDP
|
||||
|
||||
; 16-ms fixed steps, lane-relative 16.16 discs. No random hit selection.
|
||||
BowlingPlayStep3D PROC uses ebx esi edi
|
||||
local deltaX:DWORD,deltaY:DWORD,impulseX:DWORD,rackMask:DWORD
|
||||
mov esi,bpLane3D
|
||||
mov eax,bwRack3D[esi*4]
|
||||
mov rackMask,eax
|
||||
mov eax,bpBallVX3D
|
||||
add bpBallX3D,eax
|
||||
mov eax,bpBallVY3D
|
||||
add bpBallY3D,eax
|
||||
mov eax,bpBallX3D
|
||||
cdq
|
||||
xor eax,edx
|
||||
sub eax,edx
|
||||
cmp eax,FP_1*74/100
|
||||
jbe bp_step_pins
|
||||
mov bpGutter3D,1
|
||||
mov eax,FP_1*87/100
|
||||
cmp bpBallX3D,0
|
||||
jge @F
|
||||
neg eax
|
||||
@@:
|
||||
mov bpBallX3D,eax
|
||||
mov bpBallVX3D,0
|
||||
bp_step_pins:
|
||||
xor esi,esi
|
||||
bp_step_pin:
|
||||
mov ecx,esi
|
||||
mov ebx,1
|
||||
shl ebx,cl
|
||||
test rackMask,ebx
|
||||
jz bp_step_next_pin
|
||||
test bpHitMask3D,ebx
|
||||
jnz bp_step_move_pin
|
||||
cmp bpGutter3D,0
|
||||
jne bp_step_next_pin
|
||||
mov eax,bpPinX3D[esi*4]
|
||||
sub eax,bpBallX3D
|
||||
mov deltaX,eax
|
||||
sar eax,8
|
||||
imul eax,eax
|
||||
mov edi,eax
|
||||
mov eax,bpPinY3D[esi*4]
|
||||
sub eax,bpBallY3D
|
||||
sar eax,8
|
||||
imul eax,eax
|
||||
add eax,edi
|
||||
cmp eax,56*56
|
||||
ja bp_step_next_pin
|
||||
mov eax,deltaX
|
||||
sar eax,3
|
||||
add eax,bpBallVX3D
|
||||
mov impulseX,eax
|
||||
mov eax,bpBallVY3D
|
||||
imul eax,3
|
||||
sar eax,2
|
||||
invoke BowlingPlayHit3D,esi,impulseX,eax
|
||||
bp_step_move_pin:
|
||||
mov eax,bpPinVX3D[esi*4]
|
||||
add bpPinX3D[esi*4],eax
|
||||
imul eax,245
|
||||
sar eax,8
|
||||
mov bpPinVX3D[esi*4],eax
|
||||
mov eax,bpPinVY3D[esi*4]
|
||||
add bpPinY3D[esi*4],eax
|
||||
imul eax,245
|
||||
sar eax,8
|
||||
mov bpPinVY3D[esi*4],eax
|
||||
xor edi,edi
|
||||
bp_step_chain:
|
||||
mov ecx,edi
|
||||
mov ebx,1
|
||||
shl ebx,cl
|
||||
test rackMask,ebx
|
||||
jz bp_step_chain_next
|
||||
test bpHitMask3D,ebx
|
||||
jnz bp_step_chain_next
|
||||
mov eax,bpPinX3D[edi*4]
|
||||
sub eax,bpPinX3D[esi*4]
|
||||
mov deltaX,eax
|
||||
sar eax,8
|
||||
imul eax,eax
|
||||
mov ebx,eax
|
||||
mov eax,bpPinY3D[edi*4]
|
||||
sub eax,bpPinY3D[esi*4]
|
||||
mov deltaY,eax
|
||||
sar eax,8
|
||||
imul eax,eax
|
||||
add eax,ebx
|
||||
cmp eax,49*49
|
||||
ja bp_step_chain_next
|
||||
mov eax,deltaX
|
||||
sar eax,8
|
||||
imul bpPinVX3D[esi*4]
|
||||
mov ebx,eax
|
||||
mov eax,deltaY
|
||||
sar eax,8
|
||||
imul bpPinVY3D[esi*4]
|
||||
add eax,ebx
|
||||
jle bp_step_chain_next
|
||||
mov eax,bpPinVX3D[esi*4]
|
||||
sar eax,1
|
||||
mov ebx,deltaX
|
||||
sar ebx,3
|
||||
add eax,ebx
|
||||
mov impulseX,eax
|
||||
mov eax,bpPinVY3D[esi*4]
|
||||
sar eax,1
|
||||
mov ebx,deltaY
|
||||
sar ebx,3
|
||||
add eax,ebx
|
||||
invoke BowlingPlayHit3D,edi,impulseX,eax
|
||||
bp_step_chain_next:
|
||||
inc edi
|
||||
cmp edi,10
|
||||
jb bp_step_chain
|
||||
bp_step_next_pin:
|
||||
inc esi
|
||||
cmp esi,10
|
||||
jb bp_step_pin
|
||||
ret
|
||||
BowlingPlayStep3D ENDP
|
||||
|
||||
BowlingPlayFinishRoll3D PROC uses esi
|
||||
mov eax,bpHitMask3D
|
||||
xor ecx,ecx
|
||||
bp_finish_count:
|
||||
test eax,eax
|
||||
jz bp_finish_register
|
||||
lea edx,[eax-1]
|
||||
and eax,edx
|
||||
inc ecx
|
||||
jmp bp_finish_count
|
||||
bp_finish_register:
|
||||
mov bpLast3D,ecx
|
||||
mov bpLastKind3D,0
|
||||
mov esi,bpLane3D
|
||||
cmp bwBall3D[esi*4],1
|
||||
jne bp_finish_strike
|
||||
mov eax,bwFirstHit3D[esi*4]
|
||||
cmp eax,10
|
||||
je bp_finish_strike
|
||||
add eax,ecx
|
||||
cmp eax,10
|
||||
jne bp_finish_register_score
|
||||
mov bpLastKind3D,2
|
||||
jmp bp_finish_register_score
|
||||
bp_finish_strike:
|
||||
cmp ecx,10
|
||||
jne bp_finish_register_score
|
||||
mov bpLastKind3D,1
|
||||
bp_finish_register_score:
|
||||
invoke BowlingRegisterRoll3D,bpLane3D,ecx
|
||||
mov bpState3D,BP_SETTLE
|
||||
mov bpTime3D,0
|
||||
mov bwMonitorClock3D,-1
|
||||
ret
|
||||
BowlingPlayFinishRoll3D ENDP
|
||||
|
||||
BowlingPlayNext3D PROC uses ebx esi
|
||||
mov esi,bpLane3D
|
||||
mov eax,bpHitMask3D
|
||||
not eax
|
||||
and bwRack3D[esi*4],eax
|
||||
cmp bwNewRack3D[esi*4],0
|
||||
je @F
|
||||
mov bwRack3D[esi*4],1023
|
||||
@@:
|
||||
cmp bwFrameDone3D[esi*4],0
|
||||
je bp_next_ready
|
||||
xor bwTurn3D[esi*4],1
|
||||
lea ebx,[esi*2]
|
||||
add ebx,bwTurn3D[esi*4]
|
||||
cmp bwFrames3D[ebx*4],10
|
||||
jb bp_next_ready
|
||||
xor bwTurn3D[esi*4],1
|
||||
lea ebx,[esi*2]
|
||||
add ebx,bwTurn3D[esi*4]
|
||||
cmp bwFrames3D[ebx*4],10
|
||||
jb bp_next_ready
|
||||
mov bpState3D,BP_FINISHED
|
||||
ret
|
||||
bp_next_ready:
|
||||
call BowlingPlayRack3D
|
||||
call BowlingPlayStartAim3D
|
||||
mov bpTime3D,0
|
||||
mov bpState3D,BP_DIRECTION
|
||||
cmp bwTurn3D[esi*4],0
|
||||
je @F
|
||||
mov bpState3D,BP_BOT
|
||||
@@:
|
||||
ret
|
||||
BowlingPlayNext3D ENDP
|
||||
|
||||
HandleBowlingPlay3D PROC uses ebx esi
|
||||
local click:DWORD,elapsed:DWORD
|
||||
invoke Pressed3D,9
|
||||
test eax,eax
|
||||
jz @F
|
||||
xor bpScoreOpen3D,1
|
||||
@@:
|
||||
mov eax,mouseClick3D
|
||||
mov click,eax
|
||||
mov mouseClick3D,0
|
||||
cmp click,0
|
||||
je @F
|
||||
cmp mouseY3D,224
|
||||
jb @F
|
||||
cmp mouseX3D,265
|
||||
jb @F
|
||||
call LeaveBowlingPlay3D
|
||||
ret
|
||||
@@:
|
||||
invoke Pressed3D,20h
|
||||
or click,eax
|
||||
cmp bpScoreOpen3D,0
|
||||
jne bp_handle_done
|
||||
cmp bpState3D,BP_FINISHED
|
||||
jne bp_handle_clock
|
||||
cmp click,0
|
||||
je bp_handle_done
|
||||
call ResetBowlingPlay3D
|
||||
ret
|
||||
bp_handle_clock:
|
||||
mov eax,deltaTime3D
|
||||
cmp eax,250
|
||||
jbe @F
|
||||
mov eax,250
|
||||
@@:
|
||||
mov elapsed,eax
|
||||
add bpClock3D,eax
|
||||
add bpTime3D,eax
|
||||
cmp bpState3D,BP_DIRECTION
|
||||
jne bp_handle_power
|
||||
mov eax,bpClock3D
|
||||
xor edx,edx
|
||||
mov ecx,4
|
||||
div ecx
|
||||
and eax,511
|
||||
mov eax,tableSin[eax*4]
|
||||
imul eax,6
|
||||
cdq
|
||||
mov ecx,5
|
||||
idiv ecx
|
||||
mov bpAim3D,eax
|
||||
cmp click,0
|
||||
je bp_handle_done
|
||||
mov bpLockedAim3D,eax
|
||||
mov bpState3D,BP_POWER
|
||||
mov bpClock3D,0
|
||||
mov bpTime3D,0
|
||||
ret
|
||||
bp_handle_power:
|
||||
cmp bpState3D,BP_POWER
|
||||
jne bp_handle_release
|
||||
mov eax,bpClock3D
|
||||
xor edx,edx
|
||||
mov ecx,1600
|
||||
div ecx
|
||||
mov eax,edx
|
||||
cmp eax,800
|
||||
jbe @F
|
||||
neg eax
|
||||
add eax,1600
|
||||
@@:
|
||||
shr eax,3
|
||||
mov bpPower3D,eax
|
||||
cmp click,0
|
||||
je bp_handle_done
|
||||
mov bpLockedPower3D,eax
|
||||
call BowlingPlayLaunch3D
|
||||
ret
|
||||
bp_handle_release:
|
||||
cmp bpState3D,BP_RELEASE
|
||||
jne bp_handle_roll
|
||||
mov esi,bpLane3D
|
||||
mov ecx,350
|
||||
cmp bwTurn3D[esi*4],0
|
||||
je @F
|
||||
mov ecx,2400
|
||||
@@:
|
||||
cmp bpTime3D,ecx
|
||||
jb bp_handle_done
|
||||
mov bpState3D,BP_ROLL
|
||||
mov bpTime3D,0
|
||||
ret
|
||||
bp_handle_roll:
|
||||
cmp bpState3D,BP_ROLL
|
||||
jne bp_handle_settle
|
||||
mov eax,elapsed
|
||||
add bpAccumulator3D,eax
|
||||
bp_handle_fixed_step:
|
||||
cmp bpAccumulator3D,16
|
||||
jb bp_handle_roll_end
|
||||
sub bpAccumulator3D,16
|
||||
call BowlingPlayStep3D
|
||||
cmp bpBallY3D,3*FP_1
|
||||
jl bp_handle_impact_done
|
||||
jmp bp_handle_fixed_step
|
||||
bp_handle_roll_end:
|
||||
cmp bpBallY3D,3*FP_1
|
||||
jl bp_handle_impact_done
|
||||
cmp bpTime3D,12000
|
||||
jb bp_handle_done
|
||||
bp_handle_impact_done:
|
||||
call BowlingPlayFinishRoll3D
|
||||
ret
|
||||
bp_handle_settle:
|
||||
cmp bpState3D,BP_SETTLE
|
||||
jne bp_handle_bot
|
||||
cmp bpTime3D,1800
|
||||
jb bp_handle_done
|
||||
call BowlingPlayNext3D
|
||||
ret
|
||||
bp_handle_bot:
|
||||
cmp bpState3D,BP_BOT
|
||||
jne bp_handle_done
|
||||
cmp bpTime3D,1100
|
||||
jb bp_handle_done
|
||||
mov eax,bwRng3D
|
||||
imul eax,1664525
|
||||
add eax,1013904223
|
||||
mov bwRng3D,eax
|
||||
shr eax,16
|
||||
xor edx,edx
|
||||
mov ecx,101
|
||||
div ecx
|
||||
sub edx,50
|
||||
imul eax,edx,FP_1
|
||||
cdq
|
||||
mov ecx,100
|
||||
idiv ecx
|
||||
mov bpLockedAim3D,eax
|
||||
mov eax,bwRng3D
|
||||
shr eax,24
|
||||
and eax,31
|
||||
add eax,60
|
||||
mov bpLockedPower3D,eax
|
||||
call BowlingPlayLaunch3D
|
||||
bp_handle_done:
|
||||
ret
|
||||
HandleBowlingPlay3D ENDP
|
||||
|
||||
include src_graphics\bowling_play_render.inc
|
||||
80
src_graphics/bowling_play_data.inc
Normal file
80
src_graphics/bowling_play_data.inc
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
MODE_BOWLING equ 30
|
||||
INTERACT_BOWL_PLAY equ 56
|
||||
BP_DIRECTION equ 0
|
||||
BP_POWER equ 1
|
||||
BP_RELEASE equ 2
|
||||
BP_ROLL equ 3
|
||||
BP_SETTLE equ 4
|
||||
BP_BOT equ 5
|
||||
BP_FINISHED equ 6
|
||||
BeginBowlingPlay3D PROTO :DWORD
|
||||
LeaveBowlingPlay3D PROTO
|
||||
ResetBowlingPlay3D PROTO
|
||||
BowlingPlayStartAim3D PROTO
|
||||
HandleBowlingPlay3D PROTO
|
||||
RenderBowlingPlay3D PROTO
|
||||
BowlingPlayRack3D PROTO
|
||||
BowlingPlayLaunch3D PROTO
|
||||
BowlingPlayStep3D PROTO
|
||||
BowlingPlayFinishRoll3D PROTO
|
||||
BowlingPlayNext3D PROTO
|
||||
BowlingPlayHit3D PROTO :DWORD,:DWORD,:DWORD
|
||||
DrawBowlingPlayPin3D PROTO :DWORD,:DWORD
|
||||
BowlingFrameTotal3D PROTO :DWORD,:DWORD
|
||||
DrawBowlingPlayScores3D PROTO
|
||||
InitBowlingBallSurface3D PROTO
|
||||
DrawBowlingGaugeLine3D PROTO :DWORD,:DWORD,:DWORD,:DWORD
|
||||
.data
|
||||
bpActive3D dd 0
|
||||
bpLane3D dd 1
|
||||
bpTarget3D dd 1
|
||||
bpState3D dd BP_DIRECTION
|
||||
bpClock3D dd 0
|
||||
bpTime3D dd 0
|
||||
bpAim3D dd 0
|
||||
bpPower3D dd 50
|
||||
bpLockedAim3D dd 0
|
||||
bpLockedPower3D dd 50
|
||||
bpLast3D dd 0
|
||||
bpLastKind3D dd 0
|
||||
bpGutter3D dd 0
|
||||
bpAccumulator3D dd 0
|
||||
bpScoreOpen3D dd 0
|
||||
bpBallX3D dd 0
|
||||
bpBallY3D dd 0
|
||||
bpBallVX3D dd 0
|
||||
bpBallVY3D dd 0
|
||||
bpHitMask3D dd 0
|
||||
bpPinX3D dd 10 dup(0)
|
||||
bpPinY3D dd 10 dup(0)
|
||||
bpPinVX3D dd 10 dup(0)
|
||||
bpPinVY3D dd 10 dup(0)
|
||||
bpCentre3D dd 0
|
||||
bpHomeX3D dd 0
|
||||
bpHomeY3D dd 0
|
||||
bpHomeAngle3D dd 0
|
||||
bpText3D db 24 dup(0)
|
||||
bpMonitorTexts3D dd OFFSET bpDirectionText,OFFSET bpPowerText,OFFSET bpRollText,OFFSET bpRollText
|
||||
dd OFFSET bpResultText,OFFSET bpBot,OFFSET bpScoreText
|
||||
.data?
|
||||
bpBallSurface3D dd 64*64 dup(?)
|
||||
.data
|
||||
bpPlayPrompt db 200,195,208,192,210,220,32,194,32,193,206,211,203,200,205,195,0
|
||||
bpTitle db 193,206,211,203,200,205,195,0
|
||||
bpYou db 194,219,0
|
||||
bpBot db 204,192,202,209,0
|
||||
bpDirectionText db 205,192,207,208,192,194,203,197,205,200,197,0
|
||||
bpPowerText db 209,200,203,192,0
|
||||
bpRollText db 193,208,206,209,206,202,0
|
||||
bpResultText db 209,193,200,210,206,0
|
||||
bpWinText db 194,219,32,207,206,193,197,196,200,203,200,0
|
||||
bpLoseText db 207,206,193,197,196,200,203,32,204,192,202,209,0
|
||||
bpDrawText db 205,200,215,220,223,0
|
||||
bpAgainText db 209,205,206,194,192,0
|
||||
bpExitText db 194,219,201,210,200,0
|
||||
bpFrameText db 212,208,197,201,204,0
|
||||
bpScoreText db 209,215,168,210,0
|
||||
bpGutterText db 198,197,203,206,193,0
|
||||
bpStrikeText db 209,210,208,192,201,202,0
|
||||
bpSpareText db 209,207,221,208,0
|
||||
.code
|
||||
459
src_graphics/bowling_play_render.inc
Normal file
459
src_graphics/bowling_play_render.inc
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
; A small native marble surface avoids shipping a second copy of a ball sprite.
|
||||
InitBowlingBallSurface3D PROC uses ebx esi edi
|
||||
local stripe:DWORD
|
||||
xor esi,esi
|
||||
lea edi,bpBallSurface3D
|
||||
bp_ball_tex_row:
|
||||
xor ebx,ebx
|
||||
bp_ball_tex_pixel:
|
||||
mov eax,esi
|
||||
shl eax,3
|
||||
and eax,511
|
||||
mov eax,tableSin[eax*4]
|
||||
sar eax,11
|
||||
lea eax,[eax+ebx*8]
|
||||
and eax,511
|
||||
mov eax,tableSin[eax*4]
|
||||
add eax,FP_1
|
||||
shr eax,12
|
||||
mov stripe,eax
|
||||
lea edx,[eax+5]
|
||||
shl edx,16
|
||||
lea eax,[eax*2+48]
|
||||
shl eax,8
|
||||
or edx,eax
|
||||
mov eax,stripe
|
||||
shl eax,1
|
||||
add eax,155
|
||||
or eax,edx
|
||||
or eax,0FF000000h
|
||||
stosd
|
||||
inc ebx
|
||||
cmp ebx,64
|
||||
jb bp_ball_tex_pixel
|
||||
inc esi
|
||||
cmp esi,64
|
||||
jb bp_ball_tex_row
|
||||
ret
|
||||
InitBowlingBallSurface3D ENDP
|
||||
|
||||
DrawBowlingPlayPin3D PROC uses ebx esi edi pin:DWORD,centre:DWORD
|
||||
local x:DWORD,y:DWORD,z:DWORD,headY:DWORD,ry:DWORD,rz:DWORD
|
||||
mov esi,pin
|
||||
mov ecx,esi
|
||||
mov ebx,1
|
||||
shl ebx,cl
|
||||
mov edi,bpLane3D
|
||||
test bwRack3D[edi*4],ebx
|
||||
jz bp_pin_done
|
||||
mov eax,bpPinX3D[esi*4]
|
||||
add eax,centre
|
||||
mov x,eax
|
||||
mov eax,bpPinY3D[esi*4]
|
||||
mov y,eax
|
||||
mov headY,eax
|
||||
mov z,FP_1*15/100
|
||||
mov ry,FP_1/10
|
||||
mov rz,FP_1*13/100
|
||||
test bpHitMask3D,ebx
|
||||
jz bp_pin_draw
|
||||
mov z,FP_1*7/100
|
||||
mov ry,FP_1*23/100
|
||||
mov rz,FP_1*6/100
|
||||
sub headY,FP_1/4
|
||||
bp_pin_draw:
|
||||
invoke DrawRoofEllipsoid3D,x,y,z,FP_1/10,ry,rz,239
|
||||
mov eax,FP_1*34/100
|
||||
test bpHitMask3D,ebx
|
||||
jz @F
|
||||
mov eax,FP_1*7/100
|
||||
@@:
|
||||
invoke DrawRoofEllipsoid3D,x,headY,eax,FP_1*65/1000,FP_1*65/1000,FP_1*6/100,239
|
||||
mov eax,z
|
||||
add eax,rz
|
||||
invoke DrawRoofEllipsoid3D,x,headY,eax,FP_1*45/1000,FP_1*45/1000,FP_1*25/1000,240
|
||||
bp_pin_done:
|
||||
ret
|
||||
DrawBowlingPlayPin3D ENDP
|
||||
|
||||
; A frame's cumulative score stays unresolved until all its bonuses are known.
|
||||
BowlingFrameTotal3D PROC uses ebx esi edi owner:DWORD,wanted:DWORD
|
||||
local total:DWORD,index:DWORD,available:DWORD,current:DWORD
|
||||
mov ebx,owner
|
||||
mov eax,bwRollCount3D[ebx*4]
|
||||
mov available,eax
|
||||
imul ebx,96
|
||||
lea esi,bwRolls3D[ebx]
|
||||
mov index,0
|
||||
mov current,0
|
||||
mov total,0
|
||||
bp_frame_loop:
|
||||
mov edi,index
|
||||
cmp edi,available
|
||||
jae bp_frame_pending
|
||||
mov eax,[esi+edi*4]
|
||||
mov ebx,eax
|
||||
inc edi
|
||||
cmp edi,available
|
||||
jae bp_frame_pending
|
||||
add eax,[esi+edi*4]
|
||||
inc edi
|
||||
cmp ebx,10
|
||||
je bp_frame_bonus
|
||||
cmp eax,10
|
||||
jne bp_frame_open
|
||||
bp_frame_bonus:
|
||||
cmp edi,available
|
||||
jae bp_frame_pending
|
||||
add eax,[esi+edi*4]
|
||||
bp_frame_open:
|
||||
add total,eax
|
||||
cmp ebx,10
|
||||
jne @F
|
||||
dec edi
|
||||
@@:
|
||||
mov index,edi
|
||||
mov eax,current
|
||||
cmp eax,wanted
|
||||
je bp_frame_ready
|
||||
inc current
|
||||
jmp bp_frame_loop
|
||||
bp_frame_ready:
|
||||
mov eax,total
|
||||
ret
|
||||
bp_frame_pending:
|
||||
mov eax,-1
|
||||
ret
|
||||
BowlingFrameTotal3D ENDP
|
||||
|
||||
DrawBowlingPlayScores3D PROC uses ebx esi edi
|
||||
local x:DWORD,y:DWORD,owner:DWORD
|
||||
invoke DrawBoxBorder,4,47,312,139,00151F26h,005BC9BEh,1
|
||||
invoke DrawString8x8,12,55,OFFSET bpScoreText,00E8D7ADh
|
||||
xor esi,esi
|
||||
bp_score_heading:
|
||||
imul eax,esi,26
|
||||
add eax,44
|
||||
mov x,eax
|
||||
lea eax,[esi+1]
|
||||
invoke FormatNumber,eax,OFFSET bpText3D
|
||||
invoke DrawString8x8,x,73,OFFSET bpText3D,00AABDB6h
|
||||
inc esi
|
||||
cmp esi,10
|
||||
jb bp_score_heading
|
||||
xor edi,edi
|
||||
bp_score_owner:
|
||||
lea eax,[edi*2]
|
||||
imul eax,18
|
||||
add eax,96
|
||||
mov y,eax
|
||||
mov eax,OFFSET bpYou
|
||||
test edi,edi
|
||||
jz @F
|
||||
mov eax,OFFSET bpBot
|
||||
@@:
|
||||
invoke DrawString8x8,9,y,eax,005BC9BEh
|
||||
mov eax,bpLane3D
|
||||
shl eax,1
|
||||
add eax,edi
|
||||
mov owner,eax
|
||||
xor esi,esi
|
||||
bp_score_cell:
|
||||
imul eax,esi,26
|
||||
add eax,44
|
||||
mov x,eax
|
||||
invoke BowlingFrameTotal3D,owner,esi
|
||||
cmp eax,-1
|
||||
je bp_score_empty
|
||||
invoke FormatNumber,eax,OFFSET bpText3D
|
||||
invoke DrawString8x8,x,y,OFFSET bpText3D,00FFFFFFh
|
||||
jmp bp_score_next
|
||||
bp_score_empty:
|
||||
invoke DrawBox,x,y,8,1,005C727Bh
|
||||
bp_score_next:
|
||||
inc esi
|
||||
cmp esi,10
|
||||
jb bp_score_cell
|
||||
inc edi
|
||||
cmp edi,2
|
||||
jb bp_score_owner
|
||||
ret
|
||||
DrawBowlingPlayScores3D ENDP
|
||||
|
||||
DrawBowlingGaugeLine3D PROC uses ebx esi edi x0:DWORD,y0:DWORD,x1:DWORD,y1:DWORD
|
||||
local px:DWORD,py:DWORD,stepX:DWORD,stepY:DWORD
|
||||
mov eax,x1
|
||||
sub eax,x0
|
||||
cdq
|
||||
xor eax,edx
|
||||
sub eax,edx
|
||||
mov ebx,eax
|
||||
mov eax,y1
|
||||
sub eax,y0
|
||||
cdq
|
||||
xor eax,edx
|
||||
sub eax,edx
|
||||
cmp eax,ebx
|
||||
jbe @F
|
||||
mov ebx,eax
|
||||
@@:
|
||||
test ebx,ebx
|
||||
jnz @F
|
||||
inc ebx
|
||||
@@:
|
||||
mov eax,x1
|
||||
sub eax,x0
|
||||
shl eax,16
|
||||
cdq
|
||||
idiv ebx
|
||||
mov stepX,eax
|
||||
mov eax,y1
|
||||
sub eax,y0
|
||||
shl eax,16
|
||||
cdq
|
||||
idiv ebx
|
||||
mov stepY,eax
|
||||
mov eax,x0
|
||||
shl eax,16
|
||||
mov px,eax
|
||||
mov eax,y0
|
||||
shl eax,16
|
||||
mov py,eax
|
||||
inc ebx
|
||||
bp_gauge_line:
|
||||
mov eax,px
|
||||
sar eax,16
|
||||
mov edx,py
|
||||
sar edx,16
|
||||
invoke DrawBox,eax,edx,1,1,00D8F5B7h
|
||||
mov eax,stepX
|
||||
add px,eax
|
||||
mov eax,stepY
|
||||
add py,eax
|
||||
dec ebx
|
||||
jnz bp_gauge_line
|
||||
ret
|
||||
DrawBowlingGaugeLine3D ENDP
|
||||
|
||||
RenderBowlingPlay3D PROC uses ebx esi edi
|
||||
local x:DWORD,y:DWORD,color:DWORD,owner:DWORD,startY:DWORD
|
||||
mov eax,bpCentre3D
|
||||
mov playerX,eax
|
||||
mov startY,FP_1*252/10
|
||||
mov esi,bpLane3D
|
||||
cmp bwTurn3D[esi*4],0
|
||||
je @F
|
||||
mov startY,FP_1*264/10
|
||||
@@:
|
||||
mov eax,startY
|
||||
mov playerY,eax
|
||||
mov playerAngle,384
|
||||
call BowlingEye3D
|
||||
cmp bpState3D,BP_ROLL
|
||||
je bp_camera_follow
|
||||
cmp bpState3D,BP_SETTLE
|
||||
jne bp_camera_ready
|
||||
bp_camera_follow:
|
||||
mov eax,bpBallY3D
|
||||
add eax,FP_1*27/10
|
||||
cmp eax,7*FP_1
|
||||
jge @F
|
||||
mov eax,7*FP_1
|
||||
@@:
|
||||
mov playerY,eax
|
||||
mov viewEye3D,FP_1*7/10
|
||||
cmp bpState3D,BP_ROLL
|
||||
jne bp_camera_ready
|
||||
mov ebx,bpTime3D
|
||||
cmp ebx,500
|
||||
jae bp_camera_ready
|
||||
sub eax,startY
|
||||
imul eax,ebx
|
||||
cdq
|
||||
mov ecx,500
|
||||
idiv ecx
|
||||
add eax,startY
|
||||
mov playerY,eax
|
||||
imul eax,ebx,FP_1*7/20
|
||||
cdq
|
||||
idiv ecx
|
||||
mov edx,HALL_STANDING_EYE
|
||||
sub edx,eax
|
||||
mov viewEye3D,edx
|
||||
bp_camera_ready:
|
||||
call UpdateCamera3D
|
||||
call RenderBowling3D
|
||||
mov esi,bpLane3D
|
||||
cmp bwTurn3D[esi*4],1
|
||||
jne bp_render_ball
|
||||
cmp bpState3D,BP_BOT
|
||||
je bp_render_bot_ready
|
||||
cmp bpState3D,BP_RELEASE
|
||||
je bp_render_bot_throw
|
||||
cmp bpState3D,BP_ROLL
|
||||
jne bp_render_ball
|
||||
invoke ConfigureCharacter3D,OFFSET bwActor3D,6,CAST_THROW,2300,0,-FP_1
|
||||
jmp bp_render_bot_draw
|
||||
bp_render_bot_throw:
|
||||
invoke ConfigureCharacter3D,OFFSET bwActor3D,6,CAST_THROW,bpTime3D,0,-FP_1
|
||||
jmp bp_render_bot_draw
|
||||
bp_render_bot_ready:
|
||||
invoke ConfigureCharacter3D,OFFSET bwActor3D,6,CAST_IDLE,bpTime3D,0,0
|
||||
bp_render_bot_draw:
|
||||
mov eax,bpCentre3D
|
||||
add eax,FP_1*38/100
|
||||
mov bwActor3D.posX,eax
|
||||
mov bwActor3D.posY,FP_1*235/10
|
||||
invoke DrawCityObject3D,OFFSET bwActor3D,0
|
||||
bp_render_ball:
|
||||
cmp bpState3D,BP_FINISHED
|
||||
je bp_render_hud
|
||||
mov eax,bpBallX3D
|
||||
add eax,bpCentre3D
|
||||
invoke DrawBowlingBall3D,eax,bpBallY3D,253
|
||||
bp_render_hud:
|
||||
invoke DrawBox,0,0,320,17,00121B20h
|
||||
invoke DrawString8x8,8,4,OFFSET bpTitle,00E8D7ADh
|
||||
mov eax,bpLane3D
|
||||
shl eax,1
|
||||
mov owner,eax
|
||||
mov esi,eax
|
||||
invoke DrawString8x8,100,4,OFFSET bpYou,005BC9BEh
|
||||
invoke FormatNumber,bwScores3D[esi*4],OFFSET bpText3D
|
||||
invoke DrawString8x8,126,4,OFFSET bpText3D,00FFFFFFh
|
||||
invoke DrawString8x8,205,4,OFFSET bpBot,00E8D7ADh
|
||||
invoke FormatNumber,bwScores3D[esi*4+4],OFFSET bpText3D
|
||||
invoke DrawString8x8,248,4,OFFSET bpText3D,00FFFFFFh
|
||||
invoke DrawBox,0,221,320,19,00121B20h
|
||||
invoke DrawString8x8,268,227,OFFSET bpExitText,00E8D7ADh
|
||||
mov esi,bpLane3D
|
||||
mov eax,bwTurn3D[esi*4]
|
||||
add owner,eax
|
||||
mov eax,OFFSET bpYou
|
||||
cmp bwTurn3D[esi*4],0
|
||||
je @F
|
||||
mov eax,OFFSET bpBot
|
||||
@@:
|
||||
invoke DrawString8x8,8,227,eax,005BC9BEh
|
||||
mov ebx,owner
|
||||
mov eax,bwFrames3D[ebx*4]
|
||||
cmp bpState3D,BP_SETTLE
|
||||
jne @F
|
||||
cmp bwFrameDone3D[esi*4],0
|
||||
je @F
|
||||
dec eax
|
||||
@@:
|
||||
inc eax
|
||||
cmp eax,10
|
||||
jbe @F
|
||||
mov eax,10
|
||||
@@:
|
||||
invoke FormatNumber,eax,OFFSET bpText3D
|
||||
invoke DrawString8x8,60,227,OFFSET bpFrameText,00AABDB6h
|
||||
invoke DrawString8x8,116,227,OFFSET bpText3D,00FFFFFFh
|
||||
cmp bpState3D,BP_DIRECTION
|
||||
je bp_render_direction
|
||||
cmp bpState3D,BP_POWER
|
||||
je bp_render_power
|
||||
cmp bpState3D,BP_SETTLE
|
||||
je bp_render_result
|
||||
cmp bpState3D,BP_FINISHED
|
||||
je bp_render_finished
|
||||
invoke DrawString8x8,8,204,OFFSET bpRollText,00E8D7ADh
|
||||
jmp bp_render_done
|
||||
bp_render_direction:
|
||||
invoke DrawString8x8,108,145,OFFSET bpDirectionText,00E8D7ADh
|
||||
xor esi,esi
|
||||
bp_render_arc:
|
||||
lea eax,[esi-70]
|
||||
imul eax,eax
|
||||
xor edx,edx
|
||||
mov ecx,380
|
||||
div ecx
|
||||
add eax,169
|
||||
mov y,eax
|
||||
mov color,00D67057h
|
||||
cmp esi,27
|
||||
jb @F
|
||||
cmp esi,113
|
||||
ja @F
|
||||
mov color,00E7C455h
|
||||
cmp esi,59
|
||||
jb @F
|
||||
cmp esi,81
|
||||
ja @F
|
||||
mov color,005BC98Ch
|
||||
@@:
|
||||
lea eax,[esi+90]
|
||||
invoke DrawBox,eax,y,1,6,color
|
||||
inc esi
|
||||
cmp esi,141
|
||||
jb bp_render_arc
|
||||
mov eax,bpAim3D
|
||||
imul eax,52
|
||||
sar eax,16
|
||||
add eax,160
|
||||
mov x,eax
|
||||
invoke DrawBowlingGaugeLine3D,160,205,eax,162
|
||||
mov eax,x
|
||||
lea ebx,[eax-5]
|
||||
invoke DrawBowlingGaugeLine3D,eax,162,ebx,168
|
||||
mov eax,x
|
||||
lea ebx,[eax+5]
|
||||
invoke DrawBowlingGaugeLine3D,eax,162,ebx,168
|
||||
jmp bp_render_done
|
||||
bp_render_power:
|
||||
invoke DrawString8x8,246,62,OFFSET bpPowerText,00E8D7ADh
|
||||
invoke DrawBoxBorder,276,79,13,124,00121B20h,00AABDB6h,1
|
||||
invoke DrawBox,278,82,9,118,00D67057h
|
||||
invoke DrawBox,278,128,9,38,00E7C455h
|
||||
invoke DrawBox,278,82,9,46,005BC98Ch
|
||||
mov eax,bpPower3D
|
||||
imul eax,116
|
||||
xor edx,edx
|
||||
mov ecx,100
|
||||
div ecx
|
||||
mov edx,198
|
||||
sub edx,eax
|
||||
mov y,edx
|
||||
invoke DrawBox,270,y,25,2,00FFFFFFh
|
||||
invoke FormatNumber,bpPower3D,OFFSET bpText3D
|
||||
invoke DrawString8x8,246,180,OFFSET bpText3D,00FFFFFFh
|
||||
jmp bp_render_done
|
||||
bp_render_result:
|
||||
mov eax,OFFSET bpResultText
|
||||
cmp bpGutter3D,0
|
||||
je @F
|
||||
mov eax,OFFSET bpGutterText
|
||||
@@:
|
||||
cmp bpLastKind3D,1
|
||||
jne @F
|
||||
mov eax,OFFSET bpStrikeText
|
||||
@@:
|
||||
cmp bpLastKind3D,2
|
||||
jne @F
|
||||
mov eax,OFFSET bpSpareText
|
||||
@@:
|
||||
invoke DrawString8x8,104,197,eax,00E8D7ADh
|
||||
invoke FormatNumber,bpLast3D,OFFSET bpText3D
|
||||
invoke DrawString8x8,192,197,OFFSET bpText3D,00FFFFFFh
|
||||
jmp bp_render_done
|
||||
bp_render_finished:
|
||||
mov eax,bwScores3D[esi*8]
|
||||
mov ebx,OFFSET bpDrawText
|
||||
cmp eax,bwScores3D[esi*8+4]
|
||||
je @F
|
||||
mov ebx,OFFSET bpWinText
|
||||
ja @F
|
||||
mov ebx,OFFSET bpLoseText
|
||||
@@:
|
||||
invoke DrawBoxBorder,72,150,176,58,00121B20h,005BC9BEh,1
|
||||
invoke DrawString8x8,88,161,ebx,00E8D7ADh
|
||||
invoke DrawString8x8,136,187,OFFSET bpAgainText,00FFFFFFh
|
||||
bp_render_done:
|
||||
cmp bpScoreOpen3D,0
|
||||
je @F
|
||||
call DrawBowlingPlayScores3D
|
||||
@@:
|
||||
ret
|
||||
RenderBowlingPlay3D ENDP
|
||||
|
|
@ -158,7 +158,40 @@ bw_planes_done:
|
|||
RenderBowlingPlanes3D ENDP
|
||||
|
||||
DrawBowlingBall3D PROC uses ebx esi x:DWORD,y:DWORD,mat:DWORD
|
||||
local holeY:DWORD,holeZ:DWORD,phase:DWORD
|
||||
invoke DrawRoofEllipsoid3D,x,y,FP_1*135/1000,FP_1*12/100,FP_1*12/100,FP_1*12/100,mat
|
||||
cmp mat,253
|
||||
jne bw_ball_done
|
||||
mov eax,y
|
||||
sar eax,8
|
||||
and eax,511
|
||||
mov phase,eax
|
||||
mov eax,tableCos[eax*4]
|
||||
test eax,eax
|
||||
jle bw_ball_done
|
||||
imul eax,11
|
||||
cdq
|
||||
mov ecx,100
|
||||
idiv ecx
|
||||
add eax,y
|
||||
mov holeY,eax
|
||||
mov eax,phase
|
||||
mov eax,tableSin[eax*4]
|
||||
imul eax,11
|
||||
cdq
|
||||
idiv ecx
|
||||
add eax,FP_1*135/1000
|
||||
mov holeZ,eax
|
||||
mov eax,x
|
||||
sub eax,FP_1*35/1000
|
||||
invoke DrawRoofEllipsoid3D,eax,holeY,holeZ,FP_1*17/1000,FP_1*17/1000,FP_1*17/1000,233
|
||||
mov eax,x
|
||||
add eax,FP_1*35/1000
|
||||
invoke DrawRoofEllipsoid3D,eax,holeY,holeZ,FP_1*17/1000,FP_1*17/1000,FP_1*17/1000,233
|
||||
mov eax,holeZ
|
||||
sub eax,FP_1*38/1000
|
||||
invoke DrawRoofEllipsoid3D,x,holeY,eax,FP_1*18/1000,FP_1*18/1000,FP_1*18/1000,233
|
||||
bw_ball_done:
|
||||
ret
|
||||
DrawBowlingBall3D ENDP
|
||||
|
||||
|
|
@ -166,6 +199,13 @@ DrawBowlingPin3D PROC uses ebx esi edi lane:DWORD,pin:DWORD,centre:DWORD
|
|||
local x:DWORD,y:DWORD,t:DWORD,z:DWORD,ry:DWORD,rz:DWORD,headY:DWORD,headZ:DWORD
|
||||
mov esi,lane
|
||||
mov edi,pin
|
||||
cmp bpActive3D,0
|
||||
je @F
|
||||
cmp esi,bpLane3D
|
||||
jne @F
|
||||
invoke DrawBowlingPlayPin3D,edi,centre
|
||||
ret
|
||||
@@:
|
||||
mov eax,bwPinX3D[edi*4]
|
||||
add eax,centre
|
||||
mov x,eax
|
||||
|
|
@ -263,6 +303,8 @@ bw_render_pin:
|
|||
jb bw_render_pin
|
||||
cmp bwBusy3D[esi*4],0
|
||||
je bw_render_lane_next
|
||||
cmp bwBusy3D[esi*4],2
|
||||
je bw_render_lane_next
|
||||
mov time,-1
|
||||
cmp bwState3D[esi*4],2
|
||||
jne @F
|
||||
|
|
@ -347,8 +389,8 @@ RenderBowlingVisitors3D PROC uses ebx esi edi
|
|||
local action:DWORD,clock:DWORD,vx:DWORD,vy:DWORD
|
||||
xor esi,esi
|
||||
bw_cast_lane:
|
||||
cmp bwBusy3D[esi*4],0
|
||||
je bw_cast_lane_next
|
||||
cmp bwBusy3D[esi*4],1
|
||||
jne bw_cast_lane_next
|
||||
imul eax,esi,BW_LANE_STEP
|
||||
add eax,3*FP_1
|
||||
mov centre,eax
|
||||
|
|
@ -483,6 +525,12 @@ bw_cast_lane_next:
|
|||
; Four other visitors occupy the dining/bar area; ten visitors, no body doubles.
|
||||
xor esi,esi
|
||||
bw_cast_dining:
|
||||
; The match opponent leaves this restaurant seat instead of appearing twice.
|
||||
cmp bpActive3D,0
|
||||
je @F
|
||||
test esi,esi
|
||||
jz bw_cast_dining_next
|
||||
@@:
|
||||
mov eax,bwVisitorX3D[esi*4]
|
||||
mov bwSmallActor3D.posX,eax
|
||||
mov eax,bwVisitorY3D[esi*4]
|
||||
|
|
@ -494,6 +542,7 @@ bw_cast_dining:
|
|||
add bwSmallActor3D.groundZ,FP_1/4
|
||||
@@:
|
||||
invoke DrawCityObject3D,OFFSET bwSmallActor3D,0
|
||||
bw_cast_dining_next:
|
||||
inc esi
|
||||
cmp esi,4
|
||||
jb bw_cast_dining
|
||||
|
|
|
|||
|
|
@ -191,8 +191,8 @@ bw_update_stand:
|
|||
bw_update_lanes:
|
||||
xor esi,esi
|
||||
bw_update_lane:
|
||||
cmp bwBusy3D[esi*4],0
|
||||
je bw_update_next
|
||||
cmp bwBusy3D[esi*4],1
|
||||
jne bw_update_next
|
||||
mov eax,deltaTime3D
|
||||
add bwTime3D[esi*4],eax
|
||||
mov eax,bwState3D[esi*4]
|
||||
|
|
@ -372,8 +372,15 @@ bw_monitor_lane:
|
|||
invoke BowlingMonitorText3D,target,36,30,OFFSET bwFreeText3D,0FF55D9CFh
|
||||
jmp bw_monitor_advance
|
||||
bw_monitor_scores:
|
||||
cmp bwBusy3D[esi*4],2
|
||||
jne bw_monitor_visitors
|
||||
invoke BowlingMonitorText3D,target,8,21,OFFSET bpYou,0FFFF9F89h
|
||||
invoke BowlingMonitorText3D,target,70,21,OFFSET bpBot,0FF55D9CFh
|
||||
jmp bw_monitor_values
|
||||
bw_monitor_visitors:
|
||||
invoke BowlingMonitorText3D,target,8,21,OFFSET bwPlayerA3D,0FFFF9F89h
|
||||
invoke BowlingMonitorText3D,target,70,21,OFFSET bwPlayerB3D,0FF55D9CFh
|
||||
bw_monitor_values:
|
||||
lea ebx,[esi*8]
|
||||
invoke FormatNumber,bwScores3D[ebx],ADDR number
|
||||
invoke BowlingMonitorText3D,target,8,33,ADDR number,0FFFFFFFFh
|
||||
|
|
@ -381,6 +388,11 @@ bw_monitor_scores:
|
|||
invoke BowlingMonitorText3D,target,70,33,ADDR number,0FFFFFFFFh
|
||||
mov eax,bwState3D[esi*4]
|
||||
mov eax,bwPhaseTexts3D[eax*4]
|
||||
cmp bwBusy3D[esi*4],2
|
||||
jne @F
|
||||
mov eax,bpState3D
|
||||
mov eax,bpMonitorTexts3D[eax*4]
|
||||
@@:
|
||||
invoke BowlingMonitorText3D,target,8,51,eax,0FFFFBF70h
|
||||
bw_monitor_advance:
|
||||
inc esi
|
||||
|
|
|
|||
|
|
@ -166,5 +166,23 @@ ConfigureRoofVisitor3D PROC uses ebx esi edi slot:DWORD
|
|||
mov vy,-FP_1
|
||||
cast_roof_ready:
|
||||
invoke ConfigureCharacter3D,OFFSET roofActor3D,roofGuestIdentity3D[esi*4],phase,clock,vx,vy
|
||||
; The terrace uses a taller world scale than the hall; keep faces at eye level.
|
||||
mov eax,CAST_HEIGHT
|
||||
mov ecx,ROOF_STANDING_EYE
|
||||
imul ecx
|
||||
mov ecx,HALL_STANDING_EYE
|
||||
idiv ecx
|
||||
mov roofActor3D.worldH,eax
|
||||
imul eax,192
|
||||
mov ecx,224
|
||||
cdq
|
||||
idiv ecx
|
||||
mov roofActor3D.worldW,eax
|
||||
mov eax,roofActor3D.worldH
|
||||
neg eax
|
||||
cdq
|
||||
mov ecx,56
|
||||
idiv ecx
|
||||
mov roofActor3D.groundZ,eax
|
||||
ret
|
||||
ConfigureRoofVisitor3D ENDP
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ ShadeCityGround3D ENDP
|
|||
IsCityEmissive3D PROC uses ebx rgb:DWORD,material:DWORD
|
||||
cmp material,242
|
||||
jb @F
|
||||
cmp material,BW_LAST_MATERIAL
|
||||
cmp material,252
|
||||
ja @F
|
||||
mov eax,1
|
||||
ret
|
||||
|
|
|
|||
266
tools/tests/bowling_play_test.inc
Normal file
266
tools/tests/bowling_play_test.inc
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
.data
|
||||
bpTestDirection db "build\hall-expansion\bowling-play-direction.bmp",0
|
||||
bpTestDirectionLeft db "build\hall-expansion\bowling-play-direction-left.bmp",0
|
||||
bpTestPower db "build\hall-expansion\bowling-play-power.bmp",0
|
||||
bpTestPowerLow db "build\hall-expansion\bowling-play-power-low.bmp",0
|
||||
bpTestOpponent db "build\hall-expansion\bowling-play-opponent.bmp",0
|
||||
bpTestRoll db "build\hall-expansion\bowling-play-roll.bmp",0
|
||||
bpTestScores db "build\hall-expansion\bowling-play-scores.bmp",0
|
||||
.code
|
||||
BowlingPlayNativeTests PROC uses ebx esi edi
|
||||
local bank:DWORD,savedRng:DWORD,savedHits:DWORD,remainingSteps:DWORD
|
||||
mov expansionStage,150
|
||||
mov eax,bankroll
|
||||
mov bank,eax
|
||||
call InitBowling3D
|
||||
mov hallLevel3D,HALL_BOWLING
|
||||
mov engineMode,MODE_WALK
|
||||
mov playerX,5*FP_1
|
||||
mov playerY,25*FP_1
|
||||
mov playerAngle,384
|
||||
invoke BeginBowlingPlay3D,0
|
||||
test eax,eax
|
||||
jnz bp_test_fail
|
||||
invoke BeginBowlingPlay3D,1
|
||||
cmp eax,1
|
||||
jne bp_test_fail
|
||||
cmp engineMode,MODE_BOWLING
|
||||
jne bp_test_fail
|
||||
cmp bwBusy3D[4],2
|
||||
jne bp_test_fail
|
||||
mov expansionStage,151
|
||||
mov deltaTime3D,0
|
||||
mov bpClock3D,0
|
||||
mov mouseX3D,160
|
||||
mov mouseY3D,120
|
||||
mov viewWidth3D,640
|
||||
mov viewHeight3D,480
|
||||
mov viewLeft3D,0
|
||||
mov viewTop3D,0
|
||||
invoke WindowEvents3D,0,201h,1,00F00140h
|
||||
call HandleBowlingPlay3D
|
||||
cmp bpState3D,BP_POWER
|
||||
jne bp_test_fail
|
||||
invoke WindowEvents3D,0,100h,20h,40000000h
|
||||
call HandleBowlingPlay3D
|
||||
cmp bpState3D,BP_POWER
|
||||
jne bp_test_fail
|
||||
cmp bpLockedAim3D,0
|
||||
jne bp_test_fail
|
||||
call HandleBowlingPlay3D
|
||||
cmp bpState3D,BP_POWER
|
||||
jne bp_test_fail
|
||||
mov bpClock3D,560
|
||||
invoke WindowEvents3D,0,100h,20h,0
|
||||
call HandleBowlingPlay3D
|
||||
cmp bpState3D,BP_RELEASE
|
||||
jne bp_test_fail
|
||||
cmp bpLockedPower3D,70
|
||||
jne bp_test_fail
|
||||
mov eax,bwRng3D
|
||||
mov savedRng,eax
|
||||
mov deltaTime3D,16
|
||||
mov remainingSteps,1100
|
||||
bp_test_roll:
|
||||
call HandleBowlingPlay3D
|
||||
cmp bpState3D,BP_SETTLE
|
||||
je bp_test_roll_done
|
||||
dec remainingSteps
|
||||
jnz bp_test_roll
|
||||
jmp bp_test_fail
|
||||
bp_test_roll_done:
|
||||
mov eax,bwRng3D
|
||||
cmp eax,savedRng
|
||||
jne bp_test_fail
|
||||
cmp bpLast3D,1
|
||||
jb bp_test_fail
|
||||
cmp bpLast3D,10
|
||||
ja bp_test_fail
|
||||
mov eax,bpHitMask3D
|
||||
mov savedHits,eax
|
||||
; The complete fixed-step shot is identical at 16 and 32-ms frame deltas.
|
||||
call ResetBowlingPlay3D
|
||||
mov bpLockedAim3D,0
|
||||
mov bpLockedPower3D,70
|
||||
call BowlingPlayLaunch3D
|
||||
mov deltaTime3D,32
|
||||
mov remainingSteps,600
|
||||
bp_test_rate32:
|
||||
call HandleBowlingPlay3D
|
||||
cmp bpState3D,BP_SETTLE
|
||||
je bp_test_rate32_done
|
||||
dec remainingSteps
|
||||
jnz bp_test_rate32
|
||||
jmp bp_test_fail
|
||||
bp_test_rate32_done:
|
||||
mov eax,bpHitMask3D
|
||||
cmp eax,savedHits
|
||||
jne bp_test_fail
|
||||
mov expansionStage,152
|
||||
call ResetBowlingPlay3D
|
||||
mov bpLockedAim3D,0
|
||||
mov bpLockedPower3D,70
|
||||
call BowlingPlayLaunch3D
|
||||
mov esi,600
|
||||
bp_test_repeat:
|
||||
call BowlingPlayStep3D
|
||||
dec esi
|
||||
jnz bp_test_repeat
|
||||
mov eax,bpHitMask3D
|
||||
cmp eax,savedHits
|
||||
jne bp_test_fail
|
||||
call ResetBowlingPlay3D
|
||||
mov bpLockedAim3D,2*FP_1
|
||||
mov bpLockedPower3D,70
|
||||
call BowlingPlayLaunch3D
|
||||
mov esi,600
|
||||
bp_test_gutter:
|
||||
call BowlingPlayStep3D
|
||||
dec esi
|
||||
jnz bp_test_gutter
|
||||
cmp bpGutter3D,1
|
||||
jne bp_test_fail
|
||||
cmp bpHitMask3D,0
|
||||
jne bp_test_fail
|
||||
; A removed pin can never be credited again.
|
||||
call ResetBowlingPlay3D
|
||||
mov bwRack3D[4],0
|
||||
mov bpLockedAim3D,0
|
||||
mov bpLockedPower3D,70
|
||||
call BowlingPlayLaunch3D
|
||||
mov esi,600
|
||||
bp_test_empty_rack:
|
||||
call BowlingPlayStep3D
|
||||
dec esi
|
||||
jnz bp_test_empty_rack
|
||||
cmp bpHitMask3D,0
|
||||
jne bp_test_fail
|
||||
mov expansionStage,153
|
||||
call ResetBowlingPlay3D
|
||||
mov bpHitMask3D,1
|
||||
call BowlingPlayFinishRoll3D
|
||||
call BowlingPlayNext3D
|
||||
cmp bwRack3D[4],1022
|
||||
jne bp_test_fail
|
||||
cmp bwTurn3D[4],0
|
||||
jne bp_test_fail
|
||||
mov bpHitMask3D,1022
|
||||
call BowlingPlayFinishRoll3D
|
||||
call BowlingPlayNext3D
|
||||
cmp bwRack3D[4],1023
|
||||
jne bp_test_fail
|
||||
cmp bwTurn3D[4],1
|
||||
jne bp_test_fail
|
||||
cmp bpState3D,BP_BOT
|
||||
jne bp_test_fail
|
||||
cmp bpLastKind3D,2
|
||||
jne bp_test_fail
|
||||
mov deltaTime3D,250
|
||||
mov esi,5
|
||||
bp_test_bot:
|
||||
call HandleBowlingPlay3D
|
||||
dec esi
|
||||
jnz bp_test_bot
|
||||
cmp bpState3D,BP_RELEASE
|
||||
jne bp_test_fail
|
||||
mov expansionStage,154
|
||||
call ResetBowlingPlay3D
|
||||
mov bpHitMask3D,1023
|
||||
call BowlingPlayFinishRoll3D
|
||||
invoke BowlingFrameTotal3D,2,0
|
||||
cmp eax,-1
|
||||
jne bp_test_fail
|
||||
call BowlingPlayNext3D
|
||||
mov esi,23
|
||||
bp_test_perfect:
|
||||
mov bpHitMask3D,1023
|
||||
call BowlingPlayFinishRoll3D
|
||||
call BowlingPlayNext3D
|
||||
dec esi
|
||||
jnz bp_test_perfect
|
||||
cmp bpState3D,BP_FINISHED
|
||||
jne bp_test_fail
|
||||
cmp bwScores3D[8],300
|
||||
jne bp_test_fail
|
||||
cmp bwScores3D[12],300
|
||||
jne bp_test_fail
|
||||
invoke BowlingFrameTotal3D,2,9
|
||||
cmp eax,300
|
||||
jne bp_test_fail
|
||||
mov expansionStage,155
|
||||
call ResetBowlingPlay3D
|
||||
mov deltaTime3D,0
|
||||
mov bpClock3D,150
|
||||
call HandleBowlingPlay3D
|
||||
call RenderBowlingPlay3D
|
||||
invoke ExpansionSnapshot,OFFSET bpTestDirection
|
||||
mov bpClock3D,1550
|
||||
call HandleBowlingPlay3D
|
||||
call RenderBowlingPlay3D
|
||||
invoke ExpansionSnapshot,OFFSET bpTestDirectionLeft
|
||||
mov bpState3D,BP_POWER
|
||||
mov bpClock3D,560
|
||||
call HandleBowlingPlay3D
|
||||
call RenderBowlingPlay3D
|
||||
invoke ExpansionSnapshot,OFFSET bpTestPower
|
||||
mov bpClock3D,200
|
||||
call HandleBowlingPlay3D
|
||||
call RenderBowlingPlay3D
|
||||
invoke ExpansionSnapshot,OFFSET bpTestPowerLow
|
||||
mov bpScoreOpen3D,1
|
||||
call RenderBowlingPlay3D
|
||||
invoke ExpansionSnapshot,OFFSET bpTestScores
|
||||
mov bpScoreOpen3D,0
|
||||
mov bpLockedAim3D,0
|
||||
mov bpLockedPower3D,70
|
||||
call BowlingPlayLaunch3D
|
||||
mov bpState3D,BP_ROLL
|
||||
mov esi,160
|
||||
bp_test_flight:
|
||||
call BowlingPlayStep3D
|
||||
dec esi
|
||||
jnz bp_test_flight
|
||||
mov bpTime3D,2560
|
||||
call RenderBowlingPlay3D
|
||||
invoke ExpansionSnapshot,OFFSET bpTestRoll
|
||||
mov eax,bpBallY3D
|
||||
mov savedHits,eax
|
||||
mov pressedKeys3D[9],1
|
||||
mov deltaTime3D,16
|
||||
call HandleBowlingPlay3D
|
||||
call HandleBowlingPlay3D
|
||||
mov eax,bpBallY3D
|
||||
cmp eax,savedHits
|
||||
jne bp_test_fail
|
||||
mov pressedKeys3D[9],1
|
||||
call HandleBowlingPlay3D
|
||||
mov eax,bpBallY3D
|
||||
cmp eax,savedHits
|
||||
je bp_test_fail
|
||||
mov bwTurn3D[4],1
|
||||
mov bpState3D,BP_RELEASE
|
||||
mov bpTime3D,1700
|
||||
call RenderBowlingPlay3D
|
||||
invoke ExpansionSnapshot,OFFSET bpTestOpponent
|
||||
mov expansionStage,156
|
||||
call LeaveBowlingPlay3D
|
||||
cmp engineMode,MODE_WALK
|
||||
jne bp_test_fail
|
||||
cmp bwBusy3D[4],0
|
||||
jne bp_test_fail
|
||||
cmp bpActive3D,0
|
||||
jne bp_test_fail
|
||||
cmp playerX,5*FP_1
|
||||
jne bp_test_fail
|
||||
cmp playerY,25*FP_1
|
||||
jne bp_test_fail
|
||||
cmp playerAngle,384
|
||||
jne bp_test_fail
|
||||
mov eax,bankroll
|
||||
cmp eax,bank
|
||||
jne bp_test_fail
|
||||
ret
|
||||
bp_test_fail:
|
||||
invoke ExitProcess,expansionStage
|
||||
ret
|
||||
BowlingPlayNativeTests ENDP
|
||||
73
tools/tests/bowling_play_ui.inc
Normal file
73
tools/tests/bowling_play_ui.inc
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
; Interactive fixture: production MASM scene and events, no profile writes.
|
||||
.code
|
||||
BowlingUiStart PROC
|
||||
call InitPaths3D
|
||||
call Create3DWindow
|
||||
test eax,eax
|
||||
jz bp_ui_fail
|
||||
invoke SetWindowLongA,h3DWnd,-4,OFFSET WindowEvents3D
|
||||
call InitBowling3D
|
||||
call LoadBowling3D
|
||||
mov hallLevel3D,HALL_BOWLING
|
||||
mov worldMap3D,OFFSET bwMap3D
|
||||
mov playerX,FP_1*49/10
|
||||
mov playerY,25*FP_1
|
||||
mov playerAngle,384
|
||||
invoke BeginBowlingPlay3D,1
|
||||
call RenderBowlingPlay3D
|
||||
invoke ShowWindow,h3DWnd,1
|
||||
call Present3D
|
||||
invoke SetForegroundWindow,h3DWnd
|
||||
invoke GetTickCount
|
||||
mov previousTick3D,eax
|
||||
bp_ui_loop:
|
||||
invoke PeekMessageA,OFFSET msg3D,0,0,0,1
|
||||
test eax,eax
|
||||
jz bp_ui_frame
|
||||
cmp DWORD PTR msg3D[4],12h
|
||||
je bp_ui_close
|
||||
invoke TranslateMessage,OFFSET msg3D
|
||||
invoke DispatchMessageA,OFFSET msg3D
|
||||
jmp bp_ui_loop
|
||||
bp_ui_frame:
|
||||
invoke GetTickCount
|
||||
mov frameStart3D,eax
|
||||
sub eax,previousTick3D
|
||||
cmp eax,100
|
||||
jbe @F
|
||||
mov eax,100
|
||||
@@:
|
||||
mov deltaTime3D,eax
|
||||
mov eax,frameStart3D
|
||||
mov previousTick3D,eax
|
||||
invoke GetForegroundWindow
|
||||
cmp eax,h3DWnd
|
||||
jne bp_ui_idle
|
||||
invoke Pressed3D,1Bh
|
||||
test eax,eax
|
||||
jnz bp_ui_close
|
||||
mov eax,deltaTime3D
|
||||
add animationClock3D,eax
|
||||
call HandleBowlingPlay3D
|
||||
cmp engineMode,MODE_BOWLING
|
||||
jne bp_ui_mode_error
|
||||
call RenderBowlingPlay3D
|
||||
call Present3D
|
||||
bp_ui_idle:
|
||||
invoke Sleep,8
|
||||
jmp bp_ui_loop
|
||||
bp_ui_close:
|
||||
call LeaveBowlingPlay3D
|
||||
call FreeBowling3D
|
||||
call FreeCharacterCast3D
|
||||
invoke ReleaseDC,h3DWnd,h3DDC
|
||||
invoke DestroyWindow,h3DWnd
|
||||
invoke ExitProcess,0
|
||||
ret
|
||||
bp_ui_fail:
|
||||
invoke ExitProcess,157
|
||||
ret
|
||||
bp_ui_mode_error:
|
||||
invoke ExitProcess,158
|
||||
ret
|
||||
BowlingUiStart ENDP
|
||||
|
|
@ -233,8 +233,10 @@ bw_test_bar_visits:
|
|||
mov engineMode,MODE_WALK
|
||||
call ClearKeys3D
|
||||
call CharacterCastNativeTests
|
||||
call BowlingPlayNativeTests
|
||||
ret
|
||||
bw_test_fail:
|
||||
invoke ExitProcess,expansionStage
|
||||
ret
|
||||
BowlingNativeTests ENDP
|
||||
include tools/tests/bowling_play_test.inc
|
||||
|
|
|
|||
|
|
@ -260,8 +260,11 @@ cast_test_walking:
|
|||
mov phase,0
|
||||
cmp esi,CAST_COUNT
|
||||
jb cast_test_identity
|
||||
call RoofCharacterScaleNativeTests
|
||||
ret
|
||||
cast_test_fail:
|
||||
invoke ExitProcess,expansionStage
|
||||
ret
|
||||
CharacterCastNativeTests ENDP
|
||||
|
||||
include tools/tests/roof_character_scale_test.inc
|
||||
|
|
|
|||
|
|
@ -56,6 +56,12 @@ def check():
|
|||
walking[0].save(OUT/f'cast-walk-{identity}.gif',save_all=True,
|
||||
append_images=walking[1:],duration=110,loop=0)
|
||||
roster.save(OUT/'cast-native-roster.png')
|
||||
for visitor in range(8):
|
||||
native = Image.open(OUT/f'roof-cast-{visitor}.bmp').convert('RGB')
|
||||
box = ImageChops.difference(native, Image.new('RGB', native.size, (28,34,40))).getbbox()
|
||||
assert box and 175 <= box[3]-box[1] <= 270 and 195 <= box[1] <= 250,('roof visitor scale',visitor,box)
|
||||
native.save(OUT/f'roof-cast-{visitor}.png')
|
||||
print('PASS: terrace visitor proportions and grounded feet match the taller rooftop camera')
|
||||
print('PASS: ten identities, contact/passing gait, eye-level scale, 60 poses and 80 native walking frames')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,13 @@ def check_bowling_room():
|
|||
throws = [Image.open(OUT/f"bowling-throw-{i}.bmp").tobytes() for i in range(4)]
|
||||
assert len(set(throws)) == 4,"whole-body throw must visibly progress"
|
||||
assert len(captures) >= 10
|
||||
for a,b,region in (
|
||||
("direction","direction-left",(180,314,462,414)),
|
||||
("power","power-low",(536,154,596,408)),
|
||||
):
|
||||
images = [Image.open(OUT/f"bowling-play-{name}.bmp").convert("RGB").crop(region) for name in (a,b)]
|
||||
assert ImageChops.difference(*images).getbbox(), (a,b,"timing indicator must move")
|
||||
print("PASS: playable bowling gates, collision solver, frame-rate invariance, remaining racks, bonus balls, opponent and score sheet")
|
||||
print(f"PASS: eight bowling lanes, {len(reached)} connected walk points, reachable bar/dining/seats, native throw and room captures")
|
||||
|
||||
|
||||
|
|
|
|||
35
tools/tests/playtest_bowling.py
Normal file
35
tools/tests/playtest_bowling.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
"""Open the production native bowling scene without accessing player profiles."""
|
||||
import hashlib
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from check_hall_expansion import ROOT, OUT, prepare
|
||||
from check_artifacts import toolchain
|
||||
|
||||
|
||||
def main():
|
||||
def profile():
|
||||
return {str(p): hashlib.sha256(p.read_bytes()).digest()
|
||||
for p in (ROOT/'runtime').rglob('*') if p.is_file()}
|
||||
prepare()
|
||||
source = (OUT/'module.asm').read_text(encoding='cp1251')
|
||||
source = source.replace('end ExpansionTestStart',
|
||||
'include tools/tests/bowling_play_ui.inc\nend BowlingUiStart')
|
||||
target = OUT/'bowling-ui'
|
||||
target.with_suffix('.asm').write_text(source, encoding='cp1251')
|
||||
ml,link = toolchain()
|
||||
sdk = sorted(Path('C:/Program Files (x86)/Windows Kits/10/Lib').glob('*/um/x86'))[-1]
|
||||
subprocess.run([str(ml),'/c','/coff','/Cp','/nologo','/I.',
|
||||
f'/Fo{target}.obj',f'{target}.asm'],cwd=ROOT,check=True)
|
||||
subprocess.run([str(link),'/nologo','/SUBSYSTEM:WINDOWS','/ENTRY:BowlingUiStart@0',
|
||||
f'/LIBPATH:{sdk}',f'/OUT:{target}.exe',f'{target}.obj',
|
||||
str(OUT/'helpers.obj'),'kernel32.lib','user32.lib','gdi32.lib',
|
||||
'winmm.lib','ws2_32.lib'],cwd=ROOT,check=True)
|
||||
before = profile()
|
||||
result = subprocess.run([str(target.with_suffix('.exe'))],cwd=ROOT,timeout=900)
|
||||
assert result.returncode == 0,result.returncode
|
||||
assert profile() == before,'Interactive bowling changed the player profile'
|
||||
print('PASS: interactive native bowling closed without changing the player profile')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -71,10 +71,10 @@ try {
|
|||
$asmText = $cp1251.GetString($asmBytes)
|
||||
foreach ($needle in @(
|
||||
'SAVE_SIGN_SIZE equ 276',
|
||||
'SAVE_FILE_SIZE equ 280',
|
||||
'SAVE_FILE_SIZE equ 312',
|
||||
'CalcSaveSignature PROC',
|
||||
'mov DWORD PTR [saveBuffer+SAVE_SIGN_SIZE], eax',
|
||||
'cmp charsRead, SAVE_FILE_SIZE',
|
||||
'cmp charsRead,SAVE_FILE_SIZE',
|
||||
'includelib ws2_32.lib'
|
||||
)) {
|
||||
if ($asmText.IndexOf($needle) -lt 0) {
|
||||
|
|
|
|||
78
tools/tests/roof_character_scale_test.inc
Normal file
78
tools/tests/roof_character_scale_test.inc
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
.data
|
||||
roofCastTest0 db "build\hall-expansion\roof-cast-0.bmp",0
|
||||
roofCastTest1 db "build\hall-expansion\roof-cast-1.bmp",0
|
||||
roofCastTest2 db "build\hall-expansion\roof-cast-2.bmp",0
|
||||
roofCastTest3 db "build\hall-expansion\roof-cast-3.bmp",0
|
||||
roofCastTest4 db "build\hall-expansion\roof-cast-4.bmp",0
|
||||
roofCastTest5 db "build\hall-expansion\roof-cast-5.bmp",0
|
||||
roofCastTest6 db "build\hall-expansion\roof-cast-6.bmp",0
|
||||
roofCastTest7 db "build\hall-expansion\roof-cast-7.bmp",0
|
||||
roofCastTestPaths dd OFFSET roofCastTest0,OFFSET roofCastTest1,OFFSET roofCastTest2,OFFSET roofCastTest3
|
||||
dd OFFSET roofCastTest4,OFFSET roofCastTest5,OFFSET roofCastTest6,OFFSET roofCastTest7
|
||||
.code
|
||||
RoofCharacterScaleNativeTests PROC uses ebx esi edi
|
||||
local moving:DWORD
|
||||
mov expansionStage,160
|
||||
mov viewEye3D,ROOF_STANDING_EYE
|
||||
mov viewHorizon3D,HALF_H
|
||||
xor esi,esi
|
||||
roof_cast_test_visitor:
|
||||
mov eax,roofGuestMoving3D[esi*4]
|
||||
mov moving,eax
|
||||
xor ebx,ebx
|
||||
roof_cast_test_pose:
|
||||
mov roofGuestMoving3D[esi*4],ebx
|
||||
invoke ConfigureRoofVisitor3D,esi
|
||||
; Height relative to standing eyes must match the hall, in either pose.
|
||||
mov eax,roofActor3D.worldH
|
||||
mov ecx,HALL_STANDING_EYE
|
||||
imul ecx
|
||||
mov ecx,ROOF_STANDING_EYE
|
||||
idiv ecx
|
||||
sub eax,CAST_HEIGHT
|
||||
cmp eax,-1
|
||||
jl roof_cast_test_fail
|
||||
cmp eax,1
|
||||
jg roof_cast_test_fail
|
||||
mov eax,roofActor3D.worldH
|
||||
imul eax,192
|
||||
cdq
|
||||
mov ecx,224
|
||||
idiv ecx
|
||||
cmp eax,roofActor3D.worldW
|
||||
jne roof_cast_test_fail
|
||||
mov eax,roofActor3D.worldH
|
||||
neg eax
|
||||
cdq
|
||||
mov ecx,56
|
||||
idiv ecx
|
||||
cmp eax,roofActor3D.groundZ
|
||||
jne roof_cast_test_fail
|
||||
cmp roofActor3D.asset,OFFSET characterCast3D
|
||||
jne roof_cast_test_fail
|
||||
inc ebx
|
||||
cmp ebx,2
|
||||
jb roof_cast_test_pose
|
||||
invoke DrawBox,0,0,SCREEN_W,SCREEN_H,001C2228h
|
||||
lea edi,zBuffer
|
||||
mov eax,7FFFFFFFh
|
||||
mov ecx,SCREEN_W
|
||||
rep stosd
|
||||
lea edi,cityDepthBuffer3D
|
||||
mov ecx,SCREEN_SIZE
|
||||
rep stosd
|
||||
mov roofActor3D.posX,16*FP_1
|
||||
mov roofActor3D.posY,16*FP_1
|
||||
invoke DrawCityObject3D,OFFSET roofActor3D,0
|
||||
invoke ExpansionSnapshot,roofCastTestPaths[esi*4]
|
||||
mov eax,moving
|
||||
mov roofGuestMoving3D[esi*4],eax
|
||||
inc esi
|
||||
cmp esi,ROOF_GUEST_COUNT
|
||||
jb roof_cast_test_visitor
|
||||
mov viewEye3D,HALL_STANDING_EYE
|
||||
ret
|
||||
roof_cast_test_fail:
|
||||
invoke ExitProcess,expansionStage
|
||||
ret
|
||||
RoofCharacterScaleNativeTests ENDP
|
||||
Loading…
Add table
Reference in a new issue