Author Topic: Rectangle Drawing Routines  (Read 7808 times)

0 Members and 1 Guest are viewing this topic.

ZippyDee

• LV8 Addict (Next: 1000)
• Posts: 729
• Rating: +83/-8
• Why not zoidberg?
Rectangle Drawing Routines
« on: July 02, 2011, 12:51:48 am »
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.

While writing those routines, I came up with this set of rectangle drawing routines that I think are pretty good, though they probably could be optimized quite a bit.

Anyway, I thought I'd share them:

Code: [Select]
;;---------------------;; 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, 1st byte of OP2 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, 1st byte of OP2 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, 1st byte of OP2 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 [and possibly first byte of OP2] 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 [and possibly 1st byte of OP2] contains mask data for the line ;;DESTROYS: All except HL ld a, e cp 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: sla 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 ld c, a_lastbyte: ld a, e cpl and 7 ld b, a ld a,$FF jr z, _skipmask2_maskloop2: add a, a djnz _maskloop2_skipmask2: and c ld (hl), a pop hl pop bc inc c ret
Honestly I'm not sure that these routines are even the best way to do it, but I feel they're pretty good. If anyone has better routines that I could swap these for, then I'd love to see them!

EDIT: Thanks to Calc84maniac, the bugs have been fixed and it now works properly!
« Last Edit: July 03, 2011, 01:18:15 am by ZippyDee »
There's something about Tuesday...

Pushpins 'n' stuff...

Jerros

• LV4 Regular (Next: 200)
• Posts: 137
• Rating: +9/-0
Re: Rectangle Drawing Routines
« Reply #1 on: July 02, 2011, 08:35:01 am »
Looks nifty, might make use of it!

79% of all statistics are made up randomly.

ZippyDee

• LV8 Addict (Next: 1000)
• Posts: 729
• Rating: +83/-8
• Why not zoidberg?
Re: Rectangle Drawing Routines
« Reply #2 on: July 02, 2011, 08:57:46 am »
Thanks! Again, I'm not going to say that this is the most efficient method by any means. It's just what I happened to come up with. There's probably some genius out there who could write one much better than this *cough*Runer/ThePenguin/Brandon/calc84*cough*
« Last Edit: July 02, 2011, 08:58:09 am by ZippyDee »
There's something about Tuesday...

Pushpins 'n' stuff...

Quigibo

• The Executioner
• CoT Emeritus
• LV11 Super Veteran (Next: 3000)
• Posts: 2031
• Rating: +1075/-24
• I wish real life had a "Save" and "Load" button...
Re: Rectangle Drawing Routines
« Reply #3 on: July 02, 2011, 10:27:49 pm »
Well, there's always the Axe rectangle routine (see p_Box in commands.inc from developers folder).  I'm not sure if it's more efficient than yours or not because it depends on what size/speed tradeoff you want and I haven't measured the size and speed of your routine.
« Last Edit: July 02, 2011, 10:28:17 pm by Quigibo »
___Axe_Parser___
Today the calculator, tomorrow the world!

ZippyDee

• LV8 Addict (Next: 1000)
• Posts: 729
• Rating: +83/-8
• Why not zoidberg?
Re: Rectangle Drawing Routines
« Reply #4 on: July 02, 2011, 11:18:02 pm »
Unfortunately it seems there are a few errors somewhere in my routine...I could have sworn it was working just fine before. If I can get them figured out I'll post that fixed version. THEN maybe it would be worthwhile to see the size/speed of this routine.

EDIT: Fixed, all thanks to Calc84. Now you can check for speed and size if you want...I don't know how to go about doing that, otherwise I would do it myself (I'm curious to know, too!)
« Last Edit: July 03, 2011, 01:19:06 am by ZippyDee »
There's something about Tuesday...

Pushpins 'n' stuff...