home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- **************************************************************************
- ** **
- ** Fragments.c **
- ** ----------- **
- ** **
- ** Auteur : Eric Le Saux **
- ** **
- ** Club Amiga Montreal (CAM) **
- ** C.P. 195 STATION "N" **
- ** Montreal (Quebec) **
- ** H2X 3M2, CANADA **
- ** **
- ** Date : 3 mars 1988 **
- ** **
- ** Statut : DOMAINE PUBLIC - Distribution non-commerciale seulement **
- ** PUBLIC DOMAIN - Freely redistributable **
- ** **
- **************************************************************************
- ************************************************************************/
-
- /*** Fichiers d'entetes *************************************************/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <intuition/intuition.h>
- #include <libraries/dos.h>
- #include <exec/memory.h>
-
- /*** Fonctions et variables externes ************************************/
-
- extern struct Library *OpenLibrary ();
- extern struct TextFont *OpenFont ();
- extern struct Screen *OpenScreen ();
- extern struct Window *OpenWindow ();
- extern struct IntuiMessage *GetMsg ();
- extern APTR AllocMem ();
- extern LONG AvailMem ();
-
- extern int Enable_Abort;
-
- /*** Quelques constantes ************************************************/
-
- #define Largeur 640
- #define Hauteur 400
- #define Profond 1
-
- #define MEM_SECURITE 30720L /* Memoire de securite, 30K */
-
- /*** Variables globales pour le maintient du systeme ********************/
-
- #define TriangleID 0
- #define FragID 1
- #define SortieID 2
-
- SHORT BorderVectors0[] = {0,0,109,0,109,23,0,23,0,0};
- struct Border Border0 = {-1,-1,1,0,JAM1,5,BorderVectors0,NULL};
- struct IntuiText IText0 = {1,0,JAM2,39,7,NULL,(UBYTE *) "Base",NULL};
-
- struct Gadget GadgTri = {NULL,32,77,108,22,NULL,RELVERIFY,BOOLGADGET,
- (APTR)&Border0,NULL,&IText0,NULL,NULL,TriangleID,NULL};
-
- SHORT BorderVectors1[] = {0,0,109,0,109,23,0,23,0,0};
- struct Border Border1 = {-1,-1,1,0,JAM1,5,BorderVectors1,NULL};
- struct IntuiText IText1 = {1,0,JAM2,2,7,NULL,(UBYTE *) "Fragmentation",NULL};
-
- struct Gadget GadgFrag = {&GadgTri,32,50,108,22,NULL,RELVERIFY,BOOLGADGET,
- (APTR)&Border1,NULL,&IText1,NULL,NULL,FragID,NULL};
-
- SHORT BorderVectors2[] = {0,0,109,0,109,23,0,23,0,0};
- struct Border Border2 = {-1,-1,1,0,JAM1,5,BorderVectors2,NULL};
- struct IntuiText IText2 = {1,0,JAM2,29,7,NULL,(UBYTE *)"Sortie",NULL};
-
- struct Gadget GadgSortie = {&GadgFrag,32,23,108,22,NULL,RELVERIFY,BOOLGADGET,
- (APTR)&Border2,NULL,&IText2,NULL,NULL,SortieID,NULL};
-
- #define GadgetList GadgSortie
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
-
- struct TextAttr FonteAttr = { (UBYTE *) "topaz.font", 8, 0, 0 };
- struct TextFont *Fonte;
-
- struct Screen *Ecran;
- struct NewScreen EcranData =
- {
- 0,0,Largeur,Hauteur,Profond,
- 0,1,HIRES|LACE,CUSTOMSCREEN,&FonteAttr,
- (UBYTE *) " Fragmentation de surfaces - Eric Le Saux - Club Amiga Montreal", NULL, NULL
- };
-
- struct Window *Fenetre;
- struct NewWindow FenetreData =
- {
- 0,12,Largeur,Hauteur-12,-1,-1,GADGETUP,
- SIMPLE_REFRESH|BACKDROP|BORDERLESS|RMBTRAP,
- NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN
- };
- /* NB: Les gadgets ne doivent pas etre linkes maintenant */
-
- struct RastPort *RP;
-
- /*** Structures de donnees ***/
-
- struct Sommet
- {
- struct Sommet *Dr, *In; /* Voisins de droite et de dessous */
- SHORT X,Y;
- }
- *Racine = NULL, /* Racine */
- *Feuille1 = NULL, /* | */
- *Feuille2 = NULL; /* v */
- /* Feuille1 -> Feuille2 */
-
- LONG Niveau = 0L; /* Niveau de fragmentation */
- SHORT Ax, Ay; /* Amplitudes en X et en Y */
-
- /*************************************************************************
- **************************************************************************
- **
- ** DetruitStructure ()
- **
- ** Detruit la structure recursive de sommets.
- **
- */
-
- void DetruitStructure (S)
- struct Sommet *S;
- {
- if (S->In)
- {
- DetruitStructure (S->In);
- }
-
- if (S->Dr)
- {
- S->Dr->In = NULL;
- DetruitStructure (S->Dr);
- }
-
- FreeMem (S, (LONG)sizeof(*S));
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** Sortie ()
- **
- ** Ferme ce qui a ete ouvert.
- **
- */
-
- void Sortie ()
- {
- if (Fenetre)
- {
- Move (RP, 34L, 111L);
- Text (RP, "Deallocation.", 13L);
- }
-
- if (Racine) DetruitStructure (Racine);
- if (Fenetre) CloseWindow (Fenetre);
- if (Ecran) CloseScreen (Ecran);
- if (IntuitionBase) CloseLibrary (IntuitionBase);
- if (GfxBase) CloseLibrary (GfxBase);
- if (Fonte) CloseFont (Fonte);
-
- _exit (0L);
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** Erreur ()
- **
- ** Affiche un message d'erreur a travers un requester.
- ** Laisse le choix entre l'abandon de la procedure et
- ** un autre essai.
- **
- ** Si 'OnSort' est FALSE, on ne sort pas sur l'abandon, on renvoie
- ** le resultat de la requete.
- */
-
- #define ErrGfxLib 0
- #define ErrIntuiLib 1
- #define ErrOpenWin 2
- #define ErrOpenScr 3
- #define ErrFonte 4
- #define ErrMemoire 5
-
- struct IntuiText Message = { 2, 1, JAM1, 17, 10, NULL, NULL, NULL };
- struct IntuiText Essai = { 2, 1, JAM1, 5, 4, NULL, (UBYTE *) "Tentative", NULL };
- struct IntuiText Abandon = { 2, 1, JAM1, 5, 4, NULL, (UBYTE *) "Abandon", NULL };
-
- BOOL Erreur (Err,OnSort)
- SHORT Err;
- BOOL OnSort;
- {
- SHORT Resultat;
-
- switch (Err)
- {
- case ErrGfxLib : Message.IText = (UBYTE *) "OpenLibrary: GfxLib";
- break;
- case ErrIntuiLib : Message.IText = (UBYTE *) "OpenLibrary: IntuiLib";
- break;
- case ErrOpenWin : Message.IText = (UBYTE *) "OpenWindow";
- break;
- case ErrOpenScr : Message.IText = (UBYTE *) "OpenScreen";
- break;
- case ErrFonte : Message.IText = (UBYTE *) "OpenFont: Topaz 8";
- break;
- case ErrMemoire : Message.IText = (UBYTE *) "Pas assez de memoire";
- break;
- default : Message.IText = (UBYTE *) "Erreur inconnue !";
- break;
- }
-
- Resultat = AutoRequest (Fenetre, &Message, &Essai, &Abandon,
- NULL, NULL, 300L, 60L);
-
- if (Resultat || !OnSort) return (Resultat);
-
- Sortie ();
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** Initialise ()
- **
- */
-
- void Initialise ()
- {
- /*=== La librairie Intuition ===*/
- /*=== Si on n'a pas la bonne version, on ouvre celle presente pour ===*/
- /*=== appeler la fonction AutoRequest (). ===*/
-
- FOREVER
- {
- IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 33L); /* v1.2+ */
- if (!IntuitionBase)
- {
- IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0L);
- if (!IntuitionBase) Sortie (); /* Plus le choix ! */
- Erreur (ErrIntuiLib,TRUE);
- Sortie ();
- }
- else break;
- }
-
- /*=== La librairie graphique ===*/
-
- FOREVER
- {
- GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0L);
- if (!GfxBase) Erreur (ErrGfxLib,TRUE);
- else break;
- }
-
- /*=== La ROMFonte par defaut ===*/
-
- FOREVER
- {
- Fonte = OpenFont (&FonteAttr);
- if (!Fonte) Erreur (ErrFonte,TRUE);
- else break;
- }
-
- /*=== On ouvre l'ecran ===*/
-
- FOREVER
- {
- Ecran = OpenScreen (&EcranData);
- if (!Ecran) Erreur (ErrOpenScr,TRUE);
- else break;
- }
-
- ShowTitle (Ecran, (LONG)FALSE);
-
- /*=== On ouvre la fenetre ===*/
-
- FenetreData.Screen = Ecran;
-
- FOREVER
- {
- Fenetre = OpenWindow (&FenetreData);
- if (!Fenetre) Erreur (ErrOpenWin,TRUE);
- else break;
- }
-
- /*=== On pointe le RastPort de la fenetre ===*/
-
- RP = Fenetre->RPort;
-
- /*=== On assigne la fonte ===*/
-
- SetFont (RP, Fonte);
-
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** _abort (), _cli_parse (), _wb_parse
- **
- */
-
- void _abort () { Sortie (); }
- void _cli_parse () {}
- void _wb_parse () {}
-
- /*************************************************************************
- **************************************************************************
- **
- ** Rnd ()
- **
- ** Retourne un nb dans un intervalle donne, bornes incluses.
- ** Le premier argument devrait etre plus petit que le second.
- **
- */
-
- USHORT Rnd (N1, N2)
- USHORT N1, N2;
- {
- return ( ( ((rand()&0x00FF) * (N2-N1+1)) >> 8 ) + N1 );
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** Vibre ()
- **
- ** Fait varier arg1 dans l'intervalle [arg1-arg2,arg1+arg2].
- **
- */
-
- SHORT Vibre (Moyenne, Etendue)
- SHORT Moyenne, Etendue;
- {
- return ((SHORT)Rnd((USHORT)(Moyenne-Etendue),(USHORT)(Moyenne+Etendue)));
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** CreeSommet ()
- **
- ** Cree dynamiquement un sommet et l'initialise.
- **
- */
-
- struct Sommet *CreeSommet (X,Y,D,I)
- SHORT X, Y;
- struct Sommet *D, *I;
- {
- struct Sommet *S;
-
- S = (struct Sommet *) AllocMem ((LONG)sizeof(*S),MEMF_PUBLIC|MEMF_CLEAR);
-
- if (S)
- {
- S->X = X;
- S->Y = Y;
- S->Dr = D;
- S->In = I;
- }
- else Sortie (); /* Pas supposes se rendre ici */
-
- return (S);
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** FragmenteStructure ()
- **
- ** Fragmente la structure de sommets d'un niveau de plus.
- ** Si le Flag est true, on est au debut d'une rangee, et on peut descendre.
- **
- */
-
- void FragmenteStructure (S,Flag,Ax,Ay)
- struct Sommet *S;
- BOOL Flag;
- SHORT Ax, Ay;
- {
- if (Flag && S->In->In) { FragmenteStructure (S->In,TRUE,Ax,Ay); }
- if (S->Dr) { FragmenteStructure (S->Dr,FALSE,Ax,Ay); }
-
- S->In->Dr = CreeSommet (Vibre((S->In->X+S->In->Dr->X)/2,Ax),
- Vibre((S->In->Y+S->In->Dr->Y)/2,Ay),
- S->In->Dr,
- (S->In->In)?S->In->In->Dr:NULL);
-
- S->In = CreeSommet (Vibre((S->X+S->In->X)/2,Ax),
- Vibre((S->Y+S->In->Y)/2,Ay),
- CreeSommet(Vibre((S->X+S->In->Dr->Dr->X)/2,Ax),
- Vibre((S->Y+S->In->Dr->Dr->Y)/2,Ay),
- (S->Dr)?S->Dr->In:NULL,
- S->In->Dr),
- S->In);
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** AfficheStructure ()
- **
- ** Affiche la structure de sommets.
- **
- */
-
- void AfficheStructure (S,Flag)
- struct Sommet *S;
- BOOL Flag;
- {
- if (Flag && S->In->In) { AfficheStructure (S->In,TRUE); }
- if (S->Dr) { AfficheStructure (S->Dr,FALSE); }
-
- Move (RP, (LONG)S->X, (LONG)S->Y);
- Draw (RP, (LONG)S->In->X, (LONG)S->In->Y);
- Draw (RP, (LONG)S->In->Dr->X, (LONG)S->In->Dr->Y);
- Draw (RP, (LONG)S->X, (LONG)S->Y);
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** InitStructure ()
- **
- ** Initialisation de la structure de base : le triangle.
- **
- */
-
- void InitStructure ()
- {
- Racine = CreeSommet (0,0,NULL,NULL);
- Feuille1 = CreeSommet (0,0,NULL,NULL);
- Feuille2 = CreeSommet (0,0,NULL,NULL);
-
- Racine->X = Largeur/2; Racine->Y = Hauteur/7;
- Feuille1->X = Largeur/7; Feuille1->Y = Hauteur-Hauteur/5;
- Feuille2->X = Largeur-Largeur/7; Feuille2->Y = Hauteur-Hauteur/5;
-
- Racine->In = Feuille1;
- Feuille1->Dr = Feuille2;
-
- Ax = (Feuille2->X - Feuille1->X) / 3;
- Ay = (Feuille2->Y - Racine->Y) / 4;
-
- Niveau = 0L;
- }
-
-
- /*************************************************************************
- **************************************************************************
- **
- ** MemDesiree ()
- **
- ** Retourne la quantite de memoire necessaire pour le prochain niveau.
- ** Plus la marge de securite pour le systeme : MEM_SECURITE.
- **
- */
-
- LONG MemDesiree (Niveau)
- LONG Niveau;
- {
- LONG Puissance=1L, NbDeSommets;
-
- while (Niveau--) Puissance *= 2L;
-
- NbDeSommets = (Puissance) * (Puissance+1L) / 2L * 3L;
-
- return ( NbDeSommets * ((LONG)sizeof(struct Sommet)+4L) + MEM_SECURITE);
- }
-
-
- /*************************************************************************
- **************************************************************************
- **************************************************************************
- ***
- *** main ()
- ***
- **/
-
- main ()
- {
- struct IntuiMessage *Msg; /* Pointeur pour prendre les messages */
- struct Gadget *Adresse; /* Pour noter l'adresse du gadget */
-
- ULONG Secondes, Micros; /* Temps courant */
-
- /*=== On permet l'abandon du programme ===*/
-
- Enable_Abort = 1;
-
- /*=== Init ===*/
-
- Initialise ();
-
- /*=== Au travail ! ===*/
-
- CurrentTime (&Secondes, &Micros);
- srand ( (SHORT) (Secondes&0x00FF) );
- Rnd(0,0); Rnd(0,0); Rnd(0,0);
- SetAPen (RP,1L);
-
- /*=== Landscape ===*/
-
- InitStructure ();
-
- AfficheStructure (Racine,TRUE);
-
- /*=== On attends un evenement: CTRL_C ou click de gadget. ===*/
-
- FOREVER
- {
- AddGList (Fenetre, &GadgetList, 0L, -1L, NULL);
- RefreshGadgets (&GadgetList, Fenetre, NULL);
-
- if (Wait (1L<<Fenetre->UserPort->mp_SigBit|SIGBREAKF_CTRL_C) == SIGBREAKF_CTRL_C)
- Sortie ();
-
- RemoveGList (Fenetre, &GadgetList, -1L);
-
- while (Msg = GetMsg (Fenetre->UserPort))
- {
- Adresse = (struct Gadget *) Msg->IAddress;
- ReplyMsg (Msg);
- if (Adresse->GadgetID == SortieID) Sortie ();
- if (Adresse->GadgetID == TriangleID)
- {
- Move (RP, 34L, 111L); Text (RP, "Deallocation.", 13L);
- DetruitStructure (Racine);
- InitStructure ();
- }
-
- FOREVER
- {
- if ( AvailMem(MEMF_PUBLIC) < MemDesiree(Niveau) )
- {
- if (Erreur(ErrMemoire,FALSE)) continue;
- else break;
- }
- else
- {
- Move (RP, 34L, 111L); Text (RP, "Fragmentation.", 14L);
- FragmenteStructure (Racine,TRUE,Ax,Ay);
- Ax /= 2; Ay /= 2; Niveau++;
- SetRast (RP, 0L);
- AfficheStructure (Racine,TRUE);
- break;
- }
- }
- }
- }
- }
-
-