mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-02-13 13:33:41 +00:00
The ROM now round-trips with QuickDraw mostly built from source. (~30% of the ROM is now built from source.)
12035 lines
362 KiB
Plaintext
12035 lines
362 KiB
Plaintext
;
|
||
; File: Stretch.a
|
||
;
|
||
; Copyright: © 1981-1993 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM5> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
|
||
; so they can coditionalized out of the build.
|
||
; <SM4> 7/16/92 CSS Update from Reality:
|
||
; <66> 6/25/92 SAH #1033729: Fixed a bug where we don't always recognize when we're
|
||
; drawing to the alpha channel (just before calling ScaleBlt). We
|
||
; now do this correctly and take Stretch if drawing alpha,
|
||
; otherwise take the faster loops in ScaleBlt (which zero out the
|
||
; alpha channel).
|
||
; <65> 6/10/92 SAH Fixed a problem where we would defer to stretch if ScaleBlt did
|
||
; not hande the copy and the src was greater than one bits deep.
|
||
; This was causing crashes with Aldus Freehand and Macromind
|
||
; Director. Also fixed a problem where Stretch would munge
|
||
; StkLowPt, HieHeapMark and your stack in low-memory situations.
|
||
; <64> 6/8/92 SAH #1031825: Brought the ScaleBlt loops back to life. Now use
|
||
; ScaleBlt for indexed to direct (16 and 32) as well as indexed to
|
||
; indexed. Make use of new srcBlackWhiteOnly flag to enable us to
|
||
; use BitBlt when this is set and the src and dst are the same
|
||
; depths. Check to see if we need to change ScaleColor to
|
||
; ColorizeInModeCase if ScaleBlt fails. Also, test if using an
|
||
; alpha mode before calling ScaleBlt, in which case we take
|
||
; stretch.
|
||
; <SM3> 6/11/92 stb <sm 6/9/92>stb Synch with QDciPatchROM.a; added comments to
|
||
; StretchBits, MapModeTable, SRCONE, stNoStack, stMask0,
|
||
; stMASK0Slow, stHilite, arith. transfer loops for 16 & 32
|
||
; bits/pixel, OneColor, DoubleColor, QUADColor, EightLoop,
|
||
; BWtoD15Alpha, BWtoD24Alpha, AverageH16, Dither32toIndexed,
|
||
; Dither16toIndexed, Dither32toGray, Dither16toGray,
|
||
; Dither16toBitmap, Search32to32, Search32toInd, SeedCFill32,
|
||
; Search32to16, Search16toIndexed, SeedCFill16, Search16to32,
|
||
; Search16to16.
|
||
; <63> 5/5/92 SAH Put fix for clipped vertical stretch back in for Cube-E
|
||
; <62> 1/15/92 KC Fix "Short branch to the next instruction changed to a NOP"
|
||
; assembler warning.
|
||
; <61> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
|
||
; <60> 10/2/91 DTY Conditionalise last changes for TheFuture.
|
||
; <59> 10/2/91 KON Fix bug where CopyBits was crashing when vertically stretching a
|
||
; pixmap that is clipped at the top.
|
||
; <58> 10/2/91 KON Save and restore stklowPt (rather than just setting it to sp on
|
||
; exit) in stretch. This fixes a bug where someone turns off the
|
||
; stack sniffer and then calls stretch which turns it back on.
|
||
; Also, abort picture playback when QDError = AbortPicPlayBackErr.
|
||
; <57> 10/2/91 KON Save and restore stklowPt (rather than just setting it to sp on
|
||
; exit) in stretch. This fixes a bug where someone turns off the
|
||
; stack sniffer and then calls stretch which turns it back on.
|
||
; Abort picture playback when QDError = AbortPicPlayBackErr.
|
||
; <56> 9/13/91 DTY Conditionalise previous change so it doesnÕt get built for
|
||
; CubeE. (ItÕll get built for PsychoticFarmerAndLater.) Move in
|
||
; code that was taken out between <54> and <55>, and build it for
|
||
; CubeE only.
|
||
; <55> 7/23/91 KON Speed up indexed to 32-bit srcCopy mode. Speed up colorized
|
||
; text: don't take scale case when depths are the same.
|
||
; <54> 3/19/91 KON DTY, WRKSHT#SAH-QD-055: Some pixmaps created with an old version
|
||
; of ResEdit had the high bit of pmVersion set. This causes the
|
||
; pmVersion macro to crash, so I removed it.
|
||
; <53> 3/18/91 KON GSC and JT: WKSHT# SAH-QD-054 16-bit source shrinks crash
|
||
; because the average buffer is calculated from the promoted
|
||
; depth, rather than the real depth.
|
||
; <52> 3/6/91 KON CEL: BRC# 84369 Register D0 was getting trashed when search
|
||
; procs were attached to direct destinations. Also, color
|
||
; calculation for 16-bits was incorrect when search proc is
|
||
; installed.
|
||
; <51> 2/19/91 KON DDG: WorkSheet #KS-003, MaskAddr in stackframe is not
|
||
; initialized if there is not a mask. This was causing crashes in
|
||
; some cases since verticle merge scanline routines look at the
|
||
; maskaddr.
|
||
; <50> 1/25/91 KON DDG: BRC# 81625, A fix in QDciPatchROM.a required reorganizing
|
||
; part of stretch. This change keeps the files in synchronization.
|
||
; <49> 1/23/91 KON Optimize and clean up code that was rushed for B4. [SMC]
|
||
; <48> 1/14/91 KON Fix PixMaps with nil color tables and CopyDeepMask with 1-bit
|
||
; mask. Fix bug in pmVersion macro. [SMC]
|
||
; <47> 1/11/91 KON Register was getting trashed around call to SeekMask. This
|
||
; caused CopyBits with more 3 regions to get trashed as in the
|
||
; KeyCaps CDEV. [DDG]
|
||
; <46> 12/17/90 KON Fix one of the problems with NIL color tables. [smc]
|
||
; <45> 11/26/90 SMC Fixed pattern hilite once and for all, and forced arithmetic
|
||
; transfers to direct devices into rgnblt instead of the slower
|
||
; loops in bitblt. With BAL.
|
||
; <44> 11/12/90 KON Fix problem with colorizing when dithering from an indexed src
|
||
; to an indexed destination. [smc]
|
||
; <43> 11/9/90 KON Copy rectangles to local stack and fixed problems with negative
|
||
; pmVersions.
|
||
; <42> 10/31/90 SMC Fixed alpha channel bugs with BAL.
|
||
; <41> 9/25/90 KON If source is 1-bit black and white and we are not shrinking,
|
||
; clear dither bit. (With SMC).
|
||
; <40> 9/18/90 SMC Fix transparent, addMax, subOver, and addMin transfers with a
|
||
; pattern.
|
||
; <39> 9/18/90 BG Removed <25>. 040s are behaving more reliably now.
|
||
; <38> 9/14/90 SMC Commented out all of the QuickerDraw routines and changed the
|
||
; logic to send those cases through ScaleBlt which are now faster
|
||
; and smaller (by about 1K). This implicitly fixes a bus error
|
||
; problem under AU/X when scaling from a 1-bit screen to the left
|
||
; edge of an 8-bit screen.
|
||
; <37> 9/13/90 KON NEEDED FOR BETA: Fix problem where promoting source to RGB is
|
||
; messed up. This showed up when the source is 1-bit. Also fixed
|
||
; in QDciPatchROM.a.
|
||
; <36> 9/10/90 KON Fixed one-bit to one-bit colorized copy.
|
||
; <35> 9/6/90 KON Fix 16 to indexed search loop.
|
||
; <34> 9/5/90 KON Fix copymask from an indexed src. The pmtable was not set
|
||
; correctly.
|
||
; <33> 9/4/90 KON fix problem where ctseed for 1-bit sources was getting trashed.
|
||
; If direct destination and search proc installed, use versions of
|
||
; fg and bg colors which have not been changed by the proc to do
|
||
; colorizing.
|
||
; <32> 8/26/90 KON Fix Search16to32 and Search32to16 stack frame referencing. Add
|
||
; 32-bit clean versions of MaskPixPmTable and SrcPixPmTable to
|
||
; stack frame.
|
||
; <31> 8/21/90 KON Always call search proc if one exists. If search proc fails,
|
||
; still use search procs RGBColor. Replicate bits when passing
|
||
; 16-bit source color to search procs.
|
||
; <30> 8/15/90 KON Fixed transparent mode which was writing outside the destination
|
||
; rectangle. Turned off colorizing for arithmetic modes.
|
||
; <29> 7/23/90 KON Fix CopyMask in cases where left and right edge are displaying
|
||
; garbage.
|
||
; <28> 7/20/90 gbm Change some identifiers to avoid assembly conflicts
|
||
; <27> 7/17/90 KON Fix 16-bit source notCopy mode.
|
||
; <26> 7/10/90 KON Fixed CopyMask for 16-bit sources, and cases where 16-bit masks
|
||
; were failing. Also fixed vertical shrinking of 1-bit sources.
|
||
; <26> 7/9/90 KON Fixed CopyMask for 16-bit sources, and cases where16-bit masks
|
||
; were failing.
|
||
; <25> 6/28/90 BG Added EclipseNOPs for flakey 040s.
|
||
; <24> 6/5/90 KON Speed up notCopy mode for direct src to direct dst by using
|
||
; invert flag.
|
||
; <23> 6/4/90 KON Speed things that slowed down up by checking if colorizing is a
|
||
; nop.
|
||
; <22> 5/29/90 HJR Fix Mac32 build problem by moving table8 and some code saving
|
||
; mods.
|
||
; <21> 5/24/90 KON Fix transfer modes for direct devices, and fix colorizing for
|
||
; indexed devices.
|
||
; <19+> 4/12/90 KON Add deep masks for copymask.
|
||
; <19> 4/11/90 KON Suppress colorizing in src blits when the src clut is nil (i.e.
|
||
; the colors are a ramp between the foreground and background
|
||
; colors.
|
||
; <18> 3/13/90 KON Part of file got trashed. Now fixed.
|
||
; <17> 3/13/90 KON Fixed bug in 16-bit search proc.
|
||
; <16> 3/6/90 KON Fixed error term for vertical shrinking so expanding and then
|
||
; shrinking by an integral amount does not alter the image.
|
||
; <15> 2/23/90 KON Fixed buffer problem in Dither16toGray.
|
||
; <14> 2/23/90 KON Fixed Dither32toGray and Dither16toGray. Random dots were
|
||
; displayed because error term was not calculated right.
|
||
; <13> 2/23/90 KON Added 16-bit shrink.
|
||
; <12> 2/16/90 KON Cleared out high end of register of ErrBuf size calculation.
|
||
; <11> 2/14/90 KON Try to get 256K in stNoStack. Memory requirement calculation now
|
||
; use longs so high bits aren't lost. StackFree is updated
|
||
; correctly.
|
||
; <10> 2/14/90 BAL Changed MFTemp memory stack allocation to try for upto 128K
|
||
; chunk.
|
||
; <9> 2/9/90 BAL Fixed dither 8-bit to 32-bit stretched copybits.
|
||
; <8> 2/5/90 BAL Fixed bug in vertical shrinking while performing indexed to
|
||
; indexed dither.
|
||
; <7> 2/1/90 BAL Dither16toIndexed: Fix dither error calculation for 16 bit
|
||
; sources being displayed on color indexed devices.
|
||
; <6> 2/1/90 BAL Special cased SeedCFill/CalcCMask search procs for 16 and 32 bit
|
||
; sources.
|
||
; <5> 1/30/90 BAL Fixed bugs in underflow of error when dithering to a grayscale
|
||
; or bitmap destination. This affects Dither32toGray/Bitmap and
|
||
; Dither16toGray/Bitmap.
|
||
; <4> 1/28/90 KON Fix clipping when destination is clipped at the top.
|
||
; <3> 1/28/90 BAL Added the depth conversion routines Dither32toBitmap and
|
||
; Dither16toBitmap and changed the decision tree to utilize them.
|
||
; <1+> 1/3/90 BAL FOR 6.0.5: Submitted latest version to BBS. Changes include
|
||
; indexed to indexed dithering support.
|
||
; <1.9> 12/9/89 BAL Fixed bug in accumulation of dither error in some of the loops.
|
||
; Should fix in others. Fixed a bug and optimized the case of
|
||
; source rects with tops above srcbits.bounds.
|
||
; <1.8> 9/25/89 BAL Changed "NOT forROM" conditionals to "useColorICON" and
|
||
; defaulted it to false
|
||
; <1.7> 7/16/89 GGD GGD for the vacationing BAL, Fixed bug in AverageH when
|
||
; averaging 2 pixels, and optimized the entire loop at the same
|
||
; time.
|
||
; <¥1.6> 7/14/89 BAL For Aurora: Final CQD
|
||
; <1.5> 6/30/89 BAL Make A5 valid and return to 24 bit mode before calling search
|
||
; procs
|
||
; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
||
; 5/26/89 BAL Fixed bug in call to MakeITable if seed mismatch during direct
|
||
; to indexed copy.
|
||
; <¥1.3> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1
|
||
; 9/26/88 BAL Replace successfully TrimRect'ed rgns with wideopen to avoid
|
||
; multiple Trims.
|
||
; 9/22/88 BAL Moved initialization of region state records into GetSeek.
|
||
; 9/19/88 BAL Altered to use common stack frame file 'Drawing Vars.a'
|
||
; 9/18/88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed
|
||
; references to PIXSRC;
|
||
; 9/4/88 BAL Added area averaging for shrinking of 32 bit pixmaps.
|
||
; 8/29/88 BAL Changed 32 to 8-1bit dither to carry 2-D error.
|
||
; 6/28/88 BAL Added special scaling routine for B/W 1 bit to direct RGB in a
|
||
; 32 bit pixel.
|
||
; 6/27/88 BAL Changed pattern expansion routines for 16 and 32 bits to
|
||
; optimize for solid.
|
||
; 6/17/88 BAL Added routines to depth scale from direct to indexed devices.
|
||
; 5/9/88 BAL Altered depth scaling code to use long sized pixel translation
|
||
; table.
|
||
; 5/4/88 BAL fixed bug in n*8x scaling (n=3,5,6,7...)
|
||
; 5/3/88 BAL fixed 2 scaling bugs where word-sized operations overflowed
|
||
; 4/9/88 BAL altered to use 32bit addressing during blit to screens
|
||
; 12/7/87 BAL Changed <C947> to restore D7 (invertFlag) before returning to
|
||
; rgn/bitBlt. <C983>
|
||
; 11/8/87 BAL Forced stretch to only do color table pixel translation if
|
||
; absolutely necessary. <C947>
|
||
; 11/8/87 BAL Forced stretch to TrimRect(clipRgn,MinRect) before submitting to
|
||
; rgnBlt. <C951>
|
||
; 11/8/87 BAL Fixed computation of bufSize for more accurate region clipping
|
||
; at at depths greater than 1. <C954>
|
||
; 2/3/87 EHB Added error checking
|
||
; 1/3/87 CRC expect color param in stretch
|
||
; 12/12/86 CRC Added arithmetic modes
|
||
; 10/9/86 EHB Added mask parameters to stretchbits calls
|
||
; 9/11/86 EHB Added depth translation (N-bit to M-bit)
|
||
; 9/8/86 EHB Added full-ratio color scaling (N-bit to N-bit)
|
||
; 7/29/86 EHB Allocate EXPAT buffer on stack so long aligned
|
||
; 7/26/86 EHB Added support for expanded patterns
|
||
; 7/22/86 EHB Pass MODE to PatExpand for colorizing
|
||
; 7/7/86 EHB Revised use of color in blt routines.
|
||
; 7/5/86 EHB Replaced SeekMask and GetXRtn with GetSeek
|
||
; 6/24/86 EHB Big re-org: Create one stack frame shared by stretch, rgnblt,
|
||
; bitblt Set up all shared locals here, then call rgnblt, bitblt
|
||
; with parms in stack frame and registers (since stretchbits
|
||
; called from everywhere).
|
||
; 6/23/86 EHB Rearranged for shared stack frame between stretch, rgnblt,
|
||
; bitblt Set up all common fields before calls to rgnblt Removed
|
||
; all parameters passed to rgnblt (only called from here)
|
||
; 6/21/86 EHB Do expansion in 2 passes: one for data, next for chunks
|
||
; 6/20/86 EHB New params to COLORMAP Added FCOLOR and BCOLOR to stack frame
|
||
; 6/19/86 EHB Use longs in horiz calculations for big pixels
|
||
; 6/18/86 EHB Take depth into account for scaling
|
||
; 6/18/86 EHB Added a pattern param so it can be called instead of RgnBlt
|
||
; 6/16/86 EHB Added routine GetSizeShift to avoid multiplies
|
||
; 6/15/86 EHB Convert BitsToPix, and use pixelSize
|
||
; 6/14/86 EHB Call GetXRtn to set expand routine for SeekMask Changed
|
||
; SRCBITS/DSTBITS to SRCPIX/DSTPIX
|
||
; 6/13/86 EHB Moved SeekMask to another file Rearranged stack frame with
|
||
; SeekMask stuff at top
|
||
; 6/11/86 EHB Modified Stretch to use longwords and 020 instructions Made sure
|
||
; that stack buffers all longword aligned
|
||
; 6/5/86 EHB Masked off flag bits in all references to rowBytes
|
||
;
|
||
; To Do:
|
||
;
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
MACHINE MC68020
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; --> STRETCH.TEXT
|
||
;
|
||
; TO DO: TWO IDENTICAL EXPAND ROUTINES IS TOO MUCH!!!
|
||
;
|
||
;------------------------------------------------------------------
|
||
;
|
||
; MODIFICATIONS
|
||
;
|
||
; 5Jun86 EHB Masked off flag bits in all references to rowBytes
|
||
; 11Jun86 EHB Modified Stretch to use longwords and 020 instructions
|
||
; Made sure that stack buffers all longword aligned
|
||
; 13Jun86 EHB Moved SeekMask to another file
|
||
; Rearranged stack frame with SeekMask stuff at top
|
||
; 14Jun86 EHB Call GetXRtn to set expand routine for SeekMask
|
||
; Changed SRCBITS/DSTBITS to SRCPIX/DSTPIX
|
||
; 15Jun86 EHB Convert BitsToPix, and use pixelSize
|
||
; 16Jun86 EHB Added routine GetSizeShift to avoid multiplies
|
||
; 18Jun86 EHB Take depth into account for scaling
|
||
; 18Jun86 EHB Added a pattern param so it can be called instead of RgnBlt
|
||
; 19Jun86 EHB Use longs in horiz calculations for big pixels
|
||
; 20Jun86 EHB New params to COLORMAP
|
||
; Added FCOLOR and BCOLOR to stack frame
|
||
; 21Jun86 EHB Do expansion in 2 passes: 32 for data, next for chunks
|
||
; 23Jun86 EHB Rearranged for shared stack frame between stretch, rgnblt, bitblt
|
||
; Set up all common fields before calls to rgnblt
|
||
; Removed all parameters passed to rgnblt (only called from here)
|
||
; 24Jun86 EHB Big re-org: Create one stack frame shared by stretch, rgnblt, bitblt
|
||
; Set up all shared locals here, then call rgnblt, bitblt with parms
|
||
; in stack frame and registers (since stretchbits called from everywhere).
|
||
; 5Jul86 EHB Replaced SeekMask and GetXRtn with GetSeek
|
||
; 7Jul86 EHB Revised use of color in blt routines.
|
||
; 22Jul86 EHB Pass MODE to PatExpand for colorizing
|
||
; 26Jul86 EHB Added support for expanded patterns
|
||
; 29Jul86 EHB Allocate EXPAT buffer on stack so long aligned
|
||
; 8Sep86 EHB Added full-ratio color scaling (N-bit to N-bit)
|
||
; 11Sep86 EHB Added depth translation (N-bit to M-bit)
|
||
; 9Oct86 EHB Added mask parameters to stretchbits calls
|
||
; 12Dec86 CRC Added arithmetic modes
|
||
; 3Jan87 CRC expect color param in stretch
|
||
; 3Feb87 EHB Added error checking
|
||
;
|
||
;________________________________ Post Mac II _____________________________________
|
||
;
|
||
; 08Nov87 BAL Forced stretch to only do color table pixel translation if
|
||
; absolutely necessary. <C947>
|
||
; 08Nov87 BAL Forced stretch to TrimRect(clipRgn,MinRect) before submitting to rgnBlt. <C951>
|
||
; 08Nov87 BAL Fixed computation of bufSize for more accurate region clipping at
|
||
; at depths greater than 1. <C954>
|
||
; 07Dec87 BAL Changed <C947> to restore D7 (invertFlag) before returning to rgn/bitBlt. <C983>
|
||
; 09Apr88 BAL altered to use 32bit addressing during blit to screens
|
||
; 03May88 BAL fixed 2 scaling bugs where word-sized operations overflowed
|
||
; 04May88 BAL fixed bug in n*8x scaling (n=3,5,6,7...)
|
||
; 09May88 BAL Altered depth scaling code to use long sized pixel translation table.
|
||
; 17Jun88 BAL Added routines to depth scale from direct to indexed devices.
|
||
; 27Jun88 BAL Changed pattern expansion routines for 16 and 32 bits to optimize for solid.
|
||
; 28Jun88 BAL Added special scaling routine for B/W 1 bit to direct RGB in a 32 bit pixel.
|
||
; 29Aug88 BAL Changed 32 to 8-1bit dither to carry 2-D error.
|
||
; 04Sep88 BAL Added area averaging for shrinking of 32 bit pixmaps.
|
||
; 18Sep88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed references to PIXSRC;
|
||
; 19Sep88 BAL Altered to use common stack frame file 'Drawing Vars.a'
|
||
; 22Sep88 BAL Moved initialization of region state records into GetSeek.
|
||
; 26Sep88 BAL Replace successfully TrimRect'ed rgns with wideopen to avoid multiple Trims.
|
||
;
|
||
;________________________________ Post Jackson Pollack _____________________________________
|
||
;
|
||
; 26May89 BAL Fixed bug in call to MakeITable if seed mismatch during direct to indexed copy.
|
||
|
||
;
|
||
; Output: A3 contains address of current scanline.
|
||
;
|
||
MACRO
|
||
_pmVersion
|
||
if 0 then
|
||
cmp.l maskaddr(a6),a3
|
||
bne.s @CheckSrc
|
||
add.l a5,a3 ;bump mask to next row
|
||
tst.w maskpix+pmVersion(a6)
|
||
bpl.s @DoLittle
|
||
move.l a0,-(sp)
|
||
move.l maskpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
move.l a3,maskaddr(a6)
|
||
bra.s @DoLittle
|
||
@CheckSrc
|
||
;must be src.
|
||
endif
|
||
add.l a5,a3 ;bump src to next row
|
||
if 0 then
|
||
tst.w srcpix+pmVersion(a6)
|
||
bpl.s @DoLittle
|
||
move.l a0,-(sp)
|
||
move.l srcpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
@DoLittle
|
||
endif
|
||
ENDM
|
||
|
||
;
|
||
; The first time bruce is called, D3 contains the starting scan line number
|
||
; On output: A3 contains first scanline address
|
||
;
|
||
MACRO
|
||
_pmVersionSrcFirstTime
|
||
if 0 then
|
||
tst.w srcpix+pmVersion(a6)
|
||
bpl.s @NoSrcPmVersion
|
||
move.l a0,-(sp)
|
||
move.l srcpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
@NoSrcPmVersion
|
||
endif
|
||
ENDM
|
||
|
||
MACRO
|
||
_pmVersionMaskFirstTime
|
||
if 0 then
|
||
tst.l maskbits(a6) ;is there a mask?
|
||
bne.s @DoIt
|
||
moveq #0,a3 ;init MaskAddr to zero <KON 19FEB91>
|
||
bra.s @WriteIt
|
||
@DoIt
|
||
tst.w maskpix+pmVersion(a6)
|
||
bpl.s @DoLittle
|
||
move.l a0,-(sp)
|
||
move.l srcpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
@WriteIt
|
||
move.l a3,maskaddr(a6) ;a3 is returned by the routine
|
||
@DoLittle
|
||
endif
|
||
ENDM
|
||
|
||
StretchBits PROC EXPORT
|
||
IMPORT Scale32toIndexed, Scale16toIndexed, ScaleIndexedToIndexed, Scale32ToBitMap
|
||
IMPORT Scale32toGray, Scale16toGray, Scale32to16, Scale16to32, Scale16ToBitMap
|
||
IMPORT Search32toIndexed, Search16toIndexed, Search32to16, Search16to32
|
||
IMPORT Dither32toIndexed, Dither16toIndexed, Dither32toGray, Dither16toGray
|
||
IMPORT CB8to8Clip, CB8to1Clip, CB1to8Clip, Dither32toBitmap, Dither16toBitmap
|
||
IMPORT scaleBlt, Search32to32, Search16to16
|
||
IMPORT SHFTTBL
|
||
EXPORT stMASK0, stMASK1, stMASK2, stMASK3, stAvg, stAddPin, stAddOver
|
||
EXPORT stSubPin, stTransparent, stMax, stSubOver, stMin, stHilite
|
||
EXPORT Table2,TABLE4,TABLE8, setUpStretch, stNoStack
|
||
EXPORT stArith16Tab,stArith32Tab,stColorTab,stGrayTab,stSearchTab
|
||
EXPORT EXTBL,PATEXTBL,DoneStretch,OneBitProc,BlitCase,stScanLoop
|
||
EXPORT NOPfgColorTable
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
;--------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StretchBits(srcBits,maskBits,dstBits: BitMap;
|
||
; srcRect,maskRect,dstRect: Rect;
|
||
; mode: INTEGER; pat: Pattern;
|
||
; rgnA,rgnB,rgnC: RgnHandle);
|
||
;
|
||
; Transfer a rectangle of bits from srcBits to dstBits,
|
||
; stretching or compressing according to srcRect and dstRect.
|
||
; The transfer is clipped to the intersection of rgnA, rgnB, and rgnC.
|
||
; It is also clipped to the specified mask. If MaskBits is NIL, then
|
||
; no masking is done.
|
||
;
|
||
; Restrictions:
|
||
;
|
||
; if numer <> denom, then src and dst bitmaps do not overlap.
|
||
;
|
||
;
|
||
; COPYRIGHT APPLE COMPUTER INC.
|
||
; DESIGNED AND WRITTEN BY BILL ATKINSON
|
||
;
|
||
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 44 ;SIZE OF PARAMETERS
|
||
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
||
MASKBITS EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
|
||
DSTBITS EQU MASKBITS-4 ;LONG, ADDR OF BITMAP
|
||
SRCRECT EQU DSTBITS-4 ;LONG, ADDR OF RECT
|
||
MASKRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
||
DSTRECT EQU MASKRECT-4 ;LONG, ADDR OF RECT
|
||
MODE EQU DSTRECT-2 ;WORD
|
||
PAT EQU MODE-4 ;LONG, ADDR OF PATTERN
|
||
RGNA EQU PAT-4 ;LONG, RGNHANDLE
|
||
RGNB EQU RGNA-4 ;LONG, RGNHANDLE
|
||
RGNC EQU RGNB-4 ;LONG, RGNHANDLE
|
||
multColor EQU RGNC-2 ;byte, set if source contains nonblack/white colors
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
IF (&TYPE('useColorICON') = 'UNDEFINED') THEN
|
||
useColorICON EQU 0
|
||
ENDIF
|
||
|
||
|
||
;----------------------------------------------------
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
|
||
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
||
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
||
move.l stklowPt,saveStkLowPt(a6) ;keep track of the sniffer <57>
|
||
;
|
||
; Copy rectangles to stack since they might be part of a handle and could move.
|
||
; Some people don't know that CopyBits moves memory... just call me SlowDraw.
|
||
; <KON 7NOV90>
|
||
;
|
||
move.l srcrect(a6),a0
|
||
lea newSrcRect(a6),a1
|
||
move.l a1,srcrect(a6)
|
||
move.l (a0)+,(a1)+
|
||
move.l (a0)+,(a1)+
|
||
|
||
move.l maskrect(a6),a0
|
||
lea newMaskRect(a6),a1
|
||
move.l a1,maskrect(a6)
|
||
move.l (a0)+,(a1)+
|
||
move.l (a0)+,(a1)+
|
||
|
||
move.l dstrect(a6),a0
|
||
lea newDstRect(a6),a1
|
||
move.l a1,dstrect(a6)
|
||
move.l (a0)+,(a1)+
|
||
move.l (a0)+,(a1)+
|
||
|
||
MOVE.W MODE(A6),D1 ;get mode <42>
|
||
BTST #3,D1 ;pattern mode? <42>
|
||
BNE.S @0 ;yes, alpha already stripped <42>
|
||
_GetStreamMode ;get alpha mode bits <42>
|
||
MOVE.W D1,MODE(A6) ;save stripped mode <42>
|
||
@0: MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL POINTER
|
||
move.b mmu32Bit,MMUSave(a6) ;save mmu mode for cheap exit
|
||
CLR.L DSTMASKBUF(A6) ;ASSUME NO MASK
|
||
CLR.L stackHandle(A6) ;init alternate stack not used
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FAST BUFFERS)
|
||
;
|
||
MOVE.L SP,D1 ;GET THE STACK POINTER
|
||
AND.B #$FC,D1 ;FORCE LONG ALIGNMENT
|
||
MOVE.L D1,SP ;USE IT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; CONVERT SRCBITS AND DSTBITS TO PIXMAPS
|
||
; (A5 must contain global ptr)
|
||
;
|
||
; BITSTOPIX TAKES DEFAULT DEVICE FROM THEGDEVICE
|
||
|
||
MOVE.L THEGDEVICE,-(SP) ;SAVE THEGDEVICE
|
||
MOVE.L SRCDEVICE,THEGDEVICE ;SET UP SRC DEVICE
|
||
MOVE.L SRCBITS(A6),A1 ;GET POINTER TO SRCBITS
|
||
|
||
|
||
IF useColorICON THEN
|
||
|
||
;----------------------------------------------------
|
||
; SLIMEY HACK to draw Jackson Pollack Icon in Full Color:
|
||
;
|
||
move.l baseAddr(a1),d0 ;get baseAddr
|
||
_rTranslate24To32 ;clean up the address
|
||
clr.w filler2(a6) ;set myIcon flag false
|
||
tst.l d0 ;is it in slot space?
|
||
bmi.s @1 ;yes, skip chk
|
||
move.l d0,a0 ;to prevent Bus Errors
|
||
; cmp.l #$EBF557E2,108(a0) ;check for race car signature
|
||
; cmp.l #$cc45c929,108(a0) ;check for painting signature
|
||
lea 80(a0),a0 ;point into data
|
||
cmp.l #$842ba003,(a0)+ ;check for prism signature
|
||
bne.s @1
|
||
cmp.l #$8445d455,(a0)+ ;check for prism signature
|
||
bne.s @1
|
||
cmp.l #$8882e803,(a0)+ ;check for prism signature
|
||
bne.s @1
|
||
cmp.l #$89017855,(a0) ;check for prism signature
|
||
bne.s @1
|
||
|
||
move.l jpCicn,a1 ; get cicn handle
|
||
move.l (a1),a1 ; point at pixmap
|
||
move.l (sp),a0 ; get the dst gdevice handle
|
||
move.l (a0),a0 ; point to it
|
||
move.l gdPMap(a0),a0 ; get its pixmap handle
|
||
move.l (a0),a0 ; point to it
|
||
cmp.w #4,pixelsize(a0) ; check depth
|
||
bge.s @usePMap ; 4 bit or deeper-> use pixmap data
|
||
add #IconBMap,a1 ; else use bitmap data
|
||
sub #1,filler2(a6) ; using bitmap, don't hack colors
|
||
|
||
@usePMap
|
||
cmp.w #3,Mode(a6) ; BIC mode?
|
||
bne.s @2 ; no, draw the icon
|
||
bra done
|
||
|
||
|
||
@2 clr.w Mode(a6) ; use copy mode
|
||
add #1,filler2(a6) ; flag hack in progress
|
||
;
|
||
;----------------------------------------------------
|
||
|
||
ENDIF
|
||
|
||
|
||
@1 LEA SRCPIX(A6),A2 ;COPY INTO SRCPIX
|
||
_BitsToPix ;BITMAP -> PIXMAP
|
||
|
||
MOVE.L (SP)+,THEGDEVICE ;RESTORE THEGDEVICE AS DST DEVICE
|
||
MOVE.L DSTBITS(A6),A1 ;GET POINTER TO DSTBITS
|
||
LEA DSTPIX(A6),A2 ;COPY INTO DSTPIX
|
||
_BitsToPix ;BITMAP -> PIXMAP
|
||
MOVE.L D1,REALBOUNDS(A6) ;SAVE REAL DST BOUNDS.TOPLEFT
|
||
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; GET SHIFT AMOUNTS FOR SRC (D3) AND DST (D4) DEPTHS
|
||
; THE PIXSRC FLAG IS SET IF SRC IS A PIXMAP THAT ISN'T ONE BIT PER PIXEL
|
||
;
|
||
LEA SHFTTBL,A0 ;POINT TO SHIFT TABLE
|
||
MOVE SRCPIX+PIXELSIZE(A6),D0 ;GET SRC PIXEL SIZE
|
||
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D0),D3 ;GET SRC SHIFT
|
||
MOVE D3,SRCSHIFT(A6) ;AND SAVE SRC SHIFT AMOUNT
|
||
|
||
MOVE DSTPIX+PIXELSIZE(A6),D0 ;GET DST PIXEL SIZE
|
||
MOVEQ #0,D4 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D0),D4 ;GET DST SHIFT
|
||
MOVE D4,DSTSHIFT(A6) ;AND SAVE DST SHIFT AMOUNT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; CONVERT MASKBITS TO MASKPIX, AND GET SHIFT AMOUNT FOR MASK DEPTH
|
||
; If mask is direct, pass depth through. If mask is 2, 4, or 8 bit
|
||
; promote mask to 32 bit/pixel.
|
||
;
|
||
CLR MASKSHIFT(A6) ;ASSUME DEPTH = 1
|
||
MOVE.L MASKBITS(A6),D0 ;IS THERE A MASK?
|
||
BEQ.S NOMASK ;=>NO, SKIP MASK SETUP
|
||
|
||
MOVE.L D0,A1 ;GET POINTER TO MASKBITS
|
||
LEA MASKPIX(A6),A2 ;COPY INTO MASKPIX
|
||
_BitsToPix ;BITMAP -> PIXMAP
|
||
|
||
LEA SHFTTBL,A0 ;POINT TO SHIFT TABLE
|
||
MOVE MASKPIX+PIXELSIZE(A6),D0 ;GET MASK PIXEL SIZE
|
||
moveq #0,d5 ;default shift=0
|
||
move.b 0(a0,d0),d5
|
||
bne.s @PromoteIt ;mask is 1-bit/pixel
|
||
;
|
||
; should promote 1-bit masks unless it's copy mode
|
||
;
|
||
move.w MODE(A6),d0 ;COPY MODE and 1-bit deep?
|
||
and.w #$37,d0 ;mask pattern and dither bits
|
||
beq.s NoMask ;yes, don't promote it
|
||
@PromoteIt
|
||
cmp.b #4,d5 ;if it's 16 bpp, save mask depth
|
||
beq.s @gotMaskDepth
|
||
move #5,d5 ;otherwise force it to 32 bits/pixel
|
||
@gotMaskDepth
|
||
move d5,maskshift(a6)
|
||
|
||
NOMASK
|
||
|
||
;-------------------------------------------------------------------
|
||
;
|
||
; CALC MINRECT = INTERSECTION OF DSTRECT, DSTBITS.BOUNDS, AND THREE
|
||
; REGION BOUNDING BOXES. QUIT IF THE INTERSECTION IS EMPTY.
|
||
;
|
||
MOVE.L DSTRECT(A6),-(SP) ;PUSH ADDR OF DSTRECT
|
||
PEA DSTPIX+BOUNDS(A6) ;PUSH ADDR OF DSTPIX.BOUNDS
|
||
MOVE.L RGNA(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH RGN BBOX
|
||
MOVE.L RGNB(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH RGN BBOX
|
||
MOVE.L RGNC(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH RGN BBOX
|
||
MOVE #5,-(SP) ;PUSH NRECTS
|
||
PEA MINRECT(A6) ;PUSH WHERE TO PUT RESULT
|
||
_RSECT ;INTERSECT ALL RECTS
|
||
BEQ GOHOME ;QUIT IF RESULT IS EMPTY
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
|
||
; ALSO SET UP LOCAL PATTERN POINTER, LOCPAT(A6)
|
||
;
|
||
MOVE.L PAT(A6),LOCPAT(A6) ;COPY PATTERN POINTER
|
||
MOVE MODE(A6),LOCMODE(A6) ;COPY MODE
|
||
TST ([DSTBITS,A6],ROWBYTES) ;IS THE DST OLD OR NEW?
|
||
SMI NEWPATTERN(A6) ;FLAG = TRUE IF NEW PATTERN
|
||
CLR PATROW(A6) ;FLAG NOT DOING BIG PATTERNS
|
||
|
||
bclr #6,LocMode+1(a6) ;clear dither bit <07Jul88 BAL>
|
||
sne useDither(a6) ;remember whether it was set <07Jul88 BAL>
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ADJUST MODE AND PATTERN FOR COLOR SEPARATION.
|
||
; (A5 must contain global ptr)
|
||
;
|
||
btst #1,multColor+1(a6) ;check if src is a color font <05JUNE92 SAH>
|
||
sne multiColor(a6) ;set multiColor flag for ColorMap
|
||
_COLORMAP ;ALTER FOR COLOR SEPARATION
|
||
|
||
;---------------------------------------
|
||
;
|
||
; SET UP INVERT FLAG IN D7 TO REFLECT MODE BIT 2
|
||
; CHECK TO SEE IF PATTERN WILL BE USED
|
||
;
|
||
MOVE LOCMODE(A6),D2 ;GET TRANSFER MODE
|
||
|
||
IF useColorICON THEN
|
||
|
||
tst filler2(a6) ;cicn hack
|
||
beq.s @1
|
||
cmp #8,srcPix+pixelSize(a6) ;8-bit clut on icon?
|
||
bne.s @1
|
||
lea srcPix+pmtable(a6),a0 ;pnt to pmtable handle
|
||
move.l (a0),a0 ;get handle
|
||
move.l (a0),a0 ;pnt to table
|
||
pea ctTable+rgb+red(a0) ;push address of entry zero (white)
|
||
pea 255*8+ctTable+rgb+red(a0) ;push address of entry 255 (black)
|
||
_GetForeColor ;fill in entry 255
|
||
_GetBackColor ;fill in entry zero
|
||
MOVE LOCMODE(A6),D2 ;restore TRANSFER MODE
|
||
@1
|
||
ENDIF
|
||
|
||
|
||
;--------------------------------------------------------------
|
||
;
|
||
; Use table lookup to map input mode, src type, and dst type
|
||
; to a new mode, colorize location, swap fg/bk, use stretch (slow)
|
||
; and whether or not to invert.
|
||
;
|
||
; Index value is five bits: SRCTYPE DSTTYPE MODE (3 bits)
|
||
; For SRCTYPE and DSTTYPE 1 = direct, 0 = indexed
|
||
; MODE is bottom 3 bits of mode
|
||
;
|
||
; Lookup value is a byte: INVERT 0 STRETCH? SWAP FG/BG CLRXLATE NEWMODE
|
||
; For INVERT, 1 means invert in blit loop, 0 means don't
|
||
; STRETCH, 1 means go through stretch, 0 means fast case ok
|
||
; SWAP FG/BG 1 means swap, 0 means don't
|
||
; CLRXLATE 1 means colorize in blit loop, 0 means translate in makescaletable
|
||
; NEWMODE 3 bits determine which blit loop to take
|
||
;
|
||
moveq #0,d0 ;default for patterns and arithmetic modes
|
||
|
||
btst #3,d2 ;is it a pattern mode?
|
||
bne DoPattern ;=>yes, don't remap mode
|
||
|
||
btst #5,d2 ;is it a arithmetic mode?
|
||
bne.s @useCopyMode ;yes, pretend copy mode
|
||
|
||
moveq #7,d0 ;prepare to get mode
|
||
and.w d2,d0 ;get mode in bottom 3 bits
|
||
@useCopyMode
|
||
cmp.w #4,d4 ;destination indexed?
|
||
blt.s @destind
|
||
bset #3,d0 ;set dest direct bit
|
||
|
||
@destind
|
||
cmp.w #4,d3 ;src indexed?
|
||
blt.s @srcind
|
||
bset #4,d0 ;set dest direct bit
|
||
@srcind
|
||
lea MapModeTable,a0
|
||
move.w (a0,d0*2),d0 ;get table lookup value
|
||
bra.s skipTable ;temporary, move table later
|
||
|
||
ScaleColorBit EQU 3
|
||
SwapFGBGBit EQU 4
|
||
UseStretchBit EQU 5
|
||
InvertItBit EQU 7
|
||
ColorizeInModeCaseBit EQU 8
|
||
ColorizeInSrcBufBit EQU 9
|
||
|
||
InvertIt EQU 1 << InvertItBit
|
||
UseStretch EQU 1 << UseStretchBit
|
||
SwapFGBG EQU 1 << SwapFGBGBit
|
||
ScaleColor EQU 1 << ScaleColorBit ;colorize in make scale table
|
||
ColorizeInModeCase EQU 1 << ColorizeInModeCaseBit
|
||
ColorizeInSrcBuf EQU 1 << ColorizeInSrcBufBit
|
||
|
||
; from QDciPatchROM.a verbatim (with the exception of CubeE stuff put back in this file) <sm 6/9/92>stb
|
||
MapModeTable
|
||
;
|
||
; indexed src, indexed dst
|
||
;
|
||
dc.w ScaleColor + srcCopy ;
|
||
dc.w ColorizeInModeCase + srcOr ;
|
||
dc.w ColorizeInModeCase + srcXor ;
|
||
dc.w ColorizeInModeCase + srcBic ;
|
||
dc.w UseStretch + SwapFGBG + ScaleColor + SrcCopy
|
||
dc.w InvertIt + ColorizeInModeCase + notSrcOr ;
|
||
dc.w InvertIt + ColorizeInModeCase + notSrcXor ;
|
||
dc.w InvertIt + ColorizeInModeCase + notSrcBic ;
|
||
|
||
;
|
||
; indexed src, direct dst
|
||
;
|
||
dc.w ScaleColor + srcCopy ;+ UseStretch + <05JUNE92 SAH>
|
||
dc.w InvertIt + UseStretch + notSrcBic + SwapFGBG + ColorizeInModeCase
|
||
dc.w InvertIt + UseStretch + notSrcXor + SwapFGBG + ColorizeInModeCase
|
||
dc.w InvertIt + UseStretch + notSrcOr + SwapFGBG + ColorizeInModeCase
|
||
dc.w SwapFGBG + ScaleColor + SrcCopy ; UseStretch + <05JUNE92 SAH>
|
||
dc.w UseStretch + ColorizeInModeCase + srcBic + SwapFGBG
|
||
dc.w UseStretch + ColorizeInModeCase + srcXor + SwapFGBG
|
||
dc.w UseStretch + ColorizeInModeCase + srcOr + SwapFGBG
|
||
;
|
||
; direct src, indexed dst
|
||
;
|
||
dc.w ColorizeInSrcBuf + srcCopy ;
|
||
dc.w ColorizeInModeCase + srcOr ;
|
||
dc.w ColorizeInModeCase + srcXor ;
|
||
dc.w ColorizeInModeCase + srcBic ;
|
||
dc.w ColorizeInSrcBuf + SwapFGBG + srcCopy
|
||
dc.w ColorizeInModeCase + InvertIt + notSrcOr ;
|
||
dc.w ColorizeInModeCase + InvertIt + notSrcXor ;
|
||
dc.w ColorizeInModeCase + InvertIt + notSrcBic ;
|
||
;
|
||
; direct src, direct dst
|
||
;
|
||
dc.w SwapFGBG + ColorizeInModeCase + srcCopy ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcBic ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcXor ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcOr ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + SrcCopy
|
||
dc.w SwapFGBG + ColorizeInModeCase + SrcBic ;
|
||
dc.w SwapFGBG + ColorizeInModeCase + srcXor ;
|
||
dc.w SwapFGBG + ColorizeInModeCase + srcOr ;
|
||
|
||
NOPfgColorTable
|
||
dc.l $FFFFFFFF ;1-bit white
|
||
dc.l $FFFFFFFF ;2-bit white
|
||
dc.l $FFFFFFFF ;4-bit white
|
||
dc.l $FFFFFFFF ;8-bit white
|
||
dc.l $7FFF7FFF ;16-bit white
|
||
dc.l $00FFFFFF ;32-bit white
|
||
|
||
;
|
||
; This next section of code figures out how much work we're going to have to do.
|
||
; First we change the mode to that from the mapModeTable.
|
||
; Next, find the correct foreground and background colors
|
||
; Swap FG/BG colors
|
||
; Figure out if colorizing is a NOP
|
||
;
|
||
skipTable
|
||
|
||
;
|
||
; Reintroduced code from <54> for CubeE.
|
||
;
|
||
|
||
if CubeE then ; <56>
|
||
|
||
; <56>
|
||
; <56> d0 has table value, if pmVersion is negative, always use Stretch
|
||
; <56>
|
||
tst.w srcpix+pmVersion(a6) ; <56> if pmVersion negative, always use stretch
|
||
bmi.s @ForceStretch ; <56>
|
||
TST.L MASKBITS(A6) ; <56> IS THERE A MASK?
|
||
beq.s @DontForceStretch ; <56> Check if mask needs pmVersion
|
||
tst.w maskpix+pmVersion(a6) ; <56> if pmVersion negative, always use stretch
|
||
bpl.s @DontForceStretch ; <56>
|
||
@ForceStretch ; <56>
|
||
bset #useStretchBit,d0 ; <56>
|
||
@DontForceStretch ; <56>
|
||
|
||
endif ; <56>
|
||
|
||
|
||
btst #5,d2 ;is it a arithmetic mode?
|
||
beq.s @ChangeLocMode ;no, then remap mode
|
||
;
|
||
; arithmetic modes aren't colorized
|
||
;
|
||
and.w #~(ScaleColor+ColorizeInModeCase+ColorizeInSrcBuf),d0 ;clear colorize bits
|
||
bra.s @ChangeLocModeDone
|
||
@ChangeLocMode
|
||
and.b #$f8,d2 ;clear low three bits
|
||
moveq #3,d1
|
||
and.b d0,d1 ;get low bits of new mode
|
||
or.b d1,d2 ;merge with old mode
|
||
@ChangeLocModeDone
|
||
move.w d2,locMode(a6) ;store for modecase, BitBlt, RgnBlt
|
||
|
||
;
|
||
; if ScaleCase colorizing and src and dst bit depths are the same and source
|
||
; is black and white only (multColor bit 0) or is direct, change to ModeCase
|
||
; colorizing as an optimization. This allows us to take BitBlt. <05JUNE92 SAH>
|
||
;
|
||
btst.l #ScaleColorBit,d0 ;ScaleCase colorizing? <55>
|
||
beq.s @ScaleOptimizationDone ;Not scalecase, then branch <55>
|
||
cmp.w #4,d3 ;src direct? <05JUNE92 SAH>
|
||
bge.s @checkDepth
|
||
btst #0,multColor+1(a6) ;src Black/White only
|
||
beq.s @ScaleOptimizationDone ;no, can't do anything
|
||
@checkDepth
|
||
cmp.w d3,d4 ;src and dst same depth? <55>
|
||
bne.s @ScaleOptimizationDone ;no, branch and don't change to modecase <55>
|
||
eor.l #(ScaleColor+ColorizeInModeCase),d0 ;clear scale color; set modecase color <55>
|
||
|
||
@ScaleOptimizationDone
|
||
;
|
||
; Use stretch if a search proc is installed <2May90 KON>
|
||
;
|
||
move.l ([theGDevice]),A0 ; get a pointer to the device
|
||
tst.l GDSearchProc(A0) ; check the head of the search chain
|
||
beq @CheckSwapping ; no search proc: go on
|
||
bset.l #UseStretchBit,d0 ; force stretch
|
||
|
||
;
|
||
; if modecase colorizing, search proc is installed, and direct use unmapped fg and bg colors
|
||
;
|
||
cmp.w #4,d4 ; destination direct?
|
||
blt @CheckSwapping ; nope.
|
||
btst.l #ColorizeInModeCaseBit,d0
|
||
beq @CheckSwapping ; not modecase: go on
|
||
|
||
;
|
||
; This code reintroduced from version 54 for CubeE.
|
||
;
|
||
|
||
if CubeE then ; <56>
|
||
move.l ([theGDevice]),a0 ; <56> get a pointer to the device
|
||
tst.l GDSearchProc(A0) ; <56> check the head of the search chain
|
||
beq @CheckSwapping ; <56> no search proc: go on
|
||
endif ; <56>
|
||
|
||
;
|
||
; fcolor and bcolor were mapped using search proc by colormap. We want to use
|
||
; the unmapped versions.
|
||
;
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
PEA RGBBgColor(a6)
|
||
|
||
move.w d0,XLateFlag(a6) ;save translation flags <KON 5MAR91>
|
||
_GetBackColor ;get bg color for colorizing
|
||
_GetForeColor
|
||
move.w XLateFlag(a6),d0 ;restore translation flags <KON 5MAR91>
|
||
|
||
cmp.w #4,d4 ; 16-Bit?
|
||
beq.s @Do16Bit ;
|
||
;
|
||
; Convert RGB colors to 32-bit colors for foreground
|
||
;
|
||
moveq #0,d1
|
||
move.b RGBFrColor(a6),d1 ;red
|
||
swap d1
|
||
move.b RGBFrColor+2(a6),d1 ;green
|
||
lsl #8,d1
|
||
move.b RGBFrColor+4(a6),d1 ;blue
|
||
move.l d1,fcolor(a6)
|
||
|
||
moveq #0,d1 ;do background
|
||
move.b RGBBgColor(a6),d1 ;red
|
||
swap d1
|
||
move.b RGBBgColor+2(a6),d1 ;green
|
||
lsl #8,d1
|
||
move.b RGBBgColor+4(a6),d1 ;blue
|
||
move.l d1,bcolor(a6)
|
||
bra.s @CheckSwapping
|
||
@Do16Bit
|
||
;
|
||
; Convert RGB colors to 32-bit colors for background
|
||
;
|
||
moveq #0,d1
|
||
move.b RGBFrColor(a6),d1 ;red
|
||
lsl #5,d1 ; rrrrrrrr00000
|
||
move.b RGBFrColor+2(a6),d1 ;green rrrrrgggggggg
|
||
lsl.l #5,d1 ; rrrrrgggggggg00000 <KON 5MAR91>
|
||
move.b RGBFrColor+4(a6),d1 ;blue rrrrrgggggbbbbbbbb
|
||
lsr.l #3,d1 ; 000rrrrrgggggbbbbb <KON 5MAR91>
|
||
move.w d1,fcolor(a6)
|
||
move.w d1,fcolor+2(a6)
|
||
|
||
moveq #0,d1
|
||
move.b RGBBgColor(a6),d1 ;red
|
||
lsl #5,d1
|
||
move.b RGBBgColor+2(a6),d1 ;green
|
||
lsl.l #5,d1 ; <KON 5MAR91>
|
||
move.b RGBBgColor+4(a6),d1 ;blue
|
||
lsr.l #3,d1 ; <KON 5MAR91>
|
||
move.w d1,bcolor(a6)
|
||
move.w d1,bcolor+2(a6)
|
||
|
||
@CheckSwapping
|
||
|
||
btst.l #SwapFGBGBit,d0 ;swap fg/bg colors?
|
||
beq.s swapdone
|
||
swapfgbk
|
||
move.l fcolor(a6),d1 ;swap fg/bk color
|
||
move.l bcolor(a6),fcolor(a6)
|
||
move.l d1,bcolor(a6)
|
||
swapdone
|
||
|
||
|
||
;------------------------------------------------------------------------------
|
||
; Check if colorizing is a NOP. If it is, clear the colorize bits.
|
||
; There are three cases: ModeCase, ScaleCase, and SrcBuf colorizing
|
||
;
|
||
; SrcBuf and ScaleCase colorizing is a NOP IF
|
||
;
|
||
; for 1-bit sources:
|
||
; fcolor = $FFFFFFFF and bcolor = 0
|
||
;
|
||
; for deep sources:
|
||
; RGBFrColor = 0 and RGBBgColor = $00FFFFFF (32-bit)
|
||
; or RGBBgColor = $7FFF7FFF (16-bit)
|
||
;
|
||
; ModeCase colorizing is NOP if bcolor=0 and fcolor=NOPfgColorTable
|
||
;
|
||
; If ModeCase or ScaleCase colorizing, check for NOP
|
||
;
|
||
btst.l #ColorizeInModeCaseBit,d0
|
||
beq @CheckColorizeInSrcBuf ;branch if SrcBuf or ScaleCase colorizing
|
||
;
|
||
; Do ModeCase NOP check
|
||
;
|
||
move.l bcolor(a6),d1 ;is bg color a NOP ($00000000)?
|
||
bne @CheckColorizeNOPDone ;bk not a NOP, go slow
|
||
move.l fcolor(a6),d1 ;is fg color a NOP?
|
||
lea NOPfgColorTable,a0
|
||
cmp.l (a0,d4*4),d1
|
||
bne @CheckColorizeNOPDone ;no, it's not a NOP
|
||
;
|
||
; It's a NOP, clear colorize bits
|
||
;
|
||
and.w #~(ColorizeInModeCase),d0 ;turn off modecase colorizing
|
||
bra @CheckColorizeNOPDone
|
||
|
||
@CheckColorizeInSrcBuf
|
||
;
|
||
; Check SrcBuf or ScaleCase colorizing
|
||
;
|
||
; if src is indexed and destination indexed:
|
||
; NOP if fcolor = $FFFFFFFF and bcolor = 0
|
||
; if src is indexed and destination is direct:
|
||
; NOP if fcolor = 0 and bcolor = $00FFFFFF (32-bit)
|
||
; bcolor = $7FFF7FFF (16-bit)
|
||
;
|
||
; Get fg and bg color in RGB space if colorizing at srcbuf, since our source is
|
||
; still in RGB space at that time.
|
||
;
|
||
; D3 contains src pixel depth.
|
||
; D4 contains dst pixel depth.
|
||
;
|
||
cmp.w #4,d3 ;deep src?
|
||
bge.s @DeepSrc
|
||
cmp.w #4,d4 ;dst indexed?
|
||
bge.s @DoDirectNOPCheck
|
||
tst.l bcolor(a6) ;bcolor a NOP?
|
||
bne @CheckColorizeNOPDone
|
||
move.l fcolor(a6),d1 ;fcolor a NOP?
|
||
addq.l #1,d1
|
||
bne @CheckColorizeNOPDone
|
||
bra.s @ClearColorizeBits ;it's a NOP, clear the colorize bits
|
||
@DoDirectNOPCheck
|
||
tst.l fcolor(a6)
|
||
bne @CheckColorizeNOPDone ;fcolor not a NOP for direct device
|
||
move.l bcolor(a6),d1 ;is fg color a NOP?
|
||
lea NOPfgColorTable,a0
|
||
cmp.l (a0,d4*4),d1
|
||
bne @CheckColorizeNOPDone
|
||
bra.s @ClearColorizeBits ;it's a NOP, clear the colorize bits
|
||
@DeepSrc
|
||
|
||
;
|
||
; if swapfgbgBit is set, we need to swap RGB fg/bg color
|
||
;
|
||
move.w d0,XLateFlag(a6) ;save translation flags
|
||
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
|
||
beq.s @DontSwap ;don't invert
|
||
|
||
PEA RGBBgColor(a6)
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
bra.s @SwapDone
|
||
@DontSwap
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
PEA RGBBgColor(a6)
|
||
@SwapDone
|
||
_GetBackColor ;get bg color for colorizing
|
||
_GetForeColor
|
||
;
|
||
; convert 16-16-16 to 8-8-8 for 32-bit src (D3=5)
|
||
;
|
||
cmp.w #4,d3 ;16-bit src?
|
||
beq.s @ConvertTo555 ;yes, convert to 555
|
||
|
||
move.l RGBBgColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBBgColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBBgColor(a6)
|
||
|
||
move.l RGBFrColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBFrColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBFrColor(a6)
|
||
|
||
move.w XLateFlag(a6),d0 ;get translation flags
|
||
;
|
||
; if RGBFrColor and RGBBgColor are white and black, colorizing is a nop so clear
|
||
; ColorizeInSrcBufBit. This is backwards from normal since it is a direct device.
|
||
;
|
||
tst.l RGBFrColor(a6) ;is Fr color black, ie a NOP for colorizing?
|
||
bne.s @CheckColorizeNOPDone ;no, colorizing is not a nop
|
||
cmp.l #$00FFFFFF,RGBBgColor(a6) ;is bg color white ($00FFFFFF) (a NOP)
|
||
bne.s @CheckColorizeNOPDone
|
||
|
||
@ClearColorizeBits
|
||
and.w #~(ColorizeInSrcBuf+ScaleColor),d0 ;turn off SrcBuf and scale case colorizing
|
||
bra.s @CheckColorizeNOPDone
|
||
|
||
;
|
||
; convert 16-16-16 to 5-5-5 for 16-bit src (D3=4)
|
||
;
|
||
@ConvertTo555
|
||
moveq #0,d0 ;clear alpha
|
||
move.w RGBBgColor(a6),d0 ;get RRRR
|
||
lsl.l #5,d0 ;put correct red in high word
|
||
move.w RGBBgColor+2(a6),d0 ;get GGGG
|
||
lsl.l #5,d0 ;put correct green in high word
|
||
move.w RGBBgColor+4(a6),d0 ;get BBBB
|
||
lsl.l #5,d0 ;put correct blue in high word
|
||
swap d0
|
||
move.w d0,RGBBgColor(a6)
|
||
move.w d0,RGBBgColor+2(a6)
|
||
|
||
moveq #0,d0 ;clear alpha
|
||
move.w RGBFrColor(a6),d0 ;get RRRR
|
||
lsl.l #5,d0 ;put correct red in high word
|
||
move.w RGBFrColor+2(a6),d0 ;get GGGG
|
||
lsl.l #5,d0 ;put correct green in high word
|
||
move.w RGBFrColor+4(a6),d0 ;get BBBB
|
||
lsl.l #5,d0 ;put correct blue in high word
|
||
swap d0
|
||
move.w d0,RGBFrColor(a6)
|
||
move.w d0,RGBFrColor+2(a6)
|
||
|
||
;
|
||
; if RGBFrColor and RGBBgColor are white and black, colorizing is a nop so clear
|
||
; ColorizeInSrcBufBit. This is backwards from normal since it is a direct device.
|
||
;
|
||
move.w XLateFlag(a6),d0 ;save translation flags
|
||
tst.l RGBFrColor(a6) ;is Fg color black, ie a NOP for colorizing?
|
||
bne.s @CheckColorizeNOPDone ;no, colorizing is not a nop
|
||
cmp.l #$7FFF7FFF,RGBBgColor(a6) ;is bg color white ($00FFFFFF) (a NOP)
|
||
|
||
if CubeE or TheFuture then ; appease the assembler gods <62>
|
||
bne.s @CheckColorizeNOPDone
|
||
endif ; <62>
|
||
|
||
and.w #~(ColorizeInSrcBuf+ScaleColor),d0 ;turn off SrcBuf and scale case colorizing
|
||
|
||
@CheckColorizeNOPDone
|
||
move.w d0,XLateFlag(a6) ;save translation flags
|
||
btst #InvertItBit,XLateFlag+1(a6) ;TEST INVERT BIT
|
||
SNE D7 ;set byte flag in d7
|
||
EXTB.L D7 ;INVERTED; D7 GETS ALL 1'S
|
||
LEA NOPfgColorTable,A0 ;get address of white table <42>
|
||
AND.L 0(A0,D4.W*4),D7 ;remove alpha byte/bit from mask <42>
|
||
MOVE.L D7,INVERTFLAG(A6) ;SAVE INVERT FLAG
|
||
BRA.S NOTPAT ;=>NO, USE SOURCE INSTEAD
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; PATTERN WILL BE USED. EXPAND PATTERN TO THE CURRENT DEPTH.
|
||
;
|
||
DoPattern
|
||
MOVEQ #0,D7 ;if mode is arithmetic, use 0 for <SMC 18SEP90>
|
||
BTST #5,D2 ; the ivert flag and skip bit 2 clear <SMC 18SEP90>
|
||
BNE.S @notnot ; <SMC 18SEP90>
|
||
BCLR #2,D2 ;TEST AND CLR INVERT BIT
|
||
SNE D7 ;set byte flag in d7
|
||
EXTB.L D7 ;INVERTED; D7 GETS ALL 1'S
|
||
@notnot MOVE.L D7,INVERTFLAG(A6) ;SAVE INVERT FLAG <SMC 18SEP90>
|
||
; move.w d2,locMode(a6) ;store for modecase, BitBlt, RgnBlt
|
||
|
||
_PATEXPAND ;EXPAND PATTERN
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; HIDE THE CURSOR IF TO THE SCREEN AND INTERSECTS MINRECT
|
||
; (A5 must contain global ptr)
|
||
;
|
||
NOTPAT
|
||
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
|
||
BEQ.S NOTSCREEN ;=>NO
|
||
PEA MINRECT(A6) ;PUSH SHIELD RECT
|
||
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
|
||
_SHIELDCURSOR ;REMOVE CURSOR IF INTERSECT
|
||
|
||
NOTSCREEN
|
||
;----------------------------------------------------------------
|
||
;
|
||
; SET UP SRC ROWBYTES, MASK ROWBYTES, AND DST ROWBYTES
|
||
; GET SRCPIX INTO A4 AND DSTPIX INTO A5
|
||
; GET SRCRECT INTO A2 AND DSTRECT INTO A3
|
||
;
|
||
LEA SRCPIX(A6),A4 ;POINT TO SRCPIX
|
||
MOVE #nuRBMask,D0 ;GET MASK FOR ROWBYTE FLAGS
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE ROWBYTES(A4),D1 ;GET SRC ROWBYTES
|
||
AND.L D0,D1 ;CLEAR OUT FLAG BITS
|
||
MOVE.L D1,SRCROW(A6) ;SRCROW := SRC ROWBYTES
|
||
|
||
@1 LEA MASKPIX(A6),A0 ;POINT TO MASKPIX
|
||
MOVE ROWBYTES(A0),D1 ;GET DST ROWBYTES
|
||
AND.L D0,D1 ;CLEAR OUT FLAG BITS
|
||
MOVE.L D1,MASKROW(A6) ;MASKROW := MASK ROWBYTES
|
||
|
||
LEA DSTPIX(A6),A5 ;POINT TO DSTPIX
|
||
MOVE ROWBYTES(A5),D1 ;GET DST ROWBYTES
|
||
AND.L D0,D1 ;CLEAR OUT FLAG BITS
|
||
MOVE.L D1,DSTROW(A6) ;DSTROW := DST ROWBYTES
|
||
|
||
MOVE.L srcRect(a6),a2 ;get srcRect 24 bit ptr @@@@ BAL 12Jan89
|
||
MOVE.L a2,d0 ;get srcRect ptr @@@@ BAL 09Apr88
|
||
_rTranslate24To32
|
||
move.l d0,srcRect(a6) ;save 32 bit ptr @@@@ BAL 07Jul88
|
||
MOVE.L dstRect(a6),a3 ;get dstRect 24 bit ptr @@@@ BAL 12Jan89
|
||
MOVE.L a3,d0 ;get dstRect ptr @@@@ BAL 09Apr88
|
||
_rTranslate24To32
|
||
move.l d0,dstRect(a6) ;save 32 bit ptr @@@@ BAL 07Jul88
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; IF PATTERN MODE, GO DECIDE BETWEEN RGNBLT AND BITBLT
|
||
;
|
||
MOVE LOCMODE(A6),D0 ;GET MODE
|
||
ROR #4,D0 ;IS PATTERN BIT SET ?
|
||
BCS NOTSTR ;=>YES, DON'T USE STRETCH
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALC NUMER AND DENOM BASED ON DSTRECT AND SRCRECT.
|
||
; IF NUMER = DENOM AND SRC DEPTH = DST DEPTH THEN JUST CALL RGNBLT.
|
||
;
|
||
MOVE BOTTOM(A2),D1
|
||
SUB TOP(A2),D1 ;CALC SRC HEIGHT
|
||
SWAP D1 ;PUT IN HI WORD
|
||
MOVE RIGHT(A2),D1
|
||
SUB LEFT(A2),D1 ;CALC SRC WIDTH
|
||
MOVE D1,D0 ;COPY SRC PIXCNT
|
||
SUBQ #1,D0 ;MAKE IT 0 BASED
|
||
MOVE D0,SRCPIXCNT(A6) ;SAVE SRC PIXEL COUNT
|
||
|
||
MOVE BOTTOM(A3),D0
|
||
SUB TOP(A3),D0 ;CALC DST HEIGHT
|
||
SWAP D0 ;PUT IN HI WORD
|
||
MOVE RIGHT(A3),D0
|
||
SUB LEFT(A3),D0 ;CALC DST WIDTH
|
||
|
||
_BlitCase ;Go determine blit style
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; Determine whether to use Stretch, Scale, Rgn, or Bit Bliting
|
||
;
|
||
BlitCase
|
||
; clr.b FastCase(a6) ;assume not a fun case <14SEP90 SMC>
|
||
|
||
TST.L MASKBITS(A6) ;*** IS THERE A MASK?
|
||
BNE STRETCH ;=>YES, USE STRETCH FOR NOW
|
||
|
||
CMP.L D0,D1 ;ARE SRC AND DST THE SAME SIZE
|
||
BNE STRETCH ;=>NO, STRETCH THE BITS
|
||
;
|
||
; Use stretch if UseStretchBit or ColorizeInSrcBufBit is set
|
||
;
|
||
move.w XLateFlag(a6),d2
|
||
and.w #~(UseStretch+ColorizeInSrcBuf),d2 ;use stretch? <05JUNE92 SAH>
|
||
cmp.w XLateFlag(a6),d2
|
||
bne Stretch
|
||
|
||
;
|
||
; Use ScaleBlt if ScaleColorBit is set <05JUNE92 SAH>
|
||
;
|
||
btst #ScaleColorBit,XlateFlag+1(a6)
|
||
bne xScaleBlt
|
||
|
||
CMP D3,D4 ;ARE THE DEPTHS THE SAME?
|
||
bne xScaleBlt ;=>no, use ScaleBlt
|
||
|
||
;
|
||
; source and destination are the same depth, check if color table seeds are the same
|
||
;
|
||
cmp #16,dstpix+pixelType(a6) ;is it a direct device?
|
||
beq.s notstr ;yes, don't check seeds
|
||
|
||
MOVE.L SRCPIX+PMTABLE(A6),d2 ;GET SRC COLOR TABLE HANDLE <BAL>
|
||
beq XScaleBLT ;nil table so must remap colors <BAL>
|
||
move.l d2,a0 ;get handle for deref <BAL>
|
||
|
||
MOVE.L (A0),A0 ;POINT TO IT
|
||
MOVE.L CTSEED(A0),D2 ;GET SEED
|
||
MOVE.L DSTPIX+PMTABLE(A6),A0 ;GET DST COLOR TABLE HANDLE
|
||
MOVE.L (A0),A0 ;POINT TO IT
|
||
CMP.L CTSEED(A0),D2 ;DO THE SEEDS MATCH?
|
||
BNE xScaleBlt ;=>NO, use scaleBlt
|
||
|
||
NOTSTR
|
||
;----------------------------------------------------------------
|
||
;
|
||
; NOW DECIDE BETWEEN BITBLT AND RGNBLT
|
||
;
|
||
; ARE ALL THREE REGIONS RECTANGULAR ? IF SO, USE BITBLT.
|
||
;
|
||
; If the visRgn or the clipRgn is non-rectangular then call TrimRect
|
||
; to see if the intersection of the region and MinRect is rectangular,
|
||
; empty, or regional. <C951> 08Nov87 BAL
|
||
;
|
||
|
||
; <45> If going to a direct device in an arithmetic mode, force into rgnblt. Those
|
||
; blit loops are effectively as fast as the ones in bitblt through their use of
|
||
; runmasking. This change allows those cases to be stripped out of bitblt.
|
||
;
|
||
CMP #4,D4 ;direct device?
|
||
BLT @noforce ;no, do normal checks
|
||
MOVE.W locMode(A6),D0 ;get penmode
|
||
BTST #5,D0 ;arithmetic?
|
||
BNE XRGNBLT ;yes, force into rgnblt
|
||
@noforce
|
||
|
||
MOVEQ #10,D0 ;GET SIZE OF RECT RGN
|
||
MOVE.L RGNC(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
CMP RGNSIZE(A0),D0 ;IS RGNC RECTANGULAR ?
|
||
BNE XRGNBLT ;=>NO, USE RGNBLT
|
||
|
||
@chkVis MOVE.L RGNB(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
CMP RGNSIZE(A0),D0 ;IS visRgn RECTANGULAR ? <C951>
|
||
BEQ.S @chkClip ;=>yes, go check clipRgn <C951>
|
||
|
||
MOVE.L RGNB(A6),-(SP) ;PUSH visRgn HANDLE <C951>
|
||
PEA MINRECT(A6) ;PUSH ADDR OF MINRECT
|
||
MOVE.W #-1,-(SP) ;pass Trim = True
|
||
_TRIMRECT ;CALL TRIMRECT
|
||
BLT DONE ;=>INTERSECTION EMPTY, QUIT & SHOW CURSOR
|
||
BGT XRGNBLT ;=>USE RGNBLT
|
||
|
||
; In case we fall into RgnBlt, replace visRgn with WideOpen
|
||
; so that TrimRect doesn't get called again by seekMask.
|
||
|
||
MOVE.L SAVEA5(A6),A1 ;Get global ptr <BAL 26Sep88>
|
||
MOVE.L GRAFGLOBALS(A1),A1 ;point to QD globals <BAL 26Sep88>
|
||
MOVE.L WIDEOPEN(A1),RGNB(A6) ;replace visRgn with wideOpen <BAL 26Sep88>
|
||
|
||
@chkClip
|
||
MOVE.L RGNA(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
CMP RGNSIZE(A0),D0 ;IS clipRgn RECTANGULAR ?
|
||
BEQ XBITBLT ;=>YES, GO USE BITBLT
|
||
|
||
MOVE.L RGNA(A6),-(SP) ;PUSH clipRgn HANDLE <C951>
|
||
PEA MINRECT(A6) ;PUSH ADDR OF MINRECT <C951>
|
||
MOVE.W #-1,-(SP) ;pass Trim = True
|
||
_TRIMRECT ;CALL TRIMRECT <C951>
|
||
BLT DONE ;=>INTERSECTION EMPTY, QUIT & SHOW CURSOR
|
||
BEQ XBITBLT ;=>USE BITBLT
|
||
|
||
; Since we will fall into RgnBlt, swap the clipRgn and the userRgn
|
||
; so that TrimRect doesn't get called again by seekMask.
|
||
|
||
MOVE.L RGNA(A6),A1 ;copy clipRgn <BAL 26Sep88>
|
||
MOVE.L RGNC(A6),RGNA(A6) ;replace clipRgn with userRgn <BAL 26Sep88>
|
||
MOVE.L A1,RGNC(A6) ;replace userRgn with clipRgn <BAL 26Sep88>
|
||
BRA XRGNBLT ;=>USE RGNBLT <BAL 26Sep88>
|
||
|
||
|
||
XScaleBLT
|
||
;--------------------------------------------------------------
|
||
;
|
||
; Must do depth scaling but no spatial resizing and no bit mask.
|
||
; Only supports copy and dither modes. No fg/bk colorizing.
|
||
; No search procs supported for direct sources.
|
||
;
|
||
; REGISTER USE:
|
||
;
|
||
; A2: SRCRECT (24 bit addr)
|
||
; A3: DSTRECT (24 bit addr)
|
||
; A4: SRCPIX
|
||
; A5: DSTPIX
|
||
;
|
||
; D3: SRCSHIFT
|
||
; D4: DSTSHIFT
|
||
; D7: INVERT FLAG
|
||
|
||
|
||
tst locMode(a6) ;copy mode?
|
||
bne Stretch ;if not copy mode then use stretch
|
||
|
||
;
|
||
; Use Stretch if an alpha mode is set by looking at the streamMode <23JUN92 SAH>
|
||
;
|
||
; Rather than looking at the stream mode directly here, we should add a call to the alpha
|
||
; routines that returns the alpha mode so that we can localize the code! Do this before it
|
||
; goes into ROM!
|
||
;
|
||
move.l savea5(a6),a0 ;get the real a5
|
||
move.l GrafGlobals(a0),a0 ;get the qd globals
|
||
move.l thePort(a0),a0 ;get the port
|
||
TST portBits+rowBytes(A0) ;is it an old port?
|
||
BPL @noalpha ;yes, alpha mode is illegal
|
||
MOVE.W dstPix+pixelSize(A6),D2 ;get depth of destination
|
||
CMP.W #16,D2 ;direct device?
|
||
BLT.S @noalpha ;no, skip this stuff
|
||
MOVE.L grafVars(A0),D2 ;get grafvars handle
|
||
BEQ @noalpha ;no grafvars, no alpha
|
||
MOVE.L D2,A0 ;copy handle
|
||
MOVE.L (A0),A0 ;dereference handle
|
||
BTST #PmNewGVBit-8,pmFlags(A0) ;make sure grafvars have been expanded
|
||
BEQ.S @noalpha ;if not, bail
|
||
TST.B streamMode(A0) ;is there an alpha mode
|
||
bne Stretch ;yes, so go slow
|
||
|
||
;
|
||
; now look at the actual alpha channel byte/bit to see if it contains zero. If not, we
|
||
; must go slow. This is because a streamMode of zero means that we write to both graphics
|
||
; and alpha. As an optimization, we might be able to just do this check alone for any
|
||
; streamMode so that we can go fast when writing an alpha of zero.
|
||
;
|
||
; For the purposes of Cube-E, this code is remaining as it is below, but it would be wise
|
||
; to make the tests just test memory directly to save code space!
|
||
;
|
||
|
||
MOVE.W dstPix+pixelSize(A6),D2 ;get depth of destination
|
||
cmp.w #16,d2
|
||
beq.s @check16bit
|
||
|
||
;dst is 32 bit
|
||
move.l fcolor(a6),d2
|
||
rol.l #8,d2 ;get the alpha channel in the low byte
|
||
tst.b d2 ;is it non-zero
|
||
bne Stretch ;yes, so go slow
|
||
move.l bcolor(a6),d2
|
||
rol.l #8,d2 ;get the alpha channel in the low byte
|
||
tst.b d2 ;is it non-zero
|
||
bne Stretch ;yes, so go slow
|
||
bra.s @noalpha ;ok, we can go fast!
|
||
@check16bit
|
||
|
||
;dst is 16 bit
|
||
move.l fcolor(a6),d2
|
||
btst #15,d2 ;is the alpha bit zero?
|
||
bne Stretch ;yes, so go slow
|
||
move.l bcolor(a6),d2
|
||
btst #15,d2 ;is the alpha bit zero?
|
||
bne Stretch ;yes, so go slow
|
||
@noalpha
|
||
|
||
;
|
||
; if colorize in modecase or srcbuf flag is set, use stretch
|
||
;
|
||
|
||
move.w XlateFlag(a6),d2
|
||
and.w #~(ColorizeinSrcBuf+ColorizeInModeCase),d2
|
||
cmp.w XlateFlag(a6),d2
|
||
bne.s @toStretch ;if applying color then use stretch
|
||
|
||
tst.w d7 ;invert the src?
|
||
bne.s @toStretch ;if so then use stretch
|
||
; st FastCase(a6) ;remember fastCase for Andy <14SEP90 SMC>
|
||
|
||
cmp.w #4,d4 ;dst < 16 bits/pixel? <05JUNE92 SAH>
|
||
blt.s @chkSrc ; <05JUNE92 SAH>
|
||
cmp.w #3,d3 ;src <16 bits/pixel?
|
||
bgt.s @toStretch
|
||
|
||
@fast
|
||
move.l stNoStackPtr,goShow(a6) ;pass go home routine
|
||
_ScaleBlt ;CALL scaleBlt
|
||
tst d0 ;did it handle it?
|
||
bne DONE ;RESTORE CURSOR AND QUIT
|
||
;
|
||
; ScaleBlt didn't handle it, so we need to make sure that if the depths
|
||
; are one bit and ScaleColor is set, we set ColorizeInModeCase so that
|
||
; BitBlt or RgnBlt colorizes
|
||
;
|
||
|
||
btst #ScaleColorBit,XlateFlag+1(a6)
|
||
beq.s notStr ;go ahead and use BitBlt
|
||
eor.w #(ScaleColor+ColorizeInModeCase),XlateFlag(a6)
|
||
BRA.s notStr
|
||
|
||
@chkSrc
|
||
cmp.w #5,d3 ;src 32 bits/pixel?
|
||
bne.s @more ;(was Stretch) <14SEP90 SMC>
|
||
cmp.w #3,d4 ;dst = 8 bits/pixel?
|
||
bne.s Stretch
|
||
bra.s @fast
|
||
|
||
@more cmp.w #4,d3 ;src 16 bits?
|
||
beq.s Stretch ;yes, dont do it here
|
||
bra.s @fast
|
||
@toStretch
|
||
BRA.S Stretch ;end of <14SEP90 SMC>
|
||
|
||
|
||
XBITBLT
|
||
;--------------------------------------------------------------
|
||
;
|
||
; SINCE ALL THREE REGIONS ARE RECTANGULAR, WE WILL USE BITBLT.
|
||
;
|
||
; REGISTER USE:
|
||
;
|
||
; A2: SRCRECT (32 bit addr)
|
||
; A3: DSTRECT (32 bit addr)
|
||
; A4: SRCPIX
|
||
; A5: DSTPIX
|
||
;
|
||
; D3: SRCSHIFT
|
||
; D4: DSTSHIFT
|
||
; D7: INVERT FLAG
|
||
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.b d0,MMUsave(a6) ;save previous state for later
|
||
move.l srcRect(A6),a2 ;reload srcRect 32 bit ptr
|
||
move.l dstRect(A6),a3 ;reload dstRect 32 bit ptr
|
||
_BITBLT ;CALL BITBLT
|
||
BRA DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALL RGNBLT WITH ALL SHARED LOCAL VARS SET UP AND REGS LIKE THIS:
|
||
;
|
||
; A2: SRCRECT (24 bit addr)
|
||
; A3: DSTRECT (24 bit addr)
|
||
; A4: SRCPIX
|
||
; A5: DSTPIX
|
||
;
|
||
; D3: SRCSHIFT
|
||
; D4: DSTSHIFT
|
||
; D7: INVERT FLAG
|
||
|
||
|
||
XRGNBLT
|
||
move.l stNoStackPtr,goShow(a6) ;pass go home routine to getSeek <BAL 21Mar89>
|
||
_StackAvail ;GET STACK AVAIL IN D0.L
|
||
LSR.L #2,D0 ;CONVERT BYTES TO LONGS
|
||
SUB.L #qdStackXtra/4,D0 ;SUBTRACT SLOP FACTOR <1.5> BAL
|
||
MOVE.L D0,STACKFREE(A6) ;AND SAVE FREE LONGS ON STACK
|
||
_RGNBLT ;CALL RGNBLT
|
||
BRA DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
STRETCH
|
||
;
|
||
; if not shrinking and source is 1-bit b&w, clear dither flag <24Sept90 KON>
|
||
;
|
||
cmp.l d0,d1 ;src, dst same size? <24Sept90 KON>
|
||
bne.s @dontClearDither ;branch if no <24Sept90 KON>
|
||
move.l srcpix+pmtable(a6),d2 ;get source color table handle <24Sept90 KON>
|
||
beq.s @dontClearDither ;nil table: not 1-bit <24Sept90 KON>
|
||
move.l d2,a0 ;get handle for deref <24Sept90 KON>
|
||
move.l (a0),a0 ;point to it <24Sept90 KON>
|
||
moveq #1,d2 ; <24Sept90 KON>
|
||
cmp.l ctseed(a0),d2 ;one-bit b&w? <24Sept90 KON>
|
||
bne.s @dontClearDither ; <24Sept90 KON>
|
||
clr.b useDither(a6) ;don't promote source to 32-bits <24Sept90 KON>
|
||
|
||
@dontClearDither
|
||
;----------------------------------------------------------------
|
||
;
|
||
; (If dither flag or mask is deep) AND source is indexed data then
|
||
; pretend the source is 32 bit/pixel RGB data and remember
|
||
; real depth/srcShift for later.
|
||
;
|
||
move.w d3,realSrcShift(a6) ;make it real anyway
|
||
st realDepth(a6) ;assume not promoting source to RGB
|
||
cmp.w #16,srcPix+pixelType(a6) ;is src direct?
|
||
beq @dontUseRGB ;yes, leave source depth alone
|
||
tst.b useDither(a6) ;is the dither bit set?
|
||
bne.s @UseRGB ;yes, promote source depth
|
||
move maskshift(a6),d2
|
||
beq.s @dontUseRGB
|
||
|
||
@UseRGB
|
||
move.w #16,srcPix+pixelType(a6) ;pretend direct data
|
||
move.w srcPix+pixelSize(a6),realDepth(a6)
|
||
move.w #32,srcPix+pixelSize(a6) ;pretend 32 bits/pixel
|
||
moveq #5,d3 ;reset src shift
|
||
move.w d3,srcShift(a6)
|
||
;
|
||
; if scalecase colorizing was used, change to srcbuf colorizing since the scale table
|
||
; is not used when the src is 32-bits. <12NOV90 KON>
|
||
;
|
||
bclr #ScaleColorBit,XLateFlag+1(a6) ;Colorize in scale table?
|
||
beq.s @NoColorizing ;no, we're cool
|
||
;
|
||
; colorizing -> change to srcbuf colorizing and setup RGBFrColor and RGBBgColor
|
||
;
|
||
bset #ColorizeInSrcBufBit,XLateFlag(a6) ;colorize at srcbuf time
|
||
|
||
movem.l A5/D0/D1,-(SP) ;Need to preserve a5, d0, and d1
|
||
move.l SAVEA5(A6),A5 ;restore 15 for GetFore and GetBack color calls
|
||
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
|
||
beq.s @DontSwap ;don't invert
|
||
|
||
PEA RGBBgColor(a6)
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
bra.s @SwapDone
|
||
@DontSwap
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
PEA RGBBgColor(a6)
|
||
@SwapDone
|
||
_GetBackColor ;get bg color for colorizing
|
||
_GetForeColor
|
||
;
|
||
; convert 16-16-16 to 8-8-8 for 32-bit src (D3=5)
|
||
;
|
||
move.l RGBBgColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBBgColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBBgColor(a6)
|
||
|
||
move.l RGBFrColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBFrColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBFrColor(a6)
|
||
movem.l (SP)+,a5/D0/D1 ;Restore a5,d0, and d1
|
||
|
||
@NoColorizing
|
||
@dontUseRGB
|
||
|
||
;-----------------------------------------------------------------------
|
||
; Change source pixel size to 32 bits if deep mask and src is 16-bit
|
||
;
|
||
cmp #4,d3 ;is it 16 bit?
|
||
bne.s KON
|
||
tst.w maskshift(a6)
|
||
beq.s KON
|
||
moveq #5,d3
|
||
KON
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; USE SRC AND DST SIZES TO DETERMINE STRETCHING ROUTINE
|
||
;
|
||
MOVE.L D0,NUMER(A6) ;NUMER := DST SIZE
|
||
MOVE.L D1,DENOM(A6) ;DENOM := SRC SIZE
|
||
MOVEM.L D3/D4,-(SP) ;SAVE D3/D4
|
||
|
||
_SetupStretch ;CALC CASEJUMP AND HORIZ FRACT (CLOBBER D3,D4)
|
||
MOVE.L A0,RATIOCASE(A6) ;SAVE CASE JUMP FOR LATER
|
||
MOVE D0,HORIZFRACTION(A6) ;SAVE FRACTION FOR LATER
|
||
MOVEM.L (SP)+,D3/D4 ;RESTORE D3/D4
|
||
|
||
clr.l SrcPixPmTable(a6) ; <KON 13DEC90>
|
||
MOVE.L SRCPIX+PMTABLE(A6),d0 ;GET SRC COLOR TABLE HANDLE <2Sep90 KON>
|
||
beq.s @BAL ;table not nil so continue <2Sep90 KON>
|
||
MOVE.L d0,a0
|
||
MOVE.L (A0),d0 ;POINT TO IT <2Sep90 KON>
|
||
_rTranslate24To32 ;clean master pointer <20AUG90 KON and BAL>
|
||
move.l d0,SrcPixPmTable(a6) ; <20AUG90 KON and BAL>
|
||
@BAL
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; DETERMINE AMOUNT OF STACK SPACE WE CAN USE
|
||
; Raised amount left for interupts from 1024 to 1600 bytes <BAL 10Apr89>
|
||
;
|
||
_StackAvail ;GET STACK AVAIL IN D0.L
|
||
LSR.L #2,D0 ;CONVERT BYTES TO LONGS
|
||
SUB.L #qdStackXtra/4,D0 ;SUBTRACT SLOP FACTOR <1.5> BAL
|
||
MOVE.L D0,STACKFREE(A6) ;AND SAVE FREE LONGS ON STACK
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; Check to see if we are shrinking 16 or 32 bit source data OR if we are
|
||
; shrinking a deep mask. If we are, allocate a buffer for the larger of the
|
||
; two. *** Currently assuming source and mask are the same size ***
|
||
;
|
||
clr.b useAverage(a6) ;assume not averaging
|
||
move.w numer+v(A6),D0 ; get destination height
|
||
move.w denom+v(A6),D1 ; get source height
|
||
cmp.w d1,d0 ;is source larger than dest?
|
||
bge.s @noAvrg ;NO=> don't average
|
||
|
||
;yes, so average if 32 bit/pixel or deep mask
|
||
|
||
cmp.w #4,d3 ;is src indexed? <KON 2/22/90>
|
||
blt.s @noAvrg ;yes, skip averaging <KON 2/22/90>
|
||
@shrink
|
||
sge useAverage(a6) ;always average if 16 or 32bit src <KON 2/22/90>
|
||
moveq #0,d1
|
||
move.w denom+h(a6),d1 ;src width
|
||
move.l d1,d2 ;make a copy src width <16Feb90 KON and BAL>
|
||
add.l d2,d2 ;6 bytes (R.w,G.w,B.w) per pixel <BAL and KON 14Feb90>
|
||
add.l d1,d2 ;d2 is byte cnt/2 of AvrgBuf <BAL and KON 14Feb90>
|
||
;
|
||
; allocate the larger of source buffer or mask buffer
|
||
;
|
||
cmp.w #4,maskshift(a6) ;mask 16-bit data?
|
||
beq.s @DoWords ;yes, allocate twice the error buffer
|
||
; cmp.w #4,d3 ;source 16-bit data? <KON 2/22/90>
|
||
cmp.w #4,realSrcShift(a6) ;source 16-bit data (check real source)? <KON 3/18/91>
|
||
beq.s @DoWords ;Twice as many pixels, allocate twice the error buffer <KON 2/22/90>
|
||
lsr.l #1,d2 ;both 32-bit, 1/2 as many pixels
|
||
@DoWords
|
||
move.w d2,ABufSize(a6) ;save long cnt for later
|
||
SUB.L D2,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK2
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK2
|
||
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
@ClrBuf CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D2,@ClrBuf ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,AvrgBuf(A6) ;REMEMBER WHERE AvrgBuf IS
|
||
|
||
@noAvrg
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; if dstPix is direct and we aren't averaging then no
|
||
; reason to promote source to RGB, unless using deep mask.
|
||
;
|
||
tst.b realDepth(a6) ;promoting src to RGB?
|
||
bmi.s @LeaveItAlone ;no, all ok
|
||
cmp.w #16,dstPix+pixelType(a6) ;is dst direct data?
|
||
bne.s @LeaveItAlone ;no, we will be dithering
|
||
tst.b useAverage(a6) ;are we averaging
|
||
bne.s @LeaveItAlone ;yes, promote source
|
||
tst.w maskshift(a6) ;deep mask?
|
||
bne.s @LeaveItAlone ;yes: promote
|
||
;
|
||
;no, don't promote source
|
||
;
|
||
move.w realDepth(a6),srcPix+pixelSize(a6)
|
||
move.w realSrcShift(a6),d3 ;don't fake 32-bit source
|
||
move.w d3,srcShift(a6) ;remember it for later
|
||
st realDepth(a6) ;don't expand source to 32-bit
|
||
clr.w SRCPIX+pixelType(A6) ;don't fake
|
||
;
|
||
; Change colorizing back to Scalecase colorizing since the scale table
|
||
; is used for indexed sources. <12NOV90 KON>
|
||
;
|
||
bclr #ColorizeInSrcBufBit,XLateFlag(a6) ;colorize at srcbuf time?
|
||
beq.s @NoColorizing ;no, we're cool
|
||
;
|
||
; colorizing -> change back to scalecase colorizing
|
||
;
|
||
bset #ScaleColorBit,XLateFlag+1(a6) ;Colorize in scale table
|
||
|
||
@NoColorizing
|
||
|
||
@LeaveItAlone
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; IF THE SRC AND DST ARE DIFFERENT DEPTHS, THEN MUST DO PIXEL SCALING
|
||
; IF THEY ARE THE SAME DEPTH, BUT DIFFERENT COLOR TABLES, DO PIXEL SCALING
|
||
;
|
||
|
||
CLR.L SCALECASE(A6) ;ASSUME NO PIXEL DEPTH SCALING
|
||
MOVE.W SRCPIX+pixelType(A6),D0 ;IS PIXELTYPE DIRECT? %%%
|
||
BEQ HasClut ;NO, IT HAS A CLUT %%%
|
||
cmp #16,d0 ;is it RGBDirect?
|
||
bne done ;unknown pixeltype -> go home
|
||
|
||
;@@@@ should also check cmpCount, cmpSize
|
||
|
||
MOVE.L ([theGDevice]),A2 ; get the current device (trash A2)
|
||
tst.l gdSearchProc(A2) ; get the search proc head
|
||
bne.s @Slow
|
||
|
||
cmp d3,d4 ;are the depths the same
|
||
beq PIXELOK ;yes, don't depth scale
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; The src is direct data (16 or 32 bits/pixel).
|
||
; Compute D5 as index into direct mode table based on
|
||
;
|
||
; src16 -> add 4
|
||
; dstIndexed -> add 1
|
||
; searchProc -> add 16
|
||
; dithering -> add 2
|
||
; dst16 -> add 2
|
||
; dstAllGray -> add 8
|
||
;
|
||
; D3=srcShift D4=dstShift
|
||
;
|
||
|
||
@Slow
|
||
moveq #4,d0 ; init direct scaleRtn with src=16
|
||
move.l d0,d5
|
||
cmp.w d3,d5 ; is src 16 bits/pixel?
|
||
beq.s @src16
|
||
moveq #0,d5 ; init src to 32 bits/pixel
|
||
@src16
|
||
cmp.w d4,d0 ; is dst 16 bits/pixel?
|
||
bne.s @dst32
|
||
addq #2,d5 ; remember dst is 16 bits/pixel
|
||
@dst32
|
||
|
||
cmp #16,DSTPIX+pixelType(A6) ;IS PIXELTYPE DIRECT? %%%
|
||
beq @noCLUT ;don't makeItable on direct device
|
||
|
||
|
||
; IF THE DST IS AN OLD GRAFPORT AND ONE BIT PER PIXEL, THEN OVERRIDE THE
|
||
; scaleCase FOR PROPER MAPPING
|
||
|
||
TST d4 ;ONE BIT PER PIXEL?
|
||
BNE.S @notBitmap ;=>NO, PROC IS OK
|
||
MOVE.L DSTBITS(A6),A1 ;GET DST BITMAP
|
||
TST ROWBYTES(A1) ;IS IT OLD?
|
||
BMI.S @notBitmap ;=>NO, PROC IS OK
|
||
addq #8,d5 ;force bitmap procs
|
||
bra @chkDither ;go check dither <BAL 28Jan90>
|
||
@notBitmap
|
||
|
||
addq #1,d5 ; remember dst is indexed
|
||
MOVE.L ([GDPMap,A2]),A1 ; get pixMap's handle
|
||
MOVE.L PMTable(A1),A0 ; get the device colorTable's handle
|
||
MOVE.L ([A0],CTSeed),D1 ; get the device colorTable's ctSeed
|
||
MOVE.L ([GDITable,A2]),A0 ; get the Itable's master pointer
|
||
CMP.L ITabSeed(A0),D1 ; has the colortable changed?
|
||
BEQ.S @1 ; if equal, then the iTable is OK
|
||
|
||
; if table is not up to date, build a new one
|
||
|
||
MOVE.L PMTable(A1),-(SP) ; push theGDevice's color table handle <BAL 26May89>
|
||
MOVE.L GDITable(A2),-(SP) ; push theGDevice's current iTabHandle
|
||
MOVE.W GDResPref(A2),-(SP) ; push the preferred iTableResolution
|
||
_MakeITable ; make a new table
|
||
TST.W QDErr ; was this sucessful?
|
||
BEQ.S @noErr ; nope, so quit
|
||
ADDQ #4,SP ; flush saved register
|
||
BRA doneErr ; <BAL 26May89>
|
||
@noErr MOVE.L ([theGDevice]),A2 ; redereference in case it moved <BAL 31Mar89>
|
||
MOVE.L ([GDITable,A2]),A0 ; get the iTable's master pointer
|
||
@1
|
||
ADD.w #ITTable,A0 ; point directly at data
|
||
MOVE.L A0,stITabPtr(A6) ; save in stack frame
|
||
SUB.w #ITTable,A0 ; get the iTable's master pointer
|
||
MOVE.W ITabRes(A0),stITabRes(A6) ; get the iTable resolution
|
||
MOVE.L ([GDPMap,A2]),A1 ; get pixMap's handle
|
||
MOVE.L ([PMTable,A1]),stCLUTPtr(A6) ; get the device colorTable's ptr
|
||
|
||
MOVE.L gdSearchProc(A2),D0 ; get the search proc head
|
||
bne.s @search ; go use search routines
|
||
|
||
|
||
; Here we know that the dst is indexed and no search proc is present,
|
||
; so determine if the dst clut is all grays and/or we are dithering.
|
||
|
||
; the iTable's master pointer is in A0
|
||
|
||
MOVEQ #1,D0 ; prime the register again
|
||
MOVE ITabRes(A0),D2 ; get the inverse table resolution (and Bit-field width)
|
||
LSL.L D2,D0 ; calculate 2^^res
|
||
LSL.L D2,D0 ; square it
|
||
LSL.L D2,D0 ; cube it
|
||
LEA ITTable(A0,D0.L),A1 ; point us at the ITabInfo
|
||
tst.w iTabFlags(a1) ; is this a grayITab?
|
||
bpl.s @chkDither ; no, go see if dithering
|
||
add.w #ITabInfo,a1 ; point past header
|
||
move.l a1,stITabInfo(a6) ; save for later
|
||
addq #8,d5 ; remember to use gray routines
|
||
|
||
moveq #40,d0
|
||
cmp.l ITabSeed(a0),d0 ; is dst the standard 8-bit gray clut?
|
||
beq.s @readyProc ; yes, ignore dithering for speeed!
|
||
|
||
@chkDither
|
||
|
||
tst.b useDither(a6) ; should we dither?
|
||
beq.s @readyProc ; no, we're set
|
||
addq #2,d5 ; remember to use dither routines
|
||
|
||
;
|
||
; Compute and allocate scanline buffer for dither error from previous scan <BAL 29Aug88>
|
||
;
|
||
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE NUMER+H(A6),D0 ;GET WIDTH OF DST
|
||
lsl.l d4,d0 ;get bit width
|
||
add.l #31,d0 ;round to long boundary
|
||
lsr.l d4,d0 ;get adjusted pixel width
|
||
btst #3,d5 ;is dst a grayscale clut?
|
||
bne.s @gray ;only need 2 bytes per pixel for gray error <BAL 18Mar89>
|
||
|
||
move.l d0,d1 ;make a copy <BAL and KON 14Feb90>
|
||
ADD.l D0,D0 ;6 bytes (R.w,G.w,B.w) per pixel <BAL and KON 14Feb90>
|
||
add.l d1,d0 ;d0 is byte cnt/2 of ErrBuf <BAL and KON 14Feb90>
|
||
@gray LSR.l #1,D0 ;AND DIV BY 2 FOR LONGS <BAL and KON 14Feb90>
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK3
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK3
|
||
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
@ClearB CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,@ClearB ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,ErrBUF(A6) ;REMEMBER WHERE ErrBuf IS
|
||
clr.b ErrDir(a6) ;init to carry error to right
|
||
BRA.S @readyProc ; and continue
|
||
|
||
|
||
; Here we know that the dst is direct so check if search proc is present.
|
||
|
||
|
||
@noCLUT
|
||
MOVE.L gdSearchProc(A2),D0 ; get the search proc head
|
||
beq.s @readyProc
|
||
@search
|
||
MOVE.L D0,stSProc(A6) ; put search procs list head in stack frame
|
||
bset #4,d5 ; use search routines
|
||
|
||
|
||
; We have the scaleCase routine selector in D5 so compute address
|
||
; of routine and stuff it in scaleCase for later
|
||
|
||
|
||
@readyProc
|
||
move.w d5,d0 ;copy selector
|
||
lsr.w #3,d0 ;determine table to use
|
||
lea (stColorTabPtr,ZA0,d0*4),A0 ;POINT TO MODE TABLE
|
||
move.l (a0),a0 ;get table
|
||
and.w #7,d5 ;get position in this table
|
||
add.l 0(A0,D5*4),A0 ;GET CASE JUMP ADDRESS
|
||
MOVE.L A0,scaleCase(A6) ; put depth scaling routine in stack frame
|
||
BRA PIXELOK ;=>ALREADY GOT ROUTINE
|
||
|
||
Bogus ;_debugger
|
||
bra Done
|
||
|
||
|
||
ALIGN 4
|
||
|
||
|
||
;Color Blits
|
||
stColorTab
|
||
DC.L Bogus-stColorTab ;0 32 to 32
|
||
DC.L Scale32toIndexed-stColorTab ;1 32 to Indexed
|
||
DC.L Scale32to16-stColorTab ;2 32 to 16
|
||
DC.L Dither32toIndexed-stColorTab ;3 32 to Indexed Dither
|
||
DC.L Scale16to32-stColorTab ;4 16 to 32
|
||
DC.L Scale16toIndexed-stColorTab ;5 16 to Indexed
|
||
DC.L Bogus-stColorTab ;6 16 to 16
|
||
DC.L Dither16toIndexed-stColorTab ;7 16 to Indexed Dither
|
||
|
||
|
||
;Gray Blits
|
||
stGrayTab
|
||
DC.L Scale32toBitmap-stGrayTab ;8 32 to BitMap
|
||
DC.L Scale32toGray-stGrayTab ;9 32 to Indexed
|
||
DC.L Dither32toBitmap-stGrayTab ;A 32 to (16) ->BitMap Dither <BAL 28Jan90>
|
||
DC.L Dither32toGray-stGrayTab ;B 32 to Indexed Dither
|
||
DC.L Scale16ToBitMap-stGrayTab ;C 16 to BitMap
|
||
DC.L Scale16toGray-stGrayTab ;D 16 to Indexed
|
||
DC.L Dither16toBitmap-stGrayTab ;E 16 to (16) ->BitMap Dither <BAL 28Jan90>
|
||
DC.L Dither16toGray-stGrayTab ;F 16 to Indexed Dither
|
||
|
||
|
||
;Search Blits
|
||
stSearchTab
|
||
DC.L Search32to32-stSearchTab ;10 32 to 32 <20AUG90 KON>
|
||
DC.L Search32toIndexed-stSearchTab ;11 32 to Indexed
|
||
DC.L Search32to16-stSearchTab ;12 32 to 16
|
||
DC.L Bogus-stSearchTab ;13 32 to Indexed Dither
|
||
DC.L Search16to32-stSearchTab ;14 16 to 32
|
||
DC.L Search16toIndexed-stSearchTab ;15 16 to Indexed
|
||
DC.L Search16to16-stSearchTab ;16 16 to 16 <20AUG90 KON>
|
||
DC.L Bogus-stSearchTab ;17 16 to Indexed Dither
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; The src is indexed data (1,2,4,8 bits/pixel).
|
||
; If seeds don't match or depths are different then make a scale table.
|
||
; Special case 1-bit source.
|
||
;
|
||
|
||
HasClut
|
||
MOVE.L SRCPIX+PMTABLE(A6),d0 ;GET SRC COLOR TABLE HANDLE <BAL>
|
||
beq.s DOXLATE ;table not nil so continue <BAL>
|
||
move.l d0,a0 ;get handle for deref <BAL>
|
||
move.l (a0),a0 ;point to it <KON>
|
||
MOVE.L CTSEED(A0),D0 ;GET SEED
|
||
|
||
MOVE.L DSTPIX+PMTABLE(A6),A0 ;GET DST COLOR TABLE HANDLE
|
||
cmp #16,DstPix+pixelType(a6) ;is it a direct device?
|
||
beq.s @chk1 ;yes, don't check seeds
|
||
MOVE.L (A0),A0 ;POINT TO IT
|
||
CMP.L CTSEED(A0),D0 ;DO THE SEEDS MATCH?
|
||
BNE.S @chk1 ;=>NO, MUST TRANSLATE
|
||
|
||
|
||
CMP D3,D4 ;DOES SRC DEPTH = DST DEPTH?
|
||
bne.s @chk1 ;no, then scale pixels
|
||
;
|
||
; check fg and bk color and if they aren't black and white
|
||
; then take chk1 case, otherwise, take pixelok case.
|
||
;
|
||
; <KON 5MAR91> begins here... This fixes a problem with drawing to bitmaps. The problem
|
||
; is when the main device is direct and the app sets the fg color to black and the
|
||
; bg color to white, we think we are colorizing since the sense of what is black and
|
||
; what is white is reversed. This can only happen when the destination pixmap is
|
||
; 1-bit and the destination GDevice is a direct device. Thus, I special case this
|
||
; situation and check the fg and bg colors for black and white correctly. There is
|
||
; probably a more elegant fix for this, but with 7.0 ready to ship this implementation
|
||
; causes the least risk since it should effect only the case we are interested in. If
|
||
; it's not this particular case, we branch to @OldWay and processing continues as before.
|
||
; YUK!
|
||
;
|
||
;Êfrom QDciPatchROM.a verbatim (down through the RTD) <sm 6/9/92>stb
|
||
;
|
||
; if destination device is direct, and dst pixmap 1-bit bcolor = FFFFFFFF and
|
||
; fcolor = 0 is NOP
|
||
; else, bcolor = 0, fcolor = $FFFFFFFF is NOP
|
||
;
|
||
cmp #1,d3 ;1-bit?
|
||
bne.s @OldWay ;no, do it as before
|
||
MOVE.L ([theGDevice]),A2 ; get the current device
|
||
MOVE.L ([GDPMap,A2]),A1 ; get pixMap
|
||
cmp #16,pixelType(A1) ; is dest. GDevice direct?
|
||
bne.s @OldWay ;
|
||
;
|
||
; Destination pixmap is indexed but GDevice is direct. Assume we are going to
|
||
; an old 1-bit port.
|
||
;
|
||
move.l fcolor(a6),d1
|
||
bne.s @chk1 ;fg not black, go slow
|
||
move.l bcolor(a6),d1
|
||
addq #1,d1
|
||
beq PIXELOK ;bk white, fg black, go fast
|
||
bra.s @chk1
|
||
|
||
; <KON 5MAR91> ends here...
|
||
@OldWay
|
||
move.l bcolor(a6),d1
|
||
bne.s @chk1 ;fg not black, go slow
|
||
move.l fcolor(a6),d1
|
||
addq #1,d1
|
||
beq PIXELOK ;bk white, fg black, go fast
|
||
|
||
@chk1 TST D3 ;IS SRC ONE BIT PER PIXEL?
|
||
BNE.S DOXLATE ;=>NO, Build mapping table
|
||
MOVEQ #1,D1 ;GET CTSEED FOR DEFAULT ONE BIT TABLE
|
||
CMP.L D0,D1 ;IS IT THE DEFAULT?
|
||
BEQ SRCONE ;=>YES, USE EXPAND TABLES FOR SPEED
|
||
|
||
DOXLATE MOVE SRCPIX+PIXELSIZE(A6),D1 ;GET SRC BITS PER PIXEL
|
||
MOVEQ #1,D0 ;# ENTRIES = 2^ PIXELSIZE
|
||
LSL D1,D0 ;CALC # ENTRIES
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
; IF THE DST IS AN OLD GRAFPORT AND IS ONE BIT PER PIXEL, THEN OVERRIDE THE
|
||
; SEARCH PROC FOR PROPER MAPPING
|
||
|
||
MOVEQ #0,D7 ;ASSUME NO PROC INSTALLED
|
||
CMP #1,DSTPIX+PIXELSIZE(A6) ;ONE BIT PER PIXEL?
|
||
BNE.S @PROCOK ;=>NO, PROC IS OK
|
||
MOVE.L DSTBITS(A6),A1 ;GET DST BITMAP
|
||
TST ROWBYTES(A1) ;IS IT OLD?
|
||
BMI.S @PROCOK ;=>NO, PROC IS OK
|
||
|
||
MOVEQ #1,D7 ;FLAG PROC INSTALLED
|
||
PEA ONEBITPROC ;POINT TO OUR PROC
|
||
_ADDSEARCH ;AND INSTALL IT
|
||
|
||
@PROCOK MOVE.L SAVEA5(A6),A5 ;GET A5 FOR MAKESCALETBL
|
||
MOVE.L A4,-(SP) ;PUSH SRCPIX POINTER
|
||
|
||
;
|
||
; If bit 0 = 1, then MakeScaleTbl colorizes, otherwise it don't.
|
||
; if mode is BIC or OR, then don't colorize in MakeScaleTbl
|
||
;
|
||
MOVE.w XLateFlag(a6),-(SP) ;pass arithmetic mode to get fg/bg relative colors
|
||
_MakeScaleTbl ;AND MAKE PIXEL TRANSLATION TABLE
|
||
|
||
;------------------------------------------------------------------------------------------
|
||
;
|
||
; <C947> 08Nov87 BAL begins here:
|
||
;
|
||
;------------------------------------------------------------------------------------------
|
||
;
|
||
; MakeScaleTbl is called whenever the src and dst pixmaps have different
|
||
; pixel depths or different color table seeds. MakeScaleTbl returns a
|
||
; pixel translation table used to map each src pixel to a dst pixel.
|
||
;
|
||
; Here I check to see if the translation table returned by MakeScaleTbl is in
|
||
; actuality an identity mapping--in which case no mapping at all is required!
|
||
; In order for an identity mapping to result the src and dst pixMaps must be of the same
|
||
; depth.
|
||
;
|
||
; If an identity mapping is detected, I must decide whether a stretch blit loop is
|
||
; really required (ie src rect dst rect or maskBits nil) or whether a much faster
|
||
; region blit or bit blit loop would suffice.
|
||
;
|
||
;------------------------------------------------------------------------------------------
|
||
|
||
move SRCPIX+PIXELSIZE(A6),d1 ;get src bits/pixel
|
||
cmp DSTPIX+PIXELSIZE(A6),d1 ;is it the same as dst bits/pixel?
|
||
bne.s @ScaleOK ;no, have to do pixel scaling
|
||
|
||
;inspect scale table for equality
|
||
@chkTbl MOVEQ #1,D0 ;# ENTRIES = 2^ PIXELSIZE
|
||
LSL D1,D0 ;CALC # ENTRIES in d0
|
||
move d0,d1 ;make a copy of long count
|
||
lsl #2,d1 ;get size of table
|
||
subq #1,d0 ;make counter zero based for dbra
|
||
move.l sp,a0 ;point to scale tbl
|
||
add d1,a0 ;point past end of table
|
||
|
||
@1 cmp.l -(a0),d0 ;compare with dst pixel value
|
||
dbne d0,@1
|
||
bne.s @ScaleOK ;tables are not equal so perform pixel scaling
|
||
|
||
CLR.L ScaleCase(a6) ;remember no pixel xlation needed <BAL 09Apr90>
|
||
MOVE.L SP,ScaleTbl(A6) ;SAVE TRANSLATION TABLE just in case <BAL 09Apr90>
|
||
|
||
;if we installed a proc get rid of it before short circuiting stretch
|
||
|
||
TST D7 ;DID WE INSTALL A PROC
|
||
BEQ.S @NOPRC ;=>NO, DON'T NEED TO REMOVE
|
||
PEA ONEBITPROC ;ELSE PUSH OUR PROC
|
||
_DELSEARCH ;AND DELETE IT
|
||
|
||
@NOPRC LEA DSTPIX(A6),A5 ;RESTORE DSTPIX POINTER
|
||
TST.L MASKBITS(A6) ;*** IS THERE A MASK?
|
||
BNE PIXELOK ;=>YES, USE STRETCH BUT DON'T PIXEL TRANSLATE
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALC NUMER AND DENOM BASED ON DSTRECT AND SRCRECT.
|
||
; IF NUMER = DENOM AND SRC DEPTH = DST DEPTH THEN JUST CALL RGNBLT.
|
||
;
|
||
MOVE.L NUMER(A6),D0 ;GET WIDTH,HEIGHT OF DST
|
||
CMP.L DENOM(A6),D0 ;SAME AS WIDTH,HEIGHT OF SRC?
|
||
BNE PIXELOK ;no, must call stretch
|
||
MOVE.L INVERTFLAG(A6),D7 ;restore invert flag <<C983>>
|
||
BRA NOTSTR ;jump back and decide between bitblt and rgnblt
|
||
;don't really have to use stretch at all!
|
||
|
||
;------------------------------------------------------------------------------------------
|
||
;
|
||
; <C947> 08Nov87 BAL ends here.
|
||
;
|
||
;------------------------------------------------------------------------------------------
|
||
@ScaleOK
|
||
MOVE.L SP,ScaleTbl(A6) ;SAVE POINTER TO TRANSLATION TABLE
|
||
LEA DSTPIX(A6),A5 ;RESTORE DSTPIX POINTER
|
||
|
||
TST D7 ;DID WE INSTALL A PROC
|
||
BEQ.S @NOPROC ;=>NO, DON'T NEED TO REMOVE
|
||
PEA ONEBITPROC ;ELSE PUSH OUR PROC
|
||
_DELSEARCH ;AND DELETE IT
|
||
|
||
@NOPROC move.l stIndexedSrc,A0 ;POINT TO THE SCALING ROUTINE
|
||
MOVE.L A0,SCALECASE(A6) ;AND SAVE CASE JUMP FOR LATER
|
||
BRA PIXELOK ;=>ALREADY GOT ROUTINE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
ONEBITPROC
|
||
;----------------------------------------------------------------
|
||
; FUNCTION ONEBITPROC(MYCOLOR:RGBCOLOR; VAR INDEX: LONG): BOOLEAN;
|
||
;
|
||
; THIS IS A COLOR MANAGER CUSTOM SEARCH PROC THAT MAPS RGB TO
|
||
; BLACK AND WHITE FOR MAPPING TO OLD GRAFPORTS.
|
||
; Algorithm modified to use [5 9 2] luminance mapping. <BAL 30Mar89>
|
||
;
|
||
MYINDEX EQU 4
|
||
MYRGB EQU 8
|
||
RESULT EQU 12
|
||
|
||
ST.B RESULT(SP) ;ALWAYS RETURN TRUE
|
||
MOVE.L MYRGB(SP),A0 ;POINT TO RGB
|
||
moveq #0,d0 ;clear out high end
|
||
moveq #0,d1 ;clear out high end
|
||
move.w red(a0),d0 ;get red
|
||
move.l d0,a1 ;keep red in a1
|
||
move.w green(a0),d1 ;get green
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
move blue(a0),d0
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
lsr.l #2,d1
|
||
add.l a1,d1 ;accumulate luminance in d1
|
||
move green(a0),d0
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
lsr.l #2,d1
|
||
MOVE.L MYINDEX(SP),A1 ;POINT TO INDEX
|
||
CLR.L (A1) ;ASSUME INDEX = WHITE
|
||
tst d1 ;check luminance
|
||
BMI.S @RESOK ;=>IF >= $8000 THEN WHITE
|
||
ADDQ.L #1,(A1) ;ELSE RETURN BLACK
|
||
@RESOK RTD #8 ;STRIP PARAMS AND RETURN
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
;----------------------------------------------------------------
|
||
;
|
||
; FOR 1 BIT TO N BIT PIXEL-STRETCHING, SET UP EXPAND ROUTINE.
|
||
;
|
||
|
||
SRCONE move.l ExTblPtr,A0 ;POINT TO ROUTINE TABLE
|
||
CMP.W #4,D4 ;are we going to a direct device? <42>
|
||
BLT.S @2 ;no, take normal path <42>
|
||
MOVE.W locMode(A6),D0 ;get transfer mode <42>
|
||
BTST #5,D0 ;arithmetic? <42>
|
||
BNE.S @2 ;yes, take normal path <42>
|
||
AND.W #3,D0 ;is the mode copy? <42>
|
||
BEQ.S @2 ;yes, take normal path (colors swapped) <42>
|
||
MOVE.L alphaMask(A6),D1 ;get the alpha mask <42>
|
||
TST.L INVERTFLAG(A6) ;are we inverting? <42>
|
||
BEQ.S @1 ;no, leave invertflag alone <42>
|
||
MOVE.L D1,INVERTFLAG(A6) ;yes, change invertflag to alphamask <42>
|
||
@1: CLR.L alphaFore(A6) ;foreground is zeroes <42>
|
||
MOVE.L D1,alphaBack(A6) ;background is alphamask <42>
|
||
ADD.L 40(A0,D4*4),A0 ;get address of special expansion loop <42>
|
||
BRA.S @gotScale ;jump to common code <42>
|
||
@2: ;take normal path <42>
|
||
;
|
||
;take special loops if colorizing
|
||
;
|
||
btst #ScaleColorBit,XLateFlag+1(a6) ;colorize in expansion?
|
||
beq.s @nocolorize ;no, colorize in blit loop
|
||
@colorize
|
||
add.l 32(A0,d4*4),a0 ;colorize in expansion
|
||
if 0 then ;why? <10Sept90 KON>
|
||
;
|
||
; if swapfgbgBit is set, we need to swap fg/bg color again
|
||
;
|
||
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
|
||
beq.s @gotScale ;don't invert
|
||
move.l fcolor(a6),d1 ;swap fg/bk color
|
||
move.l bcolor(a6),fcolor(a6)
|
||
move.l d1,bcolor(a6)
|
||
endif
|
||
bra.s @gotScale
|
||
|
||
@nocolorize
|
||
cmp.w #4,d4
|
||
blt.s @indexedDst
|
||
add.l 8(A0,D4*4),A0 ;choose between direct loops
|
||
bra.s @gotScale
|
||
@indexedDst
|
||
add.l 0(A0,D4*4),A0 ;USE DSTSHIFT TO SELECT ROUTINE
|
||
@gotScale
|
||
MOVE.L A0,SCALECASE(A6) ;SAVE CASE JUMP FOR LATER
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; We've got our ScaleCase.
|
||
;
|
||
PIXELOK
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR SRCBUF TO HOLD SRCWIDTH.
|
||
;
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE DENOM+H(A6),D0 ;GET WIDTH OF SRC
|
||
LSL.l D3,D0 ;SCALE WIDTH BY SRC DEPTH
|
||
SUBq.l #1,D0 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D0,SRCLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLRSRC CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRSRC ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,SRCBUF(A6) ;REMEMBER WHERE SRCBUF IS
|
||
MOVE.L SP,DSTBUF(A6) ;ASSUME NO HORIZONTAL STRETCHING
|
||
MOVE.L SP,SCALEBUF(A6) ;ASSUME NO PIXEL TRANSLATION
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR DSTBUF TO HOLD DSTLONGS.
|
||
;
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE NUMER+H(A6),D0 ;GET WIDTH OF DST
|
||
CMP DENOM+H(A6),D0 ;SAME AS WIDTH OF SRC?
|
||
BEQ.S NOHSTRETCH ;=>YES, NO HORIZONTAL STRETCHING
|
||
|
||
LSL.l D3,D0 ;SCALE WIDTH BY SRC DEPTH
|
||
|
||
SUBq.l #1,D0 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D0,DSTLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
CLRDST CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRDST ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,DSTBUF(A6) ;REMEMBER WHERE DSTBUF IS
|
||
MOVE.L SP,SCALEBUF(A6) ;DEFAULT SCALEBUF = DSTBUF
|
||
|
||
|
||
NOHSTRETCH
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR MASK TO HOLD srcMASKlongs.
|
||
;
|
||
CLR.L MASKNUMER(A6) ;SRC MASK WIDTH
|
||
CLR.L MASKDENOM(A6) ; = DST MASK WIDTH
|
||
MOVE.L MASKBITS(A6),D0 ;IS THERE A MASK?
|
||
BEQ NODST ;=>NO, DON'T ALLOCATE MASK BUFFERS
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALC NUMER AND DENOM BASED ON DSTRECT AND MASKRECT.
|
||
;
|
||
MOVE.L MASKRECT(A6),A0 ;POINT TO MASKRECT
|
||
MOVE BOTTOM(A0),D1
|
||
SUB TOP(A0),D1 ;CALC MASK HEIGHT
|
||
SWAP D1 ;PUT IN HI WORD
|
||
MOVE RIGHT(A0),D1
|
||
SUB LEFT(A0),D1 ;CALC MASK WIDTH
|
||
|
||
MOVE BOTTOM(A3),D0
|
||
SUB TOP(A3),D0 ;CALC DST HEIGHT
|
||
SWAP D0 ;PUT IN HI WORD
|
||
MOVE RIGHT(A3),D0
|
||
SUB LEFT(A3),D0 ;CALC DST WIDTH
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; USE MASK AND DST SIZES TO DETERMINE MASK STRETCHING ROUTINE
|
||
;
|
||
MOVEM.L D3/D4,-(SP) ;SAVE D3/D4
|
||
MOVE.L D0,MASKNUMER(A6) ;NUMER := DST SIZE
|
||
MOVE.L D1,MASKDENOM(A6) ;DENOM := SRC SIZE
|
||
_SetupStretch ;CALC CASEJUMP AND HORIZ FRACT (CLOBBER D3,D4)
|
||
MOVE.L A0,MASKCASE(A6) ;SAVE CASE JUMP FOR LATER
|
||
MOVE D0,MASKFRACT(A6) ;SAVE FRACTION FOR LATER
|
||
MOVEM.L (SP)+,D3/D4 ;RESTORE D3/D4
|
||
MOVEQ #0,D2 ;CLEAR HIGH WORD OF D0
|
||
move.w MASKDENOM+H(A6),d2 ;get width of mask
|
||
;
|
||
;unless depth = 1, depth promoted to 32 bit/pix
|
||
;
|
||
move.w maskshift(a6),d1
|
||
beq.s @onebitmask
|
||
|
||
move.l maskpix+pmTable(a6),a0
|
||
move.l (a0),d0 ;get pointer to color table <20AUG90 KON and BAL>
|
||
_rTranslate24To32 ;clean master pointer <20AUG90 KON and BAL>
|
||
move.l d0,MaskPixPmTable(a6) ; <20AUG90 KON and BAL>
|
||
|
||
moveq #5,d1
|
||
lsl.l d1,d2 ;scale width by mask depth
|
||
@onebitmask
|
||
SUB.l #1,D2 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D2 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D2,SRCMASKLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D2,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLRMSK1 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D2,CLRMSK1 ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,SRCMASKBUF(A6) ;REMEMBER WHERE SRCMASKBUF IS
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR DSTMASKBUF TO HOLD MASKLONGS.
|
||
;
|
||
MOVE.L SP,DSTMASKBUF(A6) ;ASSUME NO DSTBUF
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE MASKNUMER+H(A6),D0 ;GET WIDTH OF DST
|
||
CMP MASKDENOM+H(A6),D0 ;SAME AS WIDTH OF SRC?
|
||
BEQ.S NODST ;=>YES, NO DSTMASKBUF
|
||
;mask depth in d1 from above
|
||
lsl.l d1,d0 ;scale width by mask depth
|
||
@onebitmask
|
||
SUB.l #1,D0 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D0,DSTMASKLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLRMSK2 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRMSK2 ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,DSTMASKBUF(A6) ;REMEMBER WHERE DSTMASKBUF IS
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR SCALEBUF TO HOLD SCALELONGS.
|
||
;
|
||
NODST TST.L SCALECASE(A6) ;IS THERE A SCALE ROUTINE?
|
||
BEQ.S NOSCALE ;=>NO, DON'T ALLOCATE BUFFER
|
||
|
||
DOSCALE MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE NUMER+H(A6),D0 ;GET DST WIDTH
|
||
SUB.l #1,D0 ;SUBTRACT 1 BIT @@@@ altered to use longs 03May88 BAL
|
||
LSL.l D4,D0 ;SCALE DSTBUF BY DSTSHIFT @@@@ altered to use longs 03May88 BAL
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS @@@@ altered to use longs 03May88 BAL
|
||
MOVE D0,SCALELONGS(A6)
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
CLRCHNK CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRCHNK ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,SCALEBUF(A6) ;REMEMBER WHERE SCALEBUF IS
|
||
|
||
|
||
;_________________________________________________________________________________________
|
||
;
|
||
; CALC expansion buffer = [ (minRect.right-minRect.left) div 32 + 1 ] * pixelsize - 0
|
||
; CALC bufSize = [ (minRect.right-minRect.left) * pixelsize - 1 ] div 32 + 1 <C954> 08Nov87 BAL
|
||
;
|
||
NOSCALE MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
||
MOVE LEFT(A0),D1 ;GET DSTRECT LEFT
|
||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL COORDS
|
||
LSL.L D4,D1 ;CONVERT DST PIXELS TO BITS
|
||
AND #$FFE0,D1 ;TRUNC TO MULT OF 32
|
||
ASR.L D4,D1 ;CONVERT DST BITS TO PIXELS
|
||
ADD BOUNDS+LEFT(A5),D1 ;CONVERT BACK TO LOCAL
|
||
MOVE D1,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
||
SUB D1,D0 ;CALC WIDTH IN DOTS
|
||
MOVE D0,bufSize(A6) ;for arithmetic modes, prime bufSize with dot size
|
||
move d0,d1 ;save for expansion scanline buffer <C954>
|
||
|
||
ext.l d1 ;clear out high word <C954>
|
||
lsl.l d4,d1 ;convert to bits <C954>
|
||
subq.l #1,d1 ;force downward round <C954>
|
||
LSR.l #5,D1 ;GET NUMBER OF LONGS IN SCANBUF - 1 <C954>
|
||
addq.l #1,d1 ;***make it one based for stretch!! <C954>
|
||
BTST #5,locMode+1(A6) ;arithmetic?
|
||
BNE.S @skipDotToLong ;if so, donÕt update bufSize
|
||
|
||
MOVE D1,BUFSIZE(A6) ;BUFSIZE = # LONGS -1 <C954>
|
||
|
||
@skipDotToLong
|
||
LSR #5,D0 ;GET NUMBER OF LONGS IN SCANBUF
|
||
ADDQ #1,D0 ;MAKE IT ONE BASED
|
||
LSL D4,D0 ;MULTIPLY BY DST PIXEL DEPTH
|
||
;*** Leave it one based !!!?
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK.
|
||
;
|
||
CLR.L -(SP) ;TWO FOR SLOP
|
||
CLR.L -(SP) ;ONE FOR SLOP
|
||
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR
|
||
DBRA D0,CLRMASK ;LOOP TILL DONE
|
||
MOVE.L SP,RGNBUFFER(A6) ;REMEMBER WHERE RGNBUFFER IS
|
||
|
||
|
||
;--------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE BUFFERS AND INIT STATE RECORDS FOR EACH NON-RECT REGION
|
||
; GET SEEK ROUTINE INTO SEEKMASK(A6)
|
||
; GET EXPAND ROUTINE INTO EXRTN(A6) FOR SEEK ROUTINE
|
||
; Clobbers: A0-A3, D0-D6
|
||
;
|
||
move.l stNoStackPtr,goShow(a6) ;pass go home routine to getSeek <BAL 21Mar89>
|
||
clr.l runBuf(a6) ;don't use run clipping <1.5> BAL
|
||
|
||
move.l dstmaskbuf(a6),d7 ;save dstmaskbuf
|
||
tst.w maskshift(a6) ;deep mask?
|
||
beq.s @dontTrickGetSeek ;branch if no
|
||
clr.l dstmaskbuf(a6) ;make seek think there is no mask
|
||
@dontTrickGetSeek
|
||
MOVE.L RGNC(A6),-(SP) ;PUSH USER RGNHANDLE (never TrimRect'ed)
|
||
MOVE.L RGNB(A6),-(SP) ;PUSH VIS RGNHANDLE
|
||
MOVE.L RGNA(A6),-(SP) ;PUSH CLIP RGNHANDLE
|
||
MOVE.L #2,-(SP) ;PUSH HANDLE COUNT - 1
|
||
_GETSEEK ;GET EXPAND ROUTINE INTO EXRTN(A6)
|
||
;AND SEEK ROUTINE INTO SEEKMASK(A6)
|
||
move.l d7,dstmaskbuf(a6) ;restore
|
||
;--------------------------------------------------
|
||
;
|
||
; CALCULATE CASE JUMP FOR DIFFERENT TRANSFER MODES
|
||
; GET INVERTFLAG INTO D7
|
||
;
|
||
SETMODE MOVE LOCMODE(A6),D0 ;GET THE MODE
|
||
BTST #5,D0 ;arithmetic mode?
|
||
BEQ.S @notArithMode
|
||
CMP #$40,D0 ;source modes are $20 É $27, $32
|
||
BGT DONE ;if bigger, undefined
|
||
BTST #3,D0 ;pattern?
|
||
BNE DONE
|
||
AND #$17,D0 ;consider only 8 mode variants
|
||
BCLR #4,D0 ;clear hilite bit
|
||
BEQ.S @notHilite
|
||
SUBQ #2,D0 ;hilite?
|
||
BNE DONE
|
||
ADDQ #8,D0 ;advance to hilite ($0C - 4)
|
||
@notHilite
|
||
cmp #16,dstPix+pixelSize(A6) ;dst 32 bits/pixel?
|
||
bge.s @useLoops16 ;yes, use alternate table
|
||
ADDQ #4,D0 ;advance past normal src modes
|
||
BRA.S @setupJump
|
||
|
||
@useLoops16
|
||
bne.s @useLoops32 ;yes, use alternate table
|
||
move.l stArith16TabPtr,A0 ;POINT TO 16 bit MODE TABLE
|
||
@getMode
|
||
BCLR #4,D0 ;clear hilite bit
|
||
add.l 0(A0,D0*4),A0 ;GET CASE JUMP ADDRESS
|
||
move.l a0,modeCase(a6) ;save for later
|
||
bra.s @gotMode
|
||
@useLoops32
|
||
move.l stArith32TabPtr,A0 ;POINT TO 32 bit MODE TABLE
|
||
bra.s @getMode
|
||
|
||
@notArithMode
|
||
MOVE.L INVERTFLAG(A6),D7 ;GET THE INVERT FLAG
|
||
BCLR #2,D0 ;CLEAR INVERT BIT
|
||
CMP #7,D0 ;IS MODE > 7 ?
|
||
BGT DONE ;YES, QUIT
|
||
@setupJump
|
||
LEA StretchModeTab,A0 ;POINT TO MODE TABLE (in trap table)
|
||
MOVE.L 0(A0,D0*4),MODECASE(A6) ;SAVE FOR LATER
|
||
@gotMode
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP srcMergeCase.
|
||
;
|
||
@noPromote
|
||
move.w srcshift(a6),d3 ;src depth
|
||
lea VMergeTable,a0 ;get base
|
||
add.l (a0,d3.w*4),a0 ;get routine offset from base
|
||
move.l a0,srcMergeCase(a6)
|
||
|
||
SourceMergeSetupDone
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP maskMergeCase
|
||
;
|
||
clr.l CombineMaskCase(a6) ;assume no mask
|
||
clr.l maskMergeCase(a6) ;assume no mask
|
||
tst.l maskbits(a6) ;is there a mask?
|
||
beq nomask1 ;=>NO
|
||
|
||
move.w maskshift(a6),d0 ;mask depth, currently 0, 4, or 5
|
||
lea VMergeTable,a0 ;get base
|
||
add.l (a0,d0.w*4),a0 ;get displacement to routine
|
||
move.l a0,maskMergeCase(a6)
|
||
|
||
|
||
MergeSetupDone
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; set up CombineMaskCase
|
||
;
|
||
tst maskshift(a6)
|
||
beq.s CombineMaskSetupDone ;one bpp mask
|
||
;
|
||
; Table is disorganized as follows:
|
||
;
|
||
; SRC DST MASK ENTRY
|
||
; 32 ind 32 0
|
||
; 32 16 32 1
|
||
; 32 32 32 2
|
||
;
|
||
; calc routine based on dst
|
||
;
|
||
;
|
||
; want indexed values to goto 0, 16 bit to 1, 32 bit to 2
|
||
;
|
||
move dstshift(a6),d0
|
||
subq #3,d0
|
||
spl d1
|
||
and d1,d0
|
||
|
||
lea CombineTable,a0 ;get base
|
||
add.l (a0,d0.w*4),a0 ;get displacement to routine
|
||
move.l a0,CombineMaskCase(a6)
|
||
|
||
CombineMaskSetupDone
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP MASKALIGN AND MASKADDR IF THERE IS A MASK
|
||
;
|
||
|
||
MOVE MASKSHIFT(A6),D3 ;GET MASKSHIFT
|
||
LEA MASKPIX(A6),A2 ;POINT TO MASKPIX
|
||
MOVE.L MASKROW(A6),D2 ;GET MASK ROWBYTES
|
||
|
||
MOVE.L MASKRECT(A6),A0 ;POINT TO MASKRECT
|
||
MOVE LEFT(A0),D1 ;GET MASKRECT LEFT
|
||
SUB BOUNDS+LEFT(A2),D1 ;CONVERT TO MASK GLOBAL
|
||
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
|
||
lsl.l d3,d1 ;convert pixels to bits
|
||
MOVEQ #$1F,D5 ;TREAT MOD 32 FOR MASKALIGN
|
||
AND.L D1,D5 ;MAKE A COPY
|
||
MOVE.L D5,MASKALIGN(A6) ;SAVE ALIGNMENT OF MASK
|
||
|
||
MOVE TOP(A0),D0 ;GET MASKRECT TOP
|
||
SUB BOUNDS+TOP(A2),D0 ;CONVERT TO MASK GLOBAL
|
||
MULS D2,D0 ;MULT BY MASK ROWBYTES BAL 02Dec88
|
||
ADD.L BASEADDR(A2),D0 ;GET START OF MASK BITMAP
|
||
|
||
SUB.L D5,D1 ;ADJUST MASKLEFT FOR MASKALIGN
|
||
ASR.L #3,D1 ;CONVERT BITS TO BYTES
|
||
ADD.L D1,D0 ;ADD BYTES TO MASKADDR
|
||
MOVE.L D0,MASKADDR(A6) ;SAVE AS MASKADDR
|
||
|
||
|
||
NOMASK1
|
||
;----------------------------------------------------------
|
||
;
|
||
; Jump into 32 bit addressing mode for blitting. @@@@ BAL 09Apr88
|
||
;
|
||
|
||
moveq #true32b,d0 ;switch to 32 bit addressing @@@@ BAL 09Apr88
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.b d0,MMUsave(a6) ;save previous state for later @@@@ BAL 09Apr88
|
||
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP SRCROW, SRCSCANS, SRCSHIFT, AND SRCADDR
|
||
;
|
||
MOVE realSRCSHIFT(A6),D3 ;GET SRCSHIFT
|
||
LEA SRCPIX(A6),A2 ;POINT TO SRCPIX
|
||
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
|
||
MOVE BOUNDS+BOTTOM(A2),D1 ;GET SRCBITS.BOUNDS.BOTTOM
|
||
SUB BOUNDS+TOP(A2),D1 ;MAKE IT GLOBAL
|
||
MOVE D1,SRCSCANS(A6) ;SAVE NUMBER OF SCANS TO DO
|
||
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
||
MOVE LEFT(A0),D1 ;GET SRCRECT LEFT
|
||
SUB BOUNDS+LEFT(A2),D1 ;CONVERT TO SRC GLOBAL
|
||
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
|
||
LSL.L D3,D1 ;CONVERT SRC PIXELS TO BITS
|
||
MOVEQ #$1F,D5 ;TREAT MOD 32 FOR SRCSHIFT
|
||
AND.L D1,D5 ;MAKE A COPY
|
||
MOVE.L D5,SRCALIGN(A6) ;SAVE ALIGNMENT OF SOURCE
|
||
|
||
MOVE TOP(A0),D0 ;GET SRCRECT TOP
|
||
SUB BOUNDS+TOP(A2),D0 ;CONVERT TO SRC GLOBAL
|
||
MULS D2,D0 ;MULT BY SRC ROWBYTES BAL 02Dec88
|
||
ADD.L BASEADDR(A2),D0 ;GET START OF SRC BITMAP
|
||
|
||
SUB.L D5,D1 ;ADJUST SRCLEFT FOR SRCSHIFT
|
||
ASR.L #3,D1 ;CONVERT BITS TO BYTES
|
||
ADD.L D1,D0 ;ADD BYTES TO SRCADDR
|
||
MOVE.L D0,SRCADDR(A6) ;SAVE AS SRCADDR
|
||
|
||
if 0 then
|
||
|
||
; If srcAlign is a multiple of 8 there is no reason to make a copy of the src. <BAL 17Mar89>
|
||
|
||
tst d5
|
||
|
||
; and #7,d5 ;alignment required? <BAL 17Mar89>
|
||
bra.s @mustAlign
|
||
clr.l SRCALIGN(A6) ;remember to skip alignment pass <BAL 17Mar89>
|
||
clr.l dstBufBump(A6) ;init to no bump <BAL 17Mar89>
|
||
clr.l scaleBufBump(A6) ;init to no bump <BAL 17Mar89>
|
||
move.l SRCBUF(A6),d1 ;REMEMBER WHERE SRCBUF was <BAL 17Mar89>
|
||
move.l srcRow(a6),d2
|
||
sub.l d2,d0 ;anticipate initial bump <BAL 17Mar89>
|
||
move.l d0,srcBuf(a6) ;use srcAddr as srcBuf <BAL 17Mar89>
|
||
cmp.l DSTBUF(A6),d1 ;is dstBuf same as srcBuf? <BAL 17Mar89>
|
||
bne.s @mustAlign
|
||
move.l d0,dstBuf(a6) ;use srcAddr as dstBuf <BAL 17Mar89>
|
||
move.l d2,dstBufBump(a6) ;set up rowBump for dstBuf <BAL 17Mar89>
|
||
cmp.l SCALEBUF(A6),d1 ;is scaleBuf same as srcBuf? <BAL 17Mar89>
|
||
bne.s @mustAlign
|
||
move.l d0,scaleBuf(a6) ;use srcAddr as scaleBuf <BAL 17Mar89>
|
||
move.l d2,scaleBufBump(a6) ;set up rowBump for scaleBuf <BAL 17Mar89>
|
||
|
||
endif
|
||
|
||
@mustAlign
|
||
;----------------------------------------------------
|
||
;
|
||
; CALC STARTING DSTROW, DSTSHIFT, AND DSTADDR
|
||
;
|
||
MOVE DSTSHIFT(A6),D4 ;GET DST SHIFT
|
||
MOVE.L DSTROW(A6),D2 ;GET DST ROWBYTES
|
||
|
||
MOVE.L DSTRECT(A6),A0
|
||
MOVE TOP(A0),VERT(A6) ;INIT CURRENT VERTICAL
|
||
MOVE LEFT(A0),D1 ;GET DSTRECT LEFT
|
||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL COORDS
|
||
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
|
||
LSL.L D4,D1 ;CONVERT DST PIXELS TO BITS
|
||
MOVEQ #$1F,D6
|
||
AND.L D1,D6 ;TREAT MOD 32 FOR SHIFTCNT
|
||
NEG.L D6 ;AND NEGATE IT
|
||
MOVE.L D6,DSTALIGN(A6) ;SAVE FOR LATER
|
||
|
||
MOVE.L D6,D0 ;GET ALIGNMENT
|
||
ASR.L D4,D0 ;CONVERT TO PIXELS
|
||
MOVE.L D0,DSTMASKALIGN(A6) ;AND SAVE FOR MASK
|
||
|
||
MOVE MINRECT+TOP(A6),D0 ;GET MINRECT TOP
|
||
SUB BOUNDS+TOP(A5),D0 ;CONVERT TO GLOBAL COORDS
|
||
MULS D2,D0 ;MULT BY DST ROWBYTES BAL 02Dec88
|
||
ADD.L BASEADDR(A5),D0 ;GET START OF DST BITMAP
|
||
|
||
ASR.L #5,D1 ;CONVERT BITS TO LONGS
|
||
LSL.L #2,D1 ;AND BACK TO BYTES (MOD 4)
|
||
ADD.L D1,D0 ;ADD BYTES TO DSTADDR
|
||
MOVE.L D0,DSTADDR(A6) ;SAVE AS DSTADDR
|
||
|
||
_stScanLoop
|
||
|
||
|
||
|
||
stScanLoop
|
||
;-----------------------------------------------------
|
||
;
|
||
; Perform quick checks to see if we can use special cases
|
||
;
|
||
|
||
if 0 then ;<14SEP90 SMC>
|
||
|
||
tst.b FastCase(a6) ;FG Black, BG White, no scaling, copy mode, no mask?
|
||
beq.s @goSlow ;no, must go slow
|
||
|
||
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;destination 8 bits/pixel?
|
||
BNE.S @ChkDst1Bit ;if not, skip
|
||
|
||
CMP.W #8,SRCPIX+PIXELSIZE(A6) ;src 8 bits/pixel?
|
||
BEQ CB8to8Clip ;yes, go fast
|
||
|
||
CMP.W #1,SRCPIX+PIXELSIZE(A6) ;src 1 bits/pixel?
|
||
BNE.S @goSlow
|
||
move.l ExTblPtr,A0 ;POINT TO ROUTINE TABLE
|
||
add.l 3*4(A0),A0 ;get 1 to 8 bit routine
|
||
CMP.L ScaleCase(a6),a0 ;standard 1 bit src?
|
||
BNE.S @goSlow
|
||
BRA CB1to8Clip
|
||
|
||
@ChkDst1Bit
|
||
CMP.W #1,DSTPIX+PIXELSIZE(A6) ;destination 8 bits/pixel?
|
||
BNE.S @goSlow ;if not, can't handle
|
||
|
||
CMP.W #8,SRCPIX+PIXELSIZE(A6) ;src 8 bits/pixel?
|
||
BEQ CB8to1Clip ;if not, skip
|
||
@goSlow
|
||
|
||
endif ;<14SEP90 SMC>
|
||
|
||
;-----------------------------------------------------
|
||
;
|
||
; INIT ERROR TERM FOR DDA
|
||
;
|
||
MOVE DENOM+V(A6),D0 ;get source height <5MAR90 KON>
|
||
cmp.w Numer+v(a6),d0 ;check against destination height <5MAR90 KON>
|
||
ble.s Expand ;src height <= destination : stretch <5MAR90 KON>
|
||
move d0,d1 ;save source height <5MAR90 KON>
|
||
ext.l d1 ;
|
||
divu.w numer+v(a6),d1 ;src MOD dst to high word of d1 <5MAR90 KON>
|
||
swap d1 ;get remainder in low word <5MAR90 KON>
|
||
tst d1 ;exact shrink? <5MAR90 KON>
|
||
bne.s Expand ; no, use general error <5MAR90 KON>
|
||
sub.w #1,d0 ;yes, use src height-1 <5MAR90 KON>
|
||
bra.s Expand1
|
||
Expand
|
||
lsr #1,d0
|
||
Expand1
|
||
neg d0
|
||
move d0, verror(a6)
|
||
move d0, maskerror(a6)
|
||
|
||
;
|
||
; Calc num destinations to skip, put in D1
|
||
;
|
||
SKIPDST
|
||
moveq #0,d3 ;assume starting on line 0 in source
|
||
move.l srcaddr(A6),a3 ;get source address in register
|
||
MOVE MINRECT+TOP(A6),D1 ;
|
||
SUB VERT(A6),D1 ;Clipped scans at top
|
||
BLE @DontSkipSource ;no, DST NOT CLIPPED
|
||
;
|
||
; Skip source while error is negative, D3 contains number of source scans to skip
|
||
;
|
||
@nxtSrc MOVE.L MASKROW(A6),D0 ;GET MASK ROWBYTES
|
||
ADD.L D0,MASKADDR(A6) ;BUMP MASK TO NEXT ROW, even if there isn't one
|
||
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
|
||
ADD.L D2,a3 ;BUMP SRC TO NEXT ROW
|
||
addq #1,d3 ;number of source scan lines skipped
|
||
MOVE maskNumer+V(A6),D0 ;update mask error: assume same as source
|
||
ADD D0,maskError(A6)
|
||
MOVE numer+V(A6),D0 ;GET NUMER.V
|
||
ADD D0,verror(A6) ;VERROR := VERROR + NUMER.V
|
||
ble.s @nxtSrc ;SKIP IF VERROR > 0
|
||
|
||
;
|
||
;Error is +, skip destinations until we've skipped D1 of them
|
||
;
|
||
MOVE DENOM+V(A6),D0 ;src height
|
||
move maskDenom+v(a6),d2
|
||
@nxtDst ADD #1,VERT(A6) ;BUMP TO NEXT VERTICAL on dest
|
||
sub d2,maskerror(a6) ;update mask error: assume same as source
|
||
SUB D0,VERROR(A6) ;VERROR := VERROR - DENOM.V
|
||
subq.w #1,d1 ;dst lines to skip
|
||
ble.s @ReadyToDraw
|
||
tst.w VERROR(A6)
|
||
blt.s @nxtSrc
|
||
bra.s @nxtDst ;IF MORE, THEN CONTINUE
|
||
|
||
@ReadyToDraw
|
||
tst.w VERROR(A6) ;don't bump further than we need to
|
||
ble.s @DestIsOK ; <63>
|
||
move.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
sub.L d2,a3 ;bump src to previous row
|
||
move.L MASKROW(A6),D0 ;GET SRC ROWBYTES
|
||
sub.L D0,MASKADDR(A6) ;BUMP SRC TO NEXT ROW
|
||
subq #1,d3 ;number of source scan lines skipped
|
||
move NUMER+V(A6),D0 ;GET NUMER.V
|
||
if not(TheFuture) then ; <60> Build old code for now
|
||
move maskDenom+v(a6),d2 ; <60>
|
||
endif ; <60>
|
||
if TheFuture then ; <60> New code for later
|
||
move maskNumer+v(a6),d2 ; <59>
|
||
endif ; <60>
|
||
sub d2,maskerror(a6)
|
||
sub D0,VERROR(A6) ;VERROR := VERROR + NUMER.V
|
||
bgt.s @ReadyToDraw ;
|
||
|
||
|
||
@DestIsOK
|
||
;
|
||
; here d3 contains number of first src line (# of src lines skipped)
|
||
; a3 contains starting address
|
||
;
|
||
@DontSkipSource
|
||
_pmVersionSrcFirstTime ;D3 contains starting scan line no.
|
||
move.l a3,srcaddr(a6) ;put src address back
|
||
|
||
_pmVersionMaskFirstTime ;D3 contains starting scan line no.
|
||
;-----------------------------------------------------
|
||
;
|
||
; GET FIRST SCANLINE OF SRC INTO SRCBUF
|
||
;
|
||
NEXTSRC TST SRCSCANS(A6) ;ANY SCANS LEFT?
|
||
BLE DONE ;=>NO, QUIT
|
||
|
||
|
||
;-----------------------------------------------------
|
||
;
|
||
; Do MergeCase moves a line of source into srcbuf and does vertical
|
||
; averaging if necessary.
|
||
;
|
||
; Do MergeCase for vertical shrinking of mask
|
||
; Do MergeCase for vertical shrinking of src
|
||
;
|
||
; Clobbers: D0-D4,D6,D7,A0,A1
|
||
;
|
||
DoMergeCase
|
||
;
|
||
; Calculate 0-based scanline count in d7.
|
||
;
|
||
move.l maskMergeCase(a6),d0
|
||
beq.s DoSrcMergeCase ;no mask
|
||
move.l d0,a0
|
||
|
||
moveq #-1,d7
|
||
move srcscans(a6),d1
|
||
move masknumer+v(a6),d0
|
||
@AnotherLine
|
||
addq #1,d7
|
||
subq #1,d1
|
||
blt.s @maskDone
|
||
add d0,maskerror(a6)
|
||
ble.s @AnotherLine ;done when maskerror > 0
|
||
@maskDone
|
||
moveq #0,d4 ;clear high word of srclongs <17JUL90 KON>
|
||
move.w srcmasklongs(a6),d4
|
||
move.l maskalign(a6),d5
|
||
move.w maskPix+pixelSize(a6),d6
|
||
|
||
move.l srcmaskbuf(a6),a2 ;dest buffer pointer
|
||
move.l maskaddr(a6),a3
|
||
move.l MaskPixPmTable(a6),a4
|
||
; move.l maskpix+pmTable(a6),a4
|
||
; move.l (a4),a4 ;get pointer to color table
|
||
move.l maskrow(a6),a5 ;row bytes
|
||
jsr (a0) ;returns to DoSrcMergeCase
|
||
move.l a3,maskaddr(a6)
|
||
|
||
DoSrcMergeCase
|
||
;
|
||
; Calculate 0-based scanline count in d7.
|
||
;
|
||
moveq #-1,d7 ;
|
||
@AnotherLine
|
||
addq #1,d7
|
||
subq #1,srcscans(A6)
|
||
blt.s @srcScansDone
|
||
move numer+v(a6),d0
|
||
add d0,verror(a6)
|
||
ble.s @AnotherLine ;done when verror > 0
|
||
@srcScansDone
|
||
moveq #0,d4 ;clear high word of srclongs <17JUL90 KON>
|
||
move.w srclongs(a6),d4
|
||
move.l srcalign(a6),d5
|
||
move.w srcPix+pixelSize(a6),d6
|
||
tst.b realDepth(a6) ;promoting src to RGB?
|
||
bmi.s @notPromoting ;no, all ok
|
||
move.w realDepth(a6),d6
|
||
@notPromoting
|
||
move.l srcbuf(a6),a2 ;dest buffer pointer
|
||
move.l srcaddr(a6),a3
|
||
|
||
move.l SrcPixPmTable(a6),a4
|
||
; move.l (a4),a4 ;get pointer to color table
|
||
move.l srcrow(a6),a5 ;row bytes
|
||
move.l srcMergeCase(a6),a0
|
||
jsr (a0)
|
||
move.l a3,srcaddr(a6)
|
||
;
|
||
; srcbuf is setup and shrunk, do colorizing if necessary.
|
||
; this is done when the source is direct and the XLateFlag is setup by mapModeTable
|
||
;
|
||
btst #ColorizeInSrcBufBit, XLateFlag(a6) ; Colorize during expansion?
|
||
beq.s @ColorizeDone ;branch if no
|
||
|
||
move.w srclongs(a6),d1
|
||
move.l srcbuf(a6),a2 ;dest buffer pointer
|
||
move.l RGBFrColor(A6),D4 ;GET FG COLOR
|
||
move.l RGBBgColor(A6),D3 ;GET BK COLOR
|
||
@ColorMe
|
||
move.l (a2),d2
|
||
;
|
||
; colorize, the fg/bk are in RGB space and hence switched
|
||
;
|
||
move.l d2,d7 ;copy source
|
||
AND.L D3,D2 ;ADD BG COLOR TO SRC
|
||
NOT.L d7 ;GET NOT SRC
|
||
AND.L D4,d7 ;ADD FG COLOR TO NOT SRC
|
||
OR.L D2,d7 ;COMBINE FG/BK DATA
|
||
|
||
MOVE.L d7,(A2)+ ;put a long to destination
|
||
DBRA D1,@ColorMe ;loop for all longs
|
||
|
||
@ColorizeDone
|
||
SRCOK
|
||
MOVE.L DSTALIGN(A6),D6 ;RESTORE DSTALIGN
|
||
MOVE.L INVERTFLAG(A6),D7 ;RESTORE INVERT FLAG
|
||
|
||
;----------------------------------------------------------
|
||
;
|
||
; HORIZONTALLY STRETCH SRCBUF INTO DSTBUF
|
||
;
|
||
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:(CLOBBERED)
|
||
; D4:(CLOBBERED) D5:(DSTPIXSIZE) D6:!DSTALIGN D7:!(INVERTFLAG)
|
||
; A0:(CLOBBERED) A1:(CLOBBERED) A2:(MASKADDR) A3:(CASEJUMP)
|
||
; A4:(SRCLONGS) A5: A6: A7:
|
||
;
|
||
MOVE NUMER+H(A6),D0 ;GET DST WIDTH
|
||
CMP DENOM+H(A6),D0 ;SAME AS SRC WIDTH?
|
||
BEQ.S SOK ;=>YES, NO STRETCHING NEEDED
|
||
MOVE DSTLONGS(A6),D0 ;GET DSTLONGS
|
||
MOVE.L SRCBUF(A6),A0 ;POINT TO SRCBUF
|
||
MOVE.L DSTBUF(A6),A1 ;POINT TO DSTBUF
|
||
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
|
||
MOVE HORIZFRACTION(A6),D4 ;GET HORIZONTAL FRACTION
|
||
MOVE SRCPIX+PIXELSIZE(A6),D5 ;GET SIZE OF DST PIXELS (= SRC PIXELS)
|
||
;
|
||
; if it's a deep mask and the pixel depth is 16, then it's really 32 bpp
|
||
;
|
||
cmp #16,d5
|
||
bne.s @allok
|
||
move.w maskshift(a6),d2 ;deep mask?
|
||
cmp #4,d2
|
||
blt.s @allok ;not deep mask, don't change pix depth
|
||
move.w #32,d5 ;really 32 bpp
|
||
@allok
|
||
MOVE.L RATIOCASE(A6),A3 ;GET CASE JUMP
|
||
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
|
||
JSR (A3) ;AND CALL STRETCHROW
|
||
|
||
|
||
;----------------------------------------------------------
|
||
;
|
||
; HORIZONTALLY STRETCH SRCMASKBUF INTO DSTMASKBUF
|
||
;
|
||
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:(CLOBBERED)
|
||
; D4:(CLOBBERED) D5:(DSTPIXSIZE) D6:!DSTALIGN D7:!(INVERTFLAG)
|
||
; A0:(CLOBBERED) A1:(CLOBBERED) A2:(MASKADDR) A3:(CASEJUMP)
|
||
; A4:(SRCLONGS) A5: A6: A7:
|
||
;
|
||
SOK MOVE MASKNUMER+H(A6),D0 ;GET DSTMASK WIDTH
|
||
CMP MASKDENOM+H(A6),D0 ;SAME AS SRCMASK WIDTH?
|
||
BEQ.S @DoMasking ;=>YES, NO STRETCHING NEEDED
|
||
MOVE DSTMASKLONGS(A6),D0 ;GET NUMBER OF LONGS
|
||
MOVE.L SRCMASKBUF(A6),A0 ;POINT TO SRCMASKBUF
|
||
MOVE.L DSTMASKBUF(A6),A1 ;POINT TO DSTMASKBUF
|
||
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
|
||
MOVE MASKFRACT(A6),D4 ;GET HORIZONTAL FRACTION
|
||
MOVE maskpix+pixelsize(a6),d5 ;***GET PIXELSIZE
|
||
cmp.w #1,d5 ;is it 1?
|
||
beq.s @sizeok ;if yes, leave it alone
|
||
moveq #32,d5 ;otherwise it's really 32
|
||
@sizeok
|
||
MOVE.L MASKCASE(A6),A3 ;GET CASE JUMP
|
||
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
|
||
JSR (A3) ;AND CALL STRETCHROW
|
||
|
||
@DoMasking
|
||
;----------------------------------------------------------
|
||
;
|
||
; Combine src and dest using mask. Only called for deep masks
|
||
;
|
||
; USES: D0: D1: D2: D3:
|
||
; D4: D5:!dstAlign D6:dst pixel size D7:pixel count
|
||
; A0: scratch A1:mask ptr A2:destination A3: src and dst ptr
|
||
; A4: src pmtable A5: not used A6: not used A7: not used
|
||
;
|
||
move.l CombineMaskCase(a6),d0
|
||
beq.s dstok ;no mask merging
|
||
move.l d0,a0 ;merge routine address
|
||
|
||
move.l dstalign(a6),d5 ;get !dstalign
|
||
neg.l d5
|
||
|
||
move.l dstbuf(a6),a3
|
||
move numer+h(a6),d7 ;number of pixels to do (width of dest)
|
||
move.l dstmaskbuf(a6),a1
|
||
move.l dstaddr(a6),a2 ;destination
|
||
move.l dstPix+pmTable(a6),a4
|
||
move.l (a4),a4 ;get clutptr
|
||
|
||
move.w dstpix+pixelsize(a6),d6 ;1, 2, 4, 8, 16, 32
|
||
|
||
jsr (a0) ;combine src w/ dst using mask
|
||
|
||
|
||
;----------------------------------------------------------
|
||
;
|
||
; Change dstbuf depth to destination depth and put result in scalebuf
|
||
;
|
||
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:!(SRCPIXSIZE)
|
||
; D4:!(DSTPIXSIZE)D5:(CLOBBERED) D6:!DSTALIGN D7:!INVERTFLAG
|
||
; A0:(DSTBUF) A1:(SCALEBUF) A2:(DSTLIMIT) A3:
|
||
; A4:!(SCALETBL) A5:! A6:! A7:!
|
||
;
|
||
DSTOK move.l dstalign(a6),d6
|
||
MOVE.L INVERTFLAG(A6),D7 ;GET THE INVERT FLAG
|
||
MOVE.L SCALECASE(A6),D1 ;NEED TO EXPAND PIXELS?
|
||
BEQ.S NXTMASK ;=>NO, DON'T BOTHER STRETCHING
|
||
MOVE SRCPIX+PIXELSIZE(A6),D3 ;GET SOURCE PIXEL SIZE
|
||
;
|
||
; if it's a deep mask and the pixel depth is 16, then it's really 32 bpp
|
||
;
|
||
cmp #16,d3
|
||
bne.s @allok
|
||
tst.w maskshift(a6) ;deep mask?
|
||
beq.s @allok ;not deep mask, don't change pix depth
|
||
move.w #32,d3 ;really 32 bpp
|
||
@allok
|
||
|
||
MOVE DSTPIX+PIXELSIZE(A6),D4 ;GET DST PIXEL SIZE
|
||
MOVE.L DSTBUF(A6),A0 ;POINT TO SRC
|
||
MOVE.L SCALEBUF(A6),A1 ;POINT TO DST
|
||
MOVE SCALELONGS(A6),D0 ;GET SIZE
|
||
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
|
||
MOVE.L D1,A3 ;GET CASE JUMP ROUTINE
|
||
MOVE.L ScaleTbl(A6),A4 ;POINT TO TRANSLATION TABLE
|
||
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
|
||
JSR (A3) ;AND CALL STRETCHROW
|
||
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; TRANSFER ONE OR MORE COPIES OF SCALEBUF INTO DSTBITS
|
||
;
|
||
; USES: D0: D1: D2: D3:!(FGCOLOR)
|
||
; D4:!(BKCOLOR) D5:arith stuff D6:!DSTALIGN D7:!INVERTFLAG
|
||
; A0: A1: A2: A3:
|
||
; A4: A5:arith stuff A6: A7:
|
||
;
|
||
NXTMASK MOVE.L FCOLOR(A6),D3 ;GET FG COLOR
|
||
MOVE.L BCOLOR(A6),D4 ;GET BK COLOR
|
||
BTST #5,locMode+1(A6) ;an arithmetic mode?
|
||
BEQ.S @skipArith
|
||
|
||
MOVEQ #0,D7
|
||
MOVE dstPix+pixelSize(A6),D7 ;get the number of bits in a pixel
|
||
MOVEQ #32,D5
|
||
DIVU D7,D5 ;# of pixels in a long
|
||
|
||
if 0 then ; don't colorize arithmetic modes anymore
|
||
; color the source first
|
||
; color only if colorizing in mode case
|
||
|
||
@doColor
|
||
BTST #ColorizeInModeCaseBit, XLateFlag(a6)
|
||
beq.s @skipColor
|
||
|
||
cmp #36,locMode(A6) ;transparent mode? ** should be an equ ** <<PB465 BAL>>
|
||
beq.s @skipColor ;if so, skip colorizing. <KON>
|
||
|
||
MOVE.L SCALEBUF(A6),A3 ;INIT SRCPTR
|
||
MOVE BUFSIZE(A6),D2 ;INIT COUNT OF LONGS
|
||
@nxtSrc
|
||
MOVE.L (A3),D0 ;get a long from source
|
||
move.l d0,d1
|
||
AND.L D3,D0 ;ADD FG COLOR TO SRC
|
||
NOT.L d1 ;GET NOT SRC
|
||
AND.L D4,d1 ;ADD BK COLOR TO NOT SRC
|
||
OR.L D0,d1 ;COMBINE FG/BK DATA
|
||
move.l d1,(A3)+ ;write it out
|
||
SUB D5,D2 ;do for all of the pixels on this row
|
||
BGE.S @nxtSrc
|
||
@skipColor
|
||
endif
|
||
|
||
MOVE.L colorTable(A6),A5 ;set up for arithmetic modes
|
||
CMP #$24,locMode(A6) ;transparent?
|
||
BNE.S @skipArith ;if not, regs are fine
|
||
BFEXTU transColor(A6){0:D7},D0
|
||
MOVE.L D0,A5
|
||
@skipArith
|
||
|
||
NXTMSK1 MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
|
||
CMP MINRECT+TOP(A6),D0 ;IS VERT < MINV ?
|
||
BLT.S NODRAW ;YES, DON'T DRAW
|
||
;
|
||
; if mask is >1 bit/pixel, trick seek into ignoring mask by zeroing dstmaskbuf
|
||
;
|
||
move.l dstmaskbuf(a6),a4 ;save dstmaskbuf <KON 9JAN90>
|
||
tst maskshift(a6)
|
||
beq.s @NoTrickorTreat
|
||
clr.l dstmaskbuf(a6) ;make seek think there is no mask
|
||
@NoTrickorTreat
|
||
JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
||
|
||
move.l a4,dstmaskbuf(a6) ; <KON 9JAN90>
|
||
|
||
MOVE.L SCALEBUF(A6),A3 ;INIT SRCPTR
|
||
MOVE.L DSTADDR(A6),A4 ;INIT DSTPTR FOR ROW
|
||
MOVE.L RGNBUFFER(A6),A2 ;INIT MASKPTR FOR ROW
|
||
MOVE BUFSIZE(A6),D2 ;INIT COUNT OF LONGS
|
||
MOVE.L MODECASE(A6),A0 ;GET MODE CASE JUMP
|
||
BTST #5,locMode+1(A6) ;an arithmetic mode?
|
||
BEQ.S @skipArith
|
||
MOVE.L transColor(A6),D4 ;set up transparent color in case different from bg
|
||
CMP #$24,locMode(A6) ;transparent?
|
||
BEQ.S @skipInvTbl ;if so, D5 contains the pixels per long value
|
||
MOVE invSize(A6),D5 ;set up resolution of inverse table for arith. modes
|
||
@skipInvTbl
|
||
MOVEQ #0,D3 ;initialize destination pixel offset
|
||
MOVE.L dstAlign(A6),D6 ;reset alignment since it is bumped by arith. modes
|
||
SUB.L D7,D6 ;bump source pixel offset back by 1
|
||
@skipArith
|
||
CMP.L DSTPIX+BASEADDR(A6),A4 ;IS IT BEFORE THE PIXMAP?
|
||
BLO.S DSTNEG ;=>YES, DON'T PUT TO DST
|
||
DOBLT JMP (A0) ;TAKE MODE JUMP
|
||
NEXTDST MOVE.L DSTROW(A6),D0 ;GET DST ROWBYTES
|
||
ADD.L D0,DSTADDR(A6) ;BUMP DST TO NEXT ROW
|
||
|
||
NODRAW ADD #1,VERT(A6) ;BUMP TO NEXT VERT
|
||
MOVE VERT(A6),D0 ;GET VERT
|
||
CMP MINRECT+BOTTOM(A6),D0 ;ARE WE AT THE LAST SCAN LINE ?
|
||
BEQ.S DONE ;YES, QUIT
|
||
MOVE maskdenom+V(A6),D0 ;update mask error
|
||
SUB D0,maskERROR(A6)
|
||
MOVE DENOM+V(A6),D0
|
||
SUB D0,VERROR(A6) ;VERROR := VERROR - DENOM.V
|
||
BLT NEXTSRC ;IF VERROR < 0 THEN GET NEXT SRC <BAL 19Mar89>
|
||
tst.b useDither(a6) ; are we dithering? <BAL 19Mar89>
|
||
bne.s dstOK ; yes dither this scan again with current error <BAL 19Mar89>
|
||
BRA NXTMSK1 ;ELSE continue to draw from this src <BAL 19Mar89>
|
||
|
||
;-----------------------------------------------------------------
|
||
;
|
||
; HANDLE CASE WHERE DST IS NEGATIVE
|
||
;
|
||
DSTNEG MOVE.L DSTPIX+BASEADDR(A6),D1 ;GET ELUSIVE BASE ADDRESS
|
||
BTST #5,locMode+1(A6) ;AN ARITHMETIC MODE?
|
||
BEQ.S @NoRith ;=>NOPE, DO NORMAL
|
||
|
||
; IF ARITHMETIC MODE, BUMP ONE PIXEL AT A TIME UNTIL DST ISN'T NEGATIVE
|
||
|
||
@LOOP LEA 0(A4,D3),A1 ;GET CURRENT ADDRESS
|
||
CMP.L A1,D1 ;ARE WE STILL NEGATIVE?
|
||
BLS.S DOBLT ;=>NO, BLIT REST OF SCANLINE
|
||
SUBQ #1,D2 ;SKIP A DOT
|
||
BMI.S NEXTDST ;=>DONE WITH SCANLINE
|
||
ADD.L D7,D6 ;BUMP SRC POINTER ONE DOT
|
||
ADD.L D7,D3 ;BUMP DST POINTER ONE DOT
|
||
BRA.S @LOOP ;=>YES, KEEP SKIPPING
|
||
|
||
; IF NORMAL MODE, BUMP ONE LONG AT A TIME UNTIL DST ISN'T NEGATIVE
|
||
|
||
@NoRith LEA 4(A4),A1 ;GET NEXT LONG OF DST
|
||
CMP.L A1,D1 ;ARE WE STILL NEGATIVE
|
||
BLS.S DOBLT ;=>NO, BLIT REST OF SCANLINE
|
||
SUBQ #1,D2 ;SKIP NEXT LONG
|
||
BMI.S NEXTDST ;=>DONE WITH SCANLINE
|
||
ADDQ.L #4,A2 ;BUMP MASKPTR
|
||
ADDQ.L #4,A3 ;BUMP SRCPTR
|
||
ADDQ.L #4,A4 ;BUMP DSTPTR
|
||
BRA.S @NoRith ;=>TRY, TRY AGAIN
|
||
|
||
;-----------------------------------------------------------------
|
||
;
|
||
; ENTIRE STRETCHBITS COMPLETE. RESTORE REGS AND STACK AND GO HOME.
|
||
;
|
||
DoneStretch
|
||
DONE clr.w QDErr ;signal no error
|
||
doneErr move.b MMUsave(a6),d0 ;get previous MMU state in d0
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
SHOW MOVE.L SAVEA5(A6),A5 ;RESTORE A5
|
||
TST.B CRSRFLAG(A6) ;DID WE SHIELD THE CURSOR?
|
||
BEQ.S GOHOME ;=>NO, JUST RETURN
|
||
_SHOWCURSOR ;RESTORE CURSOR
|
||
GOHOME BSET #hiliteBit,HiliteMode ;reset hilite override, in case colormap was skipped
|
||
MOVE.L SAVESTK(A6),SP ;STRIP VARIABLE SIZED BUFFER
|
||
move.l stackHandle(a6),d0 ;did we allocate a handle?
|
||
beq.s @noTemp ;no, forget it.
|
||
move.l d0,a0 ;pass handle in a0
|
||
_DisposeTempBuffer ;dispose it.
|
||
move.l saveStkLowPt(a6),stkLowPt ;restart the sniffer <57>
|
||
move.l oldHiHeapMark(a6),HiHeapMark ;restore extent of stack
|
||
@noTemp MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
||
UNLINK PARAMSIZE,'STRETCHB'
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
stNoStack
|
||
tst.l StackFree(a6) ;did we run out of stack?
|
||
bpl.s SHOW ;no, just go home
|
||
movem.l d0-d3/a0-a2,-(sp) ;save state
|
||
neg.l d0 ;<BAL and KON 14Feb90>
|
||
move.l d0,stackFree(a6) ;<BAL and KON 14Feb90>
|
||
tst.l stackHandle(a6) ;have we been here before?
|
||
bne.s @noMem ;yes, forget it.
|
||
|
||
move.l HiHeapMark,oldHiHeapMark(a6) ;save extent of stack
|
||
moveq #4,d0 ; <KON 14Feb90>
|
||
swap d0 ;try for 256K <BAL 14Feb90>
|
||
_NewTempBuffer ;returns a0=handle, d0=size
|
||
move.l d0,d2 ;copy the actual size
|
||
beq.s @noMem ;if zero, we didn't get it.
|
||
@gotit move.l a0,stackHandle(a6) ;remember to dispose it later
|
||
sub.l #qdStackXtra,d2 ;leave room for interrupts
|
||
asr.l #2,d2 ;make cnt of longs
|
||
add.l d2,stackFree(a6) ;new free cnt
|
||
bmi.s @noMem ;didn't get enough
|
||
clr.l stkLowPt ;disable stack sniffer
|
||
move.l a7,a2 ;remember where save regs are
|
||
move.l (a0),a0 ;get ptr
|
||
exg a0,d0 ;get ptr in d0, size in a0
|
||
_rTranslate24To32 ;strip it
|
||
move.l d0,HiHeapMark ;set up stack limit for _stackSpace
|
||
add.l d0,a0 ;point to end of block
|
||
move.l 7*4(a7),-(a0) ;copy over return address
|
||
move.l a0,a7 ;move the stack there
|
||
|
||
movem.l (a2),d0-d3/a0-a2 ;restore state
|
||
rts
|
||
|
||
@noMem move.w #nsStackerr,QDErr
|
||
bra.s SHOW
|
||
|
||
;******************************************************************************************
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Source scanline merge routines.
|
||
; There are 3 routines: OneDeep, NDeep, and Average16and32
|
||
; These routines copy from srcaddr to srcbuf and do vertical
|
||
; merging of source if necessary.
|
||
;
|
||
; When promoting source (ie dither mode) to 32 bit/pixel, Average16and32
|
||
; is called.
|
||
;
|
||
; EXPECTS: D0: D1: D2: D3:
|
||
; D4: D5:!SRCALIGN D6:!DSTALIGN D7:!INVERTFLAG
|
||
; A0: A1: A2: A3:
|
||
; A4: A5: A6: A7:
|
||
;--------------------------------------------
|
||
|
||
|
||
VMergeTable
|
||
dc.l oneDeep-VMergeTable ;src 1-bit/pixel
|
||
dc.l ndeep-VMergeTable ;src 2-bit/pixel
|
||
dc.l ndeep-VMergeTable ;src 4-bit/pixel
|
||
dc.l ndeep-VMergeTable ;src 8-bit/pixel
|
||
dc.l Average16and32-VMergeTable ;src 16-bit/pixel
|
||
dc.l Average16and32-VMergeTable ;src 32-bit/pixel
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Loop to combine d7 pixels of source and dest using mask
|
||
;
|
||
; ENTRY:
|
||
; D0: scratch A0: scratch
|
||
; D1: scratch A1: mask ptr
|
||
; D2: scratch A2: destination
|
||
; D3: scratch A3: src and dst ptr
|
||
; D4: scratch A4: src pmtable A5: rowbytes
|
||
; D5: srcAlign A5: rowbytes
|
||
; D6: realDepth (pixel size)
|
||
; D7: byte Count (zero based)
|
||
;
|
||
; There are 12 different cases: all combinations of source and mask
|
||
; being either 16- or 32-bits/pixel and dest being any depth. A mask
|
||
; of $ff means take source. The mask value ranges from 0-$7f,$81-$100.
|
||
|