mirror of
https://github.com/antoinevignau/source.git
synced 2024-10-31 22:06:40 +00:00
1 line
16 KiB
Plaintext
Executable File
1 line
16 KiB
Plaintext
Executable File
****************************************************************
|
|
* ;
|
|
* Pixelmap flipping and rotation routines ;
|
|
*______________________________________________________________*
|
|
* ;
|
|
* Pixelmaps are flipped and rotated with 4-bit Q_Pixels. ;
|
|
* (For once, I'm glad that there ISN'T a 640x400 one bit- ;
|
|
* per-pixel mode!!) 640 pixel maps that are an odd number ;
|
|
* of (640) Q_Pixels wide will lose a column when rotated. ;
|
|
* TANSTAAFL. Shit happens. ;
|
|
* ;
|
|
* It's rather strange, but the SCB for a pixelmap in a ;
|
|
* picture is ALWAYS the same as the picture's SCB. This is ;
|
|
* incredibly fortuitous, since we only have to worry about ;
|
|
* one mode at a time now. ;
|
|
* ;
|
|
* (At least, I've never SEEN them different....) ;
|
|
* ;
|
|
****************************************************************
|
|
|
|
LOAD 'Macros.dump'
|
|
INCLUDE 'Pict.equ'
|
|
INCLUDE 'Driver.equ'
|
|
|
|
IMPORT D_BeachBall
|
|
IMPORT Q_ChangePictSize
|
|
IMPORT Q_Copy2
|
|
IMPORT Q_Copy4
|
|
IMPORT Q_FixRect
|
|
IMPORT Q_JustRect
|
|
IMPORT Q_JustRgn
|
|
IMPORT Q_manglePt
|
|
IMPORT Q_Nop
|
|
IMPORT Q_PixelTable
|
|
IMPORT Q_addbytes
|
|
IMPORT Q_center
|
|
IMPORT Q_dstpixsize
|
|
IMPORT newptr
|
|
IMPORT oldptr
|
|
IMPORT Q_picterr
|
|
IMPORT Q_pixSCB
|
|
IMPORT Q_pixbounds
|
|
IMPORT Q_srcpixsize
|
|
IMPORT thepoint
|
|
IMPORT what
|
|
|
|
****************************************************************
|
|
*
|
|
* Q_PixOps -- handle picture opcodes Q_PixRect and Q_PixRgn
|
|
*
|
|
****************************************************************
|
|
Q_PixOps PROC EXPORT
|
|
;Using Q_PictData
|
|
EXPORT Q_PixRgn
|
|
EXPORT Q_PixRect
|
|
|
|
Q_Mask DS.B 2 ; is there a Q_Mask Q_Region?
|
|
toppt DS.B 4 ; upper left of old bounds
|
|
|
|
*--------------------------------------------------------------*
|
|
* Copy a pixelmap opcode and mangle its data ;
|
|
*--------------------------------------------------------------*
|
|
Q_PixRgn ;
|
|
inc Q_Mask
|
|
bra dopixels
|
|
|
|
Q_PixRect ;
|
|
stz Q_Mask
|
|
|
|
dopixels jsl Q_Nop ; copy opcode
|
|
lda [<oldptr]
|
|
and #$80 ; D_Save mode
|
|
sta Q_pixSCB
|
|
jsl Q_Copy4 ; copy SCB and BWvsColor
|
|
|
|
spacelong ; get the size of the old pixelmap
|
|
pushword [<oldptr] ; old width
|
|
subword [<oldptr]:#6,[<oldptr]:#2,s ; old height
|
|
_Multiply
|
|
pulllong Q_srcpixsize
|
|
|
|
movelong [<oldptr]:#2,toppt ; get upper left Q_Point of bounds
|
|
|
|
cmpw <what,#Q_rotr ; am I rotating?
|
|
jlt pixflip ; must not be
|
|
*--------------------------------------------------------------*
|
|
* ROTATE ;
|
|
*--------------------------------------------------------------*
|
|
subword [<oldptr]:#6,toppt,a ; get height of bounds
|
|
dec a ; convert Q_Pixels->bytes
|
|
lsr a
|
|
inc a
|
|
sta [<newptr] ; this is the width of the rotated map
|
|
|
|
movelong #0,[<newptr]:#2 ; adjust first pt. to 0
|
|
subword [<oldptr]:#6,toppt,<thepoint ; get the bounds
|
|
subword [<oldptr]:#8,toppt+2,<thepoint+2 ; and adjust
|
|
|
|
ldx <thepoint ; flip the Q_Point diagonally
|
|
lda <thepoint+2
|
|
sta <thepoint
|
|
stx <thepoint+2
|
|
|
|
movelong <thepoint,Q_pixbounds ; remember the D_New bounds NOW
|
|
|
|
lda Q_pixSCB ; adjust for 640 mode?
|
|
beq newboundsok
|
|
lsr <thepoint ; if so, halve the old width
|
|
asl <thepoint+2 ; and double the D_New width
|
|
|
|
newboundsok movelong <thepoint,[<newptr]:#6 ; store D_New (adjusted) bounds
|
|
|
|
spacelong ; compute the size of the dest. map
|
|
pushword [<newptr] ; D_New width
|
|
pushword [<newptr]:#6 ; D_New height
|
|
_Multiply
|
|
pulllong Q_dstpixsize
|
|
|
|
addwl #10,<oldptr ; adjust the pointers
|
|
addwl #10,<newptr
|
|
|
|
sublong Q_dstpixsize,Q_srcpixsize,Q_addbytes
|
|
jsl Q_ChangePictSize
|
|
jcc rotsrcrect
|
|
sta Q_picterr
|
|
brl bye
|
|
|
|
rotsrcrect pushlong Q_center ; Flip around the pixelmap's
|
|
movelong Q_pixbounds,Q_center ; Q_center, not the picture's
|
|
|
|
noshift subword [<oldptr],toppt,<thepoint+2 ; adjust upper left pt
|
|
subword [<oldptr]:#2,toppt+2,<thepoint ; and flip diagonally
|
|
|
|
getsrc1 lda <what ; Now r-rotation becomes HACK
|
|
dec a ; h-flipping, and l-rotation
|
|
dec a ; becomes v-flipping
|
|
jtl Q_manglePt ; KCAH
|
|
|
|
lda Q_pixSCB ; adjust for 640 mode?
|
|
beq srcok1
|
|
lsr <thepoint
|
|
asl <thepoint+2
|
|
|
|
srcok1 movelong <thepoint,[<newptr]
|
|
|
|
subword [<oldptr]:#4,toppt,<thepoint+2 ; repeat for
|
|
subword [<oldptr]:#6,toppt+2,<thepoint ; lower right pt
|
|
|
|
getsrc2 lda <what ; Now r-rotation becomes HACK
|
|
dec a ; h-flipping, and l-rotation
|
|
dec a ; becomes v-flipping
|
|
jtl Q_manglePt ; KCAH
|
|
|
|
lda Q_pixSCB ; adjust for 640 mode?
|
|
beq srcok2
|
|
lsr <thepoint
|
|
asl <thepoint+2
|
|
|
|
srcok2 movelong <thepoint,[<newptr]:#4
|
|
|
|
pulllong Q_center ; back to the picture's Q_center
|
|
|
|
addwl #8,<oldptr
|
|
jsl Q_FixRect ; legalize the D_New source rectangle
|
|
brl gotsrcrect
|
|
*--------------------------------------------------------------*
|
|
* FLIP ;
|
|
*--------------------------------------------------------------*
|
|
pixflip jsl Q_Copy2 ; copy width
|
|
|
|
subword [<oldptr]:#4,toppt,Q_pixbounds ; get 'Q_center'
|
|
subword [<oldptr]:#6,toppt+2,Q_pixbounds+2 ; of bounds
|
|
|
|
movelong #0,[<newptr] ; adjust the D_New bounds
|
|
movelong Q_pixbounds,[<newptr]:#4 ; Q_Rect to (0,0)
|
|
|
|
addwl #8,<oldptr ; adjust the pointers (duh...)
|
|
addwl #8,<newptr
|
|
|
|
movelong Q_srcpixsize,Q_dstpixsize ; the D_New map is the same size!
|
|
|
|
pushlong Q_center ; flip the source Q_Rect around
|
|
movelong Q_pixbounds,Q_center ; the Q_center of the bounds Q_Rect
|
|
|
|
subword [<oldptr],toppt,<thepoint ; adjust src Q_Rect
|
|
subword [<oldptr]:#2,toppt+2,<thepoint+2 ; to match bounds
|
|
jtl Q_manglePt,<what
|
|
movelong <thepoint,[<newptr]
|
|
|
|
subword [<oldptr]:#4,toppt,<thepoint
|
|
subword [<oldptr]:#6,toppt+2,<thepoint+2
|
|
jtl Q_manglePt,<what
|
|
movelong <thepoint,[<newptr]:#4
|
|
|
|
jsl Q_FixRect
|
|
addwl #8,<oldptr
|
|
|
|
pulllong Q_center ; back to the picture's coordinates
|
|
|
|
gotsrcrect jsl Q_JustRect ; copy/mangle the dstrect
|
|
jsl Q_Copy2 ; copy the transfer mode
|
|
|
|
lda Q_Mask ; is there a Q_Mask Q_Region?
|
|
jeq noregion
|
|
|
|
jsl Q_JustRgn ; if so, mangle it!
|
|
|
|
noregion pushlong <oldptr ; now for the real work....
|
|
pushlong <newptr
|
|
jtl Q_PixelTable,<what ; (no errors possible)
|
|
|
|
addlong <oldptr,Q_srcpixsize,<oldptr
|
|
addlong <newptr,Q_dstpixsize,<newptr
|
|
|
|
clc
|
|
bye rtl
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* Q_FlipHMap(srcpix:l,dstpix:l) -- flip a pixelmap horizontally
|
|
*_______________________________________________________________
|
|
*
|
|
* NOTE: The destination bitmap is assumed to be allocated.
|
|
* Q_pixbounds should contain the coordinates of the lower
|
|
* right corner of the destination map, and Q_pixSCB should
|
|
* contain the pixel map's SCB byte. Row sizes and total
|
|
* sizes (bytes) are derived from this Q_Point. No error
|
|
* checking is performed -- Q_FlipHMap and its siblings
|
|
* simply D_Write over whatever memory you Q_Point them at.
|
|
*
|
|
****************************************************************
|
|
Q_FlipHMap PROC EXPORT
|
|
;Using Q_PictData
|
|
|
|
input srcpix:l,dstpix:l
|
|
|
|
local rowsize:w,slop:w,rcount:w,mode:w
|
|
local soffset:w,doffset:w,pixel:w,temp:w
|
|
|
|
begin
|
|
|
|
spaceword
|
|
_GetMasterSCB
|
|
pla
|
|
and #$80
|
|
sta mode
|
|
|
|
lda Q_pixbounds+2 ; get rowsize in bytes
|
|
dec a
|
|
lsr a
|
|
ldx Q_pixSCB ; 640 mode?
|
|
beq gotwid
|
|
lsr a
|
|
gotwid inc a
|
|
sta rowsize
|
|
|
|
lda Q_pixbounds+2 ; is there an extra pixel on the edge?
|
|
ldx Q_pixSCB ; am i 640 mode?
|
|
beq getslop
|
|
dec a ; if so, then are there two or three
|
|
lsr a ; extra Q_Pixels on the edge?
|
|
inc a
|
|
getslop and #1
|
|
sta slop ; (slop = number of ununsed low nybbles)
|
|
|
|
stz rcount ; start at row zero
|
|
|
|
*--------------------------------------------------------------*
|
|
* ROW LOOP ;
|
|
*--------------------------------------------------------------*
|
|
rloop
|
|
jsl D_BeachBall
|
|
stz soffset ; start at the left end of source...
|
|
moveword rowsize,doffset ; ...and the right end of dest.
|
|
|
|
lda slop ; sloppy?
|
|
jne slopstart
|
|
|
|
*--------------------------------------------------------------*
|
|
* Neat point loop: the maps are an even number of Q_Pixels wide ;
|
|
*--------------------------------------------------------------*
|
|
neatloop moveword [srcpix]:soffset,a ; get the byte
|
|
|
|
and #$ff ; a = 0 0 X Y reverse the nybbles
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a ; a = 0 X Y 0
|
|
sta pixel
|
|
xba ; a = Y 0 0 B
|
|
ora pixel ; a = Y X Y X
|
|
|
|
; ldx mode
|
|
; beq neat320
|
|
; jsr FlipNyps
|
|
|
|
neat320 dec doffset ; adjust the offset
|
|
movebyte a,[dstpix]:doffset ; put the byte
|
|
|
|
lda doffset ; done?
|
|
jeq rdone
|
|
|
|
inc soffset ; adjust the offset
|
|
brl neatloop
|
|
|
|
*--------------------------------------------------------------*
|
|
* Sloppy Q_Point loop: the maps are an odd number of Q_Pixels wide ;
|
|
*--------------------------------------------------------------*
|
|
slopstart stz pixel ; initialize this.
|
|
|
|
sloploop moveword [srcpix]:soffset,a ; get the byte
|
|
pha ; D_Save it
|
|
and #$f0 ; get the high nybble
|
|
ora pixel ; fill up the byte
|
|
|
|
; ldx mode
|
|
; beq slop320
|
|
; jsr FlipNyps
|
|
|
|
slop320 dec doffset
|
|
movebyte a,[dstpix]:doffset ; D_Write it out
|
|
|
|
lda doffset ; fix the offset
|
|
jeq endslop ; am I done yet?
|
|
|
|
pla ; restore the byte from above
|
|
and #$f ; get the low nybble
|
|
sta pixel ; initialize the byte
|
|
inc soffset ; fix the offset
|
|
|
|
brl sloploop ; repeat
|
|
|
|
endslop plx ; clear up the stack
|
|
*--------------------------------------------------------------*
|
|
rdone addwl rowsize,srcpix ; We're done with one row.
|
|
addwl rowsize,dstpix ; D_Update the pointers.
|
|
|
|
inc rcount ; have I reached the last row?
|
|
cmpw rcount,Q_pixbounds
|
|
jlt rloop ; nope. try again.
|
|
|
|
return ; If so, I'm done!!
|
|
|
|
; ;--------------------------------------------------------------*
|
|
; ; FlipNyps -- reverse the nyp order in each nyble in a ;
|
|
; ; (For those who don't know, a 'nyp' is Q_half a nybble.) ;
|
|
; ;--------------------------------------------------------------*
|
|
; FlipNyps tax
|
|
; and #$3333 ; get the low nyps
|
|
; asl a
|
|
; asl a ; move them up
|
|
; sta temp
|
|
; txa
|
|
; and #$cccc ; get the high nyps
|
|
; lsr a
|
|
; lsr a ; move them down
|
|
; ora temp
|
|
; rts
|
|
;
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* Q_FlipVMap(srcpix:l,dstpix:l) -- flip a pixelmap vertically
|
|
*
|
|
****************************************************************
|
|
Q_FlipVMap PROC EXPORT
|
|
;Using Q_PictData
|
|
|
|
input srcpix:l,dstpix:l
|
|
|
|
local rowsize:w,rcount:w
|
|
|
|
begin
|
|
|
|
lda Q_pixbounds+2 ; get rowsize in bytes
|
|
dec a
|
|
lsr a
|
|
ldx Q_pixSCB ; 640 mode?
|
|
beq gotwid
|
|
lsr a
|
|
gotwid inc a
|
|
sta rowsize
|
|
|
|
stz rcount ; start at (source) row zero
|
|
|
|
spacelong
|
|
subword Q_pixbounds,#1,s
|
|
pushword rowsize
|
|
_Multiply
|
|
addlong s,dstpix,dstpix ; start at the last destination row
|
|
|
|
rloop
|
|
jsl D_BeachBall
|
|
pushlong srcpix ; copy a row
|
|
pushlong dstpix
|
|
pushword #0 ; amount high word
|
|
pushword rowsize ; amount low word
|
|
_BlockMove
|
|
|
|
addwl rowsize,srcpix ; D_Update the pointers
|
|
subwl rowsize,dstpix
|
|
|
|
inc rcount
|
|
cmpw rcount,Q_pixbounds ; done?
|
|
jlt rloop
|
|
|
|
return
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* Q_RotRMap(srcpix:l,dstpix:l) -- rotate a pixelmap clockwise
|
|
*
|
|
* Source is scanned rightwards a column at a time, starting
|
|
* at the top of each column. Destination is scanned
|
|
* downward a row at a time, starting at the right end
|
|
* of each row.
|
|
*
|
|
****************************************************************
|
|
Q_RotRMap PROC EXPORT
|
|
;Using Q_PictData
|
|
|
|
input srcpix:l,dstpix:l
|
|
|
|
local srowsize:w,drowsize:w
|
|
local soffset:w,doffset:w,rcount:w,srcrow:l
|
|
local pixel:w,slop:w,dside:w,sside:w
|
|
|
|
begin
|
|
|
|
lda Q_pixSCB
|
|
beq boundsok
|
|
|
|
dec Q_pixbounds ; adjust OLD width of bounds ONLY
|
|
lsr Q_pixbounds
|
|
inc Q_pixbounds ; <for use by Q_RotRMap and Q_RotLMap>
|
|
|
|
boundsok lda Q_pixbounds ; get source rowsize in bytes
|
|
dec a
|
|
lsr a ; (already adjusted for mode)
|
|
inc a
|
|
sta srowsize
|
|
|
|
lda Q_pixbounds+2 ; get destination rowsize in bytes
|
|
dec a
|
|
lsr a ; (already adjusted for mode)
|
|
inc a
|
|
sta drowsize
|
|
|
|
lda Q_pixbounds+2 ; is there an extra pixel on the edge
|
|
and #1 ; of the destination map?
|
|
sta slop
|
|
|
|
moveword Q_pixbounds,rcount
|
|
moveword #1,sside
|
|
stz soffset ; (start at the left of source)
|
|
|
|
rloop
|
|
jsl D_BeachBall
|
|
moveword drowsize,doffset ; initialize the offsets
|
|
movelong srcpix,srcrow ; (start at the top of source)
|
|
moveword slop,dside ; and other goodies
|
|
stz pixel
|
|
|
|
ploop moveword [srcrow]:soffset,a ; get the source byte
|
|
|
|
ldx sside ; which side is the pixel on?
|
|
bne shipixel
|
|
|
|
and #$f ; it's low.
|
|
ldx dside ; should it be?
|
|
beq putpixel
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
bra gotpixel
|
|
|
|
shipixel and #$f0 ; it's high
|
|
ldx dside ; should it be?
|
|
bne gotpixel
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
|
|
gotpixel ora pixel
|
|
putpixel sta pixel
|
|
|
|
lda dside ; am I done with this byte?
|
|
beq nowrite
|
|
|
|
dec doffset ; move backwards through the dest. row
|
|
movebyte pixel,[dstpix]:doffset
|
|
lda doffset ; am I done with this row?
|
|
jeq rdone
|
|
|
|
stz dside
|
|
stz pixel
|
|
bra nextp
|
|
|
|
nowrite inc dside
|
|
|
|
nextp addwl srowsize,srcrow ; next source row.
|
|
brl ploop
|
|
|
|
rdone dec rcount
|
|
jeq bye
|
|
|
|
addwl drowsize,dstpix ; next destination row
|
|
lda sside
|
|
eor #1
|
|
sta sside
|
|
beq stayput ; if sside = 0, same src byte column
|
|
|
|
addwl #1,soffset ; else, use next one
|
|
stayput brl rloop
|
|
|
|
bye return
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* Q_RotLMap(srcpix:l,dstpix:l) -- rotate a pixelmap anticlockwise
|
|
*
|
|
* Source is scanned leftwards a column at a time, starting
|
|
* at the bottom of each column. Destination is scanned
|
|
* downward a row at a time, starting at the right end
|
|
* of each row.
|
|
*
|
|
****************************************************************
|
|
Q_RotLMap PROC EXPORT
|
|
;Using Q_PictData
|
|
|
|
input srcpix:l,dstpix:l
|
|
|
|
local srowsize:w,drowsize:w,spicsize:l
|
|
local soffset:w,doffset:w,rcount:w,srcrow:l
|
|
local pixel:w,slop:w,dside:w,sside:w
|
|
|
|
begin
|
|
|
|
lda Q_pixSCB
|
|
beq boundsok
|
|
|
|
dec Q_pixbounds ; adjust OLD width of bounds ONLY
|
|
lsr Q_pixbounds
|
|
inc Q_pixbounds ; <for use by Q_RotRMap and Q_RotLMap>
|
|
|
|
boundsok lda Q_pixbounds ; get source rowsize in bytes
|
|
dec a
|
|
lsr a ; (already adjusted for mode)
|
|
inc a
|
|
sta srowsize
|
|
|
|
lda Q_pixbounds+2 ; get destination rowsize in bytes
|
|
dec a
|
|
lsr a ; (already adjusted for mode)
|
|
inc a
|
|
sta drowsize
|
|
|
|
lda Q_pixbounds+2 ; is there an extra pixel on the edge
|
|
and #1 ; of the destination map?
|
|
sta slop
|
|
|
|
moveword Q_pixbounds,rcount
|
|
|
|
lda Q_pixbounds ; how about the source map?
|
|
and #1
|
|
sta sside
|
|
|
|
spacelong ; how big is the whole thing?
|
|
pushword srowsize
|
|
subword Q_pixbounds+2,#1,s
|
|
_Multiply
|
|
pulllong spicsize
|
|
|
|
moveword srowsize,soffset ; start at right of source map
|
|
dec soffset
|
|
|
|
rloop
|
|
jsl D_BeachBall
|
|
moveword drowsize,doffset ; initialize the offsets
|
|
addlong srcpix,spicsize,srcrow ; (start at bottom of source)
|
|
; subwl srowsize,srcrow
|
|
moveword slop,dside ; and other goodies
|
|
stz pixel
|
|
|
|
ploop moveword [srcrow]:soffset,a ; get the source byte
|
|
|
|
ldx sside ; which side is the pixel on?
|
|
bne shipixel
|
|
|
|
and #$f ; it's low.
|
|
ldx dside ; should it be?
|
|
beq gotpixel
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
bra gotpixel
|
|
|
|
shipixel and #$f0 ; it's high
|
|
ldx dside ; should it be?
|
|
bne gotpixel
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
|
|
gotpixel ora pixel
|
|
putpixel sta pixel
|
|
|
|
lda dside ; am I done with this byte?
|
|
beq nowrite
|
|
|
|
dec doffset ; move backwards through the dest. row
|
|
movebyte pixel,[dstpix]:doffset
|
|
lda doffset ; am I done with this row?
|
|
jeq rdone
|
|
|
|
stz dside
|
|
stz pixel
|
|
bra nextp
|
|
|
|
nowrite inc dside
|
|
|
|
nextp subwl srowsize,srcrow ; previous source row.
|
|
brl ploop
|
|
|
|
rdone dec rcount
|
|
jeq bye
|
|
|
|
addwl drowsize,dstpix ; next destination row
|
|
lda sside
|
|
eor #1
|
|
sta sside
|
|
bne stayput ; if sside = 1, same src byte column
|
|
|
|
dec soffset ; else, use previous one
|
|
stayput brl rloop
|
|
|
|
bye return
|
|
|
|
ENDP
|
|
END
|
|
|