A.D.A. Amiga Demoscene Archive

        Welcome guest!

  

  

  

log in with SceneID

  

Demos Amiga Demoscene Archive Forum / Coding / coding tutorial: the blitter
 Page:  1  2  »» 
Author Message
z5_
Member
#1 - Posted: 29 Nov 2004 11:34
Reply Quote
Everything about the blitter should go in here.

I'm going to kick off with one question. I converted a font (size 8) with font2raw to .raw format (word format) and included it in my source with incbin (let's say label fontinfo).

I want to blit one character (the first letter A) to my screen (320 pixels wide). As i have saved the font info in word data, i have set my blitter values as follows:
- straight copy from A -> D
- width: 1 (=> 1 word)
- height: 8 (=> 8 lines)
- modulo for my source A: 0
- modulo for my destination D: #38 (because my screen is 40 bytes and i'm only copying 2 bytes)
- source: fontinfo (the label where the font starts in memory)
- destination: screen

somehow, i don't get anything on screen. When i increase my width to 2 words instead, i get font info on screen, but not the correct one. What am i doing wrong.

Also, can i save out my font info as byte and how does one solve the fact, in that case, my font is only 1 byte wide and one can't copy anything less than 2 bytes (minimum blit size)?
Cyf
Member
#2 - Posted: 29 Nov 2004 12:17 - Edited
Reply Quote
you dont start with a simple font 16 !!
8x font is a bit more difficult to display with blitter because of 16 pix limit

have you made 8x font with "8x + space 8x"
the width of copy is 1 word = 16 pix.

... more explanation if I have time... perhaps someone else...
z5_
Member
#3 - Posted: 29 Nov 2004 12:32
Reply Quote
@cyf:

font2raw has the ability to save a font in byte/word/longword format.
So if i save it out in word format, i get 16 pixels/letter (well, 8 pixels and the rest is filled with 0), so i thought my blitter values were correct...? Ofcourse, i will get some empty space on the right side of my letter, but it is just an exercise.

So why doesn't it work? (i don't see nothing on screen and i do if i copy 2 words instead of 1).
Cyf
Member
#4 - Posted: 29 Nov 2004 13:46 - Edited
Reply Quote
for a 8x8 font, it's possible to use a simple 68000 copy routine, not blitter (more simple :) )

hmmm... source modulo = width of font pic - 2


with blitter, for a 8 pix precision, it's possible to display a bob at <16 pix position by using source shift and masks.
and for non-plain bob (font or other shapes <> square), use a mask that define the zone to blit (for a 1 bitplan font, the mask=the font)
the next letter is put at 8 pix. after = x position + 8 (or other if proportional font)

with 3 sources (A=mask, B=font, C=screen) and dest + minterm for copy with cut-out ($ca) + shift, and source A mask =$ffff0000

or with 2 sources (A=font, B=screen) + dest and minterm=$df (in anthrox intro using proportional font)

but exist other technics for 8x8 font with blitter

ex. anthrox:
bltAfwm=$ffff000
bltAmod=40-4
bltBmod=40-4
bltDmod=40-4
bltcon1=0
TabChar=font,font+2,font+4...
TabWidth=8 if fix (or tab with differents width)
a2=font (from TabChar)
a3=screen

d7=pos X
d1=d7
lsr.w #4,d1
add.w d1,d1
a4=a3+d1 ; dest

d1=d7
andi.w #$f,d1 ; multiple 16
ror.w #4,d1
ori.w #$dfc,d1 ; bltcon0

bltcon0=d1, A=a2, B=a4, D=a4 and bltsize=h*64+2

; next
d7=d7+(Width letter-1) (7 or from TabWidth)
--------------------
and other routine with 1 source + dest for a scrolltext:

mask A: $ffffffff
modulo A: width-2
modulo B: width-2
bltcon0: 09f0 (source A + dest + minterm = A+D)
source A: font
dest D : screen
bltsize: Height * 64 + 1
Cyf
Member
#5 - Posted: 29 Nov 2004 14:39 - Edited
Reply Quote
explanation about shift :

