English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Tutorials (https://eab.abime.net/forumdisplay.php?f=73)
-   -   Plotter / Dot Flag (https://eab.abime.net/showthread.php?t=50595)

pmc 02 February 2010 20:10

Plotter / Dot Flag
 
Watcha boys :)

I'm bored at the moment waiting for other guys to (hopefully sometime soon...) deliver music and code for the megademo so I've been doing other little small bits of code while I wait. :D

In case anyone can make use of it I made a little plotter routine today and then added a couple of sine waves to turn it into a dot flag.

I can't say it's the fastest or best way to do a dot flag but it works and, well, like I said - I was bored... ;)

StingRay 02 February 2010 20:48

Nice one, had a (very) quick look, my version of your innerloop looks like:

Code:

        move.w        d0,d1
        lsr.w        #3,d0
        not.b        d1
        bset        d1,(a1,d0.w)


        ;move.w        d0,d1
        ;andi.w        #%0000000111110000,d0
        ;lsr.w        #3,d0
        ;add.w        d0,a1
        ;andi.w        #%0000000000001111,d1
        ;subi.w        #15,d1
        ;neg.w        d1
        ;move.w        (a1),d2
        ;bset.l        d1,d2
        ;or.w        d2,(a1)

Think about it. =)

pmc 02 February 2010 20:59

Nice one Sting :)

Yeah, like I just said to WayneK on PM - I literally *threw* this code together in a few minutes this afternoon so I'm 100% sure it can be made much much better. :D

I'll tweak it into something nicer code wise at some point. :great

pmc 03 February 2010 11:05

Quote:

Originally Posted by StingRay
...my version of your innerloop looks like...


...Think about it....

I looked at this a bit more closely, and concluded: :bowdown

pmc 03 February 2010 13:22

Check the new version attached.

A couple of very small optimisations have been made but the main optimisation is Sting's much (much!) better plot code - now credited in the source to him.

Accordingly, the flag now has an additional 60 dots per frame.

All hail StingRay! :)

victim 16 February 2010 17:43

Quote:

Originally Posted by pmc (Post 639382)
Check the new version attached.

A couple of very small optimisations have been made but the main optimisation is Sting's much (much!) better plot code - now credited in the source to him.

Accordingly, the flag now has an additional 60 dots per frame.

All hail StingRay! :)

Hi pmc !

I did a little experimenting and I think the routines produce good results.
I have the X and Y position and the individual bits precomputed.

try it....

Code:

;*******       
;****        Date: 16.02.2010        Prog: Dot calculation
;****       
;****        Done by Victim of Savage (Sascha Mueller)
;*******
         
;example call
                bsr    InitYCalc
                bsr    InitXCalc
                bsr    InitBit

                move #320/2,d0
                move #256/2,d1
                bsr    TurboDot
                rts
     
;*** d0.l=xpos , d1.l=ypos 

TurboDot:
            move.l    PlaneBufferWork(pc),a0
            lea        MulTabX(pc),a1
            lea        bittab(pc),a2
            add        d0,d0
            add        d1,d1
            add        MulTabY(pc,d1.w),a0 ;y-cr*screenwidth
            add        (a1,d0.w),a0
            move      (a2,d0.w),d1
            bset      d1,(a0)
            rts

InitYCalc:    lea        MulTabY(pc),a0
                move      #255,d1
                moveq    #0,d0
loop:          move      d0,(a0)+
                add        #40,d0
                dbf        d1,loop
                rts
           
MulTabY:    blk.w    256,0

InitXCalc:
            lea        MulTabX(pc),a0
            moveq    #0,d0
            move    #319,d2
loop2:    move    d0,d1
            asr        #3,d1
            move    d1,(a0)+
            addq    #1,d0
            dbf        d2,loop2
            rts       

MulTabX:    blk.w    320,0

InitBit:    lea        BitTab(pc),a0
            moveq    #0,d0
            move    #320-1,d7
Bit:        move    d0,d1
            and        #7,d1        ;Which Bit
            move    #7,d2        ;substract from $7
            sub        d1,d2        ;want pixel nul is bit 7
            move    d2,(a0)+
            addq    #1,d0
            dbf        d7,bit
            rts

BitTab:        blk.w    320,0

another version, here is only the Y position of precomputed

Code:

