Jump to content
Jagware
Sign in to follow this  
SebRmv

Blitter, Mon Ami, Dis-moi Comment On Fait Des Rotations !!

Recommended Posts

SebRmv    2

Salut,

 

voilà, j'ai un peu joué avec le blitter hier et aujourd'hui

et bonne nouvelle: j'ai réussi à faire des rotations au blitter!!

 

en fait, la doc Atari donne les infos pour le faire et j'ai compris après avoir redécouvert moi-même la méthode leurs explications :D

par contre, les auteurs de la Jaguar Underground Documentation n'avaient pas compris comment faire les rotations au blitter !

 

alors, voilà

on va faire le cas d'une rotation toute simple (sans mise à l'échelle, après, c'est pareil si vous avez compris)

 

on veut tourner une image de taille W*H d'un angle alpha avec un centre de coordonnées CX,CY

on veut mettre le résultat dans une image de taille W*H aussi avec le centre au même endroit

(on tourne juste le sprite par rapport au centre donc)

 

plaçons nous dans le repère avec comme origine CX,CY et les axes comme il faut (parallèles au bord de l'écran)

je note X,Y les coordonnées d'un point dans l'ancien repère (sprite non tourné)

et X',Y' les coordonnées de ce même point dans le nouveau repère (sprite tourné)

 

maintenant, un peu de maths

 

vous savez sans doute que l'on a

 

X = X' cos(alpha) - Y' sin(alpha)

Y = X' sin(alpha) + Y' cos(alpha)

 

(comme disait mon prof de maths sup, toujours les anciennes coordonnées en fonction des nouvelles)

 

si on dérive par rapport à X' tous ça

on obtient

 

dX = cos(alpha) dX'

dY = sin(alpha) dX' (physician's style :D)

 

ce qui veut dire que si X' devient X'+1

alors X devient X + cos(alpha) et Y devient Y+sin(alpha)

 

(pareil, on dérive par rapport à Y'

dX = -sin(alpha) dY'

dY = cos(alpha) dY')

 

 

donc, si vous connaissez le blitter un petit peu

on voit tout de suite que A2 scannera la destination (et donc dessinera le sprite tourné)

et A1 scannera la source

et on utilisera le mode PIXEL bien sur avec comme incrément cos(alpha) et sin(alpha) !!

 

INC,FINC_X = cos(alpha)

INC,FINC_Y = sin(alpha)

 

pour revenir à la ligne, on utilisera A1_STEP et A1_FSTEP

on revient de dX' = -W

donc -W * cos(alpha) pour X et -W*sin(alpha) pour Y

mais il ne faut pas oublier non plus de descendre d'une ligne (donc dY' = 1)

d'où

 

STEP,FSTEP_X = -W*cos(alpha) -sin(alpha)

STEP,FSTEP_Y = -W*sin(alpha) + cos(alpha)

 

on va aussi utiliser le clipping du blitter pour ne pas écrire n'importe quoi si l'on sort du dessin du sprite original

 

CLIP_X = W

CLIP_Y = H

 

et maintenant, il ne reste plus qu'à trouver d'où l'on commence dans A1

(c'est à dire quelles sont les coordonnées du point 0,0 dans l'image originale (là je ne suis plus dans le repère centré))

 

eh bien, on ressort encore nos formules de maths

 

on obtient

 

PIXEL,FPIXEL_X = CY*sin(alpha) - CX*cos(alpha) + CX

PIXEL,FPIXEL_Y = CY - (CX*sin(alpha) + CY*cos(alpha))

 

et voilà!!

 

un peu de code, au cas où je n'aurais pas été clair :whistling:

 

ça tourne l'image base_gfx dans l'image base_buffer

notez que j'efface d'abord la zone (en mode phrase)

puis ensuite je fais effectivement la rotation

 

l'image a une largeur de 56 qui est aussi la largeur des données (WID56)

 

l'angle est dans d1

j'ai utilisé une routine get_cos_and_sin qui lit

simplement en data les valeurs pour le cosinus et le sinus

(d1 vaut le cosinus et d2 le sinus)

 

j'ai aussi bricolé vite fait une multiplication d'une valeur 16.16 (utilisée par le blitter) par un entier positif < 32768

 

 

n'hésitez pas à poser vos questions si je n'ai pas été clair

 

Seb

 

.macro    wait_blitter
.\~:
    move.l    B_CMD,\1
    ror.w    #1,\1
    bcc.s    .\~
.endm
.macro    imul16_16
;; \1 = registre contenant la valeur 16.16
;; \2 = registre contenant un entier POSITIF sur 16 bits (15 bits donc)
;; \3 = registre temporaire pour calcul intermediaire
;; \1 est intacte apres l'operation
;; le resultat est stocke dans \2
    move.w    \2,\3
    mulu.w    \1,\3    ; partie fractionnaire
    swap    \1
    muls.w    \1,\2    ; partie entiere
    swap    \1
    swap    \2    ; decale de 16
    clr.w    \2
    add.l    \3,\2    ; ajoute la partie fractionnaire
.endm


