I have a program that uses two buffers and it toggles which buffer it's writing to using a flag. Because it uses that flag I figured it would be a good idea to utilize that for drawing routines so they can draw to whichever buffer it's currently set to instead of having to have separate routines for each buffer.
I thought the routines were working, but now I see that they're not... Here's what I have. I think the concept was good, maybe I just screwed up somewhere?
Code:
If I'm wrong and just having two separate RectInv and RectOff routines (and just calling RectOff then RectInv to do RectOn) would really be best, then where can I find routines to do those efficiently?
EDIT: Got it working thanks to Calc84maniac. Should I post my working source code? Would anyone be interested?
I thought the routines were working, but now I see that they're not... Here's what I have. I think the concept was good, maybe I just screwed up somewhere?
Code:
;;---------------------
;; Rect Off/On/Inv
;;---------------------
RectOff:
;;Clears a rectangle on the buffer
;;IN:
;; D contains x
;; E contains width
;; H contains y
;; L contains height
;;DESTROYS: All, OP1
call GetRectLine
ld a, 12
sub c
ld e, a
ld d, 0
_rOffLoop1:
push de
ld de, OP1
push bc
ld b, c
_rOffLoop2:
ld a, (de)
cpl
and (hl)
ld (hl), a
inc hl
inc de
djnz _rOffLoop2
pop bc
pop de
add hl, de
djnz _rOffLoop1
ret
RectOn:
;;Draws a rectangle on the buffer
;;IN:
;; D contains x
;; E contains width
;; H contains y
;; L contains height
;;DESTROYS: All, OP1
call GetRectLine
ld a, 12
sub c
ld e, a
ld d, 0
_rOnLoop1:
push de
ld de, OP1
push bc
ld b, c
_rOnLoop2:
ld a, (de)
or (hl)
ld (hl), a
inc hl
inc de
djnz _rOnLoop2
pop bc
pop de
add hl, de
djnz _rOnLoop1
ret
RectInv:
;;Inverts a rectangle on the buffer
;;IN:
;; D contains x
;; E contains width
;; H contains y
;; L contains height
;;DESTROYS: All, OP1
call GetRectLine
ld a, 12
sub c
ld e, a
ld d, 0
_rInvLoop1:
push de
ld de, OP1
push bc
ld b, c
_rInvLoop2:
ld a, (de)
xor (hl)
ld (hl), a
inc hl
inc de
djnz _rInvLoop2
pop bc
pop de
add hl, de
djnz _rInvLoop1
ret
GetRectLine:
;;IN:
;; D contains x
;; E contains width
;; H contains y
;; L contains height
;;OUT:
;; HL points to first byte of rectangle in buffer
;; B contains rows
;; C contains columns
;; OP1 contains mask data for the line
xor a
or l
ret z ;return if height is zero
ld a, d
add a, e
cp d
ret z ;return if the width is zero
cp 96
jr c, _grl_widthOK ;if width is > 90
ld a, 96
_grl_widthOK:
dec a
ld e, a
call RectLineToOP1
;c contains width in bytes
;b contains first column
ld a, h
add a, l
add a, -64
jr nc, _grl_heightOK
neg
add a, l
ld l, a
_grl_heightOK:
ld a, l ;store height in a
ld l, h
ld h, 0
ld d, h
ld e, l
add hl, hl
add hl, de
add hl, hl
add hl, hl
ld e, b
add hl, de
; This next line gets the current buffer address into DE.
; Obviously zBufMode is the buffer flag in zModeFlags, and backBuffer holds the address of my backBuffer.
; Note that it uses $+# format because I use it normally in a #define. I've just written it out here for you to see.
bit zBufMode, (iy+zModeFlags) \ jr z, $+7 \ ld de, plotSScreen \ jr $+5 \ ld de, backBuffer
add hl, de ;hl points to first byte of rect in buffer
ld b, a ;b contains height, c contains width
ret
RectLineToOP1:
;;IN:
;; D contains starting x
;; E contains ending x
;;OUT:
;; C contains length of line
;; B contains starting x byte
;; OP1 contains mask data for the line
;;DESTROYS: All except HL
ld a, e
sub d
ld b, 0
ret z
srl a
srl a
srl a
ld c, d
srl c
srl c
srl c
ld b, c
sub c ;a contains num bytes spanned minus 1
ld c, a
push bc
push hl
ld hl, OP1
;get mask
ld a, d
and 7
ld b, a
ld a, $FF
jr z, _skipmask
_maskloop:
sra a
djnz _maskloop
_skipmask:
ld b, c
ld c, a
xor a
or b
jr z, _lastbyte
ld a, c
_hloop:
ld (hl), a
inc hl
ld a, $FF
djnz _hloop
_lastbyte:
ld a, e
inc a
and 7
ld b, a
ld a, $FF
jr z, _skipmask2
_maskloop2:
sra a
djnz _maskloop2
_skipmask2:
cpl
and c
ld (hl), a
pop hl
pop bc
inc c
ret
If I'm wrong and just having two separate RectInv and RectOff routines (and just calling RectOff then RectInv to do RectOn) would really be best, then where can I find routines to do those efficiently?
EDIT: Got it working thanks to Calc84maniac. Should I post my working source code? Would anyone be interested?