home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / dev / c2p.lha / C2P / CPU+Blitter / c2p8_test.c < prev    next >
C/C++ Source or Header  |  1994-07-01  |  8KB  |  391 lines

  1. // set tabs to 4
  2.  
  3. #define WIDTH    320            // MUST be a multiple of 32
  4. #define HEIGHT    200
  5.  
  6. struct TagItem TagArray[] = {
  7.     SA_Interleaved, FALSE,        // c2p8 does NOT work on interleaved screens
  8.     // can add other tags here
  9.     TAG_DONE,0
  10. };
  11.  
  12. struct ExtNewScreen NewScreenStructure = {
  13.     0,0,
  14.     WIDTH,HEIGHT,
  15.     8,                // depth
  16.     0,1,
  17.     NULL,
  18.     CUSTOMSCREEN+SCREENQUIET+NS_EXTENDED,
  19.     NULL,
  20.     NULL,
  21.     NULL,
  22.     NULL,
  23.     (struct TagItem *)&TagArray
  24. };
  25.  
  26. struct NewWindow NewWindowStructure1 = {
  27.     0,0,
  28.     WIDTH,HEIGHT,
  29.     0,1,
  30.     NULL,
  31.     SIMPLE_REFRESH+BORDERLESS+NOCAREREFRESH,
  32.     NULL,
  33.     NULL,
  34.     NULL,
  35.     NULL,
  36.     NULL,
  37.     5,5,
  38.     WIDTH,HEIGHT,
  39.     CUSTOMSCREEN
  40. };
  41.  
  42.  
  43. // external function prototypes -----------------
  44.  
  45. void __asm c2p8_init (    register __a0 UBYTE *chunky,        // pointer to chunky data
  46.                         register __a1 UBYTE *chunky_cmp,    // pointer to chunky comparison buffer
  47.                         register __a2 PLANEPTR *planes,        // pointer to planes
  48.                         register __d0 ULONG signals1,        // 1 << sigbit1
  49.                         register __d1 ULONG signals2,        // 1 << sigbit2
  50.                         register __d2 ULONG pixels,            // WIDTH * HEIGHT
  51.                         register __d3 ULONG offset,            // byte offset into plane
  52.                         register __d4 UBYTE *buff2,            // Chip buffer (size = width*height)
  53.                         register __d5 UBYTE *buff3,            // Chip buffer (size = width*height)
  54.                         register __a3 struct GfxBase *GfxBase);
  55.  
  56. void __asm c2p8_go(void);
  57.  
  58.  
  59. // internal function prototypes -----------------
  60.  
  61. long get_timer(void);
  62. void free_timer(void);
  63. long get_signals(void);
  64. void free_signals(void);
  65. long get_chunky_mem(void);
  66. void free_chunky_mem(void);
  67. void init_chunky(void);
  68. long get_window(void);
  69. void free_window(void);
  70.  
  71.  
  72. // library bases --------------------------------
  73.  
  74. struct DosLibrary        *DOSBase;
  75. struct IntuitionBase    *IntuitionBase;
  76. struct ExecBase            *SysBase;
  77. struct GfxBase            *GfxBase;
  78.  
  79. struct Library            *TimerBase;
  80. struct Library            *MathIeeeDoubBasBase;
  81.  
  82. // timer related variables ----------------------
  83.  
  84. struct timerequest    timerio_m;
  85. struct EClockVal    time0_m;
  86. struct EClockVal    time1_m;
  87.  
  88. struct timerequest    *timerio = &timerio_m;
  89. struct EClockVal    *time0    = &time0_m;
  90. struct EClockVal    *time1    = &time1_m;
  91.  
  92. ULONG timerclosed = TRUE;
  93. double micros_per_eclock;        // Length of EClock tick in microseconds
  94.  
  95. // window related variables ---------------------
  96.  
  97. struct RastPort *RP;
  98. struct Screen *s;
  99. struct Window *w;
  100.  
  101.  
  102. // chunky data and c2p8() related variables -----
  103.  
  104. UBYTE *chunky;        // chunky data (preferably in fast ram)
  105. UBYTE *chunky_cmp;    // chunky data comparison buffer (preferably in fast ram)
  106. UBYTE *buff2;        // blitter buffer (chip ram)
  107. UBYTE *buff3;        // blitter buffer (chip ram)
  108.  
  109. long sigbit1 = -1;        // used by c2p8()
  110. long sigbit2 = -1;        // used by c2p8()
  111.  
  112.  
  113. #define nokick    "This needs Kickstart 3.0!\n"
  114. #define REPEAT_COUNT 10
  115.  
  116. long __saveds main(void)
  117. {
  118.     int count;
  119.     double micros, sum_micros;
  120.  
  121.     SysBase = *(struct ExecBase **)4;
  122.  
  123.     if(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library",33))
  124.     {
  125.         // check what kickstart version we are using
  126.         // inform the user and exit if lower than 39
  127.  
  128.         if( DOSBase->dl_lib.lib_Version < 39)
  129.         {
  130.             Write(Output(), nokick, sizeof(nokick) );
  131.             CloseLibrary( (struct Library *) DOSBase);
  132.             return(0);
  133.         }
  134.  
  135.  
  136.         // if compiling with 68020+ code, exit before we crash
  137.         // a 68000 machine
  138.  
  139.  
  140.         #ifdef _M68020
  141.         if(! ( SysBase->AttnFlags & AFF_68020) )
  142.         {
  143.             Printf("This version needs at least a 68020!\n");
  144.             return(0);
  145.         }
  146.         #endif
  147.  
  148.  
  149.         if(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",39))
  150.         if(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",39))
  151.         {
  152.  
  153.             if( get_timer() )
  154.             if( get_window() )
  155.             if( get_chunky_mem() )
  156.             if( get_signals() )
  157.             {
  158.                 Printf ("\nWidth = %ld, Height = %ld, Depth = 8\n\n",WIDTH, HEIGHT );
  159.         
  160.                 sum_micros = 0.0;
  161.         
  162.  
  163.                 // initialize c2p converter
  164.  
  165.         
  166.                 c2p8_init (    chunky,
  167.                             chunky_cmp,
  168.                             &RP->BitMap->Planes[0],
  169.                             1 << sigbit1,
  170.                             1 << sigbit2,
  171.                             WIDTH * HEIGHT,
  172.                             0,
  173.                             buff2,
  174.                             buff3,
  175.                             GfxBase);
  176.  
  177.                 // fill the chunky buffer with a distinct pattern and a triangle
  178.  
  179.                 init_chunky();
  180.             
  181.                 // time each c2p call and average it out over 10 calls
  182.  
  183.                 for (count = 0; count < REPEAT_COUNT; count++)
  184.                 {
  185.             
  186.                     Forbid();
  187.                     ReadEClock(time0);
  188.                     
  189.                     c2p8_go();    // Convert chunky buffer to planar
  190.                                 // only writes to the screen if the chunky
  191.                                 // buffer has changed since last time.
  192.                                 // Only converts the changed data
  193.                         
  194.                     ReadEClock (time1);
  195.                     Permit();
  196.             
  197.                     micros = (time1->ev_lo - time0->ev_lo) * micros_per_eclock;
  198.                     sum_micros += micros;
  199.             
  200.                     Printf (" %8ld : %9ld µs\n", count, (long)micros);
  201.  
  202.                 }
  203.  
  204.  
  205.                 Printf ("\nMean time = %9ld microseconds\n\n", (long)(sum_micros / REPEAT_COUNT) );
  206.  
  207.             }
  208.  
  209.             free_signals();            // wait for c2p8 to finish before
  210.                                     // freeing memory or closing screens
  211.  
  212.             free_chunky_mem();
  213.             free_window();
  214.             free_timer();
  215.  
  216.             CloseLibrary((struct Library *)GfxBase);
  217.  
  218.         }
  219.  
  220.         if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  221.  
  222.         CloseLibrary((struct Library *)DOSBase);
  223.     }
  224.  
  225.     return(0);
  226.  
  227. }
  228.  
  229.  
  230. // open timer.device and the math library -------
  231.  
  232. long get_timer(void)
  233. {
  234.     long ok = 0;
  235.  
  236.     if(MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library",33))
  237.     if( ! (timerclosed = OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerio, 0)))
  238.     {
  239.         TimerBase = (struct Library *)timerio->tr_node.io_Device;
  240.         micros_per_eclock = 1000000.0 / (double)ReadEClock (time0);
  241.  
  242.         ok = 1;
  243.     }
  244.  
  245.     return(ok);
  246.  
  247. }
  248.  
  249. void free_timer(void)
  250. {
  251.     if(!timerclosed)
  252.         CloseDevice( (struct IORequest *) timerio);
  253.  
  254.     if(MathIeeeDoubBasBase)
  255.         CloseLibrary(MathIeeeDoubBasBase);
  256. }
  257.  
  258.  
  259. // get signals necessary for c2p8() -------------
  260.  
  261. long get_signals(void)
  262. {
  263.     long ok = 0;
  264.  
  265.     if(-1 != (sigbit1 = AllocSignal(-1)))
  266.     {
  267.         SetSignal (1 << sigbit1, 1 << sigbit1); // Initial state is "finished"
  268.  
  269.         if(-1 != (sigbit2 = AllocSignal(-1)))
  270.         {
  271.             SetSignal (1 << sigbit2, 1 << sigbit2); // Initial state is "finished"
  272.  
  273.             ok = 1;
  274.         }
  275.     }
  276.  
  277.     return(ok);
  278.  
  279. }
  280.  
  281. void free_signals(void)
  282. {
  283.     if(sigbit1 != -1)
  284.     {
  285.         Wait (1 << sigbit1);    // wait for last c2p8 to finish pass 3
  286.         FreeSignal(sigbit1);
  287.         sigbit1 = -1;
  288.     }
  289.  
  290.     if(sigbit2 != -1)
  291.     {
  292.         Wait (1 << sigbit2);    // wait for last c2p8 to finish totally
  293.         FreeSignal(sigbit2);
  294.         sigbit2 = -1;
  295.     }
  296. }
  297.  
  298.  
  299. // get memory for chunky buffer, chunky comparsion buffer
  300. // and two blitter buffers needed by c2p8() -----
  301.  
  302. long get_chunky_mem(void)
  303. {
  304.     long ok = 0, size = WIDTH * HEIGHT;
  305.  
  306.     if( chunky = AllocVec(size, MEMF_CLEAR+MEMF_ANY))
  307.     if( chunky_cmp = AllocVec(size, MEMF_CLEAR+MEMF_ANY))
  308.     if( buff2 = AllocVec(size, MEMF_CLEAR+MEMF_CHIP))
  309.     if( buff3 = AllocVec(size, MEMF_CLEAR+MEMF_CHIP))
  310.     {
  311.         ok = 1;
  312.     }
  313.  
  314.     return(ok);
  315.  
  316. }
  317.  
  318. void free_chunky_mem(void)
  319. {
  320.     if(buff3)
  321.         FreeVec(buff3);
  322.  
  323.     if(buff2)
  324.         FreeVec(buff2);
  325.  
  326.     if(chunky_cmp)
  327.         FreeVec(chunky_cmp);
  328.  
  329.     if(chunky)
  330.         FreeVec(chunky);
  331.  
  332. }
  333.  
  334.  
  335. // Write a distinctive pattern to chunky buffer and a triangle
  336.  
  337. #define write_pixel(x,y,p) (chunky[y * WIDTH + x] = p )
  338.  
  339. void init_chunky(void)
  340. {
  341.     int i, j;
  342.     UBYTE *p;
  343.  
  344.     p = chunky;
  345.     for (j = 0; j < HEIGHT; j++)
  346.     for (i = 0; i < WIDTH; i++)
  347.     *p++ = (i + j) & 255;
  348.  
  349.     // Draw a triangle to check orientation
  350.  
  351.     for (i = 50; i < 150; i++)
  352.     {
  353.         write_pixel (i, 150, i);
  354.         write_pixel (i+120, 150, i);
  355.  
  356.         write_pixel (50, i, i);
  357.         write_pixel (170, i, i);
  358.  
  359.         write_pixel (i, i, i);
  360.         write_pixel (i+120, i, i);
  361.     }
  362. }
  363.  
  364.  
  365. // open a screen and a window -------------------
  366.  
  367. long get_window(void)
  368. {
  369.     long ok = 0;
  370.  
  371.     if(s = OpenScreen( (struct NewScreen *) &NewScreenStructure))
  372.     {
  373.         NewWindowStructure1.Screen = s;
  374.  
  375.         if(w = OpenWindow(&NewWindowStructure1))
  376.         {
  377.             RP = w->RPort;
  378.             ok = 1;
  379.         }
  380.     }
  381.  
  382.     return(ok);
  383.  
  384. }
  385.  
  386. void free_window(void)
  387. {
  388.     if(w) CloseWindow(w);
  389.     if(s) CloseScreen(s);
  390. }
  391.