View Full Version : Plotter / Dot Flag
pmc
02 February 2010, 20:10
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:
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
...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
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....
;*******
;**** 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
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+
;*** 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
;*** 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
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:
;*** 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:
; 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
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:
; 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.
;*** 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 :
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
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 :
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
little son was born yesterday! \o/
Congratulations pmc :) Hope your wife and son are fine.
Codetapper
24 October 2010, 22:06
PMC: Say goodbye to your free Amiga time from now on! My daughter is 4 weeks today and I've hardly had time to do anything the last month!
Lonewolf10
24 October 2010, 23:36
I will do Brett, as soon as we're finished at the hospital - just waiting to leave - our little son was born yesterday! \o/
Congratulations. :)
Regards,
Lonewolf10
StingRay
25 October 2010, 09:35
I will do Brett, as soon as we're finished at the hospital - just waiting to leave - our little son was born yesterday! \o/
Congratulations from me too! :)
Siggy999
25 October 2010, 10:18
Congrats!
I found I had very little free time all last year while my wife was pregnant (being lucky enough to work from home) and when the kids were born in May (twins - boy and girl) everything but work/sleep/kids/housework went out the window.
The good news was that after setting up the A2000 and monitor in the nursery (mainly so I could play dvds on the monitor for them) I've found that tooling around on it while they nap is not only really relaxing and gets my head back into my 'calm place', but I've made far more progress on projects than I have in the last 2 years (when I managed to finish getting the machine working).
All the best with your new arrival, they're a handful, but by far the most rewarding thing that's ever happened in my life.
TheDarkCoder
25 October 2010, 12:32
My warmest congratulations!
My daughter's birthday is the 23 of october. Is it the same day?
My daughter is now 3 years old. In these 3 years I was able to code almost nothing. Moreover, I was unable to find the time and the proper calm to mount a 68882 on my Blizzard 1230 and a Cybervision on my A4000 :blased
I also have many difficulties in updating software for my Amigas (still with old versions of many MUI classes) and in doing regular backups.
Gaming? I don't dare, I'll wait when she's a little olderso we can play together.
But despite all this, I am very happy as a father !!! :)
pmc
25 October 2010, 12:48
@ TCD & Lonewolf10 - thank you guys, much appreciated. :)
@ Codetapper - LOL - yeah, I think I might be taking a small break for a while but I won't stop coding when (if...!? :D) I ever do get the time. :) All the best to you and your little one. :)
@ StingRay - thanks man, I'll be telling the little guy all about his uncle StingRay as he grows up. :)
@ Siggy999 - thanks man - everyone I speak to says that it's the best experience ever and I'm already finding it quite overwhelming. But twins! Well, what can I say? You *really* have your work cut out! Congratulations to you and your wife. :)
@ TheDarkCoder - yes! 23rd October is my son's birthday too. All the best to you and your little one. :)
Thanks for all your kind words guys! :great
victim
25 October 2010, 14:02
I will do Brett, as soon as we're finished at the hospital - just waiting to leave - our little son was born yesterday! \o/
Hi PMC
and i Congratulations to you and wish them all the best !
so long..
victim
korruptor
25 October 2010, 14:51
Congrats PMC!
The 23rd is my Birthday as well. :great
Leffmann
26 October 2010, 20:07
Congratulations to you and Codetapper on becoming fathers :)
About the dot effects, in 15 years from now when you have time for coding again, you can look into using precomputed blocks of code.
The simplest method is generating code that plots fixed patterns which can be offset anywhere on the screen by adjusting the registers before you jump into the code.
Provide a coordinate value in D0/D1 and
calculate its offset into the bitplane
muls.w #40, d1
moveq #7, d2
and.b d0, d2
asr.w #3, d0
add.w d0, d1
D1 holds the offset and D2 is the X coordinate modulo 7 which
we need in order to pick the right OP-code and write the
complete instruction to memory
lsl.w #2, d2
move.w opcodes(pc, d2.w), (a0)+
move.w d1, (a0)+
... repeat for all dots in this pattern
Finish the code block by writing an absolute jmp instruction
that returns us to the end of our work loop
move.w #$4EF9, (a0)+
move.l #ReturnPoint, (a0)+
... go do next pattern
opcodes:
or.b D0, 1(A0)
or.b D1, 1(A1)
or.b D2, 1(A2)
or.b D3, 1(A3)
or.b D4, 1(A4)
or.b D5, 1(A5)
or.b D6, 1(A6)
or.b D7, 1(A7)
To f.ex draw a blanket of dots you would precompute f.ex a few hundred animated horizontal strings of 32 dots each, and then run 32 of these blocks of code and plot vertically down the screen.
To f.ex plot something at offset 0, 0 you would set up your registers like this:
D0 to D7: $80 $40 $20 $10 $08 $04 $02 $01
A0 to A7: 0 0 0 0 0 0 0 0
for offset 2, 3 with 40 bytes wide bitplanes you would do:
D0 to D7: $20 $10 $08 $04 $02 $01 $80 $40
A0 to A7: 120 120 120 120 120 120 121 121
etc.
Asman
26 October 2010, 23:20
Hi
Congrats for PMC and Codetapper.
I must agree with Codetapper, because ... my son have about 16 months and I can only find about 1h per week to launch amiga.
There is another easy trick with dots. You can use more bitplan then one to show more dots. Just set background color to black and rest of colors to white. And copy bitplane pointers from bpl0pth and bpl0ptl to bplxpth and bplxptl with some offsets.
Regards
Plagueis/KRX
27 October 2010, 21:33
Wow!!! Congrats to both of you dudez!
pmc
09 November 2010, 11:25
Hey fellas :)
Back at work now after my two weeks paternity leave I had some time to code again.
So, check out the attached .exe of a little intro I made for a glimpse of my new faster plot routine in action. I decided to avoid a standard dotflag and go for a formation that seemed a little more appropriate. :)
707 plots in one frame in this little intro, there's room for a few more but then it'd be right on the limit of fitting in a single frame so I think the routine can still do with being made quicker.
Enjoy. :)
no longer attached but optimised and fixed version of the Jacob plotter is available here: http://retro.untergrund.net/prods.html
Leffmann
09 November 2010, 19:38
Cool!
StingRay
09 November 2010, 19:51
Indeed, and cute! Really made me smile, nice one pmc! :)
Herpes
10 November 2010, 19:49
...
Enjoy. :)
Respect! :great
... also a very nice tune :D
pmc
13 January 2011, 12:59
For a new thing I'm working on I want to make a dot ball to make use of my faster plotter. I want it to be as nice as the one in Phenomena's Enigma demo. That one is supposedly 800 points. Now rotating, plotting and hiding the hidden points is not possible in one frame without some serious cheating with shortcuts.
So, now I'm thinking about how to get it done. I've got an idea for reducing the number of points any calculations need to be done on and wondered what you guy's thoughts were...?
My basic idea is this:
Can't I generate the point locations for a whole 800 point dot ball by rotating only 100 points and then negating x and y values to get the locations of the rest...?
Check the pics of a dotball viewed face on. Stage one would be to negate only the x values of the first 100 points to get the second 100 points. Stage two would be to negate the y values of these 200 points to get the second 200 points giving me the visible points of the dotball.
What do you guys think - is this or something similar feasible...?
pmc
17 January 2011, 11:56
Done a bit more playing around.
I've worked out a set of 3d points now for an 800 point, radius 60 pixels, dotball.
As per something Leffmann said in another thread, when these are translated to 2d points and plotted they look OK as they are ie. no need for perspective transform. This will save time as only adds and subs are needed to convert 3d to 2d - no divides required.
So, now I need to work out some shortcuts with the rotations and get some kind of mirroring working and I should get a nice dotball going. :)
korruptor
17 January 2011, 12:46
Not sure what you're thinking, but mirroring the top left to the top right would mean the dots converge at the middle, wouldn't it?
Lonewolf10
17 January 2011, 19:17
Not sure what you're thinking, but mirroring the top left to the top right would mean the dots converge at the middle, wouldn't it?
I have not experience in this (yet), but I suspect you are correct. The way I would do it is to calculate the top half dots and then mirror that to create the bottom half (using a negative modulo with the bitplanes).
Regards,
Lonewolf10
pmc
17 January 2011, 22:33
Not sure what you're thinking, but mirroring the top left to the top right would mean the dots converge at the middle, wouldn't it?
I did some testing with this today - worked just fine as per my mirroring post. :)
The way I would do it is to calculate the top half dots and then mirror that to create the bottom half (using a negative modulo with the bitplanes).
This might work for a static image (negative modulos to repeat rows of the displayed bitplane - a bit like copper "reflections") but I'm not sure how well this would work in this context. I need to be able to 3d rotate as few points as possible and mirror the rest to make it look like lots more points are rotated.
Using my method I should be able to rotate and bounce an 800 point dotball but only actually be rotating 100 points to do so. Even this may still need some short cutting to achieve in one frame when the other parts of the routine are added in...
I won't know for sure what all the short cuts needed are until I discover them and iron them out.
I'm working on it - reckon I'll have this one all done in the next few days. :)
korruptor
17 January 2011, 23:34
I can see the vertical working. Still don't get how you're doing the other way. I'm being slow.
Where's 0,0? The middle of the ball?
pmc
18 January 2011, 06:36
No you're not mate - *I* am.
Rotation sends my lame idea all to shit as you rightly say.
Back to the drawing board... :)
korruptor
18 January 2011, 09:59
If you're rotating on all axis, I think flipping the top to the bottom will be knackered as well. But, drop an axis and it'd prolly work.
Wouldn't look as cool though :(
Edit: just noticed the time of your post. Late night hacking? :D
pmc
18 January 2011, 10:03
Indeed. A rotating ball won't look good if it's not rotating properly. :D
I've already got an idea for how to solve the problem. The dotball shall live! \o/
just noticed the time of your post. Late night hacking?
Sadly no - I was about ready to leave for work. You might say I'm an early bird. :D
korruptor
18 January 2011, 10:51
This is early for me ;)
Lonewolf10
19 January 2011, 19:02
This might work for a static image (negative modulos to repeat rows of the displayed bitplane - a bit like copper "reflections") but I'm not sure how well this would work in this context. I need to be able to 3d rotate as few points as possible and mirror the rest to make it look like lots more points are rotated.
Sorry, I was a bit brief with the modulo comment. Yes, AFAIK, the only way to do partial mirroring of a screen is by altering BPL1MOD and BPL2MOD using the copper.
It depends on the angle you are looking at your rotating ball and whether you are only displaying the front plots only or all plots (front and back). If it were level with our view of it (e.g. not looking down, or up, on it) and only displaying the front plots then I believe the modulo trick would work - the middle plots would be on the mirroring line. If you are looking down, or up, on it then you can only mirror the left-side with the right-side (or vice versa).
Regards,
Lonewolf10
vBulletin® v3.7.0, Copyright ©2000-2013, Jelsoft Enterprises Ltd.