rotate_base:
W    equ    56
H    equ    50
CX    equ    56/2
CY    equ    32
;; efface le buffer
    wait_blitter    d0
    move.l    #base_buffer,A1_BASE
    move.l    #PIXEL16|XADDPHR|PITCH1|WID56,A1_FLAGS
    move.l    #0,A1_PIXEL
    move.w    #1,d0
    swap    d0
    move.w    #-W,d0
    move.l    d0,A1_STEP
    
    move.w    #H,d0
    swap    d0
    move.w    #W,d0
    move.l    d0,B_COUNT

*     move.l    #(BLUE<<16)|WHITE,B_PATD
*     move.l    #(RED<<16)|CYAN,B_PATD+4
    move.l    #0,B_PATD
    move.l    #0,B_PATD+4
    
    move.l    #UPDA1|PATDSEL,B_CMD
;; rotation
    wait_blitter    d0
    move.l    #base_buffer,A2_BASE
    move.l    #PIXEL16|XADDPIX|PITCH1|WID56,A2_FLAGS
    move.l    #0,A2_PIXEL

    move.w    #1,d0
    swap    d0
    move.w    #-W,d0
    move.l    d0,A2_STEP

    move.l    #base_gfx,A1_BASE
    move.l    #PIXEL16|XADDINC|PITCH1|WID56,A1_FLAGS

    move.w    #H,d0
    swap    d0
    move.w    #W,d0
    move.l    d0,A1_CLIP

    move.w    angle,d1
    bsr    get_cos_and_sin

    move.w    d2,d0
    swap    d2
    swap    d0
    move.w    d1,d0
    swap    d1
    move.l    d0,A1_FINC

    move.w    d2,d0
    swap    d2
    swap    d0
    move.w    d1,d0
    swap    d1
    move.l    d0,A1_INC
    
    move.w    #W,d3
    imul16_16    d1,d3,d7; W*cos(alpha)
    move.w    #W,d4
    imul16_16    d2,d4,d7; W*sin(alpha)
    move.l    d2,d5
    neg.l    d5    ; -sin(alpha)
    sub.l    d3,d5    ; -sin(alpha)-W*cos(alpha)
    move.l    d1,d6    ; cos(alpha)
    sub.l    d4,d6    ; cos(alpha)-W*sin(alpha)

    move.w    d6,d0
    swap    d6
    swap    d0
    move.w    d5,d0
    swap    d5
    move.l    d0,A1_FSTEP
    
    move.w    d6,d0
    swap    d0
    move.w    d5,d0
    move.l    d0,A1_STEP
    
    move.w    #CX,d3
    imul16_16    d1,d3,d7; CX*cos(alpha)
    move.w    #CY,d4
    imul16_16    d2,d4,d7; CY*sin(alpha)
    sub.l    d3,d4
    add.l    #CX<<16,d4
    move.w    #CX,d3
    imul16_16    d2,d3,d7; CX*sin(alpha)
    move.w    #CY,d5
    imul16_16    d1,d5,d7; CY*cos(alpha)
    add.l    d5,d3
    neg.l    d3
    add.l    #CY<<16,d3
    exg.l    d3,d4

    move.w    d4,d0
    swap    d4
    swap    d0
    move.w    d3,d0
    swap    d3
    move.l    d0,A1_FPIXEL

    move.w    d4,d0
    swap    d0
    move.w    d3,d0
    move.l    d0,A1_PIXEL
                    
    move.w    #H,d0
    swap    d0
    move.w    #W,d0
    move.l    d0,B_COUNT

    move.l    #CLIP_A1|UPDA1|UPDA1F|UPDA2|LFU_REPLACE|SRCEN|DSTA2,B_CMD
    rts

Share this post


Link to post
Share on other sites
SebRmv    2

Pour ceux qui n'auraient pas compris, une deuxième chance existe avec la traduction anglaise :D

Rendez-vous ici: http://www.jagware.org/index.php?showtopic=258&hl=

 

(j'ai changé un peu l'explication)

 

[english]

 

I have not forgotten english speaking people :hug:

Go find a translation there: http://www.jagware.org/index.php?showtopic=258&hl=

 

Seb

Share this post


Link to post
Share on other sites
SebRmv    2

Ok, maintenant que tout le monde a compris :blink:

exercice:

 

comment programmer le blitter pour la transformation du plan suivante :D

 

X = a X' + b Y' + e

Y = c X' + d Y' + f

 

??

 

[english]

 

now, as an exercise, how would you program the blitter for the following transformation :D

 

(equations just above :P )

Share this post


Link to post
Share on other sites
GT Turbo    5
Ok, maintenant que tout le monde a compris :blink:

exercice:

 

comment programmer le blitter pour la transformation du plan suivante :D

 

X = a X' + b Y' + e

Y = c X' + d Y' + f

 

??

 

Azrael, Ray, Symmetry vous etes ou ? Seb veut jouer ;)

 

[english]

 

now, as an exercise, how would you program the blitter for the following transformation :D

 

(equations just above :P )

 

Azrael , Ray, Symmetry where are you ? SebRmv want to play !!

 

GT :poulpe:

Share this post


Link to post
Share on other sites
SebRmv    2