ex.:
real position X=100
multiple 16 : 100=96+4 = 6 words + 4 pix.

dest=screen+6 and shift the source of 4 pix to right with bltcon1

the shift is a rotation, so the bob is altered.
|ABCDEFGHIJKLM| -> |JKLMABCDEFGHI|

add 16 pix (2 bytes) to the source and mask these pixels right and left with $ffff000 mask

|ABCDEFGHIJKLM........| -> |....ABCDEFGHIJKLM....|
(....=hidden)
z5_
Member
#6 - Posted: 30 Nov 2004 12:50
Reply Quote
I'm trying to do a scrolltext based on code from an old triumph intro (which is on Aminet). I'm nearly there... i have my font loaded, i have my entire text displayed on screen, but still in the same place (the scroller actually doesn't scroll yet... which is kind of ridiculous for a scroller :) ). So each letter of the scrolltext appears on top of the other.

Here's the method i'm using (please say if there is an easier way to do horizontal scrolls or if i'm talking bullshit or am using flawed logic...):

- screen is 320*256 (=> 40 bytes per line)
- my font is 8 lines high and 1 word wide (proportional font)
- i use scrollbuffer, which is 8 lines high, 44 bytes wide
- i fill in the new character from my scrolltext at the end of my scrollbuffer (at byte 40, because my screen is 40 bytes). So my new letter appears at the right, but just outside the visible window area. This is the first blitter operation.
- i copy the entire scrollbuffer to my screen, but 8 lines and only 40 bytes (i don't want the new char to appear on my screen). This is the second blitter operation.
- i move the scrollbuffer content with 7 bits shift left side (descending mode). The 3rd blitter operation.

Is that a good method to do horizontal scroll?
Cyf
Member
#7 - Posted: 30 Nov 2004 13:36 - Edited
Reply Quote
you can use screen as scrollbuffer and only the 3rd blit op.

routines DisplayChar (after get new char and font offset) and Scroll

DoChar:
...get font offset of the new char

DisplayChar:
mask A : $ffffffff
modulo source A: 40-2=38 (font 320)
modulo dest 44-2=42
bltcon0 source A+dest D, Minterm=A+D= $09f0
bltcon1 =0
source A = font
dest = screen+(heightscreen*44)+42
bltsize=heightchar*64+1

Scroll:
bltcon0 = source shift value, A+D, minterm=A+D = $09f0+shift
(note about shift: in ascending mode, blitter shift to the right. for a left shift, for example 4 pix / max 16, then shift to the right of 16-4=12 pix, and start dest 16 pix. to the left (-2 bytes) )
modulo source and dest = 0

source and dest : end screen to end screen - width char
source A = screen+heightscreen*44
dest D = screen+heightscreen*44-2

bltsize= heightscroll*64+44/2 (width in word)
z5_
Member
#8 - Posted: 30 Nov 2004 19:07 - Edited by Admin
Reply Quote
Another question in between: trying to do a simple wipe effect => make the picture appear line by line on the screen, starting from the top. Screen is 320*256 (40 bytes width). My picture is stored at ravepic and i have reserved a screen buffer (screen) 4*320*256. I'm just trying to copy the content of the picture to the screen, line by line.

wipepic:
;i've got 256 lines, and each line is 40 bytes => 10240 will be the end of the effect
cmp.w #10240,piclineswipe
bne notfinished
rts
notfinished:
;the source (A in the blitter) of my picture
lea ravepic,a1
;i'm adding line where i have arrived
add.l piclineswipe,a1
;my destination (D in the blitter)
lea screen,a2
;i'm adding line where i have arrived
add.l piclineswipe,a2
;4 bitplanes => need 4 loops
moveq #3,d0
.waitblit:
btst #6,$dff002
bne .waitblit
;standard copy from source A to destination D, no shift
move.w #$09f0,$dff040
clr.w $dff042
;first word mask all 1 => copy everything from the first word
move.w #-1,$dff044
;source A address
move.l a1,$dff050
;destination D address
move.l a2,$dff054
;no modulos needed because source and destination have same dimensions
clr.w $dff064
clr.w $dff066
;1 line high, 20 words wide (screen is 40 bytes wide)
move.w #%0000000001010100,$dff058
;need to fetch the line from my next bitplane
add.l #10240,a1
;and copy it into the next bitplane
add.l #10240,a2
dbra d0,.waitblit

;moving on to the next line
add.l #40,piclineswipe
rts

Not so surprisingly, it doesn't work :) ... I only seem to copy one bitplane here. Where's my fault? I've got the feeling that this is going to be an easy one...
Cyf
Member
#9 - Posted: 30 Nov 2004 19:43 - Edited
Reply Quote
4 bitplanes => need 4 loops
try to use rawblitter format, you can copy all bitplanes with blitter in one pass . then bltsize=h*depth*64+w/2

(why bltsize in binary ?)

bitplane with rawblitter Interleaved format :
line1 -> bitplan 1
line1 -> bitplan 2
...
line2 -> bitplan 1
line2 -> bitplan 2
...

next line = width*depth
and bitplane modulo =width*(depth-1)

I remember I had done a similare routine to copy line by line source pic in dest pic for my slide (22 zones of 16 lines) :

main screen width = 640 (80)
pic source width = 480 (60)

here is the blit loop. compare:
moveq #21,d0
lea dest,a1
adda.l #80*16*4+2,a1 ; start position
lea source,a0
add.l currentposdest,a1
add.l currentpossource,a0 ; idem

loop:
source A = a0
dest D = a1
modulo A = 0
modulo D = 80-60
mask=$ffffffff
bltcon0=$09f0 ; idem
bltsize=1*64*4+60/2 ; blitter format

; next zone
adda.l #80*4*16,a1
adda.l #60*4*16,a0
dbf d0,loop

; next line
add.l #80*4,currentposdest
add.l #60*4,currentpossource
rts

---------
after this simple effect, next part is to use a "pattern" to copy block by block with "animated" block, and random block :)
z5_
Member
#10 - Posted: 30 Nov 2004 19:59 - Edited by Admin
Reply Quote
@Cyf:
Can you say what is actually wrong with my routine? I know it's going to be easier using another rawformat, but i can't really see what is wrong with mine. Please take into consideration that i started learning assembler about one week and a half ago, so it's all going a bit too fast for me :) I'm looping 4 times, and with each loop i increment by one bitplane. Once the four bitplanes are done, i move to the next line and do the same. But the result is that only one bitplane is copied...

Also, i do have some questions about your routine above to make a scrolltext. Can you actually explain a bit what it does? And with what screensize are you working (44 bytes)? And does this work if you've got several bitplanes? Am i right in saying that you copy the font just after the last bitplane (so not visible on the screen). Then you actually shift the complete last line of the last bitplane to the left???? And does this mean that my font will actually appear in the last bitplane (important for the color use...). Nah, i don't think i get it...

It's all a bit much without explanation :)
Cyf
Member
#11 - Posted: 30 Nov 2004 20:33 - Edited
Reply Quote
Can you say what is actually wrong with my routine?

the routine seems to be the same. only one thing different : the format.

But the result is that only one bitplane is copied...

it's old "souvenir", but:
the interleaved blitter format limit number of blitter accesses.
for 4 bitplanes, you need 4 accesses with normal format. With blitter format only One!

err... somebody can help me with explanations please ^^ :p !
-----------
scrolltext:
screensize=44
work with several bitplanes (raw blitter format)

why "last blitplane" ? in this example, only one bitplane used.
so the font is copied at the end of the bitplane - 16 pix. (2 bytes), the size of char (visible screen = 40 words (320 pix) )
with more bitplanes, add width*height*nbitplanes-2 (always raw blitter)

and yes, I shift the complete line to the left. not only the new char! all the line must be shifted to see a "scroll" :)
z5_
Member
#12 - Posted: 30 Nov 2004 22:24 - Edited by Admin
Reply Quote
@Cyf:

Thanks. There wasn't actually anything wrong with my routine. Just my bitplanepointers set up for one bitplane... Sorry. So now the wipe is working :) I'll try to do some more wipes to get to grips with the blitter a bit more. And i'll search some more myself before asking questions here :)

Actually, i tried a horizontal wipe (meaning that the picture appears from the left to the right) but it doesn't work yet. Thought i could do it by setting my blitter to 256 lines, 1 word width and both my modulos to 38 (screensize=picturesize), but it doesn't work. But i should search more myself first :)