CalcDot:        move.l        PlaneBufferWork(pc),a0
                lea                MulTabY(pc),a1
                move                d0,d2
                asr                #3,d0
                add                d1,d1
                add                (a1,d1),d0
                not                d2
                bset                d2,(a0,d0)
                rts

InitYCalc:
            lea        MulTabY(pc),a0
            move      #255,d1
            moveq    #0,d0
loop:    move      d0,(a0)+
            add        #40,d0
            dbf        d1,loop
            rts
           
MulTabY:    blk.w    256,0

and here is a special routine for the 68020+

Code:


;*** for 68020+
;*** d0.l=xpos , d1.l=ypos

CalcDot:    move.l    PlaneBufferWork(pc),a0
            move    MulTabY(pc,d1.w*2),d1
            bfset    (a0,d1.w){d0:1}
            rts

InitYCalc:
            lea        MulTabY(pc),a0
            move      #255,d1
            moveq    #0,d0
loop:    move      d0,(a0)+
            add        #40,d0
            dbf        d1,loop
            rts
           
MulTabY:    blk.w    256,0

and the same version with a little clipping routine


Code:


;*** for 68020+
;*** d0.l=xpos , d1.l=ypos + Punkte Clipping

CalcDot:
            move.l    PlaneBufferWork(pc),a0
ClipXmax:
            cmp    #319,d0            ; is xd0 < or = xmax 319
            ble.s    ClipXmin    ; YES
            bra.s    PointEnd    ; NO   
       
ClipXmin:
            tst        d0                ; is xd0 > or = xmin 0
            bge.s    ClipYmax
            bra.s    PointEnd

ClipYmax:   
            cmp    #255,d1            ; is yd1 < or = ymax 255
            ble.s    ClipYmin
            bra.s    PointEnd

ClipYmin:
            tst    d1                ; IS yd1 > or = ymin 0
            bge.s    ClipSetPoint
            bra.s    PointEnd
       
ClipSetPoint:   
            move    MulTabY(pc,d1.w*2),d1
            bfset    (a0,d1.w){d0:1}
PointEnd:
            rts


InitYCalc:
            lea        MulTabY(pc),a0
            move    #255,d1
            moveq    #0,d0
loop:    move    d0,(a0)+
            add        #40,d0
            dbf        d1,loop
            rts
           
MulTabY:    blk.w    256,0

I hope they use it to

so long....
victim

StingRay 16 February 2010 18:36

Quote:

Originally Posted by victim (Post 643151)
I did a little experimenting and I think the routines produce good results.

I see you edited your post and removed the "my routines here are the fastest" bit... Good move because this:

Quote:

Originally Posted by victim (Post 643151)
Code:


;*** for 68020+
;*** d0.l=xpos , d1.l=ypos + Punkte Clipping

CalcDot:
            move.l    PlaneBufferWork(pc),a0
            lea        MulTabY(pc),a1

ClipXmax:
            cmp    #319,d0            ; is xd0 < or = xmax 319
            ble.s    ClipXmin    ; YES
            bra.s    PointEnd    ; NO   
       
ClipXmin:
            tst        d0                ; is xd0 > or = xmin 0
            bge.s    ClipYmax
            bra.s    PointEnd

ClipYmax:   
            cmp    #255,d1            ; is yd1 < or = ymax 255
            ble.s    ClipYmin
            bra.s    PointEnd

ClipYmin:
            tst    d1                ; IS yd1 > or = ymin 0
            bge.s    ClipSetPoint
            bra.s    PointEnd
       
ClipSetPoint:   
            move    (a1,d1.w*2),d1
            bfset    (a0,d1.w){d0:1}
PointEnd:
            rts


is anything but fast. Here's my version:
Code:


; d0.w: x
; d1.w: y
clip    cmp.w    #255,d1
    bhi.b    .clip

    ; calc y-pos
    ; ...
    nop
   
    cmp.w    #319,d0
    bhi.b    .clip

    ; point is inside clipping boundary, draw
    ; ...
    nop

.clip    rts


korruptor 16 February 2010 20:22

Why are the nop's in there, out of interest?

StingRay 16 February 2010 20:34

Because I didn't feel like posting trivial "calc y-offset/draw a dot" code. The nops are just placeholders.

korruptor 16 February 2010 22:10

Hahaha, fair enough, for some reason I thought there was going to be a hidden piece of cunning :D

victim 16 February 2010 23:09

Quote:

Originally Posted by StingRay (Post 643166)
I see you edited your post and removed the "my routines here are the fastest" bit... Good move because this:



