RenderBowlingPlanes3D PROC uses ebx esi edi local row:DWORD,depth:DWORD,wx:DWORD,wy:DWORD,stepX:DWORD,stepY:DWORD local base:DWORD,tile:DWORD,ceiling:DWORD,color:DWORD,shade:DWORD mov eax,bwArt3D.pixels test eax,eax jz bw_planes_done mov base,eax mov row,0 xor edi,edi bw_planes_row: mov ceiling,0 mov eax,row sub eax,viewHorizon3D jns bw_planes_floor neg eax mov ecx,eax mov eax,viewCeiling3D sub eax,viewEye3D mov ceiling,1 jmp bw_planes_depth bw_planes_floor: inc eax mov ecx,eax mov eax,viewEye3D bw_planes_depth: imul eax,SCREEN_H cdq idiv ecx mov depth,eax shr eax,16 imul eax,3 mov ecx,250 sub ecx,eax cmp ecx,160 jae @F mov ecx,160 @@: cmp ceiling,0 je @F sub ecx,65 @@: mov shade,ecx mov eax,depth imul cityRayX3D[0] shrd eax,edx,16 add eax,playerX mov wx,eax mov eax,depth imul cityRayY3D[0] shrd eax,edx,16 add eax,playerY mov wy,eax mov eax,depth imul playerPlaneX shrd eax,edx,16 shl eax,1 cdq mov ecx,SCREEN_W idiv ecx mov stepX,eax mov eax,depth imul playerPlaneY shrd eax,edx,16 shl eax,1 cdq idiv ecx mov stepY,eax mov esi,SCREEN_W bw_planes_pixel: mov tile,1 cmp ceiling,0 jne bw_planes_ceiling_tile cmp wx,FP_1*205/100 jl bw_planes_sample cmp wx,FP_1*1725/100 jge bw_planes_sample cmp wy,FP_1*255/10 jg bw_planes_sample mov tile,0 cmp wy,FP_1*225/10 jg bw_planes_sample mov eax,wx sub eax,FP_1*205/100 cdq mov ecx,BW_LANE_STEP idiv ecx cmp edx,FP_1*18/100 jb bw_planes_gutter cmp edx,FP_1*172/100 jbe bw_planes_sample bw_planes_gutter: mov tile,3 jmp bw_planes_sample bw_planes_ceiling_tile: mov tile,3 bw_planes_sample: cmp ceiling,0 je bw_planes_texture mov eax,0021262Bh mov edx,wx and edx,1FFFFh cmp edx,1800 jb bw_planes_ceiling_seam mov edx,wy and edx,1FFFFh cmp edx,1800 jae bw_planes_shade bw_planes_ceiling_seam: mov eax,0014181Ch jmp bw_planes_shade bw_planes_texture: mov eax,wy sar eax,9 and eax,255 shl eax,8 mov edx,wx sar edx,9 and edx,255 add eax,edx mov ebx,tile shl ebx,18 add ebx,base mov eax,[ebx+eax*4] bw_planes_shade: mov color,eax movzx eax,al imul eax,shade shr eax,8 mov ebx,eax mov eax,color shr eax,8 and eax,255 imul eax,shade and eax,0FF00h or ebx,eax mov eax,color shr eax,16 and eax,255 imul eax,shade and eax,0FF00h shl eax,8 or eax,ebx mov screenBuffer[edi],eax mov eax,depth mov cityDepthBuffer3D[edi],eax mov eax,stepX add wx,eax mov eax,stepY add wy,eax add edi,4 dec esi jnz bw_planes_pixel inc row cmp row,SCREEN_H jb bw_planes_row bw_planes_done: ret RenderBowlingPlanes3D ENDP DrawBowlingBall3D PROC uses ebx esi x:DWORD,y:DWORD,mat:DWORD mov eax,y sar eax,8 and eax,511 invoke DrawBowlingBallAt3D,x,y,FP_1*135/1000,mat,eax ret DrawBowlingBall3D ENDP DrawBowlingBallAt3D PROC uses ebx esi x:DWORD,y:DWORD,z:DWORD,mat:DWORD,phase:DWORD local holeY:DWORD,holeZ:DWORD invoke DrawRoofEllipsoid3D,x,y,z,FP_1*12/100,FP_1*12/100,FP_1*12/100,mat cmp mat,253 je bw_ball_holes cmp mat,255 jb bw_ball_done cmp mat,257 ja bw_ball_done bw_ball_holes: mov eax,phase and eax,511 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,z 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 DrawBowlingBallAt3D ENDP 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 mov eax,bwPinY3D[edi*4] mov y,eax mov z,FP_1*15/100 mov ry,FP_1/10 mov rz,FP_1*13/100 mov headY,eax mov headZ,FP_1*34/100 mov ecx,edi mov ebx,1 shl ebx,cl test bwRack3D[esi*4],ebx jz bw_pin_done cmp bwState3D[esi*4],4 jne bw_pin_draw test bwHit3D[esi*4],ebx jz bw_pin_draw cmp bwTime3D[esi*4],1200 ja bw_pin_done mov eax,bwTime3D[esi*4] imul edx,edi,23 sub eax,edx jle bw_pin_draw cmp eax,500 jbe @F mov eax,500 @@: mov t,eax imul eax,FP_1*7/100 cdq mov ecx,500 idiv ecx sub z,eax sub rz,eax mov eax,t imul eax,FP_1*14/100 cdq idiv ecx add ry,eax mov eax,t imul eax,FP_1*30/100 cdq idiv ecx sub headY,eax mov eax,t imul eax,FP_1*24/100 cdq idiv ecx sub headZ,eax bw_pin_draw: invoke DrawRoofEllipsoid3D,x,y,z,FP_1/10,ry,rz,239 invoke DrawRoofEllipsoid3D,x,headY,headZ,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 bw_pin_done: ret DrawBowlingPin3D ENDP RenderBowlingLanes3D PROC uses ebx esi edi local centre:DWORD,lo:DWORD,hi:DWORD,time:DWORD,ballX:DWORD,ballY:DWORD,mat:DWORD local monitorLo:DWORD,monitorHi:DWORD xor esi,esi bw_render_lane: imul eax,esi,BW_LANE_STEP add eax,3*FP_1 mov centre,eax sub eax,FP_1*83/100 mov lo,eax add eax,FP_1*166/100 mov hi,eax invoke DrawRoofSolid3D,lo,hi,FP_1*16/10,FP_1*29/10,0,FP_1*17/10,233 invoke DrawCityVertical3D,1,FP_1*291/100,lo,hi,FP_1*13/10,FP_1*18/10,234 mov eax,centre sub eax,FP_1*65/100 mov ebx,centre add ebx,FP_1*65/100 mov monitorLo,eax mov monitorHi,ebx invoke DrawRoofSolid3D,eax,ebx,FP_1*216/10,FP_1*219/10,FP_1*29/10,FP_1*38/10,238 lea edx,[esi+244] invoke DrawCityVertical3D,1,FP_1*2191/100,monitorLo,monitorHi,3*FP_1,FP_1*37/10,edx mov eax,centre sub eax,FP_1*4/100 mov ebx,centre add ebx,FP_1*4/100 invoke DrawRoofSolid3D,eax,ebx,FP_1*217/10,FP_1*218/10,FP_1*38/10,6*FP_1,238 xor edi,edi bw_render_pin: invoke DrawBowlingPin3D,esi,edi,centre inc edi cmp edi,10 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 mov eax,bwTime3D[esi*4] sub eax,1800 js bw_render_lane_next mov time,eax @@: cmp bwState3D[esi*4],3 jne @F mov eax,bwTime3D[esi*4] add eax,600 mov time,eax @@: cmp time,-1 je bw_render_sweeper mov eax,time imul bwAim3D[esi*4] mov ecx,3000 idiv ecx add eax,centre mov ballX,eax mov eax,time imul eax,FP_1*183/10 cdq idiv ecx mov edx,FP_1*225/10 sub edx,eax mov ballY,edx mov mat,242 cmp bwTurn3D[esi*4],0 je @F mov mat,243 @@: invoke DrawBowlingBall3D,ballX,ballY,mat bw_render_sweeper: cmp bwState3D[esi*4],4 jne bw_render_lane_next mov eax,bwTime3D[esi*4] cmp eax,700 jb bw_render_lane_next sub eax,700 cmp eax,1000 jbe @F mov eax,1000 @@: imul eax,2*FP_1 cdq mov ecx,1000 idiv ecx mov ebx,5*FP_1 sub ebx,eax mov eax,ebx add eax,FP_1/8 invoke DrawRoofSolid3D,lo,hi,ebx,eax,FP_1/5,FP_1*35/100,243 bw_render_lane_next: inc esi cmp esi,BW_LANES jb bw_render_lane ret RenderBowlingLanes3D ENDP BowlingHome3D PROC lane:DWORD,owner:DWORD mov eax,lane shr eax,1 imul eax,FP_1*38/10 add eax,FP_1*395/100 sub eax,FP_1*65/100 test lane,1 jz @F add eax,FP_1*9/10 @@: cmp owner,0 je @F add eax,FP_1*55/100 @@: ret BowlingHome3D ENDP RenderBowlingVisitors3D PROC uses ebx esi edi local centre:DWORD,homeX:DWORD,person:DWORD,phase:DWORD,t:DWORD local action:DWORD,clock:DWORD,vx:DWORD,vy:DWORD xor esi,esi bw_cast_lane: cmp bwBusy3D[esi*4],1 jne bw_cast_lane_next imul eax,esi,BW_LANE_STEP add eax,3*FP_1 mov centre,eax invoke BowlingHome3D,esi,bwTurn3D[esi*4] mov homeX,eax mov bwActor3D.posX,eax mov bwActor3D.posY,FP_1*279/10 lea ebx,[esi*2] add ebx,bwTurn3D[esi*4] mov eax,bwCharacterIds3D[ebx*4] mov person,eax mov eax,bwState3D[esi*4] mov phase,eax mov eax,bwTime3D[esi*4] mov t,eax mov clock,eax mov action,CAST_SEAT_TALK mov vx,0 mov vy,0 cmp phase,0 jne bw_cast_not_rest cmp eax,1500 jb bw_cast_draw sub clock,1500 mov action,CAST_STAND_UP jmp bw_cast_draw bw_cast_not_rest: cmp phase,6 jne bw_cast_not_seat cmp eax,800 jae bw_cast_draw mov action,CAST_SIT_DOWN jmp bw_cast_draw bw_cast_not_seat: cmp phase,1 jne bw_cast_not_pick cmp eax,1800 jae bw_cast_pick mov action,CAST_WALK mov vy,-FP_1 mov eax,centre sub eax,homeX mov vx,eax imul t mov ecx,1800 idiv ecx add eax,homeX mov bwActor3D.posX,eax mov eax,t imul eax,FP_1*24/10 cdq idiv ecx mov clock,eax mov edx,FP_1*279/10 sub edx,eax mov bwActor3D.posY,edx jmp bw_cast_draw bw_cast_pick: mov eax,centre mov bwActor3D.posX,eax mov bwActor3D.posY,FP_1*255/10 mov action,CAST_PICK_UP sub clock,1800 jmp bw_cast_draw bw_cast_not_pick: mov eax,centre mov bwActor3D.posX,eax mov bwActor3D.posY,FP_1*226/10 mov action,CAST_IDLE cmp phase,2 jne bw_cast_not_throw mov action,CAST_THROW mov eax,t imul eax,FP_1*29/10 cdq mov ecx,2400 idiv ecx mov edx,FP_1*255/10 sub edx,eax mov bwActor3D.posY,edx jmp bw_cast_draw bw_cast_not_throw: cmp phase,3 jne @F mov action,CAST_THROW mov clock,2300 @@: cmp phase,4 jne bw_cast_not_impact cmp bwHit3D[esi*4],0 je bw_cast_draw mov action,CAST_CHEER jmp bw_cast_draw bw_cast_not_impact: cmp phase,5 jne bw_cast_draw mov action,CAST_WALK mov vy,FP_1 mov eax,homeX sub eax,centre mov vx,eax imul t mov ecx,3600 idiv ecx add eax,centre mov bwActor3D.posX,eax mov eax,t imul eax,FP_1*53/10 cdq idiv ecx mov clock,eax add eax,FP_1*226/10 mov bwActor3D.posY,eax bw_cast_draw: invoke ConfigureCharacter3D,OFFSET bwActor3D,person,action,clock,vx,vy invoke DrawCityObject3D,OFFSET bwActor3D,0 ; The other member of this lane keeps their own identity and their own seat. mov eax,bwTurn3D[esi*4] xor eax,1 mov edi,eax invoke BowlingHome3D,esi,edi mov bwSmallActor3D.posX,eax mov bwSmallActor3D.posY,FP_1*279/10 lea ebx,[esi*2] add ebx,edi invoke ConfigureCharacter3D,OFFSET bwSmallActor3D,bwCharacterIds3D[ebx*4],CAST_SEAT_DRINK,animationClock3D,0,0 invoke DrawCityObject3D,OFFSET bwSmallActor3D,0 bw_cast_lane_next: inc esi cmp esi,BW_LANES jb bw_cast_lane ; 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 cmp esi,3 jb bw_cast_dining_next @@: mov eax,bwVisitorX3D[esi*4] mov bwSmallActor3D.posX,eax mov eax,bwVisitorY3D[esi*4] mov bwSmallActor3D.posY,eax lea edi,[esi+6] invoke ConfigureCharacter3D,OFFSET bwSmallActor3D,edi,CAST_SEAT_TALK,animationClock3D,0,0 cmp esi,2 jb @F add bwSmallActor3D.groundZ,FP_1/4 @@: invoke DrawCityObject3D,OFFSET bwSmallActor3D,0 bw_cast_dining_next: inc esi cmp esi,4 jb bw_cast_dining mov bwActor3D.posX,27*FP_1 mov bwActor3D.posY,3*FP_1 mov bwActor3D.asset,OFFSET hallBartender3D mov bwActor3D.worldW,FP_1 mov bwActor3D.worldH,FP_1 mov bwActor3D.groundZ,FP_1*9/10 mov eax,animationClock3D shr eax,9 and eax,7 cmp engineMode,MODE_BAR jne bw_bartender_ready xor eax,eax cmp barPhase3D,1 jne @F mov eax,barTime3D xor edx,edx mov ecx,375 div ecx cmp eax,7 jbe @F mov eax,7 @@: mov ecx,barSelection3D shl ecx,3 add eax,ecx bw_bartender_ready: mov bwActor3D.frame,eax invoke DrawCityObject3D,OFFSET bwActor3D,0 ret RenderBowlingVisitors3D ENDP RenderBowlingEntrance3D PROC cmp portalRendering3D,0 jne bw_entrance_done cmp hallLevel3D,0 jne bw_entrance_done cmp playerY,FP_1*15/10 jbe bw_entrance_done invoke DrawInteriorView3D,1,FP_1*15/10,3*FP_1,7*FP_1,0,FP_1*205/100,12*FP_1,29*FP_1,0,OFFSET bwMap3D,MODE_WALK,HALL_BOWLING,231,0 invoke DrawCityVertical3D,1,FP_1*151/100,3*FP_1,7*FP_1,FP_1*205/100,FP_1*246/100,252 bw_entrance_done: ret RenderBowlingEntrance3D ENDP RenderBowlingDetails3D PROC uses ebx esi edi local centerX:DWORD,x0:DWORD,x1:DWORD,centerY:DWORD xor esi,esi bw_detail_return: imul eax,esi,FP_1*38/10 add eax,FP_1*395/100 mov centerX,eax sub eax,FP_1*32/100 mov x0,eax add eax,FP_1*64/100 mov x1,eax invoke DrawCityVertical3D,1,26*FP_1+512,x0,x1,FP_1/20,FP_1*62/100,241 invoke RenderBowlingReturnMachine3D,centerX invoke RenderBowlingBallRack3D,centerX,esi mov eax,centerX sub eax,FP_1*27/100 invoke DrawRoofEllipsoid3D,eax,27*FP_1,FP_1*49/100,FP_1*16/100,FP_1*16/100,FP_1*2/100,239 mov eax,centerX add eax,FP_1*29/100 invoke DrawRoofEllipsoid3D,eax,27*FP_1,FP_1*58/100,FP_1*5/100,FP_1*5/100,FP_1*12/100,243 inc esi cmp esi,4 jb bw_detail_return call RenderBowlingReturnedBall3D xor esi,esi bw_detail_dining: mov eax,esi and eax,1 imul eax,5*FP_1 add eax,22*FP_1 mov centerX,eax mov eax,esi shr eax,1 imul eax,6*FP_1 add eax,12*FP_1 mov centerY,eax mov eax,centerX sub eax,FP_1*45/100 invoke DrawRoofEllipsoid3D,eax,centerY,FP_1*58/100,FP_1*22/100,FP_1*22/100,FP_1*2/100,239 mov eax,centerX add eax,FP_1*55/100 invoke DrawRoofEllipsoid3D,eax,centerY,FP_1*69/100,FP_1*6/100,FP_1*6/100,FP_1*14/100,243 invoke DrawRoofEllipsoid3D,centerX,centerY,FP_1*63/100,FP_1*7/100,FP_1*7/100,FP_1*8/100,242 inc esi cmp esi,4 jb bw_detail_dining ret RenderBowlingDetails3D ENDP RenderBowling3D PROC uses ebx esi edi local lo:DWORD,hi:DWORD call UpdateBowling3D call LoadBowling3D call PrepareCityRays3D lea edi,zBuffer mov eax,7FFFFFFFh mov ecx,SCREEN_W rep stosd call RenderBowlingPlanes3D xor esi,esi bw_room_walls: imul eax,esi,3*FP_1 add eax,FP_1 mov lo,eax add eax,3*FP_1 mov hi,eax invoke DrawCityVertical3D,0,FP_1,lo,hi,0,6*FP_1,232 invoke DrawCityVertical3D,0,31*FP_1,lo,hi,0,6*FP_1,232 mov ebx,234 cmp esi,6 jb @F mov ebx,232 @@: invoke DrawCityVertical3D,1,FP_1,lo,hi,0,6*FP_1,ebx invoke DrawCityVertical3D,1,31*FP_1,lo,hi,0,6*FP_1,232 inc esi cmp esi,10 jb bw_room_walls invoke DrawCityVertical3D,0,FP_1*101/100,FP_1,31*FP_1,FP_1*45/10,FP_1*455/100,242 invoke DrawCityVertical3D,0,FP_1*3099/100,FP_1,31*FP_1,FP_1*45/10,FP_1*455/100,243 lea esi,bwProps3D mov edi,BOWL_PROP_COUNT bw_room_prop: invoke DrawRoofSolid3D,[esi],[esi+4],[esi+8],[esi+12],[esi+16],[esi+20],[esi+24] add esi,28 dec edi jnz bw_room_prop ; Bottle shelves occupy only the wall behind the counter. invoke DrawCityVertical3D,1,FP_1*146/100,24*FP_1,30*FP_1,FP_1,3*FP_1,ROOF_BOTTLES call RenderBowlingDetails3D xor esi,esi bw_room_lights: imul eax,esi,4*FP_1 add eax,3*FP_1 mov ebx,eax add ebx,FP_1*22/10 invoke DrawCityHorizontal3D,eax,ebx,6*FP_1,FP_1*62/10,FP_1*55/10,242 invoke DrawCityHorizontal3D,eax,ebx,16*FP_1,FP_1*162/10,FP_1*55/10,243 inc esi cmp esi,7 jb bw_room_lights call RefreshBowlingMonitors3D call RenderBowlingLanes3D call RenderBowlingVisitors3D cmp portalRendering3D,0 jne bw_room_done cmp playerY,FP_1*305/10 jae bw_room_done invoke DrawInteriorView3D,1,FP_1*305/10,15*FP_1,19*FP_1,0,FP_1*24/10,-12*FP_1,-29*FP_1,0,OFFSET casinoMap,MODE_WALK,0,100,0 bw_room_done: ret RenderBowling3D ENDP