.MODEL MEDIUM,BASIC
.STACK 100H
.386
.CODE

;SUB RELSPRITEONSPRITES(BYVAL DESTSEG%,BYVAL DESTOFF%,BYVAL X%,BYVAL Y%,BYVAL SPRITESEGMENT%,BYVAL SPRITEOFFSET%)
;STACK
;DEST SEG       =18
;DEST OFF       =16
;X              =14  
;Y              =12
;SPRITESEGMENT  =10
;SPRITOFFSET    =8
;RET SEG        =6
;RET OFF        =4
;BP             =2
;DS             =0
;BLANK REG      =-2
;WIDTH/8        =-4
;HEIGHT         =-6     ;WIDTH SAVER ALSO
;320-CLP_WIDTH  =-8
;DESTWIDTH      =-10
;DESTHITE       =-12


;DS:SI          =SPRITE SEG:SPRITE OFF
;ES:DI		=DEST SEG:DEST OFF

;BX=WIDTH
;DX=HEIGHT
ALIGN 2


PUBLIC RELSPRITEONSPRITES
RELSPRITEONSPRITES PROC

PUSH BP
PUSH DS


MOV BP,SP	;POINT STACK POINTER TO BP

MOV AX,[BP+10]  ;POINT ADDRESS OF SPRITE TO DS
MOV CX,[BP+18]  ;POINT ADDRESS OF DEST TO ES
MOV DS,AX
MOV ES,CX
MOV SI,[BP+8]   ;WE ARE NOW ON THE WIDTH OF THE SPRITE W=(ARRAY(0)/8)-1
MOV DI,[BP+16]  ;DEST OFF
MOV BX,[SI]     ;WIDTH*8
XOR AX,AX       ;ZERO OUT BLANK REG

SHR BX,3        ;DIV WIDTH BY 8
MOV DX,[SI+2]   ;SAVE HEIGHT
PUSH AX         ;PUSH IT TO STACK

PUSH BX         ;SAVE WIDTH
ADD SI,4        ;SI NOW POINTS TO 1ST COLOR OF SPRITE ARRAY
PUSH DX         ;PUSH HEIGHT
PUSH AX         ;FOR DESTWIDTH+1-WIDTH
MOV CX,ES:[DI]  ;DEST WIDTH*8
MOV AX,ES:[DI+2];DEST HEIGHT
SHR CX,3        ;DIV 8
DEC CX          ;CORRECT IT
DEC AX
PUSH CX         ;BP-10 DESTWIDTH
PUSH AX         ;BP-12 DESTHITE
ADD DI,4

;NOTE!!!!  AFTER THE CLIPS
;AX=X     CLIPPED
;CX=Y     CLIPPED
;BX=WIDTH   NEW
;DX=HEIGHT  NEW

        MOV AX,[BP+14]          ;X VALUE
        CMP AX,[BP-10]          ;GET OUT IF X > DESTW
JG LBL_END_IT                   ;ELSE
        CMP AX,0                ;X<0 THEN
        JL LBL_CLIP_LEFT        ;CLIP OUR X VALUE
LBL_POST_CLIP_LEFT:

        MOV CX,[BP+12]          ;Y VALUE
        CMP CX,[BP-12]          ;GET OUT IF Y > DESTH
JG LBL_END_IT                   ;ELSE
        CMP CX,0                ;Y<0 THEN
        JL LBL_CLIP_TOP         ;CLIP OUR Y VALUE
LBL_POST_CLIP_TOP:

;OK HERE'S THE SCORE: AX=X,CX=Y,DX=HEIGHT,BX=WIDTH  ALL CLIPPED TOP AND LEFT
;NOW LETS CLIP IT TO THE RIGHT

        ADD BX,AX               ;ADD X TO WIDTH AND SEE IF ITS OVER  *BX IS DESTROYED
        CMP BX,[BP-10]          ;IF X+WIDTH > DESTW ;TOO RIGHT THEN CROP IT
        JG  LBL_CLIP_RIGHT      ;ELSE CONTINUE     
        SUB BX,AX               ;RESTORE BX SINCE IT WAS DESTROYED
LBL_POST_CLIP_RIGHT:

;NOW LETS CLIP IT DOWN

        ADD DX,CX               ;ADD Y TO HEIGHT AND SEE IF ITS OVER  *DX IS DESTROYED
        CMP DX,[BP-12]          ;IF Y+HEIGHT > DESTH ;TOO LOW THEN CROP IT
        JG  LBL_CLIP_DOWN       ;ELSE CONTINUE     
        SUB DX,CX               ;RESTORE DX SINCE IT WAS DESTROYED