is anything but fast. Here's my version:
Code:


; d0.w: x
; d1.w: y
clip    cmp.w    #255,d1
    bhi.b    .clip

    ; calc y-pos
    ; ...
    nop
   
    cmp.w    #319,d0
    bhi.b    .clip

    ; point is inside clipping boundary, draw
    ; ...
    nop

.clip    rts



Good man StingRay, :great because you've got me almost. But one must be careful what one writes. Above all, if you want to write that it should be on one of the fastest routine, it becomes dangerous.
There are simply too many tricks.
For this reason, I have changed my post a precaution :cheese

I think this routine produced very good results.

Code:

;*** for 68020+
;*** d0.l=xpos , d1.l=ypos

CalcDot:    move.l    PlaneBufferWork(pc),a0
              move    MulTabY(pc,d1.w*2),d1
              bfset    (a0,d1.w){d0:1}
              rts

InitYCalc:
            lea        MulTabY(pc),a0
            move      #255,d1
            moveq    #0,d0
loop:    move      d0,(a0)+
            add        #40,d0
            dbf        d1,loop
            rts
           
MulTabY:    blk.w    256,0

so long...
victim

Leffmann 16 February 2010 23:22

Just use 64 bytes wide bitplanes (or 32 even if you don't need a wide screen) and do a shift instead, it's simple and fast.

hitchhikr 16 February 2010 23:53

Yes, using a single shift whenever possible will always be faster than with a pre-calculated table, if you can't use that for whatever reason then make sure the table is located at less than 128 bytes from the accessing instruction and use something like :

Code:

            move.w  MulTabY(pc,d1.w*2),d1
sparing you a register.

Notice that it will probably be faster to use a series of shifts on 68020+ processors and faster to use precalc tables on plain 68000.

victim 17 February 2010 00:25

Quote:

Originally Posted by hitchhikr (Post 643251)
Yes, using a single shift whenever possible will always be faster than with a pre-calculated table, if you can't use that for whatever reason then make sure the table is located at less than 128 bytes from the accessing instruction and use something like :

Code:

            move.w  MulTabY(pc,d1.w*2),d1
sparing you a register.

Notice that it will probably be faster to use a series of shifts on 68020+ processors and faster to use precalc tables on plain 68000.


Correct, small but nice. :greatI have changed the top

so long...
victim

pmc 21 October 2010 21:40

Watcha chaps :)

It's a long time since I messed around with any plotting but today I made a new plotter and I've been testing it out.

I'm going for all out speed with this one so I've used shifts and tables and gotten the main plotting loop down to 8 instructions.

Doing a rough speed test by just plotting a pixel to the screen over and over I can do 1134 iterations of the plotting loop in one frame.

Now, this is a vast improvement over the circa maximum 300 or so plots per frame that my very first plotting routine could do but obviously the total won't really be as high as that once I add in required things like clearing the screen, double buffering and some kind of nice method of deciding where to plot the pixels so they make pretty patterns. :D

So, two questions:

1. Are there any other tricks or cheats (other than using lookup tables) to get even more plots per frame...?

2. If not, how are there oldskool demos out there where the coder claims things like 3000 or 10,000 (:shocked) or whatever plots per frame...?

WayneK 22 October 2010 10:53

I guess they're cheating in various ways like taking advantage of symetry/mirroring, only doing one of X/Y calcs per frame (X even, Y odd VBLs), or triple-buffering and using a previous frames 'dots' as a trail/'blur' etc... (since it's already been calced/plotted) - there must be other cheats but it's early and I haven't had coffee yet :)

pmc 22 October 2010 12:58

Nice one WayneK :great

I'll add these to my ever growing "things to do coding experiments with" list. :)

Plagueis/KRX 24 October 2010 03:05

Wow, so this is where the cool stuff is going on, on EAB....I don't know how I've been missing it all. Hey Paul! Could you send me an exe of that dot plotter flag to my email address? Thanks.

pmc 24 October 2010 19:29

I will do Brett, as soon as we're finished at the hospital - just waiting to leave - our little son was born yesterday! \o/

TCD 24 October 2010 19:37

Quote:

Originally Posted by pmc (Post 710482)
little son was born yesterday! \o/

Congratulations pmc :) Hope your wife and son are fine.


All times are GMT +2. The time now is 14:47.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.04999 seconds with 11 queries