Sources PureBasicConsultez toutes les sources

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

 
OuvrirSommaireAssembleur

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

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

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
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2008 Developpez 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.