home *** CD-ROM | disk | FTP | other *** search
- ;────────────────────────────────────────────────────────────────────────────
- ; SpriteClip v1.2 by CrASH_Man 02/14/98
- ;────────────────────────────────────────────────────────────────────────────
- ;
- ; This is a highly optimized clipping 8 by X sprite routine for the TI-82.
- ; This routine also incorporates AND/XOR masking, described below. No
- ; registers are destroyed, so you may modify the routine (lines with a **)
- ; if your code does not need to save them.
- ;
- ; For an example on how to use this routine, please take a look at
- ; SPRTEST.ASM.
- ;
- ; You may use this routine in your programs, but please give me credit
- ; for my work by including my name in the documentation and source.
- ;
- ; by CrASH_Man
- ;
- ;────────────────────────────────────────────────────────────────────────────
- ; Usage:
- ;────────────────────────────────────────────────────────────────────────────
- ; CALL PutSprClp Puts a sprite pointed by HL at (B, C) in GRAPH_MEM
- ; CALL SetSpriteHeight Sets the height of sprites used by PutSprClp to A
- ;
- ; DefaultSpriteHeight needed for compiling, as a integer definition.
- ;
- ;────────────────────────────────────────────────────────────────────────────
- ; The AND/XOR mask
- ;────────────────────────────────────────────────────────────────────────────
- ; The AND mask is first put on the screen, then the XOR is put on the
- ; screen. The result turns out so that:
- ;
- ; 00 = White 01 = Black
- ; 10 = Unchanged 11 = Inverted
- ;
- ; For example:
- ; ------------
- ; AND mask + XOR mask Result
- ;
- ; .DB %11100111 .DB 00011000 = UUUBBUUU W is white
- ; .DB %11000011 .DB 00100100 = UUBWWBUU B is black
- ; .DB %10000001 .DB 01000010 = UBWWWWBU U is unchanged
- ; .DB %00011000 .DB 10011001 = BWWIIWWB I is inverted
- ; .DB %00011000 .DB 10011001 = BWWIIWWB
- ; .DB %10000001 .DB 01000010 = UBWWWWBU
- ; .DB %11000011 .DB 00100100 = UUBWWBUU
- ; .DB %11100111 .DB 00011000 = UUUBBUUU
- ;
- ;────────────────────────────────────────────────────────────────────────────
- ; Revision History:
- ;────────────────────────────────────────────────────────────────────────────
- ; 0.9 10/04/97 - Complete clipping except for minor bug in top-left corner.
- ; 1.0 10/05/97 - Complete clipping anywhere... Kewl!!
- ; 1.1 10/09/97 - Clipping w/OR XOR Masks, variable sprite height
- ; 1.2 02/14/98 - Clipping w/AND XOR Masks, no more EX or EXX used
-
- ;────────────────────────────────────────────────────────────────────────────
- ; PutSprClp - Puts a sprite with clipping and and/xor mask (quite fast)
- ; Inputs: (B, C) coordinates, HL -> sprite
- ; OutPut: Puts clipped sprite
- ;────────────────────────────────────────────────────────────────────────────
- PutSprClp:
- PUSH BC \ PUSH DE \ PUSH HL \ PUSH IX ; ** Save Registers
-
- PUSH HL \ POP IX ; LD IX, HL
-
- __Change_1:
- LD D, DefaultSpriteHeight
- BIT 7, C \ JR NZ, _PSC_NoBotClip ; If Y is negative, clip top
- _PSC_BotClip:
- LD A, 63
- SUB C \ JP C, _PSC_Done
- __Change_2:
- CP DefaultSpriteHeight-1
- JR NC, _PSC_NoVertClip ; If the sprite fits, done clipping
-
- INC A
- JR _PSC_ClipTop
- _PSC_NoBotClip:
- LD A, C
- __Change_3:
- CP -(DefaultSpriteHeight-1)
- JR C, _PSC_Done ; If Y < -(DefaultSpriteHeight-1) then done
- _PSC_TopClip:
- LD L, A
- NEG \ LD E, A ; Find number to shift
- LD A, L
- __Change_4:
- ADD A, DefaultSpriteHeight
- LD D, 0 \ ADD IX, DE
- LD C, D ; C = 0 or -1 if at top-left
- _PSC_ClipTop:
- LD D, A
- _PSC_NoVertClip:
- LD E, $FF \ LD A, B
- BIT 7, A \ JR Z, _PSC_NoLeftClip ; If X is non-negative, check right side
- _PSC_LeftClip:
- CP -7 \ JR C, _PSC_Done ; If X is less than -7, done
- NEG \ LD H, B \ LD B, A ; Find number to shift right
- _PSC_LeftLoop:
- SRL E ; Shift mask to right
- DJNZ _PSC_LeftLoop
- LD A, H \ ADD A, 96 \ LD B, A ; Shift sprite up a row.
- JR _PSC_ClipDone2
- _PSC_NoLeftClip:
- SUB 89 \ JR C, _PSC_ClipDone ; If X < 89 then no need to clip on right
- _PSC_RightClip:
- CP 7 \ JR NC, _PSC_Done ; If Shift # > 7 then done
- LD H, B \ LD B, A \ INC B
- _PSC_RightLoop:
- SLA E ; Shift mask to left
- DJNZ _PSC_RightLoop
- LD B, H
- _PSC_ClipDone:
- INC C
- _PSC_ClipDone2:
- LD A, B \ LD B, 0 ; [11] Save B, Clear B so we can add BC
- LD H, B \ LD L, C ; [ 8] HL = BC
- ADD HL, BC \ ADD HL, BC ; [22] HL = HL + 12
- ADD HL, HL \ ADD HL, HL ; [22]
- LD C, A ; [ 4]
- SRL C \ SRL C \ SRL C ; [24] C = B \ 8
- ADD HL, BC ; [11]
- LD BC, GRAPH_MEM-12 ; [10]
- ADD HL, BC ; [11]
- LD B, D ; Number of Rows
-
- AND %00000111 ; [ 7]
- JR Z, _PSC_NoShift
-
- LD C, A ; Number to Shift
- _PSC_LineLoop:
- PUSH BC
- PUSH DE
- LD A, E
- __Change_5:
- AND (IX+DefaultSpriteHeight)
- LD D, A
- LD A, E
- CPL \ OR (IX+0)
- LD B, C
- LD C, %11111111
- LD E, %00000000
-
- _PSC_ShiftNum:
- SCF \ RRA \ RR C
- SRL D \ RR E ; Shift
- DJNZ _PSC_ShiftNum
-
- AND (HL) \ XOR D \ LD (HL), A \ INC HL ; Or data with background
- LD A, C \ AND (HL) \ XOR E \ LD (HL), A ; Xor Mask, etc.
-
- INC IX \ LD C, 11 \ ADD HL, BC ; Next row
- POP DE
- POP BC
- DJNZ _PSC_LineLoop
-
- _PSC_Done:
- POP IX \ POP HL \ POP DE \ POP BC ; ** Restore registers
- RET
-
- _PSC_NoShift:
- LD DE, 12 ; Add 12 each row
- _PSC_NoShiftLoop:
- LD A, (HL)
- AND (IX+0)
- __Change_6:
- XOR (IX+DefaultSpriteHeight)
- LD (HL), A ; Or data with background
- ADD HL, DE \ INC IX ; Next row
- DJNZ _PSC_NoShiftLoop
-
- JR _PSC_Done
-
- ;────────────────────────────────────────────────────────────────────────────
- ; SetSpriteHeight - Changes the default sprite size
- ; Inputs: A = Sprite Height
- ; Output: Self modifies routine to sprites that are A pixels in height.
- ;────────────────────────────────────────────────────────────────────────────
- SetSpriteHeight:
- LD (__Change_1+1), A
- LD (__Change_2+1), A
- LD (__Change_4+1), A
- LD (__Change_5+2), A
- LD (__Change_6+2), A
- DEC A
- NEG
- LD (__Change_3+1), A
- RET
-