# Sources PureBasicConsultez toutes les sources

Nombre d'auteurs : 41, nombre de sources : 88, dernière mise à jour : 13 août 2011

Sommaire→Assembleur

- Maintien d'un angle entre -pi et pi ou entre 0° et 360°
- Comment tester rapidement si une zone mémoire ne contient que des zéros ?
- Comment obtenir la fonction ATAN2 ?

Version hors-ligne
Maintien d'un angle entre -pi et pi ou entre 0° et 360°

Les procédures ci dessous permettent de maintenir un angle dans un intervalle :

- WrapAngleSigned(angle.f) maintient un angle en radian entre [-Pi,Pi]
- WrapAngleDegSigned(angle.f) maintient un angle en degré entre [-180,180]
- WrapAngleUnsigned(angle.f) maintient un angle en radian entre [0,2*Pi]
- WrapAngleDegUnsigned(angle.f) maintient un angle en degré entre [0,360]

Sélectionnez

    Procedure.f WrapAngleSigned(angle.f); <- wraps a value into [-Pi,Pi] fringe
      !fldpi
      !fadd st0,st0; <- now i have 2*pi into st0
      !fld dword[p.v_angle]
      !fprem1
      !fstp st1
      ProcedureReturn
    EndProcedure
    Procedure.f WrapAngleDegSigned(angle.f); <- wraps a value into [-180,180] fringe
      !fild dword[@f] ; <- now i have 360 into st0
      !fld dword[p.v_angle]
      !fprem1
      !fstp st1
      ProcedureReturn
      !@@:dd 360
    EndProcedure
    Procedure.f WrapAngleUnsigned(angle.f); <- wraps a value into [0,2*Pi) fringe
      !fldpi; <- now i have pi into st0
      !fadd st0,st0; <- now i have 2*pi into st0
      !fld dword[p.v_angle]; <- now i have angle in st0, 2*pi into st1
      !fprem; <- now i have the remainder of angle/(2*pi) division (i.e. angle%(2*pi)) in st0, 2*pi in st1
      !fadd st1,st0;<- now i have angle%(2*pi) in st0, 2*pi+angle%(2*pi) into st1
      !fldz;<- now i have 0 in st0, angle%(2*pi) in st1, 2*pi+angle%(2*pi) into st2
      !fcomip st1; <- compare st0 and st1, and pop the stack, which means i have now angle%(2*pi) in st0, 2*pi+remainder into st1
      !fcmovnbe st0,st1; <- transfer st1 to st0 if not below or equal.
      !fstp st1; <- store st0 in st1 and pops stack, which means i have now the result in st0
      ProcedureReturn; <- return the result with this last pop
    EndProcedure
    Procedure.f WrapAngleDegUnsigned(angle.f); <- wraps a value into [0,360) fringe
      !fild dword[@f] ; <- now i have 360 into st0
      !fld dword[p.v_angle]
      !fprem
      !fadd st1,st0
      !fldz
      !fcomip st1
      !fcmovnbe st0,st1
      !fstp st1
      ProcedureReturn
      !@@:dd 360
    EndProcedure

    ;Exemples d'utilisation en degré:
    angle.f=45
    angleadd.f=-90
    angle.f=WrapAngleDegUnsigned(angle.f+angleadd.f)
    Debug angle
    ;
    angle.f=45
    angleadd.f=-90
    angle.f=WrapAngleDegSigned(angle.f+angleadd.f)
    Debug angle
    ;
    ;Exemples d'utilisation en radian:
    angle.f=#PI/4.0
    angleadd.f=-#PI/2.0
    angle.f=WrapAngleUnsigned(angle.f+angleadd.f)
    Debug angle
    ;
    angle.f=#PI/4.0
    angleadd.f=-#PI/2.0
    angle.f=WrapAngleSigned(angle.f+angleadd.f)
    Debug angle

Créé le 20 février 2008 par Psychophanta
Comment tester rapidement si une zone mémoire ne contient que des zéros ?

Ce code permet de tester si une zone mémoire ne contient que des zéros pour par exemple détecter une collision.
La procédure est optimisée et renvoie #False si toutes les donnéees sont à zéro sinon #True.