Thanks for the explanation on the scrolltext. I think i'm nearly there...
Cyf
Member
#13 - Posted: 30 Nov 2004 22:50 - Edited
Reply Quote
Just my bitplanepointers set up for one bitplane... So now the wipe is working :)

8! hehe, yes, a little error.
Work but use interleaved "blitter" format is better if you want others effects with blitter.

for horizontal blitter wipe, main problem: blitter limit of 16 pix.
(like SinusScroll, use mask 1 (last word=1 & first word=1) for onepixel, loop 16 times (16 pix.), blit 1 word*height and shift mask each time with asl.w #1)

in one week, you can make a cool demo with all things on this forum !
z5_
Member
#14 - Posted: 1 Dec 2004 12:16
Reply Quote
I think i'm starting to understand so i'm going to try and explain it myself. Please correct me if i'm talking bullshit again :)

There are two ways to store a picture in raw format: sequential and interleaved (at least that is what iff-cutter calls them, Cyf is talking about blitter raw, which is interleaved)

Suppose we have a picture of 320*256 (or 40 bytes/line).
In sequential raw, the entire pixelinfo from the first bitplane is put after each other, then the entire pixelinfo of the 2nd bitplane,... So all pixelinfo is stored bitplane after bitplane.
byte 0 -> 38: pixelinfo line 1 bitplane 1
byte 40 -> 78: pixelinfo line 2 bitplane 1
byte 80 -> 118: pixelinfo line 3 bitplane 1
...
byte 10240->10278: pixelinfo line 1 bitplane 2
byte 10280->10118: pixelinfo line 2 bitplane 2
...

In interleaved mode (or blitter format), the information is stored as follows:
byte 0 -> 38: pixelinfo line 1 bitplane 1
byte 40 -> 78: pixelinfo line 1 bitplane 2
byte 80 -> 118: pixelinfo line 1 bitplane 3
byte 120 -> 158: pixelinfo line 1 bitplane 4
byte 160 -> 198: pixelinfo line 2 bitplane 1
...

Obviously, the screen bitplane pointers have to be set differently in both formats. In sequential format, the bitplane 1 pointer starts at 0, the bitplane 2 pointer starts at 10240, bitplane 3 pointer starts at 20480,...
No screen modulo is needed in this case.

In the interleaved way of storing pictures, am i right in saying that my bitplane 1 pointer points at 0, my bitplane 2 pointers points at 40, my bitplane 3 pointer points at 80,... and that i need to define a modulo of in this case 118 (=width in bytes *(number of bitplanes -1)) to get to the next line of pixelinfo?
TheDarkCoder
Member
#15 - Posted: 1 Dec 2004 13:28
Reply Quote
hello!

@z5_ : your self-explanetion is absolutely correct! :-)
As you may know, the advantage of using the interleaved format is that
in many cases you use just one blitting operation for all the bitplanes, while
in the normal format you would need one operation for each bitplane.
From the blitter and the system bus point of view there is no difference, since the number of memory accesses is the same. However the CPU spend less time because it loads the BLTxxx registers only once and then is free for other tasks, while with normal format CPU has to first load the BLTxxx registers for the bitplane 1 operation, then WAIT for the blitter to finish the first operation, RELOAD registers, and repeat for all bitplanes.
The improvement of the interleaved format is mainly evident when fast ram is available. In fact, with chip ram only, even if the CPU is free to execute other tasks, in practice cannot do much (especially if it is a CPU with no instruction cache) since the access to ram is locked by the blitter,
in particular if the BLITNASTY bit is set.
Hope this helps,
The Dark Coder
z5_
Member
#16 - Posted: 1 Dec 2004 16:55
Reply Quote
@The Dark Coder:
Thanks for the interesting addition :)
z5_
Member
#17 - Posted: 10 Dec 2004 21:16
Reply Quote
A little question... I nearly have my horizontal picture wipe working (from left to right) but i do have one problem still to solve. It's logical what happens but i need possible solutions.

