ASMONE ifnd ASMONE opt c- endc ;--- DEBUG DEBUGDISPLAY_TIME ;affiche le compteur de rater DEBUGDISPLAY_RASTER ;affiche la couleur raster rouge/vert CTR=1 ;permet de compter le nombre de boucle d'attente du blitter ;Programme Arnaud.68000 - 2020-11 ;Rotation RUBIK'S filaire 3D ; ;assembleur : ASMTwo ; ;References : ;Reprise architecture (init hardware, copperlist, ombre et miroir) : ;source : Yragael pour Stash of Code (http://www.stashofcode.fr) en 2017. ; ;contient le fichier Font8 : ;https://www.stashofcode.fr/code/coder-un-sine-scroll-sur-amiga/sinescroll.zip ; ;--- Gestion de CONF --- ;2020-11-23 - Arnaud.68000 - Afficher en couleur filaire ;2020-11-24 - Arnaud.68000 - Nettoyage Code pour plus de lisibilité ;2020-11-25 - Arnaud.68000 - Calcul des points dans table reduite (évite redondance test normale Y) ; - Remplacement de code (44 -> 16 cycles ): Rotation de plan : lsr.l #7,d4 & lsr.l #7,d4 --> Swap d4, rol.l #2,d4 ;2020-11-27a - Arnaud.68000 - OPTIISATION : Calcul de la NORMALE basee que sur l'axe Y, ajout sub Calculer_Y_Axes_Ax_AZ() ;2020-11-27b - Arnaud.68000 - OPTIISATION : Calcul des normales des axes 6 axes (Calcul / 9) + chaque polygone s'y refere(quand la pièce n'est pas dans une couronne en rotation). ; - AllocMem en 1 fois et en Chip ; - Clarifier le code avec des SUB ;.--- TODO Developpement ;TODO : afficher en plein ;TODO : créer les rotations de couronne ;TODO : gérer les interférences de polygones (lors de rotation couronne) ;TODO : afficher textes ;TODO : ajouter de la musique ;TODO : faire des animations cube + texte + musique ;TODO : passer en rotation manuelle à la demande ;--- TODO pistes optimisation ;TODO OPTIISATION : table TRIGO SUR 256 donc rotation sur 1 octet = plus besoin de comparer à 360 ;TODO OPTIISATION : Gain 10 HBL : ne pas appeler calcul3D mais recopier le code (utiliser les macros) ;TODO OPTIISATION : Faire le RAZ de BitplaneC quand CPU occupe et ne pas attendre le Blitter (50 VBH perdus) ;TODO OPTIISATION ; Faire une rotation sur 2 axes, donc blanquer le 3eme axe ;TODO Basecode portable "utilise un basecode existant, de blueberry, stingray, etc… pour Jel, voir YouTube" ;TODO supprimer les espaces dans les tables ;TODO mettre la copperlist direct en chip dans un section copper,data_c ;TODO idem pour les screens (appelés ici bitplaneA,B,C) dans un section screen,bss_c "le bss ça ne prend aucune place dans le code : c’est un hunk d’allocmem que le systeme fera automatiquement." ;TODO OPTILISATION : décaler les coordonnées de 2 bits vers la gauche, eviter rol.l #2,dn dans les rotations ;TODO OPTIMISATION : EVITER RALENTISSEMENT : mixer les couleurs des faces pour éviter d'avoir 3 faces consécutives dont les couleurs sont sur 2 bitplanes SECTION Arnaud.68000,CODE_C ;--- Objet 3D Calculer3D ;calcule les rotations AffLigneRUBIKS ;affiche le rubiks ;--- TEXTE AffTexteFixe ;--- gestion du 3eme Bitplane EffacerBitPlaneCache ;Angles au depart InitAngleAx equ 32 InitAngleAy equ 14 InitAngleAz equ 18 ;Incrément des axes PasAngleAX equ 2 PasAngleAY equ 0 PasAngleAZ equ 1 ;position du centre objet. rayon maxi 92 pix equ sqr(3*53^2), coins max 53,53,53 RayonMaxi equ 96 ;doit tre un miltiple de 8 pix, utilisé pour RAZ au blitter offsetX equ 160 ;min 87, maxi 232 offsetZ equ 100 ;mini 87, maxi 168 87=sqr(50^2+50^2+50^2) coin max (50,50,50) ;---------- RUBIK NBPOLY equ 54 ;---- Librairies ----- ExecBase equ 4 ;location of the exec.lib OldOpenLibrary equ -408 OpenLib equ -552 ;offset to the openLibrary function OpenLibVersion equ 34 ;minimum version to use CloseLib equ -414 ;offset to closeLibrary function PutString equ -948 ;offset to putStr() function AllocMem equ -198 FreeMem equ -210 Forbid equ -132 Permit equ -138 ;---- Registres ----- VPOSR equ $004 VHPOSR equ $006 INTENA equ $09A INTENAR equ $01C INTREQ equ $09C INTREQR equ $01E DMACON equ $096 DMACONR equ $002 BLTAFWM equ $044 BLTALWM equ $046 BLTAPTH equ $050 BLTAPTL equ $052 BLTCPTH equ $048 BLTDPTH equ $054 BLTAMOD equ $064 BLTBMOD equ $062 BLTCMOD equ $060 BLTDMOD equ $066 BLTADAT equ $074 BLTBDAT equ $072 BLTCON0 equ $040 BLTCON1 equ $042 BLTSIZE equ $058 DIWSTRT equ $08E DIWSTOP equ $090 BPLCON0 equ $100 BPLCON1 equ $102 BPLCON2 equ $104 DDFSTRT equ $092 DDFSTOP equ $094 BPL1MOD equ $108 BPL2MOD equ $10A BPL1PTH equ $0E0 BPL1PTL equ $0E2 BPL2PTH equ $0E4 BPL2PTL equ $0E6 BPL3PTH equ $0E8 BPL3PTL equ $0EA COLOR00 equ $180 COLOR01 equ $182 COLOR02 equ $184 COLOR03 equ $186 COLOR04 equ $188 COLOR05 equ $18A COLOR06 equ $18C COLOR07 equ $18E COLOR08 equ $190 COP1LCH equ $080 COPJMP1 equ $088 FMODE equ $1FC ;Programme DISPLAY_DEPTH=3 DISPLAY_DX=320 DISPLAY_DY=256 DISPLAY_X=$81 DISPLAY_Y=$2C SCROLL_DX=DISPLAY_DX SCROLL_X=(DISPLAY_DX-SCROLL_DX)>>1 SCROLL_DY=100 SCROLL_AMPLITUDE=SCROLL_DY-16 ;SCROLL_DY-16 donne l'amplitude des ordonnées possibles du scroll : [0,SCROLL_DY-16] ;SCROLL_DY doit être pair pour centrer le scroll sur DISPLAY_DY qui est pair ;Donc SCROLL_DY-16 est pair ;Les ordonnées sont calculées par (A>>1)*sin ce qui donne des valeurs dans [-A,A] quand A est pair et dans [-A+1,A+1] quand A est impair ;Ici A=SCROLL_DY-16 donc A est pair : pas de correction à apporter SCROLL_Y=(DISPLAY_DY-SCROLL_DY)>>1 ;SCROLL_SPEED=2 SCROLL_COLOR=$0FFF SINE_SPEED_FRAME=5 SINE_SPEED_PIXEL=1 LINE_DX=15 ;C'est le nombre de lignes de la droite - 1 : LINE_DX=max (abs(15-0),abs(0,0)) LINE_DY=0 ;C'est le nombre de colonnes de la droite - 1 : LINE_DY=min (abs(15-0),abs(0,0)) LINE_OCTANT=1 MIRROR_Y=SCROLL_Y+SCROLL_DY ;Ordonnée de la ligne à laquelle débute le miroir (le WAIT pour modifier BPL1MOD a lieu une ligne avant) MIRROR_COLOR=$00A MIRROR_SCROLL_COLOR=$000F SHADOW_DX=0 ;2 ;Compris entre 0 et 15 SHADOW_DY=0 ;2 SHADOW_COLOR=$777 TAILLE_BITPLANE=((DISPLAY_DX*DISPLAY_DY)>>3) SCROLL_POS_Y=162 SCROLL_SPEED=1 ;--- MACROS --- ;--- MACRO Attendre le Blitter. ;Quand la seconde opérande est une adresse, BTST ne permet de tester que les bits 7-0 de l'octet pointé, ;mais traitant la première opérande comme le numéro du bit modulo 8, ;BTST #14,DMACONR(a5) revient à tester le bit 14%8=6 de l'octet de poids fort de DMACONR, ;ce qui correspond bien à BBUSY... WAITBLIT: MACRO _waitBlitter0\@ IFNE CTR add.l #1,CTRWait ENDC btst #14,DMACONR(a5) bne _waitBlitter0\@ _waitBlitter1\@ IFNE CTR add.l #1,CTRWait ENDC btst #14,DMACONR(a5) bne _waitBlitter1\@ IFNE CTR sub.l #2,CTRWait ENDC ENDM ;---MACRO CALCUL: MACRO ;************************ ;utilisé : d0=X, d1=Y, d2=Z, a2=cos, a3=sin, A4=aX, A5=aY, a6=aZ ;************************ ;rotation axe Z (plan XY) ;x1=x*cos(aZ)-y*sin(aZ) ;y1=x*sin(aZ)+y*cos(aZ) move.w (a2,A6),d4 ;d4=cos(aZ) move.w (a3,A6),d3 ;d3=sin(aZ) move.w d4,d5 ;cos move.w d3,d6 ;sin muls d0,d5 ;x*cos muls d1,d6 ;y*sin sub.l d6,d5 ;d5=x1= x*cos(aZ) - y*sin(aZ) Swap d5 rol.l #2,d5 muls d0,d3 ;x*sin muls d4,d1 ;y*cos add.l d3,d1 ;d1=y1= x*sin(aZ) + y*cos(aZ) Swap d1 rol.l #2,d1 ;************************ ;utilisé : d1=y1, d2=Z, d5=x1, a2=cos, a3=sin, A4=aX, A5=aY ;************************ ;rotation axe X (plan YZ) ;D4=cos(A4), d3=sin(A4) ;y2=y1*cos(aX)-z*sin(ax) ;d0=D4, d0=d1*d0, d6=d3, d6=d2*d6, d0=d0-d6 ;z1=y1*sin(aX)+z*cos(aX) ;d3=d1*d3, d4=d2*d4, d3=d3+d4 move.w (a2,A4),d4 ;a4=cos(aX) move.w (a3,A4),d3 ;d3=sin(ax) move.w d4,d0 ;c move.w d3,d6 ;s muls d1,d0 ;y1*cos muls d2,d6 ;z*sin sub.l d6,d0 ;y2=y1*cos-z*sin Swap d0 rol.l #2,d0 muls d1,d3 ;y*sin muls d2,d4 ;z*cos add.l d4,d3 ;z1=y*sin+z*cos Swap d3 rol.l #2,d3 ;************************ ;utilisé : d0=y2, d3=z1, d5=x1, a2=cos, a3=sin, A5=aY ;************************ ;rotation axe Y (plan ZX) ;d6=cos(A5), d4=sin(A5) ;z2=z1*cos(aY)-x1*sin(aY) ,d1=d6, d1=d3*d1, d2=d4, d2=d5*d2, d1=d1-d2 ;x2=z1*sin(aY)+x1*cos(aY) ;d6=d5*d6, d4=d3*d4, d4=d6+d4 ; ;TODO OPTIISATION : Faire une rotation sur 2 axes, donc blanquer le 3eme axe Gagne 35 HBL ;move.W d5,d4 ;move.w d3,d1 ;rts move.w (a2,A5),d6 ;cos(aY) move.w (a3,A5),d4 ;sin(aY) move.w d6,d1 move.w d4,d2 muls d3,d1 ;z1*cos muls d5,d2 ;x1*sin sub.l d2,d1 ;z2=z1*cos-x1*sin Swap d1 ;16 cycles rol.l #2,d1 muls d3,d4 ;z1*sin muls d5,d6 ;x1*cos add.l d6,d4 ;x2=x1*cos+z1*sin Swap d4 rol.l #2,d4 ENDM ;---------- Initialisations ---------- Start movem.l d0-d7/a0-a6,-(sp) ;Empiler les registres lea $dff000,a5 movea.l $4.w,a6 bsr ReserverMemoireCHIP bsr CouperHardware bsr InitiliserCopperList bsr CreerPolice16x16 ;--------------------------------------- ;---------- Boucle principale ---------- ;A5=$DFF000 clr.w D7 move.l #Texte_Char,a4 _loop: IFNE CTR move.l #0,CTRWait ENDC ;--- Attendre que le faisceau d'électrons a terminé de tracer l'écran _waitVBL: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmp.w #DISPLAY_Y+DISPLAY_DY,d0 blt _waitVBL IFD DEBUGDISPLAY_RASTER move.w #$0F00,COLOR00(a5) ;si DEBUG on passe en rouge la couleur du fond ENDC ;----- PERMUTER LES BITPLANE ---------- ;Permuter circulairement les bitplanes : A(à afficher) --> C(à effacer) --> B(à construire) --> A move.l bitplaneA,d0 move.l bitplaneB,d1 move.l bitplaneC,d2 move.l d1,bitplaneA ;Bitplane Affiché move.l d2,bitplaneB ;Bitplane en construction move.l d0,bitplaneC ;Bitplane en effacement ;----- AFFICHER BitPlaneA VIA COPPERLIST ---------- ;ecriture des adresses bitplane dans la copperlist movea.l Copperlist_BitPlanes_PTR(pc),a0 ;BitplaneA0 move.w d1,2(a0) swap d1 move.w d1,6(a0) swap d1 add.l #TAILLE_BITPLANE,d1 ;BitplaneA1 move.w d1,10(a0) swap d1 move.w d1,14(a0) swap d1 add.l #TAILLE_BITPLANE,d1 ;BitplaneA2 move.w d1,18(a0) swap d1 move.w d1,22(a0) ;--- AFFICHER TEXTE FIXE 8x8 ------- ;A5 ne pas modifier ;d0,A0,A2,A3 utilisés IFD AffTexteFixe IFD DEBUGDISPLAY_TIME move.l bitplaneB(pc),a2 add.l #TAILLE_BITPLANE,a2 lea TexteAngle(pc),a3 add.l #0*8*5+35,A2 ;posx en octet (pas de 8 pix) bsr AfficherTexte8x8 ;;d0,A0,A2,A3 utilisés ENDC move.l bitplaneB(pc),a2 ;add.l #TAILLE_BITPLANE,a2 lea TexteArnaud2020(pc),a3 add.l #40*8*5+0,A2 ;posx en octet (pas de 8 pix) bsr AfficherTexte8x8 ;d0,A0,A2,A3 utilisés ENDC ; ## # # ## ; # # # # # ; # ### # # ; ## # # ### ## ;-- CALCUL 3D ******************************** IFD Calculer3D Calcul3D: movem.l d0-d7/a0-a6,-(sp) ;--- CALCULER LES ANGLES --------- lea Angles(pc),a2 ;Increment angle aX move.w (a2),a4 add.w #PasAngleAX,a4 ;increment AX cmp.w #360,a4 blo PasModuloIncrementAx sub.w #360,a4 PasModuloIncrementAx: move.w a4,(A2)+ ;Increment angle aY move.w (a2),a5 add.w #PasAngleAY,a5 ;increment AY cmp.w #360,a5 blo PasModuloIncrementAy sub.w #360,a5 PasModuloIncrementAy: move.w a5,(A2)+ ;Increment angle aZ move.w (a2),a6 add.w #PasAngleAZ,a6 ;increment AZ cmp.w #360,a6 blo PasModuloIncrementAz sub.w #360,a6 PasModuloIncrementAz: move.w a6,(A2)+ ;--- CHARGER LES TABLES TRIGO lea CosinusTbl(pc),A2 lea SinusTbl(pc),A3 add.w a6,a6 add.w a5,a5 add.w a4,a4 ;--- CALCULER LES POINTS ;dont les normales sont orientées vers observateur ;y représente la profondeur, si y> alors face visibel ;POLY: dc.w -50,0,0, 2, -53,-50,-50, -53,-18,-50, -53,-18,-18, -53,-50,-18 ;POLYCALCULES : dc.w couleur (1..6), pointA1 (x,y,z), pointA2 (x,y,z), pointB1 (x,y,z), pointB2 (x,y,z) lea NORMALES(pc),a0 lea NORMALESCalculees(pc),a1 NBNormales=6 move.l #NBNormales-1,d7 ;nb de polygones BclCalculerNormales: ;--- Calculer la normale du polygone move.w (A0)+,d0 ;nx move.w (A0)+,d1 ;ny move.w (A0)+,d2 ;nz bsr Calculer_Y_Axes_Ax_AZ ;(D0=Y, utilisés : d0,d1,d2,d3,a2,a3,a4,a6) ;bsr CalculerXYZ_3Axes(pc) move.w d0,(a1) ;ny2 addq.l #6,a1 ;le pas est de 3.w ;bpl NormaleVersFond(pc) ;saute si d0>=0 cad normale orientee vers le fond dbf d7,BclCalculerNormales ;POLY: dc.w num_yY, Coul (1..6), A(x,y,z), B(x,y,z), C(x,y,z), D(x,y,z) ;POLYCALCULES : dc.w nY, coul(1..6), A(x,y,z), B(x,y,z), C(x,y,z), D(x,y,z) lea POLY(pc),a0 lea NORMALESCalculees(pc),a1 move.l #NBPOLY-1,d7 ;nb de polygones BclCalculerPoints: move.w (a0),d0 ;numero de "normaleY" tst.w (a1,d0) ;test du signe de la "normaleY" bpl NormaleVersFond ;saute si d0>=0 cad normale orientee vers le fond ; move.w #-255,POLYCALCULES-POLY(A0) ;normale vers l'observateur addq.l #2,A0 move.w (A0),POLYCALCULES-POLY(A0) ;copie de la couleur addq.l #2,a0 ;point A move.w (A0)+,d0 ;x move.w (A0)+,d1 ;y move.w (A0)+,d2 ;z ;CALCUL bsr CalculerXYZ_3Axes add.w #offsetX,d4 ;emplacement ecran add.w #offsetZ,d1 move.w d4,POLYCALCULES-POLY-6(A0) ;x move.w d0,POLYCALCULES-POLY-4(A0) ;y move.w d1,POLYCALCULES-POLY-2(A0) ;z ;point B move.w (A0)+,d0 ;x move.w (A0)+,d1 ;y move.w (A0)+,d2 ;z ;CALCUL ;MACRO bsr CalculerXYZ_3Axes add.w #offsetX,d4 ;emplacement ecran add.w #offsetZ,d1 move.w d4,POLYCALCULES-POLY-6(A0) ;x move.w d0,POLYCALCULES-POLY-4(A0) ;y move.w d1,POLYCALCULES-POLY-2(A0) ;z ;point C move.w (A0)+,d0 ;x move.w (A0)+,d1 ;y move.w (A0)+,d2 ;z ;CALCUL bsr CalculerXYZ_3Axes add.w #offsetX,d4 ;emplacement ecran add.w #offsetZ,d1 move.w d4,POLYCALCULES-POLY-6(A0) ;x move.w d0,POLYCALCULES-POLY-4(A0) ;y move.w d1,POLYCALCULES-POLY-2(A0) ;z ;point D (Vecteur AB=CD), gagne 50 HBL ;---x4 add.w -3*3*2+POLYCALCULES-POLY(a0),d4 ;X3+X1 sub.w -2*3*2+POLYCALCULES-POLY(a0),d4 ;X3+X1-X2 move.w d4,POLYCALCULES-POLY(A0) ;X4 addq.l #2,a0 ;---y4 add.w -3*3*2+POLYCALCULES-POLY(a0),d0 sub.w -2*3*2+POLYCALCULES-POLY(a0),d0 move.w d0,POLYCALCULES-POLY(A0) addq.l #2,a0 ;---z4 add.w -3*3*2+POLYCALCULES-POLY(a0),d1 sub.w -2*3*2+POLYCALCULES-POLY(a0),d1 move.w d1,POLYCALCULES-POLY(A0) addq.l #2,a0 ;on passe au point suivant ;add.l #3*2,a0 dbf d7,BclCalculerPoints bra FinBclCalculerPoints NormaleVersFond: ;on calcule pas move.w #$1111,POLYCALCULES-POLY(A0) ;on met une normale vers le fond add.l #14*2,a0 dbf d7,BclCalculerPoints FinBclCalculerPoints: move.w #0,(a1) ;on marque la fin de liste par une normale à 0 movem.l (sp)+,d0-d7/a0-a6 ENDC movem.l d0-d7/a0-a6,-(sp) ;--- TRACER LES LIGNES DU RUBIKS IFD AffLigneRUBIKS moveq.l #0,d0 WAITBLIT move.w #40,BLTCMOD(A5) ;=largeur du plan de pixel en octets move.w #40,BLTDMOD(A5) ;=largeur du plan de pixel en octets move.w #$8000,BLTADAT(A5) move.w #$FFFF,BLTBDAT(A5) :texture de la droite, $FFFF = pleine move.w #$FFFF,BLTAFWM(A5) ;=$FFFF move.w #$FFFF,BLTALWM(A5) ;=$FFFF lea TableOctant(pc),a0 ;----- TRACE DU RUBIKS --------- ;1polygone = dc.w ny, coul, x1,y1,z1, , x2,y2,z2, x3,y3,z3, x4,y4,z4 ;POLYCALCULES : dc.w couleur (1..6), pointA (x,y,z), pointB (x,y,z), pointC (x,y,z), pointD (x,y,z) lea POLYCALCULES(pc),a3 BoucleTracerRubiks: move.w (A3)+,d7 beq FinDeTracerRubiks ;Normale 0 = fin de liste bpl Tracer_NormaleVersFond ;saute si d0>=0 cad normale orientee vers le fond ;on trace move.w (a3)+,d7 ;couleur move.l bitplaneB(pc),A1 ;A1 et A2 utilisés comme copie dans la boucle ;--- Couleur Plan0 btst #0,d7 ;couleur plan0 beq PasTracerPolyCouleurPlan0 ;le plan est a afficher moveq.l #0,d0 move.w 0(a3),d0 ;x1 move.w 4(a3),d1 ;z1 move.w 6(a3),d2 ;x2 move.w 10(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 6(a3),d0 ;x1 move.w 10(a3),d1 ;z1 move.w 12(a3),d2 ;x2 move.w 16(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 12(a3),d0 ;x1 move.w 16(a3),d1 ;z1 move.w 18(a3),d2 ;x2 move.w 22(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 18(a3),d0 ;x1 move.w 22(a3),d1 ;z1 move.w 0(a3),d2 ;x2 move.w 4(a3),d3 ;z2 bsr TracerLignePleine PasTracerPolyCouleurPlan0: add.l #TAILLE_BITPLANE,a1 ;--- Couleur Plan1 btst #1,d7 ;couleur plan1 beq PasTracerPolyCouleurPlan1 ;le plan est a afficher moveq.l #0,d0 move.w 0(a3),d0 ;x1 move.w 4(a3),d1 ;z1 move.w 6(a3),d2 ;x2 move.w 10(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 6(a3),d0 ;x1 move.w 10(a3),d1 ;z1 move.w 12(a3),d2 ;x2 move.w 16(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 12(a3),d0 ;x1 move.w 16(a3),d1 ;z1 move.w 18(a3),d2 ;x2 move.w 22(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 18(a3),d0 ;x1 move.w 22(a3),d1 ;z1 move.w 0(a3),d2 ;x2 move.w 4(a3),d3 ;z2 bsr TracerLignePleine PasTracerPolyCouleurPlan1: add.l #TAILLE_BITPLANE,a1 ;--- Couleur Plan2 btst #2,d7 ;couleur plan1 beq PasTracerPolyCouleurPlan2 ;le plan est a afficher moveq.l #0,d0 move.w 0(a3),d0 ;x1 move.w 4(a3),d1 ;z1 move.w 6(a3),d2 ;x2 move.w 10(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 6(a3),d0 ;x1 move.w 10(a3),d1 ;z1 move.w 12(a3),d2 ;x2 move.w 16(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 12(a3),d0 ;x1 move.w 16(a3),d1 ;z1 move.w 18(a3),d2 ;x2 move.w 22(a3),d3 ;z2 bsr TracerLignePleine moveq.l #0,d0 move.w 18(a3),d0 ;x1 move.w 22(a3),d1 ;z1 move.w 0(a3),d2 ;x2 move.w 4(a3),d3 ;z2 bsr TracerLignePleine PasTracerPolyCouleurPlan2: add.l #12*2,a3 bra BoucleTracerRubiks Tracer_NormaleVersFond: ;--- Polygone suivant add.l #13*2,a3 bra BoucleTracerRubiks FinDeTracerRubiks: ENDC ;--- TRACER LES AXES DE ROTATION IFD AffLigneRUBIKS IFD DEBUGDISPLAY_TIME lea CosinusTbl(pc),a3 lea SinusTbl(pc),A4 lea AngleAx(pc),a6 moveq.l #3-1,d7 BoucleAffAngles: move.l #290,d0 ;x1 move.l #30,d1 ;y1 move.l #20,d4 ;rayon ;ajout du pas y moveq.l #0,d5 move.w d7,d5 muls #40,d5 add.w d5,d1 moveq.l #0,d5 move.w (a6)+,d5 ;angle AX, AY, AZ add.w d5,d5 ;angle table move.w (a3,d5),d2 ;attention adressage pair muls d4,d2 lsr.l #7,d2 lsr.l #7,d2 ;x2 add.l d0,d2 move.w (a4,d5),d3 ;attention adressage pair muls d4,d3 lsr.l #7,d3 lsr.l #7,d3 ;y2 add.l d1,d3 bsr TracerLignePleine dbf d7,BoucleAffAngles ENDC ENDC movem.l (sp)+,d0-d7/a0-a6 ;--- EFFACER LE BITPLANE CACHE ------------------- IFD EffacerBitPlaneCache ;--- effacement complet (152 HBL) ; move.w #0,BLTDMOD(a5) ; move.w #$0000,BLTCON1(a5) ; move.w #%0000000100000000,BLTCON0(a5) ; move.l bitplaneC,BLTDPTH(a5) ; move.w #(DISPLAY_DX>>4)!(DISPLAY_DY<<6),BLTSIZE(a5) ;--- Effacement selectif = rubiks seul ;RayonMaxi=92 ;offsetX=160 ;offsetZ=100 ;TAILLE_BITPLANE=((DISPLAY_DX*DISPLAY_DY)>>3) OffsetOctetRAZBLT=(((offsetZ-RayonMaxi)*DISPLAY_DX)+(offsetX-RayonMaxi))/8 move.l bitplaneC(pc),a0 WAITBLIT move.w #$0000,BLTCON1(a5) move.w #%0000000100000000,BLTCON0(a5) add.l #OffsetOctetRAZBLT,a0 ;adresse de départ move.l a0,BLTDPTH(a5) move.w #(display_DX-(RayonMAxi*2))/8,BLTDMOD(a5) move.w #((RayonMaxi*2)>>4)!((RayonMaxi*2)<<6),BLTSIZE(a5) move.l bitplaneC(pc),a0 WAITBLIT move.w #$0000,BLTCON1(a5) move.w #%0000000100000000,BLTCON0(a5) add.l #OffsetOctetRAZBLT+TAILLE_BITPLANE,a0 ;adresse de départ move.l a0,BLTDPTH(a5) move.w #(display_DX-(RayonMAxi*2))/8,BLTDMOD(a5) move.w #((RayonMaxi*2)>>4)!((RayonMaxi*2)<<6),BLTSIZE(a5) move.l bitplaneC(pc),a0 WAITBLIT move.w #$0000,BLTCON1(a5) move.w #%0000000100000000,BLTCON0(a5) add.l #OffsetOctetRAZBLT+2*TAILLE_BITPLANE,a0 ;adresse de départ move.l a0,BLTDPTH(a5) move.w #(display_DX-(RayonMAxi*2))/8,BLTDMOD(a5) move.w #((RayonMaxi*2)>>4)!((RayonMaxi*2)<<6),BLTSIZE(a5) ENDC ;--- AFFICHE LE FAISCEAU EN VERT IFD DEBUGDISPLAY_RASTER move.w #$00F0,COLOR00(a5) ENDC ;********** DEBUGDISPLAYTIME (start) ********** ;affiche en décimal le nombre de lignes écoulées depuis la fin de l'écran (depuis la ligne DISPLAY_Y+DISPLAY_DY incluse) ;la trame se termine en DISPLAY_Y+DISPLAY_DY-1 ;le temps est donc compté en nombre de ligne à partir de DISPLAY_Y+DISPLAY_DY incluse IFD DEBUGDISPLAY_TIME movem.l d0-d2/a0-a3,-(sp) clr.w d0 move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmp.w #DISPLAY_Y+DISPLAY_DY,d0 bge _timeBelowBitplanes ;on est passé en haut de l'écran add.w #1+312-(DISPLAY_Y+DISPLAY_DY-1),d0 ;312 est la ligne la plus basse que peut trace le faisceau d'électrons bra _timeDisplayCounter _timeBelowBitplanes: ;on est toujours en bas de l'écran sub.w #DISPLAY_Y+DISPLAY_DY-1,d0 _timeDisplayCounter: ;=>d0.w = # de lignes prises par les calculs à afficher and.l #$0000FFFF,d0 moveq #0,d1 moveq #3-1,d2 _timeLoopNumber: divu #10,d0 ;=> d0=reste:quotient de la division de d0 sur 32 bits swap d0 add.b #$30-$20,d0 ;code ASCII de "0" moins l'offset de début dans font8 ($20) move.b d0,d1 lsl.l #8,d1 clr.w d0 swap d0 dbf d2,_timeLoopNumber divu #10,d0 ;=> d0=reste:quotient de la division de d0 sur 32 bits swap d0 add.b #$30-$20,d0 ;code ASCII de "0" moins l'offset de début dans font8 ($20) move.b d0,d1 ;=> d1 : suite des 4 offset ASCII dans la police des 4 chiffres à afficher, mais en sens inverse (ex: 123 => "3210") lea font8(pc),a0 movea.l bitplaneB(pc),a1 moveq #4-1,d0 _timeLoopDisplay: clr.w d2 move.b d1,d2 lsl.w #3,d2 lea (a0,d2.w),a2 move.l a1,a3 moveq #8-1,d2 _timeLoopDisplayChar: move.b (a2)+,(a3) lea DISPLAY_DX>>3(a3),a3 dbf d2,_timeLoopDisplayChar lea 1(a1),a1 lsr.l #8,d1 dbf d0,_timeLoopDisplay movem.l (sp)+,d0-d2/a0-a3 ENDC ;--- SOURIS PRESSEE ? btst #6,$bfe001 bne _loop ;--- ON QUITTE ------------ _loopEnd: WAITBLIT bsr RestaurerHardware bsr LibererMemoireCHIP ErrorMem: movem.l (sp)+,d0-d7/a0-a6 ;Dépiler les registres rts ;--------------------- ; ## # # ## ## ; # # # # # # ; ### # # ## ### ; # # # # # # ; ## ## ## ## ;--------------------- ;--- CALCULER X2, Y2, Z2 CalculerXYZ_3Axes: ;= rotation selon 3 axes (x, y, z, aX, aY, aZ) ;Entree : D0=x, D1=y, D2=Z ; A4=aX, A5=aY, A6=aZ ; A2=ptrTableCOS, A3=ptrTableSIN ;Sortie : D4=x, D0=y, D1=z ;Interne: D5, D6, D3 ;Amelioration ;lsr.l #7,d4 ;lsr.l #7,d4 ;remplacé par (16 cycles) ;Swap d4 ;16 cycles ;rol.l #2,d4 ;************************ ;utilisé : d0=X, d1=Y, d2=Z, a2=cos, a3=sin, A4=aX, A5=aY, a6=aZ ;************************ ;rotation axe Z (plan XY) ;x1=x*cos(aZ)-y*sin(aZ) ;y2=x*sin(aZ)+y*cos(aZ) move.w (a2,A6),d4 ;cos(aZ) move.w (a3,A6),d3 ;sin(aZ) move.w d4,d5 ;cos move.w d3,d6 ;sin muls d0,d5 ;x*cos muls d1,d6 ;y*sin sub.l d6,d5 ;x1=x*cos-y*sin Swap d5 rol.l #2,d5 muls d0,d3 ;x*sin muls d4,d1 ;y*cos add.l d3,d1 ;y1=y*cos+x*sin Swap d1 rol.l #2,d1 ;************************ ;utilisé : d1=y1, d2=Z, d5=x1, a2=cos, a3=sin, A4=aX, A5=aY ;************************ ;rotation axe X (plan YZ) ;D4=cos(A4), d3=sin(A4) ;y2=y1*cos(aX)-z*sin(ax) ;d0=D4, d0=d1*d0, d6=d3, d6=d2*d6, d0=d0-d6 ;z1=y1*sin(aX)+z*cos(aX) ;d3=d1*d3, d4=d2*d4, d3=d3+d4 move.w (a2,A4),d4 ;a4=cos(aX) move.w (a3,A4),d3 ;d3=sin(ax) move.w d4,d0 ;c move.w d3,d6 ;s muls d1,d0 ;y1*cos muls d2,d6 ;z*sin sub.l d6,d0 ;y2=y1*cos-z*sin Swap d0 ;16 cycles rol.l #2,d0 muls d1,d3 ;y*sin muls d2,d4 ;z*cos add.l d4,d3 ;z1=y*sin+z*cos Swap d3 ;16 cycles rol.l #2,d3 ;************************ ;utilisé : d0=y2, d3=z1, d5=x1, a2=cos, a3=sin, A5=aY ;************************ ;rotation axe Y (plan ZX) ;d6=cos(A5), d4=sin(A5) ;z2=z1*cos(aY)-x1*sin(aY) ,d1=d6, d1=d3*d1, d2=d4, d2=d5*d2, d1=d1-d2 ;x2=z1*sin(aY)+x1*cos(aY) ;d6=d5*d6, d4=d3*d4, d4=d6+d4 ;TODO OPTIISATION ;Faire une rotation sur 2 axes, donc blanquer le 3eme axe ;Gagne 35 VBL ;move.W d5,d4 ;move.w d3,d1 ;rts move.w (a2,A5),d6 ;cos(aY) move.w (a3,A5),d4 ;sin(aY) move.w d6,d1 move.w d4,d2 muls d3,d1 ;z1*cos muls d5,d2 ;x1*sin sub.l d2,d1 ;z2=z1*cos-x1*sin Swap d1 rol.l #2,d1 muls d3,d4 ;z1*sin muls d5,d6 ;x1*cos add.l d6,d4 ;x2=x1*cos+z1*sin Swap d4 rol.l #2,d4 ;Sortie : D0=x, D1=z, D2=y rts ;--- CALCULER Y2 (NORMALE nY) Calculer_Y_Axes_Ax_AZ: ;(D0=Y, utilisés : d0,d1,d2,d3,a2,a3,a4,a6) ;= rotation selon 2 axes (x, y, z, aX, aZ) ;utilisé pour le calcul de la normale nY, la rotation aY ne sert à rien ;Entree : D0=x, D1=y, D2=Z ; A4=aX, , A6=aZ ; A2=ptrTableCOS, A3=ptrTableSIN ;Sortie : D0=y ;Interne: D5, D6, D3 ; ;rotation axe Z (plan XY) move.w (a3,A6),d3 ;sin(aZ) muls d0,d3 ;x*sin move.w (a2,A6),d0 ;cos(aZ) muls d0,d1 ;y*cos add.l d3,d1 ;y1=x*sin(aZ)+y*cos(aZ) Swap d1 rol.l #2,d1 ;rotation axe X (plan YZ) move.w (a2,A4),d0 ;cos(aX) muls d1,d0 ;y1*cos move.w (a3,A4),d1 ;sin(ax) muls d2,d1 ;z*sin sub.l d1,d0 ;y2=y1*cos(aX)-z*sin(aX) Swap d0 rol.l #2,d0 ;y2=y1*cos(aX)-z*sin(ax) ;sortie rts ;D0=y ;--- TRACER LIGNE PLEINE AU BLITTER TracerLignePleine: ;Entree (d0=x1,d1=y1,d2=x2,d3=y2, a1=adresse du bitplane) ;utilisés en lecture : a1, a5 ; en écriture : d0..d6, a0, a1, a2 move.l a1,a2 ;BitplaneB ; ------------------------------ ; BIT# BLTCON0 BLTCON1 ; ---- ------- ------- ; 15 START3 TEXTURE3 ; 14 START2 TEXTURE2 ; 13 START1 TEXTURE1 ; 12 START0 TEXTURE0 ; 11 1 0 ; 10 0 0 ; 09 1 0 ; 08 1 0 ; 07 LF7 0 ; 06 LF6 SIGN ; 05 LF5 0 (Reserved) ; 04 LF4 SUD ; 03 LF3 SUL ; 02 LF2 AUL ; 01 LF1 SING ; 00 LF0 LINE(=1) = LINE DRAW ;---- Calculer Octant ---- moveq.l #0,d4 ;4 cycles sub.w d1,d3 ;d3=dy=y2-y1 bpl.b y2_sup_y1 bset #2,d4 ;8 cycles neg.w d3 ;d3=abs(dy) y2_sup_y1: sub.w d0,d2 ;d2=dx=x2-x1 bpl.b x2_sup_x1 bset #1,d4 neg.w d2 ;d2=abs(dx) x2_sup_x1: cmp.w d3,d2 ;D3=dy vs D2=dx bpl.b dX_sup_dY bset #0,d4 exg d2,d3 dX_sup_dY: move.b (a0,d4),d5 ;octant dans D5 ;d0=x1, d1=y1 ;d2=dx=GRAND DELTA, d3=dy=petit delta ;d5=octant ;--- Calculer Adresse de départ ---- ror.l #4,d0 ;move upper four bits into hi word add.w d0,d0 ;d0=d0*2 car d0 contient le nb de mots --> devient nb d'octets add.l d0,a2 ;bitplaneB+x1/8 modulo 16 pix (l'adressage étant sur 24 bits les 4 bits HI n'influent pas) lsl.w #3,d1 ;d1=y1*8 add.w d1,a2 ;A2=bitplaneB+(x1/8)+y1*8 add.w d1,d1 ;d1=y1*16 add.w d1,d1 ;d1=y1*32 add.l d1,a2 ;a2=bitplaneB+(x1/8)+y1*40 = adresse de départ moveq.l #0,d6 ;RAZ d6 add.w d3,d3 ;d3=dy*2 add.w d3,d3 ;d3=dy*4 ;;lsl.w #2,d3 ;10 cycles move.w D3,D4 ;D4=4*dy move.w d2,d1 ;d1=d2=dX add.w #$01,d2 ;dx+1 lsl.w #6,d2 ;(dx+1)*64 ; 20 cycles add.w #$02,d2 ;(dx+1)*64+2 add.w d1,d1 ;lsl.w #1,d1 ;D1=2*dx sub.w d1,D3 ;| d3=4*dy - 2*dx roxl.w #7,D6 ;| si D3<0, placer le bit SIGN à 1 dans BLTCON1 add.w d1,d1 ;D1=2*2dx or.w d6,d5 ;%xxxx000000xxxx01 ;bit 1 = 1 point par ligne ;dans Tableoctant pour éviter bset #1,d5 swap d0 or.w d6,D0 or.w #$0BCA,D0 WAITBLIT ;move.l d0,BLTCON0(A5) ;TODO voir si gain de charger BLTCON0 et CON1 en meme temps move.w d0,BLTCON0(A5) ;bits 15,14,13,12 = point de départ de la droite move.w d5,BLTCON1(A5) ;bits 15,14,13, 12 = point de départ de la droite move.w d4,BLTBMOD(A5) ;=4*dy move.l d3,BLTAPTH(A5) ;=4*dY-2*dX, sub.w d1,D4 ;d4=4*dy-4*dx move.w d4,BLTAMOD(A5) ;=4*dy-4*dx move.l a2,BLTCPTH(A5) ;adresse du point de départ de la droite move.l a2,BLTDPTH(A5) ;idem move.w d2,BLTSIZE(A5) ;c'est parti = (dX+1)*64+2 rts TableOctant: ;3 premiers bits=octant, bit1 = 1 si 1 pt /ligne, bit 0=1 mode tracé de ligne dc.b %10001 dc.b %00001 dc.b %10101 dc.b %01001 dc.b %11001 dc.b %00101 dc.b %11101 dc.b %01101 even ;--- Afficher un Texte 8x8 ;A2=adresse dans le bitplane ;A3=adresse du texte à afficher ;utilisé : d0, a0 AfficherTexte8x8: moveq.l #0,d0 move.b (a3)+,d0 ;on lit le caratère beq _finTexte ;si 0 on est la fin du texte sub.b #$20,d0 ;la table commence au caractère " " lsl.w #3,d0 ;8 octets / caractère lea font8(pc),a0 add.l d0,a0 move.w #8-1,d0 .aff8x8: move.b (A0)+,(A2) add.l #DISPLAY_DX>>3,a2 ;ligne suivante dbf d0,.aff8x8 ;fin de cara sub.l #(DISPLAY_DX>>3)*8-1,a2 ;position car suivant bra AfficherTexte8x8 _FinTexte: rts TexteArnaud2020: dc.b "Rubiks 3D - Arnaud.68000 - " dc.b "2020-11-27" dc.b 0 even TexteAngle: dc.b "Angle",0 even ;--- Reserver la memoire ReserverMemoireCHIP: ;Memoire pour copperlist et bitPlanes move.l #TAILLE_MEM_RESERVEE,d0 move.l #$10002,d1 jsr AllocMem(a6) move.l d0,copperlist_PTR beq ErrorMem ;calcul du pointeur BitPlanes de la copperList move.l d0,d1 add.l #CplBitPlanes-CopListDataStart,d1 ;move.l d1,Copperlist_BitPlanes_PTR add.l #COPSIZE,d0 move.l d0,bitplaneA add.l #DISPLAY_DEPTH*TAILLE_BITPLANE,d0 move.l d0,bitplaneB add.l #DISPLAY_DEPTH*TAILLE_BITPLANE,d0 move.l d0,bitplaneC ;memoire pour la police de caractères TAILLE_FONT16 = 256<<5 move.l #TAILLE_FONT16,d0 move.l #$10002,d1 jsr AllocMem(a6) move.l d0,Font16_PTR rts ;--- Libérer la mémoire LibererMemoireCHIP: ;Copper et bitplane movea.l Copperlist_PTR(pc),a1 move.l #TAILLE_MEM_RESERVEE,d0 jsr FreeMem(a6) ;font 16 movea.l Font16_PTR,a1 move.l #TAILLE_FONT16,d0 jsr FreeMem(a6) rts ;--- Couper et Restaurer le Hardware CouperHardware: ;Couper le système multi-taches jsr Forbid(a6) ;Couper le hardware move.w INTENAR(a5),intena_PTR move.w #$7FFF,INTENA(a5) move.w INTREQR(a5),intreq_PTR move.w #$7FFF,INTREQ(a5) move.w DMACONR(a5),dmacon_PTR move.w #$07FF,DMACON(a5) rts RestaurerHardware: movea.l $4.w,a6 ;Couper le hardware move.w #$7FFF,INTENA(a5) move.w #$7FFF,INTREQ(a5) move.w #$07FF,DMACON(a5) ;Rétablir le hardware move.w dmacon_PTR,d0 bset #15,d0 move.w d0,DMACON(a5) move.w intreq_PTR,d0 bset #15,d0 move.w d0,INTREQ(a5) move.w intena_PTR,d0 bset #15,d0 move.w d0,INTENA(a5) ;Rétablir la Copper list lea graphicslibrary(pc),a1 jsr OldOpenLibrary(a6) ;-408 move.l d0,a1 move.l 38(a1),COP1LCH(a5) clr.w COPJMP1(a5) jsr CloseLib(a6) ;-414 ;Rétablir le système multi-taches jsr Permit(a6) rts ;--- Creer et activer la Copper list ---------- InitiliserCopperList: ;copie les adresses des 3 premiers bitplanes dans copperlist moveq #DISPLAY_DEPTH-1,d1 lea bitplaneA(pc),a0 lea CplBitPlanes,a1 ;adresse de CplBitPlanes add.l #2,a1 .l1: move.l (a0)+,d0 ;adresse du pitplane move.w d0,(a1) ;poids faible swap d0 add.l #4,a1 move.w d0,(a1) ;poids fort add.l #4,a1 add.l #TAILLE_BITPLANE,a0 ;plan suivant du bitplaneA dbf d1,.l1 ;transferer la copperlist en Chip ; move.l #COPSIZE-1,d0 ; lea CopListDataStart,a0 ; movea.l copperlist_PTR(pc),a1 ;.l2: ; move.b (a0)+,(a1)+ ; dbf d0,.l2 ;Activer la Copper list ; move.l copperlist_PTR(pc),COP1LCH(a5) move.l #CopListDataStart,COP1LCH(a5) clr.w COPJMP1(a5) move.w #$83C0,DMACON(a5) ;DMAEN=1, COPEN=1, BPLEN=1, COPEN=1, BLTEN=1 rts ;---------- Création d'une police 16x16 à partir d'une police 8x8 ---------- CreerPolice16x16: ;Préparer les données de la police ;1er octet = suite des bits 7 des 8 lignes / octets du caractère, ;2ème octet = suite des bits 6 des 8 lignes / octets du caractère, etc. ;rotation de -90°). ;Noter qu'au Blitter il faudra donc tracer les colonnes de la dernière à la première ligne ;du fait de l'orientation du motif. ;il faudrait lui appliquer une symétrie d'axe Y avant pour tracer de la première à la dernière ligne lea font8(pc),a0 move.l Font16_PTR(pc),a1 move.w #256-1,d0 _fontLoop: moveq #7,d1 ; _fontLineLoop: clr.w d5 clr.w d3 clr.w d4 _fontColumnLoop: move.b (a0,d5.w),d2 ; btst d1,d2 ;on teste le bit D1 beq _fontPixelEmpty bset d4,d3 ; addq.b #1,d4 bset d4,d3 addq.b #1,d4 bra _fontPixelNext _fontPixelEmpty: addq.b #2,d4 _fontPixelNext: addq.b #1,d5 btst #4,d4 beq _fontColumnLoop move.w d3,(a1)+ move.w d3,(a1)+ dbf d1,_fontLineLoop lea 8(a0),a0 dbf d0,_fontLoop rts ;---------- Données ---------- ;--- COMPTEUR WAITBLIT IFNE CTR CTRWait: dc.l 0 ENDC graphicslibrary: DC.B "graphics.library",0 EVEN font8: INCBIN "font8.fnt" ;32 à 127 EVEN Texte_Char: DC.B "Quelle satisfaction de refaire de l'assembleur 68000 ! ... ",0 dc.b "Bug si affiche",0 EVEN TEXT_POS: dc.l 0 dmacon_PTR: DC.w 0 intena_PTR: DC.w 0 intreq_PTR: DC.w 0 scrollColumn: DC.W 0 scrollChar: DC.W 0 angle: DC.W 0 copperlist_PTR: DC.L 0 Copperlist_BitPlanes_PTR: dc.l CplBitPlanes Font16_PTR: DC.L 0 bitplaneA: DC.L 0 bitplaneB: DC.L 0 bitplaneC: DC.L 0 ********************* COPPER LIST ********************* CopListDataStart: ;Comptabilité ECS avec AGA dc.w FMODE,$0000 ;Configuration de l'écran dc.w DIWSTRT,(DISPLAY_Y<<8)!DISPLAY_X ; & = AND, ! = OR , ~ = EOR dc.w DIWSTOP,((DISPLAY_Y+DISPLAY_DY-256)<<8)!(DISPLAY_X+DISPLAY_DX-256) dc.w DDFSTRT,((DISPLAY_X-17)>>1)&$00FC dc.w DDFSTOP,((DISPLAY_X-17+(((DISPLAY_DX>>4)-1)<<4))>>1)&$00FC ;Ce qui revient ((DISPLAY_X-17+DISPLAY_DX-16)>>1)&$00FC si DISPLAY_DX est multiple de 16 dc.w BPLCON0,(DISPLAY_DEPTH<<12)!$0200 dc.w BPLCON1,SHADOW_DX<<4 ;PF2H=Playfield 2 horizontal scroll code dc.w BPLCON2,0 dc.w BPL1MOD,0 dc.w BPL2MOD,0 ;Adresse des bitplanes CplBitPlanes: dc.w BPL1PTL,0 dc.w BPL1PTH,0 dc.w BPL2PTL,0 dc.w BPL2PTH,0 dc.w BPL3PTL,0 dc.w BPL3PTH,0 ;Couleurs IFD DEBUGDISPLAY_RASTER dc.w COLOR08,0 ;pas utilisée, pour neutraliser de manière quelconque la modification de COLOR00... ENDC IFND DEBUGDISPLAY_RASTER dc.w COLOR00,0 ENDC dc.w COLOR01,$FFF ;SCROLL_COLOR dc.w COLOR02,$F00 ;rouge ;SHADOW_COLOR dc.w COLOR03,$0F0 ;Vert dc.w COLOR04,$00F ;bleu dc.w COLOR05,$F0F ; dc.w COLOR06,$FF0 dc.w COLOR07,$0FF ;Ombre et miroir dc.w ((DISPLAY_Y+SCROLL_Y+SHADOW_DY-1)<<8)!$000F,$FFFE dc.w BPL2MOD,-SHADOW_DY*(DISPLAY_DX>>3) dc.w ((DISPLAY_Y+SCROLL_Y+SHADOW_DY)<<8)!$000F,$FFFE dc.w BPL2MOD,0 dc.w BPLCON1,SHADOW_DX<<4 dc.w ((DISPLAY_Y+MIRROR_Y-1)<<8)!$000F,$FFFE dc.w BPL1MOD,-(DISPLAY_DX>>3) dc.w BPL2MOD,(SHADOW_DY-1)*(DISPLAY_DX>>3) dc.w ((DISPLAY_Y+MIRROR_Y)<<8)!$000F,$FFFE dc.w BPLCON1,$0000 dc.w BPL1MOD,-(DISPLAY_DX>>2) dc.w BPL2MOD,-(DISPLAY_DX>>2) IFD DEBUGDISPLAY_RASTER dc.w COLOR08,MIRROR_COLOR ;COLOR08 pas utilisée, pour neutraliser de manière quelconque la modification de COLOR00... ENDC IFND DEBUGDISPLAY_RASTER dc.w COLOR00,MIRROR_COLOR ENDC dc.w COLOR01,MIRROR_SCROLL_COLOR dc.w COLOR02,MIRROR_SCROLL_COLOR dc.w COLOR03,MIRROR_SCROLL_COLOR ;dc.w COLOR04,MIRROR_SCROLL_COLOR dc.w COLOR05,MIRROR_SCROLL_COLOR dc.w COLOR06,MIRROR_SCROLL_COLOR dc.w COLOR07,MIRROR_SCROLL_COLOR ;Fin dc.l $FFFFFFFE ; dc.l $00c0ffEE CopListDataEnd: COPSIZE=*-CopListDataStart TAILLE_MEM_RESERVEE=COPSIZE+(3*DISPLAY_DEPTH*TAILLE_BITPLANE) ;---- Angles de rotation objet Angles: AngleAx: dc.w InitAngleAx AngleAy: dc.w InitAngleAy AngleAz: dc.w InitAngleAz ;----- Tables Trigo ----- SinusTbl: dc.w 0,285,571,857,1142,1427,1712,1996,2280,2563 ;Sin(0) ou Cos(-90) dc.w 2845,3126,3406,3685,3963,4240,4516,4790,5062,5334 ;Sin(10) ou Cos(-80) dc.w 5603,5871,6137,6401,6663,6924,7182,7438,7691,7943 ;Sin(20) ou Cos(-70) dc.w 8191,8438,8682,8923,9161,9397,9630,9860,10086,10310 ;Sin(30) ou Cos(-60) dc.w 10531,10748,10963,11173,11381,11585,11785,11982,12175,12365 ;Sin(40) ou Cos(-50) dc.w 12550,12732,12910,13084,13254,13420,13582,13740,13894,14043 ;Sin(50) ou Cos(-40) dc.w 14188,14329,14466,14598,14725,14848,14967,15081,15190,15295 ;Sin(60) ou Cos(-30) dc.w 15395,15491,15582,15668,15749,15825,15897,15964,16025,16082 ;Sin(70) ou Cos(-20) dc.w 16135,16182,16224,16261,16294,16321,16344,16361,16374,16381 ;Sin(80) ou Cos(-10) CosinusTbl: dc.w 16384,16381,16374,16361,16344,16321,16294,16261,16224,16182 ;Sin(90) ou Cos(0) dc.w 16135,16082,16025,15964,15897,15825,15749,15668,15582,15491 ;Sin(100) ou Cos(10) dc.w 15395,15295,15190,15081,14967,14848,14725,14598,14466,14329 ;Sin(110) ou Cos(20) dc.w 14188,14043,13894,13740,13582,13420,13254,13084,12910,12732 ;Sin(120) ou Cos(30) dc.w 12550,12365,12175,11982,11785,11585,11381,11173,10963,10748 ;Sin(130) ou Cos(40) dc.w 10531,10310,10086,9860,9630,9397,9161,8923,8682,8438 ;Sin(140) ou Cos(50) dc.w 8191,7943,7691,7438,7182,6924,6663,6401,6137,5871 ;Sin(150) ou Cos(60) dc.w 5603,5334,5062,4790,4516,4240,3963,3685,3406,3126 ;Sin(160) ou Cos(70) dc.w 2845,2563,2280,1996,1712,1427,1142,857,571,285 ;Sin(170) ou Cos(80) dc.w 0,-286,-572,-858,-1143,-1428,-1713,-1997,-2281,-2564 ;Sin(180) ou Cos(90) dc.w -2846,-3127,-3407,-3686,-3964,-4241,-4517,-4791,-5063,-5335 ;Sin(190) ou Cos(100) dc.w -5604,-5872,-6138,-6402,-6664,-6925,-7183,-7439,-7692,-7944 ;Sin(200) ou Cos(110) dc.w -8193,-8439,-8683,-8924,-9162,-9398,-9631,-9861,-10087,-10311 ;Sin(210) ou Cos(120) dc.w -10532,-10749,-10964,-11174,-11382,-11586,-11786,-11983,-12176,-12366 ;Sin(220) ou Cos(130) dc.w -12551,-12733,-12911,-13085,-13255,-13421,-13583,-13741,-13895,-14044 ;Sin(230) ou Cos(140) dc.w -14189,-14330,-14467,-14599,-14726,-14849,-14968,-15082,-15191,-15296 ;Sin(240) ou Cos(150) dc.w -15396,-15492,-15583,-15669,-15750,-15826,-15898,-15965,-16026,-16083 ;Sin(250) ou Cos(160) dc.w -16136,-16183,-16225,-16262,-16295,-16322,-16345,-16362,-16375,-16382 ;Sin(260) ou Cos(170) dc.w -16384,-16382,-16375,-16362,-16345,-16322,-16295,-16262,-16225,-16183 ;Sin(270) ou Cos(180) dc.w -16136,-16083,-16026,-15965,-15898,-15826,-15750,-15669,-15583,-15492 ;Sin(280) ou Cos(190) dc.w -15396,-15296,-15191,-15082,-14968,-14849,-14726,-14599,-14467,-14330 ;Sin(290) ou Cos(200) dc.w -14189,-14044,-13895,-13741,-13583,-13421,-13255,-13085,-12911,-12733 ;Sin(300) ou Cos(210) dc.w -12551,-12366,-12176,-11983,-11786,-11586,-11382,-11174,-10964,-10749 ;Sin(310) ou Cos(220) dc.w -10532,-10311,-10087,-9861,-9631,-9398,-9162,-8924,-8683,-8439 ;Sin(320) ou Cos(230) dc.w -8193,-7944,-7692,-7439,-7183,-6925,-6664,-6402,-6138,-5872 ;Sin(330) ou Cos(240) dc.w -5604,-5335,-5063,-4791,-4517,-4241,-3964,-3686,-3407,-3127 ;Sin(340) ou Cos(250) dc.w -2846,-2564,-2281,-1997,-1713,-1428,-1143,-858,-572,-286 ;Sin(350) ou Cos(260) dc.w -1,285,571,857,1142,1427,1712,1996,2280,2563 ;Sin(360) ou Cos(270) dc.w 2845,3126,3406,3685,3963,4240,4516,4790,5062,5334 ;Sin(370) ou Cos(280) dc.w 5603,5871,6137,6401,6663,6924,7182,7438,7691,7943 ;Sin(380) ou Cos(290) dc.w 8191,8438,8682,8923,9161,9397,9630,9860,10086,10310 ;Sin(390) ou Cos(300) dc.w 10531,10748,10963,11173,11381,11585,11785,11982,12175,12365 ;Sin(400) ou Cos(310) dc.w 12550,12732,12910,13084,13254,13420,13582,13740,13894,14043 ;Sin(410) ou Cos(320) dc.w 14188,14329,14466,14598,14725,14848,14967,15081,15190,15295 ;Sin(420) ou Cos(330) dc.w 15395,15491,15582,15668,15749,15825,15897,15964,16025,16082 ;Sin(430) ou Cos(340) dc.w 16135,16182,16224,16261,16294,16321,16344,16361,16374,16381 ;Sin(440) ou Cos(350) ; ------------------------------------------------------------------------- ; ; ____________ ; / / / /| /|\Z _ Y ; /___/___/___/ | | /| ; / / / /| | aZ1 / ; /___/___/___/ |/| | aY1 ; / / / /| | | | / ; /___/___/___/ |/|/| |/ ; | | | | | | | aX2 -----|---- aX1 ----> X ; |___|___|___|/|/|/ /| ; | | | | ||/ / | ; |___|___|___|/|/ aY2 | ; | | | | / aZ2 ; |___|___|___|/ ; ; ; ; ;AXES DE ROTATION ;NumAxeRot=n, aX1=1, aY1=2, aZ1=3, aX2=4, aY2=5, aZ2=6 ; aX1=1 aY1=2 aZ1=3 aX2=4 aY2=5 aZ2=6 ; ;TABLE DE ROTATIONS ; ; Axe 0,aX1,aY1,aZ1,aX2,aY2,aZ2 ;ROT Devient TableDeRotations: aXiP: dc.w 0,aX1,aZ1,aY2,aX2,aZ2,aY1 aXim: dc.w 0,aX1,aZ2,aY1,aX2,aZ1,aY2 aYiP: dc.w 0,aZ2,aY1,aX1,aZ1,aY2,aX2 aYim: dc.w 0,aZ1,aY1,aX2,aZ2,aY2,aX1 aZiP: dc.w 0,aY1,aX2,aZ1,aY2,aX1,aZ2 aZim: dc.w 0,aY2,aX1,aZ1,aY1,aX2,aZ2 ; ;DEFINITION DU RUBIKS ; ;objet = rubik de 26 pièces ;.piece #1 ;.à ;.piece #26 ;.AxeDeRotationEnCours = element de (aX1, .. , aZ2) ;.VitessDeRotation = +/- n ;.ValeurDeRotation ;piece ;.type (1 centre, 2 bord, 3 coin) ;.nbPolygones ;.polygone_1 ;centre = 1 polygone (Q=6) ;.polygone_2 ;bord = 2 polygones (Q=12) ;.polygone_3 ;coin = 3 polygones (Q=8) ;.axeDeRotation_1 = NumAxeRot (0 si non utilisé) ;.axeDeRotation_2 = NumAxeRot (0 si non utilisé) ;.axeDeRotation_3 = NumAxeRot (0 si non utilisé) ;polygone (carre Q=56) ;.normale (x,y,z) ;.couleur (1..6) ;.pointA1 (x,y,z) ;.pointA2 (x,y,z) ;.pointB1 (x,y,z) ;.pointB2 (x,y,z) ;polygoneSauvePourRotation (Q=21) ;.normale (x,y,z) ;.couleur (1..6) ;.pointA1 (x,y,z) ;.pointA2 (x,y,z) ;.pointB1 (x,y,z) ;.pointB2 (x,y,z) ;polygoneCalcules (=nb de polygones) ;.normale (x,y,z) ;.couleur (1..6) = polygone.couleur ;.pointA1 (x,y,z) ;.pointA2 (x,y,z) ;.pointB1 (x,y,z) ;.pointB2 (x,y,z) ;*********************************************** ;ALGO GENERAL ; ;Si besoin : démarrer une rotation de couronne ; identifier les pièces concernées et faire une copie de leurs polygones ;si rotation de couronne démarrée ; incrémenter angle rotation ; calculer les polygones ;Tourner la couronne selon si son axe est en rotation ;calculer (rotation ax,ay,az) les normales des faces ;garder que les faces dont les normales sont orientées vers l'observateur ;calculer les coordonnées (rotation ax,ay,az) des points ;afficher les faces de la plus loin à la plus proche de l'observateur ;*********************************************** ;INITIALISER UNE ROTATION DE D'AXE ; ;objet.AxeDeRotationEnCours = Axe de rotation à tourner =(aX1, .. , aZ2) ; .VitessDeRotation = +/- n (incrément d'angle) ; .ValeurDeRotation= 0 ; ;sauve les polygones qui vont être impactés par la rotation ; pour chaque Pce de Piece ; si Pce.axeDeRotation_n = objet.AxeDeRotationEnCours alors ; pour i=1 à pce.nbPolygones ; polygoneSauvePourRotation = pce.polygone_n ;*********************************************** ;ROTATION DE PIECE ; ;si Objet.AxeDeRotationEnCours <> 0 ; objet.ValeurDeRotation += objet.VitessDeRotation ; ; pour chaque pce de piece ; ; si Objet.AxeDeRotationEnCours = pce.axeDeRotation_i alors ; ;l'objet a son axe de rotation concerné ; ; pour chaque poly de piece.polygone_n ; ;on tourne les points dans le nouveau repère ; poly = rot(polygoneSauvePourRotation, objet.AxeDeRotationEnCours, objet.ValeurDeRotation) ; ; si objet.ValeurDeRotation = 90 ou -90 alors ; ;rotation terminée ; pour chaque axe de pce.axeDeRotation_i ; ;on spécifie les nouveaux axes des pièces tournées ; axe = TableDeRotation(objet.AxeDeRotationEnCours, axe) ; ;on met fin à la rotation en cours ; objet.AxeDeRotationEnCours=0 ; Objet.ValeurDeRotation=0 ; fin si ; fin si ; fin pour ;fin si ;*********************************************** ;CALCULER LES NORMALES selon angles ax, ay, az ; ;pour chaque Poly de polygones ; polygoneCalcule.normale = rotation(poly.normale, ax, ay, az) ; si polygoneCalcule.normale vers observateur (donc visible) alors ; polygoneCalcule.pointAn = rotation(poly.pointAn, ax, ay, az) ; polygoneCalcule.pointBn = rotation(poly.pointBn, ax, ay, az) ; tracer trait(polygoneCalcule.pointA1, polygoneCalcule.pointA2, polygoneCalcule.couleur) 'en mode un point par ligne ; tracer trait(polygoneCalcule.pointB1, polygoneCalcule.pointB2, polygoneCalcule.couleur) ; Remplir les Polygones ***************** ** DEFINITION DU RUBIKS ***************** ; 1 Rubik Rubiks.AxeDeRotationEnCours: dc.w 0 Rubiks.VitessDeRotation: dc.w 0 Rubiks.ValeurDeRotation: dc.w 0 ***************** ; 26 Pieces ;.type (1 centre, 2 bord, 3 coin)=.nbPolygones, .polygone_1, .polygone_2, .polygone_3, .axeDeRotation_1, .axeDeRotation_2, .axeDeRotation_3 PIECE: PCE111: dc.w 3,P111aX2-POLY,P111aY2-POLY,P111aZ2-POLY,aX2,aY2,aZ2 PCE211: dc.w 2,P211aY2-POLY,P211aZ2-POLY,0,aY2,aZ2,aZ2 PCE311: dc.w 3,P311aX1-POLY,P311aY2-POLY,P311aZ2-POLY,aX1,aY2,aZ2 PCE121: dc.w 2,P121aX2-POLY,P121aZ2-POLY,0,aX2,aZ2,aZ2 PCE221: dc.w 1,P221aZ2-POLY,0,0,aZ2,aZ2,aZ2,0 PCE321: dc.w 2,P321aX1-POLY,P321aZ2-POLY,0,aX1,aZ2,aZ2 PCE131: dc.w 3,P131aX2-POLY,P131aY1-POLY,P131aZ2-POLY,aX2,aY1,aZ2 PCE231: dc.w 2,P231aY1-POLY,P231aZ2-POLY,0,aY1,aZ2,aZ2 PCE331: dc.w 3,P331aX1-POLY,P331aY1-POLY,P331aZ2-POLY,aX1,aY1,aZ2 PCE112: dc.w 2,P112aX2-POLY,P112aY2-POLY,0,aX2,aY2,aZ2 PCE212: dc.w 1,P212aY2-POLY,0,0,aY2,aY2,aZ2,0 PCE312: dc.w 2,P312aX1-POLY,P312aY2-POLY,0,aX1,aY2,aZ2 PCE122: dc.w 1,P122aX2-POLY,0,0,aX2,aY2,aZ2,0 PCE322: dc.w 1,P322aX1-POLY,0,0,aX1,aY2,aZ2,0 PCE132: dc.w 2,P132aX2-POLY,P132aY1-POLY,0,aX2,aY1,aZ2 PCE232: dc.w 1,P232aY1-POLY,0,0,aY1,aY1,aZ2,0 PCE332: dc.w 2,P332aX1-POLY,P332aY1-POLY,0,aX1,aY1,aZ2 PCE113: dc.w 3,P113aX2-POLY,P113aY2-POLY,P113aZ1-POLY,aX2,aY2,aZ1 PCE213: dc.w 2,P213aY2-POLY,P213aZ1-POLY,0,aY2,aZ1,aZ1 PCE313: dc.w 3,P313aX1-POLY,P313aY2-POLY,P313aZ1-POLY,aX1,aY2,aZ1 PCE123: dc.w 2,P123aX2-POLY,P123aZ1-POLY,0,aX2,aZ1,aZ1 PCE223: dc.w 1,P223aZ1-POLY,0,0,aZ1,aZ1,aZ1,0 PCE323: dc.w 2,P323aX1-POLY,P323aZ1-POLY,0,aX1,aZ1,aZ1 PCE133: dc.w 3,P133aX2-POLY,P133aY1-POLY,P133aZ1-POLY,aX2,aY1,aZ1 PCE233: dc.w 2,P233aY1-POLY,P233aZ1-POLY,0,aY1,aZ1,aZ1 PCE333: dc.w 3,P333aX1-POLY,P333aY1-POLY,P333aZ1-POLY,aX1,aY1,aZ1 ***************** ; 54 Polygones ;.normaleY,.couleur (1..6),.pointA1 (x,y,z),.pointA2 (x,y,z),.pointB1 (x,y,z),.pointB2 (x,y,z) POLY: P111aX2: dc.w NaX2-Normales,3,-53,-50,-50,-53,-18,-50,-53,-18,-18,-53,-50,-18 P121aX2: dc.w NaX2-Normales,3,-53,-16,-50,-53,16,-50,-53,16,-18,-53,-16,-18 P131aX2: dc.w NaX2-Normales,3,-53,18,-50,-53,50,-50,-53,50,-18,-53,18,-18 P112aX2: dc.w NaX2-Normales,3,-53,-50,-16,-53,-18,-16,-53,-18,16,-53,-50,16 P122aX2: dc.w NaX2-Normales,3,-53,-16,-16,-53,16,-16,-53,16,16,-53,-16,16 P132aX2: dc.w NaX2-Normales,3,-53,18,-16,-53,50,-16,-53,50,16,-53,18,16 P113aX2: dc.w NaX2-Normales,3,-53,-50,18,-53,-18,18,-53,-18,50,-53,-50,50 P123aX2: dc.w NaX2-Normales,3,-53,-16,18,-53,16,18,-53,16,50,-53,-16,50 P133aX2: dc.w NaX2-Normales,3,-53,18,18,-53,50,18,-53,50,50,-53,18,50 P111aY2: dc.w NaY2-Normales,2,-50,-53,-50,-18,-53,-50,-18,-53,-18,-50,-53,-18 P211aY2: dc.w NaY2-Normales,2,-16,-53,-50,16,-53,-50,16,-53,-18,-16,-53,-18 P311aY2: dc.w NaY2-Normales,2,18,-53,-50,50,-53,-50,50,-53,-18,18,-53,-18 P112aY2: dc.w NaY2-Normales,2,-50,-53,-16,-18,-53,-16,-18,-53,16,-50,-53,16 P212aY2: dc.w NaY2-Normales,2,-16,-53,-16,16,-53,-16,16,-53,16,-16,-53,16 P312aY2: dc.w NaY2-Normales,2,18,-53,-16,50,-53,-16,50,-53,16,18,-53,16 P113aY2: dc.w NaY2-Normales,2,-50,-53,18,-18,-53,18,-18,-53,50,-50,-53,50 P213aY2: dc.w NaY2-Normales,2,-16,-53,18,16,-53,18,16,-53,50,-16,-53,50 P313aY2: dc.w NaY2-Normales,2,18,-53,18,50,-53,18,50,-53,50,18,-53,50 P111aZ2: dc.w NaZ2-Normales,6,-50,-50,-53,-18,-50,-53,-18,-18,-53,-50,-18,-53 P211aZ2: dc.w NaZ2-Normales,6,-16,-50,-53,16,-50,-53,16,-18,-53,-16,-18,-53 P311aZ2: dc.w NaZ2-Normales,6,18,-50,-53,50,-50,-53,50,-18,-53,18,-18,-53 P121aZ2: dc.w NaZ2-Normales,6,-50,-16,-53,-18,-16,-53,-18,16,-53,-50,16,-53 P221aZ2: dc.w NaZ2-Normales,6,-16,-16,-53,16,-16,-53,16,16,-53,-16,16,-53 P321aZ2: dc.w NaZ2-Normales,6,18,-16,-53,50,-16,-53,50,16,-53,18,16,-53 P131aZ2: dc.w NaZ2-Normales,6,-50,18,-53,-18,18,-53,-18,50,-53,-50,50,-53 P231aZ2: dc.w NaZ2-Normales,6,-16,18,-53,16,18,-53,16,50,-53,-16,50,-53 P331aZ2: dc.w NaZ2-Normales,6,18,18,-53,50,18,-53,50,50,-53,18,50,-53 P311aX1: dc.w NaX1-Normales,%001,53,-50,-50,53,-18,-50,53,-18,-18,53,-50,-18 P321aX1: dc.w NaX1-Normales,%001,53,-16,-50,53,16,-50,53,16,-18,53,-16,-18 P331aX1: dc.w NaX1-Normales,%001,53,18,-50,53,50,-50,53,50,-18,53,18,-18 P312aX1: dc.w NaX1-Normales,%001,53,-50,-16,53,-18,-16,53,-18,16,53,-50,16 P322aX1: dc.w NaX1-Normales,%001,53,-16,-16,53,16,-16,53,16,16,53,-16,16 P332aX1: dc.w NaX1-Normales,%001,53,18,-16,53,50,-16,53,50,16,53,18,16 P313aX1: dc.w NaX1-Normales,%001,53,-50,18,53,-18,18,53,-18,50,53,-50,50 P323aX1: dc.w NaX1-Normales,%001,53,-16,18,53,16,18,53,16,50,53,-16,50 P333aX1: dc.w NaX1-Normales,%001,53,18,18,53,50,18,53,50,50,53,18,50 P131aY1: dc.w NaY1-Normales,4,-50,53,-50,-18,53,-50,-18,53,-18,-50,53,-18 P231aY1: dc.w NaY1-Normales,4,-16,53,-50,16,53,-50,16,53,-18,-16,53,-18 P331aY1: dc.w NaY1-Normales,4,18,53,-50,50,53,-50,50,53,-18,18,53,-18 P132aY1: dc.w NaY1-Normales,4,-50,53,-16,-18,53,-16,-18,53,16,-50,53,16 P232aY1: dc.w NaY1-Normales,4,-16,53,-16,16,53,-16,16,53,16,-16,53,16 P332aY1: dc.w NaY1-Normales,4,18,53,-16,50,53,-16,50,53,16,18,53,16 P133aY1: dc.w NaY1-Normales,4,-50,53,18,-18,53,18,-18,53,50,-50,53,50 P233aY1: dc.w NaY1-Normales,4,-16,53,18,16,53,18,16,53,50,-16,53,50 P333aY1: dc.w NaY1-Normales,4,18,53,18,50,53,18,50,53,50,18,53,50 P113aZ1: dc.w NaZ1-Normales,%101,-50,-50,53,-18,-50,53,-18,-18,53,-50,-18,53 P213aZ1: dc.w NaZ1-Normales,5,-16,-50,53,16,-50,53,16,-18,53,-16,-18,53 P313aZ1: dc.w NaZ1-Normales,5,18,-50,53,50,-50,53,50,-18,53,18,-18,53 P123aZ1: dc.w NaZ1-Normales,5,-50,-16,53,-18,-16,53,-18,16,53,-50,16,53 P223aZ1: dc.w NaZ1-Normales,5,-16,-16,53,16,-16,53,16,16,53,-16,16,53 P323aZ1: dc.w NaZ1-Normales,5,18,-16,53,50,-16,53,50,16,53,18,16,53 P133aZ1: dc.w NaZ1-Normales,5,-50,18,53,-18,18,53,-18,50,53,-50,50,53 P233aZ1: dc.w NaZ1-Normales,5,-16,18,53,16,18,53,16,50,53,-16,50,53 P333aZ1: dc.w NaZ1-Normales,5,18,18,53,50,18,53,50,50,53,18,50,53 FIN_POLY: ***************** ; 54 Polygones calculés suite rotation aX,aY,aZ POLYCALCULES: PolygoneCalcules: ;normaleY,coul(1..6),A(x,y,z),B(x,y,z),C(x,y,z),D(x,y,z) dcb.b FIN_POLY-POLY,$12 dc.w 0 ;fin ***************** NORMALES: NaX1: dc.w 50,0,0 NaX2: dc.w -50,0,0 NaY1: dc.w 0,50,0 NaY2: dc.w 0,-50,0 NaZ1: dc.w 0,0,50 NaZ2: dc.w 0,0,-50 NORMALESCouronnes: dcb.w 4*3,0 FIN_NORMALES: NORMALESCalculees: dcb.b FIN_NORMALES-NORMALES,$34 dc.w 0 ;fin de normales even ***************** ;soit ds.w 21*16 ;soit dcb.w 21*16,0 ***************** ; 21 Polygones en sauver en cas de rotation de couronne polygoneSauvePourRotation: dcb.w 21*16,$0AF0 ***************** FinPROG