IDEAL JUMPS P386 P387 ; Allow 386 processor model flat codeseg include "ackrtn.inc" extrn _gMultiWalls:word extrn _WallDistTable:dword extrn _BackDropRows:dword extrn _FloorCeilRtn:dword extrn _Resolution:word extrn _ScreenOffset:word extrn _bmDistance:dword extrn _bmWall:dword extrn _scPtr:dword extrn _VidTop:dword extrn _VidBottom:dword extrn _Floors1:dword extrn _Floors2:dword extrn _PlayerAngle:word extrn _BackArray:dword extrn _gWinStartX:word extrn _gWinStartY:word extrn _gWinEndX:word extrn _gWinEndY:word extrn _gWinHeight:word extrn _gWinWidth:word extrn _gCenterRow:word extrn _gCenterOff:word extrn _scVid:dword extrn _scWall:dword extrn _scPal:dword extrn _scdst:word extrn _scwht:word extrn _scmulti:word extrn _sctopht:word extrn _scbotht:word extrn _scsavwht:word extrn _scmulcnt:word extrn _scsavVid:dword extrn _scbNum:word extrn _scMulData:dword extrn _scColumn:dword extrn _WallbMaps:dword extrn _FloorMap:word extrn _CeilMap:word extrn _LastWallHeight:word extrn _ViewAngle:word extrn _ScreenOffset:word extrn _xPglobal:dword extrn _yPglobal:dword extrn _xBegGlobal:dword extrn _yBegGlobal:dword extrn _aeGlobal:dword extrn _xGridGlobal:dword extrn _yGridGlobal:dword extrn _xPglobalHI:dword extrn _yPglobalHI:dword extrn _rbaTable:dword extrn _rsHandle:dword extrn _LastX1:dword extrn _LastY1:dword extrn _iLastX:dword extrn _iLastY:dword extrn _MaxDistance:word extrn _ErrorCode:word extrn _xMapPosn:dword extrn _yMapPosn:dword extrn _Grid:dword extrn _ObjGrid:dword extrn _ViewHeight:word extrn _CeilingHeight:word extrn _gTopColor:byte extrn _gBottomColor:byte extrn _PlayerAngle:word extrn _gScrnBuffer:dword extrn _gBkgdBuffer:dword extrn _gCenterOff:word extrn _gWinHeight:word extrn _SysFlags:word extrn _xSecretmPos:word extrn _xSecretmPos1:word extrn _xSecretColumn:word extrn _ySecretmPos:word extrn _ySecretmPos1:word extrn _ySecretColumn:word extrn _TotalSecret:word extrn _ViewColumn:word extrn _SinTable:dword extrn _CosTable:dword extrn _LongTanTable:dword extrn _LongInvTanTable:dword extrn _InvCosTable:byte extrn _InvSinTable:byte extrn _LongCosTable:dword extrn _ViewCosTable:dword extrn _xNextTable:dword extrn _yNextTable:dword extrn _LastMapPosn:word extrn _LastObjectHit:word extrn _TotalObjects:word extrn _FoundObjectCount:word extrn _ObjectsSeen:byte extrn _MoveObjectCount:word extrn _MoveObjectList:byte extrn _ObjNumber:byte extrn _ObjRelDist:byte extrn _ObjColumn:byte extrn _x_xPos:dword extrn _x_yPos:dword extrn _x_xNext:dword extrn _x_yNext:dword extrn _y_xPos:dword extrn _y_yPos:dword extrn _y_xNext:dword extrn _y_yNext:dword extrn _Slice:dword extrn _sPtr:dword extrn _HitMap:byte extrn xRaySetup_:near extrn yRaySetup_:near extrn BuildSlice_:near extrn xRayCast_:near extrn yRayCast_:near extrn AckDrawFloor_:near extrn AckDrawFloorOnly_:near extrn AckDrawCeilingOnly_:near extrn DrawWalls_:near extrn CheckDoors_:near extrn BuildSliceMulti_:near extrn FindObject_:near public xRayCastMulti_ public yRayCastMulti_ public ShowColLow_ public ShowColMaskLow_ public BuildUpView_ align 2 ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ; void ShowColLow(void) ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± proc ShowColLow_ near push ebp push esi push edi mov ebp,eax mov [_scPtr],eax mov edi,[_scVid] mov edx,[_scPal] mov ax,[_scwht] mov [_scsavwht],ax movsx ecx,[_sctopht] mov ebx,[_scWall] add ebx,ecx mov [_bmWall],ebx mov ch,al inc ch mov eax,0 mov ebx,0 ;--TEST------------------------------------------------------------------------ test [word ptr _scbNum],WALL_TYPE_UPPER jz short toprun mov ebp,[_bmDistance] zztoploop: dec ch jz short zzdomulti add bx,bp cmp bh,cl jge short zzdomulti sub di,320 jmp zztoploop zzdomulti: mov ebp,[_scPtr] mov [_scwht],cx mov [_scsavVid],edi jmp chkmulti ;--TEST------------------------------------------------------------------------ toprun: mov ebp,[_bmDistance] toploop: movsx eax,bh mov esi,[_bmWall] sub esi,eax mov al,[esi] mov al,[edx+eax] mov ah,al mov [edi],ax add bx,bp cmp bh,cl jg short botrun dec ch jz short botrun sub edi,320 jmp toploop botrun: mov ebp,[_scPtr] mov [_scwht],cx mov [_scsavVid],edi mov [_VidTop],edi mov edi,[_scVid] mov cx,[_scbotht] mov bx,[_scsavwht] mov ch,bl mov ebx,0 mov esi,[_bmWall] inc esi mov ebp,[_bmDistance] dec cl botloop: add edi,320 movsx ax,bh mov al,[esi+eax] mov al,[edx+eax] mov ah,al mov [edi],ax dec ch jz short chkmulti add bx,bp cmp bh,cl jl botloop chkmulti: mov [_VidBottom],edi mov ebp,[_scPtr] mov edi,[_scsavVid] cmp [word ptr _scmulti],0 jz alldone mov cx,[_scmulcnt] mov ebx,[_scMulData] ;ptr to count and wall data mov cl,[ebx] ;get count of data inc ebx mov al,[ebx] ;first wall to show inc ebx mov [_scMulData],ebx movsx ebx,al ;get wall number shl ebx,2 ;x4 for index into wall bitmap array mov eax,[_WallbMaps] mov ebx,[eax+ebx] add ebx,[dword ptr _scColumn] ;add in current column add ebx,63 ;point to bottom of column mov [_bmWall],ebx mov bx,[_scwht] mov ch,bh cmp ch,0 jz short alldone mov ebx,0 mov ebp,[_bmDistance] mulloop: sub edi,320 movsx eax,bh mov esi,[_bmWall] sub esi,eax mov al,[esi] mov al,[edx+eax] mov ah,al mov [edi],ax dec ch jz short alldone add bx,bp cmp bh,64 jge short nextlevel jmp mulloop nextlevel: dec cl jz short alldone mov ebx,[_scMulData] mov al,[ebx] ;next wall number inc ebx mov [_scMulData],ebx movsx ebx,al shl ebx,2 mov eax,[_WallbMaps] mov ebx,[eax+ebx] add ebx,[dword ptr _scColumn] ;add in current column add ebx,63 ;point to bottom of column mov [_bmWall],ebx mov ebx,0 jmp mulloop alldone: mov [_VidTop],edi pop edi pop esi pop ebp ret endp align 2 ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ; void ShowColMaskLow(void) ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± proc ShowColMaskLow_ near push ebp push esi push edi mov ebp,eax mov [_scPtr],eax mov edi,[_scVid] mov edx,[_scPal] mov ax,[_scwht] mov [_scsavwht],ax movsx ecx,[_sctopht] mov ebx,[_scWall] add ebx,ecx mov [_bmWall],ebx mov ch,al mov eax,0 mov ebx,0 ;--TEST------------------------------------------------------------------------ test [word ptr _scbNum],WALL_TYPE_UPPER jz short m_toprun mov ebp,[_bmDistance] m_zztoploop: dec ch jz short m_zzdomulti add bx,bp cmp bh,cl jge short m_zzdomulti sub edi,320 jmp m_zztoploop m_zzdomulti: mov ebp,[_scPtr] mov [_scwht],cx mov [_scsavVid],edi jmp m_chkmulti ;--TEST------------------------------------------------------------------------ m_toprun: mov ebp,[_bmDistance] m_toploop: movsx eax,bh mov esi,[_bmWall] sub esi,eax mov al,[esi] or al,al jz m_blank1 mov al,[edx+eax] mov ah,al mov [edi],ax m_blank1: add bx,bp cmp bh,cl jg short m_botrun dec ch jz short m_botrun sub edi,320 jmp m_toploop m_botrun: mov ebp,[_scPtr] mov [_scwht],cx mov [_scsavVid],edi mov edi,[_scVid] mov cx,[_scbotht] mov bx,[_scsavwht] mov ch,bl mov ebx,0 mov esi,[_bmWall] inc esi mov ebp,[_bmDistance] m_botloop: add edi,320 movsx ax,bh mov al,[esi+eax] or al,al jz m_blank2 mov al,[edx+eax] mov ah,al mov [edi],ax m_blank2: dec ch jz short m_chkmulti add bx,bp cmp bh,cl jl m_botloop m_chkmulti: mov ebp,[_scPtr] cmp [word ptr _scmulti],0 jz short m_alldone mov cx,[_scmulcnt] mov bx,[_scwht] mov ch,bh cmp ch,0 jz short m_alldone mov edi,[_scsavVid] mov ebx,[_scWall] add ebx,63 mov [_bmWall],ebx mov ebx,0 mov ebp,[_bmDistance] m_mulloop: sub edi,320 movsx eax,bh mov esi,[_bmWall] sub esi,eax mov al,[esi] or al,al jz m_blank3 mov al,[edx+eax] mov ah,al mov [edi],ax m_blank3: dec ch jz short m_alldone add bx,bp cmp bh,64 jge short m_nextlevel jmp m_mulloop m_nextlevel: mov ebx,0 dec cl jnz m_mulloop m_alldone: pop edi pop esi pop ebp ret endp ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ; USHORT xRayCastMulti(void) ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± proc xRayCastMulti_ near ; sub esp,50 push esi push edi push ebx push ecx push edx mov [word ptr retval],0 looptop: mov edx,[dword ptr _x_xPos] cmp edx,large 0 jl short getout cmp edx,large 4096 jg short getout mov eax,[_x_yPos] cmp eax,large 0 jl short getout cmp eax,large 010000000h jle short inbounds getout: jmp loopdone inbounds: sar eax,16 and ax,-64 sar edx,6 add ax,dx mov si,ax shl ax,1 movsx eax,ax mov ebx,[dword ptr _ObjGrid] mov ax,[word ptr ebx+eax] or ax,ax jz short no_obj and ax,0FFh mov [word ptr Color],ax movsx ecx,[_FoundObjectCount] ;// Get number of current objects seen mov ebx,ecx jcxz short nofound ;// None found yet, add this new one mov edi,offset _ObjectsSeen repne scasb ;// See if this object already seen jz short no_obj ;// Yes, ignore this ray then nofound: mov edi,offset _ObjectsSeen mov [edi+ebx],al inc bx mov [word ptr _FoundObjectCount],bx no_obj: movsx eax,si shl eax,1 mov ebx,[dword ptr _xGridGlobal] mov cx,[ebx+eax] or cx,cx jz short next_square test cx,WALL_UPPER_MULTI jz short next_square cmp cl,[byte ptr _LastWallHeight] jbe short next_square mov [word ptr _xMapPosn],si mov ebx,[dword ptr _x_xPos] mov [dword ptr _iLastX],ebx mov edx,[dword ptr _x_yPos] mov [dword ptr _LastY1],edx movsx eax,cx jmp short xRayDone next_square: mov eax,[dword ptr _x_xNext] add [dword ptr _x_xPos],eax mov eax,[dword ptr _x_yNext] add [dword ptr _x_yPos],eax jmp looptop loopdone: movsx eax,[word ptr retval] xRayDone: pop edx pop ecx pop ebx pop edi pop esi ret endp ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ; USHORT yRayCastMulti(void) ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± proc yRayCastMulti_ near ; sub esp,50 push esi push edi push ebx push ecx push edx mov [word ptr retval],0 y_looptop: mov edx,[dword ptr _y_xPos] cmp edx,large 0 jl short y_getout cmp edx,large 010000000h jg short y_getout mov eax,[_y_yPos] cmp eax,large 0 jl short y_getout cmp eax,large 4096 jle short y_inbounds y_getout: jmp loopdone y_inbounds: sar edx,22 and ax,-64 add ax,dx mov si,ax shl ax,1 movsx eax,ax mov ebx,[dword ptr _ObjGrid] mov ax,[ebx+eax] or ax,ax jz short y_no_obj and ax,0FFh mov [word ptr Color],ax movsx ecx,[_FoundObjectCount] mov ebx,ecx jcxz short y_nofound mov edi,offset _ObjectsSeen repne scasb jz short y_no_obj y_nofound: mov edi,offset _ObjectsSeen mov [edi+ebx],al inc bx mov [word ptr _FoundObjectCount],bx y_no_obj: movsx eax,si shl eax,1 mov ebx,[dword ptr _yGridGlobal] mov cx,[ebx+eax] or cx,cx jz short y_next_square y_wall_here: test cx,WALL_UPPER_MULTI jz short y_next_square cmp cl,[byte ptr _LastWallHeight] jbe short y_next_square mov [word ptr _yMapPosn],si mov ebx,[dword ptr _y_xPos] mov [dword ptr _LastX1],ebx mov edx,[dword ptr _y_yPos] mov [dword ptr _iLastY],edx mov edx,ebx movsx eax,cx jmp short yRayDone y_next_square: mov eax,[dword ptr _y_xNext] add [dword ptr _y_xPos],eax mov eax,[dword ptr _y_yNext] add [dword ptr _y_yPos],eax jmp y_looptop y_loopdone: movsx eax,[word ptr retval] yRayDone: pop edx pop ecx pop ebx pop edi pop esi ret endp ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ; void CheckHitMap(void) ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± proc CheckHitMap_ near mov edi,offset _HitMap mov edx,edi mov ecx,4096 mov esi,[dword ptr _ObjGrid] chmLoop: xor eax,eax repe scasb jcxz chmDone mov ebx,edi ;get current location sub ebx,edx ;minus start for actual offset dec ebx ;minus base 0 offset shl ebx,1 ;times 2 for word array mov ax,[word ptr esi+ebx] or al,al ;is there an object there? jz chmLoop ;nope, keep checking movzx ebx,[word ptr _FoundObjectCount] mov [byte ptr _ObjectsSeen+ebx],al inc ebx mov [word ptr _FoundObjectCount],bx jmp chmLoop chmDone: ret endp ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ; void BuildUpView(void) ;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± proc BuildUpView_ near push ebp ; Save registers used by this routine push esi push edi push ebx push ecx push edx call CheckDoors_ ; Determine the state of the doors used in the view mov edi,offset _HitMap ; Access the hit map mov ecx,1024 ; Size of the hit map xor eax,eax ; Clear each location rep stosd ; Clear out entire hit map ; Check to see if moveable objects are found in the view. If so, access the object list ; and store the objects. mov [word ptr _MaxDistance],0 movzx ecx,[word ptr _MoveObjectCount] ; Get # of moveable objects mov [_FoundObjectCount],cx ; Store # of objects found in view jcxz short buv010 ; No objects are used, jump ahead mov edi,offset _ObjectsSeen ; Reference global object list mov esi,offset _MoveObjectList ; List of movable objects mov ebx,ecx ; # of moveable objects sar ecx,2 ; Divide by 2 rep movsd mov ecx,ebx ; # of moveable objects and ecx,3 rep movsb ; Finish copying _ObjectSeen to ; _MoveObjectList buv010: movzx esi,[_gWinEndX] ; Get right side of viewport cmp si,320 ; Is right coord. = 320? jae short buv020 inc esi ; Adjust right viewport if not 320 buv020: movzx eax,[_PlayerAngle] ; Get current player’s angle sub eax,INT_ANGLE_32 ; Check with 32 degree point jnc short buv030 ; Skip if in range add eax,INT_ANGLE_360 ; Add 360 degrees to angle buv030: movzx ebx,[_gWinStartX] ; Get left side of viewport mov [_ViewColumn],bx ; Save location in _ViewColumn add eax,ebx ; Add angle to left side cmp eax,INT_ANGLE_360 ; Are we out of range? jl short buv040 ; We’re ok! sub eax,INT_ANGLE_360 ; Reduce angle by 360 degrees buv040: mov [_ViewAngle],ax ; Store updated angle ; The start of the main loop that builds individual slices for the view. ; This loop continues until the entire view has been built. Each time through ; the loop, the player’s viewing angle is increased. This continues until a full ; 64 degre range is casted (assuming a full width screen is used). buv050: movzx ebx,[_ViewColumn] ; Get left column position mov [dword ptr _WallDistTable+ebx*4],4096 ; Max distance to walls mov eax,offset _Slice ; Access base adress of Slice structure imul ebx,saSize ; Calculate offset into actual slice add eax,ebx ; Add offset to base address mov [_sPtr],eax ; Set up pointer to actual column slice movzx edi,[_ViewAngle] ; Use current viewing angle call xRaySetup_ ; Set up x ray to start casting buv060: call yRaySetup_ ; Set up y ray to start casting buv070: mov [word ptr _LastWallHeight],0 ; For checking mult-height walls call BuildSlice_ ; Build the current slice cmp [word ptr _gMultiWalls],0 ; Are multi-height walls used? jz short buv080 ; Nope, no need to check cmp [word ptr _LastWallHeight],200 ; No need to check if > 200 jg short buv080 mov eax,[_sPtr] ; Get base address of column slice cmp [dword ptr eax+saNext],0 ; Check for any more walls je short buv080 cmp [word ptr eax+saDist],96 ; Distance from POV to slice is jle short buv080 ; less than or equal to 96 call BuildSliceMulti_ ; Build the current slice for ; a multi-height wall buv080: movzx eax,[_ViewColumn] ; Get current column inc eax ; Advance to the next column inc edi ; Increment the casting angle cmp [word ptr _Resolution],RES_LOW ; Check for screen resolution jne short buv090 inc edi ; Increment angle and position inc eax ; for higher resolution casting buv090: cmp edi,INT_ANGLE_360 ; Did we go past 360 degrees? jl short buv100 ; We’re ok sub edi,INT_ANGLE_360 ; Adjust angle for building next slice buv100: mov [_ViewAngle],di ; Save current viewing angle mov [_ViewColumn],ax ; Save column position cmp eax,esi ; Are we done yet? jl buv050 ; Nope; go build next slice buv_exit: call CheckHitMap_ call FindObject_ ; Update slice structures with objects found call [dword ptr _FloorCeilRtn] ; Build the floor and ceiling call DrawWalls_ ; Build the walls pop edx ; Restore the registers used pop ecx pop ebx pop edi pop esi pop ebp ret endp end