home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 108.lha / Fragments.c < prev    next >
C/C++ Source or Header  |  1988-03-02  |  16KB  |  571 lines

  1. /************************************************************************
  2. **************************************************************************
  3. **                                                                      **
  4. **  Fragments.c                                                         **
  5. **  -----------                                                         **
  6. **                                                                      **
  7. **  Auteur : Eric Le Saux                                               **
  8. **                                                                      **
  9. **           Club Amiga Montreal (CAM)                                  **
  10. **           C.P. 195 STATION "N"                                       **
  11. **           Montreal (Quebec)                                          **
  12. **           H2X 3M2, CANADA                                            **
  13. **                                                                      **
  14. **  Date   : 3 mars 1988                                                **
  15. **                                                                      **
  16. **  Statut : DOMAINE PUBLIC - Distribution non-commerciale seulement    **
  17. **           PUBLIC DOMAIN  - Freely redistributable                    **
  18. **                                                                      **
  19. **************************************************************************
  20.  ************************************************************************/
  21.  
  22. /*** Fichiers d'entetes *************************************************/
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <intuition/intuition.h>
  27. #include <libraries/dos.h>
  28. #include <exec/memory.h>
  29.  
  30. /*** Fonctions et variables externes ************************************/
  31.  
  32. extern struct Library        *OpenLibrary ();
  33. extern struct TextFont        *OpenFont    ();
  34. extern struct Screen        *OpenScreen  ();
  35. extern struct Window        *OpenWindow  ();
  36. extern struct IntuiMessage    *GetMsg      ();
  37. extern APTR                      AllocMem    ();
  38. extern LONG                      AvailMem    ();
  39.  
  40. extern int Enable_Abort;
  41.  
  42. /*** Quelques constantes ************************************************/
  43.  
  44. #define Largeur 640
  45. #define Hauteur 400
  46. #define Profond 1
  47.  
  48. #define MEM_SECURITE 30720L            /* Memoire de securite, 30K */
  49.  
  50. /*** Variables globales pour le maintient du systeme ********************/
  51.  
  52. #define TriangleID 0     
  53. #define FragID     1
  54. #define SortieID   2
  55.  
  56. SHORT BorderVectors0[]  = {0,0,109,0,109,23,0,23,0,0};
  57. struct Border Border0   = {-1,-1,1,0,JAM1,5,BorderVectors0,NULL};
  58. struct IntuiText IText0 = {1,0,JAM2,39,7,NULL,(UBYTE *) "Base",NULL};
  59.  
  60. struct Gadget GadgTri   = {NULL,32,77,108,22,NULL,RELVERIFY,BOOLGADGET,
  61.                       (APTR)&Border0,NULL,&IText0,NULL,NULL,TriangleID,NULL};
  62.  
  63. SHORT BorderVectors1[]  = {0,0,109,0,109,23,0,23,0,0};
  64. struct Border Border1   = {-1,-1,1,0,JAM1,5,BorderVectors1,NULL};
  65. struct IntuiText IText1 = {1,0,JAM2,2,7,NULL,(UBYTE *) "Fragmentation",NULL};
  66.  
  67. struct Gadget GadgFrag  = {&GadgTri,32,50,108,22,NULL,RELVERIFY,BOOLGADGET,
  68.                       (APTR)&Border1,NULL,&IText1,NULL,NULL,FragID,NULL};
  69.  
  70. SHORT BorderVectors2[]  = {0,0,109,0,109,23,0,23,0,0};
  71. struct Border Border2   = {-1,-1,1,0,JAM1,5,BorderVectors2,NULL};
  72. struct IntuiText IText2 = {1,0,JAM2,29,7,NULL,(UBYTE *)"Sortie",NULL};
  73.  
  74. struct Gadget GadgSortie = {&GadgFrag,32,23,108,22,NULL,RELVERIFY,BOOLGADGET,
  75.                       (APTR)&Border2,NULL,&IText2,NULL,NULL,SortieID,NULL};
  76.  
  77. #define GadgetList GadgSortie
  78.  
  79. struct IntuitionBase     *IntuitionBase;
  80. struct GfxBase           *GfxBase;
  81.  
  82. struct TextAttr      FonteAttr = { (UBYTE *) "topaz.font", 8, 0, 0 };
  83. struct TextFont     *Fonte;
  84.  
  85. struct Screen        *Ecran;
  86. struct NewScreen    EcranData =
  87.             {
  88.                0,0,Largeur,Hauteur,Profond,
  89.                0,1,HIRES|LACE,CUSTOMSCREEN,&FonteAttr,
  90.                (UBYTE *) "   Fragmentation de surfaces  -  Eric Le Saux  -  Club Amiga Montreal", NULL, NULL
  91.             };
  92.  
  93. struct Window         *Fenetre;
  94. struct NewWindow    FenetreData =
  95.             {
  96.                0,12,Largeur,Hauteur-12,-1,-1,GADGETUP,
  97.                SIMPLE_REFRESH|BACKDROP|BORDERLESS|RMBTRAP,
  98.                NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN
  99.             };
  100.                     /* NB: Les gadgets ne doivent pas etre linkes maintenant */
  101.  
  102. struct RastPort        *RP;
  103.  
  104. /*** Structures de donnees ***/
  105.  
  106. struct Sommet
  107. {
  108.     struct Sommet *Dr, *In;  /* Voisins de droite et de dessous */
  109.     SHORT X,Y;
  110. }
  111. *Racine   = NULL,      /*   Racine                 */
  112. *Feuille1 = NULL,      /*      |                   */
  113. *Feuille2 = NULL;      /*      v                   */
  114.                        /*   Feuille1 -> Feuille2   */
  115.  
  116. LONG  Niveau = 0L;     /* Niveau de fragmentation */
  117. SHORT Ax, Ay;          /* Amplitudes en X et en Y */
  118.  
  119. /*************************************************************************
  120. **************************************************************************
  121. **
  122. **  DetruitStructure ()
  123. **
  124. **  Detruit la structure recursive de sommets.
  125. **
  126. */
  127.  
  128. void DetruitStructure (S)
  129. struct Sommet *S;
  130. {
  131.     if (S->In)
  132.     {
  133.        DetruitStructure (S->In);
  134.     }
  135.  
  136.     if (S->Dr)
  137.     {
  138.        S->Dr->In = NULL;
  139.        DetruitStructure (S->Dr);
  140.     }
  141.  
  142.     FreeMem (S, (LONG)sizeof(*S));
  143. }
  144.  
  145.  
  146. /*************************************************************************
  147. **************************************************************************
  148. **
  149. **  Sortie ()
  150. **
  151. **  Ferme ce qui a ete ouvert.
  152. **
  153. */
  154.  
  155. void Sortie ()
  156. {
  157.     if (Fenetre)
  158.     {
  159.        Move (RP, 34L, 111L);
  160.        Text (RP, "Deallocation.", 13L);
  161.     }
  162.  
  163.     if (Racine)        DetruitStructure (Racine);
  164.     if (Fenetre)       CloseWindow  (Fenetre);
  165.     if (Ecran)       CloseScreen  (Ecran);
  166.     if (IntuitionBase) CloseLibrary (IntuitionBase);
  167.     if (GfxBase)       CloseLibrary (GfxBase);
  168.     if (Fonte)       CloseFont    (Fonte);
  169.  
  170.     _exit (0L);
  171. }
  172.  
  173.  
  174. /*************************************************************************
  175. **************************************************************************
  176. **
  177. **  Erreur ()
  178. **
  179. **  Affiche un message d'erreur a travers un requester.
  180. **  Laisse le choix entre l'abandon de la procedure et
  181. **  un autre essai.
  182. **
  183. **  Si 'OnSort' est FALSE, on ne sort pas sur l'abandon, on renvoie
  184. **  le resultat de la requete.
  185. */
  186.  
  187. #define ErrGfxLib   0
  188. #define ErrIntuiLib 1
  189. #define ErrOpenWin  2
  190. #define ErrOpenScr  3
  191. #define ErrFonte    4
  192. #define ErrMemoire  5
  193.  
  194. struct IntuiText Message = { 2, 1, JAM1, 17, 10, NULL, NULL, NULL };
  195. struct IntuiText Essai   = { 2, 1, JAM1, 5, 4, NULL, (UBYTE *) "Tentative", NULL };
  196. struct IntuiText Abandon = { 2, 1, JAM1, 5, 4, NULL, (UBYTE *) "Abandon", NULL };
  197.  
  198. BOOL Erreur (Err,OnSort)
  199. SHORT Err;
  200. BOOL  OnSort;
  201. {
  202.     SHORT Resultat;
  203.  
  204.     switch (Err)
  205.     {
  206.        case ErrGfxLib   : Message.IText = (UBYTE *) "OpenLibrary: GfxLib";
  207.                           break;
  208.        case ErrIntuiLib : Message.IText = (UBYTE *) "OpenLibrary: IntuiLib";
  209.                           break;
  210.        case ErrOpenWin  : Message.IText = (UBYTE *) "OpenWindow";
  211.                           break;
  212.        case ErrOpenScr  : Message.IText = (UBYTE *) "OpenScreen";
  213.                           break;
  214.        case ErrFonte    : Message.IText = (UBYTE *) "OpenFont: Topaz 8";
  215.                           break;
  216.        case ErrMemoire  : Message.IText = (UBYTE *) "Pas assez de memoire";
  217.                           break;
  218.        default          : Message.IText = (UBYTE *) "Erreur inconnue !";
  219.                           break;
  220.     }
  221.  
  222.     Resultat = AutoRequest (Fenetre, &Message, &Essai, &Abandon,
  223.                            NULL, NULL, 300L, 60L);
  224.  
  225.     if (Resultat || !OnSort) return (Resultat);
  226.  
  227.     Sortie ();
  228. }
  229.  
  230.  
  231. /*************************************************************************
  232. **************************************************************************
  233. **
  234. **  Initialise ()
  235. **
  236. */
  237.  
  238. void Initialise ()
  239. {
  240.    /*=== La librairie Intuition ===*/
  241.    /*=== Si on n'a pas la bonne version, on ouvre celle presente pour ===*/
  242.    /*=== appeler la fonction AutoRequest ().                          ===*/
  243.  
  244.     FOREVER
  245.     {
  246.        IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 33L); /* v1.2+ */
  247.        if (!IntuitionBase)
  248.        {
  249.           IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0L);
  250.           if (!IntuitionBase) Sortie ();   /* Plus le choix ! */
  251.           Erreur (ErrIntuiLib,TRUE);
  252.           Sortie ();
  253.        }
  254.        else break;
  255.     }
  256.  
  257.    /*=== La librairie graphique ===*/
  258.  
  259.     FOREVER
  260.     {
  261.        GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0L);
  262.        if (!GfxBase) Erreur (ErrGfxLib,TRUE);
  263.                 else break;
  264.     }
  265.  
  266.    /*=== La ROMFonte par defaut ===*/
  267.  
  268.     FOREVER
  269.     {
  270.        Fonte = OpenFont (&FonteAttr);
  271.        if (!Fonte) Erreur (ErrFonte,TRUE);
  272.               else break;
  273.     }
  274.  
  275.    /*=== On ouvre l'ecran ===*/
  276.  
  277.     FOREVER
  278.     {
  279.        Ecran = OpenScreen (&EcranData);
  280.        if (!Ecran) Erreur (ErrOpenScr,TRUE);
  281.               else break;
  282.     }
  283.  
  284.     ShowTitle (Ecran, (LONG)FALSE);
  285.  
  286.    /*=== On ouvre la fenetre ===*/
  287.  
  288.     FenetreData.Screen = Ecran;
  289.  
  290.     FOREVER
  291.     {
  292.        Fenetre = OpenWindow (&FenetreData);
  293.        if (!Fenetre) Erreur (ErrOpenWin,TRUE);
  294.                 else break;
  295.     }
  296.  
  297.    /*=== On pointe le RastPort de la fenetre ===*/
  298.  
  299.     RP = Fenetre->RPort;
  300.  
  301.    /*=== On assigne la fonte ===*/
  302.  
  303.     SetFont (RP, Fonte);
  304.  
  305. }
  306.  
  307.  
  308. /*************************************************************************
  309. **************************************************************************
  310. **
  311. **  _abort (), _cli_parse (), _wb_parse
  312. **
  313. */
  314.  
  315. void _abort () { Sortie (); }
  316. void _cli_parse () {}
  317. void _wb_parse () {}
  318.  
  319. /*************************************************************************
  320. **************************************************************************
  321. **
  322. **  Rnd ()
  323. **
  324. **  Retourne un nb dans un intervalle donne, bornes incluses.
  325. **  Le premier argument devrait etre plus petit que le second.
  326. **
  327. */
  328.  
  329. USHORT Rnd (N1, N2)
  330. USHORT N1, N2;
  331. {
  332.     return ( ( ((rand()&0x00FF) * (N2-N1+1)) >> 8 ) + N1 );
  333. }
  334.  
  335.  
  336. /*************************************************************************
  337. **************************************************************************
  338. **
  339. **  Vibre ()
  340. **
  341. **  Fait varier arg1 dans l'intervalle [arg1-arg2,arg1+arg2].
  342. **
  343. */
  344.  
  345. SHORT Vibre (Moyenne, Etendue)
  346. SHORT Moyenne, Etendue;
  347. {
  348.     return ((SHORT)Rnd((USHORT)(Moyenne-Etendue),(USHORT)(Moyenne+Etendue)));
  349. }
  350.  
  351.  
  352. /*************************************************************************
  353. **************************************************************************
  354. **
  355. **  CreeSommet ()
  356. **
  357. **  Cree dynamiquement un sommet et l'initialise.
  358. **
  359. */
  360.  
  361. struct Sommet *CreeSommet (X,Y,D,I)
  362. SHORT X, Y;
  363. struct Sommet *D, *I;
  364. {
  365.     struct Sommet *S;
  366.  
  367.     S = (struct Sommet *) AllocMem ((LONG)sizeof(*S),MEMF_PUBLIC|MEMF_CLEAR);
  368.  
  369.     if (S)
  370.     {
  371.        S->X  = X;
  372.        S->Y  = Y;
  373.        S->Dr = D;
  374.        S->In = I;
  375.     }
  376.     else Sortie (); /* Pas supposes se rendre ici */
  377.  
  378.     return (S);
  379. }
  380.  
  381.  
  382. /*************************************************************************
  383. **************************************************************************
  384. **
  385. **  FragmenteStructure ()
  386. **
  387. **  Fragmente la structure de sommets d'un niveau de plus.
  388. **  Si le Flag est true, on est au debut d'une rangee, et on peut descendre.
  389. **
  390. */
  391.  
  392. void FragmenteStructure (S,Flag,Ax,Ay)
  393. struct Sommet *S;
  394. BOOL Flag;
  395. SHORT Ax, Ay;
  396. {
  397.     if (Flag && S->In->In) { FragmenteStructure (S->In,TRUE,Ax,Ay); }
  398.     if (S->Dr)             { FragmenteStructure (S->Dr,FALSE,Ax,Ay); }
  399.  
  400.     S->In->Dr = CreeSommet (Vibre((S->In->X+S->In->Dr->X)/2,Ax),
  401.                             Vibre((S->In->Y+S->In->Dr->Y)/2,Ay),
  402.                             S->In->Dr,
  403.                             (S->In->In)?S->In->In->Dr:NULL);
  404.     
  405.     S->In     = CreeSommet (Vibre((S->X+S->In->X)/2,Ax),
  406.                             Vibre((S->Y+S->In->Y)/2,Ay),
  407.                             CreeSommet(Vibre((S->X+S->In->Dr->Dr->X)/2,Ax),
  408.                                        Vibre((S->Y+S->In->Dr->Dr->Y)/2,Ay),
  409.                                            (S->Dr)?S->Dr->In:NULL,
  410.                                        S->In->Dr),
  411.                                 S->In);
  412. }
  413.  
  414.  
  415. /*************************************************************************
  416. **************************************************************************
  417. **
  418. **  AfficheStructure ()
  419. **
  420. **  Affiche la structure de sommets.
  421. **
  422. */
  423.  
  424. void AfficheStructure (S,Flag)
  425. struct Sommet *S;
  426. BOOL Flag;
  427. {
  428.     if (Flag && S->In->In) { AfficheStructure (S->In,TRUE); }
  429.     if (S->Dr)             { AfficheStructure (S->Dr,FALSE); }
  430.  
  431.     Move (RP, (LONG)S->X,         (LONG)S->Y);
  432.     Draw (RP, (LONG)S->In->X,     (LONG)S->In->Y);
  433.     Draw (RP, (LONG)S->In->Dr->X, (LONG)S->In->Dr->Y);
  434.     Draw (RP, (LONG)S->X,         (LONG)S->Y);
  435. }
  436.  
  437.  
  438. /*************************************************************************
  439. **************************************************************************
  440. **
  441. **  InitStructure ()
  442. **
  443. **  Initialisation de la structure de base : le triangle.
  444. **
  445. */
  446.  
  447. void InitStructure ()
  448. {
  449.     Racine   = CreeSommet (0,0,NULL,NULL);
  450.     Feuille1 = CreeSommet (0,0,NULL,NULL);
  451.     Feuille2 = CreeSommet (0,0,NULL,NULL);
  452.  
  453.     Racine->X   = Largeur/2;          Racine->Y   = Hauteur/7;
  454.     Feuille1->X = Largeur/7;          Feuille1->Y = Hauteur-Hauteur/5;
  455.     Feuille2->X = Largeur-Largeur/7;  Feuille2->Y = Hauteur-Hauteur/5;
  456.  
  457.     Racine->In   = Feuille1;
  458.     Feuille1->Dr = Feuille2;
  459.  
  460.     Ax = (Feuille2->X - Feuille1->X) / 3;
  461.     Ay = (Feuille2->Y - Racine->Y) / 4;
  462.  
  463.     Niveau = 0L;
  464. }
  465.  
  466.  
  467. /*************************************************************************
  468. **************************************************************************
  469. **
  470. **  MemDesiree ()
  471. **
  472. **  Retourne la quantite de memoire necessaire pour le prochain niveau.
  473. **  Plus la marge de securite pour le systeme : MEM_SECURITE.
  474. **
  475. */
  476.  
  477. LONG MemDesiree (Niveau)
  478. LONG Niveau;
  479. {
  480.     LONG Puissance=1L, NbDeSommets;
  481.  
  482.     while (Niveau--) Puissance *= 2L;
  483.  
  484.     NbDeSommets = (Puissance) * (Puissance+1L) / 2L * 3L;
  485.  
  486.     return ( NbDeSommets * ((LONG)sizeof(struct Sommet)+4L) + MEM_SECURITE);
  487. }
  488.  
  489.  
  490. /*************************************************************************
  491. **************************************************************************
  492. **************************************************************************
  493. ***
  494. ***  main ()
  495. ***
  496. **/
  497.  
  498. main ()
  499. {
  500.     struct IntuiMessage *Msg;     /* Pointeur pour prendre les messages */
  501.     struct Gadget   *Adresse;     /* Pour noter l'adresse du gadget */
  502.  
  503.     ULONG Secondes, Micros;       /* Temps courant */
  504.  
  505.    /*=== On permet l'abandon du programme ===*/
  506.  
  507.     Enable_Abort = 1;
  508.  
  509.    /*=== Init ===*/
  510.  
  511.     Initialise ();
  512.  
  513.    /*=== Au travail ! ===*/
  514.  
  515.     CurrentTime (&Secondes, &Micros);
  516.     srand ( (SHORT) (Secondes&0x00FF) );
  517.     Rnd(0,0); Rnd(0,0); Rnd(0,0);
  518.     SetAPen (RP,1L);
  519.  
  520.    /*=== Landscape ===*/
  521.  
  522.     InitStructure ();
  523.  
  524.     AfficheStructure (Racine,TRUE);
  525.  
  526.    /*=== On attends un evenement: CTRL_C ou click de gadget. ===*/
  527.  
  528.     FOREVER
  529.     {
  530.        AddGList (Fenetre, &GadgetList, 0L, -1L, NULL);
  531.        RefreshGadgets (&GadgetList, Fenetre, NULL);
  532.  
  533.        if (Wait (1L<<Fenetre->UserPort->mp_SigBit|SIGBREAKF_CTRL_C) == SIGBREAKF_CTRL_C)
  534.           Sortie ();
  535.  
  536.        RemoveGList (Fenetre, &GadgetList, -1L);
  537.  
  538.        while (Msg = GetMsg (Fenetre->UserPort))
  539.        {
  540.           Adresse = (struct Gadget *) Msg->IAddress;
  541.           ReplyMsg (Msg);
  542.           if (Adresse->GadgetID == SortieID) Sortie ();
  543.           if (Adresse->GadgetID == TriangleID)
  544.           {
  545.              Move (RP, 34L, 111L); Text (RP, "Deallocation.", 13L);
  546.              DetruitStructure (Racine);
  547.              InitStructure ();
  548.           }
  549.  
  550.           FOREVER
  551.           {
  552.              if ( AvailMem(MEMF_PUBLIC) < MemDesiree(Niveau) )
  553.              {
  554.                 if (Erreur(ErrMemoire,FALSE)) continue;
  555.                                          else break;
  556.              }
  557.              else
  558.              {
  559.                 Move (RP, 34L, 111L); Text (RP, "Fragmentation.", 14L);
  560.                 FragmenteStructure (Racine,TRUE,Ax,Ay);
  561.                 Ax /= 2; Ay /= 2; Niveau++;
  562.                 SetRast (RP, 0L);
  563.                 AfficheStructure (Racine,TRUE);
  564.                 break;
  565.              }
  566.           }
  567.        }
  568.     }
  569. }
  570.  
  571.