mirror of
https://github.com/elliotnunn/boot3.git
synced 2024-06-09 17:29:28 +00:00
5b0f0cc134
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
19650 lines
657 KiB
Plaintext
19650 lines
657 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
|