En fait, je pense qu'Azrael est dispensé de l'exercice :D

 

[english]

 

Actually, I think that Azrael can ignore the question (I think that he knows)

Share this post


Link to post
Share on other sites
SebRmv    2

Ok, as I can't sleep, I have written the solution (I mean the code of the solution).

 

You can look the result with http://removers.atari.org/blit2d.bin

 

The transformation matrix is written on screen.

The blue values are "a" and "b"

The red values are "c" and "d"

The white values are "e" and "f"

 

You can of course edit the values with the program.

 

To select the value you want, press 1 to 6 on the joypad.

Then you can increment or decrement the value by 1<<SCALE with up and down on the joypad.

The default SCALE is 0 (so the default increment is 1) but you can change the scale with 7, 8, 9 and 0. The corresponding scales are 0, 4, 8 and 12.

 

Enjoy

 

Seb

 

PS: the exercise is still up!

Share this post


Link to post
Share on other sites
SebRmv    2

Yes, I should have mentionned that :D

 

And the displayed values should be read as 16.16 signed values.

Share this post


Link to post
Share on other sites
SebRmv    2

No, there are still things to learn with the Blitter.

I would like to see an example of Gouraud Shading and/or Zbuffering for example.

And do not forget also the collision detection using the blitter.

 

I might extend a bit the little demo 2d transformations with the blitter to enter values for rotations easily... Maybe tonight :D

Share this post


Link to post
Share on other sites
Azrael    0
En fait, je pense qu'Azrael est dispensé de l'exercice :D

 

[english]

 

Actually, I think that Azrael can ignore the question (I think that he knows)

 

Thanks SebRmv :)

Anyway, I'll try to do it by myself too... perhaps it'll give me ideas.

 

Ah... I forgot : great job ! :yes:

Share this post


Link to post
Share on other sites

>Azrael , Ray, Symmetry where are you ? SebRmv want to play !!

 

hehe =) ...Im buzzy! =) ...and the following days Im babysitting my sisters daughter :) 10months.. I will diskuss the solution with her ;P

 

 

 

>SebRmv

>I would like to see an example of Gouraud Shading and/or Zbuffering for example.

 

well i have debugged some gouroud shaded lines in my life.. and have a rather good understanding of what is going on, and the limitations that exists (and the workarounds that might be needed).... but by the time I have written a howto you have made a well written tutorial in nice looking pdf format ;)

 

regarding zbuffer I have a realy cool effect i made some year ago when i thought of what the zbuffer could be used for (that demostrates the zbuffer good).... BUT... as with the interlace routine I would have liked to keep this effect "secret" for a possible upcoming megademo.... =)

And i am hence a bit torn what to do.. =) I would so much like to show you all, but then the "wow" effect is lost.... (most important in a demo ;) .. I dont know what to do =)

And as with interlace its possible that this effect is thought of rather soon here since you are hackers ;)

 

I could and will however, trye to answer any questions about the topic that might come upp....

Perhapps I can incorporate the zbuffer example in a gouroud one... well se how much time i get, or/and if these topics evolve here at the forum.

 

great job with the rotation btw!

 

cheers

/Sym

Share this post


Link to post
Share on other sites
Zerosquare    10
the following days Im babysitting my sisters daughter :) 10months.. I will diskuss the solution with her ;P
Young children are said to have a very "flexible" mind, maybe the Jag hardware would make sense to her :D

Share this post


Link to post
Share on other sites
SebRmv    2

smile, I have worked on an improved version tonight.

 

get it at http://removers.atari.org/blit2d2.bin

 

additionnal keys are

 

B+Left or B+Right to change the rotation angle

A and C to zoom in / out (very sensitive)

* + # to reset values

 

I think that's all :D

 

Seb

Share this post


Link to post
Share on other sites
Orion_    1

nice :) just a little bug of the reset of the zoom when rotating, is it possible to choose the rotating center ?

Share this post


Link to post
Share on other sites
SebRmv    2
nice :) just a little bug of the reset of the zoom when rotating, is it possible to choose the rotating center ?

 

actually, it is not a bug

but I admit the actual behaviour is a bit frustating

 

to choose the rotating center, you can edit the white values :P (key 3 and 6)

 

however, if I have time tonight, I will take your remarks in consideration

 

Seb

Share this post


Link to post
Share on other sites
SebRmv    2

Hello,

 

I have not improved my test program but I have added some color bars to bench the blitter...

The yellow bar (not visible actually) represents the time the 68k initialises the blitter

and the red bar represents the time spent by the blitter to do the work.

 

Actually, I am a bit disappointed by this bench. What about you?

The source image is 64x44 and the target image is 128x128

(16 bits depth)

 

get the binary there:

 

http://removers.atari.org/blit2dbench.bin

 

Seb

Share this post


Link to post
Share on other sites
SebRmv    2

pour recompiler les sources (inclues avec les Removers libraries), il faut madmac et aln

pour tester, il faut juste l'uploader BJL par exemple

 

[english]

to recompile the sources (included with the Removers libraries), you will need madmac & aln

for testing, you just need the BJL uploader for instance

Share this post


Link to post
Share on other sites
Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoticons maximum are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×