mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-27 10:29:32 +00:00
4325cdcc78
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.
830 lines
24 KiB
Plaintext
830 lines
24 KiB
Plaintext
;
|
|
; File: SaveRestoreBits.a
|
|
;
|
|
; Contains: calls to save and restore bits
|
|
; also, calls that attach to a port and do buffering
|
|
;
|
|
; SaveBits is used to store bits from the screen of the Macintosh.
|
|
; After the bits have been saved, use RestoreBits to put them back on screen.
|
|
; The bits are stored in an off-screen handle.
|
|
;
|
|
; If there is insufficient memory for the bits off-screen, we allocate a handle
|
|
; containing only the rectangle. If there is too little space even for a handle
|
|
; containing a rectangle, we return nil.
|
|
;
|
|
; TYPE
|
|
; SavedBits = LONGINT;
|
|
;
|
|
; FUNCTION SaveBits(saveRect: Rect; purgeable: BOOLEAN; VAR bits: SavedBits): OSErr;
|
|
; FUNCTION RestoreBits(bits: SavedBits): OSErr;
|
|
; FUNCTION DiscardBits(bits: SavedBits): OSErr;
|
|
;
|
|
; TYPE
|
|
; OffscreenBuffer = LONGINT;
|
|
;
|
|
; FUNCTION BeginDrawingOffscreen(bufferRect: Rect; VAR buffer: OffscreenBuffer): OSErr;
|
|
; FUNCTION EndDrawingOffscreen(buffer: OffscreenBuffer): OSErr;
|
|
;
|
|
; FUNCTION NewOffscreenBuffer(bufferRect: Rect; purgeable: BOOLEAN; VAR buffer: OffscreenBuffer): OSErr;
|
|
; FUNCTION AttachOffscreenBuffer(buffer: OffscreenBuffer): OSErr;
|
|
; FUNCTION DetachOffscreenBuffer(buffer: OffscreenBuffer): OSErr;
|
|
; FUNCTION DisposeOffscreenBuffer(buffer: OffscreenBuffer): OSErr;
|
|
;
|
|
; Written by: Darin Adler
|
|
;
|
|
; Copyright: © 1990-1991 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; This file is used in these builds: BigBang
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <14> 5/21/91 gbm dba: fix obscure rowBytes bit bug
|
|
; <13> 2/5/91 stb gs: include MenuMgrPriv.a
|
|
; <12> 11/27/90 KON Make fgColor black, bgColor white before calling CopyBits to
|
|
; save bits to offscreen buffer. This eliminates undesirable
|
|
; colorizing. <KSM>
|
|
; <11> 10/23/90 KSM <KON>Use WMgr port instead of relying on A5 world because some
|
|
; monitors change the base address.
|
|
; <10> 9/22/90 dba Ed Tecot meant well when he told us to do a PaintOne(RootLayer),
|
|
; but he really meant PaintBehind(RootLayer).
|
|
; <9> 8/21/90 VL (with dba) fixed DetachOffscreenBuffer by using local
|
|
; coordinates for the offscreen pixmap.
|
|
; <8> 6/25/90 DTY Included LayerEqu.a
|
|
; <7> 6/25/90 dba replace PaintBehind(WindowList) with PaintOne(RootLayer)
|
|
; <6> 6/8/90 dba added calls to attach an off-screen buffer to an unsuspecting
|
|
; port
|
|
; <5> 6/8/90 dba always save the rectangle that goes with the bits; also support
|
|
; cases where the WMgrPort is not set to local=global; also get
|
|
; rid of the workaround to the ÒbugÓ in NewScreenBuffer since I
|
|
; now understand why the call works the way it does (and I fixed
|
|
; some bugs in the Classic and Macintosh II versions of it)
|
|
; <4> 5/31/90 KSM Since this is really following Pascal calling conventions,
|
|
; return the errors on the stack and NOT in D0.
|
|
; <3> 5/21/90 KSM As requested by Finder team, SaveBits tries to allocate from
|
|
; temp memory first, rather than using the app heap first.
|
|
; <2> 4/20/90 KSM Use Darin's new (and totally awesome) 1-line dispatcher macro to
|
|
; dispatch these routines (i.e. all functions return OSErr).
|
|
; <1> 4/9/90 dba new today
|
|
;
|
|
; To Do:
|
|
; use a device loop for SavedBits
|
|
; move equates into system equate files
|
|
; share more code between SavedBits and OffscreenBuffer
|
|
;
|
|
|
|
load 'StandardEqu.d'
|
|
include 'LayerEqu.a'
|
|
include 'InternalMacros.a'
|
|
include 'LinkedPatchMacros.a'
|
|
include 'MenuMgrPriv.a'
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
SavedBitsRecord record 0
|
|
rectangle ds.w 4 ; the rectangle
|
|
pixMap ds.l 1 ; the pixMap handle
|
|
endrsize
|
|
|
|
OffscreenBufferRecord record 0
|
|
rectangle ds.w 4 ; the rectangle (local coordinates)
|
|
bufferPixMap ds.l 1 ; the pixMap of the buffer
|
|
bufferGDevice ds.l 1 ; the gDevice for drawing in the buffer
|
|
savedPortBits ds.b bitMapRec ; the old bitmap of the port (for B&W)
|
|
org savedPortBits
|
|
savedPortPixMap ds.l 1 ; the old pixMap of the port
|
|
savedGDevice ds.l 1 ; the old gDevice for the port
|
|
org
|
|
endrsize
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
selectBeginDrawingOffscreen EQU 4
|
|
paramWordsBeginDrawingOffscreen EQU 4
|
|
|
|
MACRO
|
|
_BeginDrawingOffscreen
|
|
DoDispatch _SaveRestoreBits,selectBeginDrawingOffscreen,paramWordsBeginDrawingOffscreen
|
|
ENDM
|
|
|
|
selectEndDrawingOffscreen EQU 5
|
|
paramWordsEndDrawingOffscreen EQU 2
|
|
|
|
MACRO
|
|
_EndDrawingOffscreen
|
|
DoDispatch _SaveRestoreBits,selectEndDrawingOffscreen,paramWordsEndDrawingOffscreen
|
|
ENDM
|
|
|
|
selectNewOffscreenBuffer EQU 6
|
|
paramWordsNewOffscreenBuffer EQU 5
|
|
|
|
MACRO
|
|
_NewOffscreenBuffer
|
|
DoDispatch _SaveRestoreBits,selectNewOffscreenBuffer,paramWordsNewOffscreenBuffer
|
|
ENDM
|
|
|
|
selectAttachOffscreenBuffer EQU 7
|
|
paramWordsAttachOffscreenBuffer EQU 2
|
|
|
|
MACRO
|
|
_AttachOffscreenBuffer
|
|
DoDispatch _SaveRestoreBits,selectAttachOffscreenBuffer,paramWordsAttachOffscreenBuffer
|
|
ENDM
|
|
|
|
selectDetachOffscreenBuffer EQU 8
|
|
paramWordsDetachOffscreenBuffer EQU 2
|
|
|
|
MACRO
|
|
_DetachOffscreenBuffer
|
|
DoDispatch _SaveRestoreBits,selectDetachOffscreenBuffer,paramWordsDetachOffscreenBuffer
|
|
ENDM
|
|
|
|
selectDisposeOffscreenBuffer EQU 9
|
|
paramWordsDisposeOffscreenBuffer EQU 2
|
|
|
|
MACRO
|
|
_DisposeOffscreenBuffer
|
|
DoDispatch _SaveRestoreBits,selectDisposeOffscreenBuffer,paramWordsDisposeOffscreenBuffer
|
|
ENDM
|
|
|
|
|
|
SaveRestoreBitsDispatch Dispatcher _SaveRestoreBits,(Plus,SE,II,Portable,IIci), \
|
|
(\
|
|
SaveBits, \
|
|
RestoreBits, \
|
|
DiscardBits, \
|
|
BeginDrawingOffscreen, \
|
|
EndDrawingOffscreen, \
|
|
NewOffscreenBuffer, \
|
|
AttachOffscreenBuffer, \
|
|
DetachOffscreenBuffer, \
|
|
DisposeOffscreenBuffer, \
|
|
)
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
SaveBits proc export
|
|
entry CalculateOffscreenRect
|
|
export SetUpFgBgToBW
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
saveRectPtr ds.l 1 ; the rectangle of bits to save
|
|
purgeable ds.w 1 ; set this true if we want a purgeable buffer
|
|
resultPtr ds.l 1 ; where to put the saved handle
|
|
localsStackFrame
|
|
saveRect ds.w 4 ; rectangle to save (global coords)
|
|
offscreenRect ds.w 4 ; calculate the off-screen rectangle here
|
|
pixMap ds.l 1 ; the created pixMap handle
|
|
gDevice ds.l 1 ; the appropriate device
|
|
endStackFrame
|
|
|
|
linkSave a3
|
|
|
|
; save the rectangle, so we can take parameters from the middle of relocatable blocks
|
|
|
|
move.l saveRectPtr(a6),a0 ; get the rectangle into a local
|
|
move.l topLeft(a0),saveRect+topLeft(a6)
|
|
move.l botRight(a0),saveRect+botRight(a6)
|
|
|
|
; allocate our handle
|
|
|
|
move.l #0,a3 ; initialize result to 0
|
|
|
|
moveq #SavedBitsRecord.size,d0 ; make the handle we need
|
|
_NewHandle clear
|
|
bnz Done ; oops, failed
|
|
move.l a0,a3 ; store away the result
|
|
|
|
move.l (a0),a0 ; dereference the handle
|
|
move.l saveRect+topLeft(a6),(a0)+
|
|
move.l saveRect+botRight(a6),(a0)+
|
|
|
|
moveq #1,d0 ; try temp. memory
|
|
bsr DoNewScreenBuffer1
|
|
bz.s GotBuffer ; go if we got the buffer successfully
|
|
|
|
moveq #0,d0 ; donÕt use temp. memory
|
|
bsr DoNewScreenBuffer1
|
|
bz.s GotBuffer ; go if we got the buffer successfully
|
|
|
|
GotRectangleOnly
|
|
moveq #memFullErr,d0 ; return an error
|
|
bra.s Done
|
|
|
|
GotBuffer
|
|
rsrv.b ; make room for the result
|
|
push.l pixMap(a6)
|
|
_LockPixels
|
|
tst.b (sp)+ ; was the thing already purged?
|
|
bz.s GotPixMap ; this is not an error; it was purged right away!
|
|
|
|
btst #6,ROM85 ; check for color QuickDraw
|
|
bnz.s @noSetSaveDevice
|
|
|
|
rsrv.l ; make room for the saved device
|
|
_GetGDevice
|
|
|
|
push.l gDevice(a6) ; set the device to the one we desire
|
|
_SetGDevice
|
|
@noSetSaveDevice
|
|
|
|
move.l WMgrPort,a0 ; get non-color port
|
|
btst #6,ROM85 ; check for color QuickDraw
|
|
bnz.s @gotport
|
|
move.l WMgrCPort,a0 ; get color port
|
|
@gotport
|
|
bsr SetUpFgBgToBW ; <12> Set fg=black bg=white
|
|
|
|
pea portBits(a0) ; pass screenBits as the source
|
|
move.l pixMap(a6),a0 ; dereference the PixMapHandle
|
|
push.l (a0) ; pass the offscreen pixmap as the destination
|
|
lea offscreenRect(a6),a0 ; calculate the offscreen rectangle
|
|
lea saveRect(a6),a1 ; from the passed rectangle
|
|
bsr.s CalculateOffscreenRect
|
|
push.l a1 ; source is passed rectangle
|
|
push.l a0 ; destination is off-screen
|
|
push.w #srcCopy ; srcCopy
|
|
push.l #0 ; no masking
|
|
_CopyBits ; put the bits off-screen
|
|
|
|
btst #6,ROM85 ; check for color QuickDraw
|
|
bnz.s @noRestoreDevice
|
|
|
|
_SetGDevice ; set the device back to normal
|
|
@noRestoreDevice
|
|
|
|
push.l pixMap(a6)
|
|
_UnlockPixels ; unlock those pixels
|
|
|
|
GotPixMap
|
|
move.l (a3),a0 ; put pixmap in result
|
|
move.l pixMap(a6),SavedBitsRecord.pixMap(a0)
|
|
|
|
GotResult
|
|
moveq #noErr,d0 ; success!
|
|
|
|
Done
|
|
; at this point, the error is in d0 and the result is in a3
|
|
|
|
move.l resultPtr(a6),a0 ; get place to put result
|
|
move.l a3,(a0) ; put result there
|
|
move.w d0,error(a6) ; and remember to return any error <4>
|
|
|
|
restoreUnlinkReturn
|
|
|
|
DoNewScreenBuffer1
|
|
rsrv.w ; make room for error result
|
|
pea saveRect(a6) ; our global rectangle
|
|
push.b purgeable(a6) ; try purgeable bits?
|
|
pea gDevice(a6) ; get the device
|
|
pea pixMap(a6) ; get the pixMap
|
|
tst.b d0 ; should we use temp. memory?
|
|
bnz.s @temp
|
|
_NewScreenBuffer ; get buffer in current zone
|
|
bra.s @done
|
|
@temp
|
|
_NewTempScreenBuffer ; get buffer in shared memory
|
|
@done
|
|
pop.w d0 ; get error result
|
|
rts
|
|
|
|
CalculateOffscreenRect
|
|
clr.l topLeft(a0) ; offscreeRect.topLeft is always at 0,0
|
|
move.w bottom(a1),d0 ; calculate bottom
|
|
sub.w top(a1),d0 ; minus top
|
|
move.w d0,bottom(a0) ; offscreeRect.bottom is srcRect height
|
|
move.w right(a1),d0 ; calculate right
|
|
sub.w left(a1),d0 ; minus left
|
|
move.w d0,right(a0) ; offscreeRect.right is srcRect width
|
|
|
|
rts
|
|
|
|
SetUpFgBgToBW ; <12>
|
|
SetUpFgBgToBWReg REG a0/d0
|
|
movem.l SetUpFgBgToBWReg,-(sp)
|
|
moveq #BlackColor,d0
|
|
move.l d0,-(sp)
|
|
_ForeColor
|
|
moveq #WhiteColor,d0
|
|
move.l d0,-(sp)
|
|
_BackColor
|
|
movem.l (sp)+,SetUpFgBgToBWReg
|
|
rts
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
RestoreBits proc export
|
|
import DiscardBits
|
|
import CalculateOffscreenRect
|
|
import SetUpFgBgToBW
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
savedBits ds.l 1 ; bits to restore
|
|
localsStackFrame
|
|
bitsRect ds.w 4 ; rectangle to copy bits into
|
|
offscreenRect ds.w 4 ; calculate the off-screen rectangle here
|
|
menuBarRect ds.w 4 ; rectangle for the menu bar
|
|
endStackFrame
|
|
|
|
linkSave d3/a2
|
|
|
|
rsrv.l ; make room for saved port
|
|
push.l sp ; point to result
|
|
_GetPort
|
|
|
|
rsrv.l ; set the port to the Window Mgr port
|
|
push.l sp ; point to result
|
|
_GetWMgrPort
|
|
move.l (sp),a2 ; keep a pointer around
|
|
_SetPort
|
|
jsr SetUpFgBgToBW ; <12> Set fg=black bg=white
|
|
|
|
move.l savedBits(a6),d3 ; look at the handle
|
|
bz.s InvalAll ; no handle, invalidate a wide-open region
|
|
|
|
move.l d3,a0 ; dereference the handle
|
|
move.l (a0),a0
|
|
|
|
move.l SavedBitsRecord.rectangle+topLeft(a0),bitsRect+topLeft(a6)
|
|
move.l SavedBitsRecord.rectangle+botRight(a0),bitsRect+botRight(a6)
|
|
|
|
move.l SavedBitsRecord.pixMap(a0),d3 ; get the pixMap handle
|
|
bz.s Inval
|
|
|
|
rsrv.b ; make room for the result
|
|
push.l d3
|
|
_LockPixels
|
|
tst.b (sp)+ ; was the thing purged?
|
|
bz.s Inval ; purged, so do an invalidate
|
|
|
|
pea bitsRect+topLeft(a6)
|
|
_GlobalToLocal
|
|
pea bitsRect+botRight(a6)
|
|
_GlobalToLocal
|
|
|
|
pea bitsRect(a6) ; set the clip to this rectangle
|
|
_ClipRect
|
|
|
|
move.l d3,a0 ; dereference the PixMapHandle
|
|
push.l (a0) ; pass the offscreen pixmap as the source
|
|
pea portBits(a2) ; pass portBits as the destination
|
|
lea offscreenRect(a6),a0 ; calculate a source rectangle
|
|
lea bitsRect(a6),a1 ; from the destination rectangle
|
|
jsr CalculateOffscreenRect
|
|
push.l a0 ; source is off-screen
|
|
push.l a1 ; destination is local on-screen
|
|
push.w #srcCopy ; srcCopy
|
|
push.l #0 ; no masking
|
|
_CopyBits ; put the bits back on-screen
|
|
|
|
bra.s Done
|
|
|
|
InvalAll
|
|
move.l #$80028002,bitsRect+topLeft(a6) ; fairly wide open, but a bit smaller
|
|
move.l #$7FFE7FFE,bitsRect+botRight(a6) ; (I think I remember some Mac Plus bug)
|
|
|
|
Inval
|
|
move.l portRect+topLeft(a2),menuBarRect+topLeft(a6)
|
|
move.w portRect+right(a2),menuBarRect+right(a6)
|
|
move.w portRect+top(a2),d0
|
|
add.w MBarHeight,d0 ; calculate the rectangle for the menu bar
|
|
move.w d0,menuBarRect+bottom(a6)
|
|
|
|
rsrv.b ; make room for result
|
|
pea bitsRect(a6) ; intersect with the menu bar
|
|
pea menuBarRect(a6) ; intersect with the menu bar
|
|
push.l (sp) ; put result in menu bar rectangle
|
|
_SectRect ; see if it intersects the menu
|
|
tst.b (sp)+ ; does it
|
|
bz.s @noNeedToDrawMenubar
|
|
_InvalMenuBar ; it intersects; draw the menu bar
|
|
@noNeedToDrawMenubar
|
|
|
|
rsrv.l ; make a nice fresh region
|
|
_NewRgn
|
|
move.l (sp),d3 ; get resulting region
|
|
pea bitsRect(a6) ; and make it rectangular
|
|
_RectRgn
|
|
|
|
rsrv.l
|
|
_GetRootLayer
|
|
push.l d3 ; and clobber everything
|
|
_PaintBehind ; <10>
|
|
|
|
push.l d3 ; now we are done
|
|
_DisposRgn
|
|
|
|
Done
|
|
_SetPort ; restore the current port
|
|
|
|
rsrv.w ; make room for results
|
|
push.l savedBits(a6) ; now, get rid of those bits
|
|
_DiscardBits ; all of them!
|
|
pop.w error(a6) ; return the error result
|
|
|
|
restoreUnlinkReturn
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
DiscardBits proc export
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
bits ds.l 1 ; bits to discard
|
|
endStackFrame
|
|
|
|
linkSave d3
|
|
|
|
move.l bits(a6),d3 ; look at the handle
|
|
bz.s Done ; no handle
|
|
|
|
move.l d3,a0 ; dereference the handle
|
|
move.l (a0),a1
|
|
move.l SavedBitsRecord.pixMap(a1),d3 ; get the pixMap handle
|
|
_DisposHandle ; get rid of the handle
|
|
|
|
tst.l d3 ; check the screen buffer
|
|
bz.s Done ; no buffer
|
|
|
|
push.l d3 ; get it
|
|
_DisposeScreenBuffer ; get rid of it
|
|
|
|
Done
|
|
move.w #noErr,error(a6) ; show no error
|
|
|
|
restoreUnlinkReturn
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
BeginDrawingOffscreen proc export
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
bufferRectPtr ds.l 1 ; rectangle to buffer
|
|
bufferHandlePtr ds.l 1 ; result
|
|
endStackFrame
|
|
|
|
linkSave
|
|
|
|
rsrv.w
|
|
push.l bufferRectPtr(a6)
|
|
push.b #false
|
|
push.l bufferHandlePtr(a6)
|
|
_NewOffscreenBuffer
|
|
pop.w d0 ; check error code
|
|
bnz.s @done
|
|
|
|
rsrv.w
|
|
move.l bufferHandlePtr(a6),a0
|
|
push.l (a0) ; push the bufferHandle
|
|
_AttachOffscreenBuffer
|
|
pop.w d0
|
|
@done
|
|
move.w d0,error(a6) ; return the error code
|
|
|
|
restoreUnlinkReturn
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
EndDrawingOffscreen proc export
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
bufferHandle ds.l 1 ; buffer parameter
|
|
endStackFrame
|
|
|
|
linkSave
|
|
|
|
rsrv.w
|
|
push.l bufferHandle(a6)
|
|
_DetachOffscreenBuffer ; ignore the error
|
|
push.l bufferHandle(a6)
|
|
_DisposeOffscreenBuffer
|
|
pop.w error(a6) ; get the error code
|
|
|
|
restoreUnlinkReturn
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
NewOffscreenBuffer proc export
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
bufferRectPtr ds.l 1 ; rectangle to buffer
|
|
purgeable ds.w 1 ; purgeable flag
|
|
resultPtr ds.l 1 ; place to put result
|
|
localsStackFrame
|
|
localBufferRect ds.w 4 ; rectangle to buffer
|
|
globalBufferRect ds.w 4 ; globalized
|
|
pixMap ds.l 1 ; the created pixMap handle
|
|
gDevice ds.l 1 ; the appropriate device
|
|
endStackFrame
|
|
|
|
linkSave a2-a4
|
|
|
|
; save the rectangle, so we can take parameters from the middle of relocatable blocks
|
|
|
|
move.l bufferRectPtr(a6),a0
|
|
move.l topLeft(a0),localBufferRect+topLeft(a6)
|
|
move.l botRight(a0),localBufferRect+botRight(a6)
|
|
|
|
; get the port (keep it around in a2)
|
|
|
|
rsrv.l
|
|
push.l sp
|
|
_GetPort
|
|
pop.l a2 ; keep it
|
|
|
|
; allocate our handle
|
|
|
|
move.l #0,a3 ; initialize result to 0
|
|
|
|
moveq #OffscreenBufferRecord.size,d0 ; make the handle we need
|
|
_NewHandle clear
|
|
bnz.s Done ; oops, failed
|
|
move.l a0,a3 ; store away the result
|
|
|
|
; fill in the handle with the port and the rectangle
|
|
|
|
move.l (a3),a0
|
|
move.l localBufferRect+topLeft(a6),(a0)+
|
|
move.l localBufferRect+botRight(a6),(a0)+
|
|
|
|
; get rectangle into our stack frame (into global coordinates)
|
|
|
|
move.l localBufferRect+topLeft(a6),globalBufferRect+topLeft(a6)
|
|
move.l localBufferRect+botRight(a6),globalBufferRect+botRight(a6)
|
|
|
|
pea globalBufferRect+topLeft(a6)
|
|
_LocalToGlobal ; convert topLeft to global coordinates
|
|
pea globalBufferRect+botRight(a6)
|
|
_LocalToGlobal ; convert botRight to global coordinates
|
|
|
|
; allocate the buffer
|
|
|
|
moveq #1,d0 ; try temp. memory
|
|
bsr.s DoNewScreenBuffer2
|
|
bz.s GotBuffer ; go if we got the buffer successfully
|
|
|
|
moveq #0,d0 ; donÕt use temp. memory
|
|
bsr.s DoNewScreenBuffer2
|
|
bz.s GotBuffer ; go if we got the buffer successfully
|
|
|
|
GotHandleOnly
|
|
move.l a3,a0 ; get rid of handle
|
|
_DisposHandle
|
|
|
|
move.l #0,a3
|
|
moveq #memFullErr,d0 ; return an error
|
|
bra.s Done
|
|
|
|
GotBuffer
|
|
move.l pixMap(a6),a4
|
|
|
|
move.l (a3),a0 ; stuff the handle
|
|
move.l a4,OffscreenBufferRecord.bufferPixMap(a0)
|
|
move.l gDevice(a6),OffscreenBufferRecord.bufferGDevice(a0)
|
|
|
|
move.l (a4),a0
|
|
pea pmBounds(a0) ; offset this rectangle
|
|
push.l localBufferRect+topLeft(a6) ; so that it corresponds to local coordinates
|
|
_OffsetRect ; move the pixmap
|
|
|
|
moveq #noErr,d0
|
|
|
|
Done
|
|
move.l resultPtr(a6),a0 ; store the result
|
|
move.l a3,(a0)
|
|
move.w d0,error(a6) ; return the error
|
|
|
|
restoreUnlinkReturn
|
|
|
|
DoNewScreenBuffer2
|
|
rsrv.w ; make room for error result
|
|
pea globalBufferRect(a6) ; our rectangle
|
|
push.b purgeable(a6) ; try purgeable bits?
|
|
pea gDevice(a6) ; get the device
|
|
pea pixMap(a6) ; get the pixMap
|
|
tst.b d0 ; should we use temp. memory?
|
|
bnz.s @temp
|
|
_NewScreenBuffer ; get buffer in current zone
|
|
bra.s @done
|
|
@temp
|
|
_NewTempScreenBuffer ; get buffer in shared memory
|
|
@done
|
|
pop.w d0 ; get error result
|
|
rts
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
AttachOffscreenBuffer proc export
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
buffer ds.l 1 ; buffer to dispose
|
|
endStackFrame
|
|
|
|
linkSave d3/a3-a4
|
|
|
|
move.w #memFullErr,error(a6) ; assume out of memory
|
|
|
|
move.l buffer(a6),d0 ; look at the handle
|
|
bz.s GotError ; no handle
|
|
move.l d0,a3
|
|
|
|
move.l (a3),a0 ; dereference the handle
|
|
move.l OffscreenBufferRecord.bufferPixMap(a0),a4
|
|
|
|
rsrv.b ; make room for the result
|
|
push.l a4
|
|
_LockPixels
|
|
tst.b (sp)+ ; could we lock it?
|
|
bz.s GotError ; nope, we are done
|
|
|
|
; get the port (keep it around in a2)
|
|
|
|
rsrv.l
|
|
push.l sp
|
|
_GetPort
|
|
pop.l a2 ; keep it
|
|
|
|
; attach buffer to the port
|
|
|
|
tst.w portVersion(a2) ; color?
|
|
bmi.s @color
|
|
|
|
; classic case
|
|
|
|
lea portBits(a2),a0 ; source
|
|
move.l (a3),a1
|
|
lea OffscreenBufferRecord.savedPortBits(a1),a1 ; destination
|
|
moveq #bitmapRec/2-1,d0 ; loop count
|
|
@loop move.w (a0)+,(a1)+
|
|
dbra d0,@loop
|
|
|
|
push.l (a4) ; get pointer to pixmap
|
|
_SetPBits ; set the port bits up
|
|
and.w #$3FFF,portBits+rowBytes(a2) ; mask off rowBytes value (only works for 1-bit) <14>
|
|
|
|
bra.s @done
|
|
|
|
; color case
|
|
|
|
@color
|
|
rsrv.l
|
|
_GetGDevice
|
|
move.l (a3),a0
|
|
move.l portPixMap(a2),OffscreenBufferRecord.savedPortPixMap(a0) ; save the portÕs pixMap
|
|
pop.l OffscreenBufferRecord.savedGDevice(a0) ; get device to save
|
|
push.l OffscreenBufferRecord.bufferGDevice(a0)
|
|
_SetGDevice ; set to the right device
|
|
push.l a4
|
|
_SetPortPix ; set the pixmap
|
|
|
|
@done
|
|
move.w #noErr,error(a6) ; show no error
|
|
GotError
|
|
|
|
restoreUnlinkReturn
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
DetachOffscreenBuffer proc export
|
|
import SetUpFgBgToBW
|
|
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
buffer ds.l 1 ; buffer to dispose
|
|
endStackFrame
|
|
|
|
linkSave a3
|
|
|
|
move.l buffer(a6),d0 ; look at the handle
|
|
bz.s Done ; no handle
|
|
move.l d0,a3
|
|
|
|
move.l (a3),a0
|
|
tst.l OffscreenBufferRecord.savedPortPixMap(a0)
|
|
bz.s Done ; pixmap is not attached, we are done
|
|
|
|
move.l OffscreenBufferRecord.bufferPixMap(a0),a4
|
|
|
|
; get the port (keep it around in a2)
|
|
|
|
rsrv.l
|
|
push.l sp
|
|
_GetPort
|
|
pop.l a2 ; keep it
|
|
|
|
; detach buffer from the port
|
|
|
|
move.l (a3),a0 ; dereference the handle
|
|
|
|
tst.w portVersion(a2) ; color?
|
|
bmi.s @color
|
|
|
|
; classic case
|
|
|
|
pea OffscreenBufferRecord.savedPortBits(a0)
|
|
_SetPBits ; set the port bits back
|
|
|
|
bra.s PortDone
|
|
|
|
; color case
|
|
|
|
@color
|
|
push.l OffscreenBufferRecord.savedGDevice(a0)
|
|
push.l OffscreenBufferRecord.savedPortPixMap(a0)
|
|
_SetPortPix ; set the pixmap
|
|
_SetGDevice ; set to the right device
|
|
|
|
PortDone
|
|
jsr SetUpFgBgToBW ; <12> Set fg=black bg=white
|
|
|
|
; mark that this buffer is done
|
|
|
|
move.l (a3),a0
|
|
clr.l OffscreenBufferRecord.savedPortPixMap(a0)
|
|
|
|
; copy bits from offscreen to onscreen
|
|
|
|
push.l (a4) ; srcBits (offscreen bits)
|
|
pea portBits(a2) ; dstBits (the port)
|
|
move.l (a3),a0
|
|
pea OffscreenBufferRecord.rectangle(a0) ; srcRect (on-screen) <9>
|
|
move.l (SP),-(SP) ; destRect too <9>
|
|
push.w #srcCopy ; mode (srcCopy)
|
|
push.l #0 ; maskRgn (none)
|
|
_CopyBits
|
|
|
|
push.l a4
|
|
_UnlockPixels
|
|
|
|
Done
|
|
move.w #noErr,error(a6) ; show no error
|
|
|
|
restoreUnlinkReturn
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
DisposeOffscreenBuffer proc export
|
|
|
|
resultsStackFrame
|
|
error ds.w 1 ; the resulting error code
|
|
parametersStackFrame
|
|
buffer ds.l 1 ; buffer to dispose
|
|
endStackFrame
|
|
|
|
linkSave d3
|
|
|
|
move.l buffer(a6),d3 ; look at the handle
|
|
bz.s Done ; no handle
|
|
|
|
rsrv.w
|
|
push.l d3
|
|
_DetachOffscreenBuffer ; detach the buffer
|
|
free.w ; ignore result
|
|
|
|
move.l d3,a0 ; get handle in a0
|
|
move.l (a0),a1
|
|
push.l OffscreenBufferRecord.bufferPixMap(a1) ; push buffer
|
|
_DisposHandle ; get rid of the handle
|
|
_DisposeScreenBuffer ; get rid of the buffer
|
|
|
|
Done
|
|
move.w #noErr,error(a6) ; show no error
|
|
|
|
restoreUnlinkReturn
|
|
|
|
endproc
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
|
|
end
|