I'm using a standard copy blit, source A (picture) and destination D (screen), copy $09f0, blitsize: height =256 and 1 word, both source and destination modulo 38 (40 bytes screen, 1 word blit). I thought i could use the mask function on my source A (both first and last word the same), so i start my mask with $8000 => first line copied ok. Then i thought i could do a lsr.w on my mask => mask $4000, and move my mask 16 times for each pixel, before i move one word in my bitplane data and do the same.

But, logically, when i shift my mask from $8000 to $4000 => my second line is copied but my first line is deleted... and so on => as a result i only have the last line in each word.

Is there a way i could make my mask move from $8000, $C000,$E000,$F000,... That way my problem would be solved. Or should i take another approach?
Anonymous
Member
#18 - Posted: 10 Dec 2004 22:23
Reply Quote
hmm... perhaps an OR in bltcon0 to avoid erasing others line : $0df0
Cyf
Member
#19 - Posted: 10 Dec 2004 22:23 - Edited
Reply Quote
err... it was me ^^

the blitter allowing transfers only of one minimum word, it's necessary to make an OR with the source and the destination, else it erases the other lines.
source B=dest D
minterm: A OR B=D = $dfc (source A, source B, dest D)
EDIT: just in case of the "mask" was a pattern, not the bltafwm mask
TheDarkCoder
Member
#20 - Posted: 11 Dec 2004 10:44
Reply Quote
@z5: I am not sure to have understood your question..
maybe it is enough to shift your mask with ASR.
As opposed to LSR, ASR copies the most significant bit.
So ASR #1,$8000 = $c000
ASR #1,$aaaa= $d555
is that what you were looking for??
Cyf
Member
#21 - Posted: 11 Dec 2004 13:02 - Edited
Reply Quote
and LSL/LSR add 0 during shift, no ?
or create a table with the 16 masks (and so test which are good)
z5_
Member
#22 - Posted: 11 Dec 2004 15:55 - Edited by Admin
Reply Quote
I was looking for a way to make such a bit pattern (which is my first and last word mask on source A, with bltafwm and bltalwm):
$8000, $c000,$e000,$f000,$f800,$fc00,$fe00,$ff00,$ff80,$ffc0...
(which is a shift to the right but everything on left side gets filled with 1)
Is that possible?