Sélectionnez

    ; Thorium le 21/11/09
    ; PB 4.40

    Procedure NoneZero(*DestBufStart, DestBufSize.i)

      CompilerSelect #PB_Compiler_Processor

        CompilerCase #PB_Processor_x86

          !push edi
          !push ebx

          !mov edi,[p.p_DestBufStart+8]

          !mov edx,[p.v_DestBufSize+8]
          !mov ecx,edx
          !mov ebx,ecx
          !shr edx,4
          !and ecx,15
          !shr ecx,2
          !and ebx,3

          !test edx,edx
          !je NoneZero_FirstEnd
          !pxor xmm1,xmm1

          !align 4
          !NoneZero_FirstStart:

            !movdqu xmm0,[edi]
            !pcmpeqb xmm0,xmm1

            !add edi,16

            !pmovmskb eax,xmm0
            !cmp eax,$0000FFFF
            !jne NoneZero_EndTrueSse

          !dec edx
          !jne NoneZero_FirstStart

          !emms

          !align 4
          !NoneZero_FirstEnd:

          !test ecx,ecx
          !je NoneZero_SecondEnd

          !align 4
          !NoneZero_SecondStart:

            !mov eax,[edi]
            !test eax,eax
            !jne NoneZero_EndTrue

            !add edi,4

          !dec ecx
          !jne NoneZero_SecondStart

          !align 4
          !NoneZero_SecondEnd:

          !test ebx,ebx
          !je NoneZero_ThirdEnd

          !align 4
          !NoneZero_ThirdStart:

            !mov al,[edi]
            !test al,al
            !jne NoneZero_EndTrue

            !inc edi

          !dec ebx
          !jne NoneZero_ThirdStart

          !align 4
          !NoneZero_ThirdEnd:

          !pop ebx
          !pop edi

          ProcedureReturn #False

          !NoneZero_EndTrue:
          !pop ebx
          !pop edi

          ProcedureReturn #True

          !NoneZero_EndTrueSse:
          !pop ebx
          !pop edi
          !emms

          ProcedureReturn #True

        CompilerCase #PB_Processor_x64

          !push rdi
          !push rbx

          !mov rdi,[p.p_DestBufStart+16]

          !mov rdx,[p.v_DestBufSize+16]
          !mov rcx,rdx
          !mov rbx,rcx
          !shr rdx,4
          !and rcx,15
          !shr rcx,2
          !and rbx,3

          !test rdx,rdx
          !je NoneZero_FirstEnd
          !pxor xmm1,xmm1

          !align 8
          !NoneZero_FirstStart:

            !movdqu xmm0,[rdi]
            !pcmpeqb xmm0,xmm1

            !add rdi,16

            !pmovmskb eax,xmm0
            !cmp eax,$0000FFFF
            !jne NoneZero_EndTrueSse

          !dec rdx
          !jne NoneZero_FirstStart

          !emms

          !align 8
          !NoneZero_FirstEnd:

          !test rcx,rcx
          !je NoneZero_SecondEnd

          !align 8
          !NoneZero_SecondStart:

            !mov eax,[rdi]
            !test eax,eax
            !jne NoneZero_EndTrue

            !add rdi,4

          !dec rcx
          !jne NoneZero_SecondStart

          !align 8
          !NoneZero_SecondEnd:

          !test rbx,rbx
          !je NoneZero_ThirdEnd

          !align 8
          !NoneZero_ThirdStart:

            !mov al,[rdi]
            !test al,al
            !jne NoneZero_EndTrue

            !inc rdi

          !dec rbx
          !jne NoneZero_ThirdStart

          !align 8
          !NoneZero_ThirdEnd:

          !pop rbx
          !pop rdi

          ProcedureReturn #False

          !NoneZero_EndTrue:
          !pop rbx
          !pop rdi

          ProcedureReturn #True

          !NoneZero_EndTrueSse:
          !pop rbx
          !pop rdi
          !emms

          ProcedureReturn #True

      CompilerEndSelect

    EndProcedure

    ;- Test de la procédure
    *Buffer = AllocateMemory(64000) ; Buffer de 64000 octets
    *Ptr.Byte = *Buffer + 64000 - 1 ; On se place sur le dernier octet
    *ptr\b = 5                      ; Modifie le dernier octet du *Buffer

    Debug NoneZero(*Buffer, MemorySize(*Buffer))

Créé le 21 novembre 2009 par Thorium
Comment obtenir la fonction ATAN2 ?

Atan2(y,x) est l'angle en radians entre la partie positive de l'axe des x d'un plan, et le point de ce plan aux coordonnées (x,y). (wikipédia)
Note : La commande Atan2() est ajoutée dans la bibliothèque Math depuis la version 4.50.

Sélectionnez

    Procedure.d ATan2(y.d,x.d)
      !fld qword[p.v_y]
      !fld qword[p.v_x]
      !fpatan
      ProcedureReturn
    EndProcedure

    y.d = 70
    x.d = 0
    #RAD2DEG = 180.0/#PI ; Conversion Radians en degrés
    Debug ATan2(y, x) * #RAD2DEG

Mis à jour le 7 novembre 2010 par Comtois
Version hors-ligne

Les sources présentés sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une œuvre intellectuelle protégée par les droits d'auteurs. Copyright ©2008 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.