mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-11-19 06:30:59 +00:00
19650 lines
658 KiB
Plaintext
19650 lines
658 KiB
Plaintext
;
|
||
; File: QDciPatchROM.a
|
||
;
|
||
; Contains: Quickdraw patches for ci and descendents
|
||
;
|
||
; Written by: Konstantin Othmer
|
||
;
|
||
; Copyright: © 1990-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.
|
||
; <135> 8/18/92 SAH #1040323 <KON>: Fixed Indexed SeedCFill bug by making
|
||
; MakeScaleTbl check to see if fg color is black and bg color is
|
||
; white before it inverts the bg color when drawing to a one bit
|
||
; destination.
|
||
; <134> 6/25/92 SAH #1033729: Fixed a bug where we did not fully recognize when we
|
||
; were drawing to the alpha channel just before we jump into
|
||
; ScaleBlt. We now do this properly and take Stretch if drawing
|
||
; alpha stuff, otherwise take ScaleBlt.
|
||
; <133> 6/10/92 SAH Fixed problem where we would go to Stretch if ScaleBlt did not
|
||
; handle the copy and the source was greater than one bit. This
|
||
; was causing crashes in Freehand and Macromind Director.
|
||
; Associated with this, fixed problems where StkLowPt, HiHeapMark
|
||
; and your stack were getting munged when StretchBits couldn't get
|
||
; all the stack it wanted. Fixed notSrcCopy and SearchProc
|
||
; problems in MakeScaleTbl.
|
||
; <132> 6/8/92 SAH #1031825: Changed StretchBits so that it calls ScaleBlt whenever
|
||
; possible (indexed to indexed and indexed to direct). If the
|
||
; source is black/white only (from multColor), take BitBlt
|
||
; whenever source and dest are same depths and change ScaleColor
|
||
; to ColorizeInModeCase. Brought in Kon's changes for deciding
|
||
; when colorizing is a no-op.
|
||
; <131> 5/5/92 SAH Put fix for clipped vertical stretch back in for Cube-E
|
||
; <130> 4/10/92 SAH Moved the bSetup0 patch from this file to QuickDrawPatches.a.
|
||
; <129> 2/18/92 DTY Pete, y’broke the dang build! :)
|
||
; <128> 2/18/92 pvh Leave out bSETUP0 (questionable MOVE16 patch) to save a K or so
|
||
; of space in the System.
|
||
; <127> 2/17/92 pvh Removed QD patch for MOVE16. Fast blit abandoned for Regatta &
|
||
; Cube-E.
|
||
; <126> 10/16/91 KON Move some routines over to linked patches so this file can be
|
||
; expanded later.
|
||
; <125> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
|
||
; <124> 10/2/91 DTY Conditionalise <122> and <123> for TheFuture.
|
||
; <123> 10/2/91 KON Fix bug where CopyBits was crashing when vertically stretching a
|
||
; pixmap that is clipped at the top.
|
||
; <122> 10/1/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.
|
||
; <121> 9/25/91 JSM Change PsychoticFarmerAndLater to PsychoticFarmerOrLater.
|
||
; <120> 9/13/91 DTY What was I thinking? (Obviously I wasn’t.) Give the If a Then to
|
||
; keep it company.
|
||
; <119> 9/13/91 DTY Don’t build <117> for CubeE. (The optimization will build for
|
||
; PsychoticFarmer.)
|
||
; <118> 8/23/91 JSM Remove benign redefinition of TRUE and FALSE, which are now
|
||
; defined by the build script.
|
||
; <117> 7/23/91 KON Put in optimization for colorized text. If scalecase colorizing
|
||
; and depths are the same, use bitblt instead of stretch.
|
||
; <116> 7/17/91 JSM Remove obsolete SysVers conditionals, remove pre-7.0 code, and
|
||
; remove code that was ifdefed for 0.
|
||
; <115> 7/10/91 dba end of the forPost70 conditional; we are past 7.0 for good
|
||
; <114> 6/14/91 JL Removed benign redefinition of HWCfgFlags declared in Private.a.
|
||
; <113> 6/12/91 LN Removed #includes for private interfaces from public interfaces.
|
||
; Changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
|
||
; <112> 6/11/91 gbm Take out conditional for Regatta
|
||
; <111> 5/30/91 KON Checked in for Eclipse. Fixed most ScaleCase and modecase
|
||
; colorizing NOP checks.
|
||
; <110> 5/8/91 KON SetCCursor now in RAM because register A2 was getting trashed on
|
||
; multiple device systems. Also sped up stretch (right after map
|
||
; mode table). Some of the checks to see if colorizing is
|
||
; happening were wrong.
|
||
; <109> 4/10/91 KON mrr, gbm,csd: Calculate numer and denom to 32-bits, and then
|
||
; shift to make it fit in 15-bits if necessary. This fixes the
|
||
; problem where text was not scaling uniformly in pictures.
|
||
; <108> 4/9/91 KON csd: When reducing a picture, text would not reduce properly
|
||
; since both numer and denom are small and the divide underflows.
|
||
; The fix is not to reduce numer/denom if the picture is being
|
||
; scaled down.
|
||
; <107> 4/5/91 KON csd, BRC#85913: When putting a PixPat to a picture, PutPMData is
|
||
; called which trashes register A1. With this fix, A1 is saved and
|
||
; restored across the call to PutPMData.
|
||
; <106> 3/23/91 KON csd, WRKSHT#SAH-QD-58: ReduceD3D4 would hang because MapRatio
|
||
; would return a zero result. I removed calls to MapRatio (since
|
||
; ReduceD3D4 does the same work) and changed ReduceD3D4 so it
|
||
; won't hang.
|
||
; <105> 3/22/91 KON CSD, WRKSHT#7P-WA-054: Large text does not draw correctly since
|
||
; fromRect scaled by numer/denom can overflow a word.
|
||
; <104> 3/20/91 KON gbm, WRKSHT#SAH-QD-053: StdOpCodeProc sets the denom of a
|
||
; picture created with OpenCpicture. This is a problem since
|
||
; DrawPicture reduced numer/denom, and blasting denom to a large
|
||
; value makes the fraction invalid. The fix is to reduce
|
||
; numer/denom after the header has been processed. Also fixed
|
||
; WRKSHT#SAH-QD-056: Test for screen device in overlapping device
|
||
; test was backwards.
|
||
; <103> 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 removed this feature.
|
||
; <102> 3/19/91 KON DTY, CSD: BRC# 84342, Fixing 84342 made this file too big, so we
|
||
; removed NewPixMap and BitMapRgn and made them linked patches now
|
||
; included in QuickDrawPatches.a.
|
||
; <101> 3/18/91 KON GSC: WKSHT# SAH-QD-054 16-bit source shrinks crash because the
|
||
; average buffer is calculated from the promoted depth, rather
|
||
; than the real depth.
|
||
; <100> 3/14/91 JT After rolling in both Konstantine's changes and my own changes
|
||
; (build mix-up), this file was just too big to link properly
|
||
; (lame linker). Moved the GCD routines to the top of the file so
|
||
; that PC-relative references in the "cut back" installation code
|
||
; (hack) would be closer to the referenced routines. No one
|
||
; checked this change (late night) and there are no BRC or
|
||
; Worksheet reference numbers (not approved). Programmer
|
||
; Subliminal rides again!
|
||
; <99> 3/13/91 JT Added the glyph state opcode support to text and picture drawing
|
||
; under new QuickDraw. This opcode records the state of the Font
|
||
; Manager and TrueType so text will be drawn the same on picture
|
||
; playback as it was during picture recording. Also prevented font
|
||
; naming, line layout, and glyph state opcodes from being recorded
|
||
; in old pictures. Finally, changed the symbol UpdateRgn in
|
||
; ScrollRect to prevent compiler warnings. Code checked by KON and
|
||
; BAL. BRC numbers 82651 and 79185. Worksheet number KON-022.
|
||
; <98> 3/13/91 SMC CEL, Worksheet #AMR-029: Setup BGnotWhite based on xlateFlags
|
||
; before calling rgnblt. It was using whatever happened to be on
|
||
; the stack to decide whether or not to colorize.
|
||
; <97> 3/13/91 SMC forRegattaCPUs, fixed cpuFlag check in bSetup0 patch to include
|
||
; '040 processors and greater.
|
||
; <96> 3/6/91 KON CEL: BRC# 84369, WKSHT# B5-MTM-009 Register D0 was getting
|
||
; trashed when search procs were attached to direct destinations.
|
||
; Also, 32-bit to 16-bit conversion was not correct when modecase
|
||
; colorizing and destination is direct. MakeScaleTable began
|
||
; search for unused colors at the wrong place in the stack. If
|
||
; the value it was looking for happened to be there, that location
|
||
; on the stack was getting trashed.
|
||
; <95> 2/27/91 KON DTY BRC #82863: Some large text does not print in pictures
|
||
; because numer and denom overflow. Here I reduce the scale factor
|
||
; (the ratio of the rectangle sides) before scaling numer and
|
||
; denom. This prevents the overflow. Also rolled in 040 patches
|
||
; conditionalized by forRegattaCPUs. Finally, I now clear the
|
||
; dither flag if the destination is larger than the source and the
|
||
; color tables are the same. This is forPost70.
|
||
; <94> 2/19/91 KON DDG: WorkSheet #KS-003, MaskAddr in the stackframe is not
|
||
; initialized if there is not a mask. This was causing crashes in
|
||
; some cases since vertical merge scanline routines look at the
|
||
; maskaddr.
|
||
; <93> 2/4/91 KON DDG: BRC# unknown: PutPicPixPat should call PutDirectPMData for
|
||
; direct pixpats.
|
||
; <92> 1/25/91 KON DDG: BRC# 81625 and 81626, Add patch to BitsDevLoop to check for
|
||
; overlapping screen gDevices. If devices overlap, don't copy
|
||
; between them. Fix Bic and notBic transfer modes for
|
||
; CopyDeepMask.
|
||
; <91> 1/23/91 KON Optimize and clean up code that was rushed for B4. [smc]
|
||
; <90> 1/15/91 KON Change OffscreenVersion from 120 to 130. [CEL]
|
||
; <89> 1/14/91 KON Fixed pixmaps with nil color tables. Fixed CopyDeepMask when
|
||
; the mask is 1-bit. Fix bug in pmVersion macro. [SMC]
|
||
; <88> 1/11/91 KON Change updateGWorld so that returned flags get updated. Reduce
|
||
; Numer and Denom by GCD when drawing a picture. Fix problem with
|
||
; regions that showed up in KeyCaps. [CEL]
|
||
; <87> 12/13/90 KON If color table NIL on PixMap record into picture, put special
|
||
; color table with signature. On Picture playback, check for color
|
||
; table signature before throwing it away. [smc]
|
||
; <86> 12/3/90 KON Color Table in pictures, take three. If color table is NIL on
|
||
; picture creation, put a minimal color table to the picture.
|
||
; Always read color table in on playback; if it was nil in the PM
|
||
; record then throw it away. [smc]
|
||
; <85> 11/28/90 SMC Fixed slab/stretch/rgnblt pattern hiliting and fixed problem
|
||
; with L-shaped polygons getting optimized out as rectangles.
|
||
; With BAL.
|
||
; <84> 11/13/90 KON Fix problem with colorizing when dithering from an indexed src
|
||
; to an indexed destination. [smc]
|
||
; <83> 11/13/90 JSM <dba> ifdef come-from patch on _StdTxMeas inside GetRect for
|
||
; pre-7.0 only (the entire GetRect routine is patched out in 7.0),
|
||
; move the following patches to QuickDrawPatches.a: come-from
|
||
; patch on _PackBits inside PutPMData, come-from patch on
|
||
; _CopyBits inside CopyBits, come-from patch on _GetMaxDevice
|
||
; inside NewGWorld and NewTempScreenBuffer, come-from patch on
|
||
; _DisposeGWorld inside UpdateGWorld.
|
||
; <82> 11/12/90 KON Stretch now copies input rectangles and negative pmVersion
|
||
; pixmaps work. [smc]
|
||
; <81> 11/6/90 gbm the fact that change #80 broke the build with an assembly error
|
||
; was all Konstantin’s fault, really. My initials were on it, but
|
||
; I really didn’t have anything to do with it. (with sab)
|
||
; <80> 11/6/90 gbm All patches to picitem1 assume the result will be non-zero.
|
||
; Centralize this so that each opcode proc doesn't need to set
|
||
; this individually. [KON]
|
||
; <79> 11/6/90 SMC Fixed pattern alignment problem in QuickerDraw slab copy (KON).
|
||
; <78> 11/6/90 KON GetCTable should return NIL if call fails. This is at an offset
|
||
; of 6, not 8.
|
||
; <77> 10/31/90 SMC Added patches for alpha channel fixes with BAL.
|
||
; <76> 10/30/90 KON If color table is nil, don't save it to the picture. [SMC]
|
||
; <75> 10/29/90 KON If GetCTable fails, it should return NIL. There were cases where
|
||
; it returned without setting the return value at all. NewPixMap
|
||
; should always return an hres, vres value of 72.
|
||
; <74> 10/21/90 KON Move 16-bit and 32-bit arithmetic transfer modes to RAM. They
|
||
; are only about 1500 bytes and, unfortunately end with a hard
|
||
; branch to ROM. Made BitMapRgn create 64K rgns and accept
|
||
; pmVersion=4. Got rid of warning from the dandy new 3.2
|
||
; assembler.
|
||
; <73> 10/8/90 SMC Fixed pattern hilite setup for 16 and 32-bit slabbing.
|
||
; <72> 10/8/90 SMC Patched bTransparent and rTransparent to remove an optimization
|
||
; that was losing pattern data. Related changes in Arith8Blt.a.
|
||
; <71> 10/8/90 SMC Fixed right edge problem in bSubOver16.
|
||
; <70> 10/3/90 KON Change comefrom patch on packbits to check return address as a6
|
||
; relative instead of a7 relative since stdpixpat routine long
|
||
; aligns the stack.
|
||
; <69> 9/27/90 SMC Use common code to patch out specific entries in blit-loop
|
||
; offset tables. Also, fixed problem of sc32To8Dither not really
|
||
; getting hooked into RAMscDirTab8.
|
||
; <68> 9/25/90 KON Don't dither if source is 1-bit b&w and no resizing. Also fixed
|
||
; bug with StdOval introduced in last version. (With SMC).
|
||
; <67> 9/23/90 KON Patch standard drawing routines to call a new putpicverb which
|
||
; calls a new updatepat so CPictures can be created in old style
|
||
; ports.
|
||
; <66> 9/18/90 SMC Added fix to GetCPixel patch so it returns valid colors along
|
||
; the left and top edges of a gdevice.
|
||
; <65> 9/18/90 SMC Fixed Transparent, addMax, subOver, addMin pattern transfers.
|
||
; <64> 9/18/90 BG Removed <45> (and <46>). 040s are behaving more reliably now.
|
||
; <63> 9/16/90 KON NEEDED FOR BETA: Fix problem with saving pixpats into pictures.
|
||
; The fix is a comefrom putpicdata on packbits. It's a nasty fix.
|
||
; <62> 9/14/90 SMC Fixed problem bSloHilite where the background color was getting
|
||
; set to white after the first scanline hilited. This patch also
|
||
; includes changes made to stretch to handle vertically aligned
|
||
; hiliting.
|
||
; <61> 9/13/90 KON NEEDED FOR BETA: Fix problem where promoting pixmaps for dither
|
||
; and deep copymask didn't work since register D3 was not setup
|
||
; before call to SetupStretch.
|
||
; <60> 9/10/90 KON Added comefrom PaintVector patch to BitstoPix so that if the
|
||
; VCount in PaintVector is 0, the routine aborts.
|
||
; <59> 9/10/90 KON Fix one-bit to one-bit colorize copy.
|
||
; <58> 9/7/90 KON Patch MapRgn to return immediately if the region is wide open
|
||
; and rectangular.
|
||
; <57> 9/6/90 KON Fix stretching bugs and update to coincide with MacII stretch
|
||
; (always call search procs, search proc color is a VAR).
|
||
; <56> 8/29/90 KON Fix bug in GetMaxDevice ptch.
|
||
; <55> 8/28/90 KON Fix search procs so they are always called and treat RGB color
|
||
; passed as a VAR. Also added 32-bit clean versions of MaskPix
|
||
; pmTable and SrcPix pmTable to stretch stack frame. Fixed
|
||
; pictures so packtype 1 pixmaps can be saved in pictures. Fixed
|
||
; GetMaxDevice so it calls proper param error routine.
|
||
; <54> 8/24/90 PKE (per JT) Use new Script Mgr line layout values in GrafGlobals
|
||
; instead of soon-to-be-obsolete values in Script Mgr globals. Use
|
||
; new names picQdChExtra and picQdRunSlop instead of picSMgrChar
|
||
; and picSMgrSlop. Also deleted duplicate definition of
|
||
; PutPicWord.
|
||
; <53> 8/20/90 SMC Patched rXMASK8 to deal with the pattern offset as a unsigned
|
||
; instead of signed number.
|
||
; <52> 8/17/90 KON Fix transparent mode when it goes through stretch. Don't
|
||
; colorize arithmetic modes. Don't install DelSearch and DelComp
|
||
; on Erickson since the fix is in the ROM. This is not a misprint.
|
||
; <52> 8/17/90 KON Fix transparent mode when it goes through stretch. Don't
|
||
; colorize arithmetic modes.
|
||
; <51> 8/16/90 dba get rid of VisRgnChanged
|
||
; <50> 8/3/90 gbm axe warnings, again
|
||
; <49> 8/1/90 SMC Made more changes to non-black pattern and source hiliting blit
|
||
; loop patch (rSlowHilite) so that 16 and 32-bit cases work.
|
||
; <48> 7/31/90 SMC Fix RgnBlt so non-black patterned and source hiliting works.
|
||
; <47> 7/30/90 KON Roll over new versions of Stretch, MakeScaleTable, ColorMap,
|
||
; BitBlt.
|
||
; <46> 7/25/90 gbm took out local Macro def for EclipseNOP... BigBang breaks, big
|
||
; time. Also got rid of a couple of warnings...
|
||
; <45> 7/25/90 BG Added some EclipseNOPs for flakey 040s.
|
||
; <44> 7/24/90 KON Zero pmVersion after getting devices pixmap in PatConvert incase
|
||
; it's a gWorld and pmVersion was set indicating the baseAddr is a
|
||
; handle.
|
||
; <43> 7/20/90 gbm Change a few identifiers, just for the hell of it.
|
||
; <42> 7/16/90 DDG Fixed strange change history header; there were two <40> changes
|
||
; and this can screw up some of my scripts.
|
||
; <41> 7/11/90 gbm waste some asm warnings
|
||
; <40> 7/10/90 JT Some kind of PG&E fiasco here. Making sure this really gets
|
||
; checked in. Changes for <39> are not needed for SixPack, repeat
|
||
; not needed for SixPack.
|
||
; <39> 7/9/90 JT Remember to set the result to true after processing a line
|
||
; layout picture opcode in the PicItem1 patch. If we don't set
|
||
; this then the DrawPicture routine will stop processing the
|
||
; picture after encountering the line layout opcode, even if
|
||
; there is more interesting stuff in the picture. Special
|
||
; apologies to Konstantin Othmer and Peter Edberg. I accept full
|
||
; responsibility.
|
||
; <38> 6/30/90 DDG NEEDED FOR SIXPACK: Fixed another problem with trap $AB81. This
|
||
; really fixes the problem with the Color Picker introduced in rev
|
||
; 22.
|
||
; <37> 6/29/90 KON NEEDED FOR SIXPACK: Fixed entry point to trap $AB81. This
|
||
; fixes problem in Color Picker introduced in rev 22.
|
||
; <36> 6/29/90 KON Changed the order the fields in the picSave record or
|
||
; initialized to reflect changes in ColorEqu.a.
|
||
; <35> 6/27/90 KON Always clear the script manager state information in a picture
|
||
; save record.
|
||
; <34> 6/25/90 KON Obscure-show-hide leaves crsr hidden only, Obscure-hide-show
|
||
; leaves crsr obscured only.
|
||
; <33> 6/22/90 KON Ptch'd getPixel and GetCPixel so they work with 32-bit addressed
|
||
; pixmaps (pmVersion=4). Fixed NewGWorld so when called with
|
||
; noNewDevice bit set, the depth is taken from theGDevice.
|
||
; <32> 6/20/90 CL Took out rswapmmumode macro since it now exists in qdhooks.a.
|
||
; <31> 6/6/90 KON Change DelSearch and DelComp so Translate24to32 is called on the
|
||
; address. Added copymask with mode and rgn parameter. Added
|
||
; comeFrom GWorld calls ptch to GetMaxDevice to check for NIL
|
||
; devices.
|
||
; <30> 5/22/90 KON Fixed UpdateGWorld by patching DisposeGWorld so that the saved
|
||
; GWorld pointer and GDevice are updated before the GWorld is
|
||
; disposed.
|
||
; <29> 5/2/90 JT Copied the Script Manager specific changes from DrawPicture to
|
||
; this patch set.
|
||
; <28> 4/25/90 csd with BAL: changed the patch to BitsToPix to support the
|
||
; needs32BitAddressing flag in D2.
|
||
; <27> 3/30/90 KON Fix GetGWorldPixmap so it returns the right result.
|
||
; <26> 3/26/90 KON Comefrom patch to StdTxMeas should call through dispatch table
|
||
; instead of calling ROM directly. Use NewHandle,sys instead of
|
||
; changing theZone. Ptched InvertColor so comp procs work. Added
|
||
; VisRgnChanged (trap $A0A5).
|
||
; <25> 3/13/90 KON Fix 16-bit search proc.
|
||
; <24> 3/6/90 KON Fixed error term for vertical shrinking so expanding and then
|
||
; shrinking by an integral amount does not alter the image.
|
||
; <23> 3/2/90 KON Patch MakeITable so it looks for memory in Temp memory first,
|
||
; then system zone, and finally theZone. Consolidated old
|
||
; MakeITable patch which saved the zone. This also required
|
||
; patching DisposeTempBuffer to regain control at the end of
|
||
; patch.
|
||
; <22> 3/1/90 KON Add faster versions of traps AB80, AB81, and AB84 from QDUtil.a.
|
||
; This fixes a bug in 8-bit transparent modes.
|
||
; <21> 2/26/90 KON Added 16-bit shrink. Added ptch's for Dither32toGray and
|
||
; Dither16toGray so the error term is calculated correctly and
|
||
; black dots aren't left randomly.
|
||
; <20> 2/20/90 KON If LastTxGDevice is the same as the device we are disposing in
|
||
; DisposGDevice, move mainDevice into lastTxGDevice.
|
||
; <19> 2/16/90 KON NEEDED FOR 6.0.5: Fixed trashed register during shrink.
|
||
; <18> 2/15/90 KON Add comefrom patch to StdTxMeas so GetRect multiplies width by
|
||
; scaling factor.
|
||
; <17> 2/14/90 KON NEEDED FOR 6.0.5: ptch'd OpenPort for baseAddr change, make
|
||
; poly's, lines, arcs calc bit offset as long to support large
|
||
; rowbytes. This is done as a come-from ptch in GetSeek. Changed
|
||
; offscreenVersion to 120. ptch'd stNoStack to try 256K (not 64K),
|
||
; and updates StackFree correctly. Memory calculations in stretch
|
||
; now use longs.
|
||
; <16> 2/12/90 KON NEEDED FOR 6.0.5: Removed references to BaseAddr to support
|
||
; gDevices with changing base addresses.
|
||
; <15> 2/7/90 KON NEEDED FOR 6.0.5: Fixed 8-bit to 32-bit dither when stretching.
|
||
; <14> 2/6/90 KON NEEDED FOR 6.0.5: Changed some PutPicByte calls to DPutPicByte.
|
||
; Fixed header in OpenPicture.
|
||
; <13> 2/3/90 BAL Rolled in fix to StdBits patch to prevent the baseaddr's of
|
||
; non-mainscreens from being stripped by the call to BitsToPix
|
||
; during the one screen optimization.
|
||
; <12> 2/2/90 KON NEEDED FOR 6.0.5: Check useAverage after expanding in
|
||
; stScanLoop. Also took out RecoverHandle because it's patched
|
||
; elsewhere now.
|
||
; <11> 2/2/90 KON NEEDED FOR 6.0.5: Add ability to record 32-bit addressed pixmaps
|
||
; into pictures.
|
||
; <10> 2/2/90 KON NEEDED FOR 6.0.5: When recording an old picture flatten source
|
||
; pixmaps. Moved DDG's StdBits ptch from GetMaxDevice back into
|
||
; StdBits since most of StdBits is now patched out. Changed
|
||
; Pixmap32bit to use EXT32Bit gdevice flag. Added ptch to speed up
|
||
; CalcCMask and SeedCFill. Ptched Dither16toIndexed to get rid of
|
||
; error propagation.
|
||
; <9> 1/30/90 DDG NEEDED FOR 6.0.5: Fixed a bug in StdBits by patching out
|
||
; GetMaxDevice. The bug would cause pictures being recorded from a
|
||
; 32-bit screen into an old-style grafport to be garbage.
|
||
; <8> 1/30/90 DVB NEEDED FOR 6.0.5: Don't walk nonexisting portlists at boot time.
|
||
; <7> 1/30/90 KON NEEDED FOR 6.0.5: Dither during flatten in copybits,
|
||
; Dither32toBitmap and Dither16toBitMap added (stretch.a tables),
|
||
; altered modecase selection (comefrom in setup stretch), clear
|
||
; dither bit when recording an old picture.
|
||
; <6> 1/29/90 KON NEEDED FOR 6.0.5: Added index to index dithering, destination
|
||
; clip in stretch, patched out DitherCore8 and 32 to indexed
|
||
; dither by moving jmp tables to ram, added quickerdraw patches.
|
||
; <5> 1/23/90 KON NEEDED FOR 6.0.5: Added patches for InitGDevice, InitPort,
|
||
; BitsToPix (to support devices with changing base addresses), and
|
||
; OffscreenVersion.
|
||
; <4> 1/22/90 KON NEEDED FOR 6.0.5: Added patches for MakeITable, fixed pixPat
|
||
; expansion bug by patching PatConvert, patched GetCIcon so Icon
|
||
; size is calculated correctly, added selectors 22 and 23 to
|
||
; QDExtDispatcher.
|
||
; <3> 1/18/90 KON NEEDED FOR 6.0.5: Added DrawPicture, PicItem1, and StdOpCode
|
||
; patches. Fixed bug in StdOpCode so it handles header version -2
|
||
; correctly.
|
||
; <2> 1/16/90 KON NEEDED FOR 6.0.5: Fixed various picture patch bugs.
|
||
; <1> 1/16/90 KON NEEDED FOR 6.0.5: Checked in for the first time.
|
||
;
|
||
; To Do:
|
||
;
|
||
;--------------------------------------------------------------------------------
|
||
;
|
||
; Things that have been fixed on the Mac II, but will not be fixed on the ci:
|
||
;
|
||
; Arithmetic loops work when vertically aligned, horizontally overlapped on
|
||
; MacII, but will not be added to ci since it requires patching out the entire
|
||
; blit loop for a case that will probably never happen.
|
||
;
|
||
;--------------------------------------------------------------------------------
|
||
;
|
||
|
||
MACHINE MC68020 ; changed from MC68000 to MC68020 <24July89smb>
|
||
|
||
IF (&TYPE('SCRIPT_CHAR_EXTRA') = 'UNDEFINED') THEN
|
||
IF forROM THEN
|
||
SCRIPT_CHAR_EXTRA EQU 0
|
||
ELSE
|
||
SCRIPT_CHAR_EXTRA EQU 1
|
||
ENDIF
|
||
ENDIF
|
||
|
||
IF (&TYPE('hasGlyphState') = 'UNDEFINED') THEN
|
||
IF forROM THEN
|
||
hasGlyphState EQU 0
|
||
ELSE
|
||
hasGlyphState EQU 1
|
||
ENDIF
|
||
ENDIF
|
||
|
||
WholeErrors EQU 1
|
||
INCLUDE 'SysErr.a'
|
||
INCLUDE 'FastTraps.a'
|
||
INCLUDE 'PatchMacros.a'
|
||
INCLUDE 'paletteEqu.a' ;
|
||
INCLUDE 'palettePriv.a'
|
||
include 'quickEqu.a' ;
|
||
include 'colorequ.a'
|
||
INCLUDE 'qdHooks.a'
|
||
INCLUDE 'SysEqu.a'
|
||
INCLUDE 'VideoEqu.a'
|
||
include 'HardwarePrivateEqu.a'
|
||
INCLUDE 'fontPrivate.a'
|
||
INCLUDE 'ToolEqu.a'
|
||
|
||
GBLC &CurFile ;current file name used by DrawingVars
|
||
|
||
MACRO
|
||
_tstMFExists
|
||
move.l ($E00+$9f*4),d0 ;get address of unimplemented trap
|
||
cmp.l ($E00+$8f*4),d0 ;same as OSDispatch?
|
||
ENDM
|
||
|
||
START PROC EXPORT
|
||
IMPORT InitPatches
|
||
EXPORT StartPatch
|
||
|
||
RomVersions Aurora
|
||
|
||
|
||
StartPatch
|
||
; Bra InitPatches ; Carry out the patches
|
||
jmpFar InitPatches,a0 ;do the patches
|
||
DC.B 'ptch' ; resource type
|
||
DC.B 'QDci' ; patch ID.
|
||
|
||
ENDPROC
|
||
;
|
||
; Rom entry points used by several of the picture routines.
|
||
;
|
||
|
||
PutPicData EQU $32BD0
|
||
DPutPicOp EQU $32C90
|
||
PutPicOp EQU $32C96
|
||
DPutPicByte EQU $32BF0
|
||
PutPicByte EQU $32BF6
|
||
PutPicWord EQU $32C10
|
||
PutPicLong EQU $32C30
|
||
PutPicTable EQU $32FC0
|
||
PutPicRgn EQU $32CD0
|
||
PutPMData EQU $336D0
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;= =
|
||
;= RESIDENT PATCH INSTALL CODE IS BELOW THIS POINT =
|
||
;= =
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
;
|
||
; Add routines to calculate to reduce numer and denom by GCD
|
||
;
|
||
; These are called by DrawPicture and PicItem1
|
||
;
|
||
|
||
CalcGCD PROC EXPORT
|
||
; Routine returns GCD( d0, d1 ) using Euclidean method
|
||
; On Entry: D0 and D1 contain word size values to reduce
|
||
; On Exit: D0 and D1 both contain GCD
|
||
;
|
||
cmp.l d0,d1 ;while d0 != d1 (unsigned word compare)
|
||
beq.s @FoundGCD
|
||
bgt.s @D1isBigger ; if( d1 < d0 )
|
||
exg d0,d1 ; swap( d1, d0 )
|
||
@D1isBigger
|
||
sub d0,d1 ; d1 = d1 - d0
|
||
bra.s CalcGCD ;end while
|
||
@FoundGCD
|
||
rts ;d0 and d1 contain GCD
|
||
ENDPROC
|
||
|
||
;
|
||
; <124> Bring back SeedFill and CalcMask patches until the future is here.
|
||
;
|
||
|
||
if not(TheFuture) then ; <124>
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch SeedFill and CalcMask to check both up and down on the first pass of filling
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
SeedFill PROC EXPORT
|
||
EXPORT CalcMask
|
||
|
||
ciSeedFill EQU $35A4C
|
||
ciGoHome EQU $35B0A
|
||
;-------------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE SeedFill(srcPtr,dstPtr: Ptr;
|
||
; srcRow,dstRow,height,words: INTEGER;
|
||
; seedH,seedV: INTEGER)
|
||
;
|
||
MOVE.L (SP)+,A0 ;pop return addr
|
||
MOVEQ #-1,D0 ;get a long of -1
|
||
MOVE.L D0,-(SP) ;push edge = all ones
|
||
BRA.S SHARE ;share common code
|
||
|
||
|
||
;-------------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE CalcMask(srcPtr,dstPtr: Ptr;
|
||
; srcRow,dstRow,height,words: INTEGER);
|
||
;
|
||
CalcMask MOVE.L (SP)+,A0 ;pop return addr
|
||
MOVEQ #-1,D0 ;get a long of -1
|
||
MOVE.L D0,-(SP) ;push seed = (-1,-1)
|
||
CLR.L -(SP) ;push edge = zeros
|
||
SHARE MOVE.L A0,-(SP) ;restore return addr
|
||
|
||
|
||
|
||
;-------------------------------------------------------------------------
|
||
;
|
||
; LOCAL PROCEDURE MakeMask(srcPtr,dstPtr: Ptr;
|
||
; srcRow,dstRow,height,words: INTEGER;
|
||
; seedH,seedV: INTEGER;
|
||
; edge: LongInt);
|
||
;
|
||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 24
|
||
srcPtr EQU PARAMSIZE+8-4 ;long
|
||
dstPtr EQU srcPtr-4 ;long
|
||
srcRow EQU dstPtr-2 ;word
|
||
dstRow EQU srcRow-2 ;word
|
||
height EQU dstRow-2 ;word
|
||
words EQU height-2 ;word
|
||
seedH EQU words-2 ;word
|
||
seedV EQU seedH-2 ;word
|
||
edge EQU seedV-4 ;long
|
||
|
||
|
||
dstBump EQU -2 ;word
|
||
saveStk EQU dstBump-4 ;long
|
||
varSize EQU saveStk ;total locals
|
||
|
||
|
||
LINK A6,#varSize ;allocate stack frame
|
||
MOVEM.L D3-D7/A2-A4,-(SP) ;save regs
|
||
MOVE.L SP,saveStk(A6) ;save stack pointer
|
||
|
||
;
|
||
; prepare height and words for DBRA count. Quit if either <= 0.
|
||
;
|
||
MOVE words(A6),D5 ;get count of words
|
||
BLE GOHOME ;quit if words <= 0
|
||
SUB #1,D5 ;subtract 1 for DBRA count
|
||
SUB #1,height(A6) ;convert height to DBRA
|
||
BLT GOHOME ;quit if height <= 0
|
||
|
||
;
|
||
; init dst to all ones:
|
||
;
|
||
MOVE words(A6),D0 ;get # of words
|
||
ADD D0,D0 ;double for bytes
|
||
MOVE dstRow(A6),D1 ;get dstRow
|
||
SUB D0,D1 ;subtract bytes for dstBump
|
||
MOVE D1,dstBump(A6) ;save dstBump for later
|
||
MOVE.L dstPtr(A6),A2 ;point to dst
|
||
MOVEQ #-1,D0 ;get some black
|
||
MOVE height(A6),D3 ;init DBRA rowCount
|
||
BLACK1 MOVE D5,D2 ;init DBRA wordCount
|
||
BLACK2 MOVE D0,(A2)+ ;put a word of black
|
||
DBRA D2,BLACK2 ;loop all words in row
|
||
ADD D1,A2 ;bump to next row
|
||
DBRA D3,BLACK1 ;loop height rows
|
||
|
||
;
|
||
; clear one dst pixel at seedH,seedV
|
||
;
|
||
MOVE seedV(A6),D0 ;get seed vert coord
|
||
BLT.S NOSEED ;skip if neg (no seed)
|
||
MULU dstRow(A6),D0 ;mul times dst row
|
||
MOVE.L dstPtr(A6),A0 ;point to dst
|
||
ADD.L D0,A0 ;add vertical offset <EHB 28-Oct-85>
|
||
MOVE seedH(A6),D0 ;get seed horiz coord
|
||
MOVE D0,D1 ;copy seedH
|
||
ASR #3,D0 ;div by 8 for byte
|
||
NOT D1 ;invert bit number
|
||
BCLR D1,0(A0,D0) ;clear seed pixel
|
||
NOSEED
|
||
;
|
||
; allocate a scanline buffer of ones or zeros on the stack:
|
||
;
|
||
MOVE.L edge(A6),D6 ;get zero or all ones
|
||
MOVE D5,D1 ;get longCount
|
||
NEXTBUF MOVE D6,-(SP) ;write a word of ones or zeros
|
||
DBRA D1,NEXTBUF ;loop all words
|
||
|
||
MOVE.L srcPtr(A6),A0 ;point to top of src
|
||
MOVE.L dstPtr(A6),A2 ;point to top of dst
|
||
st d7 ;set dirty flag to force <KON 24JAN91>
|
||
; bra.s FirstPass ;search up and down <KON 24JAN91>
|
||
;NXTPASS SF D7 ;clear dirty flag
|
||
FirstPass
|
||
jmpROM ciSeedFill
|
||
GoHome
|
||
jmpROM ciGoHome
|
||
ENDPROC
|
||
endif ; <124> of not TheFuture
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to set up pattern hilite correctly when slabbing to 16 and 32-bit destinations.
|
||
; <08OCT90 SMC> <73>
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
SlabMode PROC EXPORT
|
||
|
||
&CurFile SETC 'DRAWSLAB'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
ciSkipHilite EQU $2FEF2
|
||
ciClrInvBit EQU $2FF38
|
||
ciPatPrep EQU $2FEFC
|
||
|
||
AND #$37,D2 ;toss all but arithmetic, hilite bits + variant bits
|
||
BCLR #5,D2 ;arithmetic mode?
|
||
BEQ.S @clrInvBit ;if so, don’t clear the invert bit
|
||
BCLR #4,D2 ;hilite?
|
||
BEQ.S @skipHilite ;if not, don’t add hilite offset
|
||
CMP #16,dstPix+pixelSize(A6)
|
||
BLT.S @1
|
||
jsrROM ciPatPrep
|
||
@1: MOVEQ #8,D2 ;hilite is at $20, so put ($20 / 2) - 8 here
|
||
@skipHilite
|
||
jmpROM ciSkipHilite
|
||
@clrInvBit
|
||
AND #$3,D2 ;GET LO 2 BITS OF MODE, clearing bit 4 also
|
||
BNE.S @4 ;if not a copy mode, skip over this stuff
|
||
TST.B alphaMode(A6) ;are drawing in alpha mode?
|
||
BEQ.S @4 ;no, use normal loops
|
||
LEA slMASK8A,A4 ;get address of small pat alpha copy loop
|
||
CMP #4,PATROW(A6) ;large pattern?
|
||
BLE.S @3 ;no, exit
|
||
LEA slXMASK8A,A4 ;yes, use big pattern copy loop
|
||
@3 RTS
|
||
@4 jmpROM ciClrInvBit
|
||
; CMP #4,PATROW(A6) ;NEED EXPANDED PATTERN?
|
||
|
||
;ciPatPrep
|
||
; MOVE #$1F,patHMask(A6) ;set up patHMask for 1 long for small patterns
|
||
; CMP #4,PATROW(A6) ;NEED EXPANDED PATTERN?
|
||
; BLE.S @1 ;if not, all ready to go
|
||
; MOVEM.L D2/D3,-(SP) ;save work registers...
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 58: (pat as mask) background color <--> hilite color
|
||
; <85> fixed slab hiliting with pixpats.
|
||
;
|
||
; Note that a fast case could be implemented (like in rgnblt, bitblt) if the pattern source
|
||
; was known to be black.
|
||
|
||
ciArithSetup EQU $2F3A0
|
||
EXPORT slHilite, RAMslArith16Tab, RAMslArith32Tab
|
||
|
||
slHilite
|
||
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
||
jsrROM ciArithSetup ;set up registers for slab bitblt
|
||
BFEXTU transColor(A6){0:D7},D5 ;get a pixel of the background color
|
||
BFEXTU hilitColor(A6){0:D7},D0 ;get a pixel of the hilite color
|
||
MOVE.L D0,A0 ;save the hilite color pixel in a free register
|
||
TST D2 ;TEST NUMBER OF BYTES TO DO
|
||
BRA.S @loopEnd
|
||
@loopRight
|
||
AND.L D1,D3 ;combine left and right masks
|
||
@loopTop
|
||
ADD.L D7,D6 ;advance the pattern
|
||
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
||
|
||
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
||
BEQ.S @skip
|
||
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
||
CMP.L D5,D0 ; <85>
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A1){D4:D7},D0 ;get a pixel of the destination
|
||
CMP.L D5,D0 ;same as the background color?
|
||
BNE.S @tryNew
|
||
MOVE.L A0,D0 ;put hilite color in data register
|
||
BFINS D0,(A1){D4:D7} ;move hilite color to destination
|
||
BRA.S @skip
|
||
@tryNew
|
||
CMP.L A0,D0 ;same as new color?
|
||
BNE.S @skip
|
||
|
||
BFINS D5,(A1){D4:D7} ;move to the destination
|
||
@skip
|
||
ADD.L D7,D4 ;bump destination and mask
|
||
MOVE D4,D0 ;copy destination offset
|
||
AND #31,D0 ;combine with long sized mask
|
||
BNE.S @loopTop ;loop if haven’t finished a long yet
|
||
MOVEQ #-1,D3 ;flush the mask
|
||
SUBQ #1,D2 ;decrement long counter
|
||
@loopEnd
|
||
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
BEQ.S @loopRight
|
||
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
||
RTS
|
||
|
||
slAvg16 EQU $0
|
||
slAddPin16 EQU $0
|
||
slAddOver16 EQU $0
|
||
slSubPin16 EQU $0
|
||
slTransparent16 EQU $0
|
||
slMax16 EQU $0
|
||
slSubOver16 EQU $0
|
||
slMin16 EQU $0
|
||
|
||
slAvg32 EQU $0
|
||
slAddPin32 EQU $0
|
||
slAddOver32 EQU $0
|
||
slSubPin32 EQU $0
|
||
slTransparent32 EQU $0
|
||
slMax32 EQU $0
|
||
slSubOver32 EQU $0
|
||
slMin32 EQU $0
|
||
|
||
RAMslArith16Tab
|
||
slArith16Tab
|
||
DC.L slAvg16-slArith16Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
||
DC.L slAddPin16-slArith16Tab ;12 PAT + DST --> DST (pin to max)
|
||
DC.L slAddOver16-slArith16Tab ;13 PAT + DST --> DST (no pin)
|
||
DC.L slSubPin16-slArith16Tab ;16 DST - PAT --> DST (pin to min)
|
||
DC.L slTransparent16-slArith16Tab ;18 PAT less bg --> DST
|
||
DC.L slMax16-slArith16Tab ;1A MAX(PAT, DST) --> DST
|
||
DC.L slSubOver16-slArith16Tab ;1C DST - PAT --> DST (no pin)
|
||
DC.L slMin16-slArith16Tab ;1E MIN(PAT, DST) --> DST
|
||
DC.L slHilite-slArith16Tab ;20 (pat as mask) hilite <--> background
|
||
|
||
RAMslArith32Tab
|
||
slArith32Tab
|
||
DC.L slAvg32-slArith32Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
||
DC.L slAddPin32-slArith32Tab ;12 PAT + DST --> DST (pin to max)
|
||
DC.L slAddOver32-slArith32Tab ;13 PAT + DST --> DST (no pin)
|
||
DC.L slSubPin32-slArith32Tab ;16 DST - PAT --> DST (pin to min)
|
||
DC.L slTransparent32-slArith32Tab ;18 PAT less bg --> DST
|
||
DC.L slMax32-slArith32Tab ;1A MAX(PAT, DST) --> DST
|
||
DC.L slSubOver32-slArith32Tab ;1C DST - PAT --> DST (no pin)
|
||
DC.L slMin32-slArith32Tab ;1E MIN(PAT, DST) --> DST
|
||
DC.L slHilite-slArith32Tab ;20 (pat as mask) hilite <--> background
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: PATTERN --> DST
|
||
;
|
||
; Slab small pattern copy using alpha mask
|
||
;
|
||
slMASK8A
|
||
MOVE.L alphaMask(A6),D0 ;get alpha mask
|
||
AND.L D0,D1 ;clip left mask with alpha mask
|
||
AND.L D0,D3 ;clip right mask with alpha mask
|
||
MOVE.L D0,A0 ;save copy of alpha mask
|
||
TST D2 ;re-test long count
|
||
BRA.S DO8A
|
||
END8A AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
||
NEXT8A MOVE.L D6,D0 ;GET PATTERN DATA
|
||
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
||
AND.L D3,D0 ;MASK PATTERN DATA
|
||
NOT.L D3 ;MAKE NOTMASK
|
||
AND.L (A1),D3 ;AND NOTMASK WITH OLD DST
|
||
OR.L D0,D3 ;FILL HOLE WITH PATTERN
|
||
MOVE.L D3,(A1)+ ;UPDATE DST
|
||
MOVE.L A0,D3 ;FLUSH MASK to alpha mask
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
DO8A BGT NEXT8A ;LOOP FOR ALL LONGS IN ROW
|
||
BEQ END8A ;DO LAST LONG WITH MASK
|
||
RTS
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: BIG PATTERN --> DST
|
||
;
|
||
; Slab big pattern copy using alpha mask
|
||
;
|
||
slXMASK8A
|
||
MOVE D7,-(SP) ;SAVE WORK REGISTER
|
||
MOVE PATHMASK(A6),D7 ;GET HORIZ MASK
|
||
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
||
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
||
AND D7,D6 ;MASK INDEX INTO PATTERN
|
||
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
||
ADD.L PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN
|
||
MOVE.L alphaMask(A6),D0 ;get alpha mask
|
||
AND.L D0,D1 ;clip left mask with alpha mask
|
||
AND.L D0,D3 ;clip right mask with alpha mask
|
||
MOVE.L D0,A0 ;save copy of alpha mask
|
||
TST D2 ;re-test long count
|
||
BRA.S XDO8A
|
||
|
||
XEND8A AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
||
XNEXT8A MOVE.L 0(A3,D6),D0 ;GET PATTERN DATA
|
||
ADDQ #4,D6 ;BUMP PATTERN INDEX
|
||
AND D7,D6 ;MASK INDEX INTO PATTERN
|
||
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
||
AND.L D3,D0 ;MASK PATTERN DATA
|
||
NOT.L D3 ;MAKE NOTMASK
|
||
AND.L (A1),D3 ;AND NOTMASK WITH OLD DST
|
||
OR.L D0,D3 ;FILL HOLE WITH PATTERN
|
||
MOVE.L D3,(A1)+ ;UPDATE DST
|
||
MOVE.L A0,D3 ;FLUSH MASK to alpha mask
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
XDO8A BGT XNEXT8A ;LOOP FOR ALL LONGS IN ROW
|
||
BEQ XEND8A ;DO LAST LONG WITH MASK
|
||
MOVE (SP)+,D7 ;RESTORE WORK REGISTER
|
||
RTS
|
||
|
||
|
||
EXPORT RAMFastSlabMode
|
||
|
||
;--------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE FastSlabMode, Call when rect clipped and pattern black.
|
||
;
|
||
; INPUT: D2: MODE, CLOBBERED mode 0=black, 1=xor, 2=white
|
||
; OUTPUT: A4: MODECASE
|
||
;
|
||
|
||
ciFASTTAB EQU $30050
|
||
|
||
;NOTE: FAST8A,10A and 11A must be before FASTTAB so that offsets are positive
|
||
|
||
ALIGN Alignment
|
||
|
||
; FAST FOREGROUND/BACKGROUND SLAB USING ALPHA MASK:
|
||
|
||
FAST11A MOVE.L D5,D4 ;USE BKCOLOR INSTEAD OF FGCOLOR
|
||
FAST8A MOVE.L alphaMask(A6),D0 ;GET ALPHA MASK
|
||
AND.L D0,D1 ;CLIP LEFTMASK WITH ALPHAMASK
|
||
AND.L D0,D3 ;CLIP RIGHTMASK WITH ALPHAMASK
|
||
MOVE.L D0,A0 ;save copy of alpha mask
|
||
TST D2 ;RETEST THE LONG COUNT
|
||
BEQ.S MERGE8A ;BR IF ALL IN ONE LONG
|
||
MOVE.L D3,D0 ;GET LEFTMASK
|
||
NOT.L D0 ;GET NOT LEFTMASK
|
||
AND.L (A1),D0 ;PUNCH OUT DST
|
||
AND.L D4,D3 ;OR FGCOLOR INTO LEFTMASK
|
||
OR.L D3,D0 ;COMBINE SRC AND DST
|
||
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
||
SUB #2,D2 ;ADJUST LONGCOUNT FOR DBRA
|
||
BLT.S LAST8A ;BR IF NO UNMASKED LONGS
|
||
MOVE.L A0,D3 ;GET CENTER MASK
|
||
NOT.L D3 ;GET NOT OF MASK
|
||
LOOP8A MOVE.L (A1),D0 ;GET THE DST
|
||
EOR.L D4,D0 ;APPLY FGCOLOR
|
||
AND.L D3,D0 ;MASK OUT PART OF DST
|
||
EOR.L D4,D0 ;REAPPLY FGCOLOR
|
||
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
||
DBRA D2,LOOP8A ;LOOP ALL UNMASKED LONGS
|
||
BRA.S LAST8A ;GO DO LAST LONG
|
||
MERGE8A AND.L D3,D1 ;COMBINE LEFTMASK AND RIGHTMASK
|
||
LAST8A MOVE.L D1,D0 ;GET RIGHTMASK
|
||
NOT.L D0 ;GET NOT RIGHTMASK
|
||
AND.L (A1),D0 ;PUNCH OUT DST
|
||
AND.L D4,D1 ;OR FGCOLOR INTO RIGHTMASK
|
||
OR.L D1,D0 ;COMBINE SRC AND DST
|
||
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
||
RTS ;AND RETURN
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
; FAST XOR SLAB USING ALPHA MASK:
|
||
|
||
FAST10A MOVE.L alphaMask(A6),D0 ;GET ALPHAMASK
|
||
AND.L D0,D1 ;CLIP LEFTMASK WITH ALPHAMASK
|
||
AND.L D0,D3 ;CLIP RIGHTMASK WITH ALPHAMASK
|
||
TST D2 ;RETEST THE LONG COUNT
|
||
BEQ.S MERGE10A ;BR IF ALL IN ONE LONG
|
||
EOR.L D3,(A1)+ ;XOR LEFTMASK INTO DST
|
||
SUB #2,D2 ;ADJUST LONGCOUNT FOR DBRA
|
||
BLT.S LAST10A ;BR IF NO UNMASKED LONGS
|
||
LOOP10A EOR.L D0,(A1)+ ;INVERT A LONG OF DST
|
||
DBRA D2,LOOP10A ;LOOP ALL UNMASKED LONGS
|
||
LAST10A EOR.L D1,(A1)+ ;XOR RIGHTMASK INTO DST
|
||
RTS ;AND RETURN
|
||
MERGE10A AND.L D3,D1 ;COMBINE LEFTMASK AND RIGHTMASK
|
||
EOR.L D1,(A1)+ ;XOR RIGHTMASK INTO DST
|
||
RTS ;AND RETURN
|
||
|
||
|
||
RAMFastSlabMode
|
||
leaROM ciFASTTAB,A4
|
||
AND #$3,D2 ;GET LO 2 BITS OF MODE
|
||
TST.B alphaMode(A6) ;are we drawing in alpha mode?
|
||
BEQ.S @1 ;no, use original fast cases
|
||
LEA FASTTAB,A4 ;POINT TO MODE TABLE
|
||
@1 MOVE.B 0(A4,D2),D2 ;GET OFFSET FROM FASTTAB
|
||
SUB D2,A4 ;GET CASE JUMP ADDRESS
|
||
RTS
|
||
|
||
FASTTAB DC.B FASTTAB-FAST8A ;alpha BLACK (foreground)
|
||
DC.B FASTTAB-FAST10A ;alpha XOR
|
||
DC.B FASTTAB-FAST11A ;alpha WHITE (background)
|
||
DC.B 0 ;alignment
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to fix transparent rgnblt. Removes optimization that was losing pattern data.
|
||
; <08Oct90 SMC> <72>
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
rTransparent PROC EXPORT
|
||
IMPORT rTransparent8
|
||
|
||
ciNxtNewSrc EQU $2ABAC
|
||
|
||
&CurFile SETC 'RGNBLT'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
TST.L D3 ;right to left?
|
||
BMI.S @1 ;if so, skip
|
||
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
|
||
BEQ rTransparent8 ;yes, go use quickdraw
|
||
@1: LEA @RealrTransparent,A0
|
||
MOVE.L A0,ModeCase(A6)
|
||
@RealrTransparent
|
||
MOVE patHMask(A6),D1 ;set up source constriction
|
||
MOVE pixInLong1(A6),A0 ;set up absolute long bump
|
||
MOVE longBump(A6),A2 ;set up long bump
|
||
BFEXTU D5{0:D7},D0
|
||
MOVE.L D0,A1 ;set up pixel of background
|
||
@loopTop
|
||
AND D1,D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU (A4){D4:D7},D0 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A3){D6:D7},D0 ;get a pixel of the source (zeros top word)
|
||
CMP.L D0,A1 ;same as a pixel of the background?
|
||
BEQ.S @skip
|
||
BFINS D0,(A5){D4:D7} ;move to the destination
|
||
@skip
|
||
ADD.L D3,D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L D3,D4 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
jmpROM ciNxtNewSrc
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to fix right edge problem in bSubOver16. The right pixel was getting moved
|
||
; from the source using a move.l instead of a move.w. As a result, the pixel one to
|
||
; the right of the last source pixel was being used.
|
||
; Table from BitBlt.a moved to RAM.
|
||
; <SMC 08Oct90> <71>
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
RAMbArith16Tab PROC EXPORT
|
||
|
||
bAvg16 EQU $0
|
||
bAddPin16 EQU $0
|
||
bAddOver16 EQU $0
|
||
bSubPin16 EQU $0
|
||
bTransparent16 EQU $0
|
||
bMax16 EQU $0
|
||
;bSubOver16 EQU $0 ;This routine added below
|
||
bMin16 EQU $0
|
||
bAvg16Half EQU $0
|
||
|
||
|
||
bArith16Tab
|
||
DC.L bAvg16-bArith16Tab ;18 AVG(SRC, DST, WEIGHT) --> DST
|
||
DC.L bAddPin16-bArith16Tab ;1A SRC + DST --> DST (pin to max)
|
||
DC.L bAddOver16-bArith16Tab ;1C SRC + DST --> DST (no pin)
|
||
DC.L bSubPin16-bArith16Tab ;1E DST - SRC --> DST (pin to min)
|
||
DC.L bTransparent16-bArith16Tab ;20 SRC less bg --> DST
|
||
DC.L bMax16-bArith16Tab ;22 MAX(SRC, DST) --> DST
|
||
DC.L bSubOver16-bArith16Tab ;24 DST - SRC --> DST (no pin)
|
||
DC.L bMin16-bArith16Tab ;26 MIN(SRC, DST) --> DST
|
||
DC.L bAvg16Half-bArith16Tab ;50% case
|
||
|
||
|
||
&CurFile SETC 'BITBLT'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
ciNxtNewSrc32 EQU $2CC78
|
||
|
||
bSubOver16
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
move.w #$3def,d0 ;get high bit clearing mask
|
||
move.w #$4210,d1 ;get high bit mask
|
||
|
||
@loopTop
|
||
move.w d1,d3 ;copy high bit mask
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
add.w a3,a0 ;bump bidirectionally
|
||
and.w d7,d3 ;remember src msb's
|
||
eor.w d1,d3 ;invert src msb's
|
||
and.w d0,d7 ;mask out stragglers
|
||
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb <SMC 08OCT90> <71>
|
||
move.w d1,d4 ;copy high bit mask
|
||
and.w d5,d4 ;remember dst msb's
|
||
and.w d0,d5 ;mask out high byte
|
||
or.w d1,d5 ;force high bits on
|
||
|
||
sub.w d7,d5 ;compute dst - src
|
||
eor.w d3,d4 ;compute partial sum of msb's
|
||
eor.w d4,d5 ;compute partial sum of msb's
|
||
|
||
move.w d5,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
jmpROM ciNxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to fix transparent bitblt. Removes an optimization that was losing pattern
|
||
; data. It also fixes transparent copies between overlapping sources and destinations.
|
||
; <08Oct90 SMC> <72>
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
EXPORT bTransparent
|
||
IMPORT bTransparent8
|
||
|
||
ciNxtNewSrc EQU $2CC8A
|
||
|
||
bTransparent
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
lea @RealbTransparent1,a1 ; <08Oct90 SMC> <72>
|
||
tst.l (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bmi.s @1 ; <14AUG90 KON>
|
||
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode? <08Oct90 SMC> <72>
|
||
BEQ bTransparent8 ; <08Oct90 SMC> <72>
|
||
BRA.S @RealbTransparent1 ; <08Oct90 SMC> <72>
|
||
@1: sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
lea @RealbTransparent,a1 ;remember correct entry point for remaining scans <14AUG90 KON>
|
||
@RealbTransparent
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbTransparent1
|
||
|
||
cmp.w #32,d7 ;1 pixel per long? <08Jan89 BAL>
|
||
beq.s @firstMask ;yes, d2 is unfortunately zero <08Jan89 BAL>
|
||
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
CMP.L D3,A3 ;same as a pixel of the background?
|
||
BEQ.S @skip
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
@loopEnd
|
||
ADDQ #1,D2 ;check to see if we ended on a natural long
|
||
BEQ.S @noPixelAlign ;if so, expect a -1 here
|
||
SUB.L (SP),D6 ;unbump source
|
||
SUB.L (SP),D0 ;unbump destination
|
||
BRA.S @loopEnd
|
||
@noPixelAlign
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
jmpROM ciNxtNewSrc
|
||
|
||
|
||
|
||
EXPORT bXMAIN8,bSETUP8,bLONG8,bXLONG8
|
||
|
||
cibXMAIN8 EQU $2D1B0
|
||
cibSETUP8 EQU $2CFC0
|
||
cibLONG8 EQU $2CF30
|
||
cibXLONG8 EQU $2D150
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||
; PATTERN ALREADY HAS COLOR IN IT, SO NONE IS ADDED
|
||
;
|
||
bXMAIN8 TST.B alphaMode(A6) ;drawing in alpha mode? ;Start of alpha changes block
|
||
BEQ.S @bXMAIN8G ;no, use normal loop
|
||
MOVE.L alphaMask(A6),D3 ;get alpha mask
|
||
AND.L D3,D1 ;AND ALPHA WITH LEFT MASK
|
||
MOVE.L D1,FIRSTMASK(A6) ;SAVE THAT RESULT
|
||
AND.L D3,D5 ;AND ALPHA WITH RIGHT MASK
|
||
BRA.S @bX8 ;jump into alpha loop
|
||
@bXMAIN8G jmpROM cibXMAIN8
|
||
|
||
ALIGN Alignment
|
||
|
||
@bXEND8 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
@bX8 MOVE.L 0(A4,D6),D4 ;GET PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L (A5),D0 ;GET DST
|
||
EOR.L D0,D4 ;APPLY DST TO PATTERN
|
||
AND.L D1,D4 ;MASK OFF EDGE
|
||
EOR.L D0,D4 ;REAPPLY DST
|
||
MOVE.L D4,(A5)+ ;PUT RESULT TO DST
|
||
MOVE.L D3,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ @bXEND8 ;DO LAST LONG WITH LASTMASK
|
||
BLT.S @nxtBigPat ;BUMP TO NEXT PATTERN ROW
|
||
SUBQ #1,D2 ;DEC LONG COUNT
|
||
|
||
NOT.L D3 ;REVERSE ALPHA MASK
|
||
@alpha MOVE.L 0(A4,D6),D4 ;GET PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L (A5),D0 ;GET DST
|
||
EOR.L D4,D0 ;APPLY PATTERN TO DST
|
||
AND.L D3,D0 ;MASK WITH ALPHA MASK
|
||
EOR.L D4,D0 ;REAPPLY PATTERN
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
DBRA D2,@alpha ;DEC LONG COUNT
|
||
NOT.L D3 ;REVERSE ALPHA MASK BACK
|
||
BRA.S @bXEND8 ;DO LAST LONG WITH LASTMASK
|
||
|
||
@nxtBigPat clr.w d6 ;make it unsigned
|
||
SWAP D6 ;GET VERT POSITION IN PAT
|
||
SUB.l D6,A4 ;GET BACK PAT BASE
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
||
AND PATVMASK(A6),D6 ;AND MASK WITHIN PATTERN
|
||
ADD.l D6,A4 ;BUMP TO PROPER VERT
|
||
SWAP D6 ;SAVE VERTICAL POSITION
|
||
MOVE PATHPOS(A6),D6 ;INIT HORIZONTAL OFFSET
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
beq GOHOME ;LOOP FOR ALL SRCROWS
|
||
MOVE.L FIRSTMASK(A6),D1 ;MASK:=FIRSTMASK
|
||
MOVE LONGCNT(A6),D2 ;GET LONGCOUNT
|
||
bra.s @bX8 ;go do next row
|
||
;end of alpha changes block
|
||
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||
;
|
||
bSETUP8 TST.B alphaMode(A6) ;drawing in alpha mode?
|
||
BEQ.S @bSETUP8 ;no, use normal loop
|
||
MOVE.L alphaMask(A6),D3 ;get alpha mask
|
||
AND.L D3,D1 ;AND ALPHA WITH LEFT MASK
|
||
MOVE.L D1,FIRSTMASK(A6) ;SAVE THAT RESULT
|
||
AND.L D3,D5 ;AND ALPHA WITH RIGHT MASK
|
||
BRA.S @bMAIN8 ;jump into alpha loop
|
||
|
||
@bEND8 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
@bMAIN8 MOVE.L D1,D0 ;COPY MASK
|
||
AND.L D6,D1 ;GET MASKED PATTERN
|
||
NOT.L D0 ;REVERSE MASK
|
||
AND.L (A5),D0 ;GET NOT MASKED DST
|
||
OR.L D1,D0 ;COMBINE PATTERN AND DST
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
MOVE.L D3,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT @bMAIN8 ;LOOP TILL LAST LONG
|
||
BEQ @bEND8 ;DO LAST LONG WITH LASTMASK
|
||
@NXTPAT ADD #1,D7 ;BUMP PATTERN SELECTOR
|
||
AND #$0F,D7 ;MOD 16 FOR 16 LONG REPEAT
|
||
MOVE.L ([EXPAT,A6],D7*4),D6 ;GET FIRST PATTERN DATA
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BEQ.S GOHOME ;LOOP FOR ALL SRCROWS
|
||
MOVE.L FIRSTMASK(A6),D1 ;MASK:=FIRSTMASK
|
||
MOVE LONGCNT(A6),D2 ;GET LONGCOUNT
|
||
BRA.S @bMAIN8 ;GO NEXT LINE
|
||
@bSETUP8 jmpROM cibSETUP8
|
||
GOHOME RTS
|
||
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; OPTIMIZE MODE 8 OR 12 IF DST FITS IN ONE LONG (VERT LINES ETC)
|
||
;
|
||
bLONG8 AND.L alphaMask(A6),D1
|
||
jmpROM cibLONG8
|
||
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; OPTIMIZE MODE 8 OR 12 IF DST FITS IN ONE LONG (VERT LINES ETC)
|
||
;
|
||
bXLONG8 AND.L alphaMask(A6),D1
|
||
jmpROM cibXLONG8
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to handle vertically aligned hilites (like that ever happens) and to
|
||
; preserve a non-white background color through the entire blit (more common).
|
||
; <14SEP90 SMC>
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
bSloHilite PROC EXPORT
|
||
|
||
ciRealbSloHilite1 EQU $2DE14
|
||
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
leaROM ciRealbSloHilite1,a1 ; <13SEP90 SMC>
|
||
BFEXTU D4{0:D7},D4 ;set up pixel of the background color <13SEP90 SMC>
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbSloHilite1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
lea @RealbSloHilite,a1 ;remember correct entry point for remaining scans <14AUG90 KON>
|
||
@RealbSloHilite
|
||
; tst (sp) ;is bump amount negative? <08OCT90 SMC>
|
||
; bpl.s @RealbSloHilite1 ; <08OCT90 SMC>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbSloHilite1
|
||
jmpROM ciRealbSloHilite1
|
||
|
||
;=========================================================================================
|
||
;
|
||
; Patch to MapRgn to return immediatly if the region is rectangular and wide open
|
||
; <7Sept90 KON>
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
newMapRgn PROC EXPORT
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE MapRgn(rgn: RgnHandle; fromRect,toRect: Rect);
|
||
;
|
||
; A6 OFFSETS OF PARAMETERS AND LOCALS AFTER LINK:
|
||
;
|
||
rts EQU 0
|
||
toRect EQU rts+4
|
||
fromRect EQU toRect+4
|
||
rgn EQU fromRect+4
|
||
|
||
NOTSAME MOVE.L rgn(sp),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE RGN
|
||
CMP #10,RGNSIZE(A0) ;IS RGN RECTANGULAR ?
|
||
BNE.S BackToROM ;Back to ROM version
|
||
;
|
||
; Don't do anything if region is rectangular and wide open since MapRect will choke <7Sept90 KON>
|
||
; a0 points to rgn
|
||
;
|
||
cmp.l #$80018001,2(a0) ;
|
||
bne.s BackToROM
|
||
cmp.l #$7fff7fff,6(a0) ;wide open?
|
||
bne.s BackToROM ;No, Use ROM routine
|
||
;
|
||
; region is rectangular and wide open, return without doing anything
|
||
;
|
||
move.l (sp)+,a0 ;get return address
|
||
add.l #12,sp ;remove toRect, fromRect, and rgn
|
||
jmp (a0) ;return to caller
|
||
|
||
BackToROM
|
||
BackToTrap OldMapRgn
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to RgnBlt so patterned hilite works.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
RgnBlt PROC EXPORT
|
||
EXPORT rslowHilite
|
||
EXPORT rXMASK8, rMASK8
|
||
|
||
ciOldWay EQU $2A73C
|
||
ciNewWay EQU $2A73E
|
||
ciNoHilite EQU $2A726
|
||
ciNxtNewSrc EQU $2ABAC
|
||
|
||
;--------------------------------------------------------------
|
||
;
|
||
; PROCEDURE RgnBlt(srcPix,dstPix: PixMap;
|
||
; srcRect,dstRect: Rect;
|
||
; mode: INTEGER; pat: Pattern;
|
||
; rgnA,rgnB,rgnC: RgnHandle);
|
||
;
|
||
; See description in RgnBlt.a
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; 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 non black/white colors
|
||
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'RGNBLT'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
;-----------------------------------
|
||
;
|
||
; SAVE STACK FOR NOW, BECAUSE WE'RE STILL ALLOCATING SCANLINE BUFFERS
|
||
;
|
||
MOVE.L SP,SAVESTK2(A6) ;PRESERVE STACK POINTER
|
||
|
||
;-----------------------------------
|
||
;
|
||
; CALC BUFLEFT AND BUFSIZE (BUFSIZE = DSTSIZE)
|
||
;
|
||
MOVE MINRECT+LEFT(A6),D1 ;GET MINRECT LEFT
|
||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL COORDS
|
||
EXT.L D1 ;CLEAR HI WORD
|
||
LSL.L D4,D1 ;CONVERT PIXELS TO BITS
|
||
AND #$FFE0,D1 ;TRUNC TO MULT OF 32
|
||
LSR.L D4,D1 ;CONVERT BITS TO PIXELS
|
||
ADD BOUNDS+LEFT(A5),D1 ;CONVERT BACK TO LOCAL
|
||
MOVE D1,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
||
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
||
SUB D1,D0 ;CALC WIDTH IN DOTS (=SCANSIZE)
|
||
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>
|
||
MOVE D1,BUFSIZE(A6) ;BUFSIZE = # LONGS -1 <C954>
|
||
|
||
LSR #5,D0 ;get (pixels in scanbuf)/32 <C954>
|
||
ADDQ #1,D0 ;MAKE IT ONE BASED
|
||
LSL D4,D0 ;MULTIPLY BY DEPTH
|
||
; SUBQ #1,D0 ;MAKE SIZE 0 BASED
|
||
|
||
addQ #4,D0 ;add in slop for 4-bit <BAL solo>
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK.
|
||
;
|
||
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-D4
|
||
;
|
||
MOVEQ #-1,D0 ;assume run clipping <85> start
|
||
MOVE LOCMODE(A6),D2 ;GET TRANSFER MODE
|
||
CMP #32,D2 ;new arithmetic mode?
|
||
BLO @newWay
|
||
CMP #64,D2
|
||
BHS Done ;unimplemented mode
|
||
CMP #48,D2
|
||
BLT.S @noHilite
|
||
CMP #50,D2 ;source highlight mode?
|
||
BEQ.S @oldWay ;if so, can't be fast pattern case
|
||
CMP #58,D2 ;pattern highlight mode?
|
||
BNE Done ;if not, it is unimplemented
|
||
TST PATROW(A6) ;BIG PATTERN?
|
||
BNE.S @oldWay ;if so, assume pattern contains background color
|
||
MOVE.L exPat(A6),A0 ;check if non-background pattern
|
||
MOVE.L BCOLOR(A6),D1 ;get background color
|
||
MOVEQ #$0F,D0 ;number of longs in a short pattern
|
||
@nextPatRow
|
||
CMP.L (A0)+,D1 ;is the row non-background?
|
||
DBEQ D0,@nextPatRow ;if so, check for more rows
|
||
BEQ.S @oldWay ;if not, can’t do fast hiliting
|
||
MOVE #$10,locMode(A6) ;set the mode to the fast hilite variety
|
||
BRA.S @newWay ;assume D0 = -1
|
||
@noHilite
|
||
CMP.W #4,d4 ;is dst 16 or 32 bits/pixel?
|
||
BGE.S @newWay ;yes, handle new way
|
||
CMP.W #32,D2 ;is it an arithmetic mode?
|
||
BLT.S @newWay ;no, handle new way
|
||
CMP.W #47,D2 ;is it an arithmetic mode?
|
||
BGT.S @newWay ;no, handle new way (hilite mode)
|
||
@oldWay MOVEQ #0,D0 ;don't use run clipping <85> end
|
||
@newWay
|
||
move.l d0,runBuf(a6) ;set non-zero for run clipping <1.5> BAL
|
||
MOVE.L RGNC(A6),-(SP) ;PUSH USER RGNHANDLE
|
||
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.W DSTSHIFT(A6),D4 ;RESTORE DSTSHIFT
|
||
MOVE.L DSTRECT(A6),A3 ;RESTORE DSTRECT
|
||
|
||
;----------------------------------------------------------
|
||
;
|
||
; ASSUME WE WILL BE DRAWING DOWNWARD AND TO RIGHT.
|
||
;
|
||
MOVE MINRECT+TOP(A6),FIRSTV(A6) ;FIRSTV:=MINRECT TOP
|
||
MOVE MINRECT+BOTTOM(A6),LASTV(A6) ;LASTV:=MINRECT BOTTOM
|
||
MOVE.L #$00040001,HBUMP(A6) ;HBUMP:=4 BYTES, VBUMP:=1 SCAN
|
||
MOVE.L RGNBUFFER(A6),RGNADDR(A6) ;RGNADDR:=RGNBUFFER
|
||
|
||
;--------------------------------------------------
|
||
;
|
||
; CALCULATE CASE JUMP FOR DIFFERENT TRANSFER MODES
|
||
; GET INVERTFLAG INTO D7
|
||
;
|
||
|
||
ciFastHilite EQU $2A7BC
|
||
ciAfterNoFastHilite EQU $2A7E6
|
||
ciDoOldWay EQU $2A838
|
||
|
||
SETMODE MOVE LOCMODE(A6),D2 ;GET TRANSFER MODE
|
||
MOVE D2,D1 ;SAVE MODE
|
||
|
||
CMP.W #$10,D2 ;fast hilite mode?
|
||
BNE.S @notFastHilite
|
||
jmpROM ciFastHilite
|
||
; MOVE.L rHiliteTabPtr,A0 ;get address of table (from trap table)
|
||
; ADD.L -4(a0,D4*4),a0 ;select routine based on destination depth
|
||
; MOVE.L A0,ModeCase(A6) ;set up jump
|
||
; MOVE dstPix+pixelSize(A6),D7 ;how far to extract to get a pixel worth
|
||
; BFEXTU hilitColor(A6){0:D7},D3 ;and a pixel sized highlight color
|
||
; BFEXTU transColor(A6){0:D7},D6 ;set up a pixel sized background color
|
||
; CLR patRow(A6) ;no pattern
|
||
; BRA GetDst ;go to it
|
||
|
||
@notFastHilite
|
||
CMP.W #$20,D2 ;non-arithmetic mode?
|
||
BLO @doOldWay
|
||
jmpROM ciAfterNoFastHilite
|
||
; AND #$37,D2 ;treat mode MOD $07 + arithmetic bit, hilite bit
|
||
; BCLR #4,D2 ;and clear the hilite bit
|
||
; BNE.S @Hilite
|
||
@doOldWay
|
||
jmpROM ciDoOldWay
|
||
|
||
|
||
|
||
rslowHilite
|
||
CMP #16,D7 ;if 16 or 32 bit/pixel, undo some setup
|
||
BLT.S @notDirect
|
||
LSL.L #3,D6 ;turn the patOffset back to pixels from bytes
|
||
MOVE.L D6,patOffset(A6)
|
||
MOVE patHMask(A6),D1 ;convert patHMask back into pixels from bytes
|
||
LSL.W #3,D1
|
||
MOVE D1,patHMask(A6)
|
||
@notDirect
|
||
LEA @rsHilite,A0 ;get address of real blit loop
|
||
MOVE.L A0,modeCase(A6) ;go there from now on
|
||
JMP (A0) ;go there right now
|
||
|
||
@rsHilite
|
||
MOVE patHMask(A6),D1 ;set up source constriction
|
||
BFEXTU transColor(A6){0:D7},D0
|
||
MOVE.L D0,A1 ;set up pixel of background color
|
||
@loopTop
|
||
AND D1,D6 ;constrict to the source long if in a pattern mode
|
||
|
||
BFEXTU (A3){D6:D7},D0 ;get pixel of source
|
||
CMP.L A1,D0 ;is it the same as the background color?
|
||
BEQ.S @skip ;skip if so
|
||
|
||
BFEXTU (A4){D4:D7},D0 ;get pixel of the mask
|
||
BEQ.S @skip ;skip if empty
|
||
|
||
BFEXTU (A5){D4:D7},D0 ;get a pixel of the dest (zeros top word)
|
||
CMP.L A1,D0 ;same as a pixel of the background?
|
||
BEQ.S @putHilite ;yes, go put hilite there
|
||
CMP.L D5,D0 ;same as a pixel of the hilite color?
|
||
BNE.S @skip ;no, skip it
|
||
MOVE.L A1,D0
|
||
BFINS D0,(A5){D4:D7} ;yes, move pixel of back color to dest
|
||
BRA.S @skip
|
||
@putHilite
|
||
BFINS D5,(A5){D4:D7} ;move hilite color to dest
|
||
@skip ADD.L D3,D6 ;bump srcptr left or right by 1 pixel
|
||
ADD.L D3,D4 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
; BRA NxtNewSrc ;loop back for more
|
||
jmpROM ciNxtNewSrc
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; MODE 8 OR 12: Big PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
ciDONE EQU $2ABA6
|
||
cinextMask EQU $2AB3C
|
||
|
||
;Lifted from cqd.a include file
|
||
runMaskBit EQU 30 ;bit number for run MASK instruction
|
||
|
||
|
||
rXMASK8 LEA rXMASK8G,A2 ;get address of normal loop ;Start of alpha changes block
|
||
TST.B alphaMode(A6) ;drawing in alpha mode?
|
||
BEQ.S @1 ;no, use normal loop
|
||
LEA rXMASK8A,A2 ;get address of alpha loop
|
||
@1: MOVE.L A2,modeCase(A6) ;save proc address
|
||
JMP (A2) ;go there now
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
@nxtScan
|
||
MOVE PATHPOS(A6),D6 ;GET HORIZONTAL POSITION
|
||
SWAP D6 ;GET VERT POSITION IN PATTERN
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
||
AND PATVMASK(A6),D6 ;AND MASK WITHIN PATTERN
|
||
;LEAVE PATVPOS IN D6
|
||
add.l d2,a5 ;BUMP DST TO NEXT ROW
|
||
MOVE vert(A6),D0
|
||
ADDQ #1,D0 ;BUMP DOWN A SCAN LINE
|
||
CMP lastV(a6),D0 ;ARE WE AT THE LAST SCAN LINE ?
|
||
bge DONE ;YES, BAIL
|
||
subq #1,d1
|
||
ble.s nextMask
|
||
MOVE D0,vert(A6)
|
||
|
||
@runs move.l a5,a2 ;set up destAddr
|
||
move.l a3,a0 ;set up srcAddr
|
||
MOVEQ #0,D4 ;clear out high word
|
||
MOVE D6,D4 ;get vert pattern offset
|
||
ADD.L D4,A0 ;BUMP TO PROPER ROW
|
||
SWAP D6 ;AND GET PATHPOS
|
||
move.l a4,A1 ;point to run encoded mask buffer
|
||
MOVE.L alphaMask(A6),D5
|
||
|
||
@inst move.l (a1)+,d3 ;pick up next instruction long
|
||
bmi.s @nxtScan
|
||
add.w d3,a2 ;bump destptr by skip amount
|
||
ADD.W D3,D6 ;BUMP PATTERN POS
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
swap d3 ;get mask/blit cnt and check done flag
|
||
bclr #runMaskBit-16,d3 ;check and clear mask flag
|
||
BEQ.S @blit
|
||
|
||
@mask MOVE.L 0(A0,D6),D0 ;GET PATTERN DATA
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L (A2),D4 ;GET DST
|
||
EOR.L D4,D0 ;COMBINE DST AND PATTERN
|
||
AND.L (A1)+,D0 ;APPLY REGION MASK
|
||
AND.L D5,D0 ;APPLY ALPHA MASK
|
||
EOR.L D4,D0 ;REAPPLY DST TO PATTERN
|
||
MOVE.L D0,(A2)+ ;PUT RESULT TO DST
|
||
DBRA D3,@mask ;LOOP ALL LONGS THIS ROW
|
||
BRA.s @inst ;LOOP BACK FOR more runs
|
||
|
||
@blit MOVE.L 0(A0,D6),D0 ;GET PATTERN DATA
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L (A2),D4 ;GET DST
|
||
EOR.L D4,D0 ;COMBINE DST AND PATTERN
|
||
AND.L D5,D0 ;APPLY ALPHA MASK
|
||
EOR.L D4,D0 ;REAPPLY DST TO PATTERN
|
||
MOVE.L D0,(A2)+ ;PUT RESULT TO DST
|
||
DBRA D3,@blit ;LOOP ALL LONGS THIS ROW
|
||
BRA.S @inst ;LOOP BACK FOR MORE RUNS
|
||
|
||
rXMASK8A equ @runs ;end of alpha changes block
|
||
|
||
DONE jmpROM ciDONE
|
||
nextMask
|
||
jmpROM cinextMask
|
||
|
||
ALIGN Alignment
|
||
|
||
@nxtScan
|
||
MOVE PATHPOS(A6),D6 ;GET HORIZONTAL POSITION
|
||
SWAP D6 ;GET VERT POSITION IN PATTERN
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
||
AND PATVMASK(A6),D6 ;AND MASK WITHIN PATTERN
|
||
;LEAVE PATVPOS IN D6
|
||
|
||
add.l d2,a5 ;BUMP DST TO NEXT ROW
|
||
ADDQ #1,D0 ;BUMP DOWN A SCAN LINE
|
||
CMP lastV(a6),D0 ;ARE WE AT THE LAST SCAN LINE ?
|
||
bge.s DONE ;YES, BAIL
|
||
subq #1,d1
|
||
ble.s nextMask
|
||
;rXMASK8
|
||
@runs move.l a5,a2 ;set up destAddr
|
||
move.l a3,a0 ;set up srcAddr
|
||
MOVEQ #0,D5 ;clear out high word <SMC 20Aug90>
|
||
MOVE D6,D5 ;get vert pattern offset <SMC 20Aug90>
|
||
ADD.L D5,A0 ;BUMP TO PROPER ROW <SMC 20Aug90>
|
||
SWAP D6 ;AND GET PATHPOS
|
||
move.l a4,A1 ;point to run encoded mask buffer
|
||
|
||
@inst
|
||
move.l (a1)+,d3 ;pick up next instruction long
|
||
bmi.s @nxtScan
|
||
add.w d3,a2 ;bump destptr by skip amount
|
||
ADD.W D3,D6 ;BUMP PATTERN POS
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
swap d3 ;get mask/blit cnt and check done flag
|
||
bclr #runMaskBit-16,d3 ;check and clear mask flag
|
||
beq.s @blit ;no mask, so go fast
|
||
|
||
@mask MOVE.L 0(A0,D6),D5 ;GET PATTERN DATA
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L (A1)+,D4 ;GET MASK
|
||
AND.L D4,D5 ;MASK PATTERN DATA
|
||
NOT.L D4 ;MAKE NOTMASK
|
||
AND.L (A2),D4 ;GET DST DATA
|
||
OR.L D4,D5 ;MERGE WITH PAT DATA
|
||
MOVE.L D5,(A2)+ ;PUT RESULT TO DST
|
||
DBRA D3,@mask ;LOOP ALL LONGS THIS ROW
|
||
BRA.s @inst ;LOOP BACK FOR more runs
|
||
|
||
@blit MOVE.L 0(A0,D6),(A2)+ ;write pattern to dest
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
DBRA D3,@blit ;LOOP ALL LONGS THIS ROW
|
||
BRA.s @inst ;LOOP BACK FOR more runs
|
||
|
||
rXMASK8G EQU @runs
|
||
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||
;
|
||
;-------------------------------------------------------
|
||
|
||
cirMASK8 EQU $2B0EC
|
||
|
||
rMASK8 leaROM cirMASK8,A2 ;get address of normal routine ;Start of alpha changes block
|
||
TST.B alphaMode(A6) ;drawing in alpha mode?
|
||
BEQ.S @1 ;no, use normal loop
|
||
LEA rMASK8A,A2 ;get address of alpha loop
|
||
@1: MOVE.L A2,modeCase(A6) ;save proc address
|
||
JMP (A2) ;go there now
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
@nxtScan
|
||
ADDQ #1,D7 ;BUMP PATTERN SELECTOR
|
||
AND #$F,D7 ;MOD 16 FOR 16 LONG REPEAT
|
||
MOVE.L (a3,D7*4),D6 ;GET PATTERN FOR NEXT ROW
|
||
|
||
add.l d2,a5 ;BUMP DST TO NEXT ROW
|
||
MOVE vert(A6),D0
|
||
ADDQ #1,D0 ;BUMP DOWN A SCAN LINE
|
||
CMP lastV(a6),D0 ;ARE WE AT THE LAST SCAN LINE ?
|
||
bge.s DONE ;YES, BAIL
|
||
subq #1,d1
|
||
ble.s nextMask
|
||
MOVE D0,vert(A6)
|
||
|
||
;rMASK8A
|
||
@runs move.l a5,a2 ;init tmp dst ptr
|
||
move.l a4,a1 ;point to run encoded mask buffer
|
||
MOVE.L alphaMask(A6),D5 ;get alpha mask
|
||
|
||
@inst move.l (a1)+,d3 ;pick up next instruction long
|
||
bmi.s @nxtScan ;if high bit set then done with scan
|
||
add.w d3,a2 ;bump destptr by skip amount
|
||
swap d3 ;get mask/blit cnt and check done flag
|
||
bclr #runMaskBit-16,d3 ;check and clear mask flag
|
||
beq.s @blit ;no mask, so go fast
|
||
|
||
@mask MOVE.L D6,D0 ;GET PATTERN DATA
|
||
MOVE.L (A2),D4 ;GET DST
|
||
EOR.L D4,D0 ;COMBINE DST WITH PATTERN
|
||
AND.L (A1)+,D0 ;APPLY REGION MASK
|
||
AND.L D5,D0 ;APPLY ALPHA MASK
|
||
EOR.L D4,D0 ;REAPPLY DST TO PATTERN
|
||
MOVE.L D0,(A2)+ ;PUT RESULT TO DST
|
||
DBRA D3,@mask ;LOOP ALL LONGS THIS ROW
|
||
BRA.s @inst ;LOOP BACK FOR more runs
|
||
|
||
@blit MOVE.L D6,D0 ;GET PATTERN DATA
|
||
MOVE.L (A2),D4 ;GET DST
|
||
EOR.L D4,D0 ;COMBINE DST WITH PATTERN
|
||
AND.L D5,D0 ;APPLY ALPHA MASK
|
||
EOR.L D4,D0 ;REAPPLY DST TO PATTERN
|
||
MOVE.L D0,(A2)+ ;PUT RESULT TO DST
|
||
DBRA D3,@blit ;LOOP ALL LONGS THIS ROW
|
||
BRA.s @inst ;LOOP BACK FOR more runs
|
||
|
||
rMASK8A equ @runs ;end of alpha changes block
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to PatConvert. If we were called from GetPicPixPat, set patXValid
|
||
; to -1 and return, otherwise patch to make direct pixpats work for offscreen gWorlds.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
PATCONVERT PROC EXPORT
|
||
IMPORT PatDither,MakeScaleTbl
|
||
;------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE PATCONVERT (PAT: PixPatHandle);
|
||
;
|
||
; Convert the specified pattern to the current depth and color table.
|
||
; Note: This routine is shared by patterns and cursors, which are parallel
|
||
; structures. Expand data for the pattern is kept in the patXMap handle, which
|
||
; is carefully unused if the structure is a cursor.
|
||
;
|
||
|
||
PARAMSIZE EQU 4
|
||
PAT EQU PARAMSIZE+8-4 ; handle to pattern
|
||
|
||
SAVESTK EQU -4 ; save the stack
|
||
WIDCNT EQU SAVESTK-2 ; width of pattern in pixels
|
||
HTCNT EQU WIDCNT-2 ; height of pattern in scans
|
||
HREPCNT EQU HTCNT-2 ; horizontal repetitions of pattern
|
||
VREPCNT EQU HREPCNT-2 ; vertical repetitions of pattern
|
||
PATROW EQU VREPCNT-2 ; rowbytes of src pattern
|
||
DstPix EQU PATROW-PMREC ; dst pixmap for calling stretch <1.5> BAL
|
||
VARSIZE EQU DstPix ; local vars <1.5> BAL
|
||
|
||
FromGetPicPixPat EQU $3313E
|
||
IndexedPatConvert EQU $30CFC
|
||
DirectPatConvert EQU $30D7E
|
||
GetDevPix EQU $28080
|
||
RSetHSize EQU $31450
|
||
|
||
cmpRA FromGetPicPixPat, (sp)
|
||
bne.s DoNormal
|
||
move.l 4(sp),a0 ;pixpatHandle
|
||
move.l (a0),a0 ;point to pixpat
|
||
move.w #-1,patXValid(a0)
|
||
RTD #4
|
||
|
||
DoNormal
|
||
LINK A6,#VARSIZE ; allocate stack frame
|
||
MOVEM.L D3-D7/A0/A2-A4,-(SP) ; save all registers
|
||
; A0 saved for SetFillPat
|
||
MOVE.L SP,SAVESTK(A6) ; save stack pointer
|
||
|
||
; get the dst pixel size in D6 and the src pixel size in D7
|
||
|
||
jsrROM GetDevPix ; get pointer to GDevice in A0
|
||
MOVE PixelSize(A0),D6 ; get dst pixel size
|
||
EXT.L D6 ; make long for translate loop
|
||
|
||
MOVE.L PAT(A6),A4 ; get the PixPat Handle
|
||
MOVE.L (A4),A1 ; point to the pixPat
|
||
|
||
MOVE patType(A1),D0 ; get the type of pattern
|
||
BMI.S NoDither ; => it's a cursor, no offset to set
|
||
|
||
MOVE.L patXMap(A1),A0 ; get handle to patXMap
|
||
MOVE.L (A0),A0 ; point to patXMap
|
||
CLR LastOfst(A0) ; we're expanding with offset 0
|
||
CMP #ditherPat,D0 ; does pat need to be dithered?
|
||
BNE.S NoDither ; => no, don't adjust
|
||
MOVE.L A4,-(SP) ; push pixPat handle
|
||
_PatDither ; create best-match dither
|
||
MOVE.L (A4),A1 ; point to the pixPat
|
||
|
||
NoDither MOVE.L PatMap(A1),A3 ; get the pixmap handle
|
||
MOVE.L (A3),A0 ; point to the pixmap
|
||
MOVE pixelSize(A0),D7 ; get source pixel size
|
||
EXT.L D7 ; make long for translate loop
|
||
|
||
; set up patXRow, patXHMask, patXVMask
|
||
|
||
MOVE rowBytes(A0),D0 ; get src rowbytes
|
||
AND #nuRBMask,D0 ; clear flag bits
|
||
MOVE D0,patRow(A6) ; save for expand loop
|
||
|
||
CLR HREPCNT(A6) ; assume no horizontal reps
|
||
CLR VREPCNT(A6) ; assume no vertical reps
|
||
|
||
LEA bounds+right(A0),A2 ; point to end of bounds
|
||
MOVE (A2),D4 ; get right
|
||
MOVE -(A2),D3 ; get bottom
|
||
SUB -(A2),D4 ; get width in pixels in D4
|
||
SUB -(A2),D3 ; get height in D3
|
||
|
||
MOVE D4,D0 ; get src width in pixels
|
||
SUBQ #1,D0 ; make it 0 based
|
||
MOVE D0,WIDCNT(A6) ; save src width in pixels
|
||
|
||
MOVE D3,D0 ; get height
|
||
SUBQ #1,D0 ; make it 0 based
|
||
MOVE D0,HTCNT(A6) ; save src height in pixels
|
||
|
||
; if the pattern is a cursor, skip repeat stuff
|
||
|
||
MOVE patType(A1),D0 ; get the type of pattern
|
||
BPL.S NoCrsr ; => not a cursor, get reps
|
||
LSR #3,D4 ; convert dst bits to bytes
|
||
MULU D6,D4 ; stretch to dst depth
|
||
BRA.S GotReps ; => don't replicate cursors
|
||
|
||
; If the pattern will fit into a long, repeat, if necessary, to fill the whole
|
||
; word. Also make the pattern 16 scans high. Set patXRow to 0 to indicate a 32*16 pattern.
|
||
|
||
NoCrsr MOVE.L patXMap(A1),A2 ; get handle to expanded info
|
||
MOVE.L (A2),A2 ; point to expanded info
|
||
|
||
MULU D6,D4 ; get dst width in bits
|
||
MOVEQ #32,D0 ; get number of bits in a long
|
||
DIVU D4,D0 ; get times to repeat to fit into long
|
||
SUBQ #1,D0 ; make repeat count 0 based
|
||
BMI.S NOREPS ; => no horizontal repetitions
|
||
MOVE D0,HREPCNT(A6) ; and set horizontal rep count
|
||
; pattern fits into a long, so set
|
||
CLR PATXROW(A2) ; flag to use the old blt routines
|
||
MOVEQ #4,D4 ; and set rowbytes to 4
|
||
|
||
MOVEQ #16,D0 ; get minimum number of vert lines
|
||
DIVU D3,D0 ; get 16 DIV height
|
||
CMP #1,D0 ; is it 1 or less?
|
||
BLT.S NOREPS2 ; => yes, no repetitions
|
||
MULU D0,D3 ; multiply height by repcount
|
||
SUBQ #1,D0 ; make VRepCnt 0 based
|
||
MOVE D0,VREPCNT(A6) ; and set vertical rep count
|
||
BRA.S REPS ; => patXRow already cleared
|
||
|
||
NOREPS LSR #3,D4 ; convert dst bits to bytes
|
||
NOREPS2 MOVE D4,PATXROW(A2) ; save expanded rowbytes
|
||
REPS MOVE D4,D0 ; copy expanded rowBytes
|
||
SUBQ #1,D0 ; HMASK := $FFFC AND (rowbytes-1)
|
||
AND #$FFFC,D0 ; mask to long boundary
|
||
MOVE D0,PatXHMask(A2) ; save HMask
|
||
|
||
MOVE D4,D0 ; get (adjusted) rowbytes
|
||
MULU D3,D0 ; VMASK := rowbytes*height - 1
|
||
SUBQ #1,D0 ; make it a mask
|
||
MOVE D0,PatXVMask(A2) ; save VMask
|
||
|
||
; Calc total size of the dst and set the size of patXData
|
||
|
||
GotReps MOVE D4,D0 ; get (adjusted) width in bytes
|
||
MULU D3,D0 ; multiply by (adjusted) height
|
||
MOVE.L (A4),A0 ; point to the pixPat
|
||
MOVE.L patXData(A0),A0 ; get the handle to expanded bits
|
||
jsrROM RSetHSize ; set to proper size
|
||
|
||
; Allocate pixel translate table on top of stack and initialize
|
||
|
||
cmp.W #8,d7 ; is src direct data? <1.5> BAL
|
||
bgt.s DirectPixPat ; yes, go call stretchbits <1.5> BAL
|
||
jmpROM IndexedPatConvert
|
||
|
||
; MOVE.L (A3),-(SP) ; push pixMap pointer
|
||
; MOVE #$20,-(SP) ; pass srcAverage as a mode (so colors are used)
|
||
; _MakeScaleTbl ; make translate table
|
||
|
||
DirectPixPat
|
||
MOVE.L (A4),A0 ; point to the pixPat
|
||
MOVE.L patData(A0),A0 ; get the src data handle
|
||
MOVE.L (a0),a0 ; get the src data ptr
|
||
|
||
MOVE.L (A3),A1 ; point to the pixmap
|
||
MOVE.L a0,baseAddr(a1) ; point the baseAddr to the patData
|
||
|
||
jsrROM GetDevPix ; get pointer to GDevice in A0
|
||
lea dstPix(a6),a1 ; point to dst pixMap
|
||
MOVEQ #PMREC/2-1,D0 ; make a local copy of dst gdpmap
|
||
@NXTWORD MOVE (A0)+,(A1)+ ;
|
||
DBRA D0,@NXTWORD ;
|
||
|
||
lea dstPix+bounds+top(a6),a0 ; set up dstPix for patXData
|
||
clr.w dstPix+pmVersion(a6) ; base address is pointer <24JUL90 KON>
|
||
jmpROM DirectPatConvert
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Register A2 is getting trashed when setting CCursor on mulitple device systems
|
||
; This patches that baby out!
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
PatchJSetCCursor PROC EXPORT
|
||
|
||
ciGETMAINCRSR EQU $2E484
|
||
ciERASECURSOR EQU $2E27A
|
||
ciDRAWCURSOR EQU $2E2BC
|
||
;_______________________________________________________________________
|
||
;
|
||
; PROCEDURE SetCCursor(cCrsr: CCrsrHandle);
|
||
;
|
||
; This procedure copies the data in the specified color cursor into the
|
||
; system's cursor save area. If the depth > 2, it expands it.
|
||
|
||
SetCCursor MOVEM.L D3-D4/A2-A4,-(SP) ;save work registers
|
||
move.l 24(sp),a2 ;get ccrsrHandle <BAL 21Jun88>
|
||
move.l a2,a0 ;make a copy
|
||
_HGetState
|
||
move d0,-(sp) ;save state for later
|
||
move.l a2,a0 ;make a copy
|
||
_HLock
|
||
MOVE.L (a2),A2 ;GET POINTER TO NEW CURSOR
|
||
|
||
MOVE.L ([CRSRPTR]),A3 ;point to current cursor (LOCKED)
|
||
MOVE.L crsrID(A2),D0 ;and get ID of new cursor
|
||
CMP #CCrsrPat,ccType(A3) ;is current cursor a color cursor?
|
||
BNE.S NotCC ;=>no, it has definitely changed
|
||
CMP.L ccID(A3),D0 ;same as current one?
|
||
BEQ SCCDONE ;=>yes, just return
|
||
|
||
NotCC MOVE.B #1,CRSRBUSY ;flag the cursor as busy
|
||
MOVE.L D0,ccID(A3) ;set new ID
|
||
LEA crsr1Data(A2),A0 ;point to old-cursor data
|
||
LEA THECRSR,A1 ;put it here
|
||
MOVEQ #16,D0 ;data+mask+hotspot = 17 longs
|
||
@0 MOVE.L (A0)+,(A1)+ ;copy data
|
||
DBRA D0,@0 ;until done
|
||
|
||
LEA crsr1Data(A2),A0 ;point to old-cursor data
|
||
LEA CCLASTCRSR(A3),A1 ;save here to indicate cursor changed
|
||
MOVEQ #7,D0 ;move 8 longs
|
||
@1 MOVE.L (A0)+,(A1)+ ;copy data
|
||
DBRA D0,@1 ;=>loop until done
|
||
|
||
MOVE crsrType(A2),ccType(A3) ;copy the type
|
||
|
||
; NOTE: ALL THE DST HANDLES ARE LOCKED, BUT THEY HAVE BEEN SET TO THE PROPER SIZE
|
||
|
||
MOVE.L crsrMap(A2),-(SP) ;push src pixMap handle
|
||
MOVE.L ccMap(A3),-(SP) ;push dst pixMap handle
|
||
_CopyPixMap ;copy the pixMap
|
||
|
||
MOVE.L crsrData(A2),-(SP) ;push src data handle
|
||
MOVE.L ccData(A3),-(SP) ;push dst data handle
|
||
_CopyHandle ;copy the cursor data
|
||
|
||
; FOR EACH ACTIVE SCREEN DEVICE, EXPAND CURSOR, IF NECESSARY
|
||
|
||
MOVE.L DEVICELIST,D4 ;D4 = CURRENT DEVICE
|
||
MOVE.L D4,A4 ;GET HANDLE TO CURRENT DEVICE
|
||
NXTSCR MOVE.L (A4),A4 ;A4 = POINTER TO CURRENT DEVICE
|
||
TST.W GDFLAGS(A4) ;IS THE DEVICE ACTIVE?
|
||
BPL CHKNXT ;=>NO, CHECK NEXT DEVICE
|
||
;ACTIVE DEVICES ARE LOCKED DOWN
|
||
MOVE.L GDPMAP(A4),A0 ;GET HANDLE TO DEVICE'S PIXMAP
|
||
MOVE.L (A0),A0 ;POINT TO DEVICE'S PIXMAP
|
||
MOVE PIXELSIZE(A0),D3 ;GET DEVICE'S PIXELSIZE
|
||
|
||
; IF THE PATTERN IS PRE-EXPANDED TO THE RIGHT DEPTH, JUST COPY THAT DATA
|
||
|
||
CLR GDCCDEPTH(A4) ;flag to expand one-bit data
|
||
MOVE CRSRXVALID(A2),D0 ;is there pre-expanded data?
|
||
BEQ.S GOEXP ;=>no, do expansion
|
||
CMP D3,D0 ;is the expanded data the right depth?
|
||
BNE.S GOEXP ;=>no, expand from the source
|
||
MOVE D0,GDCCDEPTH(A4) ;else copy the expanded depth
|
||
MOVE.L crsrXData(A2),-(SP) ;push the src xdata handle
|
||
MOVE.L CCXDATA(A3),-(SP) ;push the dst xdata handle
|
||
_CopyHandle ;and copy it
|
||
BRA.S CHKNXT ;=>data already expanded, just exit
|
||
|
||
GOEXP CMP #CCRSRPAT,CCTYPE(A3) ;IS IT A COLOR CURSOR?
|
||
BNE.S DONEONE ;=>NO, EXIT WITH DEPTH = 0
|
||
CMP #2,D3 ;IS DEPTH GREATER THAN 2?
|
||
BLE.S DONEONE ;=>NO, EXIT WITH DEPTH = 0
|
||
|
||
MOVE D3,GDCCDEPTH(A4) ;RECORD THE EXPANDED DEPTH
|
||
MOVE.L GDCCXDATA(A4),CCXDATA(A3) ;GET DEVICE'S EXPANDED DATA FOR PATCONVERT
|
||
MOVE.L THEGDEVICE,-(SP) ;SAVE GRAFDEVICE (USED BY PATCONVERT)
|
||
MOVE.L D4,THEGDEVICE ;SET IT TO CURRENT DEVICE
|
||
MOVE.L CRSRPTR,-(SP) ;PUSH HANDLE TO CURSOR (LOCKED)
|
||
_PATCONVERT ;AND EXPAND TO CURRENT DEPTH
|
||
MOVE.L (SP)+,THEGDEVICE ;RESTORE GRAFDEVICE
|
||
|
||
; EXPAND THE MASK TO THE CURRENT DEPTH
|
||
|
||
MOVE D3,D0 ;GET DEPTH
|
||
MOVEQ #0,D1 ;DEFAULT SHIFT = 0
|
||
NXTSHFT1 LSR #1,D0 ;CHECK NEXT DEPTH BIT
|
||
BCS.S GOTSHFT1 ;=>GOT SHIFT
|
||
ADDQ #1,D1 ;ELSE ADD ONE TO SHIFT
|
||
BRA.S NXTSHFT1 ;LOOP UNTIL WE HIT A ONE
|
||
|
||
GOTSHFT1 LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK
|
||
MOVE.L ([GDCCXMASK,A4]),A1 ;POINT TO EXPANDED MASK (LOCKED)
|
||
|
||
move.l a2,d4 ;save pointer to new cursor <25APR91 KON>
|
||
MOVE.L A1,A2 ;GET START OF DST BUFFER <27May87 EHB>
|
||
MOVE #32,D0 ;GET #BYTES OF SOURCE <27May87 EHB>
|
||
LSL D1,D0 ;MULTIPLY BY DEPTH <27May87 EHB>
|
||
ADD D0,A2 ;POINT TO END OF BUFFER <27May87 EHB>
|
||
|
||
move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE
|
||
add.l 0(A3,D1*4),A3 ;USE DEPTH TO SELECT ROUTINE
|
||
MOVEQ #0,D0 ;CLEAR HIGH PART OF D0
|
||
JSR (A3) ;EXPAND 32*DEPTH BYTES
|
||
MOVE.L ([CRSRPTR]),A3 ;GET BACK POINTER TO CURSOR (LOCKED)
|
||
move.l d4,a2 ;restore pointer to new cursor <25APR91 KON>
|
||
|
||
DONEONE MOVE GDCCDEPTH(A4),D0 ;GET EXPANDED DEPTH
|
||
ADD D0,D0 ;DOUBLE IT
|
||
MOVE D0,GDCCBYTES(A4) ;AND SAVE AS CURSOR'S ROWBYTES
|
||
|
||
CHKNXT MOVE.L GDNEXTGD(A4),D4 ;IS THERE A NEXT DEVICE?
|
||
MOVE.L D4,A4 ;GET HANDLE TO NEXT DEVICE
|
||
BNE NXTSCR ;=>THERE IS ONE, PREPARE ITS CURSOR
|
||
|
||
jsrROM ciGETMAINCRSR ;RESTORE EXPAND DATA FOR MAIN CURSOR
|
||
jsrROM ciERASECURSOR ;HIDE THE OLD CURSOR
|
||
jsrROM ciDRAWCURSOR ;DISPLAY THE NEW CURSOR
|
||
SCCDONE CLR.B CRSRBUSY ;CURSOR NOT BUSY ANYMORE
|
||
move (sp)+,d0 ;get ccrsrhandle state
|
||
move.l 24(sp),a0 ;get ccrsrHandle
|
||
_HSetState
|
||
MOVEM.L (SP)+,D3-D4/A2-A4 ;restore work registers
|
||
MOVE.L (SP)+,(SP) ;strip parameter
|
||
RTS ;and return
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Obscure-show-hide leaves crsr hidden only, Obscure-hide-show leaves crsr
|
||
; obscured only.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
PatchJShowCursor PROC EXPORT
|
||
|
||
ciROMDrawCursor EQU $2E2BC
|
||
ciROMDoneSho EQU $2E2DC
|
||
|
||
ShieldDepth EQU $0D4C ;this equate should not be here
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; SHOWCURSOR - Called from CrsrVBLTask and via Jump Table.
|
||
;
|
||
; Adds 1 to CRSRSTATE and paints cursor if zero and cursor is
|
||
; not already visible.
|
||
;
|
||
|
||
ShowCursor
|
||
MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS
|
||
|
||
TST ShieldDepth ;Any shielding?
|
||
BEQ.s @2
|
||
|
||
@1 SUBQ #1,ShieldDepth ;If so, this ShowCursor unshields,
|
||
BRA.s DrawCursor ;but doesn't up the cursor level.
|
||
|
||
@2 ADDQ #1,CRSRSTATE ;CURSOR HIDDEN ONE LESS DEEP
|
||
bmi.s DoneSho
|
||
beq.s DrawCursor ;<KON 25JUN90>
|
||
clr.b CrsrObscure ;unobscure cursor if level went past zero <KON 25JUN90>
|
||
|
||
;fall into DrawCursor
|
||
|
||
;________________________________________________________________________
|
||
; DrawCursor is much like ShowCursor, but doesn't increment the CrsrState <dvb 19sep88>
|
||
|
||
DrawCursor
|
||
jmpROM ciROMDrawCursor
|
||
|
||
DoneSho
|
||
jmpROM ciROMDoneSho
|
||
|
||
ENDPROC
|
||
|
||
;
|
||
; <124> Bring back GetCPixel until the Future arrives
|
||
;
|
||
|
||
if not(TheFuture) then
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to getPixel and getCPixel so that SwapMMUMode is called if pixmap needs 32-bit
|
||
; addressing (pmVersion = 4). These calls are in QDUtil.a.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
GetCPixel FUNC EXPORT
|
||
EXPORT GETPIXEL
|
||
IMPORT PortToMap
|
||
|
||
ciMMUModeOK EQU $2F018
|
||
ciGetPixelDone EQU $2F070
|
||
|
||
;---------------------------------------------------------
|
||
;
|
||
; FUNCTION GetPixel(h,v: INTEGER): BOOLEAN;
|
||
; PROCEDURE GetCPixel(h,v: INTEGER; myColor: RGBColor);
|
||
;
|
||
; Returns TRUE if the pixel at (h,v) is set to black.
|
||
; h and v are in local coords of the current grafport.
|
||
;
|
||
; WATCH OUT FOR STACK TRICKERY WHEN GETCPIXEL CALLS GETPIXEL!!
|
||
;
|
||
; CLOBBERS A0,A1,D0,D1,D2
|
||
;
|
||
PARAMSIZE EQU 4
|
||
RETURN EQU PARAMSIZE+8 ;ADDRESS OF BOOLEAN/RGBCOLOR
|
||
HLOC EQU PARAMSIZE+8-2 ;HORIZONTAL POSITION
|
||
VLOC EQU HLOC-2 ;VERTICAL POSITION
|
||
|
||
VARSIZE EQU 0 ;TOTAL SIZE OF LOCALS
|
||
|
||
MOVE.L 8(SP),-(SP) ;PUSH H,V
|
||
MOVEQ #1,D2 ;ROUTINE = GETCPIXEL
|
||
BSR.S SHARE ;USE COMMON CODE
|
||
RTD #8 ;STRIP PARAMS AND RETURN
|
||
|
||
GETPIXEL
|
||
MOVEQ #0,D2 ;ROUTINE = GETPIXEL
|
||
|
||
SHARE LINK A6,#VARSIZE ;ALLOCATE STACKFRAME
|
||
MOVEM.L D4-D5/A2-A3,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L THEGDEVICE,-(SP) ;SAVE CURRENT GRAFDEVICE
|
||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A0),A0 ;GET THEPORT
|
||
_PORTTOMAP ;GET BIT/PIXMAP IN A0
|
||
|
||
; GET GLOBAL COORDINATES OF VLOC INTO D4 AND HLOC INTO D5
|
||
|
||
OLDRB MOVE VLOC(A6),D4 ;GET VERTICAL
|
||
SUB BOUNDS+TOP(A0),D4 ;CONVERT TO GLOBAL COORDS
|
||
MOVE HLOC(A6),D5 ;GET HORIZ COORD
|
||
SUB BOUNDS+LEFT(A0),D5 ;CONVERT TO GLOBAL
|
||
|
||
; IS IT FROM THE SCREEN?
|
||
|
||
MOVE.L MAINDEVICE,A2 ;GET MAIN DEVICE
|
||
MOVE.L (A2),A2 ;POINT TO IT
|
||
MOVE.L GDPMAP(A2),A2 ;GET PIXMAP HANDLE
|
||
MOVE.L (A2),A2 ;POINT TO PIXMAP
|
||
MOVE.L BASEADDR(A0),D1 ;GET PORT'S BASEADDR
|
||
CMP.L BASEADDR(A2),D1 ;SAME AS SCREEN'S?
|
||
seq.b -(sp) ;push crsrFlag @@@@ BAL 14Apr88
|
||
move.l a0,a3 ;save pixmap in a3
|
||
BNE.S NOTSCRN ;=>NO, NOT SCREEN
|
||
|
||
; IT IS FROM THE SCREEN! Shield the Cursor. @@@@ BAL 14Apr88
|
||
|
||
MOVE D5,-(SP) ;PUSH GLOBAL LEFT
|
||
MOVE D4,-(SP) ;PUSH GLOBAL TOP
|
||
MOVE D5,-(SP) ;PUSH GLOBAL RIGHT
|
||
MOVE D4,-(SP) ;PUSH GLOBAL BOTTOM
|
||
MOVE.L JShieldCursor,A1 ;get lo mem vector
|
||
JSR (A1) ;and call it
|
||
|
||
MOVE.L DEVICELIST,A3 ;GET FIRST IN DEVICE LIST
|
||
|
||
DONXT MOVE.L (A3),A2 ;POINT TO DEVICE
|
||
TST GDFLAGS(A2) ;IS DEVICE ACTIVE?
|
||
BPL.S NXTDEV ;=>NO, NOT ACTIVE
|
||
LEA GDRECT(A2),A1 ;POINT TO DEVICE'S RECT
|
||
CMP (A1)+,D4 ;IS VERTICAL < GDRECT.TOP ? <SMC 18SEP90>
|
||
BLT.S NXTDEV ;=>YES, CHECK NEXT DEVICE <SMC 18SEP90>
|
||
CMP (A1)+,D5 ;IS HORIZONTAL < GDRECT.LEFT ? <SMC 18SEP90>
|
||
BLT.S NXTDEV ;=>YES, CHECK NEXT DEVICE <SMC 18SEP90>
|
||
CMP (A1)+,D4 ;IS VERTICAL >= GDRECT.BOTTOM ?
|
||
BGE.S NXTDEV ;=>YES, CHECK NEXT DEVICE
|
||
CMP (A1)+,D5 ;IS HORIZONTAL >= GDRECT.RIGHT ?
|
||
BLT.S GOTDEV ;=>NO, FOUND DEVICE
|
||
|
||
NXTDEV MOVE.L GDNEXTGD(A2),D0 ;GET HANDLE TO NEXT DEVICE
|
||
MOVE.L D0,A3 ;KEEP IN A3
|
||
BNE.S DONXT ;=>THERE IS A DEVICE
|
||
BRA DONE ;=>DEVICE NOT FOUND, JUST RETURN
|
||
|
||
; FOUND THE DEVICE! SET DEVICE AND OFFSET POINT TO DEVICE LOCAL COORDINATES
|
||
|
||
GOTDEV MOVE.L A3,THEGDEVICE ;MAKE DEVICE CURRENT
|
||
LEA GDRECT(A2),A1 ;POINT TO DEVICE'S RECT
|
||
SUB (A1)+,D4 ;OFFSET VERTICAL
|
||
SUB (A1)+,D5 ;OFFSET HORIZONTAL
|
||
MOVE.L GDPMAP(A2),A3 ;GET PIXMAP HANDLE
|
||
MOVE.L (A3),d0 ;POINT TO PIXMAP
|
||
_rTranslate24To32 ;strip off high byte @@@@ BAL 14Apr88
|
||
move.l d0,a3
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; Switch to 32 bit addressing mode
|
||
;
|
||
Needs32BitMode
|
||
move.b #$ff,(sp) ;flag the fact that MMU mode must be swapped <KON 20JUN90>
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
move.w d2,-(sp) ;save color/ bw flag across call
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a2, d0/d2)
|
||
move.w (sp)+,d2 ;restore flag in d2
|
||
;save previous state in d0 for later
|
||
bra.s MMUModeOK
|
||
|
||
NOTSCRN
|
||
;
|
||
; Check if pixmap needs 32-bit addressing <KON 20JUN90>
|
||
;
|
||
baseAddr32Bit EQU 2
|
||
|
||
tst.w rowbytes(a3) ; <KON 20JUN90>
|
||
bpl.s MMUModeOK ;it's a bitmap <KON 20JUN90>
|
||
btst #baseAddr32Bit,pmVersion+1(a3) ; <KON 20JUN90>
|
||
bne.s Needs32BitMode ;pixmap needs 32-bit addressing <KON 20JUN90>
|
||
|
||
MMUModeOK
|
||
jmpROM ciMMUModeOK
|
||
DONE
|
||
jmpROM ciGetPixelDone
|
||
|
||
ENDPROC
|
||
endif ; <124> of not TheFuture
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; New call KopyMask is copyMask with a mode and a rgn parameter.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
KopyMask PROC EXPORT
|
||
IMPORT PORTTOMAP,BITSTOMAP
|
||
|
||
CMDevLoopinROM EQU $35990
|
||
;--------------------------------------------------------------
|
||
;
|
||
; PROCEDURE KopyMask(srcBits,maskBits,dstBits: BitMap;
|
||
; srcRect,maskRect,dstRect: Rect;
|
||
; mode: INTEGER;
|
||
; maskRgn: RgnHandle *);
|
||
;
|
||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 30 ;total bytes of params
|
||
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
|
||
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
||
|
||
VARSIZE EQU 0
|
||
|
||
share LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE WORK REGISTERS FOR DEVLOOP
|
||
|
||
; SET UP REGISTERS FOR CALLING CMDEVLOOP
|
||
|
||
MOVE.L DSTBITS(A6),A1 ;GET DST BIT/PIXMAP
|
||
MOVE.L MASKBITS(A6),D0 ;GET MASK BIT/PIXMAP
|
||
MOVE.L MASKRECT(A6),D1 ;GET MASK RECTANGLE
|
||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A4),A3 ;GET THE PORT IN A3 FOR DEVLOOP
|
||
MOVE.L WIDEOPEN(A4),D2 ;ASSUME NO CLIPPING FOR FIRST RGN
|
||
MOVE.L D2,D3 ;ASSUME NO CLIPPING FOR SECOND RGN
|
||
|
||
; PUSH PARAMETERS FOR CALLING CMDEVLOOP (SAME AS STDBITS)
|
||
|
||
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRC BIT/PIXMAP
|
||
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRC RECTANGLE
|
||
MOVE.L DSTRECT(A6),-(SP) ;PUSH DST RECTANGLE
|
||
MOVE MODE(A6),-(SP) ;PUSH MODE
|
||
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN
|
||
BNE.S MASKOK ;WAS IT NIL ?
|
||
MOVE.L D2,(SP) ;YES, REPLACE WITH WIDEOPEN
|
||
MASKOK
|
||
|
||
;-----------------------------------------------------
|
||
;
|
||
; TEST IF DST IS TO THEPORT, (IF SO WE CLIP)
|
||
;
|
||
|
||
SRCOK MOVE.L DSTBITS(A6),A0 ;POINT TO DSTBITS
|
||
_BITSTOMAP ;GET POINTER TO BIT/PIXMAP IN A0
|
||
MOVE.L A0,A1 ;SAVE IN A1
|
||
MOVE.L A3,D4 ;IS THEPORT NIL ?
|
||
BEQ.S NOTPORT ;YES, NOT TO THEPORT
|
||
BTST #0,D4 ;IS THEPORT ODD ?
|
||
BNE.S NOTPORT ;YES, NOT TO THEPORT
|
||
MOVE.L D4,A0 ;GET THEPORT
|
||
_PORTTOMAP ;CONVERT PORT TO BIT/PIXMAP
|
||
MOVE.L BASEADDR(A0),D4 ;GET PORTBITS.BASEADDR
|
||
CMP.L BASEADDR(A1),D4 ;IS DST BASEADDR SAME ?
|
||
BNE.S NOTPORT ;NO, NOT TO THEPORT
|
||
MOVE.L BOUNDS(A0),D4 ;GET PORT BOUNDS TOPLEFT
|
||
CMP.L BOUNDS(A1),D4 ;IS BOUNDS TOPLEFT SAME ?
|
||
BNE.S NOTPORT ;=>NO, NOT TO THE PORT
|
||
|
||
MOVE.L CLIPRGN(A3),D2 ;YES, CLIP TO CLIPRGN
|
||
MOVE.L VISRGN(A3),D3 ;AND TO VISRGN
|
||
|
||
NOTPORT MOVE.L DSTBITS(A6),A1 ;Pass DSTBITS (not derefed) <BAL 28May89>
|
||
jsrROM CMDevLoopinROM ;AND DRAW THE IMAGE
|
||
|
||
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
|
||
UNLINK PARAMSIZE,'KopyMask'
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; DelSearch and DelComp need to call Translate24to32 on the address before searching
|
||
; for it in the list of search and comp procs. Due a screwup in the Erickson ROM, these
|
||
; routines are only installed if it's a ci class ROM. This is done below the EntryTable
|
||
; for the rest of the traps.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
DelComp PROC EXPORT ; <C666/22Jan87> DAF
|
||
|
||
ciDelCompEntry EQU $3CAF4
|
||
|
||
MOVE.L 4(SP),D0 ; get the CompProc pointer
|
||
_rTranslate24To32 ; clean up the address <KON 29May90>
|
||
move.l d0,d1 ; put proc pointer where the ROM expects it
|
||
jmpROM ciDelCompEntry
|
||
|
||
ENDPROC
|
||
|
||
DelSearch PROC EXPORT ; <C666/22Jan87> DAF
|
||
|
||
ciDelSearchEntry EQU $3CAC4
|
||
|
||
MOVE.L 4(SP),D0 ; get the SearchProc pointer
|
||
_rTranslate24To32 ; clean up the address <KON 29May90>
|
||
move.l d0,d1 ; put proc pointer where the ROM expects it
|
||
jmpROM ciDelSearchEntry
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Pointer to color was incorrect when a comp proc is installed. The offset should
|
||
; be 10 (not 8) to compensate for byte result.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
InvertColor PROC EXPORT
|
||
|
||
ciDefComp EQU $3C536
|
||
ciInvertColorEntry EQU $3C51A
|
||
;
|
||
; procedure InvertColor ( VAR myColor : RGBColor );
|
||
;
|
||
; This procedure takes an RGBColor, calculates its inverse using the current
|
||
; inverse rules, then updates the provided RGBColor. It only uses the
|
||
; compProc interface if the default is not called.
|
||
;
|
||
|
||
MOVE.L A2,-(SP) ; save a register <C601/07Jan87> DAF
|
||
MOVE.L ([theGDevice]),A2 ; get a pointer to the device port
|
||
MOVE.L GDCompProc(A2),D0 ; get the head of the complement chain
|
||
@1
|
||
BEQ.S DefComp ; if NIL, then apply default rule
|
||
MOVE.L D0,A2 ; save the pointer <C601/07Jan87> DAF
|
||
MOVE.L D0,A0 ; set up to lock this element <C666/22Jan87> DAF
|
||
_HLock ; lock it down so that A2 will be valid after the JSR <C666/22Jan87> DAF
|
||
CLR.B -(SP) ; room for a boolean result
|
||
MOVE.L 8+2(SP),-(SP) ; push the pointer to the color <26MAR90 KON>
|
||
jmpROM ciInvertColorEntry
|
||
|
||
; MOVE.L (A0),A0 ; get the element pointer <C666/22Jan87> DAF
|
||
; MOVE.L CompProc(A0),A0 ; get the complement proc ptr <C666/22Jan87> DAF
|
||
; JSR (A0) ; execute routine
|
||
; MOVE.L A2,A0 ; set up for HUnlock <C666/22Jan87> DAF
|
||
; _HUnlock ; release the compElement <C666/22Jan87> DAF
|
||
; TST.B (SP)+ ; test the result
|
||
; BNE.S FoundComp ; if result = TRUE then quit
|
||
; MOVE.L (A2),A0 ; get the compElement pointer again <C666/22Jan87> DAF
|
||
; MOVE.L NxtComp(A0),D0 ; get pointer to next <C666/22Jan87> DAF
|
||
; BRA.S @1 ;
|
||
|
||
;FoundComp
|
||
; MOVE.L (SP)+,A2 ; restore the register <C601/07Jan87> DAF
|
||
; RTD #4 ; and go home
|
||
|
||
; the default procedure is VERY simple. It just gets the complement of each
|
||
; component. It always returns a sucessful result.
|
||
DefComp
|
||
jmpROM ciDefComp
|
||
; MOVE.L 8(SP),A0 ; get pointer to RGBColor
|
||
|
||
; NOT.W (A0)+ ; complement red
|
||
; NOT.W (A0)+ ; complement green
|
||
; NOT.W (A0) ; complement bleu, svp.
|
||
; BRA.S FoundComp ; and it always works too.
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patchd to MakeITable to first search temp memory, then system zone, and finally
|
||
; theZone.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
MakeITable PROC EXPORT
|
||
EXPORT DisposeTempBuffer
|
||
FromMakeITable EQU $3C11C
|
||
ciDisposeTempBuffer EQU $31510
|
||
ciNotTemp2 EQU $3BEE4
|
||
;----------------------------------------------------------------
|
||
;
|
||
; PROCEDURE MakeITable (CTABH: CTabHandle; ITabH: ITabHandle; res:integer);
|
||
;
|
||
; This procedure builds an inverse lookup table with res bits per channel
|
||
; based on the specified color table. Algorithm by MJ Potel, based on Voronoi theory.
|
||
; Algorithm modified by Art Cabral, adding a linked list at the end of the table
|
||
; which is used to find hidden colors in Color2Index.
|
||
;
|
||
; Still to be done : Consolidate Queue and table into 1 memory block
|
||
; Convert to bitmap/iLUT form
|
||
; Eliminate BTST for TST.B
|
||
;
|
||
; 1. Use supplied cTabHandle and iTabHandle. This makes it context independent.
|
||
; 2. Compress directly into iTable. A little faster.
|
||
; 3. Shouldn't need to to error checking in QUEUE and DEQUEUE
|
||
|
||
|
||
UNDEF EQU $8000 ; hi bit on
|
||
BOUND EQU $7FFF ; non-neg, large unused index
|
||
|
||
QInTempBit EQU $00
|
||
ITableInTempBit EQU $01
|
||
|
||
PARAMSIZE EQU 10 ; total bytes of params
|
||
CTabH EQU PARAMSIZE+8-4 ; Color table handle
|
||
ITabH EQU CTabH-4 ; ITable handle
|
||
RES EQU ITabH-2 ; entry size
|
||
|
||
QStart EQU -4 ; pointer to the queue
|
||
SvZone EQU QStart-4 ; save the current zone
|
||
TblH EQU SvZone-4 ; copy of our temp ITable
|
||
TblSize EQU TblH-4 ; size of our temp ITable
|
||
InfoOffset EQU TblSize-4 ; offset to ITInfoTable from ITabH
|
||
isTmpHandle EQU InfoOffset-2 ; boolean->true if TblH is a TmpMem handle
|
||
QHandle EQU isTmpHandle-4 ; Handle for queue <28Feb90 KON>
|
||
VARSIZE EQU QHandle
|
||
|
||
|
||
LINK A6,#VARSIZE ; set up a stack frame
|
||
MOVEM.L A2-A5/D3-D7,-(SP) ; save 'em all
|
||
; move.l theZone,SvZone(A6) ; save the current heap zone for later restore <16Jan90> BAL
|
||
|
||
CLR.W QDErr ; clear QDError flag <C666/22Jan87> DAF
|
||
|
||
MOVE res(A6),D7 ; get the channel size <C777/12Feb87> EHB
|
||
CMP.L #-1,theGDevice ; if -1, then it's uninitialized <C777/12Feb87> DAF
|
||
BEQ.S @ResCheck ; OK, so continue <C777/12Feb87> DAF
|
||
|
||
@GDevOK
|
||
MOVE.L ([theGDevice]),A0 ; get a pointer to the current device <C777/12Feb87> DAF
|
||
|
||
; test the parameters. If ITabH or CTabH are NIL, substitute handles from theGDevice <C695/26Jan87> DAF
|
||
|
||
TST.L ITabH(A6) ; is ITabH NIL? <C695/26Jan87> DAF
|
||
BNE.S @DoCTabH ; no, so continue <C695/26Jan87> DAF
|
||
MOVE.L GDITable(A0),ITabH(A6) ; stick theGDevice's ITabH in stack frame <C695/26Jan87> DAF
|
||
|
||
@DoCTabH
|
||
|
||
TST.L CTabH(A6) ; is CTabH NIL? <C695/26Jan87> DAF
|
||
BNE.S @DoITabRes ; no, so continue <C695/26Jan87> DAF
|
||
MOVE.L ([GDPMap,A0]),A1 ; get pixMap's handle <C695/26Jan87> DAF
|
||
MOVE.L PMTable(A1),CTabH(A6) ; get the device colorTable's pointer <C695/26Jan87> DAF
|
||
|
||
@DoITabRes
|
||
|
||
; get the ITable resolution
|
||
|
||
TST D7 ; test the channel size <C777/09Feb87> EHB
|
||
BNE.S @ResCheck ; if valid, continue <C695/26Jan87> DAF
|
||
|
||
; the res parameter was 0, so get theGDevice's preferred resolution <C777/09Feb87> DAF
|
||
MOVE.W GDResPref(A0),D7 ; get the preferred ITabRes <C695/26Jan87> DAF
|
||
BNE.S @ResSubst ; if non-zero, then continue <C777/09Feb87> DAF
|
||
MOVEQ #4,D7 ; if resPref=0, then force to 4 <C777/09Feb87> DAF
|
||
@ResSubst
|
||
MOVE.W D7,res(A6) ; and put it in the stack frame <C695/26Jan87> DAF
|
||
|
||
@ResCheck
|
||
CMP.W #2,D7 ; don't accept res≤2 <C695/26Jan87> DAF
|
||
BLE.S @BadRes ; <C695/26Jan87> DAF
|
||
CMP.W #6,D7 ; or ≥ 6 <C695/26Jan87> DAF
|
||
BLT.S @ResOK ; <C695/26Jan87> DAF
|
||
|
||
@BadRes MOVE.W #cResErr,QDErr ; mark the error and quit <C695/26Jan87> DAF
|
||
BRA MITDone ; <C695/26Jan87> DAF
|
||
@ResOK ; <C695/26Jan87> DAF
|
||
|
||
; Calculate the size of the compressed table and verify the handle
|
||
|
||
MOVE D7,D1 ; get the channel size <C733/02Feb87> DAF
|
||
MOVEQ.L #1,D0 ; prime the register
|
||
LSL.L D1,D0 ; calculate 2^^res
|
||
LSL.L D1,D0 ; square it
|
||
LSL.L D1,D0 ; cube it
|
||
ADD.L #ITTable,D0 ; make room for everybody
|
||
MOVE.L D0,InfoOffset(A6) ; save offset to end of table
|
||
ADD.L #ITExtraSize,D0 ; make room for InfoTable
|
||
|
||
MOVE.L ITabH(A6),A0 ; get the ITable handle
|
||
TST.L (A0) ; is the table purged? <C751/03Feb87> DAF
|
||
BEQ.S @1 ; yes, so Realloc it <C751/03Feb87> DAF
|
||
_SetHandleSize ; set the size <C751/03Feb87> DAF
|
||
BRA.S @2 ; and continue <C751/03Feb87> DAF
|
||
@1
|
||
_ReallocHandle ; <C751/03Feb87> DAF
|
||
@2
|
||
BEQ.S @SizeOK ; => size ok, so continue <C733/02Feb87> DAF
|
||
MOVE.W #CNoMemErr,QDErr ; report this error <C733/02Feb87> DAF
|
||
BRA MITDone ; and quit <C733/02Feb87> DAF
|
||
|
||
@SizeOK
|
||
;--------------------------------------------------------------------- <BAL 15Mar89>
|
||
;
|
||
; Cruise through the clut and check if all non-reserved entries are grays.
|
||
; If they are then build a gray Itab and set flag in Info header to indicate grayness.
|
||
;
|
||
|
||
move.l CTabH(a6),a0 ;
|
||
move.l (a0),a0 ; get CTab ptr
|
||
move.w ctSize(a0),d0 ; get clut entries-1
|
||
lea ctTable(a0),a1 ; point at first clut entry
|
||
|
||
@nextEntry
|
||
move.l (a1)+,d1 ; pick up value,red
|
||
move.l (a1)+,d2 ; pick up green,blue
|
||
cmp.w d1,d2 ; red==blue?
|
||
bne.s @notGray ;
|
||
swap d2 ; get green
|
||
cmp.w d1,d2 ; red==green?
|
||
bne.s @notGray ;
|
||
@skippy dbra d0,@nextEntry ; continue checking
|
||
|
||
_MakeGrayITab ; go make special Gray ITab
|
||
bra MITDone ; all done
|
||
|
||
@notGray
|
||
btst #ReserveBit+24,d1 ; is this entry reserved?
|
||
bne.s @skippy ; don't check reserved entries
|
||
|
||
;--------------------------------------------------------------------- <BAL 15Mar89>
|
||
|
||
AdjZone
|
||
;
|
||
; Later we regain control at DisposeTempBuffer which is called only if isTmpHandle
|
||
; is non-zero. Since we only use the low bits to signal whether or not the handle
|
||
; resides in tmp memory or not, we set high bits to force the call to DisposeTempBuffer.
|
||
|
||
move.w #$8080,isTmpHandle(a6) ;assume handles are not in temp memory <28Feb90 KON>
|
||
;and set high bits so DisposeTempBuffer is called later
|
||
|
||
; allocate space on the heap for the queue, reading queue size from resource
|
||
|
||
SUBQ #4,SP ; make room for the function return <C835/20Feb87> DAF
|
||
MOVE.L #'mitq',-(SP) ; push the queue size resource type <C835/20Feb87> DAF
|
||
CLR.W -(SP) ; want mitq=0 <C835/20Feb87> DAF
|
||
_rGetResource ; system first, then ROM <C835/20Feb87> DAF
|
||
MOVE.L (SP)+,A0 ; get the handle <C835/20Feb87> DAF
|
||
MOVE.L (A0),A0 ; get the pointer in A0 <C835/20Feb87> DAF
|
||
MOVE.L -12(A0,D7*4),D0 ; get the queue size (adjust for no 1 or 2 bit resolutions) <C835/20Feb87> DAF
|
||
MOVE.L D0,D3 ; hold it for a second
|
||
bsr NewHandleTempSysApp ;get memory <28Feb90 KON>
|
||
BNE MakeIErrLate ; if there was an error report it
|
||
;
|
||
; Got a handle. Check which heap it's in and lock it.
|
||
;
|
||
tst.w d1 ;d1=0 -> memory in temp heap <28Feb90 KON>
|
||
bne.s @notTemp1 ; <28Feb90 KON>
|
||
bset #QInTempBit, isTmpHandle(a6) ;Main ITable is in temp memory <28Feb90 KON>
|
||
@notTemp1
|
||
;
|
||
; want a ptr, so lock and deref handle
|
||
;
|
||
move.l a0,QHandle(a6) ;save QHandle <28Feb90 KON>
|
||
_HLock ;preserves a0 <28Feb90 KON>
|
||
move.l (a0),a0 ;deref it <28Feb90 KON>
|
||
|
||
MOVE.L A0,QStart(A6) ; save the starting addr in stack frame
|
||
ADD.L D3,A0 ; compute the addr of the queue end
|
||
MOVE.L A0,A5 ; keep the queue end here
|
||
|
||
; allocate BIG space on the heap for the ITable (to be shrunken and moved to sysheap later)
|
||
|
||
MOVEQ #1,D6 ; prime the register
|
||
LSL.L D7,D6 ; calculate 2^^res
|
||
MOVE.L D6,D5 ; save here for boundary setting
|
||
ADDQ #2,D6 ; increase by 2 for the boundary
|
||
MOVE.L D6,D0 ; get it in a working register
|
||
MULU.W D6,D0 ; square it
|
||
MULU.W D6,D0 ; cube it
|
||
ADD.L D0,D0 ; table size -> words
|
||
MOVE.L D0,TblSize(A6) ; save size of table
|
||
|
||
bsr.s NewHandleTempSysApp ;search everywhere for some memory <28Feb90 KON>
|
||
bne.s MakeIErr ;failed! <28Feb90 KON>
|
||
;
|
||
; Got memory, check which heap it's in
|
||
;
|
||
tst.w d1 ;d1=0 -> memory in temp heap <28Feb90 KON>
|
||
bne.s @notTemp2 ; <28Feb90 KON>
|
||
bset #ITableInTempBit, isTmpHandle(a6) ;Main ITable is in temp memory <28Feb90 KON>
|
||
@notTemp2
|
||
jmpROM ciNotTemp2
|
||
|
||
; MOVE.L A0,TblH(A6) ; save temporary table
|
||
; MOVE.L (A0),A0 ; dereference the handle
|
||
; MOVE.L A0,A3 ; set up the table base ptr
|
||
|
||
|
||
MakeIErr
|
||
MOVE.W #CTempMemErr,QDErr ; report a table allocation error
|
||
bra.s DisposeQ
|
||
MakeIErrLate
|
||
MOVE.W #CTempMemErr,QDErr ; report a table allocation error
|
||
BRA.S MITDone
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; ComeFrom MakeITable patch on DisposeTempBuffer to do clean up for MakeITable
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
DisposeTempBuffer
|
||
|
||
cmpRA FromMakeITable, (sp)
|
||
beq.s @DoMakeITableDispose
|
||
jmpROM ciDisposeTempBuffer ;not from MakeITable: Go back to ROM
|
||
|
||
@DoMakeITableDispose
|
||
;
|
||
; remove return address so registers are restored properly
|
||
;
|
||
addq #4, sp
|
||
|
||
; a0 has handle to dispose
|
||
|
||
btst #ITableInTempBit, isTmpHandle(a6) ;is handle in temp memory? <28Feb90 KON>
|
||
beq.s @notTmp ; no, use normal dispose <2.2> BAL
|
||
_DisposeTempBuffer ; bag it <2.2> BAL
|
||
bra.s @allGone ; continue <2.2> BAL
|
||
|
||
@notTmp _DisposHandle ; release it
|
||
@allGone
|
||
|
||
;
|
||
; dispose of the memory for the Queue
|
||
;
|
||
DisposeQ ; <24Apr87> DAF
|
||
MOVE.L QHandle(A6),A0 ; release the queue <28Feb90 KON>
|
||
btst #QInTempBit, isTmpHandle(a6) ;is Queue in temp memory <28Feb90 KON>
|
||
beq.s @QnotTmp ; no, use normal dispose <28Feb90 KON>
|
||
_DisposeTempBuffer ; bag it <28Feb90 KON>
|
||
bra.s @QallGone ; continue <28Feb90 KON>
|
||
|
||
@QnotTmp _DisposHandle ; release it <28Feb90 KON>
|
||
@QallGone ; <28Feb90 KON>
|
||
|
||
MITDone ; <C695/26Jan87> DAF
|
||
; MOVE.L SvZone(A6),theZone ; always restore the zone (needed for error exits) <BAL>
|
||
MOVEM.L (SP)+,A2-A5/D3-D7 ; restore registers
|
||
UNLK A6 ; bag the stack frame
|
||
|
||
RTD #ParamSize ; flush parameters and return home <C733/02Feb87> DAF
|
||
|
||
|
||
;----------------- Subroutine to hunt for memory -----------------------------
|
||
|
||
NewHandleTempSysApp
|
||
;
|
||
; Called with requested size in d0. Routine first tries to get memory first in
|
||
; multifinder temp memory, then sys heap, then app heap. If memory found in
|
||
; temp memory, d1 returns 0, otherwise d1 is 1.
|
||
;
|
||
; Returns with: d0 error, 0=noErr
|
||
; a0 handle if no error
|
||
|
||
;
|
||
; Try temp memory if multifinder exists
|
||
;
|
||
move.l d0, -(sp) ;save requested size
|
||
moveq #0, d1 ;assume temp memory
|
||
_NewTempHandle ; look for it in temp memory
|
||
cmp.l (sp),d0 ;is it the size we requested?
|
||
beq.s @GotMem ;yes, it's big enough
|
||
|
||
_DisposeTempBuffer ;A0 already has handle of wrong size
|
||
;
|
||
; Try sys memory
|
||
;
|
||
@noMF
|
||
moveq #1, d1 ;not temp memory
|
||
move.l (sp),d0
|
||
_NewHandle ,sys
|
||
beq.s @GotMem
|
||
;
|
||
; Try app memory if zone different from system zone
|
||
;
|
||
move.l theZone,d0
|
||
cmp.l sysZone, d0 ;have we already tried this zone?
|
||
beq.s @Memoryerr ;don't try it again
|
||
|
||
move.l (sp),d0
|
||
_NewHandle
|
||
bne.s @MemoryErr ;couldn't find the memory anywhere
|
||
|
||
@GotMem
|
||
moveq #0,d0 ;signal noErr
|
||
@MemoryErr
|
||
addq #4,sp ;remove requested memory size
|
||
tst.w d0 ;set condition codes
|
||
rts
|
||
|
||
ENDPROC
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Quickerdraw traps 380, 381, 384
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
FillClipScanLine PROC EXPORT
|
||
EXPORT FillClipOrLine, FillClipXLine
|
||
|
||
;---------------------------------------------------------
|
||
;
|
||
; INTERFACE TO EACH SCAN LINE ROUTINE:
|
||
;
|
||
; ENTER WITH Z-FLAG SET IF ALL IN ONE LONG
|
||
;
|
||
; INPUTS: A1: DSTPTR
|
||
; A2: MASKPTR
|
||
; D1: RIGHTMASK
|
||
; D2: LONGCNT
|
||
; D3: LEFTMASK
|
||
; D4: FGCOLOR
|
||
; D5: BKCOLOR
|
||
; D6: PATTERN
|
||
;
|
||
; CLOBBERS: D0,D3,D2,A1,A2
|
||
; A3,D6 (BUT NOT IN FASTSLAB)
|
||
;
|
||
|
||
ciROM384 EQU $2F230
|
||
ciOld381 EQU $2F1E6 ;<38> <6/30/90 DDG> corrected the return point for $AB81.
|
||
|
||
&CurFile SETC 'DRAWSLAB'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
ALIGN Alignment
|
||
|
||
|
||
;******************************************************************************************
|
||
; QuickerDraw
|
||
; Scan line handler for clipped pattern fill copy mode (called by oval, rrect) -- trap $380
|
||
|
||
FCSL1 ; << PB452 BAL>>
|
||
FCSL2
|
||
slMASK8
|
||
|
||
AND.L (A2)+,D3 ;use left mask to start with
|
||
SUBQ #1,D2
|
||
BMI.S DoFCLast0
|
||
|
||
; special case the left edge
|
||
|
||
MOVE.L D6,D0 ;get pattern
|
||
AND.L D3,D0 ;mask it
|
||
NOT.L D3 ;flip mask
|
||
AND.L (A1),D3 ;combine with source
|
||
OR.L D3,D0 ;form dest longword
|
||
MOVE.L D0,(A1)+ ;deposit it
|
||
|
||
MOVE.L (A2)+,D3
|
||
|
||
SUBQ #1,D2
|
||
BMI.S DoFCLast0
|
||
|
||
; see if we're in the unclipped case; if so, use a faster loop
|
||
|
||
MOVE.L SEEKMASK(A6),A0 ;get seekRgn address
|
||
; CMP.W #$4E75,(A0) ;is it a RTS?
|
||
CMP.L #$343C7fff,(A0) ;is it "move.w #$7fff,d2"
|
||
BEQ.S DoFCUnclipped ;if so, handle specially
|
||
|
||
BRA.S FCNotOn1
|
||
|
||
; here's the loop -- use standard technique of special casing region masks
|
||
|
||
FCLineLoop
|
||
MOVE.L (A2)+,D3 ;fetch region mask
|
||
BEQ.S FCOff ;if all zero, can optimize
|
||
FCNotOff1
|
||
CMP.L MINUSONE,D3 ;all ones? << PB452 BAL>>
|
||
BEQ.S FCOn ;if so, optimize
|
||
FCNotOn1
|
||
MOVE.L D6,D0 ;get pattern
|
||
AND.L D3,D0 ;mask it
|
||
NOT.L D3 ;flip mask
|
||
AND.L (A1),D3 ;combine with source
|
||
OR.L D3,D0 ;form dest longword
|
||
MOVE.L D0,(A1)+ ;deposit it
|
||
|
||
DBRA D2,FCLineLoop
|
||
|
||
; handle the last one, using the mask in D1
|
||
|
||
DoFCLast
|
||
MOVE.L (A2)+,D3
|
||
DoFCLast0
|
||
AND.L D1,D3 ;use right mask
|
||
|
||
MOVE.L D6,D0 ;get pattern
|
||
AND.L D3,D0 ;mask it
|
||
NOT.L D3 ;flip mask
|
||
AND.L (A1),D3 ;combine with source
|
||
OR.L D3,D0 ;form dest longword
|
||
MOVE.L D0,(A1)+ ;deposit it
|
||
|
||
RTS
|
||
|
||
; handle the case of an all zero region mask
|
||
|
||
FCOff
|
||
ADDQ #4,A1 ;skip over it
|
||
|
||
SUBQ #1,D2
|
||
BMI.S DoFCLast
|
||
|
||
FCOffLoop
|
||
MOVE.L (A2)+,D3
|
||
BNE.S FCNotOff1
|
||
|
||
ADDQ #4,A1 ;skip it
|
||
|
||
DBRA D2,FCOffLoop
|
||
BRA.S DoFCLast
|
||
|
||
; handle the case of an all one's region mask
|
||
|
||
FCOn
|
||
MOVE.L D6,(A1)+
|
||
|
||
SUBQ #1,D2
|
||
BMI.S DoFCLast
|
||
FCOnLoop
|
||
MOVE.L (A2)+,D3
|
||
CMP.L MINUSONE,D3 ; << PB452 BAL>>
|
||
BNE.S FCNotOn1
|
||
|
||
MOVE.L D6,(A1)+
|
||
|
||
DBRA D2,FCOnLoop
|
||
BRA.S DoFCLast
|
||
|
||
; handle the unclipped case with faster unwound code
|
||
|
||
DoFCUnclipped
|
||
LEA 0(A2,D2.W*4),A2 ;bump region ptr
|
||
|
||
ADDQ #1,D2 ;compute count to do
|
||
|
||
CMP.W #8,D2
|
||
BLT.S FinishFCUnClip
|
||
|
||
MOVE.W D2,D0
|
||
LSR #3,D0 ;divide by 8
|
||
SUBQ #1,D0 ;bias for DBRA
|
||
FCUnClipLoop
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
|
||
DBRA D0,FCUnClipLoop
|
||
|
||
; now finish up the last 7 or less
|
||
|
||
FinishFCUnClip
|
||
AND #7,D2
|
||
EOR #7,D2
|
||
JMP FinishFCUCTab(D2.W*2)
|
||
FinishFCUCTab
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
|
||
BRA.S DoFCLast
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 9 OR 13: PATTERN OR DST --> DST
|
||
;
|
||
;END9 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
||
;NEXT9 AND.L D6,D3 ;MASK PATTERN DATA
|
||
; AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
||
; MOVE.L D3,D0 ;COPY MASKED, CLIPPED SRC
|
||
; AND.L D4,D0 ;APPLY FG COLOR TO SRC
|
||
; NOT.L D3 ;GET NOT MASKED, CLIPPED SRC
|
||
; AND.L (A1),D3 ;USE TO PUNCH OUT DST
|
||
; OR.L D3,D0 ;COMBINE SRC AND DST
|
||
; MOVE.L D0,(A1)+ ;MOVE RESULT INTO DST
|
||
; MOVEQ #-1,D3 ;FLUSH MASK
|
||
; SUB #1,D2 ;DEC LONG COUNT
|
||
oldslMASK9
|
||
jmpROM ciOld381
|
||
; BGT NEXT9 ;LOOP FOR ALL LONGS IN ROW
|
||
; BEQ END9 ;DO LAST LONG WITH MASK
|
||
; RTS
|
||
|
||
|
||
;******************************************************************************************
|
||
; QuickerDraw
|
||
; Scan line handler for clipped pattern fill OR mode (called by oval, rrect) -- trap $381
|
||
; similar to above, but in OR mode. We can only handle if the foreground pattern
|
||
; is all ones; if so, use the copy mode routine to fill.
|
||
|
||
UseOld381
|
||
TST.W D2
|
||
bra.s oldslMASK9
|
||
|
||
FillClipOrLine
|
||
slMASK9
|
||
CMP.L #-1,D6 ;all foreground?
|
||
BNE.S UseOld381 ;if not, we can't handle
|
||
|
||
MOVE.L D4,D6 ;set up fill pattern
|
||
BRA slMASK8 ;use common code
|
||
|
||
|
||
;******************************************************************************************
|
||
|
||
ALIGN Alignment
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: BIG PATTERN --> DST
|
||
;
|
||
slXMASK8big
|
||
jmpROM ciROM384
|
||
; MOVE D7,-(SP) ;SAVE WORK REGISTER
|
||
; MOVE PATHMASK(A6),D7 ;GET HORIZ MASK
|
||
; MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
||
; ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
||
; AND D7,D6 ;MASK INDEX INTO PATTERN
|
||
; MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
||
; ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
||
; TST D2
|
||
; BRA.S XDO8
|
||
|
||
;XEND8 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
||
;XNEXT8 MOVE.L 0(A3,D6),D0 ;GET PATTERN DATA
|
||
; ADDQ #4,D6 ;BUMP PATTERN INDEX
|
||
; AND D7,D6 ;MASK INDEX INTO PATTERN
|
||
; AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
||
; AND.L D3,D0 ;MASK PATTERN DATA
|
||
; NOT.L D3 ;MAKE NOTMASK
|
||
; AND.L (A1),D3 ;AND NOTMASK WITH OLD DST
|
||
; OR.L D0,D3 ;FILL HOLE WITH PATTERN
|
||
; MOVE.L D3,(A1)+ ;UPDATE DST
|
||
; MOVEQ #-1,D3 ;FLUSH MASK
|
||
; SUB #1,D2 ;DEC LONG COUNT
|
||
;XDO8 BGT XNEXT8 ;LOOP FOR ALL LONGS IN ROW
|
||
; BEQ XEND8 ;DO LAST LONG WITH MASK
|
||
; MOVE (SP)+,D7 ;RESTORE WORK REGISTER
|
||
; RTS
|
||
|
||
|
||
;******************************************************************************************
|
||
; QuickerDraw
|
||
; Scan line handler for clipped pattern fill copy mode (called by oval, rrect)
|
||
; for complex patterns-- trap $384
|
||
|
||
|
||
FillClipXLine
|
||
slXMASK8
|
||
|
||
CMP.W #4,PATHMASK(A6) ;pattern too complex?
|
||
BGT.S slXMASK8big ;if so, don't handle
|
||
|
||
MOVE.L D7,-(SP) ;save work register
|
||
|
||
; keep the pattern in D6 and D7
|
||
|
||
ADD.W PATHPOS(A6),D0
|
||
AND #4,D0
|
||
|
||
MOVE.L EXPAT(A6),A0
|
||
ADD.l PATVPOS(A6),A0 ; <BAL 07Nov89>
|
||
|
||
MOVE.L 0(A0,D0),D6 ;get left pattern
|
||
EOR.W #4,D0
|
||
MOVE.L 0(A0,D0),D7 ;get right pattern
|
||
|
||
; fetch the leftmost region mask
|
||
|
||
MOVEQ #-1,D4 ;all ones for comparing
|
||
AND.L (A2)+,D3 ;use left mask to start with
|
||
|
||
SUBQ #1,D2
|
||
BMI.S DoFCXLast0
|
||
|
||
; special case the left edge
|
||
|
||
MOVE.L D6,D0 ;get pattern
|
||
AND.L D3,D0 ;mask it
|
||
NOT.L D3 ;flip mask
|
||
AND.L (A1),D3 ;combine with source
|
||
OR.L D3,D0 ;form dest longword
|
||
MOVE.L D0,(A1)+ ;deposit it
|
||
|
||
EXG.L D6,D7
|
||
|
||
MOVE.L (A2)+,D3
|
||
|
||
SUBQ #1,D2
|
||
BMI.S DoFCXLast0
|
||
|
||
; see if we're in the unclipped case; if so, use a faster loop
|
||
|
||
MOVE.L SEEKMASK(A6),A0 ;get seekRgn address
|
||
; CMP.W #$4E75,(A0) ;is it a RTS?
|
||
CMP.L #$343C7fff,(A0) ;is it "move.w #$7fff,d2"
|
||
BEQ.S DoFCXUnclipped ;if so, handle specially
|
||
|
||
BRA.S FCXNotOn1
|
||
|
||
; here's the loop -- use standard technique of special casing region masks
|
||
|
||
FCXLineLoop
|
||
MOVE.L (A2)+,D3 ;fetch region mask
|
||
BEQ.S FCXOff ;if all zero, can optimize
|
||
FCXNotOff1
|
||
CMP.L D4,D3 ;all ones?
|
||
BEQ.S FCXOn ;if so, optimize
|
||
FCXNotOn1
|
||
MOVE.L D6,D0 ;get pattern
|
||
AND.L D3,D0 ;mask it
|
||
NOT.L D3 ;flip mask
|
||
AND.L (A1),D3 ;combine with source
|
||
OR.L D3,D0 ;form dest longword
|
||
MOVE.L D0,(A1)+ ;deposit it
|
||
|
||
EXG.L D6,D7
|
||
DBRA D2,FCXLineLoop
|
||
|
||
; handle the last one, using the mask in D1
|
||
|
||
DoFCXLast
|
||
MOVE.L (A2)+,D3
|
||
DoFCXLast0
|
||
AND.L D1,D3 ;use right mask
|
||
|
||
MOVE.L D6,D0 ;get pattern
|
||
AND.L D3,D0 ;mask it
|
||
NOT.L D3 ;flip mask
|
||
AND.L (A1),D3 ;combine with source
|
||
OR.L D3,D0 ;form dest longword
|
||
MOVE.L D0,(A1)+ ;deposit it
|
||
|
||
MOVE.L (SP)+,D7 ;restore work reg
|
||
RTS
|
||
|
||
; handle the case of an all zero region mask
|
||
|
||
FCXOff
|
||
ADDQ #4,A1 ;skip over it
|
||
EXG D6,D7 ;swap pattern halves, even if skipping <79>
|
||
|
||
SUBQ #1,D2
|
||
BMI.S DoFCXLast
|
||
|
||
FCXOffLoop
|
||
MOVE.L (A2)+,D3
|
||
BNE.S FCXNotOff1
|
||
|
||
ADDQ #4,A1 ;skip it
|
||
EXG D6,D7 ;swap pattern halves, even if skipping <79>
|
||
|
||
DBRA D2,FCXOffLoop
|
||
BRA.S DoFCXLast
|
||
|
||
; handle the case of an all one's region mask
|
||
|
||
FCXOn
|
||
MOVE.L D6,(A1)+
|
||
EXG.L D6,D7
|
||
|
||
SUBQ #1,D2
|
||
BMI.S DoFCXLast
|
||
FCXOnLoop
|
||
MOVE.L (A2)+,D3
|
||
CMP.L D4,D3
|
||
BNE.S FCXNotOn1
|
||
|
||
MOVE.L D6,(A1)+
|
||
EXG.L D6,D7
|
||
|
||
DBRA D2,FCXOnLoop
|
||
BRA.S DoFCXLast
|
||
|
||
; handle the unclipped case with faster unwound code
|
||
|
||
DoFCXUnclipped
|
||
LEA 0(A2,D2.W*4),A2 ;bump region ptr
|
||
|
||
ADDQ #1,D2 ;compute count to do
|
||
|
||
CMP.W #8,D2
|
||
BLT.S FinishFCXUnClip
|
||
|
||
MOVE.W D2,D0
|
||
LSR #3,D0 ;divide by 8
|
||
SUBQ #1,D0 ;bias for DBRA
|
||
FCXUnClipLoop
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D7,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D7,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D7,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D7,(A1)+
|
||
|
||
DBRA D0,FCXUnClipLoop
|
||
|
||
; now finish up the last 7 or less
|
||
|
||
FinishFCXUnClip
|
||
AND #7,D2
|
||
EOR #7,D2
|
||
|
||
BTST #0,D2
|
||
BEQ.S @0
|
||
|
||
EXG.L D6,D7
|
||
@0
|
||
JMP FinishFCXUCTab(D2.W*2)
|
||
FinishFCXUCTab
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D7,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D7,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
MOVE.L D7,(A1)+
|
||
MOVE.L D6,(A1)+
|
||
|
||
EXG.L D6,D7
|
||
BRA DoFCXLast
|
||
|
||
ENDPROC
|
||
|
||
;******************************************************************************************
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to DisposGDevice
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
newDisposGDevice PROC EXPORT
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DisposGDevice (GDH: GDHandle);
|
||
;
|
||
; disposes of the gDevice record and its handles
|
||
;
|
||
; if the device we're disposing is the same as LastTxGDevice,
|
||
; move MainGDevice to LastTxGDevice
|
||
|
||
move.l 4(sp), a1 ;ok to Trash a1
|
||
cmp.l LastTxGDevice, a1 ;handle we're disposing same as LastTxGDev?
|
||
bne.s @BackToROM
|
||
move.l MainDevice, LastTxGDevice ;yes, update LastTxGDevice
|
||
@BackToROM
|
||
BackToTrap oldDisposGDevice
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to stNoStack to try for 128K instead of 64K.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
stNoStack PROC EXPORT
|
||
|
||
ciNoMem EQU $379D8
|
||
ciSHOW EQU $37942
|
||
cistNoStack EQU $37992
|
||
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
tst.l StackFree(a6) ;did we run out of stack?
|
||
bpl.s SHOW ;no, just go home
|
||
clr.l StackFree(a6)
|
||
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.
|
||
|
||
moveq #4,d0 ;Get 128K
|
||
jmpROM cistNoStack
|
||
@noMem
|
||
jmpROM ciNoMem
|
||
SHOW
|
||
jmpROM ciSHOW
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Come-from Patch so quickPoly's, drawline, and drawarc support large rowbytes.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
ciFastSlabMode EQU $30040
|
||
FromArc EQU $34AB2
|
||
FromLine EQU $29D42
|
||
FromPoly EQU $340A8
|
||
|
||
FastSlabMode PROC EXPORT
|
||
IMPORT TryLineArc, RAMFastSlabMode
|
||
|
||
;--------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE FastSlabMode, Call when rect clipped and pattern black.
|
||
;
|
||
; INPUT: D2: MODE, CLOBBERED mode 0=black, 1=xor, 2=white
|
||
; OUTPUT: A4: MODECASE
|
||
;
|
||
&CurFile SETC 'DRAWPOLY'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
cmpRA FromPoly, (sp)
|
||
bne.s TryLineArc
|
||
MOVE MINRECT+TOP(A6),D1 ;GET MINRECT TOP
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT TO GLOBAL COORDS
|
||
MOVE DSTPIX+ROWBYTES(A6),D0 ;GET DST ROWBYTES
|
||
AND #nuRBMask,D0 ;CLEAR FLAG BITS
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE.L D0,DSTROW(A6) ;SAVE FOR LATER
|
||
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
||
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
||
|
||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
||
ext.l d2 ;clear out high end <BAL 13Feb90>
|
||
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
||
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
||
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
||
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
||
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
|
||
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
|
||
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||
BRA RAMFastSlabMode
|
||
|
||
ENDPROC
|
||
|
||
TryLineArc PROC EXPORT
|
||
IMPORT TryLine, RAMFastSlabMode
|
||
|
||
&CurFile SETC 'DRAWARC'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
cmpRA FromArc, (sp)
|
||
bne.s TryLine
|
||
MOVE MINRECT+TOP(A6),D1 ;GET MINRECT TOP
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT TO GLOBAL COORDS
|
||
MOVE DSTPIX+ROWBYTES(A6),D0 ;GET DST ROWBYTES
|
||
AND #nuRBMask,D0 ;CLEAR FLAG BITS
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE.L D0,DSTROW(A6) ;SAVE FOR LATER
|
||
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
||
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
||
|
||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
||
ext.l d2 ;clear out high end <BAL 13Feb90>
|
||
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
||
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
||
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
||
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
||
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
|
||
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
|
||
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||
BRA RAMFastSlabMode
|
||
|
||
ENDPROC
|
||
|
||
TryLine PROC EXPORT
|
||
IMPORT RAMFastSlabMode
|
||
&CurFile SETC 'DRAWLINE'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
cmpRA FromLine, (sp)
|
||
bne.s ArcLinePolyBackToROM
|
||
MOVE MINRECT+TOP(A6),D1
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT MINV TO GLOBAL COORDS
|
||
MOVE DSTPIX+ROWBYTES(A6),D0 ;get dst rowbytes
|
||
AND #nuRBMask,D0 ;clear off flag bits
|
||
MOVE D0,DSTROW(A6) ;SAVE FOR LATER
|
||
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
||
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
||
|
||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
||
ext.l d2 ;clear out high end <BAL 13Feb90>
|
||
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
||
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
||
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
||
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
||
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
|
||
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
|
||
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
||
|
||
ArcLinePolyBackToROM
|
||
BRA RAMFastSlabMode
|
||
|
||
ENDPROC
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Come-from Patch so quickPoly's, drawline, and drawarc support large rowbytes.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
ciGetSeek EQU $3AF40
|
||
|
||
GETSEEK PROC EXPORT
|
||
IMPORT TryArcOrLine
|
||
|
||
ciReturnPoly EQU $34086
|
||
FromPolys EQU $34058
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; GetSeek(RgnHandle1, RgnHandle2, ..., HandleCount.L);
|
||
;
|
||
; SET UP ADDRESS OF SEEK ROUTINE IN SEEKMASK(A6)
|
||
; SET UP ADDRESS OF EXPAND ROUTINE IN EXRTN(A6)
|
||
;
|
||
; CLOBBERS: A0-A3,D0-D4
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; LINK DONE BY CALLER (STRETCHBITS, RGNBLT, ScaleBlt, DRAWLINE, DRAWARC, QuickPolys)
|
||
;
|
||
&CurFile SETC 'DRAWPOLY'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
cmpRA FromPolys, (sp) ;check old return address
|
||
bne.s TryArcOrLine
|
||
addq #4,sp ;set stack up just like getSeek expects
|
||
jsrROM ciGetSeek
|
||
peaROM ciReturnPoly ;new return address
|
||
MOVE MINRECT+TOP(A6),D1 ;GET MINRECT TOP
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT TO GLOBAL COORDS
|
||
MOVE DSTPIX+ROWBYTES(A6),D0 ;GET DST ROWBYTES
|
||
AND #nuRBMask,D0 ;CLEAR FLAG BITS
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE.L D0,DSTROW(A6) ;SAVE FOR LATER
|
||
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
||
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
||
|
||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
||
ext.l d2 ;clear out high end <BAL 13Feb90>
|
||
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
||
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
||
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
||
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
||
rts
|
||
|
||
ENDPROC
|
||
|
||
TryArcOrLine PROC EXPORT
|
||
IMPORT TryArc
|
||
|
||
FromDrawLine EQU $29CEC
|
||
ciReturnLine EQU $29D18
|
||
|
||
&CurFile SETC 'DRAWLINE'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
cmpRA FromDrawLine, (sp)
|
||
bne.s TryArc
|
||
addq #4,sp ;set stack up just like getSeek expects
|
||
jsrROM ciGetSeek
|
||
peaROM ciReturnLine
|
||
MOVE MINRECT+TOP(A6),D1
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT MINV TO GLOBAL COORDS
|
||
MOVE DSTPIX+ROWBYTES(A6),D0 ;get dst rowbytes
|
||
AND #nuRBMask,D0 ;clear off flag bits
|
||
MOVE D0,DSTROW(A6) ;SAVE FOR LATER
|
||
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
||
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
||
|
||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
||
ext.l d2 ;clear out high end <BAL 13Feb90>
|
||
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
||
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
||
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
||
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
||
rts
|
||
|
||
ENDPROC
|
||
|
||
TryArc PROC EXPORT
|
||
|
||
FromDrawArc EQU $34A4A
|
||
ciReturnArc EQU $34A78
|
||
|
||
&CurFile SETC 'DRAWARC'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
cmpRA FromDrawArc, (sp)
|
||
bne.s JustDoIt
|
||
addq #4,sp ;set stack up just like getSeek expects
|
||
jsrROM ciGetSeek
|
||
peaROM ciReturnArc
|
||
MOVE MINRECT+TOP(A6),D1 ;GET MINRECT TOP
|
||
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT TO GLOBAL COORDS
|
||
MOVE DSTPIX+ROWBYTES(A6),D0 ;GET DST ROWBYTES
|
||
AND #nuRBMask,D0 ;CLEAR FLAG BITS
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE.L D0,DSTROW(A6) ;SAVE FOR LATER
|
||
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
||
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
||
|
||
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
||
ext.l d2 ;clear out high end <BAL 13Feb90>
|
||
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
||
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
||
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
||
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
||
rts
|
||
|
||
JustDoIt
|
||
jmpROM ciGetSeek
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch PutDirectPMData
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
PutDirectPMData PROC EXPORT ;17Jun88 BAL
|
||
|
||
PackWords EQU $35D60
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; PROCEDURE PutDirectPMData (mySrc,myData: Ptr; oldRowBytes: INTEGER);
|
||
;
|
||
; Currently, only default packing is implemented and packType is ignored
|
||
;
|
||
PARAMSIZE EQU 10
|
||
MYSRC EQU PARAMSIZE+8-4 ;src pixmap pointer
|
||
MYDATA EQU MYSRC-4 ;data pointer
|
||
OLDROWBYTES EQU MYDATA-2 ;old row bytes
|
||
|
||
SRCPTR EQU -4 ;VAR POINTER TO SOURCE
|
||
DSTPTR EQU SRCPTR-4 ;VAR POINTER TO DST
|
||
SRCBUF EQU DSTPTR-4 ;PTR TO REARRANGED SRC <16Jun88 BAL>
|
||
PACKBUF EQU SRCBUF-4 ;POINTER TO PACKING BUFFER
|
||
SAVEDSP EQU PACKBUF-4 ;PRESERVE STACK POINTER
|
||
VARSIZE EQU SAVEDSP
|
||
|
||
LINK A6,#VARSIZE ;MAKE A STACK FRAME
|
||
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
MOVE.L SP,SAVEDSP(A6) ;PRESERVE STACK POINTER
|
||
MOVE.L MYSRC(A6),A2 ;POINT TO (TRIMMED) BITMAP
|
||
MOVE.L MYDATA(A6),A3 ;POINT TO THE DATA
|
||
MOVE OLDROWBYTES(A6),D4 ;GET OLD ROWBYTES
|
||
MOVEQ #8,D6 ;GET USEFUL VALUE
|
||
|
||
MOVE BOUNDS+BOTTOM(A2),D7
|
||
SUB BOUNDS+TOP(A2),D7 ;HEIGHT := BOUNDS BOT - TOP
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; 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
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; Determine desired packing scheme:
|
||
;
|
||
; Type Depth(s) Description
|
||
; ---- -------- -----------
|
||
; 1 16/32 No packing; Save trimmed memory image
|
||
; 2 16 Pixel packing; RunLength by pixel size (PackWords)
|
||
; 3 32 Drop pad byte; Save RGB triples
|
||
; 4 32 Run packing; RunLength by component by scanline
|
||
;
|
||
|
||
MOVE ROWBYTES(A2),D5 ;GET ROWBYTES
|
||
AND #nuRBMask,D5 ;CLEAR OFF FLAG BITS
|
||
CMP D6,D5 ;IS NEWROW < 8 ?
|
||
BLT NoPacking ;YES, DON'T TRY TO PACK
|
||
cmp.w #2,packType(a2) ;is packing desired?
|
||
blt NoPacking ;no, don't pack
|
||
beq DropPadByte ;yes, just drop pad byte
|
||
cmp.w #3,packType(a2) ;RunLength 16 bit pixels?
|
||
beq PixelPacking ;yes, run length (16 bit) pixels
|
||
|
||
|
||
|
||
RunPacking
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ALLOCATE PACKBUF ON THE STACK
|
||
;
|
||
SUB D5,SP ;GET SIZE OF SRCBUF <16Jun88 BAL>
|
||
MOVE.L SP,SRCBUF(A6) ;POINT TO SRCBUF <16Jun88 BAL>
|
||
SUB D5,SP ;GET SIZE OF PACKBUF <16Jun88 BAL>
|
||
MOVE D5,D0 ;GET ROWBYTES <16Jun88 BAL>
|
||
LSR #8,D0 ;COMPUTE RUNS OF 128 BYTES <12Jul88 BAL>
|
||
ADDQ #1,D0 ;ROUND UP <16Jun88 BAL>
|
||
ADD.L D0,D0 ;ROUND UP <12Jul88 BAL>
|
||
SUB D0,SP ;GET ROOM FOR PACK COUNTS <16Jun88 BAL>
|
||
MOVE.L SP,PACKBUF(A6) ;POINT TO PACKBUF
|
||
|
||
; ASSUME: PIXELSIZE = 32
|
||
; CMPSIZE = 8
|
||
; CMPCOUNT = 3,4
|
||
|
||
ADDQ #4,A3 ;POINT PAST END OF FIRST PIXEL
|
||
SUB CMPCOUNT(A2),A3 ;POINT TO FIRST CMP OF FIRST PIXEL
|
||
;----------------------------------------------------------------
|
||
;
|
||
; PACKED FORMAT = [BYTECOUNT][RLE:rrrr...gggg...bbbb] FOR EACH SCANLINE
|
||
;
|
||
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
|
||
;
|
||
BRA START4 ;GO TO LOOP START
|
||
|
||
MORE4
|
||
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
MOVE CMPCOUNT(A2),D0 ;GET CMPCOUNT FOR LOOP <16Jun88 BAL>>
|
||
SUBQ #1,D0 ;MAKE IT ZERO BASED
|
||
MOVE.L SRCBUF(A6),A0 ;POINT TO UNWINDING BUFFER
|
||
MOVE D5,D3 ;GET ROWBYTES
|
||
LSR #2,D3 ;GET PIXEL WIDTH @@@@@
|
||
SUBQ #1,D3 ;MAKE IT ZERO BASED
|
||
|
||
@NXTCMP MOVE.L A3,A4 ;PTR INTO THIS CMP OF FIRST PIXEL
|
||
ADDQ #1,A3 ;POINT AT NEXT CMP
|
||
MOVE D3,D6 ;GET ROWBYTES
|
||
|
||
@NXTPIX MOVE.B (A4),(A0)+ ;COPY COMPONENT
|
||
ADDQ #4,A4 ;BUMP TO NEXT PIXEL
|
||
DBRA D6,@NXTPIX
|
||
DBRA D0,@NXTCMP ; <16Jun88 BAL><
|
||
|
||
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
SUB CMPCOUNT(A2),A3 ;RESET A3 TO FIRSTCMP, FIRSTPIX
|
||
MOVE.L SRCBUF(A6),SRCPTR(A6) ;SRCPTR := ^SCANLINE DATA
|
||
MOVE.L PACKBUF(A6),A0
|
||
MOVE.L A0,DSTPTR(A6) ;DSTPTR := @PACKBUF
|
||
PEA SRCPTR(A6) ;PUSH VAR SRCPTR
|
||
PEA DSTPTR(A6) ;PUSH VAR DSTPTR
|
||
ADDQ #1,D3 ;MAKE IT ONE BASED <16Jun88 BAL>
|
||
MULU CMPCOUNT(A2),D3 ;COMPUTE SIZE OF SRCBUF DATA <16Jun88 BAL>
|
||
MOVE D3,-(SP) ;PUSH SRCBYTES = NEWROW <16Jun88 BAL>
|
||
_PackBits ;PACK ROW INTO PACKBUF
|
||
MOVE.L DSTPTR(A6),D6 ;GET UPDATED DSTPTR
|
||
MOVE.L PACKBUF(A6),A0 ;POINT TO PACKBUF
|
||
SUB.L A0,D6 ;CALC PACKED BYTECOUNT
|
||
CMP #250,D5 ;IS ROWBYTES > 250?
|
||
BGT.S @1 ;=>YES, PUT WORD
|
||
MOVE.B D6,-(SP) ;ELSE PUSH THE BYTE
|
||
JSRROM PUTPICBYTE ;AND PUT TO PICTURE
|
||
BRA.S @2 ;=>AND GO PUT DATA
|
||
@1 MOVE.W D6,-(SP) ;PUSH PACKED BYTECOUNT
|
||
JSRROM PUTPICWORD ;PUT THE WORD
|
||
@2 MOVE.L PACKBUF(A6),-(SP)
|
||
MOVE D6,-(SP)
|
||
JSRROM PutPicData ;PUT PACKED DATA TO THEPIC
|
||
ADD D4,A3 ;ADD OLDROW TO BITS PTR
|
||
START4 DBRA D7,MORE4 ;LOOP FOR HEIGHT ROWS
|
||
BRA DONE ;ALL DONEROO
|
||
|
||
|
||
|
||
PixelPacking
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ASSUME: PIXELSIZE = 16
|
||
;
|
||
; D4 = Src rowBytes
|
||
; D5 = Dst rowBytes
|
||
; D7 = Height
|
||
; A3 = Src Ptr
|
||
;
|
||
;----------------------------------------------------------------
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ALLOCATE PACKBUF ON THE STACK
|
||
;
|
||
SUB D5,SP ;SET SIZE OF PACKBUF
|
||
SUB D5,SP ;TO 2*ROWBYTES FOR LONG ALIGNMENT
|
||
MOVE.L SP,PACKBUF(A6) ;POINT TO PACKBUF
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; PACKED FORMAT = [BYTECOUNT][DATA] FOR EACH SCANLINE
|
||
;
|
||
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
|
||
;
|
||
BRA.S START3 ;GO TO LOOP START
|
||
MORE3 MOVE.L A3,SRCPTR(A6) ;SRCPTR := ^SCANLINE DATA
|
||
MOVE.L PACKBUF(A6),A0
|
||
MOVE.L A0,DSTPTR(A6) ;DSTPTR := @PACKBUF
|
||
PEA SRCPTR(A6) ;PUSH VAR SRCPTR
|
||
PEA DSTPTR(A6) ;PUSH VAR DSTPTR
|
||
MOVE D5,-(SP) ;PUSH SRCBYTES = NEWROW
|
||
|
||
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
JSRROM PackWords ;PACK ROW INTO PACKBUF
|
||
|
||
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
MOVE.L DSTPTR(A6),D6 ;GET UPDATED DSTPTR
|
||
MOVE.L PACKBUF(A6),A0 ;POINT TO PACKBUF
|
||
SUB.L A0,D6 ;CALC PACKED BYTECOUNT
|
||
CMP #250,D5 ;IS ROWBYTES > 250?
|
||
BGT.S @1 ;=>YES, PUT WORD
|
||
MOVE.B D6,-(SP) ;ELSE PUSH THE BYTE
|
||
JSRROM PUTPICBYTE ;AND PUT TO PICTURE
|
||
BRA.S @2 ;=>AND GO PUT DATA
|
||
@1 MOVE.W D6,-(SP) ;PUSH PACKED BYTECOUNT
|
||
JSRROM PUTPICWORD ;PUT THE WORD
|
||
@2 MOVE.L PACKBUF(A6),-(SP)
|
||
MOVE D6,-(SP)
|
||
JSRROM PutPicData ;PUT PACKED DATA TO THEPIC
|
||
ADD D4,A3 ;ADD OLDROW TO BITS PTR
|
||
START3 DBRA D7,MORE3 ;LOOP FOR HEIGHT ROWS
|
||
BRA DONE ;ALL DONEROO
|
||
|
||
|
||
|
||
|
||
DropPadByte
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ASSUME: PIXELSIZE = 32
|
||
; CMPSIZE = 8
|
||
; CMPCOUNT = 3
|
||
;
|
||
; D4 = Src rowBytes
|
||
; D5 = Dst rowBytes
|
||
; D7 = Height
|
||
; A3 = Src Ptr
|
||
;
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ALLOCATE PACKBUF ON THE STACK
|
||
;
|
||
SUB D5,SP ;GET SIZE OF SRCBUF
|
||
MOVE.L SP,SRCBUF(A6) ;POINT TO SRCBUF
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; PACKED FORMAT = [BYTECOUNT][RGB,RGB,RGB,...] FOR EACH SCANLINE
|
||
;
|
||
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
|
||
;
|
||
MOVE D5,D6 ;GET ROWBYTES
|
||
LSR #2,D6 ;GET PIXEL WIDTH @@@@@
|
||
SUBQ #1,D6 ;MAKE IT ZERO BASED
|
||
;D6 has rowPixels-1
|
||
|
||
BRA.S START2 ;GO TO LOOP START
|
||
MORE2
|
||
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
MOVE.L SRCBUF(A6),A2 ;POINT TO UNWINDING BUFFER
|
||
MOVE.L A3,A4 ;PTR TO FIRST CMP OF FIRST PIXEL
|
||
move.w d6,d0 ;get rowPixels-1 in d0
|
||
|
||
@NXTPIX ADDQ #1,A4 ;POINT AT FIRST CMP (skip pad)
|
||
MOVE.B (A4)+,(A2)+ ;COPY red COMPONENT
|
||
MOVE.B (A4)+,(A2)+ ;COPY green COMPONENT
|
||
MOVE.B (A4)+,(A2)+ ;COPY blue COMPONENT
|
||
DBRA D0,@NXTPIX
|
||
|
||
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
SUB.L SRCBUF(A6),A2 ;CALC PACKED BYTECOUNT
|
||
@2 MOVE.L SRCBUF(A6),-(SP)
|
||
MOVE A2,-(SP)
|
||
JSRROM PutPicData ;PUT PACKED DATA TO THEPIC
|
||
ADD D4,A3 ;ADD OLDROW TO BITS PTR
|
||
START2 DBRA D7,MORE2 ;LOOP FOR HEIGHT ROWS
|
||
BRA.S DONE ;ALL DONEROO
|
||
|
||
|
||
|
||
NoPacking
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ROWBYTES < 8, or PackType->noPacking, DONT USE PACKBITS
|
||
;
|
||
;
|
||
; D4 = Src rowBytes
|
||
; D5 = Dst rowBytes
|
||
; D7 = Height
|
||
; A3 = Src Ptr
|
||
;
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ALLOCATE PACKBUF ON THE STACK
|
||
;
|
||
SUB D5,SP ;GET SIZE OF SRCBUF
|
||
MOVE.L SP,SRCBUF(A6) ;POINT TO SRCBUF
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; IF ROWBYTES > 250 THEN BYTECOUNT IS A WORD, ELSE IT IS A BYTE
|
||
;
|
||
ext.l d5 ;D5 has rowbytes
|
||
|
||
BRA.S START1 ;GO TO LOOP START
|
||
MORE1
|
||
moveq #true32b,d0 ;switch to 32 bit addressing for source access <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
MOVE.L SRCBUF(A6),A1 ;POINT TO dest BUFFER
|
||
MOVE.L A3,A0 ;PTR TO FIRST byte of src
|
||
move.l d5,d0 ;get rowbytes in d0
|
||
|
||
_BlockMove ;copy from there to here
|
||
;assumes here is a 24 bit address
|
||
|
||
moveq #false32b,d0 ;switch back before calling PutPicProc <BAL 02Feb90>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
MOVE.L SRCBUF(A6),-(SP)
|
||
MOVE D5,-(SP)
|
||
JSRROM PutPicData ;PUT PACKED DATA TO THEPIC
|
||
ADD D4,A3 ;ADD OLDROW TO BITS PTR
|
||
START1 DBRA D7,MORE1 ;LOOP FOR HEIGHT ROWS
|
||
|
||
DONE MOVE.L SAVEDSP(A6),SP ;RESTORE STACK POINTER
|
||
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
|
||
UNLINK PARAMSIZE,'PUTDPMDAT' ;UNLINK AND RETURN
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to ScrollRect so the update region is set properly when scrolling between
|
||
; different resolution devices.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
ScrollRect PROC EXPORT
|
||
|
||
ciScrollEntry EQU $35C1A
|
||
ciAbort EQU $35C3E
|
||
|
||
;---------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE ScrollRect(srcRect: Rect; dh,dv: INTEGER; updateRgn: RgnHandle);
|
||
;
|
||
; Scroll a rectangular block of bits, erase and return an update region
|
||
; If the update region is nil, don't erase it.
|
||
;
|
||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 12 ;TOTAL BYTES OF PARAMS
|
||
SRCRECT EQU PARAMSIZE+8-4 ;LONG, ADDR OF RECT
|
||
DH EQU SRCRECT-2 ;WORD
|
||
DV EQU DH-2 ;WORD
|
||
UPDATEREGION EQU DV-4 ;LONG, RGNHANDLE
|
||
|
||
DSTRECT EQU -8 ;RECT
|
||
tempRect1 EQU DSTRECT-8 ;rect
|
||
tempRect2 EQU tempRect1-8 ;rect
|
||
globalSrc EQU tempRect2-8 ;rect
|
||
VARSIZE EQU globalSrc ;TOTAL LOCALS
|
||
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D6-D7/A3-A4,-(SP) ;SAVE REGS
|
||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
|
||
MOVE.L PICSAVE(A3),-(SP) ;SAVE PICSAVE HANDLE
|
||
CLR.L PICSAVE(A3) ;DON'T RECORD TO PICTURES
|
||
|
||
TST PNVIS(A3) ;IS PNVIS < 0 ?
|
||
BLT ABORT ;YES, QUIT FAST
|
||
TST.L DV(A6) ;ARE DH AND DV BOTH 0 ?
|
||
BEQ ABORT ;YES, QUIT FAST
|
||
|
||
; SAVE FOREGROUND AND BACKGROUND COLORS, AND SET TO BLACK AND WHITE FOR SCROLL
|
||
|
||
|
||
sub.l #ColorSpecSize,sp ;make room for an ColorSpec <DDG 28Jan90>
|
||
move.l sp,-(sp) ;point to this record
|
||
_SaveFore
|
||
sub.l #ColorSpecSize,sp ;make room for an ColorSpec <DDG 28Jan90>
|
||
move.l sp,-(sp) ;point to this record
|
||
_SaveBack
|
||
|
||
MOVE.L #BLACKCOLOR,-(SP) ;PUSH BLACK
|
||
_FORECOLOR ;AND SET FOREGROUND COLOR TO BLACK
|
||
MOVE.L #WHITECOLOR,-(SP) ;PUSH WHITE
|
||
_BACKCOLOR ;AND SET BACKGROUND COLOR TO BLACK
|
||
|
||
; ALLOCATE TEMP REGIONS FOR CALCULATIONS
|
||
|
||
SUB #8,SP ;ROOM FOR 2 FCN RESULT
|
||
_NEWRGN ;ALLOCATE SRCRGN
|
||
MOVE.L (SP)+,D7 ;GET SRCRGN IN D7
|
||
_NEWRGN ;ALLOCATE DSTRGN
|
||
MOVE.L (SP)+,D6 ;GET DSTRGN IN D6
|
||
|
||
; srcRgn := srcRect SECT visRgn SECT clipRgn
|
||
|
||
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
||
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
||
_RECTRGN ;RectRgn(srcRgn,srcRect);
|
||
|
||
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
||
MOVE.L VISRGN(A3),-(SP) ;PUSH VISRGN
|
||
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
||
_SECTRGN ;SectRgn(srcRgn,visRgn,srcRgn);
|
||
|
||
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
||
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN
|
||
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
||
_SECTRGN ;SectRgn(srcRgn,clipRgn,srcRgn);
|
||
|
||
; dstRgn := offset srcRgn
|
||
|
||
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
||
MOVE.L D6,-(SP) ;PUSH DSTRGN
|
||
_COPYRGN ;CopyRgn(srcRgn,dstRgn);
|
||
MOVE.L D6,-(SP) ;PUSH DSTRGN
|
||
MOVE.L DV(A6),-(SP) ;PUSH DH,DV
|
||
_OFSETRGN ;OffsetRgn(dstRgn,dh,dv);
|
||
|
||
; DSTRECT := OFFSETRECT(SRCRECT,DH,DV)
|
||
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
||
MOVE.L (A0)+,DSTRECT(A6) ;COPY SRCRECT INTO DSTRECT
|
||
MOVE.L (A0)+,DSTRECT+4(A6)
|
||
MOVE.L DV(A6),D0 ;GET DH,DV
|
||
ADD D0,DSTRECT+LEFT(A6) ;OFFSET DSTRECT (DH,DV)
|
||
ADD D0,DSTRECT+RIGHT(A6)
|
||
SWAP D0 ;GET DV IN LO WORD
|
||
ADD D0,DSTRECT+TOP(A6)
|
||
ADD D0,DSTRECT+BOTTOM(A6)
|
||
|
||
; MASKRGN := SECTRGN(SRCRGN,DSTRGN)
|
||
; NOTE: UPDATERGN CAN'T BE USED AS MASKRGN BECAUSE IF UPDATERGN = VISRGN
|
||
; THEN NOTHING WILL BE SCROLLED
|
||
|
||
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
||
MOVE.L D6,-(SP) ;PUSH DSTRGN
|
||
MOVE.L D6,-(SP) ;KEEP MASKRGN
|
||
_SECTRGN ;SectRgn(srcRgn,dstRgn,maskRgn);
|
||
|
||
|
||
;----------------------------------------------------------------------------------------------------
|
||
;
|
||
; Now we check for multiple devices and do the correct things here <DDG 28Jan90>
|
||
;
|
||
|
||
move.l DeviceList,a0 ;get the head of the device list <DDG 28Jan90>
|
||
move.l (a0),a0 ;deref it
|
||
move.l GDNextGD(a0),d0 ;check the next device field. If it's zero
|
||
beq oneDevice ;..then goto one device
|
||
|
||
;
|
||
; Allocate extra region used by cutOutDevices
|
||
;
|
||
movem.l d5/a2,-(sp) ;save reg.
|
||
clr.l -(sp) ;make room for result
|
||
_NewRgn ;allocate another RGN <DDG 28Jan90>
|
||
move.l (sp)+,d5 ;put our new region in d5
|
||
|
||
;
|
||
; convert the source rect to global coordinates
|
||
;
|
||
|
||
move.l srcRect(a6),a1 ;point to our source rect
|
||
lea globalSrc(a6),a0 ;point to out global source rect
|
||
move.l (a1)+,topleft(a0) ;copy srcRect.topleft
|
||
move.l (a1)+,botright(a0) ;copy srcRect.botRight
|
||
pea topleft(a0) ;convert the global rect to global coordinates
|
||
_LocalToGlobal
|
||
pea botright(a0)
|
||
_LocalToGlobal
|
||
|
||
;
|
||
; Start scanning through the device list
|
||
;
|
||
|
||
move.l DeviceList,a2 ;get the device list header into A2
|
||
|
||
@loop move.l (a2),a4 ;deref the current device list handle
|
||
tst GDFlags(a4) ;is the device active ?
|
||
bpl.s @next ;=>no, skip to the next device
|
||
|
||
clr.b -(sp) ;make space for boolean result
|
||
pea globalSrc(a6) ;pointer to the SrcRect in global coordinates
|
||
pea GDRect(a4) ;pointer to the device rect
|
||
pea tempRect1(a6) ;pointer to the result
|
||
_SectRect ;get the intersection
|
||
tst.b (sp)+ ;if they didn't intersect at all, then skip to
|
||
beq.s @next ;..the next device
|
||
|
||
move.l DV(a6),d0 ;get DV into high word and DH into low word
|
||
add d0,tempRect1+left(a6)
|
||
add d0,tempRect1+right(a6)
|
||
swap d0 ;get DV into the low word
|
||
add d0,tempRect1+top(a6)
|
||
add d0,tempRect1+bottom(a6)
|
||
|
||
move.l GDPMap(a4),a0 ;get handle to the source pixMap
|
||
move.l (a0),a0 ;deref it
|
||
move.l pmTable(a0),a0 ;get handle to source color table
|
||
move.l (a0),a0 ;deref it
|
||
move.l ctSeed(a0),d1 ;get color table seed into d1
|
||
|
||
bsr cutOutDevices ;this cuts out different devices from d5
|
||
|
||
@next move.l (a2),a4 ;deref the current device list handle
|
||
move.l GDNextGD(a4),d0 ;get the next device handle into D0
|
||
move.l d0,a2 ;move it to our current handle. If it's NOT null
|
||
bne.s @loop ;..then loop back.
|
||
|
||
MOVE.L D5,A0 ;GET tmp region used by cutOutDevices
|
||
_DISPOSHANDLE ;DISCARD IT
|
||
movem.l (sp)+,d5/a2 ;restore d5
|
||
|
||
;----------------------------------------------------------------------------------------------------
|
||
oneDevice
|
||
|
||
; Scroll the rect using CopyBits
|
||
|
||
PEA PORTBITS(A3) ;PUSH SRCBITS
|
||
MOVE.L (SP),-(SP) ;PUSH DSTBITS
|
||
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
||
PEA DSTRECT(A6) ;PUSH DSTRECT
|
||
CLR -(SP) ;PUSH MODE = SRCCOPY
|
||
MOVE.L D6,-(SP) ;PUSH MASK REGION
|
||
_COPYBITS ;COPY THE BITS
|
||
|
||
; RESTORE FOREGROUND AND BACKGROUND COLORS
|
||
|
||
move.l sp,-(sp) ;point to the saved back color and restore it
|
||
_RestoreBack ; <DDG 28Jan90>
|
||
add.l #ColorSpecSize,sp ;strip the ColorSpec off the stack
|
||
move.l sp,-(sp) ;point to the saved back color and restore it
|
||
_RestoreFore
|
||
add.l #ColorSpecSize,sp ;strip the ColorSpec off the stack
|
||
|
||
jmpROM ciScrollEntry
|
||
ABORT
|
||
jmpROM ciAbort
|
||
|
||
;----------------------------------------------------------------------------------------------------
|
||
cutOutDevices
|
||
move.l DeviceList,a1 ;get the device list header into A1
|
||
|
||
@loop move.l (a1),a0 ;deref the current device list handle
|
||
tst GDFlags(a0) ;is the device active ?
|
||
bpl @next ;=>no, skip to the next device
|
||
|
||
move.l GDPMap(a0),a0 ;get handle to the source pixMap
|
||
move.l (a0),a0 ;deref it
|
||
move.l pmTable(a0),a0 ;get handle to source color table
|
||
move.l (a0),a0 ;deref it
|
||
cmp.l ctSeed(a0),d1 ;do the color tables seeds match ?
|
||
beq.s @next
|
||
|
||
movem.l d1/a1,-(sp) ;save our scratch registers
|
||
|
||
clr.b -(sp) ;make space for boolean result
|
||
pea tempRect1(a6) ;pointer to the SrcRect in global coordinates
|
||
move.l (a1),a0 ;deref the current device list handle
|
||
pea GDRect(a0) ;pointer to the device rect
|
||
pea tempRect2(a6) ;pointer to the result
|
||
_SectRect ;get the intersection
|
||
tst.b (sp)+ ;if they didn't intersect at all, then skip to
|
||
beq.s @skip ;..the next device
|
||
|
||
lea tempRect2(a6),a0 ;point to our temp rect
|
||
pea topleft(a0) ;convert the temp rect back to local coordinates
|
||
_GlobalToLocal
|
||
pea botright(a0)
|
||
_GlobalToLocal
|
||
|
||
move.l d5,-(sp) ;convert tempRect2 into a region
|
||
pea tempRect2(a6)
|
||
_RectRgn
|
||
move.l d6,-(sp) ;subtract this little invalid rect out of the
|
||
move.l d5,-(sp) ;..mask region.
|
||
move.l d6,-(sp)
|
||
_DiffRgn
|
||
|
||
@skip movem.l (sp)+,d1/a1 ;restore our scratch registers
|
||
|
||
@next move.l (a1),a0 ;deref the current device list handle
|
||
move.l GDNextGD(a0),d0 ;get the next device handle into D0
|
||
move.l d0,a1 ;move it to our current handle. If it's NOT null
|
||
bne.s @loop ;..then loop back.
|
||
|
||
rts
|
||
|
||
ENDPROC
|
||
;----------------------------------------------------------------------------------------------------
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to Index2Color to use the same algorithm as Search16toIndexed (stretch.a) in
|
||
; order to make colors match in SeedCFill/CalcCMask.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
Index2Color PROC EXPORT
|
||
|
||
;
|
||
; procedure Index2Color ( index : longint; VAR myColor : RGBColor );
|
||
;
|
||
; This procedure takes an index value and returns the RGB
|
||
; components of this element of theGDPort^^.GDPMap.pmTable.
|
||
;
|
||
|
||
ciIndex2ColorEntry EQU $3C4DE
|
||
|
||
|
||
MOVE.L 8(SP),D0 ; get the index <C491/06Dec86> DAF
|
||
MOVE.L 4(SP),A0 ; get pointer to result RGB <C491/06Dec86> DAF
|
||
MOVE.L ([theGDevice]),A1 ; get the current device pointer
|
||
MOVE.L ([GDPMap,A1]),A1 ; get the device pixelmap pointer
|
||
cmp #16,pixelType(a1) ; is it a direct device? <BAL 06Jul88>
|
||
beq.s I2CDirect ; yes, no CLUT <BAL 06Jul88>
|
||
|
||
MOVE.L ([pmTable,A1]),A1 ; point to the color table
|
||
; CLR.W QDErr ; clear the error register <1.9>
|
||
|
||
MOVE.W ctSize(A1),D1 ; get ctSize <C491/06Dec86> DAF
|
||
CMP.W D1,D0 ; is index in range? <C491/06Dec86> DAF
|
||
BGT.S I2CErr ; nope, so quit <C491/06Dec86> DAF
|
||
MOVE.W CTTable+rgb+red(A1,D0.L*8),red(A0) ; move red <C491/06Dec86> DAF
|
||
MOVE.L CTTable+rgb+green(A1,D0.L*8),green(A0) ; move green & blue <C491/06Dec86> DAF
|
||
I2CDone
|
||
RTD #8 ; and return
|
||
|
||
I2CErr
|
||
MOVE.W #cRangeErr,QDErr ; set error code
|
||
BRA.S I2CDone ;
|
||
|
||
I2CDirect ; Handle 24bit/pixel direct devices <BAL 06Jul88>
|
||
moveq #8,d1 ; get handy constant
|
||
sub.w cmpSize(a1),d1 ; shift needed to left justify cmp
|
||
beq.s I2C24 ; cmpsize is 8 so go fast
|
||
|
||
;enter with a 16-bit source pixel in d0
|
||
|
||
lsl.l #3,d0 ;left align blue in lo byte
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;get 5 bits of blue
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;make into 10 bits of blue
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;make into 15 bits of blue
|
||
move.b d0,d1
|
||
lsr.l #7,d1 ;get a word of blue
|
||
MOVE.w d1,blue(a0) ;store out in color spec
|
||
|
||
lsr.l #5,d0 ;left align green in lo byte
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;get 5 bits of green
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;make into 10 bits of green
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;make into 15 bits of green
|
||
move.b d0,d1
|
||
lsr.l #7,d1 ;get a word of green
|
||
MOVE.w d1,green(a0) ;store out in color spec
|
||
|
||
lsr.l #5,d0 ;left align red in lo byte
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;get 5 bits of red
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;make into 10 bits of red
|
||
move.b d0,d1
|
||
lsl.l #5,d1 ;make into 15 bits of red
|
||
move.b d0,d1
|
||
lsr.l #7,d1 ;get a word of red
|
||
MOVE.w d1,red(a0) ;store out in color spec
|
||
|
||
bra.s I2CDone
|
||
I2C24
|
||
jmpROM ciIndex2ColorEntry
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to StdBits to clear dither bit when recording an old picture.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
StdBits PROC EXPORT
|
||
IMPORT PutDirectPMData
|
||
|
||
;PutPMData EQU $336D0 defined earlier...
|
||
ciEntry EQU $3518E
|
||
ciNOTD EQU $351A6
|
||
ciNotPic EQU $351CE
|
||
ciBitsOK EQU $351CC
|
||
SHFTTBL EQU $304B6
|
||
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdBits(VAR srcBits: BitMap;
|
||
; VAR srcRect: Rect;
|
||
; VAR dstRect: Rect;
|
||
; mode: INTEGER;
|
||
; maskRgn: RgnHandle);
|
||
;
|
||
|
||
; SRC DEVICE RECORDS STORED ON STACK
|
||
|
||
FLAG EQU 0 ;OFFSET TO FLAG
|
||
DEV EQU FLAG+2 ;OFFSET TO DEVICE
|
||
RECT EQU DEV+4 ;OFFSET TO RECT
|
||
SIZE EQU RECT+8 ;SIZE OF RECORD
|
||
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 18
|
||
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
||
SRCRECT EQU SRCBITS-4 ;LONG, ADDR OF RECT
|
||
DSTRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
||
MODE EQU DSTRECT-2 ;WORD
|
||
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
||
|
||
SRCPIX EQU -(PMREC+CTREC+20) ;PIXMAP + COLOR TABLE
|
||
TEMPPIX EQU SRCPIX-PMREC ;PIXMAP
|
||
DSTBITS EQU TEMPPIX-4 ;DST BITMAP
|
||
GLOBALSRC EQU DSTBITS-8 ;GLOBAL COPY OF SRC RECT
|
||
GLOBALDST EQU GLOBALSRC-8 ;GLOBAL COPY OF DST RECT
|
||
SRCRECT1 EQU GLOBALDST-8 ;LOCAL COPY OF SRC RECT
|
||
DSTRECT1 EQU SRCRECT1-8 ;LOCAL COPY OF DST RECT (MUST FOLLOW SRCRECT1)
|
||
RECT1 EQU DSTRECT1-8 ;RESULT OF INTERSECTION
|
||
DEFSRC EQU RECT1-SIZE ;DEFAULT SRC RECORD
|
||
ENDSRC EQU DEFSRC-4 ;0 FOR TERMINATING SRC LIST
|
||
SRCDEV EQU ENDSRC-4 ;CURRENT SRC DEVICE RECORD
|
||
ENDDST EQU SRCDEV-4 ;0 FOR TERMINATING DST LIST
|
||
DSTDEV EQU ENDDST-4 ;CURRENT DST DEVICE
|
||
SRCLIST EQU DSTDEV-4 ;POINTER TO SORTED SRC RECT LIST
|
||
DSTLIST EQU SRCLIST-4 ;POINTER TO SORTED DST RECT LIST
|
||
SAVEDSP EQU DSTLIST-4 ;SAVED STACK POINTER
|
||
LASTSEED EQU SAVEDSP-4 ;LAST COLOR TABLE SEED
|
||
SAVEFG EQU LASTSEED-4 ;ORIGINAL FG COLOR
|
||
SAVEBK EQU SAVEFG-4 ;ORIGINAL BK COLOR
|
||
SAVEHILITE EQU SAVEBK-2 ;SAVED HILITE MODE FLAG
|
||
RGNA EQU SAVEHILITE-4 ;FIRST REGION FOR CLIPPING
|
||
RGNB EQU RGNA-4 ;SECOND REGION FOR CLIPPING
|
||
MASKBITS EQU RGNB-4 ;BITMAP FOR MASK
|
||
MASKRECT EQU MASKBITS-4 ;LONG, ADDR OF MASK RECT
|
||
isTmpHandle EQU MASKRECT-1 ;BYTE, FLAG SET IF temp memory used <1.5> BAL
|
||
OLDPIC EQU isTmpHandle-1 ;BYTE, FLAG SET IF OLD PICTURE <1.5> BAL
|
||
VARSIZE EQU OLDPIC ;TOTAL SIZE OF LOCALS
|
||
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGS
|
||
_CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
;
|
||
; Set flag in OLDPIC(A6) if recording to old picture. <28May89 BAL>
|
||
;
|
||
MOVE.L PICSAVE(A3),A0 ;GET PICSAVE HANDLE <26May87 EHB>
|
||
MOVE.L (A0),A0 ;POINT TO PICSAVE RECORD <26May87 EHB>
|
||
CMP #PICTVERSION,PICVERSION(A0) ;IS IT AN OLD PICTURE? <26May87 EHB>
|
||
SEQ OLDPIC(A6) ;yes, set flag <26May87 EHB>
|
||
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; CONVERT SRCBITS TO A PIXMAP
|
||
; (A5 must contain global ptr)
|
||
;
|
||
MOVE.L SRCBITS(A6),A1 ;GET POINTER TO SRCBITS
|
||
TST ROWBYTES(A1) ;IS IT A BITMAP OR A PIXMAP
|
||
SPL D7 ;SET FLAG IF BITMAP
|
||
move d7,d6 ;Bits to pix clears pixmap/bitmap bit <30Jan90 KON>
|
||
or.b oldPic(a6),d7 ;d7=oldPic|bitMap <28May89 BAL>
|
||
LEA SRCPIX(A6),A2 ;COPY INTO SRCPIX
|
||
_BitsToPix ;BITMAP -> PIXMAP; RETURNS SCREEN FLAG IN D2 <BAL 19Sep88>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; GET SHIFT AMOUNT FOR SRC DEPTH INTO D3
|
||
;
|
||
leaROM SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
||
MOVE SRCPIX+PIXELSIZE(A6),D0 ;GET SRC PIXEL SIZE
|
||
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D0),D3 ;GET SHIFT AMOUNT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; IF SRC IS THE SCREEN, THEN USE COPYBITS TO COPY THE SRC TO AN OFFSCREEN BITMAP
|
||
; THIS ENSURES THAT SRC IS CONTIGUOUS, ALL ONE DEPTH, ETC.
|
||
;
|
||
CLR.L RECT1(A6) ;CLEAR HANDLE TO SAVED BITS
|
||
TST.B D2 ;IS SRC THE SCREEN? <BAL 19Sep88>
|
||
Bne.s doScreen ;Yes, convert it <KON 30Jan90>
|
||
tst.b d6 ;is source a bitmap? <KON 30Jan90>
|
||
bne notScrn ;YES, don't convert <KON 30Jan90>
|
||
tst.b OldPic(a6) ;is dst old port? <KON 30Jan90>
|
||
beq notScrn ;No, then don't convert source <KON 30Jan90>
|
||
bra doConvert
|
||
|
||
doScreen
|
||
|
||
IF 1 THEN ;Can't optimize if screen needs 32-bit addressing
|
||
|
||
|
||
;<d√b>
|
||
;----------------------------------------------------
|
||
; If the source is only one screen, copy straight across. (No need for
|
||
; temp offscreen pixmap.)
|
||
TST.B D7 ;Unless, that is, the dst is an OLD port,
|
||
BNE MultiMapSrc ;which'll require flattening.
|
||
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRC RECTANGLE
|
||
LEA SRCRECT1(A6),A1 ;POINT TO PLACE FOR COPY
|
||
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
||
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
||
|
||
PEA SRCRECT1(A6) ;PUSH COPY OF SRCRECT
|
||
NEG.W D1 ;left (D1=topLeft from BitsToPix)
|
||
SWAP D1
|
||
NEG.W D1 ;top
|
||
SWAP D1
|
||
MOVE.L D1,-(SP)
|
||
_OffsetRect ;SRCRECT1 is the global srcrect. (it used to happen later on)
|
||
|
||
CLR D4 ;How many devices does src intersect? <pb535a>
|
||
MOVE.L DeviceList,A2 ;A0=handle to head of device list
|
||
@gdrt
|
||
MOVE.L (A2),A2 ;A2->device
|
||
TST GDFLAGS(A2) ;IS IT ACTIVE?
|
||
BPL.S @nextgd ;=>NO, SKIP TO NEXT
|
||
|
||
SUBQ #2,SP ;Boolean result
|
||
PEA gdRect(A2) ;device global rect
|
||
PEA SRCRECT1(A6) ;source bitmap rect in global
|
||
PEA DSTRECT1(A6) ;put the intersection here(throwaway).
|
||
_SectRect
|
||
TST.B (SP)+ ;Any intersection at all?
|
||
BEQ.S @nextgd ;=>No, go do the next gd.
|
||
ADDQ #1,D4 ;=>Yes, count it. <pb535a>
|
||
MOVE.L A2,DSTDEV(A6) ;stash this device ptr here (as SRC)
|
||
|
||
@nextgd
|
||
MOVE.L gdNextGD(A2),D0
|
||
MOVE.L D0,A2
|
||
BNE.S @gdrt
|
||
|
||
CMP #1,D4 ;If the srcrect intersects more than <pb535a>
|
||
BGT.S MultiMapSrc ;one gdevice, do offscreen map.
|
||
|
||
MOVE.L DSTDEV(A6),A1 ;A1->the single source gdevice
|
||
MOVE.L gdPMap(A1),A1 ;A1=handle to pixmap
|
||
MOVE.L (A1),A1 ;A1->pixmap
|
||
move.l baseAddr(a1),d4 ;save un-stripped screen base in d4
|
||
LEA SRCPIX(A6),A2 ;A2->our local srcpix record
|
||
_BitsToPix ;BITMAP -> PIXMAP; RETURNS SCREEN FLAG IN D2
|
||
|
||
move.l d4,SRCPIX+baseAddr(a6) ;prevent stripping on alternate screens
|
||
PEA SRCPIX+bounds(A6) ;Fix bounds for SRCPIX
|
||
MOVE.L SRCBITS(A6),A0 ;by offsetting by original source bounds
|
||
MOVE.L bounds+topLeft(A0),-(SP)
|
||
_OffsetRect
|
||
|
||
leaROM SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
||
MOVE SRCPIX+PIXELSIZE(A6),D0 ;GET SRC PIXEL SIZE (redo for different gdevice)
|
||
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D0),D3 ;GET SHIFT AMOUNT (redo for different gdevice)
|
||
BRA NOTSCRN ;And pretend source isn't a screen.
|
||
|
||
MultiMapSrc ;2 or more active gdevices intersected
|
||
|
||
|
||
ENDIF
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; OFFSET SRCRECT TO GLOBAL COORDINATES AND GET SCREEN DEPTH
|
||
;
|
||
doConvert
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRC RECTANGLE
|
||
LEA SRCRECT1(A6),A1 ;POINT TO PLACE FOR COPY
|
||
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
||
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
||
|
||
PEA SRCRECT1(A6) ;PUSH COPY OF SRCRECT
|
||
MOVE.L SRCBITS(A6),A0 ;GET SRCBITS
|
||
MOVE.L BOUNDS(A0),D0 ;GET BOUNDS.TOPLEFT
|
||
NEG D0 ;NEGATE BOUNDS.LEFT
|
||
SWAP D0 ;GET BOUNDS.TOP
|
||
NEG D0 ;NEGATE BOUNDS.TOP
|
||
SWAP D0 ;GET BOUNDS.TOPLEFT
|
||
MOVE.L D0,-(SP) ;PUSH BOUNDS.TOPLEFT
|
||
_OFFSETRECT ;OFFSET RECT TO GLOBAL COORDINATES
|
||
|
||
CLR.L -(SP) ;MAKE ROOM FOR HANDLE
|
||
PEA SRCRECT1(A6) ;POINT TO GLOBAL RECT
|
||
_GETMAXDEVICE ;GET DEEPEST SCREEN DEVICE
|
||
MOVE.L (SP)+,D0 ;POP DEVICE HANDLE
|
||
BEQ BITSOK ;=>NOT ON SCREEN, DON'T RECORD
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; Set up off screen GDevice for the Copy
|
||
; SET TEMP PIXMAP USING INFO FROM DEEPEST SCREEN
|
||
;
|
||
move.l theGDevice,-(sp) ;save current GDevice <BAL 23Jan89>
|
||
move.l d0,theGDevice ;set up offscreen GDevice <BAL 23Jan89>
|
||
|
||
MOVE.L D0,A0 ;GET HANDLE TO DEEPEST DEVICE
|
||
MOVE.L (A0),A0 ;POINT TO DEEPEST DEVICE
|
||
MOVE.L GDPMAP(A0),A0 ;GET HANDLE TO ITS PIXMAP
|
||
MOVE.L (A0),A0 ;POINT TO PIXMAP
|
||
LEA TEMPPIX(A6),A1 ;POINT TO DST
|
||
MOVEQ #(PMREC/2)-1,D0 ;GET NUMBER OF WORDS IN RECORD
|
||
@0 MOVE (A0)+,(A1)+ ;COPY A WORD
|
||
DBRA D0,@0 ;=>REPEAT UNTIL DONE
|
||
|
||
clr.w TEMPPIX+PMVERSION(A6) ;clear 32bit addressing flag <BAL 15Dec88>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; SET TEMPPIX.BOUNDS TO SRCRECT
|
||
;
|
||
MOVE.L SRCRECT(A6),A0 ;POINT AT SRC RECTANGLE
|
||
LEA TEMPPIX+BOUNDS(A6),A1 ;POINT AT DST BOUNDS
|
||
MOVE.L (A0)+,D1 ;GET TOPLEFT
|
||
MOVE.L D1,(A1)+ ;COPY TOPLEFT
|
||
MOVE.L (A0)+,D0 ;GET BOTRIGHT
|
||
MOVE.L D0,(A1)+ ;COPY BOTRIGHT
|
||
|
||
MOVE D0,D5 ;GET A COPY OF RIGHT
|
||
SUB D1,D5 ;GET WIDTH IN PIXELS
|
||
EXT.L D5 ;MAKE IT LONG
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; FLAG IN D7 is set IF RECORDING A BITMAP or recording to old picture.
|
||
; GET DEPTH-SHIFT FOR PIXMAP IN D3 AND ROWBYTES FOR PICTURE IN D5.
|
||
; FORCE DEPTH TO 1 IF SRC IS BITMAP OR IF RECORDING OLD PICTURE.
|
||
;
|
||
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
||
|
||
TST.B D7 ;IS IT A BITMAP? <BAL 28May89>
|
||
BNE.S ITSBITS ;=>YES, GO CALCULATE ROWBYTES
|
||
|
||
leaROM SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
||
MOVE TEMPPIX+PIXELSIZE(A6),D2 ;GET BITS PER PIXEL
|
||
MOVE.B 0(A0,D2),D3 ;GET SHIFT AMOUNT
|
||
|
||
ITSBITS LSL.L D3,D5 ;CONVERT PIXELS TO BITS
|
||
MOVEQ #15,D2 ;GET 15
|
||
ADD.L D2,D5 ;ROUND UP TO NEAREST WORD BOUNDARY
|
||
ASR.L #4,D5 ;DIV BY 16
|
||
BLE BITSOK ;IGNORE IF NEWROW <= 0
|
||
ADD D5,D5 ;DOUBLE FOR NEW ROWBYTES
|
||
MOVE D5,TEMPPIX+ROWBYTES(A6) ;COPY ROWBYTES
|
||
MOVE D5,D4 ;OLD ROWBYTES := NEW ROWBYTES
|
||
TST.B D7 ;IS DST A PIXMAP?
|
||
BNE.S NOFLAG ;=>NO, DON'T NEED FLAG
|
||
OR #$8000,TEMPPIX+ROWBYTES(A6) ;SET PIXMAP FLAG
|
||
|
||
NOFLAG
|
||
;----------------------------------------------------
|
||
;
|
||
; ALLOCATE MEMORY FOR TEMP PIXMAP AND COPY TO IT
|
||
;
|
||
SWAP D1 ;GET LEFTTOP
|
||
SWAP D0 ;GET RIGHTBOT
|
||
SUB D1,D0 ;GET HEIGHT
|
||
MULU D5,D0 ;GET DATA SIZE IN BYTES
|
||
move.l d0,d5 ;copy size in d5 <1.5> BAL
|
||
clr.b isTmpHandle(a6) ;clear temp memory flag <1.5> BAL
|
||
_NEWHANDLE ;ALLOCATE MEMORY FOR BITMAP
|
||
beq.s @gotMem ;go use it <1.5> BAL
|
||
|
||
st isTmpHandle(a6) ;set temp memory flag <1.5> BAL
|
||
move.l d5,d0 ;request size <1.5> BAL
|
||
_NewTempHandle ;ask for it <1.5> BAL
|
||
cmp.l d5,d0 ;did we get it all? <1.5> BAL
|
||
bge.s @gotMem ;yes, go use it <1.5> BAL
|
||
|
||
move.l (sp)+,theGDevice ;restore the current GDevice <1.5> BAL
|
||
move.w #-143,qdErr ;return something <1.5> BAL
|
||
bra BITSOK ;=>ERROR, JUST TRY TO DRAW <1.5> BAL
|
||
|
||
@gotMem MOVE.L A0,RECT1(A6) ;SAVE FOR DISPOSE
|
||
_HLOCK ;LOCK THE HANDLE
|
||
MOVE.L (A0),d0 ;POINT AT THE STORAGE
|
||
_rTranslate24To32 ;map address in D0 <02Feb90 BAL>
|
||
MOVE.L d0,TEMPPIX+BASEADDR(A6) ;AND SET BASE ADDRESS OF TEMP
|
||
|
||
MOVE.L PICSAVE(A3),-(SP) ;SAVE PICSAVE ON THE STACK
|
||
CLR.L PICSAVE(A3) ;DISABLE PICTURE FOR COPY!
|
||
|
||
SUBQ #6,SP ;MAKE ROOM FOR RGBCOLOR
|
||
MOVE.L SP,-(SP) ;POINT TO VAR RGBCOLOR
|
||
_GETFORECOLOR ;SAVE THE RGBFORECOLOR
|
||
MOVEQ #BLACKCOLOR,D0 ;GET A LITTLE BLACK
|
||
MOVE.L D0,-(SP) ;AND SMACK IT ON THE STACK
|
||
_FORECOLOR ;SO OUR COPY'S BACK IN WHACK
|
||
|
||
PEA SRCPIX(A6) ;PUSH TRIMMED SRC PIXMAP
|
||
PEA TEMPPIX(A6) ;PUSH DST PIXMAP
|
||
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
||
MOVE.L (SP),-(SP) ;DSTRECT = SRCRECT
|
||
CLR -(SP) ;MODE = SRC COPY
|
||
btst.b #6,Mode+1(a6) ;dither? <KON 30Jan90>
|
||
beq.s @NoDither ; <KON 30Jan90>
|
||
move.w #$40,(sp) ;set dither mode <KON 30Jan90>
|
||
@NoDither
|
||
CLR.L -(SP) ;NO MASKRGN
|
||
_COPYBITS ;COPY THE PIXMAP
|
||
|
||
MOVE.L SP,-(SP) ;POINT AT FORECOLOR
|
||
_RGBFORECOLOR ;RESTORE IT
|
||
ADDQ #6,SP ;STRIP FORECOLOR
|
||
MOVE.L (SP)+,PICSAVE(A3) ;RESTORE PICTURE STATE
|
||
|
||
move.l (sp)+,theGDevice ;restore the current GDevice <BAL 23Jan89>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; COPY TEMPPIX INTO SRCPIX AND USE AS NEW SRC PIXMAP
|
||
;
|
||
LEA TEMPPIX(A6),A0 ;POINT TO TEMPPIX
|
||
LEA SRCPIX(A6),A1 ;POINT TO SRCPIX
|
||
MOVEQ #(PMREC/2)-1,D0 ;GET NUMBER OF WORDS IN PIXMAP
|
||
@0 MOVE (A0)+,(A1)+ ;COPY A WORD
|
||
DBRA D0,@0 ;=>REPEAT UNTIL DONE
|
||
|
||
|
||
NOTSCRN
|
||
;----------------------------------------------------
|
||
;
|
||
; TRIM LOCAL COPY OF PIXMAP
|
||
;
|
||
|
||
LEA SRCPIX(A6),A1 ;POINT TO PIXMAP
|
||
MOVE.L BASEADDR(A1),A3 ;GET BASEADDR
|
||
MOVE ROWBYTES(A1),D4 ;GET OLD ROWBYTES
|
||
AND #nuRBMask,D4 ;CLEAR FLAG BITS
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
||
MOVE TOP(A0),D0 ;GET SRCRECT.TOP
|
||
SUB BOUNDS+TOP(A1),D0 ;SKIPTOP:=SRCRECT.TOP-BOUNDS.TOP
|
||
BLE.S TOPOK ;CONTINUE IF SKIPTOP NEG
|
||
ADD D0,BOUNDS+TOP(A1) ;NEWTOP := SRCRECT TOP
|
||
MULU D4,D0 ;CALC VERT OFFSET
|
||
ADD.L D0,A3 ;ADJUST BASEADDR
|
||
|
||
TOPOK MOVE BOTTOM(A0),D0 ;GET SRCRECT.BOTTOM
|
||
CMP BOUNDS+BOTTOM(A1),D0 ;IS SRCRECT BOT < BOUNDS BOT ?
|
||
BGE.S BOTOK ;NO, CONTINUE
|
||
MOVE D0,BOUNDS+BOTTOM(A1) ;YES, TRIM BOUNDS BOTTOM
|
||
|
||
BOTOK MOVE LEFT(A0),D0 ;GET SRCRECT.LEFT
|
||
SUB BOUNDS+LEFT(A1),D0 ;CALC SKIPLEFT
|
||
BLE.S LEFTOK ;CONTINUE IF SKIPLEFT NEG
|
||
EXT.L D0 ;MAKE IT LONG
|
||
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
||
ASR.L #3,D0 ;DIV BY 8 FOR SKIP BYTES
|
||
ADD.L D0,A3 ;OFFSET BASEADDR HORIZ
|
||
LSL.L #3,D0 ;BYTES TIMES 8 FOR BITS
|
||
ASR.L D3,D0 ;CONVERT BITS TO PIXELS
|
||
ADD D0,BOUNDS+LEFT(A1) ;ADD DOTS TO BOUNDS.LEFT
|
||
|
||
LEFTOK MOVE RIGHT(A0),D0 ;GET SRCRECT.RIGHT
|
||
SUB BOUNDS+LEFT(A1),D0 ;CONVERT TO GLOBAL
|
||
EXT.L D0 ;MAKE IT LONG
|
||
ADDQ.L #7,D0 ;ROUND UP
|
||
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
||
AND #$FFF8,D0 ;TRUNC TO BYTE BOUNDARY
|
||
ASR.L D3,D0 ;CONVERT BITS TO PIXELS
|
||
ADD BOUNDS+LEFT(A1),D0 ;RETURN TO LOCAL
|
||
CMP BOUNDS+RIGHT(A1),D0 ;IS RESULT < BOUNDS.RIGHT ?
|
||
BGE.S RIGHTOK ;NO, CONTINUE
|
||
MOVE D0,BOUNDS+RIGHT(A1) ;YES, TRIM RIGHT
|
||
RIGHTOK
|
||
;
|
||
; CALC NEW ROWBYTES AFTER TRIMMING
|
||
;
|
||
MOVE BOUNDS+RIGHT(A1),D5 ;GET TRIMMED RIGHT
|
||
SUB BOUNDS+LEFT(A1),D5 ;CALC WIDTH IN PIXELS
|
||
EXT.L D5 ;MAKE IT LONG
|
||
LSL.L D3,D5 ;CONVERT PIXELS TO BITS
|
||
MOVEQ #15,D0 ;GET 15
|
||
ADD.L D0,D5 ;ROUND UP TO NEAREST WORD BOUNDARY
|
||
ASR.L #4,D5 ;DIV BY 16
|
||
BLE BITSOK ;IGNORE IF NEWROW <= 0
|
||
ADD D5,D5 ;DOUBLE FOR NEW ROWBYTES
|
||
MOVE D5,ROWBYTES(A1) ;COPY ROWBYTES
|
||
OR #$8000,ROWBYTES(A1) ;SET PIXMAP FLAG
|
||
|
||
clr.w SRCPIX+PMVERSION(A6) ;clear 32bit addressing flag <BAL 15Dec88>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; PUT THE BITMAP TO THE PICTURE
|
||
;
|
||
MOVEQ #8,D6 ;GET A USEFUL NUMBER
|
||
MOVE #opBitsRect,-(SP) ;PUSH OPCODE=BITSRECT
|
||
TST.L MASKRGN(A6) ;IS MASKRGN NIL ?
|
||
BEQ.S NOTRGN ;YES, CONTINUE
|
||
ADD #1,(SP) ;REPLACE OPCODE=BITSRGN (IE. $91)
|
||
;FIXED BUG 12/3/83, RP
|
||
NOTRGN CMP D6,D5 ;IS NEWROW < 8 ?
|
||
Bge.s PACK ;YES, DONT BITPACK
|
||
move #1,SRCPIX+PACKTYPE(A6) ;replace with "UnPacked" packType
|
||
bra.s NoPack
|
||
PACK ADD #8,(SP) ;SET BIT 3 FOR BITPACK
|
||
NoPack TST.B D7 ;New Picture?
|
||
BNE.S OPOK ;=>NO, can't be direct data <BAL 01Mar89>
|
||
MOVE.W SRCPIX+pixelType(A6),D2 ;get pixelType in d2 for later %%%
|
||
cmp #16,D2 ;is it chunky direct? %%%
|
||
bne.s OPOK ;NO, OPCODE IS OK %%%
|
||
OR.W #$A,(SP) ;YES, USE $9A AND $9B %%%
|
||
jsrROM PutPicOp ;PUT OPCODE TO THEPIC %%%
|
||
MOVE.L #$0FF,-(SP) ;PUT HACK TO PIC %%%
|
||
jsrROM PutPicLong
|
||
|
||
lea srcPix+packType(a6),a0 ;point at packType
|
||
CMP #1,(a0) ;PACKING? <BAL 11Jul88>
|
||
beq.s @PackOK ;no, don't need to adjust packType <BAL 11Jul88>
|
||
|
||
CMP #16,SRCPIX+PIXELSIZE(A6) ;16 bit/pixel? <BAL 15Dec88>
|
||
bne.s @pack32 ;no, check 32 bit/pixel packing types <BAL 15Dec88>
|
||
move #3,(a0) ;use only supported type
|
||
bra.s @PackOK
|
||
|
||
@pack32 cmp #2,(a0) ;drop pad byte only? <BAL 11Jul88>
|
||
beq.s @PackOK ;yes, don't need to adjust packType <BAL 11Jul88>
|
||
move #4,(a0) ;replace with only remaining supported packType <BAL 15Dec88>
|
||
|
||
|
||
@PackOK MOVE SRCPIX+BOUNDS+BOTTOM(A6),D1 ; %%%
|
||
SUB SRCPIX+BOUNDS+TOP(A6),D1 ;HEIGHT := BOUNDS BOT - TOP %%%
|
||
MULU D1,D5 ;SAVE PMDATA SIZE IN D5 %%%
|
||
|
||
PEA SRCPIX+ROWBYTES(A6) ;PUSH ADDR OF PIXMAP %%%
|
||
MOVE #PMREC-4,-(SP) ;PUSH SIZE OF PIXMAP (-BASEADDR)
|
||
jsrROM PutPicData ;PUT PIXMAP TO THEPIC %%%
|
||
BRA.S NOTABLE ;SKIP CLUT STUFF %%%
|
||
|
||
OPOK jsrROM PutPicOp ;PUT OPCODE TO THEPIC
|
||
|
||
MOVEQ #PMREC-4,D0 ;GET SIZE OF PIXMAP (-BASEADDR)
|
||
TST.B D7 ;ARE WE RECORDING A BITMAP?
|
||
BEQ.S DOPM ;=>SRC IS PIXMAP, PUT PIXMAP
|
||
|
||
AND #nuRBMask,SRCPIX+ROWBYTES(A6) ;ELSE BITMAP, CLEAR FLAGS
|
||
MOVEQ #BITMAPREC-4,D0 ;GET SIZE OF BITMAP (-BASEADDR)
|
||
DOPM PEA SRCPIX+ROWBYTES(A6) ;PUSH ADDR OF BITMAP/PIXMAP
|
||
MOVE D0,-(SP) ;PUSH BYTECOUNT
|
||
jsrROM PutPicData ;PUT BITMAP/PIXMAP TO THEPIC
|
||
|
||
; IF IT'S A PIXMAP, PUT THE COLOR TABLE TO THE PICTURE
|
||
|
||
TST.B D7 ;IS IT A PIXMAP?
|
||
BNE.S NOTABLE ;=>NO, DON'T DO TABLE
|
||
MOVE.L SRCPIX+PMTABLE(A6),d0 ;get CTabHandle
|
||
beq.s PutMinimalTable ;Put min table if NIL <21> <KON 29NOV90>
|
||
move.l d0, -(SP) ;PUSH CTABHANDLE <20> <KON 30OCT90>
|
||
jsrROM PutPicTable ;ADD TABLE TO THEPIC
|
||
bra.s NoTable
|
||
;
|
||
; The following is a minimal color table. It is put to the picture if a PixMap has
|
||
; a NIL color table. <KON 29NOV90>
|
||
;
|
||
|
||
arithMode
|
||
;avg addPin addOver subPin trans max subOver min
|
||
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
|
||
|
||
MinimalTable
|
||
dc.l 0 ;ctSeed
|
||
dc.w 0 ;flags
|
||
dc.w 0 ;0-based count of entries -> 1 entry
|
||
dc.w cTabSignature,0,0,0 ;ColorSpec for 1 entry with signature
|
||
|
||
MinTableSize EQU 16
|
||
|
||
;
|
||
; Put the minimal color table to the picture
|
||
;
|
||
PutMinimalTable
|
||
|
||
pea MinimalTable ;PUSH DATAPTR <KON 29NOV90>
|
||
move #MinTableSize,-(sp) ;GET SIZE IN ENTRIES <KON 29NOV90>
|
||
jsrROM PutPicData ;ADD TO THEPIC <KON 29NOV90>
|
||
|
||
NOTABLE MOVE.L SRCRECT(A6),-(SP)
|
||
MOVE D6,-(SP)
|
||
jsrROM PutPicData ;PUT SRCRECT
|
||
MOVE.L DSTRECT(A6),-(SP)
|
||
MOVE D6,-(SP)
|
||
jsrROM PutPicData ;PUT DSTRECT
|
||
|
||
MOVE MODE(A6),D0 ;get desired mode <26May87 EHB>
|
||
TST.B OLDPIC(A6) ;is it an old picture? <26May87 EHB>
|
||
BEQ.S @ModeOK ;=>no, mode is fine <26May87 EHB>
|
||
bclr #6,d0 ;don't record ditherCopy in old Picts
|
||
BTST #5,D0 ;an arithmetic mode? <26May87 EHB>
|
||
BEQ.S @ModeOK ;=>no, mode is fine <26May87 EHB>
|
||
AND #$07,D0 ;else strip to low 3 bits <26May87 EHB>
|
||
MOVE.B ARITHMODE(D0),D0 ;and remap it <26May87 EHB>
|
||
@ModeOK MOVE D0,-(SP) ;push mode <26May87 EHB>
|
||
jsrROM PutPicWord ;PUT MODE
|
||
|
||
TST.L MASKRGN(A6) ;IS MASKRGN NIL ?
|
||
BEQ.S NOMASK ;YES, SKIP IT
|
||
MOVE.L MASKRGN(A6),-(SP) ;NO, PUSH MASKRGN
|
||
jsrROM PutPicRgn ;PUT MASKRGN TO THEPIC
|
||
|
||
NOMASK tst.b d7 ;is it a pixmap ? If not, then <17Jan89 DDG>
|
||
bne.s @NOTD ;don't check pixmap fields ! <17Jan89 DDG>
|
||
cmp #16,SRCPIX+pixelType(A6) ;is it chunky direct? %%%
|
||
bne.s @NOTD ;NO, CALL PACKING STUFF %%%
|
||
LEA SRCPIX(A6),A0 ;GET PIXMAP POINTER
|
||
MOVE.L A0,-(SP) ;PUSH PIXMAP POINTER
|
||
MOVE.L A3,-(SP) ;PUSH ADJUSTED BASEADDR
|
||
MOVE D4,-(SP) ;PUSH OLD ROWBYTES
|
||
bsr PutDirectPMData ;AND PUT DATA TO PICTURE
|
||
BRA.S @DONE
|
||
|
||
@NOTD LEA SRCPIX(A6),A0 ;GET PIXMAP POINTER
|
||
MOVE.L A0,-(SP) ;PUSH PIXMAP POINTER
|
||
MOVE.L A3,-(SP) ;PUSH ADJUSTED BASEADDR
|
||
MOVE D4,-(SP) ;PUSH OLD ROWBYTES
|
||
jsrROM PutPMData ;AND PUT DATA TO PICTURE
|
||
|
||
@DONE MOVE.L RECT1(A6),D0 ;DID WE ALLOCATE DATA FOR A PIXMAP?
|
||
BEQ.S BITSOK ;=>NOPE, DON'T NEED TO DISPOSE
|
||
MOVE.L D0,A0 ;ELSE GET HANDLE
|
||
tst.b isTmpHandle(a6) ;is it from temp memory? <1.5> BAL
|
||
beq.s @notTmp ;no, dispose as usual <1.5> BAL
|
||
_DisposeTempBuffer ;yes, dispose as temp memory <1.5> BAL
|
||
bra.s BITSOK ; <1.5> BAL
|
||
|
||
@notTmp _DISPOSHANDLE ;AND DISPOSE OF IT
|
||
|
||
BITSOK MOVE.L THEPORT(A4),A3 ;RESTORE THEPORT
|
||
|
||
; CALL HEAVY-DUTY LOOP TO DRAW TO ALL DEVICES
|
||
|
||
NOTPIC TST PNVIS(A3) ;IS PNVIS >= 0 ?
|
||
BLT.S GOHOME ;NO, QUIT
|
||
LEA PORTBITS(A3),A0 ;GET DST BITMAP
|
||
MOVE.L A0,DSTBITS(A6) ;AND PLACE IN STACK FRAME
|
||
MOVE.L VISRGN(A3),RGNA(A6) ;PASS VISRGN
|
||
MOVE.L CLIPRGN(A3),RGNB(A6) ;AND CLIPRGN
|
||
CLR.L MASKBITS(A6) ;NO MASK BITMAP
|
||
CLR.L MASKRECT(A6) ;NO MASK RECTANGLE
|
||
_BitsDevLoop ;DRAW TO ALL DEVICES
|
||
|
||
GOHOME MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGS
|
||
UNLINK PARAMSIZE,'STDBITS '
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to make direct pixpats work in pictures
|
||
; Requires come-from on CopyPixPat and complete replacement of PutPicPixPat
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
COPYPIXPAT PROC EXPORT
|
||
IMPORT COPYPIXMAP,COPYHANDLE,PutPicPixPat
|
||
|
||
ciCopyPixPat EQU $30840
|
||
FromUpdatePat EQU $32EAE
|
||
ciUpdatePat EQU $32EBE
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE COPYPIXPAT (SRCPP,DSTPP: PixPatHandle);
|
||
;
|
||
; COPY THE SRC PIXPAT'S DATA TO THE DST PIXPAT'S HANDLES
|
||
;
|
||
cmpRA FromUpdatePat,(sp)
|
||
beq.s @FoundIt
|
||
jmpROM ciCopyPixPat
|
||
@FoundIt
|
||
|
||
;
|
||
; Patch uses updatePat stack frame
|
||
;
|
||
PARAMSIZE EQU 20
|
||
SRCPAT EQU PARAMSIZE+8-4 ;PTR
|
||
SRCPIXPAT EQU SRCPAT-4 ;HANDLE
|
||
SAVEPAT EQU SRCPIXPAT-4 ;PTR
|
||
SAVEPIXPAT EQU SAVEPAT-4 ;HANDLE
|
||
OLDOP EQU SAVEPIXPAT-2 ;WORD
|
||
NEWOP EQU OLDOP-2 ;WORD
|
||
|
||
addq #4,sp ;delete old return address
|
||
jsrROM ciCopyPixPat ;call it and comeback here
|
||
MOVE NEWOP(A6),D0 ;GET PIXPAT OPCODE
|
||
jsrROM DPutPicOp ;ADD TO THEPIC
|
||
MOVE.L SAVEPIXPAT(A6),-(SP) ;PUSH NEW PAT
|
||
JSR PutPicPixPat ;AND PUT TO PICTURE
|
||
jmpROM ciUpdatePat
|
||
ENDPROC
|
||
|
||
PutPicPixPat PROC EXPORT
|
||
IMPORT PutDirectPMData
|
||
|
||
PutPicPixMap EQU $33030
|
||
;------------------------------------------------------
|
||
;
|
||
; PROCEDURE PutPicPixPat(PixPatHandle);
|
||
;
|
||
MOVE.L A2,-(SP) ;SAVE WORK REGISTER
|
||
MOVE.L 8(SP),A0 ;GET HANDLE TO PIXPAT
|
||
_HLock ;LOCK PIXPAT
|
||
MOVE.L (A0),A2 ;A2 = PIXPAT POINTER
|
||
MOVE.L patMap(A2),A0 ;GET PIXMAP HANDLE
|
||
MOVE.L (A0),A0 ;A1 = PIXMAP POINTER
|
||
|
||
; PUT TYPE AND ONE BIT PATTERN
|
||
|
||
MOVE patType(A2),-(SP) ;PUSH TYPE
|
||
jsrROM PutPicWord ;PUT TYPE TO THEPIC
|
||
MOVE.L pat1Data(A2),-(SP) ;PUSH 1ST HALF OF ONE BIT PATTERN
|
||
jsrROM PutPicLong ;PUT 1st HALF TO THEPIC
|
||
MOVE.L pat1Data+4(A2),-(SP) ;PUSH 2ND HALF OF ONE BIT PATTERN
|
||
jsrROM PutPicLong ;PUT 2ND HALF TO THEPIC
|
||
|
||
; IF IT IS A DITHERPAT, PUT RGB COLOR TO THE PICTURE (AND SKIP PIXMAP AND DATA)
|
||
|
||
CMP #ditherPat,patType(A2) ;IS IT A DITHER PATTERN?
|
||
BNE.S @PutMap ;=>NO, PUT PIXMAP
|
||
MOVE.L patMap(A2),A0 ;GET PATTERN'S PIXMAP
|
||
MOVE.L (A0),A0 ;POINT AT IT
|
||
MOVE.L PMTable(A0),A0 ;GET COLOR TABLE
|
||
MOVE.L (A0),A0 ;AND POINT AT IT
|
||
LEA CTTable+(4*CTEntrySize)(A0),A0 ;POINT TO RGB
|
||
MOVE rgb+blue(A0),-(SP) ;PUSH BLUE
|
||
MOVE.L rgb+red(A0),-(SP) ;PUSH RED, GREEN
|
||
jsrROM PutPicLong ;PUT RED, GREEN TO PICTURE
|
||
jsrROM PutPicWord ;PUT BLUE TO PICTURE
|
||
BRA @NoData ;=>DON'T NEED PIXMAP
|
||
|
||
; PUT PIXMAP TO THE PICTURE
|
||
|
||
@PutMap
|
||
MOVE.L patMap(A2),A1 ;GET PIXMAP HANDLE
|
||
MOVE.L (A1),A1 ;GET PIXMAP PTR
|
||
|
||
move.w packtype(a1),-(sp) ;save packtype <KON 4FEB90>
|
||
move.w pmVersion(a6),-(sp) ;save pmVersion <KON 4FEB90>
|
||
move.l a1,-(sp) ;PutPMData trashes A1 <KON 5APR91>
|
||
clr.w pmVersion(a6) ;only let version zero be stored in pict.
|
||
|
||
cmp #16,pixelType(A1) ;is it chunky direct?
|
||
bne.s @PackOK ;don't do special packing
|
||
|
||
lea packtype(a1),a0
|
||
cmp #1,(a0) ;PACKING?
|
||
beq.s @PackOK ;no, don't need to adjust packType
|
||
|
||
cmp #16,pixelsize(A1) ;16 bit/pixel?
|
||
bne.s @pack32 ;no, check 32 bit/pixel packing types
|
||
move #3,(a0) ;use only supported type
|
||
bra.s @PackOK
|
||
|
||
@pack32 cmp #2,(a0) ;drop pad byte only?
|
||
beq.s @PackOK ;yes, don't need to adjust packType
|
||
move #4,(a0) ;replace with only remaining supported packType
|
||
@PackOK
|
||
|
||
MOVE.L patMap(A2),-(SP) ;PUSH PIXMAP HANDLE FOR PUTPICPIXMAP
|
||
jsrROM PutPicPixMap ;ADD PIXMAP TO THEPIC
|
||
|
||
; PUT DATA TO PICTURE
|
||
|
||
MOVE.L patData(A2),A0 ;GET DATA HANDLE
|
||
_HLock ;LOCK DATA
|
||
MOVE.L patMap(A2),A1 ;GET PIXMAP HANDLE
|
||
MOVE.L (A1),A1 ;GET PIXMAP PTR
|
||
MOVE.L A1,-(SP) ;PUSH PIXMAP PTR
|
||
|
||
move.l (a0),d0
|
||
_rTranslate24To32 ;map address in D0 <02Feb90 BAL>
|
||
MOVE.L d0,-(SP) ;PUSH DATA PTR
|
||
|
||
MOVE ROWBYTES(A1),D0 ;GET ROWBYTES
|
||
AND #nuRBMask,D0 ;CLEAR FLAG BITS
|
||
MOVE D0,-(SP) ;PUSH SOURCE ROWBYTES
|
||
|
||
;
|
||
; if direct pixPat, call PutDirectPMData <KON 4FEB90>
|
||
;
|
||
cmp #16,pixelType(A1) ;is it chunky direct?
|
||
bne.s @NOTD ;NO, CALL PACKING STUFF
|
||
;
|
||
; Do direct case
|
||
;
|
||
|
||
bsr PutDirectPMData ;and put data to picture
|
||
bra.s @done
|
||
|
||
@NOTD
|
||
;
|
||
; Do indexed case
|
||
;
|
||
jsrROM PutPMData ;PUT DATA TO PICTURE
|
||
@DONE
|
||
move.l (sp)+,a1 ;restore a1 which was trashed by PutPMData <KON 5APR91>
|
||
move.w (sp)+,pmVersion(a6) ;restore pmVersion <KON 4FEB90>
|
||
move.w (sp)+,packtype(a1) ;restore packtype <KON 4FEB90>
|
||
|
||
MOVE.L patData(A2),A0 ;GET DATA HANDLE
|
||
_HUnlock ;UNLOCK DATA
|
||
|
||
; UNLOCK PIXPAT AND RETURN
|
||
|
||
@NoData MOVE.L 8(SP),A0 ;GET PIXPAT HANDLE
|
||
_HUnlock ;UNLOCK PIXPAT
|
||
MOVE.L (SP)+,A2 ;RESTORE WORK REGISTER
|
||
MOVE.L (SP)+,(SP) ;STRIP PARAM
|
||
RTS ;AND RETURN
|
||
ENDPROC
|
||
|
||
arithMode PROC EXPORT
|
||
; hilite
|
||
;avg addPin addOver subPin trans max subOver min
|
||
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to ColorMap to make 1-bit old copy mode work
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
ColorMap PROC EXPORT
|
||
IMPORT arithMode, NOPfgColorTable
|
||
|
||
ciDestBitMap EQU $2ED48
|
||
ciReMap2 EQU $2EDD6
|
||
ciColorOK EQU $2EE24
|
||
ciReMapReturn EQU $2EDAE
|
||
ciRep EQU $2EDBE
|
||
;----------------------------------------------------------------
|
||
;
|
||
; PROCEDURE ColorMap: (pat: Pattern; mode: INTEGER);
|
||
;
|
||
; ADJUST INPUT MODE AND PATTERN TO ACCOMPLISH COLOR SEPARATION.
|
||
; POTENTIALLY MODIFIES: LOCMODE, NEWPATTERN, LOCPAT, FCOLOR, BCOLOR.
|
||
;
|
||
; ADJUSTED MODE IS RETURNED IN LOCMODE(A6).
|
||
; IF PATTERN IS ADJUSTED, THEN NEWPATTERN(A6) IS SET FALSE AND LOCPAT(A6) IS MODIFIED.
|
||
; FCOLOR(A6) AND BCOLOR(A6) ARE MODIFIED AS DESCRIBED BELOW.
|
||
;
|
||
; IF OLD PORT, TRANSLATES OLD-STYLE FGCOLOR, BKCOLOR INTO AN RGB,
|
||
; AND THEN GETS THE INDEX FOR THAT COLOR. FOR ALL PORTS, THE
|
||
; RETURNED COLOR CONTAINS THE PIXEL REPLICATED THROUGHOUT THE LONG
|
||
; (SUITABLE FOR MASKING).
|
||
;
|
||
; FOR EITHER MODE, IF THE DESTINATION IS ONE BIT DEEP, DO PLANAR REMAPPING
|
||
; SO THAT FASTEST COPYBITS BLT ROUTINES DON'T NEED TO APPLY COLOR.
|
||
;
|
||
; CLOBBERS A0-A1,D0-D2
|
||
;
|
||
; CALLED BY: DRAWARC, DRAWLINE, STRETCH
|
||
|
||
; A6 STACK FRAME ALLOCATED BY CALLER, USED LOCALLY.
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
;
|
||
&CurFile SETC 'COLORMAP'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;-------------------------------------------------
|
||
|
||
PARAMSIZE EQU 0 ;SIZE OF PARAMETERS
|
||
|
||
VARSIZE EQU 0 ;SIZE OF LOCALS
|
||
|
||
; LINK A4,#VARSIZE ;MAKE A STACK FRAME
|
||
MOVEM.L D3-D7/A2-A3,-(SP) ;SAVE REGS
|
||
|
||
MOVE.L GRAFGLOBALS(A5),A2 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A2),A2 ;POINT TO THE PORT
|
||
MOVE locMode(A6),D3 ;get the mode
|
||
MOVE.L FGCOLOR(A2),D6 ;GET FOREGROUND COLOR INTO D6
|
||
MOVE.L BKCOLOR(A2),D7 ;GET BACKGROUND COLOR INTO D7
|
||
; <1.6> BAL
|
||
@modeOK MOVE D3,D1 ;make a copy of the mode
|
||
AND #$FFF7,D3 ;clear the pattern bit
|
||
EOR D3,D1 ;set only the pattern bit
|
||
CMP #srcXor,D3 ;could it be replaced by hilite?
|
||
BNE.S @noXorSub
|
||
BSET #hiliteBit,HiliteMode ;check to see if highlight bit was set
|
||
BNE.S @noXorSub ;if not, invert old way
|
||
MOVE #$32,D3 ;set to src highlight
|
||
@noXorSub
|
||
BTST #5,D3 ;an arithmetic mode?
|
||
BEQ.S @leaveModeAlone ;skip if no mode
|
||
CMP #1,dstPix+pixelSize(A6) ;1 bit per pixel on the destination
|
||
BNE.S @leaveModeAlone
|
||
AND #$07,D3 ;get variants
|
||
MOVE.B arithMode(D3),D3 ;get mapped mode in 1 bit
|
||
@leaveModeAlone
|
||
OR D1,D3 ;combine mapped mode and pattern bit
|
||
MOVE D3,locMode(A6) ;save off altered mode
|
||
|
||
CLR.B alphaMode(A6) ;clear the alpha mode to default
|
||
BTST #5,D3 ;check again for arithmetic modes
|
||
BNE @noalpha ;skip alpha stuff if arithmetic
|
||
MOVE.W dstShift(A6),D0 ;yes, get pixel size
|
||
|
||
; MOVE.L ((NOPfgColorTable-*).L,PC,D0.W*4),D0
|
||
|
||
LEA (NOPfgColorTable-*).L,A1 ;get distance from here to NOPfgColorTable
|
||
LEA *-6(A1.L),A1 ;get address of "white" table
|
||
MOVE.L 0(A1,D0.W*4),D0 ;get default mask for current depth
|
||
MOVE.L D0,alphaBack(A6) ;save for later use
|
||
MOVE.W D3,D5 ;make copy of adjusted mode
|
||
AND.W #$03,D5 ;mask off all but base mode
|
||
CMP.W #srcXor,D5 ;are we xoring?
|
||
BEQ.S @1 ;yes, use normal default mask
|
||
MOVEQ #-1,D0 ;get all ones
|
||
@1: MOVE.L D0,alphaMask(A6) ;save default alphaMask
|
||
|
||
TST portBits+rowBytes(A2) ;is it an old port?
|
||
BPL @noalpha ;yes, alpha mode is illegal
|
||
MOVE.W dstPix+pixelSize(A6),D0 ;get depth of destination
|
||
CMP.W #16,D0 ;direct device?
|
||
BLT.S @noalpha ;no, skip this stuff
|
||
MOVE.L grafVars(A2),D4 ;get grafvars handle
|
||
BEQ @noalpha ;no grafvars, no alpha
|
||
MOVE.L D4,A0 ;copy handle
|
||
MOVE.L (A0),A1 ;dereference handle
|
||
BTST #PmNewGVBit-8,pmFlags(A1) ;make sure grafvars have been expanded
|
||
BEQ.S @noalpha ;if not, bail
|
||
MOVE.B streamMode(A1),alphaMode(A6);save alpha mode in stack frame
|
||
SUB #16,SP ;make room on stack for results
|
||
PEA backStream(A1) ;push pointer to background stream and ratio
|
||
PEA 12(SP) ;push pointer to where we want results
|
||
PEA foreStream(A1) ;push pointer to foreground stream and ratio
|
||
PEA 12(SP) ;push pointer to where we want results
|
||
_StreamToMask ;get foreground mask for this device
|
||
_StreamToMask ;get background mask for this device
|
||
MOVE.L (SP)+,D0 ;get alpha mask
|
||
MOVE.L (SP)+,D4 ;get alpha fore color
|
||
CMP.W #srcXor,D5 ;are we xoring?
|
||
BNE.S @2 ;no, use normal default mask
|
||
MOVE.L D4,D0 ;yes, use alpha fore color as alpha mask
|
||
@2: MOVE.L D0,alphaFore(A6) ;save alpha mask
|
||
ADDQ #4,SP ;throw away background mask
|
||
MOVE.L (SP)+,D5 ;get alpha back color
|
||
MOVEQ #0,D2 ;clear out alpha mask
|
||
MOVE.B alphaMode(A6),D0 ;get alpha again
|
||
BNE.S @3 ;if non-zero, use that value
|
||
MOVEQ #3,D0 ;if zero, draw to both
|
||
@3: BTST #1,D0 ;are we drawing to graphics?
|
||
BEQ.S @4 ;no, skip
|
||
OR.L alphaFore(A6),D2 ;yes, add alpha bits to mask
|
||
OR.L D4,D6 ;apply alphaFgColor to the foreground color
|
||
OR.L D5,D7 ;apply alphaBkColor to the background color
|
||
@4: BTST #0,D0 ;is the alpha going to be drawn?
|
||
BEQ.S @5 ;no, then don't apply alpha to fg,bk colors
|
||
OR.L alphaBack(A6),D2 ;yes, add graphic bits to mask
|
||
@5: MOVE.L D2,alphaMask(A6) ;save alpha mask in stack frame
|
||
NOT.L D2 ;check for mask of all ones
|
||
SNE alphaMode(A6) ;if mask of all ones, set alphamode to true
|
||
@noalpha
|
||
MOVE COLRBIT(A2),D2 ;GET COLOR BIT SELECT
|
||
MOVEQ #-1,D4 ;DEFAULT VALUE FOR FGLONG
|
||
MOVEQ #0,D5 ;DEFAULT VALUE FOR BKLONG
|
||
|
||
; IF IT IS AN OLD PORT, AND WE ARE GOING TO THE SCREEN, THEN DON'T DO
|
||
; SEPARATION, JUST MAP PLANAR COLOR VALUES INTO COLOR INDICES.
|
||
; IF IT IS A NEW PORT, DON'T NEED TO REMAP THE VALUES (UNLESS ONE BIT DEEP).
|
||
|
||
|
||
; if pattern mode and new pattern, leave black and white
|
||
|
||
MOVE D3,D0 ;copy the mode
|
||
BCLR #3,D0 ;clear pattern bit
|
||
|
||
; not necessary since d1 already has pattern bit
|
||
; SNE D1 ;remember that the pattern bit was set
|
||
|
||
CMP #srcXor,D0 ;is it srcXor or patXor?
|
||
BEQ COLOROK ;if so, use black/white
|
||
CMP #notSrcXor,D0 ;is it notSrcXor or notPatXor?
|
||
BEQ COLOROK ;if so, use black/white
|
||
TST.B D1 ;IS IT A PATTERN MODE?
|
||
BEQ.S DestBitMap ;if not skip, otherwise check if its a multibit pattern <08JUNE92 SAH>
|
||
|
||
ISPAT
|
||
TST.B NEWPATTERN(A6) ;FLAG TRUE IF DESTINATION IS PIXMAP
|
||
BEQ.S DestBitMap ;=>YES, GET COLOR PIXEL MASKS
|
||
MOVE.L LOCPAT(A6),A0 ;GET PATTERN POINTER
|
||
MOVE.L (A0),A0 ;GET HANDLE TO PATTERN
|
||
MOVE.L (A0),A0 ;GET POINTER TO PATTERN
|
||
TST PATTYPE(A0) ;WHAT TYPE OF PATTERN IS IT?
|
||
BNE COLOROK ;=>A NEW ONE, BLACK FG & WHITE BK
|
||
|
||
DestBitMap
|
||
;here src is either an old pattern or image data
|
||
TST PORTBITS+ROWBYTES(A2) ;old port or new?
|
||
BPL.S REMAP ;if old, go check color bit
|
||
jmpROM ciDestBitMap
|
||
|
||
REMAP TST D2 ;GET COLOR BIT SELECT
|
||
BMI COLOROK ;COLRBIT NEG MEANS NO COLOR
|
||
BNE.S REMAP2 ;=>DOING PLANES, DO OLD WAY
|
||
CMP #1,DSTPIX+PIXELSIZE(A6) ;IS PIXELSIZE 1?
|
||
BEQ.S remapOld1bit ;=>yes, REMAP COLORS FOR old 1-bit pixels
|
||
jmpROM ciReMapReturn
|
||
|
||
; From here to COLOROK, the port is old, the destination is 1 bit, the modes are old
|
||
|
||
remapOld1bit ;Special case colorbit is zero
|
||
btst #0,d6
|
||
bne.s @fgOK
|
||
moveq #0,d4
|
||
@fgOK
|
||
btst #0,d7
|
||
beq.s ColorOK
|
||
moveq #-1,d5
|
||
ColorOK
|
||
jmpROM ciColorOK
|
||
; bra.s ColorOK
|
||
|
||
REP
|
||
jmpROM ciRep
|
||
REMAP2
|
||
jmpROM ciReMap2
|
||
|
||
ENDPROC
|
||
|
||
PutPicVerb PROC EXPORT
|
||
IMPORT UpdatePat
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; PROCEDURE PutPicVerb(verb: GrafVerb);
|
||
;
|
||
; Check additional picture params associated with
|
||
; this verb, and add those that have changed to thePic.
|
||
;
|
||
PARAMSIZE EQU 2
|
||
VERB EQU PARAMSIZE+8-2 ;BYTE
|
||
|
||
LINK A6,#0 ;NO LOCAL VARS
|
||
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
|
||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT PORT
|
||
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
|
||
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
|
||
MOVE.B VERB(A6),D7 ;GET VERB
|
||
CMP.B #PAINT,D7 ;CASE JUMP BASED ON VERB
|
||
BLT.S FRAME1
|
||
BEQ.S PAINT1 ;YES CHECK PNMODE, PNPAT
|
||
CMP.B #INVERT,D7 ;IS VERB INVERT ?
|
||
BEQ DONE ;YES, NOTHING TO CHECK
|
||
BLT.S ERASE1
|
||
|
||
FILL1 PEA FILLPAT(A3) ;OLD SRC PTR
|
||
MOVE.L FILLPIXPAT(A3),-(SP) ;NEW SRC HANDLE
|
||
PEA PICFILLPAT(A4) ;OLD SAVE PTR
|
||
MOVE.L PICFILLPP(A4),-(SP) ;NEW SAVE HANDLE
|
||
MOVE #opFillPat,-(SP) ;OLD PAT OPCODE
|
||
MOVE #opFillPixPat,-(SP) ;NEW PAT OPCODE
|
||
JSR UpdatePat ;PUT PAT TO PICT IF NECESSARY
|
||
BRA DONE ;=>AND RETURN
|
||
;
|
||
; This table is repeated 3 places in this file. Sortof sucks.
|
||
;
|
||
arithMode ;avg addPin addOver subPin trans max subOver min
|
||
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
|
||
|
||
|
||
ERASE1 PEA BKPAT(A3) ;OLD SRC PTR
|
||
MOVE.L BKPIXPAT(A3),-(SP) ;NEW SRC HANDLE
|
||
PEA PICBKPAT(A4) ;OLD SAVE PTR
|
||
MOVE.L PICBKPP(A4),-(SP) ;NEW SAVE HANDLE
|
||
MOVE #opBkPat,-(SP) ;OLD PAT OPCODE
|
||
MOVE #opBkPixPat,-(SP) ;NEW PAT OPCODE
|
||
JSR UpdatePat ;PUT PAT TO PICT IF NECESSARY
|
||
BRA DONE ;AND QUIT
|
||
|
||
FRAME1 MOVE.L PNSIZE(A3),D7 ;GET PNSIZE
|
||
CMP.L PICPNSIZE(A4),D7 ;HAS IT CHANGED ?
|
||
BEQ.S PAINT1 ;NO, CONTINUE
|
||
MOVEQ #opPnSize,D0 ;Get PnSize opcode
|
||
jsrROM DPutPicOp ;YES, PUT PNSIZE OPCODE
|
||
MOVE.L D7,-(SP)
|
||
jsrROM PutPicLong ;PUT NEW PNSIZE
|
||
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
|
||
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
|
||
MOVE.L D7,PICPNSIZE(A4) ;AND UPDATE STATE VARIABLE
|
||
|
||
PAINT1 MOVE PNMODE(A3),D7 ;GET PNMODE
|
||
CMP PICPNMODE(A4),D7 ;HAS IT CHANGED ?
|
||
BEQ.S MODEOK ;NO, CONTINUE
|
||
CMP #PICTVERSION,PicVersion(A4) ;IS IT A NEW PICTURE?
|
||
BNE.S @DOMODE ;=>YES, NEW MODES OK
|
||
BTST #5,D7 ;AN ARITHMETIC MODE?
|
||
BEQ.S @DOMODE ;=>NO, MODE IS FINE
|
||
AND #$07,D7 ;ELSE STRIP MODE TO BOTTOM 3 BITS
|
||
MOVE.B ARITHMODE(D7),D7 ;AND REMAP IT
|
||
CMP PICTXMODE(A4),D7 ;HAS IT CHANGED ?
|
||
BEQ.S MODEOK ;NO, CONTINUE
|
||
|
||
@DOMODE MOVEQ #opPnMode,D0 ;GET PNMODE OPCODE
|
||
jsrROM DPutPicOp ;YES, PUT PNMODE OPCODE
|
||
MOVE D7,-(SP)
|
||
jsrROM PutPicWord ;PUT NEW PNMODE
|
||
MOVE.L PICSAVE(A3),A4 ;GET PICSAVE HANDLE
|
||
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE
|
||
MOVE D7,PICPNMODE(A4) ;AND UPDATE STATE VARIABLE
|
||
|
||
MODEOK PEA PNPAT(A3) ;OLD SRC PTR
|
||
MOVE.L PNPIXPAT(A3),-(SP) ;NEW SRC HANDLE
|
||
PEA PICPNPAT(A4) ;OLD SAVE PTR
|
||
MOVE.L PICPNPP(A4),-(SP) ;NEW SAVE HANDLE
|
||
MOVE #opPnPat,-(SP) ;OLD PAT OPCODE
|
||
MOVE #opPnPixPat,-(SP) ;NEW PAT OPCODE
|
||
JSR UpdatePat ;PUT PAT TO PICT IF NECESSARY
|
||
|
||
DONE MOVEM.L (SP)+,D7/A3-A4 ;RESTORE REGS
|
||
UNLINK PARAMSIZE,'PUTPICVERB'
|
||
|
||
ENDPROC
|
||
|
||
StdLine PROC EXPORT
|
||
IMPORT PutPicVerb
|
||
ciStdLineEntry EQU $29598
|
||
ciLineNotPic EQU $2960E
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdLine(newPt: Point);
|
||
;
|
||
PARAMSIZE EQU 4
|
||
NEWPT EQU PARAMSIZE+8-4
|
||
|
||
VARSIZE EQU 0 ;TOTAL SIZE OF LOCALS
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D5-D7/A3-A4,-(SP) ;SAVE REGS
|
||
_CheckPic ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
MOVE.B #FRAME,-(SP) ;PUSH VERB
|
||
bsr PutPicVerb ;CHECK pnSize, pnMode, pnPat
|
||
jmpROM ciStdLineEntry
|
||
NotPic
|
||
jmpROM ciLineNotPic
|
||
ENDPROC
|
||
|
||
StdRect PROC EXPORT
|
||
IMPORT PutPicVerb
|
||
ciStdRectEntry EQU $2C16A
|
||
ciRectNotPic EQU $2C178
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdRect(verb: GrafVerb; r: Rect);
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 6
|
||
VERB EQU PARAMSIZE+8-2 ;GRAFVERB
|
||
RECT EQU VERB-4 ;LONG, ADDR OF RECT
|
||
|
||
VARSIZE EQU 0 ;TOTAL SIZE OF LOCALS
|
||
|
||
LINK A6,#VARSIZE ;NO LOCALS
|
||
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
|
||
MOVE.B VERB(A6),D7 ;GET VERB
|
||
_CheckPic ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
MOVE.B D7,-(SP) ;PUSH VERB
|
||
bsr PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||
jmpROM ciStdRectEntry
|
||
NotPic
|
||
jmpROM ciRectNotPic
|
||
ENDPROC
|
||
|
||
StdRRect PROC EXPORT
|
||
IMPORT PutPicVerb
|
||
ciStdRRectEntry EQU $3458A
|
||
ciRRectNotPic EQU $345B8
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdRRect(verb: GrafVerb; r: Rect; ovWd,ovHt: INTEGER);
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 10
|
||
VERB EQU PARAMSIZE+8-2 ;GRAFVERB
|
||
RECT EQU VERB-4 ;LONG, ADDR OF RECT
|
||
OVWD EQU RECT-2 ;WORD
|
||
OVHT EQU OVWD-2 ;WORD
|
||
|
||
LINK A6,#0 ;NO LOCALS
|
||
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
|
||
MOVE.B VERB(A6),D7 ;GET VERB
|
||
_CheckPic ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
MOVE.B D7,-(SP) ;PUSH VERB
|
||
bsr PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||
jmpROM ciStdRRectEntry
|
||
NOTPIC
|
||
jmpROM ciRRectNotPic
|
||
ENDPROC
|
||
|
||
StdOval PROC EXPORT
|
||
IMPORT PutPicVerb
|
||
ciOvalEntry EQU $3BA3C
|
||
ciOvalNotPic EQU $3BA4C
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdOval(verb: GrafVerb; r: Rect);
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 6
|
||
VERB EQU PARAMSIZE+8-2 ;GRAFVERB
|
||
RECT EQU VERB-4 ;LONG, ADDR OF RECT
|
||
|
||
OVWD EQU -2 ;WORD
|
||
OVHT EQU OVWD-2 ;WORD
|
||
VARSIZE EQU OVHT ;TOTAL BYTES OF LOCALS
|
||
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D7/A3-A4,-(SP) ;SAVE REGS
|
||
MOVE.B VERB(A6),D7 ;GET VERB
|
||
_CheckPic ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
MOVE.B D7,-(SP)
|
||
bsr PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||
jmpROM ciOvalEntry
|
||
NOTPIC
|
||
jmpROM ciOvalNotPic
|
||
ENDPROC
|
||
|
||
StdArc PROC EXPORT
|
||
IMPORT PutPicVerb
|
||
ciArcEntry EQU $3BB4C
|
||
ciArcNotPic EQU $3BB70
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdArc(verb: GrafVerb; r: Rect; startAngle,arcAngle: INTEGER);
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 10
|
||
VERB EQU PARAMSIZE+8-2 ;GRAFVERB
|
||
RECT EQU VERB-4 ;LONG, ADDR OF RECT
|
||
STARTANG EQU RECT-2 ;WORD
|
||
ARCANG EQU STARTANG-2 ;WORD
|
||
|
||
OVWD EQU -2 ;WORD
|
||
OVHT EQU OVWD-2 ;WORD
|
||
VARSIZE EQU OVHT ;TOTAL BYTES OF LOCALS
|
||
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D4/D7/A3-A4,-(SP) ;SAVE REGS
|
||
MOVE.B VERB(A6),D7 ;GET VERB
|
||
_CheckPic ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
MOVE.B D7,-(SP)
|
||
bsr PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||
jmpROM ciArcEntry
|
||
NOTPIC
|
||
jmpROM ciArcNotPic
|
||
ENDPROC
|
||
|
||
StdPoly PROC EXPORT
|
||
IMPORT PutPicVerb, DrawPoly
|
||
;ciPolyEntry EQU $33B4C
|
||
;ciPolyNotPic EQU $33B5C
|
||
ciDPutPicOp EQU $32C90
|
||
ciPutPicRgn EQU $32CD0
|
||
ciGetRect EQU $33B74
|
||
ciToFramePoly EQU $33BAA
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdPoly(verb: GrafVerb; poly: PolyHandle);
|
||
;
|
||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 6
|
||
VERB EQU PARAMSIZE+8-2 ;GRAFVERB
|
||
POLY EQU VERB-4 ;LONG, PolyHandle
|
||
|
||
MINRECT EQU -8 ;RECT
|
||
VARSIZE EQU MINRECT ;TOTAL BYTES OF LOCALS
|
||
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D5-D7/A2-A4,-(SP) ;SAVE REGS
|
||
MOVEQ #0,D7 ;CLEAR LO WORD OF REG SO OPCODE WILL BE OK TO 16BITS <C952/08Nov87> DAF
|
||
MOVE.B VERB(A6),D7 ;GET VERB
|
||
_CheckPic ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
MOVE.B D7,-(SP)
|
||
bsr PutPicVerb ;PUT ADDIONAL PARAMS TO THEPIC
|
||
; jmpROM ciPolyEntry
|
||
;NOTPIC
|
||
; jmpROM ciPolyNotPic
|
||
|
||
MOVEQ #$70,D0 ;PUT POLYNOUN IN HI NIBBLE
|
||
ADD D7,D0 ;PUT VERB IN LO NIBBLE
|
||
jsrROM ciDPutPicOp ;PUT OPCODE TO THEPIC <26May87 EHB>
|
||
MOVE.L POLY(A6),-(SP) ;PUSH POLYHANDLE
|
||
jsrROM ciPutPicRgn ;TREAT SAME AS A REGION
|
||
|
||
; CALL STANDARD LOOP TO DRAW TO ALL DEVICES
|
||
|
||
NOTPIC PEA StdDraw ;PUSH ADDRESS OF DRAW ROUTINE
|
||
peaROM ciGetRect ;PUSH ADDRESS OF RECT ROUTINE
|
||
_StdDevLoop ;DRAW TO ALL DEVICES
|
||
|
||
GOHOME MOVEM.L (SP)+,D5-D7/A2-A4 ;RESTORE REGS
|
||
UNLINK PARAMSIZE,'STDPOLY '
|
||
|
||
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdDraw;
|
||
;
|
||
; DRAW THE OBJECT
|
||
;
|
||
StdDraw MOVE.L POLY(A6),A2 ;GET POLYHANDLE
|
||
TST.B D7 ;IS VERB FRAME ?
|
||
; BNE.S NOTFR ;NO, CONTINUE
|
||
; MOVE.L A2,-(SP) ;PUSH POLYHANDLE
|
||
; JSR FrPoly ;FrPoly(poly);
|
||
; BRA.S DONE ;AND QUIT
|
||
BEQ.S ToFrame
|
||
|
||
NOTFR MOVE.L (A2),A0 ;DE-REFERANCE POLYHANDLE
|
||
PEA POLYBBOX(A0) ;PUSH POLYBBOX
|
||
MOVE.L VISRGN(A3),A0 ;GET VISRGN HANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE HANDLE
|
||
PEA RGNBBOX(A0) ;PUSH VISRGN BBOX
|
||
MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE HANDLE
|
||
PEA RGNBBOX(A0) ;PUSH CLIPRGN BBOX
|
||
MOVE #3,-(SP) ;PUSH NRECTS = 3
|
||
PEA MINRECT(A6) ;PUT RESULT IN MINRECT
|
||
_RSECT ;CALC INTERSECTION
|
||
BEQ.S DONE ;QUIT IF NO INTERSECT
|
||
|
||
MOVE.L A2,-(SP) ;PUSH POLYHANDLE
|
||
_PushVerb ;PUSH MODE AND PATTERN
|
||
JSR DrawPoly ;DrawPoly(poly,mode,pat);
|
||
DONE RTS
|
||
ToFrame jmpROM ciToFramePoly
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PROCEDURE DrawPoly(poly: PolyHandle; mode: integer; VAR pat: Pattern);
|
||
;
|
||
|
||
DrawPoly PROC EXPORT
|
||
ciIsRect EQU $3445C
|
||
ciNotRect EQU $3447A
|
||
|
||
ParamSize Equ 10
|
||
Poly Equ ParamSize+8-4
|
||
Mode Equ Poly-2
|
||
Pat Equ Mode-4
|
||
|
||
PolyRect Equ -8
|
||
VarSize Equ PolyRect
|
||
|
||
; <11Jul88> PMAB543 BAL/JDB Implemented fast case for rectangular filled polys.
|
||
|
||
Link A6,#VarSize ; local variables
|
||
move.l ([poly,a6]),a0 ; pick up polyptr <Begin PMAB543 BAL/JDB>
|
||
move (a0)+,d0 ; pick up byte count
|
||
cmp #4*5+10,d0 ; quadrilateral?
|
||
bne.s @chk4pt ; no, take general case
|
||
move.l 8+4*4(a0),d1 ; pick up last pnt
|
||
cmp.l 8(a0),d1 ; cmpare with first pnt
|
||
bne.s @notRect ;
|
||
bra.s @4Pnts
|
||
|
||
@chk4pt cmp #4*4+10,d0 ; quadrilateral?
|
||
bne.s @notRect ; no, take general case
|
||
@4Pnts moveq #2,d0 ; force to 4 points
|
||
addq #8,a0 ; bump past rect
|
||
lea 4(a0),a1 ; point to next point
|
||
@nxtPnt SWAP D0 ; swap equality flags into low word <6>
|
||
cmp (a0)+,(a1)+ ; cmp h's
|
||
seq d1 ; remember equality
|
||
ADD.B D0,D0 ; shift left to make room for new flag bit <6>
|
||
SUB.B D1,D0 ; if same, set low bit, if not, clear it <6>
|
||
cmp (a0)+,(a1)+ ; cmp v's
|
||
seq d2 ; remember equality
|
||
or.b d2,d1 ; compute h1=h2 | v1=v2
|
||
beq.s @notRect ; no, not rect
|
||
ADD.B D0,D0 ; shift left to make room for new flag bit <6>
|
||
SUB.B D2,D0 ; if same, set low bit, if not, clear it <6>
|
||
SWAP D0 ; put counter back in low word <6>
|
||
dbra d0,@nxtPnt
|
||
|
||
SWAP D0 ; swap equality flags into low word <6>
|
||
lea -12(a0),a1 ; point to first point
|
||
cmp (a0)+,(a1)+ ; cmp h's
|
||
seq d1 ; remember equality
|
||
ADD.B D0,D0 ; shift left to make room for new flag bit <6>
|
||
SUB.B D1,D0 ;if same, set low bit, if not, clear it <6>
|
||
cmp (a0)+,(a1)+ ; cmp v's
|
||
seq d2 ; remember equality
|
||
or.b d2,d1 ; compute h1=h2 | v1=v2
|
||
beq.s @notRect ; no, not rect
|
||
ADD.B D0,D0 ; shift left to make room for new flag bit <6>
|
||
SUB.B D2,D0 ; if same, set low bit, if not, clear it <6>
|
||
CMP.B #$99,D0 ; do the equality flags match that of type 1 rectangle ?<6>
|
||
BEQ.S @isRect ; yes, use fast case <6>
|
||
CMP.B #$66,D0 ; do they match that of a type 2 rectangle ? <6>
|
||
BNE.S @notRect ; no, use slow case <6>
|
||
@isRect jmpROM ciIsRect
|
||
@notRect jmpROM ciNotRect
|
||
|
||
ENDPROC
|
||
|
||
StdRgn PROC EXPORT
|
||
IMPORT PutPicVerb
|
||
ciRgnEntry EQU $35E8C
|
||
ciRgnNotPic EQU $35E9E
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdRgn(verb: GrafVerb; rgn: RgnHandle);
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 6
|
||
VERB EQU PARAMSIZE+8-2 ;GRAFVERB
|
||
RGN EQU VERB-4 ;LONG, RGNHANDLE
|
||
|
||
LINK A6,#0 ;NO LOCALS
|
||
MOVEM.L D6-D7/A2-A4,-(SP) ;SAVE REGS
|
||
MOVEQ #0,D7 ;CLEAR LOWORD OF PICT OPCODE <C952/08Nov87> DAF
|
||
MOVE.B VERB(A6),D7 ;GET VERB
|
||
_CheckPic ;SET UP A4,A3 AND CHECK PICSAVE
|
||
BLE.S NOTPIC ;BRANCH IF NOT PICSAVE
|
||
|
||
MOVE.B D7,-(SP) ;PUSH VERB
|
||
JSR PutPicVerb ;PUT ADDITONAL PARAMS TO THEPIC
|
||
jmpROM ciRgnEntry
|
||
NOTPIC
|
||
jmpROM ciRgnNotPic
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to BitsDevLoop to support changing BaseAddresses
|
||
; In addition, if screen devices overlap (only the top-left coordinate is checked,
|
||
; don't copy between them.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
BitsDevLoop PROC EXPORT
|
||
ciBitsDevTop EQU $3520C
|
||
ciROMCMPTBL EQU $35658
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DevLoop;
|
||
;
|
||
; On Entry: A3: GrafPort
|
||
; A6: StdBits' stack frame
|
||
; DSTBITS(A6): Destination bitmap/pixmap
|
||
; RGNA(A6): First region to clip to
|
||
; RGNB(A6): Second region to clip to
|
||
; MASKBITS(A6): Mask's bitmap
|
||
; MASKRECT(A6): Mask's rectangle
|
||
;
|
||
; D3-D7/A2-A4 have been preserved and can be used.
|
||
; SRC DEVICE RECORDS STORED ON STACK
|
||
|
||
FLAG EQU 0 ;OFFSET TO FLAG
|
||
DEV EQU FLAG+2 ;OFFSET TO DEVICE
|
||
RECT EQU DEV+4 ;OFFSET TO RECT
|
||
SIZE EQU RECT+8 ;SIZE OF RECORD
|
||
|
||
; Uses StdBits stack frame:
|
||
;
|
||
PARAMSIZE EQU 18
|
||
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
||
SRCRECT EQU SRCBITS-4 ;LONG, ADDR OF RECT
|
||
DSTRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
||
MODE EQU DSTRECT-2 ;WORD
|
||
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
||
|
||
SRCPIX EQU -(PMREC+CTREC+20) ;PIXMAP + COLOR TABLE
|
||
TEMPPIX EQU SRCPIX-PMREC ;PIXMAP
|
||
DSTBITS EQU TEMPPIX-4 ;DST BITMAP
|
||
GLOBALSRC EQU DSTBITS-8 ;GLOBAL COPY OF SRC RECT
|
||
GLOBALDST EQU GLOBALSRC-8 ;GLOBAL COPY OF DST RECT
|
||
SRCRECT1 EQU GLOBALDST-8 ;LOCAL COPY OF SRC RECT
|
||
DSTRECT1 EQU SRCRECT1-8 ;LOCAL COPY OF DST RECT (MUST FOLLOW SRCRECT1)
|
||
RECT1 EQU DSTRECT1-8 ;RESULT OF INTERSECTION
|
||
DEFSRC EQU RECT1-SIZE ;DEFAULT SRC RECORD
|
||
ENDSRC EQU DEFSRC-4 ;0 FOR TERMINATING SRC LIST
|
||
SRCDEV EQU ENDSRC-4 ;CURRENT SRC DEVICE RECORD
|
||
ENDDST EQU SRCDEV-4 ;0 FOR TERMINATING DST LIST
|
||
DSTDEV EQU ENDDST-4 ;CURRENT DST DEVICE
|
||
SRCLIST EQU DSTDEV-4 ;POINTER TO SORTED SRC RECT LIST
|
||
DSTLIST EQU SRCLIST-4 ;POINTER TO SORTED DST RECT LIST
|
||
SAVEDSP EQU DSTLIST-4 ;SAVED STACK POINTER
|
||
LASTSEED EQU SAVEDSP-4 ;LAST COLOR TABLE SEED
|
||
SAVEFG EQU LASTSEED-4 ;ORIGINAL FG COLOR
|
||
SAVEBK EQU SAVEFG-4 ;ORIGINAL BK COLOR
|
||
SAVEHILITE EQU SAVEBK-2 ;SAVED HILITE MODE FLAG
|
||
RGNA EQU SAVEHILITE-4 ;FIRST REGION FOR CLIPPING
|
||
RGNB EQU RGNA-4 ;SECOND REGION FOR CLIPPING
|
||
MASKBITS EQU RGNB-4 ;BITMAP FOR MASK
|
||
MASKRECT EQU MASKBITS-4 ;LONG, ADDR OF MASK RECT
|
||
isTmpHandle EQU MASKRECT-1 ;BYTE, FLAG SET IF temp memory used <1.5> BAL
|
||
OLDPIC EQU isTmpHandle-1 ;BYTE, FLAG SET IF OLD PICTURE <1.5> BAL
|
||
VARSIZE EQU OLDPIC ;TOTAL SIZE OF LOCALS
|
||
|
||
; IF THERE IS ONLY ONE SCREEN DEVICE, THEN DO IT FAST
|
||
|
||
MOVE.L DEVICELIST,A0 ;GET HEAD OF DEVICE LIST
|
||
MOVE.L (A0),A0 ;POINT TO DEVICE
|
||
MOVE.L GDNEXTGD(A0),D0 ;CHECK NEXT DEVICE
|
||
BNE.S MANYVIDI ;=>GO DO MANY DEVICES
|
||
|
||
jmpROM ciBitsDevTop
|
||
|
||
MANYVIDI
|
||
|
||
; INITIALIZE THE DEFAULT DESTINATION DEVICE LIST
|
||
; THE LIST CONSISTS OF ONE DEVICE HANDLE FOLLOWED BY A 0
|
||
|
||
MOVE.L SP,SAVEDSP(A6) ;SAVE STACK POINTER
|
||
LEA DSTDEV(A6),A1 ;POINT TO START OF DEFAULT DST LIST
|
||
MOVE.L A1,DSTLIST(A6) ;SAVE POINTER TO DEFAULT DST LIST
|
||
MOVE.L THEGDEVICE,A0 ;GET DEFAULT DEVICE <07Jul88 BAL>
|
||
MOVE.L A0,(A1)+ ;DSTDEV := DEFAULT SCREEN DEVICE
|
||
CLR.L (A1)+ ;CLEAR FLAG AT END OF DST LIST
|
||
|
||
; INITIALIZE THE DEFAULT SRC DEVICE LIST
|
||
; THE LIST CONSISTS OF ONE RECORD POINTER FOLLOWED BY A 0
|
||
|
||
MOVE.L A1,SRCLIST(A6) ;SAVE POINTER TO DEFAULT SRC RECORD
|
||
LEA DEFSRC(A6),A2 ;POINT TO DEFAULT SRC RECORD
|
||
MOVE.L A2,(A1)+ ;INSTALL RECORD POINTER INTO LIST
|
||
CLR.L (A1)+ ;CLEAR FLAG AT END OF SRC LIST
|
||
MOVE.L A0,DEV(A2) ;INITIALIZE DEVICE FIELD OF RECORD
|
||
|
||
; DETERMINE WHETHER SRC AND DST ARE THE SCREEN AND SET UP DRAWING DIRECTIONS
|
||
|
||
; MOVE.L MAINDEVICE,A0 ;GET DEFAULT SCREEN DEVICE <10Jul88 BAL>
|
||
; MOVE.L (A0),A0 ;POINT TO DEFAULT SCREEN DEVICE
|
||
; MOVE.L GDPMAP(A0),A0 ;GET HANDLE TO PIXMAP
|
||
; MOVE.L (A0),A0 ;POINT TO PIXMAP
|
||
; MOVE.L BASEADDR(A0),D0 ;GET BASE ADDR OF SCREEN IN D0
|
||
MOVE.L ScrnBase,D0 ;GET BASE ADDR OF main SCREEN IN D0 <23Dec89 BAL>
|
||
|
||
MOVE.L DSTBITS(A6),A0 ;GET DESTINATION IN A0
|
||
_BITSTOMAP ;GET BIT/PIXMAP IN A0
|
||
; MOVE.L A0,DSTBITS(A6) ; <Don't carry derefed port's pixmap across rgbForeColor>
|
||
; <28May89 BAL>
|
||
MOVE.L A0,A1 ;KEEP DST PIXMAP IN A1
|
||
|
||
MOVE.L SRCBITS(A6),A0 ;POINT TO SRC BITMAP
|
||
_BITSTOMAP ;GET BIT/PIXMAP IN A0
|
||
MOVE.L A0,A2 ;SAVE SRC PIXMAP IN A2
|
||
|
||
CMP.L BASEADDR(A0),D0 ;SRC FROM THE SCREEN?
|
||
SEQ D6 ;IF SO, SET SRCSCRN FLAG
|
||
CMP.L BASEADDR(A1),D0 ;DST TO THE SCREEN?
|
||
SEQ D7 ;IF SO, SET DSTSCRN FLAG
|
||
|
||
MOVEQ #6,D2 ;ASSUME COPY FROM TOP TO BOTTOM
|
||
MOVE.B D6,D5 ;GET SRC FLAG
|
||
AND.B D7,D5 ;D5 SET IF SRC AND DST BOTH SCREEN
|
||
BEQ.S DIROK ;=>NO, DON'T WORRY ABOUT OVERLAP
|
||
|
||
; SRC AND DST BOTH ON SCREEN, AND THERE ARE MULTIPLE SCREENS. DETERMINE TRANSFER DIRECTION
|
||
|
||
MOVEQ #0,D2 ;ELSE ASSUME TRANSFER DOWN AND TO RIGHT
|
||
MOVE.L ([SRCRECT,A6]),D0 ;GET TOPLEFT OF SRCRECT
|
||
SUB BOUNDS+LEFT(A0),D0 ;CONVERT LEFT TO GLOBAL COORDINATES
|
||
MOVE.L ([DSTRECT,A6]),D1 ;GET TOPLEFT OF DSTRECT
|
||
SUB BOUNDS+LEFT(A1),D1 ;CONVERT LEFT TO GLOBAL COORDINATES
|
||
CMP D1,D0 ;IS SRC <= DST?
|
||
BLE.S TORT ;=>IF SO, TRANSFER IS TO RIGHT
|
||
ADDQ #2,D2 ;ELSE TRANSFER TO LEFT
|
||
|
||
TORT SWAP D0 ;GET TOP OF SRCRECT
|
||
SWAP D1 ;GET TOP OF DSTRECT
|
||
SUB BOUNDS+TOP(A0),D0 ;CONVERT TOP TO GLOBAL COORDINATES
|
||
SUB BOUNDS+TOP(A1),D1 ;CONVERT TOP TO GLOBAL COORDINATES
|
||
CMP D1,D0 ;IS SRC <= DST?
|
||
BLE.S DIROK ;=>IF SO, TRANSFER IS DOWNWARD
|
||
ADDQ #4,D2 ;ELSE TRANSFER IS UPWARD
|
||
|
||
DIROK leaROM ciROMCMPTBL,A4 ;POINT TO TABLE OF OFFSETS
|
||
ADD 0(A4,D2),A4 ;A4 = RECT COMPARE ROUTINE
|
||
|
||
; COPY SRC RECT AND CONVERT COPY TO GLOBAL COORDINATES
|
||
|
||
TST.B D6 ;IS SRC THE SCREEN?
|
||
BEQ CHKDST ;=>NO, CHECK DEST
|
||
|
||
MOVE.L SRCRECT(A6),A1 ;POINT TO RECT
|
||
LEA GLOBALSRC(A6),A0 ;POINT TO LOCAL COPY
|
||
MOVE.L (A1)+,TOPLEFT(A0) ;COPY SRCRECT.TOPLEFT
|
||
MOVE.L (A1)+,BOTRIGHT(A0) ;COPY SRCRECT.BOTRIGHT
|
||
MOVE.L BOUNDS(A2),D0 ;GET SRCBITS.TOPLEFT
|
||
MOVE.L D0,D1 ;LEAVE LEFT IN D0
|
||
SWAP D1 ;AND TOP IN D1
|
||
SUB D1,(A0)+ ;OFFSET TOP
|
||
BVC.S @0 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@0 SUB D0,(A0)+ ;OFFSET LEFT
|
||
BVC.S @1 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@1 SUB D1,(A0)+ ;OFFSET BOTTOM
|
||
BVC.S @2 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@2 SUB D0,(A0)+ ;OFFSET RIGHT
|
||
BVC.S @3 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@3
|
||
|
||
; FOR EACH SRC DEVICE THAT INTERSECTS WITH THE SRCRECT, BUILD A RECORD ON THE STACK
|
||
; EACH RECORD IN LIST CONSISTS OF: [FLAG WORD] [DEVICE HANDLE] [RECTANGLE]
|
||
; [FLAG WORD]: O = END OF LIST; 1 = VALID RECORD; -1 = RECORD ALREADY USED IN SORT
|
||
|
||
MOVE.L DEVICELIST,A2 ;GET HANDLE TO FIRST DEVICE
|
||
CLR -(SP) ;[FLAG WORD] := END OF LIST
|
||
|
||
DONEXT1 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
||
TST GDFLAGS(A0) ;IS THIS SCREEN ACTIVE?
|
||
BPL.S NXTDEV1 ;=>NO, SKIP TO NEXT
|
||
|
||
CLR.B -(SP) ;MAKE ROOM FOR BOOLEAN RESULT
|
||
PEA GLOBALSRC(A6) ;POINT TO SRC RECT
|
||
PEA GDRECT(A0) ;POINT AT DEVICE RECT
|
||
PEA RECT1(A6) ;GET RESULT IN RECT1
|
||
_SECTRECT ;INTERSECT THEM
|
||
TST.B (SP)+ ;DID THEY INTERSECT?
|
||
BEQ.S NXTDEV1 ;=>NO, KEEP LOOKING
|
||
|
||
LEA RECT1(A6),A0 ;POINT AT RESULT
|
||
MOVE.L 4(A0),-(SP) ;PUSH BOTRIGHT
|
||
MOVE.L (A0),-(SP) ;PUSH TOPLEFT
|
||
MOVE.L A2,-(SP) ;PUSH CURRENT DEVICE
|
||
MOVE #1,-(SP) ;FLAG VALID ENTRY
|
||
|
||
NXTDEV1 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
||
MOVE.L GDNEXTGD(A0),D0 ;IS THERE ANOTHER DEVICE IN CHAIN?
|
||
MOVE.L D0,A2 ;GET IT INTO A0
|
||
BNE.S DONEXT1 ;=>YES, DO NEXT DEVICE
|
||
|
||
; BUILD SORTED LIST OF POINTERS TO THE DEVICE RECORDS
|
||
|
||
MOVE.L SP,A2 ;POINT TO FIRST DEVICE
|
||
CLR.L -(SP) ;AND FLAG END OF LIST
|
||
MOVEQ #0,D1 ;USEFUL CONSTANT
|
||
|
||
NXTLOOP MOVE.L A2,A0 ;POINT TO START OF LIST
|
||
MOVE.L D1,A1 ;INITIALIZE BEST FIT TO NONE
|
||
|
||
NXTRECT TST FLAG(A0) ;CHECK RECT STATUS?
|
||
BMI.S DONEXT ;=>RECT ALREADY USED, SKIP IT
|
||
BEQ.S LASTRECT ;=>LAST RECT, DONE WITH THIS LOOP
|
||
CMP.L A1,D1 ;SOMETHING TO COMPARE AGAINST?
|
||
BEQ.S NORECT ;=>NO, A WINNER BY DEFAULT
|
||
JSR (A4) ;COMPARE A0 TO A1
|
||
BEQ.S DONEXT ;=>A1 IS BETTER, TRY NEXT
|
||
NORECT MOVE.L A0,A1 ;ELSE PUT NEW BEST FIT IN A1
|
||
DONEXT ADD #SIZE,A0 ;BUMP TO NEXT RECORD
|
||
BRA.S NXTRECT ;=>DO NEXT RECT IN LIST
|
||
|
||
LASTRECT CMP.L A1,D1 ;DID WE FIND A BEST FIT?
|
||
BEQ.S ENDLOOP ;=>NO, ALL DONE
|
||
ST FLAG(A1) ;SAY IT'S USED
|
||
MOVE.L A1,-(SP) ;AND PUSH RECORD POINTER ONTO STACK
|
||
BRA.S NXTLOOP ;=>GO FIND NEXT BEST
|
||
|
||
ENDLOOP MOVE.L SP,SRCLIST(A6) ;SAVE POINTER TO SRC DEVICE LIST
|
||
|
||
|
||
; COPY DST RECT AND CONVERT COPY TO GLOBAL COORDINATES
|
||
|
||
CHKDST TST.B D7 ;IS DST THE SCREEN?
|
||
BEQ DRAWLOOP ;=>NO, GO TO DRAWING LOOP
|
||
MOVE.L DSTRECT(A6),a0 ;POINT TO RECT
|
||
LEA GLOBALDST(A6),a1 ;POINT TO LOCAL COPY
|
||
MOVE.L (a0)+,TOPLEFT(a1) ;COPY DSTRECT.TOPLEFT
|
||
MOVE.L (a0)+,BOTRIGHT(a1) ;COPY DSTRECT.BOTRIGHT
|
||
MOVE.L DSTBITS(A6),A0 ;GET DESTINATION IN A0
|
||
_BITSTOMAP ;make sure it's not a cportPtr <28May89 BAL>
|
||
MOVE.L BOUNDS(a0),D0 ;GET TOPLEFT
|
||
MOVE.L D0,D1 ;LEAVE LEFT IN D0
|
||
SWAP D1 ;AND TOP IN D1
|
||
SUB D1,(a1)+ ;OFFSET TOP
|
||
BVC.S @0 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@0 SUB D0,(a1)+ ;OFFSET LEFT
|
||
BVC.S @1 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@1 SUB D1,(a1)+ ;OFFSET BOTTOM
|
||
BVC.S @2 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@2 SUB D0,(a1)+ ;OFFSET RIGHT
|
||
BVC.S @3 ;=>NO OVERFLOW
|
||
_PINIT ;ELSE PIN VALUE
|
||
@3
|
||
|
||
; FOR EACH DST DEVICE THAT INTERSECTS WITH THE DSTRECT, BUILD A RECORD ON THE STACK
|
||
; EACH RECORD IN LIST CONSISTS OF: [FLAG WORD] [DEVICE HANDLE] [RECTANGLE]
|
||
; [FLAG WORD]: O = END OF LIST; 1 = VALID RECORD; -1 = RECORD ALREADY USED IN SORT
|
||
|
||
MOVE.L DEVICELIST,A2 ;GET HANDLE TO FIRST DEVICE
|
||
CLR -(SP) ;[FLAG WORD] := END OF LIST
|
||
|
||
DONEXT2 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
||
TST GDFLAGS(A0) ;IS THIS SCREEN ACTIVE?
|
||
BPL.S NXTDEV2 ;=>NO, SKIP TO NEXT
|
||
|
||
CLR.B -(SP) ;MAKE ROOM FOR BOOLEAN RESULT
|
||
PEA GLOBALDST(A6) ;POINT TO DST RECT
|
||
PEA GDRECT(A0) ;POINT AT DEVICE RECT
|
||
PEA RECT1(A6) ;GET RESULT IN RECT1
|
||
_SECTRECT ;INTERSECT THEM
|
||
TST.B (SP)+ ;DID THEY INTERSECT?
|
||
BEQ.S NXTDEV2 ;=>NO, KEEP LOOKING
|
||
|
||
LEA RECT1(A6),A0 ;POINT AT RESULT
|
||
MOVE.L 4(A0),-(SP) ;PUSH BOTRIGHT
|
||
MOVE.L (A0),-(SP) ;PUSH TOPLEFT
|
||
MOVE.L A2,-(SP) ;PUSH CURRENT DEVICE
|
||
MOVE #1,-(SP) ;FLAG VALID ENTRY
|
||
|
||
NXTDEV2 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
||
MOVE.L GDNEXTGD(A0),D0 ;IS THERE ANOTHER DEVICE IN CHAIN?
|
||
MOVE.L D0,A2 ;GET IT INTO A0
|
||
BNE.S DONEXT2 ;=>YES, DO NEXT DEVICE
|
||
|
||
; BUILD SORTED LIST OF DEVICES
|
||
|
||
MOVE.L SP,A2 ;POINT TO FIRST DEVICE
|
||
CLR.L -(SP) ;AND FLAG END OF LIST
|
||
MOVEQ #0,D1 ;USEFUL CONSTANT
|
||
|
||
NXTLUP2 MOVE.L A2,A0 ;POINT TO START OF LIST
|
||
MOVE.L D1,A1 ;INITIALIZE BEST FIT TO NONE
|
||
|
||
NXTRCT2 TST FLAG(A0) ;CHECK RECT STATUS?
|
||
BMI.S DONXT2 ;=>RECT ALREADY USED, SKIP IT
|
||
BEQ.S LSTRCT2 ;=>LAST RECT, DONE WITH THIS LOOP
|
||
CMP.L A1,D1 ;SOMETHING TO COMPARE AGAINST?
|
||
BEQ.S NORCT2 ;=>NO, A WINNER BY DEFAULT
|
||
JSR (A4) ;COMPARE A0 TO A1
|
||
BEQ.S DONXT2 ;=>A1 IS BETTER, TRY NEXT
|
||
NORCT2 MOVE.L A0,A1 ;ELSE PUT NEW BEST FIT IN A1
|
||
DONXT2 ADD #SIZE,A0 ;BUMP TO NEXT RECORD
|
||
BRA.S NXTRCT2 ;=>DO NEXT RECT IN LIST
|
||
|
||
LSTRCT2 CMP.L A1,D1 ;DID WE FIND A BEST FIT?
|
||
BEQ.S ENDLUP2 ;=>NO, ALL DONE
|
||
ST FLAG(A1) ;SAY IT'S USED
|
||
MOVE.L DEV(A1),-(SP) ;AND PUSH DEVICE HANDLE ONTO STACK
|
||
BRA.S NXTLUP2 ;=>GO FIND NEXT BEST
|
||
|
||
ENDLUP2 MOVE.L SP,DSTLIST(A6) ;SAVE POINTER TO DST DEVICE LIST
|
||
|
||
|
||
DRAWLOOP
|
||
|
||
; IN CASE WE ARE GOING TO SCREEN, SAVE OFF STATE INFO
|
||
|
||
MOVE.L THEGDEVICE,-(SP) ;SAVE DST DEVICE
|
||
MOVE.L SRCDEVICE,-(SP) ;SAVE SRC DEVICE
|
||
|
||
MOVE.L THEGDEVICE,A0 ;GET HANDLE TO THE GDEVICE
|
||
MOVE.L (A0),A0 ;POINT TO THE GDEVICE
|
||
MOVE.L GDPMAP(A0),A0 ;GET HANDLE TO ITS PIXMAP
|
||
MOVE.L (A0),A0 ;POINT AT PIXMAP
|
||
MOVE.L PMTABLE(A0),A0 ;GET COLOR TABLE HANDLE
|
||
MOVE.L (A0),A0 ;POINT TO COLOR TABLE
|
||
MOVE.L CTSEED(A0),LASTSEED(A6) ;SAVE LAST COLOR TABLE SEED
|
||
MOVE.L FGCOLOR(A3),SAVEFG(A6) ;SAVE FG COLOR
|
||
MOVE.L BKCOLOR(A3),SAVEBK(A6) ;SAVE BK COLOR
|
||
MOVE.B HiliteMode,saveHilite(A6) ;save the hilite state
|
||
|
||
; MAKE A LOCAL COPY OF THE SRC AND DST RECTS IN SRCRECT1 AND DSTRECT1
|
||
; AND SET D7 TO NON-ZERO IF WE ARE STRETCHING
|
||
|
||
LEA DSTRECT1(A6),A1 ;POINT TO DSTRECT1, SRCRECT1
|
||
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
||
MOVE.L (A0)+,D0 ;GET TOPLEFT
|
||
MOVE.L D0,(A1)+ ;COPY TOPLEFT
|
||
MOVE.L (A0)+,D7 ;GET BOTRIGHT
|
||
MOVE.L D7,(A1)+ ;COPY BOTRIGHT
|
||
SUB D0,D7 ;GET DST WIDTH
|
||
SWAP D0 ;GET TOP
|
||
SWAP D7 ;GET BOTTOM
|
||
SUB D0,D7 ;GET DST HEIGHT
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
||
MOVE.L (A0)+,D0 ;GET TOPLEFT
|
||
MOVE.L D0,(A1)+ ;COPY TOPLEFT
|
||
MOVE.L (A0)+,D1 ;GET BOTRIGHT
|
||
MOVE.L D1,(A1)+ ;COPY BOTRIGHT
|
||
SWAP D7 ;GET DST WIDTH
|
||
ADD D0,D7 ;SUBTRACT WIDTH OF SRC
|
||
SUB D1,D7 ;FROM WIDTH OF DST
|
||
SWAP D7 ;GET HEIGHT
|
||
SWAP D0 ;GET TOP
|
||
SWAP D1 ;GET BOTTOM
|
||
ADD D0,D7 ;SUBTRACT HEIGHT OF SRC
|
||
SUB D1,D7 ;FROM HEIGHT OF DST
|
||
;D7.L <> 0 IF STRETCHING
|
||
|
||
; FOR EACH DEVICE IN THE SRCLIST, DRAW TO EACH DEVICE IN THE DSTLIST
|
||
|
||
MOVE.L SRCLIST(A6),A2 ;POINT TO SRCLIST
|
||
NXTSRC MOVE.L DSTLIST(A6),A4 ;POINT TO DSTLIST
|
||
MOVE.L (A2)+,D0 ;GET NEXT SRC RECORD
|
||
MOVE.L D0,A0 ;GET RECORD POINTER
|
||
BEQ DONE ;=>NO MORE
|
||
MOVE.L DEV(A0),SRCDEVICE ;AND SET SRC DEVICE
|
||
NXTDST MOVE.L (A4)+,D1 ;GET NEXT DST DEVICE
|
||
BEQ.S NXTSRC ;=>NO MORE
|
||
|
||
MOVE.L D1,THEGDEVICE ;ELSE SET DST DEVICE
|
||
TST.B D6 ;IS SRC THE SCREEN?
|
||
BEQ CLIPOK ;=>NO, DON'T CHECK CLIPPING
|
||
;
|
||
; if source and destination are both screen devices and they overlap, copy only to
|
||
; destination devices which are the same gDevice as the source. This will be needed
|
||
; for devices which use a mask plane. It assures that items moved around in the mask
|
||
; plane are only copied to the mask plane, and items moved around on the screen are
|
||
; only copied to the screen. Without this, the mask would goto the screen and vice-versa.
|
||
; <KON 2/19/90>
|
||
;
|
||
tst.b d5 ;are both src and destination the screen? <KON 23JAN91>
|
||
beq.s @cont ;=>NO, Don't check for overlap <104>
|
||
cmp.l SRCDEVICE,d1 ;are src and destination the same device? <KON 28NOV90>
|
||
beq.s @cont ;=>YES, Don't check for overlap
|
||
;
|
||
; Src and Dst are different screen devices. If the top-left corner of their rectangles
|
||
; are the same, assume the devices overlap and don't copy between them.
|
||
;
|
||
MOVE.L srcDevice,A1 ;handle to source gDevice
|
||
move.l (a1),a1 ;pointer to source gDevice
|
||
move.l gdRect(a1),d0 ;get rect top.left
|
||
move.l theGDevice,a1 ;handle to destination gDevice
|
||
move.l (a1),a1 ;pointer to destination gDevice
|
||
cmp.l gdRect(a1),d0 ;dest and src gDevice have same top-left?
|
||
beq.s nxtdst ;devices overlap, skip drawing
|
||
|
||
|
||
@cont
|
||
;
|
||
; End of <KON 2/19/90>
|
||
;
|
||
|
||
; CLIP SRCRECT TO SRC DEVICE BOUNDARIES
|
||
|
||
MOVE.L -4(A2),A0 ;POINT TO SOURCE RECORD
|
||
ADDQ #RECT,A0 ;POINT TO CLIPPED RECT
|
||
MOVE.L (A0)+,D0 ;GET GLOBAL CLIPPED.TOPLEFT
|
||
MOVE.L (A0)+,D1 ;GET GLOBAL CLIPPED.BOTRIGHT
|
||
CMP.L GLOBALSRC+TOPLEFT(A6),D0 ;WAS TOPLEFT TRIMMED?
|
||
BNE.S DOTRIM ;=>YES, TRIM SRC, DST RECTS
|
||
CMP.L GLOBALSRC+BOTRIGHT(A6),D1 ;WAS BOTRIGHT TRIMMED?
|
||
BEQ.S CLIPOK ;=>NO, DON'T TRIM SRC, DST RECTS
|
||
|
||
DOTRIM MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
||
LEA DSTRECT1(A6),A1 ;POINT TO DSTRECT1, SRCRECT1
|
||
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
||
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
||
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
||
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
||
|
||
SUB GLOBALSRC+LEFT(A6),D0 ;IS LEFT CLIPPED ON DEVICE?
|
||
BLE.S @1 ;=>LEFT OK
|
||
ADD D0,SRCRECT1+LEFT(A6) ;ELSE TRIM SRC
|
||
ADD D0,DSTRECT1+LEFT(A6) ;AND DST
|
||
@1 SWAP D0 ;GET TOP
|
||
SUB GLOBALSRC+TOP(A6),D0 ;IS TOP CLIPPED ON DEVICE?
|
||
BLE.S @2 ;=>TOP OK
|
||
ADD D0,SRCRECT1+TOP(A6) ;ELSE TRIM SRC
|
||
ADD D0,DSTRECT1+TOP(A6) ;AND DST
|
||
@2 SUB GLOBALSRC+RIGHT(A6),D1 ;IS RIGHT CLIPPED ON DEVICE?
|
||
BPL.S @3 ;=>RIGHT OK
|
||
ADD D1,SRCRECT1+RIGHT(A6) ;ELSE TRIM SRC
|
||
ADD D1,DSTRECT1+RIGHT(A6) ;AND DST
|
||
@3 SWAP D1 ;GET BOTTOM
|
||
SUB GLOBALSRC+BOTTOM(A6),D1 ;IS BOTTOM CLIPPED ON DEVICE?
|
||
BPL.S @4 ;=>BOTTOM OK
|
||
ADD D1,SRCRECT1+BOTTOM(A6) ;ELSE TRIM SRC
|
||
ADD D1,DSTRECT1+BOTTOM(A6) ;AND DST
|
||
|
||
@4 TST.L D7 ;ARE WE SCALING?
|
||
BEQ.S CLIPOK ;=>YES, DON'T NEED TO MAP DST
|
||
LEA SRCRECT1(A6),A0 ;ELSE GET TRIMMED SRC
|
||
LEA DSTRECT1(A6),A1 ;AND SAVE AS UNMAPPED TRIMMED DST
|
||
MOVE.L (A0)+,(A1)+ ;COPY SRCRECT1 TO DSTRECT1
|
||
MOVE.L (A0)+,(A1)+
|
||
PEA DSTRECT1(A6) ;PUSH RECT TO BE MAPPED
|
||
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRC RECTANGLE
|
||
MOVE.L DSTRECT(A6),-(SP) ;PUSH DST RECTANGLE
|
||
_MAPRECT ;MAP RECTANGLE TO DST COORDINATES
|
||
|
||
CLIPOK MOVE.B saveHilite(A6),HiliteMode ;RESTORE HILITE FLAGS
|
||
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD GRAFPORT?
|
||
BPL DOIT ;=>YES, COLORS ARE OK
|
||
MOVE.L THEGDEVICE,A0 ;GET THE DST DEVICE
|
||
MOVE.L (A0),A0 ;POINT AT IT
|
||
MOVE.L GDPMAP(A0),A0 ;GET PIXMAP
|
||
MOVE.L (A0),A0 ;POINT AT IT
|
||
MOVE.L PMTABLE(A0),A0 ;GET COLOR TABLE
|
||
MOVE.L (A0),A0 ;POINT AT IT
|
||
MOVE.L CTSEED(A0),D0 ;GET SEED
|
||
CMP.L LASTSEED(A6),D0 ;SAME AS CURRENT SEED?
|
||
BEQ.S DOIT ;=>YES, COLORS ARE OK
|
||
|
||
MOVE.L D0,LASTSEED(A6) ;SAVE LAST COLOR TABLE SEED
|
||
SUBQ #6,SP ;MAKE ROOM FOR A COLOR RECORD
|
||
CLR.L -(SP) ;CLEAR INDEX, FLAGS WORDS
|
||
|
||
; This is a patch rolled in <6Jun87 EHB>
|
||
; The idea here is that to keep the index field in the grafPort valid, we must
|
||
; check to see whether we should use palette manager or not.
|
||
|
||
MOVE.L GrafVars(A3),D0 ;get the grafVars handle
|
||
BEQ.S @NoPlt ;=>none there
|
||
MOVE.L D0,A0 ;get grafVars handle
|
||
MOVE.L (A0),A0 ;point at grafVars
|
||
TST.L PmFgColor(A0) ;is there a palette?
|
||
BEQ.S @NoPlt ;=>no, continue
|
||
|
||
MOVE PmFlags(A0),D2 ;else get flags
|
||
MOVE PmBkIndex(A0),2(SP) ;save bk index
|
||
BTST #PmBkBit,D2 ;bk set by palette mgr?
|
||
SNE (SP) ;if so set flag
|
||
|
||
BTST #PmFgBit,D2 ;fg set by palette mgr?
|
||
BEQ.S @NoPlt ;=>no, continue
|
||
|
||
MOVE PmFgIndex(A0),-(SP) ;else push last index
|
||
_PmForeColor ;and set that color
|
||
BRA.S @NoPlt1 ;=>no, do old way
|
||
|
||
@NoPlt PEA 4(SP) ;POINT AT RECORD FOR RGBFC
|
||
MOVE.L (SP),-(SP) ;AND AGAIN FOR GETFC
|
||
_GETFORECOLOR ;GET THE FOREGROUND COLOR
|
||
_RGBFORECOLOR ;SET THE FOREGROUND COLOR
|
||
|
||
@NoPlt1 TST.B (SP) ;bk set by palette mgr?
|
||
BEQ.S @NoPlt2 ;=>no, do old way
|
||
MOVE 2(SP),-(SP) ;else push bk index
|
||
_PmBackColor ;and set that color
|
||
BRA.S @BkDone ;=>done setting colors
|
||
|
||
@NoPlt2 PEA 4(SP) ;POINT AT RECORD
|
||
MOVE.L (SP),-(SP) ;AND AGAIN FOR GETFC
|
||
_GETBACKCOLOR ;GET THE BACKGROUND COLOR
|
||
_RGBBACKCOLOR ;SET THE BACKGROUND COLOR
|
||
|
||
@BkDone ADD #10,SP ;STRIP THE RECORD
|
||
|
||
DOIT MOVE.L SRCBITS(A6),-(SP) ;PUSH SRCBITS
|
||
MOVE.L MASKBITS(A6),-(SP) ;PUSH MASKBITS
|
||
MOVE.L DSTBITS(A6),-(SP) ;PUSH DSTBITS
|
||
PEA SRCRECT1(A6) ;PUSH SRCRECT
|
||
MOVE.L MASKRECT(A6),-(SP) ;PUSH MASKRECT
|
||
PEA DSTRECT1(A6) ;PUSH DSTRECT
|
||
MOVE MODE(A6),-(SP) ;PUSH MODE
|
||
AND #$FFF7,(SP) ;clear the pattern bit in case the user set it
|
||
CLR.L -(SP) ;NO PATTERN NEEDED
|
||
MOVE.L RGNA(A6),-(SP) ;PUSH FIRST REGION
|
||
MOVE.L RGNB(A6),-(SP) ;PUSH SECOND REGION
|
||
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN
|
||
BNE.S MASKOK ;WAS IT NIL ?
|
||
MOVE.L GRAFGLOBALS(A5),A0 ;GET GRAFGLOBALS
|
||
MOVE.L WIDEOPEN(A0),(SP) ;YES, REPLACE WITH WIDEOPEN
|
||
MASKOK CLR -(SP) ;pass multicolor flag false
|
||
_STRETCHBITS ;CALL STRETCHBITS
|
||
|
||
BRA.S NXTDST ;=>TRY NEXT DESTINATION
|
||
|
||
DONE MOVE.L (SP)+,SRCDEVICE ;RESTORE SRC DEVICE
|
||
MOVE.L (SP)+,THEGDEVICE ;RESTORE DST DEVICE
|
||
|
||
MOVE.L SAVEFG(A6),FGCOLOR(A3) ;RESTORE FG COLOR
|
||
MOVE.L SAVEBK(A6),BKCOLOR(A3) ;RESTORE BK COLOR
|
||
BSET #HILITEBIT,HILITEMODE ;TURN OFF HILITING
|
||
|
||
MOVE.L SAVEDSP(A6),SP ;RESTORE THE STACK POINTER
|
||
RTS
|
||
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; New entry in table below.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
Dither32toBitmap PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherBitmap32
|
||
|
||
move.b d3,d2 ; get the blue component
|
||
lsr.l #8,d3 ; get red,green in low word
|
||
move.b d3,d1 ; get the green component
|
||
lsr.w #8,d3 ; get red in low byte
|
||
move.b d3,d0 ; get the red component
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
spl d0 ; ≥$80 -> $00; <$80 -> $ff
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
not.b d0 ; get luminance value of output pixel
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
sub.w d0,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.L -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap32
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.L (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap32
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; New entry in table below.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
Dither16toBitmap PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherBitmap16
|
||
|
||
lsl.l #3,d3 ; left justify lo 5 bits
|
||
move.b d3,d2 ; get the blue component
|
||
lsl.w #5,d2 ; save 5 bits
|
||
move.b d3,d2 ; get 5 more bits
|
||
lsr.w #5,d2 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d1 ; get 5 of the green bits
|
||
lsl.w #5,d1 ; save 5 bits
|
||
move.b d3,d1 ; get 5 more bits
|
||
lsr.w #5,d1 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d0 ; get 5 of the red bits
|
||
lsl.w #5,d0 ; save 5 bits
|
||
move.b d3,d0 ; get 5 more bits
|
||
lsr.w #5,d0 ; chuck 2 of the ten
|
||
move.w d0,d3 ; make a copy of the red
|
||
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
spl d0 ; ≥$80 -> $00; <$80 -> $ff
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
not.b d0 ; get luminance value of output pixel
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
sub.w d0,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
moveq #0,d3 ;clear out high word
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.w -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap16
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.w (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap16
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Speedup for Search32toIndexed.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
MyCProc EQU $3D728
|
||
MySProc EQU $3D6FC
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; Perform a one time check to see if the search proc is the standard
|
||
; SeedCFill or CalcCMask search procedure. If it is then use an optimized
|
||
; loop instead.
|
||
|
||
Search32toIndexed PROC EXPORT
|
||
IMPORT SeedCFill32, CalcCMask32, Search32toInd
|
||
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
movem.l a0-a2,-(sp) ;save work registers
|
||
lea Search32toInd,a0 ;assume the hard case
|
||
MOVE.L stSProc(A6),a1 ;get the search proc head
|
||
MOVE.L (a1),a1 ;get sProcRec pointer
|
||
MOVE.L srchProc(a1),a1 ;get search proc address
|
||
leaROM MySProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @tryC
|
||
lea SeedCFill32,a0
|
||
bra.s @gotit
|
||
|
||
@tryC leaROM MyCProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @gotIt
|
||
lea CalcCMask32,a0
|
||
@gotIt
|
||
MOVE.L A0,scaleCase(A6) ;remember to go there from now on
|
||
move.l a0,d0 ;save scalecase in d0
|
||
movem.l (sp)+,a0-a2 ;restore work registers
|
||
jmp (ZA0,d0.l) ;go there
|
||
ENDPROC
|
||
|
||
|
||
Search32toInd PROC EXPORT
|
||
;
|
||
; this routine converts a 32-bit direct pixel to a 1,2,4, or 8 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; into the appropriate inverse table if that fails. The stack frame is included
|
||
; solely to copy the stack frame offsets from the caller in Stretch.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D6-D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
MOVEQ #0,D7 ;init offset into destination
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
|
||
NXTSLNG
|
||
MOVE.L (A4)+,D5 ;pick up a 32-bit source pixel
|
||
MOVE.B D5,blue(SP) ;put blue byte in hi byte of blue component
|
||
MOVE.B D5,blue+1(SP) ;put blue byte in lo byte of blue component
|
||
ROR.L #8,D5 ;get green in the lo byte
|
||
MOVE.B D5,green(SP) ;put green byte in hi byte of green component
|
||
MOVE.B D5,green+1(SP) ;put green byte in lo byte of green component
|
||
ROR.L #8,D5 ;get red in the lo byte
|
||
MOVE.B D5,red(SP) ;put in hi red channel
|
||
MOVE.B D5,red+1(SP) ;put in lo red channel
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S UseITable ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D3 ;get result in D3
|
||
BRA.S BuildLong ;and put into output buffer
|
||
|
||
UseITable ;go here if no search proc matched
|
||
|
||
MOVE.L stITabPtr(A6),A0 ;get pointer to the inverse table (past header)
|
||
MOVE.W stITabRes(A6),D1 ;get the iTable resolution
|
||
move.b red(sp),d5 ;get red
|
||
BFEXTU D5{24:D1},D0 ;extract iTabRes bits of red (clearing hi bits)
|
||
LSL.L D1,D0 ;shift over by iTabRes
|
||
|
||
move.b green(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;get the green component
|
||
OR.L D3,D0 ;put them together
|
||
LSL.L D1,D0 ;shift again
|
||
|
||
move.b blue(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;get the blue component
|
||
OR.L D3,D0 ;put them together to form iTable index
|
||
|
||
MOVE.B (A0,D0.L),D3 ;get the index in D3 (hi 3 bytes still clear)
|
||
|
||
BuildLong
|
||
BFINS D3,D6{D7:D4} ;PUT TO DST LONG
|
||
ADD D4,D7 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D7 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
MOVE.L D6,(A3)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D6-D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
SeedCFill32 PROC EXPORT
|
||
Export CalcCMask32
|
||
;
|
||
; this routine converts a 32-bit direct pixel to a 1 bit destination with zero's
|
||
; wherever the source matches the color pointed to by the GDRefcon field and
|
||
; one's everywhere else.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
moveq #0,d1 ;clear high bit of d1 to signal SeedCFill
|
||
bra.s share
|
||
|
||
CalcCMask32
|
||
moveq #-1,d1 ;set high bit of d1 to signal CalcCMask
|
||
|
||
share
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1- BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
move.l a2,D5 ;save end of dst buffer in D5
|
||
MOVE.L theGDevice,A2 ;get handle to the gDevice
|
||
MOVE.L (A2),A2 ;point to theGDevice
|
||
MOVE.L GDRefCon(A2),A2 ;point to seed RGB
|
||
move.l (a2)+,d3 ;get RRrrGGgg
|
||
lsr.l #8,d3 ;get 00RRrrGG
|
||
lsl.w #8,d3 ;get 00RRGG00
|
||
move.b (a2),d3 ;get 00RRGGBB
|
||
move.l d5,a2 ;restore end of dst buffer
|
||
|
||
move.l MaskBC,d0 ;get low3bytes mask
|
||
MOVEQ #0,D4 ;init offset into destination
|
||
|
||
NXTSLNG
|
||
MOVE.L (A0)+,D5 ;pick up a 32-bit source pixel
|
||
and.l d0,d5 ;clear high byte for compare
|
||
cmp.l d5,d3 ;compare to seed value
|
||
sne.b d1 ;match ? d1=0 : d1=FF
|
||
|
||
BuildLong
|
||
BFINS D1,D2{D4:1} ;PUT TO DST LONG
|
||
ADDq #1,D4 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D4 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
|
||
addx.l d1,d1 ;tst high bit of d1
|
||
subx.l d1,d1 ;extend high bit throughout long
|
||
eor.l d1,d2 ;conditionally invert resulting bits
|
||
|
||
MOVE.L D2,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Speedup for Search16toIndexed.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; Perform a one time check to see if the search proc is the standard
|
||
; SeedCFill or CalcCMask search procedure. If it is then use an optimized
|
||
; loop instead.
|
||
|
||
Search16toIndexed PROC EXPORT
|
||
IMPORT SeedCFill16, CalcCMask16
|
||
|
||
&CurFile SETC 'STRETCH'
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
movem.l a0-a2,-(sp) ;save work registers
|
||
lea Search16toInd,a0 ;assume the hard case
|
||
MOVE.L stSProc(A6),a1 ;get the search proc head
|
||
MOVE.L (a1),a1 ;get sProcRec pointer
|
||
MOVE.L srchProc(a1),a1 ;get search proc address
|
||
leaROM MySProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @tryC
|
||
lea SeedCFill16,a0
|
||
bra.s @gotit
|
||
|
||
@tryC lea MyCProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @gotIt
|
||
lea CalcCMask16,a0
|
||
@gotIt
|
||
MOVE.L A0,scaleCase(A6) ;remember to go there from now on
|
||
move.l a0,d0 ;save scalecase in d0
|
||
movem.l (sp)+,a0-a2 ;restore work registers
|
||
jmp (ZA0,d0.l) ;go there
|
||
|
||
Search16toInd
|
||
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 1,2,4, or 8 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; into the appropriate inverse table if that fails. The stack frame is included
|
||
; solely to copy the stack frame offsets from the caller in Stretch.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
;&CurFile SETC 'STRETCH'
|
||
;
|
||
; INCLUDE 'DrawingVars.a'
|
||
; ...included above...
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF TWO BYTES OF THE FORM 'xrrrrrgggggbbbbb'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D6-D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
MOVEQ #0,D7 ;init offset into destination
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
|
||
NXTSLNG
|
||
MOVE.W (A4)+,D5 ;pick up a 16-bit source pixel
|
||
lsl.l #3,d5 ;left align blue in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of blue
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of blue
|
||
MOVE.w D0,blue(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align green in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of green
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of green
|
||
MOVE.w D0,green(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align red in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of red
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of red
|
||
MOVE.w D0,red(SP) ;store out in color spec
|
||
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D3 ;get result in D3
|
||
BRA.S BuildLong ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
|
||
MOVE.L stITabPtr(A6),A0 ;get pointer to the inverse table (past header)
|
||
MOVE.W stITabRes(A6),D1 ;get the iTable resolution
|
||
|
||
move.b red(sp),d5
|
||
BFEXTU D5{24:D1},D0 ;5,8,8 ;extract iTabRes bits of red (clearing hi bits)
|
||
LSL.L D1,D0 ;3,6,6 ;shift over by iTabRes
|
||
move.b green(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;5,8,8 ;get the green component
|
||
OR.L D3,D0 ;0,2,3 ;put them together
|
||
LSL.L D1,D0 ;3,6,6 ;shift again
|
||
move.b blue(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;5,8,8 ;get the blue component
|
||
OR.L D3,D0 ;0,2,3 ;put them together to form iTable index
|
||
;21,40,42
|
||
MOVE.B (A0,D0.w),D3 ;get the index in D3 <KON 12MAR90>
|
||
|
||
BuildLong
|
||
BFINS D3,D6{D7:D4} ;PUT TO DST LONG <KON 12MAR90>
|
||
ADD D4,D7 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D7 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
MOVE.L D6,(A3)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D6-D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
|
||
SeedCFill16 PROC EXPORT
|
||
Export CalcCMask16
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 1 bit destination with zero's
|
||
; wherever the source matches the color pointed to by the GDRefcon field and
|
||
; one's everywhere else.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
moveq #0,d1 ;clear high bit of d1 to signal SeedCFill
|
||
bra.s share
|
||
|
||
CalcCMask16
|
||
moveq #-1,d1 ;set high bit of d1 to signal CalcCMask
|
||
|
||
share
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1- BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
move.l a2,D5 ;save end of dst buffer in D5
|
||
MOVE.L theGDevice,A2 ;get handle to the gDevice
|
||
MOVE.L (A2),A2 ;point to theGDevice
|
||
MOVE.L GDRefCon(A2),A2 ;point to seed RGB
|
||
move.w (a2)+,d3 ;get RRrr
|
||
lsr.w #1,d3 ;clear high bit
|
||
lsl.l #6,d3 ;save 6 bits in high word
|
||
move.w (a2)+,d3 ;get GGrr
|
||
lsl.l #5,d3 ;save 5 more bits in high word
|
||
move.w (a2),d3 ;get BBbb
|
||
lsr.l #8,d3
|
||
lsr.l #3,d3 ; convert to 5-5-5 pixel in low word
|
||
move.l d5,a2 ;restore end of dst buffer
|
||
|
||
moveq #-1,d0 ;get low 15 bits mask
|
||
lsr.w #1,d0
|
||
MOVEQ #0,D4 ;init offset into destination
|
||
|
||
NXTSLNG
|
||
MOVE.w (A0)+,D5 ;pick up a 32-bit source pixel
|
||
and.w d0,d5 ;clear high byte for compare
|
||
cmp.w d5,d3 ;compare to seed value
|
||
sne.b d1 ;match ? d1=0 : d1=FF
|
||
|
||
BuildLong
|
||
BFINS D1,D2{D4:1} ;PUT TO DST LONG
|
||
ADDq #1,D4 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D4 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
|
||
addx.l d1,d1 ;tst high bit of d1
|
||
subx.l d1,d1 ;extend high bit throughout long
|
||
eor.l d1,d2 ;conditionally invert resulting bits
|
||
|
||
MOVE.L D2,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; More dither32. This stuff is from ScaleBlt.a
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;-------------------------------------------------------
|
||
;
|
||
; seek loop for serpentine dithering with run masks
|
||
;
|
||
;-------------------------------------------------------
|
||
|
||
NXTMASKDither PROC EXPORT
|
||
EXPORT sc32to8Dither
|
||
|
||
runMaskBit equ 30 ;bit number for run MASK instruction
|
||
|
||
move MinRect+bottom(a6),d2 ;get bottom vertical position
|
||
sub vert(a6),d2 ;compute scans remaining, prime d2
|
||
ble Done
|
||
move d2,d3 ;save scans remaining
|
||
JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
||
move d2,d1 ;get scan count in d1
|
||
cmp d3,d1 ;scan count > scans remaining?
|
||
ble.s @go ;no, call the blit loop
|
||
move d3,d1 ;yes, pin to scans remaining
|
||
@go
|
||
move.l runBuf(a6),d3 ;save original
|
||
move.w #-4,RUNBUMP(a6) ;set transfer direction for seekmask
|
||
move.l runBuf2(a6),runBuf(a6) ;point at alternate
|
||
JSR ([RUNRTN,A6]) ;MAKE BAKWRDS RUN BUFFER CURRENT
|
||
move.l d3,runBuf(a6) ;restore original
|
||
move.w #4,RUNBUMP(a6) ;set transfer direction for seekmask
|
||
JSR ([RUNRTN,A6]) ;MAKE FORWRDS RUN BUFFER CURRENT
|
||
move.l scaleBltA3(a6),A3 ;reload A3 for scan loops
|
||
MOVE.L ScaleCase(A6),A2 ;GET MODE CASE JUMP
|
||
JMP (A2) ;TAKE MODE JUMP
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; scale, dither and clip 32-bit src to 8-bit dst
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = src RGB pixel
|
||
; a1 = tmpmask d1 = pixel cnt/scratch
|
||
; a2 = tmpdst d2 = output pixels
|
||
; a3 = ITable d3 = run cnt
|
||
; a4 = errBuffer d4 = scratch
|
||
; a5 = CLUT d5 = red error
|
||
; a6 = locals d6 = grn error
|
||
; a7^= scancount d7 = blu error (itabres)
|
||
;-------------------------------------------------------
|
||
|
||
sc32to8Dither
|
||
;----------------------------------------------------
|
||
;
|
||
; 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'
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; scale, dither and clip 32-bit src to 8-bit dst
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = src RGB pixel
|
||
; a1 = tmpmask d1 = pixel cnt/scratch
|
||
; a2 = tmpdst d2 = output pixels
|
||
; a3 = ITable d3 = run cnt
|
||
; a4 = errBuffer d4 = scratch
|
||
; a5 = CLUT d5 = red error
|
||
; a6 = locals d6 = grn error
|
||
; a7^= scancount d7 = blu error (itabres)
|
||
;-------------------------------------------------------
|
||
|
||
;One time initializations here
|
||
|
||
subq #4,sp ;space for scancount
|
||
move.l dstAlign(a6),d0 ; -(# of dst bits to skip)
|
||
asr.l #1,d0 ; compute - (# of src bytes to back up)
|
||
add.l d0,a4 ; back off src ptr to beginning of dst long
|
||
move.l a4,srcAddr(a6) ; save for later
|
||
MOVE.L stITabPtr(A6),A3 ; get ptr to ITable
|
||
MOVE.L stCLUTPtr(A6),A5 ; get ptr to CLUT
|
||
moveq #0,d4 ; clear out high word always
|
||
|
||
lea @first,a0 ;go here from now on
|
||
move.l A3,scaleBltA3(a6) ;save for reload after seekMask
|
||
move.l a0,ScaleCase(a6) ;remember for later
|
||
bra.s NXTMASKDither ;go to it
|
||
|
||
align 16
|
||
|
||
@nxtScan
|
||
move.l dstRow(a6),d2 ;get dst rowbytes
|
||
add.l d2,dstAddr(a6) ;BUMP DST TO NEXT ROW
|
||
move.l srcRow(a6),d2 ;get src rowbytes
|
||
add.l d2,srcAddr(a6) ;BUMP src TO NEXT ROW
|
||
addq.w #1,vert(a6) ;BUMP DOWN A SCAN LINE
|
||
subq #1,(sp) ;decrement scan count
|
||
move (sp),d1 ;get back scan count
|
||
ble.s NXTMASKDither
|
||
@first
|
||
move.l srcAddr(a6),a0 ;init tmp src ptr
|
||
move.l dstAddr(a6),a2 ;init tmp dst ptr
|
||
move.l runBuf(a6),a1 ;point to run encoded mask buffer
|
||
move d1,(sp) ;save scan count on stack
|
||
MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;init redAccum
|
||
MOVE.L D5,D6 ;init grnAccum
|
||
MOVE.L D5,D7 ;init bluAccum
|
||
MOVE.W stITabRes(A6),d7 ;get the iTable resolution
|
||
swap d7 ;keep in high word
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @inst ;all ok if going left to right
|
||
|
||
move.l runBuf2(a6),a1 ;get right to left run buffer
|
||
|
||
@inst move.l (a1)+,d3 ;pick up next instruction long
|
||
bmi.s @nxtScan ;if high bit set then done with scan
|
||
add.w d3,a2 ;bump destptr by skip amount
|
||
add.w d3,d3 ;bump errbuf by 1x
|
||
add.w d3,a4 ;bump errbuf by 2x
|
||
add.w d3,d3 ;make dst byte skip src byte skip
|
||
add.w d3,a0 ;bump src ptr by 4x
|
||
add.w d3,a4 ;bump errbuf by 6x
|
||
swap d3 ;get mask/blit
|
||
lsl.l #32-runMaskBit,d3 ;shift mask flag into high word
|
||
lsr.w #32-runMaskBit,d3 ;clear flags from low word
|
||
tst.b errDir(a6) ;check diffusion direction
|
||
bne.s @forward ;src is OK for forward travel
|
||
|
||
|
||
@backward
|
||
bsr.s ditherCore8
|
||
|
||
sub.w #48,a4 ;bump back by 4+4 error pixels
|
||
sub.w #32,a0 ;bump back by 4+4 src pixels
|
||
|
||
btst #16,d3 ;check mask flag
|
||
beq.s @bblit ;no mask
|
||
|
||
MOVE.L (A1)+,D0 ;GET MASK
|
||
AND.L D0,D2 ;MASK src DATA
|
||
NOT.L D0 ;MAKE NOTMASK
|
||
AND.L (A2),D0 ;GET DST DATA
|
||
OR.L D0,D2 ;MERGE WITH PAT DATA
|
||
@bblit MOVE.L D2,(A2) ;PUT RESULT TO DST
|
||
subq #4,a2 ;bump the dst
|
||
DBRA D3,@backward ;LOOP ALL PIXELS THIS RUN
|
||
BRA.s @inst ;LOOP BACK FOR more runs
|
||
|
||
|
||
@forward
|
||
bsr.s ditherCore8
|
||
|
||
btst #16,d3 ;check mask flag
|
||
beq.s @fblit ;no mask
|
||
|
||
MOVE.L (A1)+,D0 ;GET MASK
|
||
AND.L D0,D2 ;MASK src DATA
|
||
NOT.L D0 ;MAKE NOTMASK
|
||
AND.L (A2),D0 ;GET DST DATA
|
||
OR.L D0,D2 ;MERGE WITH PAT DATA
|
||
@fblit MOVE.L D2,(A2)+ ;PUT RESULT TO DST
|
||
DBRA D3,@forward ;LOOP ALL PIXELS THIS RUN
|
||
BRA.s @inst ;LOOP BACK FOR more runs
|
||
|
||
DitherCore8
|
||
moveq #3,d1 ;4 per dst long; clear high 3 bytes
|
||
@nxtSrc
|
||
swap d1 ;save pixel cnt in high word
|
||
move.l (a0)+,d0 ;fetch next src pixel
|
||
|
||
move.b d0,d4 ;get blue as a word
|
||
add.w 4(a4),D7 ;consume blu error from above
|
||
add.w d4,d7 ;accumulate blue
|
||
spl d4 ;get pin value if neg
|
||
cmp.w d4,d7 ;is it too big
|
||
sgt d1 ;get pin value if too big
|
||
and d4,d7 ;mask to zero or a byte
|
||
or d1,d7 ;conditionally pin to ff
|
||
lsr.w #8,d0 ;toss blue
|
||
|
||
add.w 2(a4),D6 ;consume grn error from above
|
||
add.w d0,d6 ;accumulate green
|
||
spl d4 ;get pin value if neg
|
||
cmp.w d4,d6 ;is it too big
|
||
sgt d1 ;get pin value if too big
|
||
and d4,d6 ;mask to zero or a byte
|
||
or d1,d6 ;conditionally pin to ff
|
||
swap d0 ;toss green
|
||
|
||
move.b d0,d4 ;get red as a word
|
||
add.w (a4),D5 ;consume red error from above
|
||
add.w d4,d5 ;accumulate red
|
||
spl d4 ;get pin value if neg
|
||
cmp.w d4,d5 ;is it too big
|
||
sgt d1 ;get pin value if too big
|
||
and d4,d5 ;mask to zero or a byte
|
||
or d1,d5 ;conditionally pin to ff
|
||
|
||
move.l d7,d0 ;get the iTable resolution in high word
|
||
swap d0 ;move it to low word
|
||
move.b d5,d4 ;get desired red value
|
||
lsl.l d0,d4 ;move it up
|
||
move.b d6,d4 ;get desired grn value
|
||
lsl.l d0,d4 ;move it up
|
||
move.b d7,d4 ;get desired blu value
|
||
neg d0
|
||
addq #8,d0
|
||
lsr.l d0,d4 ;throw out the insignificant bits
|
||
|
||
move.b (a3,d4.L),d1 ;get the index in D1.w (hi byte still clear)
|
||
lsl.l #8,d2 ;shift other pixels up to make room
|
||
move.b d1,d2 ;save this pixel
|
||
move.l CTTable+rgb+red(a5,d1.w*8),d0 ;get RRRRGGGG
|
||
|
||
moveq #0,d4 ;clear out high end
|
||
lsr.l #8,d0 ;get high byte of green
|
||
move.b d0,d4 ;make it a word
|
||
sub.w d4,d6 ;compute green error
|
||
|
||
swap d0 ;get high byte of red
|
||
sub.w d0,d5 ;compute red error
|
||
|
||
move.b CTTable+rgb+blue(a5,d1.w*8),d4 ;get BBBB
|
||
sub.w d4,d7 ;compute blue error
|
||
|
||
MOVEQ #0,D4 ;GET A HANDY KONSTANT
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
ADDX.W D4,D5 ;KEEP NEGATIVE NUMBERS FROM DRIFTING AWAY FROM ZERO
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
ADDX.W D4,D6 ;KEEP NEGATIVE NUMBERS FROM DRIFTING AWAY FROM ZERO
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
ADDX.W D4,D7 ;KEEP NEGATIVE NUMBERS FROM DRIFTING AWAY FROM ZERO
|
||
|
||
swap d1 ;get back pixel cnt
|
||
dbra d1,@nxtSrc ;do for each src pixel in this dst long
|
||
rts
|
||
|
||
Done MoveQ #1,d0 ;return success
|
||
MOVE.L SAVESTK2(A6),SP ;RESTORE STACK POINTER
|
||
RTS ;AND RETURN TO STRETCHBITS
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Table from ScaleBlt.a moved to RAM.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
;8-Bit Blits
|
||
RAMscDirTab8 PROC EXPORT
|
||
|
||
scCopy16toIndexed EQU $0
|
||
scDither16 EQU $0
|
||
scGray16 EQU $0
|
||
scDitherGray16 EQU $0
|
||
sc32to8 EQU $0
|
||
sc32to8gray EQU $0
|
||
;sc32to8Dither ;patched out below
|
||
|
||
DC.L scCopy16toIndexed-RAMscDirTab8 ;0 16 to 8
|
||
DC.L scDither16-RAMscDirTab8 ;1 16 to 8 dither
|
||
DC.L scGray16-RAMscDirTab8 ;2 16 to 8 gray
|
||
DC.L scDitherGray16-RAMscDirTab8 ;3 16 to 8 gray+dither
|
||
DC.L sc32to8-RAMscDirTab8 ;4 32 to 8
|
||
DC.L sc32to8Dither-RAMscDirTab8 ;5 32 to 8 dither
|
||
DC.L sc32to8gray-RAMscDirTab8 ;6 32 to 8 gray
|
||
DC.L sc32to8gray-RAMscDirTab8 ;7 32 to 8 gray+dither
|
||
;*** should probably do a 32to8gray dither as well ***
|
||
|
||
ENDPROC
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Quickerdraw patches.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
patchciROM EQU 1
|
||
INCLUDE 'Arith8Blt.a'
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch 32toIndexed to eliminate accumulation of dither error.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
Dither32toIndexed PROC EXPORT
|
||
|
||
ditherCore32 EQU $39432
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
|
||
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO DST
|
||
MOVE.L D2,D5 ;init redAccum
|
||
MOVE.L D2,D6 ;init grnAccum
|
||
MOVE.L D2,D7 ;init bluAccum
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d2 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D2 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #6,a4
|
||
MOVE.L -(A0),D0 ;GET NEXT LONG OF SRC
|
||
jsrROM ditherCore32
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,0(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,2(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,4(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
sub.w D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d2
|
||
MOVE.L D1,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s donescl
|
||
|
||
@forward
|
||
MOVE.L (A0)+,D0 ;GET NEXT LONG OF SRC
|
||
jsrROM ditherCore32
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
@again
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D2 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch Dither32toGray to eliminate accumulation of dither error.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
Dither32toGray PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherGray
|
||
|
||
move.b d3,d2 ; get the blue component
|
||
lsr.l #8,d3 ; get red,green in low word
|
||
move.b d3,d1 ; get the green component
|
||
lsr.w #8,d3 ; get red in low byte
|
||
move.b d3,d0 ; get the red component
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
move.b (a3,d1),d0 ; pick up index for this luminance
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
move.b (a5,d1),d1 ; get actual luminance as a word <BAL 30Jan90>
|
||
sub.w d1,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
MOVE.L stITabInfo(A6),A3 ;get pointer to the luminance table (past header)
|
||
lea ITabLuma-ITabInfo(a3),a5 ;point to luma table
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.L -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.L (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch Dither16toGray to eliminate accumulation of dither error.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
Dither16toGray PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherGray16
|
||
|
||
lsl.l #3,d3 ; left justify lo 5 bits
|
||
move.b d3,d2 ; get the blue component
|
||
lsl.w #5,d2 ; save 5 bits
|
||
move.b d3,d2 ; get 5 more bits
|
||
lsr.w #5,d2 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d1 ; get 5 of the green bits
|
||
lsl.w #5,d1 ; save 5 bits
|
||
move.b d3,d1 ; get 5 more bits
|
||
lsr.w #5,d1 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d0 ; get 5 of the red bits
|
||
lsl.w #5,d0 ; save 5 bits
|
||
move.b d3,d0 ; get 5 more bits
|
||
lsr.w #5,d0 ; chuck 2 of the ten
|
||
move.w d0,d3 ; make a copy of the red
|
||
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
move.b (a3,d1),d0 ; pick up index for this luminance
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
move.b (a5,d1),d1 ; get actual luminance as a word <BAL 30Jan90>
|
||
sub.w d1,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
moveq #0,d3 ;clear out high word
|
||
MOVE.L stITabInfo(A6),A3 ;get pointer to the luminance table (past header)
|
||
lea ITabLuma-ITabInfo(a3),a5 ;point to luma table
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.w -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray16
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.w (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray16
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Move stColorTab to RAM to patch direct dither entries.
|
||
; This PROC doesn't do anything, it only holds space for the RAM table.
|
||
; Code below the CutBack point installs the table.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
RAMstColorTab PROC EXPORT
|
||
IMPORT Dither16toIndexed
|
||
ALIGN 4
|
||
|
||
Bogus EQU 0
|
||
Scale32toIndexed EQU 0
|
||
Scale32to16 EQU 0
|
||
;Dither32toIndexed EQU 0 ;new routine is above
|
||
Scale16to32 EQU 0
|
||
Scale16toIndexed EQU 0
|
||
;Dither16toIndexed EQU 0
|
||
;Color Blits EQU 0
|
||
|
||
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
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Table from Stretch.a moved to RAM.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
RAMstGrayTab PROC EXPORT
|
||
;Gray Blits
|
||
|
||
Scale32toBitmap EQU $0
|
||
Scale32toGray EQU $0
|
||
;Dither32toBitmap EQU $0 This routine added above
|
||
;Dither32toGray EQU $0 This routine added above
|
||
Scale16ToBitMap EQU $0
|
||
Scale16toGray EQU $0
|
||
;Dither16toBitmap EQU $0 This routine added above
|
||
;Dither16toGray EQU $0 This routine added above
|
||
|
||
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
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Table from Stretch.a now resides totally in RAM
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
RAMstSearchTab PROC EXPORT
|
||
IMPORT Search32to32, Search32toIndexed
|
||
IMPORT Search32to16, Search16to32
|
||
IMPORT Search16toIndexed, Search16to16
|
||
|
||
Bogus EQU $0
|
||
|
||
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
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; All the new search procs follow.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
Search16to32 PROC EXPORT
|
||
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 32 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 32 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
|
||
DoOne
|
||
MOVE.W (A4)+,D5 ;pick up a 16-bit source pixel
|
||
lsl.l #3,d5 ;left align blue in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of blue
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of blue
|
||
MOVE.w D0,blue(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align green in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of green
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of green
|
||
MOVE.w D0,green(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align red in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of red
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of red
|
||
MOVE.w D0,red(SP) ;store out in color spec
|
||
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D0 ;get result in D0
|
||
bra.s Loop ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
; moveq #0,d0 ;d0 is already 0
|
||
move.b red(sp),D0 ;get red
|
||
swap d0
|
||
move.b green(sp),d0 ;get green
|
||
lsl.w #8,d0
|
||
move.b blue(sp),d0 ;get blue
|
||
|
||
Loop
|
||
MOVE.L D0,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S DoOne ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
Search16to16 PROC EXPORT ;<20AUG90 KON>
|
||
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 16 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 32 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
bra loop ;do 2 at a time <20AUG90 KON>
|
||
DoOne
|
||
MOVE.W (A4)+,D5 ;pick up a 16-bit source pixel
|
||
lsl.l #3,d5 ;left align blue in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of blue
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of blue
|
||
MOVE.w D0,blue+4(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align green in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of green
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of green
|
||
MOVE.w D0,green+4(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align red in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of red
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of red
|
||
MOVE.w D0,red+4(SP) ;store out in color spec
|
||
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2+4(SP) ;push pointer to stack colorspec
|
||
PEA 12+4(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6+4(SP),D3 ;get result in D0
|
||
rts ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
;
|
||
; take rgb from stack and convert to 5-5-5
|
||
;
|
||
moveq #0,d0
|
||
move.b red+4(sp),d0 ;get high byte of red 00000000rrrrrrrr
|
||
lsl.w #5,d0 ;xxxrrrrrrrr00000
|
||
move.b green+4(sp),d0 ;get high byte of green xxxrrrrrgggggggg
|
||
lsl.l #5,d0 ;0rr|rrrgggggggg00000
|
||
move.b blue+4(sp),d0 ;0rr|rrrgggggbbbbbbbb
|
||
lsr.l #3,d0 ;0rrrrrgggggbbbbb
|
||
rts
|
||
|
||
Loop
|
||
bsr.s DoOne
|
||
move.w d0,d7
|
||
swap d7
|
||
bsr.s DoOne
|
||
move.w d0,d7
|
||
MOVE.L d7,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S Loop ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
Search32to16 PROC EXPORT
|
||
|
||
;
|
||
; this routine converts a 32-bit direct pixel to a 16 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 16 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
bra.s loop
|
||
|
||
DoOne
|
||
MOVE.L (A4)+,D5 ;pick up a 32-bit source pixel
|
||
MOVE.B D5,blue+4(SP) ;put blue byte in hi byte of blue component
|
||
MOVE.B D5,blue+5(SP) ;put blue byte in lo byte of blue component
|
||
ROR.L #8,D5 ;get green in the lo byte
|
||
MOVE.B D5,green+4(SP) ;put green byte in hi byte of green component
|
||
MOVE.B D5,green+5(SP) ;put green byte in lo byte of green component
|
||
ROR.L #8,D5 ;get red in the lo byte
|
||
MOVE.B D5,red+4(SP) ;put in red channel hi
|
||
MOVE.B D5,red+5(SP) ;put in red channel lo
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2+4(SP) ;push pointer to stack colorspec
|
||
PEA 12+4(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6+4(SP),D0 ;get result in D0
|
||
rts ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
;
|
||
; take rgb from stack and convert to 5-5-5
|
||
;
|
||
moveq #0,d0
|
||
move.b red+4(sp),d0 ;get high byte of red 00000000rrrrrrrr
|
||
lsl.w #5,d0 ;xxxrrrrrrrr00000
|
||
move.b green+4(sp),d0 ;get high byte of green xxxrrrrrgggggggg
|
||
lsl.l #5,d0 ;0rr|rrrgggggggg00000
|
||
move.b blue+4(sp),d0 ;0rr|rrrgggggbbbbbbbb
|
||
lsr.l #3,d0 ;0rrrrrgggggbbbbb
|
||
rts
|
||
|
||
|
||
Loop bsr.s DoOne ;process one input long
|
||
move.w d0,d7 ;get low word
|
||
swap d7
|
||
bsr.s DoOne ;process one input long
|
||
move.w d0,d7 ;get low word
|
||
MOVE.L D7,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S Loop ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
Search32to32 PROC EXPORT ; <20AUG90 KON>
|
||
;
|
||
; this routine draws a 32-bit direct pixel to a 32 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 16 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
Loop
|
||
MOVE.L (A4)+,D5 ;pick up a 32-bit source pixel
|
||
MOVE.B D5,blue(SP) ;put blue byte in hi byte of blue component
|
||
MOVE.B D5,blue+1(SP) ;put blue byte in lo byte of blue component
|
||
lsR.L #8,D5 ;get green in the lo byte
|
||
MOVE.B D5,green(SP) ;put green byte in hi byte of green component
|
||
MOVE.B D5,green+1(SP) ;put green byte in lo byte of green component
|
||
lsR.L #8,D5 ;get red in the lo byte
|
||
MOVE.B D5,red(SP) ;put in red channel
|
||
MOVE.B D5,red+1(SP) ;put in red channel lo
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D0 ;get result in D0
|
||
bra.s writeItOut ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
moveq #0,d0
|
||
move.b red(sp),D0 ;get red
|
||
swap d0
|
||
move.b green(sp),d0 ;get green
|
||
lsl.w #8,d0
|
||
move.b blue(sp),d0 ;get blue
|
||
|
||
writeItOut
|
||
move.l d0,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S Loop ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Dither16toIndexed patched to replicate high 3 bits of each channel of 16 bit color
|
||
; to the low three bits. This prevents error from accumulating "out of nowhere."
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
Dither16toIndexed PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO DST
|
||
MOVE.L D2,D5 ;init redAccum
|
||
MOVE.L D2,D6 ;init grnAccum
|
||
MOVE.L D2,D7 ;init bluAccum
|
||
moveq #0,d3
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d2 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D2 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #6,a4
|
||
MOVE.w -(A0),D0 ;GET NEXT word OF SRC
|
||
bsr.s ditherCore
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,0(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,2(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,4(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
sub.w D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d2
|
||
MOVE.L D1,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s donescl
|
||
|
||
@forward
|
||
MOVE.w (A0)+,D0 ;GET NEXT LONG OF SRC
|
||
bsr.s ditherCore
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
@again
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D2 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
DitherCore
|
||
add.w (a4),D5 ;consume red error from above
|
||
add.w 2(a4),D6 ;consume grn error from above
|
||
add.w 4(a4),D7 ;consume blu error from above
|
||
; moveq #0,d3 ;clear out temp ;cleared on entry
|
||
swap d4 ;save dst pixel size in high word
|
||
|
||
move.b d0,d3 ;get blue as a word
|
||
lsl.b #3,d3 ;left justify 5 bits
|
||
move.b d3,d4
|
||
lsr.b #5,d4 ;right justify high 3 bits
|
||
or.b d4,d3 ;replicate into 8 bits
|
||
add.w d3,d7 ;accumulate blue
|
||
lsr.l #5,d0 ;toss blue
|
||
|
||
move.b d0,d3 ;get green as a word
|
||
lsl.b #3,d3 ;left justify 5 bits
|
||
move.b d3,d4
|
||
lsr.b #5,d4 ;right justify high 3 bits
|
||
or.b d4,d3 ;replicate into 8 bits
|
||
add.w d3,d6 ;accumulate green
|
||
lsr.l #5,d0 ;toss green
|
||
|
||
move.b d0,d3 ;get red as a word
|
||
lsl.b #3,d3 ;left justify 5 bits
|
||
move.b d3,d4
|
||
lsr.b #5,d4 ;right justify high 3 bits
|
||
or.b d4,d3 ;replicate into 8 bits
|
||
add.w d3,d5 ;accumulate red
|
||
|
||
move.w stITabRes(A6),D0 ;get the iTable resolution
|
||
|
||
tst.w d5 ;get desired red
|
||
spl d3 ;get pin value if neg
|
||
cmp.w d3,d5 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d5,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
|
||
moveq #0,d5
|
||
move.b d3,d5
|
||
|
||
lsl.l d0,d3 ;move it up
|
||
|
||
tst.w d6 ;get desired green
|
||
spl d3 ;get pin value if neg
|
||
cmp.w #$ff,d6 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d6,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
|
||
moveq #0,d6
|
||
move.b d3,d6
|
||
|
||
lsl.l d0,d3 ;move it up
|
||
|
||
tst.w d7 ;get desired blue
|
||
spl d3 ;get pin value if neg
|
||
cmp.w #$ff,d7 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d7,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
neg d0
|
||
addq #8,d0
|
||
|
||
moveq #0,d7
|
||
move.b d3,d7
|
||
|
||
lsr.l d0,d3 ;throw out the insignificant bits
|
||
|
||
swap d4 ;get back dst pixel size
|
||
moveq #0,d0 ;clear out high end
|
||
MOVE.L stITabPtr(A6),A3 ;get pointer to the inverse table (past header)
|
||
move.b (a3,d3.L),d0 ;get the index in D0 (hi 3 bytes still clear)
|
||
BFINS D0,D1{D2:D4} ;PUT TO DST LONG
|
||
MOVE.L stCLUTPtr(a6),A3 ;get clut ptr
|
||
lea CTTable+rgb+red(A3,D0.L*8),a5 ;point at red value
|
||
move.l (a5)+,d3 ;get RRRRGGGG <05JUNE92 SAH>
|
||
|
||
lsr.l #8,d3 ;get high byte of green <05JUNE92 SAH>
|
||
move.b d3,d0 ;make it a word (hi 3 bytes d0 clear) <05JUNE92 SAH>
|
||
sub.w d0,d6 ;compute green error <05JUNE92 SAH>
|
||
|
||
swap d3 ;get high byte of red <05JUNE92 SAH>
|
||
sub.w d3,d5 ;compute red error <05JUNE92 SAH>
|
||
|
||
move.b (a5)+,d0 ;get high byte of blue <05JUNE92 SAH>
|
||
sub.w d0,d7 ;compute blue error <05JUNE92 SAH>
|
||
|
||
rts
|
||
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch SetupStretch to add support for 16-bit shrinking.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
SetupStretch PROC EXPORT
|
||
|
||
&CurFile SETC 'STRETCH'
|
||
INCLUDE 'DrawingVars.a'
|
||
;----------------------------------------------------
|
||
;
|
||
; 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
|
||
|
||
|
||
;--------------------------------------------------------------
|
||
;
|
||
; Routine to setup case jump for StretchRow,
|
||
; based on horiz numer and denom.
|
||
;
|
||
; Call SetupStretch with numer in D0, denom in D1.
|
||
; Returns case jump in A0, horizfraction in D0.
|
||
;
|
||
; Call resulting case jump with:
|
||
;
|
||
; A0: srcPtr
|
||
; A1: dstPtr
|
||
; A2: dstLimit
|
||
; D4: horizfraction
|
||
;
|
||
; clobbers D0-D4,A0-A1
|
||
;
|
||
ciDONE EQU $37934
|
||
ciONE EQU $38570
|
||
ciStrching EQU $38460
|
||
ciFound EQU $384E4
|
||
ciFastRatios EQU $384FE
|
||
ciPIXSHRNK EQU $392F8
|
||
ci32Shrink EQU $39270
|
||
|
||
MOVE D3,-(SP) ;SAVE SRC DEPTH
|
||
|
||
leaROM ciDONE,A0 ;POINT TO ABORT
|
||
TST D0 ;IS NUMER <= 0 ?
|
||
BLE.s FOUND ;YES, POINT TO ABORT
|
||
TST D1 ;IS DENOM <= 0 ?
|
||
BLE.s FOUND ;YES, POINT TO ABORT
|
||
leaROM ciONE,A0 ;POINT TO FAST COPY
|
||
CMP D1,D0 ;IS NUMER = DENOM ?
|
||
BEQ.s FOUND ;YES, USE FAST COPY
|
||
BLT.s SHRNKING ;NO, BRANCH IF SHRINKING
|
||
jmpROM ciStrching
|
||
|
||
;
|
||
; We will be shrinking. Calc fract = numer/denom and check for fast.
|
||
;
|
||
SHRNKING
|
||
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
||
MOVE D0,-(SP) ;PUSH NUMER
|
||
MOVE D1,-(SP) ;PUSH DENOM
|
||
_FixRatio ;CALL FIXRATIO, < 1.0
|
||
MOVE.L (SP)+,D0 ;POP RESULT
|
||
|
||
leaROM ciPIXSHRNK,A0 ;ASSUME WE'RE SHRINKING PIXELS
|
||
move.w (SP),d3 ;check source depth
|
||
beq.s ciCheckFast
|
||
cmp.w #4,d3 ;16-bit or greater
|
||
blt.s Found ;No, 8 bits or less. Assumption correct
|
||
beq.s Do16Shrink
|
||
leaROM ci32Shrink,a0
|
||
bra.s Found
|
||
Do16Shrink
|
||
lea averageH16,a0
|
||
Found
|
||
jmpROM ciFound
|
||
|
||
ciCheckFast
|
||
jmpROM ciFastRatios
|
||
|
||
averageH16
|
||
MOVEM.L D5/A5,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE D4,D2 ;GET RATIO IN D2
|
||
MOVE D4,D3 ;COPY RATIO
|
||
LSR #1,D3 ;INIT ERR TO RATIO/2
|
||
MOVEQ #0,D5 ;clear out working register
|
||
bra.s @NXTDST ; enter the loop
|
||
|
||
@1to1 MOVE.w (A0)+,(A1)+ ;copy source to dest
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
bhs @Done ;=>yes, all done
|
||
|
||
@NXTDST moveq #0,d0 ;to extend to long
|
||
add.w D2,D3 ;is mapping 1 to 1?
|
||
bcs.s @1to1 ;if so, just copy the pixel
|
||
|
||
MOVE.w (A0)+,D0 ;GET a PIXEL OF SRC
|
||
move.b d0,d5 ;get blue component
|
||
and.b #$1F,d5
|
||
move.w d5,a5 ;INIT accumulated blu
|
||
|
||
lsr.w #5,d0 ;get green component
|
||
move.b d0,d5 ;INIT accumulated grn
|
||
and.b #$1F,d5
|
||
move.w d5,a4
|
||
|
||
lsr.w #5,d0 ;get red component
|
||
and.b #$1F,d0 ;extend to word
|
||
move.w d0,a3 ;INIT accumulated red
|
||
moveq #1,d4 ;init src pixel count
|
||
|
||
@NXTSRC MOVE.w (A0)+,D0 ;GET A PIXEL OF SRC
|
||
addq.w #1,d4 ;inc cnt of src pixels for this dst
|
||
move.b d0,d5 ;extend to word
|
||
and.b #$1F,d5 ;5-bits of blue
|
||
add.w d5,a5 ;accumulate blue component
|
||
|
||
lsr.w #5,d0 ;toss blue component
|
||
move.b d0,d5
|
||
and.b #$1F,d5
|
||
add.w d5,a4 ;accumulate green component
|
||
|
||
lsr.w #5,d0 ;toss green component
|
||
and.b #$1F,d0 ;extend to word
|
||
add.w d0,a3 ;accumulate red component
|
||
|
||
ADD D2,D3 ;TIME FOR NEXT DST PIXEL?
|
||
BCC.S @NXTSRC ;NO, GET NEXT SRC PIXEL
|
||
|
||
cmp.w #2,d4 ;how many pixels are being averaged?
|
||
; blt.s @noDiv ;Can't Happen ;;only one src pixel so skip divides
|
||
beq.s @doShift ;two src pixels so use shifts
|
||
|
||
@hardWay
|
||
moveq #0,d1 ;clear out dst pixel
|
||
move.l a3,d0 ;get red total
|
||
divu.w d4,d0 ;get red avrg
|
||
move.b d0,d1 ;save result
|
||
|
||
lsl.l #5,d1 ;make room for next component
|
||
move.l a4,d0 ;get grn total
|
||
divu.w d4,d0 ;get grn avrg
|
||
or.b d0,d1 ;save result
|
||
|
||
lsl.l #5,d1 ;make room for next component
|
||
move.l a5,d0 ;get blu total
|
||
divu.w d4,d0 ;get blu avrg
|
||
or.b d0,d1 ;save result
|
||
bra.s @noDiv
|
||
|
||
@doShift
|
||
move.l a3,d1 ;get red total, clear out dst pixel <1.7>
|
||
and.w #$003E,d1 ;only want 5 bits.
|
||
lsl.w #4,d1 ;get red avrg, make room for next component <1.7>
|
||
move.l a4,d0 ;get grn total
|
||
lsr.w #1,d0 ;get grn avrg <1.7>
|
||
or.b d0,d1 ;save result
|
||
lsl.l #5,d1 ;make room for next component <1.7>
|
||
move.l a5,d0 ;get blu total
|
||
lsr.w #1,d0 ;get blu avrg
|
||
or.b d0,d1 ;save result
|
||
|
||
@noDiv
|
||
MOVE.w D1,(A1)+ ;ELSE SAVE CURRENT DST word
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTDST ;=>NO, COPY NEXT SRC TO NEXT DST
|
||
@done MOVEM.L (SP)+,D5/A5 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Complete replacement for Stretch, stScanLoop, BlitCase, and 16 and 32-bit arith blit
|
||
; loops
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
;
|
||
; Output: A3 contains address of current scanline.
|
||
;
|
||
MACRO
|
||
_pmVersion
|
||
add.l a5,a3 ;bump src to next row
|
||
ENDM
|
||
|
||
;
|
||
; The first time bruce is called, D3 contains the starting scan line number
|
||
; On output: A3 contains first scanline address
|
||
;
|
||
MACRO
|
||
_pmVersionSrcFirstTime
|
||
ENDM
|
||
|
||
MACRO
|
||
_pmVersionMaskFirstTime
|
||
ENDM
|
||
|
||
StretchBits PROC EXPORT
|
||
IMPORT Scale32toIndexed, Scale16toIndexed, ScaleIndexedToIndexed, Scale32ToBitMap
|
||
IMPORT Scale32toGray, Scale16toGray, Scale32to16, Scale16ToBitMap
|
||
IMPORT Search32toIndexed, Search16toIndexed, Search32to16, Search16to32
|
||
IMPORT Dither32toIndexed, Dither16toIndexed, Dither32toGray, Dither16toGray
|
||
IMPORT Dither32toBitmap, Dither16toBitmap
|
||
IMPORT scaleBlt
|
||
EXPORT stScanLoop, BlitCase, stMask0, stArith16Tab, stArith32Tab
|
||
EXPORT NOPfgColorTable
|
||
|
||
ciROMTable2 EQU $38846
|
||
ciROMTable4 EQU $38AE8
|
||
ciROMTable8 EQU $38FF4
|
||
|
||
ciScale16to32 EQU $39C80
|
||
SHFTTBL EQU $304B6
|
||
ciCB8to8Clip EQU $3A8E0
|
||
ciCB1to8Clip EQU $3A680
|
||
ciCB8to1Clip EQU $3AC6E
|
||
|
||
;--------------------------------------------------------------
|
||
;
|
||
; 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
|
||
|
||
ciFromDrawLine EQU $29B84
|
||
ciFromFrameRect EQU $2C608
|
||
|
||
;----------------------------------------------------
|
||
|
||
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 <121> <09JUN92 SAH>
|
||
;
|
||
; 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
|
||
cmpRA ciFromDrawLine,4(A6) ;are we coming from drawline?
|
||
BEQ.S @getstream ;yes, then force it through GetStreamMode
|
||
cmpRA ciFromFrameRect,4(A6) ;are we coming from framerect?
|
||
BEQ.S @getstream ;yes, then force it through GetStreamMode
|
||
BTST #3,D1 ;pattern mode?
|
||
BNE.S @0 ;yes, skip because alpha mode already stripped
|
||
@getstream
|
||
_GetStreamMode ;get alpha mode bits
|
||
MOVE.W D1,MODE(A6) ;get new stripped mode
|
||
@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
|
||
;
|
||
LeaROM 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
|
||
|
||
LEAROM 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
|
||
|
||
|
||
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
|
||
skipTable
|
||
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
|
||
;
|
||
; 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)
|
||
bne.s @CheckColorizeNOPDone
|
||
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
|
||
|
||
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, ScaleColorBit, 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
|
||
;
|
||
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
|
||
;
|
||
;<85>
|
||
; Force into rgnblt instead of bitblt if pattern hiliting. Both rgn and bitblt
|
||
; check for a fast, black pattern hiliting case in a stupid way. The problem
|
||
; is fixed in RgnBlt because it's near the top, but not in bitblt because it
|
||
; would mean patching out gobs of stuff. So, this slimey hack forces a call to
|
||
; rgnblt so the fast case is taken instead of the slow case in bitblt.
|
||
; If forcing into rgnblt, the clipRgn and userRgn are not swapped because we DO
|
||
; want TrimRect to get called in SeekMask.
|
||
;
|
||
CMP.W #58,LOCMODE(A6) ;pattern hilite mode? <85>
|
||
BEQ XRGNBLT ;yes, force into rgnblt <85>
|
||
|
||
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 ;is dst 16 bit?
|
||
beq.s @check16bit ;yes
|
||
|
||
;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 Stretch ;if applying color then use stretch
|
||
|
||
tst.w d7 ;invert the src?
|
||
bne Stretch ;if so then use stretch
|
||
st FastCase(a6) ;remember fastCase for Andy
|
||
|
||
cmp.w #4,d4 ;dst < 16 bits/pixel? <05JUNE92 SAH>
|
||
blt.s @chkSrc ; <05JUNE92 SAH>
|
||
cmp.w #3,d3 ;src <16 bits/pixel?
|
||
bgt Stretch
|
||
|
||
@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 <08JUNE92 SAH>
|
||
;
|
||
; 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 <08JUNE92 SAH>
|
||
;
|
||
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 Stretch
|
||
cmp.w #3,d4 ;dst = 8 bits/pixel?
|
||
bne.s Stretch
|
||
bra.s @fast
|
||
|
||
|
||
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
|
||
|
||
move.w XLateFlag(a6), BGnotWhite(a6) ;BitBlt expects BGnotWhite to be setup
|
||
|
||
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
|
||
|
||
clr.w BGnotWhite(a6) ;assume bitblt can go fast
|
||
BTST #ColorizeInModeCaseBit, XLateFlag(a6) ;colorize?
|
||
BNE.S @slow ;no, continue
|
||
|
||
tst.l d7 ;inverting? <KON 6JUN90>
|
||
beq.s @fast ;no, go fast <KON 6JUN90>
|
||
|
||
@slow move.w #1,BGnotWhite(a6) ;tell bitblt to go slow
|
||
@fast _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
|
||
clr.w BGnotWhite(a6) ;assume rgnblt can go fast <98>
|
||
BTST #ColorizeInModeCaseBit, XLateFlag(a6) ;colorize? <98>
|
||
BEQ.S @fast ;no, continue <98>
|
||
move.w #1,BGnotWhite(a6) ;tell rgnblt to go slow <98>
|
||
@fast ; <98>
|
||
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.w d0,d1 ;compare dst(d0) and src(d1) widths
|
||
blt.s @dontClearDither ;if expanding, don't dither <27FEB90 KON>
|
||
cmp.l d0,d1 ;compare dst(d0) and src(d1) heights
|
||
blt.s @dontClearDither ;if expanding, don't dither <27FEB90 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
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; 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
|
||
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!
|
||
;
|
||
; if destination device is direct, and dst pixmap 1-bit bcolor = FFFFFFFF and
|
||
; fcolor = 0 is NOP
|
||
; else, bcolor = 0, fcolor = $FFFFFFFF is NOP
|
||
;
|
||
tst 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.l #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.l #1,d1 ; <KON 6MAR91>
|
||
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
|
||
|
||
ALIGN Alignment
|
||
;
|
||
; loops that do colorizing, ptch versions destroy a3
|
||
;
|
||
ColorExTblPtr
|
||
DC.L ONEColor-ColorExTblPtr ;Need 1-bit colorizing <10Sept90 KON>
|
||
DC.L DOUBLEColor-ColorExTblPtr
|
||
DC.L QUADColor-ColorExTblPtr
|
||
DC.L EIGHTColor-ColorExTblPtr
|
||
DC.L SIXTEENColor-ColorExTblPtr
|
||
DC.L THRTWOColor-ColorExTblPtr
|
||
|
||
;
|
||
; One bit to N-bit colorizing loops
|
||
;
|
||
ALIGN Alignment
|
||
|
||
OneColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
|
||
MOVE.L A2,D1 ; D3->last address we write to
|
||
SUB.L A1,D1 ; D3 = number of bytes to write
|
||
LSR #2,D1 ; divided in 4 to write longs
|
||
SUBQ #1,D1 ; less one for DBRA
|
||
@a MOVE.l (A0)+,D2 ; fetch long
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.l d2,(A1)+ ; send it out
|
||
DBRA D1,@a
|
||
RTS
|
||
|
||
ALIGN Alignment
|
||
|
||
DoubleColor
|
||
leaROM ciROMTable2,a3 ;get address of doubling table <30JUL90 KON>
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
|
||
CLR D0 ; incoming bytes'll go here
|
||
MOVE.L A2,D1 ; D3->last address we write to
|
||
SUB.L A1,D1 ; D3 = number of bytes to write
|
||
LSR #1,D1 ; divided in half, because we write words
|
||
SUBQ #1,D1 ; less one for DBRA
|
||
@a MOVE.B (A0)+,D0 ; fetch a byte
|
||
MOVE 0(a3,D0*2),d2 ;convert to 2-bit <30JUL90 KON>
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.w d2,(A1)+ ; send its double out
|
||
DBRA D1,@a
|
||
RTS
|
||
|
||
ALIGN Alignment
|
||
;
|
||
; One bit to 4-bit colorizing
|
||
;
|
||
QUADColor
|
||
leaROM ciROMTable4,a3 ;get address of quad table <30JUL90 KON>
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
|
||
SUB.L A1,A2 ;Get byte count
|
||
MOVE.L A2,D1 ;
|
||
LSR.L #2,D1 ;Get count of longs
|
||
SUBQ #1,D1 ;less one for the dbra
|
||
@4 MOVE.B (A0)+,D0 ;GET A BYTE FROM SRC
|
||
MOVE.L 0(a3,D0*4),D2 ;convert to 4 bits/pixel <30JUL90 KON>
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.l d2,(A1)+ ;AND SPIT OUT A LONG
|
||
DBRA D1,@4 ;IS DSTPTR >= DSTLIMIT ?
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP BY EIGHT USING TABLE LOOKUP, then colorize
|
||
;
|
||
|
||
EIGHTColor
|
||
leaROM ciROMTable8,a3 ;get address of eight table <30JUL90 KON>
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
EightLoop
|
||
MOVE.B (A0)+,D0 ;GET A BYTE OF SRC
|
||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||
AND #$F0,D1 ;MASK FOR HI NIBBLE
|
||
LSR #2,D1 ;SHIFT FOR TABLE INDEX
|
||
MOVE.L (a3,D1),d2 ;get four pixels
|
||
AND #$0F,D0 ;MASK FOR LO NIBBLE
|
||
MOVE.L (a3,D0*4),D0 ;get second set of four pixels <30JUL90 KON>
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.l d2,(A1)+ ;PUT FIRST LONG TO DST
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D0,D5 ;copy of source
|
||
NOT.L D0 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D0 ;color foreground bits same as foreground color
|
||
OR.L D5,D0 ;combine colored foreground and background bits
|
||
|
||
move.l D0,(A1)+ ;PUT SECOND LONG TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO.s EightLoop ;NO, GO FOR MORE
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; SCALE UP BY 16 (thanks to Gary Davidian)
|
||
; with colorizing
|
||
;
|
||
BWtoD15Alpha
|
||
MOVE.L alphaFore(A6),D3
|
||
MOVE.L alphaBack(A6),D4
|
||
BRA.S XXSIXTEEN
|
||
SIXTEENColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
XXSIXTEEN
|
||
@SIXTEEN
|
||
MOVEQ #15,D2 ;16 output longs
|
||
MOVE.L (A0)+,D0 ;fetch a long of src
|
||
@NxtBit ADD.L D0,D0 ;extend first bit into hi word
|
||
SUBX.L D1,D1
|
||
ADD.L D0,D0 ;extend next bit into lo word
|
||
SUBX.W D1,D1
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D1,D5 ;copy of source
|
||
NOT.L D1 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D1 ;color foreground bits same as foreground color
|
||
OR.L D5,D1 ;combine colored foreground and background bits
|
||
|
||
MOVE.L D1,(A1)+
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
DBHS D2,@NxtBit ;process remaining bits
|
||
BLO @SIXTEEN ;fetch next input long
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP BY 32 (thanks to gary)
|
||
;
|
||
BWtoD24Alpha
|
||
MOVE.L alphaFore(A6),D3
|
||
MOVE.L alphaBack(A6),D4
|
||
BRA.S XXTHRTWO
|
||
THRTWOColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
XXTHRTWO
|
||
@THRTWO
|
||
MOVEQ #31,D2 ;32 output longs
|
||
MOVE.L (A0)+,D0 ;fetch a long of src
|
||
@NxtBit ADD.L D0,D0 ;extend high bit into long
|
||
SUBX.L D1,D1
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D1,D5 ;copy of source
|
||
NOT.L D1 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D1 ;color foreground bits same as foreground color
|
||
OR.L D5,D1 ;combine colored foreground and background bits
|
||
|
||
MOVE.L D1,(A1)+
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
DBHS D2,@NxtBit ;process remaining bits
|
||
BLO @THRTWO ;fetch next input long
|
||
RTS ;ALL DONE
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; 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?
|
||
BLT.S @2 ;no, take normal path
|
||
MOVE.W locMode(A6),D0 ;get transfer mode
|
||
BTST #5,D0 ;arithmetic?
|
||
BNE.S @2 ;yes, take normal path
|
||
AND.W #3,D0 ;is the mode copy?
|
||
BEQ.S @2 ;yes, take normal path (because colors swapped)
|
||
MOVE.L alphaMask(A6),D1 ;get the alpha mask
|
||
TST.L INVERTFLAG(A6) ;are we inverting?
|
||
BEQ.S @1 ;no, leave invertflag alone
|
||
MOVE.L D1,INVERTFLAG(A6) ;yes, change invertflag to alphamask
|
||
@1: CLR.L alphaFore(A6) ;foreground is zeroes
|
||
MOVE.L D1,alphaBack(A6) ;background is alphamask
|
||
LEA @patchTable,A0
|
||
ADD.L -16(A0,D4*4),A0
|
||
BRA.S @gotScale ;jump to common code
|
||
@patchTable
|
||
DC.L BWtoD15Alpha-@patchTable
|
||
DC.L BWtoD24Alpha-@patchTable
|
||
@2: ;take normal path
|
||
;
|
||
;take special loops if colorizing
|
||
;
|
||
btst #ScaleColorBit,XLateFlag+1(a6) ;colorize in expansion?
|
||
beq.s @nocolorize ;no, colorize in blit loop
|
||
@colorize
|
||
|
||
lea ColorExTblPtr,a0
|
||
add.l (a0,d4*4),a0 ;colorize in expansion
|
||
;
|
||
; if swapfgbgBit is set, we need to swap fg/bg color again
|
||
;
|
||
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
|
||
|
||
@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
|
||
;
|
||
|
||
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.s @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
|
||
|
||
@CB1to8Clip jmpROM ciCB1to8Clip ;3A680
|
||
@CB8to8Clip jmpROM ciCB8to8Clip ;3A8E0
|
||
@CB8to1Clip jmpROM ciCB8to1Clip ;3AC6E
|
||
|
||
@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.s @CB8to1Clip ;if not, skip
|
||
|
||
@goSlow
|
||
;-----------------------------------------------------
|
||
;
|
||
; 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 ;<131>
|
||
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 ; <124> Old code for now
|
||
move maskDenom+v(a6),d2 ; <124>
|
||
endif ; <124>
|
||
if TheFuture then ; <124> New code for later
|
||
move maskNumer+v(a6),d2 ;<123>
|
||
endif ; <124>
|
||
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 srcpix+pmTable(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)
|
||
SrcMergeCaseReturn
|
||
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
|
||
|
||
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 jsr (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 <121> <09JUN92 SAH>
|
||
move.l oldHiHeapMark(a6),HiHeapMark ;restore extent of stack
|
||
@noTemp MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
||
UNLINK PARAMSIZE,'STRETCHB'
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
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 <09JUN92 SAH>
|
||
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.
|
||
|
||
CombineTable
|
||
;SRC DST MASK ENTRY
|
||
dc.l Combine32in32-CombineTable ;32 ind 32 0
|
||
dc.l Combine321632-CombineTable ;32 16 32 1
|
||
dc.l Combine323232-CombineTable ;32 32 32 2
|
||
|
||
|
||
;*******************************************************************
|
||
;
|
||
; CombineMaskCase
|
||
;
|
||
; Loop to combine d7 pixels of source and dest using mask
|
||
;
|
||
;ENTRY:
|
||
; D0: (dst) A0: address of routine called
|
||
; D1: (src) A1: mask ptr
|
||
; D2: (dst component) A2: destination
|
||
; D3: (mask) A3: src and dst ptr
|
||
; D4: (build pixel) A4: src pmtable A5: rowbytes
|
||
; D5: srcAlign A5:
|
||
; 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.
|
||
;
|
||
;EXIT:
|
||
;
|
||
;
|
||
;*******************************************************************
|
||
;
|
||
; handle merging with indexed destinations, assume source and mask are 32 bpp
|
||
;
|
||
; Promote destination pixel to 32-bits/pixel, combine with source on a
|
||
; component by component basis according to value stored in mask
|
||
;
|
||
Combine32in32
|
||
bfextu (a2){d5:d6},d0 ;get a pixel of destination
|
||
add d6,d5 ;bump to next pixel
|
||
moveq #0,d4
|
||
move.w d4,d1 ;clear regs
|
||
move.w d4,d2
|
||
move.w d4,d3
|
||
move.b 1(a3),d2 ;get red of source
|
||
move.b ctTable+rgb+red(a4,d0.w*8),d1 ;get destination red into virgin reg
|
||
|
||
sub.w d2,d1 ;red dst - red source
|
||
move.b 1(a1),d3 ;get red mask
|
||
bpl.s @1
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@1
|
||
muls.w d3,d1
|
||
lsl.w #8,d2 ;src*256
|
||
add.w d2,d1 ;(dst-src)*mask+(src*256)
|
||
move.w d1,d4 ;new red component (0000RRXX)
|
||
;
|
||
; now do green
|
||
;
|
||
move.w #0,d1 ;clear regs
|
||
move.w d1,d2
|
||
move.w d1,d3
|
||
move.b 2(a3),d2 ;get green of source
|
||
move.b ctTable+rgb+green(a4,d0.w*8),d1 ;get destination green into virgin reg
|
||
|
||
sub.w d2,d1 ;green dst - green src
|
||
move.b 2(a1),d3 ;get green mask
|
||
bpl.s @2
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@2
|
||
muls.w d3,d1 ;(dst-src)*mask
|
||
lsl.w #8,d2 ;src*256
|
||
add.w d2,d1 ;(dst-src)*mask+(src*256)
|
||
lsr.w #8,d1
|
||
move.b d1,d4 ;move in green component (0000RRGG)
|
||
;
|
||
; now do blue
|
||
;
|
||
move.w #0,d1 ;clear regs
|
||
move.w d1,d2
|
||
move.w d1,d3
|
||
move.b 3(a3),d2 ;get blue of source
|
||
move.b ctTable+rgb+blue(a4,d0.w*8),d1 ;get destination green into virgin reg
|
||
|
||
sub.w d2,d1 ;blue dst - blue src
|
||
move.b 3(a1),d3 ;get green mask
|
||
bpl.s @3
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@3
|
||
muls.w d3,d1 ;(dst-src)*mask
|
||
lsl.w #8,d2 ;src*256
|
||
add.w d2,d1 ;(dst-src)*mask+(src*256)
|
||
lsr.w #8,d1
|
||
lsl.l #8,d4 ;result = 00RRGG00
|
||
move.b d1,d4 ;move in blue component (00RRGGBB)
|
||
MOVE.L d4,(A3)+ ;PUT A LONG TO SRCBUF
|
||
addq #4,a1 ;bump to next mask
|
||
DBRA D7,Combine32in32 ;LOOP FOR ALL LONGS
|
||
rts
|
||
|
||
;
|
||
; Handle when src and mask are 32 bpp, dst is 16 bpp
|
||
;
|
||
Combine321632
|
||
move.l maskBC,a0 ;get useful Konstantin
|
||
Combine321632Loop
|
||
move.l (a1)+,d5 ;get a pixel of mask
|
||
bne.s @maskNonZero
|
||
addq.l #4,a3 ;mask 0 -> all src so just skip
|
||
addq.l #2,a2 ;bump destination
|
||
dbra D7,Combine321632Loop ;LOOP FOR ALL LONGS
|
||
rts
|
||
@maskNonZero
|
||
move.w (a2)+,d4 ;get a pixel of destination
|
||
cmp.l d5,a0 ;mask $7FFF?
|
||
beq @Writeout555 ;all dst, so write out d4
|
||
|
||
@DoSlowCase
|
||
move.w d4,d0 ;copy destination pixel
|
||
move.l (a3),d6 ;get a pixel of source
|
||
|
||
moveq #0,d4
|
||
|
||
move.w d4,d1 ;clear regs
|
||
move.w d4,d3
|
||
move.w d4,d2
|
||
|
||
swap d6
|
||
move.b d6,d2 ;get red of source
|
||
swap d6
|
||
|
||
move.w d0,d4 ;red destination in 14 - 10
|
||
lsr.w #7,d4 ;move red to bits 7 - 3
|
||
and.w #$00f8,d4 ;strip bits 2 - 0
|
||
move.b d4,d3
|
||
lsr.b #5,d3 ;replicate top 3 bits
|
||
or.b d3,d4 ;merge top five bits with top 3 bits
|
||
|
||
sub.w d2,d4 ;red dst - red src
|
||
swap d5
|
||
move.b d5,d3 ;get red mask
|
||
bpl.s @1
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@1
|
||
swap d5
|
||
muls.w d3,d4 ;d2=(dst-src)*mask
|
||
asr.l #8,d4 ;(dst-src)*mask/256
|
||
add.l d2,d4 ;(dst-src)*mask/256+(src)
|
||
swap d4 ;new red component (00RR0000)
|
||
;
|
||
; now do green
|
||
;
|
||
move.w d6,d1 ;get green of source
|
||
lsr.w #8,d1 ;get green in low byte
|
||
|
||
move.w d0,d2 ;green destination in 9 - 5
|
||
lsr.w #2,d2 ;green in bits 7 - 3
|
||
and.w #$00f8,d2 ;strip bits 2 - 0
|
||
move.b d2,d3
|
||
lsr.b #5,d3 ;replicate top 3 bits
|
||
or.b d3,d2 ;merge top five bits with top 3 bits
|
||
|
||
sub.w d1,d2 ;green dst - green src
|
||
move.w d5,d3 ;get green mask
|
||
lsr.w #8,d3
|
||
tst.b d3
|
||
bpl.s @2
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@2
|
||
muls.w d3,d2 ;d2 = (dst-src)*mask
|
||
lsl.w #8,d1 ;src*256
|
||
add.w d1,d2 ;(dst-src)*mask+(src*256)
|
||
move.w d2,d4 ;move in green component (00RRGGxx)
|
||
;
|
||
; now do blue
|
||
;
|
||
move.w #0,d1 ;clear regs
|
||
move.w d1,d3
|
||
move.b d6,d1 ;get blue of source
|
||
|
||
move.b d0,d2 ;blue destination in 4 - 0
|
||
lsl.w #3,d2 ;green in bits 7 - 3
|
||
and.w #$00f8,d2 ;strip bits 2 - 0
|
||
move.b d2,d3
|
||
lsr.b #5,d3 ;replicate top 3 bits
|
||
or.b d3,d2 ;merge top five bits with top 3 bits
|
||
sub.w d1,d2 ;blue dst - blue src
|
||
|
||
move.b d5,d3 ;get green mask
|
||
bpl.s @3
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@3
|
||
muls.w d3,d2 ;(dst-src)*mask
|
||
lsl.w #8,d1 ;src*256
|
||
add.w d1,d2 ;(src-dst)*mask+(dst*256)
|
||
lsr.w #8,d2
|
||
move.b d2,d4 ;move in blue component (00RRGGBB)
|
||
@writeoutPixel
|
||
move.l d4,(a3)+ ;PUT A LONG TO SRCBUF
|
||
dbra D7,Combine321632Loop ;LOOP FOR ALL LONGS
|
||
rts
|
||
@Writeout555
|
||
;
|
||
; d4 has pixel to write out in 555: convert to 888 and write it out
|
||
;
|
||
moveq #0,d0
|
||
move.w d4,d0 ;red in 14-10
|
||
and.w #$7c00,d0
|
||
swap d0 ;red in 31-24
|
||
lsr.l #7,d0 ;red in 23-16
|
||
move.w d4,d0 ;green in 9-5
|
||
and.w #$03e0,d0
|
||
lsl.w #6,d0 ;green in 15-8
|
||
move.b d4,d0 ;blue in 4-0
|
||
and.b #$1f,d0
|
||
lsl.b #3,d0 ;blue in 7-0, green in 15-8, red in 23-16
|
||
move.l d0,d4
|
||
bra.s @writeoutPixel
|
||
|
||
;
|
||
; Handle when src, mask, dst all 32 bpp
|
||
;
|
||
Combine323232
|
||
move.l maskBC,a0 ;get useful Konstantin
|
||
Combine323232Loop
|
||
move.l (a1)+,d5 ;get a pixel of mask
|
||
bne.s @maskNonZero ;no, go the hard way
|
||
addq.l #4,a3 ;yes, all src so just skip
|
||
addq.l #4,a2 ;bump dst
|
||
dbra D7,Combine323232Loop ;LOOP FOR ALL LONGS
|
||
rts
|
||
@maskNonZero
|
||
move.l (a2)+,d4 ;get a pixel of destination
|
||
cmp.l d5,a0 ;mask $00FFFFFF?
|
||
beq.s @WriteoutPixel ;all dst, so write out d4
|
||
|
||
@DoSlowCase
|
||
move.l d4,d0 ;copy destination pixel
|
||
move.l (a3),d6 ;get a pixel of source
|
||
|
||
moveq #0,d4
|
||
|
||
move.w d4,d1 ;clear regs
|
||
move.w d4,d2
|
||
move.w d4,d3
|
||
|
||
swap d6
|
||
move.b d6,d2 ;get red of source
|
||
swap d0
|
||
swap d6
|
||
move.b d0,d4 ;get a pixel of destination
|
||
swap d0
|
||
sub.w d2,d4 ;red dst - red src
|
||
swap d5
|
||
move.b d5,d3 ;get red mask
|
||
bpl.s @1
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@1
|
||
swap d5
|
||
muls.w d3,d4
|
||
asr.l #8,d4 ;(dst-src)*mask/256
|
||
add.l d2,d4 ;(dst-src)*mask/256+(src)
|
||
swap d4 ;new red component (00RR0000)
|
||
;
|
||
; now do green
|
||
;
|
||
move.w d6,d1 ;get green of source
|
||
move.w d0,d2 ;get a pixel of destination
|
||
lsr.w #8,d1 ;get green in low byte
|
||
lsr.w #8,d2 ;get green in low byte
|
||
|
||
sub.w d1,d2 ;green dst - green src
|
||
move.w d5,d3 ;get green mask
|
||
lsr.w #8,d3
|
||
tst.b d3
|
||
bpl.s @2
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@2
|
||
muls.w d3,d2 ;(dst-src)*mask
|
||
lsl.w #8,d1 ;src*256
|
||
add.w d1,d2 ;(dst-src)*mask+(src*256)
|
||
move.w d2,d4 ;move in green component (00RRGGxx)
|
||
;
|
||
; now do blue
|
||
;
|
||
move.w #0,d1 ;clear regs
|
||
move.w d1,d2
|
||
move.w d1,d3
|
||
move.b d6,d1 ;get blue of source
|
||
move.b d0,d2 ;get blue of destination
|
||
sub.w d1,d2 ;blue dst - blue src
|
||
|
||
move.b d5,d3 ;get green mask
|
||
bpl.s @3
|
||
addq #1,d3 ;make mask go from 0 to 256
|
||
@3
|
||
muls.w d3,d2 ;(dst-src)*mask
|
||
lsl.w #8,d1 ;src*256
|
||
add.w d1,d2 ;(src-dst)*mask+(dst*256)
|
||
lsr.w #8,d2
|
||
move.b d2,d4 ;move in blue component (00RRGGBB)
|
||
@writeoutPixel
|
||
move.l d4,(a3)+ ;PUT A LONG TO SRCBUF
|
||
dbra D7,Combine323232Loop ;LOOP FOR ALL LONGS
|
||
rts
|
||
|
||
;*********************************************************************
|
||
;
|
||
; Loop to expand and merge D7 scanlines of indexed pixels
|
||
;
|
||
;ENTRY:
|
||
; D0: scratch A0: scratch ptr
|
||
; D1: scratch A1: scratch ptr
|
||
; D2: scratch A2: destination
|
||
; D3: scratch A3: source
|
||
; D4: src longs A4: src pmtable
|
||
; D5: srcAlign A5: rowbytes
|
||
; D6: realDepth (pixel size)
|
||
; D7: Scanline Count (zero based)
|
||
;
|
||
;EXIT:
|
||
;
|
||
; a3: new srcaddr
|
||
;
|
||
;GLOBALS: AvgBufPtr(a6), AvgBufSize(a6)
|
||
;
|
||
;*********************************************************************
|
||
|
||
NDEEP
|
||
|
||
; LOOP FOR ALL LONGS IN SRC SCANLINE
|
||
|
||
move.l a3,a0 ;point to source
|
||
move.l a2,a1 ;point to destination
|
||
move d4,d1 ;get count of longs
|
||
|
||
@Align bfextu (a0){d5:0},d0 ;get an aligned long of source
|
||
add #4,a0 ;bump to next long
|
||
move.l d0,(a1)+ ;put a long to destination
|
||
dbra d1,@Align ;loop for all longs
|
||
|
||
; add.l a5,a3 ;bump source to next row
|
||
_pmVersion
|
||
subq #1,d7
|
||
bpl.s @1
|
||
rts
|
||
|
||
; do verticle merging
|
||
@1
|
||
move d6,d3 ;get pixel depth
|
||
move.w d4,a4 ;save count of longs
|
||
NdeepMerge
|
||
|
||
move.l d7,-(sp) ;save count of lines to do
|
||
move.l a3,a0 ;point to source
|
||
move.l a2,a1 ;point to destination
|
||
move a4,d6 ;get long count
|
||
moveq #0,d4 ;start at beginning of long
|
||
|
||
ndlong bfextu (a0){d5:0},d0 ;extract a long from source
|
||
move.l (a1),d1 ;get next long from destination
|
||
|
||
ndpxl bfextu d0{d4:d3},d2 ;get pixel from source
|
||
bfextu d1{d4:d3},d7 ;get pixel from destination
|
||
cmp.l d7,d2 ;which is greater?
|
||
ble.s nochng ;only change if source is greater
|
||
bfins d2,d1{d4:d3} ;replace pixel is destination
|
||
NOCHNG add d3,d4 ;bump to next pixel within long
|
||
and #$1f,d4 ;done with long?
|
||
bne.s ndpxl ;no, keep looping
|
||
|
||
add #4,a0 ;bump src offset
|
||
move.l d1,(a1)+ ;write to destination
|
||
dbra d6,ndlong ;repeat for all longs
|
||
|
||
; add.l a5,a3 ;add rowbytes to src pointer
|
||
move.l (sp)+,d7 ;retrieve line count
|
||
_pmVersion
|
||
dbra d7,NdeepMerge ;loop while there are lines left
|
||
rts
|
||
|
||
;*********************************************************************
|
||
|
||
ALIGN Alignment
|
||
|
||
;*********************************************************************
|
||
;
|
||
; Loop to expand and merge D7 scanlines (0-based) to direct destination
|
||
;
|
||
; Src sizes (d6) of 1-8 are promoted to 32-bit/pixel.
|
||
; Src size (d6) of 16 are carried across to 16-bit destinations.
|
||
;
|
||
;ENTRY:
|
||
; D0: scratch A0: scratch ptr
|
||
; D1: scratch A1: scratch ptr
|
||
; D2: scratch A2: destination
|
||
; D3: scratch A3: source
|
||
; D4: src longs A4: src pmtable A5: rowbytes
|
||
; D5: srcAlign A5: rowbytes
|
||
; D6: realDepth (pixel size)
|
||
; D7: Scanline Count (zero based)
|
||
;
|
||
;EXIT:
|
||
;
|
||
; a3: new srcaddr
|
||
;
|
||
;GLOBALS: AvgBufPtr(a6), AvgBufSize(a6)
|
||
;
|
||
|
||
Average16and32
|
||
|
||
; First check if only one scanline to be merged;
|
||
; If so just copy from srcAddr to SrcBuf, expanding if nec.
|
||
; else fill average buffer, calc average and move to srcbuf
|
||
|
||
tst.w d7 ;doing more than 1 scanline?
|
||
bne @Average ;yes, average scan lines
|
||
|
||
;-------------------------------------------------------------------------
|
||
;
|
||
; Just copy srcAddr to SrcBuf, expanding pixels if necessary
|
||
;
|
||
move.l d4,d1 ;get srclongs
|
||
move.l a3,a0
|
||
|
||
;
|
||
; If dithering or averaging an indexed src then expand it to 32 bit/pixel RGB data.
|
||
;
|
||
cmp.w #16,d6 ;is srcpix indexed?
|
||
bgt.s @Align ;32-bit => just copy
|
||
beq.s @Align0 ;16-bit => just copy
|
||
;
|
||
; if there is no color table, ramp each entry between the foreground and background color.
|
||
;
|
||
tst.l a4 ;color table?
|
||
beq.s @NoCTab
|
||
|
||
@Xpand BFEXTU (A0){D5:D6},D0 ;get a pixel of src
|
||
add d6,d5 ;bump to next pixel
|
||
move.l ctTable+rgb+red(a4,d0.w*8),d2 ;get RRRRGGGG in d2
|
||
lsr.l #8,d2 ;get 00RRRRGG
|
||
lsl.w #8,d2 ;get 00RRGG00
|
||
move.b ctTable+rgb+blue(a4,d0.w*8),d2 ;get 00RRGGBB in d2
|
||
MOVE.L d2,(A2)+ ;put a long to destination
|
||
DBRA D1,@Xpand ;loop for all longs
|
||
bra @SrcBufFull
|
||
|
||
@NoCTab BFEXTU (A0){D5:D6},D0 ;get a pixel of src
|
||
add d6,d5 ;bump to next pixel
|
||
|
||
;
|
||
; replicate pixel first to 8 bits and then to 24
|
||
;
|
||
move.w d0,d3
|
||
MOVEQ #8,D2 ;replicate to byte size
|
||
@NXTPXL SUB D6,D2 ;SAY WE'VE DONE A PIXEL
|
||
BLE.S @RepDone ;=>IT WAS THE LAST ONE
|
||
LSL.w D6,D0 ;replicate
|
||
OR.w D3,D0 ;INSTALL FG PIXEL
|
||
BRA.S @NXTPXL ;=>DO ENTIRE LONG
|
||
; d0 has xxxxxxBB
|
||
@RepDone
|
||
not.b d0 ;invert it since 00 = black in RGB and white in index
|
||
moveq #0,d2 ;clear high 8 bits
|
||
move.b d0,d2
|
||
swap d2
|
||
move.b d0,d2
|
||
lsl.w #8,d2
|
||
move.b d0,d2
|
||
MOVE.L d2,(A2)+ ;put a long to destination
|
||
DBRA D1,@NoCTab ;loop for all longs
|
||
bra.s @SrcBufFull
|
||
|
||
|
||
@Align0
|
||
;
|
||
; promote 16-bit src/mask to 32 bit if deep mask
|
||
;
|
||
tst d5 ;alignment
|
||
beq.s @Align
|
||
addq #2,a0 ;do alignment of 16 bit
|
||
@Align
|
||
tst.w maskshift(a6) ;promote 16 if deep mask
|
||
beq.s @CopyLoop ;
|
||
cmp.w #16,d6 ;16 bit?
|
||
bne.s @CopyLoop
|
||
;
|
||
; Promote 16 bit to 32 bit using existing Scale16to32 routine
|
||
;
|
||
; a0 ptr to src
|
||
; a1 ptr to beginning of dst
|
||
; a2 ptr to end of dst
|
||
;
|
||
move.l a2,a1 ;get beginning of dst
|
||
addq #1,d4 ;make destination 1-based
|
||
lsl.l #2,d4 ;calc size of dst: longs->bytes *4 <7JULY90 KON>
|
||
add.l d4,a2 ;calc end of dst ptr
|
||
; add.l a5,a3 ;bump source to next row
|
||
_pmVersion
|
||
jmpROM ciScale16to32 ;inherits return address
|
||
@CopyLoop
|
||
move.l (a0)+,(a2)+ ;copy source to destination
|
||
dbra D1,@CopyLoop ;loop for all longs
|
||
|
||
@SrcBufFull
|
||
; add.l a5,a3 ;bump source to next row
|
||
_pmVersion
|
||
rts
|
||
|
||
;------------------------------------------------------------------------
|
||
|
||
|
||
@Average
|
||
;
|
||
; average 16 or 32 bit source
|
||
;
|
||
useAverageBuf
|
||
moveq #0,d1 ;get a useful constant
|
||
|
||
; Init R-G-B accumulation buffer to zero
|
||
|
||
move.w ABufSize(a6),d0 ;get count of longs in buffer
|
||
move.l AvrgBuf(a6),a0 ;point at buffer
|
||
@1 move.l d1,(a0)+ ;clear it out
|
||
dbra d0,@1
|
||
|
||
;
|
||
; Are we averaging 16-bit or 32-bit data?
|
||
;
|
||
move.w d7,-(sp) ;save scanline count
|
||
cmp #16,d6 ;16-bit data?
|
||
beq NextAverageV16 ;YES: do 16-bit average loop
|
||
|
||
; Top of 32-bit scanline averaging loop
|
||
|
||
NextAverageV32
|
||
|
||
; loop for all longs in source scanline
|
||
|
||
move.l d5,d2 ;GET SHIFT FOR SRC ALIGNMENT
|
||
move.l a3,a0 ;point to source buffer
|
||
move.l AvrgBuf(A6),A1 ;point to accumulation buffer
|
||
move d4,d3 ;get count of source
|
||
|
||
;-------------------------------------------------------------------------
|
||
;
|
||
; If dithering or averaging an indexed src then first pre-Expand it
|
||
; to 32 bit/pixel RGB data.
|
||
;
|
||
cmp.w #32,d6 ;promoting src to RGB?
|
||
beq @NDLONG0 ;no, all ok
|
||
;
|
||
; if no color table, use grey scale
|
||
;
|
||
tst.l a4 ;color table?
|
||
beq.s @NoCTab
|
||
|
||
@Xpand BFEXTU (a0){D2:D6},D0 ;get a pixel of src
|
||
add d6,d2 ;bump to next pixel
|
||
move.l ctTable+rgb+red(a4,d0.w*8),d1 ;get RRrrGGgg
|
||
swap d1 ;get GGggRRrr
|
||
lsr.w #8,d1 ;get GGgg00RR
|
||
add.w d1,(a1)+ ;accumulate red value
|
||
swap d1 ;get 00RRGGgg
|
||
lsr.w #8,d1 ;get 00RR00GG
|
||
add.w d1,(a1)+ ;accumulate green value
|
||
move.b ctTable+rgb+blue(a4,d0.w*8),d1 ;get 00RR00BB
|
||
add.w d1,(a1)+ ;accumulate blue value
|
||
dbra d3,@Xpand ;LOOP FOR ALL LONGS
|
||
; add.l a5,a3 ;bump to next source row
|
||
_pmVersion
|
||
dbra d7, NextAverageV32 ;accumulate d7 scanlines
|
||
bra MakeAverage
|
||
|
||
|
||
@NoCTab BFEXTU (A0){D5:D6},D0 ;get a pixel of src
|
||
add d6,d5 ;bump to next pixel
|
||
|
||
;
|
||
; replicate pixel first to 8 bits and then to 24
|
||
;
|
||
move.w d0,d1
|
||
MOVEQ #8,D2 ;replicate to byte size
|
||
@NXTPXL SUB D6,D2 ;SAY WE'VE DONE A PIXEL
|
||
BLE.S @RepDone ;=>IT WAS THE LAST ONE
|
||
LSL.w D6,D0 ;replicate
|
||
OR.w D1,D0 ;INSTALL FG PIXEL
|
||
BRA.S @NXTPXL ;=>DO ENTIRE LONG
|
||
; d0 has xxxxxxBB
|
||
@RepDone
|
||
not.b d0 ;invert it since 00 = black in RGB and white in index
|
||
and.w #$00FF,d0
|
||
add.w d0,(a1)+ ;accumulate red value
|
||
add.w d0,(a1)+ ;accumulate green value
|
||
add.w d0,(a1)+ ;accumulate blue value
|
||
dbra d3,@NoCTab ;LOOP FOR ALL LONGS
|
||
; add.l a5,a3 ;bump to next source row
|
||
_pmVersion
|
||
dbra d7, NextAverageV32 ;accumulate d7 scanlines
|
||
bra.s MakeAverage
|
||
|
||
;------------------------------------------------------------------------
|
||
;
|
||
;
|
||
;
|
||
@NDLONG0
|
||
moveq #0,d1
|
||
moveq #0,d2 ;use for extending to word data
|
||
moveq #0,d5
|
||
|
||
@NDLONG move.l (a0)+,D0 ;EXTRACT A LONG FROM SRC
|
||
move.b d0,d1 ;pick up blue component as a word
|
||
|
||
lsr.l #8,d0 ;toss blue
|
||
move.b d0,d2 ;pick up green component as a word
|
||
|
||
lsr.l #8,d0 ;toss green
|
||
move.b d0,d5 ;pick up red component as a word
|
||
add.w d5,(a1)+ ;accumulate blue value
|
||
add.w d2,(a1)+ ;accumulate green value
|
||
add.w d1,(a1)+ ;accumulate red value
|
||
DBRA d3,@NDLONG ;=>REPEAT FOR ALL LONGS
|
||
; add.l a5,a3 ;bump to next source row
|
||
_pmVersion
|
||
dbra d7, NextAverageV32 ;accumulate d7 scanlines
|
||
|
||
MakeAverage
|
||
move.w (sp)+,d7 ;restore scanline count (0-based)
|
||
addq #1,d7 ;make it 1 based
|
||
|
||
; Now we must compute the average of the accumulated R-G-B's
|
||
|
||
move.l a2,a1 ;pointer to destination buffer
|
||
move.l AvrgBuf(A6),A0 ;point to accumulation buffer
|
||
move d4,d3 ;longs in source
|
||
|
||
cmp.w #2,d7 ;merged exactly 2 scanlines?
|
||
beq.s @useShift ;avoid division by using a shift
|
||
|
||
@hardWay
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
divu.w d7,d1 ;get red average
|
||
move.b d1,d0 ;put in low byte of pixel <KON MAY90>
|
||
lsl.l #8,d0 ;make room for next component
|
||
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
divu.w d7,d1 ;get green average
|
||
move.b d1,d0 ;put in low byte of pixel
|
||
lsl.l #8,d0 ;make room for next component
|
||
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
divu.w d7,d1 ;get red average
|
||
move.b d1,d0 ;put in low byte of pixel
|
||
move.l d0,(a1)+ ;dump pixel into destination
|
||
dbra d3,@hardWay ;loop for all src longs
|
||
rts
|
||
|
||
@useShift
|
||
moveq #0,d0 ;zero alpha channel <KON MAY90>
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
lsr.w #1,d1 ;get red average
|
||
move.b d1,d0 ;put in low byte of pixel <KON MAY90>
|
||
lsl.l #8,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
lsr.w #1,d1 ;get green average
|
||
move.b d1,d0 ;put in low byte of pixel
|
||
lsl.l #8,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
lsr.w #1,d1 ;get red average
|
||
move.b d1,d0 ;put in low byte of pixel
|
||
move.l d0,(a1)+ ;dump pixel into srcBuf
|
||
dbra d3,@useShift ;loop for all src longs
|
||
rts
|
||
|
||
;-------------- Top of 16-bit average loop -----------------
|
||
; Top of 16-bit scanline averaging loop
|
||
; d7 and word at top of stack is number of scanlines to merge
|
||
;
|
||
NextAverageV16
|
||
|
||
;
|
||
; loop for all longs in source scanline
|
||
;
|
||
move.l a3,a0 ;get source address
|
||
move.l AvrgBuf(A6),A1 ;point to accumulation buffer
|
||
move d4,d5 ;get count of source
|
||
moveq #0,d1 ;use for extending to word data
|
||
moveq #0,d2 ;use for extending to word data
|
||
moveq #0,d3 ;use for extending to word data
|
||
|
||
;------------------------------------------------------------------------
|
||
|
||
@NDLONG move.l (A0)+,D0 ;EXTRACT A LONG FROM SRC (2 pixels)
|
||
move.b d0,d3 ;pick up blue component as a byte
|
||
and.b #$1f,d3
|
||
lsr.l #5,d0 ;toss blue
|
||
move.b d0,d2 ;pick up green component as a byte
|
||
and.b #$1f,d2
|
||
lsr.l #5,d0 ;toss green
|
||
move.b d0,d1 ;pick up red component as a word
|
||
and.b #$1f,d1
|
||
add.w d1,(a1)+ ;accumulate red value
|
||
add.w d2,(a1)+ ;accumulate green value
|
||
add.w d3,(a1)+ ;accumulate blue value
|
||
;
|
||
; Do second pixel in long
|
||
;
|
||
lsr.l #5+1,d0 ;move to second 16-bit pixel in long
|
||
move.b d0,d3 ;pick up blue component as a byte
|
||
and.b #$1f,d3
|
||
lsr.l #5,d0 ;toss blue
|
||
move.b d0,d2 ;pick up green component as a byte
|
||
and.b #$1f,d2
|
||
lsr.l #5,d0 ;toss green
|
||
move.b d0,d1 ;pick up red component as a word
|
||
and.b #$1f,d1
|
||
add.w d1,(a1)+ ;accumulate red value
|
||
add.w d2,(a1)+ ;accumulate green value
|
||
add.w d3,(a1)+ ;accumulate blue value
|
||
|
||
dbra d5,@NDLONG ;repeat for all longs
|
||
|
||
; add.l a5,a3 ;bump source to next row
|
||
_pmVersion
|
||
dbra d7,NextAverageV16 ;loop while scan lines left
|
||
|
||
move.w (a7)+,d7 ;retrieve # scanlines merged (0-based)
|
||
addq #1,d7 ;make it 1 based
|
||
|
||
; Now we must compute the average of the accumulated R-G-B's
|
||
|
||
move.l a2,a1 ;point to destination buffer
|
||
move.l AvrgBuf(A6),A0 ;point to accumulation buffer
|
||
move d4,d3 ;longs in source
|
||
;
|
||
; if it's a deep mask, we promote all 16-bit values to 32-bit
|
||
;
|
||
move.w maskshift(a6),d0
|
||
cmp.w #4,d0
|
||
bge Promote16Loop
|
||
|
||
cmp.w #2,d7 ;two scan lines merged?
|
||
beq.s @useShift ;avoid division by using a shift
|
||
|
||
@hardWay
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
||
move.w d1,d0 ;put in low byte of pixel (only 6 bits count)
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
divu.w d7,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
divu.w d7,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
;
|
||
; Now do second pixel in long
|
||
;
|
||
lsl.l #5+1,d0 ;bump to beginning of second pixel
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
||
or.w d1,d0 ;put in low byte of pixel (only 5 bits count)
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
divu.w d7,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
divu.w d7,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
swap d0 ;pixels mixed in AvrgBuf because of how constructed
|
||
move.l d0,(a1)+ ;dump pixel into srcBuf
|
||
dbra d3,@hardWay ;loop for all src longs
|
||
rts
|
||
|
||
@useShift
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
move.w d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
lsr.b #1,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
;
|
||
; do second pixel (2/long in 16-bit mode)
|
||
;
|
||
lsl.l #5+1,d0
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
lsr.b #1,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
swap d0
|
||
move.l d0,(a1)+ ;dump pixel into srcBuf
|
||
dbra d3,@useShift ;loop for all src longs
|
||
rts
|
||
|
||
Promote16Loop
|
||
;
|
||
; Average 16 bit values and put result back in AvrgBuf, then call
|
||
; Scale16to32 to promote to 32 bits
|
||
;
|
||
move.l a0,a1 ;copy AvrgBuf ptr
|
||
cmp.w #2,d7 ;two scan lines merged?
|
||
beq.s @useShift ;avoid division by using a shift
|
||
|
||
@hardWay
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
||
move.w d1,d0 ;put in low byte of pixel (only 6 bits count)
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
divu.w d7,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
divu.w d7,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
;
|
||
; Now do second pixel in long
|
||
;
|
||
lsl.l #5+1,d0 ;bump to beginning of second pixel
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
||
or.w d1,d0 ;put in low byte of pixel (only 5 bits count)
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
divu.w d7,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
moveq #0,d1 ;use for extending to word data
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
divu.w d7,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
swap d0 ;pixels mixed in AvrgBuf because of how constructed
|
||
move.l d0,(a1)+ ;dump pixel into srcBuf
|
||
dbra d3,@hardWay ;loop for all src longs
|
||
bra.s @DoPromote
|
||
|
||
@useShift
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
move.w d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
lsr.b #1,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
;
|
||
; do second pixel (2/long in 16-bit mode)
|
||
;
|
||
lsl.l #5+1,d0
|
||
move.w (a0)+,d1 ;pick up red accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up green accumulation
|
||
lsr.b #1,d1 ;get green average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
lsl.l #5,d0 ;make room for next component
|
||
move.w (a0)+,d1 ;pick up blue accumulation
|
||
lsr.b #1,d1 ;get red average
|
||
or.b d1,d0 ;put in low byte of pixel
|
||
|
||
swap d0
|
||
move.l d0,(a1)+ ;dump pixel into srcBuf
|
||
dbra d3,@useShift ;loop for all src longs
|
||
@DoPromote
|
||
;
|
||
; Call Scale16to32 to promote pixels to 32 bpp
|
||
;
|
||
move.l AvrgBuf(A6),A0 ;pointer to source
|
||
move.l a2,a1 ;pointer to destination
|
||
lsl.l #3,d4 ;calc size of dst:
|
||
;longs to bytes and 16 bit to 32 bit = *8 <7JULY90 KON>
|
||
add.l d4,a2 ;calc end of dst buffer
|
||
jmpROM ciScale16to32 ;inherits return address.
|
||
;
|
||
;----------------Bottom of 16-bit average loop ----------------
|
||
;
|
||
;*********************************************************************
|
||
|
||
ALIGN Alignment
|
||
|
||
;*********************************************************************
|
||
;
|
||
; Loop to expand and merge D7 1-bit/pixel scanlines.
|
||
;
|
||
;ENTRY:
|
||
; D0: scratch A0: scratch ptr
|
||
; D1: scratch A1: scratch ptr
|
||
; D2: scratch A2: destination
|
||
; D3: scratch A3: source
|
||
; D4: src longs A4: src pmtable A5: rowbytes
|
||
; D5: srcAlign A5: rowbytes
|
||
; D6: realDepth (pixel size)
|
||
; D7: Scanline Count (zero based)
|
||
;
|
||
;EXIT:
|
||
;
|
||
; a3: new srcaddr
|
||
;
|
||
;GLOBALS: AvgBufPtr(a6), AvgBufSize(a6)
|
||
;
|
||
;*********************************************************************
|
||
|
||
ONEDEEP
|
||
|
||
; LOOP FOR ALL LONGS IN SRC SCANLINE
|
||
|
||
move.l a3,a0 ;point to source
|
||
move.l a2,a1 ;point to destination
|
||
move d4,d1 ;get count of longs
|
||
|
||
@Align bfextu (a0){d5:0},d0 ;get an aligned long of source
|
||
add #4,a0 ;bump to next long
|
||
move.l d0,(a1)+ ;put a long to destination
|
||
dbra d1,@Align ;loop for all longs
|
||
|
||
; add.l a5,a3 ;bump source to next row
|
||
_pmVersion
|
||
dbra d7,@OneMerge ; <KON 1NOV90>
|
||
rts
|
||
@OneMerge
|
||
|
||
move.l a3,a0 ;point to source
|
||
move.l a2,a1 ;point to destination
|
||
move d4,d1 ;get count of longs
|
||
@NXTLNG bfextu (a0){d5:0},d0 ;get an aligned long of source
|
||
add #4,a0 ;bump to next long
|
||
or.l d0,(a1)+ ;put a long to destination
|
||
dbra d1,@NXTLNG ;loop for all longs <10July90 KON>
|
||
|
||
; add.l a5,a3 ;bump source to next row
|
||
_pmVersion
|
||
dbra d7,@OneMerge
|
||
rts
|
||
|
||
;******************************************************************************************
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to stMask0 and stMask1 to colorize only when needed.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 0 OR 4: SRC --> DST
|
||
;
|
||
; FOR PROPER INVERSION, ASSUME SRC IS COLORED. INVERT SRC AFTER
|
||
; ADDING COLOR TO IT (RATHER THAN EXCHANGING FG AND BK, INVERT THEM).
|
||
|
||
;
|
||
; On first entry, find fastest drawing case, and put it in ModeCase(a6)
|
||
;
|
||
stMask0 TST.B alphaMode(A6) ;drawing in alpha mode?
|
||
BEQ.S @1 ;no, use normal loops
|
||
LEA stAlphaMask0,A0 ;get address of alpha copy loop
|
||
BRA.S @RememberAndDoIt ;go remember and do it
|
||
@1: lea FaststMask0,a0 ;assume fast
|
||
;
|
||
; should we colorize here?
|
||
;
|
||
btst #ColorizeInModeCaseBit,XLateFlag(a6)
|
||
bne.s @goslow
|
||
;
|
||
;if we got here, there's no colorizing
|
||
;
|
||
@DontColorize
|
||
tst.l d6 ;need to shift?
|
||
bne.s @ShiftNoColor
|
||
tst.l d7 ;need to invert?
|
||
bne.s @ShiftNoColor
|
||
;
|
||
;if we got here, it's the fast case
|
||
|
||
@RememberAndDoIt
|
||
move.l a0,ModeCase(a6)
|
||
jmp (a0)
|
||
@goSlow
|
||
lea stMask0Slow,a0 ;shift, invert, and colorize
|
||
bra.s @RememberAndDoIt
|
||
|
||
@ShiftNoColor
|
||
lea stMask0ShiftNoColorInvert,a0 ;shift, don't colorize, but invert
|
||
bra.s @RememberAndDoIt
|
||
;
|
||
;don't shift, invert, or colorize
|
||
;
|
||
FaststMask0
|
||
;draw
|
||
move.l (a3)+,d0 ;get source
|
||
move.l (a4),d1 ;get dst
|
||
eor.l d1,d0 ;src xor dst
|
||
move.l (a2)+,d3
|
||
and.l d3,d0 ;(src xor dst) and mask
|
||
eor.l d0,d1
|
||
move.l d1,(a4)+ ;dst = [(src xor dst) and mask] xor dst
|
||
DBRA D2,FaststMask0 ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
;
|
||
; shift, no colorize, and invert
|
||
;
|
||
stMask0ShiftNoColorInvert
|
||
;shift
|
||
BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
||
ADD #4,A3 ;bump to next long of source
|
||
move.l (a2)+,d3
|
||
;invert
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
;draw
|
||
move.l (a4),d1 ;get dst
|
||
eor.l d1,d0 ;src xor dst
|
||
and.l d3,d0 ;(src xor dst) and mask
|
||
eor.l d0,d1 ;dst = [(src xor dst) and mask] xor dst
|
||
move.l d1,(a4)+
|
||
DBRA D2,stMask0ShiftNoColorInvert ;LOOP ALL LONGS THIS ROW
|
||
rts ;GO FOR NEXT ROW
|
||
|
||
stAlphaMask0 ;(ENTIRE LOOP)
|
||
MOVE.L alphaMask(A6),D5
|
||
@1: BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
||
ADD #4,A3 ;bump to next long of source
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
|
||
MOVE.L (A4),D1 ;GET DST DATA
|
||
EOR.L D1,D0
|
||
AND.L (A2)+,D0
|
||
AND.L D5,D0
|
||
EOR.L D1,D0
|
||
MOVE.L D0,(A4)+ ;PUT RESULT IN DST
|
||
DBRA D2,@1 ;LOOP ALL LONGS THIS ROW
|
||
EOR.L D4,D3 ;(THIS MAY NOT BE NEEDED)
|
||
BRA NEXTDST ;GO FOR NEXT ROW
|
||
|
||
stMASK0Slow
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 0 OR 4: SRC --> DST
|
||
;
|
||
; FOR PROPER INVERSION, ASSUME SRC IS COLORED. INVERT SRC AFTER
|
||
; ADDING COLOR TO IT (RATHER THAN EXCHANGING FG AND BK, INVERT THEM).
|
||
;
|
||
BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
||
ADD #4,A3 ;bump to next long of source
|
||
MOVE.L (A2)+,D1 ;GET MASK
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
|
||
MOVE.L D0,D5 ;COPY SRC
|
||
AND.L D3,D0 ;ADD FG COLOR TO SRC
|
||
NOT.L D5 ;GET NOT SRC
|
||
AND.L D4,D5 ;ADD BK COLOR TO NOT SRC
|
||
OR.L D5,D0 ;COMBINE FG/BK DATA
|
||
AND.L D1,D0 ;MASK RESULT
|
||
|
||
NOT.L D1 ;FORM NOTMASK
|
||
AND.L (A4),D1 ;GET DST DATA
|
||
OR.L D1,D0 ;MERGE WITH SRC DATA
|
||
MOVE.L D0,(A4)+ ;PUT RESULT IN DST
|
||
DBRA D2,stMASK0Slow ;LOOP ALL LONGS THIS ROW
|
||
rts ;GO FOR NEXT ROW
|
||
|
||
|
||
;
|
||
; The eight bit loops are moved to RAM by code at the end of this file. <KON 09OCT90>
|
||
;
|
||
ALIGN Alignment
|
||
|
||
stHilite
|
||
BFEXTU D4{0:D7},D4 ;set up a pixel of the backcolor
|
||
BFEXTU hilitColor(A6){0:D7},D5 ;and a pixel of the hilite color as well
|
||
@loopTop
|
||
ADD.L D7,D6 ;bump source pointer
|
||
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
||
BEQ.S @skip ;if none, skip the pixel
|
||
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
||
CMP.L D4,D0 ;is pixel same as background color? <85>
|
||
BEQ.S @skip
|
||
BFEXTU (A4){D3:D7},D0 ;get a pixel of the destination
|
||
CMP.L D4,D0 ;same as the background color?
|
||
BNE.S @tryNew
|
||
BFINS D5,(A4){D3:D7}
|
||
BRA.S @skip
|
||
@tryNew
|
||
CMP.L D5,D0 ;same as new color?
|
||
BNE.S @skip
|
||
BFINS D4,(A4){D3:D7} ;move to the destination
|
||
@skip
|
||
ADD.L D7,D3 ;advance to next destination
|
||
DBRA D2,@loopTop ;LOOP ALL pixels THIS ROW
|
||
BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
;
|
||
; Here begins the arithmetic transfer loops for 32 bits/pixel:
|
||
;
|
||
;
|
||
;
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
; MODE 42: PAT + DST --> DST (no pin)
|
||
;-------------------------------------------------------
|
||
; a0 = hi bit mask d0 = hi bit clring mask
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = src msb's
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = dst msb's
|
||
;-------------------------------------------------------
|
||
ALIGN Alignment
|
||
|
||
stAddOver32
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
move.l #~$ff808080,d0 ;get high bit clearing mask
|
||
move.l #$00808080,a0 ;get high bit mask
|
||
|
||
@blit tst.l (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
move.l 0(a3,d6),d1 ;get src pixel
|
||
move.l a0,d7 ;copy high bit mask
|
||
and.l d1,d7 ;remember src msb's
|
||
and.l d0,d1 ;mask out stragglers
|
||
|
||
move.l (a1),d5 ;get dest pixel
|
||
move.l a0,d3 ;copy high bit mask
|
||
and.l d5,d3 ;remember dst msb's
|
||
and.l d0,d5 ;mask out stragglers
|
||
|
||
add.l d1,d5 ;merge src with dst
|
||
eor.l d7,d3 ;compute partial sum of msb's
|
||
eor.l d3,d5 ;compute partial sum of msb's
|
||
MOVE.L d5,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;——————————————————————————————————————————————————————
|
||
; Utility arithSetup
|
||
; sets up registers for 32 bit arithmetic modes:
|
||
;
|
||
; INPUT
|
||
; REGISTERS: A0: D0: CLOBBERED ;
|
||
; A1: D1: CLOBBERED ;
|
||
; A2: MASKPTR D2: LONGCNT ;
|
||
; A3: SRCPTR D3: FGCOLOR ;
|
||
; A4: DSTPTR D4: BKCOLOR ;
|
||
; A5: D5: CLOBBERED ;
|
||
; A6: D6: DSTALIGN ;
|
||
; A7: D7: PixelSize ;
|
||
; ;
|
||
|
||
arithSetup32
|
||
move.l a4,a1 ;reroute dstPtr
|
||
moveq #0,D6 ;zero src index
|
||
; moveq #-1,D4 ;flush src modulus
|
||
; move.l d4,patHMask(a6)
|
||
RTS
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 41: PAT + DST --> DST (pin to max)
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 = lo3Bytes mask
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = pin pixel 0rgb
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
stAddPin32
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
;set up pin pixel as 0rgb in D3
|
||
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
|
||
move.l Lo3Bytes,d1 ;pick up mask
|
||
|
||
@blit tst.l (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
move.l 0(a3,d6),d7 ;get src pixel
|
||
and.l d1,d7 ;waste high byte
|
||
move.l d7,d0 ;make a copy of the src xrgb
|
||
|
||
move.l (a1),d5 ;get dest pixel
|
||
and.l d1,d5 ;waste high byte
|
||
|
||
clr.b d0 ;prevent carries from below
|
||
add.w d5,d0 ;add green components
|
||
BCS.S @PinGreen
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bls.s @GreenOK
|
||
@PinGreen
|
||
move.w d3,d0 ;use pin value instead
|
||
@GreenOK
|
||
move.b d7,d0 ;get src blue
|
||
add.b d5,d0 ;add dest blue
|
||
BCS.S @PinBlue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bls.s @BlueOK
|
||
@PinBlue
|
||
move.b d3,d0 ;use pin value instead
|
||
@BlueOK
|
||
clr.w d5 ;now d5 has only red in byte 3
|
||
add.l d5,d0 ;add red components
|
||
cmp.l d3,d0 ;compare red components
|
||
bls.s @RedOK
|
||
@PinRed
|
||
swap d3 ;get max red in lo word
|
||
swap d0 ;get too big red in lo word
|
||
move.w d3,d0 ;pin to max red
|
||
swap d0 ;get back 0rgb
|
||
swap d3 ;restore pin pixel
|
||
@RedOK
|
||
MOVE.L d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 46: DST - PAT --> DST (no pin)
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = hi bit clring mask
|
||
; a1 = dstPtr d1 = high bit mask
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = src msb's
|
||
; a4 = d4 = dst msb's
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
stSubOver32
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
move.l #~$ff808080,d0 ;get high bit clearing mask
|
||
move.l #$00808080,d1 ;get high bit mask
|
||
|
||
@blit tst.l (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
move.l 0(a3,d6),d7 ;get src pixel
|
||
move.l d1,d3 ;copy high bit mask
|
||
and.l d7,d3 ;remember src msb's
|
||
eor.l d1,d3 ;invert src msb's
|
||
and.l d0,d7 ;mask out stragglers
|
||
|
||
move.l (a1),d5 ;get dest pixel
|
||
move.l d1,d4 ;copy high bit mask
|
||
and.l d5,d4 ;remember dst msb's
|
||
and.l d0,d5 ;mask out high byte
|
||
or.l d1,d5 ;force high bits on
|
||
|
||
sub.l d7,d5 ;compute dst - src
|
||
eor.l d3,d4 ;compute partial sum of msb's
|
||
eor.l d4,d5 ;compute partial sum of msb's
|
||
MOVE.L d5,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 43: DST - PAT --> DST (pin to min)
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 = lo3Bytes mask
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = pin pixel 0rgb
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = src pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = dst pixel
|
||
;-------------------------------------------------------
|
||
stSubPin32
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
;set up pin pixel as 0rgb in D3
|
||
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
|
||
move.l Lo3Bytes,d1 ;pick up mask
|
||
|
||
@blit tst.l (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
move.l 0(a3,d6),d5 ;get src pixel
|
||
and.l d1,d5 ;waste high byte
|
||
|
||
move.l (a1),d7 ;get dest pixel
|
||
and.l d1,d7 ;waste high byte
|
||
move.l d7,d0 ;make a copy of the dst xrgb
|
||
|
||
st d0 ;prevent borrows from below
|
||
sub.w d5,d0 ;sub green components
|
||
BCS.S @PinGreen
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bhs.s @GreenOK
|
||
@PinGreen
|
||
move.w d3,d0 ;use pin value instead
|
||
@GreenOK
|
||
move.b d7,d0 ;get dest blue
|
||
sub.b d5,d0 ;sub src blue
|
||
BCS.S @PinBlue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bhs.s @BlueOK
|
||
@PinBlue
|
||
move.b d3,d0 ;use pin value instead
|
||
@BlueOK
|
||
clr.w d5 ;now d5 has only red in byte 3
|
||
sub.l d5,d0 ;sub red components
|
||
cmp.l d3,d0 ;compare red components
|
||
bge.s @RedOK
|
||
@PinRed
|
||
swap d3 ;get max red in lo word
|
||
swap d0 ;get too big red in lo word
|
||
move.w d3,d0 ;pin to max red
|
||
swap d0 ;get back 0rgb
|
||
swap d3 ;restore pin pixel
|
||
@RedOK
|
||
|
||
MOVE.L d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 45: MAX(PAT, DST) --> DST
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 =
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
stMax32
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
@blit tst.l (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
move.l 0(a3,d6),d1 ;get src pixel
|
||
move.l (a1),d5 ;get dest pixel
|
||
|
||
move.l d5,d0 ;make a copy of the dest xrgb
|
||
cmp.w d1,d0 ;compare g,b components
|
||
BHI.S @gotMaxGreen
|
||
move.w d1,d0 ;keep the bigger of the two
|
||
move.b d5,d0 ;prime for blue
|
||
@gotMaxGreen
|
||
cmp.b d1,d5 ;compare blue components
|
||
BHI.S @gotMaxBlue
|
||
move.b d1,d0 ;keep the bigger of the two
|
||
@gotMaxBlue
|
||
swap d1
|
||
swap d0
|
||
cmp.b d1,d0 ;compare red components
|
||
BHI.S @gotMaxRed
|
||
move.b d1,d0 ;keep the bigger of the two
|
||
@gotMaxRed
|
||
swap d0 ;get new xrgb
|
||
MOVE.L d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 47: MIN(PAT, DST) --> DST
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 =
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
stMin32
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
@blit tst.l (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
move.l 0(a3,d6),d1 ;get src pixel
|
||
move.l (a1),d5 ;get dest pixel
|
||
|
||
move.l d5,d0 ;make a copy of the dest xrgb
|
||
cmp.w d1,d0 ;compare g,b components
|
||
BLS.S @gotMinGreen
|
||
move.w d1,d0 ;keep the smaller of the two
|
||
move.b d5,d0 ;prime for blue
|
||
@gotMinGreen
|
||
cmp.b d1,d5 ;compare blue components
|
||
BLS.S @gotMinBlue
|
||
move.b d1,d0 ;keep the smaller of the two
|
||
@gotMinBlue
|
||
swap d1
|
||
swap d0
|
||
cmp.b d1,d0 ;compare red components
|
||
BLS.S @gotMinRed
|
||
move.b d1,d0 ;keep the smaller of the two
|
||
@gotMinRed
|
||
swap d0 ;get new xrgb
|
||
MOVE.L d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 40: AVG(SRC, DST, WEIGHT) --> DST
|
||
;
|
||
; CLOBBERS: D0,D3,D2,A1,A2
|
||
; A3,D6 (BUT NOT IN FASTSLAB)
|
||
;-------------------------------------------------------
|
||
; a0 = /last dst d0 = red weight
|
||
; a1 = dstPtr d1 = blue/grn weight (scanCount)
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = /last src
|
||
; a4 = d4 = /last result
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
stAvg32
|
||
lea @stAvg32Slow,a0 ;assume, general blend32 from now on
|
||
move.l a0,modeCase(a6)
|
||
lea weight(a6),a0 ;point to weights
|
||
move.w (a0)+,d3
|
||
cmp.w (a0)+,d3 ;is opColor gray?
|
||
bne.s @stAvg32Slow
|
||
cmp.w (a0),d3
|
||
bne.s @stAvg32Slow
|
||
addq #1,d3 ;yes, check for gray values of $8000 or $7fff
|
||
and.w #$fffe,d3
|
||
cmp.w #$8000,d3
|
||
bne.s @stAvg32Slow
|
||
lea @stAvg32Half,a0 ;use fast 50% blend32 from now on
|
||
move.l a0,modeCase(a6)
|
||
bra @stAvg32Half
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; General blend case for non 50% gray weights
|
||
;
|
||
;
|
||
@stAvg32Slow
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
lea weight(a6),a0 ;point at blue weight
|
||
move.l (a0)+,d1 ;get blue/green weight
|
||
move.w (a0),d0 ;get red weight
|
||
|
||
@short0 moveq #0,d4 ;init last result
|
||
move.l d4,d3 ;init last src
|
||
move.l d4,a0 ;init last dst
|
||
|
||
@blit tst.l (A2)+ ;a pixel of the clip region
|
||
BEQ.S @skip
|
||
move.l 0(a3,d6),d7 ;get src pixel
|
||
move.l (a1),d5 ;get dest pixel
|
||
|
||
@short1 cmp.l d3,d7 ;same as last time?
|
||
bne.s @blue ;no, go do it
|
||
cmp.l a0,d5 ;same as last time?
|
||
beq.s @again ;yes, go fast
|
||
|
||
@blue moveq #0,d3 ;clr out high end
|
||
move.b d7,d3 ;get src blue
|
||
swap d1 ;get blue weight
|
||
mulu.w d1,d3 ;% blue
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
move.b d5,d4 ;get dst blue
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% blue
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 24 bits of dst blue
|
||
swap d4 ;dst blue
|
||
move.w d4,a0 ;a0 has 000B
|
||
|
||
@grn move.w d7,d3 ;get src grn
|
||
lsr.w #8,d3
|
||
swap d1 ;get grn weight
|
||
mulu.w d1,d3 ;% grn
|
||
|
||
move.w d5,d4 ;get dst grn
|
||
lsr.w #8,d4
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% grn
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 24 bits of dst grn
|
||
swap d4 ;dst grn
|
||
lsl.w #8,d4
|
||
add.w d4,a0 ;a0 has 00GB
|
||
|
||
@red moveq #0,d3 ;clr out high end
|
||
swap d7
|
||
move.b d7,d3 ;get src red
|
||
mulu.w d0,d3 ;% red
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
swap d5
|
||
move.b d5,d4 ;get dst red
|
||
neg.w d0
|
||
mulu.w d0,d4 ;% red
|
||
neg.w d0
|
||
|
||
add.l d3,d4 ;get 24 bits of dst red
|
||
move.w a0,d4 ;d4 has 0RGB
|
||
|
||
@short2 swap d5 ;get back dst
|
||
move.l d5,a0 ;save for short circuit
|
||
swap d7 ;get back src
|
||
move.l d7,d3 ;save for short circuit
|
||
|
||
@again MOVE.L d4,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Optimized 50% blend case for 32 bits/pixel
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = low bit mask d0 = high bit mask
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = lsb's of result
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
@stAvg32Half
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
move.l #~$ff808080,d0 ;get high bit mask
|
||
move.l #$10101,a0 ;get low bit mask
|
||
|
||
@blit2 tst.l (A2)+ ;a pixel of the clip region
|
||
BEQ.S @skip2
|
||
move.l 0(a3,d6),d1 ;get src pixel
|
||
|
||
move.l a0,d3 ;copy low bit mask
|
||
and.l d1,d3 ;remember src lsb's
|
||
lsr.l #1,d1 ;get almost 1/2 of it
|
||
and.l d0,d1 ;mask out stragglers
|
||
|
||
move.l (a1),d5 ;get dest pixel
|
||
and.l d5,d3 ;compute carry out of lsb
|
||
lsr.l #1,d5 ;get almost 1/2 of it
|
||
and.l d0,d5 ;mask out stragglers
|
||
|
||
add.l d5,d1 ;merge src with dst
|
||
add.l d3,d1 ;propagate carrys
|
||
MOVE.L d1,(a1) ;write pattern to dest
|
||
|
||
@skip2 addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit2 ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Mode: 36 Transparent for 32 bits/pixel
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 =
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 =
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = backColor
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
stTransparent32
|
||
BSR arithSetup32 ;set up registers for slab bitblt
|
||
|
||
move.l transColor(A6),D5 ;get a pixel of the transparent color
|
||
|
||
@blit tst.l (A2)+ ;a pixel of the clip region
|
||
BEQ.S @skip
|
||
move.l 0(a3,d6),d1 ;get src pixel
|
||
|
||
cmp.l d1,d5 ;is src backColor?
|
||
beq.s @skip ;yes, don't write to dst
|
||
MOVE.L d1,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #4,a1 ;bump dst ptr
|
||
addq.l #4,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
;
|
||
; Here begin the arithmetic transfer loops for 16 bits/pixel:
|
||
;
|
||
;
|
||
;
|
||
ALIGN Alignment
|
||
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
; MODE 42: PAT + DST --> DST (no pin)
|
||
;-------------------------------------------------------
|
||
; a0 = hi bit mask d0 = hi bit clring mask
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = src msb's
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = dst msb's
|
||
;-------------------------------------------------------
|
||
stAddOver16
|
||
BSR.s arithSetup16 ;set up registers for slab bitblt
|
||
|
||
move.w #$3def,d0 ;get high bit clearing mask
|
||
move.w #$4210,a0 ;get high bit mask
|
||
|
||
@blit tst.w (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
move.w 0(a3,d6),d1 ;get src pixel
|
||
move.w a0,d7 ;copy high bit mask
|
||
and.w d1,d7 ;remember src msb's
|
||
and.w d0,d1 ;mask out stragglers
|
||
|
||
move.w (a1),d5 ;get dest pixel
|
||
move.w a0,d3 ;copy high bit mask
|
||
and.w d5,d3 ;remember dst msb's
|
||
and.w d0,d5 ;mask out stragglers
|
||
|
||
add.w d1,d5 ;merge src with dst
|
||
eor.w d7,d3 ;compute partial sum of msb's
|
||
eor.w d3,d5 ;compute partial sum of msb's
|
||
MOVE.w d5,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;——————————————————————————————————————————————————————
|
||
; Utility arithSetup
|
||
; sets up registers for 16 bit arithmetic modes:
|
||
;
|
||
; INPUT
|
||
; REGISTERS: A0: D0: CLOBBERED ;
|
||
; A1: D1: CLOBBERED ;
|
||
; A2: MASKPTR D2: LONGCNT ;
|
||
; A3: SRCPTR D3: FGCOLOR ;
|
||
; A4: DSTPTR D4: BKCOLOR ;
|
||
; A5: D5: CLOBBERED ;
|
||
; A6: D6: DSTALIGN ;
|
||
; A7: D7: PixelSize ;
|
||
; ;
|
||
|
||
arithSetup16
|
||
move.l a4,a1 ;reroute dstPtr
|
||
moveq #0,D6 ;zero src index
|
||
; moveq #-1,D4 ;flush src modulus
|
||
; move.l d4,patHMask(a6)
|
||
tst dstAlign(a6) ;on longword boundary?
|
||
beq.s @srcOK
|
||
subq #2,a3 ;align src with mask
|
||
@srcOK RTS
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 41: PAT + DST --> DST (pin to max)
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 =
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = pin pixel 0rgb
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
stAddPin16
|
||
BSR.s arithSetup16 ;set up registers for slab bitblt
|
||
|
||
;set up pin pixel as 0rgb in D3
|
||
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
lsr.b #3,d3 ;get right aligned 5 bits
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
lsr.w #3,d3 ;get right aligned 5 bits
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
lsr.b #3,d3 ;right flush blue
|
||
|
||
@blit tst.w (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
moveq #0,d7
|
||
move.w 0(a3,d6),d7 ;get src pixel
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
moveq #0,d5
|
||
move.w (a1),d5 ;get dest pixel
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
add.l d5,d7 ;add all components at once
|
||
move.l d7,d0 ;prime result with red
|
||
cmp.l d3,d0 ;do we need to pin result?
|
||
bls.s @redOK ;no, don't pin
|
||
move.l d3,d0 ;use pin value instead
|
||
@redOK
|
||
move.w d7,d0 ;prime result with green
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bls.s @greenOK ;no, don't pin
|
||
move.w d3,d0 ;use pin value instead
|
||
@greenOK
|
||
move.b d7,d0 ;prime result with blue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bls.s @blueOK ;no, don't pin
|
||
move.b d3,d0 ;use pin value instead
|
||
@blueOK
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
MOVE.w d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 46: DST - PAT --> DST (no pin)
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = hi bit clring mask
|
||
; a1 = dstPtr d1 = high bit mask
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = src msb's
|
||
; a4 = d4 = dst msb's
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
stSubOver16
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
move.w #$3def,d0 ;get high bit clearing mask
|
||
move.w #$4210,d1 ;get high bit mask
|
||
|
||
@blit tst.w (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
move.w 0(a3,d6),d7 ;get src pixel
|
||
move.w d1,d3 ;copy high bit mask
|
||
and.w d7,d3 ;remember src msb's
|
||
eor.w d1,d3 ;invert src msb's
|
||
and.w d0,d7 ;mask out stragglers
|
||
|
||
move.w (a1),d5 ;get dest pixel
|
||
move.w d1,d4 ;copy high bit mask
|
||
and.w d5,d4 ;remember dst msb's
|
||
and.w d0,d5 ;mask out high byte
|
||
or.w d1,d5 ;force high bits on
|
||
|
||
sub.w d7,d5 ;compute dst - src
|
||
eor.w d3,d4 ;compute partial sum of msb's
|
||
eor.w d4,d5 ;compute partial sum of msb's
|
||
MOVE.w d5,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 43: DST - PAT --> DST (pin to min)
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 = lo3Bytes mask
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = pin pixel 0rgb
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = src pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = dst pixel
|
||
;-------------------------------------------------------
|
||
stSubPin16
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
;set up pin pixel as 0rgb in D3
|
||
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
lsr.b #3,d3 ;get right aligned 5 bits
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
lsr.w #3,d3 ;get right aligned 5 bits
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
lsr.b #3,d3 ;right flush blue
|
||
move.l #$808080,d1 ;borrow stopper
|
||
add.l d1,d3 ;prevent borrows from crossing byte boundaries
|
||
|
||
@blit tst.w (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
moveq #0,d5
|
||
move.w 0(a3,d6),d5 ;get src pixel
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
moveq #0,d7
|
||
move.w (a1),d7 ;get dest pixel
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
add.l d1,d7 ;prevent borrows from crossing byte boundaries
|
||
|
||
sub.l d5,d7 ;sub all components at once
|
||
move.l d7,d0 ;prime result with red
|
||
cmp.l d3,d0 ;do we need to pin result?
|
||
bhs.s @redOK ;no, don't pin
|
||
move.l d3,d0 ;use pin value instead
|
||
@redOK
|
||
move.w d7,d0 ;prime result with green
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bhs.s @greenOK ;no, don't pin
|
||
move.w d3,d0 ;use pin value instead
|
||
@greenOK
|
||
move.b d7,d0 ;prime result with blue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bhs.s @blueOK ;no, don't pin
|
||
move.b d3,d0 ;use pin value instead
|
||
@blueOK
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
MOVE.w d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 45: MAX(PAT, DST) --> DST
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 =
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
stMax16
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
@blit tst.w (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
moveq #0,d7
|
||
move.w 0(a3,d6),d7 ;get src pixel
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
moveq #0,d5
|
||
move.w (a1),d5 ;get dest pixel
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
move.l d7,d0 ;prime result with src
|
||
cmp.l d5,d0 ;is dst greater?
|
||
bhs.s @gotRed ;no, use src
|
||
move.l d5,d0 ;use dst value instead
|
||
@gotRed
|
||
move.w d7,d0 ;prime result with src
|
||
cmp.w d5,d0 ;is dst greater?
|
||
bhs.s @gotGreen ;no, use src
|
||
move.w d5,d0 ;use dst value instead
|
||
@gotGreen
|
||
move.b d7,d0 ;prime result with src
|
||
cmp.b d5,d0 ;is dst greater?
|
||
bhs.s @gotBlue ;no, use src
|
||
move.b d5,d0 ;use dst value instead
|
||
@gotBlue
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
MOVE.w d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 47: MIN(PAT, DST) --> DST
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 = result
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 =
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
stMin16
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
@blit tst.w (a2)+ ;a pixel of the clip region
|
||
beq.s @skip
|
||
|
||
moveq #0,d7
|
||
move.w 0(a3,d6),d7 ;get src pixel
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
moveq #0,d5
|
||
move.w (a1),d5 ;get dest pixel
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
move.l d7,d0 ;prime result with src
|
||
cmp.l d5,d0 ;is dst smaller?
|
||
bls.s @gotRed ;no, use src
|
||
move.l d5,d0 ;use dst value instead
|
||
@gotRed
|
||
move.w d7,d0 ;prime result with src
|
||
cmp.w d5,d0 ;is dst smaller?
|
||
bls.s @gotGreen ;no, use src
|
||
move.w d5,d0 ;use dst value instead
|
||
@gotGreen
|
||
move.b d7,d0 ;prime result with src
|
||
cmp.b d5,d0 ;is dst smaller?
|
||
bls.s @gotBlue ;no, use src
|
||
move.b d5,d0 ;use dst value instead
|
||
@gotBlue
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
MOVE.w d0,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 40: AVG(SRC, DST, WEIGHT) --> DST
|
||
;
|
||
; CLOBBERS: D0,D3,D2,A1,A2
|
||
; A3,D6 (BUT NOT IN FASTSLAB)
|
||
;-------------------------------------------------------
|
||
; a0 = /last dst d0 = red weight
|
||
; a1 = dstPtr d1 = blue/grn weight (scanCount)
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = /last src
|
||
; a4 = d4 = /last result
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
stAvg16
|
||
lea @stAvg16Slow,a0 ;assume, general blend16 from now on
|
||
move.l a0,modeCase(a6)
|
||
lea weight(a6),a0 ;point to weights
|
||
move.w (a0)+,d3
|
||
cmp.w (a0)+,d3 ;is opColor gray?
|
||
bne.s @stAvg16Slow
|
||
cmp.w (a0),d3
|
||
bne.s @stAvg16Slow
|
||
addq #1,d3 ;yes, check for gray values of $8000 or $7fff
|
||
and.w #$fffe,d3
|
||
cmp.w #$8000,d3
|
||
bne.s @stAvg16Slow
|
||
lea @stAvg16Half,a0 ;use fast 50% blend16 from now on
|
||
move.l a0,modeCase(a6)
|
||
bra @stAvg16Half
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; General blend case for non 50% gray weights
|
||
;
|
||
;
|
||
@stAvg16Slow
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
lea weight(a6),a0 ;point at blue weight
|
||
move.l (a0)+,d1 ;get blue/green weight
|
||
move.w (a0),d0 ;get red weight
|
||
|
||
@short0 moveq #0,d4 ;init last result
|
||
move.l d4,d3 ;init last src
|
||
move.l d4,a0 ;init last dst
|
||
|
||
@blit tst.w (A2)+ ;a pixel of the clip region
|
||
BEQ @skip
|
||
moveq #0,d7
|
||
move.w 0(a3,d6),d7 ;get src pixel
|
||
moveq #0,d5
|
||
move.w (a1),d5 ;get dest pixel
|
||
|
||
@short1 cmp.w d3,d7 ;same as last time?
|
||
bne.s @hardway ;no, go do it
|
||
cmp.w a0,d5 ;same as last time?
|
||
beq.s @again ;yes, go fast
|
||
@hardway
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
@blue moveq #0,d3 ;clr out high end
|
||
move.b d7,d3 ;get src blue
|
||
swap d1 ;get blue weight
|
||
mulu.w d1,d3 ;% blue
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
move.b d5,d4 ;get dst blue
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% blue
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 21 bits of blue
|
||
swap d4 ;right align 5 blue bits
|
||
move.l d4,a0 ;a0 has 000B
|
||
|
||
@grn move.w d7,d3 ;get src grn
|
||
lsr.w #8,d3
|
||
swap d1 ;get grn weight
|
||
mulu.w d1,d3 ;% grn
|
||
|
||
move.w d5,d4 ;get dst grn
|
||
lsr.w #8,d4
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% grn
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 21 bits of grn
|
||
swap d4 ;right align 5 green bits
|
||
lsl.w #5,d4 ;shift into place
|
||
add.w d4,a0 ;a0 has 00GB
|
||
|
||
@red moveq #0,d3 ;clr out high end
|
||
swap d7
|
||
move.b d7,d3 ;get src red
|
||
mulu.w d0,d3 ;% red
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
swap d5
|
||
move.b d5,d4 ;get dst red
|
||
neg.w d0
|
||
mulu.w d0,d4 ;% red
|
||
neg.w d0
|
||
|
||
add.l d3,d4 ;get 21 bits of red
|
||
clr.w d4 ;clear lsb's
|
||
lsr.l #6,d4 ;shift into place
|
||
add.w a0,d4 ;d4 has 0RGB
|
||
|
||
@short2 swap d5 ;get back dst
|
||
lsl.b #3,d5 ;rejoin green/blue
|
||
lsl.w #3,d5 ;rejoin red/green/blue
|
||
lsr.l #6,d5 ;right flush red/green/blue
|
||
move.l d5,a0 ;save for short circuit
|
||
swap d7 ;get back src
|
||
lsl.b #3,d7 ;rejoin green/blue
|
||
lsl.w #3,d7 ;rejoin red/green/blue
|
||
lsr.l #6,d7 ;right flush red/green/blue
|
||
move.l d7,d3 ;save for short circuit
|
||
|
||
@again MOVE.w d4,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Optimized 50% blend case for 16 bits/pixel
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = low bit mask d0 = high bit mask
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 = lsb's of result
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = dest pixel
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
@stAvg16Half
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
move.w #$3def,d0 ;get high bit clearing mask
|
||
move.w #$0421,a0 ;get low bit mask
|
||
|
||
@blit2 tst.w (A2)+ ;a pixel of the clip region
|
||
BEQ.S @skip2
|
||
move.w 0(a3,d6),d1 ;get src pixel
|
||
|
||
move.w a0,d3 ;copy low bit mask
|
||
and.w d1,d3 ;remember src lsb's
|
||
lsr.w #1,d1 ;get almost 1/2 of it
|
||
and.w d0,d1 ;mask out stragglers
|
||
|
||
move.w (a1),d5 ;get dest pixel
|
||
and.w d5,d3 ;compute carry out of lsb
|
||
lsr.w #1,d5 ;get almost 1/2 of it
|
||
and.w d0,d5 ;mask out stragglers
|
||
|
||
add.w d5,d1 ;merge src with dst
|
||
add.w d3,d1 ;propagate carrys
|
||
MOVE.w d1,(a1) ;write pattern to dest
|
||
|
||
@skip2 addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit2 ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Mode: 36 Transparent for 16 bits/pixel
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 =
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 =
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = backColor
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
stTransparent16
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
move.l transColor(A6),D5 ;get a pixel of the transparent color
|
||
|
||
@blit tst.w (A2)+ ;a pixel of the clip region
|
||
BEQ.S @skip
|
||
move.w 0(a3,d6),d1 ;get src pixel
|
||
|
||
cmp.w d1,d5 ;is src backColor?
|
||
beq.s @skip ;yes, don't write to dst
|
||
MOVE.w d1,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
rts
|
||
; BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
Align 4
|
||
|
||
stArith16Tab
|
||
DC.L stAvg16-stArith16Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
||
DC.L stAddPin16-stArith16Tab ;12 PAT + DST --> DST (pin to max)
|
||
DC.L stAddOver16-stArith16Tab ;13 PAT + DST --> DST (no pin)
|
||
DC.L stSubPin16-stArith16Tab ;16 DST - PAT --> DST (pin to min)
|
||
DC.L stTransparent16-stArith16Tab ;18 PAT less bg --> DST
|
||
DC.L stMax16-stArith16Tab ;1A MAX(PAT, DST) --> DST
|
||
DC.L stSubOver16-stArith16Tab ;1C DST - PAT --> DST (no pin)
|
||
DC.L stMin16-stArith16Tab ;1E MIN(PAT, DST) --> DST
|
||
DC.L stHilite-stArith16Tab ;20 (pat as mask) hilite <--> background
|
||
|
||
stArith32Tab
|
||
DC.L stAvg32-stArith32Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
||
DC.L stAddPin32-stArith32Tab ;12 PAT + DST --> DST (pin to max)
|
||
DC.L stAddOver32-stArith32Tab ;13 PAT + DST --> DST (no pin)
|
||
DC.L stSubPin32-stArith32Tab ;16 DST - PAT --> DST (pin to min)
|
||
DC.L stTransparent32-stArith32Tab ;18 PAT less bg --> DST
|
||
DC.L stMax32-stArith32Tab ;1A MAX(PAT, DST) --> DST
|
||
DC.L stSubOver32-stArith32Tab ;1C DST - PAT --> DST (no pin)
|
||
DC.L stMin32-stArith32Tab ;1E MIN(PAT, DST) --> DST
|
||
DC.L stHilite-stArith32Tab ;20 (pat as mask) hilite <--> background
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to BitsToPix. Add support changing baseAddrs.
|
||
; Also check if from paint vector. If so, abort paint vector if VCount=0
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
BitsToPix PROC EXPORT
|
||
|
||
FromPaintVector equ $33EC6
|
||
AbortPaintVector equ $343FC
|
||
ciROMNotScreen equ $30406
|
||
ciROMnot32Bit equ $303CE
|
||
ciROMbase32 equ $30468
|
||
ciROMbase24 equ $30462
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE BitsToPix (XM: XMap; VAR PM: PixMap);
|
||
;
|
||
; See description in ColorAsm.a. This patch allows GDevice base addresses to change
|
||
; when the depth changes.
|
||
;
|
||
cmpRA FromPaintVector,(sp)
|
||
bne.s NormalBitsToPix
|
||
;
|
||
; From PaintVector: We still have paint vector's stack frame
|
||
;
|
||
ParamSize Equ 18
|
||
Vector Equ ParamSize+8-4
|
||
VCount Equ Vector-2
|
||
EoFill Equ VCount-2
|
||
VectRect Equ EoFill-4
|
||
Mode Equ VectRect-2
|
||
Pat Equ Mode-4
|
||
|
||
tst.w VCount(a6) ;number of edges 0?
|
||
bne.s NormalBitsToPix ;no, carry on.
|
||
;
|
||
; Here we caught the case we are looking for.
|
||
; Jump to the end of Bits to Pix which will clean up the stack for us.
|
||
;
|
||
jmpROM AbortPaintVector
|
||
NormalBitsToPix
|
||
MOVEQ #0,D2 ;ASSUME NOT SCREEN
|
||
MOVE ROWBYTES(A1),D0 ;IS SRC A PIXMAP?
|
||
BPL.S DOBITMAP ;=>NO, IT'S A BITMAP
|
||
BTST #isCPort,D0 ;IS IT A COLOR GRAFPORT?
|
||
BEQ.S NOTPORT ;=>NO, NOT A PORT
|
||
|
||
; IT'S A PIXMAP, SEE IF IT'S THE SCREEN
|
||
|
||
MOVE.L BASEADDR(A1),A1 ;GET HANDLE TO PORT'S PIXMAP
|
||
MOVE.L (A1),A1 ;GET POINTER TO PORT'S PIXMAP
|
||
NOTPORT MOVE.L BOUNDS+TOPLEFT(A1),D1 ;RETURN BOUNDS.TOPLEFT IN D1
|
||
MOVE.L ScrnBase,D0 ;GET MainScreen.BASEADDR
|
||
CMP.L BASEADDR(A1),D0 ;IS IT TO THE SCREEN?
|
||
BNE.S COPYPMAP ;=>NO, GO COPY IT
|
||
BRA.S ISSCREEN ;=>ELSE IT IS THE SCREEN
|
||
|
||
; IT'S A BITMAP. SEE IF IT'S THE SCREEN
|
||
|
||
DOBITMAP MOVE.L BOUNDS+TOPLEFT(A1),D1 ;RETURN BOUNDS.TOPLEFT IN D1
|
||
MOVE.L ScrnBase,D0 ;GET MainScreen.BASEADDR
|
||
CMP.L BASEADDR(A1),D0 ;IS BITMAP BASEADDR SAME ?
|
||
beq.s ISSCREEN ;
|
||
jmpROM ciROMNotScreen
|
||
|
||
|
||
ISSCREEN MOVEQ #1,D2 ;SET SCREEN FLAG FOR CALLER
|
||
MOVE.L THEGDEVICE,A0 ;GET HANDLE TO THE GDEVICE
|
||
MOVE.L (A0),A0 ;GET POINTER TO THE GDEVICE
|
||
btst #ext32Device,gdFlags(a0) ;does it need 32-bit addressing?
|
||
beq.s @not32Bit
|
||
moveq #-1,d2 ;is screen and needs 32-bit addressing
|
||
@not32Bit ;
|
||
jmpROM ciROMnot32Bit
|
||
|
||
SpecialBase
|
||
move.l (a1)+,a0 ;get baseAddr
|
||
btst #1,d0 ;is this a handle?
|
||
beq.s @notHand ;no, don't deref
|
||
move.l (a0),a0 ;yes, dereference it
|
||
@notHand btst #2,d0 ;32-bit clean address?
|
||
exg a0,d0 ;get address in d0, don't change cc's
|
||
beq.s base24 ;no flag -> 24-bit addressing
|
||
moveq #-1,d2 ;
|
||
clr.w d2 ;set needs 32-bit addressing flag, not screen
|
||
jmpROM ciROMbase32 ;flag set-> 32-bit addressing
|
||
|
||
; COPY THE SRC TO THE DST
|
||
|
||
COPYPMAP
|
||
move.w pmVersion(a1),d0 ;get baseAddr flags
|
||
bne.s SpecialBase ;if flags set go decide
|
||
MOVE.L (A1)+,d0 ;COPY BASEADDR
|
||
base24 jmpROM ciROMbase24
|
||
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to InitGDevice. Add support for GDevices with baseAddrs that change across
|
||
; depths (Trident card) in a MultiFinder friendly way.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
InitGDevice PROC EXPORT
|
||
|
||
WITH VDPageInfo ;<1.1>
|
||
|
||
ciROMGetDevPixMap EQU $27A30
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE InitGDevice (refNum: INTEGER; mode: LONGINT; GDH: GDHandle);
|
||
;
|
||
; Initialize the specified device to the specified mode. The GDevice
|
||
; data is placed into the provided handle.
|
||
;
|
||
; If mode = -1 then the driver is not called. It is assumed that the pixmap
|
||
; has been set up before InitGDevice is called.
|
||
;
|
||
; CAUTION: this routine is used during ROM boot; various Macintosh functions
|
||
; may not yet be available! <dvb - found out the hard way>
|
||
;
|
||
IGDVars RECORD {A6Link},DECREMENT
|
||
result DS.B 0 ; no result
|
||
REFNUM DS.B 2
|
||
MODE DS.B 4 ; LONG, mode for video card
|
||
GDH DS.B 4 ; LONG, handle to devPort
|
||
return DS.B 4 ; the return address
|
||
A6Link DS.B 4 ; our link
|
||
|
||
IOPBlk DS.B IOVQElSize ; [64] parameter blk for I/O calls
|
||
VidParms DS.B 12 ; [12] size of mode params
|
||
GDHState DS.B 2 ; [word] lock state of GDH
|
||
GDPState DS.B 2 ; [word] lock state of GDP
|
||
SaveDevice DS.B 4 ; [long] saved device handle
|
||
|
||
oldBaseAddr DS.B 4 ; old base address, for later comparison
|
||
oldPort DS.B 4 ; thePort, before we got here
|
||
oldColor DS.B 8 ; a colorSpec used to reinstantiate fg/bk
|
||
|
||
VARSIZE DS.B 0 ; size of locals
|
||
ENDR
|
||
|
||
WITH IGDVars
|
||
|
||
LINK A6,#VARSIZE ; allocate stack frame
|
||
MOVEM.L D3/A2-A4,-(SP) ; save off work registers
|
||
|
||
MOVE.L GDH(A6),A0 ; get the gDevice handle
|
||
_HGetState ; get the current lock state
|
||
MOVE D0,GDHState(A6) ; save the state
|
||
_HLOCK ; and lock down the gDevice
|
||
MOVE.L (A0),A2 ; get pointer to gDevice record
|
||
MOVE.L GDPMap(A2),A0 ; get handle to pixMap
|
||
MOVE.L (A0),A1 ; A1->pixmap
|
||
MOVE.L baseAddr(A1),oldBaseAddr(A6) ; save the base address, for later portfixing
|
||
_HGetState ; get the current lock state of the pixmap
|
||
MOVE D0,GDPState(A6) ; save the state
|
||
_HLOCK ; lock it down
|
||
MOVE.L (A0),A3 ; keep pointer in A3
|
||
MOVE.L theGDevice,SaveDevice(A6) ; save theGDevice
|
||
|
||
TST.B QDExist ; qd around?
|
||
BNE.S @noShield ; no, don't shield cursor
|
||
BTST #screenDevice,gdFlags(A2) ; is it screen (check hi byte with #>8)
|
||
BEQ.S @noShield
|
||
PEA gdRect(A2)
|
||
CLR.L -(SP) ; in global coörds
|
||
_ShieldCursor
|
||
@noShield
|
||
|
||
; initialize the GDevice's mode and refnum
|
||
|
||
MOVE REFNUM(A6),GDRefNum(A2) ; set up RefNum
|
||
MOVE.L MODE(A6),D0 ; get the mode
|
||
CMP.L MinusOne,D0 ; is the mode -1?
|
||
BEQ ModeOK ; if so, then don't call the driver
|
||
|
||
; set up the driver parameter block in case we need to use it
|
||
|
||
LEA IOPBlk(A6),A0 ; point to parameter block
|
||
CLR.L ioCompletion(A0) ; no completion routine
|
||
CLR.W ioVRefNum(A0) ; no volRefNum
|
||
MOVE RefNum(A6),ioRefNum(A0) ; set device's refnum
|
||
LEA VidParms(A6),A1 ; point to params for GetMode
|
||
MOVE.L A1,csParam(A0) ; point to param list
|
||
|
||
CMP.L GDMode(A2),D0 ; has the mode changed?
|
||
BEQ GrayOrColor ; => no, so don't set depth
|
||
MOVE.L D0,GDMode(A2) ; set up mode
|
||
|
||
; setup the gDevice fields for the new screen depth
|
||
|
||
CLR GDCCDepth(A2) ; invalidate cursor depth <C837>
|
||
|
||
MOVEM.L A0/A1,-(SP) ; save these regs
|
||
MOVE REFNUM(A6),-(SP) ; push refnum
|
||
MOVE.L MODE(A6),-(SP) ; push mode
|
||
MOVE.L GDPMap(A2),-(SP) ; pixMap handle
|
||
PEA GDType(A2) ; point to device type
|
||
jsrROM ciROMGetDevPixMap ; read in pixMap from device
|
||
MOVEM.L (SP)+,A0/A1 ; restore them
|
||
|
||
; first, set the mode (A0 points to IOPB, A1 to control parameter block)
|
||
|
||
MOVE #2,csCode(A0) ; csc_GetMode
|
||
|
||
MOVE.L mode(A6),D0 ; get the mode
|
||
MOVE D0,csMode(A1) ; set desired mode
|
||
CLR csPage(A1) ; set page 1
|
||
CLR.L csData(A1) ; no additional data
|
||
|
||
_Control ,IMMED ; SetMode(Mode,Page,Data);
|
||
|
||
; then gray the screen
|
||
|
||
MOVE #5,csCode(A0) ; csc_GrayPage
|
||
_Control ,IMMED ; paint current page gray
|
||
|
||
; set the device to color or monochrome, according to GDFlags
|
||
|
||
GrayOrColor
|
||
MOVE GDFlags(A2),D0 ; get flags word
|
||
NOT D0 ; flip all bits
|
||
AND #1,D0 ; clear all but low bit
|
||
MOVE.B D0,csMode(A1) ; csMode = color/gray scale
|
||
MOVE #6,csCode(A0) ; csc_SetGray
|
||
_Control ,IMMED ; set color or monochrome
|
||
|
||
; if the device has a color table, set the device's color table
|
||
|
||
CMP #ClutType,GDType(A2) ; is there a lookup table?
|
||
BNE.S NoTbl ; =>no, don't set one
|
||
|
||
MOVE.L pmTable(A3),A0 ; get handle to color table
|
||
_HLock ; lock down the color table
|
||
|
||
;+++ LEA VidParms(A6),A1 ; point to params for SetEntries
|
||
MOVE.L (A0),A0 ; get ctabPtr <DAF>
|
||
CLR.W csStart(A1) ; start at zero, use sequence mode <DAF>
|
||
MOVE.W ctSize(A0),csCount(A1) ; for the length of the table <DAF>
|
||
LEA ctTable(A0),A0 ; get pointer to colorspecs <DAF>
|
||
MOVE.L A0,csTable(A1) ; color table pointer is first param <DAF>
|
||
|
||
LEA IOPBlk(A6),A0 ; point to parameter block
|
||
MOVE.W #3,csCode(A0) ; csc_SetEntries
|
||
MOVE.L A1,csParam(A0) ; move addr of parms into block
|
||
|
||
_Control ,IMMED ; SetEntries(ColorTable);
|
||
|
||
MOVE.L pmTable(A3),A0 ; get handle to color table
|
||
_HUnlock ; unlock the color table
|
||
NoTbl
|
||
|
||
; if CLUT or fixed color table, build inverse table
|
||
|
||
CMP #DirectType,GDType(A2) ; should there be an inverse table?
|
||
BEQ.S ModeOK ; =>no inverse table
|
||
|
||
MOVE.L pmTable(A3),-(SP) ; push color table handle
|
||
MOVE.L GDITable(A2),-(SP) ; push inverse table handle
|
||
MOVEQ #4,D0 ; make 4-4-4 inverse tables
|
||
MOVE D0,GDResPref(A2) ; save in GDevice
|
||
MOVE D0,-(SP) ; and push res
|
||
_MakeITable ; and generate table
|
||
|
||
; If this device has not been initialized from the system file, then copy the
|
||
; bounds from the pixMap to the GDRect. Otherwise copy the GDRect to the Bounds.
|
||
|
||
ModeOK
|
||
LEA BOUNDS(A3),A0 ; point to pixmap.bounds <C837>
|
||
LEA GDRECT(A2),A1 ; point to device's global rect
|
||
MOVE GDFlags(A2),D0 ; get the flags word
|
||
BTST #RAMInit,D0 ; initialized from RAM?
|
||
BEQ.S BndsOK ; => no, copy pixMap.bounds to GDRect
|
||
EXG A0,A1 ; else copy GDRect to pixMap.bounds
|
||
BndsOK MOVE.L (A0)+,(A1)+ ; copy topLeft
|
||
MOVE.L (A0)+,(A1)+ ; copy botRight
|
||
|
||
; <dvb 3Jan89>
|
||
; if we're about the main device, then fix all those
|
||
; potentially errant ports.
|
||
;
|
||
TST.B QDExist ; (Unless QuickDraw don't exist)
|
||
BNE @noQD
|
||
MOVE.L portList,D1 ; or if portlist = 0 or -1
|
||
BEQ @noQD
|
||
ADDQ.L #1,D1
|
||
BEQ @noQD
|
||
|
||
BTST #mainScreen,D0 ; is it the main scrn? (flags already in D0)
|
||
BEQ @notMain
|
||
|
||
PEA oldPort(A6) ; Save the current port
|
||
_GetPort
|
||
MOVE.L mainDevice,theGDevice ; and set to the screen
|
||
|
||
MOVE.L PortList,A4 ; A4 = handle to list of ALL ports
|
||
MOVE.L (A4),A4 ; A4->list of all ports
|
||
MOVE (A4),D3 ; D3 = number of ports that exist
|
||
BRA.S @portWalkEnd
|
||
|
||
@portWalkLoop
|
||
MOVE.L PortList,A4
|
||
MOVE.L (A4),A4
|
||
MOVE.L 2(A4,D3.W*4),A4 ; A4 = this port
|
||
MOVE.L A4,-(SP) ; Set to each port in the port list
|
||
_SetPort
|
||
|
||
MOVE.L oldBaseAddr(A6),D1 ; D1 = the scrnbase of ports to change
|
||
BTST #7,portVersion(A4) ; high bit set?
|
||
BEQ.S @oldPort
|
||
MOVE.L portPixMap(A4),A4 ; A4 = handle to the port's pixmap
|
||
MOVE.L (A4),A4 ; A4->port's pixmap
|
||
CMP.L baseAddr(A4),D1 ; same as the screen's?
|
||
BNE.S @portWalkEnd ; no, skip this port
|
||
|
||
MOVE.L baseAddr(A3),baseAddr(A4) ; replace a bunch of fields
|
||
MOVE rowBytes(A3),rowBytes(A4)
|
||
MOVE.L pixelType(A3),pixelType(A4) ; (gets pixelSize, too)
|
||
MOVE.L cmpCount(A3),cmpCount(A4) ; (gets cmpSize, too)
|
||
MOVE.L planeBytes(A3),planeBytes(A4)
|
||
|
||
PEA oldColor(A6) ; placeholder for reinstantiating colors
|
||
MOVE.L (SP),-(SP)
|
||
MOVE.L (SP),-(SP)
|
||
MOVE.L (SP),-(SP)
|
||
_SaveFore ; Save and restore the foreground color
|
||
_RestoreFore ; (Allowing for pmFore)
|
||
_SaveBack ; And the same for the background
|
||
_RestoreBack
|
||
BRA.S @portWalkEnd
|
||
|
||
@oldPort
|
||
CMP.L portBits+baseAddr(A4),D1 ; same base on old port?
|
||
BNE.S @portWalkEnd
|
||
MOVE.L baseAddr(A3),portBits+baseAddr(A4)
|
||
MOVE rowBytes(A3),D1
|
||
AND #nurbMask,D1 ; handle NURBs here
|
||
MOVE D1,portBits+rowBytes(A4)
|
||
|
||
@portWalkEnd
|
||
DBRA D3,@portWalkLoop
|
||
MOVE.L oldPort(A6),-(SP) ; restore the pre-existing port
|
||
_SetPort
|
||
|
||
MOVE.L oldBaseAddr(A6),D1
|
||
CMP.L scrnBase,D1 ; fix scrnBase too, if neede
|
||
BNE.S @notMain
|
||
MOVE.L baseAddr(A3),scrnBase
|
||
|
||
@notMain
|
||
_AllocCursor
|
||
_ShowCursor
|
||
@noQD
|
||
|
||
;
|
||
; notify the Palette Manager that the mode has changed
|
||
;
|
||
; <2.6> moved after GDRect has been adjusted <2.6>
|
||
CMP.L #-1,PMgrHandle ; has the Palette Mgr been initialized?
|
||
BEQ.S @noPMgr ; nope, so skip this
|
||
MOVE.L GDH(A6),-(SP) ; push the device handle
|
||
_RestoreDeviceClut ; call the Palette Manager Unhook device vector
|
||
@noPMgr
|
||
|
||
MOVE.L SaveDevice(A6),theGDevice ; restore theGDevice
|
||
MOVE.L GDPMap(A2),A0 ; get pixMap handle
|
||
MOVE GDPState(A6),D0 ; get the lock state
|
||
_HSetState ; restore prior state
|
||
MOVE.L GDH(A6),A0 ; get the gDevice handle
|
||
MOVE GDHState(A6),D0 ; get the lock state
|
||
_HSetState ; restore prior state
|
||
|
||
MOVEM.L (SP)+,D3/A2-A4 ; restore work registers
|
||
UNLINK result-return-4,'INITGDEV'
|
||
|
||
ENDPROC
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to InitPort. Add support for GDevices with baseAddrs that change across
|
||
; depths (Trident card) in a MultiFinder friendly way.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
OpenPort PROC EXPORT
|
||
IMPORT NewPort,InsPortList
|
||
ciInsPortList EQU $319D0
|
||
ciNewPort EQU $316C0
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE OpenPort(port: GrafPtr);
|
||
; { allocate clipRgn and visRgn, then call InitPort.
|
||
;
|
||
MOVE.L 4(SP),-(SP) ; push grafPort
|
||
MOVE.L (SP),-(SP) ; and a copy for InsPortList
|
||
jsrROM ciNewPort ; and init regions
|
||
jsrROM ciInsPortList ; add port to portlist
|
||
; fall into InitPort
|
||
EXPORT InitPort
|
||
InitPort ; <1.6>
|
||
;-------------------------------------------------------------
|
||
;
|
||
; PROCEDURE InitPort(port: GrafPtr);
|
||
;
|
||
; Initialize all fields of a grafPort
|
||
; Do fields used by cGrafPort first, then call routine for shared fields
|
||
;
|
||
|
||
ciROMGetDevPix EQU $28080
|
||
ciInitPortEntry EQU $31702
|
||
|
||
MOVE.L A2,-(SP) ; save work register
|
||
jsrROM ciROMGetDevPix ;GET DEVICE'S PIXMAP IN A0
|
||
|
||
MOVE.L 8(SP),A2 ; A2 = port param
|
||
LEA PORTBITS(A2),A1 ; POINT TO PORTBITS
|
||
|
||
MOVE PIXELSIZE(A0),D1 ;GET PIXEL DEPTH <BAL/KON> 17DEC89
|
||
MOVE.L (A0)+,(A1)+ ;COPY BASEADDR
|
||
MOVE (A0)+,D2 ;GET ROWBYTES
|
||
AND #nuRBMask,D2 ;CLEAR FLAG BITS
|
||
MOVE D2,D0 ;GET A COPY
|
||
EXT.L D0 ;MAKE SURE LONG FOR DIVIDE
|
||
DIVU D1,D0 ;PRETEND SCREEN IS ONE BIT DEEP
|
||
MOVE D0,(A1)+ ;COPY ROWBYTES
|
||
jmpROM ciInitPortEntry
|
||
|
||
; MOVE.L (A0),(A1)+ ;COPY BOUNDS.TOPLEFT
|
||
; MOVE.L 4(A0),(A1)+ ;COPY BOUNDS.BOTRIGHT <BAL/KON> 17DEC89
|
||
;
|
||
; JSR InitShared ; init shared fields
|
||
|
||
ENDPROC
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to OpenCPort. If called from NewGWorld, save and restore thePort across
|
||
; the call.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
;
|
||
; This patch is in PatchIIciROM.a
|
||
;
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; GWorld patches follow. The equates for the GWorld stuff start here.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
;___________________________________________________________________________
|
||
;
|
||
; QDExtensions Equates -- This file defines the public equates for QuickDraw
|
||
; extensions.
|
||
;___________________________________________________________________________
|
||
|
||
|
||
|
||
; New Error code
|
||
|
||
cDepthErr equ -157 ; invalid pixel depth
|
||
|
||
; Flag bits passed to NewGWorld
|
||
|
||
purgePixBit equ 0 ; make the offscreen buffer purgeable
|
||
noNewDeviceBit equ 1 ; don't create an offscreen device
|
||
useMFTempBit equ 2 ; allocate pixels in MFTemp memory <06Jul89> BAL
|
||
|
||
; Mask equivalents of the above bits
|
||
|
||
purgePixMask equ 1
|
||
noNewDeviceMask equ 2
|
||
useMFTempMask equ 4 ; <07Jul89> JCM
|
||
|
||
; Flag bits passed to or returned by UpdateGWorld
|
||
|
||
mapPixBit equ 16 ; set if color table mapping occurred
|
||
newDepthBit equ 17 ; set if pixels were scaled to a different depth
|
||
alignPixBit equ 18 ; set if pixels were realigned to screen alignment
|
||
newRowBytesBit equ 19 ; set if pixmap was reconfigured in a new rowBytes
|
||
reallocPixBit equ 20 ; set if offscreen buffer had to be reallocated
|
||
clipPixBit equ 28 ; set if pixels were or are to be clipped
|
||
stretchPixBit equ 29 ; set if pixels were or are to be stretched/shrinked
|
||
ditherPixBit equ 30 ; set if pixels were or are to be dithered
|
||
|
||
; Mask equivalents of the above bits
|
||
|
||
mapPixMask equ $10000
|
||
newDepthMask equ $20000
|
||
alignPixMask equ $40000
|
||
newRowBytesMask equ $80000
|
||
reallocPixMask equ $100000
|
||
clipPixMask equ $10000000
|
||
stretchPixMask equ $20000000
|
||
ditherPixMask equ $40000000
|
||
|
||
; Flag bits returned by GetPixelsState and passed to SetPixelsState
|
||
|
||
pixelsLockedBit equ 7 ; pixels are locked
|
||
pixelsPurgeableBit equ 6 ; pixels are purgeable
|
||
|
||
; Mask equivalents of the above bits
|
||
|
||
pixelsLockedMask equ $80
|
||
pixelsPurgeableMask equ $40
|
||
|
||
|
||
|
||
;___________________________________________________________________________
|
||
;
|
||
; Private equates for the additional field in the grafVars structure
|
||
;
|
||
;___________________________________________________________________________
|
||
|
||
attachDevice equ grafVarRec ; [4 bytes] handle to attached gDevice
|
||
devOwned equ attachDevice+4 ; [1 byte] true if NewGWorld created the offscreen device
|
||
useMFTemp equ devOwned+1 ; [1 byte] true if bits are in MultiFinder memory <07Jul89> JCM
|
||
grafVarExtRec equ useMFTemp+1 ; size of extended grafVars structure <07Jul89> JCM
|
||
|
||
|
||
; Bit in portVersion marking a CGrafPort as being a GWorld
|
||
|
||
isGWorldMask equ 1 ; bit 0 set means a CGrafPort is a GWorld
|
||
|
||
; If the portVersion/rowBytes of any port has the following bits set, it is a GWorld
|
||
|
||
GWorldFlag equ $C001 ; isPixMap+isCPort+isGWorld
|
||
|
||
; PixMaps in GWorlds have two possible version numbers
|
||
|
||
PixMapVers0 equ 0 ; marks that baseAddr is a 24-bit pointer <06Jul89> BAL
|
||
PixMapVers1 equ 1 ; marks that baseAddr is a clean derefed handle
|
||
PixMapVers2 equ 2 ; marks that baseAddr is a handle
|
||
PixMapVers4 equ 4 ; marks that baseAddr is a 32-bit pointer <06Jul89> BAL
|
||
|
||
PixMapVers1Bit equ 0 ; marks that baseAddr is a clean derefed handle
|
||
PixMapVers2Bit equ 1 ; marks that baseAddr is a handle
|
||
PixMapVers4Bit equ 2 ; marks that baseAddr is a 32-bit pointer <06Jul89> BAL
|
||
|
||
; As incredible as may seem, srcAverage is not defined in the includes used
|
||
; for building ROM or system code.
|
||
; srcAverage is used by MakeScaleTbl.
|
||
|
||
srcAverage equ $20 ; arithmetic mode average
|
||
|
||
; Define the constant nil to distinguish between scalars and pointers
|
||
|
||
IF &TYPE('Nil') = 'UNDEFINED' THEN
|
||
Nil: Equ 0
|
||
ENDIF
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to NewGWorld. Selector 0 in QDExtDispatcher.
|
||
; If called with noNewDevice bit set, the pix map depth should be taken from the
|
||
; current device.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
PatchNewGWorld PROC EXPORT
|
||
|
||
ciGetPixelDepthFromDevice EQU $3FBBA
|
||
ciCheckPixelShift EQU $3FBCA
|
||
ciParamError EQU $3FEE6
|
||
ciReportError EQU $3FEEE
|
||
ciBadPixelDepth EQU $3FEDE
|
||
ciFindMaxDevice EQU $3FB7C
|
||
|
||
;
|
||
; See description in GWorld.a
|
||
;
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; A6 offsets of parameters after link:
|
||
;
|
||
paramSize equ 22 ; size of parameters
|
||
result equ paramSize+8 ; WORD, QDErr
|
||
offscreenGWorld equ result-4 ; LONG, address of GWorldPtr variable
|
||
pixelDepth equ offscreenGWorld-2 ; WORD, pixel depth
|
||
boundsRect equ pixelDepth-4 ; LONG, address of bound Rectangle
|
||
cTable equ boundsRect-4 ; LONG, handle to color table
|
||
aGDevice equ cTable-4 ; LONG, handle to a device to use as model
|
||
theFlags equ aGDevice-4 ; LONG, flags
|
||
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; A6 offsets of local variables after link:
|
||
;
|
||
|
||
pixelShift equ -2 ; WORD, pixel shift amount
|
||
resPref equ pixelShift-2 ; WORD, device's preferred resolution
|
||
bytesPerRow equ resPref-2 ; WORD, rowBytes of offscreen pixmap
|
||
offscreenBufH equ bytesPerRow-4 ; LONG, handle to the offscreen buffer
|
||
offscreenPixMap equ offscreenBufH-4 ; LONG, handle to the offscreen pixmap
|
||
offscreenCTable equ offscreenPixMap-4 ; LONG, handle to the offscreen color table
|
||
offscreenDevice equ offscreenCTable-4 ; LONG, handle to the offscreen device
|
||
offscreenITable equ offscreenDevice-4 ; LONG, handle to the offscreen inverse table
|
||
offscreenPortH equ offscreenITable-4 ; LONG, handle to the offscreen port
|
||
offscreenPort equ offscreenPortH-4 ; LONG, pointer to the offscreen port
|
||
museDevice equ offscreenPort-4 ; LONG, handle to device used for inspiration
|
||
saveDevice equ museDevice-4 ; LONG, handle to previous current device
|
||
devType equ saveDevice-2 ; WORD, type of device
|
||
horizOffset equ devType-2 ; WORD, alignment of offscreen pixmap to screen
|
||
pixmapBounds equ horizOffset-8 ; Rect, rectangle describing pixmap bounds
|
||
localRect equ pixmapBounds-8 ; Rect, used for portRect (computed from boundsRect)
|
||
varSize equ localRect ; size of local variables
|
||
|
||
;----------------------------------------------------------------------------
|
||
|
||
link a6,#varSize ; allocate local variables
|
||
movem.l d3-d7/a2-a4,-(sp) ; save regs
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Initialize the function result to no error. Optimistically assume that
|
||
; everything will go fine.
|
||
|
||
move #noErr,result(a6) ; flag a successful operation,
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Initialize all offscreen local variables to zero.
|
||
; If an error happens during this function, we deallocate the memory for
|
||
; all allocated offscreen variables.
|
||
|
||
clr.l offscreenBufH(a6) ; handle to offscreen buffer
|
||
clr.l offscreenPixMap(a6) ; handle to offscreen pixmap
|
||
clr.l offscreenCTable(a6) ; handle to cloned color table
|
||
clr.l offscreenDevice(a6) ; handle to offscreen device
|
||
clr.l offscreenITable(a6) ; handle to offscreen device's inverse table
|
||
clr.l offscreenPortH(a6) ; handle to the offscreen port
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Check that the boundsRect is not an empty rectangle.
|
||
; If it is empty, don't do anything.
|
||
;
|
||
clr.b -(sp) ; leave room for Boolean result
|
||
move.l boundsRect(a6),-(sp) ; push address of rectangle on the stack
|
||
_EmptyRect ; check if rectangle is empty or not
|
||
move.b (sp)+,d0 ; look at the result
|
||
bne paramError ; if true, boundsRect is empty, exit with error
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Choose a device as our source of inspiration (muse) to determine
|
||
; default things like gdResPref, color table, etc.
|
||
; Use current device unless pixelDepth = 0 or noNewDeviceBit is set.
|
||
|
||
move.l theGDevice,museDevice(a6) ; get current device
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Allocate memory for port. Do it early on to avoid heap fragmentation.
|
||
; Also, try to allocate it as low as possible in memory.
|
||
; No need to allocate a clear handle, it will be completely filled out by OpenCPort.
|
||
|
||
moveq #portRec,d0 ; size of CGrafPort
|
||
_ResrvMem ; reserve memory in lowest possible location
|
||
bne reportError ; if Memory Manager error, report it and quit
|
||
|
||
moveq #portRec,d0 ; size of CGrafPort
|
||
_NewHandle ; allocate a handle (no need to clear it)
|
||
bne reportError ; if Memory Manager error, report it and quit
|
||
|
||
move.l a0,offscreenPortH(a6) ; save handle to offscreen port
|
||
|
||
_HLock ; lock it down forever
|
||
|
||
move.l (a0),d0 ; get pointer to offscreen port
|
||
_StripAddress ; make it 32-bit fully clean
|
||
move.l d0,offscreenPort(a6) ; save it
|
||
|
||
; Initialize the portVersion field to 0. This field is used in case of
|
||
; memory error to check whether the port has been opened or not (and therefore
|
||
; I need to close it)
|
||
|
||
move.l d0,a0 ; get pointer to port
|
||
clr portVersion(a0) ; clear the portVersion field
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Remember the theFlags in d3
|
||
|
||
move.l theFlags(a6),d3 ; remember for future use
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Check range validity of pixelDepth -- it must be between 0 and 32.
|
||
|
||
move pixelDepth(a6),d7 ; pixel resolution
|
||
beq.s findMaxDevice ; if depth = 0, find max resolution
|
||
cmp #32,d7 ; illegal if > 32
|
||
bhi badPixelDepth ; exit with error
|
||
|
||
;-------------------------------------------------------------------------
|
||
; If pixelDepth is not 0, don't try to align offscreen pixmap to screen
|
||
|
||
clr horizOffset(a6) ; no alignment offset
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Set localRect to the same as boundsRect (later use for portRect, etc.)
|
||
|
||
move.l boundsRect(a6),a0 ; get pointer to boundsRect
|
||
move.l topLeft(a0),localRect+topLeft(a6) ; copy boundsRect to localRect
|
||
move.l botRight(a0),localRect+botRight(a6)
|
||
|
||
; If noNewDeviceBit is set, use the given aGDevice as museDevice.
|
||
; Report an error if it is NIL.
|
||
|
||
btst.l #noNewDeviceBit,d3 ; is noNewDeviceBit set? (d3 contains the flags)
|
||
beq.s @0 ; no, leave museDevice as is
|
||
move.l aGDevice(a6),d0 ; yes, get aGDevice
|
||
beq.s paramError ; if aGDevice is NIL, report a parameter error
|
||
move.l d0,museDevice(a6) ; if not NIL, use it as muse Device
|
||
jmpROM ciGetPixelDepthFromDevice
|
||
; bra.s GetPixelDepthFromDevice ; take the pixel depth from the museDevice <KON 21JUN90>
|
||
@0
|
||
jmpROM ciCheckPixelShift
|
||
|
||
; bra.s checkPixelShift ; skip next part and check pixel resolution
|
||
|
||
paramError
|
||
jmpROM ciParamError
|
||
badPixelDepth
|
||
jmpROM ciBadPixelDepth
|
||
findMaxDevice
|
||
jmpROM ciFindMaxDevice
|
||
reportError
|
||
jmpROM ciReportError
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to UpdateGWorld. Selector 3 in QDExtDispatcher.
|
||
; Altered 'OR' (not MOVE) clip/stretch bit into result.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
; This routine used to jump back into the ROM, but there are so many changes in so many
|
||
; places that I decided to patch the whole thing out. These ROM entry points were used.
|
||
; If disk space is extemely critical, some brave soul could convert it back.
|
||
;
|
||
;ciUpdateGWorld EQU $40290
|
||
;cinothingToDo EQU $403BA
|
||
;ciReallocBuffer EQU $403C2
|
||
;cimapColors EQU $404AC
|
||
;cirealignPixels EQU $403E6
|
||
;ciBadPixelDepth EQU $40A5A
|
||
;ciParamError EQU $40A8A
|
||
;ciROMShiftTable EQU $3FF3A
|
||
|
||
UpdateGWorld PROC EXPORT
|
||
EXPORT paramError
|
||
|
||
FINDINVERSETABLE EQU $3FF60
|
||
USEPALETTEMGR EQU 1
|
||
ciROMShiftTable EQU $3FF3A
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION UpdateGWorld (VAR offscreenGWorld: GWorldPtr; pixelDepth: INTEGER;
|
||
; boundsRect: Rect; cTable: CTabHandle; aGDevice: GDHandle;
|
||
; flags: LONGINT): LONGINT;
|
||
;
|
||
; Update the given graphics world to the new conditions (pixelDepth, boundsRect,
|
||
; color table, and optionally aGDevice).
|
||
;
|
||
; offscreenGWorld is both input and output. A pointer to the new GWorld is returned
|
||
; in offscreenGWorld.
|
||
;
|
||
; Flags determine how the pixels are preserved. It contains the following bits:
|
||
; clipPixBit = clip the pixels to the new boundsRect.
|
||
; stretchPixBit = stretch or shrink the pixels to the new boundsRect.
|
||
; ditherPixBit = dither the pixels
|
||
;
|
||
; clipPixBit and stretchPixBit are mutually exclusive.
|
||
; If flags is 0, no update occurs.
|
||
; Possible combinations are:
|
||
; 0, clipPixMask, stretchPixMask, clipPixMask+ditherPixMask, stretchPixMask+ditherPixMask
|
||
;
|
||
; PixelDepth, boundsRect, and cTable work in the same way as in NewGWorld.
|
||
;
|
||
; If aGDevice is not NIL, pixelDepth and cTable are ignored, and aGDevice's pixel depth
|
||
; and color table are used instead.
|
||
;
|
||
; If offscreenGWorld doesn't have an offscreen device and aGDevice is not NIL, aGDevice
|
||
; becomes the new attached device.
|
||
;
|
||
; UpdateGWorld returns an error code if it failed, 0 if it didn't do anything, and
|
||
; a positive number if it succeeded. This number describes what actions UpdateGWorld performed
|
||
; with the following bits:
|
||
;
|
||
; mapPixBit = set if color table mapping occurred
|
||
; newDepthBit = set if pixels were scaled to a different depth
|
||
; alignPixBit = set if pixels were realigned to screen alignment
|
||
; newRowBytesBit = set if pixmap was reconfigured in a new rowBytes
|
||
; reallocPixBit = set if offscreen buffer had to be reallocated
|
||
; clipPixBit = set if pixels were or are to be clipped
|
||
; stretchPixBit = set if pixels were or are to be stretched/shrinked
|
||
; ditherPixBit = set if pixels were or are to be dithered
|
||
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; A6 offsets of parameters after link:
|
||
;
|
||
paramSize equ 22 ; size of parameters
|
||
result equ paramSize+8 ; LONG, QDErr or flags
|
||
offscreenGWorld equ result-4 ; LONG, address of offscreen GWorldPtr variable
|
||
pixelDepth equ offscreenGWorld-2 ; WORD, new pixel depth
|
||
boundsRect equ pixelDepth-4 ; LONG, address of new bound Rectangle
|
||
cTable equ boundsRect-4 ; LONG, handle to new color table
|
||
aGDevice equ cTable-4 ; LONG, handle to device to use instead of pixelDepth and cTable
|
||
gDevflags equ aGDevice-4 ; LONG, defines pixel transfer
|
||
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; A6 offsets of local variables after link:
|
||
;
|
||
|
||
newGWorld equ -4 ; LONG, new offscreen GWorld
|
||
clipSrcRect equ newGWorld-8 ; Rect, srcRect clipped
|
||
clipDstRect equ clipSrcRect-8 ; Rect, same size as srcRect, but in dstRect coordinates
|
||
newFlags equ clipDstRect-4 ; LONG, contains purgePixBit and noNewDeviceBit
|
||
state equ newFlags-4 ; LONG, lock/purge state of pixels
|
||
purged equ state-1 ; BYTE, true if offscreen buffer has been purged
|
||
sameBounds equ purged-1 ; BYTE, true if the portRects of old and new gworlds are the same
|
||
mode equ sameBounds-2 ; WORD, transfer mode used by CopyBits
|
||
savePort equ mode-4 ; LONG, pointer to saved port
|
||
saveDevice equ savePort-4 ; LONG, handle to saved device
|
||
newBounds equ saveDevice-8 ; Rect, boundsRect converted to portRect
|
||
pixSize equ newBounds-2 ; WORD, pixel size of new offscreen gworld
|
||
colTabSeed equ pixSize-4 ; LONG, seed of new offscreen gworld's color table
|
||
horizOffset equ colTabSeed-2 ; WORD, alignment of new offscreen pixmap
|
||
newRowBytes equ horizOffset-2 ; WORD, rowBytes of new offscreen gworld
|
||
reserved equ newRowBytes-2 ; WORD, (match the ROM version of this stack frame)
|
||
saveStack equ reserved-4 ; LONG, copy of stack pointer after saving the register
|
||
maxDevice equ saveStack-4 ; LONG, handle to max device if pixelDepth = 0
|
||
newCTable equ maxDevice-4 ; LONG, handle to the new color table
|
||
newITable equ newCTable-4 ; LONG, handle to the new inverse table
|
||
resPref equ newITable-2 ; WORD, preferred resolution for inverse table
|
||
oldBufSize equ resPref-4 ; LONG, size of old offscreen buffer
|
||
saveForeColor equ oldBufSize-colorSpecSize ; ColorSpec, saved fg RGB color
|
||
saveBackColor equ saveForeColor-colorSpecSize ; ColorSpec, saved bk RGB color
|
||
saveClip equ saveBackColor-4 ; LONG, handle to saved clip region
|
||
varSize equ saveClip ; size of local variables
|
||
|
||
;----------------------------------------------------------------------------
|
||
|
||
link a6,#varSize ; allocate local variables
|
||
movem.l a2-a4/d5-d7,-(sp) ; save regs
|
||
move.l sp,saveStack(a6) ; save the stack pointer
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Initialize the flags
|
||
|
||
clr.l result(a6) ; Assume no error and nothing to do
|
||
clr.l newFlags(a6) ; initialize flags for NewGWorld
|
||
|
||
; Check that no other bit than clipPixBit, stretchPixBit and ditherPixBit are set
|
||
|
||
move.l gDevFlags(a6),d0 ; get the flags
|
||
and.l #~(clipPixMask+stretchPixMask+ditherPixMask),d0 ; clear clipPixBit, stretchPixBit, ditherPixBit
|
||
tst.l d0 ; is any other bit set?
|
||
bne paramError ; yes, report a parameter error and quit
|
||
|
||
; Check that clipPixBit and stretchPixBit are not both set in the flags
|
||
|
||
move.l gDevFlags(a6),d0 ; get the flags
|
||
and.l #clipPixMask+stretchPixMask,d0 ; get clipPixBit and stretchPixBit
|
||
cmp.l #clipPixMask+stretchPixMask,d0 ; if both bit are set, quit with parameter error
|
||
beq paramError ; report error and quit
|
||
|
||
; Check that if ditherPixBit is set, one of clipPixBit or stretchPixBit is also set
|
||
|
||
move.l gDevFlags(a6),d0 ; get the flags
|
||
btst.l #ditherPixBit,d0 ; is ditherPixBit set?
|
||
beq getOffGWorld ; no, skip this
|
||
and.l #clipPixMask+stretchPixMask,d0 ; is one those bits set?
|
||
beq paramError ; nope, they're both 0, report error and quit
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Remember pointer to offscreen GWorld
|
||
|
||
getOffGWorld
|
||
move.l ([offscreenGWorld,a6]),a3 ; get pointer to offscreen GWorld
|
||
|
||
; Save the current graphics world
|
||
|
||
pea savePort(a6) ; push address of savePort
|
||
pea saveDevice(a6) ; push address of saveDevice
|
||
_GetGWorld ; get current graphics world
|
||
|
||
;----------------------------------------------------------------------------
|
||
; If aGDevice is not NIL, use its depth and color table
|
||
|
||
checkAGDevice
|
||
move.l aGDevice(a6),d0 ; get handle to aGDevice
|
||
beq.s getNewParms ; it's NIL, don't do anything with it
|
||
|
||
move.l d0,a0 ; get handle in a0
|
||
move.l (a0),a0 ; get pointer to aGDevice
|
||
move.l ([gdPMap,a0]),a0 ; get pointer to its pixmap
|
||
move pixelSize(a0),pixelDepth(a6) ; use its pixelSize
|
||
move.l pmTable(a0),cTable(a6) ; and its color table
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Compute new portRect and get new pixSize and color table seed for new offscreen graphics world
|
||
|
||
getNewParms
|
||
move.l boundsRect(a6),a0 ; get pointer to boundsRect
|
||
|
||
; Check range validity of pixelDepth -- it must be between 0 and 32.
|
||
|
||
move pixelDepth(a6),d7 ; pixel resolution
|
||
beq.s useMaxDevice ; if depth = 0, find max resolution
|
||
cmp #32,d7 ; illegal if > 32
|
||
bhi badPixelDepth ; exit with error
|
||
bra.s boundsIsLocal ; no, just copy boundsRect as is
|
||
|
||
;----------------------------------------------------------------------------
|
||
; If pixelDepth = 0:
|
||
; Offset boundsRect in newBounds so that topLeft = (0,0)
|
||
|
||
useMaxDevice
|
||
clr.l newBounds+topLeft(a6)
|
||
move bottom(a0),d0 ; compute newBounds.bottom = boundsRect->bottom - boundsRect->top
|
||
sub top(a0),d0
|
||
move d0,newBounds+bottom(a6)
|
||
move right(a0),d0 ; compute newBounds.right = boundsRect->right - boundsRect->left
|
||
sub left(a0),d0
|
||
move d0,newBounds+right(a6)
|
||
|
||
; Get pixSize from max device
|
||
|
||
clr.l -(sp) ; leave room for GDHandle result
|
||
move.l boundsRect(a6),-(sp) ; pass boundsRect as a global rect in screen space
|
||
_GetMaxDevice ; find deepest device that intersects boundsRect
|
||
move.l (sp)+,d0 ; get handle to max device <KON 6JUN90>
|
||
beq paramError ; if NIL, exit <KON 6JUN90>
|
||
move.l d0,a0 ; <KON 6JUN90>
|
||
move.l a0,maxDevice(a6) ; remember max device
|
||
|
||
move.l (a0),a1 ; get pointer to device
|
||
move.l ([gdPMap,a1]),a0 ; get pointer to its pixmap
|
||
move pixelSize(a0),pixSize(a6) ; get its pixel size
|
||
|
||
; Get color table seed from max device
|
||
|
||
move.l ([pmTable,a0]),a0 ; get pointer to color table
|
||
move.l ctSeed(a0),colTabSeed(a6) ; get its color table seed
|
||
|
||
; Get new pixmap alignment with the max device
|
||
|
||
move.l boundsRect(a6),a0 ; get pointer to boundsRect
|
||
move left(a0),d0 ; get left coordinate of boundsRect
|
||
sub gdRect+left(a1),d0 ; subtract left coordinate of device rectangle
|
||
move d0,horizOffset(a6) ; save offset
|
||
|
||
bra.s checkPixShift
|
||
|
||
;----------------------------------------------------------------------------
|
||
; If pixelDepth is not 0:
|
||
; Copy boundsRect to newBounds without modification
|
||
|
||
boundsIsLocal
|
||
move.l topLeft(a0),newBounds+topLeft(a6) ; copy boundsRect to newBounds
|
||
move.l botRight(a0),newBounds+botRight(a6)
|
||
|
||
; Alignment is 0
|
||
|
||
clr horizOffset(a6) ; no alignment if boundsRect is not global
|
||
|
||
; PixSize = pixelDepth
|
||
|
||
move pixelDepth(a6),pixSize(a6) ; if pixDepth is not 0, pixSize = pixelDepth
|
||
|
||
; If cTable is not 0, get its seed
|
||
|
||
move.l cTable(a6),d0 ; get handle to color table
|
||
beq.s noCTable ; if cTable is 0, use default seed
|
||
|
||
move.l d0,a0 ; get handle to color table
|
||
move.l (a0),a0 ; get pointer to color table
|
||
move.l ctSeed(a0),colTabSeed(a6) ; get color table seed
|
||
bra.s checkPixShift
|
||
|
||
; If cTable is 0, the color table seed is cmpCnt * cmpSize
|
||
|
||
noCtable
|
||
move pixelDepth(a6),d0 ; get pixel depth
|
||
cmp #16,d0 ; is it 16 bits/pixel?
|
||
bne.s check32 ; no, check to see if it is 32 bits/pixel
|
||
|
||
move #3*5,d0 ; if 16 bits/pixel, cmpCnt * cmpSize = 3 * 5
|
||
bra.s setCtSeed
|
||
|
||
check32 cmp #32,d0 ; is it 32 bits/pixel?
|
||
bne.s setCTSeed ; no, then pixelDepth = cmpCnt * cmpSize
|
||
|
||
move #3*8,d0 ; if 32 bits/pixel, cmpCnt * cmpSize = 3 * 8
|
||
|
||
setCtSeed
|
||
ext.l d0 ; convert to long
|
||
move.l d0,colTabSeed(a6) ; remember color table seed
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Convert pixel depth to shift amount
|
||
; Use ShiftTbl for conversion
|
||
|
||
checkPixShift
|
||
move pixSize(a6),d7 ; get pixel size
|
||
leaROM ciROMShiftTable,a0 ; table to convert pixSize to pixelShift (exponent of 2)
|
||
moveq #0,d0 ; clear high byte
|
||
move.b 0(a0,d7),d7 ; fetch table
|
||
bmi badPixelDepth ; if table returned -1, pixelDepth is invalid, exit w/error
|
||
|
||
; Convert horizOffset to a number of pixels such that the equivalent number of bits is modulo 32
|
||
|
||
move horizOffset(a6),d0 ; get horizontal offset in pixels
|
||
lsl d7,d0 ; convert to bits
|
||
and #$1f,d0 ; offset modulo 32
|
||
lsr d7,d0 ; convert back to pixels
|
||
move d0,horizOffset(a6) ; save back in horizOffset <19Jun89> JCM
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Get rowBytes from old pixmap, assume it will not change
|
||
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to old pixmap
|
||
move rowBytes(a0),d0 ; get rowBytes
|
||
and #nuRBMask,d0 ; strip off flags
|
||
move d0,newRowBytes(a6) ; assume rowBytes doesn't change
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Compare the portRects of the old and new world.
|
||
; If same, set the sameBounds flag
|
||
|
||
clr.b sameBounds(a6) ; assume portRects are different
|
||
move.l portRect+topLeft(a3),d0 ; get the topLeft coordinates of the old gworld
|
||
cmp.l newBounds+topLeft(a6),d0 ; compare with topLeft coordinates of new gworld
|
||
bne.s compareSize
|
||
move.l portRect+botRight(a3),d0 ; get the botRight coordinates of the old gworld
|
||
cmp.l newBounds+botRight(a6),d0 ; compare with botRight coordinates of new gworld
|
||
bne.s compareSize
|
||
|
||
move.b #true,sameBounds(a6) ; rectangles are equal, set the sameBounds flag
|
||
bra checkAlignment ; skip comparing size
|
||
|
||
;----------------------------------------------------------------------------
|
||
; If different size, set clipPixBit or stretchPixBit depending on flags
|
||
|
||
compareSize
|
||
move portRect+right(a3),d0 ; calculate old port's width (a3 = old GWorldPtr)
|
||
sub portRect+left(a3),d0
|
||
move newBounds+right(a6),d1 ; calculate new port's width
|
||
sub newBounds+left(a6),d1
|
||
cmp d0,d1 ; are widths the same?
|
||
bne.s checkRowBytes ; no, check the rowBytes
|
||
|
||
move portRect+bottom(a3),d0 ; calculate old port's height
|
||
sub portRect+top(a3),d0
|
||
move newBounds+bottom(a6),d1 ; calculate new port's height
|
||
sub newBounds+top(a6),d1
|
||
cmp d0,d1 ; are heights the same?
|
||
beq.s checkAlignment ; yes, portRect's are same size, no clipping/stretching
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Compute rowBytes of new world.
|
||
; Compare the rowBytes of the old and new world.
|
||
; If different, set newRowBytes bit
|
||
; Then, set the clipPixBit or stretchPixBit
|
||
|
||
checkRowBytes
|
||
move newBounds+right(a6),d0 ; compute pixmap.bounds.right - pixmap.bounds.left
|
||
sub newBounds+left(a6),d0 ; don't take into account alignment
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Allocate the actual offscreen buffer.
|
||
; rowBytes is computed as the smallest number of longs containing one line of pixel + 31 bits,
|
||
; converted to bytes:
|
||
; (((localRect.right - localRect.left) * pixelSize + 31 + 31) / 32) * 4
|
||
;
|
||
; NOTE 1: Adding 31 bits gives us some leg room if we want to realign the pixmap in UpdateGWorld.
|
||
; The additional 31 bits are to force a round-up top the next long (as usual).
|
||
; NOTE 2: localRect is used instead of pixmapBounds because rowBytes is computed independently
|
||
; of the current alignment but for all possible alignments.
|
||
; NOTE 3: The above formula for rowBytes can be simplified in:
|
||
; (((localRect.right-localRect.left) * pixelSize + 30) / 32 + 1) * 4
|
||
|
||
ext.l d0 ; convert to long
|
||
lsl.l d7,d0 ; convert pixels to bits (pixShift is in d7)
|
||
add.l #30,d0 ; add 30 bits as per simplified formula above
|
||
lsr.l #5,d0 ; convert bits to longs
|
||
addq #1,d0 ; add one long as per simplified formula above
|
||
lsl.l #2,d0 ; convert longs to bytes
|
||
move d0,newRowBytes(a6) ; save # of bytes in a row
|
||
|
||
; Compare the rowBytes of the old and new world and set the newRowBytesBit if different
|
||
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to old pixmap
|
||
move rowBytes(a0),d1 ; get rowBytes
|
||
and #nuRBMask,d1 ; mask out flags
|
||
cmp d1,d0 ; if different, set newRowBytes bit
|
||
beq.s setClipStretchBit ; same rowBytes, don't set newRowBytes bit
|
||
or.l #newRowBytesMask,result(a6) ; set newRowBytes bit
|
||
|
||
;----------------------------------------------------------------------------
|
||
; PortRects of old and new world are of different sizes, decide between clip and stretch
|
||
|
||
setClipStretchBit
|
||
move.l gDevFlags(a6),d0 ; get flags
|
||
and.l #clipPixMask,d0 ; is the clipPixBit set?
|
||
bne.s @0 ; yes, use clipping
|
||
move.l #stretchPixMask,d0 ; no, use stretching
|
||
@0
|
||
or.l d0,result(a6) ; store bits in result <1.6>
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Compare the left coordinates of the portPixMap->bounds of the old and new world.
|
||
; If different, assume alignment is taking place (don't bother getting with
|
||
; max area device and checking that alignment might still be the same)
|
||
|
||
checkAlignment
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to old pixmap
|
||
move bounds+left(a0),d0 ; get bounds.left of old pixmap
|
||
move horizOffset(a6),d1 ; get alignment of new pixmap
|
||
neg d1 ; the algebraic opposite is the bounds.left of the new pixmap
|
||
cmp d1,d0 ; compare them both
|
||
beq.s checkPixelDepth ; identical, no alignment
|
||
or.l #alignPixMask,result(a6) ; different, set alignment bit
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Compare the pixel depths of the old and new world. If different, set the scalePixelsBit
|
||
|
||
checkPixelDepth
|
||
move #srcCopy,mode(a6) ; initialize transfer mode to srcCopy
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to old pixmap again (if got here directly)
|
||
move pixelSize(a0),d0 ; get pixel size of old pixmap
|
||
cmp pixSize(a6),d0 ; compare with pixel size of new pixmap
|
||
beq.s checkColTable ; identical, no scaling
|
||
or.l #newDepthMask,result(a6) ; different, set scaling bit
|
||
|
||
move.l gDevFlags(a6),d0 ; get flags
|
||
and.l #ditherPixMask,d0 ; get dither bit
|
||
beq.s @0 ; dither bit not set, don't change transfer mode
|
||
move #64,mode(a6) ; dither bit set, use dither mode
|
||
or.l #ditherPixMask,result(a6) ; and set ditherPixBit in result
|
||
@0
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Compare the color table seeds. If different, set the mapPixelsBit
|
||
|
||
checkColTable
|
||
move.l ([pmTable,a0]),a0 ; get pointer to old color table
|
||
move.l ctSeed(a0),d0 ; get old seed
|
||
cmp.l colTabSeed(a6),d0 ; compare with new seed
|
||
beq.s getState ; identical, no color mapping
|
||
or.l #mapPixMask,result(a6) ; different, set mapping bit
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Get state of offscreen buffer
|
||
|
||
getState
|
||
clr.l -(sp) ; leave room for flags result
|
||
move.l portPixMap(a3),-(sp) ; push handle to pixmap
|
||
_GetPixelsState ; get state of pixels
|
||
move.l (sp)+,d0 ; get the result
|
||
move.l d0,state(a6) ; remember it for later
|
||
|
||
; Prevent purging of the offscreen buffer for the time of UpdateGWorld
|
||
|
||
move.l portPixMap(a3),-(sp) ; push handle to pixmap
|
||
_NoPurgePixels ; don't purge the pixels
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Set purgePixBit in the flags for NewGWorld if the pixels are purgeable or purged
|
||
; Set reallocPixBit in the result of UpdateGWorld if the pixels are purged
|
||
|
||
clr.b purged(a6) ; assume pixels aren't purged
|
||
|
||
clr.l -(sp) ; leave room for Ptr result
|
||
move.l portPixMap(a3),-(sp) ; push handle to pixmap
|
||
_GetPixBaseAddr ; get address of offscreen buffer
|
||
move.l (sp)+,d0 ; put it in d0
|
||
bne.s notPurged ; offscreen buffer hasn't been purged
|
||
|
||
or.l #purgePixMask,newFlags(a6) ; offscreen buffer is purged, it means it's purgeable
|
||
or.l #reallocPixMask,result(a6) ; flag that we had to reallocate the pixels
|
||
|
||
; Remember that offscreen buffer is purged.
|
||
; GetPixelsState returns an error if the offscreen buffer is purged.
|
||
; Changed the result of GetPixelsState to a long with the purge bit set.
|
||
; (lock bit wasn't set before the purge or buffer wouldn't have been purged)
|
||
|
||
move.b #true,purged(a6) ; remember that offscreen buffer is purged
|
||
move.l #pixelsPurgeableMask,state(a6) ; if the pixels are purged, recompute state
|
||
|
||
bra.s testNoDevice
|
||
|
||
notPurged
|
||
move.l state(a6),d0 ; get the state of the pixels
|
||
btst.l #pixelsPurgeableBit,d0 ; is the pixelsPurgeableBit set?
|
||
beq.s testNoDevice ; no, don't set purgePixBit in the flags
|
||
|
||
or.l #purgePixMask,newFlags(a6) ; offscreen buffer is purgeable, set the purgePixBit
|
||
|
||
; If the attached device is not owned by the offscreen GWorld,
|
||
; set noNewDeviceBit in the flags for NewGWorld.
|
||
|
||
testNoDevice
|
||
move.l ([grafVars,a3]),a0 ; get pointer to grafVars (a3 = old GWorldPtr)
|
||
move.b devOwned(a0),d0 ; get devOwned flag
|
||
bne.s testMFTempPixels ; device is owned, don't set noNewDeviceBit <07Jul89> JCM
|
||
or.l #noNewDeviceMask,newFlags(a6) ; device is not owned, set noNewDeviceBit
|
||
|
||
; If the pixels are allocated in MultiFinder temp memory (as indicated in the <07Jul89> JCM
|
||
; grafVars), set the useMFTempBit in the flags for NewGWorld. <07Jul89> JCM
|
||
|
||
testMFTempPixels
|
||
tst.b useMFTemp(a0) ; test useMFTemp flag in grafVars <07Jul89> JCM
|
||
beq.s dispatchFlags ; not set, don't set useMFTempBit <07Jul89> JCM
|
||
or.l #useMFTempMask,newFlags(a6) ; set useMFTempBit <07Jul89> JCM
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Look at the result flags and find if we can use optimized algorithms
|
||
; Currently optimized cases are:
|
||
; 0. Nothing needs to be done (just exit and return 0)
|
||
; 1. Pixels have been purged (nothing else changes)
|
||
; 2. Color Table changes (nothing else changes, not even pixel depth)
|
||
; 3. Pixels need to be realigned (but boundsRect's size doesn't change)
|
||
|
||
dispatchFlags
|
||
move.l result(a6),d0 ; get the result flags
|
||
beq.s nothingToDo ; if no bit set, there is nothing to do
|
||
|
||
cmp.l #reallocPixMask,d0 ; is reallocPixBit the only bit set?
|
||
beq.s reallocBuffer ; yes, just reallocate the offscreen buffer
|
||
|
||
; The following cases are relevant only if the pixels are to be preserved
|
||
; If the pixels are not to be preserved, just dispose of the old gworld and create a new one
|
||
|
||
tst.l gDevFlags(a6) ; is any update flag set?
|
||
beq updatePixels ; nope, go dispose of old gworld and create a new one
|
||
|
||
cmp.l #mapPixMask,d0 ; is mapPixBit the only bit set?
|
||
bne.s @0 ; no, can't just do color mapping
|
||
tst.b sameBounds(a6) ; are the bounds of both gworlds the same
|
||
beq.s @0 ; no, can't just do color mapping
|
||
cmp #4,d7 ; is the pixel resolution <16 (pixShift < 4)
|
||
blt mapColors ; yes, just have to do a color mapping with same pixel depth
|
||
@0
|
||
cmp.l #alignPixMask,d0 ; is alignPixBit the only bit set?
|
||
beq.s realignPixels ; yes, just realign the pixels and pixmap
|
||
|
||
bra updatePixels ; none of these cases apply, use regular case
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Nothing at all has changed in the offscreen gworld.
|
||
|
||
nothingToDo
|
||
move.l a3,newGWorld(a6) ; that's it, we already have the new gworld
|
||
|
||
bra setState ; set the state of the offscreen buffer and quit
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Nothing has changed in the offscreen gworld except that the pixels have been purged
|
||
; Reallocate them and put the handle in the baseAddr of the pixmap.
|
||
; NOTE: If the pixels are purged, the pmVersion of the pixmap is always PixMapVers2 (LockPixels
|
||
; doesn't set the pmVersion to PixMapVers1 if the pixels are purged), therefore, the handle
|
||
; is the appropriate thing to put in the baseAddr.
|
||
|
||
reallocBuffer
|
||
move newBounds+bottom(a6),d0 ; compute height = bottom-top
|
||
sub newBounds+top(a6),d0
|
||
mulu.w newRowBytes(a6),d0 ; compute height * rowBytes
|
||
|
||
move.l ([portPixMap,a3]),a1 ; get pointer to offscreen pixmap <06Jul89> BAL
|
||
move.l baseAddr(a1),a0 ; get handle to offscreen buffer from offscreen pixmap <06Jul89> BAL
|
||
_ReallocHandle ; allocate offscreen buffer (could be in MFTemp memory) <06Jul89> BAL
|
||
bne reportError ; if Memory Manager error, report it and quit
|
||
|
||
_MoveHHi ; move the buffer as high as possible in memory
|
||
|
||
move.l a3,newGWorld(a6) ; that's it, we already have the new gworld
|
||
|
||
bra setState ; set the state of the offscreen buffer and quit
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Nothing has changed in the offscreen gworld except that the boundsRect
|
||
; has been moved around (while keeping the same size).
|
||
; The algorithm realigns all the pixels. No mask is used for the edges because they
|
||
; contain unused pixels.
|
||
|
||
realignPixels
|
||
|
||
; Get the address of the pixels
|
||
|
||
clr.l -(sp) ; leave room for Ptr result
|
||
move.l portPixMap(a3),-(sp) ; push handle to pixmap
|
||
_GetPixBaseAddr ; get address of pixels
|
||
move.l (sp)+,a1 ; keep address in a1
|
||
|
||
; Get pointer past end of pixels
|
||
|
||
move newBounds+bottom(a6),d0 ; compute height
|
||
sub newBounds+top(a6),d0
|
||
move newRowBytes(a6),d1 ; get rowBytes
|
||
mulu.w d1,d0 ; compute size of offscreen buffer
|
||
move.l a1,a4 ; get starting address
|
||
add.l d0,a4 ; compute end of offscreen buffer + 1
|
||
|
||
; Compute alignment difference between old gworld and new gworld:
|
||
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to offscreen pixmap
|
||
move bounds+left(a0),d6 ; get left coordinate (= -alignment)
|
||
neg d6 ; get old alignment
|
||
sub horizOffset(a6),d6 ; subtract new alignment
|
||
ext.l d6 ; convert to long
|
||
lsl.l d7,d6 ; convert from pixels to bits
|
||
blt.s goBackwards ; go backwards if alignment difference negative
|
||
|
||
; If alignment difference is positive, go from beginning to end of buffer
|
||
|
||
@nxtLong
|
||
bfextu (a1){d6:0},d0 ; get one long of pixels at new alignment
|
||
move.l d0,(a1)+ ; store back in pixmap in the correct location
|
||
cmp.l a4,a1 ; are we at the limit?
|
||
blt.s @nxtLong ; no, get a new long and continue
|
||
|
||
bra.s updateTheRects ; go update the pixmap's bounds, portRect and gdRect
|
||
|
||
; If alignment difference is negative, go from end to beginning of buffer
|
||
|
||
goBackwards
|
||
sub.l #32,d6 ; extract at one long earlier because of the predecrement used below
|
||
|
||
@nxtLong
|
||
bfextu (a4){d6:0},d0 ; get one long of pixels at new alignment
|
||
move.l d0,-(a4) ; store back in pixmap in the correct location
|
||
cmp.l a4,a1 ; have we reached the beginning of the buffer?
|
||
blt.s @nxtLong ; no, continue
|
||
|
||
; Update the port pixmap's bounds to the newBounds with alignment
|
||
|
||
updateTheRects
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to pixmap
|
||
move newBounds+top(a6),bounds+top(a0) ; put new bounds.top
|
||
move newBounds+left(a6),d0 ; compute left coordinate with alignment
|
||
sub horizOffset(a6),d0
|
||
move d0,bounds+left(a0) ; put new bounds.left
|
||
move.l newBounds+botRight(a6),bounds+botRight(a0) ; put new bounds.botRight
|
||
|
||
; Update the port's portRect to the newBounds without alignment
|
||
|
||
move.l newBounds+topLeft(a6),portRect+topLeft(a3) ; copy newBounds to portRect
|
||
move.l newBounds+botRight(a6),portRect+botRight(a3)
|
||
|
||
; Set visible region of offscreen port to portRect
|
||
|
||
move.l visRgn(a3),-(sp) ; push handle to visRgn
|
||
pea portRect(a3) ; push address of portRect
|
||
_RectRgn ; make visRgn = portRect
|
||
|
||
; Return the old GWorld into the newGWorld
|
||
|
||
move.l a3,newGWorld(a6) ; GWorld hasn't changed
|
||
|
||
; If the attached device is owned by the GWorld, update its pixmap's bounds and gdRect
|
||
|
||
move.l ([grafVars,a3]),a1 ; get pointer to grafVars (a3 = old GWorldPtr)
|
||
move.b devOwned(a1),d0 ; get devOwned flag
|
||
beq setState ; device is not owned, we're done, go set the pixels' state and quit
|
||
|
||
move.l ([attachDevice,a1]),a1 ; get the pointer to the offscreen device attached
|
||
move.l bounds+topLeft(a0),gdRect+topLeft(a1) ; copy port's pixmap's bounds to gdRect
|
||
move.l bounds+botRight(a0),gdRect+botRight(a1)
|
||
|
||
move.l ([gdPMap,a1]),a1 ; get pointer to device's pixmap
|
||
move.l bounds+topLeft(a0),bounds+topLeft(a1) ; copy port's pixmap's bounds to device's pixmap's bounds
|
||
move.l bounds+botRight(a0),bounds+botRight(a1)
|
||
|
||
bra setState ; we're done, go set the state of the offscreen buffer and quit
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Nothing has changed in the offscreen gworld except the color table
|
||
; Do things differently if the gworld owns the attached device or not
|
||
|
||
mapColors
|
||
move.l theGDevice,saveDevice(a6) ; save the current device
|
||
|
||
move.l a3,newGWorld(a6) ; new offscreen gworld is same as old one
|
||
|
||
move.l ([grafVars,a3]),a4 ; get pointer to grafVars structure
|
||
|
||
; Set the current GWorld to the old (same as new) GWorld for Palette Manager calls
|
||
|
||
move.l a3,-(sp) ; push pointer to old offscreen gworld
|
||
clr.l -(sp) ; use attached device
|
||
_SetGWorld ; set current port and device to old world
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Save Foreground and Background colors before the color mapping
|
||
|
||
; If Palette Manager is there, use SaveFore and SaveBack to save fg and bk colors
|
||
|
||
if UsePaletteMgr then
|
||
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_SaveFore ; get foreground color from Palette Manager
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_SaveBack ; get background color from Palette Manager
|
||
|
||
; If Palette Manager is not there, use GetForeColor and GetBackColor instead
|
||
|
||
else
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_GetForeColor ; get foreground color from port
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_GetBackColor ; get background color from port
|
||
endif
|
||
|
||
; Check whether the attached device was created by NewGWorld or not
|
||
|
||
move.l newFlags(a6),d0 ; get the flags for NewGWorld
|
||
and.l #noNewDeviceMask,d0 ; extract noNewDeviceBit
|
||
beq.s updateDevice ; noNewDeviceBit is clear, update the existing attached device
|
||
|
||
;----------------------------------------------------------------------------
|
||
; If the noNewDeviceBit is set in the flags for NewGWorld:
|
||
; set aGDevice as the new current device
|
||
; call MakeScaleTbl to make a scale table between the old and the new color table
|
||
; dispose of the old device (if previous current device was old device, change it to aGDevice)
|
||
; use aGDevice as the new attached device
|
||
; put the handle to the new color table into the port's pixmap's pmTable field
|
||
|
||
move.l aGDevice(a6),theGDevice ; set aGDevice as the new current device
|
||
|
||
move.l ([portPixMap,a3]),-(sp) ; push pointer to offscreen pixmap
|
||
move #srcAverage,-(sp) ; pass srcAverage as the mode for MakeScaleTbl
|
||
_MakeScaleTbl ; create a scale table for color mapping
|
||
|
||
move.l attachDevice(a4),a0 ; get handle to currently attached device
|
||
move.l saveDevice(a6),a1 ; get handle to saved device
|
||
cmp.l a0,a1 ; was this the previous current device
|
||
bne.s @0 ; no, just get rid of it
|
||
move.l aGDevice(a6),saveDevice(a6) ; yes, then replace it with aGDevice
|
||
@0
|
||
move.l a0,-(sp) ; push handle to attached device
|
||
_DisposGDevice ; get rid of it (including color table referenced by pixmap)
|
||
|
||
move.l aGDevice(a6),a0 ; get handle to aGDevice
|
||
move.l a0,attachDevice(a4) ; use aGDevice as the new attached device
|
||
move.l (a0),a0 ; get pointer to new attached device
|
||
move.l ([gdPMap,a0]),a0 ; get pointer to its pixmap
|
||
move.l ([portPixMap,a3]),a1 ; get pointer to old pixmap
|
||
move.l pmTable(a0),pmTable(a1) ; copy color table handle (share actual color table with device)
|
||
|
||
move.l saveDevice(a6),theGDevice ; restore current device
|
||
|
||
bra mapThePixels ; go use the scale table to map the pixels
|
||
|
||
;----------------------------------------------------------------------------
|
||
; If the noNewDeviceBit is clear:
|
||
; get the new color table and put its reference in the attached device's pixmap
|
||
; get or create an inverse table for the color table
|
||
; set the attached device as the new current device
|
||
; call MakeScaleTbl to make a scale table between the old and the new color table
|
||
; get rid of the old color table
|
||
; put the handle to the new color table into the port's pixmap's pmTable field
|
||
|
||
updateDevice
|
||
|
||
; Get preferred resolution for inverse table from the attached device
|
||
|
||
move.l ([attachDevice,a4]),a0 ; get pointer to attached device
|
||
move gdResPref(a0),resPref(a6) ; get preferrred resolution
|
||
|
||
move.l cTable(a6),a0 ; get color table handle
|
||
|
||
clr.l newITable(a6) ; initialize handle to inverse table
|
||
|
||
; If pixelDepth = 0, ignore cTable, copy color table from museDevice
|
||
|
||
tst pixelDepth(a6) ; is pixelDepth 0?
|
||
beq.s getFromMax ; yes, get color table from maxDevice
|
||
|
||
; If cTable is not nil, clone it
|
||
|
||
cmp.l #nil,a0 ; if cTable is not nil,
|
||
bne.s cloneCTab ; just clone it
|
||
|
||
; if cTable is nil and pixelDepth <> 0, get default color table for pixelDepth
|
||
|
||
clr.l -(sp) ; leave room for CTabHandle result
|
||
move pixelDepth(a6),-(sp) ; use pixelDepth as ID
|
||
_GetCTable ; get a copy of the system color table for pixelDepth
|
||
move.l (sp)+,a0 ; get handle to color table
|
||
tst.l a0 ; was the call successful?
|
||
beq getCTabError ; no, report an error in GetCTable
|
||
|
||
bra.s dontCloneCTab ; color table from GetCTable is already a copy, don't clone it
|
||
|
||
; If pixelDepth = 0, get color table and inverse table from the max gDevice
|
||
|
||
getFromMax
|
||
move.l ([maxDevice,a6]),a0 ; get the master pointer to the device
|
||
move.l gdITable(a0),newITable(a6) ; get its inverse table handle and save it
|
||
move.l ([gdPMap,a0]),a0 ; get the master pointer to its pixmap
|
||
move.l pmTable(a0),a0 ; get the color table handle
|
||
|
||
; Clone the color table
|
||
|
||
cloneCTab
|
||
_HandToHand ; color table handle is in a0
|
||
bne reportError ; if Memory Manager error, report it and quit
|
||
|
||
; Store handle to color table in pixmap
|
||
|
||
dontCloneCTab
|
||
move.l a0,newCTable(a6) ; save cloned color table handle
|
||
|
||
;-------------------------------------------------------------------------
|
||
; Create an inverse table for the offscreen color table.
|
||
; If the color table came from an existing device, we already have the inverse
|
||
; table.
|
||
; If we don't have the inverse table yet, scan the DeviceList for a device
|
||
; that might have the same color table.
|
||
; If still unsuccessful, we have to call MakeITable.
|
||
|
||
; If we got the inverse table for free (from maxDevice), just clone it.
|
||
; At this point, newITable hasn't been cloned yet.
|
||
|
||
move.l newITable(a6),a0 ; get handle to offscreen inverse table
|
||
tst.l a0 ; is it nil?
|
||
bne.s cloneITab ; no, we already have it, just clone it
|
||
|
||
; Scan device list to find a device with same color table
|
||
|
||
clr.l -(sp) ; leave room for ITabHandle result
|
||
move.l newCTable(a6),-(sp) ; push handle to color table
|
||
jsrROM FindInverseTable ; find corresponding inverse table in the device list
|
||
move.l (sp)+,a0 ; get ITabHandle result
|
||
tst.l a0 ; if we found an already built inverse table,
|
||
bne.s cloneITab ; clone it
|
||
|
||
; Allocate inverse table to its initial size
|
||
|
||
moveq #2,d0 ; initial size is 2
|
||
_NewHandle ,CLEAR ; allocate it
|
||
bne reportError ; if Memory Manager error, report it and quit
|
||
|
||
move.l a0,newITable(a6) ; save handle to inverse table
|
||
|
||
; Build Inverse Table
|
||
|
||
move.l newCTable(a6),-(sp) ; push handle to offscreen color table
|
||
move.l a0,-(sp) ; push handle to offscreen inverse table
|
||
move resPref(a6),-(sp) ; push inverse table resolution
|
||
_MakeITable ; build inverse table
|
||
move QDErr,d0 ; check for MakeITable errors (in QDErr)
|
||
bne makeITabError ; report error and quit
|
||
|
||
bra.s storeInDevice ; go update the offscreen device
|
||
|
||
; Clone inverse table if not created by MakeITable
|
||
|
||
cloneITab
|
||
_HandToHand ; inverse table handle is in a0, clone it
|
||
bne reportError ; if Memory Manager error, report it and quit
|
||
|
||
move.l a0,newITable(a6) ; save handle to cloned inverse table
|
||
|
||
storeInDevice
|
||
move.l ([grafVars,a3]),a4 ; get pointer to grafVars structure
|
||
move.l ([attachDevice,a4]),a0 ; get pointer to attached device <19Jun89> JCM
|
||
move.l gdITable(a0),a0 ; get handle to current inverse table <19Jun89> JCM
|
||
_DisposHandle ; get rid of it <19Jun89> JCM
|
||
move.l ([attachDevice,a4]),a0 ; get pointer to attached device
|
||
move.l newITable(a6),gdITable(a0) ; store handle to new inverse table in device
|
||
move.l ([gdPMap,a0]),a0 ; get handle to device's pixmap
|
||
move.l newCTable(a6),pmTable(a0) ; store handle to new color table in device
|
||
|
||
move.l attachDevice(a4),theGDevice ; set attached device as new current device for MakeScaleTbl
|
||
|
||
move.l ([portPixMap,a3]),-(sp) ; push pointer to offscreen pixmap
|
||
move #srcAverage,-(sp) ; pass srcAverage as the mode for MakeScaleTbl
|
||
_MakeScaleTbl ; create a scale table for color mapping
|
||
|
||
move.l saveDevice(a6),theGDevice ; restore current device
|
||
|
||
move.l ([portPixMap,a3]),a4 ; get pointer to offscreen pixmap
|
||
move.l pmTable(a4),a0 ; get handle to old color table
|
||
_DisposHandle ; get rid of it
|
||
|
||
move.l newCTable(a6),pmTable(a4) ; store handle to new color table into old pixmap
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Use the scale table to map the pixels to the new color table
|
||
|
||
mapThePixels
|
||
|
||
; First check that the scale table is not identical
|
||
; If identical, don't have to do anything!
|
||
|
||
@chkTbl moveq #1,d0 ; # entries = 2^ pixelSize
|
||
move pixSize(a6),d7 ; get pixel size
|
||
lsl d7,d0 ; calc # entries in d0
|
||
clr.l d1 ; clear upper-half of d1 <20Jun89> JCM
|
||
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.l d1,a0 ; point past end of table
|
||
|
||
@1 cmp.l -(a0),d0 ; compare with dst pixel value
|
||
dbne d0,@1
|
||
beq setState ; tables are equal, we're done, go set the state of the pixels
|
||
|
||
; Tables are not equal, do the mapping
|
||
; Get initial parameters:
|
||
; a1 = pointer to the beginning of the pixels
|
||
; a4 = pointer past the end of the pixels
|
||
; d1 = $1f (mask for longs)
|
||
; d6 = pixel offset into one long of pixels
|
||
; d7 = pixel size
|
||
; sp = pointer to scale table
|
||
;
|
||
; The algorithm maps all the pixels (even the ones on the edges).
|
||
; The pixels on the edges should not be changed (index 0 typically stays black in all color tables)
|
||
; Even if the pixels on the edges change, they're not used anyway (so why bother...)
|
||
|
||
clr.l -(sp) ; leave room for Ptr result
|
||
move.l portPixMap(a3),-(sp) ; push handle to pixmap
|
||
_GetPixBaseAddr ; get address of pixels
|
||
move.l (sp)+,a1 ; keep address in a1
|
||
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to offscreen pixmap
|
||
move rowBytes(a0),d1 ; get rowBytes
|
||
and #nuRBMask,d1 ; get rid of flags
|
||
move bounds+bottom(a0),d0 ; compute height
|
||
sub bounds+top(a0),d0
|
||
mulu.w d1,d0 ; compute size of offscreen buffer
|
||
move.l a1,a4 ; get starting address
|
||
add.l d0,a4 ; compute end of offscreen buffer + 1
|
||
|
||
; Start loop
|
||
|
||
moveq #0,d6 ; initialize pixel offset within a long of pixels
|
||
moveq #$1f,d1 ; get mask for longs
|
||
@nxtLong
|
||
move.l (a1),d5 ; get one long of pixels
|
||
@nxtPixel
|
||
bfextu d5{d6,d7},d0 ; get one pixel
|
||
move.l 0(sp,d0*4),d0 ; translate it
|
||
bfins d0,d5{d6,d7} ; insert translated pixel into long
|
||
add d7,d6 ; bump to next pixel
|
||
and d1,d6 ; time for next long?
|
||
bne.s @nxtPixel ; no, do next pixel
|
||
move.l d5,(a1)+ ; yes, save current long
|
||
cmp.l a4,a1 ; have we reached the limit?
|
||
blt.s @nxtLong ; no, get a new long and continue
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update foreground and background colors to new color table
|
||
|
||
; If Palette Manager is there, use RestoreFore and RestoreBack to restore fg and bk colors
|
||
|
||
if UsePaletteMgr then
|
||
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_RestoreFore ; set foreground color with Palette Manager call
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_RestoreBack ; set background color with Palette Manager call
|
||
|
||
; If Palette Manager is not there, use RGBForeColor and RGBBackColor instead
|
||
|
||
else
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_RGBForeColor ; set foreground color
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_RGBBackColor ; set background color
|
||
endif
|
||
|
||
bra setState ; we're done, go set the state of the offscreen buffer and quit
|
||
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Create a new graphics world and, if necessary, CopyBits the old graphics world into the new one
|
||
|
||
updatePixels
|
||
|
||
; Update the flags in result according to the update flags passed to UpdateGWorld
|
||
; We're going to realloc the offscreen
|
||
|
||
or.l #reallocPixMask,result(a6) ; flag that we had to reallocate the pixels
|
||
|
||
; If the attached device is owned by the offscreenGWorld,
|
||
; we don't need aGDevice anymore (we'll create a new one with NewGWorld)
|
||
|
||
move.l newFlags(a6),d0 ; get the flags for NewGWorld
|
||
and.l #noNewDeviceMask,d0 ; extract the noNewDeviceBit
|
||
bne.s testUpdate ; if bit is set, pass aGDevice to NewGWorld
|
||
clr.l aGDevice(a6) ; if bit is clear, clear aGDevice so that NewGWorld create a new device
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Dispose of old offscreen buffer if no CopyBits will take place.
|
||
; Don't dispose of the old graphics world (in case NewGWorld fails).
|
||
|
||
testUpdate
|
||
clr.l oldBufSize(a6) ; initialize to 0 (assume old offscreen not disposed of)
|
||
|
||
tst.b purged(a6) ; are the pixels purged?
|
||
bne.s @0 ; yes, dispose of the old graphics world
|
||
move.l gDevFlags(a6),d0 ; get flags
|
||
bne.s createNew ; if there is update to do, don't dispose old GWorld
|
||
@0
|
||
move.l portPixMap(a3),a4 ; get handle to old pixmap
|
||
|
||
move.l a4,-(sp) ; push it
|
||
_UnlockPixels ; unlock pixels so we have a handle in baseAddr
|
||
|
||
move.l (a4),a1 ; get pointer to pixmap
|
||
move.l baseAddr(a1),a4 ; get handle to offscreen buffer
|
||
|
||
clr.l baseAddr(a1) ; clear it to mark that it's disposed
|
||
|
||
move.l a4,a0 ; get offscreen buffer handle in a0
|
||
_GetHandleSize ; get size of offscreen buffer
|
||
move.l d0,oldBufSize(a6) ; remember it in case NewGWorld fails
|
||
|
||
move.l a4,a0
|
||
_DisposHandle ; get rid of old offscreen buffer
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Create a new graphics world
|
||
|
||
createNew
|
||
clr -(sp) ; leave room for result
|
||
pea newGWorld(a6) ; push address of new offscreen GWorldPtr variable
|
||
move pixelDepth(a6),-(sp) ; new pixel depth
|
||
move.l boundsRect(a6),-(sp) ; new bound rectangle
|
||
move.l cTable(a6),-(sp) ; new color table
|
||
move.l aGDevice(a6),-(sp) ; pass aGDevice (NIL if noNewDeviceBit is clear)
|
||
move.l newFlags(a6),-(sp) ; flags with appropriate noNewDeviceBit and purgePixBit
|
||
_NewGWorld ; create a new GWorld
|
||
move (sp)+,d0 ; look at result
|
||
bne newGWorldError ; an error happened, handle it properly
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update new grafport with fields from old grafport
|
||
|
||
move.l newGWorld(a6),a4 ; get pointer to new grafport
|
||
move chExtra(a3),chExtra(a4) ; copy fields that should be remembered
|
||
move pnLocHFrac(a3),pnLocHFrac(a4)
|
||
|
||
; Update clipRgn by:
|
||
; offsetting it to the new portRect if clipPixBit set
|
||
; mapping it to the new portRect if stretchPixBit set
|
||
|
||
move.l clipRgn(a3),-(sp) ; first copy clip region
|
||
move.l clipRgn(a4),-(sp)
|
||
_CopyRgn
|
||
|
||
; Compare the rowBytes of the old and new world and set the newRowBytesBit if different
|
||
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to old pixmap
|
||
move rowBytes(a0),d0 ; get rowBytes
|
||
and #nuRBMask,d0 ; mask out flags
|
||
move.l ([portPixMap,a4]),a0 ; get pointer to old pixmap
|
||
move rowBytes(a0),d1 ; get rowBytes
|
||
and #nuRBMask,d1 ; mask out flags
|
||
cmp d1,d0 ; if different, set newRowBytes bit
|
||
beq.s @RowBytesFlagDone ; same rowBytes, don't set newRowBytes bit
|
||
or.l #newRowBytesMask,result(a6) ; set newRowBytes bit
|
||
@RowBytesFlagDone
|
||
|
||
move.l gDevFlags(a6),d0 ; get the flags
|
||
and.l #clipPixMask,d0 ; look at the clipPixBit
|
||
bne offsetClip ; clipPixBit set, offset the clip region
|
||
move.l clipRgn(a4),-(sp) ; push handle to clip Region
|
||
pea portRect(a3) ; push address of old portRect
|
||
pea portRect(a4) ; push address of new portRect
|
||
_MapRgn ; map region from old portRect to new portRect
|
||
bra copyPixPats
|
||
|
||
; Offset clipRgn to the new portRect
|
||
|
||
offsetClip
|
||
move.l clipRgn(a4),-(sp) ; push handle to clip Region
|
||
move portRect+left(a4),d0 ; compute offset between left coordinates of old and new portRect
|
||
sub portRect+left(a3),d0
|
||
move d0,-(sp)
|
||
move portRect+top(a4),d0 ; compute offset between top coordinates of old and new portRect
|
||
sub portRect+top(a3),d0
|
||
move d0,-(sp)
|
||
_OfsetRgn ; offset the region
|
||
|
||
; Copy the pixel patterns, pen characteristics, etc.
|
||
|
||
copyPixPats
|
||
move.l bkPixPat(a3),d0 ; get old background pixel pattern
|
||
beq noBkPixPat ; if it is NIL, don't copy it
|
||
move.l d0,-(sp) ; copy it to the new port
|
||
move.l bkPixPat(a4),-(sp)
|
||
_CopyPixPat
|
||
|
||
noBkPixPat
|
||
move.l RGBFgColor(a3),RGBFgColor(a4) ; copy RGB foreground and background colors
|
||
move.l RGBFgColor+4(a3),RGBFgColor+4(a4)
|
||
move.l RGBBkColor+2(a3),RGBBkColor+2(a4)
|
||
move.l pnLoc(a3),pnLoc(a4) ; copy pen characteristics
|
||
move.l pnSize(a3),pnSize(a4)
|
||
move pnMode(a3),pnMode(a4)
|
||
move.l pnPixPat(a3),d0 ; get old pen pixel pattern
|
||
beq noPnPixPat ; if it is NIL, don't copy it
|
||
move.l d0,-(sp) ; copy it to the new port
|
||
move.l pnPixPat(a4),-(sp)
|
||
_CopyPixPat
|
||
|
||
noPnPixPat
|
||
move.l fillPixPat(a3),d0 ; get old fill pixel pattern
|
||
beq noFillPixPat ; if it is NIL, don't copy it
|
||
move.l d0,-(sp) ; copy it to the new port
|
||
move.l fillPixPat(a4),-(sp)
|
||
_CopyPixPat
|
||
|
||
noFillPixPat
|
||
lea pnVis(a3),a0 ; copy all remaining fields, starting from pnVis
|
||
lea pnVis(a4),a1
|
||
moveq #((portRec-pnVis)/2)-1,d0 ; number of words to copy (0-based for dbra)
|
||
@0 move (a0)+,(a1)+ ; copy one word
|
||
dbra d0,@0 ; loop until all copied
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update new pixmap with fields from old pixmap
|
||
|
||
move.l ([portPixMap,a3]),a0 ; get pointer to old pixmap
|
||
move.l ([portPixMap,a4]),a1 ; get pointer to new pixmap
|
||
move packType(a0),packType(a1) ; copy interesting fields
|
||
move.l packSize(a0),packSize(a1)
|
||
move.l hRes(a0),hRes(a1)
|
||
move.l vRes(a0),vRes(a1)
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update new grafVars with fields from old grafVars
|
||
|
||
MOVE.L grafVars(A3),A0 ;get src port grafVars <21>
|
||
_HandToHand ;make copy of handle <21>
|
||
BNE reportError ;leave if memory error <21>
|
||
MOVE.L grafVars(A4),A1 ;get handle to dst port grafVars <21>
|
||
MOVE.L A0,grafVars(A4) ;save new grafVars in dst port <21>
|
||
MOVE.L (A0),A0 ;deref new grafVars handle <21>
|
||
MOVE.L A1,D0 ;save handle to old grafVars <21>
|
||
MOVE.L (A1),A1 ;deref handle to old grafVars <21>
|
||
MOVE.L attachDevice(A1),attachDevice(A0) ;copy attachDevice from old to new <21>
|
||
MOVE.W devOwned(A1),devOwned(A0) ;copy devOwned, useMFTemp from old to new <21>
|
||
MOVE.L D0,A0 ;get handle to old grafVars back <21>
|
||
_DisposHandle ;dispose dst port grafvars handle <21>
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update new grafProcs with old grafProcs
|
||
|
||
move.l grafProcs(a3),grafProcs(a4) ; copy grafProcs handle from old to new gworld
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update new gDevice with fields from old gDevice
|
||
|
||
move.l ([grafVars,a3]),a0 ; get pointer to old grafVars
|
||
move.l ([attachDevice,a0]),a0 ; get pointer to old attached device
|
||
move.l ([grafVars,a4]),a1 ; get pointer to new grafVars
|
||
move.l ([attachDevice,a1]),a1 ; get pointer to new attached device
|
||
move.l gdSearchProc(a0),gdSearchProc(a1) ; copy interesting fields
|
||
move.l gdCompProc(a0),gdCompProc(a1)
|
||
move.l gdRefCon(a0),gdRefCon(a1)
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update new gDevice's pixmap with fields from old gDevice's pixmap
|
||
|
||
move.l ([gdPMap,a0]),a0 ; get pointer to old attached device's pixmap
|
||
move.l ([gdPMap,a1]),a1 ; get pointer to new attached device's pixmap
|
||
move packType(a0),packType(a1) ; copy interesting fields
|
||
move.l packSize(a0),packSize(a1)
|
||
move.l hRes(a0),hRes(a1)
|
||
move.l vRes(a0),vRes(a1)
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Update foreground and background color indices while being compatible
|
||
; with the Palette Manager if active.
|
||
|
||
; Save Foreground and Background colors from the old gworld
|
||
|
||
move.l a3,-(sp) ; push pointer to old offscreen gworld
|
||
clr.l -(sp) ; use attached device
|
||
_SetGWorld ; set current port and device to old world
|
||
|
||
; If Palette Manager is there, use SaveFore and SaveBack to get fg and bk colors
|
||
|
||
if UsePaletteMgr then
|
||
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_SaveFore ; get foreground color from Palette Manager
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_SaveBack ; get background color from Palette Manager
|
||
|
||
; If Palette Manager is not there, use GetForeColor and GetBackColor instead
|
||
|
||
else
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_GetForeColor ; get foreground color from port
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_GetBackColor ; get background color from port
|
||
endif
|
||
|
||
; And restore them to new gworld, using the Palette Manager
|
||
|
||
move.l a4,-(sp) ; push pointer to new offscreen gworld
|
||
clr.l -(sp) ; use attached device
|
||
_SetGWorld ; set current port and device to new world
|
||
|
||
; If Palette Manager is there, use RestoreFore and RestoreBack to restore fg and bk colors
|
||
|
||
if UsePaletteMgr then
|
||
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_RestoreFore ; set foreground color with Palette Manager call
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_RestoreBack ; set background color with Palette Manager call
|
||
|
||
; If Palette Manager is not there, use RGBForeColor and RGBBackColor instead
|
||
|
||
else
|
||
pea saveForeColor(a6) ; push address of saved foreground ColorSpec
|
||
_RGBForeColor ; set foreground color
|
||
|
||
pea saveBackColor(a6) ; push address of saved background ColorSpec
|
||
_RGBBackColor ; set background color
|
||
endif
|
||
|
||
|
||
;----------------------------------------------------------------------------
|
||
; If the pixels in the old world are purged, don't update them
|
||
|
||
tst.b purged(a6) ; are the old pixels purged?
|
||
bne noCopyBits ; yes, don't CopyBits
|
||
|
||
; If flags is not 0, find out how the pixels will be updated and call CopyBits to update them
|
||
|
||
move.l gDevFlags(a6),d0 ; if flags is 0,
|
||
beq noCopyBits ; just set state of new offscreen buffer and return
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Lock the pixels of both gworlds
|
||
|
||
clr.b -(sp) ; leave room for Boolean result
|
||
move.l portPixMap(a3),-(sp) ; handle to old offscreen PixMap
|
||
_LockPixels ; lock the pixels down
|
||
move.b (sp)+,d0 ; ignore result (if we're here, it means pixels are not purged)
|
||
|
||
clr.b -(sp) ; leave room for Boolean result
|
||
move.l newGWorld(a6),a0 ; get pointer to new offscreen GWorld
|
||
move.l portPixMap(a0),-(sp) ; push handle to new offscreen PixMap
|
||
_LockPixels ; lock the pixels down
|
||
move.b (sp)+,d0 ; if pixels are purged already, quit now
|
||
beq purgedError ; report error and exit
|
||
|
||
; Set current graphics world to new GWorld
|
||
|
||
move.l newGWorld(a6),-(sp) ; push pointer to new GWorld
|
||
clr.l -(sp) ; NIL device
|
||
_SetGWorld ; set current GWorld for CopyBits
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Save the clipRgn of the newGWorld and set it to newGWorld's portRect
|
||
; so that CopyBits copies the whole pixmap
|
||
|
||
clr.l -(sp) ; leave room for RgnHandle result
|
||
_NewRgn ; create a new region for saveClip
|
||
move.l (sp),saveClip(a6) ; remember region handle in saveClip
|
||
|
||
_GetClip ; get the current clipRgn in saveClip
|
||
|
||
move.l newGWorld(a6),a0 ; get pointer to new GWorld
|
||
pea portRect(a0) ; push address of portRect
|
||
_ClipRect ; set clipRgn to portRect
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Call CopyBits to update the pixels. Compute srcRect and dstRect according
|
||
; to update mode (clipping or stretching)
|
||
|
||
move.l ([portPixMap,a3]),-(sp) ; srcBits = pointer to old pixmap
|
||
move.l newGWorld(a6),a1 ; get pointer to new offscreen port
|
||
move.l ([portPixMap,a1]),-(sp) ; dstBits = pointer to new pixmap
|
||
|
||
lea portRect(a3),a0 ; get address of old portRect
|
||
lea portRect(a1),a1 ; get address of new portRect
|
||
|
||
move.l gDevFlags(a6),d0 ; get the flags
|
||
btst.l #stretchPixBit,d0 ; is stretchPixBit set?
|
||
bne.s doCopyBits ; yes, use srcRect and dstRect with no clipping
|
||
|
||
; If clipPixBit is set, clip CopyBits to size of destination rectangle
|
||
|
||
doClipping
|
||
|
||
move.l topLeft(a0),clipSrcRect+topLeft(a6) ; topLeft coordinates remain the same
|
||
move.l topLeft(a1),clipDstRect+topLeft(a6)
|
||
|
||
; Compute smallest height of old and new rectangle
|
||
|
||
move bottom(a0),d0 ; compute old height
|
||
sub top(a0),d0
|
||
move bottom(a1),d1 ; compute new height
|
||
sub top(a1),d1
|
||
cmp d0,d1 ; which height is smaller?
|
||
blt.s @0 ; new height is smaller, keep in d1
|
||
move d0,d1 ; old height is smaller, keep in d1
|
||
@0
|
||
move top(a0),d0 ; compute old top + clipped height
|
||
add d1,d0
|
||
move d0,clipSrcRect+bottom(a6) ; store in clipSrcRect.bottom
|
||
move top(a1),d0 ; compute new top + clipped height
|
||
add d1,d0
|
||
move d0,clipDstRect+bottom(a6) ; store in clipDstRect.bottom
|
||
|
||
; Compute smallest width of old and new rectangle
|
||
|
||
move right(a0),d0 ; compute old width
|
||
sub left(a0),d0
|
||
move right(a1),d1 ; compute new width
|
||
sub left(a1),d1
|
||
cmp d0,d1 ; which width is smaller?
|
||
blt.s @1 ; new width is smaller, keep in d1
|
||
move d0,d1 ; old width is smaller, keep in d1
|
||
@1
|
||
move left(a0),d0 ; compute old left + clipped width
|
||
add d1,d0
|
||
move d0,clipSrcRect+right(a6) ; store in clipSrcRect.right
|
||
move left(a1),d0 ; compute new left + clipped width
|
||
add d1,d0
|
||
move d0,clipDstRect+right(a6) ; store in clipDstRect.right
|
||
|
||
lea clipSrcRect(a6),a0 ; srcRect = smallest of old portRect and new portRect
|
||
lea clipDstRect(a6),a1 ; dstRect = idem but in coordinate system of new port
|
||
|
||
doCopyBits
|
||
move.l a0,-(sp) ; srcRect = old portRect (clipped or unclipped)
|
||
move.l a1,-(sp) ; dstRect = new portRect
|
||
move mode(a6),-(sp) ; mode = srcCopy or dither
|
||
move.l #nil,-(sp) ; no mask
|
||
_CopyBits ; transfer the pixels
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Restore the clipRgn of the newGWorld
|
||
|
||
move.l saveClip(a6),-(sp) ; push handle to saveClip
|
||
_SetClip ; restore clipRgn
|
||
|
||
move.l saveClip(a6),-(sp) ; push handle to saveClip
|
||
_DisposRgn ; get rid of clipRgn
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Unlock the pixels of the new offscreen GWorld (don't care about the old one, we'll get rid of it)
|
||
|
||
move.l newGWorld(a6),a0 ; get pointer to new offscreen GWorld
|
||
move.l portPixMap(a0),-(sp) ; push handle to its pixmap
|
||
_UnlockPixels ; unlock the pixels
|
||
|
||
;----------------------------------------------------------------------------
|
||
; After CopyBits, dispose of the old offscreen graphics world
|
||
|
||
noCopyBits
|
||
move.l a3,-(sp) ; push handle to old GWorld for dispose
|
||
|
||
;---------------------------------------------------------------------------- <17May90 KON>
|
||
; If savePort is the old GWorld, set savePort to the new one
|
||
; If saveDevice is the old attached device, set saveDevice to the new attached device
|
||
|
||
move.l a3,a0 ; get old GWorld
|
||
move.l newGWorld(a6),a3 ; get pointer to new GWorld
|
||
cmpa.l savePort(a6),a0 ; compare with savePort
|
||
bne.s checkSaveDevice ; if not the same, go check the saveDevice
|
||
|
||
move.l a3,savePort(a6) ; savePort is old GWorld, replace with new GWorld
|
||
|
||
checkSaveDevice
|
||
move.l ([grafVars,a0]),a0 ; get pointer to old grafVars
|
||
move.l attachDevice(a0),a0 ; get handle to old attached device
|
||
cmp.l saveDevice(a6),a0 ; compare with saveDevice
|
||
bne.s saveDeviceOK ; if not the same, just restore the current GWorld
|
||
|
||
move.l ([grafVars,a3]),a0 ; if same, replace with new attachDevice
|
||
move.l attachDevice(a0),saveDevice(a6)
|
||
saveDeviceOK
|
||
|
||
_DisposeGWorld ; dispose of it
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Set lock/purge state of new offscreen buffer to the same as old offscreen buffer
|
||
|
||
setState
|
||
move.l newGWorld(a6),a3 ; get pointer to new GWorld
|
||
|
||
; Get here if restoring state of old offscreen buffer after an error (old GWorldPtr is in a3)
|
||
|
||
setStateWithError
|
||
|
||
move.l portPixMap(a3),-(sp) ; push handle to its pixmap
|
||
move.l state(a6),-(sp) ; push lock/purge state
|
||
_SetPixelsState ; set the state
|
||
|
||
; Restore current graphics world
|
||
|
||
move.l savePort(a6),-(sp) ; push pointer to saved port
|
||
move.l saveDevice(a6),-(sp) ; push handle to saved device
|
||
_SetGWorld ; restore current environment
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Return pointer to new GWorld in offscreenGWorld
|
||
; If got here after an error, a3 contains the old graphics world
|
||
|
||
move.l offscreenGWorld(a6),a0 ; get pointer to GWorldPtr variable
|
||
move.l a3,(a0) ; store pointer to new GWorld in offscreenGWorld variable
|
||
|
||
exit move #noErr,QDErr ; assume no error <21Jun89> JCM
|
||
move.l result(a6),d0 ; copy result to d0 <21Jun89> JCM
|
||
bpl.s @0 ; if result is < 0, <21Jun89> JCM
|
||
move d0,QDErr ; copy low-word of result to QDErr <21Jun89> JCM
|
||
@0 ; <21Jun89> JCM
|
||
move.l saveStack(a6),sp ; restore the stack pointer
|
||
movem.l (sp)+,a2-a4/d5-d7 ; restore regs
|
||
unlk a6 ; get rid of stack frame
|
||
rtd #paramSize ; get rid of parameters and return to caller
|
||
|
||
;----------------------------------------------------------------------------
|
||
; Errors
|
||
|
||
reportError
|
||
ext.l d0 ; convert error to a long
|
||
move.l d0,result(a6) ; report error
|
||
bra.s setStateWithError ; restore state of old offscreen buffer and quit
|
||
|
||
badPixelDepth
|
||
move.l #cDepthErr,result(a6) ; pixel depth invalid
|
||
bra.s exit ; exit
|
||
|
||
getCTabError
|
||
move QDErr,d0 ; look at QDErr
|
||
bne reportError ; if contains an error, report it
|
||
move MemErr,d0 ; if no QDErr, look at MemErr
|
||
bne.s reportError ; if contains an error, report it
|
||
clr -(sp) ; if no MemErr, look at ResError
|
||
_ResError ; get Resource Manager error
|
||
move (sp)+,d0 ; look at it
|
||
bra.s setStateWithError ; restore state of old offscreen buffer and quit
|
||
; if no error anywhere, just return a cNoMemErr
|
||
purgedError
|
||
move.l #cNoMemErr,result(a6) ; report a Quickdraw memory error
|
||
bra.s setStateWithError ; restore state of old offscreen buffer and quit
|
||
|
||
paramError
|
||
move.l #paramErr,result(a6) ; report a parameter error
|
||
bra.s exit ; and exit
|
||
|
||
makeITabError
|
||
ext.l d0 ; convert QD error to long
|
||
move.l d0,result(a6) ; return QD error
|
||
move.l newCTable(a6),a0 ; get rid of color table and inverse table
|
||
_DisposHandle
|
||
move.l newITable(a6),a0
|
||
_DisposHandle
|
||
bra.s setStateWithError ; restore state of old offscreen buffer and quit
|
||
|
||
; If NewGWorld error fails and the old offscreen buffer was disposed of,
|
||
; reallocate old offscreen buffer, report error, and quit.
|
||
|
||
newGWorldError
|
||
move.l oldBufSize(a6),d1 ; get size of old offscreen buffer
|
||
beq.s reportError ; if 0, it means old offscreen hasn't been disposed of
|
||
|
||
move d0,d7 ; save error code
|
||
|
||
move.l d1,d0 ; get size of old offscreen buffer in d0
|
||
|
||
move.l ([grafVars,a3]),a0 ; get grafVars <07Jul89> JCM
|
||
tst.b useMFTemp(a0) ; were the pixels in temp memory? <07Jul89> JCM
|
||
beq.s @useCurHeap ; no, allocate in current heap <07Jul89> JCM
|
||
_NewTempHandle ; allocate it in Juggler heap, returns actual size in D0 <07Jul89> JCM
|
||
tst.l d0 ; is it empty? <07Jul89> JCM
|
||
bne.s @gotMem ; no, got the memory <07Jul89> JCM
|
||
move d7,d0 ; yes, restore error and report <07Jul89> JCM
|
||
bra reportError ; <07Jul89> JCM
|
||
|
||
@useCurHeap
|
||
_NewHandle ; allocate offscreen buffer (don't initialize it) <07Jul89> JCM
|
||
bne reportError ; if Memory Manager error, report it and quit <07Jul89> JCM
|
||
|
||
@gotMem
|
||
move.l ([portPixMap,a3]),a1 ; get pointer to old pixmap
|
||
move.l a0,baseAddr(a1) ; store handle to offscreen buffer in baseAddr
|
||
|
||
move d7,d0 ; restore error code
|
||
bra.s reportError ; report error and quit
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to OffscreenVersion (selector 20 on QDExtDispatcher).
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
OffscreenVersion PROC EXPORT
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION OffscreenVersion (): LONGINT;
|
||
;
|
||
; Returns the version number of the current version of the Quickdraw extensions.
|
||
; The first version doesn't have OffscreenVersion implemented and will therefore
|
||
; return a paramErr.
|
||
|
||
OffscreenVersNum equ $130 ; version 1.3 of the quickdraw extensions
|
||
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; Stack offsets of parameters
|
||
;
|
||
paramSize equ 0 ; size of parameters
|
||
version equ paramSize+4 ; LONG, result
|
||
|
||
move.l #OffscreenVersNum,version(sp) ; return version number
|
||
rts
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to QDExtDispatcher. Add selectors 22 and 23.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
QDExtDispatcher PROC EXPORT
|
||
IMPORT Pixmap32Bit, GetGWorldPixMap, UpdateGWorld
|
||
|
||
ROMexit EQU $3FAC2
|
||
ROMDispatch EQU $3FA66
|
||
|
||
;----------------------------------------------------------------------------
|
||
; QDExtensions Dispatcher.
|
||
;
|
||
; All Quickdraw extensions routines use a common trap and a selector.
|
||
; The selector is in the low word of D0
|
||
; The size of the parameters is in the high word of D0
|
||
; NOTE: To avoid changing the include files again, functions number 0 through 19
|
||
; are accepted with an unspecified parameter size (high word of D0 cleared).
|
||
; In future versions, any new function should specify the size of parameters.
|
||
;----------------------------------------------------------------------------
|
||
|
||
cmp #23,d0 ; if unsigned d0 > max selector,
|
||
bhi.s exit ; don't do anything
|
||
|
||
cmp #3,d0
|
||
beq UpdateGWorld ;UpdateGWorld patched out above
|
||
|
||
cmp #20,d0 ;OffscreenVersion selector
|
||
beq.s OffscreenVersion ;OffscreenVersion patched out above
|
||
|
||
tst.w d0 ;selector 0 is NewGWorld
|
||
beq PatchNewGWorld
|
||
|
||
cmp #21,d0
|
||
ble.s GoROMDispatch ;Handle 0 - 21 with ROM
|
||
;
|
||
; Handle selectors 22 and 23 here
|
||
;
|
||
sub.w #22,d0 ;22 is 0th entry, 23 is 1st entry
|
||
jmp dispatchTable(d0*4) ; jump in jump table
|
||
|
||
dispatchTable
|
||
jmp Pixmap32Bit ; selector 22
|
||
jmp GetGWorldPixMap ; selector 23
|
||
|
||
GoROMDispatch
|
||
jmpROM ROMDispatch
|
||
|
||
exit
|
||
jmpROM ROMexit
|
||
|
||
Pixmap32Bit PROC EXPORT
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; FUNCTION Pixmap32Bit (pm: PixMapHandle): boolean;
|
||
;
|
||
;
|
||
; If pmVersion is PixMapVers4, the baseAddr is a 32-bit pointer, return true.
|
||
; If pmVersion is PixMapVers2, the baseAddr is a handle, return false.
|
||
; If pmVersion is PixMapVers1, the baseAddr is a 24-bit pointer, return false.
|
||
; If pmVersion is PixMapVers0,
|
||
; if the baseAddr is the same as a devicelist screen, then return true (for now)
|
||
; else return false.
|
||
|
||
;----------------------------------------------------------------------------
|
||
;
|
||
; Stack offsets of parameters
|
||
;
|
||
paramSize equ 4 ; size of parameters
|
||
bufResult equ paramSize+4 ; boolean, result
|
||
pm equ bufResult-4 ; LONG, handle to pixmap
|
||
|
||
|
||
; Initialize result to false (assume pmVersion is not PixMapVers4 or a screen).
|
||
|
||
move.l ([pm,sp]),a1 ; get pointer to pixmap
|
||
clr.w bufResult(sp) ; assume return false
|
||
|
||
; Check PixMap's pmVersion.
|
||
|
||
move pmVersion(a1),d0 ; get pmVersion
|
||
beq.s chkForScreen ; go check to see if it's a screen
|
||
cmp.w #PixMapVers4,d0 ; is it explicitly 32-bit?
|
||
bne.s exit ; no, return false
|
||
retTrue move.b #1,bufResult(sp) ; return true
|
||
exit rtd #paramSize ; get rid of parameters and return to caller
|
||
|
||
chkForScreen
|
||
move.l baseAddr(a1),d0 ; get baseAddr
|
||
MOVE.L DEVICELIST,A1 ; GET FIRST ELEMENT IN DEVICE LIST
|
||
NEXTGD MOVE.L (A1),A0 ; POINT TO DEVICE
|
||
MOVE.W GDFlags(A0),D2 ; get the flags word <5+>
|
||
MOVE.L GDPMAP(A0),A0 ; GET PIXMAP
|
||
MOVE.L (A0),A0 ; POINT TO PIXMAP
|
||
cmp.l baseAddr(A0),D0 ; compare base address
|
||
BNE.S @NxtDev ; doesn't match, so try next device <5+>
|
||
BTST #ext32Device,D2 ; is this a 32-bit accessed device? <5+>
|
||
BNE.s retTrue ; if so, then base addr 32-bit, ret true <5+>
|
||
BRA.S exit ; if not, then base addr 24-bit, ret false <5+>
|
||
@NxtDev
|
||
MOVE.L (A1),A0 ; GET DEVICE
|
||
MOVE.L GDNEXTGD(A0),D1 ; GET NEXT DEVICE
|
||
MOVE.L D1,A1 ; SAVE IT
|
||
BNE.S NEXTGD ;
|
||
bra.s exit ; not a screen so return false
|
||
|
||
ENDPROC
|
||
|
||
GetGWorldPixmap PROC EXPORT
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; FUNCTION GetGWorldPixmap (gw: GWorldPtr): pixmaphandle;
|
||
;
|
||
; Slimed from local routine PORTTOMAP found in colorasm.a
|
||
;
|
||
;
|
||
; Enter with: (sp): address of caller
|
||
; 4(sp): GworldPtr
|
||
; 8(sp): pixmap handle result
|
||
;
|
||
move.l (sp)+,a1 ;save caller's address
|
||
move.l (sp)+,a0 ;pick up GWorld (port) ptr
|
||
clr.l (sp) ;init result assuming failure
|
||
TST PORTBITS+ROWBYTES(A0) ;BITMAP OR PIXMAP?
|
||
BPL.S GOTBITMAP ;=>JUST A BITMAP
|
||
BTST #ISCPORT,PORTBITS+ROWBYTES(A0) ;IS IT A COLOR PORT?
|
||
BEQ.S GOTBITMAP ;=>NO, JUST A PIXMAP
|
||
MOVE.L portBits+BASEADDR(A0),(sp) ;ELSE GET PORT'S PIXMAP HANDLE
|
||
GOTBITMAP jmp (a1) ;return to caller
|
||
|
||
ENDPROC
|
||
|
||
MakeScaleTbl PROC EXPORT
|
||
MACRO
|
||
_ColorThing2Index
|
||
JSR ([$E00+$392*4])
|
||
ENDM
|
||
;---------------------------------------------------------------
|
||
;
|
||
; PROCEDURE MakeScaleTbl (PMP: PixMapPtr);
|
||
;
|
||
; Allocates a translate table on the stack and returns with SP at the
|
||
; start of the table. The translate table contains one entry for each
|
||
; possible pixel value in the source pixMap (PMP); each entry contains the
|
||
; value to be written to the destination pixMap to best approximate that color.
|
||
; The translation table has 32 bits per entry. <BAL 09May88> @@@@
|
||
;
|
||
redHigh EQU 8
|
||
greenHigh EQU 4
|
||
blueHigh EQU 0
|
||
|
||
&CurFile SETC 'STRETCH'
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
ScaleColorBit EQU 3
|
||
SwapFGBGBit EQU 4
|
||
UseStretchBit EQU 5
|
||
InvertItBit EQU 7
|
||
ColorizeInModeCaseBit EQU 8
|
||
ColorizeInSrcBufBit EQU 9
|
||
|
||
ciROMScaleBlt EQU $39f52
|
||
|
||
MOVE.L (SP)+,A0 ; get return address
|
||
MOVE.w (SP)+,D2 ; should we do colorizing here flag in bit 5
|
||
|
||
;
|
||
; <8JUN92 SAH>
|
||
; The old MakeScaleTbl used to use bit 5 for colorizing. It now uses bit 3 (ScaleColorBit).
|
||
; This didn't seem to cause many problems except now that ScaleBlt is being called
|
||
; again, we have problems when colorizing. So, rather than patch all of ScaleBlt for
|
||
; ci roms, we're doing a come from patch here. We can then then look at the actual XLateFlags
|
||
; from stretch (which is what should be passed to MakeScaleTbl anyway).
|
||
;
|
||
leaROM ciROMScaleBlt,a1 ;get where we want to check <8JUN92 SAH>
|
||
cmp.l a1,a0 ;is this from ScaleBlt? <8JUN92 SAH>
|
||
bne.s @colorizeOK ;no, so continue on <8JUN92 SAH>
|
||
move.w XLateFlag(a6),d2 ;get the real XLateFlags <9JUN92 SAH>
|
||
@colorizeOK
|
||
MOVE.L (SP)+,A1 ; get pixMap handle
|
||
MOVE pixelSize(A1),D1 ; get size of pixels
|
||
|
||
MOVEQ #1,D0 ; # entries = 2^pixelsize
|
||
LSL D1,D0 ; # entries = 2^pixelsize
|
||
MOVE D0,D1 ; save possible # of colors
|
||
|
||
SUBQ #1,D0 ; make zero based for DBRA
|
||
NXTWORD
|
||
move.l #$7fffffff,-(SP) ; allocate one entry per long <BAL 09May88> @@@@
|
||
DBRA D0,NXTWORD
|
||
|
||
; leave table on stack, save work regs, etc., on top of it
|
||
|
||
TBLOFST EQU 9*4+12 ; ret addr, save regs, RGBSpec, Back and ForeColor
|
||
|
||
MOVE.L A0,-(SP) ; push return address
|
||
MOVEM.L A2/D3-D7,-(SP) ; save work registers
|
||
MOVEQ #0,D5 ; clear high word
|
||
MOVE D1,D5 ; save # of available colors
|
||
SUBQ #6,SP ; allocate VAR ColorSpec on stack
|
||
clr.w -(sp) ; force default color space to RGB <BAL/dvb 23Feb89>
|
||
;
|
||
; Allocate forecolor and back color on stack for colorizing and for use later
|
||
;
|
||
move.l a1,a2 ;save pixmap handle
|
||
|
||
MOVEQ #-1,D0 ;GET WHITE
|
||
MOVE.L D0,-(SP) ;PUSH R,G,B FOR WHITE
|
||
MOVE D0,-(SP)
|
||
CLR.L -(SP) ;PUSH R,G,B FOR BLACK
|
||
CLR -(SP)
|
||
|
||
btst #ScaleColorBit,d2 ;should we colorize?
|
||
beq @useDefault ;skip if no.
|
||
|
||
moveq #6,d4
|
||
btst #swapfgbgBit,d2 ;swap fg/bk colors?
|
||
beq.s @dontswap
|
||
moveq #0,d4
|
||
@dontswap
|
||
PEA (SP,d4)
|
||
_GetBackColor ;get fg, bg to do colorizing
|
||
eor.w #6,d4
|
||
PEA (sp,d4)
|
||
_GetForeColor
|
||
|
||
|
||
;
|
||
; Check to see if destination device is 1 bit deep. If so, we need to see if the fg and bg
|
||
; colors map to the same thing. If they do, then check to see if the colors themselves are
|
||
; the same. If not, then we invert the bg color <08JUN92 SAH>
|
||
;
|
||
; <135> <18AUG92 SAH>
|
||
; NOTE: This check is not correct. It should check to see if the destination is 1 or 2
|
||
; bits deep and is a new port. There is also a major bug where we colorize with the inverted
|
||
; background color rather than just setting the background index. In particular, this breaks
|
||
; SeedCFill for indexed pixmaps. For the purposes of Cube-E, we will do an explicit check to
|
||
; see if the background color is white and the foreground is black, if so we won't invert.
|
||
;
|
||
move.l ([theGDevice]),A0 ;get a pointer to the device
|
||
move.l ([gdPMap,a0]),a0 ;get a pointer to its pixmap
|
||
cmp.w #1,pixelSize(a0)
|
||
bne.s @fgBgColorsOK ;not one bit, we don't have to worry
|
||
move.w d2,d3 ;save d2 here from _Color2Index <09JUN92 SAH>
|
||
|
||
; now do the check for fg = black, bg = white <18AUG92 SAH>
|
||
tst.l (sp) ;look at fg red and green <135>
|
||
bne.s @doInvertCheck ;not black, so bail <135>
|
||
tst.w 4(sp) ;look at fg blue <135>
|
||
bne.s @doInvertCheck ;not black, so bail <135>
|
||
moveq #-1,d0 ;get a white long <135>
|
||
cmp.l 6(sp),d0 ;compare with bg red and green <135>
|
||
bne.s @doInvertCheck ;not white, so bail <135>
|
||
cmp.w 10(sp),d0 ;compare with bg blue <135>
|
||
beq.s @fgBgColorsOK ;equal, so don't do invert <135>
|
||
|
||
@doInvertCheck
|
||
; get copies of our colors on the stack <09JUN92 SAH>
|
||
; it starts out like this. Make sure we copy things in the right order!
|
||
; RRRRGGGG 0
|
||
; BBBBrrrr 4
|
||
; ggggbbbb 8
|
||
|
||
move.l 8(sp),-(sp) ;do ggggbbbb
|
||
move.l 8(sp),-(sp) ;do BBBBrrrr
|
||
move.l 8(sp),-(sp) ;do RRRRGGGG
|
||
|
||
;now we have another copy of the above
|
||
|
||
subq.l #4,sp ;room for index
|
||
pea 4(sp) ;ptr to the bg color
|
||
_Color2Index
|
||
subq.l #4,sp ;room for index
|
||
pea 14(sp) ;ptr to the fg color
|
||
_Color2Index
|
||
move.w d3,d2 ;get our d2 back from _Color2Index <09JUN92 SAH>
|
||
move.l (sp)+,d0 ;get the fg color
|
||
cmp.l (sp)+,d0 ;compare against the bg color
|
||
add.w #12,sp ;get rid of our private colors
|
||
bne.s @fgBgColorsOK ;we're ok
|
||
|
||
;now, the two map to the same thing, so we need to check of the colors themselves
|
||
;are the same. If so, we don't do anything.
|
||
|
||
move.l 0(sp),d0
|
||
cmp.l 6(sp),d0
|
||
bne.s @invertbg
|
||
move.w 4(sp),d0
|
||
cmp.w 10(sp),d0
|
||
beq.s @fgBgColorsOK
|
||
@invertbg
|
||
pea 6(sp) ;push ptr to bg color
|
||
_InvertColor ;and invert it
|
||
|
||
@fgBgColorsOK
|
||
|
||
;
|
||
; if foreground black and background white, don't colorize.
|
||
;
|
||
move.l 0(sp),d4 ;get long of fg color
|
||
bne.s @useDefault ;abort if not black
|
||
move.w 4(sp),d4 ;get high word of fg color
|
||
bne.s @useDefault ;abort if not black
|
||
;
|
||
; check fg color
|
||
;
|
||
move.l 6(sp),d4 ;get long of bg color
|
||
addq #1,d4 ;check for white
|
||
bne.s @useDefault
|
||
move.w $0A(sp),d4 ;check high word
|
||
add.w #1,d4
|
||
bne.s @useDefault
|
||
bclr #ScaleColorBit,d2 ;fg black, bk white, don't colorize
|
||
|
||
@useDefault
|
||
;
|
||
; Build pixel translation table
|
||
;
|
||
move.l a2,a1 ;get pm handle back
|
||
MOVEQ #-1,D6 ; assume no colors in color table
|
||
MOVE.L pmTable(A1),D0 ; does it exist?
|
||
BEQ noPredefinedColors
|
||
|
||
MOVE.L D0,A2 ; get color table handle
|
||
MOVE ([A2],CTSize),D4 ; get size of table in entries
|
||
cmp D5,D4 ; more entries than bits allow?
|
||
blo.s @notTooMany ; no, fine
|
||
move D5,D4 ; yes, pin to depth
|
||
subq #1,D4 ; make zero-based
|
||
@notTooMany
|
||
MOVE ([a2],TransIndex),D3 ; get ctFlags <BAL 10Mar89>
|
||
btst #14,d3 ; are they palette references? <BAL 10Mar89>
|
||
bne brink ; yes call dave <BAL 10Mar89>
|
||
|
||
MOVEQ #0,D6 ; zero high word
|
||
MOVE D4,D6 ; remember number of colors
|
||
|
||
btst #ScaleColorBit,d2 ;should we colorize?
|
||
beq.s noColorizeLoop ;skip if no.
|
||
|
||
@nxtEntry MOVE.L (A2),A0 ; get color table pointer
|
||
MOVE D4,D3 ; assume entry = index
|
||
TST TransIndex(A0) ; look for flag in transIndex
|
||
BMI.S @UseIndex ; => flag set, use index
|
||
MOVE.w CTTable+value(A0,D4*8),D3 ; get value of current entry <BAL/dvb 23Feb89>
|
||
@UseIndex MOVE CTTable+rgb+red(A0,D4*8),d0 ; get red
|
||
|
||
;
|
||
; colorize the red
|
||
;
|
||
MOVE.w D0,d1 ;COPY SRC
|
||
move.w 6(sp),d2 ;get red of bk color into low 16 bits
|
||
AND.w D2,D0 ;ADD FG COLOR TO SRC
|
||
NOT.w D1 ;GET NOT SRC
|
||
move 0(sp),d2 ;get red of fg color into low 16 bits
|
||
AND.w D2,D1 ;ADD BK COLOR TO NOT SRC
|
||
OR.w D1,D0 ;COMBINE FG/BK DATA
|
||
move.w d0,rgb+red+12(sp)
|
||
|
||
|
||
MOVE.L CTTable+rgb+green(A0,D4*8),d0 ; copy green,blue
|
||
;
|
||
; colorize the green and blue at the same time
|
||
;
|
||
MOVE.l D0,d1 ;COPY SRC
|
||
move.l 8(sp),d2 ;get blue and green of bk color
|
||
AND.l D2,D0 ;ADD FG COLOR TO SRC
|
||
NOT.l D1 ;GET NOT SRC
|
||
move.l 2(sp),d2 ;get blue and green of fg color
|
||
AND.l D2,D1 ;ADD BK COLOR TO NOT SRC
|
||
OR.l D1,D0 ;COMBINE FG/BK DATA
|
||
move.l d0,rgb+green+12(SP)
|
||
|
||
CLR.L -(SP) ; make room for function result
|
||
PEA rgb+4+12(SP) ; point to VAR RGBColor <KON 28Apr90>
|
||
_Color2Index ; convert to index <BAL/dvb 23Feb89>
|
||
MOVE.L (SP)+,D0 ; get result
|
||
move.l D0,TBLOFST(SP,D3*4) ; put returned value in table <BAL 09May88> @@@@
|
||
DBRA D4,@nxtEntry ; => repeat until done
|
||
|
||
bra.s noPredefinedColors
|
||
|
||
noColorizeLoop
|
||
|
||
@nxtEntry MOVE.L (A2),A0 ; get color table pointer
|
||
MOVE D4,D3 ; assume entry = index
|
||
TST TransIndex(A0) ; look for flag in transIndex
|
||
BMI.S @UseIndex ; => flag set, use index
|
||
MOVE.w CTTable+value(A0,D4*8),D3 ; get value of current entry <BAL/dvb 23Feb89>
|
||
@UseIndex MOVE CTTable+rgb+red(A0,D4*8),rgb+red+12(sp)
|
||
MOVE.L CTTable+rgb+green(A0,D4*8),rgb+green+12(SP)
|
||
|
||
CLR.L -(SP) ; make room for function result
|
||
PEA rgb+4+12(SP) ; point to VAR RGBColor <KON 28Apr90>
|
||
_Color2Index ; convert to index <BAL/dvb 23Feb89>
|
||
MOVE.L (SP)+,D0 ; get result
|
||
move.l D0,TBLOFST(SP,D3*4) ; put returned value in table <BAL 09May88> @@@@
|
||
DBRA D4,@nxtEntry ; => repeat until done
|
||
|
||
bra.s noPredefinedColors
|
||
|
||
brink MOVEQ #0,D6 ; zero high word
|
||
MOVE D4,D6 ; remember number of colors
|
||
@nxtPEntry MOVE.L (a2),A0 ; get color table pointer
|
||
MOVE D4,D3 ; assume entry = index
|
||
MOVE.w CTTable+value(A0,D4*8),12(sp) ; put pmIndex in colorSpec <KON 28Apr90
|
||
MOVE CTTable+rgb+red(A0,D4*8),rgb+red+12(SP) ; copy value, red <KON 28Apr90
|
||
MOVE.L CTTable+rgb+green(A0,D4*8),rgb+green+12(SP) ; copy green,blue <KON 28Apr90
|
||
CLR.L -(SP) ; make room for function result
|
||
PEA 4+12(SP) ; point to VAR ColorSpec <KON 28Apr90
|
||
_ColorThing2Index ; convert to index <BAL/dvb 23Feb89>
|
||
MOVE.L (SP)+,D0 ; get result
|
||
move.l D0,TBLOFST(SP,D3*4) ; put returned value in table <BAL 09May88> @@@@
|
||
DBRA D4,@nxtPEntry ; => repeat until done
|
||
|
||
clr.w QDErr ;remove any lingering error from ColorThing2Index
|
||
; <BAL 28Jan90>
|
||
; leave ColorSpec on stack
|
||
|
||
noPredefinedColors
|
||
; figure the number of unused colors
|
||
ADDQ.L #1,D6 ; make the number of colors 1 based
|
||
SUB.L D5,D6 ; figure difference between bit depth and colors defined
|
||
NEG.L D6 ; figure number of unused colors (zero based)
|
||
bgt.s @continue
|
||
; if negative or zero, strip foreground and background colors off stack: all done
|
||
add #12,sp ;throw away fore and back colors
|
||
|
||
bra @noRelativeColors
|
||
|
||
|
||
;
|
||
; At this point forecolor is on top of stack
|
||
;
|
||
|
||
@continue
|
||
MOVE.L SP,A1
|
||
MOVE.L A1,A2 ; save a copy of where the foreground is
|
||
MOVEQ #2,D0 ; three colors, two based
|
||
@startColor
|
||
MOVE #$8000,-(SP) ; put 1/2 on stack
|
||
MOVE (A1)+,-(SP) ; save integer on stack
|
||
DBRA D0,@startColor
|
||
|
||
MOVE.L A2,A1 ; start back with forecolor
|
||
LEA TBLOFST+12(SP,D5*4),A2 ; start of stack based table + 2 (12 bytes long colors) <KON 6MAR91>
|
||
SUBQ #1,D6 ; number of new colors, zero based
|
||
BEQ.S @skipDivision ; if only 1 color left, no need to interpolate
|
||
|
||
LEA 6(A1),A0 ; get start of real background color
|
||
MOVEQ #2,D0 ; three colors, one based
|
||
@nextColor
|
||
MOVEQ #0,D1 ; clear high word
|
||
MOVE (A0)+,D1 ; background color component
|
||
SUB (A1)+,D1 ; change from foreground
|
||
SLO D7 ; remember if it was negated
|
||
BHS.S @orderedOK
|
||
NEG D1 ; flip if subtraction would overflow
|
||
@orderedOK
|
||
SWAP D1 ; multiply high word times 65K
|
||
DIVU.L D6,D1 ; figure fixed point color increment
|
||
TST.B D7
|
||
BEQ.S @notFlipped
|
||
NEG.L D1 ; flip it
|
||
@notFlipped
|
||
MOVE.L D1,-(SP) ; save it
|
||
DBRA D0,@nextColor
|
||
|
||
MOVEM.L (SP)+,D3-D5 ; load red, blue, green increments into registers
|
||
|
||
@skipDivision
|
||
@findUnused
|
||
cmp.l #$7fffffff,-(A2) ; is it unused? <HACK> <BAL 09May88> @@@@
|
||
bne.s @findUnused ; if not, plow onward <BAL 09May88> @@@@
|
||
MOVE redHigh(SP),red+12(SP) ; >> redHigh = 8
|
||
MOVE greenHigh(SP),green+12(SP) ; >> greenHigh = 4
|
||
MOVE blueHigh(SP),blue+12(SP) ; >> blueHigh = 0
|
||
CLR.L -(SP) ; make room for function result
|
||
PEA 16(SP) ; location of RGBColor
|
||
_Color2Index
|
||
MOVE.L (SP)+,D0 ; get long result
|
||
move.l D0,(A2) ; save away index <BAL 09May88> @@@@
|
||
|
||
MOVEM.L (SP)+,D0-D2 ; last colors
|
||
ADD.L D3,D0
|
||
ADD.L D4,D1
|
||
ADD.L D5,D2 ; increment red, blue green
|
||
MOVEM.L D0-D2,-(SP) ; save them for next time
|
||
DBRA D6,@findUnused
|
||
ADD #24,SP ; throw away 3 long colors
|
||
@noRelativeColors
|
||
MOVEM.L (SP)+,A2/D0-D1/D3-D7 ; toss 8 on stack (D0,D1) & restore work registers
|
||
RTS
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to GetCIcon. When calculating icon size, don't multiply by
|
||
; pixelSize since rowBytes already includes the depth.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
GETCICON PROC EXPORT
|
||
|
||
ciGetCIcon EQU $3126A
|
||
ciNoGetNew EQU $3128A
|
||
;-------------------------------------------------------------
|
||
;
|
||
; FUNCTION GetCIcon(cIconID: INTEGER): cIconHandle;
|
||
;
|
||
; See description in Patterns.a
|
||
;
|
||
|
||
PARAMSIZE EQU 2
|
||
result EQU PARAMSIZE+8 ; cIconHandle RESULT
|
||
cIconID EQU PARAMSIZE+8-2 ; icon ID
|
||
|
||
LINK A6,#0 ; build stack frame
|
||
MOVEM.L D3-D4/A2-A4,-(SP) ; preserve work registers
|
||
CLR.L RESULT(A6) ; set result to NIL
|
||
|
||
; Load the data, detach from resource manager and lock it down
|
||
|
||
SUBQ #4,SP ; make space for result
|
||
MOVE.L #'cicn',-(SP) ; push resource type
|
||
MOVE cIconID(A6),-(SP) ; push resource ID
|
||
_GetResource ; get the resource
|
||
MOVE.L (SP)+,A0 ; keep handle in A0 <1.5> BAL
|
||
MOVE.L A0,D0 ; did we get one? <1.5> BAL
|
||
BEQ NoGetNew ; if not, don't allocate one
|
||
|
||
; copy resource data to the main pattern/cursor data structure, keep in A4
|
||
; The resource should be purgeable. Just leave it lying around.
|
||
|
||
_HandToHand ; create a copy without purgeing src <1.5> BAL
|
||
move.l A0,A4 ; get new handle into A4 <1.5> BAL
|
||
_HLock ; and lock it down
|
||
|
||
; Point to the color table
|
||
|
||
MOVE.L (A4),A3 ; keep pointer in A3
|
||
MOVE iconPMap+bounds+bottom(A3),D4 ; get bottom
|
||
SUB iconPMap+bounds+top(A3),D4 ; calc height, keep in D4
|
||
|
||
LEA iconRec(A3),A2 ; point to the mask data
|
||
MOVE iconMask+rowbytes(A3),D0 ; get mask's rowbytes
|
||
MULU D4,D0 ; get size of mask data
|
||
ADD D0,A2 ; point to bitmap table
|
||
MOVE iconBMap+rowbytes(A3),D0 ; get bitMap's rowbytes
|
||
MULU D4,D0 ; get size of bitmap data
|
||
ADD D0,A2 ; point to color table
|
||
|
||
; Install the color table
|
||
|
||
CLR.L -(SP) ; make room for function result
|
||
_GetCTSeed ; go get seed for new color table
|
||
MOVE.L (SP)+,CTSeed(A2) ; and set seed value
|
||
|
||
MOVE.L A2,A0 ; point to the color table data
|
||
MOVE CTSize(A2),D0 ; get number of entries in table
|
||
ADDQ #1,D0 ; make it one based
|
||
MULU #CTEntrySize,D0 ; get size of entries
|
||
ADD #CTRec,D0 ; add in size of header
|
||
EXT.L D0 ; long for PtrToHand
|
||
MOVE.L D0,D3 ; save size in D4
|
||
_PtrToHand ; get a new handle into A0
|
||
BNE NoGetNew ; =>exit if no memory
|
||
MOVE.L A0,iconPMap+pmTable(A3) ; install color table into pixMap
|
||
|
||
; Create the pixMap's data handle and install it
|
||
|
||
MOVE.L A2,A0 ; point to the color table
|
||
ADD.L D3,A0 ; bump to beginning of pixel data
|
||
MOVE iconPMap+rowBytes(A3),D0 ; get the pixMap rowbytes
|
||
AND #nuRBMask,D0 ; clear flag bits
|
||
MULU D4,D0 ; multiply rowbytes * height
|
||
; MULU iconPMap+pixelSize(A3),D0 ; and multiply by depth for size (silly mistake!!)
|
||
jmpROM ciGetCIcon
|
||
NoGetNew jmpROM ciNoGetNew
|
||
|
||
ENDPROC
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to StdOpcodeProc. This patch takes care of adjusting the picframe when hres and
|
||
; vres information is supplied in the header.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
StdOpcodeProc PROC EXPORT
|
||
; IMPORT GetLong,GetPicdata
|
||
|
||
ciGetLong EQU $32B90
|
||
ciGetPicdata EQU $32BA0
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
|
||
;
|
||
THERECT EQU 0 ;RECT
|
||
PENLOC EQU THERECT+8 ;POINT
|
||
TEXTLOC EQU PENLOC+4 ;POINT
|
||
OVALSIZES EQU TEXTLOC+4 ;POINT
|
||
FROMRECT EQU OVALSIZES+4 ;RECT
|
||
TORECT EQU FROMRECT+8 ;RECT
|
||
NUMER EQU TORECT+8 ;POINT
|
||
DENOM EQU NUMER+4 ;POINT
|
||
THECLIP EQU DENOM+4 ;RGNHANDLE
|
||
USERCLIP EQU THECLIP+4 ;RGNHANDLE
|
||
PLAYVERSION EQU USERCLIP+4 ;PICTURE VERSION
|
||
TXHFRAC EQU PLAYVERSION+2 ;FRACTIONAL TEXT POSITION
|
||
NEWHFRAC EQU TXHFRAC+2 ;UPDATED FRACTION RECIEVED
|
||
TEMPPIXPAT EQU NEWHFRAC+2 ;PIXPAT FOR PLAYING NEW PICS IN OLD PORTS
|
||
FontMappingTbl EQU TEMPPIXPAT+4 ;Handle to array of old,new font id pairs
|
||
PSreserve1 EQU FontMappingTbl+4 ;reserved
|
||
PSreserve2 EQU PSreserve1+4 ;reserved
|
||
PLAYREC EQU PSreserve2+4 ;TOTAL SIZE
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; New offsets in a PICT2 header record:
|
||
;
|
||
hdrVersion EQU 0 ;Word (=-2)
|
||
hdrReserved EQU hdrVersion+2 ;Word
|
||
hdrHRes EQU hdrReserved+2 ;Fixed
|
||
hdrVRes EQU hdrHRes+4 ;Fixed
|
||
hdrSrcRect EQU hdrVRes+4 ;Rect
|
||
hdrReserved2 EQU hdrSrcRect+8 ;Long
|
||
picHdrSize EQU hdrReserved2+4 ;size of a PICT2 header record
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StdOpcode(fromRect,toRect: Rect; opcode,version: INTEGER);
|
||
;
|
||
; GETS CALLED FOR OPCODE VALUES $0100-$FFFF
|
||
;
|
||
; OPCODE: $0100-$01FF 2 BYTES DATA
|
||
; $0200-$02FF 4 BYTES DATA
|
||
; ...
|
||
; $7F00-$7FFF 254 BYTES DATA
|
||
; $8000-$80FF 0 BYTES DATA
|
||
; $8100-$FFFF 4 BYTES SIZE + SIZE BYTES DATA
|
||
;
|
||
; THIS PROCEDURE READS THE OPCODE'S DATA AND IGNORES IT
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 12
|
||
pFROMRECT EQU PARAMSIZE+8-4 ;LONG
|
||
pTORECT EQU pFROMRECT-4 ;LONG
|
||
OPCODE EQU pTORECT-2 ;WORD
|
||
VERSION EQU OPCODE-2 ;WORD
|
||
|
||
LINK A6,#0 ;NO LOCAL VARS
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L #256,D6 ;GET USEFUL NUMBER
|
||
SUB.L D6,SP ;ALLOCATE STACK BUFFER
|
||
|
||
MOVE OPCODE(A6),D0 ;GET THE OPCODE
|
||
BMI.S GETSIZE ;=>OP CONTAINS SIZE
|
||
LSR #8,D0 ;GET SIZE/2 IN LOW NIBBLE
|
||
ADD D0,D0 ;CALC SIZE
|
||
EXT.L D0 ;MAKE IT LONG
|
||
BRA.S SHARE ;=>USE COMMON CODE
|
||
GETSIZE AND #$7F00,D0 ;MASK THE OPCODE
|
||
BEQ.S DONE ;=>NO DATA BYTES
|
||
jsrROM ciGetLong ;READ IN SIZE
|
||
SHARE MOVE.L D0,D7 ;SAVE WHOLE SIZE
|
||
NXTCHNK MOVE D6,D0 ;ASSUME SIZE >= 256
|
||
CMP.L D6,D7 ;IS SIZE >= 256?
|
||
BGE.S SIZEOK ;=>YES, SKIP 256 BYTES
|
||
MOVE D7,D0 ;ELSE SKIP REMAINING BYTES
|
||
SIZEOK MOVE.L SP,-(SP) ;PUSH BUFFER POINTER
|
||
MOVE D0,-(SP) ;PUSH BYTECOUNT
|
||
if TheFuture then ; <124> Take out of current builds
|
||
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <121>
|
||
beq.s Done
|
||
endif ; <124>
|
||
jsrROM ciGetPicdata ;READ DATA INTO BUFFER
|
||
SUB.L D6,D7 ;SUBTRACT BUFSIZE FROM COUNT
|
||
BGT.S NXTCHNK ;=>GO SKIP NEXT CHUNK
|
||
|
||
;Slimey hack assumes that StdOpCodeProc is called with a pointer to the fromRect inside
|
||
;the active playstate record for the pict. Fortunately, this is the case. Otherwise, the
|
||
;"illegal" altering of Denom and FromRect would not affect the picture playback.
|
||
|
||
;If this opcode were in the midst of a picture (or we supported more than one per pict)
|
||
;then we would also have to remap the pensize and potentially the cliprgn as well.
|
||
|
||
cmp.w #ngHeaderOp,OPCODE(a6) ;pict2 header opcode?
|
||
bne.s done ;not a pict2 header opcode
|
||
cmp.w #$fffe,(sp) ;is it version -2 header?
|
||
bne.s done ;<27nov89 KON>
|
||
move.l pFromRect(a6),a1 ;point to playstate's FromRect
|
||
lea hdrSrcRect(sp),a0 ;point to sourceRect stored in header record
|
||
MOVE RIGHT(A0),D0
|
||
SUB LEFT(A0),D0 ;CALC SRC WIDTH
|
||
MOVE D0,DENOM+H-FromRect(A1) ;DENOM.H := SRC WIDTH
|
||
MOVE BOTTOM(A0),D0
|
||
SUB TOP(A0),D0 ;CALC SRC HEIGHT
|
||
MOVE D0,DENOM+V-FromRect(A1) ;DENOM.V := SRC HEIGHT
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+ ;FROMRECT := PICFRAME
|
||
|
||
DONE ADD.L D6,SP ;STRIP BUFFER
|
||
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
UNLINK PARAMSIZE,'STDPICPR'
|
||
ENDPROC
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to DrawPicture. This patch performs font name/ID binding on picture playback
|
||
; We need the entire routine since the stack frame has changed from the ROM version.
|
||
; Specifically, SAVEPORT moved and is used near the end of this routine.
|
||
;
|
||
; Patch to DrawPicture. This patch also handles the line-layout state on picture
|
||
; playback for the Script Manager.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
|
||
DrawPicture PROC EXPORT
|
||
; IMPORT PicItem1,NewRgn,InitColorStuff
|
||
;------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DrawPicture(myPicture: PicHandle; dstRect: Rect);
|
||
;
|
||
|
||
;
|
||
; -- ROM Entry points
|
||
;
|
||
InitColorStuff EQU $30160
|
||
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
|
||
;
|
||
THERECT EQU 0 ;RECT
|
||
PENLOC EQU THERECT+8 ;POINT
|
||
TEXTLOC EQU PENLOC+4 ;POINT
|
||
OVALSIZES EQU TEXTLOC+4 ;POINT
|
||
FROMRECT EQU OVALSIZES+4 ;RECT
|
||
TORECT EQU FROMRECT+8 ;RECT
|
||
NUMER EQU TORECT+8 ;POINT
|
||
DENOM EQU NUMER+4 ;POINT
|
||
THECLIP EQU DENOM+4 ;RGNHANDLE
|
||
USERCLIP EQU THECLIP+4 ;RGNHANDLE
|
||
PLAYVERSION EQU USERCLIP+4 ;PICTURE VERSION
|
||
TXHFRAC EQU PLAYVERSION+2 ;FRACTIONAL TEXT POSITION
|
||
NEWHFRAC EQU TXHFRAC+2 ;UPDATED FRACTION RECIEVED
|
||
TEMPPIXPAT EQU NEWHFRAC+2 ;PIXPAT FOR PLAYING NEW PICS IN OLD PORTS
|
||
FontMappingTbl EQU TEMPPIXPAT+4 ;Handle to array of old,new font id pairs
|
||
PSreserve1 EQU FontMappingTbl+4 ;reserved
|
||
PSreserve2 EQU PSreserve1+4 ;reserved
|
||
PLAYREC EQU PSreserve2+4 ;TOTAL SIZE
|
||
|
||
;
|
||
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 8
|
||
MYPICTURE EQU PARAMSIZE+8-4 ;LONG, PICHANDLE
|
||
DSTRECT EQU MYPICTURE-4 ;LONG, ADDR OF RECT
|
||
|
||
PLAYSTATE EQU -PLAYREC ;PICTURE PLAY STATE RECORD
|
||
SAVEPORT EQU PLAYSTATE-PORTREC ;GRAFPORT RECORD
|
||
saveQdRunSlop equ SAVEPORT-4 ;Fixed <54>
|
||
saveQdChExtra equ saveQdRunSlop-4 ;Fixed <54>
|
||
saveOutline equ saveQdChExtra-1 ;Byte
|
||
savePreserve equ saveOutline-1 ;Byte
|
||
saveFractional equ savePreserve-1 ;Byte
|
||
saveUnscaled equ saveFractional-1 ;Byte
|
||
VARSIZE EQU saveUnscaled ;TOTAL BYTES OF LOCALS
|
||
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE LOCALS
|
||
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGISTERS
|
||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
|
||
TST.L MYPICTURE(A6) ;IS PICHANDLE NIL ?
|
||
BEQ GOHOME ;YES, QUIT
|
||
|
||
;--------------------------------------------------
|
||
;
|
||
; SET UP NUMER AND QUIT IF DSTRECT WIDTH OR HEIGHT IS <= 0
|
||
; COPY DSTRECT INTO TORECT
|
||
;
|
||
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
||
MOVE RIGHT(A0),D0
|
||
SUB LEFT(A0),D0 ;CALC DST WIDTH
|
||
BLE GOHOME ;QUIT IF WIDTH <= 0
|
||
MOVE D0,PLAYSTATE+NUMER+H(A6) ;NUMER.H := DST WIDTH
|
||
MOVE BOTTOM(A0),D0
|
||
SUB TOP(A0),D0 ;CALC DST HEIGHT
|
||
BLE GOHOME ;QUIT IF HEIGHT <= 0
|
||
MOVE D0,PLAYSTATE+NUMER+V(A6) ;NUMER.V := DST HEIGHT
|
||
LEA PLAYSTATE+TORECT(A6),A1
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+ ;TORECT := DSTRECT
|
||
|
||
|
||
;--------------------------------------------------
|
||
;
|
||
; SET UP DENOM AND QUIT IF PICFRAME WIDTH OR HEIGHT IS <= 0
|
||
; COPY PICFRAME INTO FROMRECT.
|
||
;
|
||
|
||
MOVE.L MYPICTURE(A6),A0 ;GET PICHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
|
||
;if PICT 2 and header version = -2, use source rect instead of picFrame.
|
||
|
||
;<<<Moved to StdOpcodeProc to support spooling>>>
|
||
|
||
; cmp.l #$001102ff,picData(a0) ;PICT 2 ?
|
||
; bne.s @notPic2
|
||
; cmp.l #$0c00fffe,picData+4(a0) ;hdr version -2 ?
|
||
; bne.s @notPic2
|
||
; lea picData+4+2+hdrSrcRect(a0),a0 ;point to srcRect
|
||
; bra.s @share
|
||
|
||
@notPic2
|
||
LEA PICFRAME(A0),A0 ;POINT TO PICTURE FRAME
|
||
@share
|
||
MOVE RIGHT(A0),D0
|
||
SUB LEFT(A0),D0 ;CALC SRC WIDTH
|
||
BLE GOHOME ;QUIT IF WIDTH <= 0
|
||
MOVE D0,PLAYSTATE+DENOM+H(A6) ;DENOM.H := SRC WIDTH
|
||
MOVE BOTTOM(A0),D0
|
||
SUB TOP(A0),D0 ;CALC SRC HEIGHT
|
||
BLE GOHOME ;QUIT IF HEIGHT <= 0
|
||
MOVE D0,PLAYSTATE+DENOM+V(A6) ;DENOM.V := SRC HEIGHT
|
||
|
||
LEA PLAYSTATE+FROMRECT(A6),A1 ;POINT TO FROMRECT
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+ ;FROMRECT := PICFRAME
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PRESERVE THE CURRENT GRAFPORT IN SAVEPORT
|
||
;
|
||
MOVE.L A3,A0 ;SRC = THEPORT
|
||
LEA SAVEPORT(A6),A1 ;DST = SAVEPORT
|
||
MOVEQ #PORTREC/2-1,D0 ;INIT DBRA COUNT
|
||
SAVELP MOVE.W (A0)+,(A1)+ ;COPY A WORD
|
||
DBRA D0,SAVELP ;LOOP ENTIRE PORT
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PRESERVE AND INIT THE CURRENT LINE-LAYOUT STATE
|
||
;
|
||
IF SCRIPT_CHAR_EXTRA THEN
|
||
move.l grafGlobals(a5),a0 ; load quickDraw globals. <54>
|
||
move.l qdChExtra(a0),saveQdChExtra(a6) ; save character extra amount. <54>
|
||
move.l qdRunSlop(a0),saveQdRunSlop(a6) ; save run slop amount. <54>
|
||
clr.l qdChExtra(a0) ; clear character extra amount. <54>
|
||
clr.l qdRunSlop(a0) ; clear run slop amount. <54>
|
||
ENDIF
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; PRESERVE THE INITIAL GLYPH RENDERING STATE
|
||
;
|
||
IF hasGlyphState THEN
|
||
btst.b #splinePreferred,HiliteMode ; bit flag set in HiliteMode?
|
||
sne.b saveOutline(a6) ; yes, set outline preferred flag
|
||
btst.b #preserveGlyph,HiliteMode ; bit flag set in HiliteMode?
|
||
sne.b savePreserve(a6) ; yes, set preserve glyph flag
|
||
move.b FractEnable,saveFractional(a6) ; save fractional widths flag
|
||
move.b FScaleDisable,saveUnscaled(a6) ; save scale disable flag
|
||
ENDIF
|
||
|
||
|
||
;----------------------------------------
|
||
;
|
||
; INIT GLOBAL VARS:
|
||
;
|
||
CLR.L PATALIGN(A4) ;PATALIGN := (0,0)
|
||
MOVE.L MYPICTURE(A6),PLAYPIC(A4) ;SAVE PICTURE FOR STDGETPIC
|
||
MOVE.L #PICDATA,PLAYINDEX(A4) ;INIT INDEX TO FIRST OPCODE
|
||
|
||
|
||
;----------------------------------------
|
||
;
|
||
; INIT PLAY STATE RECORD:
|
||
;
|
||
LEA PLAYSTATE(A6),A0
|
||
CLR.L (A0)+ ;THERECT := (0,0,0,0)
|
||
CLR.L (A0)+
|
||
CLR.L (A0)+ ;PENLOC := (0,0)
|
||
CLR.L (A0)+ ;TEXTLOC := (0,0)
|
||
CLR.L (A0)+ ;OVALSIZES := (0,0)
|
||
;FROMRECT SET UP
|
||
;TORECT SET UP
|
||
;NUMER SET UP
|
||
;DENOM SET UP
|
||
|
||
|
||
MOVE.L CLIPRGN(A3),PLAYSTATE+USERCLIP(A6) ;SAVE USER CLIPRGN
|
||
|
||
CLR.L -(SP)
|
||
_NEWRGN
|
||
MOVE.L (SP)+,PLAYSTATE+THECLIP(A6) ;ALLOCATE THECLIP
|
||
MOVE #$8000,D0 ;INITIALIZE FRACTIONAL PARTS
|
||
MOVE D0,PLAYSTATE+TXHFRAC(A6) ;TXHFRAC = 1/2
|
||
MOVE D0,PLAYSTATE+NEWHFRAC(A6) ;NEW FRACTION = 1/2
|
||
|
||
|
||
;
|
||
; Allocate handle for mapping of fond id's we have seen so far
|
||
;
|
||
; Format of FontMappingTbl handle is:
|
||
; handle size [long]
|
||
; # of entries - 1 used [word]
|
||
; oldID1,newID1 ... oldIDn,newIDn
|
||
|
||
FontMapSize equ 25*4
|
||
|
||
doFontList
|
||
moveq #FontMapSize+6,d0 ;initial size for 50 entries
|
||
_NewHandle
|
||
move.l a0,PLAYSTATE+FontMappingTbl(a6) ;save picFontList handle in picSave record
|
||
beq.s @noHandle
|
||
|
||
move.l (a0),a0 ;point into fontList
|
||
moveq #FontMapSize+6,d0 ;initial size for 25 entries
|
||
move.l d0,(a0)+
|
||
move.w #-1,(a0) ; 0 entries
|
||
|
||
; clr.l (a0)+ ; 1 entry, first oldID = 0
|
||
; clr.w (a0) ; first newID = 0
|
||
|
||
@noHandle
|
||
|
||
;--------------------------------------------------------
|
||
;
|
||
; INIT MOST FIELDS OF THEPORT
|
||
;
|
||
CLR.L -(SP)
|
||
_NEWRGN
|
||
MOVE.L (SP)+,CLIPRGN(A3) ;ALLOCATE TEMP CLIPRGN
|
||
LEA BKPAT(A3),A0 ;POINT TO BKPAT
|
||
CLR.L (A0)+ ;BKPAT := WHITE
|
||
CLR.L (A0)+
|
||
MOVEQ #-1,D0 ;GET SOME BLACK
|
||
MOVE.L D0,(A0)+ ;fillPat := BLACK
|
||
MOVE.L D0,(A0)+
|
||
CLR.L (A0)+ ;PNLOC := (0,0)
|
||
MOVE.L #$00010001,D1
|
||
MOVE.L D1,(A0)+ ;pnSize := (1,1)
|
||
MOVE #8,(A0)+ ;pnMode := patCopy
|
||
MOVE.L D0,(A0)+ ;pnPat := black
|
||
MOVE.L D0,(A0)+
|
||
ADD #2,A0 ;skip over pnVis
|
||
CLR.L (A0)+ ;txFont, txFace := 0
|
||
MOVE #1,(A0)+ ;txMode := srcOr
|
||
CLR (A0)+ ;txSize := 0;
|
||
CLR.L (A0)+ ;spExtra := 0.0;
|
||
MOVE.L #blackColor,(A0)+ ;FGCOLOR := blackColor
|
||
MOVE.L #whiteColor,(A0)+ ;BKCOLOR := whiteColor
|
||
;LEAVE COLRBIT ALONE
|
||
;LEAVE PATSTRETCH ALONE
|
||
;LEAVE PICSAVE ALONE
|
||
;LEAVE RGNSAVE ALONE
|
||
;LEAVE POLYSAVE ALONE
|
||
;LEAVE GRAFPROCS ALONE
|
||
|
||
;--------------------------------------------------
|
||
;
|
||
PEA PNSIZE(A3) ;Scale initial pensize <BAL/CSD 02Apr89>
|
||
PEA FROMRECT+PLAYSTATE(A6) ;so that 1,1 lines scale
|
||
PEA TORECT+PLAYSTATE(A6)
|
||
_SCALEPT ;SCALE PNSIZE
|
||
|
||
;--------------------------------------------------
|
||
;
|
||
; IF IT'S A NEW GRAFPORT, SET UP NEW FIELDS IN GRAFPORT.
|
||
;
|
||
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
|
||
BMI.S @NEWPIC ;=>YES, INSTALL NEW FIELDS
|
||
|
||
; IF OLD GRAFPORT, ALLOCATE A PIXPAT TO READ INTO
|
||
|
||
CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT
|
||
_NEWPIXPAT ;ALLOCATE A PIXPAT
|
||
MOVE.L (SP)+,PLAYSTATE+TEMPPIXPAT(A6) ;SAVE IN PLAYSTATE RECORD
|
||
BRA.S DRAWPIC ;AND SKIP NEW GRAFPORT STUFF
|
||
|
||
; INVALIDATE PIXPAT FIELDS SO THEY GET NEW PIXPATS INSTALLED
|
||
|
||
@NEWPIC CLR.L BKPIXPAT(A3) ;ONE IS THE BACKGROUND PATTERN
|
||
CLR.L PNPIXPAT(A3) ;ONE IS THE PEN PATTERN
|
||
CLR.L FILLPIXPAT(A3) ;AND ONE IS THE FILL PATTERN
|
||
|
||
MOVE.L A3,-(SP) ;PUSH GRAFPORT
|
||
jsrROM INITCOLORSTUFF ;AND INITIALIZE PATTERNS AND COLORS
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; NOW DRAW THE PICTURE:
|
||
; REPEAT UNTIL NOT PicItem1(playState);
|
||
;
|
||
DRAWPIC MOVE #PICTVERSION,PLAYSTATE+PLAYVERSION(A6) ;DEFAULT TO OLD PICTURE
|
||
|
||
MOVE.L MYPICTURE(A6),A0 ;GET PICTURE HANDLE <16Jun88 BAL>
|
||
_HGETSTATE ;GET AND SAVE STATE <16Jun88 BAL>
|
||
MOVE D0,-(SP) ; <16Jun88 BAL>
|
||
_HLOCK ;LOCK IT DOWN <16Jun88 BAL>
|
||
MORE
|
||
if TheFuture then ; <124> Take out of current builds
|
||
cmp.w #AbortPicPlayBackErr,qdErr ;abort if special error <121>
|
||
beq.s Done ; <121>
|
||
endif ; <124>
|
||
CLR.B -(SP) ;MAKE ROOM FOR FCN RESULT
|
||
PEA PLAYSTATE(A6) ;PUSH ADDR OF PLAYSTATE
|
||
_PicItem1 ;DRAW ONE PICTURE ITEM
|
||
MOVE.B (SP)+,D0 ;POP BOOLEAN RESULT
|
||
BNE.S MORE ;LOOP TILL FALSE
|
||
|
||
|
||
;-----------------------------------------------------
|
||
;
|
||
; DISCARD HANDLES AND RESTORE GRAFPORT STATE
|
||
;
|
||
DONE MOVE.L MYPICTURE(A6),A0 ;GET PICTURE HANDLE <16Jun88 BAL>
|
||
MOVE (SP)+,D0 ;GET SAVED STATE <16Jun88 BAL>
|
||
_HSETSTATE ;RESTORE STATE <16Jun88 BAL>
|
||
|
||
MOVE.L PLAYSTATE+THECLIP(A6),A0 ;GET THECLIP RGNHANDLE
|
||
_DisposHandle ;DISCARD IT
|
||
|
||
MOVE.L PLAYSTATE+FontMappingTbl(A6),A0 ;get the fontID association table
|
||
_DisposHandle ;DISCARD IT
|
||
|
||
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW PORT?
|
||
BMI.S @NEWPORT ;=>YES, DISPOSE PIXPATS
|
||
MOVE.L PLAYSTATE+TEMPPIXPAT(A6),-(SP) ;ELSE PUSH TEMP PIXPAT
|
||
_DISPOSPIXPAT ;AND DISCARD IT
|
||
BRA.S DONE1 ;=>DISPOSE COMMON STUFF
|
||
|
||
@NEWPORT MOVE.L BKPIXPAT(A3),-(SP) ;PUSH THE BACKGROUND PATTERN
|
||
_DISPOSPIXPAT ;AND DISCARD IT
|
||
MOVE.L PNPIXPAT(A3),-(SP) ;PUSH THE PEN PATTERN
|
||
_DISPOSPIXPAT ;AND DISCARD IT
|
||
MOVE.L FILLPIXPAT(A3),-(SP) ;PUSH THE FILL PATTERN
|
||
_DISPOSPIXPAT ;AND DISCARD IT
|
||
|
||
DONE1 MOVE.L CLIPRGN(A3),A0 ;GET TEMPCLIP
|
||
_DisposHandle ;DISCARD IT
|
||
LEA SAVEPORT(A6),A0 ;SRC = SAVEPORT
|
||
MOVEQ #PORTREC/2-1,D0 ;INIT DBRA COUNT
|
||
DONELP MOVE.W (A0)+,(A3)+ ;COPY A WORD INTO THEPORT
|
||
DBRA D0,DONELP ;LOOP ENTIRE PORT
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; RESTORE THE GLYPH RENDERING STATE
|
||
;
|
||
IF hasGlyphState THEN
|
||
move.b saveOutline(a6),-(sp) ; push saved outline preferred flag
|
||
_SetOutlinePreferred ; restore saved outline preferred
|
||
move.b savePreserve(a6),-(sp) ; push saved preserve glyph flag
|
||
_SetPreserveGlyph ; restore saved preserve glyph
|
||
move.b saveFractional(a6),-(sp) ; push saved fractional widths flag
|
||
_SetFractEnable ; restore saved fractional widths
|
||
move.b saveUnscaled(a6),-(sp) ; push saved scale disable flag
|
||
_SetFScaleDisable ; restore saved scale disable
|
||
ENDIF
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; RESTORE THE LINE-LAYOUT STATE
|
||
;
|
||
IF SCRIPT_CHAR_EXTRA THEN
|
||
move.l grafGlobals(a5),a0 ; load quickDraw globals. <54>
|
||
move.l saveQdChExtra(a6),qdChExtra(a0) ; restore character extra amount. <54>
|
||
move.l saveQdRunSlop(a6),qdRunSlop(a0) ; restore run slop amount. <54>
|
||
ENDIF
|
||
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; RESTORE GLOBAL VARS AND QUIT
|
||
;
|
||
CLR.L PATALIGN(A4) ;RESTORE PATALIGN TO (0,0)
|
||
CLR.L PLAYPIC(A4) ;SET PLAYPIC TO NIL
|
||
CLR.L PLAYINDEX(A4) ;AND PLAYINDEX TO 0
|
||
|
||
GOHOME MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGISTERS
|
||
UNLINK PARAMSIZE,'DRAWPICT'
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to add PicItem1. PicItem1 dispatches the picture drawing opcodes. Since we are
|
||
; only changing opcode $2C and opcode $03, we handle them at the top. If we have any
|
||
; other opcode, we jump to the ROM version.
|
||
;
|
||
; But wait! Don't forget to check for the $2C opcode which is used to record the line-
|
||
; layout state for the Script Manager.
|
||
;
|
||
; Even better! We now check for the $2E opcode which is used to record the state of the
|
||
; Font Manager and TrueType for glyph rendering.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
PicItem1 FUNC EXPORT
|
||
;------------------------------------------------------------------
|
||
;
|
||
; FUNCTION PicItem1(VAR playState: PicPlayRec): BOOLEAN;
|
||
;
|
||
; Draws one picture item, updating playState and thePort.
|
||
; Returns FALSE when an endPic opCode is encountered.
|
||
; The only state modified other than thePort and playState is patAlign.
|
||
;
|
||
; When reading from an NPIC, skips to word boundary before fetching
|
||
; word-long opcode.
|
||
|
||
PicItemContinue EQU $31F80
|
||
PicItemDone EQU $32B48
|
||
ciGetByte EQU $32B60
|
||
ciGetWord EQU $32B80
|
||
ciGetLong EQU $32B90
|
||
ciGetPicData EQU $32BA0
|
||
ciGetPicOp EQU $32ABE
|
||
ciIgnoreShort EQU $3236E
|
||
ciIgCount EQU $3237E
|
||
ciCALL1 EQU $32B16
|
||
ciGOIGCOUNT EQU $32378
|
||
ciBitsOp2 EQU $326A6
|
||
ciContinueBitsOp EQU $3268C
|
||
ciGETPICTABLE EQU $32F70
|
||
ciMAPRATIO EQU $33AE0
|
||
|
||
ciDoBits EQU $32732
|
||
ciBadBits EQU $327AE
|
||
ciAfterLstBand EQU $3296A
|
||
ciAbort EQU $32B3A
|
||
ciGetHndl EQU $32AE6
|
||
|
||
TxFontOpCode EQU $0003
|
||
TxRatioOpCode EQU $0010
|
||
FontIDOpCode EQU $002C
|
||
LayoutOpCode EQU $002D
|
||
GlyphOpCode EQU $002E
|
||
UserQDOpCode EQU $00A2
|
||
;--------------------------------------------
|
||
;
|
||
; OFFSETS WITHIN A PICTURE PLAY STATE RECORD:
|
||
;
|
||
THERECT EQU 0 ;RECT
|
||
PENLOC EQU THERECT+8 ;POINT
|
||
TEXTLOC EQU PENLOC+4 ;POINT
|
||
OVALSIZES EQU TEXTLOC+4 ;POINT
|
||
FROMRECT EQU OVALSIZES+4 ;RECT
|
||
TORECT EQU FROMRECT+8 ;RECT
|
||
NUMER EQU TORECT+8 ;POINT
|
||
DENOM EQU NUMER+4 ;POINT
|
||
THECLIP EQU DENOM+4 ;RGNHANDLE
|
||
USERCLIP EQU THECLIP+4 ;RGNHANDLE
|
||
PLAYVERSION EQU USERCLIP+4 ;PICTURE VERSION
|
||
TXHFRAC EQU PLAYVERSION+2 ;FRACTIONAL TEXT POSITION
|
||
NEWHFRAC EQU TXHFRAC+2 ;UPDATED FRACTION RECIEVED
|
||
TEMPPIXPAT EQU NEWHFRAC+2 ;PIXPAT FOR PLAYING NEW PICS IN OLD PORTS
|
||
FontMappingTbl EQU TEMPPIXPAT+4 ;Handle to array of old,new font id pairs
|
||
PSreserve1 EQU FontMappingTbl+4 ;reserved
|
||
PSreserve2 EQU PSreserve1+4 ;reserved
|
||
PLAYREC EQU PSreserve2+4 ;TOTAL SIZE
|
||
;
|
||
; params:
|
||
;
|
||
PARAMSIZE EQU 4
|
||
RESULT EQU PARAMSIZE+8 ;BOOLEAN
|
||
PLAYSTATE EQU RESULT-4 ;LONG, PICHANDLE
|
||
;
|
||
; locals:
|
||
;
|
||
HANDLE1 EQU -4 ;HANDLE
|
||
HANDLE2 EQU HANDLE1-4 ;HANDLE
|
||
TmpHANDLE1 EQU HANDLE2-4 ;temporary memory handle <1.5> BAL
|
||
DSTRECT EQU TmpHANDLE1-8 ;RECT (MUST BE BEFORE SRCRECT)
|
||
SRCRECT EQU DSTRECT-8 ;RECT (MUST FOLLOW DSTRECT)
|
||
SRCPIX EQU SRCRECT-PMREC ;PIXMAP
|
||
SRCBITS EQU SRCPIX-BITMAPREC ;BITMAP
|
||
SAMEFLAG EQU SRCBITS-2 ;BOOLEAN
|
||
NEWPT EQU SAMEFLAG-4 ;LONG
|
||
TXDATA EQU NEWPT-256 ;UP TO 256 CHARACTERS,
|
||
;ALSO USED FOR PACKBUF !!!
|
||
SRCPTR EQU TXDATA-4 ;LONG
|
||
DSTPTR EQU SRCPTR-4 ;LONG
|
||
SAVEDSP EQU DSTPTR-4 ;LONG
|
||
VARSIZE EQU SAVEDSP ;TOTAL BYTES OF LOCALS
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE LOCALS
|
||
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGISTERS
|
||
MOVE.L SP,SAVEDSP(A6) ;REMEMBER STACK FOR ABORT
|
||
clr.l tmpHandle1(a6) ;don't dispose it again
|
||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
|
||
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
|
||
|
||
; GET PICTURE OPCODE AND CHECK FOR END OF PICTURE.
|
||
|
||
MOVE.B #1,RESULT(A6) ;Assume NOT END OF PICTURE
|
||
jsrROM ciGetPicOp ;READ OPCODE INTO D0
|
||
if TheFuture then ; <124> Do only in the future
|
||
cmp.w #AbortPicPlayBackErr,qdErr ;abort if special error <121>
|
||
beq Done ; <121>
|
||
endif ; <124>
|
||
cmp #TxFontOpCode, d0
|
||
beq DoTxFontOpCode
|
||
cmp #TxRatioOpCode, d0 ;is it font/ID opcode?
|
||
beq DoTxRatioOpCode
|
||
cmp #FontIDOpCode, d0 ;is it font/ID opcode?
|
||
beq DoFontIDOpCode
|
||
IF SCRIPT_CHAR_EXTRA THEN
|
||
cmp #LayoutOpCode,d0 ;line-layout opcode?
|
||
beq DoLayoutOpCode ;yes -> load line-layout state.
|
||
ENDIF
|
||
IF hasGlyphState THEN
|
||
cmp #GlyphOpCode,d0 ; glyph state opcode?
|
||
beq DoStateOpCode ; yes, glyph state information
|
||
ENDIF
|
||
;
|
||
; Check for 90, 91, 98, 99, 9A, and 9B. If color table is zero, don't load it.
|
||
;
|
||
cmp #$90,d0
|
||
blt.s @NotUs
|
||
cmp #$9B,d0
|
||
ble.s @DoBitsOpCode
|
||
@NotUs
|
||
CLR.B RESULT(A6) ;ASSUME END OF PICTURE
|
||
jmpROM PicItemContinue ;BacktoRom
|
||
|
||
@DoBitsOpCode
|
||
move d0,d7
|
||
and #$07,d7 ;get verb from low nibble
|
||
BITSOP CMP #3,D7 ;CHECK OPCODE <16Jun88 BAL>
|
||
BGT IGNORESHORT ;=>READ WORD LENGTH + DATA
|
||
CMP #1,D7 ;IS IT INDEXED <16Jun88 BAL>
|
||
BLE.S @IND ;YES DON'T SKIP BOGUS LONG <16Jun88 BAL>
|
||
jsrROM ciGETLONG ;GET BOGUS LONG FROM PICTURE <16Jun88 BAL>
|
||
|
||
@IND jsrROM ciGETWORD ;GET ROWBYTES FROM PICTURE
|
||
MOVE D0,SRCPIX+ROWBYTES(A6) ;SAVE ROWBYTES
|
||
MOVEQ #BITMAPREC-6,D1 ;GET SIZE OF BITMAP
|
||
MOVE D0,D6 ;IS IT A BITMAP OR A PIXMAP?
|
||
BPL.S BITSOP1 ;=>IT'S A BITMAP
|
||
MOVEQ #PMREC-6,D1 ;GET SIZE OF PIXMAP
|
||
BITSOP1 PEA SRCPIX+BOUNDS(A6) ;PUSH ADDR OF SRCPIX.BOUNDS
|
||
MOVE D1,-(SP) ;PUSH BYTECOUNT
|
||
jsrROM ciGETPICDATA ;GET BITMAP/PIXMAP
|
||
|
||
clr.w SRCPIX+pmVersion(A6) ; assume 24 bit addressing
|
||
|
||
; IF IT'S A PIXMAP, THEN ALLOCATE A COLOR TABLE AND GET IT FROM THE PICTURE
|
||
|
||
TST D6 ;IS IT A PIXMAP?
|
||
BPL.S BITSOP2 ;=>NO, DON'T GET TABLE
|
||
move.l srcpix+pmTable(a6),d6 ;Get color table from record <28> <KON 28NOV90>
|
||
clr.l srcPix+PMTable(a6) ;assume no clut <12Jul88 BAL>
|
||
BTST #1,D7 ;IS IT DIRECT DATA? <16Jun88 BAL>
|
||
bne.s BITSOP2 ;yes, no CLUT <12Jul88 BAL>
|
||
|
||
@GETLUT MOVEQ #CTREC,D0 ;GET SIZE OF COLOR TABLE
|
||
_NewHandle ;assume it works....
|
||
; JSR RNEWHANDLE ;GET A HANDLE FOR IT
|
||
MOVE.L A0,SRCPIX+PMTABLE(A6) ;SAVE COLOR TABLE HANDLE
|
||
MOVE.L A0,-(SP) ;PUSH COLOR TABLE HANDLE
|
||
jsrROM ciGETPICTABLE ;READ COLOR TABLE INTO HANDLE
|
||
tst.l d6 ;was color table NIL?
|
||
bne.s BitsOp2 ;no, continue
|
||
;
|
||
; Color table was NIL on record. If it's a dummy CTable, throw it away. Value field
|
||
; of $4B4F in value field of 0th entry signals dummy table.
|
||
;
|
||
move.l srcPix+pmTable(a6),a0
|
||
move.l (a0),a2 ;get ptr to color table
|
||
cmp.w #cTabSignature,ctTable(a2) ;signature there?
|
||
bne.s BITSOP2 ;no, then skip
|
||
_DisposHandle ;yes, throw ctable away
|
||
clr.l srcPix+pmTable(a6)
|
||
|
||
BitsOp2
|
||
if not(TheFuture) then ; <124> Use this old code for present builds
|
||
jmpROM ciBitsOp2 ; <124>
|
||
endif ; <124>
|
||
if TheFuture then ; <124> Use this only in TheFuture builds
|
||
PEA SRCRECT(A6) ;PUSH ADDR OF SRCRECT
|
||
MOVE #16,-(SP) ;PUSH BYTECOUNT = 16
|
||
jsrROM ciGetPicData ;GET SRCRECT,DSTRECT
|
||
|
||
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
|
||
PEA DSTRECT(A6)
|
||
PEA FROMRECT(A2)
|
||
PEA TORECT(A2)
|
||
_MAPRECT ;MAP DSTRECT
|
||
PEA SRCPIX(A6) ;PUSH SRCPIX
|
||
PEA SRCRECT(A6) ;PUSH ADDR OF SRCRECT
|
||
PEA DSTRECT(A6) ;PUSH ADDR OF DSTRECT
|
||
jsrROM ciGETWORD ;GET MODE
|
||
MOVE D0,-(SP) ;PUSH MODE
|
||
|
||
CLR.L -(SP) ;ASSUME MASKRGN = NIL
|
||
BTST #0,D7 ;IS MASKRGN USED ? <16Jun88 BAL>
|
||
BEQ.S NOTRGN ;=> YES, USE NIL RGN
|
||
|
||
USERGN jsrROM ciGetHndl ;GET MASKRGN INTO HANDLE1
|
||
MOVE.L HANDLE1(A6),-(SP) ;PUSH MASKRGN
|
||
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
|
||
PEA FROMRECT(A2) ;PUSH FROMRECT
|
||
PEA TORECT(A2) ;PUSH TORECT
|
||
_MAPRGN ;MAP RGN INTO DSTRECT COORDS
|
||
MOVE.L HANDLE1(A6),(SP) ;PASS MASKRGN
|
||
MOVE.L HANDLE1(A6),HANDLE2(A6) ;AND REMEMBER MASKRGN IN HANDLE2
|
||
|
||
NOTRGN MOVE SRCPIX+BOUNDS+BOTTOM(A6),D6 ;GET SRCPIX.BOTTOM
|
||
SUB SRCPIX+BOUNDS+TOP(A6),D6 ;CALC HEIGHT
|
||
MOVE D6,D5 ;COPY HEIGHT
|
||
MOVE SRCPIX+ROWBYTES(A6),D0 ;GET BITMAP/PIXMAP ROWBYTES
|
||
AND #nuRBMask,D0 ;CLEAR FLAG BITS
|
||
MULU D0,D5 ;CALC BITMAP SIZE
|
||
|
||
; If the memory request fails, go image a band at a time <C946>
|
||
MOVE.L D5,D0 ;GET BYTECOUNT
|
||
_NewHandle ;ALLOCATE BITS HANDLE
|
||
BNE tryBands ;=> error, try a band at a time <C946>
|
||
|
||
MEMOK MOVE.L A0,HANDLE1(A6) ;REMEMBER IN HANDLE1
|
||
_HLock ;LOCK HANDLE1
|
||
gotTmpMem
|
||
PEA SRCPIX(A6) ;PUSH PIXMAP
|
||
MOVE.L A0,-(SP) ;PUSH HANDLE
|
||
_GetPMData ;AND READ IN PIXMAP DATA
|
||
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <42>
|
||
beq.s cleanUpBADBITS
|
||
|
||
jmpROM ciDoBits
|
||
cleanUpBADBITS
|
||
add #18,sp ;get rid of parameters to stdBits already pushed
|
||
BADBITS
|
||
jmpROM ciBADBits
|
||
abort
|
||
jmpROM ciAbort
|
||
|
||
tryBands ; Here Begins <C946> 07Nov87 BAL
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
; The NewHandle for the whole pixmap has failed so lets try a divide and conquer:
|
||
;
|
||
; d5 = byte count of entire pixmap
|
||
; d6 = pixmap height
|
||
; d7 = maskrgn flag (word)
|
||
;
|
||
; Now the stack looks as follows:
|
||
;
|
||
; srcPix 14(sp) \
|
||
; srcRect 10(sp) \
|
||
; dstRect 6(sp) > parameters to stdBits call
|
||
; mode 4(sp) /
|
||
; maskRgn <- TOS /
|
||
;
|
||
|
||
move.l d5,d0 ;ask for the whole banana
|
||
_NewTempBuffer ;returns a0=handle, d0=size
|
||
move.l a0,tmpHandle1(a6) ;store handle for later
|
||
move.l a0,Handle1(a6) ;in case we decide to use it
|
||
move.l d0,d4 ;remember tmp buffer size in d4
|
||
cmp.l d5,d0 ;did we get it all?
|
||
bge gotTmpMem ;yes, go take non-banded case
|
||
|
||
MOVE SRCPIX+ROWBYTES(A6),D5 ;GET BITMAP/PIXMAP ROWBYTES
|
||
AND #nuRBMask,D5 ;CLEAR FLAG BITS
|
||
ext.l d5 ;get size of one scanline in d5
|
||
|
||
_PurgeSpace ;determine available contiguous memory (in a0)
|
||
move.l a0,d3 ;get largest block size
|
||
cmp.l d3,d4 ;is the temp memory block larger?
|
||
ble.s @useAppHeap ;no, use app heap instead
|
||
|
||
move.l d4,d3 ;use temp memory block
|
||
divu.l d5,d3 ;d3 is number of scanlines in each band
|
||
bne.s @gotMem ;if more than zero scanlines then doit
|
||
bra abort ;else abort
|
||
|
||
@useAppHeap
|
||
move.l tmpHandle1(a6),a0 ;get the temp buffer handle
|
||
_DisposeTempBuffer ;release it
|
||
clr.l tmpHandle1(a6) ;don't dispose it again
|
||
|
||
divu.l d5,d3 ;d3 is number of scanlines to allocate
|
||
beq abort ;sorry, no space
|
||
move.l d5,d0 ;get bytes per scanline
|
||
mulu.l d3,d0 ;compute handle size
|
||
|
||
_NewHandle ;allocate the space
|
||
bne abort ;couldn't get it -> abort (hard to believe!)
|
||
move.l a0,handle1(a6) ;save handle for later
|
||
_HLock ;lock it down
|
||
|
||
@gotMem
|
||
move srcPix+bounds+bottom(a6),d6 ;save srcPix.bounds.bottom in d6
|
||
move.w srcPix+Bounds+top(a6),d0 ;get srcpix top
|
||
add d3,d0 ;compute srcpix bottom = srcpix top+srcBandHght;
|
||
move.w d0,srcPix+Bounds+bottom(a6) ;set srcPix bottom
|
||
move.w srcRect+top(a6),d0 ;get srcRect top
|
||
add d3,d0 ;compute srcRect bottom = srcRect top+srcBandHght;
|
||
move.w d0,srcRect+bottom(a6) ;set srcRect bottom
|
||
|
||
move.w dstRect+bottom(a6),d5 ;save dstRect bottom in d5
|
||
move d5,d4 ;copy dstRect.bottom
|
||
sub.w dstRect+top(a6),d4 ;d4 is dstRect height
|
||
|
||
clr.l -(SP) ;make room for fcn result
|
||
move d4,-(SP) ;dstRect height
|
||
move d6,-(SP) ;srcRect.bottom
|
||
move.w srcPix+Bounds+top(a6),d0 ;get srcpix top
|
||
sub d0,(sp) ;srcRect height
|
||
|
||
_FixRatio ;calc vert scale ratio
|
||
move.l (SP)+,d0 ;D6 is dst scanlines per src scanline
|
||
move.l d0,d4 ;copy in d4
|
||
mulu.l d3,d4 ;d4 is dstBandHght
|
||
|
||
move.w dstRect+top(a6),d2 ;get dstRect.top
|
||
swap d2 ;convert to fixed point
|
||
clr.w d2 ;
|
||
add.l d4,d2 ;compute dstRect bottom = dstRect.top+dstBandHght;
|
||
swap d2 ;truncate
|
||
move.w d2,dstRect+bottom(a6) ;set dstRect bottom
|
||
swap d2 ;back to fixed
|
||
|
||
;
|
||
; Register useage from here on:
|
||
;
|
||
; D0,D1 scratch A0,A1 scratch
|
||
; D2 dstRect.bottom (Fixed) A2 preserves d2 across proc calls
|
||
; D3 src band height A3 ThePort
|
||
; D4 dst band height (Fixed) A4 StdBits proc
|
||
; D5 original dstRect.bottom
|
||
; D6 original srcRect.bottom
|
||
; D7 maskRgn flag (word),
|
||
; bit #31 -> compress data to 1 bit/pixel for bottle necks
|
||
;
|
||
|
||
MOVE.L HANDLE1(A6),A0 ;GET HANDLE1
|
||
MOVE.L (A0),SRCPIX+BASEADDR(A6) ;FILL IN BASEADDR
|
||
MOVE.L JStdBits,A4 ;ASSUME GRAFPROCS NOT INSTALLED
|
||
bclr.l #31,d7 ;clear sign bit of d7.l -> don't make bitmap
|
||
MOVE.L GRAFPROCS(A3),d0 ;ARE GRAFPROCS NIL?
|
||
beq.s nxtBand ;no bottle neck procs so skip copy to 1-bit
|
||
move.l d0,a0 ;point to grafProcs
|
||
move.l bitsProc(a0),d0 ;get installed proc
|
||
cmp.l a4,d0 ;bitsProc replaced?
|
||
beq.s nxtBand ;=>no, skip copy to 1-bit
|
||
move.l d0,a4 ;replace stdbits with user's bottle neck proc
|
||
|
||
; IF ITS AN OLD GRAFPORT AND GRAFPROCS ARE INSTALLED, THEN COPY THE IMAGE TO AN
|
||
; OFFSCREEN BITMAP BEFORE CALLING THE GRAFPROC
|
||
|
||
TST SRCPIX+ROWBYTES(A6) ;IS SRC A PIXMAP?
|
||
BPL.S nxtBand ;=>NO, DON'T NEED TO COPY IT
|
||
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD PORT?
|
||
BMI.S nxtBand ;=>NO, NEW GRAFPORT
|
||
;
|
||
; Construct a bitmap that tracks the srcPix map and shares its baseAddr
|
||
;
|
||
bset.l #31,d7 ;set flag -> make 1-bit deep bitmap bands
|
||
LEA SRCPIX+ROWBYTES(A6),A0 ;POINT TO PIXMAP ROWBYTES
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD
|
||
MOVE (A0)+,D0 ;GET ROWBYTES
|
||
AND #nuRBMask,D0 ;MASK FLAG BITS
|
||
LSL.L #3,D0 ;CONVERT BYTES TO BITS
|
||
DIVU SRCPIX+PIXELSIZE(A6),D0 ;GET ROWBITS FOR ONE-BIT COPY
|
||
ADD #15,D0 ;ROUND TO NEAREST WORD BOUNDARY
|
||
LSR.L #4,D0 ;DIV BY 16 (WORD BOUNDARY)
|
||
BEQ BADBITS ;=>TOO NARROW!
|
||
ADD D0,D0 ;HERE'S THE REAL ROWBYTES
|
||
|
||
LEA SRCBITS+ROWBYTES(A6),A1 ;POINT TO BITMAP BOUNDS
|
||
MOVE D0,(A1)+ ;COPY ROWBYTES
|
||
MOVE.L (A0)+,(A1)+ ;COPY BOUNDS
|
||
MOVE.L (A0)+,(A1)+ ;INTO OUR BITMAP
|
||
|
||
MOVE.L SRCPIX+BaseAddr(A6),SRCBITS+BASEADDR(A6) ;share bits with pixmap
|
||
LEA SRCBITS(A6),A0 ;POINT TO BITMAP
|
||
MOVE.L A0,14(SP) ;REPLACE PIXMAP WITH BITMAP (params to stdbits)
|
||
|
||
; Now unpack a full band of the data into srcPix, optionally compress it to a bitmap,
|
||
; and then make the stdBits call. Next, advance the src and dest rects and loop for
|
||
; all full bands.
|
||
;
|
||
; Assumes we need more than one band since original newHandle failed.
|
||
|
||
nxtBand
|
||
PEA SRCPIX(A6) ;PUSH PIXMAP
|
||
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE
|
||
move.l d2,a2 ;preserve d2
|
||
_GetPMData ;AND READ IN PIXMAP DATA
|
||
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <42>
|
||
beq BADBITS ; <42>
|
||
TST.L d7 ;convert to 1 bit deep?
|
||
BPL.S @1 ;no, skip copybits
|
||
|
||
PEA SRCPIX(A6) ;POINT TO SRC
|
||
PEA SRCBITS(A6) ;POINT TO DST
|
||
PEA SRCPIX+BOUNDS(A6) ;POINT TO SRCRECT
|
||
MOVE.L (SP),-(SP) ;POINT TO DSTRECT
|
||
MOVE #SRCCOPY,-(SP) ;PUSH MODE
|
||
CLR.L -(SP) ;NO MASK REGION
|
||
_COPYBITS ;PIXMAP -> BITMAP (converted in place)
|
||
|
||
@1 move.l 14(sp),-(sp) ;duplicate srcPix/srcBits
|
||
move.l 14(sp),-(sp) ;duplicate srcRect
|
||
move.l 14(sp),-(sp) ;duplicate dstRect
|
||
move.w 16(sp),-(sp) ;duplicate mode <BAL/CSD 09Jul88>
|
||
move.l 14(sp),-(sp) ;duplicate maskRgn
|
||
JSR (a4) ;CALL BITSPROC
|
||
|
||
move.l a2,d2 ;restore d2
|
||
add d3,srcPix+bounds+top(a6) ;bump srcPix.bounds.top
|
||
add d3,srcPix+bounds+bottom(a6) ;bump srcPix.bounds.bottom
|
||
add d3,srcBits+bounds+top(a6) ;bump srcBits.bounds.top
|
||
add d3,srcBits+bounds+bottom(a6) ;bump srcBits.bounds.bottom
|
||
add d3,srcRect+top(a6) ;bump srcRect.top
|
||
add d3,srcRect+bottom(a6) ;bump srcRect.bottom
|
||
|
||
move dstRect+bottom(a6),dstRect+top(a6) ;compute dstRect.top = prev dstRect.bottom
|
||
add.l d4,d2 ;compute dstRect.bottom = dstRect.top+dstBandHght;
|
||
swap d2 ;truncate
|
||
move.w d2,dstRect+bottom(a6) ;set dstRect bottom
|
||
swap d2 ;back to fixed
|
||
cmp srcPix+bounds+bottom(a6),d6
|
||
bgt.s nxtBand ;loop for each full scanline band
|
||
|
||
; Finish up remaining scanlines <= srcBandHght
|
||
|
||
LstBand move d5,dstRect+bottom(a6) ;pin dstRect.bottom to original dst bottom
|
||
move.w d6,srcPix+Bounds+bottom(a6) ;pin srcPix.bottom to original src bottom
|
||
move.w d6,srcBits+Bounds+bottom(a6) ;pin srcBits.bottom to original src bottom
|
||
move.w d6,srcRect+bottom(a6) ;pin srcRect.bottom to original src bottom
|
||
|
||
PEA SRCPIX(A6) ;PUSH PIXMAP
|
||
MOVE.L HANDLE1(A6),-(SP) ;PUSH HANDLE
|
||
_GetPMData ;AND READ IN PIXMAP DATA
|
||
cmp.w #AbortPicPlayBackErr,qdErr ;abort if our special error <42>
|
||
beq BADBITS ; <42>
|
||
jmpROM ciAfterLstBand
|
||
endif ; <124> of TheFuture
|
||
|
||
|
||
;---------------- TxFont OpCode $0003 ----------------------
|
||
DoTxFontOpCode
|
||
XTXFONT LEA TXFONT(A3),A3
|
||
jsrROM ciGetWord ;get the old font ID in d0
|
||
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
|
||
MOVE.L FontMappingTbl(A2),d1 ;get the fontID association table
|
||
beq.s @doit ;just use ID as is
|
||
move.l d1,a0
|
||
move.l (a0),a0
|
||
addq #4,a0 ;point to zero based entry count
|
||
move.w (a0)+,d1 ;pick up entry count (could be -1)
|
||
bmi.s @doit ;no mapping entries
|
||
|
||
;entries: oldID,newID word pairs
|
||
@1 cmp.w (a0),d0 ;entry for this ID?
|
||
addq #4,a0 ;bump to next pair
|
||
dbeq d1,@1 ;look until the end or we find it
|
||
bne.s @doit ;not found: so don't map
|
||
move.w -2(a0),d0 ;found: so use new ID
|
||
|
||
@doit move.w d0,(a3) ;install the font id in the port
|
||
BRA Done ;
|
||
|
||
;---------------- Handle TxRatio Opcode $0010 ----------------------
|
||
|
||
DoTxRatioOpCode
|
||
MOVE.L PLAYSTATE(A6),A3 ;POINT TO PLAYSTATE RECORD
|
||
jsrROM ciGETLONG ;GET TEXT NUMER
|
||
MOVE.L D0,NUMER(A3) ;INSTALL INTO PLAYSTATE
|
||
jsrROM ciGETLONG ;GET TEXT DENOM
|
||
MOVE.L D0,DENOM(A3) ;INSTALL INTO PLAYSTATE
|
||
;
|
||
; Calculate new numer/denom to 32-bits using ConcatRatio.
|
||
;
|
||
move.w numer+v(a3),d3
|
||
move.w toRect+bottom(a3),d4
|
||
sub.w toRect+top(a3),d4 ;get height of toRect
|
||
swap d3
|
||
swap d4
|
||
move.w denom+v(a3),d3
|
||
move.w fromRect+bottom(a3),d4
|
||
sub.w fromRect+top(a3),d4 ;get height of fromRect
|
||
|
||
bsr ConcatRatio
|
||
move.w d3,denom+v(a3)
|
||
swap d3
|
||
move.w d3,numer+v(a3)
|
||
|
||
move.w numer+h(a3),d3
|
||
move.w toRect+right(a3),d4
|
||
sub.w toRect+left(a3),d4 ;get width of toRect
|
||
swap d3
|
||
swap d4
|
||
move.w denom+h(a3),d3
|
||
move.w fromRect+right(a3),d4
|
||
sub.w fromRect+left(a3),d4 ;get width of fromRect
|
||
|
||
bsr ConcatRatio
|
||
move.w d3,denom+h(a3)
|
||
swap d3
|
||
move.w d3,numer+h(a3)
|
||
|
||
bra done
|
||
|
||
ConcatRatio
|
||
;
|
||
; takes two 16-bit numer/denom pairs and returns a 16-bit numer/denom
|
||
; D3 = numer/denom
|
||
; D4 = ToRect/FromRect
|
||
;
|
||
; Returns answer in D3
|
||
;
|
||
move.w d3,d0
|
||
mulu.w d4,d0 ;has 32-bit denom
|
||
swap d3
|
||
swap d4
|
||
|
||
mulu.w d4,d3 ;has 32-bit numer
|
||
;
|
||
; Need to convert 32-bit ratio (in d3/d0) into 16-bit ratio in d3
|
||
;
|
||
move.l d0,d1
|
||
or.l d3,d1 ;number of bits to mask in high word
|
||
bra.s @FifteenBitsYet
|
||
;
|
||
; shift until we're clear.
|
||
;
|
||
@loop
|
||
lsr.l #1,d3 ;
|
||
lsr.l #1,d0
|
||
lsr.l #1,d1
|
||
@FifteenBitsYet
|
||
move.l d1,d4 ;ratio fit in 15 bits?
|
||
and.l #$FFFF8000,d4
|
||
bne.s @loop ;nope, loop again
|
||
swap d3
|
||
move.w d0,d3
|
||
rts
|
||
|
||
;---------------- Font/ID binding OpCode $002C ----------------------
|
||
|
||
DoFontIDOpCode
|
||
;
|
||
; At this point we have found a non-zero fond ID which we have not seen previously
|
||
; so we must add it to the FontMappingTbl handle. If the handle needs to be resized we do that
|
||
; here as well.
|
||
AddFontToTbl
|
||
fontMapChunk equ 20*4
|
||
|
||
MOVE.L PLAYSTATE(A6),A2 ;POINT TO PLAYSTATE RECORD
|
||
MOVE.L FontMappingTbl(A2),d1 ;get the fontID association table
|
||
beq ignoreShort ;skip opcode data if no handle
|
||
move.l d1,a0
|
||
move.l (a0),a1 ;
|
||
moveq #0,d0 ;clear out high end
|
||
move.w 4(a1),d0 ;get amnt of handle in use
|
||
addq.w #1,d0 ;make 1 based
|
||
add.w d0,d0
|
||
add.w d0,d0 ;4 bytes per entry
|
||
addq.w #6,d0 ;hdr size
|
||
cmp.l (a1),d0 ;same as size of handle?
|
||
blt.s addFontID ;no need to grow list
|
||
|
||
add.w #fontMapChunk,d0 ;bump handleSize enough for 25 more fonts
|
||
move.l d0,(a1) ;save the new size
|
||
_SetHandleSize ;grow list
|
||
MOVE.L FontMappingTbl(A2),a0 ;get the fontID association table
|
||
move.l (a0),a1 ;get fontList handle
|
||
tst.w d0 ;did we get it?
|
||
beq.s addFontID ;yes, continue
|
||
sub.w #fontMapChunk,(a1) ;couldn't grow it.
|
||
bra ignoreShort ;skip name stuff
|
||
|
||
addFontID
|
||
|
||
move.l a0,a3 ;save fontMappingTbl handle in a3
|
||
jsrROM ciGetWord ;get word data length
|
||
subq #2,d0 ;get length of fond name (incl. length byte)
|
||
MOVE D0,D6 ;SAVE LENGTH IN D6
|
||
jsrROM ciGetWord ;get old fond ID
|
||
MOVE D0,D7 ;save fond ID in D7
|
||
PEA TXDATA(A6) ;PUSH ADDR OF TEXT BUF
|
||
MOVE D6,-(SP) ;PUSH BYTECOUNT
|
||
jsrROM ciGetPicData ;get the name pstring
|
||
|
||
PEA TXDATA(A6) ;PUSH ADDR OF font name
|
||
PEA NewPt(A6) ;PUSH ADDR OF var font id
|
||
_GetFNum ;find the appropriate id for this system
|
||
move.w NewPt(a6),d6 ;get new fond ID
|
||
beq.s fontDone ;not found, so don't add to table
|
||
cmp.w d6,d7 ;does old ID = new ID?
|
||
beq.s fontDone ;yes, don't add to table
|
||
|
||
move.l (a3),a1 ;fontID association table handle in A3
|
||
addq.w #4,a1 ;point to number of entries in use - 1
|
||
addq.w #1,(a1) ;bump the entry count
|
||
move.w (a1)+,d0 ;get new entry count and point to entry array
|
||
lea (a1,d0*4),a1 ;point to this 0ld,New pair
|
||
move.w d7,(a1)+ ;store old ID
|
||
move.w d6,(a1) ;store new ID
|
||
|
||
fontDone
|
||
bra Done
|
||
|
||
;---------------- Line-layout OpCode $002D --------------------------
|
||
|
||
IF SCRIPT_CHAR_EXTRA THEN
|
||
DoLayoutOpCode
|
||
jsrROM ciGetWord ; get the data length.
|
||
move.w d0,-(sp) ; save this for later.
|
||
jsrROM ciGetLong ; get the character extra.
|
||
move.l grafGlobals(a5),a0 ; load quickDraw globals. <54>
|
||
move.l d0,qdChExtra(a0) ; restore character extra amount. <54>
|
||
jsrROM ciGetLong ; get the run slop.
|
||
move.l grafGlobals(a5),a0 ; load quickDraw globals. <54>
|
||
move.l d0,qdRunSlop(a0) ; restore run slop amount. <54>
|
||
|
||
clr.l d0 ; clear a long.
|
||
move.w (sp)+,d0 ; load original data length.
|
||
sub.l #8,d0 ; extra data included?
|
||
beq.s Done ; no -> bail out now.
|
||
jsrROM ciIgCount ; yes -> skip that extra data.
|
||
ENDIF
|
||
|
||
;---------------- Glyph State OpCode $002E --------------------------
|
||
|
||
IF hasGlyphState THEN
|
||
DoStateOpCode
|
||
jsrROM ciGetWord ; get data length
|
||
move.w d0,-(sp) ; save this for later
|
||
|
||
jsrROM ciGetByte ; get outline preferred flag
|
||
move.b d0,-(sp) ; push it on the stack
|
||
_SetOutlinePreferred ; set outline preferred state
|
||
|
||
jsrROM ciGetByte ; get preserve glyph flag
|
||
move.b d0,-(sp) ; push it on the stack
|
||
_SetPreserveGlyph ; set preserve glyph state
|
||
|
||
jsrROM ciGetByte ; get fractional widths flag
|
||
move.b d0,-(sp) ; push it on the stack
|
||
_SetFractEnable ; set fractional widths state
|
||
|
||
jsrROM ciGetByte ; get scaling disabled flag
|
||
move.b d0,-(sp) ; push it on the stack
|
||
_SetFScaleDisable ; set scaling disabled state
|
||
|
||
clr.l d0 ; clear a long
|
||
move.w (sp)+,d0 ; load original data length
|
||
sub.l #4,d0 ; extra data included?
|
||
beq.s Done ; no, bail out now
|
||
jsrROM ciIgCount ; yes, skip that extra data.
|
||
ENDIF
|
||
|
||
Done jmpROM PicItemDone
|
||
ignoreShort jmpROM ciIgnoreShort
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; Patch to add OpenCPicture. Patch OpenPicture to allocate storage for putting font
|
||
; names in pictures. Patch ClosePicture to dispose of font name storage. Patch StdText
|
||
; so it saves the names after an opcode $2C.
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
OpenCPicture FUNC EXPORT
|
||
EXPORT OpenPicture
|
||
IMPORT HidePen,NewRgn
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; Offsets in parameter block passed to OpenCPicture
|
||
;
|
||
ppSrcRect EQU 0 ;Rect
|
||
ppHRes EQU ppSrcRect+8 ;Fixed
|
||
ppVRes EQU ppHRes+4 ;Fixed
|
||
ppVersion EQU ppVRes+4 ;Word (=0)
|
||
ppReserved EQU ppVersion+2 ;Word
|
||
ppReserved2 EQU ppReserved+2 ;Long
|
||
PicParamSize EQU ppReserved2+4 ;size of a PICT2 header record
|
||
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; New offsets in a PICT2 header record:
|
||
;
|
||
hdrVersion EQU 0 ;Word (=-2)
|
||
hdrReserved EQU hdrVersion+2 ;Word
|
||
hdrHRes EQU hdrReserved+2 ;Fixed
|
||
hdrVRes EQU hdrHRes+4 ;Fixed
|
||
hdrSrcRect EQU hdrVRes+4 ;Rect
|
||
hdrReserved2 EQU hdrSrcRect+8 ;Long
|
||
picHdrSize EQU hdrReserved2+4 ;size of a PICT2 header record
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; FUNCTION OpenCPicture( newHeader: PICT2Header ) : cPicHandle;
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 4
|
||
RESULT EQU PARAMSIZE+8 ;LONG, PICHANDLE
|
||
params EQU RESULT-4 ;ptr to input params
|
||
|
||
SAVEVERSION EQU -2 ;PICTURE VERSION NUMBER
|
||
picHdrRec EQU SAVEVERSION-picHdrSize ;PICT2 header record
|
||
defaultFrame EQU picHdrRec-8 ;pic frame to be recorded in picture
|
||
VARSIZE EQU defaultFrame ;TOTAL BYTES OF LOCALS
|
||
|
||
LINK A6,#VARSIZE ;MAKE STACK FRAME
|
||
MOVE #npicVersion,SAVEVERSION(A6) ;SAVE VERSION NUMBER
|
||
|
||
;copy input parameters into pict 2 header record and compute picFrame
|
||
|
||
move.l params(a6),a0 ;point to input parameters
|
||
move.l ppSrcRect(a0),picHdrRec+hdrSrcRect(a6)
|
||
move.l ppSrcRect+bottom(a0),picHdrRec+hdrSrcRect+bottom(a6)
|
||
move.l ppHRes(a0),picHdrRec+hdrHRes(a6)
|
||
move.l ppVRes(a0),picHdrRec+hdrVRes(a6)
|
||
move.w ppVersion(a0),d0 ;orginal version?
|
||
bne.s @newversion
|
||
move.w #-2,picHdrRec+hdrVersion(a6)
|
||
clr.w picHdrRec+hdrReserved(a6)
|
||
clr.l picHdrRec+hdrReserved2(a6)
|
||
bra.s @computePicFrame
|
||
|
||
@newversion ;fill out additional fields
|
||
move.w d0,picHdrRec+hdrVersion(a6)
|
||
move.w ppReserved(a0),picHdrRec+hdrReserved(a6)
|
||
move.l ppReserved2(a0),picHdrRec+hdrReserved2(a6)
|
||
|
||
@computePicFrame
|
||
|
||
move.l picHdrRec+hdrSrcRect+top(a6),d0 ;get topLeft in d0
|
||
move.l picHdrRec+hdrSrcRect+bottom(a6),d1 ;get botRight in d1
|
||
move.l d0,defaultFrame+top(a6) ;set default new height
|
||
move.l d1,defaultFrame+bottom(a6) ;set default new width
|
||
sub.w d0,d1 ;get width in d1.w
|
||
move.w d1,d2 ;save width in d2.w
|
||
swap d0
|
||
swap d1
|
||
sub.w d0,d1 ;get height in d1.w
|
||
moveq #72,d0
|
||
mulu.w d0,d1 ;d1.L = height*72
|
||
move.l d1,a0 ;save height*72 in a0
|
||
mulu.w d0,d2 ;d2.L = width*72
|
||
|
||
swap d2
|
||
moveq #0,d1 ;extend d1 to long in copy: don't trash high word <KON>
|
||
move.w d2,d1
|
||
clr.w d2
|
||
move.l picHdrRec+hdrHRes(a6),d0
|
||
beq.s @skip
|
||
divu.l d0,d1:d2 ;d2.w = (width*72)/vRes
|
||
|
||
move.l picHdrRec+hdrVRes(a6),d0
|
||
beq.s @skip
|
||
|
||
clr.l defaultFrame+top(a6) ;force topLeft to be 0,0
|
||
move.w d2,defaultFrame+right(a6) ;right = new width
|
||
|
||
moveq #0,d2
|
||
move.l a0,d1 ;restore d1
|
||
swap d1
|
||
move.w d1,d2
|
||
clr.w d1
|
||
divu.l d0,d2:d1 ;d1.w = (height*72)/vRes
|
||
move.w d1,defaultFrame+bottom(a6) ;bottom = new height
|
||
@skip
|
||
BRA.s OPShare ;=>GO USE COMMON CODE
|
||
|
||
|
||
OpenPicture
|
||
|
||
OpenPictciEntry: EQU $31BFC
|
||
OpenPictciDONE: EQU $31D12
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; FUNCTION OpenPicture(picFrame: Rect): PicHandle;
|
||
;
|
||
; A6 OFFSETS OF PARAMS AFTER LINK:
|
||
;
|
||
; the following is defined above...
|
||
;
|
||
;PARAMSIZE EQU 4
|
||
;RESULT EQU PARAMSIZE+8 ;LONG, PICHANDLE
|
||
;params EQU RESULT-4 ;ptr to input params
|
||
|
||
;SAVEVERSION EQU -2 ;PICTURE VERSION NUMBER
|
||
;picHdrRec EQU SAVEVERSION-picHdrSize ;PICT2 header record
|
||
;defaultFrame EQU picHdrRec-8 ;pic frame to be recorded in picture
|
||
;VARSIZE EQU defaultFrame ;TOTAL BYTES OF LOCALS
|
||
|
||
|
||
LINK A6,#VARSIZE ;MAKE STACK FRAME
|
||
MOVE #pictVersion,SAVEVERSION(A6) ;SAVE VERSION NUMBER
|
||
|
||
move.l params(a6),a0 ;point to input rect
|
||
move.l (a0)+,defaultFrame(a6) ;copy topLeft
|
||
move.l (a0),defaultFrame+bottom(a6) ;copy botRight
|
||
|
||
lea picHdrRec+picHdrSize(a6),a1 ;point to end of hdr record <06Feb90 KON>
|
||
CLR.L -(a1) ;CLEAR RESERVED LONG
|
||
MOVE.L params(A6),A0 ;POINT TO BOUNDING RECT
|
||
MOVE.L BOTTOM(A0),D0 ;GET BOTTOM AS FIXED
|
||
CLR D0 ;CLEAR LOW WORD
|
||
MOVE.L D0,-(a1) ;PUSH FIXED BOTTTOM
|
||
MOVE.L RIGHT(A0),D0 ;GET RIGHT AS FIXED
|
||
CLR D0 ;CLEAR LOW WORD
|
||
MOVE.L D0,-(a1) ;PUSH FIXED RIGHT
|
||
MOVE.L TOP(A0),D0 ;GET TOP AS FIXED
|
||
CLR D0 ;CLEAR LOW WORD
|
||
MOVE.L D0,-(a1) ;PUSH FIXED TOP
|
||
MOVE.L LEFT(A0),D0 ;GET LEFT AS FIXED
|
||
CLR D0 ;CLEAR LOW WORD
|
||
MOVE.L D0,-(a1) ;PUSH FIXED LEFT
|
||
MOVEQ #-1,D0 ;GET -1 AS SIZE
|
||
MOVE.L D0,-(a1) ;PUSH LONG SIZE
|
||
|
||
OPShare MOVEM.L D3/A3-A4,-(SP) ;SAVE REGS
|
||
CLR.L RESULT(A6) ;INIT FCN RESULT TO NIL
|
||
|
||
; Abort OpenPicture if heap doesn't have at least 1500 bytes. <16Jan89 KON>
|
||
|
||
MOVE.L #1500,D0 ;GET BYTE COUNT
|
||
_NewHandle ;AT LEAST 1000 BYTES IN THE HEAP ?
|
||
BNE DONE ;NO, RETURN NIL AND QUIT
|
||
_DisposHandle ;YES, Discard test handle
|
||
|
||
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A4),A3 ;GET CURRENT GRAFPORT
|
||
TST.L PICSAVE(A3) ;ARE WE ALREADY SAVING ?
|
||
BNE DONE ;YES, RETURN NIL AND QUIT
|
||
_HidePen ;NO, TURN OFF DRAWING
|
||
|
||
; IF IT'S A NEW GRAFPORT, FORCE NEW PICTURE
|
||
|
||
TST PORTBITS+ROWBYTES(A3) ;IS IT A NEW GRAFPORT?
|
||
BPL.S @OLDGP ;=>NO, OLD GRAFPORT
|
||
MOVE #npicVersion,SAVEVERSION(A6) ;ELSE FORCE TO NEW PICTURE
|
||
|
||
; ALLOCATE PICSAVE RECORD
|
||
|
||
@OLDGP MOVE.L #npicSaveRec,D0 ;GET BYTE COUNT
|
||
_NewHandle ;ALLOCATE PICSAVE RECORD
|
||
MOVE.L A0,A4 ;GET RESULT HANDLE
|
||
MOVE.L A4,PICSAVE(A3) ;SAVE RESULT IN THEPORT
|
||
;
|
||
; ALLOCATE PICCLIPRGN (leave on stack for now)
|
||
;
|
||
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
||
_NEWRGN ;ALLOCATE A NEW REGION
|
||
;
|
||
; ALLOCATE THEPIC PICHANDLE
|
||
;
|
||
MOVE.L #256,D0 ;BYTE COUNT = 256
|
||
_NewHandle ;ALLOCATE NEWHANDLE(256)
|
||
MOVE.L A0,A1 ;GET THEPIC HANDLE
|
||
MOVE.L A1,RESULT(A6) ;PUT HANDLE IN FCN RESULT
|
||
;
|
||
; NOW FILL THEPIC'S PICSIZE AND PICFRAME
|
||
;
|
||
MOVE.L (A4),A4 ;DE-REFERENCE PICSAVE HANDLE
|
||
MOVE.L A1,(A4)+ ;SAVE PICHANDLE IN THEPIC
|
||
MOVE.L (A1),A1 ;DE-REFERENCE PICHANDLE
|
||
MOVE #10,(A1)+ ;INSTALL PICSIZE = 10
|
||
lea defaultFrame(A6),A0 ;POINT TO PICFRAME
|
||
MOVE.L (A0)+,(A1)+ ;COPY RECT INTO PICTURE
|
||
MOVE.L (A0)+,(A1)+
|
||
;
|
||
; INIT STATE VARIABLES FOR PICTURE CAPTURE
|
||
;
|
||
MOVE.L #256,(A4)+ ;PICMAX := 256;
|
||
MOVE.L #10,(A4)+ ;PICINDEX := 10
|
||
MOVE.L (SP)+,(A4)+ ;INSTALL PICCLIPRGN
|
||
CLR.L (A4)+ ;PICBKPAT := WHITE
|
||
CLR.L (A4)+
|
||
CLR.L (A4)+ ;PICTXFONT = 0, PICTXFACE = []
|
||
MOVE #1,(A4)+ ;PICTXMODE := SRCCOPY
|
||
CLR (A4)+ ;PICTXSIZE := 0
|
||
CLR.L (A4)+ ;PICSPEXTRA := 0.0
|
||
MOVE.L #$00010001,D0 ;GET (1,1)
|
||
MOVE.L D0,(A4)+ ;PICTXNUMER := (1,1)
|
||
MOVE.L D0,(A4)+ ;PICTXDENOM := (1,1)
|
||
CLR.L (A4)+ ;PICTXLOC := (0,0)
|
||
CLR.L (A4)+ ;PICPNLOC := (0,0)
|
||
MOVE.L D0,(A4)+ ;PICPNSIZE := (1,1)
|
||
MOVE #8,(A4)+ ;PICPNMODE := PATCOPY
|
||
MOVEQ #-1,D0 ;GET SOME BLACK
|
||
MOVE.L D0,(A4)+ ;PICPNPAT := BLACK
|
||
MOVE.L D0,(A4)+
|
||
MOVE.L D0,(A4)+ ;PICFILLPAT := BLACK
|
||
MOVE.L D0,(A4)+
|
||
CLR.L (A4)+ ;PICTHERECT := (0,0,0,0)
|
||
CLR.L (A4)+
|
||
CLR.L (A4)+ ;PICOVSIZE := (0,0)
|
||
MOVE.L PORTRECT+TOPLEFT(A3),(A4)+ ;PICORIGIN := CURRENT ORIGIN
|
||
MOVE.L #blackColor,(A4)+ ;PICFGCOLOR := blackColor
|
||
MOVE.L #whiteColor,(A4)+ ;PICBKCOLOR := whiteColor
|
||
MOVE SAVEVERSION(A6),(A4)+ ;picVersion := version number
|
||
|
||
CLR.L (A4)+ ;picRGBFgCol := black
|
||
CLR (A4)+
|
||
MOVE.L D0,(A4)+ ;picRGBBkCol := white
|
||
MOVE D0,(A4)+
|
||
|
||
MOVE.L #$00008000,(A4)+ ;picChExtra := 0
|
||
;picLocHFrac := 1/2
|
||
|
||
CLR.L (A4)+ ;picRGBOpColor := black
|
||
CLR (A4)+
|
||
CLR.L (A4)+ ;picRGBHiColor := black
|
||
CLR (A4)+
|
||
|
||
; IF IT'S A NEW PICTURE, ALLOCATE THE PIXEL PATTERNS
|
||
|
||
CMP #pictVersion,SAVEVERSION(A6) ;is it a pict?
|
||
BEQ.S doFontList ;=>yes, skip new stuff
|
||
tst portBits+rowBytes(a3) ;is it a new picture in an old grafport? <20Sept90 KON>
|
||
bpl.s doFontList ;=>yes, skip new stuff <20Sept90 KON>
|
||
|
||
MOVEQ #2,D3 ;allocate 3 pixPats
|
||
NXTPP CLR.L -(SP) ;make room for function result
|
||
sub.l ([PicSave,a3]),a4 ;get offset into picSave record <<BAL 04Apr88>>
|
||
_NEWPIXPAT ;get a new pixPat
|
||
MOVE.L (SP)+,A0 ;get pixPat handle
|
||
add.l ([PicSave,a3]),a4 ;offset into record <<BAL 04Apr88>>
|
||
MOVE.L A0,(A4)+ ;save pixPat to picsave record
|
||
MOVE.L (A0),A0 ;point at pixPat
|
||
MOVE #oldPat,patType(A0) ;init to old pattern
|
||
DBRA D3,NXTPP ;=>repeat for all pixPats
|
||
|
||
;
|
||
; Allocate handle for fond id's we have seen so far
|
||
;
|
||
; Format of picFontList handle is:
|
||
; handle size [long]
|
||
; # of entries - 1 used [word]
|
||
; id1, id2, ... idn
|
||
|
||
FontListSize equ 50*2
|
||
|
||
doFontList
|
||
moveq #FontListSize+6,d0 ;initial size for 50 entries
|
||
_NewHandle
|
||
move.l picSave(a3),a1 ;get picSave handle
|
||
move.l (a1),a1
|
||
move.l a0,picFontList(a1) ;save picFontList handle in picSave record
|
||
beq.s @noHandle
|
||
|
||
move.l (a0),a0 ;point into fontList
|
||
moveq #FontListSize+6,d0 ;initial size for 50 entries
|
||
move.l d0,(a0)+
|
||
clr.l (a0) ; 1 entry, first entry = 0
|
||
|
||
@noHandle
|
||
|
||
;
|
||
; Clear picQdRunSlop and picQdChExtra
|
||
;
|
||
move.l picSave(a3),a1 ; load the picSave handle
|
||
move.l (a1),a1 ; load the picSave pointer
|
||
clr.l picQdChExtra(a1) ; clear the character extra
|
||
clr.l picQdRunSlop(a1) ; clear the run slop
|
||
|
||
; INIT GLYPH STATE TO INVALID
|
||
|
||
move.l #$80808080,picGlyphState(a1) ; set glyph state to invalid values
|
||
|
||
; PUT VERSION NUMBER TO PICTURE
|
||
|
||
MOVEQ #opVersion,D0 ;GET VERSION OPCODE
|
||
jsrROM DPutPicOp ;PUT TO PICTURE
|
||
MOVE SAVEVERSION(A6),D0 ;GET VERSION NUMBER
|
||
CMP #pictVersion,D0 ;IS IT AN OLD PICTURE?
|
||
BNE.S @NotPic ;=>NO, NOT AN OLD PICT
|
||
jsrROM DPUTPICBYTE ;IF OLD PUT BYTE TO PICTURE
|
||
BRA.S DONE ;AND RETURN
|
||
|
||
; IT'S A NEW PICTURE! PUT VERSION AS WORD, FOLLOW IT WITH HEADER OPCODE
|
||
|
||
@NotPic MOVE D0,-(SP) ;ELSE PUSH VERSION
|
||
jsrROM PUTPICWORD ;AND PUT ENTIRE WORD FOR NEW PICTURES
|
||
|
||
; HEADER EXTENSION = [OP] [SIZE] [BBOX] [RESERVED]
|
||
|
||
MOVE #ngHeaderOp,D0 ;GET HEADER OPCODE
|
||
jsrROM DPutPicOp ;PUT TO PICTURE
|
||
|
||
pea picHdrRec(a6) ;PUSH POINTER TO DATA
|
||
MOVE #24,-(SP) ;PUSH SIZE OF DATA
|
||
jsrROM PUTPICDATA ;AND BLAST IT TO THE PICTURE
|
||
|
||
DONE MOVEM.L (SP)+,D3/A3-A4 ;RESTORE REGS
|
||
UNLINK PARAMSIZE,'OPENPICT'
|
||
|
||
ENDPROC
|
||
|
||
UpdatePat PROC EXPORT
|
||
|
||
ciUpdatePatEntry EQU $32E30
|
||
ciPatNew EQU $32E60
|
||
;------------------------------------------------------
|
||
;
|
||
; PROCEDURE UpdatePat(SRCPAT: PTR; SRCPIXPAT: HANDLE;
|
||
; SAVEPAT: PTR; SAVEPIXPAT: HANDLE;
|
||
; OLDOP,NEWOP: INTEGER);
|
||
;
|
||
; CHECK TO SEE IF THE SPECIFIED PATTERN NEEDS UPDATING.
|
||
; IF SO, PUT THE NEW PATTERN TO THE PICTURE AND RECORD THE
|
||
; CHANGE IN THE PICSAVE RECORD.
|
||
;
|
||
; ASSUMES THAT AN OLD PICTURE WILL ONLY BE RECORDED IN AN OLD GRAFPORT
|
||
; AND THAT A NEW PICTURE WILL ONLY BE RECORDED IN A NEW GRAFPORT.
|
||
;
|
||
; ON ENTRY: A3 = GRAFPORT
|
||
; A4 = PICSAVE RECORD
|
||
;
|
||
PARAMSIZE EQU 20
|
||
SRCPAT EQU PARAMSIZE+8-4 ;PTR
|
||
SRCPIXPAT EQU SRCPAT-4 ;HANDLE
|
||
SAVEPAT EQU SRCPIXPAT-4 ;PTR
|
||
SAVEPIXPAT EQU SAVEPAT-4 ;HANDLE
|
||
OLDOP EQU SAVEPIXPAT-2 ;WORD
|
||
NEWOP EQU OLDOP-2 ;WORD
|
||
|
||
LINK A6,#0 ;NO LOCAL VARS
|
||
MOVEM.L D5/D6,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
tst portBits+rowBytes(a3) ;in an old grafport? <18Sept90 KON>
|
||
bmi.s patnew ;=>yes, skip old stuff <18Sept90 KON>
|
||
; CMP #PICTVERSION,PICVERSION(A4) ;IS IT AN OLD PICTURE? <18Sept90 KON>
|
||
; BNE.S PATNEW ;=>NEW, CHECK NEW PICTURE <18Sept90 KON>
|
||
|
||
jmpROM ciUpdatePatEntry
|
||
patnew
|
||
jmpROM ciPatNew
|
||
ENDPROC
|
||
|
||
;
|
||
; <124> Bring this code back for CubeE and TheFuture.
|
||
;
|
||
|
||
if not(TheFuture) then
|
||
ClosePicture PROC EXPORT
|
||
|
||
ciClosePictureEntry: EQU $31D4C
|
||
ciClosePictureGoHome: EQU $31D82
|
||
cinopp EQU $31D74
|
||
;------------------------------------------------------------------
|
||
;
|
||
; PROCEDURE ClosePicture;
|
||
;
|
||
MOVEM.L D6-D7/A3,-(SP) ;SAVE REGS
|
||
MOVE.L GRAFGLOBALS(A5),A3 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L THEPORT(A3),A3 ;GET CURRENT GRAFPORT
|
||
MOVE.L PICSAVE(A3),D7 ;ARE WE SAVING A PICTURE ?
|
||
BEQ.S GOHOME ;NO, OOPS, EXIT
|
||
MOVE #opEndPic,D0 ;PUSH ENDPIC OPCODE
|
||
jsrROM DPutPicOp ;PUT TO THEPIC
|
||
MOVE.L D7,A0 ;GET PICSAVE HANDLE
|
||
MOVE.L (A0),A0 ;POINT TO PICSAVE RECORD
|
||
move.l picFontList(a0),a0 ;get fontList handle
|
||
_DisposHandle
|
||
MOVE.L D7,A0 ;GET HANDLE TO PICSAVE RECORD
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
MOVE.L PICCLIPRGN(A0),D6 ;GET picClipRgn
|
||
MOVE.L PICINDEX(A0),D0 ;DID PICTURE OVERFLOW ?
|
||
BEQ.S OVERFLO ;YES, CONTINUE
|
||
MOVE.L THEPIC(A0),A0 ;NO, GET THEPIC HANDLE
|
||
_SetHandleSize ;AND TRIM TO FINAL SIZE
|
||
OVERFLO MOVE.L D6,A0 ;GET PICCLIPRGN
|
||
_DisposHandle ;DISCARD IT
|
||
tst portBits+rowBytes(a3) ;is it in an old grafport? <20Sept90 KON>
|
||
bpl.s nopp ;=>yes, skip new stuff <20Sept90 KON>
|
||
jmpROM ciClosePictureEntry
|
||
nopp jmpROM cinopp
|
||
GOHOME jmpROM ciClosePictureGoHome ;AND RETURN
|
||
endif ; <124>
|
||
|
||
|
||
;ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª
|
||
;ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª
|
||
;
|
||
; Patches for Alpha Channel Fixes
|
||
;
|
||
;ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª
|
||
;ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª
|
||
|
||
|
||
;Patch for GWorld.a
|
||
|
||
RectRgn PROC EXPORT
|
||
|
||
ciRectRgn EQU $361D0
|
||
ciNGWRectRgn EQU $3FE7E
|
||
ciNGWSkip EQU $3FE8C
|
||
|
||
pixelShift equ -2 ; WORD, pixel shift amount
|
||
resPref equ pixelShift-2 ; WORD, device's preferred resolution
|
||
bytesPerRow equ resPref-2 ; WORD, rowBytes of offscreen pixmap
|
||
offscreenBufH equ bytesPerRow-4 ; LONG, handle to the offscreen buffer
|
||
offscreenPixMap equ offscreenBufH-4 ; LONG, handle to the offscreen pixmap
|
||
offscreenCTable equ offscreenPixMap-4 ; LONG, handle to the offscreen color table
|
||
offscreenDevice equ offscreenCTable-4 ; LONG, handle to the offscreen device
|
||
offscreenITable equ offscreenDevice-4 ; LONG, handle to the offscreen inverse table
|
||
offscreenPortH equ offscreenITable-4 ; LONG, handle to the offscreen port
|
||
offscreenPort equ offscreenPortH-4 ; LONG, pointer to the offscreen port
|
||
|
||
cmpRA ciNGWRectRgn,(SP) ;is call of RectRgn from NewGWorld?
|
||
BNE.S @toROM ;no, go to RectRgn
|
||
ADDQ #4,SP ;throw away return address
|
||
jsrROM ciRectRgn ;call RectRgn
|
||
MOVE.L offscreenPort(A6),A0 ;get pointer to port
|
||
MOVE.L grafVars(A0),-(SP) ;push grafVars handle
|
||
_ResizeGrafVars ;make the grafVars bigger
|
||
jmpROM ciNGWSkip ;jump to just after GrafVars resizing code
|
||
@toROM jmpROM ciRectRgn
|
||
|
||
|
||
;Patches from Rects.a
|
||
|
||
PushVerb PROC EXPORT
|
||
;----------------------------------------------------------
|
||
;
|
||
; PUSH A MODE AND A PATTERN, BASED ON VERB
|
||
; ENTER WITH VERB IN D7, GRAFGLOBALS IN A4, THEPORT IN A3.
|
||
;
|
||
; CLOBBERS A0-A1/D0/D2
|
||
;
|
||
ciPushVerb EQU $2C41C
|
||
|
||
MOVE.L (SP)+,A1 ;POP RETURN ADDR
|
||
MOVE #8,-(SP) ;PUSH MODE = PATCOPY (IE. DEFAULT)
|
||
CMP.B #1,D7 ;CASE ON VERB
|
||
BLE.S PAINT1
|
||
MOVEQ #0,D1 ;push clear pen mode
|
||
_GetStreamMode ;clear alpha mode bits
|
||
MOVE.L A1,A0
|
||
jmpROM ciPushVerb
|
||
|
||
PAINT1 MOVE PNMODE(A3),D1 ;push the pen mode
|
||
_GetStreamMode ;extract alpha mode bits
|
||
OR D1,(SP) ;push mode, but leave the pattern bit set
|
||
PEA PNPAT(A3) ;PUSH PAT = PNPAT
|
||
JMP (A1) ;RETURN TO CALLER
|
||
|
||
ENDPROC
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; Dispatcher for alpha channel utility routines (Trap $ABC0)
|
||
;
|
||
AlphaDispatch PROC EXPORT
|
||
|
||
ciRSetHSize EQU $31450
|
||
|
||
JMP @dispatch(PC,D0.W*4)
|
||
@dispatch
|
||
BRA.W AlphaVersion
|
||
BRA.W SetForeStream
|
||
BRA.W SetForeTransparency
|
||
BRA.W SetBackStream
|
||
BRA.W SetBackTransparency
|
||
BRA.W GetForeStream
|
||
BRA.W GetForeTransparency
|
||
BRA.W GetBackStream
|
||
BRA.W GetBackTransparency
|
||
BRA.W ResizeGrafVars
|
||
BRA.W GetStreamMode
|
||
|
||
;
|
||
; FUNCTION AlphaVersion:INTEGER;
|
||
;
|
||
AlphaVersion
|
||
MOVE.W #$0100,4(SP) ;return version 1.0
|
||
RTS
|
||
|
||
|
||
;
|
||
; PROCEDURE SetForeStream(streamID: LongInt);
|
||
; PROCEDURE SetBackStream(streamID: LongInt);
|
||
;
|
||
SetForeStream
|
||
MOVEQ #foreStream,D1 ;point at foreStream/foreRatio in grafvars
|
||
BRA.S SetStream ;jump into common code
|
||
SetBackStream
|
||
MOVEQ #backStream,D1 ;point at backStream/backRatio in grafvars
|
||
SetStream
|
||
BSR.S SetSub
|
||
BEQ.S @exit
|
||
MOVE.L 4(SP),(A0) ;move stream from stack to grafvars
|
||
@exit RTD #4 ;clean off stack and return
|
||
|
||
|
||
;
|
||
; PROCEDURE SetForeTransparency(streamRatio: INTEGER);
|
||
; PROCEDURE SetBackTransparency(streamRatio: INTEGER);
|
||
;
|
||
SetForeTransparency
|
||
MOVEQ #foreRatio,D1 ;point at foreStream/foreRatio in grafvars
|
||
BRA.S SetTrans ;jump into common code
|
||
SetBackTransparency
|
||
MOVEQ #backRatio,D1 ;point at backStream/backRatio in grafvars
|
||
SetTrans
|
||
BSR.S SetSub
|
||
BEQ.S @exit
|
||
MOVE.W 4(SP),(A0) ;move ratio from stack to grafvars
|
||
@exit RTD #2 ;clean off stack and return
|
||
|
||
|
||
SetSub MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
||
MOVE.L thePort(A0),A0 ;get pointer to current port
|
||
TST portBits+rowBytes(A0) ;new port?
|
||
BPL.S @exit ;no, then don't access grafVars
|
||
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
||
BEQ.S @exit ;if null, exit
|
||
MOVE.L D0,A0 ;move grafvars handle to more useful register
|
||
MOVE.L (A0),A0 ;deref it
|
||
BTST #PmNewGVBit-8,pmFlags(A0) ;check for new grafvars flag
|
||
BNE.S @1 ;if it was set, no need to grow grafvars
|
||
MOVE.L D0,-(SP) ;save grafvars handle
|
||
MOVE.L D0,-(SP) ;push grafvars handle for resize call
|
||
_ResizeGrafVars ;grow grafvars to new size
|
||
MOVE.L (SP)+,A0 ;restore grafvars handle
|
||
MOVE.L (A0),A0 ;deref it again
|
||
@1: ADD.W D1,A0 ;bump to field being modified
|
||
ST D0 ;set do it flag to true
|
||
RTS
|
||
@exit CLR D0 ;set do it flag to false
|
||
RTS
|
||
|
||
;
|
||
; PROCEDURE GetForeStream: INTEGER;
|
||
; PROCEDURE GetBackStream: INTEGER;
|
||
;
|
||
GetForeStream
|
||
MOVEQ #foreStream,D1 ;point at foreStream in grafvars
|
||
BRA.S GetStream ;jump into common code
|
||
GetBackStream
|
||
MOVEQ #backStream,D1 ;point at backStream in grafvars
|
||
GetStream
|
||
MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
||
MOVE.L thePort(A0),A0 ;get pointer to current port
|
||
TST portBits+rowBytes(A0) ;new port?
|
||
BPL.S @default ;no, then don't access grafVars
|
||
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
||
BEQ.S @default ;if null, return default info
|
||
MOVE.L D0,A0 ;move grafvars handle to more useful register
|
||
MOVE.L (A0),A0 ;deref it
|
||
BTST #PmNewGVBit-8,pmFlags(A0) ;check for new grafvars flag
|
||
BEQ.S @default ;if it was clear, return default info
|
||
ADD.W D1,A0 ;bump to either foreStream or backStream
|
||
MOVE.L (A0),4(SP) ;move stream from grafvars to user variable
|
||
RTS
|
||
@default
|
||
CLR.L 4(SP) ;move default stream to user variable
|
||
RTS
|
||
|
||
;
|
||
; PROCEDURE GetForeTransparency: INTEGER;
|
||
; PROCEDURE GetBackTransparency: INTEGER;
|
||
;
|
||
GetForeTransparency
|
||
MOVEQ #foreRatio,D1 ;point at foreRatio in grafvars
|
||
BRA.S GetTrans ;jump into common code
|
||
GetBackTransparency
|
||
MOVEQ #backRatio,D1 ;point at backRatio in grafvars
|
||
GetTrans
|
||
MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
||
MOVE.L thePort(A0),A0 ;get pointer to current port
|
||
TST portBits+rowBytes(A0) ;new port?
|
||
BPL.S @default ;no, then don't access grafVars
|
||
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
||
BEQ.S @default ;if null, return default info
|
||
MOVE.L D0,A0 ;move grafvars handle to more useful register
|
||
MOVE.L (A0),A0 ;deref it
|
||
BTST #PmNewGVBit-8,pmFlags(A0) ;check for new grafvars flag
|
||
BEQ.S @default ;if it was clear, return default info
|
||
ADD.W D1,A0 ;bump to either foreStream or backStream
|
||
MOVE.W (A0),4(SP) ;move ratio from grafvars to user variable
|
||
RTS
|
||
@default
|
||
CLR.W 4(SP) ;move default ratio to user variable
|
||
RTS
|
||
|
||
|
||
;
|
||
; On Entry:
|
||
; (on stack): grafvars handle
|
||
;
|
||
; ONLY TRASHES D0/A0
|
||
;
|
||
ResizeGrafVars
|
||
MOVE.L 4(SP),A0 ;get grafVars handle
|
||
MOVE.L (A0),A0 ;deref grafvars handle
|
||
BSET #PmNewGVBit-8,pmFlags(A0) ;check new grafvars flag and set it if not already
|
||
BNE.S @exit ;if it was set, then we are too
|
||
MOVE.L 4(SP),A0 ;get grafVars handle agian
|
||
MOVE.L #newGrafVarRec,D0 ;get size of new grafvars
|
||
jsrROM ciRSetHSize ;set the handle to be that size
|
||
MOVE.L (A0),A0 ;deref again
|
||
LEA foreStream(A0),A0 ;bump to beginning of our stuff
|
||
CLR.L (A0)+ ;clear foreStream
|
||
CLR.L (A0)+ ;clear foreRatio, half of backStream
|
||
CLR.L (A0)+ ;clear half of backStream, backRatio
|
||
CLR.W (A0)+ ;clear stream mode and filler
|
||
@exit RTD #4 ;all done
|
||
|
||
;
|
||
; On Entry:
|
||
; D1: penmode (not necessarily from the current port)
|
||
;
|
||
; On Exit:
|
||
; D1: penmode stripped of alpha transfer bits
|
||
;
|
||
GetStreamMode
|
||
MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
||
MOVE.L thePort(A0),A0 ;get pointer to current port
|
||
TST portBits+rowBytes(A0) ;new port?
|
||
BPL.S @exit ;no, then don't access grafVars
|
||
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
||
BEQ.S @exit ;if null, exit
|
||
MOVE.L D0,-(SP) ;save copy of grafvars handle
|
||
MOVE.L D0,-(SP) ;put grafVars handle on stack
|
||
_ResizeGrafVars ;make sure grafvars are big enough
|
||
MOVE.L (SP)+,A0 ;get grafVars handle off stack
|
||
MOVE.L (A0),A0 ;dereference it
|
||
MOVE.W D1,D0 ;make copy of penmode
|
||
LSR.W #8,D0 ;right align alpha bits
|
||
AND.W #3,D0 ;mask off all but alpha bits
|
||
MOVE.B D0,streamMode(A0) ;put alphamode into streamMode
|
||
@exit AND.W #$FCFF,D1 ;remove alpha bits from penmode
|
||
RTS ;return stripped penmode
|
||
|
||
|
||
;
|
||
; On Entry:
|
||
; (on stack): pointer to streamID and ratio
|
||
; (on stack): pointer to where to put
|
||
; alphamask (long) and alphacolor (long)
|
||
;
|
||
StreamToMask PROC EXPORT
|
||
MOVE.L 8(SP),A0 ;get pointer to streamID/ratio
|
||
MOVE.L 4(SP),A1 ;get pointer to result destination
|
||
MOVE.W 4(A0),D0 ;get ratio
|
||
TST.L (A0) ;check if stream is graphics (zero)
|
||
BEQ.S @1 ;yes, skip
|
||
NOT.W D0 ;no, reverse context of transparency
|
||
@1: MOVE.W D0,D1
|
||
SWAP D0
|
||
MOVE.W D1,D0
|
||
MOVE.L THEGDEVICE,A0 ;get handle of current gdevice
|
||
MOVE.L (A0),A0 ;deref it
|
||
MOVE.L gdPMap(A0),A0 ;get handle of gdevice's pixmap
|
||
MOVE.L (A0),A0 ;deref it
|
||
MOVE.W pmPixelSize(A0),D1 ;get its pixel size
|
||
CMP #16,D1 ;is it 16-bits per pixel?
|
||
BEQ.S @16bits
|
||
MOVE.L MaskBC,D1 ;get 32-bits per pixel not mask
|
||
BRA.S @2
|
||
@16bits MOVE.L #$7FFF7FFF,D1 ;get 16-bits per pixel not mask
|
||
@2: NOT.L D1 ;reverse the mask
|
||
AND.L D1,D0 ;mask alpha color
|
||
MOVE.L D1,(A1)+ ;save alphamask
|
||
MOVE.L D0,(A1)+ ;save alphacolor
|
||
RTD #8
|
||
|
||
|
||
if not(TheFuture) then
|
||
;Patches from Patterns.a
|
||
|
||
PatExpand PROC EXPORT
|
||
|
||
ciRSetHSize EQU $31450
|
||
ciGotCopy EQU $30972
|
||
ciNEWDONE EQU $30A96
|
||
ciNOTOLD EQU $30A9E
|
||
|
||
&CurFile SETC 'PATEXPAND'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;-------------------------------------------------------------
|
||
|
||
PARAMSIZE EQU 0
|
||
|
||
TWOPAT EQU -16 ;ROOM FOR TWO COPIES OF PAT
|
||
SAVESTK EQU TWOPAT-4 ;ROOM TO SAVE STACK POINTER
|
||
ROTSIZE EQU SAVESTK-2 ;SCANLINE SIZE FOR ROTATION
|
||
ROTSHIFT EQU ROTSIZE-2 ;ROTATE AMOUNT
|
||
GGLOBALS EQU ROTSHIFT-4 ;POINTER TO GRAFGLOBALS
|
||
SAVEA5 EQU GGLOBALS-4 ;PLACE TO SAVE A5
|
||
VARSIZE EQU SAVEA5 ;TOTAL BYTES OF LOCAL VARS
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; IF OLD PATTERN, ALLOCATE A BUFFER ON THE STACK AND POINT TO IT.
|
||
; IF NEW PATTERN, GO EXPAND IF NECESSARY.
|
||
;
|
||
TST.B NEWPATTERN(A6) ;IS IT A NEW PATTERN?
|
||
BNE NEWPATEXPAND ;=>YES, EXPAND PIXELPAT
|
||
|
||
; ALLOCATE AN EXPAND BUFFER ON THE STACK FOR USE BY CALLER
|
||
|
||
DOOLD MOVE.L (SP)+,A0 ;GET RETURN ADDRESS
|
||
MOVEQ #64,D0 ;MINIMUM BUFFER IS 64 BYTES
|
||
MOVE DSTSHIFT(A6),D1 ;GET DEPTH SHIFT
|
||
subq #3,D1 ;DEPTHS 1-8 OK @@@@ BAL 10Apr88
|
||
ble.S GETBUF ;=>SO GET THE PATTERN BUFFER @@@@ BAL 10Apr88
|
||
LSL D1,D0 ;ELSE DOUBLE FOR 16, QUAD FOR 32
|
||
GETBUF SUB D0,SP ;MAKE THE BUFFER (LONG ALIGNED)
|
||
MOVE.L SP,EXPAT(A6) ;POINT TO PATTERN BUFFER
|
||
MOVE.L A0,-(SP) ;REPLACE RETURN ADDRESS
|
||
|
||
|
||
PSHARE LINK A4,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D3-D6/A2-A3/A5,-(SP) ;SAVE REGS
|
||
|
||
MOVE LOCMODE(A6),D0 ;GET MODE
|
||
MOVE DSTPIX+BOUNDS+LEFT(A6),D2 ;GET GLOBAL-LOCAL OFFSET (PIXELS)
|
||
MOVE.L FCOLOR(A6),D3 ;GET CURRENT FG COLOR
|
||
MOVE.L BCOLOR(A6),D4 ;GET CURRENT BK COLOR
|
||
MOVE DSTSHIFT(A6),D5 ;GET SHIFT FOR PIXEL DEPTH
|
||
|
||
MOVE.L LOCPAT(A6),A0 ;GET PATTERN
|
||
LEA PATROW(A6),A1 ;AND DATA DST
|
||
|
||
AND #$F3,D0 ;TURN OFF PAT, INVERT BITS
|
||
BEQ.S GOTCOPY ;=>IT'S COPY MODE
|
||
BTST #5,D0 ;is it a new mode?
|
||
BNE.S GotCopy
|
||
; MOVEQ #-1,D3 ;ELSE FGCOLOR = BLACK
|
||
MOVE.L alphaMask(A6),D3
|
||
MOVEQ #0,D4 ;AND BKCOLOR = WHITE
|
||
GotCopy jmpROM ciGotCopy
|
||
|
||
|
||
NEWPATEXPAND
|
||
;----------------------------------------------------------------
|
||
;
|
||
; NEWPATEXPAND -- EXPAND A PIXELPAT, IF NECESSARY
|
||
;
|
||
; NOTE: STACK FRAME LINKED USING A4 SO NORMAL FRAME STILL IN A6
|
||
;
|
||
LINK A4,#VARSIZE ;ALLOCATE STACK FRAME
|
||
MOVEM.L D3-D6/A2-A3/A5,-(SP) ;SAVE REGS
|
||
MOVE.L SP,SAVESTK(A4) ;SAVE STACK POINTER
|
||
MOVE.L GRAFGLOBALS(A5),A3 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L A3,GGLOBALS(A4) ;SAVE IN STACK FRAME
|
||
MOVE.L A5,SAVEA5(A4) ;AND SAVE GLOBAL POINTER
|
||
|
||
MOVE.L LOCPAT(A6),A0 ;GET THE PIXPAT HANDLE POINTER
|
||
MOVE.L (A0),A0 ;GET THE PIXPAT HANDLE
|
||
MOVE.L (A0),A0 ;GET THE PIXPAT POINTER
|
||
|
||
TST PATTYPE(A0) ;IS IT AN OLD PATTERN?
|
||
BNE.S NOTOLD ;=>NO, CHECK FOR EXPANSION OF NEW PAT
|
||
|
||
;---------------------------------------------------------
|
||
;
|
||
; IF OLD PATTERN, USE SHARED CODE TO EXPAND IT
|
||
;
|
||
MOVE.L PATXDATA(A0),A0 ;GET THE EXPANDED DATA HANDLE
|
||
MOVEQ #64,D0 ;MINIMUM BUFFER IS 64 BYTES
|
||
MOVE DSTSHIFT(A6),D1 ;GET DEPTH SHIFT
|
||
subq #3,D1 ;DEPTHS 1-8 OK @@@@ BAL 10Apr88
|
||
ble.S BUFOK ;=>SO GET THE PATTERN BUFFER @@@@ BAL 10Apr88
|
||
LSL.L D1,D0 ;ELSE DOUBLE FOR 16, QUAD FOR 32
|
||
BUFOK jsrROM ciRSetHSize
|
||
|
||
MOVE.L (A0),d0 ;get master pointer @@@@ BAL 10Apr88
|
||
_rTranslate24To32 ;mask off high byte @@@@ BAL 10Apr88
|
||
move.l d0,EXPAT(A6) ;SAVE POINTER TO EXPAND DATA AREA
|
||
;*** LEAVE IT UNLOCKED
|
||
MOVE.L LOCPAT(A6),A0 ;GET PIXPAT HANDLE POINTER
|
||
MOVE.L A0,-(SP) ;SAVE PIXPAT HANDLE POINTER
|
||
MOVE.L (A0),A0 ;GET HANDLE TO PIXPAT
|
||
MOVE.L (A0),A0 ;GET POINTER TO PIXPAT
|
||
MOVE.L PATDATA(A0),A0 ;GET HANDLE TO DATA
|
||
MOVE.L (A0),A0 ;GET POINTER TO DATA
|
||
MOVE.L A0,LOCPAT(A6) ;SET UP POINTER TO SRC DATA
|
||
|
||
JSR PSHARE ;AND CALL COMMON CODE
|
||
|
||
MOVE.L (SP)+,LOCPAT(A6) ;RESTORE PATTERN HANDLE
|
||
|
||
NEWDONE jmpROM ciNEWDONE
|
||
NOTOLD jmpROM ciNOTOLD
|
||
|
||
endif ;not(TheFuture)
|
||
;Patches from DrawLine.a
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; PROCEDURE DRAWLINE(P1,P2: POINT);
|
||
;
|
||
; DRAWS A LINE CLIPPED TO CURRENT PORT'S CLIPRGN AND VISRGN
|
||
;
|
||
; P1 AND P2 ARE GIVEN IN LOCAL COORDINATES OF THEPORT.
|
||
;
|
||
|
||
DrawLine PROC EXPORT
|
||
; IMPORT SHFTTBL
|
||
Export FastLine,FastSlant
|
||
|
||
ciDrawLine EQU $29A06
|
||
ciSHFTTBL EQU $304B6
|
||
ciGOHOME EQU $29E80
|
||
|
||
&CurFile SETC 'DRAWLINE'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
PARAMSIZE EQU 8 ;SIZE OF PARAMETERS
|
||
P1 EQU PARAMSIZE+8-4 ;POINT
|
||
P2 EQU P1-4 ;POINT
|
||
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
|
||
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
||
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
||
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
|
||
CLR.L DSTMASKBUF(A6) ;ASSUME NO MASK
|
||
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
||
MOVE.L WIDEOPEN(A0),BIGRGN(A6) ;STASH WIDEOPEN IN BIGRGN
|
||
MOVE.L THEPORT(A0),A3 ;POINT TO CURRENT GRAFPORT
|
||
TST PNVIS(A3) ;IS PNVIS NEGATIVE ?
|
||
BLT GOHOME ;YES, QUIT
|
||
MOVE.W PNMODE(A3),D1
|
||
_GetStreamMode
|
||
MOVE.W D1,LOCMODE(A6)
|
||
MOVE.L A3,PORT(A6) ;SAVE PORT FOR LATER
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; 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 DSTBITS TO PIXMAP
|
||
; (A5 must contain global ptr)
|
||
;
|
||
LEA PORTBITS(A3),A1 ;GET POINTER TO DSTBITS
|
||
LEA DSTPIX(A6),A2 ;USE DSTPIX IN ITS PLACE
|
||
_BitsToPix ;CONVERT BITMAP
|
||
MOVE.L D1,REALBOUNDS(A6) ;SAVE REAL DST BOUNDS.TOPLEFT
|
||
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; CONVERT PIXEL DEPTH TO SHIFT AMOUNT TO AVOID MULTIPLIES
|
||
;
|
||
leaROM ciSHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
||
MOVE DSTPIX+PIXELSIZE(A6),D0 ;GET DST PIXEL SIZE
|
||
MOVEQ #0,D1 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D0),D1 ;GET SRC SHIFT
|
||
MOVE D1,DSTSHIFT(A6) ;AND SAVE DST SHIFT AMOUNT
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
|
||
; ALSO SET UP LOCAL PATTERN POINTER, LOCPAT(A6)
|
||
;
|
||
LEA PNPAT(A3),A0 ;POINT TO THE PATTERN
|
||
MOVE.L A0,LOCPAT(A6) ;COPY PATTERN POINTER
|
||
MOVE LOCMODE(A6),D0 ;get requested mode
|
||
jmpROM ciDrawLine
|
||
GOHOME jmpROM ciGOHOME
|
||
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; SET UP AND DRAW A FAST HORIZONTAL OR VERTICAL LINE.
|
||
;
|
||
|
||
FASTLINE
|
||
|
||
ciDONE EQU $29E66
|
||
ciDOONE EQU $29F02
|
||
ciDOEND EQU $29F0A
|
||
ciALLONE EQU $29F20
|
||
ciVLINE EQU $29F72
|
||
ciHVSETUP EQU $29FE0
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; Switch to 32 bit addressing mode
|
||
;
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
move.w d1,-(sp) ;save a register
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.w (sp)+,d1 ;restore d1
|
||
move.b d0,MMUsave(a6) ;save previous state for later
|
||
MOVE.L alphaMask(A6),D4 ;get alpha mask
|
||
CMP D1,D3 ;IS LINE HORIZONTAL ?
|
||
BNE VLINE ;NO, MUST BE VERTICAL
|
||
jsrROM ciHVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
||
MOVEQ #-1,D6 ;GET ONES IN D6
|
||
LSR.L D0,D6 ;CONVERT TO LEFTMASK
|
||
MOVE MINRECT+RIGHT(A6),D2 ;GET MINRECT RIGHT
|
||
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL
|
||
EXT.L D2 ;MAKE IT LONG
|
||
LSL.L D3,D2 ;CONVERT PIXELS TO BITS
|
||
MOVEQ #$1F,D0 ;NEED RIGHT MOD 32
|
||
AND.L D2,D0 ;MAKE A COPY OF RIGHT
|
||
MOVEQ #-1,D3 ;GET ONES IN D3
|
||
LSR.L D0,D3 ;SHIFT IN 0'S FOR LEFTMASK
|
||
NOT.L D3 ;CONVERT TO RIGHTMASK
|
||
AND.L D4,D6 ;
|
||
AND.L D4,D3 ;
|
||
LSR.L #5,D2 ;CONVERT BITS TO LONGS
|
||
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
||
BLT.S HSET ;BR IF FOREGROUND
|
||
BEQ.S HTOGL ;BR IF XOR
|
||
;ELSE BACKGROUND
|
||
|
||
;------------------------------------------------------
|
||
;
|
||
; DRAW A HORIZONTAL LINE IN THE BACKGROUND COLOR (NORMALLY WHITE)
|
||
;
|
||
MOVE.L BCOLOR(A6),D5 ;GET THE COLOR
|
||
BRA.S HDRAW
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; DRAW A HORIZONTAL LINE IN THE FOREGROUND COLOR (NORMALLY BLACK)
|
||
;
|
||
HSET MOVE.L FCOLOR(A6),D5 ;GET THE FOREGROUND COLOR
|
||
HDRAW SUB D1,D2 ;CALC LONG COUNT
|
||
BEQ.S ALLONE ;BR IF ALL IN ONE LONG
|
||
MOVE.L D5,D1 ;COPY COLOR
|
||
AND.L D6,D1 ;MASK COLOR FOR LEFT EDGE
|
||
NOT.L D6 ;GET NOT LEFTMASK
|
||
AND.L (A4),D6 ;PUNCH HOLE IN DEST
|
||
OR.L D1,D6 ;COMBINE SRC AND DST
|
||
MOVE.L D6,(A4)+ ;AND DROP COLOR IN
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ.S DOEND ;BR IF NO UNMASKED LONG
|
||
|
||
NOT.L D4
|
||
BEQ.S DOONE
|
||
ALPHALINE
|
||
MOVE.L (A4),D0
|
||
EOR.L D5,D0
|
||
AND.L D4,D0
|
||
EOR.L D5,D0
|
||
MOVE.L D0,(A4)+
|
||
DBRA D2,ALPHALINE
|
||
DOEND jmpROM ciDOEND
|
||
DOONE jmpROM ciDOONE
|
||
ALLONE jmpROM ciALLONE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;--------------------------------------------------
|
||
;
|
||
; DRAW AN XOR HORIZONTAL LINE
|
||
;
|
||
HTOGL SUB D1,D2 ;CALC LONGCOUNT
|
||
BEQ.S ONETOGL ;BR IF ALL IN ONE LONG
|
||
EOR.L D6,(A4)+ ;DO LEFT LONG WITH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ.S ENDTOGL ;BR IF NO UNMASKED LONGS
|
||
BRA.S TOGLONE ;SEE IF ANY LONGS LEFT TO DO
|
||
TOGLTWO EOR.L D4,(A4)+ ;INVERT A LONG
|
||
TOGLONE EOR.L D4,(A4)+ ;INVERT ANOTHER LONG
|
||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
||
TOGLMORE BGT TOGLTWO ;YES, AT LEAST TWO LONGS
|
||
BEQ TOGLONE ;YES, FINISH UP LAST LONG
|
||
ENDTOGL EOR.L D3,(A4) ;DRAW LINE
|
||
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
ONETOGL AND.L D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
||
EOR.L D6,(A4) ;DRAW LINE
|
||
DONE jmpROM ciDONE ;RESTORE CURSOR AND QUIT
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; DRAW A ONE PIXEL WIDE VERTICAL LINE.
|
||
;
|
||
VLINE jsrROM ciHVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
||
MOVEQ #-1,D2 ;GET ONES IN D2
|
||
LSR.L D0,D2 ;CONVERT TO LEFTMASK (LEFT MOD 32 IN D0)
|
||
MOVE.L D2,D0 ;GET LEFTMASK
|
||
MOVE DSTPIX+PIXELSIZE(A6),D1 ;GET PIXEL SIZE
|
||
LSR.L D1,D0 ;SHIFT BY PIXEL SIZE FOR RIGHT EDGE
|
||
NOT.L D0 ;MAKE IT A RIGHTMASK
|
||
AND.L D0,D2 ;AND RIGHTMASK INTO LEFTMASK
|
||
AND.L D4,D2
|
||
jmpROM ciVLINE
|
||
|
||
|
||
FASTSLANT
|
||
|
||
ciFASTSLANT EQU $2A080
|
||
ciGOBACK EQU $2A410
|
||
|
||
TST.B alphaMode(A6) ;if alphamode != 0, use slower code
|
||
;The logic here is different than
|
||
BEQ.S @stay ; RAM based version to avoid patching
|
||
@goBack jmpROM ciGOBACK ; out a bunch of code to speed up
|
||
@stay jmpROM ciFASTSLANT ; two marginal line drawing cases.
|
||
|
||
|
||
;Patches from GWorlds.a
|
||
|
||
;RectRgn PROC EXPORT
|
||
|
||
; cmpRA FromROMNewGWorld,(SP)
|
||
; BEQ.S @1
|
||
; ADDQ #4,SP
|
||
; peaROM ciSkipGVarStuff
|
||
; @1: jmpROM ciRectRgn
|
||
|
||
; Store museDevice (which is the offscreen device or aGDevice or the deepest
|
||
; device intersecting boundsRect) in the grafVars.
|
||
; move.l offscreenPort(a6),a0 ; get pointer to offscreen port
|
||
; move.l ([grafVars,a0]),a0 ; get pointer to grafVars structure
|
||
; move.l museDevice(a6),attachDevice(a0) ; store museDevice in grafVars
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
;
|
||
; INSTALLS HERE
|
||
;
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
CutBackPt PROC EXPORT
|
||
EXPORT InitPatches
|
||
|
||
EntryTable CopyPixPat,$AA09 ; comefrom to fix direct pixpats in pictures <KON 4FEB90>
|
||
if not(TheFuture) then ; <124> Need this for the present
|
||
EntryTable CalcMask,$A838 ; CalcMask and SeedFill need to <KON 24JAN91>
|
||
EntryTable SeedFill,$A839 ; always scan up as well as down <KON 24JAN91>
|
||
endif ; <124>
|
||
EntryTable slHilite,$AB90 ; Fix hilite slabbing of pixpats <85>
|
||
EntryTable RAMslArith16Tab,$ABBD ; Fix hilite slabbing of pixpats <85>
|
||
EntryTable RAMslArith32Tab,$ABBE ; Fix hilite slabbing of pixpats <85>
|
||
|
||
EntryTable RectRgn,$A8DF ; Fixes of alpha channel crimes
|
||
EntryTable DrawLine,$AB0A ;
|
||
EntryTable FastSlabMode,$AB0C ;
|
||
if not(TheFuture) then
|
||
EntryTable PatExpand,$AB15 ;
|
||
endif
|
||
EntryTable PushVerb,$AB18 ;
|
||
EntryTable bSETUP8,$AB34 ;
|
||
EntryTable bXMAIN8,$AB38 ;
|
||
EntryTable bLONG8,$AB44 ;
|
||
EntryTable bXLONG8,$AB48 ;
|
||
EntryTable rMASK8,$AB5E ;
|
||
EntryTable FastLine,$AB9C ;
|
||
EntryTable FastSlant,$AB9D ;
|
||
EntryTable AlphaDispatch,$ABC0 ;
|
||
EntryTable StreamToMask,$ABC1 ;
|
||
|
||
EntryTable stArith16Tab, $ABA6 ;Patch 16-bit arithmetic loops to end in RTS
|
||
EntryTable stArith32Tab, $ABA7 ;Patch 32-bit arithmetic loops to end in RTS
|
||
EntryTable StdRect, $A8A0 ;Patch all these so OpenCPicture
|
||
EntryTable StdLine, $A890 ;works in GrafPorts. The problem
|
||
EntryTable StdRRect, $A8AF ;is Update pat is not vectored and
|
||
EntryTable StdOval, $A8B6 ;it is called by PutPicVerb which
|
||
EntryTable StdArc, $A8BD ;is called by all the std procs.
|
||
EntryTable StdRgn, $A8D1 ;You're lucky you didn't have to do
|
||
EntryTable StdPoly, $A8C5 ;this.
|
||
|
||
EntryTable SlabMode,$AB25 ;set up patterns for 16 and 32-bit dests
|
||
EntryTable rTransparent,$AB6A ;new transparent rgn-clipped blit loop
|
||
EntryTable bTransparent,$AB54 ;new transparent rect-clipped blit loop
|
||
EntryTable RAMbArith16Tab,$ABB8 ;bArith16Tab move to RAM to fix subOver16
|
||
EntryTable bSloHilite,$AB4E ; Make it use background color correctly
|
||
EntryTable rXMASK8,$AB62 ; new big pattern rgnblit copy loop
|
||
EntryTable rSlowHilite,$AB70 ; new hilite pattern blit loop
|
||
EntryTable RgnBlt,$AB1F ; to make hilite patterns work
|
||
if not(TheFuture) then ; <124> Need this for the present
|
||
EntryTable GetPixel,$A865 ; make it work with pmVersion 4 pixmaps
|
||
EntryTable GetCPixel,$AA17 ; make it work with pmVersion 4 pixmaps
|
||
endif ; <124>
|
||
EntryTable KopyMask,$AA51 ; new trap: copyMask with mode and rgn
|
||
EntryTable OpenCPicture,$AA20 ; Add handle for font name list
|
||
EntryTable OpenPicture,$A8F3 ; Add new trap
|
||
if not(TheFuture) then ; <124> Need this for the present
|
||
EntryTable ClosePicture,$A8F4 ; Dispose of font name list handle
|
||
endif ; <124>
|
||
EntryTable DrawPicture,$A8F6 ; Support font name/ID binding on playback
|
||
EntryTable PicItem1, $AB9A ; font name/ID binding support
|
||
EntryTable StdOpcodeProc, $ABF8 ;hres, vres support to picFrames
|
||
EntryTable PatConvert, $AB13 ;fix pixpat expansion bug
|
||
EntryTable GetCIcon, $AA1E ;size = height * rowbytes (not *pixdepth)
|
||
EntryTable QDExtDispatcher, $AB1D ;added selectors 22 and 23 and patch UpdateGWorld
|
||
;
|
||
; UpdateGWorld patched to OR.L rather than MOVE.L StretchPixMask into the result
|
||
;
|
||
EntryTable InitPort, $A86D ;added support for moving base adr.
|
||
EntryTable OpenPort, $A86F ;added support for moving base adr.
|
||
EntryTable InitGDevice, $AA2E ;moving base adr support
|
||
EntryTable BitsToPix, $AB02 ;moving base adr support
|
||
EntryTable SetupStretch, $AB24 ;come from patch to add index to index dithering
|
||
;
|
||
; Completely replace stretch
|
||
;
|
||
EntryTable StretchBits, $AB27 ;complete stretch replacement
|
||
EntryTable BlitCase, $AB98 ;complete stretch replacement
|
||
EntryTable StScanLoop, $AB99 ;complete stretch replacement
|
||
EntryTable stMask0, $AB73 ;do colorizing only when needed
|
||
|
||
EntryTable ColorMap, $AB04 ;patched for colorizing in color space
|
||
EntryTable MakeScaleTbl, $AB0E ;pin to pixdepth entries, add color space colorizing
|
||
|
||
EntryTable RAMstColorTab, $ABA8 ;stColorTab moved to RAM to support fix dither bug
|
||
EntryTable RAMscDirTab8, $ABB5 ;scDirTab moved to RAM to support fix dither bug
|
||
EntryTable RAMstGrayTab, $ABA9 ;stGrayTab moved to RAM for Dither
|
||
EntryTable RAMstSearchTab, $ABAA ;stSearchTab moved to RAM for Speedup of 32 and 16 to ind.
|
||
EntryTable StdBits, $A8EB ;clear dither bit when recording old pict.
|
||
EntryTable Index2Color, $AA34 ;Calc color the same as Search16toIndexed.
|
||
EntryTable ScrollRect, $A8EF ;Set update region when scrolling between diff. res. dev.
|
||
; EntryTable RecoverHandle, $A028 ;also recover handles in MFZone
|
||
EntryTable BitsDevLoop, $AB9E ;remove references to BaseAddr
|
||
EntryTable GetSeek, $AB0D ;come-from lines, arcs, poly for wide rowbytes
|
||
EntryTable FastSlabMode, $AB0C ;come-from lines, arcs, poly for wide rowbytes
|
||
EntryTable stNoStack, $AB97 ;Try for 128K instead of 64K
|
||
EntryTable MakeITable, $AA39 ;save theZone across calls
|
||
EntryTable DisposeTempBuffer, $AB1E ;comefrom MakeITable patch to clean up temp handles
|
||
EntryTable InvertColor, $AA35 ;Address of color for comp procs was not correct.
|
||
;
|
||
; patched below
|
||
;
|
||
; EntryTable StdTxMeas, $A8ED ;comefrom GetRect patch to multiply by size by h scaling
|
||
; EntryTable GetMaxDevicePatch,$AA27 ; new trap: copyMask with mode and rgn
|
||
|
||
;
|
||
; Quicker Draw Patches
|
||
;
|
||
EntryTable slAddOver8,$AB8A
|
||
EntryTable slSubOver8,$AB8E
|
||
EntryTable slAddPin8,$AB89
|
||
EntryTable slSubPin8,$AB8B
|
||
EntryTable slMax8,$AB8D
|
||
EntryTable slMin8,$AB8F
|
||
EntryTable slAvg8,$AB88
|
||
EntryTable slTransparent8,$AB8C
|
||
|
||
EntryTable rAddOver8,$AB68
|
||
EntryTable rSubOver8,$AB6C
|
||
EntryTable rAddPin8,$AB67
|
||
EntryTable rSubPin8,$AB69
|
||
EntryTable rMax8,$AB6B
|
||
EntryTable rMin8,$AB6D
|
||
EntryTable rAvg8,$AB66
|
||
; EntryTable rTransparent8,$AB6A ;<SMC 08OCT90> <72>
|
||
|
||
EntryTable bAddOver8,$AB52
|
||
EntryTable bSubOver8,$AB56
|
||
EntryTable bAddPin8,$AB51
|
||
EntryTable bSubPin8,$AB53
|
||
EntryTable bMax8,$AB55
|
||
EntryTable bMin8,$AB57
|
||
EntryTable bAvg8,$AB50
|
||
; EntryTable bTransparent8,$AB54 ;<SMC 08OCT90> <72>
|
||
EntryTable FillClipScanLine, $AB80 ;More Quickerdraw stuff <27FEB90 KON>
|
||
EntryTable FillClipOrLine, $AB81
|
||
EntryTable FillClipXLine, $AB84
|
||
EntryTable 0
|
||
|
||
InitPatches
|
||
Import FixupTbl ; added FixupTbl
|
||
|
||
;____________________________________________________________________________
|
||
; Fixup patch addresses
|
||
;
|
||
; The Fixing up of addresses generated by the CMPRA, JSRROM & JMPROM
|
||
; Breaks down as follows:
|
||
;
|
||
; Addressing High Byte in Action
|
||
; mode: instruction:
|
||
; ---------- ------------ ------
|
||
; 24 bit NZ Do not alter the address in the instruction.
|
||
; Used with CMPRA to a ROM Resource.
|
||
; 32 bit NZ Mask out 12 high bits from the address
|
||
; in the instruction, leaving a ROM offset
|
||
; Then add in ROMBase.
|
||
; either Zero Normal Case. Add ROMBase to the address
|
||
; in the instruction.
|
||
;
|
||
; Registers:
|
||
; D0: Address Size Flag. Pos: 24 bit mode; Neg: 32 bit Mode
|
||
; D1: Entry from table of offsets of locations to be fixed up
|
||
; D2: (RomBase)
|
||
; A0: Pointer into table of offsets of locations to be fixed up.
|
||
; A1: Base of fixup table; also location from which offsets are computed.
|
||
|
||
if not(TheFuture) then ; <124> OId equate for now
|
||
GetPMData EQU $40833610 ; <124>
|
||
endif ; <124>
|
||
if TheFuture then ; <124> New equate for TheFuture
|
||
GetPMData EQU $33610
|
||
endif ; <124>
|
||
; EntryTable GetPMData, $ABC4 ;install as a trap
|
||
|
||
if not(TheFuture) then ; <124> Old code for now
|
||
move.l #GetPMData,a0 ; <124>
|
||
endif ; <124>
|
||
if TheFuture then ; <124> New code for TheFuture
|
||
move.l rombase,a0
|
||
add.l #GetPMData,a0
|
||
endif ; <124>
|
||
move #$ABC4,d0
|
||
_SetTrapAddress ,NEWTOOL
|
||
|
||
; EntryTable DelSearch,$AA4C ; call xlate24to32 on address
|
||
; EntryTable DelComp,$AA4D ; call xlate24to32 on address
|
||
;
|
||
; Only install DelSearch and DelComp if our return address is what we are expecting
|
||
; This hack is necessary since DelSearch and DelComp routines in the Erickson ROM
|
||
; are already patched! Thanx!
|
||
;
|
||
|
||
ciDelCompEntryValue EQU $2270
|
||
ciDelCompEntry EQU $3CAC4
|
||
|
||
move.l #ciDelCompEntry,a0
|
||
add.l ROMBase,a0
|
||
cmp.w #ciDelCompEntryValue,(a0)
|
||
lea DelSearch,a0
|
||
bne.s @Erickson
|
||
move #$AA4C,d0
|
||
_SetTrapAddress ,NEWTOOL
|
||
|
||
lea DelComp,a0
|
||
move #$AA4D,d0
|
||
_SetTrapAddress ,NEWTOOL
|
||
@Erickson
|
||
|
||
;
|
||
; Move stColorTab to RAM ;<SMC 27SEP90> <69>
|
||
;
|
||
MOVE.W #$ABA8,D0
|
||
MOVEQ #-120,D1 ;MOVEQ #%10001000,D1 (stupid assembler)
|
||
LEA RAMstColorTab,A1
|
||
BSR TabPatcher8
|
||
;
|
||
; Move scDirTab8 to RAM ;<SMC 27SEP90> <69>
|
||
;
|
||
MOVE.W #$ABB5,D0
|
||
MOVEQ #%00100000,D1 ;assembles because high bit is clear
|
||
LEA RAMscDirTab8,A1
|
||
BSR TabPatcher8
|
||
;
|
||
; Move stGrayTab to RAM ;<SMC 27SEP90> <69>
|
||
;
|
||
MOVE.W #$ABA9,D0
|
||
MOVEQ #-52,D1 ;MOVEQ #%11001100,D1 (again, stupid assembler)
|
||
LEA RAMstGrayTab,A1
|
||
BSR TabPatcher8
|
||
;
|
||
; Move bArith16Tab to RAM ;<SMC 08OCT90> <71>
|
||
;
|
||
MOVE.W #$ABB8,D0
|
||
MOVEQ #%001000000,D1
|
||
LEA RAMbArith16Tab,A1
|
||
MOVEQ #8,D2 ;9 entries
|
||
BSR TabPatcher
|
||
;
|
||
; Move slArith16Tab to RAM ;<85>
|
||
;
|
||
MOVE.W #$ABBD,D0
|
||
MOVE.L #%100000000,D1
|
||
LEA RAMslArith16Tab,A1
|
||
MOVEQ #8,D2 ;9 entries
|
||
BSR TabPatcher
|
||
;
|
||
; Move slArith32Tab to RAM ;<85>
|
||
;
|
||
MOVE.W #$ABBE,D0
|
||
MOVE.L #%100000000,D1
|
||
LEA RAMslArith32Tab,A1
|
||
MOVEQ #8,D2 ;9 entries
|
||
BSR TabPatcher
|
||
;
|
||
; (stSearchTab is now patched out entirely to RAM)
|
||
;
|
||
|
||
;-------------------------------------------------------------------------------
|
||
|
||
;
|
||
; Routine patches Traps $AB75 - $AB7F to end with an RTS
|
||
;
|
||
; The routine is moved into RAM and then the RTS is added and the
|
||
; new trap address is set
|
||
;
|
||
|
||
move.w #$AB74,d0
|
||
_GetTrapAddress ,newTool
|
||
move.l a0,a1 ;copy source address
|
||
;
|
||
; Get newptr to copy trap into
|
||
;
|
||
|
||
RtnSize EQU $37D98-$37A20 ;$379F0 ($AB73) ; End of $AB7F - beginning of $AB74
|
||
|
||
move.l #RtnSize, d0 ;
|
||
_NewPtr ,SYS
|
||
move.l a0,a2 ;save beginning of 1st routine
|
||
suba.l a1,a2
|
||
|
||
move.w #$AB74,d0
|
||
_SetTrapAddress ,NewTool ;set address of first trap
|
||
|
||
;
|
||
; Check for errors?
|
||
;
|
||
move.w #(RtnSize/4)-1, d2 ; long count of routine size
|
||
@Loop
|
||
move.l (a1)+,(a0)+ ;move all the code over
|
||
dbra d2, @Loop
|
||
|
||
;
|
||
; Now change all the BRA's at the end of the routines to RTS's by looking backward
|
||
; for a $6000
|
||
;
|
||
move.w #$AB75,d2 ;first routine ends
|
||
@Loop1
|
||
move.w d2,d0
|
||
_GetTrapAddress ,newTool
|
||
;
|
||
; Patch up the Trap addresses while we're here
|
||
;
|
||
move.w d2,d0
|
||
adda.l a2,a0
|
||
move.l a0,a1
|
||
_SetTrapAddress ,NewTool
|
||
@Loop2
|
||
cmp.w #$6000,-(a1)
|
||
bne.s @Loop2
|
||
move.w #$4E75, (a1)
|
||
|
||
addq.w #1,d2
|
||
cmp.w #$AB80,d2
|
||
bne.s @Loop1
|
||
;
|
||
; Trap AB7B has two hard branches we need to replace, so search backwards for
|
||
; the one we missed.
|
||
;
|
||
@Special
|
||
cmp.w #$6000,-(a1)
|
||
bne.s @Special
|
||
move.w #$4E75, (a1)
|
||
|
||
;
|
||
; To handle the last one, search forward for $6000
|
||
;
|
||
@Loop3
|
||
cmp.w #$6000,(a1)+ ;This was done by a dark skinned man....
|
||
bne.s @Loop3
|
||
move.w #$4E75, -2(a1)
|
||
; _Debugger
|
||
|
||
move.l RomBase, D2
|
||
moveq #-1, D0
|
||
_StripAddress
|
||
lea FixupTbl, A0
|
||
move.l A0, A1
|
||
FixUpLooP move.l (A0)+, D1
|
||
beq.s @1
|
||
tst.b 0(A1, D1.L)
|
||
beq.s @AddIt
|
||
tst.l D0 ; If Address has any high bits set
|
||
bpl.s FixUpLoop ; 24 Bit mode; Dont alter this one.
|
||
and.w #$f, 0(A1, D1.L); 32 Bit Mode; Clear High 12 bits.
|
||
|
||
@AddIt add.l D2, 0(A1, D1.L) ; Normal Case: Add in ROMBase
|
||
bra.s FixUpLoop
|
||
@1
|
||
|
||
|
||
MOVE.W HwCfgFlags,D0 ; check ‘em the compulsive way
|
||
BTST #hwCbAUX,D0 ; is it A/UX time?
|
||
BNE.S @NoNewCursor ; if so, skip crsr installs
|
||
|
||
lea PatchJShowCursor,a0
|
||
move.l a0,JShowCursor
|
||
|
||
lea PatchJSetCCursor,a0
|
||
move.l a0,JSetCCrsr
|
||
|
||
@NoNewCursor
|
||
|
||
PatchToolJump oldDisposGDevice,$230 ;If gDevice = lastTxDevice, move mainGdevice to lastTxDev
|
||
InstToolTp newDisposGDevice,$230
|
||
|
||
PatchToolJump oldMapRgn,$0FB ;check for wide open rectangular regions
|
||
InstToolTp newMapRgn,$0FB
|
||
|
||
leaFar CutBackPt,a0 ; ptchInstall will cut back to here
|
||
; and install the traps in the table.
|
||
rts
|
||
|
||
;---------------------------------------------------------
|
||
; <SMC 27SEP90> <69>
|
||
;
|
||
; TabPatcher - patch specific entries in a vectorized
|
||
; blit-loop offset table.
|
||
;
|
||
; D0 = table trap number
|
||
; D1 = bitmask
|
||
; D2 = entries count (zero based)
|
||
; A1 = RAM table address
|
||
;
|
||
; The lowest bit of the of the bitmask corresponds to the
|
||
; first entry in the table, and so on. If a bit in the mask
|
||
; is one, the proc is in RAM so leave the entry alone in the
|
||
; new table. If a bit is zero, the entry is still in ROM so
|
||
; adjust the offset in the new table to be the distance between
|
||
; it and the ROM proc.
|
||
;
|
||
|
||
TabPatcher8 MOVEQ #7,D2
|
||
TabPatcher MOVE.L D3,-(SP)
|
||
_GetTrapAddress ,newTool
|
||
MOVE.L A0,D0
|
||
SUB.L A1,D0
|
||
@1: MOVE.L (A0)+,D3
|
||
LSR.L #1,D1
|
||
BCS.S @2
|
||
ADD.L D0,D3
|
||
MOVE.L D3,(A1)
|
||
@2: ADDQ #4,A1
|
||
DBRA D2,@1
|
||
MOVE.L (SP)+,D3
|
||
RTS
|
||
|
||
endproc
|
||
|
||
Proc
|
||
Export FixupTbl
|
||
;################## TABLE OF LOCATIONS TO BE OFFSET BY [ROMBase] ####################
|
||
;
|
||
; Table contains one entry for each reference to a ROM address from the
|
||
; JmpROM, JsrROM, and CmpRA macros. &RomFixIndex is a count of the total
|
||
; number of these references, and is also used to synthesize the label
|
||
; names for them. The reference labels have the form
|
||
; RXXX000, RXXX001, RXXX002, ...
|
||
; See the Macro definitions for JmpROM, JsrROM and CmpRA (near the top of
|
||
; this file) for more info.
|
||
;
|
||
; MkTbl is a macro only because assembler while loops will not work
|
||
; outside of macros.
|
||
;
|
||
MACRO
|
||
MkTbl
|
||
gbla &RomFixIndex
|
||
while &RomFixIndex <> 0 do
|
||
&RomFIxIndex seta &RomFixIndex - 1
|
||
dc.l RXXX&I2S(&ROMFIXINDEX,-3) - FixUpTbl
|
||
endwhile
|
||
dc.l 0 ; Zero entry marks end of table
|
||
ENDM
|
||
|
||
FixupTbl MkTbl
|
||
|
||
;########################### END PATCHES CUT BACK CODE ################################
|
||
endproc
|
||
|
||
end
|