LBL_POST_CLIP_DOWN:


;WHEW!!!!!!!!! THAT WAS DISORIENTING!!!!!!!!
;BUT ALL VARIABLES ARE EITHER CLIPPED OR CROPPED NOW   ;-)
;AX=X,CX=Y,BX=WIDTH,DX=HEIGHT
;DI=Y*DESTWIDTH+1+X


MOV [BP-6],BX   ;DAMN FULL OF AGI'S HERE :(    SAVE BX/CLIPPPED WIDTH
MOV BX,[BP-10]
INC BX
IMUL CX,BX
SUB BX,[BP-6]
MOV [BP-8],BX   ;SAVE DESTW+1-WIDTH TO STACK


;LET US NOW CALCULATE  THE OFFSET NORMALLY

ADD DI,CX       ;SAVE Y VALUE TO DX
ADD DI,AX       ;DEST OFFSET(X,Y)=Y*DESTW+1+X


MOV BX,[BP-6]   ;RESTORE BX
MOV AX,BX               ;SAVE WIDTH
AND BX,3                ;REMAINDER
SHR AX,2                ;DIV AX BY 4


LBL_MAIN_SPR_LOOP:

MOV CX,AX               ;PUT CLIPPED WIDTH TO COUNTER
REP MOVSD               ;PUT ONE SCANLINE USING DOUBLE
MOV CX,BX               ;RESTORE COUNTER FOR REMAINDER CHECK
REP MOVSB               ;PUT REMAINDER
        
ADD DI,[BP-8]                   ;ADD TO DI OUR DESTW+1-CLP_WIDTH
ADD SI,[BP-2]                   ;CORRECTOR POINT TO NEXT ROW

DEC DX

JNZ  LBL_MAIN_SPR_LOOP

LBL_END_IT:

ADD SP,12

POP DS      ;RESTORE DS
POP BP      ;RESTORE BP


RET 12


LBL_CLIP_LEFT:
        NEG AX          ;NEGATE AX AX=-AX=+AX
        SUB BX,AX       ;SUBRACT CLIPPED WIDTH TO REAL WIDTH
        JLE LBL_END_IT  ;IF AX<=0 THEN ENDIT SINCE ITS TOOLEFT TO SEE A COL OF PIX ;)
        ADD SI,AX       ;ADD OUR AX TO SI(POINT TO CLIPPED X OFFSET
                        ;BX IS OUR NEW CLIPPED WIDTH
        MOV [BP-2],AX   ;SAVE IT TO STACK FOR SKIPPING CHECK PURPOSES
        
        XOR AX,AX       ;ZERO IS OUR X COORD
JMP LBL_POST_CLIP_LEFT



LBL_CLIP_TOP:
        NEG CX          ;NEGATE CX CX=-CX=+CX
        SUB DX,CX       ;SUBRACT CLIPPED HEIGHT TO REAL HEIGHT
                        ;DX IS OUR NEW CLIPPED HEIGHT
        JLE LBL_END_IT  ;IF CX<=0 THEN ENDIT SINCE ITS TOOLEFT TO SEE A ROW OF PIX ;)

     LBL_HEIGHT_LOOP:
        ADD SI,[BP-4]   ;ADD OUR REAL WIDTH TO SI(POINT TO CLIPPED Y OFFSET)
        DEC CX
     JNZ LBL_HEIGHT_LOOP        ;LOOP IT UNTIL WE GET TO RIGHT Y OFFSET
                                ;CX=0 ZERO IS OUR Y COORD
JMP LBL_POST_CLIP_TOP


LBL_CLIP_RIGHT:
       SUB BX,[BP-10]   ;SUBTRACT X+WIDTH WITH DESTW  TRUST ME NO NEGS HERE :)
       DEC BX           ;BX NOW IS CLIPPED RIGHT
       ADD [BP-2],BX    ;ADD IT TO THE CHECKER AS OUR SPR DATA IS IN COLUMN MAJOR ORDER
       MOV BX,[BP-10]   ;CORRECT BX TO  CLIPX2+1
       INC BX
       SUB BX,AX        ;SUBTRACT AX TO BX TO CORRECT WIDTH (0 TO DESTW)
JMP LBL_POST_CLIP_RIGHT

LBL_CLIP_DOWN:
       ADD CX,DX        ;ADD THE HEIGHT TO Y
       SUB CX,[BP-12]   ;CORRECT IT
       DEC CX
       SUB DX,CX        ;CROP OUR HEIGHT
       MOV CX,[BP+12]   ;RESTORE Y
JMP LBL_POST_CLIP_DOWN


RELSPRITEONSPRITES ENDP

END

