Wolf3D-Mac/Wolf.68k
2013-12-20 01:25:00 -05:00

1 line
4.7 KiB
Plaintext

;
; Assembly language functions for wolf 3-D
; By Bill Heineman
; 9-12-94 (Rev to use tight loop for scale code)
;
; Call the compiled scaler
; void ScaleGlue(void *TextPtr,t_compscale *CodePtr);
;
CASE ON
WALLHEIGHT EQU 128+1
EXPORT IO_ScaleWallColumn
EXPORT SpriteGlue
IMPORT VideoPointer:DATA
IMPORT VideoWidth:DATA
IMPORT ScaleDiv:DATA
IMPORT ArtData:DATA
IMPORT MacViewHeight:DATA
IO_ScaleWallColumn PROC
Adder1 EQU 20
ParmX EQU 4+Adder1
ParmScale EQU 6+Adder1
ParmTile EQU 8+Adder1
ParmColumn EQU 10+Adder1
;
; D0 = Temp, A0 = Temp
;
RegScrn EQU A0 ;Pointer to the screen
RegArt2 EQU A1 ;True pointer to art
RegArt EQU D1 ;Offset into the shape
RegDelta EQU D2 ;Delta counter
RegFrac EQU D3 ;Fixed point fraction
RegInt EQU D4 ;Fixed point integer
RegVidWidth EQU D5 ;Width of the screen in bytes
RegScale EQU D6 ;Scale factor
MOVEM.L D2-D6,-(A7) ;Save my registers
MOVE.L #0,RegScale ;Force scale to a long value
MOVE.W ParmScale(A7),RegScale ;Preload the scale factor
CMP.W #0,RegScale ;Scale of zero?
BEQ.S ByeBye ;Exit now! (Can't draw zero height)
MOVE.W ParmX(A7),D0 ;Get the X coord
MOVE.L VideoPointer,RegScrn ;Init the screen pointer
ADD.W D0,RegScrn ;Add the X coord
MOVE.W VideoWidth,RegVidWidth ;Init the video width
LEA ScaleDiv,RegArt2 ;Get pointer to the scaler recipocal table
MOVE.W RegScale,D0 ;Place scale value in temp
LSL.W #2,D0 ;Mul by 4 for longword index
MOVE.L (RegArt2,D0.W),RegFrac ;Get the precalced fraction
ADD.W RegScale,RegScale ;Convert scale to pixel value
MOVE.W ParmColumn(A7),RegArt ;Get the column index to the art
LSL.W #7,RegArt ;I have the pixel index
MOVE.W ParmTile(A7),D0
LSL.W #2,D0 ;Shift down 7 up 2
LEA ArtData,RegArt2 ;Get pointer to my shape ptr array
MOVE.L (RegArt2,D0.W),RegArt2 ;Get the base pointer to the art in A2
MOVE.W MacViewHeight,D0 ;Get the height
CMP.W D0,RegScale ;Clipping needed?
BCC.S ClipTop ;Do the clipped version
SUB.W RegScale,D0 ;How many line are clear?
LSR.W #1,D0 ;Number of lines to jump DOWN (Center it)
MULU.W RegVidWidth,D0 ;Mul by bytes per line
ADD.L D0,RegScrn ;Add to the screen pointer
MOVE.L RegFrac,RegInt ;Copy the full fixed point number
SWAP RegInt ;Isolate the integer
MOVE.W #0,RegDelta ;Zap the delta
SUB.W #1,RegScale ;-1 from the count for DBF
;
; This is the tight loop that draws the scaled line
; RegArt2/RegArt = Source ptr
; RegScrn = Video pointer
; RegFrac = Scale fraction
; RegInt = Scale integer
; RegDelta = Scale delta
; RegScale = Pixel count (Max MacViewHeight)
;
Loopy
MOVE.B (RegArt2,RegArt.W),D0 ;Move shape byte
MOVE.B D0,(RegScrn)
ADD.W RegFrac,RegDelta ;Adjust the delta
ADDX.W RegInt,RegArt ;Adjust the source byte offset
ADD.W RegVidWidth,RegScrn ;Next dest scan line
DBF RegScale,Loopy ;Still more?
ByeBye ;Exit
MOVEM.L (A7)+,D2-D6
RTS
ClipTop
SUB.W D0,RegScale ;Number of lines clipped
LSR.W #1,RegScale ;True number of lines skipped from top
MOVE.W RegFrac,RegDelta ;Init the delta for the mul
MULU.W RegScale,RegDelta ;Make the new delta for skipped lines
MOVE.L RegDelta,D0 ;Copy the delta
SWAP D0 ;Isolate the integer
ADD.W D0,RegArt ;Skip the hidden lines
MOVE.L RegFrac,D0
SWAP D0
MULU.W RegScale,D0
ADD.W D0,RegArt
MOVE.L RegFrac,RegInt ;Copy the full fixed point number
SWAP RegInt ;Isolate the integer
MOVE.W MacViewHeight,RegScale ;Use maximum height
SUB.W #1,RegScale ;Adjust for DBF
JMP Loopy
;
; Call the compiled scaler to draw a run of the line
;
;void SpriteGlue(Byte *a,LongWord b,Byte *c,Word d,Word e);
SpriteGlue PROC
Off EQU 20
ParmSGArt EQU 4+Off ;Pointer to the 6 byte run structure
ParmTFrac EQU 8+Off ;Pointer to the scaler
ParmScrn EQU 12+Off ;Pointer to the run base address
ParmCnt EQU 16+Off ;Line count
ParmDelta EQU 18+Off ;Initial delta
SGArt2 EQU A0 ;Pointer to the 6 byte run structure
SGScrn EQU A1 ;Pointer to the run base address
SGArt EQU D1
SGFrac EQU D2 ;Pointer to the scaler
SGInt EQU D3 ;Pointer to the video
SGCount EQU D6
SGDelta EQU D4
SGVidWidth EQU D5
MOVEM.L D2-D6,-(A7)
MOVE.L ParmSGArt(A7),SGArt2
MOVE.L ParmScrn(A7),SGScrn
MOVE.L ParmTFrac(A7),SGFrac ;Get pointer to the run structure
MOVE.L SGFrac,SGInt
SWAP SGInt
MOVE.W ParmCnt(A7),SGCount
MOVE.W ParmDelta(A7),SGDelta
MOVE.W VideoWidth,SGVidWidth ;Init the video width
MOVE.L #0,SGArt
SUB.W #1,SGCount ;Adjust for count used in DBF
Loopy2
MOVE.B (SGArt2,SGArt.W),D0 ;Get shape byte
MOVE.B D0,(SGScrn)
ADD.W SGFrac,SGDelta ;Adjust the delta
ADDX.W SGInt,SGArt ;Adjust the source byte offset
ADD.W SGVidWidth,SGScrn ;Next dest scan line
DBF SGCount,Loopy2 ;Still more?
MOVEM.L (A7)+,D2-D6
RTS
END