mbergmann-sh

Mandelbench.c

Oct 8th, 2021
540
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*  
  2.  *  mandelbench.c
  3.  *  Mandelbrot Fraktal Benchmark
  4.  *  Norman Walter / Michael Bergmann
  5.  */
  6.  
  7. #include <exec/types.h>
  8. #include <exec/exec.h>
  9. #include <intuition/intuition.h>
  10. #include <graphics/gfx.h>
  11. #include <dos/dos.h>
  12.  
  13. #include <proto/intuition.h>
  14. #include <proto/graphics.h>
  15. #include <proto/exec.h>
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <time.h>
  20. #include <math.h>
  21.  
  22.  
  23. // Unsere Header-Datei mit dem Array Colors
  24. #include "Farben.h"
  25.  
  26. #ifdef __SASC
  27. const int sasversion = __VERSION__;
  28. const int sasrev = __REVISION__;
  29. #endif
  30.  
  31. struct Screen *myScreen;
  32.  
  33. /* -- Easy Request structure -- */
  34. struct EasyStruct timereq =
  35. {
  36.     sizeof(struct EasyStruct),
  37.     0,
  38.     "Statistics",
  39.  
  40.     "Mandelbrot Runtime Benchmark\nbased on a source by N. Walter\n\nCompiler: %s\n\nExecution took %s seconds.",
  41.     "Ok"
  42. };
  43.  
  44.  
  45. double time1 = 0.0, tstart; /* vars for time measurement */
  46. char extimestring[20] = ""; /* string var or converted execution time result */
  47. char compilerstring[50] = "Default";
  48. char screenstring[50] = "Mandelbrot Benchmark © 2021 by M. Bergmann";
  49. char titlestring[100] = "Mandelbrot Test is running...";
  50. UWORD pens[] = {~0};
  51.  
  52.  
  53. // Platz für 64 Pen-Nummern
  54. LONG Pens[64];
  55.  
  56. char *compilerinfo(void)
  57. {
  58.     char puffer[80];
  59.     char *datum = "unbekannt";
  60.     char *compiler = "Compiler: unbekannt";
  61.  
  62.     // SAS C
  63.     #ifdef __SASC
  64.         strcpy(compiler, "SAS/C, Version ");
  65.         sprintf(puffer, "%d", sasversion);  // Integer in String umwandeln für Weiterverarbeitung!
  66.         strcat(compiler,puffer);
  67.         strcat(compiler, ".");
  68.         sprintf(puffer, "%d", sasrev);  // Integer in String umwandeln für Weiterverarbeitung!
  69.         strcat(compiler, puffer);
  70.     #endif
  71.     // StormC 3
  72.     #ifdef __STORM__
  73.         strcpy(compiler, "StormC 3, Revision ");
  74.         sprintf(puffer, "%ld", __STORM__);
  75.         strcat(compiler, puffer);
  76.     #endif
  77.     // StormGCC (StormC 4)
  78.     #ifdef __STORMGCC__
  79.         strcpy(compiler,"Compiler:GNU gcc, Flavour: StormGCC, Version ");
  80.         sprintf(puffer, "%d", __GNUC__);    // Integer in String umwandeln für Weiterverarbeitung!
  81.         strcat(compiler, puffer);
  82.         strcat(compiler, ".");
  83.         sprintf(puffer, "%d", __GNUC_MINOR__);  // Integer in String umwandeln für Weiterverarbeitung!
  84.         strcat(compiler, puffer);
  85.     #endif
  86.     // GNU C
  87.     #ifndef __STORMGCC__
  88.         #ifdef __GNUC__
  89.             strcpy(compiler, "Compiler: GNU gcc, Version ");
  90.             sprintf(puffer, "%d", __GNUC__);    // Integer in String umwandeln für Weiterverarbeitung!
  91.             strcat(compiler, puffer);
  92.             strcat(compiler, ".");
  93.             sprintf(puffer, "%d", __GNUC_MINOR__);  // Integer in String umwandeln für Weiterverarbeitung!
  94.             strcat(compiler, puffer);
  95.         #endif
  96.     #endif
  97.     // VBCC
  98.     #ifdef __VBCC__
  99.         strcpy(compiler, "VBCC");
  100.     #endif
  101.     return compiler;
  102. }
  103.  
  104.  
  105. /*  InitPens Initialisiert unser Array Pens
  106.  *  Dazu werden die zu den Einträgen im Array Colors
  107.  *  am besten passenden Pens der ColorMap cm herausgesucht
  108.  *  und deren Nummern im Array Pens abgelegt.
  109.  */
  110. void InitPens(struct ColorMap *cm)
  111. {
  112.    int i,j;
  113.    j=0;
  114.  
  115.    // Gehe alle Einträge vom Array Colors durch
  116.    for(i=0;i<64*3;i+=3)
  117.    {
  118.        Pens[j] = ObtainBestPen(cm,
  119.                                Colors[i],    // Rotanteil
  120.                                Colors[i+1],  // Grünanteil
  121.                                Colors[i+2],  // Blauanteil
  122.                                OBP_Precision, PRECISION_EXACT,
  123.                                OBP_FailIfBad, FALSE,
  124.                                TAG_DONE);
  125.        j++;
  126.    }
  127. }
  128.  
  129. /* Pens wieder freigeben */
  130. void FreePens(struct ColorMap *cm)
  131. {
  132.    int i;
  133.  
  134.    for(i=0;i<64;i++) ReleasePen(cm,Pens[i]);
  135. }
  136.  
  137. /*  Berechnet Parameter n für das Mandelbrot Fraktal
  138.  *  abhängig von cx,cy.
  139.  */
  140. UBYTE Berechne_n(double cx, double cy)
  141. {
  142.   double x,y,tx,ty;
  143.   UBYTE n = 0;
  144.  
  145.   x = 0.0;
  146.   y = 0.0;
  147.  
  148.   do
  149.   {
  150.       tx = x*x - y*y + cx;
  151.       ty = 2.0 * x * y + cy;
  152.       x = tx;
  153.       y = ty;
  154.  
  155.       n++;
  156.   }
  157.   while((x*x + y*y <= 4.0) && (n < 100));
  158.  
  159.   return n;
  160. }
  161.  
  162. /* Zeichnet Mandelbrot Fraktal in das Fenster */
  163. void Mandelbrot(struct Window *Win, double x_offset, double y_offset, double zoomfaktor)
  164. {
  165.   int x,y,xmin,xmax,ymin,ymax;
  166.   UBYTE n;
  167.   int w,h;
  168.   double zoom;
  169.  
  170.   struct RastPort *rp;
  171.   rp=Win->RPort;
  172.   strcpy(titlestring, "Mandelbrot Test is running...");
  173.   SetWindowTitles((struct Window *)Win, titlestring, screenstring);
  174.  
  175.   /* -- starte Zeitmessung -- */
  176.   tstart = clock();
  177.  
  178.   w = Win->GZZWidth;   // Breite des Fensters
  179.   h = Win->GZZHeight;  // Höhe des Fensters
  180.  
  181.   zoom = w*zoomfaktor;
  182.  
  183.   xmin=-w/2;
  184.   ymin=-h/2;
  185.   xmax=w/2;
  186.   ymax=h/2;
  187.  
  188.   x=xmin;
  189.   y=ymin;
  190.  
  191.   /* Busy Pointer setzen */
  192.   SetWindowPointer(Win, WA_BusyPointer, TRUE, TAG_DONE);
  193.  
  194.   /* Schleife für Spalten */
  195.   for (x=xmin;x<=xmax;x++)
  196.   {
  197.      /* Schleife für Zeilen */
  198.      for(y=ymin;y<=ymax;y++)
  199.      {
  200.         /* Farbwert hängt vom Parameter n ab */
  201.         n = Berechne_n( (double)(x+x_offset)/zoom,(double)(y+y_offset)/zoom);
  202.  
  203.         if (n>=100) SetAPen(rp,Pens[0]);
  204.         else SetAPen(rp,Pens[n%64]);
  205.  
  206.         WritePixel(rp,x+xmax,y+ymax);
  207.       }
  208.   }
  209.  
  210.   /* Normaler Mousepointer */
  211.   SetWindowPointer(Win, TAG_DONE);
  212.  
  213.   time1 += clock() - tstart;    /* end measureing */
  214.  
  215.   /* convert result to be displayed in a requester */
  216.   time1 = time1 / CLOCKS_PER_SEC;
  217.   sprintf(extimestring, "%.2lf", time1);
  218.   sprintf(titlestring, "Mandelbrot Benchmark was done in %.2lf secs!", time1);
  219.  
  220.   strcpy(compilerstring, compilerinfo());
  221.   SetWindowTitles((struct Window *)Win, titlestring, screenstring);
  222.   EasyRequest(Win, &timereq, NULL, compilerstring, extimestring);
  223. }
  224.  
  225.  
  226. int main(void)
  227. {
  228.   struct Window *Fenster;               // Zeiger auf Window-Struktur
  229.   struct IntuitionBase *IntuitionBase;  // Zeiger auf IntuitionBase-Struktur
  230.   struct GfxBase *GfxBase;              // Zeiger auf GfxBase-Struktur
  231.  
  232.   /* Zeiger auf die ColorMap, die wir verändern möchten */
  233.   struct ColorMap *cm;
  234.  
  235.   /* Variablen zur Message-Bearbeitung */
  236.   struct MsgPort *Port;             // Zeiger auf Message Port Struktur
  237.   struct IntuiMessage *Nachricht;   // Zeiger auf Intuition Message Struktur
  238.   ULONG  klasse;
  239.   USHORT code;
  240.  
  241.   double zoom;                      // Zoom für Mandelbrot Fraktal
  242.   double x_offset,y_offset;
  243.  
  244.   BOOL Weiter=TRUE;                 // Boolsche Variable: Programmende?
  245.  
  246.   // Intuition Library öffnen
  247.   IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",36L);
  248.  
  249.   if (IntuitionBase != NULL)
  250.   {
  251.     // Graphics Library öffnen
  252.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L);
  253.  
  254.     if (GfxBase != NULL)
  255.     {
  256.         /* -- open new Screen with parameters -- */
  257.                 myScreen = OpenScreenTags(NULL,
  258.                     //SA_LikeWorkbench, TRUE,
  259.                     SA_Left, 0,
  260.                     SA_Top, 0,
  261.                     /* PAL LoRes Interlace */
  262.                     SA_Width, 640,  //359,
  263.                     SA_Height, 400, //274,
  264.                     SA_Pens, (ULONG)pens,   /* use wb-like default colors */
  265.                     SA_Depth, 6,            /* 32 Color mode */
  266.                     SA_Title, screenstring,
  267.                     SA_Type, CUSTOMSCREEN, SA_SysFont, 1,
  268.                     TAG_DONE);
  269.  
  270.       // Fenster mittels Tags öffnen
  271.       Fenster = OpenWindowTags(NULL,
  272.                                WA_Left, 0,      // Abstand vom linken Rand
  273.                                WA_Top, 15,      // Abstand vom oberen Rand
  274.                                WA_Width, 320,   // Breite
  275.                                WA_Height, 385,  // Höhe
  276.                                WA_Title, titlestring,    // Fenstertitel
  277.                                WA_CloseGadget, TRUE,           // Close-Gadget
  278.                                WA_DragBar, TRUE,               // Ziehleiste
  279.                                WA_DepthGadget, TRUE,           // Depth-Gadget
  280.                                WA_SizeGadget, FALSE,
  281.                                WA_GimmeZeroZero, TRUE,         // Ursprung 0/0
  282.                                WA_CustomScreen, myScreen,
  283.                                WA_IDCMP,                       // IDCMP Flags
  284.                                IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_NEWSIZE | IDCMP_RAWKEY,
  285.                                WA_Activate, TRUE,              // Fenster aktivieren
  286.                                WA_MinWidth, 100,               // minimale Breite
  287.                                WA_MinHeight, 100,              // minimale Breite
  288.                                WA_MaxWidth, 1024,              // maximale Breite
  289.                                WA_MaxHeight, 768,              // maximale Höhe
  290.                                TAG_DONE);
  291.  
  292.       if (Fenster != NULL)
  293.       {
  294.         /*  Zeiger auf die ColorMap des Screens,
  295.          *  auf dem sich unser Fenster befindet
  296.          */
  297.          cm = Fenster->WScreen->ViewPort.ColorMap;
  298.  
  299.          zoom=0.3;
  300.          x_offset=-zoom*Fenster->GZZWidth/2.0;
  301.          y_offset=0.0;
  302.  
  303.          /* Jetzt initialisieren wir unser Array Pens */
  304.          InitPens(cm);
  305.  
  306.          /* Unser Port ist der UserPort unseres Fensters */
  307.          Port = Fenster->UserPort;
  308.  
  309.          /* Mandelbrot Fraktal zeichnen */
  310.          Mandelbrot(Fenster,x_offset,y_offset,zoom);
  311.  
  312.          /*  Schleife läuft so lange, bis das Programm
  313.           *  durch anclicken des Close-Gadgets beedet wird.
  314.           */
  315.           while (Weiter)
  316.             {
  317.              /* Auf ankommende Nachricht warten */
  318.              WaitPort(Port);
  319.  
  320.              /* Schleife läuft bis alle Ereignisse
  321.               * abgearbeitet sind.
  322.               */
  323.                 while(Nachricht = (struct IntuiMessage *) GetMsg(Port))
  324.                 {
  325.                   klasse = Nachricht->Class;
  326.                   code =  Nachricht->Code;
  327.  
  328.                /* Welches Ereignis ist eingetreten? */
  329.                   switch(klasse)
  330.                   {
  331.                      /*  Ein Klick auf das CloseGadget
  332.                       *  beendet das Programm
  333.                       */
  334.                   case CLOSEWINDOW:
  335.                        Weiter=FALSE;
  336.                        break;
  337.  
  338.                   /*  Mit den Tasten + und - kann man
  339.                    *  in das Fraktal zoomen.
  340.                    */
  341.                   case VANILLAKEY:
  342.                        if (code == '+')
  343.                        {
  344.                          zoom += 0.05;
  345.                          Mandelbrot(Fenster,x_offset,y_offset,zoom);
  346.                        }
  347.                        if (code == '-')
  348.                        {
  349.                          zoom -= 0.05;
  350.                          Mandelbrot(Fenster,x_offset,y_offset,zoom);
  351.                        }
  352.                        break;
  353.  
  354.                   /*  Sondertaste wurde gedrückt
  355.                    */
  356.                   case RAWKEY:
  357.                        switch (code)
  358.                        {
  359.                           // Es war die Escape-Taste
  360.                           case 0x45:
  361.                                Weiter=FALSE;
  362.                                break;
  363.  
  364.                           // Pfeiltaste links
  365.                           case 0x4F:
  366.                                x_offset += 10.0;
  367.                                Mandelbrot(Fenster,x_offset,y_offset,zoom);
  368.                                break;
  369.  
  370.                           // Pfeiltaste rechts
  371.                           case 0x4E:
  372.                                x_offset -= 10.0;
  373.                                Mandelbrot(Fenster,x_offset,y_offset,zoom);
  374.                                break;
  375.  
  376.                           // Pfeiltaste oben
  377.                           case 0x4C:
  378.                                y_offset += 10.0;
  379.                                Mandelbrot(Fenster,x_offset,y_offset,zoom);
  380.                                break;
  381.  
  382.                           // Pfeilteste unten
  383.                           case 0x4D:
  384.                                y_offset -= 10.0;
  385.                                Mandelbrot(Fenster,x_offset,y_offset,zoom);
  386.                                break;
  387.  
  388.                        }
  389.                        break;
  390.  
  391.                   /*  Wenn der Benutzer die Fenstergröße ändert,
  392.                    *  muß der Inhalt des Fensters neu gezeichnet
  393.                    *  werden.
  394.                    */
  395.                   case NEWSIZE:
  396.                        Mandelbrot(Fenster,x_offset,y_offset,zoom);
  397.                        break;
  398.  
  399.                  } // Ende der switch-Verzweigung
  400.  
  401.                ReplyMsg((struct Message *)Nachricht);
  402.  
  403.              } // Ende der inneren while-Schleife
  404.         } // Ende der äußeren while-Schleife
  405.  
  406.          /* Alle Pens aus dem Array wieder freigeben */
  407.          FreePens(cm);
  408.  
  409.          CloseWindow(Fenster);   // Fenster schließen
  410.       } // end if
  411.         CloseScreen(myScreen);
  412.     } // end if
  413.  
  414.   } // end if
  415.  
  416.   // Libraries schließen
  417.   if (GfxBase != NULL) CloseLibrary((struct Library *)GfxBase);
  418.   if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase);
  419.  
  420.   return 0;
  421. }
  422.  
RAW Paste Data