I have solved the problem in a different way in the meantime, by setting an extra source B, which is my screen (and is also my destination) and doing "A OR B". So with mask i'm setting on source A (my picture), i extract the pixel i want from the word, then do an OR with the screen. et voila :) (but i'm still interested in an answer to my question because it would even be easier that way as i don't need the extra source B).

edit: update: asr.w was exactly what i needed. So no need to have a second source for the horizontal wipe effect.
z5_
Member
#23 - Posted: 11 Dec 2004 16:05
Reply Quote
Another question: suppose that i want to make a mask by adding a source B, my picture is source A, my screen is destination D. I want to blit 1 line of 20 words (screen width) but i don't want all pixels to appear on the screen, but with a pattern 1010101010101010 => one pixel shown, one pixel not shown, one pixel shown, one pixel not shown...

I have defined my mask as:

my_mask:
dc.w $aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa
dc.w $aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa,$aaaa

i have setup my blitter as:
lea my_pic,a1
lea my_mask,a2
lea screen,a3

and just pushing those into my bltpointers:
move.l a1,bltapt
move.l a2,bltbpt
move.l a3,bltdpt

and doing a $0dc0 (A AND B)

both i don't see nothing on my screen. What could be wrong.
(typed fast so don't mind any wrong names or such...)
Cyf
Member
#24 - Posted: 11 Dec 2004 20:47 - Edited
Reply Quote
for this type of blit with a pattern, I used this method (like with Bobs but mask of bob replaced by pattern) :
bltafwm=$ffffffff
source A = picture source
source B = pattern
source C = screen
dest D = screen
with bltcon0=$fca (A,B,C and D + minterm=$ca)

it's the "cookie cut" function. AB+aC
Cyf
Member
#25 - Posted: 11 Dec 2004 21:16
Reply Quote
perhaps a good tuts about Minterm (boolean equation), not yet explained.

bltcon0 bits :
bits 15-12 : shift
bits 11-8 : source A, source B, source C, destination D
bits LF7 : ABC = 111
bits LF6 : ABc = 110
bits LF5 : AbC = 101
bits LF4 : Abc = 100
bits LF3 : aBC = 011
bits LF2 : aBc = 010
bits LF1 : abC = 001
bits LF0 : abc = 000

8 booleans equations possibles.
D=result of an OR with the 8 equ.
z5_
Member
#26 - Posted: 11 Dec 2004 22:52
Reply Quote
@Cyf:

I don't see why i should use my screen as a source here? After all, my destination is just a black screen and i just want to put a picture on it, but i want to use a pattern to copy the picture. My end goal for this is to create a diagonal wipe effect.

I can understand that one needs to use the screen as source if you copy a picture onto another picture, but that is not the case here.

So is there anything wrong with my approach?
Cyf
Member
#27 - Posted: 11 Dec 2004 23:27 - Edited
Reply Quote
hmm...yes, but with a pattern, to avoid the blitter to erase previous blit, you need to OR current screen with other sources to obtain the good result... (it's not the same "mask" than the horizontal wipe).

others wipe effects use this method.
but if other way exist, so, anybody lets know ^^ thanx

I never done a diagonal wipe with blit...
some ideas: draw a line or fill with line a screenbuffer used as pattern and OR with source.
or fill screen with pic as pattern/texture...(like "Stencil Vectors"). but before, learn how to use blitter for drawline and fill surface, draw ellipse...octants...pfiu many things!
Cyf
Member
#28 - Posted: 13 Dec 2004 21:39 - Edited
Reply Quote
rahh! diagonal is simple!
for a wipe from left to right and top to bottom for example: it's possible by using the horizontal wipe but lets start with Height=1 and increment Height. continue blit columns having H<maxheight.
and for the second half, decrement Height.

the drawline or fill is for more complex wipe like the famous Skidrow cracktro or the slide Forgotten/Mirage : start with diagonal line, and rotate line 320°.

and with horizontal wipe, you can made a trickle effect (alcatraz megademo 4 credits part)

EDIT: all wipes effects H and V can also be done with CPU.
z5_
Member
#29 - Posted: 2 Jan 2005 22:19
Reply Quote
I wanted to learn a bit more about the using the blitter to draw lines, but the amiga hardware reference is remarkably short on that topic. I don't have all figures from it aswell, and i don't have the figure of the octants (can't imagine plotting lines in octant with only 2 dimensions...).

So before asking questions about it, i just want to know if this is much used in demos. Can you name a couple of demos that use the blitter in line mode (demo + effect)? This will give me some idea of what is possible with it. Then i can start asking questions :)
Cyf
Member
#30 - Posted: 3 Jan 2005 11:04 - Edited
Reply Quote
linemode ? err...all 3D effects and 2D effects with "lines" (state of the art or major release, quartex substance credits...). (yes it's possible to draw a line with cpu, but i dont think it's more faster)

lines effects :
 Page:  1  2  »» 

  Please log in to comment

  

  

  

 

A.D.A. Amiga Demoscene Archive, Version 3.0